graphddb 0.5.2 → 0.6.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.
- package/README.md +8 -0
- package/dist/cdc/index.d.ts +37 -0
- package/dist/cdc/index.js +29 -0
- package/dist/{chunk-QBXLQNXY.js → chunk-5NXNEW43.js} +4 -1
- package/dist/{chunk-W3GEJPPV.js → chunk-F2DI3GTI.js} +154 -1024
- package/dist/chunk-MMVHOUM4.js +24 -0
- package/dist/{chunk-H5TUW2WR.js → chunk-N5NQM3SO.js} +3749 -3606
- package/dist/chunk-PDUVTYC5.js +992 -0
- package/dist/cli.js +922 -19
- package/dist/from-change-CFzBy7aU.d.ts +327 -0
- package/dist/index-CtJbTrfB.d.ts +690 -0
- package/dist/index.d.ts +53 -1113
- package/dist/index.js +48 -41
- package/dist/linter/index.d.ts +126 -0
- package/dist/linter/index.js +36 -0
- package/dist/{types-m1Ect6hG.d.ts → maintenance-view-adapter-CFeasCKo.d.ts} +380 -187
- package/dist/registry-DbqmFyab.d.ts +76 -0
- package/dist/relation-depth-0TiWr5OW.d.ts +36 -0
- package/dist/spec/index.d.ts +4 -0
- package/dist/spec/index.js +54 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +5 -4
- package/docs/design-patterns.md +150 -27
- package/docs/doc-sample.md +263 -0
- package/docs/docs-generation.md +183 -0
- package/package.json +55 -4
- package/dist/chunk-MCKGQKYU.js +0 -15
- package/dist/typescript-ZUQEBJRV.js +0 -210764
|
@@ -1,5 +1,118 @@
|
|
|
1
1
|
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* CDC emulator types (issue #72). These types are **cdc-module-owned**; core
|
|
5
|
+
* never references them. The {@link ChangeEvent} shape mirrors DynamoDB Streams
|
|
6
|
+
* (`NEW_AND_OLD_IMAGES`) so a consumer written against the emulator runs
|
|
7
|
+
* unchanged against real Streams in production (spec §4).
|
|
8
|
+
*/
|
|
9
|
+
/** Stream view type. Fixed to `NEW_AND_OLD_IMAGES` — incremental aggregation
|
|
10
|
+
* needs both images (spec §4). */
|
|
11
|
+
type StreamViewType = 'NEW_AND_OLD_IMAGES';
|
|
12
|
+
/** Stream event kind, matching DynamoDB Streams. */
|
|
13
|
+
type ChangeEventName = 'INSERT' | 'MODIFY' | 'REMOVE';
|
|
14
|
+
/**
|
|
15
|
+
* A single change event. Within one shard, `sequenceNumber` is monotonically
|
|
16
|
+
* increasing; across shards order is independent (spec §6).
|
|
17
|
+
*/
|
|
18
|
+
interface ChangeEvent<T = Record<string, unknown>> {
|
|
19
|
+
eventName: ChangeEventName;
|
|
20
|
+
table: string;
|
|
21
|
+
/** Resolved model name when known. */
|
|
22
|
+
model?: string;
|
|
23
|
+
keys: {
|
|
24
|
+
pk: string;
|
|
25
|
+
sk: string;
|
|
26
|
+
};
|
|
27
|
+
/** Present for MODIFY / REMOVE. */
|
|
28
|
+
oldImage?: T;
|
|
29
|
+
/** Present for INSERT / MODIFY. */
|
|
30
|
+
newImage?: T;
|
|
31
|
+
/** Deterministic-clock-derived creation time (ISO 8601). */
|
|
32
|
+
approximateCreationTime: string;
|
|
33
|
+
/** Monotonic within a shard (zero-padded for lexicographic ordering). */
|
|
34
|
+
sequenceNumber: string;
|
|
35
|
+
/** Partition = hash(pk). */
|
|
36
|
+
shardId: string;
|
|
37
|
+
}
|
|
38
|
+
/** A delivered batch. Records of the same shard are in `sequenceNumber` order. */
|
|
39
|
+
interface ChangeBatch<T = Record<string, unknown>> {
|
|
40
|
+
records: ChangeEvent<T>[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The consumer's response to a batch (spec §6, `ReportBatchItemFailures`
|
|
44
|
+
* equivalent). Returning the `sequenceNumber`s of records that failed lets the
|
|
45
|
+
* emulator advance the checkpoint past the successful prefix and redeliver only
|
|
46
|
+
* the failures.
|
|
47
|
+
*/
|
|
48
|
+
interface BatchResult {
|
|
49
|
+
/** `sequenceNumber`s of records the consumer failed to process. */
|
|
50
|
+
batchItemFailures?: string[];
|
|
51
|
+
}
|
|
52
|
+
/** The consumer handler. */
|
|
53
|
+
type ChangeHandler = (batch: ChangeBatch) => Promise<BatchResult | void>;
|
|
54
|
+
/** Unsubscribe handle. */
|
|
55
|
+
type Unsubscribe = () => void;
|
|
56
|
+
/** Where a fresh subscriber begins reading. */
|
|
57
|
+
type StartingPosition = 'TRIM_HORIZON' | 'LATEST';
|
|
58
|
+
/** Clock mode. `virtual` makes time deterministic via `advanceClock`. */
|
|
59
|
+
type ClockMode = 'real' | 'virtual';
|
|
60
|
+
/** Delivery mode (spec §7). */
|
|
61
|
+
type CdcMode = 'inline' | 'queued' | 'record' | 'replay';
|
|
62
|
+
/** Deterministic fault-injection spec (spec §8). All probabilities are seeded. */
|
|
63
|
+
interface FaultSpec {
|
|
64
|
+
/** Probability [0,1] a delivered record is also re-delivered (duplicate). */
|
|
65
|
+
duplicate?: number;
|
|
66
|
+
/** Shuffle within-shard order on delivery (invariant-violation testing). */
|
|
67
|
+
reorder?: boolean;
|
|
68
|
+
/** Per-record virtual-time delivery delay range (ms). Requires queued mode. */
|
|
69
|
+
delay?: {
|
|
70
|
+
min: number;
|
|
71
|
+
max: number;
|
|
72
|
+
};
|
|
73
|
+
/** Probability [0,1] a record is dropped on first delivery then redelivered. */
|
|
74
|
+
dropThenRedeliver?: number;
|
|
75
|
+
/** Probability [0,1] a record is reported as a partial-batch failure. */
|
|
76
|
+
partialBatchFailure?: number;
|
|
77
|
+
}
|
|
78
|
+
/** A reference whose recompute should be forced to race a mark (spec §8, §7). */
|
|
79
|
+
interface ConcurrentRecomputeRef {
|
|
80
|
+
/** Opaque node ref the harness recomputes concurrently with marking. */
|
|
81
|
+
ref: string;
|
|
82
|
+
}
|
|
83
|
+
/** A persisted event log (spec §10, record/replay). */
|
|
84
|
+
interface EventLog {
|
|
85
|
+
seed: number;
|
|
86
|
+
events: ChangeEvent[];
|
|
87
|
+
}
|
|
88
|
+
/** Replay options (spec §10). */
|
|
89
|
+
interface ReplayOptions {
|
|
90
|
+
/** Deliver events in a deterministic shuffled order (any-order replay). */
|
|
91
|
+
shuffle?: boolean;
|
|
92
|
+
/** Probability [0,1] each event is delivered twice during replay. */
|
|
93
|
+
duplicate?: number;
|
|
94
|
+
}
|
|
95
|
+
/** Constructor options (spec §11). */
|
|
96
|
+
interface CdcEmulatorOptions {
|
|
97
|
+
/** Stream-enabled model classes (opt-in; default none). */
|
|
98
|
+
models?: Function[];
|
|
99
|
+
/** Delivery mode. Default `inline`. */
|
|
100
|
+
mode?: CdcMode;
|
|
101
|
+
/** Clock mode. Default `virtual` for queued, `real` otherwise. */
|
|
102
|
+
clock?: ClockMode;
|
|
103
|
+
/** Records per delivered batch. Default 100. */
|
|
104
|
+
batchSize?: number;
|
|
105
|
+
/** Max redelivery attempts before a record goes to the DLQ. Default 3. */
|
|
106
|
+
maxRetries?: number;
|
|
107
|
+
/** Where a subscriber starts. Default `TRIM_HORIZON`. */
|
|
108
|
+
startingPosition?: StartingPosition;
|
|
109
|
+
/** Seed for fault injection / shard assignment determinism. Default 1. */
|
|
110
|
+
seed?: number;
|
|
111
|
+
/** Number of shards events are partitioned across. Default 8. */
|
|
112
|
+
shardCount?: number;
|
|
113
|
+
}
|
|
114
|
+
type ShardId = string;
|
|
115
|
+
|
|
3
116
|
/**
|
|
4
117
|
* App-level throttle / transient-error retry for single-op sends (issue #111).
|
|
5
118
|
*
|
|
@@ -555,7 +668,34 @@ type Scalar = string | number | boolean | bigint | symbol | null | undefined | D
|
|
|
555
668
|
* - Function properties → excluded
|
|
556
669
|
*/
|
|
557
670
|
type SelectableOf<T> = {
|
|
558
|
-
[K in keyof T as T[K] extends Function ? never : K]?: T[K] extends Array<infer E> ? [E] extends [DDBModel] ? RelationSpec<E> : true : NonNullable<T[K]> extends DDBModel ? null extends T[K] ? RelationSpec<NonNullable<T[K]>> : SelectableOf<T[K]> : T[K] extends Scalar ? true : SelectableOf<T[K]>;
|
|
671
|
+
[K in keyof T as T[K] extends Function ? never : K]?: T[K] extends Array<infer E> ? [E] extends [DDBModel] ? RelationSpec<E> | InlineSnapshotSpec : true : NonNullable<T[K]> extends DDBModel ? null extends T[K] ? RelationSpec<NonNullable<T[K]>> | InlineSnapshotSpec : SelectableOf<T[K]> : T[K] extends Scalar ? true : SelectableOf<T[K]>;
|
|
672
|
+
};
|
|
673
|
+
/**
|
|
674
|
+
* Inline-read spec for an **`embeddedSnapshot`** relation field (issue #196).
|
|
675
|
+
*
|
|
676
|
+
* An `embeddedSnapshot` relation (`@hasMany` collection like
|
|
677
|
+
* `ThreadSummary.latestPosts`, or a `@belongsTo`/`@hasOne` single-row mirror)
|
|
678
|
+
* keeps a *maintained projected copy* of the related data as a **physical
|
|
679
|
+
* attribute on the owner row** — docs §3 calls this "read inline off the owner
|
|
680
|
+
* row". `{ inline: true }` selects exactly that stored copy: the read projects
|
|
681
|
+
* the owner-row attribute and returns it in its declared shape, WITHOUT any
|
|
682
|
+
* child-partition traversal.
|
|
683
|
+
*
|
|
684
|
+
* It is deliberately a **distinct shape** from the traversal spec
|
|
685
|
+
* {@link RelationSpec} (`{ select: … }` / a `relation(…)` builder):
|
|
686
|
+
*
|
|
687
|
+
* - `{ latestPosts: { select: { … } } }` → **traversal** — a Query against the
|
|
688
|
+
* relation's child partition (the real children). A different physical read.
|
|
689
|
+
* - `{ latestPosts: { inline: true } }` → **inline read** — the maintained
|
|
690
|
+
* copy stored on the owner row. No join.
|
|
691
|
+
*
|
|
692
|
+
* The two never overlap structurally (`inline` vs `select`), so the type layer
|
|
693
|
+
* keeps them apart, and at runtime `{ inline: true }` is rejected on any field
|
|
694
|
+
* that is not an `embeddedSnapshot` relation (a loud error), so the two paths
|
|
695
|
+
* are unambiguous in BOTH the types and the execution.
|
|
696
|
+
*/
|
|
697
|
+
type InlineSnapshotSpec = {
|
|
698
|
+
inline: true;
|
|
559
699
|
};
|
|
560
700
|
/**
|
|
561
701
|
* What a relation field accepts in a `select`: either the plain
|
|
@@ -625,7 +765,7 @@ type StrictSelect<T, Sel> = {
|
|
|
625
765
|
select: infer Nested;
|
|
626
766
|
} ? K extends keyof T ? Sel[K] & {
|
|
627
767
|
select: StrictSelect<RelationTargetOf<T[K]>, Nested>;
|
|
628
|
-
} : Sel[K] : Sel[K] extends object ? Sel[K] extends RelationBuilder<infer _RT, infer _RS> ? Sel[K] : K extends keyof T ? Sel[K] & StrictSelect<NonNullable<T[K]>, Sel[K]> : Sel[K] : Sel[K] : never;
|
|
768
|
+
} : Sel[K] : Sel[K] extends InlineSnapshotSpec ? Sel[K] : Sel[K] extends object ? Sel[K] extends RelationBuilder<infer _RT, infer _RS> ? Sel[K] : K extends keyof T ? Sel[K] & StrictSelect<NonNullable<T[K]>, Sel[K]> : Sel[K] : Sel[K] : never;
|
|
629
769
|
};
|
|
630
770
|
/**
|
|
631
771
|
* Extracts the relation **target entity type** from an entity field type:
|
|
@@ -681,7 +821,7 @@ type EntityInput<T> = {
|
|
|
681
821
|
*/
|
|
682
822
|
|
|
683
823
|
type QueryResult<T, S> = S extends unknown ? {
|
|
684
|
-
[K in keyof S & keyof T]: S[K] extends true ? T[K] : S[K] extends RelationBuilder<infer _RT, infer Sel> ? T[K] extends Array<infer E> ? {
|
|
824
|
+
[K in keyof S & keyof T]: S[K] extends true ? T[K] : S[K] extends InlineSnapshotSpec ? T[K] : S[K] extends RelationBuilder<infer _RT, infer Sel> ? T[K] extends Array<infer E> ? {
|
|
685
825
|
items: QueryResult<E, Sel>[];
|
|
686
826
|
cursor: string | null;
|
|
687
827
|
} : QueryResult<NonNullable<T[K]>, Sel> | null : S[K] extends {
|
|
@@ -2016,6 +2156,21 @@ interface UniqueEffect {
|
|
|
2016
2156
|
* An edge write effect (proposal §2 `edges`): create / delete the adjacency row
|
|
2017
2157
|
* that materializes a target relation. Derived to an adjacency `Put` / `Delete`
|
|
2018
2158
|
* by #82/#85 (the `src/relation/edge-write.ts` primitive) — stored opaquely here.
|
|
2159
|
+
*
|
|
2160
|
+
* ## `inverse` — dual-edge synchronization through the command IF (Epic #118 pattern 9, issue #195)
|
|
2161
|
+
*
|
|
2162
|
+
* A plain edge above is **one physical row** (the target relation's adjacency row),
|
|
2163
|
+
* created on create and deleted on delete. A **dual edge** (pattern 9 / #133) is a
|
|
2164
|
+
* bidirectional relation kept as TWO physical rows — a forward row (the target
|
|
2165
|
+
* relation's adjacency) and an inverse row on its OWN partition (a SECOND adjacency
|
|
2166
|
+
* model). {@link inverse}, when present, names that inverse row so the command /
|
|
2167
|
+
* mutation derivation ({@link import('../spec/mutation-command.js')}) maintains BOTH
|
|
2168
|
+
* rows in the SAME atomic transaction — the create `Put`s both, the delete `Delete`s
|
|
2169
|
+
* both, a foreign-key change `Delete`s+`Put`s both — exactly as the low-level
|
|
2170
|
+
* {@link import('../relation/edge-write.js').deriveModelEdgeWriteItems} path does. It
|
|
2171
|
+
* mirrors {@link import('../relation/edge-write.js').EdgeWriteDeclaration.inverse} so
|
|
2172
|
+
* the two edge-write vocabularies stay structurally identical; omit `inverse` for the
|
|
2173
|
+
* historical single-row (base + inverse GSI) bidirectional edge.
|
|
2019
2174
|
*/
|
|
2020
2175
|
interface EdgeEffect {
|
|
2021
2176
|
readonly kind: 'putEdge' | 'deleteEdge';
|
|
@@ -2023,6 +2178,22 @@ interface EdgeEffect {
|
|
|
2023
2178
|
readonly targetFactory: () => new (...args: unknown[]) => unknown;
|
|
2024
2179
|
/** The relation property on the target that reads this edge. */
|
|
2025
2180
|
readonly relationProperty: string;
|
|
2181
|
+
/**
|
|
2182
|
+
* The INVERSE edge to keep in sync (Epic #118 pattern 9 / issue #133 & #195, dual-edge).
|
|
2183
|
+
* Names the second adjacency model whose own row materializes the reverse-direction
|
|
2184
|
+
* relation. When present, the mutation-command derivation maintains the inverse row
|
|
2185
|
+
* alongside the forward row in the SAME transaction, so a one-direction declaration
|
|
2186
|
+
* driven through the command IF keeps a two-row bidirectional edge consistent. Absent
|
|
2187
|
+
* = the historical single-row (base + inverse GSI) bidirectional edge.
|
|
2188
|
+
*/
|
|
2189
|
+
readonly inverse?: {
|
|
2190
|
+
/** Resolves the inverse adjacency model whose row IS the inverse edge. */
|
|
2191
|
+
readonly adjacencyFactory: () => new (...args: unknown[]) => unknown;
|
|
2192
|
+
/** Resolves the target model whose relation the inverse row feeds. */
|
|
2193
|
+
readonly targetFactory: () => new (...args: unknown[]) => unknown;
|
|
2194
|
+
/** The relation property on the inverse target that reads the inverse row. */
|
|
2195
|
+
readonly relationProperty: string;
|
|
2196
|
+
};
|
|
2026
2197
|
}
|
|
2027
2198
|
/**
|
|
2028
2199
|
* A derived (cascading) update (proposal §2 `derive`): e.g. `User.postCount +=
|
|
@@ -2492,6 +2663,42 @@ interface WriteRecorder {
|
|
|
2492
2663
|
putEdge(target: () => new (...args: unknown[]) => unknown, relationProperty: string): EdgeEffect;
|
|
2493
2664
|
/** Declare an edge delete effect (§2 `edges`; derived #82/#85). */
|
|
2494
2665
|
deleteEdge(target: () => new (...args: unknown[]) => unknown, relationProperty: string): EdgeEffect;
|
|
2666
|
+
/**
|
|
2667
|
+
* Declare a **dual edge** (Epic #118 pattern 9 / issue #133 & #195): a bidirectional
|
|
2668
|
+
* edge maintained as TWO physical rows — a forward row (the `forward.target`'s
|
|
2669
|
+
* `relationProperty` adjacency) and an inverse row on a SECOND adjacency model
|
|
2670
|
+
* (read by `inverse.target`'s `relationProperty`). Both rows are written / deleted /
|
|
2671
|
+
* moved together from this single declaration, so the command / mutation IF keeps the
|
|
2672
|
+
* two directions in sync WITHOUT an inverse GSI — the same two-row maintenance the
|
|
2673
|
+
* low-level {@link import('../relation/edge-write.js').edgeWrites} `w.dualEdge` performs,
|
|
2674
|
+
* now reachable through `entityWrites` and thus through `executeCommandMethod` /
|
|
2675
|
+
* `DDBModel.mutate`. Use this when the reverse direction lives on its own partition
|
|
2676
|
+
* (a second row) rather than a GSI of the forward row.
|
|
2677
|
+
*
|
|
2678
|
+
* The lifecycle is chosen by the fragment intent (create → both `Put`, remove → both
|
|
2679
|
+
* `Delete`, update → both `Delete(old)+Put(new)`), so the SAME declaration is placed
|
|
2680
|
+
* under whichever lifecycle(s) the save contract maintains the edge on.
|
|
2681
|
+
*
|
|
2682
|
+
* @example
|
|
2683
|
+
* ```ts
|
|
2684
|
+
* static readonly writes = entityWrites<FollowEdgeModel>((w) => ({
|
|
2685
|
+
* create: w.lifecycle({
|
|
2686
|
+
* edges: [w.dualEdge(
|
|
2687
|
+
* { target: () => UserModel, relationProperty: 'following' },
|
|
2688
|
+
* { adjacency: () => FollowedByEdgeModel, target: () => UserModel, relationProperty: 'followers' },
|
|
2689
|
+
* )],
|
|
2690
|
+
* }),
|
|
2691
|
+
* }));
|
|
2692
|
+
* ```
|
|
2693
|
+
*/
|
|
2694
|
+
dualEdge(forward: {
|
|
2695
|
+
target: () => new (...args: unknown[]) => unknown;
|
|
2696
|
+
relationProperty: string;
|
|
2697
|
+
}, inverse: {
|
|
2698
|
+
adjacency: () => new (...args: unknown[]) => unknown;
|
|
2699
|
+
target: () => new (...args: unknown[]) => unknown;
|
|
2700
|
+
relationProperty: string;
|
|
2701
|
+
}): EdgeEffect;
|
|
2495
2702
|
/** Declare a derived / cascading update (§2 `derive`; derived #85). */
|
|
2496
2703
|
increment(target: () => new (...args: unknown[]) => unknown, keys: Readonly<Record<string, EffectPath>>, attribute: string, amount: number): DeriveEffect;
|
|
2497
2704
|
/**
|
|
@@ -2832,74 +3039,6 @@ declare function mutation(name: string, body: MutationBody): CommandPlan;
|
|
|
2832
3039
|
*/
|
|
2833
3040
|
declare const definePlan: typeof mutation;
|
|
2834
3041
|
|
|
2835
|
-
/**
|
|
2836
|
-
* Decorator-metadata → maintenance-graph `ViewDefinition` adapter (issue #152).
|
|
2837
|
-
*
|
|
2838
|
-
* ## What this replaces
|
|
2839
|
-
*
|
|
2840
|
-
* The old `defineView` / `defineVersioned` builders (deleted) registered
|
|
2841
|
-
* `ViewDefinition`s into a side `ViewRegistry`, which the maintenance graph read.
|
|
2842
|
-
* That builder carried a registration side-effect + a `generation` counter (a
|
|
2843
|
-
* silent-drop guard). This adapter removes that whole path: it derives the SAME
|
|
2844
|
-
* `ViewDefinition` IR purely from the declarative `MetadataRegistry` — the
|
|
2845
|
-
* Contract-layer SSoT, whose own `generation` counter is the single
|
|
2846
|
-
* invalidation source — so a view declared via `@model({ kind })` + `@maintainedFrom`
|
|
2847
|
-
* (and a versioned relation declared via `@hasOne/@hasMany` `pattern`) is discovered
|
|
2848
|
-
* with no separate registry.
|
|
2849
|
-
*
|
|
2850
|
-
* ## IR invariance
|
|
2851
|
-
*
|
|
2852
|
-
* The `ViewDefinition` / `ViewSourceSlice` shapes are UNCHANGED. The maintenance
|
|
2853
|
-
* graph, the K (#130) stream/drain, and the L (#131) rebuild consume the adapter's
|
|
2854
|
-
* output exactly as they consumed `ViewRegistry.getAll()`. Only the SOURCE of the
|
|
2855
|
-
* definitions moved from a builder side-effect to declarative metadata.
|
|
2856
|
-
*
|
|
2857
|
-
* ## Order independence (issue #152 hardening)
|
|
2858
|
-
*
|
|
2859
|
-
* Stacked `@maintainedFrom` declarations carry no order meaning. The adapter rejects
|
|
2860
|
-
* — symmetrically, so the error is identical whichever order the decorators are
|
|
2861
|
-
* stacked — any two declarations on the same view that:
|
|
2862
|
-
* 1. write the SAME projection target attribute (ambiguous duplicate projection);
|
|
2863
|
-
* 2. maintain the SAME `collection.field`;
|
|
2864
|
-
* 3. bind the SAME view-key field to a DIFFERENT source path (the view-row identity
|
|
2865
|
-
* would be inconsistent across sources).
|
|
2866
|
-
* A legitimate multi-source view (different sources filling DIFFERENT fields, all
|
|
2867
|
-
* binding the SAME key the SAME way) is fine.
|
|
2868
|
-
*/
|
|
2869
|
-
|
|
2870
|
-
type AnyModelClass = abstract new (...args: any[]) => any;
|
|
2871
|
-
/** The view source slice IR the maintenance graph consumes (one per source × view). */
|
|
2872
|
-
interface ViewSourceSlice {
|
|
2873
|
-
readonly sourceClass: AnyModelClass;
|
|
2874
|
-
readonly maintainedOn: readonly MaintainTrigger[];
|
|
2875
|
-
readonly keys: Readonly<Record<string, EffectPath>>;
|
|
2876
|
-
readonly project: ProjectionMap;
|
|
2877
|
-
readonly collection?: {
|
|
2878
|
-
readonly field: string;
|
|
2879
|
-
readonly maxItems?: number;
|
|
2880
|
-
readonly orderBy?: EffectPath;
|
|
2881
|
-
readonly orderDir?: 'ASC' | 'DESC';
|
|
2882
|
-
};
|
|
2883
|
-
readonly predicate?: MembershipPredicate;
|
|
2884
|
-
}
|
|
2885
|
-
/** The view definition IR — an independent view row maintained from one or more sources. */
|
|
2886
|
-
interface ViewDefinition {
|
|
2887
|
-
readonly name: string;
|
|
2888
|
-
readonly viewClass: AnyModelClass;
|
|
2889
|
-
readonly pattern: 'materializedView' | 'sparseView';
|
|
2890
|
-
readonly slices: readonly ViewSourceSlice[];
|
|
2891
|
-
readonly updateMode?: 'mutation' | 'stream';
|
|
2892
|
-
readonly consistency?: 'transactional' | 'eventual';
|
|
2893
|
-
}
|
|
2894
|
-
/**
|
|
2895
|
-
* Build every {@link ViewDefinition} for a registry — from `@model({ kind })` +
|
|
2896
|
-
* `@maintainedFrom` view models AND from versioned-pattern relations. This is the
|
|
2897
|
-
* adapter the maintenance graph calls in place of the deleted `ViewRegistry.getAll()`.
|
|
2898
|
-
*
|
|
2899
|
-
* @param registry The models to scan. Defaults to `MetadataRegistry.getAll()`.
|
|
2900
|
-
*/
|
|
2901
|
-
declare function collectViewDefinitions(registry?: ReadonlyMap<Function, EntityMetadata>): ViewDefinition[];
|
|
2902
|
-
|
|
2903
3042
|
/**
|
|
2904
3043
|
* Maintenance graph builder (Epic #118 issue #124 — the RFC B-案 core).
|
|
2905
3044
|
*
|
|
@@ -3124,11 +3263,23 @@ interface ManifestGsi extends ManifestKey {
|
|
|
3124
3263
|
readonly description?: string;
|
|
3125
3264
|
}
|
|
3126
3265
|
interface ManifestRelation {
|
|
3127
|
-
readonly type: 'hasMany' | 'hasOne' | 'belongsTo';
|
|
3266
|
+
readonly type: 'hasMany' | 'hasOne' | 'belongsTo' | 'refs';
|
|
3128
3267
|
/** Target entity (model class) name. */
|
|
3129
3268
|
readonly target: string;
|
|
3130
3269
|
/** target field → source field (on this entity). */
|
|
3131
3270
|
readonly keyBinding: Readonly<Record<string, string>>;
|
|
3271
|
+
/**
|
|
3272
|
+
* List-valued source descriptor for a `refs` relation (issue #197). Present IFF
|
|
3273
|
+
* `type === 'refs'`: `from` is the parent LIST attribute holding the inline
|
|
3274
|
+
* reference elements (e.g. `'tagRefs'`), `key` the field read off each element
|
|
3275
|
+
* (e.g. `'tagId'`). Absent for every scalar-keyed relation (byte-identical to
|
|
3276
|
+
* the pre-#197 manifest). Carried so a manifest consumer can reconstruct where a
|
|
3277
|
+
* `refs` relation's BatchGet keys come from.
|
|
3278
|
+
*/
|
|
3279
|
+
readonly refs?: Readonly<{
|
|
3280
|
+
from: string;
|
|
3281
|
+
key: string;
|
|
3282
|
+
}>;
|
|
3132
3283
|
/**
|
|
3133
3284
|
* Optional human-readable description of the relation (issue #166, follow-up of
|
|
3134
3285
|
* #154), from `@hasMany/@belongsTo/@hasOne(..., { description })`. Pure documentation
|
|
@@ -4100,6 +4251,56 @@ interface DerivedMaintainWrite {
|
|
|
4100
4251
|
readonly value?: unknown;
|
|
4101
4252
|
};
|
|
4102
4253
|
}
|
|
4254
|
+
/**
|
|
4255
|
+
* Drop the cached global {@link MaintenanceGraph} (built lazily by
|
|
4256
|
+
* {@link resolveMaintainers}). Invalidation is now automatic — the cache is keyed
|
|
4257
|
+
* by {@link MetadataRegistry.generation}, so a model registered after a build is
|
|
4258
|
+
* already picked up without calling this. Retained as an explicit escape hatch (and
|
|
4259
|
+
* for source-compatibility); forcing a rebuild is never required for correctness.
|
|
4260
|
+
*/
|
|
4261
|
+
declare function resetMaintenanceGraphCache(): void;
|
|
4262
|
+
/**
|
|
4263
|
+
* Resolve the maintenance {@link MaintainItem effects} a fragment's lifecycle event
|
|
4264
|
+
* fires (issue #125 — the compile-side consumer of D/#124's {@link MaintenanceGraph}).
|
|
4265
|
+
* The fragment's source entity is its written model (its LOGICAL name — #118
|
|
4266
|
+
* contract), and the trigger is `<logicalName>.<event>` where `event` is the
|
|
4267
|
+
* past-tense of the fragment intent ({@link INTENT_MAINTAIN_EVENT}). Returns every
|
|
4268
|
+
* `MaintainItem` the graph indexes under that trigger (`graph.effectsFor(...)`),
|
|
4269
|
+
* empty when nothing maintains on it (the no-regression path — a fragment that fires
|
|
4270
|
+
* no maintainer compiles exactly as before).
|
|
4271
|
+
*
|
|
4272
|
+
* @param fragment The fragment whose lifecycle event is the maintenance trigger.
|
|
4273
|
+
* @param graph The maintenance graph to query. Defaults to a lazily-built,
|
|
4274
|
+
* cached graph over the global registry ({@link MetadataRegistry.getAll}); an
|
|
4275
|
+
* explicit graph is accepted for scoped tests.
|
|
4276
|
+
*/
|
|
4277
|
+
declare function resolveMaintainers(fragment: MutationFragment, graph?: MaintenanceGraph): readonly MaintainItem[];
|
|
4278
|
+
/**
|
|
4279
|
+
* Cross-fragment guard (issue #127 audit 是正1): reject — LOUDLY, with the true cause
|
|
4280
|
+
* named — a set of aggregated maintenance writes (collected across ALL of a multi-
|
|
4281
|
+
* fragment mutation's fragments by {@link buildPlannedCommandMethod}'s flatMap) in
|
|
4282
|
+
* which **two or more** writes resolve to the SAME destination (owner) row.
|
|
4283
|
+
*
|
|
4284
|
+
* ## Why this layer exists
|
|
4285
|
+
*
|
|
4286
|
+
* 論点2 = b ("1 mutation × 1 target row = 1 maintain effect") must hold for the WHOLE
|
|
4287
|
+
* mutation, not just within one fragment. {@link deriveMaintainItems} enforces it
|
|
4288
|
+
* INTRA-fragment, but two *different* fragments can each fire a maintainer onto the
|
|
4289
|
+
* same owner row; the flatMap that aggregates them is a plain concat and would not
|
|
4290
|
+
* notice. Without this guard those two writes collapse together in the runtime's
|
|
4291
|
+
* same-physical-key layer and surface as a `mergeAddUpdates` "ADD delta is non-numeric"
|
|
4292
|
+
* throw — loud (atomicity is preserved) but MISLEADING: it reads as a derived-counter
|
|
4293
|
+
* merge failure and hides the real cause (two maintenance effects resolving to one
|
|
4294
|
+
* owner row). This guard fires FIRST, with a message that names the true cause.
|
|
4295
|
+
*
|
|
4296
|
+
* The identity rule is {@link maintainWriteRowKey} — the same owner-row identity the
|
|
4297
|
+
* intra-fragment reject uses (`destinationRowKey`), so both layers agree on what "the
|
|
4298
|
+
* same row" means. Merging two maintenance writes into one row is a future issue (the
|
|
4299
|
+
* #96 same-physical-key "may not touch one key twice" philosophy); this layer rejects.
|
|
4300
|
+
*
|
|
4301
|
+
* @throws if two aggregated maintenance writes resolve to the same owner row.
|
|
4302
|
+
*/
|
|
4303
|
+
declare function assertNoCrossFragmentMaintainCollision(methodName: string, writes: readonly DerivedMaintainWrite[]): void;
|
|
4103
4304
|
/**
|
|
4104
4305
|
* A **derived uniqueness guard** — the marker-row `Put` (and, on a unique-field
|
|
4105
4306
|
* change, the old-guard `Delete` + new-guard `Put` swap) that enforces an
|
|
@@ -4417,6 +4618,8 @@ declare function compileFragment(fragment: MutationFragment, index?: number, res
|
|
|
4417
4618
|
* @throws if `plan` is not a {@link CommandPlan}, or declares more than one fragment.
|
|
4418
4619
|
*/
|
|
4419
4620
|
declare function compileSingleFragmentPlan(plan: CommandPlan): CompiledFragment;
|
|
4621
|
+
/** The DynamoDB `TransactWriteItems` item cap — an atomic tx is never split (#64). */
|
|
4622
|
+
declare const MAX_TRANSACT_COMPOSE_ITEMS = 25;
|
|
4420
4623
|
/**
|
|
4421
4624
|
* The result of compiling a (1..N)-fragment {@link CommandPlan} (#90): the ordered
|
|
4422
4625
|
* per-fragment {@link CompiledFragment}s, merged so they form **one atomic
|
|
@@ -6023,119 +6226,6 @@ type MutateParallelResult<E extends WriteEnvelope> = {
|
|
|
6023
6226
|
readonly [K in keyof E]: BulkWrap<E[K], ParallelResultOf<E[K]>>;
|
|
6024
6227
|
};
|
|
6025
6228
|
|
|
6026
|
-
/**
|
|
6027
|
-
* CDC emulator types (issue #72). These types are **cdc-module-owned**; core
|
|
6028
|
-
* never references them. The {@link ChangeEvent} shape mirrors DynamoDB Streams
|
|
6029
|
-
* (`NEW_AND_OLD_IMAGES`) so a consumer written against the emulator runs
|
|
6030
|
-
* unchanged against real Streams in production (spec §4).
|
|
6031
|
-
*/
|
|
6032
|
-
/** Stream view type. Fixed to `NEW_AND_OLD_IMAGES` — incremental aggregation
|
|
6033
|
-
* needs both images (spec §4). */
|
|
6034
|
-
type StreamViewType = 'NEW_AND_OLD_IMAGES';
|
|
6035
|
-
/** Stream event kind, matching DynamoDB Streams. */
|
|
6036
|
-
type ChangeEventName = 'INSERT' | 'MODIFY' | 'REMOVE';
|
|
6037
|
-
/**
|
|
6038
|
-
* A single change event. Within one shard, `sequenceNumber` is monotonically
|
|
6039
|
-
* increasing; across shards order is independent (spec §6).
|
|
6040
|
-
*/
|
|
6041
|
-
interface ChangeEvent<T = Record<string, unknown>> {
|
|
6042
|
-
eventName: ChangeEventName;
|
|
6043
|
-
table: string;
|
|
6044
|
-
/** Resolved model name when known. */
|
|
6045
|
-
model?: string;
|
|
6046
|
-
keys: {
|
|
6047
|
-
pk: string;
|
|
6048
|
-
sk: string;
|
|
6049
|
-
};
|
|
6050
|
-
/** Present for MODIFY / REMOVE. */
|
|
6051
|
-
oldImage?: T;
|
|
6052
|
-
/** Present for INSERT / MODIFY. */
|
|
6053
|
-
newImage?: T;
|
|
6054
|
-
/** Deterministic-clock-derived creation time (ISO 8601). */
|
|
6055
|
-
approximateCreationTime: string;
|
|
6056
|
-
/** Monotonic within a shard (zero-padded for lexicographic ordering). */
|
|
6057
|
-
sequenceNumber: string;
|
|
6058
|
-
/** Partition = hash(pk). */
|
|
6059
|
-
shardId: string;
|
|
6060
|
-
}
|
|
6061
|
-
/** A delivered batch. Records of the same shard are in `sequenceNumber` order. */
|
|
6062
|
-
interface ChangeBatch<T = Record<string, unknown>> {
|
|
6063
|
-
records: ChangeEvent<T>[];
|
|
6064
|
-
}
|
|
6065
|
-
/**
|
|
6066
|
-
* The consumer's response to a batch (spec §6, `ReportBatchItemFailures`
|
|
6067
|
-
* equivalent). Returning the `sequenceNumber`s of records that failed lets the
|
|
6068
|
-
* emulator advance the checkpoint past the successful prefix and redeliver only
|
|
6069
|
-
* the failures.
|
|
6070
|
-
*/
|
|
6071
|
-
interface BatchResult {
|
|
6072
|
-
/** `sequenceNumber`s of records the consumer failed to process. */
|
|
6073
|
-
batchItemFailures?: string[];
|
|
6074
|
-
}
|
|
6075
|
-
/** The consumer handler. */
|
|
6076
|
-
type ChangeHandler = (batch: ChangeBatch) => Promise<BatchResult | void>;
|
|
6077
|
-
/** Unsubscribe handle. */
|
|
6078
|
-
type Unsubscribe = () => void;
|
|
6079
|
-
/** Where a fresh subscriber begins reading. */
|
|
6080
|
-
type StartingPosition = 'TRIM_HORIZON' | 'LATEST';
|
|
6081
|
-
/** Clock mode. `virtual` makes time deterministic via `advanceClock`. */
|
|
6082
|
-
type ClockMode = 'real' | 'virtual';
|
|
6083
|
-
/** Delivery mode (spec §7). */
|
|
6084
|
-
type CdcMode = 'inline' | 'queued' | 'record' | 'replay';
|
|
6085
|
-
/** Deterministic fault-injection spec (spec §8). All probabilities are seeded. */
|
|
6086
|
-
interface FaultSpec {
|
|
6087
|
-
/** Probability [0,1] a delivered record is also re-delivered (duplicate). */
|
|
6088
|
-
duplicate?: number;
|
|
6089
|
-
/** Shuffle within-shard order on delivery (invariant-violation testing). */
|
|
6090
|
-
reorder?: boolean;
|
|
6091
|
-
/** Per-record virtual-time delivery delay range (ms). Requires queued mode. */
|
|
6092
|
-
delay?: {
|
|
6093
|
-
min: number;
|
|
6094
|
-
max: number;
|
|
6095
|
-
};
|
|
6096
|
-
/** Probability [0,1] a record is dropped on first delivery then redelivered. */
|
|
6097
|
-
dropThenRedeliver?: number;
|
|
6098
|
-
/** Probability [0,1] a record is reported as a partial-batch failure. */
|
|
6099
|
-
partialBatchFailure?: number;
|
|
6100
|
-
}
|
|
6101
|
-
/** A reference whose recompute should be forced to race a mark (spec §8, §7). */
|
|
6102
|
-
interface ConcurrentRecomputeRef {
|
|
6103
|
-
/** Opaque node ref the harness recomputes concurrently with marking. */
|
|
6104
|
-
ref: string;
|
|
6105
|
-
}
|
|
6106
|
-
/** A persisted event log (spec §10, record/replay). */
|
|
6107
|
-
interface EventLog {
|
|
6108
|
-
seed: number;
|
|
6109
|
-
events: ChangeEvent[];
|
|
6110
|
-
}
|
|
6111
|
-
/** Replay options (spec §10). */
|
|
6112
|
-
interface ReplayOptions {
|
|
6113
|
-
/** Deliver events in a deterministic shuffled order (any-order replay). */
|
|
6114
|
-
shuffle?: boolean;
|
|
6115
|
-
/** Probability [0,1] each event is delivered twice during replay. */
|
|
6116
|
-
duplicate?: number;
|
|
6117
|
-
}
|
|
6118
|
-
/** Constructor options (spec §11). */
|
|
6119
|
-
interface CdcEmulatorOptions {
|
|
6120
|
-
/** Stream-enabled model classes (opt-in; default none). */
|
|
6121
|
-
models?: Function[];
|
|
6122
|
-
/** Delivery mode. Default `inline`. */
|
|
6123
|
-
mode?: CdcMode;
|
|
6124
|
-
/** Clock mode. Default `virtual` for queued, `real` otherwise. */
|
|
6125
|
-
clock?: ClockMode;
|
|
6126
|
-
/** Records per delivered batch. Default 100. */
|
|
6127
|
-
batchSize?: number;
|
|
6128
|
-
/** Max redelivery attempts before a record goes to the DLQ. Default 3. */
|
|
6129
|
-
maxRetries?: number;
|
|
6130
|
-
/** Where a subscriber starts. Default `TRIM_HORIZON`. */
|
|
6131
|
-
startingPosition?: StartingPosition;
|
|
6132
|
-
/** Seed for fault injection / shard assignment determinism. Default 1. */
|
|
6133
|
-
seed?: number;
|
|
6134
|
-
/** Number of shards events are partitioned across. Default 8. */
|
|
6135
|
-
shardCount?: number;
|
|
6136
|
-
}
|
|
6137
|
-
type ShardId = string;
|
|
6138
|
-
|
|
6139
6229
|
/**
|
|
6140
6230
|
* `subscribe` — the declarative, batch CDC consumer builder (issue #153).
|
|
6141
6231
|
*
|
|
@@ -6731,11 +6821,46 @@ interface RelationOptions {
|
|
|
6731
6821
|
readonly updateMode?: MaintainUpdateMode;
|
|
6732
6822
|
};
|
|
6733
6823
|
}
|
|
6824
|
+
/**
|
|
6825
|
+
* Descriptor for a `refs` relation (issue #197, Pattern 2 Embedded Refs read
|
|
6826
|
+
* side). A `refs` relation resolves an **inline id-list** held on the parent row
|
|
6827
|
+
* — e.g. `PPost.tagRefs: { tagId: string }[]` — into the referenced child
|
|
6828
|
+
* bodies, in ONE deduped `BatchGetItem` (never per-ref `GetItem`).
|
|
6829
|
+
*
|
|
6830
|
+
* Unlike `hasMany`/`belongsTo`/`hasOne`, whose key is bound from a parent
|
|
6831
|
+
* **scalar** field ({@link RelationMetadata.keyBinding} — `target key ← parent
|
|
6832
|
+
* scalar`), a `refs` key is bound from EACH ELEMENT of a parent LIST attribute:
|
|
6833
|
+
* the traversal reads `parent[from]` (a list), pulls `.key` off every element,
|
|
6834
|
+
* and fans those out into a single BatchGet against the target. This descriptor
|
|
6835
|
+
* captures exactly that list-valued source shape, which the scalar `keyBinding`
|
|
6836
|
+
* `Record<string,string>` cannot express.
|
|
6837
|
+
*
|
|
6838
|
+
* `keyBinding` on a `refs` relation still records the **target child key field ←
|
|
6839
|
+
* element key name** mapping (e.g. `{ tagId: 'tagId' }`), so key building /
|
|
6840
|
+
* projection reuse the existing scalar machinery per resolved element; `refs`
|
|
6841
|
+
* only adds *where the scalar values come from* (the parent list), not a new key
|
|
6842
|
+
* grammar. That keeps `refs` byte-compatible with every scalar-keyBinding
|
|
6843
|
+
* consumer (manifest, planner, dedupe) — an unknown-to-them relation kind is
|
|
6844
|
+
* simply carried through with a valid scalar `keyBinding`.
|
|
6845
|
+
*/
|
|
6846
|
+
interface RefsBinding {
|
|
6847
|
+
/** The parent LIST attribute holding the inline reference elements (e.g. `'tagRefs'`). */
|
|
6848
|
+
from: string;
|
|
6849
|
+
/** The key field to read off EACH list element (e.g. `'tagId'`). */
|
|
6850
|
+
key: string;
|
|
6851
|
+
}
|
|
6734
6852
|
interface RelationMetadata {
|
|
6735
|
-
type: 'hasMany' | 'hasOne' | 'belongsTo';
|
|
6853
|
+
type: 'hasMany' | 'hasOne' | 'belongsTo' | 'refs';
|
|
6736
6854
|
propertyName: string;
|
|
6737
6855
|
targetFactory: () => new (...args: unknown[]) => unknown;
|
|
6738
6856
|
keyBinding: Record<string, string>;
|
|
6857
|
+
/**
|
|
6858
|
+
* List-valued source descriptor for a `refs` relation (issue #197). Present
|
|
6859
|
+
* IFF `type === 'refs'`; the traversal reads the parent list `refs.from`, pulls
|
|
6860
|
+
* `refs.key` off each element, and resolves the referenced child bodies in one
|
|
6861
|
+
* deduped BatchGet. Absent for every scalar-keyed relation (byte-compatible).
|
|
6862
|
+
*/
|
|
6863
|
+
refs?: RefsBinding;
|
|
6739
6864
|
options?: RelationOptions;
|
|
6740
6865
|
}
|
|
6741
6866
|
/**
|
|
@@ -6879,4 +7004,72 @@ interface EntityMetadata {
|
|
|
6879
7004
|
ttlAttribute?: string;
|
|
6880
7005
|
}
|
|
6881
7006
|
|
|
6882
|
-
|
|
7007
|
+
/**
|
|
7008
|
+
* Decorator-metadata → maintenance-graph `ViewDefinition` adapter (issue #152).
|
|
7009
|
+
*
|
|
7010
|
+
* ## What this replaces
|
|
7011
|
+
*
|
|
7012
|
+
* The old `defineView` / `defineVersioned` builders (deleted) registered
|
|
7013
|
+
* `ViewDefinition`s into a side `ViewRegistry`, which the maintenance graph read.
|
|
7014
|
+
* That builder carried a registration side-effect + a `generation` counter (a
|
|
7015
|
+
* silent-drop guard). This adapter removes that whole path: it derives the SAME
|
|
7016
|
+
* `ViewDefinition` IR purely from the declarative `MetadataRegistry` — the
|
|
7017
|
+
* Contract-layer SSoT, whose own `generation` counter is the single
|
|
7018
|
+
* invalidation source — so a view declared via `@model({ kind })` + `@maintainedFrom`
|
|
7019
|
+
* (and a versioned relation declared via `@hasOne/@hasMany` `pattern`) is discovered
|
|
7020
|
+
* with no separate registry.
|
|
7021
|
+
*
|
|
7022
|
+
* ## IR invariance
|
|
7023
|
+
*
|
|
7024
|
+
* The `ViewDefinition` / `ViewSourceSlice` shapes are UNCHANGED. The maintenance
|
|
7025
|
+
* graph, the K (#130) stream/drain, and the L (#131) rebuild consume the adapter's
|
|
7026
|
+
* output exactly as they consumed `ViewRegistry.getAll()`. Only the SOURCE of the
|
|
7027
|
+
* definitions moved from a builder side-effect to declarative metadata.
|
|
7028
|
+
*
|
|
7029
|
+
* ## Order independence (issue #152 hardening)
|
|
7030
|
+
*
|
|
7031
|
+
* Stacked `@maintainedFrom` declarations carry no order meaning. The adapter rejects
|
|
7032
|
+
* — symmetrically, so the error is identical whichever order the decorators are
|
|
7033
|
+
* stacked — any two declarations on the same view that:
|
|
7034
|
+
* 1. write the SAME projection target attribute (ambiguous duplicate projection);
|
|
7035
|
+
* 2. maintain the SAME `collection.field`;
|
|
7036
|
+
* 3. bind the SAME view-key field to a DIFFERENT source path (the view-row identity
|
|
7037
|
+
* would be inconsistent across sources).
|
|
7038
|
+
* A legitimate multi-source view (different sources filling DIFFERENT fields, all
|
|
7039
|
+
* binding the SAME key the SAME way) is fine.
|
|
7040
|
+
*/
|
|
7041
|
+
|
|
7042
|
+
type AnyModelClass = abstract new (...args: any[]) => any;
|
|
7043
|
+
/** The view source slice IR the maintenance graph consumes (one per source × view). */
|
|
7044
|
+
interface ViewSourceSlice {
|
|
7045
|
+
readonly sourceClass: AnyModelClass;
|
|
7046
|
+
readonly maintainedOn: readonly MaintainTrigger[];
|
|
7047
|
+
readonly keys: Readonly<Record<string, EffectPath>>;
|
|
7048
|
+
readonly project: ProjectionMap;
|
|
7049
|
+
readonly collection?: {
|
|
7050
|
+
readonly field: string;
|
|
7051
|
+
readonly maxItems?: number;
|
|
7052
|
+
readonly orderBy?: EffectPath;
|
|
7053
|
+
readonly orderDir?: 'ASC' | 'DESC';
|
|
7054
|
+
};
|
|
7055
|
+
readonly predicate?: MembershipPredicate;
|
|
7056
|
+
}
|
|
7057
|
+
/** The view definition IR — an independent view row maintained from one or more sources. */
|
|
7058
|
+
interface ViewDefinition {
|
|
7059
|
+
readonly name: string;
|
|
7060
|
+
readonly viewClass: AnyModelClass;
|
|
7061
|
+
readonly pattern: 'materializedView' | 'sparseView';
|
|
7062
|
+
readonly slices: readonly ViewSourceSlice[];
|
|
7063
|
+
readonly updateMode?: 'mutation' | 'stream';
|
|
7064
|
+
readonly consistency?: 'transactional' | 'eventual';
|
|
7065
|
+
}
|
|
7066
|
+
/**
|
|
7067
|
+
* Build every {@link ViewDefinition} for a registry — from `@model({ kind })` +
|
|
7068
|
+
* `@maintainedFrom` view models AND from versioned-pattern relations. This is the
|
|
7069
|
+
* adapter the maintenance graph calls in place of the deleted `ViewRegistry.getAll()`.
|
|
7070
|
+
*
|
|
7071
|
+
* @param registry The models to scan. Defaults to `MetadataRegistry.getAll()`.
|
|
7072
|
+
*/
|
|
7073
|
+
declare function collectViewDefinitions(registry?: ReadonlyMap<Function, EntityMetadata>): ViewDefinition[];
|
|
7074
|
+
|
|
7075
|
+
export { type BridgeBundle as $, type Param as A, type BatchResult as B, type CdcEmulatorOptions as C, type DynamoDBOperation as D, type EventLog as E, type FaultSpec as F, type QueryMethodSpec as G, type CommandModelContract as H, type CommandMethodSpec as I, type ContractSpec as J, type QuerySpec as K, type CommandSpec as L, type ModelStatic as M, type TransactionSpec as N, type ContextSpec as O, type PutInput as P, type QueryModelContract as Q, type ReplayOptions as R, type ShardId as S, type TransactWriteExecItem as T, type Unsubscribe as U, type ViewDefinition as V, type WriteExecOptions as W, type DefinitionMap as X, type OperationsDocument as Y, type AnyOperationDefinition as Z, type Manifest as _, type CdcMode as a, type DynamoType as a$, type ConditionSpec as a0, type CommandContractMethodSpec as a1, type CommandResolutionTarget as a2, type CompiledFragment as a3, type CompiledMutationPlan as a4, type ComposeSpec as a5, type CompositionPlanSpec as a6, type ContractCardinality as a7, type ContractCommandResult as a8, type ContractInputArity as a9, type ReadOperationType as aA, SPEC_VERSION as aB, type TransactionItemSpec as aC, type TransactionItemType as aD, type WhenSpec as aE, type WriteOperationType as aF, assertNoCrossFragmentMaintainCollision as aG, compileFragment as aH, compileMutationPlan as aI, compileSingleFragmentPlan as aJ, resetMaintenanceGraphCache as aK, resolveLifecycle as aL, resolveMaintainers as aM, type SelectableOf as aN, type PrimaryKeyOf as aO, type RequestContext as aP, type Middleware as aQ, type ReadRequestKind as aR, type CtxModel as aS, type ReadParams as aT, type ReadRequestCtx as aU, type Item as aV, type RetryPolicy as aW, type KeyDefinition as aX, type GsiDefinition as aY, type ModelKind as aZ, type FieldOptions as a_, type ContractKeySpec as aa, type ContractKind as ab, type ContractResolution as ac, type DerivedConditionCheck as ad, type DerivedEdgeWrite as ae, type DerivedIdempotencyGuard as af, type DerivedMaintainOutbox as ag, type DerivedMaintainWrite as ah, type DerivedOutboxEvent as ai, type DerivedUniqueGuard as aj, type DerivedUpdate as ak, type EntityRefResolver as al, type ExecutionPlanSpec as am, type FilterSpec as an, MAX_TRANSACT_COMPOSE_ITEMS as ao, type ManifestEntity as ap, type ManifestField as aq, type ManifestFieldType as ar, type ManifestGsi as as, type ManifestKey as at, type ManifestRelation as au, type ManifestTable as av, type OperationSpec as aw, type ParamSpec as ax, type QueryContractMethodSpec as ay, type RangeConditionSpec as az, type ChangeBatch as b, type DeleteOptions as b$, type ProjectionTransform as b0, type MaintainEvent as b1, type MembershipPredicate as b2, type MaintainConsistency as b3, type MaintainUpdateMode as b4, type MembershipPredicateOp as b5, type RelationOptions as b6, type AggregateOptions as b7, type AggregateValue as b8, type SelectBuilderSpec as b9, type CollectionOptions as bA, type Column as bB, type ColumnMap as bC, type CommandInputShape as bD, type CommandMethod as bE, type CommandPlan as bF, type CommandResultKind as bG, type CommandSelectShape as bH, type CondSlot as bI, type ConditionCheckInput as bJ, type Connection as bK, type ContractCallSignature as bL, type ContractCommandParams as bM, type ContractComposeNode as bN, type ContractFromRef as bO, type ContractItem as bP, type ContractKeyFieldRef as bQ, type ContractKeyInput as bR, type ContractKeyRef as bS, type ContractMethodOp as bT, type ContractParamRef as bU, type ContractQueryParams as bV, type CounterAggregate as bW, type CounterEffect as bX, type CtxBase as bY, DEFAULT_MAX_ATTEMPTS as bZ, DEFAULT_RETRY_POLICY as b_, type RawCondition as ba, type RetryOverride as bb, type ExecutionPlan as bc, type FieldMetadata as bd, type ResolvedKey as be, type RelationMetadata as bf, type MaintainEffect as bg, type OperationDefinition as bh, type WriteDefinitionOptions as bi, type PartialQueryKeyOf as bj, type StrictSelectSpec as bk, type ReadDefinitionOptions as bl, type EntityInput as bm, type UniqueQueryKeyOf as bn, type AggregateMetadata as bo, type BatchDeleteRequest as bp, type BatchGetOptions as bq, type BatchGetRequest as br, BatchGetResult as bs, type BatchPutRequest as bt, type BatchWriteRequest as bu, CONTRACT_RANGE_FANOUT_CONCURRENCY as bv, type CdcModelRegistry as bw, type CdcSubscribeHandlers as bx, type Change as by, type CollectionEffect as bz, type ChangeEvent as c, type ReadRouteResult as c$, type DeriveEffect as c0, type DescriptorBinding as c1, ENTITY_WRITES_MARKER as c2, type EdgeEffect as c3, type EffectPath as c4, type EmbeddedMetadata as c5, type EmitEffect as c6, type EntityWritesDefinition as c7, type EntityWritesShape as c8, type ExecutableCommandContract as c9, type MutateTransactionResult as cA, type MutationBody as cB, type MutationDescriptorMap as cC, type MutationFragment as cD, type MutationInputProxy as cE, type MutationInputRef as cF, type MutationIntent as cG, type NumberParam as cH, type OperationKind as cI, type ParallelOpResult as cJ, type ParamKind as cK, type ParamStructure as cL, type PersistCtx as cM, type PersistOrigin as cN, type PlannedCommandMethod as cO, type ProjectionMap as cP, type ProjectionTransformOp as cQ, type PutOptions as cR, type QueryEnvelopeResult as cS, type QueryKeyOf as cT, type QueryMethod as cU, type QueryResult as cV, type ReadEnvelope as cW, type ReadOpCtx as cX, type ReadOpKind as cY, type ReadRouteDescriptor as cZ, type ReadRouteOptions as c_, type ExecutableQueryContract as ca, type FilterInput as cb, type FragmentInput as cc, type GsiDefinitionMarker as cd, type GsiOptions as ce, type IdempotencyEffect as cf, type InProcessWriteDescriptor as cg, type InlineSnapshotSpec as ch, type InputArity as ci, type KeyDefinitionMarker as cj, type KeySegment as ck, type KeySlot as cl, type KeyStructure as cm, type KeyedResult as cn, LIFECYCLE_CONTRACT_MARKER as co, type LifecycleContract as cp, type LifecycleEffects as cq, type LiteralParam as cr, type MaintainItem as cs, type MaintainTrigger as ct, type MaintenanceGraph as cu, type MembershipEffect as cv, type ModelRef as cw, type MutateMode as cx, type MutateOptions as cy, type MutateParallelResult as cz, type ChangeEventName as d, isContractComposeNode as d$, type RecordedCompose as d0, type RelationBuilder as d1, type RelationConsistency as d2, type RelationLimitOptions as d3, type RelationPattern as d4, type RelationProjection as d5, type RelationReadOptions as d6, type RelationSelect as d7, type RelationSpec as d8, type RelationUpdateMode as d9, attachModelClass as dA, buildDeleteInput as dB, buildMaintenanceGraph as dC, buildPutInput as dD, buildUpdateInput as dE, collectViewDefinitions as dF, cond as dG, contractOfMethodSpec as dH, definePlan as dI, entityWrites as dJ, executeBatchGet as dK, executeBatchWrite as dL, executeCommandMethod as dM, executeDelete as dN, executeKeyedBatchGet as dO, executePut as dP, executeQueryMethod as dQ, executeRangeFanout as dR, executeTransaction as dS, executeUpdate as dT, from as dU, getEntityWrites as dV, gsi as dW, identity as dX, isColumn as dY, isCommandModelContract as dZ, isCommandPlan as d_, type RelationWriteOptions as da, type RequiresEffect as db, type Resolution as dc, type RetryInfo as dd, type RetryOperationKind as de, type SegmentSpec as df, type SegmentedKey as dg, type SelectBuilder as dh, type SelectOf as di, type SnapshotEffect as dj, type StringParam as dk, TransactionContext as dl, type UniqueEffect as dm, type Updatable as dn, type UpdateOptions as dp, type ViewSourceSlice as dq, type WriteCtx as dr, type WriteDescriptor as ds, type WriteEnvelope as dt, type WriteInput as du, type WriteKind as dv, type WriteLifecyclePhase as dw, type WriteMiddleware as dx, type WriteRecorder as dy, type WriteResultProjection as dz, type ChangeHandler as e, isContractFromRef as e0, isContractKeyFieldRef as e1, isContractKeyRef as e2, isContractParamRef as e3, isEntityWritesDefinition as e4, isKeySegment as e5, isLifecycleContract as e6, isMaintainTrigger as e7, isMutationFragment as e8, isMutationInputRef as e9, isParam as ea, isPlannedCommandMethod as eb, isQueryModelContract as ec, isRetryableError as ed, isRetryableTransactionCancellation as ee, k as ef, key as eg, lifecyclePhaseForIntent as eh, maintainTrigger as ei, mintContractKeyFieldRef as ej, mintContractParamRef as ek, mutation as el, param as em, preview as en, publicCommandModel as eo, publicQueryModel as ep, query as eq, wholeKeysSentinel as er, type ClockMode as f, type ConcurrentRecomputeRef as g, type StartingPosition as h, type StreamViewType as i, type SubscribeHandler as j, type SubscribeHandlers as k, buildSubscribeHandler as l, type EntityMetadata as m, type Executor as n, type ReadExecOptions as o, type ExecutorResult as p, type BatchGetExecInput as q, type WriteResult as r, type UpdateInput as s, type DeleteInput as t, type BatchWriteExecItem as u, type BatchExecOptions as v, DDBModel as w, type ParamDescriptor as x, type EntityRef as y, type ConditionInput as z };
|