Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/embed-objectql/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import { ObjectQL } from '@objectstack/objectql/core';

`@objectstack/objectql/core` exposes the engine, registry, hooks, and validation
only. It does **not** pull in `ObjectQLPlugin`, the kernel factory, or
`@objectstack/metadata-protocol` (the 268KB metadata-management layer), so none
`@objectstack/metadata-protocol` (the metadata-management layer), so none
of that lands in your bundle. (The batteries-included `@objectstack/objectql`
entry still re-exports everything for full hosts.)

Expand Down
2 changes: 1 addition & 1 deletion examples/embed-objectql/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@
//
// This imports from `@objectstack/objectql/core` — the LEAN entry. It pulls the
// data engine (query/CRUD/hooks/validation) only: NO kernel, NO ObjectQLPlugin,
// and NOT `@objectstack/metadata-protocol` (the 268KB metadata-management layer).
// and NOT `@objectstack/metadata-protocol` (the metadata-management layer).
// Ideal for a thin, latency-sensitive host (e.g. a gateway) that wants the
// engine and the *same* object definitions as the full platform, without the
// platform itself.
Expand Down
65 changes: 64 additions & 1 deletion packages/objectql/src/core-boundary.ratchet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,47 @@
// (src/core.ts) and its entire local import closure must NOT depend on the kernel
// plugin, the kernel factory, or the metadata-management protocol — so a thin
// embedder importing `@objectstack/objectql/core` never pulls
// `@objectstack/metadata-protocol` (or its 268KB) into its graph.
// `@objectstack/metadata-protocol` into its graph.
//
// ---------------------------------------------------------------------------
// Why no byte figure is quoted for what is excluded (#9803)
//
// The entry comment used to sell this boundary with a hard number. That number
// was real once, but it never measured the thing the sentence claimed. Full
// provenance, each line re-derivable with `git cat-file -s <rev>:<path>`
// (measured 2026-08-19; the extraction predates the default shallow clone, so
// `git fetch --deepen=1200` first):
//
// 268,886 B packages/objectql/src/protocol.ts @ d9fe95fcf
// the pre-extraction SOURCE FILE — what ADR-0076's premise
// paragraph counted. 268,886 B = 268.9 decimal KB, hence "268KB".
// 268,921 B packages/metadata-protocol/src/protocol.ts @ 13dbcf2d0
// the same file as it landed in the new package, 2026-06-28,
// "extract metadata-protocol + add lean ./core entry (ADR-0076
// Step 1)" (#2415).
// 1,054,749 B packages/metadata-protocol/src/protocol.ts @ HEAD
// 3.9x the quoted figure — and that is ONE file of a package
// whose src tree totals ~3.6 MB (`find … -type f | xargs wc -c`).
//
// So the figure was raw source bytes of a single file, and was then re-pointed
// at a whole package ("the 268KB metadata-management layer") — a unit it never
// had. Re-measuring cannot repair that, because there is no one number to
// re-measure. "The size of @objectstack/metadata-protocol" on 2026-08-19, after
// `pnpm --filter @objectstack/metadata-protocol build`, via `wc -c` and
// `gzip -9 -c | wc -c`:
//
// 169,718 B dist/index.js, gzipped (LESS than the quoted figure)
// 591,087 B dist/index.js, raw
// 1,054,749 B src/protocol.ts (the quoted figure's own unit)
// 1,513,973 B src/**/*.ts, excluding tests
// 3,637,237 B src/**/*.ts
//
// A 21x spread that straddles "268KB" in BOTH directions, before an embedder's
// own bundler and tree-shaking are even considered. The defect is therefore not
// staleness — it is that the figure never had a stated unit, and no refresh can
// supply one. The claim worth making is EXCLUSION, and the test below is what
// pins it. The second test keeps a figure from growing back into core.ts.
// ---------------------------------------------------------------------------
//
// If this test fails, you added a forbidden import somewhere reachable from
// core.ts. Keep metadata/plugin/kernel concerns out of the core closure.
Expand DownExpand Up@@ -70,4 +110,27 @@ describe('ADR-0076 D2 — @objectstack/objectql/core boundary', () => {
// sanity: the engine itself IS in the closure
expect([...visited].some((f) => f.endsWith('/engine.ts'))).toBe(true);
});

// #9803. The exclusion claim is pinned by the test above. A byte figure for
// the excluded weight is pinned by nothing, so core.ts must not state one —
// that is how "268KB" sat there unverified from 2026-06-28 until #9803.
// Scope is deliberately this package's entry only: the historical figures in
// this file's own header are provenance (dated, commit-pinned), not a claim,
// and are meant to stay.
it('core.ts quotes no unverifiable byte figure for the excluded weight', () => {
const src = readFileSync(resolve(SRC, 'core.ts'), 'utf8');
const offenders = src
.split('\n')
.filter((line) => /^\s*(?:\/\/|\/\*|\*)/.test(line))
.filter((line) => /metadata[- ](?:protocol|management)/i.test(line))
.filter((line) => /\b\d[\d.,]*\s*(?:[KMG]i?B|kB)\b/.test(line))
.map((line) => line.trim());

expect(
offenders,
`core.ts states a byte figure for the excluded metadata protocol:\n${offenders.join(
'\n',
)}\nNothing re-measures such a number. State the exclusion, not a size — see this file's header.`,
).toEqual([]);
});
});
7 changes: 4 additions & 3 deletions packages/objectql/src/core.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,12 +4,13 @@
// registry, hooks, validation, in-memory aggregation, utilities — WITHOUT the
// kernel plugin (`ObjectQLPlugin`), the kernel factory, or any metadata
// management (`@objectstack/metadata-protocol`). Embedders that want only the
// engine (e.g. a thin gateway) import from `@objectstack/objectql/core` so the
// 268KB metadataprotocol is never pulled into their dependency graph.
// engine (e.g. a thin gateway) import from `@objectstack/objectql/core` so
// `@objectstack/metadata-protocol` is never pulled into their dependency graph.
//
// A boundary ratchet (ADR-0076 D2) keeps this entry free of protocol/plugin
// imports; do not add `./plugin`, `./kernel-factory`, or `@objectstack/metadata-protocol`
// re-exports here.
// re-exports here. That ratchet — not a byte figure — is what backs the sentence
// above; see core-boundary.ratchet.test.ts for why no size is quoted (#9803).

// Registry
export {
Expand Down
Loading