graphddb 0.8.0 → 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-LGHSZIEE.js → chunk-NWTEUWJD.js} +7 -5
- package/dist/{chunk-N4NWYNGZ.js → chunk-SSVG6NQK.js} +657 -18
- package/dist/{chunk-L4QRCHRQ.js → chunk-WOFRHRXY.js} +6 -25
- package/dist/{chunk-I4LEJ4TF.js → chunk-XZTA4VJH.js} +44 -9
- 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-DR7_lpyk.d.ts → key-Dne-a20Q.d.ts} +204 -7
- package/dist/linter/index.d.ts +6 -5
- package/dist/{linter-C-vypgut.d.ts → linter-Cr1Hnw7n.d.ts} +1 -1
- package/dist/{prepared-artifact-BpPgkXEo.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-BXLzIcQD.d.ts → types-BnFsTZwl.d.ts} +1 -1
- package/dist/{types-2PMXEn5x.d.ts → types-CfxzTEFL.d.ts} +262 -20
- package/docs/cqrs-contract.md +55 -4
- package/docs/python-bridge.md +33 -49
- package/package.json +11 -3
package/docs/python-bridge.md
CHANGED
|
@@ -276,63 +276,46 @@ Every operation carries a `params` map of `ParamSpec`:
|
|
|
276
276
|
|
|
277
277
|
#### Queries
|
|
278
278
|
|
|
279
|
-
A `QuerySpec` has `params`, an
|
|
280
|
-
(`"one"` or `"many"`).
|
|
279
|
+
A `QuerySpec` has `params`, an `operations` array carrying exactly **one**
|
|
280
|
+
entry — the root physical op — and a `cardinality` (`"one"` or `"many"`).
|
|
281
|
+
Since SCP IR Phase 3 (#290 P3-5) relation fan-out is NOT part of `queries`:
|
|
282
|
+
it lives exclusively in the universal `components[]` graph (below). The root
|
|
283
|
+
`OperationSpec`:
|
|
281
284
|
|
|
282
285
|
```jsonc
|
|
283
286
|
{
|
|
284
287
|
"type": "Query", // "Query" | "GetItem" | "BatchGetItem"
|
|
285
288
|
"tableName": "UserPermissions",
|
|
286
289
|
"indexName": "GSI1", // omitted for base-table access
|
|
287
|
-
"keyCondition": { "GSI1PK": "EMAIL#{email}", "GSI1SK": "PROFILE" },
|
|
288
|
-
"rangeCondition": { "operator": "begins_with", "key": "SK", "value": "USER#" },
|
|
289
290
|
"projection": ["email", "name", "status", "userId"],
|
|
291
|
+
"keyExpr": { "GSI1PK": { "concat": ["EMAIL#", { "ref": ["input", "email"] }] },
|
|
292
|
+
"GSI1SK": "PROFILE" },
|
|
293
|
+
"rangeCondition": { "operator": "begins_with", "key": "SK", "valueExpr": "USER#" },
|
|
290
294
|
"limit": 20,
|
|
291
|
-
"filter": { /* declarative FilterExpression */ }
|
|
292
|
-
"resultPath": "$", // "$" or e.g. "$.groups.items"
|
|
293
|
-
"sourceField": "userId" // present on relation child operations
|
|
295
|
+
"filter": { /* declarative FilterExpression */ }
|
|
294
296
|
}
|
|
295
297
|
```
|
|
296
298
|
|
|
297
299
|
The operation type is chosen by the planner from the key shape: a full PK+SK is
|
|
298
300
|
a `GetItem`; a partial key with a contiguous sort-key prefix is a `Query` with a
|
|
299
301
|
`begins_with` `rangeCondition`; a partition-key-only access is a `Query`. The
|
|
300
|
-
`projection` is the set of scalar fields selected `true`.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
A relation traversal is expressed as additional `OperationSpec` nodes in the same
|
|
319
|
-
query's `operations` array. Each child references its parent through
|
|
320
|
-
`{result.sourceField}` in its `keyCondition`, and its `resultPath` nests the
|
|
321
|
-
result under the parent (`$.groups.items` for a `hasMany`, `$.account` for a
|
|
322
|
-
`belongsTo` / `hasOne`). `belongsTo` / `hasOne` children are emitted as
|
|
323
|
-
`BatchGetItem`; `hasMany` children as `Query`.
|
|
324
|
-
|
|
325
|
-
A query may carry an `executionPlan`:
|
|
326
|
-
|
|
327
|
-
```jsonc
|
|
328
|
-
{ "groups": [[1, 2], [3]], "concurrency": 16 }
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
`groups` is an ordered list of stages of operation indices (the root, index 0,
|
|
332
|
-
is implicit and runs first). Operations within a stage are mutually independent
|
|
333
|
-
and may run concurrently; later stages may read `{result.*}` produced by earlier
|
|
334
|
-
ones. The same `deriveExecutionPlan` routine is used by the generator and by the
|
|
335
|
-
TypeScript runtime, so the staging cannot drift between them.
|
|
302
|
+
`projection` is the set of scalar fields selected `true`. The key wiring is
|
|
303
|
+
portable Expression IR (`keyExpr` / `valueExpr`, #289), derived by **symbolic
|
|
304
|
+
evaluation** of the model's key mapping. The runtime executes the root op via
|
|
305
|
+
its `components[]` entry; the emitted root op remains the validation /
|
|
306
|
+
`explain` / contract point-batch surface.
|
|
307
|
+
|
|
308
|
+
#### Relation chaining and staging (`components[]`)
|
|
309
|
+
|
|
310
|
+
A relation traversal is expressed as the query's entry in the top-level
|
|
311
|
+
`components[]` — the universal SCP component graph (behavior-contracts
|
|
312
|
+
`Component`): the root op becomes a `componentRef` body node, each relation a
|
|
313
|
+
`componentRef` / `map` node whose id is the dotted result path
|
|
314
|
+
(`groups.items`, `groups.items.group`), wired to its producer via `parent`
|
|
315
|
+
and executed by `run_behavior` with the DynamoDB catalog handlers. A
|
|
316
|
+
multi-node component carries a `plan` (`{ "groups": [[0], [1, 2]],
|
|
317
|
+
"concurrency": 16 }`) staging mutually-independent nodes; the shared executor
|
|
318
|
+
honors it.
|
|
336
319
|
|
|
337
320
|
#### Commands
|
|
338
321
|
|
|
@@ -581,8 +564,9 @@ resuming with a cursor for the wrong key is rejected.
|
|
|
581
564
|
|
|
582
565
|
### 7.6 Relations, Batch, and Concurrency
|
|
583
566
|
|
|
584
|
-
Relation
|
|
585
|
-
|
|
567
|
+
Relation nodes of the query's `components[]` entry are resolved against the
|
|
568
|
+
parents produced by earlier nodes and folded into the result at their node id
|
|
569
|
+
path:
|
|
586
570
|
|
|
587
571
|
- **`belongsTo` / `hasOne`** — source values from all parents are deduplicated
|
|
588
572
|
and fetched in a single `BatchGetItem`, then matched back to each parent (a
|
|
@@ -592,10 +576,10 @@ operations and merged into the result at their `resultPath`:
|
|
|
592
576
|
|
|
593
577
|
`BatchGetItem` requests are chunked at 100 keys, deduplicated, and retried on
|
|
594
578
|
`UnprocessedKeys` with capped exponential backoff (up to 10 attempts).
|
|
595
|
-
`BatchWriteItem` is chunked at 25 with the same `UnprocessedItems` retry.
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
579
|
+
`BatchWriteItem` is chunked at 25 with the same `UnprocessedItems` retry. Node
|
|
580
|
+
staging follows the component's `plan` inside the shared `run_behavior`
|
|
581
|
+
executor (deterministic in-order reference semantics). Result order is
|
|
582
|
+
preserved.
|
|
599
583
|
|
|
600
584
|
### 7.7 Transactions
|
|
601
585
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphddb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Graph data modeling on DynamoDB with adjacency list pattern",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -54,6 +54,9 @@
|
|
|
54
54
|
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
55
55
|
"gen:py:fixtures": "tsx src/cli.ts generate python --entry python/tests/fixtures/models.ts --transactions python/tests/fixtures/definitions.ts --contracts python/tests/fixtures/definitions.ts --out python/tests/fixtures/generated",
|
|
56
56
|
"gen:py:fixtures:multi": "tsx src/cli.ts generate python --entry python/tests/fixtures/models.ts --contracts python/tests/fixtures/definitions_multi.ts --out python/tests/fixtures/generated_multi",
|
|
57
|
+
"gen:py:behaviors:fixture": "tsx src/cli.ts generate behaviors --lang python --entry python/tests/fixtures/models.ts --transactions python/tests/fixtures/definitions.ts --contracts python/tests/fixtures/definitions.ts --out python/tests/fixtures/generated_behaviors",
|
|
58
|
+
"gen:rust:behaviors:fixture": "tsx src/cli.ts generate behaviors --lang rust --entry python/tests/fixtures/models.ts --transactions python/tests/fixtures/definitions.ts --contracts python/tests/fixtures/definitions.ts --out rust/graphddb_runtime/tests/generated_behaviors",
|
|
59
|
+
"gen:php:behaviors:fixture": "tsx src/cli.ts generate behaviors --lang php --entry python/tests/fixtures/models.ts --transactions python/tests/fixtures/definitions.ts --contracts python/tests/fixtures/definitions.ts --out php/tests/fixtures/generated_behaviors",
|
|
57
60
|
"test:py": "python3 -m pytest python/tests -m \"not integration\"",
|
|
58
61
|
"test:py:integration": "python3 -m pytest python/tests -m integration",
|
|
59
62
|
"test:conformance": "tsx conformance/run.ts",
|
|
@@ -71,7 +74,9 @@
|
|
|
71
74
|
"embedoc:build": "embedoc build",
|
|
72
75
|
"embedoc:watch": "embedoc watch",
|
|
73
76
|
"embedoc:generate": "embedoc generate --all",
|
|
77
|
+
"prepare": "git config core.hooksPath .githooks 2>/dev/null || true",
|
|
74
78
|
"embedoc:check": "node scripts/embedoc-drift-check.mjs",
|
|
79
|
+
"deps:check": "node scripts/check-no-local-deps.mjs",
|
|
75
80
|
"vendor:bc-php": "node scripts/vendor-behavior-contracts-php.mjs",
|
|
76
81
|
"vendor:bc-php:check": "node scripts/vendor-behavior-contracts-php.mjs --check",
|
|
77
82
|
"vendor:bc-vectors": "node scripts/vendor-behavior-contracts-vectors.mjs",
|
|
@@ -80,6 +85,9 @@
|
|
|
80
85
|
"bench:crosslang:integration": "tsx benchmark/crosslang/integration.ts",
|
|
81
86
|
"bench:crosslang:test": "vitest run benchmark/crosslang/__tests__"
|
|
82
87
|
},
|
|
88
|
+
"size-limit-notes": {
|
|
89
|
+
"graphddb/spec (build-time)": "#290 transitional loop CLOSED at the final sub-pass (P3-5): the components[] emitter is now the PERMANENT (and only) portable carrier of relation fan-out + transaction write plans, so the sub-pass-1 dual-emit bump does not fully revert — the old operation/transaction builders remain as the emitter INTERNAL lowering input (they also feed the TS declarative executor and the AOT prepared plan); only their serialization into operations.json was removed, replaced by the small portable projection. Measured 22.38->22.51 KB across the flip (all first-party src/spec, zero new dependencies, all runtime bundles flat); budget stays 23 KB as the steady-state ceiling. Any future growth must be traced per the size-limit-gate discipline, never blanket-raised. #297 SP1+SP2 traced growth: 22.51->25.02 KB (+2.51 brotli), two traced components — (1) first-party src/spec/catalog.ts: the bc-typed GRAPHDDB_CATALOG + the SP1c emitter validation + the SP2 CQRS effect-derivation invariant, both wired into buildOperations so a catalog/effect mismatch is a BUILD error (load-bearing by design, must ship in this bundle); (2) behavior-contracts/dist/authoring.js partial inclusion, 5.66 KB minified (esbuild metafile-traced): the SP2-mandated classifyBehaviorEffect/referencedComponents live in bc's authoring module, whose top-level `export const add = binOp('add')`-style const-initializer calls esbuild cannot prove pure — bc 0.1.6 ships no sideEffects:false / __PURE__ annotations, so the two tiny helpers drag the authoring-DSL scaffolding along. NOT a new dependency (behavior-contracts already supplied this bundle's contract types); an upstream bc annotation fix reclaims (2), and the ceiling must be re-tightened when it lands. New ceiling 25.5 KB keeps the same ~0.5 KB headroom discipline as the previous 23 KB ceiling. #297 SP3+SP4 traced growth: 25.04->25.26 KB (+0.22 brotli), all first-party src/spec — the SP4 inversion (deriveComponentEffects + assertPublishSplitMatchesDerived with method-naming errors, replacing the SP2 symmetric assertion) plus the additive contractInputs.behaviors registration loop in buildOperations (rename + collision check + re-validation); the publishBehaviors authoring machinery itself is type-only from this bundle (src/define/behaviors.ts never enters dist/spec). Runtime-core bucket flat (39.08->39.07: the eager graphddb.publishBehaviors member tree-shakes out of a { DDBModel }-only consumer — bc 0.1.7 ships sideEffects:false); import-* bucket 47.8->55.4 (+7.6: bc compileBehaviors recorder/scanner + src/define/behaviors.ts + src/executor/behavior-exec.ts, all reachable only via publishBehaviors / behaviorComponents / behavior-exec). #297 SP5 traced growth: 25.26->28.84 KB (+3.58 brotli), one traced component — behavior-contracts/dist/builder.js (11.69 KB minified) + its guard.js dependency (3.51 KB minified), esbuild metafile-traced: SP5 moved components[] IR assembly/validation/canonicalization OUT of src/spec/components.ts and INTO bc's data-registration builder (buildComponentDefinition, bc#26 — the owner-decided split: extraction stays graphddb, IR shape is bc's), and the builder internally applies assertPortableComponentGraph (guard.js) as its fail-closed self-check, so both are load-bearing in the spec build path BY DESIGN (this is the seam the sub-pass exists to create, not a dependency leak). First-party src/spec shrank slightly (the hand-assembled Component return + inline plan emission were replaced by the registration call). New ceiling 29.3 KB keeps the same ~0.5 KB headroom discipline."
|
|
90
|
+
},
|
|
83
91
|
"size-limit": [
|
|
84
92
|
{
|
|
85
93
|
"name": "runtime core (DDBModel + authoring)",
|
|
@@ -102,7 +110,7 @@
|
|
|
102
110
|
"name": "graphddb/spec (build-time)",
|
|
103
111
|
"path": "dist/spec/index.js",
|
|
104
112
|
"import": "{ buildBridgeBundle }",
|
|
105
|
-
"limit": "
|
|
113
|
+
"limit": "29.3 KB"
|
|
106
114
|
},
|
|
107
115
|
{
|
|
108
116
|
"name": "graphddb/internal (AOT prepared-plan loader)",
|
|
@@ -150,7 +158,7 @@
|
|
|
150
158
|
},
|
|
151
159
|
"license": "MIT",
|
|
152
160
|
"dependencies": {
|
|
153
|
-
"behavior-contracts": "0.
|
|
161
|
+
"behavior-contracts": "0.2.0",
|
|
154
162
|
"commander": "^15.0.0",
|
|
155
163
|
"handlebars": "^4.7.9"
|
|
156
164
|
},
|