graphddb 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/behaviors-DDltNivc.d.ts +217 -0
- package/dist/cdc/index.d.ts +5 -4
- package/dist/cdc/index.js +3 -3
- package/dist/{chunk-HNY2EJPV.js → chunk-KOIJ4SNO.js} +1 -1
- package/dist/{chunk-S2NI4PBW.js → chunk-NWTEUWJD.js} +7 -5
- package/dist/{chunk-LAT64YCZ.js → chunk-SSVG6NQK.js} +657 -18
- package/dist/{chunk-L4QRCHRQ.js → chunk-WOFRHRXY.js} +6 -25
- package/dist/{chunk-T44OB5GU.js → chunk-XZTA4VJH.js} +23 -7
- package/dist/{chunk-GS4C5VGO.js → chunk-YGQ2NO6J.js} +2 -2
- package/dist/{chunk-L2NEDS7U.js → chunk-ZNU7OI5I.js} +241 -8
- package/dist/cli.js +366 -80
- package/dist/index.d.ts +131 -5
- package/dist/index.js +121 -5
- package/dist/internal/index.d.ts +6 -5
- package/dist/internal/index.js +7 -7
- package/dist/{key-DZtjAQDh.d.ts → key-Dne-a20Q.d.ts} +40 -5
- package/dist/linter/index.d.ts +6 -5
- package/dist/{linter-DQY7gUEk.d.ts → linter-Cr1Hnw7n.d.ts} +1 -1
- package/dist/{prepared-artifact-HFealr1q.d.ts → prepared-artifact-BXkARxwO.d.ts} +4 -4
- package/dist/spec/index.d.ts +225 -24
- package/dist/spec/index.js +17 -9
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +3 -3
- package/dist/transform/index.d.ts +2 -1
- package/dist/transform/index.js +2 -2
- package/dist/{types-DW__-Icc.d.ts → types-BnFsTZwl.d.ts} +1 -1
- package/dist/{types-2PMXEn5x.d.ts → types-CfxzTEFL.d.ts} +262 -20
- package/docs/python-bridge.md +33 -49
- package/package.json +11 -3
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// src/spec/types.ts
|
|
2
2
|
var SPEC_VERSION = "1.1";
|
|
3
3
|
var SPEC_VERSION_SCP = "1.2";
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var SPEC_VERSION_KEY_EXPR = "2.0";
|
|
5
|
+
var SPEC_VERSION_SUPPORTED = SPEC_VERSION_KEY_EXPR;
|
|
6
|
+
var EXPR_VERSION = 2;
|
|
6
7
|
var MARKER_ROW_ENTITY = "__marker__";
|
|
7
8
|
|
|
8
9
|
// src/define/transaction.ts
|
|
@@ -236,33 +237,14 @@ function canonicalizeExpressionSpec(input, context) {
|
|
|
236
237
|
function isScpExprConditionInput(condition) {
|
|
237
238
|
return "scpExpr" in condition;
|
|
238
239
|
}
|
|
239
|
-
function
|
|
240
|
-
return
|
|
241
|
-
}
|
|
242
|
-
function operationsContainScpNodes(doc) {
|
|
243
|
-
for (const command of Object.values(doc.commands)) {
|
|
244
|
-
if (conditionHasScp(command.condition)) return true;
|
|
245
|
-
}
|
|
246
|
-
for (const transaction of Object.values(doc.transactions ?? {})) {
|
|
247
|
-
for (const item of transaction.items) {
|
|
248
|
-
if (item.guard !== void 0 || conditionHasScp(item.condition)) return true;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
for (const contract of Object.values(doc.contracts ?? {})) {
|
|
252
|
-
if (contract.kind !== "command") continue;
|
|
253
|
-
for (const method of Object.values(contract.methods)) {
|
|
254
|
-
if (method.guard !== void 0) return true;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return false;
|
|
258
|
-
}
|
|
259
|
-
function operationsSpecVersion(doc) {
|
|
260
|
-
return operationsContainScpNodes(doc) ? SPEC_VERSION_SCP : SPEC_VERSION;
|
|
240
|
+
function operationsSpecVersion(_doc) {
|
|
241
|
+
return SPEC_VERSION_KEY_EXPR;
|
|
261
242
|
}
|
|
262
243
|
|
|
263
244
|
export {
|
|
264
245
|
SPEC_VERSION,
|
|
265
246
|
SPEC_VERSION_SCP,
|
|
247
|
+
SPEC_VERSION_KEY_EXPR,
|
|
266
248
|
SPEC_VERSION_SUPPORTED,
|
|
267
249
|
EXPR_VERSION,
|
|
268
250
|
MARKER_ROW_ENTITY,
|
|
@@ -273,6 +255,5 @@ export {
|
|
|
273
255
|
SCP_LOWERED_MARKER,
|
|
274
256
|
canonicalizeExpressionSpec,
|
|
275
257
|
isScpExprConditionInput,
|
|
276
|
-
operationsContainScpNodes,
|
|
277
258
|
operationsSpecVersion
|
|
278
259
|
};
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
normalizeTopLevelSelect,
|
|
18
18
|
parseChange,
|
|
19
19
|
validateInlineSnapshotSelect
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-KOIJ4SNO.js";
|
|
21
21
|
import {
|
|
22
22
|
EXPR_VERSION,
|
|
23
23
|
MARKER_ROW_ENTITY,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
isScpExprConditionInput,
|
|
27
27
|
isTransactionDefinition,
|
|
28
28
|
isTransactionRef
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-WOFRHRXY.js";
|
|
30
30
|
import {
|
|
31
31
|
BATCH_GET_MAX_KEYS,
|
|
32
32
|
CONDITION_OPERATOR_KEYS,
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
serializeFieldValue,
|
|
62
62
|
serializeRawCondition,
|
|
63
63
|
skTemplate
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-ZNU7OI5I.js";
|
|
65
65
|
import {
|
|
66
66
|
TableMapping,
|
|
67
67
|
createColumnMap,
|
|
@@ -4680,8 +4680,16 @@ function buildCommandContract(methods) {
|
|
|
4680
4680
|
const resolved = {};
|
|
4681
4681
|
for (const [name, body] of Object.entries(methods)) {
|
|
4682
4682
|
if (isPublicWriteDescriptor(body)) {
|
|
4683
|
-
const { plan: plan2, select, condition, mode, description } = writeDescriptorToPlan(name, body);
|
|
4684
|
-
resolved[name] = finalizeDescriptorCommand(
|
|
4683
|
+
const { plan: plan2, select, condition, mode, batchWriteEligible, description } = writeDescriptorToPlan(name, body);
|
|
4684
|
+
resolved[name] = finalizeDescriptorCommand(
|
|
4685
|
+
name,
|
|
4686
|
+
plan2,
|
|
4687
|
+
select,
|
|
4688
|
+
condition,
|
|
4689
|
+
mode,
|
|
4690
|
+
description,
|
|
4691
|
+
batchWriteEligible
|
|
4692
|
+
);
|
|
4685
4693
|
continue;
|
|
4686
4694
|
}
|
|
4687
4695
|
if (isPublicCompositeDescriptor(body)) {
|
|
@@ -4771,7 +4779,7 @@ function buildPlannedCommandMethod(name, planned) {
|
|
|
4771
4779
|
...returnSelection !== void 0 ? { returnSelection } : {}
|
|
4772
4780
|
};
|
|
4773
4781
|
}
|
|
4774
|
-
function finalizeDescriptorCommand(name, plan2, select, condition,
|
|
4782
|
+
function finalizeDescriptorCommand(name, plan2, select, condition, declaredMode, description, batchWriteEligible = false) {
|
|
4775
4783
|
const planned = {
|
|
4776
4784
|
[PLANNED_COMMAND_BRAND]: true,
|
|
4777
4785
|
plan: plan2,
|
|
@@ -4779,6 +4787,13 @@ function finalizeDescriptorCommand(name, plan2, select, condition, mode, descrip
|
|
|
4779
4787
|
select
|
|
4780
4788
|
};
|
|
4781
4789
|
const built = buildPlannedCommandMethod(name, planned);
|
|
4790
|
+
const promoted = built.ops !== void 0 && built.ops.length > 1 || built.conditionChecks !== void 0 || built.edgeWrites !== void 0 || built.derivedUpdates !== void 0 || built.uniqueGuards !== void 0 || built.outboxEvents !== void 0 || built.idempotencyGuard !== void 0 || built.maintainWrites !== void 0 || built.maintainOutbox !== void 0;
|
|
4791
|
+
if (declaredMode === "batchWrite" && (!batchWriteEligible || promoted)) {
|
|
4792
|
+
throw new Error(
|
|
4793
|
+
`publishCommand: method '${name}' declares mode: 'batchWrite', but DynamoDB's BatchWriteItem carries no ConditionExpression, no Update and no composed derived effects \u2014 only an UNCONDITIONAL put/delete qualifies (an \`upsert\` or a condition-free \`remove\` with no derived effects). This method is ${!batchWriteEligible ? "conditional / not an unconditional put/delete" : "promoted to an atomic TransactWriteItems by its derived effects"}. Use mode: 'transaction' (atomic TransactWriteItems, condition-capable, \u226425) \u2014 or the transaction forEach form for atomic per-item values.`
|
|
4794
|
+
);
|
|
4795
|
+
}
|
|
4796
|
+
const mode = declaredMode ?? (batchWriteEligible && !promoted ? "batchWrite" : "transaction");
|
|
4782
4797
|
const builtOp = built.op;
|
|
4783
4798
|
const op = condition !== void 0 ? { ...builtOp, condition } : builtOp;
|
|
4784
4799
|
return {
|
|
@@ -5015,7 +5030,8 @@ function writeDescriptorToPlan(name, d) {
|
|
|
5015
5030
|
});
|
|
5016
5031
|
const select = d.result !== void 0 && d.result.select !== void 0 ? d.result.select : void 0;
|
|
5017
5032
|
const condition = d.condition !== void 0 ? descriptorConditionRecord(d.condition, name) : void 0;
|
|
5018
|
-
|
|
5033
|
+
const batchWriteEligible = (intent === "upsert" || intent === "remove") && d.condition === void 0;
|
|
5034
|
+
return { plan: plan2, select, condition, mode: d.mode, batchWriteEligible, description: d.description };
|
|
5019
5035
|
}
|
|
5020
5036
|
|
|
5021
5037
|
// src/spec/mutation-command.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildMaintenanceGraph
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KOIJ4SNO.js";
|
|
4
4
|
import {
|
|
5
5
|
ChangeCaptureRegistry,
|
|
6
6
|
ClientManager,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
buildDeleteInput,
|
|
10
10
|
buildPutInput,
|
|
11
11
|
resolveModelClass
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ZNU7OI5I.js";
|
|
13
13
|
|
|
14
14
|
// src/cdc/prng.ts
|
|
15
15
|
var SeededRandom = class {
|
|
@@ -227,10 +227,35 @@ var param = {
|
|
|
227
227
|
const param2 = { kind: "array", element };
|
|
228
228
|
if (options?.description !== void 0) param2.description = options.description;
|
|
229
229
|
return param2;
|
|
230
|
+
},
|
|
231
|
+
/**
|
|
232
|
+
* A placeholder for a **map / embedded object** value written to a single
|
|
233
|
+
* DynamoDB `M` attribute (issue #295). Free-form by design: the model-side
|
|
234
|
+
* vocabulary (`@map` / `@embedded`) records no nested schema, so the param is
|
|
235
|
+
* typed as the language-native map in generated bindings (`dict` /
|
|
236
|
+
* `map[string]any` / `serde_json::Value` / `array`) while the optional type
|
|
237
|
+
* parameter `T` keeps the TS authoring surface precise.
|
|
238
|
+
*
|
|
239
|
+
* Legal at **value positions only** (a write descriptor's `input`, a
|
|
240
|
+
* transaction fragment value, a batch-write per-item payload field) — a map
|
|
241
|
+
* cannot compose a key, so a `param.map()` in a key position is rejected
|
|
242
|
+
* loudly at build time.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* putLeaf: {
|
|
247
|
+
* upsert: TreeNode,
|
|
248
|
+
* key: { part: param.string(), child: param.string() },
|
|
249
|
+
* input: { value: param.map<AvgValue>(), computedAt: param.number() },
|
|
250
|
+
* }
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
map(options) {
|
|
254
|
+
return makeParam("map", void 0, options?.description);
|
|
230
255
|
}
|
|
231
256
|
};
|
|
232
257
|
function isParam(value) {
|
|
233
|
-
return typeof value === "object" && value !== null && "kind" in value && (value.kind === "string" || value.kind === "number" || value.kind === "literal" || value.kind === "array");
|
|
258
|
+
return typeof value === "object" && value !== null && "kind" in value && (value.kind === "string" || value.kind === "number" || value.kind === "literal" || value.kind === "array" || value.kind === "map");
|
|
234
259
|
}
|
|
235
260
|
|
|
236
261
|
// src/client/lib-dynamodb.ts
|
|
@@ -337,17 +362,220 @@ async function executeBatchGet(docClient, operation) {
|
|
|
337
362
|
return { items: allItems };
|
|
338
363
|
}
|
|
339
364
|
|
|
365
|
+
// src/spec/catalog.ts
|
|
366
|
+
import { classifyBehaviorEffect } from "behavior-contracts";
|
|
367
|
+
var P = (type, required) => required ? { type, required } : { type };
|
|
368
|
+
var READ_PORTS = {
|
|
369
|
+
table: P("string", true),
|
|
370
|
+
indexName: P("string"),
|
|
371
|
+
rangeKey: P("string"),
|
|
372
|
+
rangeOperator: P("string"),
|
|
373
|
+
rangeValue: P("expr"),
|
|
374
|
+
limit: P("number"),
|
|
375
|
+
filter: P("string"),
|
|
376
|
+
projection: P("string[]", true),
|
|
377
|
+
implicitSourceField: P("string")
|
|
378
|
+
};
|
|
379
|
+
var WRITE_PORTS = {
|
|
380
|
+
table: P("string", true),
|
|
381
|
+
entity: P("string", true),
|
|
382
|
+
literalKey: P("boolean"),
|
|
383
|
+
maintain: P("string"),
|
|
384
|
+
"condition.kind": P("string"),
|
|
385
|
+
"condition.field": P("string"),
|
|
386
|
+
"condition.declarative": P("string"),
|
|
387
|
+
"condition.expression": P("string"),
|
|
388
|
+
"condition.names": P("string")
|
|
389
|
+
};
|
|
390
|
+
var entry = (name, inputPorts, shape, portableToIR) => ({
|
|
391
|
+
name,
|
|
392
|
+
inputPorts,
|
|
393
|
+
output: { shape },
|
|
394
|
+
portableToIR,
|
|
395
|
+
// Dynamic port families (key-attribute / write record ports) are validated by
|
|
396
|
+
// assertComponentsInCatalog, not statically enumerable — see the module doc
|
|
397
|
+
// ("Dynamic-port opt-in"). TransactWrite overrides this back to fail-closed.
|
|
398
|
+
additionalPorts: true
|
|
399
|
+
});
|
|
400
|
+
var GRAPHDDB_CATALOG = {
|
|
401
|
+
GetItem: entry("GetItem", READ_PORTS, "item", true),
|
|
402
|
+
Query: entry(
|
|
403
|
+
"Query",
|
|
404
|
+
// `cardinality: 'one'` is the root-collapse port only the Query root emits.
|
|
405
|
+
{ ...READ_PORTS, cardinality: P("string") },
|
|
406
|
+
"items",
|
|
407
|
+
true
|
|
408
|
+
),
|
|
409
|
+
BatchGetItem: entry("BatchGetItem", READ_PORTS, "items", true),
|
|
410
|
+
PutItem: entry("PutItem", WRITE_PORTS, "item", true),
|
|
411
|
+
UpdateItem: entry("UpdateItem", WRITE_PORTS, "item", true),
|
|
412
|
+
DeleteItem: entry("DeleteItem", WRITE_PORTS, "item", true),
|
|
413
|
+
ConditionCheck: entry("ConditionCheck", WRITE_PORTS, "item", true),
|
|
414
|
+
// The executor-side atomic envelope: never referenced by the portable IR
|
|
415
|
+
// (a transaction IS a component over the item primitives) — TS-runtime-only.
|
|
416
|
+
// Its single port is static, so it keeps bc's fail-closed default (no
|
|
417
|
+
// additionalPorts opt-in).
|
|
418
|
+
TransactWrite: {
|
|
419
|
+
...entry("TransactWrite", { TransactItems: P("map[]", true) }, "item", false),
|
|
420
|
+
additionalPorts: false
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
function catalogEntry(name) {
|
|
424
|
+
return GRAPHDDB_CATALOG[name];
|
|
425
|
+
}
|
|
426
|
+
var CATALOG_NAMES = [
|
|
427
|
+
"GetItem",
|
|
428
|
+
"Query",
|
|
429
|
+
"BatchGetItem",
|
|
430
|
+
"PutItem",
|
|
431
|
+
"UpdateItem",
|
|
432
|
+
"DeleteItem",
|
|
433
|
+
"ConditionCheck",
|
|
434
|
+
"TransactWrite"
|
|
435
|
+
];
|
|
436
|
+
var WRITE_CATALOG_NAMES = [
|
|
437
|
+
"PutItem",
|
|
438
|
+
"UpdateItem",
|
|
439
|
+
"DeleteItem",
|
|
440
|
+
"ConditionCheck",
|
|
441
|
+
"TransactWrite"
|
|
442
|
+
];
|
|
443
|
+
var WRITE_SET = new Set(WRITE_CATALOG_NAMES);
|
|
444
|
+
var KEY_ATTR_PORT = /^[A-Za-z0-9_]*(?:PK|SK)$/;
|
|
445
|
+
var WRITE_PORT_FAMILIES = [
|
|
446
|
+
"item.",
|
|
447
|
+
"key.",
|
|
448
|
+
"changes.",
|
|
449
|
+
"add.",
|
|
450
|
+
"condition.equals.",
|
|
451
|
+
"condition.params.",
|
|
452
|
+
"condition.values."
|
|
453
|
+
];
|
|
454
|
+
function assertComponentsInCatalog(components) {
|
|
455
|
+
const errs = [];
|
|
456
|
+
for (const c of components) {
|
|
457
|
+
for (const n of c.body) {
|
|
458
|
+
if ("cond" in n) continue;
|
|
459
|
+
const ref = "map" in n ? n.map : n;
|
|
460
|
+
const entryDef = GRAPHDDB_CATALOG[ref.component];
|
|
461
|
+
if (entryDef === void 0) {
|
|
462
|
+
errs.push(`${c.name}/${n.id}: references '${ref.component}', not a GRAPHDDB_CATALOG entry (known: ${CATALOG_NAMES.join(", ")})`);
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
const ports = ref.ports;
|
|
466
|
+
for (const [p, s] of Object.entries(entryDef.inputPorts)) {
|
|
467
|
+
if (s.required === true && !(p in ports)) {
|
|
468
|
+
errs.push(`${c.name}/${n.id} (${ref.component}): required port '${p}' is not wired`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const isWriteItem = WRITE_SET.has(ref.component);
|
|
472
|
+
for (const p of Object.keys(ports)) {
|
|
473
|
+
if (p in entryDef.inputPorts) continue;
|
|
474
|
+
if (isWriteItem ? WRITE_PORT_FAMILIES.some((f) => p.startsWith(f)) : KEY_ATTR_PORT.test(p)) continue;
|
|
475
|
+
errs.push(`${c.name}/${n.id} (${ref.component}): port '${p}' is not declared by the catalog entry (nor a ${isWriteItem ? "write record-family" : "key-attribute"} port)`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (errs.length > 0) {
|
|
480
|
+
throw new Error(`graphddb catalog validation failed (${errs.length} violation${errs.length === 1 ? "" : "s"}):
|
|
481
|
+
- ${errs.join("\n - ")}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function deriveContractEffect(component) {
|
|
485
|
+
return classifyBehaviorEffect(component, WRITE_CATALOG_NAMES) === "writing" ? "command" : "query";
|
|
486
|
+
}
|
|
487
|
+
function deriveComponentEffects(components) {
|
|
488
|
+
const out = /* @__PURE__ */ new Map();
|
|
489
|
+
for (const c of components) out.set(c.name, deriveContractEffect(c));
|
|
490
|
+
return out;
|
|
491
|
+
}
|
|
492
|
+
function assertPublishSplitMatchesDerived(derived, split, contracts) {
|
|
493
|
+
const errs = [];
|
|
494
|
+
const check = (name, declared, at) => {
|
|
495
|
+
const truth = derived.get(name);
|
|
496
|
+
if (truth === void 0) {
|
|
497
|
+
errs.push(`${at}: no emitted component '${name}'`);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
if (truth !== declared) {
|
|
501
|
+
const verb = declared === "query" ? "publishQuery" : "publishCommand";
|
|
502
|
+
const fix = truth === "command" ? "publishCommand" : "publishQuery";
|
|
503
|
+
errs.push(
|
|
504
|
+
`${at}: published under ${verb} (declares '${declared}') but component '${name}' derives '${truth}' from its graph \u2014 the component graph is the source of truth; publish it with ${fix}`
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
for (const name of derived.keys()) {
|
|
509
|
+
if (split.behaviors.has(name)) continue;
|
|
510
|
+
if (split.queries.has(name)) check(name, "query", "components");
|
|
511
|
+
else if (split.transactions.has(name)) check(name, "command", "components");
|
|
512
|
+
else errs.push(`components: '${name}' has no declared publish origin (queries / transactions / behaviors) to verify against`);
|
|
513
|
+
}
|
|
514
|
+
for (const [cname, contract] of Object.entries(contracts)) {
|
|
515
|
+
for (const [mname, m] of Object.entries(contract.methods)) {
|
|
516
|
+
const at = `contract ${cname}.${mname}`;
|
|
517
|
+
if (contract.kind === "query") {
|
|
518
|
+
const q = m;
|
|
519
|
+
if (!split.queries.has(q.operation)) errs.push(`${at}: operation '${q.operation}' is not in queries`);
|
|
520
|
+
else check(q.operation, "query", at);
|
|
521
|
+
} else {
|
|
522
|
+
const cm = m;
|
|
523
|
+
for (const target of [cm.single, cm.batch]) {
|
|
524
|
+
if (target === void 0) continue;
|
|
525
|
+
if (target.mode === "transaction" || target.mode === "batchWrite") {
|
|
526
|
+
if (!split.transactions.has(target.transaction)) errs.push(`${at}: transaction '${target.transaction}' is not in transactions`);
|
|
527
|
+
else check(target.transaction, "command", at);
|
|
528
|
+
} else if (!split.commands.has(target.operation)) {
|
|
529
|
+
errs.push(`${at}: operation '${target.operation}' is not in commands`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (cm.returnSelection !== void 0) check(`${cname}__${mname}__readback`, "query", `${at} readback`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (errs.length > 0) {
|
|
537
|
+
throw new Error(
|
|
538
|
+
`graphddb CQRS classification: the declared publish split contradicts the graph-derived truth (${errs.length}):
|
|
539
|
+
- ${errs.join("\n - ")}`
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// src/executor/handler-registry.ts
|
|
545
|
+
function resolveReadHandler(registry, name) {
|
|
546
|
+
const handler = registry[name];
|
|
547
|
+
if (handler === void 0) {
|
|
548
|
+
throw new Error(
|
|
549
|
+
`graphddb handler registry: no handler bound for catalog component '${name}' (known: ${Object.keys(registry).join(", ")})`
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
return handler;
|
|
553
|
+
}
|
|
554
|
+
function assertHandlersInCatalog(registry) {
|
|
555
|
+
for (const name of Object.keys(registry)) {
|
|
556
|
+
if (catalogEntry(name) === void 0) {
|
|
557
|
+
throw new Error(
|
|
558
|
+
`graphddb handler registry: handler '${name}' has no catalog entry (every bound handler must declare a Port schema in GRAPHDDB_CATALOG)`
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
340
564
|
// src/executor/dynamo-executor.ts
|
|
565
|
+
var READ_HANDLERS = {
|
|
566
|
+
GetItem: (docClient, operation) => executeGetItem(docClient, operation),
|
|
567
|
+
Query: (docClient, operation) => executeQuery(docClient, operation),
|
|
568
|
+
BatchGetItem: (docClient, operation) => {
|
|
569
|
+
const op = operation;
|
|
570
|
+
return executeBatchGet(docClient, op);
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
assertHandlersInCatalog(READ_HANDLERS);
|
|
341
574
|
var DynamoExecutor = class {
|
|
342
575
|
async execute(operation, _options) {
|
|
343
576
|
const docClient = await ClientManager.getDocumentClient();
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
if (operation.type === "BatchGetItem") {
|
|
348
|
-
return this.batchGet(operation);
|
|
349
|
-
}
|
|
350
|
-
return executeQuery(docClient, operation);
|
|
577
|
+
const handler = resolveReadHandler(READ_HANDLERS, operation.type);
|
|
578
|
+
return handler(docClient, operation);
|
|
351
579
|
}
|
|
352
580
|
async batchGet(input, _options) {
|
|
353
581
|
const docClient = await ClientManager.getDocumentClient();
|
|
@@ -2448,6 +2676,11 @@ export {
|
|
|
2448
2676
|
isParam,
|
|
2449
2677
|
BATCH_GET_MAX_KEYS,
|
|
2450
2678
|
chunkArray,
|
|
2679
|
+
GRAPHDDB_CATALOG,
|
|
2680
|
+
assertComponentsInCatalog,
|
|
2681
|
+
deriveContractEffect,
|
|
2682
|
+
deriveComponentEffects,
|
|
2683
|
+
assertPublishSplitMatchesDerived,
|
|
2451
2684
|
ClientManager,
|
|
2452
2685
|
isRawCondition,
|
|
2453
2686
|
cond,
|