Changelog
This project follows Keep a Changelog and Semantic Versioning.
Changed
Section titled “Changed”- Documentation site now matches the provided design: a custom 404, a changelog page generated
from
CHANGELOG.md, top-level section navigation with a version chip, and the bee mark inside “Bee aware” callouts (#19) - Landing page rebuilt against the design markup: two-column hero with the bee mark, radial glow, pill badge, hexagon feature icons, framed code sample and the driver grid (#20)
- Doc-page chrome matched to the design — sidebar rails, table of contents, previous/next cards, heading scale, honey-tinted inline code, and a breadcrumb above each title (#21)
1.0.0 - 2026-09-08
Section titled “1.0.0 - 2026-09-08”First release. @qubeejs/core is the framework-agnostic engine extracted from
ng-qubee, which remains supported and unaffected.
Every URI this library builds was verified byte-for-byte against ng-qubee@3.8.0 across all
eighteen drivers before release — see test/parity/ and npm run test:parity.
- The core, with no Angular, no React, no RxJS and no Signals, and zero runtime dependencies: 18 backend drivers, each with a request and a response strategy (#1)
QueryBuilder— the fluent, capability-checked builder.generateUri()is synchronous and throws; URI construction never performed I/O (#6)QubeeStore— state exposed asgetSnapshot()+subscribe(), deliberately React’suseSyncExternalStorecontract, so each adapter supplies its own reactivity (#5)Paginator— parses a response through the driver’s response strategy and syncs the page and last page back into the store, so navigation helpers stop throwing (#16)createQubee({ driver })— wires the three together sharing one store, at a measured cost of 108 bytes over hand-wiring. Takes a driver definition rather than an id, so it never pulls the registry into a consumer’s bundle (#18)QubeeErrorbase carrying a machine-readablecode, diagnosticcontextand ES2022cause, withObject.setPrototypeOfhardening soinstanceofsurvives downlevelling (#8)- Derived union types —
Driver,FilterOperator,PaginationMode,SortDirection— alongside the enums, so{ driver: 'strapi' }and{ driver: DriverEnum.STRAPI }both typecheck (#2) RawResponse, modelling the bare-array body PostgREST and the WordPress REST API return, which the previous types could not express (#7)PaginatedCollection.normalize()accepts a selector function as well as a key name (#7)idonDriverDefinition, so a driver passed on its own can still name itself in errors (#18)- Public API as named re-exports from
src/index.ts— including the threeAbstract*bases,StrategyCapabilitiesand the registry, so third parties can author a driver (#11) - One file per driver under
src/drivers/, which is what makes a single-driver import tree-shakeable (#15) - A documentation site: 145 pages, with the API reference, all 18 driver pages and the capability matrix generated from source (#17)
Carried over from ng-qubee, where these are still present:
ResponseOptionsmerged with||, so a subclass passing''to mean “this driver derives the field” had its intent replaced by the Laravel default. Affected 11 of 14 drivers (#9)- All eight
Unsupported*Errormessages named specific drivers, and every one had become factually wrong — “Filters are only supported by the Spatie and NestJS drivers” when 16 of 18 support them. Messages are now derived from the capability and the active driver (#8) KeyNotFoundErrorandUnselectableModelErrornever setthis.name, soerr.namewas'Error'(#8)- Response strategies widened
paginate()toRecord<string, any>while the interface declaredRecord<string, unknown>; TypeScript’s bivariance hid the mismatch (#7) - Dot-path resolution could not read OData envelope keys, which contain literal dots
(
@odata.count). An exact key match is now preferred before splitting (#7) - The two response bases disagreed about a missing page: one defaulted to 1, the other yielded
undefinedfor a field declarednumber, which then threw from the store (#18) hasOwnPropertycalled directly on instances, and${array}relying on implicitArray.toString()coercion (#13)
Changed
Section titled “Changed”qsis gone. It was used only forstringify(payload, { encode: false }); a 40-line internal serialiser replaces it, verified againstqscase by case. A single-driver import fell from 15.7 kB to 2.5 kB gzipped (#10)- Data shapes are un-prefixed
types in*.type.ts.Iand*.interface.tsare reserved for the two interfaces a class actually implements (#2) header-bag.interface.tssplit into a type and a util — it exported a runtime function from a.interface.tsfile, which type-only elision could have dropped (#3)- Snapshots handed out by
QubeeStoreare deeply frozen. Identity stays stable between writes, asuseSyncExternalStorerequires, and tampering throws instead of silently corrupting a later read (#5)
Internal
Section titled “Internal”- 1,270 tests ported and added; 98.6% statement coverage, enforced in CI (#4)
test/conventions.spec.tsenforces the structural standards — one declaration kind per file, filename suffixes, theIprefix, constant casing — so a slip fails the build (#14)- CI verifies both entry points resolve, that there are no runtime dependencies, and that a single-driver import still tree-shakes (#12)
