graphddb 0.2.4 → 0.2.5
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 +314 -305
- package/dist/{chunk-GCPEUPAA.js → chunk-4TYK3AV6.js} +671 -155
- package/dist/{chunk-LNESVUTO.js → chunk-ITHQ2EDH.js} +1 -1
- package/dist/{chunk-IQEOJVHI.js → chunk-SGYBE2OV.js} +378 -49
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +167 -3
- package/dist/index.js +3 -3
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/{types-BEeQ_nSd.d.ts → types--tdHK3vi.d.ts} +674 -212
- package/package.json +1 -1
|
@@ -778,6 +778,552 @@ type AtLeastOneKey<T> = {
|
|
|
778
778
|
*/
|
|
779
779
|
type PartialQueryKeyOf<C> = QueryKeyOf<C> extends infer U ? U extends Record<string, unknown> ? AtLeastOneKey<U> : never : never;
|
|
780
780
|
|
|
781
|
+
interface PutOptions<T = unknown> {
|
|
782
|
+
condition?: WriteCondition<T>;
|
|
783
|
+
/**
|
|
784
|
+
* Per-call throttle / transient-error retry override (issue #111). A
|
|
785
|
+
* {@link RetryPolicy} replaces the global policy for this call; `false` disables
|
|
786
|
+
* retry for this call. Omit to use the configured (or built-in default) policy.
|
|
787
|
+
*/
|
|
788
|
+
retry?: RetryOverride;
|
|
789
|
+
/**
|
|
790
|
+
* Host-injected per-call write context (issue #50 / #139) — exposed to every
|
|
791
|
+
* write hook (W1–W5) as `ctx.context`. A host-language value, NEVER serialized
|
|
792
|
+
* into the SSoT / `operations.json` (the bridge #48 is unaffected). Absent ⇒ `{}`.
|
|
793
|
+
*/
|
|
794
|
+
context?: RequestContext;
|
|
795
|
+
}
|
|
796
|
+
interface UpdateOptions<T = unknown> {
|
|
797
|
+
condition?: WriteCondition<T>;
|
|
798
|
+
/**
|
|
799
|
+
* Per-call throttle / transient-error retry override (issue #111). A
|
|
800
|
+
* {@link RetryPolicy} replaces the global policy for this call; `false` disables
|
|
801
|
+
* retry for this call.
|
|
802
|
+
*/
|
|
803
|
+
retry?: RetryOverride;
|
|
804
|
+
/**
|
|
805
|
+
* How to re-derive a GSI key whose composing fields are changed but **not all**
|
|
806
|
+
* available from `{ ...key, ...changes }` (issue #115).
|
|
807
|
+
*
|
|
808
|
+
* - **unset (default)** — refuse with an explicit error rather than let the
|
|
809
|
+
* index silently rot. The error names the index, the changed field, and the
|
|
810
|
+
* missing field(s). The happy path (all composing fields available) re-derives
|
|
811
|
+
* in the SAME `UpdateExpression` and is unaffected by this option.
|
|
812
|
+
* - `'read-modify-write'` — read the current item, merge `{ ...item, ...changes }`,
|
|
813
|
+
* re-derive every affected GSI key from the merged image, and write back under
|
|
814
|
+
* an optimistic condition (the item must still exist / be unchanged). This costs
|
|
815
|
+
* one extra read and is NOT atomic with the original update, but always re-derives
|
|
816
|
+
* correctly.
|
|
817
|
+
*/
|
|
818
|
+
rederive?: 'read-modify-write';
|
|
819
|
+
/**
|
|
820
|
+
* Host-injected per-call write context (issue #50 / #139) — exposed to every
|
|
821
|
+
* write hook (W1–W5) as `ctx.context`. NEVER serialized. Absent ⇒ `{}`.
|
|
822
|
+
*/
|
|
823
|
+
context?: RequestContext;
|
|
824
|
+
}
|
|
825
|
+
interface DeleteOptions<T = unknown> {
|
|
826
|
+
condition?: WriteCondition<T>;
|
|
827
|
+
/**
|
|
828
|
+
* Per-call throttle / transient-error retry override (issue #111). A
|
|
829
|
+
* {@link RetryPolicy} replaces the global policy for this call; `false` disables
|
|
830
|
+
* retry for this call.
|
|
831
|
+
*/
|
|
832
|
+
retry?: RetryOverride;
|
|
833
|
+
/**
|
|
834
|
+
* Host-injected per-call write context (issue #50 / #139) — exposed to every
|
|
835
|
+
* write hook (W1–W5) as `ctx.context`. NEVER serialized. Absent ⇒ `{}`.
|
|
836
|
+
*/
|
|
837
|
+
context?: RequestContext;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
interface PutInput {
|
|
841
|
+
TableName: string;
|
|
842
|
+
Item: Record<string, unknown>;
|
|
843
|
+
ConditionExpression?: string;
|
|
844
|
+
ExpressionAttributeNames?: Record<string, string>;
|
|
845
|
+
ExpressionAttributeValues?: Record<string, unknown>;
|
|
846
|
+
}
|
|
847
|
+
declare function buildPutInput(modelClass: Function, item: Record<string, unknown>, options?: PutOptions): PutInput;
|
|
848
|
+
declare function executePut(modelClass: Function, item: Record<string, unknown>, options?: PutOptions): Promise<void>;
|
|
849
|
+
|
|
850
|
+
interface UpdateInput {
|
|
851
|
+
TableName: string;
|
|
852
|
+
Key: Record<string, unknown>;
|
|
853
|
+
UpdateExpression: string;
|
|
854
|
+
ExpressionAttributeNames: Record<string, string>;
|
|
855
|
+
ExpressionAttributeValues?: Record<string, unknown>;
|
|
856
|
+
ConditionExpression?: string;
|
|
857
|
+
}
|
|
858
|
+
declare function buildUpdateInput(modelClass: Function, entity: Record<string, unknown>, changes: Record<string, unknown>, options?: UpdateOptions): UpdateInput;
|
|
859
|
+
declare function executeUpdate(modelClass: Function, entity: Record<string, unknown>, changes: Record<string, unknown>, options?: UpdateOptions): Promise<void>;
|
|
860
|
+
|
|
861
|
+
interface DeleteInput {
|
|
862
|
+
TableName: string;
|
|
863
|
+
Key: Record<string, unknown>;
|
|
864
|
+
ConditionExpression?: string;
|
|
865
|
+
ExpressionAttributeNames?: Record<string, string>;
|
|
866
|
+
ExpressionAttributeValues?: Record<string, unknown>;
|
|
867
|
+
}
|
|
868
|
+
declare function buildDeleteInput(modelClass: Function, keyObj: Record<string, unknown>, options?: DeleteOptions): DeleteInput;
|
|
869
|
+
declare function executeDelete(modelClass: Function, keyObj: Record<string, unknown>, options?: DeleteOptions): Promise<void>;
|
|
870
|
+
|
|
871
|
+
/** Result of a read operation (GetItem / Query / BatchGetItem). */
|
|
872
|
+
interface ExecutorResult {
|
|
873
|
+
items: Record<string, unknown>[];
|
|
874
|
+
lastEvaluatedKey?: Record<string, unknown>;
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Result of a single structured write. `oldItem` is the pre-write image,
|
|
878
|
+
* present only when the caller requested it (`returnOldImage: true`, mapped to
|
|
879
|
+
* DynamoDB `ReturnValues: ALL_OLD`) and an item existed before the write. The
|
|
880
|
+
* write-capture seam (issue #72) reads it to derive INSERT vs MODIFY and the
|
|
881
|
+
* REMOVE OldImage.
|
|
882
|
+
*/
|
|
883
|
+
interface WriteResult {
|
|
884
|
+
oldItem?: Record<string, unknown>;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* A per-call retry override threaded down to {@link RetryingExecutor} (issue
|
|
888
|
+
* #111). `undefined` ⇒ use the globally-configured (or default) policy; a
|
|
889
|
+
* {@link RetryPolicy} ⇒ use that for this call; `false` ⇒ disable retry for this
|
|
890
|
+
* call. The default {@link DynamoExecutor} and the test `MemoryExecutor` ignore
|
|
891
|
+
* it — only {@link RetryingExecutor} acts on it.
|
|
892
|
+
*/
|
|
893
|
+
type RetryOverride = RetryPolicy | false;
|
|
894
|
+
/**
|
|
895
|
+
* Per-call options for the READ path (issue #111). Carries the per-op retry
|
|
896
|
+
* override down to {@link RetryingExecutor}. Extended (rather than passing the
|
|
897
|
+
* override positionally) so future per-call read knobs have a home.
|
|
898
|
+
*/
|
|
899
|
+
interface ReadExecOptions {
|
|
900
|
+
/** Per-call retry override; see {@link RetryOverride}. */
|
|
901
|
+
retry?: RetryOverride;
|
|
902
|
+
}
|
|
903
|
+
/** Options shared by the single-item structured write methods. */
|
|
904
|
+
interface WriteExecOptions {
|
|
905
|
+
/** Request the pre-write image (DynamoDB `ReturnValues: ALL_OLD`). */
|
|
906
|
+
returnOldImage?: boolean;
|
|
907
|
+
/** Per-call retry override (issue #111); see {@link RetryOverride}. */
|
|
908
|
+
retry?: RetryOverride;
|
|
909
|
+
}
|
|
910
|
+
/** Per-call options for the batch / transact paths (issue #111). */
|
|
911
|
+
interface BatchExecOptions {
|
|
912
|
+
/** Per-call retry override; see {@link RetryOverride}. */
|
|
913
|
+
retry?: RetryOverride;
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* One BatchGetItem sub-request: a single physical table plus its keys and an
|
|
917
|
+
* optional projection. Mirrors {@link import('../planner/types.js').BatchGetItemOperation}
|
|
918
|
+
* without the discriminant `type` field, so callers that already chunked keys
|
|
919
|
+
* (relation traversal) and the planner-driven read path share one entry point.
|
|
920
|
+
*/
|
|
921
|
+
interface BatchGetExecInput {
|
|
922
|
+
tableName: string;
|
|
923
|
+
keys: Record<string, unknown>[];
|
|
924
|
+
projectionExpression?: string;
|
|
925
|
+
expressionAttributeNames?: Record<string, string>;
|
|
926
|
+
consistentRead?: boolean;
|
|
927
|
+
}
|
|
928
|
+
/** A single item in a {@link Executor.batchWrite} request, grouped by table. */
|
|
929
|
+
type BatchWriteExecItem = {
|
|
930
|
+
type: 'put';
|
|
931
|
+
item: Record<string, unknown>;
|
|
932
|
+
} | {
|
|
933
|
+
type: 'delete';
|
|
934
|
+
key: Record<string, unknown>;
|
|
935
|
+
};
|
|
936
|
+
/**
|
|
937
|
+
* A read-only `ConditionCheck` entry for {@link Executor.transactWrite} (issue
|
|
938
|
+
* #81): it asserts a `ConditionExpression` holds for the keyed item without
|
|
939
|
+
* mutating it. A failed assertion cancels the **whole** `TransactWriteItems`
|
|
940
|
+
* atomically — the foundation for referential-integrity derivation.
|
|
941
|
+
*/
|
|
942
|
+
interface ConditionCheckInput {
|
|
943
|
+
TableName: string;
|
|
944
|
+
Key: Record<string, unknown>;
|
|
945
|
+
ConditionExpression: string;
|
|
946
|
+
ExpressionAttributeNames?: Record<string, string>;
|
|
947
|
+
ExpressionAttributeValues?: Record<string, unknown>;
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* A `{ Put | Update | Delete | ConditionCheck }` entry for
|
|
951
|
+
* {@link Executor.transactWrite}. The first three mutate an item; `ConditionCheck`
|
|
952
|
+
* (issue #81) is a read-only assertion on another item.
|
|
953
|
+
*/
|
|
954
|
+
type TransactWriteExecItem = {
|
|
955
|
+
Put: PutInput;
|
|
956
|
+
} | {
|
|
957
|
+
Update: UpdateInput;
|
|
958
|
+
} | {
|
|
959
|
+
Delete: DeleteInput;
|
|
960
|
+
} | {
|
|
961
|
+
ConditionCheck: ConditionCheckInput;
|
|
962
|
+
};
|
|
963
|
+
/**
|
|
964
|
+
* The unified I/O seam (issue #76). All of GraphDDB's read and write I/O is
|
|
965
|
+
* funneled through one injectable executor so the engine (planner / hydrator /
|
|
966
|
+
* relation traversal / write paths) can run unchanged against either real
|
|
967
|
+
* DynamoDB ({@link DynamoExecutor}, the default) or an in-process memory store
|
|
968
|
+
* (`MemoryExecutor`, the test adapter).
|
|
969
|
+
*
|
|
970
|
+
* Reads take a structured {@link DynamoDBOperation}; writes take the structured
|
|
971
|
+
* inputs the operation layer already builds (`PutInput` / `UpdateInput` / …),
|
|
972
|
+
* never an AWS SDK command. This keeps the seam at the *structured operation
|
|
973
|
+
* boundary* (proposal option B): no expression-string parsing is required to
|
|
974
|
+
* implement a fake.
|
|
975
|
+
*/
|
|
976
|
+
interface Executor {
|
|
977
|
+
/**
|
|
978
|
+
* Read path: GetItem / Query / BatchGetItem. The optional {@link ReadExecOptions}
|
|
979
|
+
* carries a per-call retry override (issue #111); the default
|
|
980
|
+
* {@link DynamoExecutor} and `MemoryExecutor` ignore it, only `RetryingExecutor`
|
|
981
|
+
* acts on it.
|
|
982
|
+
*/
|
|
983
|
+
execute(operation: DynamoDBOperation, options?: ReadExecOptions): Promise<ExecutorResult>;
|
|
984
|
+
/**
|
|
985
|
+
* BatchGetItem for a single table. The caller is responsible for chunking
|
|
986
|
+
* keys ≤100 (the relation traversal and the planner-driven path both do).
|
|
987
|
+
*/
|
|
988
|
+
batchGet(input: BatchGetExecInput, options?: ReadExecOptions): Promise<ExecutorResult>;
|
|
989
|
+
/** Put one item. */
|
|
990
|
+
put(input: PutInput, options?: WriteExecOptions): Promise<WriteResult>;
|
|
991
|
+
/** Update one item (applies its structured UpdateExpression). */
|
|
992
|
+
update(input: UpdateInput, options?: WriteExecOptions): Promise<WriteResult>;
|
|
993
|
+
/** Delete one item. */
|
|
994
|
+
delete(input: DeleteInput, options?: WriteExecOptions): Promise<WriteResult>;
|
|
995
|
+
/**
|
|
996
|
+
* BatchWriteItem for a single table (non-atomic). Keys/items are chunked ≤25
|
|
997
|
+
* with UnprocessedItems retry by the implementation.
|
|
998
|
+
*/
|
|
999
|
+
batchWrite(tableName: string, items: BatchWriteExecItem[], options?: BatchExecOptions): Promise<void>;
|
|
1000
|
+
/** TransactWriteItems — all-or-nothing atomic. */
|
|
1001
|
+
transactWrite(items: TransactWriteExecItem[], options?: BatchExecOptions): Promise<void>;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Write middleware / hook public surface (issue #50 write path, #139). The merged
|
|
1006
|
+
* design is `docs/proposals/read-middleware.md`; this module implements the
|
|
1007
|
+
* **write** hook points W1–W5 and their context objects, layered on the SAME
|
|
1008
|
+
* registry / runtime machinery the read hooks (#138) introduced.
|
|
1009
|
+
*
|
|
1010
|
+
* A write {@link Middleware} hook is host-only, runtime-registered (via
|
|
1011
|
+
* `DDBModel.use`), and **never serialized** — like the read hooks it lives only on
|
|
1012
|
+
* the {@link import('../client/ClientManager.js').ClientManager} host-runtime
|
|
1013
|
+
* singleton and never touches the planner / spec generator / `operations.json`, so
|
|
1014
|
+
* the TS↔Python bridge (#48) is unaffected. It is **unrestricted by intent**: a
|
|
1015
|
+
* hook may observe, mutate `ctx`, `throw` to cancel, or (on `onError`) recover by
|
|
1016
|
+
* returning a value. The library does NOT validate hook logic or impose semantics
|
|
1017
|
+
* (proposal appendix A). The internal CDC / capture mechanism (`src/capture/`,
|
|
1018
|
+
* `src/cdc/`) is a SEPARATE surface — write hooks are not a substitute for it nor
|
|
1019
|
+
* it for them (proposal appendix C).
|
|
1020
|
+
*
|
|
1021
|
+
* @see docs/proposals/read-middleware.md (hook points W1–W5)
|
|
1022
|
+
*/
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* The logical write kinds a {@link WriteCtx} may carry (W1 / W2 / W5). A W1 hook
|
|
1026
|
+
* may REWRITE this in place — the canonical case is a `delete` → `update`
|
|
1027
|
+
* (soft-delete-by-rewrite); derivation then runs on the rewritten op, so the
|
|
1028
|
+
* stored effect is the update, not the delete (proposal W1 + examples).
|
|
1029
|
+
*/
|
|
1030
|
+
type WriteKind = 'put' | 'update' | 'delete';
|
|
1031
|
+
/**
|
|
1032
|
+
* The mutable logical write input a W1 hook observes / mutates. This is the
|
|
1033
|
+
* declarative write payload — NOT a serialized spec — at the granularity the
|
|
1034
|
+
* logical op carries:
|
|
1035
|
+
*
|
|
1036
|
+
* - `put` — the full `item` is in {@link WriteInput.item};
|
|
1037
|
+
* - `update` — the target `key` (entity) is in {@link WriteInput.key} and the
|
|
1038
|
+
* field `changes` in {@link WriteInput.changes};
|
|
1039
|
+
* - `delete` — the target `key` is in {@link WriteInput.key}.
|
|
1040
|
+
*
|
|
1041
|
+
* A W1 hook may mutate these in place (e.g. inject `updatedBy`), and may rewrite
|
|
1042
|
+
* `ctx.kind` together with these fields (a `delete` → `update` sets `changes`).
|
|
1043
|
+
* Keeping `input` and `kind` consistent is the host's responsibility (appendix A).
|
|
1044
|
+
*/
|
|
1045
|
+
interface WriteInput {
|
|
1046
|
+
/** The item written by a `put` (its key fields appear here). Mutable in W1. */
|
|
1047
|
+
item?: Record<string, unknown>;
|
|
1048
|
+
/** The target entity / key of an `update` / `delete`. Mutable in W1. */
|
|
1049
|
+
key?: Record<string, unknown>;
|
|
1050
|
+
/** The field changes of an `update`. Mutable in W1 (and when rewriting delete→update). */
|
|
1051
|
+
changes?: Record<string, unknown>;
|
|
1052
|
+
/** The per-call write options (`condition` / `retry` / `rederive` / …). Mutable in W1. */
|
|
1053
|
+
options?: Record<string, unknown>;
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* W1 / W2 / W5 (logical-write-level) context. `before` (W1) may mutate
|
|
1057
|
+
* {@link WriteCtx.input} and {@link WriteCtx.kind} (incl. the delete→update
|
|
1058
|
+
* rewrite) and may `throw` to cancel the write (in a transaction, aborting ALL
|
|
1059
|
+
* ops); `after` (W2) observes the committed change `{ oldImage?, newImage? }`;
|
|
1060
|
+
* `onError` (W5) sees the logical-level failure and may recover by returning a
|
|
1061
|
+
* value (symmetric with the read `onError`).
|
|
1062
|
+
*/
|
|
1063
|
+
interface WriteCtx extends CtxBase {
|
|
1064
|
+
/** The logical write kind. Mutable in W1 (incl. delete→update rewrite). */
|
|
1065
|
+
kind: WriteKind;
|
|
1066
|
+
/** The mutable logical write payload (W1). */
|
|
1067
|
+
input: WriteInput;
|
|
1068
|
+
/**
|
|
1069
|
+
* Present when this logical write is part of an atomic transaction
|
|
1070
|
+
* (`DDBModel.transaction` / `mutate({ mode: 'transaction' })`). Its `id` symbol
|
|
1071
|
+
* is shared by every logical op in the same atomic batch, so a hook can
|
|
1072
|
+
* correlate the W1/W2 ops that compose one transaction. Absent for a
|
|
1073
|
+
* non-transactional single-op write (and for `parallel`-mode ops, which are
|
|
1074
|
+
* independent).
|
|
1075
|
+
*/
|
|
1076
|
+
readonly transaction?: {
|
|
1077
|
+
readonly id: symbol;
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* The committed change handed to a W2 (`write.after`) hook. A
|
|
1082
|
+
* `TransactWriteItems` returns no item images (spec §14), so within a transaction
|
|
1083
|
+
* the images are best-effort (often absent); a single-op write may carry the
|
|
1084
|
+
* pre-write `oldImage` when one was fetched.
|
|
1085
|
+
*/
|
|
1086
|
+
interface Change {
|
|
1087
|
+
readonly oldImage?: Record<string, unknown>;
|
|
1088
|
+
readonly newImage?: Record<string, unknown>;
|
|
1089
|
+
}
|
|
1090
|
+
/** One origin entry describing a logical op that contributed to a persist batch. */
|
|
1091
|
+
interface PersistOrigin {
|
|
1092
|
+
readonly model: CtxModel;
|
|
1093
|
+
readonly kind: WriteKind;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* W3 / W4 / W5 (physical-persist-level) context — fires AFTER derivation, on the
|
|
1097
|
+
* REAL composed batch. `before` (W3) may mutate {@link PersistCtx.items} (the
|
|
1098
|
+
* fully composed `Put` / `Update` / `Delete` / `ConditionCheck` set: the user
|
|
1099
|
+
* write(s) PLUS every derived edge / counter / GSI re-derivation / referential
|
|
1100
|
+
* ConditionCheck) and may `throw` to abort the batch — mutations are honored on
|
|
1101
|
+
* the ACTUAL send. `after` (W4) observes the executor's results; `onError` (W5)
|
|
1102
|
+
* sees the persist-level failure and may recover by returning a value.
|
|
1103
|
+
*
|
|
1104
|
+
* In a transaction the persist hooks fire ONCE for the whole atomic batch; for a
|
|
1105
|
+
* non-transactional single-op write `items` is the one-element `[{ Put|Update|Delete }]`.
|
|
1106
|
+
*/
|
|
1107
|
+
interface PersistCtx {
|
|
1108
|
+
/** The fully composed physical batch (user + derived). Mutable in W3. */
|
|
1109
|
+
items: TransactWriteExecItem[];
|
|
1110
|
+
/** The logical ops that composed this batch (one per contributing W-level op). */
|
|
1111
|
+
readonly origins: readonly PersistOrigin[];
|
|
1112
|
+
/** The host-injected per-call context (`{}` when the write passed none). */
|
|
1113
|
+
readonly context: RequestContext;
|
|
1114
|
+
/** Scratch shared across this persist op's W3 → W4 → W5 phases. */
|
|
1115
|
+
readonly state: Record<string, unknown>;
|
|
1116
|
+
/** Present (with the shared `id`) when this batch is an atomic transaction. */
|
|
1117
|
+
readonly transaction?: {
|
|
1118
|
+
readonly id: symbol;
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* The write half of a registered {@link import('./types.js').Middleware}. Any
|
|
1123
|
+
* subset of the write hook points may be set; an unset hook is skipped. All hooks
|
|
1124
|
+
* are async-first — the runtime always `await`s, so sync and async hooks compose
|
|
1125
|
+
* uniformly (proposal "sync / async").
|
|
1126
|
+
*
|
|
1127
|
+
* @see docs/proposals/read-middleware.md (hook points W1–W5)
|
|
1128
|
+
*/
|
|
1129
|
+
interface WriteMiddleware {
|
|
1130
|
+
/** W1 — logical write, before effect derivation. May mutate `ctx.input` / `ctx.kind`; `throw` cancels (in a tx, aborts all). */
|
|
1131
|
+
before?(ctx: WriteCtx): void | Promise<void>;
|
|
1132
|
+
/** W2 — logical write, after commit. Observes the committed `{ oldImage?, newImage? }`. */
|
|
1133
|
+
after?(ctx: WriteCtx, change: Change): void | Promise<void>;
|
|
1134
|
+
persist?: {
|
|
1135
|
+
/** W3 — physical persist, after derivation, on the real batch. May mutate `ctx.items`; `throw` aborts the batch. */
|
|
1136
|
+
before?(ctx: PersistCtx): void | Promise<void>;
|
|
1137
|
+
/** W4 — physical persist, after the executor returns. Observes `results`. */
|
|
1138
|
+
after?(ctx: PersistCtx, results: unknown): void | Promise<void>;
|
|
1139
|
+
/**
|
|
1140
|
+
* W5 (persist-level) — the persist failed. Runs LIFO. **Recover** by RETURNING
|
|
1141
|
+
* a non-`undefined` value: the persist is treated as succeeded and the value is
|
|
1142
|
+
* available to W4 (the first hook that returns a value wins and short-circuits
|
|
1143
|
+
* the chain). Return `void` / `undefined` to decline — if no hook recovers, the
|
|
1144
|
+
* original error rethrows (symmetric with the read `op.onError`).
|
|
1145
|
+
*/
|
|
1146
|
+
onError?(ctx: PersistCtx, err: unknown): unknown;
|
|
1147
|
+
};
|
|
1148
|
+
/**
|
|
1149
|
+
* W5 (logical-level) — the logical write failed. Runs LIFO. **Recover** by
|
|
1150
|
+
* RETURNING a non-`undefined` value: it becomes the write's resolved value in
|
|
1151
|
+
* place of throwing (the first hook that returns a value wins). Return `void` /
|
|
1152
|
+
* `undefined` to decline — if no hook recovers, the original error rethrows
|
|
1153
|
+
* (symmetric with the read `onError`).
|
|
1154
|
+
*/
|
|
1155
|
+
onError?(ctx: WriteCtx, err: unknown): unknown;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
/**
|
|
1159
|
+
* Read middleware / hook public surface (issue #50, implemented for the read
|
|
1160
|
+
* path in #138). The merged design is `docs/proposals/read-middleware.md`; this
|
|
1161
|
+
* module implements the **read** hook points R1–R5 and their context objects.
|
|
1162
|
+
*
|
|
1163
|
+
* A {@link Middleware} is a host-only, runtime-registered object (registered via
|
|
1164
|
+
* `DDBModel.use`) that runs at fixed seams in the read pipeline. Hooks are
|
|
1165
|
+
* **never serialized** — they live only on the {@link import('../client/ClientManager.js').ClientManager}
|
|
1166
|
+
* host-runtime singleton and never touch the planner / spec generator /
|
|
1167
|
+
* `operations.json`, so the TS↔Python bridge (#48) is unaffected. Hooks are
|
|
1168
|
+
* **unrestricted by intent**: a hook may observe, mutate `ctx`, `throw` to
|
|
1169
|
+
* cancel, or return a replacement value. The library does NOT validate hook
|
|
1170
|
+
* logic or impose semantics — see the proposal appendix A.
|
|
1171
|
+
*
|
|
1172
|
+
* @see docs/proposals/read-middleware.md
|
|
1173
|
+
*/
|
|
1174
|
+
|
|
1175
|
+
/** A raw DynamoDB item (the shape R3 sees, per-op). */
|
|
1176
|
+
type Item = Record<string, unknown>;
|
|
1177
|
+
/**
|
|
1178
|
+
* Host-injected, library-opaque per-call context — the value passed as
|
|
1179
|
+
* `{ context }` on a read. Threaded unchanged to every R2/R3 fan-out op (issue
|
|
1180
|
+
* #138). A read issued with no `{ context }` sees `{}`.
|
|
1181
|
+
*/
|
|
1182
|
+
type RequestContext = Record<string, unknown>;
|
|
1183
|
+
/**
|
|
1184
|
+
* The `ModelStatic` shape the library hands to a hook's `ctx.model`. The
|
|
1185
|
+
* concrete entity type is erased at the hook boundary (a hook is registered
|
|
1186
|
+
* globally and may see any model), so it is the permissive
|
|
1187
|
+
* `ModelStatic<DDBModel>`.
|
|
1188
|
+
*/
|
|
1189
|
+
type CtxModel = ModelStatic<DDBModel>;
|
|
1190
|
+
/** Fields shared by every read context object. */
|
|
1191
|
+
interface CtxBase {
|
|
1192
|
+
/** The model the read targets. */
|
|
1193
|
+
readonly model: CtxModel;
|
|
1194
|
+
/** The host-injected per-call context (`{}` when the read passed none). */
|
|
1195
|
+
readonly context: RequestContext;
|
|
1196
|
+
/**
|
|
1197
|
+
* Scratch space shared across this op's phases (R2 → R3 → R5 for one op, or
|
|
1198
|
+
* R1 → R4 → R5 for the request). A fresh object per request context object;
|
|
1199
|
+
* each fan-out op gets its own `state` (see proposal appendix D — siblings run
|
|
1200
|
+
* concurrently, so a shared accumulator should live on a host object via
|
|
1201
|
+
* `context`, updated commutatively).
|
|
1202
|
+
*/
|
|
1203
|
+
readonly state: Record<string, unknown>;
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* The logical read kinds an {@link ReadRequestCtx} may carry (R1 / R4 / R5).
|
|
1207
|
+
*
|
|
1208
|
+
* Only the kinds the runtime actually emits are advertised. A `query` route in
|
|
1209
|
+
* the read envelope delegates to {@link import('../operations/query.js').executeQuery}
|
|
1210
|
+
* (kind `'query'`), a `list` route to {@link import('../operations/list.js').executeList}
|
|
1211
|
+
* (kind `'list'`), so there is no distinct `'envelopeRoute'` kind. `batchGet`
|
|
1212
|
+
* (`DDBModel.batchGet`, the public multi-key read primitive) fires request-level
|
|
1213
|
+
* hooks since issue #142 — its R1/R4/R5 carry kind `'batchGet'`; each underlying
|
|
1214
|
+
* physical `BatchGetItem` op fires R2/R3/R5 with op kind `'BatchGetItem'`.
|
|
1215
|
+
*/
|
|
1216
|
+
type ReadRequestKind = 'query' | 'list' | 'batchGet';
|
|
1217
|
+
/**
|
|
1218
|
+
* The mutable request-level parameters R1 may observe / mutate. This is the
|
|
1219
|
+
* declarative read input — `key` / `select` / and per-call read options — NOT a
|
|
1220
|
+
* serialized spec. A hook may mutate these in place before key-resolution /
|
|
1221
|
+
* planning (R1).
|
|
1222
|
+
*
|
|
1223
|
+
* For a `batchGet` read (kind `'batchGet'`, issue #142) there is no single
|
|
1224
|
+
* `key` / `select` — the read spans multiple models/keys — so `key` / `select`
|
|
1225
|
+
* are empty placeholders and the mutable batch input lives on
|
|
1226
|
+
* {@link ReadParams.requests}; the library re-reads `requests` after R1 runs.
|
|
1227
|
+
*/
|
|
1228
|
+
interface ReadParams {
|
|
1229
|
+
/** The key input (PK / GSI fields). Mutable in R1. Empty `{}` for `batchGet`. */
|
|
1230
|
+
key: Record<string, unknown>;
|
|
1231
|
+
/** The select / projection spec (plain object or a `project(...)` builder). Mutable in R1. Empty `{}` for `batchGet`. */
|
|
1232
|
+
select: Record<string, unknown>;
|
|
1233
|
+
/**
|
|
1234
|
+
* The per-call read options (`consistentRead` / `maxDepth` / `limit` /
|
|
1235
|
+
* `after` / `order` / `filter` / `updatable` / …) for this read kind. Mutable
|
|
1236
|
+
* in R1. The library re-reads these after R1 runs.
|
|
1237
|
+
*/
|
|
1238
|
+
options: Record<string, unknown>;
|
|
1239
|
+
/**
|
|
1240
|
+
* Only for a `batchGet` read (issue #142): the mutable list of batch-get
|
|
1241
|
+
* requests (each `{ model, keys }`). A hook may add / drop / mutate requests
|
|
1242
|
+
* or their keys in place before the underlying `BatchGetItem` ops are issued;
|
|
1243
|
+
* the library re-reads this after R1 runs. `undefined` for `query` / `list`.
|
|
1244
|
+
*/
|
|
1245
|
+
requests?: unknown[];
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* R1 / R4 / R5 (request-level) context. `before` (R1) may mutate
|
|
1249
|
+
* {@link ReadParams} and may `throw` to cancel the whole read; `afterFetch` (R4)
|
|
1250
|
+
* receives the final hydrated, relation-merged result and may return a
|
|
1251
|
+
* replacement; `onError` (R5) sees a request-level failure.
|
|
1252
|
+
*/
|
|
1253
|
+
interface ReadRequestCtx extends CtxBase {
|
|
1254
|
+
readonly kind: ReadRequestKind;
|
|
1255
|
+
/** Mutable in R1 (request entry, before key-resolution / plan). */
|
|
1256
|
+
params: ReadParams;
|
|
1257
|
+
}
|
|
1258
|
+
/** The physical op kinds an {@link ReadOpCtx} may carry (R2 / R3 / R5). */
|
|
1259
|
+
type ReadOpKind = 'GetItem' | 'Query' | 'BatchGetItem';
|
|
1260
|
+
/**
|
|
1261
|
+
* R2 / R3 / R5 (op-level) context — fires for the root read AND for every
|
|
1262
|
+
* relation fan-out fetch (incl. nested recursion). `before` (R2) may mutate
|
|
1263
|
+
* {@link ReadOpCtx.operation} before it is sent and may `throw` to cancel;
|
|
1264
|
+
* `afterFetch` (R3) receives the op's raw items and may return a replacement
|
|
1265
|
+
* array; `onError` (R5) sees the op-level failure.
|
|
1266
|
+
*/
|
|
1267
|
+
interface ReadOpCtx extends CtxBase {
|
|
1268
|
+
readonly kind: ReadOpKind;
|
|
1269
|
+
/** The physical operation about to be sent. Mutable in R2. */
|
|
1270
|
+
operation: DynamoDBOperation;
|
|
1271
|
+
/**
|
|
1272
|
+
* The relation path from the root read to this op: `[]` for the root read,
|
|
1273
|
+
* `['orders']` for a direct relation fetch, `['orders', 'product']` for a
|
|
1274
|
+
* nested one. Lets a hook scope behavior to a specific fan-out leg.
|
|
1275
|
+
*/
|
|
1276
|
+
readonly relationPath: readonly string[];
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* A registered read middleware object. Any subset of the read hook points may
|
|
1280
|
+
* be set; an unset hook is simply skipped. All hooks may be synchronous or
|
|
1281
|
+
* return a `Promise` — the runtime always `await`s (async-first, see proposal
|
|
1282
|
+
* "sync / async").
|
|
1283
|
+
*
|
|
1284
|
+
* @see docs/proposals/read-middleware.md (the write hooks W1–W5 are a later phase)
|
|
1285
|
+
*/
|
|
1286
|
+
interface Middleware {
|
|
1287
|
+
/** Optional name (for host-side debugging / ordering introspection). */
|
|
1288
|
+
name?: string;
|
|
1289
|
+
read?: {
|
|
1290
|
+
/** R1 — request entry, before key-resolution / plan. May mutate `ctx.params`; `throw` cancels. */
|
|
1291
|
+
before?(ctx: ReadRequestCtx): void | Promise<void>;
|
|
1292
|
+
/** R4 — final hydrated, relation-merged result. Returns the (possibly replaced) result. */
|
|
1293
|
+
afterFetch?<T>(ctx: ReadRequestCtx, result: T): T | Promise<T>;
|
|
1294
|
+
op?: {
|
|
1295
|
+
/** R2 — each physical op, before send. May mutate `ctx.operation`; `throw` cancels. */
|
|
1296
|
+
before?(ctx: ReadOpCtx): void | Promise<void>;
|
|
1297
|
+
/** R3 — each physical op's raw items. Returns the (possibly replaced) items. */
|
|
1298
|
+
afterFetch?(ctx: ReadOpCtx, items: Item[]): Item[] | Promise<Item[]>;
|
|
1299
|
+
/**
|
|
1300
|
+
* R5 (op-level) — a physical op failed. Runs LIFO. **Recover** by RETURNING
|
|
1301
|
+
* an `Item[]`: those become this op's items and the read pipeline continues
|
|
1302
|
+
* (the first hook that returns a value wins and short-circuits the chain).
|
|
1303
|
+
* Return `void` / `undefined` to decline — if no hook recovers, the original
|
|
1304
|
+
* error rethrows. (See proposal R5 + appendix A — hooks are unrestricted.)
|
|
1305
|
+
*/
|
|
1306
|
+
onError?(ctx: ReadOpCtx, err: unknown): void | Item[] | Promise<void | Item[]>;
|
|
1307
|
+
};
|
|
1308
|
+
/**
|
|
1309
|
+
* R5 (request-level) — the read failed. Runs LIFO. **Recover** by RETURNING a
|
|
1310
|
+
* value: it becomes the read's result in place of throwing (the first hook
|
|
1311
|
+
* that returns a non-`undefined` value wins and short-circuits the chain).
|
|
1312
|
+
* Return `void` / `undefined` to decline — if no hook recovers, the original
|
|
1313
|
+
* error rethrows. The returned value is the read's resolved value verbatim, so
|
|
1314
|
+
* its shape is the host's responsibility (e.g. `null` / an item for `query`, a
|
|
1315
|
+
* `{ items, cursor }` for `list`).
|
|
1316
|
+
*/
|
|
1317
|
+
onError?(ctx: ReadRequestCtx, err: unknown): unknown;
|
|
1318
|
+
};
|
|
1319
|
+
/**
|
|
1320
|
+
* The write hook points W1–W5 (issue #50 write path, #139). Any subset may be
|
|
1321
|
+
* set; one registered object may carry read and/or write hooks. See
|
|
1322
|
+
* {@link WriteMiddleware}.
|
|
1323
|
+
*/
|
|
1324
|
+
write?: WriteMiddleware;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
781
1327
|
/**
|
|
782
1328
|
* A top-level `select` may be either a plain projection (`SelectableOf<T>`) or
|
|
783
1329
|
* a {@link SelectBuilder} produced by `Model.project(...)`. The builder is
|
|
@@ -847,6 +1393,13 @@ type ListCallOptions<T> = {
|
|
|
847
1393
|
* `& Updatable`, so it can be passed straight back to `updateItem()`.
|
|
848
1394
|
*/
|
|
849
1395
|
updatable?: boolean;
|
|
1396
|
+
/**
|
|
1397
|
+
* Host-injected per-call read context (issue #50 / #138) — passed to every
|
|
1398
|
+
* registered read hook as `ctx.context` and threaded to every relation
|
|
1399
|
+
* fan-out op. A host-language value, never serialized (the bridge #48 is
|
|
1400
|
+
* unaffected). Absent ⇒ `{}`.
|
|
1401
|
+
*/
|
|
1402
|
+
context?: RequestContext;
|
|
850
1403
|
};
|
|
851
1404
|
/**
|
|
852
1405
|
* Public, type-inferring API surface produced by {@link DDBModel.asModel}.
|
|
@@ -914,6 +1467,8 @@ interface ModelStatic<T extends DDBModel, C = unknown> {
|
|
|
914
1467
|
maxDepth?: number;
|
|
915
1468
|
updatable?: boolean;
|
|
916
1469
|
hydrate: (raw: QueryResult<T, ProjectionOf<T, Sel>>) => R;
|
|
1470
|
+
/** Host-injected per-call read context (issue #50 / #138); see {@link ListCallOptions.context}. */
|
|
1471
|
+
context?: RequestContext;
|
|
917
1472
|
}): Promise<R | null>;
|
|
918
1473
|
/**
|
|
919
1474
|
* Fetch a single item by a unique key, requesting an **updatable** result.
|
|
@@ -927,6 +1482,8 @@ interface ModelStatic<T extends DDBModel, C = unknown> {
|
|
|
927
1482
|
consistentRead?: boolean;
|
|
928
1483
|
maxDepth?: number;
|
|
929
1484
|
updatable: true;
|
|
1485
|
+
/** Host-injected per-call read context (issue #50 / #138); see {@link ListCallOptions.context}. */
|
|
1486
|
+
context?: RequestContext;
|
|
930
1487
|
}): Promise<(QueryResult<T, ProjectionOf<T, Sel>> & Updatable) | null>;
|
|
931
1488
|
/**
|
|
932
1489
|
* Fetch a single item by a unique key. The return type contains only the
|
|
@@ -936,6 +1493,8 @@ interface ModelStatic<T extends DDBModel, C = unknown> {
|
|
|
936
1493
|
consistentRead?: boolean;
|
|
937
1494
|
maxDepth?: number;
|
|
938
1495
|
updatable?: false;
|
|
1496
|
+
/** Host-injected per-call read context (issue #50 / #138); see {@link ListCallOptions.context}. */
|
|
1497
|
+
context?: RequestContext;
|
|
939
1498
|
}): Promise<QueryResult<T, ProjectionOf<T, Sel>> | null>;
|
|
940
1499
|
/**
|
|
941
1500
|
* List items for a partition, symmetric with {@link ModelStatic.query}:
|
|
@@ -985,213 +1544,6 @@ interface ModelStatic<T extends DDBModel, C = unknown> {
|
|
|
985
1544
|
deleteItem(key: DeleteKey<C>, options?: WriteOptions<T>): Promise<void>;
|
|
986
1545
|
}
|
|
987
1546
|
|
|
988
|
-
interface UpdateInput {
|
|
989
|
-
TableName: string;
|
|
990
|
-
Key: Record<string, unknown>;
|
|
991
|
-
UpdateExpression: string;
|
|
992
|
-
ExpressionAttributeNames: Record<string, string>;
|
|
993
|
-
ExpressionAttributeValues?: Record<string, unknown>;
|
|
994
|
-
ConditionExpression?: string;
|
|
995
|
-
}
|
|
996
|
-
declare function buildUpdateInput(modelClass: Function, entity: Record<string, unknown>, changes: Record<string, unknown>, options?: UpdateOptions): UpdateInput;
|
|
997
|
-
declare function executeUpdate(modelClass: Function, entity: Record<string, unknown>, changes: Record<string, unknown>, options?: UpdateOptions): Promise<void>;
|
|
998
|
-
|
|
999
|
-
interface DeleteInput {
|
|
1000
|
-
TableName: string;
|
|
1001
|
-
Key: Record<string, unknown>;
|
|
1002
|
-
ConditionExpression?: string;
|
|
1003
|
-
ExpressionAttributeNames?: Record<string, string>;
|
|
1004
|
-
ExpressionAttributeValues?: Record<string, unknown>;
|
|
1005
|
-
}
|
|
1006
|
-
declare function buildDeleteInput(modelClass: Function, keyObj: Record<string, unknown>, options?: DeleteOptions): DeleteInput;
|
|
1007
|
-
declare function executeDelete(modelClass: Function, keyObj: Record<string, unknown>, options?: DeleteOptions): Promise<void>;
|
|
1008
|
-
|
|
1009
|
-
/** Result of a read operation (GetItem / Query / BatchGetItem). */
|
|
1010
|
-
interface ExecutorResult {
|
|
1011
|
-
items: Record<string, unknown>[];
|
|
1012
|
-
lastEvaluatedKey?: Record<string, unknown>;
|
|
1013
|
-
}
|
|
1014
|
-
/**
|
|
1015
|
-
* Result of a single structured write. `oldItem` is the pre-write image,
|
|
1016
|
-
* present only when the caller requested it (`returnOldImage: true`, mapped to
|
|
1017
|
-
* DynamoDB `ReturnValues: ALL_OLD`) and an item existed before the write. The
|
|
1018
|
-
* write-capture seam (issue #72) reads it to derive INSERT vs MODIFY and the
|
|
1019
|
-
* REMOVE OldImage.
|
|
1020
|
-
*/
|
|
1021
|
-
interface WriteResult {
|
|
1022
|
-
oldItem?: Record<string, unknown>;
|
|
1023
|
-
}
|
|
1024
|
-
/**
|
|
1025
|
-
* A per-call retry override threaded down to {@link RetryingExecutor} (issue
|
|
1026
|
-
* #111). `undefined` ⇒ use the globally-configured (or default) policy; a
|
|
1027
|
-
* {@link RetryPolicy} ⇒ use that for this call; `false` ⇒ disable retry for this
|
|
1028
|
-
* call. The default {@link DynamoExecutor} and the test `MemoryExecutor` ignore
|
|
1029
|
-
* it — only {@link RetryingExecutor} acts on it.
|
|
1030
|
-
*/
|
|
1031
|
-
type RetryOverride = RetryPolicy | false;
|
|
1032
|
-
/**
|
|
1033
|
-
* Per-call options for the READ path (issue #111). Carries the per-op retry
|
|
1034
|
-
* override down to {@link RetryingExecutor}. Extended (rather than passing the
|
|
1035
|
-
* override positionally) so future per-call read knobs have a home.
|
|
1036
|
-
*/
|
|
1037
|
-
interface ReadExecOptions {
|
|
1038
|
-
/** Per-call retry override; see {@link RetryOverride}. */
|
|
1039
|
-
retry?: RetryOverride;
|
|
1040
|
-
}
|
|
1041
|
-
/** Options shared by the single-item structured write methods. */
|
|
1042
|
-
interface WriteExecOptions {
|
|
1043
|
-
/** Request the pre-write image (DynamoDB `ReturnValues: ALL_OLD`). */
|
|
1044
|
-
returnOldImage?: boolean;
|
|
1045
|
-
/** Per-call retry override (issue #111); see {@link RetryOverride}. */
|
|
1046
|
-
retry?: RetryOverride;
|
|
1047
|
-
}
|
|
1048
|
-
/** Per-call options for the batch / transact paths (issue #111). */
|
|
1049
|
-
interface BatchExecOptions {
|
|
1050
|
-
/** Per-call retry override; see {@link RetryOverride}. */
|
|
1051
|
-
retry?: RetryOverride;
|
|
1052
|
-
}
|
|
1053
|
-
/**
|
|
1054
|
-
* One BatchGetItem sub-request: a single physical table plus its keys and an
|
|
1055
|
-
* optional projection. Mirrors {@link import('../planner/types.js').BatchGetItemOperation}
|
|
1056
|
-
* without the discriminant `type` field, so callers that already chunked keys
|
|
1057
|
-
* (relation traversal) and the planner-driven read path share one entry point.
|
|
1058
|
-
*/
|
|
1059
|
-
interface BatchGetExecInput {
|
|
1060
|
-
tableName: string;
|
|
1061
|
-
keys: Record<string, unknown>[];
|
|
1062
|
-
projectionExpression?: string;
|
|
1063
|
-
expressionAttributeNames?: Record<string, string>;
|
|
1064
|
-
consistentRead?: boolean;
|
|
1065
|
-
}
|
|
1066
|
-
/** A single item in a {@link Executor.batchWrite} request, grouped by table. */
|
|
1067
|
-
type BatchWriteExecItem = {
|
|
1068
|
-
type: 'put';
|
|
1069
|
-
item: Record<string, unknown>;
|
|
1070
|
-
} | {
|
|
1071
|
-
type: 'delete';
|
|
1072
|
-
key: Record<string, unknown>;
|
|
1073
|
-
};
|
|
1074
|
-
/**
|
|
1075
|
-
* A read-only `ConditionCheck` entry for {@link Executor.transactWrite} (issue
|
|
1076
|
-
* #81): it asserts a `ConditionExpression` holds for the keyed item without
|
|
1077
|
-
* mutating it. A failed assertion cancels the **whole** `TransactWriteItems`
|
|
1078
|
-
* atomically — the foundation for referential-integrity derivation.
|
|
1079
|
-
*/
|
|
1080
|
-
interface ConditionCheckInput {
|
|
1081
|
-
TableName: string;
|
|
1082
|
-
Key: Record<string, unknown>;
|
|
1083
|
-
ConditionExpression: string;
|
|
1084
|
-
ExpressionAttributeNames?: Record<string, string>;
|
|
1085
|
-
ExpressionAttributeValues?: Record<string, unknown>;
|
|
1086
|
-
}
|
|
1087
|
-
/**
|
|
1088
|
-
* A `{ Put | Update | Delete | ConditionCheck }` entry for
|
|
1089
|
-
* {@link Executor.transactWrite}. The first three mutate an item; `ConditionCheck`
|
|
1090
|
-
* (issue #81) is a read-only assertion on another item.
|
|
1091
|
-
*/
|
|
1092
|
-
type TransactWriteExecItem = {
|
|
1093
|
-
Put: PutInput;
|
|
1094
|
-
} | {
|
|
1095
|
-
Update: UpdateInput;
|
|
1096
|
-
} | {
|
|
1097
|
-
Delete: DeleteInput;
|
|
1098
|
-
} | {
|
|
1099
|
-
ConditionCheck: ConditionCheckInput;
|
|
1100
|
-
};
|
|
1101
|
-
/**
|
|
1102
|
-
* The unified I/O seam (issue #76). All of GraphDDB's read and write I/O is
|
|
1103
|
-
* funneled through one injectable executor so the engine (planner / hydrator /
|
|
1104
|
-
* relation traversal / write paths) can run unchanged against either real
|
|
1105
|
-
* DynamoDB ({@link DynamoExecutor}, the default) or an in-process memory store
|
|
1106
|
-
* (`MemoryExecutor`, the test adapter).
|
|
1107
|
-
*
|
|
1108
|
-
* Reads take a structured {@link DynamoDBOperation}; writes take the structured
|
|
1109
|
-
* inputs the operation layer already builds (`PutInput` / `UpdateInput` / …),
|
|
1110
|
-
* never an AWS SDK command. This keeps the seam at the *structured operation
|
|
1111
|
-
* boundary* (proposal option B): no expression-string parsing is required to
|
|
1112
|
-
* implement a fake.
|
|
1113
|
-
*/
|
|
1114
|
-
interface Executor {
|
|
1115
|
-
/**
|
|
1116
|
-
* Read path: GetItem / Query / BatchGetItem. The optional {@link ReadExecOptions}
|
|
1117
|
-
* carries a per-call retry override (issue #111); the default
|
|
1118
|
-
* {@link DynamoExecutor} and `MemoryExecutor` ignore it, only `RetryingExecutor`
|
|
1119
|
-
* acts on it.
|
|
1120
|
-
*/
|
|
1121
|
-
execute(operation: DynamoDBOperation, options?: ReadExecOptions): Promise<ExecutorResult>;
|
|
1122
|
-
/**
|
|
1123
|
-
* BatchGetItem for a single table. The caller is responsible for chunking
|
|
1124
|
-
* keys ≤100 (the relation traversal and the planner-driven path both do).
|
|
1125
|
-
*/
|
|
1126
|
-
batchGet(input: BatchGetExecInput, options?: ReadExecOptions): Promise<ExecutorResult>;
|
|
1127
|
-
/** Put one item. */
|
|
1128
|
-
put(input: PutInput, options?: WriteExecOptions): Promise<WriteResult>;
|
|
1129
|
-
/** Update one item (applies its structured UpdateExpression). */
|
|
1130
|
-
update(input: UpdateInput, options?: WriteExecOptions): Promise<WriteResult>;
|
|
1131
|
-
/** Delete one item. */
|
|
1132
|
-
delete(input: DeleteInput, options?: WriteExecOptions): Promise<WriteResult>;
|
|
1133
|
-
/**
|
|
1134
|
-
* BatchWriteItem for a single table (non-atomic). Keys/items are chunked ≤25
|
|
1135
|
-
* with UnprocessedItems retry by the implementation.
|
|
1136
|
-
*/
|
|
1137
|
-
batchWrite(tableName: string, items: BatchWriteExecItem[], options?: BatchExecOptions): Promise<void>;
|
|
1138
|
-
/** TransactWriteItems — all-or-nothing atomic. */
|
|
1139
|
-
transactWrite(items: TransactWriteExecItem[], options?: BatchExecOptions): Promise<void>;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
interface PutOptions<T = unknown> {
|
|
1143
|
-
condition?: WriteCondition<T>;
|
|
1144
|
-
/**
|
|
1145
|
-
* Per-call throttle / transient-error retry override (issue #111). A
|
|
1146
|
-
* {@link RetryPolicy} replaces the global policy for this call; `false` disables
|
|
1147
|
-
* retry for this call. Omit to use the configured (or built-in default) policy.
|
|
1148
|
-
*/
|
|
1149
|
-
retry?: RetryOverride;
|
|
1150
|
-
}
|
|
1151
|
-
interface UpdateOptions<T = unknown> {
|
|
1152
|
-
condition?: WriteCondition<T>;
|
|
1153
|
-
/**
|
|
1154
|
-
* Per-call throttle / transient-error retry override (issue #111). A
|
|
1155
|
-
* {@link RetryPolicy} replaces the global policy for this call; `false` disables
|
|
1156
|
-
* retry for this call.
|
|
1157
|
-
*/
|
|
1158
|
-
retry?: RetryOverride;
|
|
1159
|
-
/**
|
|
1160
|
-
* How to re-derive a GSI key whose composing fields are changed but **not all**
|
|
1161
|
-
* available from `{ ...key, ...changes }` (issue #115).
|
|
1162
|
-
*
|
|
1163
|
-
* - **unset (default)** — refuse with an explicit error rather than let the
|
|
1164
|
-
* index silently rot. The error names the index, the changed field, and the
|
|
1165
|
-
* missing field(s). The happy path (all composing fields available) re-derives
|
|
1166
|
-
* in the SAME `UpdateExpression` and is unaffected by this option.
|
|
1167
|
-
* - `'read-modify-write'` — read the current item, merge `{ ...item, ...changes }`,
|
|
1168
|
-
* re-derive every affected GSI key from the merged image, and write back under
|
|
1169
|
-
* an optimistic condition (the item must still exist / be unchanged). This costs
|
|
1170
|
-
* one extra read and is NOT atomic with the original update, but always re-derives
|
|
1171
|
-
* correctly.
|
|
1172
|
-
*/
|
|
1173
|
-
rederive?: 'read-modify-write';
|
|
1174
|
-
}
|
|
1175
|
-
interface DeleteOptions<T = unknown> {
|
|
1176
|
-
condition?: WriteCondition<T>;
|
|
1177
|
-
/**
|
|
1178
|
-
* Per-call throttle / transient-error retry override (issue #111). A
|
|
1179
|
-
* {@link RetryPolicy} replaces the global policy for this call; `false` disables
|
|
1180
|
-
* retry for this call.
|
|
1181
|
-
*/
|
|
1182
|
-
retry?: RetryOverride;
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
interface PutInput {
|
|
1186
|
-
TableName: string;
|
|
1187
|
-
Item: Record<string, unknown>;
|
|
1188
|
-
ConditionExpression?: string;
|
|
1189
|
-
ExpressionAttributeNames?: Record<string, string>;
|
|
1190
|
-
ExpressionAttributeValues?: Record<string, unknown>;
|
|
1191
|
-
}
|
|
1192
|
-
declare function buildPutInput(modelClass: Function, item: Record<string, unknown>, options?: PutOptions): PutInput;
|
|
1193
|
-
declare function executePut(modelClass: Function, item: Record<string, unknown>, options?: PutOptions): Promise<void>;
|
|
1194
|
-
|
|
1195
1547
|
type TransactWriteItemInput = {
|
|
1196
1548
|
Put: PutInput;
|
|
1197
1549
|
} | {
|
|
@@ -1218,9 +1570,32 @@ interface TransactCaptureMeta {
|
|
|
1218
1570
|
};
|
|
1219
1571
|
newItem?: Record<string, unknown>;
|
|
1220
1572
|
}
|
|
1573
|
+
/**
|
|
1574
|
+
* One recorded logical write op of an imperative {@link TransactionContext}
|
|
1575
|
+
* (issue #139). Captured at `tx.put/update/delete` call time so the write hooks
|
|
1576
|
+
* W1 (`write.before`) can run on each op — and rebuild its physical item from the
|
|
1577
|
+
* possibly-mutated input — before the batch composes / commits. A `conditionCheck`
|
|
1578
|
+
* records NO logical op (it is a read-only assertion, not a logical write).
|
|
1579
|
+
*/
|
|
1580
|
+
interface LogicalWriteOp {
|
|
1581
|
+
kind: WriteKind;
|
|
1582
|
+
modelClass: Function;
|
|
1583
|
+
item?: Record<string, unknown>;
|
|
1584
|
+
key?: Record<string, unknown>;
|
|
1585
|
+
changes?: Record<string, unknown>;
|
|
1586
|
+
options?: PutOptions & UpdateOptions & DeleteOptions;
|
|
1587
|
+
}
|
|
1221
1588
|
declare class TransactionContext {
|
|
1222
1589
|
private readonly items;
|
|
1223
1590
|
private readonly captureMeta;
|
|
1591
|
+
/**
|
|
1592
|
+
* The logical write ops, parallel to {@link items} but EXCLUDING `conditionCheck`
|
|
1593
|
+
* entries (those are read-only assertions, recorded only in `items`). Used by the
|
|
1594
|
+
* write-hook path (#139) to run W1 on each logical op and recompose the batch.
|
|
1595
|
+
* A `null` entry marks an `items` slot that has no logical op (a ConditionCheck),
|
|
1596
|
+
* so the eager and logical arrays can be re-aligned at commit.
|
|
1597
|
+
*/
|
|
1598
|
+
private readonly logicalOps;
|
|
1224
1599
|
get itemCount(): number;
|
|
1225
1600
|
put(model: ModelStatic<DDBModel>, item: Record<string, unknown>, options?: PutOptions): void;
|
|
1226
1601
|
update(model: ModelStatic<DDBModel>, entity: Record<string, unknown>, changes: Record<string, unknown>, options?: UpdateOptions): void;
|
|
@@ -1242,16 +1617,35 @@ declare class TransactionContext {
|
|
|
1242
1617
|
}): void;
|
|
1243
1618
|
/** @internal */
|
|
1244
1619
|
getTransactItems(): TransactWriteItemInput[];
|
|
1620
|
+
/** @internal — the recorded logical write ops (issue #139 W1), `null` per ConditionCheck slot. */
|
|
1621
|
+
getLogicalOps(): readonly (LogicalWriteOp | null)[];
|
|
1245
1622
|
/** @internal — capture descriptors for the write-capture seam (issue #72). */
|
|
1246
1623
|
getCaptureMeta(): TransactCaptureMeta[];
|
|
1247
1624
|
private assertWithinLimit;
|
|
1248
1625
|
}
|
|
1249
|
-
declare function executeTransaction(fn: (tx: TransactionContext) => void | Promise<void
|
|
1626
|
+
declare function executeTransaction(fn: (tx: TransactionContext) => void | Promise<void>, options?: {
|
|
1627
|
+
context?: RequestContext;
|
|
1628
|
+
}): Promise<void>;
|
|
1250
1629
|
|
|
1251
1630
|
interface BatchGetRequest {
|
|
1252
1631
|
model: ModelStatic<DDBModel>;
|
|
1253
1632
|
keys: Record<string, unknown>[];
|
|
1254
1633
|
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Per-call options for {@link DDBModel.batchGet} (issue #142).
|
|
1636
|
+
*/
|
|
1637
|
+
interface BatchGetOptions {
|
|
1638
|
+
/**
|
|
1639
|
+
* Host-injected per-call read context (issue #50 / #138 / #142) — exposed to
|
|
1640
|
+
* every read hook (R1/R4/R5 at the `batchGet` request level, R2/R3/R5 on each
|
|
1641
|
+
* underlying `BatchGetItem` op) as `ctx.context`, and threaded UNCHANGED to
|
|
1642
|
+
* every physical op so a global hook (e.g. a tenant-scope R2 FilterExpression
|
|
1643
|
+
* or an observability probe) applies across the whole multi-key batch read. A
|
|
1644
|
+
* host-language value, NEVER serialized into the SSoT / `operations.json` (the
|
|
1645
|
+
* bridge #48 is unaffected). Absent ⇒ `{}`.
|
|
1646
|
+
*/
|
|
1647
|
+
context?: RequestContext;
|
|
1648
|
+
}
|
|
1255
1649
|
interface BatchPutRequest {
|
|
1256
1650
|
type: 'put';
|
|
1257
1651
|
model: ModelStatic<DDBModel>;
|
|
@@ -1270,7 +1664,23 @@ declare class BatchGetResult {
|
|
|
1270
1664
|
constructor(groups: Map<Function, Record<string, unknown>[]>);
|
|
1271
1665
|
get<T extends DDBModel>(model: ModelStatic<T>): Partial<T>[];
|
|
1272
1666
|
}
|
|
1273
|
-
|
|
1667
|
+
/**
|
|
1668
|
+
* The multi-key, multi-model batch-read core (issue #142). Wraps the request
|
|
1669
|
+
* entry in the request-level read hooks R1 (`read.before`) / R4
|
|
1670
|
+
* (`read.afterFetch`) / R5 (`read.onError`) with request kind `'batchGet'`, and
|
|
1671
|
+
* each underlying physical `BatchGetItem` op (per table/chunk) in R2/R3/R5 via
|
|
1672
|
+
* {@link executeBatchGetForTable}. The read middleware runtime is built ONCE here
|
|
1673
|
+
* from `options.context` and threaded UNCHANGED to every op, so a global hook
|
|
1674
|
+
* (e.g. a tenant-scope R2 FilterExpression) applies across the whole batch.
|
|
1675
|
+
*
|
|
1676
|
+
* R1 sees the mutable batch `requests` on `ctx.params.requests`; the library
|
|
1677
|
+
* re-reads them after R1 runs, so a hook may add / drop / mutate requests before
|
|
1678
|
+
* any op is issued and may `throw` to cancel the whole batch. R4 may transform /
|
|
1679
|
+
* replace the assembled {@link BatchGetResult}; R5 may recover by returning one.
|
|
1680
|
+
* With no middleware registered the shared `NO_MIDDLEWARE` runtime keeps the hot
|
|
1681
|
+
* path unchanged (the zero-overhead fast path).
|
|
1682
|
+
*/
|
|
1683
|
+
declare function executeBatchGet(requests: BatchGetRequest[], options?: BatchGetOptions): Promise<BatchGetResult>;
|
|
1274
1684
|
declare function executeBatchWrite(requests: BatchWriteRequest[]): Promise<void>;
|
|
1275
1685
|
|
|
1276
1686
|
/**
|
|
@@ -4391,6 +4801,13 @@ interface ReadRouteOptions {
|
|
|
4391
4801
|
readonly after?: string;
|
|
4392
4802
|
readonly order?: 'ASC' | 'DESC';
|
|
4393
4803
|
readonly filter?: Record<string, unknown>;
|
|
4804
|
+
/**
|
|
4805
|
+
* Host-injected per-call read context (issue #50 / #138). Threaded into the
|
|
4806
|
+
* route's underlying read (`executeQuery` / `executeList`), so the read hooks
|
|
4807
|
+
* R1–R5 fire for the route with this `ctx.context`. Each route runs
|
|
4808
|
+
* independently, so its hooks see only its own context. Absent ⇒ `{}`.
|
|
4809
|
+
*/
|
|
4810
|
+
readonly context?: RequestContext;
|
|
4394
4811
|
}
|
|
4395
4812
|
/** One read route: a `query` (point/unique) or a `list` (partition) descriptor. */
|
|
4396
4813
|
interface ReadRouteDescriptor {
|
|
@@ -4447,6 +4864,13 @@ interface MutateOptions {
|
|
|
4447
4864
|
* built-in default policy.
|
|
4448
4865
|
*/
|
|
4449
4866
|
readonly retry?: RetryOverride;
|
|
4867
|
+
/**
|
|
4868
|
+
* Host-injected per-call write context (issue #50 / #139) — exposed to every
|
|
4869
|
+
* write hook (W1–W5) as `ctx.context`. In `transaction` mode every composed op
|
|
4870
|
+
* shares it and the persist hooks fire once for the atomic batch; in `parallel`
|
|
4871
|
+
* mode each independent op sees it. NEVER serialized. Absent ⇒ `{}`.
|
|
4872
|
+
*/
|
|
4873
|
+
readonly context?: RequestContext;
|
|
4450
4874
|
}
|
|
4451
4875
|
/** A per-alias result in `parallel` mode: success carries the read-back, else error. */
|
|
4452
4876
|
type ParallelOpResult = {
|
|
@@ -4548,7 +4972,33 @@ declare abstract class DDBModel {
|
|
|
4548
4972
|
* for that call (`false` disables retry).
|
|
4549
4973
|
*/
|
|
4550
4974
|
static setRetryPolicy(policy: RetryPolicy | null): void;
|
|
4551
|
-
|
|
4975
|
+
/**
|
|
4976
|
+
* Register a {@link Middleware} (issue #50; read path #138, write path #139).
|
|
4977
|
+
* One registered object may carry read and/or write hooks.
|
|
4978
|
+
*
|
|
4979
|
+
* - **Read** R1–R5 — request entry (`read.before`), each physical op before send
|
|
4980
|
+
* / after raw fetch (`read.op.before` / `read.op.afterFetch`, INCLUDING every
|
|
4981
|
+
* relation fan-out fetch), the final hydrated result (`read.afterFetch`), and on
|
|
4982
|
+
* error (`read.op.onError` / `read.onError`).
|
|
4983
|
+
* - **Write** W1–W5 — the logical write before effect derivation (`write.before`,
|
|
4984
|
+
* may mutate `ctx.input` / `ctx.kind` incl. a delete→update rewrite), after commit
|
|
4985
|
+
* (`write.after`), the physical persist on the fully composed batch
|
|
4986
|
+
* (`write.persist.before` / `write.persist.after`, fires ONCE per atomic
|
|
4987
|
+
* transaction), and on error (`write.persist.onError` / `write.onError`).
|
|
4988
|
+
*
|
|
4989
|
+
* Hooks may observe, mutate `ctx`, `throw` to cancel, or (on `onError`) recover by
|
|
4990
|
+
* returning a value; the library imposes no semantics. Ordering: `before*` runs
|
|
4991
|
+
* first-registered-first (FIFO); `after*` / `onError` run last-registered-first
|
|
4992
|
+
* (LIFO). Mirrors {@link setRetryPolicy} — a host-runtime global stored on
|
|
4993
|
+
* {@link ClientManager}; never serialized (the bridge #48 is unaffected). Per-call
|
|
4994
|
+
* host context flows in via the read's / write's `{ context }` option.
|
|
4995
|
+
*/
|
|
4996
|
+
static use(mw: Middleware): void;
|
|
4997
|
+
/** Remove every registered middleware (read AND write; teardown / tests). See {@link use}. */
|
|
4998
|
+
static clearMiddleware(): void;
|
|
4999
|
+
static transaction(fn: (tx: TransactionContext) => void | Promise<void>, options?: {
|
|
5000
|
+
context?: RequestContext;
|
|
5001
|
+
}): Promise<void>;
|
|
4552
5002
|
/**
|
|
4553
5003
|
* In-process multi-route READ (issue #101 — the unified envelope). Each alias
|
|
4554
5004
|
* route (`{ query | list: Model, key, select, options? }`) runs **independently
|
|
@@ -4576,7 +5026,19 @@ declare abstract class DDBModel {
|
|
|
4576
5026
|
static mutate<const E extends WriteEnvelope>(envelope: E, options: {
|
|
4577
5027
|
mode: 'parallel';
|
|
4578
5028
|
}): Promise<MutateParallelResult<E>>;
|
|
4579
|
-
|
|
5029
|
+
/**
|
|
5030
|
+
* Multi-key, multi-model batch read. Each {@link BatchGetRequest} contributes its
|
|
5031
|
+
* keys to a chunked `BatchGetItem` per physical table; results are re-grouped by
|
|
5032
|
+
* model on the returned {@link BatchGetResult}.
|
|
5033
|
+
*
|
|
5034
|
+
* Fires the read hooks (issue #142): request-level R1/R4/R5 with kind
|
|
5035
|
+
* `'batchGet'`, and op-level R2/R3/R5 for each underlying physical `BatchGetItem`
|
|
5036
|
+
* op. The optional `{ context }` is exposed to every hook as `ctx.context` and
|
|
5037
|
+
* threaded UNCHANGED to every op (absent ⇒ `{}`), so a global hook (e.g. a
|
|
5038
|
+
* tenant-scope R2 FilterExpression) applies across the whole batch. With no
|
|
5039
|
+
* middleware registered the read path is unchanged (zero-overhead fast path).
|
|
5040
|
+
*/
|
|
5041
|
+
static batchGet(requests: BatchGetRequest[], options?: BatchGetOptions): Promise<BatchGetResult>;
|
|
4580
5042
|
static batchWrite(requests: BatchWriteRequest[]): Promise<void>;
|
|
4581
5043
|
static asModel<C extends new (...args: never[]) => DDBModel>(this: C): ModelStatic<InstanceType<C>, C>;
|
|
4582
5044
|
}
|
|
@@ -4820,4 +5282,4 @@ interface CdcEmulatorOptions {
|
|
|
4820
5282
|
}
|
|
4821
5283
|
type ShardId = string;
|
|
4822
5284
|
|
|
4823
|
-
export { type
|
|
5285
|
+
export { type EntityRef as $, type ConcurrentRecomputeRef as A, type BatchGetExecInput as B, type ChangeEvent as C, type DynamoDBOperation as D, type Executor as E, type FaultSpec as F, type EventLog as G, type ReplayOptions as H, type Item as I, type ShardId as J, type TransactionItemSpec as K, type Param as L, type ModelStatic as M, type ParamDescriptor as N, type DefinitionMap as O, type PutInput as P, type OperationDefinition as Q, type ReadExecOptions as R, type SelectableOf as S, type TransactWriteExecItem as T, type UpdateInput as U, type WriteDefinitionOptions as V, type WriteExecOptions as W, type PartialQueryKeyOf as X, type StrictSelectSpec as Y, type EntityInput as Z, type UniqueQueryKeyOf as _, type ExecutorResult as a, type DerivedUpdate as a$, type ConditionInput as a0, type QueryModelContract as a1, type QueryMethodSpec as a2, type CommandModelContract as a3, type CommandMethodSpec as a4, type ContractSpec as a5, type QuerySpec as a6, type CommandSpec as a7, type ContextSpec as a8, type OperationsDocument as a9, type ComposeSpec as aA, type CondSlot as aB, type ConditionCheckInput as aC, type Connection as aD, type ContractCallSignature as aE, type ContractCardinality as aF, type ContractCommandParams as aG, type ContractCommandResult as aH, type ContractComposeNode as aI, type ContractFromRef as aJ, type ContractInputArity as aK, type ContractItem as aL, type ContractKeyFieldRef as aM, type ContractKeyInput as aN, type ContractKeyRef as aO, type ContractKeySpec as aP, type ContractKind as aQ, type ContractMethodOp as aR, type ContractParamRef as aS, type ContractQueryParams as aT, type ContractResolution as aU, type CtxBase as aV, DEFAULT_MAX_ATTEMPTS as aW, DEFAULT_RETRY_POLICY as aX, type DeleteOptions as aY, type DeriveEffect as aZ, type DerivedEdgeWrite as a_, type AnyOperationDefinition as aa, type BridgeBundle as ab, type ConditionSpec as ac, type BatchDeleteRequest as ad, type BatchGetOptions as ae, type BatchGetRequest as af, BatchGetResult as ag, type BatchPutRequest as ah, type BatchResult as ai, type BatchWriteRequest as aj, CONTRACT_RANGE_FANOUT_CONCURRENCY as ak, type CdcMode as al, type Change as am, type ChangeBatch as an, type ChangeEventName as ao, type ClockMode as ap, type Column as aq, type ColumnMap as ar, type CommandContractMethodSpec as as, type CommandInputShape as at, type CommandMethod as au, type CommandPlan as av, type CommandResolutionTarget as aw, type CommandResultKind as ax, type CommandSelectShape as ay, type CompiledFragment as az, type WriteResult as b, type ReadOpKind as b$, type DescriptorBinding as b0, ENTITY_WRITES_MARKER as b1, type EdgeEffect as b2, type EffectPath as b3, type EmitEffect as b4, type EntityWritesDefinition as b5, type EntityWritesShape as b6, type ExecutableCommandContract as b7, type ExecutableQueryContract as b8, type FilterInput as b9, type MutateParallelResult as bA, type MutateTransactionResult as bB, type MutationBody as bC, type MutationDescriptorMap as bD, type MutationFragment as bE, type MutationInputProxy as bF, type MutationInputRef as bG, type MutationIntent as bH, type NumberParam as bI, type OperationKind as bJ, type OperationSpec as bK, type ParallelOpResult as bL, type ParamKind as bM, type ParamSpec as bN, type ParamStructure as bO, type PersistCtx as bP, type PersistOrigin as bQ, type PlannedCommandMethod as bR, type PutOptions as bS, type QueryContractMethodSpec as bT, type QueryEnvelopeResult as bU, type QueryKeyOf as bV, type QueryMethod as bW, type QueryResult as bX, type RangeConditionSpec as bY, type ReadEnvelope as bZ, type ReadOpCtx as b_, type FilterSpec as ba, type FragmentInput as bb, type GsiDefinitionMarker as bc, type GsiOptions as bd, type IdempotencyEffect as be, type InProcessWriteDescriptor as bf, type InputArity as bg, type KeyDefinitionMarker as bh, type KeySegment as bi, type KeySlot as bj, type KeyStructure as bk, type KeyedResult as bl, LIFECYCLE_CONTRACT_MARKER as bm, type LifecycleContract as bn, type LifecycleEffects as bo, type LiteralParam as bp, type ManifestEntity as bq, type ManifestField as br, type ManifestFieldType as bs, type ManifestGsi as bt, type ManifestKey as bu, type ManifestRelation as bv, type ManifestTable as bw, type ModelRef as bx, type MutateMode as by, type MutateOptions as bz, type DeleteInput as c, isContractFromRef as c$, type ReadOperationType as c0, type ReadRouteDescriptor as c1, type ReadRouteOptions as c2, type ReadRouteResult as c3, type RecordedCompose as c4, type RelationBuilder as c5, type RelationSelect as c6, type RelationSpec as c7, type RequiresEffect as c8, type Resolution as c9, buildDeleteInput as cA, buildPutInput as cB, buildUpdateInput as cC, compileFragment as cD, compileMutationPlan as cE, compileSingleFragmentPlan as cF, cond as cG, contractOfMethodSpec as cH, definePlan as cI, entityWrites as cJ, executeBatchGet as cK, executeBatchWrite as cL, executeCommandMethod as cM, executeDelete as cN, executeKeyedBatchGet as cO, executePut as cP, executeQueryMethod as cQ, executeRangeFanout as cR, executeTransaction as cS, executeUpdate as cT, from as cU, getEntityWrites as cV, gsi as cW, isColumn as cX, isCommandModelContract as cY, isCommandPlan as cZ, isContractComposeNode as c_, type RetryInfo as ca, type RetryOperationKind as cb, SPEC_VERSION as cc, type SegmentSpec as cd, type SelectBuilder as ce, type SelectOf as cf, type StartingPosition as cg, type StreamViewType as ch, type StringParam as ci, TransactionContext as cj, type TransactionItemType as ck, type UniqueEffect as cl, type Updatable as cm, type UpdateOptions as cn, type WhenSpec as co, type WriteCtx as cp, type WriteDescriptor as cq, type WriteEnvelope as cr, type WriteInput as cs, type WriteKind as ct, type WriteLifecyclePhase as cu, type WriteMiddleware as cv, type WriteOperationType as cw, type WriteRecorder as cx, type WriteResultProjection as cy, attachModelClass as cz, type BatchWriteExecItem as d, isContractKeyFieldRef as d0, isContractKeyRef as d1, isContractParamRef as d2, isEntityWritesDefinition as d3, isKeySegment as d4, isLifecycleContract as d5, isMutationFragment as d6, isMutationInputRef as d7, isParam as d8, isPlannedCommandMethod as d9, isQueryModelContract as da, isRetryableError as db, isRetryableTransactionCancellation as dc, k as dd, key as de, lifecyclePhaseForIntent as df, mintContractKeyFieldRef as dg, mintContractParamRef as dh, mutation as di, param as dj, publicCommandModel as dk, publicQueryModel as dl, query as dm, resolveLifecycle as dn, wholeKeysSentinel as dp, type BatchExecOptions as e, DDBModel as f, type PrimaryKeyOf as g, type RequestContext as h, type Middleware as i, type ReadRequestKind as j, type CtxModel as k, type ReadParams as l, type ReadRequestCtx as m, type RetryPolicy as n, type ExecutionPlanSpec as o, type SegmentedKey as p, type SelectBuilderSpec as q, type RawCondition as r, type TransactionSpec as s, type Manifest as t, type RetryOverride as u, type ExecutionPlan as v, type ResolvedKey as w, type CdcEmulatorOptions as x, type ChangeHandler as y, type Unsubscribe as z };
|