graphddb 0.7.10 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +6 -6
  2. package/dist/cdc/index.d.ts +389 -5
  3. package/dist/cdc/index.js +4 -4
  4. package/dist/{chunk-AD6ZQTTE.js → chunk-GS4C5VGO.js} +2 -6
  5. package/dist/{chunk-DFUKGU2Q.js → chunk-HNY2EJPV.js} +216 -229
  6. package/dist/{chunk-EOJDN3SA.js → chunk-I4LEJ4TF.js} +3744 -6144
  7. package/dist/{chunk-3ZU2VW3L.js → chunk-L2NEDS7U.js} +582 -781
  8. package/dist/chunk-L4QRCHRQ.js +278 -0
  9. package/dist/chunk-LGHSZIEE.js +187 -0
  10. package/dist/chunk-N4NWYNGZ.js +1987 -0
  11. package/dist/{chunk-PDUVTYC5.js → chunk-XTWXMOHD.js} +0 -1
  12. package/dist/cli.js +63 -254
  13. package/dist/index.d.ts +23 -1550
  14. package/dist/index.js +94 -1850
  15. package/dist/internal/index.d.ts +84 -0
  16. package/dist/internal/index.js +701 -0
  17. package/dist/{maintenance-view-adapter-BAZ9uBGe.d.ts → key-DR7_lpyk.d.ts} +504 -1910
  18. package/dist/linter/index.d.ts +39 -7
  19. package/dist/linter/index.js +22 -4
  20. package/dist/{registry-LWE54Sdc.d.ts → linter-C-vypgut.d.ts} +22 -22
  21. package/dist/prepared-artifact-BpPgkXEo.d.ts +281 -0
  22. package/dist/spec/index.d.ts +506 -5
  23. package/dist/spec/index.js +22 -18
  24. package/dist/testing/index.d.ts +2 -3
  25. package/dist/testing/index.js +4 -4
  26. package/dist/transform/index.d.ts +1 -1
  27. package/dist/transform/index.js +4 -4
  28. package/dist/{types-BQLzTEqh.d.ts → types-2PMXEn5x.d.ts} +8 -10
  29. package/dist/types-BXLzIcQD.d.ts +450 -0
  30. package/docs/cdc-projection.md +5 -5
  31. package/docs/class-hydration.md +1 -1
  32. package/docs/cqrs-contract.md +28 -20
  33. package/docs/design-patterns.md +5 -5
  34. package/docs/docs-generation.md +6 -6
  35. package/docs/middleware.md +15 -15
  36. package/docs/mutation-command-derivation.md +52 -42
  37. package/docs/prepared-statements.md +14 -14
  38. package/docs/python-bridge.md +96 -65
  39. package/docs/spec.md +153 -124
  40. package/docs/testing.md +9 -8
  41. package/package.json +14 -4
  42. package/dist/chunk-3UD3XIF2.js +0 -860
  43. package/dist/chunk-MMVHOUM4.js +0 -24
  44. package/dist/from-change-Ty95KA8C.d.ts +0 -327
  45. package/dist/index-Dc7d8mWI.d.ts +0 -1089
  46. package/dist/relation-depth-BRS513Tq.d.ts +0 -36
@@ -1,9 +1,41 @@
1
- import { L as LintRule } from '../registry-LWE54Sdc.js';
2
- export { a as LintResult, b as Linter } from '../registry-LWE54Sdc.js';
3
- export { c as createDefaultLinter, g as gsiAmbiguityRule, m as missingGsiRule, n as noScanRule, q as queryBoundaryRule, r as relationDepthRule, a as requireLimitRule } from '../relation-depth-BRS513Tq.js';
4
- import '../maintenance-view-adapter-BAZ9uBGe.js';
5
- import '@aws-sdk/client-dynamodb';
6
- import '../types-BQLzTEqh.js';
1
+ import { L as Linter, a as LintRule } from '../linter-C-vypgut.js';
2
+ export { b as LintResult } from '../linter-C-vypgut.js';
3
+ import '../types-BXLzIcQD.js';
4
+ import '../key-DR7_lpyk.js';
5
+ import '../types-2PMXEn5x.js';
6
+
7
+ /**
8
+ * Creates a Linter pre-loaded with rules safe for Entity registration.
9
+ *
10
+ * Rules included: no-scan, require-limit, gsi-ambiguity, missing-gsi,
11
+ * relation-depth, same-partition-preset, plus the Epic #118 Phase 1 maintenance
12
+ * validators (issue #126): missing-context, 400kb, hot-partition, fan-out,
13
+ * multi-maintainer-same-row. The maintenance validators are no-ops for any
14
+ * relation that does not declare `write.maintainedOn`, so unannotated models are
15
+ * unaffected. query-boundary is excluded because it flags non-unique GSIs which
16
+ * are valid for list() operations; boundary enforcement is handled at runtime by
17
+ * the planner's boundary-check.
18
+ *
19
+ * Also includes cfn-schema-consistency (issue #169): a whole-table validator
20
+ * that rejects entities sharing a physical table with an ambiguous base
21
+ * KeySchema, inconsistently-shared GSI index names, or more than 20 unioned
22
+ * GSIs — the CFn deploy-consistency user-error class, caught statically at
23
+ * finalize. It is additive: a single entity on its own table with ≤ 20 GSIs is
24
+ * never affected.
25
+ */
26
+ declare function createDefaultLinter(): Linter;
27
+
28
+ declare const noScanRule: LintRule;
29
+
30
+ declare const requireLimitRule: LintRule;
31
+
32
+ declare const queryBoundaryRule: LintRule;
33
+
34
+ declare const gsiAmbiguityRule: LintRule;
35
+
36
+ declare const missingGsiRule: LintRule;
37
+
38
+ declare const relationDepthRule: LintRule;
7
39
 
8
40
  /**
9
41
  * `samePartition` preset validator (Epic #118 child issue H).
@@ -124,4 +156,4 @@ declare const multiMaintainerSameRowRule: LintRule;
124
156
 
125
157
  declare const cfnSchemaConsistencyRule: LintRule;
126
158
 
127
- export { LintRule, cfnSchemaConsistencyRule, embeddedSnapshotSizeRule, fanOutRule, hotPartitionRule, missingContextRule, multiMaintainerSameRowRule, samePartitionPresetRule };
159
+ export { LintRule, Linter, cfnSchemaConsistencyRule, createDefaultLinter, embeddedSnapshotSizeRule, fanOutRule, gsiAmbiguityRule, hotPartitionRule, missingContextRule, missingGsiRule, multiMaintainerSameRowRule, noScanRule, queryBoundaryRule, relationDepthRule, requireLimitRule, samePartitionPresetRule };
@@ -1,6 +1,3 @@
1
- import {
2
- queryBoundaryRule
3
- } from "../chunk-MMVHOUM4.js";
4
1
  import {
5
2
  Linter,
6
3
  cfnSchemaConsistencyRule,
@@ -16,7 +13,28 @@ import {
16
13
  relationDepthRule,
17
14
  requireLimitRule,
18
15
  samePartitionPresetRule
19
- } from "../chunk-PDUVTYC5.js";
16
+ } from "../chunk-XTWXMOHD.js";
17
+
18
+ // src/linter/rules/query-boundary.ts
19
+ var queryBoundaryRule = {
20
+ id: "query-boundary",
21
+ severity: "error",
22
+ check(metadata) {
23
+ const results = [];
24
+ for (const gsi of metadata.gsiDefinitions) {
25
+ if (!gsi.unique) {
26
+ results.push({
27
+ ruleId: "query-boundary",
28
+ severity: "error",
29
+ message: `GSI '${gsi.indexName}' on entity '${metadata.prefix}' is not marked as unique. Using query() on a non-unique GSI may return multiple items. Use list() instead, or mark the GSI as unique if it guarantees single results.`,
30
+ entity: metadata.prefix,
31
+ field: gsi.indexName
32
+ });
33
+ }
34
+ }
35
+ return results;
36
+ }
37
+ };
20
38
  export {
21
39
  Linter,
22
40
  cfnSchemaConsistencyRule,
@@ -1,24 +1,4 @@
1
- import { m as EntityMetadata } from './maintenance-view-adapter-BAZ9uBGe.js';
2
-
3
- interface LintRule {
4
- id: string;
5
- severity: 'error' | 'warning';
6
- check(metadata: EntityMetadata, registry: typeof MetadataRegistry): LintResult[];
7
- }
8
- interface LintResult {
9
- ruleId: string;
10
- severity: 'error' | 'warning';
11
- message: string;
12
- entity: string;
13
- field?: string;
14
- }
15
-
16
- declare class Linter {
17
- private rules;
18
- addRule(rule: LintRule): void;
19
- run(metadata: EntityMetadata, registry: typeof MetadataRegistry): LintResult[];
20
- runAll(registry: typeof MetadataRegistry): LintResult[];
21
- }
1
+ import { E as EntityMetadata } from './types-BXLzIcQD.js';
22
2
 
23
3
  declare class MetadataRegistry {
24
4
  private static store;
@@ -73,4 +53,24 @@ declare class MetadataRegistry {
73
53
  private static handleLintResults;
74
54
  }
75
55
 
76
- export { type LintRule as L, MetadataRegistry as M, type LintResult as a, Linter as b };
56
+ interface LintRule {
57
+ id: string;
58
+ severity: 'error' | 'warning';
59
+ check(metadata: EntityMetadata, registry: typeof MetadataRegistry): LintResult[];
60
+ }
61
+ interface LintResult {
62
+ ruleId: string;
63
+ severity: 'error' | 'warning';
64
+ message: string;
65
+ entity: string;
66
+ field?: string;
67
+ }
68
+
69
+ declare class Linter {
70
+ private rules;
71
+ addRule(rule: LintRule): void;
72
+ run(metadata: EntityMetadata, registry: typeof MetadataRegistry): LintResult[];
73
+ runAll(registry: typeof MetadataRegistry): LintResult[];
74
+ }
75
+
76
+ export { Linter as L, MetadataRegistry as M, type LintRule as a, type LintResult as b };
@@ -0,0 +1,281 @@
1
+ import { E as EntityMetadata } from './types-BXLzIcQD.js';
2
+ import { C as ContractSpec, Q as QuerySpec, a as CommandSpec, T as TransactionSpec, b as ContextSpec, S as SPEC_VERSION, P as ParamSpec } from './types-2PMXEn5x.js';
3
+ import { Q as QueryModelContract, k as QueryMethodSpec, l as CommandModelContract, m as CommandMethodSpec } from './key-DR7_lpyk.js';
4
+
5
+ /**
6
+ * Contract-layer serialization (issue #59, CQRS Contract layer, Epic #57;
7
+ * spec `docs/cqrs-contract.md`, "SSoT Schema").
8
+ *
9
+ * The Contract IR (#58, `src/define/contract.ts`) holds, per contract method, a
10
+ * resolved declarative {@link ContractMethodOp} plus the **decided facts** the
11
+ * planner derived (`resolution` / `inputArity` / `result`). This module
12
+ * **serializes** those facts into the JSON SSoT — it does **not** re-derive them:
13
+ *
14
+ * - The `contracts` map (contract name → {@link ContractSpec}) is layered **on
15
+ * top of** the existing `queries` / `commands` / `transactions`. Each method
16
+ * references one of them by name (`ContractName__methodName`), so the existing
17
+ * operation-spec shapes are unchanged and the current runtime keeps working.
18
+ * - The referenced operation spec is produced by **reusing** the proven
19
+ * {@link buildQuerySpec} / {@link buildCommandSpec} planners: a
20
+ * {@link ContractMethodOp} is translated back into the {@link AnyOperationDefinition}
21
+ * shape those planners consume (the contract's sentinel references become the
22
+ * `Param` placeholders the planner already understands), so the symbolic key
23
+ * evaluation, projection, relation chaining, and condition handling are shared
24
+ * — never re-implemented, never drifting.
25
+ *
26
+ * Everything emitted is **JSON-serializable** by construction (only strings /
27
+ * numbers / booleans / arrays / plain objects). A contract-free input emits no
28
+ * `contracts` / `contexts` keys, so the pre-#59 operations document is reproduced
29
+ * byte-for-byte (backward compatibility).
30
+ *
31
+ * ## What this issue serializes vs. defers
32
+ *
33
+ * The #58 IR captures a single declarative op per method with a boolean `select`
34
+ * projection; it does **not** model External Query / Query Composition (no
35
+ * `query(Contract.method, { from(...) })` primitive exists yet). So no #58
36
+ * contract produces a `compose`. The serializer nonetheless **supports** it: when
37
+ * a method op carries composition (a forward-compatible {@link ContractMethodOp}
38
+ * extension), it is emitted per the proposal's `compose` shape. The N+1 checker
39
+ * (#60), boundary lint (#61), and runtime execution (#62) are out of scope here —
40
+ * this is serialization + generator only.
41
+ */
42
+
43
+ /**
44
+ * A contract as accepted by the serializer: either a resolved
45
+ * {@link QueryModelContract} or a {@link CommandModelContract} (the #58 factory
46
+ * output). The Key type is erased — the serializer reads the key **fields** off
47
+ * the resolved op / model metadata, not the phantom type.
48
+ */
49
+ type AnyModelContract = QueryModelContract<unknown, Record<string, QueryMethodSpec<unknown, unknown, unknown>>> | CommandModelContract<unknown, Record<string, CommandMethodSpec<unknown, unknown, unknown>>>;
50
+ /** A map of contract name → resolved contract IR (as passed to the generator). */
51
+ type ContractMap = Record<string, AnyModelContract>;
52
+ /**
53
+ * A context-ownership declaration as authored by the producer: context name →
54
+ * the Model (entity) and Contract names that belong to it. The serializer sorts
55
+ * the member lists deterministically; see {@link ContextSpec}.
56
+ */
57
+ interface ContextOwnership {
58
+ readonly models?: readonly string[];
59
+ readonly contracts?: readonly string[];
60
+ }
61
+ /** A map of context name → its membership (as passed to the generator). */
62
+ type ContextOwnershipMap = Record<string, ContextOwnership>;
63
+ /**
64
+ * The output of {@link buildContracts}: the `contracts` map and the
65
+ * **synthesized** operation specs each method references. The caller merges the
66
+ * synthesized `queries` / `commands` / `transactions` into the document's
67
+ * existing maps (a contract method's referenced op lives alongside hand-written
68
+ * definitions, addressed by name).
69
+ */
70
+ interface BuiltContracts {
71
+ readonly contracts: Record<string, ContractSpec>;
72
+ /** Synthesized read ops referenced by query contract methods. */
73
+ readonly queries: Record<string, QuerySpec>;
74
+ /** Synthesized write ops referenced by command contract methods (single form). */
75
+ readonly commands: Record<string, CommandSpec>;
76
+ /**
77
+ * Synthesized transactions referenced by command contract methods whose array
78
+ * form resolves to a `'transact'` batched write (issue #64). One transaction per
79
+ * such method, named `<Contract>__<method>__batch`: a single `forEach`-over-keys
80
+ * write item that the runtime expands once per key (≤25, atomic), reusing the
81
+ * proven declarative-transaction machinery (#46). Empty when no command method
82
+ * declares a `'transact'` batch.
83
+ */
84
+ readonly transactions: Record<string, TransactionSpec>;
85
+ }
86
+ /**
87
+ * The derived-effect family of one serialized prepared-write transaction item
88
+ * (issue #208). Index-aligned to `TransactionSpec.items`; the AOT loader groups
89
+ * rendered items by category ACROSS the plan's ops so the composed
90
+ * `TransactWriteItems` matches the in-process execution core's order
91
+ * (writes, then all edges, then all derived updates, …) byte-for-byte.
92
+ */
93
+ type PreparedWriteItemCategory = 'base' | 'edge' | 'derive' | 'unique' | 'outbox' | 'idempotency' | 'maintain' | 'maintainOutbox' | 'check';
94
+ /**
95
+ * Serialize a map of resolved contracts into the `contracts` SSoT map plus the
96
+ * synthesized operation specs each method references. Deterministic: contracts
97
+ * and methods are emitted in sorted-key order.
98
+ *
99
+ * @param contracts Contract name → resolved {@link QueryModelContract} /
100
+ * {@link CommandModelContract} (the #58 factory output). Empty → empty output.
101
+ * @throws if a contract method op cannot be serialized (a non-boolean projection
102
+ * slot, an unsupported write condition); or if a contract violates an N+1
103
+ * safety rule (#60, {@link assertContractN1Safe}) — an array into a `range`
104
+ * method, a "list under a list", or a `range` composed child.
105
+ */
106
+ declare function buildContracts(contracts?: ContractMap): BuiltContracts;
107
+ /**
108
+ * Serialize the context-ownership declarations into the SSoT `contexts` map.
109
+ * Member lists are sorted for determinism. An empty input yields an empty map
110
+ * (the caller then omits the key for backward compatibility).
111
+ */
112
+ declare function buildContexts(contexts?: ContextOwnershipMap): Record<string, ContextSpec>;
113
+
114
+ /**
115
+ * Static prepared-plan artifact — the SHARED, dependency-minimal half of the
116
+ * AOT pipeline (issue #208; layering fixed by #223).
117
+ *
118
+ * This module carries everything BOTH sides of the pipeline need:
119
+ *
120
+ * - the artifact shapes ({@link PreparedPlanDocument} and friends),
121
+ * - the format version ({@link PREPARED_FORMAT_VERSION}),
122
+ * - canonical JSON ({@link canonicalJson}) and the drift-detection
123
+ * fingerprints ({@link entityFingerprint} / {@link planFingerprint}).
124
+ *
125
+ * ## Layering (#223)
126
+ *
127
+ * The dependency direction is strictly one-way:
128
+ *
129
+ * ```
130
+ * emitter (src/spec/prepared.ts, build-time) ──▶ THIS MODULE
131
+ * loader (src/runtime/prepared-loader.ts) ──▶ THIS MODULE
132
+ * ```
133
+ *
134
+ * The loader must NEVER import the emitter: the emitter drags the whole
135
+ * build-time spec machinery into the runtime bundle (`dist/index.js`), which
136
+ * is exactly the leak the size-limit CI gate caught in #223. This module's
137
+ * only value-level dependencies are ones the loader already carries
138
+ * (`buildManifestEntity` / spec types).
139
+ *
140
+ * ## Fingerprints are checksums, not cryptography
141
+ *
142
+ * The fingerprint exists to detect DRIFT (model declarations changed since
143
+ * the artifact was generated). It is not a security boundary, so it uses a
144
+ * pure-TypeScript FNV-1a 64-bit hash — no `node:crypto`, no platform builtin,
145
+ * bundles everywhere. Switching the algorithm (sha-256 → FNV-1a) is what
146
+ * bumped {@link PREPARED_FORMAT_VERSION} '1' → '2': a format-'1' artifact's
147
+ * fingerprints can never match, so the loader rejects the version loudly
148
+ * instead of failing the comparison confusingly.
149
+ */
150
+
151
+ /**
152
+ * The prepared-plan artifact format version (independent of {@link SPEC_VERSION}).
153
+ *
154
+ * '2' (#223): fingerprints are FNV-1a 64-bit over canonical JSON (16 hex
155
+ * chars). '1' (#208, graphddb ≤ 0.7.2) used sha-256 via `node:crypto`; the
156
+ * loader rejects '1' artifacts with a regeneration instruction.
157
+ */
158
+ declare const PREPARED_FORMAT_VERSION: "2";
159
+ /**
160
+ * One serialized value bind: a `$`-param slot (bound from the caller's
161
+ * `execute(params)` by name) or a static literal recorded at build time. `Date`
162
+ * and `bigint` literals — which JSON cannot carry natively — are encoded
163
+ * explicitly and revived by the loader, so the bound value is the SAME typed
164
+ * value the runtime `prepare` would have captured.
165
+ */
166
+ type PreparedBindSpec = {
167
+ readonly param: string;
168
+ } | {
169
+ readonly literal: string | number | boolean | null;
170
+ } | {
171
+ readonly literalDate: string;
172
+ } | {
173
+ readonly literalBigInt: string;
174
+ };
175
+ /** A `{ field: bind }` map (a serialized slot map). */
176
+ type PreparedBindMap = Readonly<Record<string, PreparedBindSpec>>;
177
+ /** One serialized read route of a prepared READ plan. */
178
+ interface PreparedReadRouteSpec {
179
+ readonly alias: string;
180
+ readonly op: 'query' | 'list';
181
+ /** The target entity name (re-bound via the registry at load). */
182
+ readonly entity: string;
183
+ /** The static, params-independent select template (JSON-safe by the #206 lint). */
184
+ readonly select: Record<string, unknown>;
185
+ /** Key-field binds (`{ field: { param | literal } }`). */
186
+ readonly key: PreparedBindMap;
187
+ /** Static option literals decided at build time. */
188
+ readonly maxDepth?: number;
189
+ readonly order?: 'ASC' | 'DESC';
190
+ readonly filter?: Record<string, unknown>;
191
+ /** Dynamic option binds (a `$` param or a literal, decided per call). */
192
+ readonly consistentRead?: PreparedBindSpec;
193
+ readonly limit?: PreparedBindSpec;
194
+ readonly after?: PreparedBindSpec;
195
+ /**
196
+ * The spec-IR read plan (`operations.json` vocabulary: physical ops, templated
197
+ * `{<field>}` key conditions, relation fan-outs, execution plan) derived from
198
+ * this route at build time. Key-condition tokens are the entity's key FIELD
199
+ * names; the per-call param→field mapping is {@link key}. Deriving it at build
200
+ * time surfaces a broken route as a BUILD failure and freezes the physical
201
+ * plan for drift comparison.
202
+ */
203
+ readonly query: QuerySpec;
204
+ }
205
+ /** One serialized write op of a prepared WRITE plan. */
206
+ interface PreparedWriteOpSpec {
207
+ readonly alias: string;
208
+ readonly entity: string;
209
+ readonly intent: 'create' | 'update' | 'remove' | 'upsert';
210
+ /** The target model's primary-key input fields (W1 key/changes split + read-back key). */
211
+ readonly keyFields: readonly string[];
212
+ /** Key-field binds. */
213
+ readonly key: PreparedBindMap;
214
+ /** Input-field binds. */
215
+ readonly input: PreparedBindMap;
216
+ /** In-process write-gate binds (flat equality / existence template), if declared. */
217
+ readonly condition?: PreparedBindMap;
218
+ /** The read-back projection + options, verbatim (JSON-safe by the #206 lint). */
219
+ readonly result?: {
220
+ readonly select?: Record<string, unknown>;
221
+ readonly options?: {
222
+ readonly consistentRead?: boolean;
223
+ readonly maxDepth?: number;
224
+ };
225
+ };
226
+ /**
227
+ * The consistent read-back's spec-IR plan (derived from `result.select` at
228
+ * build time — a broken read-back projection fails the BUILD). Present iff
229
+ * {@link result} declares a non-empty select.
230
+ */
231
+ readonly readback?: QuerySpec;
232
+ /**
233
+ * The op's full declarative {@link TransactionSpec}: `items[0]` is the base
234
+ * write, followed by every derived effect the mutation compiler resolved at
235
+ * build time. Templates bind `{<field>}` tokens — the op's key/input FIELD
236
+ * names — which the loader renders from the per-call bound field values.
237
+ */
238
+ readonly transaction: TransactionSpec;
239
+ /** Per-item derived-effect categories, index-aligned to `transaction.items`. */
240
+ readonly categories: readonly PreparedWriteItemCategory[];
241
+ }
242
+ /** One compiled prepared plan (all routes of one `DDBModel.prepare` body). */
243
+ interface PreparedPlanSpec {
244
+ readonly kind: 'read' | 'write';
245
+ /**
246
+ * The `$` params the plan binds (union across routes), with kinds recovered
247
+ * from the bound entity fields where determinable.
248
+ */
249
+ readonly params: Readonly<Record<string, ParamSpec>>;
250
+ /**
251
+ * Entity name → fingerprint of its canonical manifest entry at build time.
252
+ * The loader recomputes these from the live registry and LOUDLY rejects a
253
+ * mismatch (stale plan / model drift).
254
+ */
255
+ readonly entities: Readonly<Record<string, string>>;
256
+ /** Read routes, in body declaration order (read plans only). */
257
+ readonly reads?: readonly PreparedReadRouteSpec[];
258
+ /** Write ops, in body declaration order (write plans only). */
259
+ readonly writes?: readonly PreparedWriteOpSpec[];
260
+ }
261
+ /** The full static prepared-plan artifact. */
262
+ interface PreparedPlanDocument {
263
+ readonly formatVersion: typeof PREPARED_FORMAT_VERSION;
264
+ /** The shared operation-IR version the plans were compiled against. */
265
+ readonly specVersion: typeof SPEC_VERSION;
266
+ /** Plan id (the transform's stable call-site id) → compiled plan. */
267
+ readonly plans: Readonly<Record<string, PreparedPlanSpec>>;
268
+ }
269
+ /** Deterministic JSON: object keys sorted at every level (arrays keep order). */
270
+ declare function canonicalJson(value: unknown): string;
271
+ /**
272
+ * The fingerprint of one entity's canonical manifest entry — every plan-relevant
273
+ * declaration fact (table, physical name, prefix, fields + formats, key / GSI
274
+ * templates, relations incl. `refs` bindings, TTL). Computed identically at
275
+ * build (emit) and at load (live registry), so any drift is caught.
276
+ */
277
+ declare function entityFingerprint(metadata: EntityMetadata): string;
278
+ /** Stable content hash of a compiled plan (drift-check convenience). */
279
+ declare function planFingerprint(plan: PreparedPlanSpec): string;
280
+
281
+ export { type AnyModelContract as A, type BuiltContracts as B, type ContractMap as C, type PreparedWriteOpSpec as P, type PreparedPlanDocument as a, type PreparedBindSpec as b, type PreparedPlanSpec as c, type PreparedReadRouteSpec as d, type ContextOwnershipMap as e, type ContextOwnership as f, PREPARED_FORMAT_VERSION as g, type PreparedBindMap as h, buildContexts as i, buildContracts as j, canonicalJson as k, entityFingerprint as l, planFingerprint as p };