diff --git a/CHANGELOG.md b/CHANGELOG.md index c04cba3..18f498e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,46 @@ The format follows [Keep a Changelog](https://keepachangelog.com/1.1.0/) and thi adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) — with the caveat that the public API is not frozen until `1.0.0`. Pin an exact version. +## [0.1.3] + +An additive release. No packing request/result field or solver algorithm changed. + +### Added + +- **First-party carrier connectors for UPS, FedEx, DHL Express and USPS**, and a live + rate-card contract behind them. Connectors prepare ordinary rate-table data before a + deterministic solve; no network call, clock or carrier module enters a packing engine. + A rate card records which tariff version priced a quote and when it was fetched, and a + card that has gone stale is refused rather than served. + +### Fixed + +- **`@packvium/browser` now works under Node**, not only in a browser. The WebAssembly + loader generated for the `web` target fetches its own `.wasm` from a `file:` URL, which + Node's `fetch` refuses — so server-side rendering, a Vitest node environment and + `node --test` failed at initialization on 0.1.1 and 0.1.2. The package now selects a + Node entry point that reads the module off disk. Browser behaviour is unchanged. +- **The PHP package's compatibility tree could not autoload a class on old PHP.** Its + entry point was the one shipped file the downgrade did not process, and it used a PHP 8 + function to match the namespace prefix. Three of its solver files also could not be + parsed by PHP 8.0 or 8.1, which that tree also serves. Both are fixed, and the tree is + installed and loaded on 7.3, 7.4, 8.0 and 8.1 before release. +- **The compatibility tree did not place items where the canonical engine does on PHP 7.** + Several solver comparators were partial and relied on `usort` being stable, which PHP + guarantees only from 8.0, so three shared fixtures came back with a different rotation + chosen. The tie-breaking is explicit now — identical results on every supported version — + and no released package ever carried it, because none was installable below 8.2. + +### Changed + +- **`packvium/packvium` now requires `php: >=7.3` instead of `>=8.2`.** One package + carries both the canonical PHP 8.2+ source and a generated `src-legacy/` tree, and its + `autoload.php` selects by `PHP_VERSION_ID`; PHP parses only what it loads. + `composer require packvium/packvium` is the right command on 7.3 through 8.5, and every + one of those versions is held to the same committed placement results. Nothing changes + for an 8.2+ consumer: the same files load, under the same names. +- Every package's `homepage` now points at . + ## [0.1.2] An additive documentation and integration release. No packing request/result field or diff --git a/README.md b/README.md index 6a317da..2bcd108 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,9 @@ One request and result contract, implemented independently in four engines (Rust Python, PHP, JavaScript) and held to identical placements on a shared fixture set. Pick the package for your stack; mixing them in one system is safe. +Documentation, the constraint reference and the benchmarks are at +[packvium.com](https://packvium.com). + | Package | Install | Source | | --- | --- | --- | | Python — [`packvium`](https://pypi.org/project/packvium/) | `pip install packvium` | [packvium-python](https://github.com/toxakara/packvium-python) | diff --git a/docs/GUARANTEES.md b/docs/GUARANTEES.md index 499404a..af5efb3 100644 --- a/docs/GUARANTEES.md +++ b/docs/GUARANTEES.md @@ -48,7 +48,7 @@ silently — if you need them, they belong in your own layer above this library. ## Status of this release -Version `0.1.2` is an early release. The public API is not yet frozen: field names, +Version `0.1.3` is an early release. The public API is not yet frozen: field names, status codes and the objective vector may change before `1.0.0`. Pin an exact version. The algorithm complexities documented in `ALGORITHMS-AND-COMPLEXITY.md` are design diff --git a/index.js b/index.js index 44cef6b..a4cee21 100644 --- a/index.js +++ b/index.js @@ -29,7 +29,7 @@ export function rebalanceWeight(request,result,{maxMoves=64}={}){ } return rebalanceFallback(request,result,{maxMoves}); } -export const version=()=>native?.version?.()??'0.1.2-js-fallback'; +export const version=()=>native?.version?.()??'0.1.3-js-fallback'; /** * The exported commercial and control-plane API: a quote, a policy decision and catalog diff --git a/package.json b/package.json index 5dee38b..e7344fe 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name":"@packvium/engine", - "version":"0.1.2", + "version":"0.1.3", "description":"Native-first 3D cartonization with deterministic JS fallback", "keywords":["3d-bin-packing","bin-packing","cartonization","packing","container-loading","logistics","shipping","deterministic"], - "homepage":"https://github.com/toxakara/packvium-node#readme", + "homepage":"https://packvium.com", "repository":{"type":"git","url":"git+https://github.com/toxakara/packvium-node.git"}, "bugs":{"url":"https://github.com/toxakara/packvium-node/issues"}, "type":"module", @@ -12,7 +12,7 @@ "exports":{".":{"types":"./index.d.ts","import":"./index.js"}}, "files":["index.js","fallback.js","contact-graph.js","policy.js","commerce.js","commerce-model.js","examples","index.d.ts","README.md","SECURITY.md"], "engines":{"node":">=16"}, - "optionalDependencies":{"@packvium/native":"0.1.2"}, + "optionalDependencies":{"@packvium/native":"0.1.3"}, "scripts":{ "test":"node --test \"test/*.test.mjs\"", "test:legacy":"node test/legacy-conformance.mjs" diff --git a/test/fallback.test.mjs b/test/fallback.test.mjs index 4065c80..7aec916 100644 --- a/test/fallback.test.mjs +++ b/test/fallback.test.mjs @@ -40,11 +40,17 @@ const rebalanceFixtureUrl = new URL('../../../../conformance/scene/rebalance-fix const sharedRebalanceCase = existsSync(rebalanceFixtureUrl) ? JSON.parse(readFileSync(rebalanceFixtureUrl)).cases[0] : null; +// Also workspace-only, and guarded for the same reason as the fixture above: in a +// published copy this path resolves above the package root, where nothing exists. Loading +// it unguarded took every job in the mirror's matrix down at module load, on every OS and +// every Node version, from 2026-08-14 until this guard was added. const nestedTopLoadFixtureUrl = new URL( '../../conformance/shared/fixtures/regression-grid-cumulative-top-load.json', import.meta.url, ); -const sharedNestedTopLoadRequest = JSON.parse(readFileSync(nestedTopLoadFixtureUrl)); +const sharedNestedTopLoadRequest = existsSync(nestedTopLoadFixtureUrl) + ? JSON.parse(readFileSync(nestedTopLoadFixtureUrl)) + : null; test('explanations are deterministic and localization-ready', () => { const item = { @@ -259,7 +265,11 @@ test('general grid propagates top load through adjacent nested items', () => { assert.deepEqual(placements(result).map(placement => placement.top_load.ticks), [8_000_000_000, 0]); }); -test('shared nested lattice honours support ratio, single contact, and cumulative load', () => { +test('shared nested lattice honours support ratio, single contact, and cumulative load', (t) => { + if (sharedNestedTopLoadRequest === null) { + t.skip('the shared cross-language fixture corpus is not part of this package'); + return; + } const result = packSound(sharedNestedTopLoadRequest); assert.equal(result.complete, true);