graphddb 0.2.4 → 0.3.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/index.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  buildBridgeBundle,
17
17
  buildContexts,
18
18
  buildContracts,
19
+ buildMaintenanceGraph,
19
20
  buildManifest,
20
21
  buildOperations,
21
22
  buildProjection,
@@ -56,6 +57,7 @@ import {
56
57
  getEntityWrites,
57
58
  getImplicitKeyFields,
58
59
  hydrate,
60
+ identity,
59
61
  isCommandModelContract,
60
62
  isCommandPlan,
61
63
  isContractComposeNode,
@@ -66,6 +68,7 @@ import {
66
68
  isEdgeWritesDefinition,
67
69
  isEntityWritesDefinition,
68
70
  isLifecycleContract,
71
+ isMaintainTrigger,
69
72
  isMutationFragment,
70
73
  isMutationInputRef,
71
74
  isPlannedCommandMethod,
@@ -73,11 +76,13 @@ import {
73
76
  isSelectBuilder,
74
77
  isTransactionRef,
75
78
  lifecyclePhaseForIntent,
79
+ maintainTrigger,
76
80
  mapWithConcurrency,
77
81
  mintContractKeyFieldRef,
78
82
  mintContractParamRef,
79
83
  mutation,
80
84
  plan,
85
+ preview,
81
86
  publicCommandModel,
82
87
  publicQueryModel,
83
88
  query,
@@ -86,11 +91,11 @@ import {
86
91
  validateDepth,
87
92
  when,
88
93
  wholeKeysSentinel
89
- } from "./chunk-IQEOJVHI.js";
94
+ } from "./chunk-QEOFIXTN.js";
90
95
  import {
91
96
  CdcEmulator,
92
97
  createCdcEmulator
93
- } from "./chunk-LNESVUTO.js";
98
+ } from "./chunk-QQNP43JL.js";
94
99
  import {
95
100
  BATCH_GET_MAX_KEYS,
96
101
  BATCH_WRITE_MAX_ITEMS,
@@ -139,7 +144,7 @@ import {
139
144
  resolveKey,
140
145
  resolveModelClass,
141
146
  serializeFieldValue
142
- } from "./chunk-GCPEUPAA.js";
147
+ } from "./chunk-6AIAHP3A.js";
143
148
 
144
149
  // src/metadata/prefix.ts
145
150
  function derivePrefix(customPrefix, className) {
@@ -189,6 +194,7 @@ function validateGsiAmbiguity(primaryKey, gsiDefinitions) {
189
194
  var pendingFields = [];
190
195
  var pendingEmbedded = [];
191
196
  var pendingRelations = [];
197
+ var pendingAggregates = [];
192
198
  function collectField(field2) {
193
199
  pendingFields.push(field2);
194
200
  }
@@ -198,6 +204,9 @@ function collectEmbedded(embedded2) {
198
204
  function collectRelation(relation) {
199
205
  pendingRelations.push(relation);
200
206
  }
207
+ function collectAggregate(aggregate2) {
208
+ pendingAggregates.push(aggregate2);
209
+ }
201
210
  function drainFields() {
202
211
  const result = pendingFields;
203
212
  pendingFields = [];
@@ -213,6 +222,11 @@ function drainRelations() {
213
222
  pendingRelations = [];
214
223
  return result;
215
224
  }
225
+ function drainAggregates() {
226
+ const result = pendingAggregates;
227
+ pendingAggregates = [];
228
+ return result;
229
+ }
216
230
 
217
231
  // src/decorators/model.ts
218
232
  function model(options) {
@@ -220,6 +234,7 @@ function model(options) {
220
234
  const fields = drainFields();
221
235
  const embeddedFields = drainEmbedded();
222
236
  const relations = drainRelations();
237
+ const aggregates = drainAggregates();
223
238
  const prefix = derivePrefix(options.prefix, context.name);
224
239
  MetadataRegistry.register(target, {
225
240
  tableName: options.table,
@@ -228,6 +243,7 @@ function model(options) {
228
243
  primaryKey: null,
229
244
  gsiDefinitions: [],
230
245
  relations,
246
+ aggregates,
231
247
  embeddedFields
232
248
  });
233
249
  };
@@ -322,7 +338,7 @@ function hasMany(targetFactory, keyBinding, options) {
322
338
  });
323
339
  };
324
340
  }
325
- function belongsTo(targetFactory, keyBinding) {
341
+ function belongsTo(targetFactory, keyBinding, options) {
326
342
  return function(_value, context) {
327
343
  const propertyName = String(context.name);
328
344
  assertRelationPropertyNameAllowed(propertyName);
@@ -330,7 +346,8 @@ function belongsTo(targetFactory, keyBinding) {
330
346
  type: "belongsTo",
331
347
  propertyName,
332
348
  targetFactory,
333
- keyBinding
349
+ keyBinding,
350
+ options
334
351
  });
335
352
  };
336
353
  }
@@ -347,6 +364,29 @@ function hasOne(targetFactory, keyBinding) {
347
364
  };
348
365
  }
349
366
 
367
+ // src/decorators/aggregate.ts
368
+ function aggregate(targetFactory, keyBinding, options) {
369
+ return function(_value, context) {
370
+ collectAggregate({
371
+ propertyName: String(context.name),
372
+ targetFactory,
373
+ keyBinding,
374
+ options
375
+ });
376
+ };
377
+ }
378
+ function count() {
379
+ return { op: "count" };
380
+ }
381
+ function max(field2) {
382
+ if (typeof field2 !== "string" || field2.length === 0) {
383
+ throw new Error(
384
+ `max(...) requires a non-empty source field name to aggregate (e.g. max('createdAt')), but received ${JSON.stringify(field2)}.`
385
+ );
386
+ }
387
+ return { op: "max", field: field2 };
388
+ }
389
+
350
390
  // src/operations/declarative-transaction.ts
351
391
  var PLACEHOLDER_RE = /\{[^{}]+\}/g;
352
392
  function resolveTemplate(template, params, element) {
@@ -484,6 +524,79 @@ function entityByName(manifest, name) {
484
524
  function physicalTableName(manifest, logical) {
485
525
  return manifest.tables[logical]?.physicalName ?? logical;
486
526
  }
527
+ function applyMaintainTransform(op, args, value) {
528
+ if (op === "identity") return value;
529
+ if (op === "preview") {
530
+ const n = args[0];
531
+ if (typeof n !== "number" || !Number.isInteger(n) || n <= 0) {
532
+ throw new Error(
533
+ `declarative transaction: a maintenance \`preview\` projection has a non-positive-integer length bound (${JSON.stringify(n)}).`
534
+ );
535
+ }
536
+ if (value === null || value === void 0) return value;
537
+ return String(value).slice(0, n);
538
+ }
539
+ throw new Error(
540
+ `declarative transaction: unknown maintenance projection op '${String(op)}' (expected 'identity' / 'preview').`
541
+ );
542
+ }
543
+ function buildMaintainProjection(maintain, params, element) {
544
+ const out = {};
545
+ for (const [attr, transform] of Object.entries(maintain.projection)) {
546
+ const value = resolveValue(`{${transform.inputField}}`, params, element);
547
+ out[attr] = applyMaintainTransform(transform.op, transform.args, value);
548
+ }
549
+ return out;
550
+ }
551
+ function buildMaintainUpdateItem(spec, maintain, table, key2, params, element) {
552
+ const update = { TableName: table, Key: key2 };
553
+ if (maintain.kind === "counter") {
554
+ const counter = maintain.counter;
555
+ if (counter === void 0) {
556
+ throw new Error(
557
+ `declarative transaction: a 'counter' maintenance write on '${spec.entity}' has no \`counter\` payload.`
558
+ );
559
+ }
560
+ update.UpdateExpression = "ADD #a0 :a0";
561
+ update.ExpressionAttributeNames = { "#a0": counter.attribute };
562
+ update.ExpressionAttributeValues = {
563
+ ":a0": typeof counter.delta === "string" ? Number(counter.delta) : counter.delta
564
+ };
565
+ return { Update: update };
566
+ }
567
+ const projection = buildMaintainProjection(maintain, params, element);
568
+ if (maintain.kind === "collection") {
569
+ const field2 = maintain.collection?.field;
570
+ if (field2 === void 0) {
571
+ throw new Error(
572
+ `declarative transaction: a 'collection' maintenance write on '${spec.entity}' has no \`collection.field\`.`
573
+ );
574
+ }
575
+ update.UpdateExpression = "SET #c = list_append(if_not_exists(#c, :empty), :item)";
576
+ update.ExpressionAttributeNames = { "#c": field2 };
577
+ update.ExpressionAttributeValues = { ":empty": [], ":item": [projection] };
578
+ } else {
579
+ const names = {};
580
+ const values = {};
581
+ const sets = [];
582
+ let i = 0;
583
+ for (const [attr, value] of Object.entries(projection)) {
584
+ names[`#m${i}`] = attr;
585
+ values[`:m${i}`] = value;
586
+ sets.push(`#m${i} = :m${i}`);
587
+ i++;
588
+ }
589
+ if (sets.length === 0) {
590
+ throw new Error(
591
+ `declarative transaction: a 'snapshot' maintenance write on '${spec.entity}' has an empty projection.`
592
+ );
593
+ }
594
+ update.UpdateExpression = `SET ${sets.join(", ")}`;
595
+ update.ExpressionAttributeNames = names;
596
+ update.ExpressionAttributeValues = values;
597
+ }
598
+ return { Update: update };
599
+ }
487
600
  function buildTransactItem(spec, manifest, params, element) {
488
601
  const literal2 = spec.literalKey === true;
489
602
  const entity = literal2 ? void 0 : entityByName(manifest, spec.entity);
@@ -511,6 +624,9 @@ function buildTransactItem(spec, manifest, params, element) {
511
624
  applyCondition(spec.condition, check, params, element);
512
625
  return { ConditionCheck: check };
513
626
  }
627
+ if (spec.maintain !== void 0) {
628
+ return buildMaintainUpdateItem(spec, spec.maintain, table, key2, params, element);
629
+ }
514
630
  const changes = resolveRecord(spec.changes, params, element);
515
631
  const adds = resolveRecord(spec.add, params, element);
516
632
  const names = {};
@@ -600,8 +716,8 @@ async function executeDeclarativeTransaction(spec, manifest, params) {
600
716
  expanded.map((e) => e.item),
601
717
  {
602
718
  modelBySignature,
603
- limitError: (count) => new Error(
604
- `declarative transaction: expanded to ${count} items, exceeds the DynamoDB TransactWriteItems limit of ${MAX_TRANSACT_ITEMS}.`
719
+ limitError: (count2) => new Error(
720
+ `declarative transaction: expanded to ${count2} items, exceeds the DynamoDB TransactWriteItems limit of ${MAX_TRANSACT_ITEMS}.`
605
721
  )
606
722
  }
607
723
  );
@@ -1063,6 +1179,7 @@ export {
1063
1179
  SPEC_VERSION,
1064
1180
  TableMapping,
1065
1181
  TransactionContext,
1182
+ aggregate,
1066
1183
  assertBundleSerializable,
1067
1184
  assertContractBoundaries,
1068
1185
  assertContractN1Safe,
@@ -1077,6 +1194,7 @@ export {
1077
1194
  buildContexts,
1078
1195
  buildContracts,
1079
1196
  buildDeleteInput,
1197
+ buildMaintenanceGraph,
1080
1198
  buildManifest,
1081
1199
  buildOperations,
1082
1200
  buildProjection,
@@ -1094,6 +1212,7 @@ export {
1094
1212
  compileSingleFragmentPlan,
1095
1213
  cond,
1096
1214
  contractOfMethodSpec,
1215
+ count,
1097
1216
  createCdcEmulator,
1098
1217
  createDefaultLinter,
1099
1218
  datetime,
@@ -1146,6 +1265,7 @@ export {
1146
1265
  hasMany,
1147
1266
  hasOne,
1148
1267
  hydrate,
1268
+ identity,
1149
1269
  isColumn,
1150
1270
  isCommandModelContract,
1151
1271
  isCommandPlan,
@@ -1158,6 +1278,7 @@ export {
1158
1278
  isEntityWritesDefinition,
1159
1279
  isKeySegment,
1160
1280
  isLifecycleContract,
1281
+ isMaintainTrigger,
1161
1282
  isMutationFragment,
1162
1283
  isMutationInputRef,
1163
1284
  isParam,
@@ -1172,7 +1293,9 @@ export {
1172
1293
  lifecyclePhaseForIntent,
1173
1294
  list,
1174
1295
  literal,
1296
+ maintainTrigger,
1175
1297
  map,
1298
+ max,
1176
1299
  mintContractKeyFieldRef,
1177
1300
  mintContractParamRef,
1178
1301
  missingGsiRule,
@@ -1183,6 +1306,7 @@ export {
1183
1306
  numberSet,
1184
1307
  param,
1185
1308
  plan,
1309
+ preview,
1186
1310
  publicCommandModel,
1187
1311
  publicQueryModel,
1188
1312
  query,
@@ -1,4 +1,4 @@
1
- import { E as Executor, D as DynamoDBOperation, R as ReadExecOptions, a as ExecutorResult, B as BatchGetExecInput, P as PutInput, W as WriteExecOptions, b as WriteResult, U as UpdateInput, c as DeleteInput, d as BatchWriteExecItem, e as BatchExecOptions, T as TransactWriteExecItem, M as ModelStatic, f as DDBModel, C as ChangeEvent } from '../types-BEeQ_nSd.js';
1
+ import { E as Executor, D as DynamoDBOperation, R as ReadExecOptions, a as ExecutorResult, B as BatchGetExecInput, P as PutInput, W as WriteExecOptions, b as WriteResult, U as UpdateInput, c as DeleteInput, d as BatchWriteExecItem, e as BatchExecOptions, T as TransactWriteExecItem, M as ModelStatic, f as DDBModel, C as ChangeEvent } from '../types-xJRn5qkv.js';
2
2
  import '@aws-sdk/client-dynamodb';
3
3
 
4
4
  /**
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createCdcEmulator
3
- } from "../chunk-LNESVUTO.js";
3
+ } from "../chunk-QQNP43JL.js";
4
4
  import {
5
5
  ClientManager,
6
6
  MetadataRegistry,
7
7
  TableMapping,
8
8
  resolveModelClass
9
- } from "../chunk-GCPEUPAA.js";
9
+ } from "../chunk-6AIAHP3A.js";
10
10
 
11
11
  // src/memory/memory-store.ts
12
12
  function deepClone(value) {