refactor: le paquet s'appelle polyfill, « SDK » désigne celui de NextGraph
Le nom @ng-eventually/sdk entrait en collision avec le SDK de NextGraph, dont ce paquet est justement un polyfill. Impossible d'écrire « le SDK » sans lever l'ambiguïté à chaque phrase — et le contrat publié, lu par une application, était le pire endroit pour laisser traîner ça. packages/sdk → packages/polyfill, @ng-eventually/sdk → @ng-eventually/polyfill, contract_sdk-surface → contract_polyfill-surface, e2e/sdk-entry.ts → e2e/polyfill-entry.ts, docs/sdk-reference.md → docs/polyfill-reference.md. Les occurrences de « SDK » qui désignent celui de NextGraph restent intactes, y compris les chemins dans nextgraph-rs (sdk/js/orm, sdk/js/web). Le tri s'est fait occurrence par occurrence, pas par substitution. Le contrat énonce désormais son identité en une phrase : « This package is a polyfill of NextGraph's SDK. »
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* `@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. The
|
||||
// per-symbol ruling, with its epistemic label, is in `docs/api-contract.md`.
|
||||
|
||||
// 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
|
||||
// Scope `storeRegistry.*`, `watchShape`
|
||||
// PrincipalId `ensureIdentity`, `inbox.Deposit`/`PostOptions`, `EventuallyConfig`
|
||||
// NgLike `EventuallyConfig.ng`
|
||||
// UseShapeLike `EventuallyConfig.useShape`
|
||||
export type { Nuri, NuriLike, Scope, PrincipalId, NgLike, UseShapeLike } from "./model/types";
|
||||
export { useShape } from "./surface/use-shape";
|
||||
export { watchShape } from "./surface/watch-shape";
|
||||
export type { ShapeQuery, ShapeObservable } from "./surface/watch-shape";
|
||||
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` is exposed as a function, not under a `readModel` namespace: "model" is
|
||||
// neither the target's vocabulary nor neutral glue, and the namespace bought nothing —
|
||||
// it held one published function. Renamed 2026-08-03 by the vocabulary check.
|
||||
export { readUnion } from "./surface/read-model";
|
||||
export type { UnionSubject } from "./surface/read-model";
|
||||
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).
|
||||
export type { ShapeType, BaseType, Schema } from "@ng-org/shex-orm";
|
||||
export type { DeepSignalSet } from "@ng-org/alien-deepsignals";
|
||||
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";
|
||||
export type { RegistrySession } from "./shared-wallet/account-registry";
|
||||
|
||||
// --- 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.
|
||||
|
||||
// ── 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 { makeNg } from "./surface/ng-proxy";
|
||||
|
||||
/** SDK-identical `ng` (wrapped). Drop-in replacement for `@ng-org/web`'s `ng`. */
|
||||
export const ng: Record<string, any> = makeNg();
|
||||
Reference in New Issue
Block a user