graphddb 0.7.10 → 0.8.1

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.
Files changed (46) hide show
  1. package/README.md +6 -6
  2. package/dist/cdc/index.d.ts +389 -5
  3. package/dist/cdc/index.js +4 -4
  4. package/dist/{chunk-AD6ZQTTE.js → chunk-GS4C5VGO.js} +2 -6
  5. package/dist/{chunk-DFUKGU2Q.js → chunk-HNY2EJPV.js} +216 -229
  6. package/dist/{chunk-3ZU2VW3L.js → chunk-L2NEDS7U.js} +582 -781
  7. package/dist/chunk-L4QRCHRQ.js +278 -0
  8. package/dist/chunk-LAT64YCZ.js +1987 -0
  9. package/dist/chunk-S2NI4PBW.js +187 -0
  10. package/dist/{chunk-EOJDN3SA.js → chunk-T44OB5GU.js} +3757 -6138
  11. package/dist/{chunk-PDUVTYC5.js → chunk-XTWXMOHD.js} +0 -1
  12. package/dist/cli.js +63 -254
  13. package/dist/index.d.ts +23 -1550
  14. package/dist/index.js +94 -1850
  15. package/dist/internal/index.d.ts +84 -0
  16. package/dist/internal/index.js +701 -0
  17. package/dist/{maintenance-view-adapter-BAZ9uBGe.d.ts → key-DZtjAQDh.d.ts} +573 -1817
  18. package/dist/linter/index.d.ts +39 -7
  19. package/dist/linter/index.js +22 -4
  20. package/dist/{registry-LWE54Sdc.d.ts → linter-DQY7gUEk.d.ts} +22 -22
  21. package/dist/prepared-artifact-HFealr1q.d.ts +281 -0
  22. package/dist/spec/index.d.ts +506 -5
  23. package/dist/spec/index.js +22 -18
  24. package/dist/testing/index.d.ts +2 -3
  25. package/dist/testing/index.js +4 -4
  26. package/dist/transform/index.d.ts +1 -1
  27. package/dist/transform/index.js +4 -4
  28. package/dist/{types-BQLzTEqh.d.ts → types-2PMXEn5x.d.ts} +8 -10
  29. package/dist/types-DW__-Icc.d.ts +450 -0
  30. package/docs/cdc-projection.md +5 -5
  31. package/docs/class-hydration.md +1 -1
  32. package/docs/cqrs-contract.md +79 -20
  33. package/docs/design-patterns.md +5 -5
  34. package/docs/docs-generation.md +6 -6
  35. package/docs/middleware.md +15 -15
  36. package/docs/mutation-command-derivation.md +52 -42
  37. package/docs/prepared-statements.md +14 -14
  38. package/docs/python-bridge.md +96 -65
  39. package/docs/spec.md +153 -124
  40. package/docs/testing.md +9 -8
  41. package/package.json +14 -4
  42. package/dist/chunk-3UD3XIF2.js +0 -860
  43. package/dist/chunk-MMVHOUM4.js +0 -24
  44. package/dist/from-change-Ty95KA8C.d.ts +0 -327
  45. package/dist/index-Dc7d8mWI.d.ts +0 -1089
  46. package/dist/relation-depth-BRS513Tq.d.ts +0 -36
@@ -0,0 +1,187 @@
1
+ import {
2
+ evaluateKey
3
+ } from "./chunk-T44OB5GU.js";
4
+ import {
5
+ SPEC_VERSION
6
+ } from "./chunk-L4QRCHRQ.js";
7
+ import {
8
+ MetadataRegistry
9
+ } from "./chunk-L2NEDS7U.js";
10
+ import {
11
+ TableMapping
12
+ } from "./chunk-XTWXMOHD.js";
13
+
14
+ // src/spec/manifest.ts
15
+ var DYNAMO_TYPE_TO_FIELD_TYPE = {
16
+ S: "string",
17
+ N: "number",
18
+ BOOL: "boolean",
19
+ B: "binary",
20
+ SS: "stringSet",
21
+ NS: "numberSet",
22
+ L: "list",
23
+ M: "map"
24
+ };
25
+ function sortedRecord(record) {
26
+ const out = {};
27
+ for (const key of Object.keys(record).sort()) {
28
+ out[key] = record[key];
29
+ }
30
+ return out;
31
+ }
32
+ function buildKey(key) {
33
+ if (!key) return null;
34
+ const { pk, sk } = evaluateKey(key.segmented, "param");
35
+ return {
36
+ inputFields: [...key.inputFieldNames],
37
+ pkTemplate: pk,
38
+ skTemplate: sk ?? null
39
+ };
40
+ }
41
+ function buildGsis(metadata) {
42
+ return [...metadata.gsiDefinitions].sort((a, b) => a.indexName.localeCompare(b.indexName)).map((gsi) => {
43
+ const { pk, sk } = evaluateKey(gsi.segmented, "param");
44
+ return {
45
+ indexName: gsi.indexName,
46
+ unique: gsi.unique,
47
+ inputFields: [...gsi.inputFieldNames],
48
+ pkTemplate: pk,
49
+ skTemplate: sk ?? null,
50
+ // Purely-documentary GSI description (issue #166); emitted only when declared
51
+ // so an undescribed index is byte-identical to the pre-#166 manifest.
52
+ ...gsi.description !== void 0 ? { description: gsi.description } : {}
53
+ };
54
+ });
55
+ }
56
+ function buildRelations(metadata) {
57
+ const relations = {};
58
+ for (const rel of metadata.relations) {
59
+ const targetClass = rel.targetFactory();
60
+ relations[rel.propertyName] = {
61
+ type: rel.type,
62
+ target: targetClass.name,
63
+ keyBinding: { ...rel.keyBinding },
64
+ // List-valued source descriptor for a `refs` relation (issue #197); emitted
65
+ // only for `refs` so a scalar-keyed relation is byte-identical to the pre-#197
66
+ // manifest.
67
+ ...rel.refs !== void 0 ? { refs: { ...rel.refs } } : {},
68
+ // Purely-documentary relation description (issue #166); emitted only when
69
+ // declared so an undescribed relation is byte-identical to the pre-#166 manifest.
70
+ ...rel.options?.description !== void 0 ? { description: rel.options.description } : {}
71
+ };
72
+ }
73
+ return sortedRecord(relations);
74
+ }
75
+ function buildFields(metadata) {
76
+ const fields = {};
77
+ for (const field of metadata.fields) {
78
+ const format = field.options?.format;
79
+ const description = field.options?.description;
80
+ fields[field.propertyName] = {
81
+ type: DYNAMO_TYPE_TO_FIELD_TYPE[field.dynamoType],
82
+ ...format ? { format } : {},
83
+ ...description !== void 0 ? { description } : {}
84
+ };
85
+ }
86
+ return sortedRecord(fields);
87
+ }
88
+ function buildManifestEntity(metadata) {
89
+ return buildEntity(metadata);
90
+ }
91
+ function buildEntity(metadata) {
92
+ return {
93
+ table: metadata.tableName,
94
+ physicalName: TableMapping.resolve(metadata.tableName),
95
+ prefix: metadata.prefix,
96
+ fields: buildFields(metadata),
97
+ key: buildKey(metadata.primaryKey),
98
+ gsis: buildGsis(metadata),
99
+ relations: buildRelations(metadata),
100
+ ...metadata.description !== void 0 ? { description: metadata.description } : {},
101
+ // TTL (issue #172, Epic #167 — C4): a physical-schema fact carried on the
102
+ // manifest so the CFn emitter can render `TimeToLiveSpecification`. Absent
103
+ // when no `@ttl` field is declared (byte-identical to the pre-#172 manifest).
104
+ ...metadata.ttlAttribute !== void 0 ? { ttlAttribute: metadata.ttlAttribute } : {}
105
+ };
106
+ }
107
+ function buildManifest(registry = MetadataRegistry) {
108
+ const all = registry.getAll();
109
+ const entitiesByName = /* @__PURE__ */ new Map();
110
+ for (const [cls, metadata] of all) {
111
+ entitiesByName.set(cls.name, metadata);
112
+ }
113
+ const entities = {};
114
+ const tables = {};
115
+ const ttlByPhysicalTable = /* @__PURE__ */ new Map();
116
+ for (const name of [...entitiesByName.keys()].sort()) {
117
+ const metadata = entitiesByName.get(name);
118
+ entities[name] = buildEntity(metadata);
119
+ const physicalName = TableMapping.resolve(metadata.tableName);
120
+ tables[metadata.tableName] = {
121
+ physicalName
122
+ };
123
+ if (metadata.ttlAttribute !== void 0) {
124
+ const existing = ttlByPhysicalTable.get(physicalName);
125
+ if (existing && existing.attr !== metadata.ttlAttribute) {
126
+ throw new Error(
127
+ `Manifest build: physical table '${physicalName}' has more than one TTL attribute \u2014 entity '${existing.entity}' declares \`@ttl\` on '${existing.attr}' and entity '${name}' on '${metadata.ttlAttribute}'. DynamoDB allows exactly one TTL attribute per table; align the \`@ttl\` attribute across all entities sharing this table (or drop one).`
128
+ );
129
+ }
130
+ if (!existing) {
131
+ ttlByPhysicalTable.set(physicalName, {
132
+ entity: name,
133
+ attr: metadata.ttlAttribute
134
+ });
135
+ }
136
+ }
137
+ }
138
+ return {
139
+ version: SPEC_VERSION,
140
+ tables: sortedRecord(tables),
141
+ entities
142
+ };
143
+ }
144
+
145
+ // src/spec/prepared-artifact.ts
146
+ var PREPARED_FORMAT_VERSION = "2";
147
+ function canonicalJson(value) {
148
+ return JSON.stringify(value, (_k, v) => {
149
+ if (v !== null && typeof v === "object" && !Array.isArray(v)) {
150
+ const sorted = {};
151
+ for (const key of Object.keys(v).sort()) {
152
+ sorted[key] = v[key];
153
+ }
154
+ return sorted;
155
+ }
156
+ return v;
157
+ });
158
+ }
159
+ var FNV64_OFFSET_BASIS = 0xcbf29ce484222325n;
160
+ var FNV64_PRIME = 0x100000001b3n;
161
+ var U64_MASK = 0xffffffffffffffffn;
162
+ function fnv1a64Hex(input) {
163
+ let hash = FNV64_OFFSET_BASIS;
164
+ for (let i = 0; i < input.length; i++) {
165
+ const unit = input.charCodeAt(i);
166
+ hash ^= BigInt(unit & 255);
167
+ hash = hash * FNV64_PRIME & U64_MASK;
168
+ hash ^= BigInt(unit >>> 8);
169
+ hash = hash * FNV64_PRIME & U64_MASK;
170
+ }
171
+ return hash.toString(16).padStart(16, "0");
172
+ }
173
+ function entityFingerprint(metadata) {
174
+ return fnv1a64Hex(canonicalJson(buildManifestEntity(metadata)));
175
+ }
176
+ function planFingerprint(plan) {
177
+ return fnv1a64Hex(canonicalJson(plan));
178
+ }
179
+
180
+ export {
181
+ buildManifestEntity,
182
+ buildManifest,
183
+ PREPARED_FORMAT_VERSION,
184
+ canonicalJson,
185
+ entityFingerprint,
186
+ planFingerprint
187
+ };