/** * `@ng-eventually/polyfill` — the one door. Everything an application imports, it imports * from here. * * ── What the single entry costs, and how that cost is paid ──────────────── * There were two entries until 2026-08-07 (`.` and `./polyfill`), and the second one * carried a signal worth naming before removing it: *what you import from that path is * exactly what you will delete at migration*. One door loses that — nothing at an * import line now distinguishes `configure`, which goes away, from `docs`, which the * real SDK replaces in place. Three things carry it instead: * * 1. **The `POLYFILL-ERA` block below**, which is the deletion list. It is short by * construction, and it is meant to keep shrinking. * 2. **`docs/api-contract.md`**, which rules on every symbol with an epistemic label * (PASSTHROUGH / LEVEL-1 SHAPE / ASSUMPTION / NO COUNTERPART) and whose export * inventory is pinned by `test/vocabulary.test.ts` — so it cannot go stale * quietly, which a hand-kept list would. * 3. **The names themselves.** Every published name is built from the target's own * vocabulary or carries a marker saying why it exists only here — pinned by the * same test. A name that has to disappear says so. * * ── What is deliberately NOT published ──────────────────────────────────── * The entry publishes what an application CALLS, and nothing else. Not the machinery * accessors (`getConfig`, `getStoreRegistryDeps` — internal wiring the surface reaches * through `shared-wallet/bootstrap`), and not the test resets (`resetConfig`, * `resetStoreRegistry`, `resetCaps` — the suite reaches them by their internal path, * which is what they are for). Merging the entries made publishing those a visible * choice rather than an inherited one; the choice is no. * * Earlier removals, each because an application coding against it learns something it * must unlearn — the one failure this library exists to prevent: * * - `getCaps` / `CapRegistry` (2026-08-05) — the emulation's engine room. It has * neither a successor nor an inert form, so anything built on it must be rewritten. * - `getCurrentUser` (2026-08-05) — an application knows who it signed in; asking the * library back is a convenience of the shared wallet, not a brick of the model. * - `virtualUsers` / `IdentityStore` (2026-08-05) — remembering an identity between * sessions is the application's job upstream too. The gate persists what IT needs. * - `hasCap(doc)` (2026-08-06) — it read like "may I read this?", and once a public * store serves its caps to whoever asks (`emulated-verifier/public-store.ts`) the * two answers part company: a readable document answers `false` right up until * something asks. Upstream you open a document and find out. */ // ── SDK-SHAPED — a target counterpart for every symbol ────────────────────── // At migration the build alias is removed and these resolve to the real SDK. // // WHAT each symbol is aligned on is recorded BESIDE IT, not in a document that drifts: // // // @provenance kind= level=<1|2|3|none> ref= [announced-by=@] — // // `level` numbers the target's stack from the bottom (1 engine, 2 wasm binding / // `@ng-org/web`, 3 JS ORM); `ref` cites a SYMBOL, never a line number — in `nextgraph-rs` // for every kind that cites the target, and in THIS working copy for the one kind that // has no upstream file to cite. `kind` is closed: `passthrough` (upstream's own symbol, // name and shape), `aligned` (our name or ergonomics, upstream's semantics), // `declared-not-wired` (upstream DEFINES the shape and constructs it nowhere — an // absence, which is NOT evidence the thing is ours), `announced-not-written` (upstream's // developers have STATED this direction and nothing in the tree carries it yet), // `reserved-name` (upstream has declared a NAME with no shape behind it), // `invention` (nothing answers, a documented bet), `divergent` (upstream does this, we do // it differently). Pinned by `test/provenance.test.ts`; the reasoning behind each ruling // stays in `docs/api-contract.md`, and where the two disagree the annotation wins. // // A `ref` names a path and a symbol, never a VERSION - the version is a property of the // checkout every citation resolves against, so it is recorded once, in the `ANCHOR` of // `test/provenance.test.ts`, and checked at both ends there. Read it before letting a // citation settle anything about a release: the tree is BEHIND the packages this repo // builds against, so a claim about a shipped version cannot be refuted by opening it. // // `announced-not-written` is the STRONGEST kind available to a symbol with no counterpart // in the tree - deviating TOWARD what the target has announced is alignment, and calling // it `invention` tells a later reader the shape is ours to change when it is not. Being // the strongest, it is the hardest to assert: it carries `announced-by=@` and // its `ref` is the `.md` in this working copy where the statement is on record. An // announcement nobody wrote down is hearsay, so the test refuses it. // A type is published only when a PUBLISHED SIGNATURE uses it. `export *` published // eight in one gesture (2026-08-10: it was a blanket re-export), of which two named // nothing a consumer can reach — `ReadCap` (used only by two private helpers of // `surface/inbox.ts`) and `InboxScope` (used only by the unpublished // `account-registry.userInbox`). A published type with no published signature is a // promise about the target that nothing here keeps: it invites a consumer to hold a // value it has no call to obtain — and for `ReadCap`, the one value the model says a // caller must never be handed on request. They stay DEFINED in `model/types.ts`, where // the library uses them; they stop being surface. `docs/api-contract.md` § 10, § 14. // Each one, and the signature that earns it its place: // Nuri every reference the surface RETURNS // NuriLike every reference the surface ACCEPTS // PrincipalId `ensureIdentity`, `inbox.Deposit`/`PostOptions`, `EventuallyConfig` // NgLike `EventuallyConfig.ng` // UseShapeLike `EventuallyConfig.useShape` // OrmSubscriptionLike `EventuallyConfig.ormSubscription` // GetObjectsLike `EventuallyConfig.getObjects` // InsertObjectLike `EventuallyConfig.insertObject` // RdfOrmConfig `getObjects` // // `OrmSubscriptionHandle` - what that last one RETURNS - is deliberately NOT here. An // application hands the shape query in and reads the snapshot back; it never holds a // subscription, and publishing the handle would offer a path around the capability filter // and the shared-wallet identity boundary. It stays defined in `model/types.ts`. // // `Scope` left this list in `1.0.0-dev.5`, and it is the only one that left because the // TYPE was wrong rather than unreachable. It was `"public" | "protected" | "private"` - // our own three strings under a name the SDK also uses, for a different thing: upstream // a `Scope` is `{ graphs, subjects }` and scopes a READ, while those three strings are // `doc_create`'s `store_type` and place a WRITE. One name over two questions. The read // takes the SDK's `Scope` now (re-exported below, from the SDK itself), and a store is // named by its reference. The three strings stay DEFINED in `model/types.ts` as // `StoreType`, where the library's own modules still tell the three apart. export type { Nuri, NuriLike, PrincipalId, NgLike, UseShapeLike, OrmSubscriptionLike, GetObjectsLike, InsertObjectLike, } from "./model/types"; export { useShape } from "./surface/use-shape"; export { useShapeQuery } from "./surface/use-shape-query"; export type { ShapeQuery, ShapeObservable } from "./surface/use-shape-query"; // The ORM's one-shot read and its subscription-free write - WRAPPED, at upstream's own // names and signatures, never re-exported. `surface/orm.ts` says what each wrapper adds, // and which neighbours of theirs in `@ng-org/orm`'s entry are deliberately not here // (`RdfOrmSubscription`, `DiscreteOrmSubscription`, `ngSession`, `getRaw`). export { getObjects, insertObject } from "./surface/orm"; export { init, initNg } from "./surface/lifecycle"; export * as inbox from "./surface/inbox"; export * as docs from "./surface/docs"; export { subscribeDoc, subscribeDocs, docChangeType } from "./surface/subscribe"; export type { DocChange, DocChangeType, Unsubscribe } from "./surface/subscribe"; // `readUnion` and `UnionSubject` were published here until `1.0.0-dev.8`. They are gone, // and nothing replaces them: a `document read` over several documents was N anchored // queries plus a batch policy, which no level of the target answers - so its provenance // cited `sparql_query`, a citation that is exact attached to a claim that is false. A // composition cannot be aligned on a single function. Reading one document by name is // `docs.sparqlQuery(sessionId, query, undefined, doc)`, which IS upstream's own primitive // and is published beside this line; reading several is that call, once per document. export * as storeRegistry from "./surface/placement"; // SDK type re-exports — so the app imports these from @ng-eventually/polyfill too, not from // @ng-org. `export type` is ERASED at build, so this adds NO runtime @ng-org import to // the lib (no risk of a duplicate SDK copy in the bundle). // @provenance ShapeType kind=passthrough level=3 ref=sdk/js/shex-orm/src/types.ts:ShapeType // @provenance BaseType kind=passthrough level=3 ref=sdk/js/shex-orm/src/types.ts:BaseType - the cited revision keeps `"@graph"` commented out behind a TODO; the published `@ng-org/shex-orm@0.1.2-alpha.9` declares it, and it is the published one that is re-exported here // @provenance Schema kind=passthrough level=3 ref=sdk/js/shex-orm/src/types.ts:Schema export type { ShapeType, BaseType, Schema } from "@ng-org/shex-orm"; // @provenance DeepSignalSet kind=passthrough level=3 ref=sdk/js/alien-deepsignals/src/types.ts:DeepSignalSet export type { DeepSignalSet } from "@ng-org/alien-deepsignals"; // The scope `useShapeQuery` takes, re-exported from the SDK rather than restated here: // restating it is how a type drifts, and the two axes it filters on (`graphs`, // `subjects`) are upstream's to change. // @provenance Scope kind=passthrough level=3 ref=sdk/js/orm/src/types.ts:Scope - the cited revision declares `graphs?` OPTIONAL; the published `@ng-org/orm@0.1.2-alpha.21` makes it required, and it is the published one that is re-exported here export type { Scope } from "@ng-org/orm"; // What `getObjects` takes: a `Scope` plus `where` and `orderBy`. It is re-exported from // the SDK's `/all` subpath because that is where the SDK puts it - the type the function // DECLARES is not exported beside the function, which is upstream's packaging and not a // choice here. Restating it would be how it drifts. // @provenance RdfOrmConfig kind=passthrough level=3 ref=sdk/js/orm/src/utilTypes.ts:OrmConfig - the published `@ng-org/orm@0.1.2-alpha.21` renames it `RdfOrmConfig` and re-parameterises it on the shape's type rather than its `ShapeType`, which the cited revision has not yet done export type { RdfOrmConfig } from "@ng-org/orm/all"; // @provenance NG kind=passthrough level=2 ref=sdk/js/web/src/index.ts:NG — every member forwarded; the proxy adds none and removes none. The count lives once, with the release it belongs to, in `surface/ng-proxy.ts` export type { NG } from "@ng-org/web"; // ── POLYFILL-ERA — THE DELETION LIST ──────────────────────────────────────── // Everything below exists because one shared wallet hosts every user, and nothing // below has a target counterpart. At migration each call goes, and the imports with // them. Keep this block short: an addition here is a promise to delete it later. /** * Inject the real SDK, and tell the library about the shared wallet. Upstream nothing * is injected — an application imports the SDK and opens its own wallet — so this call * is the shape of that absence. `docs/api-contract.md` § 1. * * **It is the ONLY call here**, and keeping it that way is the design target: an * application's bootstrap should be one line to delete, not four. */ export { configure } from "./shared-wallet/bootstrap"; export type { EventuallyConfig } from "./shared-wallet/bootstrap"; // `RegistrySession` went with `getSession` (2026-08-12): it was published for exactly one // reason — an application typed the session thunk it injected with it — and a published // type whose signature is gone is a promise about the target that nothing keeps. Upstream a // session is RETURNED, never assembled, so no consumer has a session shape to declare. It // stays DEFINED in `shared-wallet/account-registry.ts`, where the library uses it. // --- what this block deliberately does NOT contain -------------------------- // // Three calls were published here and removed on 2026-08-07, when the count had drifted // to four against a target of two. Each removal is a thing an application no longer does: // // - `configureStoreRegistry` — folded into `configure`. Two bootstrap calls existed // because the library has two internals, which is not a reason a caller should pay. // - `setCurrentUser` — the access gate sets the identity (`ensureIdentity`, below). // An application naming its own identity is the gesture that inverts the model, and // it must not have a published call to reach for. The e2e harness plays several // identities on one page and reaches it by its internal path, which is what a // harness is allowed to do and an application is not. // - `connectedUser` — `ensureIdentity` awaits it. Upstream, opening the session IS the // connection; no application awaits a second call, so ours should not either. // // And two FIELDS of `EventuallyConfig` on 2026-08-12, for the same reason one call up: // // - `getSession` — the session is `init()`'s to deliver, and this package's to keep. An // application that assembles one out of `session_id` / `private_store_id` / … is // building a shape the target never asks for, and every consumer built the same one. // - `normalizeId` — the identities being normalized are this package's own invention, so // there was never a decision here for a consumer to make. // // Both are still substitutable through `shared-wallet/bootstrap`'s `configureStoreRegistry` // — the suites and the e2e harness need it, and nothing published reaches it. // ── the access gate — polyfill-era in substance, one line in the app ──────── // One call before the app renders. It shows a technical barrier only while the shared // wallet needs one; the day the wallet supplies the identity it resolves silently, and // this line stays as it is (`shared-wallet/access-gate.ts`). export { ensureIdentity } from "./shared-wallet/access-gate"; export type { SharedWalletConfig } from "./shared-wallet/access-gate"; import type { NG } from "@ng-org/web"; import { wrappedNg } from "./surface/ng-proxy"; /** * SDK-identical `ng` (wrapped). Drop-in replacement for `@ng-org/web`'s `ng`. * * Declared `NG` — upstream's own type for its `ng` (`index.d.ts:NG`). It was published as * `Record` until 2026-08-14, which announced a different surface from the one * it forwards to: an application got no completion and no check on any of its members. */ // @provenance ng kind=passthrough level=2 ref=sdk/js/web/src/index.ts:ng — a Proxy over the injected real `ng`; only `sparql_update` is overridden (the emulated write guard) export const ng: NG = wrappedNg();