graphddb 0.5.1 → 0.5.3
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 +10 -0
- package/dist/cdc/index.d.ts +37 -0
- package/dist/cdc/index.js +29 -0
- package/dist/{chunk-B3GWIWT6.js → chunk-CCIVET5K.js} +74 -1026
- package/dist/{chunk-EMJHTUA4.js → chunk-M6URQOAW.js} +4 -1
- package/dist/chunk-MMVHOUM4.js +24 -0
- package/dist/chunk-PDUVTYC5.js +992 -0
- package/dist/{chunk-FI63YKK5.js → chunk-Y7XV5QL2.js} +3564 -3549
- package/dist/cli.js +1174 -21
- package/dist/from-change-DQK2Jm9R.d.ts +327 -0
- package/dist/index-CtDBo8Se.d.ts +690 -0
- package/dist/index.d.ts +18 -1113
- package/dist/index.js +33 -41
- package/dist/linter/index.d.ts +126 -0
- package/dist/linter/index.js +36 -0
- package/dist/{types-B9rJ1z3H.d.ts → maintenance-view-adapter-D5t9taTE.d.ts} +304 -182
- package/dist/registry-BD_5Rm5C.d.ts +76 -0
- package/dist/relation-depth-DLkhG0xX.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 -3
- package/docs/doc-sample.md +263 -0
- package/docs/docs-generation.md +183 -0
- package/package.json +49 -3
|
@@ -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
|
*
|
|
@@ -724,11 +837,26 @@ interface GsiDefinitionMarker<T extends Record<string, unknown> = Record<string,
|
|
|
724
837
|
readonly segmented: SegmentedKey;
|
|
725
838
|
readonly inputFieldNames: string[];
|
|
726
839
|
readonly unique: U;
|
|
840
|
+
/**
|
|
841
|
+
* Optional human-readable description of the GSI (issue #166, follow-up of #154),
|
|
842
|
+
* from `gsi(name, key, { description })`. Pure documentation — the registry copies
|
|
843
|
+
* it onto {@link GsiDefinition} (→ `manifest.json` + generated Python). Absent
|
|
844
|
+
* unless declared.
|
|
845
|
+
*/
|
|
846
|
+
readonly description?: string;
|
|
727
847
|
/** @internal Phantom field for type-level input type extraction. */
|
|
728
848
|
readonly _phantom?: T;
|
|
729
849
|
}
|
|
730
850
|
interface GsiOptions {
|
|
731
851
|
unique?: boolean;
|
|
852
|
+
/**
|
|
853
|
+
* Optional human-readable description of the index (issue #166, follow-up of #154).
|
|
854
|
+
* Pure documentation metadata — it does NOT affect the index key, projection, or any
|
|
855
|
+
* runtime behaviour. Propagated to `manifest.json` ({@link ManifestGsi.description})
|
|
856
|
+
* and surfaces as the docstring of a generated Python query method that reads through
|
|
857
|
+
* this index. Omit for byte-identical output.
|
|
858
|
+
*/
|
|
859
|
+
description?: string;
|
|
732
860
|
}
|
|
733
861
|
type GsiBuilder<T extends Record<string, unknown>> = (c: {
|
|
734
862
|
readonly [K in keyof T]-?: Column<T[K], T>;
|
|
@@ -2817,74 +2945,6 @@ declare function mutation(name: string, body: MutationBody): CommandPlan;
|
|
|
2817
2945
|
*/
|
|
2818
2946
|
declare const definePlan: typeof mutation;
|
|
2819
2947
|
|
|
2820
|
-
/**
|
|
2821
|
-
* Decorator-metadata → maintenance-graph `ViewDefinition` adapter (issue #152).
|
|
2822
|
-
*
|
|
2823
|
-
* ## What this replaces
|
|
2824
|
-
*
|
|
2825
|
-
* The old `defineView` / `defineVersioned` builders (deleted) registered
|
|
2826
|
-
* `ViewDefinition`s into a side `ViewRegistry`, which the maintenance graph read.
|
|
2827
|
-
* That builder carried a registration side-effect + a `generation` counter (a
|
|
2828
|
-
* silent-drop guard). This adapter removes that whole path: it derives the SAME
|
|
2829
|
-
* `ViewDefinition` IR purely from the declarative `MetadataRegistry` — the
|
|
2830
|
-
* Contract-layer SSoT, whose own `generation` counter is the single
|
|
2831
|
-
* invalidation source — so a view declared via `@model({ kind })` + `@maintainedFrom`
|
|
2832
|
-
* (and a versioned relation declared via `@hasOne/@hasMany` `pattern`) is discovered
|
|
2833
|
-
* with no separate registry.
|
|
2834
|
-
*
|
|
2835
|
-
* ## IR invariance
|
|
2836
|
-
*
|
|
2837
|
-
* The `ViewDefinition` / `ViewSourceSlice` shapes are UNCHANGED. The maintenance
|
|
2838
|
-
* graph, the K (#130) stream/drain, and the L (#131) rebuild consume the adapter's
|
|
2839
|
-
* output exactly as they consumed `ViewRegistry.getAll()`. Only the SOURCE of the
|
|
2840
|
-
* definitions moved from a builder side-effect to declarative metadata.
|
|
2841
|
-
*
|
|
2842
|
-
* ## Order independence (issue #152 hardening)
|
|
2843
|
-
*
|
|
2844
|
-
* Stacked `@maintainedFrom` declarations carry no order meaning. The adapter rejects
|
|
2845
|
-
* — symmetrically, so the error is identical whichever order the decorators are
|
|
2846
|
-
* stacked — any two declarations on the same view that:
|
|
2847
|
-
* 1. write the SAME projection target attribute (ambiguous duplicate projection);
|
|
2848
|
-
* 2. maintain the SAME `collection.field`;
|
|
2849
|
-
* 3. bind the SAME view-key field to a DIFFERENT source path (the view-row identity
|
|
2850
|
-
* would be inconsistent across sources).
|
|
2851
|
-
* A legitimate multi-source view (different sources filling DIFFERENT fields, all
|
|
2852
|
-
* binding the SAME key the SAME way) is fine.
|
|
2853
|
-
*/
|
|
2854
|
-
|
|
2855
|
-
type AnyModelClass = abstract new (...args: any[]) => any;
|
|
2856
|
-
/** The view source slice IR the maintenance graph consumes (one per source × view). */
|
|
2857
|
-
interface ViewSourceSlice {
|
|
2858
|
-
readonly sourceClass: AnyModelClass;
|
|
2859
|
-
readonly maintainedOn: readonly MaintainTrigger[];
|
|
2860
|
-
readonly keys: Readonly<Record<string, EffectPath>>;
|
|
2861
|
-
readonly project: ProjectionMap;
|
|
2862
|
-
readonly collection?: {
|
|
2863
|
-
readonly field: string;
|
|
2864
|
-
readonly maxItems?: number;
|
|
2865
|
-
readonly orderBy?: EffectPath;
|
|
2866
|
-
readonly orderDir?: 'ASC' | 'DESC';
|
|
2867
|
-
};
|
|
2868
|
-
readonly predicate?: MembershipPredicate;
|
|
2869
|
-
}
|
|
2870
|
-
/** The view definition IR — an independent view row maintained from one or more sources. */
|
|
2871
|
-
interface ViewDefinition {
|
|
2872
|
-
readonly name: string;
|
|
2873
|
-
readonly viewClass: AnyModelClass;
|
|
2874
|
-
readonly pattern: 'materializedView' | 'sparseView';
|
|
2875
|
-
readonly slices: readonly ViewSourceSlice[];
|
|
2876
|
-
readonly updateMode?: 'mutation' | 'stream';
|
|
2877
|
-
readonly consistency?: 'transactional' | 'eventual';
|
|
2878
|
-
}
|
|
2879
|
-
/**
|
|
2880
|
-
* Build every {@link ViewDefinition} for a registry — from `@model({ kind })` +
|
|
2881
|
-
* `@maintainedFrom` view models AND from versioned-pattern relations. This is the
|
|
2882
|
-
* adapter the maintenance graph calls in place of the deleted `ViewRegistry.getAll()`.
|
|
2883
|
-
*
|
|
2884
|
-
* @param registry The models to scan. Defaults to `MetadataRegistry.getAll()`.
|
|
2885
|
-
*/
|
|
2886
|
-
declare function collectViewDefinitions(registry?: ReadonlyMap<Function, EntityMetadata>): ViewDefinition[];
|
|
2887
|
-
|
|
2888
2948
|
/**
|
|
2889
2949
|
* Maintenance graph builder (Epic #118 issue #124 — the RFC B-案 core).
|
|
2890
2950
|
*
|
|
@@ -3099,6 +3159,14 @@ interface ManifestKey {
|
|
|
3099
3159
|
interface ManifestGsi extends ManifestKey {
|
|
3100
3160
|
readonly indexName: string;
|
|
3101
3161
|
readonly unique: boolean;
|
|
3162
|
+
/**
|
|
3163
|
+
* Optional human-readable description of the index (issue #166, follow-up of #154),
|
|
3164
|
+
* from `gsi(name, key, { description })`. Pure documentation — absent unless declared,
|
|
3165
|
+
* so a GSI with no description serializes byte-identically to the pre-#166 manifest.
|
|
3166
|
+
* The Python codegen surfaces it as the docstring of a generated query method that
|
|
3167
|
+
* reads through this index.
|
|
3168
|
+
*/
|
|
3169
|
+
readonly description?: string;
|
|
3102
3170
|
}
|
|
3103
3171
|
interface ManifestRelation {
|
|
3104
3172
|
readonly type: 'hasMany' | 'hasOne' | 'belongsTo';
|
|
@@ -3106,6 +3174,14 @@ interface ManifestRelation {
|
|
|
3106
3174
|
readonly target: string;
|
|
3107
3175
|
/** target field → source field (on this entity). */
|
|
3108
3176
|
readonly keyBinding: Readonly<Record<string, string>>;
|
|
3177
|
+
/**
|
|
3178
|
+
* Optional human-readable description of the relation (issue #166, follow-up of
|
|
3179
|
+
* #154), from `@hasMany/@belongsTo/@hasOne(..., { description })`. Pure documentation
|
|
3180
|
+
* — absent unless declared, so a relation with no description serializes
|
|
3181
|
+
* byte-identically to the pre-#166 manifest. The Python codegen surfaces it as a
|
|
3182
|
+
* trailing `# …` comment on the relation's field in the generated result type.
|
|
3183
|
+
*/
|
|
3184
|
+
readonly description?: string;
|
|
3109
3185
|
}
|
|
3110
3186
|
interface ManifestEntity {
|
|
3111
3187
|
/** Declared (logical) table name. */
|
|
@@ -4069,6 +4145,56 @@ interface DerivedMaintainWrite {
|
|
|
4069
4145
|
readonly value?: unknown;
|
|
4070
4146
|
};
|
|
4071
4147
|
}
|
|
4148
|
+
/**
|
|
4149
|
+
* Drop the cached global {@link MaintenanceGraph} (built lazily by
|
|
4150
|
+
* {@link resolveMaintainers}). Invalidation is now automatic — the cache is keyed
|
|
4151
|
+
* by {@link MetadataRegistry.generation}, so a model registered after a build is
|
|
4152
|
+
* already picked up without calling this. Retained as an explicit escape hatch (and
|
|
4153
|
+
* for source-compatibility); forcing a rebuild is never required for correctness.
|
|
4154
|
+
*/
|
|
4155
|
+
declare function resetMaintenanceGraphCache(): void;
|
|
4156
|
+
/**
|
|
4157
|
+
* Resolve the maintenance {@link MaintainItem effects} a fragment's lifecycle event
|
|
4158
|
+
* fires (issue #125 — the compile-side consumer of D/#124's {@link MaintenanceGraph}).
|
|
4159
|
+
* The fragment's source entity is its written model (its LOGICAL name — #118
|
|
4160
|
+
* contract), and the trigger is `<logicalName>.<event>` where `event` is the
|
|
4161
|
+
* past-tense of the fragment intent ({@link INTENT_MAINTAIN_EVENT}). Returns every
|
|
4162
|
+
* `MaintainItem` the graph indexes under that trigger (`graph.effectsFor(...)`),
|
|
4163
|
+
* empty when nothing maintains on it (the no-regression path — a fragment that fires
|
|
4164
|
+
* no maintainer compiles exactly as before).
|
|
4165
|
+
*
|
|
4166
|
+
* @param fragment The fragment whose lifecycle event is the maintenance trigger.
|
|
4167
|
+
* @param graph The maintenance graph to query. Defaults to a lazily-built,
|
|
4168
|
+
* cached graph over the global registry ({@link MetadataRegistry.getAll}); an
|
|
4169
|
+
* explicit graph is accepted for scoped tests.
|
|
4170
|
+
*/
|
|
4171
|
+
declare function resolveMaintainers(fragment: MutationFragment, graph?: MaintenanceGraph): readonly MaintainItem[];
|
|
4172
|
+
/**
|
|
4173
|
+
* Cross-fragment guard (issue #127 audit 是正1): reject — LOUDLY, with the true cause
|
|
4174
|
+
* named — a set of aggregated maintenance writes (collected across ALL of a multi-
|
|
4175
|
+
* fragment mutation's fragments by {@link buildPlannedCommandMethod}'s flatMap) in
|
|
4176
|
+
* which **two or more** writes resolve to the SAME destination (owner) row.
|
|
4177
|
+
*
|
|
4178
|
+
* ## Why this layer exists
|
|
4179
|
+
*
|
|
4180
|
+
* 論点2 = b ("1 mutation × 1 target row = 1 maintain effect") must hold for the WHOLE
|
|
4181
|
+
* mutation, not just within one fragment. {@link deriveMaintainItems} enforces it
|
|
4182
|
+
* INTRA-fragment, but two *different* fragments can each fire a maintainer onto the
|
|
4183
|
+
* same owner row; the flatMap that aggregates them is a plain concat and would not
|
|
4184
|
+
* notice. Without this guard those two writes collapse together in the runtime's
|
|
4185
|
+
* same-physical-key layer and surface as a `mergeAddUpdates` "ADD delta is non-numeric"
|
|
4186
|
+
* throw — loud (atomicity is preserved) but MISLEADING: it reads as a derived-counter
|
|
4187
|
+
* merge failure and hides the real cause (two maintenance effects resolving to one
|
|
4188
|
+
* owner row). This guard fires FIRST, with a message that names the true cause.
|
|
4189
|
+
*
|
|
4190
|
+
* The identity rule is {@link maintainWriteRowKey} — the same owner-row identity the
|
|
4191
|
+
* intra-fragment reject uses (`destinationRowKey`), so both layers agree on what "the
|
|
4192
|
+
* same row" means. Merging two maintenance writes into one row is a future issue (the
|
|
4193
|
+
* #96 same-physical-key "may not touch one key twice" philosophy); this layer rejects.
|
|
4194
|
+
*
|
|
4195
|
+
* @throws if two aggregated maintenance writes resolve to the same owner row.
|
|
4196
|
+
*/
|
|
4197
|
+
declare function assertNoCrossFragmentMaintainCollision(methodName: string, writes: readonly DerivedMaintainWrite[]): void;
|
|
4072
4198
|
/**
|
|
4073
4199
|
* A **derived uniqueness guard** — the marker-row `Put` (and, on a unique-field
|
|
4074
4200
|
* change, the old-guard `Delete` + new-guard `Put` swap) that enforces an
|
|
@@ -4386,6 +4512,8 @@ declare function compileFragment(fragment: MutationFragment, index?: number, res
|
|
|
4386
4512
|
* @throws if `plan` is not a {@link CommandPlan}, or declares more than one fragment.
|
|
4387
4513
|
*/
|
|
4388
4514
|
declare function compileSingleFragmentPlan(plan: CommandPlan): CompiledFragment;
|
|
4515
|
+
/** The DynamoDB `TransactWriteItems` item cap — an atomic tx is never split (#64). */
|
|
4516
|
+
declare const MAX_TRANSACT_COMPOSE_ITEMS = 25;
|
|
4389
4517
|
/**
|
|
4390
4518
|
* The result of compiling a (1..N)-fragment {@link CommandPlan} (#90): the ordered
|
|
4391
4519
|
* per-fragment {@link CompiledFragment}s, merged so they form **one atomic
|
|
@@ -5992,119 +6120,6 @@ type MutateParallelResult<E extends WriteEnvelope> = {
|
|
|
5992
6120
|
readonly [K in keyof E]: BulkWrap<E[K], ParallelResultOf<E[K]>>;
|
|
5993
6121
|
};
|
|
5994
6122
|
|
|
5995
|
-
/**
|
|
5996
|
-
* CDC emulator types (issue #72). These types are **cdc-module-owned**; core
|
|
5997
|
-
* never references them. The {@link ChangeEvent} shape mirrors DynamoDB Streams
|
|
5998
|
-
* (`NEW_AND_OLD_IMAGES`) so a consumer written against the emulator runs
|
|
5999
|
-
* unchanged against real Streams in production (spec §4).
|
|
6000
|
-
*/
|
|
6001
|
-
/** Stream view type. Fixed to `NEW_AND_OLD_IMAGES` — incremental aggregation
|
|
6002
|
-
* needs both images (spec §4). */
|
|
6003
|
-
type StreamViewType = 'NEW_AND_OLD_IMAGES';
|
|
6004
|
-
/** Stream event kind, matching DynamoDB Streams. */
|
|
6005
|
-
type ChangeEventName = 'INSERT' | 'MODIFY' | 'REMOVE';
|
|
6006
|
-
/**
|
|
6007
|
-
* A single change event. Within one shard, `sequenceNumber` is monotonically
|
|
6008
|
-
* increasing; across shards order is independent (spec §6).
|
|
6009
|
-
*/
|
|
6010
|
-
interface ChangeEvent<T = Record<string, unknown>> {
|
|
6011
|
-
eventName: ChangeEventName;
|
|
6012
|
-
table: string;
|
|
6013
|
-
/** Resolved model name when known. */
|
|
6014
|
-
model?: string;
|
|
6015
|
-
keys: {
|
|
6016
|
-
pk: string;
|
|
6017
|
-
sk: string;
|
|
6018
|
-
};
|
|
6019
|
-
/** Present for MODIFY / REMOVE. */
|
|
6020
|
-
oldImage?: T;
|
|
6021
|
-
/** Present for INSERT / MODIFY. */
|
|
6022
|
-
newImage?: T;
|
|
6023
|
-
/** Deterministic-clock-derived creation time (ISO 8601). */
|
|
6024
|
-
approximateCreationTime: string;
|
|
6025
|
-
/** Monotonic within a shard (zero-padded for lexicographic ordering). */
|
|
6026
|
-
sequenceNumber: string;
|
|
6027
|
-
/** Partition = hash(pk). */
|
|
6028
|
-
shardId: string;
|
|
6029
|
-
}
|
|
6030
|
-
/** A delivered batch. Records of the same shard are in `sequenceNumber` order. */
|
|
6031
|
-
interface ChangeBatch<T = Record<string, unknown>> {
|
|
6032
|
-
records: ChangeEvent<T>[];
|
|
6033
|
-
}
|
|
6034
|
-
/**
|
|
6035
|
-
* The consumer's response to a batch (spec §6, `ReportBatchItemFailures`
|
|
6036
|
-
* equivalent). Returning the `sequenceNumber`s of records that failed lets the
|
|
6037
|
-
* emulator advance the checkpoint past the successful prefix and redeliver only
|
|
6038
|
-
* the failures.
|
|
6039
|
-
*/
|
|
6040
|
-
interface BatchResult {
|
|
6041
|
-
/** `sequenceNumber`s of records the consumer failed to process. */
|
|
6042
|
-
batchItemFailures?: string[];
|
|
6043
|
-
}
|
|
6044
|
-
/** The consumer handler. */
|
|
6045
|
-
type ChangeHandler = (batch: ChangeBatch) => Promise<BatchResult | void>;
|
|
6046
|
-
/** Unsubscribe handle. */
|
|
6047
|
-
type Unsubscribe = () => void;
|
|
6048
|
-
/** Where a fresh subscriber begins reading. */
|
|
6049
|
-
type StartingPosition = 'TRIM_HORIZON' | 'LATEST';
|
|
6050
|
-
/** Clock mode. `virtual` makes time deterministic via `advanceClock`. */
|
|
6051
|
-
type ClockMode = 'real' | 'virtual';
|
|
6052
|
-
/** Delivery mode (spec §7). */
|
|
6053
|
-
type CdcMode = 'inline' | 'queued' | 'record' | 'replay';
|
|
6054
|
-
/** Deterministic fault-injection spec (spec §8). All probabilities are seeded. */
|
|
6055
|
-
interface FaultSpec {
|
|
6056
|
-
/** Probability [0,1] a delivered record is also re-delivered (duplicate). */
|
|
6057
|
-
duplicate?: number;
|
|
6058
|
-
/** Shuffle within-shard order on delivery (invariant-violation testing). */
|
|
6059
|
-
reorder?: boolean;
|
|
6060
|
-
/** Per-record virtual-time delivery delay range (ms). Requires queued mode. */
|
|
6061
|
-
delay?: {
|
|
6062
|
-
min: number;
|
|
6063
|
-
max: number;
|
|
6064
|
-
};
|
|
6065
|
-
/** Probability [0,1] a record is dropped on first delivery then redelivered. */
|
|
6066
|
-
dropThenRedeliver?: number;
|
|
6067
|
-
/** Probability [0,1] a record is reported as a partial-batch failure. */
|
|
6068
|
-
partialBatchFailure?: number;
|
|
6069
|
-
}
|
|
6070
|
-
/** A reference whose recompute should be forced to race a mark (spec §8, §7). */
|
|
6071
|
-
interface ConcurrentRecomputeRef {
|
|
6072
|
-
/** Opaque node ref the harness recomputes concurrently with marking. */
|
|
6073
|
-
ref: string;
|
|
6074
|
-
}
|
|
6075
|
-
/** A persisted event log (spec §10, record/replay). */
|
|
6076
|
-
interface EventLog {
|
|
6077
|
-
seed: number;
|
|
6078
|
-
events: ChangeEvent[];
|
|
6079
|
-
}
|
|
6080
|
-
/** Replay options (spec §10). */
|
|
6081
|
-
interface ReplayOptions {
|
|
6082
|
-
/** Deliver events in a deterministic shuffled order (any-order replay). */
|
|
6083
|
-
shuffle?: boolean;
|
|
6084
|
-
/** Probability [0,1] each event is delivered twice during replay. */
|
|
6085
|
-
duplicate?: number;
|
|
6086
|
-
}
|
|
6087
|
-
/** Constructor options (spec §11). */
|
|
6088
|
-
interface CdcEmulatorOptions {
|
|
6089
|
-
/** Stream-enabled model classes (opt-in; default none). */
|
|
6090
|
-
models?: Function[];
|
|
6091
|
-
/** Delivery mode. Default `inline`. */
|
|
6092
|
-
mode?: CdcMode;
|
|
6093
|
-
/** Clock mode. Default `virtual` for queued, `real` otherwise. */
|
|
6094
|
-
clock?: ClockMode;
|
|
6095
|
-
/** Records per delivered batch. Default 100. */
|
|
6096
|
-
batchSize?: number;
|
|
6097
|
-
/** Max redelivery attempts before a record goes to the DLQ. Default 3. */
|
|
6098
|
-
maxRetries?: number;
|
|
6099
|
-
/** Where a subscriber starts. Default `TRIM_HORIZON`. */
|
|
6100
|
-
startingPosition?: StartingPosition;
|
|
6101
|
-
/** Seed for fault injection / shard assignment determinism. Default 1. */
|
|
6102
|
-
seed?: number;
|
|
6103
|
-
/** Number of shards events are partitioned across. Default 8. */
|
|
6104
|
-
shardCount?: number;
|
|
6105
|
-
}
|
|
6106
|
-
type ShardId = string;
|
|
6107
|
-
|
|
6108
6123
|
/**
|
|
6109
6124
|
* `subscribe` — the declarative, batch CDC consumer builder (issue #153).
|
|
6110
6125
|
*
|
|
@@ -6525,6 +6540,24 @@ interface MaintainedFromMetadata {
|
|
|
6525
6540
|
when?: MembershipPredicate;
|
|
6526
6541
|
consistency?: MaintainConsistency;
|
|
6527
6542
|
updateMode?: MaintainUpdateMode;
|
|
6543
|
+
/**
|
|
6544
|
+
* Optional human-readable description of this maintained-from source slice (issue
|
|
6545
|
+
* #166, follow-up of #154), supplied via
|
|
6546
|
+
* `@maintainedFrom(() => Source, (self, source) => ({ description, ... }))`. Pure
|
|
6547
|
+
* documentation metadata — it does NOT affect the maintenance IR (`keyBind` /
|
|
6548
|
+
* `project` / `on` / `collection` / `when`) or any runtime behaviour.
|
|
6549
|
+
*
|
|
6550
|
+
* NOTE (representation): the maintenance IR is deliberately kept OFF the
|
|
6551
|
+
* serializable `manifest.json` / `operations.json` — the {@link Manifest} carries
|
|
6552
|
+
* only the physical shape (table / keys / GSIs / relation navigation), NOT the
|
|
6553
|
+
* maintenance graph (see `detectStreamMaintenance` in `src/codegen/cloudformation.ts`).
|
|
6554
|
+
* There is therefore no manifest / operations / generated-Python site for a
|
|
6555
|
+
* maintained-from source; this description is captured at the metadata layer only
|
|
6556
|
+
* (mirroring where #154 captured its descriptions before propagation), available to
|
|
6557
|
+
* any future consumer that DOES surface `@maintainedFrom` (e.g. the CDC-projection
|
|
6558
|
+
* typed-consumer path, #153). Absent → byte-for-byte unchanged metadata.
|
|
6559
|
+
*/
|
|
6560
|
+
description?: string;
|
|
6528
6561
|
}
|
|
6529
6562
|
interface KeyDefinition {
|
|
6530
6563
|
/** The canonical structured key (PK/SK segment lists). */
|
|
@@ -6537,6 +6570,17 @@ interface GsiDefinition {
|
|
|
6537
6570
|
segmented: SegmentedKey;
|
|
6538
6571
|
inputFieldNames: string[];
|
|
6539
6572
|
unique: boolean;
|
|
6573
|
+
/**
|
|
6574
|
+
* Optional human-readable description of the GSI (issue #166, follow-up of #154),
|
|
6575
|
+
* supplied via `gsi(name, key, { description })`. Pure documentation metadata — it
|
|
6576
|
+
* does NOT affect the index key, projection, or any runtime behaviour. When present
|
|
6577
|
+
* it is propagated to the index entry in `manifest.json`
|
|
6578
|
+
* ({@link ManifestGsi.description}) and surfaces as the docstring of any generated
|
|
6579
|
+
* Python query method that reads through this index (a query carrying the GSI's
|
|
6580
|
+
* `indexName`, when the query itself declares no description). Absent →
|
|
6581
|
+
* byte-for-byte unchanged output (backward compatible).
|
|
6582
|
+
*/
|
|
6583
|
+
description?: string;
|
|
6540
6584
|
}
|
|
6541
6585
|
interface RelationLimitOptions {
|
|
6542
6586
|
default: number;
|
|
@@ -6635,6 +6679,16 @@ type RelationProjection = Readonly<Record<string, ProjectionTransform | string>>
|
|
|
6635
6679
|
interface RelationOptions {
|
|
6636
6680
|
limit?: RelationLimitOptions;
|
|
6637
6681
|
order?: 'ASC' | 'DESC';
|
|
6682
|
+
/**
|
|
6683
|
+
* Optional human-readable description of the relation (issue #166, follow-up of
|
|
6684
|
+
* #154), supplied via `@hasMany/@belongsTo/@hasOne(() => T, keyBind, { description })`.
|
|
6685
|
+
* Pure documentation metadata — it does NOT affect navigation, key binding, or any
|
|
6686
|
+
* runtime behaviour. When present it is propagated to the relation entry in
|
|
6687
|
+
* `manifest.json` ({@link ManifestRelation.description}) and surfaces as a trailing
|
|
6688
|
+
* `# …` comment on the relation's field in the generated Python result TypedDict /
|
|
6689
|
+
* dataclass. Absent → byte-for-byte unchanged output (backward compatible).
|
|
6690
|
+
*/
|
|
6691
|
+
description?: string;
|
|
6638
6692
|
/**
|
|
6639
6693
|
* Named maintenance preset (Epic #118). Omitted = plain read-only navigation,
|
|
6640
6694
|
* fully backward compatible with the historical relation decorators.
|
|
@@ -6809,4 +6863,72 @@ interface EntityMetadata {
|
|
|
6809
6863
|
ttlAttribute?: string;
|
|
6810
6864
|
}
|
|
6811
6865
|
|
|
6812
|
-
|
|
6866
|
+
/**
|
|
6867
|
+
* Decorator-metadata → maintenance-graph `ViewDefinition` adapter (issue #152).
|
|
6868
|
+
*
|
|
6869
|
+
* ## What this replaces
|
|
6870
|
+
*
|
|
6871
|
+
* The old `defineView` / `defineVersioned` builders (deleted) registered
|
|
6872
|
+
* `ViewDefinition`s into a side `ViewRegistry`, which the maintenance graph read.
|
|
6873
|
+
* That builder carried a registration side-effect + a `generation` counter (a
|
|
6874
|
+
* silent-drop guard). This adapter removes that whole path: it derives the SAME
|
|
6875
|
+
* `ViewDefinition` IR purely from the declarative `MetadataRegistry` — the
|
|
6876
|
+
* Contract-layer SSoT, whose own `generation` counter is the single
|
|
6877
|
+
* invalidation source — so a view declared via `@model({ kind })` + `@maintainedFrom`
|
|
6878
|
+
* (and a versioned relation declared via `@hasOne/@hasMany` `pattern`) is discovered
|
|
6879
|
+
* with no separate registry.
|
|
6880
|
+
*
|
|
6881
|
+
* ## IR invariance
|
|
6882
|
+
*
|
|
6883
|
+
* The `ViewDefinition` / `ViewSourceSlice` shapes are UNCHANGED. The maintenance
|
|
6884
|
+
* graph, the K (#130) stream/drain, and the L (#131) rebuild consume the adapter's
|
|
6885
|
+
* output exactly as they consumed `ViewRegistry.getAll()`. Only the SOURCE of the
|
|
6886
|
+
* definitions moved from a builder side-effect to declarative metadata.
|
|
6887
|
+
*
|
|
6888
|
+
* ## Order independence (issue #152 hardening)
|
|
6889
|
+
*
|
|
6890
|
+
* Stacked `@maintainedFrom` declarations carry no order meaning. The adapter rejects
|
|
6891
|
+
* — symmetrically, so the error is identical whichever order the decorators are
|
|
6892
|
+
* stacked — any two declarations on the same view that:
|
|
6893
|
+
* 1. write the SAME projection target attribute (ambiguous duplicate projection);
|
|
6894
|
+
* 2. maintain the SAME `collection.field`;
|
|
6895
|
+
* 3. bind the SAME view-key field to a DIFFERENT source path (the view-row identity
|
|
6896
|
+
* would be inconsistent across sources).
|
|
6897
|
+
* A legitimate multi-source view (different sources filling DIFFERENT fields, all
|
|
6898
|
+
* binding the SAME key the SAME way) is fine.
|
|
6899
|
+
*/
|
|
6900
|
+
|
|
6901
|
+
type AnyModelClass = abstract new (...args: any[]) => any;
|
|
6902
|
+
/** The view source slice IR the maintenance graph consumes (one per source × view). */
|
|
6903
|
+
interface ViewSourceSlice {
|
|
6904
|
+
readonly sourceClass: AnyModelClass;
|
|
6905
|
+
readonly maintainedOn: readonly MaintainTrigger[];
|
|
6906
|
+
readonly keys: Readonly<Record<string, EffectPath>>;
|
|
6907
|
+
readonly project: ProjectionMap;
|
|
6908
|
+
readonly collection?: {
|
|
6909
|
+
readonly field: string;
|
|
6910
|
+
readonly maxItems?: number;
|
|
6911
|
+
readonly orderBy?: EffectPath;
|
|
6912
|
+
readonly orderDir?: 'ASC' | 'DESC';
|
|
6913
|
+
};
|
|
6914
|
+
readonly predicate?: MembershipPredicate;
|
|
6915
|
+
}
|
|
6916
|
+
/** The view definition IR — an independent view row maintained from one or more sources. */
|
|
6917
|
+
interface ViewDefinition {
|
|
6918
|
+
readonly name: string;
|
|
6919
|
+
readonly viewClass: AnyModelClass;
|
|
6920
|
+
readonly pattern: 'materializedView' | 'sparseView';
|
|
6921
|
+
readonly slices: readonly ViewSourceSlice[];
|
|
6922
|
+
readonly updateMode?: 'mutation' | 'stream';
|
|
6923
|
+
readonly consistency?: 'transactional' | 'eventual';
|
|
6924
|
+
}
|
|
6925
|
+
/**
|
|
6926
|
+
* Build every {@link ViewDefinition} for a registry — from `@model({ kind })` +
|
|
6927
|
+
* `@maintainedFrom` view models AND from versioned-pattern relations. This is the
|
|
6928
|
+
* adapter the maintenance graph calls in place of the deleted `ViewRegistry.getAll()`.
|
|
6929
|
+
*
|
|
6930
|
+
* @param registry The models to scan. Defaults to `MetadataRegistry.getAll()`.
|
|
6931
|
+
*/
|
|
6932
|
+
declare function collectViewDefinitions(registry?: ReadonlyMap<Function, EntityMetadata>): ViewDefinition[];
|
|
6933
|
+
|
|
6934
|
+
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 RecordedCompose 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 MutationBody as cA, type MutationDescriptorMap as cB, type MutationFragment as cC, type MutationInputProxy as cD, type MutationInputRef as cE, type MutationIntent as cF, type NumberParam as cG, type OperationKind as cH, type ParallelOpResult as cI, type ParamKind as cJ, type ParamStructure as cK, type PersistCtx as cL, type PersistOrigin as cM, type PlannedCommandMethod as cN, type ProjectionMap as cO, type ProjectionTransformOp as cP, type PutOptions as cQ, type QueryEnvelopeResult as cR, type QueryKeyOf as cS, type QueryMethod as cT, type QueryResult as cU, type ReadEnvelope as cV, type ReadOpCtx as cW, type ReadOpKind as cX, type ReadRouteDescriptor as cY, type ReadRouteOptions as cZ, type ReadRouteResult 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 InputArity as ch, type KeyDefinitionMarker as ci, type KeySegment as cj, type KeySlot as ck, type KeyStructure as cl, type KeyedResult as cm, LIFECYCLE_CONTRACT_MARKER as cn, type LifecycleContract as co, type LifecycleEffects as cp, type LiteralParam as cq, type MaintainItem as cr, type MaintainTrigger as cs, type MaintenanceGraph as ct, type MembershipEffect as cu, type ModelRef as cv, type MutateMode as cw, type MutateOptions as cx, type MutateParallelResult as cy, type MutateTransactionResult as cz, type ChangeEventName as d, isContractFromRef as d$, type RelationBuilder as d0, type RelationConsistency as d1, type RelationLimitOptions as d2, type RelationPattern as d3, type RelationProjection as d4, type RelationReadOptions as d5, type RelationSelect as d6, type RelationSpec as d7, type RelationUpdateMode as d8, type RelationWriteOptions as d9, buildDeleteInput as dA, buildMaintenanceGraph as dB, buildPutInput as dC, buildUpdateInput as dD, collectViewDefinitions as dE, cond as dF, contractOfMethodSpec as dG, definePlan as dH, entityWrites as dI, executeBatchGet as dJ, executeBatchWrite as dK, executeCommandMethod as dL, executeDelete as dM, executeKeyedBatchGet as dN, executePut as dO, executeQueryMethod as dP, executeRangeFanout as dQ, executeTransaction as dR, executeUpdate as dS, from as dT, getEntityWrites as dU, gsi as dV, identity as dW, isColumn as dX, isCommandModelContract as dY, isCommandPlan as dZ, isContractComposeNode as d_, type RequiresEffect as da, type Resolution as db, type RetryInfo as dc, type RetryOperationKind as dd, type SegmentSpec as de, type SegmentedKey as df, type SelectBuilder as dg, type SelectOf as dh, type SnapshotEffect as di, type StringParam as dj, TransactionContext as dk, type UniqueEffect as dl, type Updatable as dm, type UpdateOptions as dn, type ViewSourceSlice as dp, type WriteCtx as dq, type WriteDescriptor as dr, type WriteEnvelope as ds, type WriteInput as dt, type WriteKind as du, type WriteLifecyclePhase as dv, type WriteMiddleware as dw, type WriteRecorder as dx, type WriteResultProjection as dy, attachModelClass as dz, type ChangeHandler as e, isContractKeyFieldRef as e0, isContractKeyRef as e1, isContractParamRef as e2, isEntityWritesDefinition as e3, isKeySegment as e4, isLifecycleContract as e5, isMaintainTrigger as e6, isMutationFragment as e7, isMutationInputRef as e8, isParam as e9, isPlannedCommandMethod as ea, isQueryModelContract as eb, isRetryableError as ec, isRetryableTransactionCancellation as ed, k as ee, key as ef, lifecyclePhaseForIntent as eg, maintainTrigger as eh, mintContractKeyFieldRef as ei, mintContractParamRef as ej, mutation as ek, param as el, preview as em, publicCommandModel as en, publicQueryModel as eo, query as ep, wholeKeysSentinel as eq, 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 };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { m as EntityMetadata } from './maintenance-view-adapter-D5t9taTE.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
|
+
}
|
|
22
|
+
|
|
23
|
+
declare class MetadataRegistry {
|
|
24
|
+
private static store;
|
|
25
|
+
private static _linter;
|
|
26
|
+
/**
|
|
27
|
+
* A monotonically-increasing counter bumped on every change to the set of
|
|
28
|
+
* registered models ({@link register} / {@link clear}). It lets a consumer that
|
|
29
|
+
* caches a structure derived from the whole registry (e.g. the maintenance graph
|
|
30
|
+
* in `src/spec/mutation-command.ts`) detect that the registry has changed since
|
|
31
|
+
* the cache was built and rebuild — closing the silent-drop window where a model
|
|
32
|
+
* registered after a cache build would be invisible to it. Only the membership
|
|
33
|
+
* of {@link store} changes here; per-model lazy finalize ({@link finalize}) does
|
|
34
|
+
* not bump it (it adds no relations/triggers, so it cannot change the graph).
|
|
35
|
+
*/
|
|
36
|
+
private static _generation;
|
|
37
|
+
/**
|
|
38
|
+
* The current registry generation (see {@link _generation}). A consumer caches
|
|
39
|
+
* the value it built against and rebuilds when it no longer matches.
|
|
40
|
+
*/
|
|
41
|
+
static get generation(): number;
|
|
42
|
+
static register(target: Function, metadata: EntityMetadata): void;
|
|
43
|
+
static get(target: Function): EntityMetadata;
|
|
44
|
+
static has(target: Function): boolean;
|
|
45
|
+
static getAll(): Map<Function, EntityMetadata>;
|
|
46
|
+
/**
|
|
47
|
+
* Snapshot of the entities that are **already finalized**, WITHOUT triggering
|
|
48
|
+
* finalize on any pending entity (unlike {@link getAll}). This is the safe view
|
|
49
|
+
* for a cross-entity lint rule that runs *inside* `finalize`: eagerly
|
|
50
|
+
* finalizing the rest of the registry from within a finalize pass would
|
|
51
|
+
* re-enter (and duplicate) the in-progress entity's finalize. A whole-registry
|
|
52
|
+
* rule instead reasons over the already-finalized peers plus the entity
|
|
53
|
+
* currently being checked; any conflicting pair is caught when the later of the
|
|
54
|
+
* two finalizes (both are present by then).
|
|
55
|
+
*
|
|
56
|
+
* @internal — for cross-entity linter rules.
|
|
57
|
+
*/
|
|
58
|
+
static getFinalized(): Map<Function, EntityMetadata>;
|
|
59
|
+
static get linter(): Linter | null;
|
|
60
|
+
static set linter(linter: Linter | null);
|
|
61
|
+
/** Resets linter to the environment default (built-in rule set outside production). */
|
|
62
|
+
static resetLinter(): void;
|
|
63
|
+
/**
|
|
64
|
+
* @internal — for testing only. Resets to a no-op linter (no rules): matches
|
|
65
|
+
* the pre-#189 `new Linter()` behaviour where a cleared registry does not lint
|
|
66
|
+
* on re-registration. `null` is finalize-equivalent to an empty linter (the
|
|
67
|
+
* `finalize` guard skips a null linter), and nothing reads the linter getter
|
|
68
|
+
* to invoke it, so this preserves existing test semantics without importing
|
|
69
|
+
* the `Linter` class as a value (keeping it out of a production bundle).
|
|
70
|
+
*/
|
|
71
|
+
static clear(): void;
|
|
72
|
+
private static finalize;
|
|
73
|
+
private static handleLintResults;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { type LintRule as L, MetadataRegistry as M, type LintResult as a, Linter as b };
|