@revisium/schema-toolkit 0.14.2 → 0.15.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.
Files changed (88) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-DJ4JPKI4.js → chunk-2NRQPOQY.js} +126 -218
  3. package/dist/chunk-2NRQPOQY.js.map +1 -0
  4. package/dist/chunk-3IKI64T2.js +3 -0
  5. package/dist/{chunk-H7W4QNMA.js.map → chunk-3IKI64T2.js.map} +1 -1
  6. package/dist/chunk-5WZ4YPH5.cjs +2209 -0
  7. package/dist/chunk-5WZ4YPH5.cjs.map +1 -0
  8. package/dist/chunk-A4E524UU.cjs +2179 -0
  9. package/dist/chunk-A4E524UU.cjs.map +1 -0
  10. package/dist/{chunk-L5MLJEC7.js → chunk-CYTPQYVM.js} +2 -2
  11. package/dist/chunk-CYTPQYVM.js.map +1 -0
  12. package/dist/chunk-F4UBBZAL.js +2147 -0
  13. package/dist/chunk-F4UBBZAL.js.map +1 -0
  14. package/dist/{chunk-B22UU3JK.cjs → chunk-GAPLSVZN.cjs} +2 -2
  15. package/dist/chunk-GAPLSVZN.cjs.map +1 -0
  16. package/dist/chunk-OP35BPMU.js +2178 -0
  17. package/dist/chunk-OP35BPMU.js.map +1 -0
  18. package/dist/chunk-TBFTADML.cjs +4 -0
  19. package/dist/{chunk-ODCH3PP2.cjs.map → chunk-TBFTADML.cjs.map} +1 -1
  20. package/dist/chunk-WSPFHUHU.cjs +130 -0
  21. package/dist/chunk-WSPFHUHU.cjs.map +1 -0
  22. package/dist/{chunk-VX5C5YMF.cjs → chunk-XS47N22X.cjs} +125 -218
  23. package/dist/chunk-XS47N22X.cjs.map +1 -0
  24. package/dist/chunk-YFWOURZL.js +128 -0
  25. package/dist/chunk-YFWOURZL.js.map +1 -0
  26. package/dist/{chunk-KJCURW4D.js → chunk-ZBPUTF3Q.js} +3 -3
  27. package/dist/chunk-ZBPUTF3Q.js.map +1 -0
  28. package/dist/{chunk-GF3XXYOS.cjs → chunk-ZRNFSUOV.cjs} +3 -3
  29. package/dist/chunk-ZRNFSUOV.cjs.map +1 -0
  30. package/dist/computeValueDiff-CDwbNw8F.d.ts +5 -0
  31. package/dist/computeValueDiff-CNT84rwK.d.cts +5 -0
  32. package/dist/core/index.cjs +474 -0
  33. package/dist/core/index.cjs.map +1 -0
  34. package/dist/core/index.d.cts +313 -0
  35. package/dist/core/index.d.ts +313 -0
  36. package/dist/core/index.js +336 -0
  37. package/dist/core/index.js.map +1 -0
  38. package/dist/formula/index.d.cts +1 -1
  39. package/dist/formula/index.d.ts +1 -1
  40. package/dist/index.cjs +166 -44
  41. package/dist/index.d.cts +11 -7
  42. package/dist/index.d.ts +11 -7
  43. package/dist/index.js +7 -5
  44. package/dist/{json-patch.types-CYt9TCu3.d.ts → json-patch.types-DTUHS9SV.d.ts} +1 -1
  45. package/dist/{json-patch.types-DUcWbQRY.d.cts → json-patch.types-eltVqnWC.d.cts} +1 -1
  46. package/dist/{json-string.store-CcZ197KO.d.cts → json-string.store-DKlkc1u_.d.cts} +1 -1
  47. package/dist/{json-string.store-DckDcMVN.d.ts → json-string.store-DMrHPJ3v.d.ts} +1 -1
  48. package/dist/json-value-patch.types-CjBpq5VF.d.cts +24 -0
  49. package/dist/json-value-patch.types-U2y_ugm1.d.ts +24 -0
  50. package/dist/lib/index.cjs +40 -39
  51. package/dist/lib/index.d.cts +6 -7
  52. package/dist/lib/index.d.ts +6 -7
  53. package/dist/lib/index.js +4 -3
  54. package/dist/mocks/index.cjs +1 -1
  55. package/dist/mocks/index.d.cts +2 -2
  56. package/dist/mocks/index.d.ts +2 -2
  57. package/dist/mocks/index.js +1 -1
  58. package/dist/model/index.cjs +125 -2
  59. package/dist/model/index.d.cts +582 -4
  60. package/dist/model/index.d.ts +582 -4
  61. package/dist/model/index.js +5 -2
  62. package/dist/plugins/index.cjs +1 -1
  63. package/dist/plugins/index.d.cts +25 -1
  64. package/dist/plugins/index.d.ts +25 -1
  65. package/dist/plugins/index.js +1 -1
  66. package/dist/{schema.types-CLHMJmkJ.d.cts → schema.types-ZX5fUW1X.d.cts} +6 -0
  67. package/dist/{schema.types-CLHMJmkJ.d.ts → schema.types-ZX5fUW1X.d.ts} +6 -0
  68. package/dist/types/index.cjs +5 -5
  69. package/dist/types/index.d.cts +8 -29
  70. package/dist/types/index.d.ts +8 -29
  71. package/dist/types/index.js +3 -3
  72. package/dist/{value-diff.types-BRoI_kGE.d.cts → types-C_GxaUve.d.cts} +4 -4
  73. package/dist/{value-diff.types-BRoI_kGE.d.ts → types-C_GxaUve.d.ts} +4 -4
  74. package/dist/types-CwJ2OWO_.d.cts +183 -0
  75. package/dist/types-XDWz0V1v.d.ts +183 -0
  76. package/package.json +15 -2
  77. package/dist/chunk-B22UU3JK.cjs.map +0 -1
  78. package/dist/chunk-DJ4JPKI4.js.map +0 -1
  79. package/dist/chunk-GF3XXYOS.cjs.map +0 -1
  80. package/dist/chunk-H7W4QNMA.js +0 -3
  81. package/dist/chunk-KJCURW4D.js.map +0 -1
  82. package/dist/chunk-L5MLJEC7.js.map +0 -1
  83. package/dist/chunk-ODCH3PP2.cjs +0 -4
  84. package/dist/chunk-SBJFTOWW.js +0 -3
  85. package/dist/chunk-SBJFTOWW.js.map +0 -1
  86. package/dist/chunk-VX5C5YMF.cjs.map +0 -1
  87. package/dist/chunk-XAFOMEOK.cjs +0 -4
  88. package/dist/chunk-XAFOMEOK.cjs.map +0 -1
@@ -0,0 +1,2209 @@
1
+ 'use strict';
2
+
3
+ var chunkA4E524UU_cjs = require('./chunk-A4E524UU.cjs');
4
+ var nanoid = require('nanoid');
5
+
6
+ var SchemaParser = class {
7
+ pendingFormulas = [];
8
+ parse(schema) {
9
+ this.pendingFormulas = [];
10
+ return this.parseNode(schema, "root");
11
+ }
12
+ parseFormulas(tree) {
13
+ for (const pending of this.pendingFormulas) {
14
+ const node = tree.nodeById(pending.nodeId);
15
+ if (node.isNull()) {
16
+ continue;
17
+ }
18
+ const formula = new chunkA4E524UU_cjs.ParsedFormula(tree, pending.nodeId, pending.expression);
19
+ node.setFormula(formula);
20
+ }
21
+ this.pendingFormulas = [];
22
+ }
23
+ parseNode(schema, name) {
24
+ if ("$ref" in schema) {
25
+ return chunkA4E524UU_cjs.createRefNode(
26
+ nanoid.nanoid(),
27
+ name,
28
+ schema.$ref,
29
+ this.extractMetadata(schema)
30
+ );
31
+ }
32
+ const schemaWithType = schema;
33
+ switch (schemaWithType.type) {
34
+ case "object" /* Object */:
35
+ return this.parseObject(schemaWithType, name);
36
+ case "array" /* Array */:
37
+ return this.parseArray(schemaWithType, name);
38
+ case "string" /* String */:
39
+ return this.parseString(schemaWithType, name);
40
+ case "number" /* Number */:
41
+ return this.parseNumber(schemaWithType, name);
42
+ case "boolean" /* Boolean */:
43
+ return this.parseBoolean(schemaWithType, name);
44
+ default:
45
+ throw new Error(`Unknown schema type: ${schemaWithType.type}`);
46
+ }
47
+ }
48
+ parseObject(schema, name) {
49
+ const children = [];
50
+ for (const propName of Object.keys(schema.properties).sort((a, b) => a.localeCompare(b))) {
51
+ const propSchema = schema.properties[propName];
52
+ if (propSchema) {
53
+ children.push(this.parseNode(propSchema, propName));
54
+ }
55
+ }
56
+ return chunkA4E524UU_cjs.createObjectNode(
57
+ nanoid.nanoid(),
58
+ name,
59
+ children,
60
+ this.extractMetadata(schema)
61
+ );
62
+ }
63
+ parseArray(schema, name) {
64
+ const items = this.parseNode(schema.items, "items");
65
+ return chunkA4E524UU_cjs.createArrayNode(
66
+ nanoid.nanoid(),
67
+ name,
68
+ items,
69
+ this.extractMetadata(schema)
70
+ );
71
+ }
72
+ parseString(schema, name) {
73
+ const nodeId = nanoid.nanoid();
74
+ this.collectFormula(nodeId, schema["x-formula"]);
75
+ return chunkA4E524UU_cjs.createStringNode(nodeId, name, {
76
+ defaultValue: schema.default,
77
+ foreignKey: schema.foreignKey,
78
+ metadata: this.extractMetadata(schema)
79
+ });
80
+ }
81
+ parseNumber(schema, name) {
82
+ const nodeId = nanoid.nanoid();
83
+ this.collectFormula(nodeId, schema["x-formula"]);
84
+ return chunkA4E524UU_cjs.createNumberNode(nodeId, name, {
85
+ defaultValue: schema.default,
86
+ metadata: this.extractMetadata(schema)
87
+ });
88
+ }
89
+ parseBoolean(schema, name) {
90
+ const nodeId = nanoid.nanoid();
91
+ this.collectFormula(nodeId, schema["x-formula"]);
92
+ return chunkA4E524UU_cjs.createBooleanNode(nodeId, name, {
93
+ defaultValue: schema.default,
94
+ metadata: this.extractMetadata(schema)
95
+ });
96
+ }
97
+ extractMetadata(schema) {
98
+ const meta = {};
99
+ let hasValue = false;
100
+ if ("title" in schema && schema.title) {
101
+ meta.title = schema.title;
102
+ hasValue = true;
103
+ }
104
+ if ("description" in schema && schema.description) {
105
+ meta.description = schema.description;
106
+ hasValue = true;
107
+ }
108
+ if ("deprecated" in schema && schema.deprecated) {
109
+ meta.deprecated = schema.deprecated;
110
+ hasValue = true;
111
+ }
112
+ return hasValue ? meta : void 0;
113
+ }
114
+ collectFormula(nodeId, xFormula) {
115
+ if (xFormula) {
116
+ this.pendingFormulas.push({ nodeId, expression: xFormula.expression });
117
+ }
118
+ }
119
+ };
120
+ var NodeFactory = class {
121
+ createNode(name, type) {
122
+ switch (type) {
123
+ case "string":
124
+ return chunkA4E524UU_cjs.createStringNode(nanoid.nanoid(), name, { defaultValue: "" });
125
+ case "number":
126
+ return chunkA4E524UU_cjs.createNumberNode(nanoid.nanoid(), name, { defaultValue: 0 });
127
+ case "boolean":
128
+ return chunkA4E524UU_cjs.createBooleanNode(nanoid.nanoid(), name, { defaultValue: false });
129
+ case "object":
130
+ return chunkA4E524UU_cjs.createObjectNode(nanoid.nanoid(), name, []);
131
+ case "array":
132
+ return this.createArrayNode(name);
133
+ default:
134
+ throw new Error(`Unknown field type: ${type}`);
135
+ }
136
+ }
137
+ createArrayNode(name) {
138
+ const items = chunkA4E524UU_cjs.createStringNode(nanoid.nanoid(), "items", { defaultValue: "" });
139
+ return chunkA4E524UU_cjs.createArrayNode(nanoid.nanoid(), name, items);
140
+ }
141
+ };
142
+
143
+ // src/model/default-value/generateDefaultValue.ts
144
+ var DEFAULT_STRING = "";
145
+ var DEFAULT_NUMBER = 0;
146
+ var DEFAULT_BOOLEAN = false;
147
+ function isRefSchema(schema) {
148
+ return "$ref" in schema;
149
+ }
150
+ function isObjectSchema(schema) {
151
+ return "type" in schema && schema.type === "object" /* Object */;
152
+ }
153
+ function isArraySchema(schema) {
154
+ return "type" in schema && schema.type === "array" /* Array */;
155
+ }
156
+ function hasDefaultValue(schema) {
157
+ return "default" in schema && schema.default !== void 0;
158
+ }
159
+ function generatePrimitiveDefault(schema) {
160
+ if (!("type" in schema)) {
161
+ return void 0;
162
+ }
163
+ switch (schema.type) {
164
+ case "string" /* String */:
165
+ return DEFAULT_STRING;
166
+ case "number" /* Number */:
167
+ return DEFAULT_NUMBER;
168
+ case "boolean" /* Boolean */:
169
+ return DEFAULT_BOOLEAN;
170
+ default:
171
+ return void 0;
172
+ }
173
+ }
174
+ function generateObjectDefault(schema, options) {
175
+ const result = {};
176
+ if (!schema.properties) {
177
+ return result;
178
+ }
179
+ for (const [key, propertySchema] of Object.entries(schema.properties)) {
180
+ result[key] = generateDefaultValueInternal(propertySchema, options);
181
+ }
182
+ return result;
183
+ }
184
+ function generateArrayDefault(schema, options) {
185
+ const itemCount = options.arrayItemCount ?? 0;
186
+ if (itemCount === 0 || !schema.items) {
187
+ return [];
188
+ }
189
+ const itemDefault = generateDefaultValueInternal(schema.items, options);
190
+ return Array.from({ length: itemCount }, () => {
191
+ if (typeof itemDefault === "object" && itemDefault !== null) {
192
+ return generateDefaultValueInternal(schema.items, options);
193
+ }
194
+ return itemDefault;
195
+ });
196
+ }
197
+ function generateRefDefault(schema, options) {
198
+ const refSchemas = options.refSchemas;
199
+ if (!refSchemas) {
200
+ return {};
201
+ }
202
+ const refSchema = refSchemas[schema.$ref];
203
+ if (!refSchema) {
204
+ return {};
205
+ }
206
+ return generateDefaultValueInternal(refSchema, options);
207
+ }
208
+ function generateDefaultValueInternal(schema, options) {
209
+ if (hasDefaultValue(schema)) {
210
+ return schema.default;
211
+ }
212
+ if (isRefSchema(schema)) {
213
+ return generateRefDefault(schema, options);
214
+ }
215
+ if (isObjectSchema(schema)) {
216
+ return generateObjectDefault(schema, options);
217
+ }
218
+ if (isArraySchema(schema)) {
219
+ return generateArrayDefault(schema, options);
220
+ }
221
+ return generatePrimitiveDefault(schema);
222
+ }
223
+ function generateDefaultValue(schema, options = {}) {
224
+ if (!schema) {
225
+ return {};
226
+ }
227
+ return generateDefaultValueInternal(schema, options);
228
+ }
229
+
230
+ // src/model/schema-model/SchemaModelImpl.ts
231
+ var SchemaModelImpl = class {
232
+ _baseTree;
233
+ _currentTree;
234
+ _reactivity;
235
+ _patchBuilder = new chunkA4E524UU_cjs.PatchBuilder();
236
+ _serializer = new chunkA4E524UU_cjs.SchemaSerializer();
237
+ _nodeFactory = new NodeFactory();
238
+ _formulaIndex = new chunkA4E524UU_cjs.FormulaDependencyIndex();
239
+ constructor(schema, options) {
240
+ const parser = new SchemaParser();
241
+ const rootNode = parser.parse(schema);
242
+ this._currentTree = chunkA4E524UU_cjs.createSchemaTree(rootNode);
243
+ parser.parseFormulas(this._currentTree);
244
+ this._buildFormulaIndex();
245
+ this._baseTree = this._currentTree.clone();
246
+ this._reactivity = options?.reactivity;
247
+ if (this._reactivity) {
248
+ this._reactivity.makeObservable(this, {
249
+ _currentTree: "observable.ref",
250
+ _baseTree: "observable.ref",
251
+ root: "computed",
252
+ isDirty: "computed",
253
+ getPatches: "computed",
254
+ getJsonPatches: "computed",
255
+ getPlainSchema: "computed",
256
+ addField: "action",
257
+ removeField: "action",
258
+ renameField: "action",
259
+ changeFieldType: "action",
260
+ updateMetadata: "action",
261
+ updateFormula: "action",
262
+ updateForeignKey: "action",
263
+ updateDefaultValue: "action",
264
+ markAsSaved: "action",
265
+ revert: "action"
266
+ });
267
+ }
268
+ }
269
+ root() {
270
+ return this._currentTree.root();
271
+ }
272
+ nodeById(id) {
273
+ return this._currentTree.nodeById(id);
274
+ }
275
+ pathOf(id) {
276
+ return this._currentTree.pathOf(id);
277
+ }
278
+ addField(parentId, name, type) {
279
+ const node = this._nodeFactory.createNode(name, type);
280
+ this._currentTree.addChildTo(parentId, node);
281
+ return node;
282
+ }
283
+ removeField(nodeId) {
284
+ const path = this._currentTree.pathOf(nodeId);
285
+ if (path.isEmpty()) {
286
+ return false;
287
+ }
288
+ return this._currentTree.removeNodeAt(path);
289
+ }
290
+ renameField(nodeId, newName) {
291
+ const node = this._currentTree.nodeById(nodeId);
292
+ if (node.isNull()) {
293
+ return;
294
+ }
295
+ this._currentTree.renameNode(nodeId, newName);
296
+ }
297
+ changeFieldType(nodeId, newType) {
298
+ const node = this._currentTree.nodeById(nodeId);
299
+ if (node.isNull()) {
300
+ return node;
301
+ }
302
+ const path = this._currentTree.pathOf(nodeId);
303
+ if (path.isEmpty()) {
304
+ return node;
305
+ }
306
+ const newNode = this._nodeFactory.createNode(node.name(), newType);
307
+ this._currentTree.setNodeAt(path, newNode);
308
+ this._currentTree.trackReplacement(nodeId, newNode.id());
309
+ return newNode;
310
+ }
311
+ updateMetadata(nodeId, meta) {
312
+ const node = this._currentTree.nodeById(nodeId);
313
+ if (node.isNull()) {
314
+ return;
315
+ }
316
+ const currentMeta = node.metadata();
317
+ const newMeta = {
318
+ ...currentMeta,
319
+ ...meta
320
+ };
321
+ node.setMetadata(newMeta);
322
+ }
323
+ updateFormula(nodeId, expression) {
324
+ const node = this._currentTree.nodeById(nodeId);
325
+ if (node.isNull()) {
326
+ return;
327
+ }
328
+ if (expression === void 0) {
329
+ node.setFormula(void 0);
330
+ this._formulaIndex.unregisterFormula(nodeId);
331
+ } else {
332
+ const formula = new chunkA4E524UU_cjs.ParsedFormula(this._currentTree, nodeId, expression);
333
+ node.setFormula(formula);
334
+ this._formulaIndex.registerFormula(nodeId, formula);
335
+ }
336
+ }
337
+ updateForeignKey(nodeId, foreignKey) {
338
+ const node = this._currentTree.nodeById(nodeId);
339
+ if (node.isNull()) {
340
+ return;
341
+ }
342
+ node.setForeignKey(foreignKey);
343
+ }
344
+ updateDefaultValue(nodeId, value) {
345
+ const node = this._currentTree.nodeById(nodeId);
346
+ if (node.isNull()) {
347
+ return;
348
+ }
349
+ node.setDefaultValue(value);
350
+ }
351
+ isDirty() {
352
+ return this.getPatches().length > 0;
353
+ }
354
+ isValid() {
355
+ return this._currentTree.root().isObject();
356
+ }
357
+ getPatches() {
358
+ return this._patchBuilder.build(this._currentTree, this._baseTree);
359
+ }
360
+ getJsonPatches() {
361
+ return this.getPatches().map((p) => p.patch);
362
+ }
363
+ markAsSaved() {
364
+ this._baseTree = this._currentTree.clone();
365
+ }
366
+ revert() {
367
+ this._currentTree = this._baseTree.clone();
368
+ }
369
+ getPlainSchema() {
370
+ return this._serializer.serializeTree(this._currentTree);
371
+ }
372
+ generateDefaultValue(options) {
373
+ return generateDefaultValue(this.getPlainSchema(), options);
374
+ }
375
+ _buildFormulaIndex() {
376
+ this._formulaIndex.clear();
377
+ for (const nodeId of this._currentTree.nodeIds()) {
378
+ const node = this._currentTree.nodeById(nodeId);
379
+ const formula = node.formula();
380
+ if (formula) {
381
+ this._formulaIndex.registerFormula(nodeId, formula);
382
+ }
383
+ }
384
+ }
385
+ };
386
+ function createSchemaModel(schema, options) {
387
+ return new SchemaModelImpl(schema, options);
388
+ }
389
+
390
+ // src/model/table/row/RowModelImpl.ts
391
+ var UNSET_INDEX = -1;
392
+ var RowModelImpl = class {
393
+ constructor(_rowId, _tree, _reactivity) {
394
+ this._rowId = _rowId;
395
+ this._tree = _tree;
396
+ this._reactivity = _reactivity;
397
+ this.initObservable();
398
+ }
399
+ _tableModel = null;
400
+ initObservable() {
401
+ this._reactivity?.makeObservable(this, {
402
+ _tableModel: "observable.ref",
403
+ index: "computed",
404
+ prev: "computed",
405
+ next: "computed",
406
+ isDirty: "computed",
407
+ isValid: "computed",
408
+ errors: "computed"
409
+ });
410
+ }
411
+ get rowId() {
412
+ return this._rowId;
413
+ }
414
+ get tableModel() {
415
+ return this._tableModel;
416
+ }
417
+ get tree() {
418
+ return this._tree;
419
+ }
420
+ get index() {
421
+ if (!this._tableModel) {
422
+ return UNSET_INDEX;
423
+ }
424
+ return this._tableModel.getRowIndex(this._rowId);
425
+ }
426
+ get prev() {
427
+ if (!this._tableModel) {
428
+ return null;
429
+ }
430
+ const currentIndex = this.index;
431
+ if (currentIndex <= 0) {
432
+ return null;
433
+ }
434
+ return this._tableModel.getRowAt(currentIndex - 1) ?? null;
435
+ }
436
+ get next() {
437
+ if (!this._tableModel) {
438
+ return null;
439
+ }
440
+ const currentIndex = this.index;
441
+ if (currentIndex === UNSET_INDEX || currentIndex >= this._tableModel.rowCount - 1) {
442
+ return null;
443
+ }
444
+ return this._tableModel.getRowAt(currentIndex + 1) ?? null;
445
+ }
446
+ get(path) {
447
+ return this._tree.get(path);
448
+ }
449
+ getValue(path) {
450
+ return this._tree.getValue(path);
451
+ }
452
+ setValue(path, value) {
453
+ this._tree.setValue(path, value);
454
+ }
455
+ getPlainValue() {
456
+ return this._tree.getPlainValue();
457
+ }
458
+ get isDirty() {
459
+ return this._tree.isDirty;
460
+ }
461
+ get isValid() {
462
+ return this._tree.isValid;
463
+ }
464
+ get errors() {
465
+ return this._tree.errors;
466
+ }
467
+ getPatches() {
468
+ return this._tree.getPatches();
469
+ }
470
+ commit() {
471
+ this._tree.commit();
472
+ }
473
+ revert() {
474
+ this._tree.revert();
475
+ }
476
+ setTableModel(tableModel) {
477
+ this._tableModel = tableModel;
478
+ }
479
+ };
480
+
481
+ // src/model/value-node/BaseValueNode.ts
482
+ var nodeIdCounter = 0;
483
+ function generateNodeId() {
484
+ return `node-${++nodeIdCounter}`;
485
+ }
486
+ function resetNodeIdCounter() {
487
+ nodeIdCounter = 0;
488
+ }
489
+ var BaseValueNode = class {
490
+ id;
491
+ schema;
492
+ _parent = null;
493
+ _name;
494
+ constructor(id, name, schema) {
495
+ this.id = id ?? generateNodeId();
496
+ this._name = name;
497
+ this.schema = schema;
498
+ }
499
+ get parent() {
500
+ return this._parent;
501
+ }
502
+ set parent(value) {
503
+ this._parent = value;
504
+ }
505
+ get name() {
506
+ return this._name;
507
+ }
508
+ isObject() {
509
+ return false;
510
+ }
511
+ isArray() {
512
+ return false;
513
+ }
514
+ isPrimitive() {
515
+ return false;
516
+ }
517
+ get errors() {
518
+ return [];
519
+ }
520
+ get warnings() {
521
+ return [];
522
+ }
523
+ get isValid() {
524
+ return this.errors.length === 0;
525
+ }
526
+ get hasWarnings() {
527
+ return this.warnings.length > 0;
528
+ }
529
+ };
530
+
531
+ // src/model/value-node/types.ts
532
+ var ValueType = /* @__PURE__ */ ((ValueType2) => {
533
+ ValueType2["String"] = "string";
534
+ ValueType2["Number"] = "number";
535
+ ValueType2["Boolean"] = "boolean";
536
+ ValueType2["Object"] = "object";
537
+ ValueType2["Array"] = "array";
538
+ return ValueType2;
539
+ })(ValueType || {});
540
+ function extractFormulaDefinition(schema) {
541
+ if ("x-formula" in schema && schema["x-formula"]) {
542
+ const xFormula = schema["x-formula"];
543
+ return { expression: xFormula.expression, version: xFormula.version };
544
+ }
545
+ return void 0;
546
+ }
547
+
548
+ // src/model/value-node/ArrayValueNode.ts
549
+ var ArrayValueNode = class extends BaseValueNode {
550
+ constructor(id, name, schema, items, reactivity) {
551
+ super(id, name, schema);
552
+ this.reactivity = reactivity;
553
+ this._items = reactivity?.observableArray() ?? [];
554
+ this._baseItems = [];
555
+ if (items) {
556
+ for (const item of items) {
557
+ item.parent = this;
558
+ this._items.push(item);
559
+ }
560
+ }
561
+ this._baseItems = [...this._items];
562
+ this.initObservable();
563
+ }
564
+ type = "array" /* Array */;
565
+ _items;
566
+ _baseItems;
567
+ _nodeFactory = null;
568
+ initObservable() {
569
+ if (!this.reactivity) {
570
+ return;
571
+ }
572
+ this.reactivity.makeObservable(this, {
573
+ _items: "observable",
574
+ _baseItems: "observable",
575
+ value: "computed",
576
+ length: "computed",
577
+ isDirty: "computed",
578
+ errors: "computed",
579
+ warnings: "computed",
580
+ push: "action",
581
+ insertAt: "action",
582
+ removeAt: "action",
583
+ move: "action",
584
+ replaceAt: "action",
585
+ clear: "action",
586
+ commit: "action",
587
+ revert: "action",
588
+ pushValue: "action",
589
+ insertValueAt: "action"
590
+ });
591
+ }
592
+ get value() {
593
+ return this._items;
594
+ }
595
+ get length() {
596
+ return this._items.length;
597
+ }
598
+ getPlainValue() {
599
+ return this._items.map((item) => item.getPlainValue());
600
+ }
601
+ at(index) {
602
+ if (index < 0) {
603
+ return this._items[this._items.length + index];
604
+ }
605
+ return this._items[index];
606
+ }
607
+ push(node) {
608
+ node.parent = this;
609
+ this._items.push(node);
610
+ }
611
+ insertAt(index, node) {
612
+ if (index < 0 || index > this._items.length) {
613
+ throw new Error(`Index out of bounds: ${index}`);
614
+ }
615
+ node.parent = this;
616
+ this._items.splice(index, 0, node);
617
+ }
618
+ removeAt(index) {
619
+ if (index < 0 || index >= this._items.length) {
620
+ throw new Error(`Index out of bounds: ${index}`);
621
+ }
622
+ const removed = this._items.splice(index, 1)[0];
623
+ if (removed) {
624
+ removed.parent = null;
625
+ }
626
+ }
627
+ move(fromIndex, toIndex) {
628
+ if (fromIndex < 0 || fromIndex >= this._items.length) {
629
+ throw new Error(`Source index out of bounds: ${fromIndex}`);
630
+ }
631
+ if (toIndex < 0 || toIndex >= this._items.length) {
632
+ throw new Error(`Target index out of bounds: ${toIndex}`);
633
+ }
634
+ if (fromIndex === toIndex) {
635
+ return;
636
+ }
637
+ const [item] = this._items.splice(fromIndex, 1);
638
+ if (item) {
639
+ this._items.splice(toIndex, 0, item);
640
+ }
641
+ }
642
+ replaceAt(index, node) {
643
+ if (index < 0 || index >= this._items.length) {
644
+ throw new Error(`Index out of bounds: ${index}`);
645
+ }
646
+ const oldNode = this._items[index];
647
+ if (oldNode) {
648
+ oldNode.parent = null;
649
+ }
650
+ node.parent = this;
651
+ this._items[index] = node;
652
+ }
653
+ clear() {
654
+ for (const item of this._items) {
655
+ item.parent = null;
656
+ }
657
+ this._items.length = 0;
658
+ }
659
+ setNodeFactory(factory) {
660
+ this._nodeFactory = factory;
661
+ }
662
+ pushValue(value) {
663
+ const node = this.createItemNode(this._items.length, value);
664
+ this.push(node);
665
+ }
666
+ insertValueAt(index, value) {
667
+ const node = this.createItemNode(index, value);
668
+ this.insertAt(index, node);
669
+ }
670
+ createItemNode(index, value) {
671
+ if (!this._nodeFactory) {
672
+ throw new Error("NodeFactory not set");
673
+ }
674
+ const arraySchema = this.schema;
675
+ const itemSchema = arraySchema.items;
676
+ if (!itemSchema) {
677
+ throw new Error("No items schema");
678
+ }
679
+ const itemValue = value === void 0 && "default" in itemSchema ? itemSchema.default : value;
680
+ const node = this._nodeFactory.create(String(index), itemSchema, itemValue);
681
+ this.propagateFactory(node);
682
+ return node;
683
+ }
684
+ propagateFactory(node) {
685
+ if (!this._nodeFactory) {
686
+ return;
687
+ }
688
+ if (node.isArray()) {
689
+ node.setNodeFactory(this._nodeFactory);
690
+ for (const item of node.value) {
691
+ this.propagateFactory(item);
692
+ }
693
+ } else if (node.isObject()) {
694
+ for (const child of node.children) {
695
+ this.propagateFactory(child);
696
+ }
697
+ }
698
+ }
699
+ get isDirty() {
700
+ if (this._items.length !== this._baseItems.length) {
701
+ return true;
702
+ }
703
+ for (let i = 0; i < this._items.length; i++) {
704
+ if (this._items[i] !== this._baseItems[i]) {
705
+ return true;
706
+ }
707
+ }
708
+ for (const item of this._items) {
709
+ if ("isDirty" in item && item.isDirty) {
710
+ return true;
711
+ }
712
+ }
713
+ return false;
714
+ }
715
+ commit() {
716
+ this._baseItems = [...this._items];
717
+ for (const item of this._items) {
718
+ if ("commit" in item && typeof item.commit === "function") {
719
+ item.commit();
720
+ }
721
+ }
722
+ }
723
+ revert() {
724
+ for (const item of this._items) {
725
+ item.parent = null;
726
+ }
727
+ this._items = this.reactivity?.observableArray() ?? [];
728
+ for (const baseItem of this._baseItems) {
729
+ this._items.push(baseItem);
730
+ }
731
+ for (const item of this._items) {
732
+ item.parent = this;
733
+ if ("revert" in item && typeof item.revert === "function") {
734
+ item.revert();
735
+ }
736
+ }
737
+ }
738
+ isArray() {
739
+ return true;
740
+ }
741
+ get errors() {
742
+ const errors = [];
743
+ for (const item of this._items) {
744
+ errors.push(...item.errors);
745
+ }
746
+ return errors;
747
+ }
748
+ get warnings() {
749
+ const warnings = [];
750
+ for (const item of this._items) {
751
+ warnings.push(...item.warnings);
752
+ }
753
+ return warnings;
754
+ }
755
+ };
756
+
757
+ // src/model/value-node/BasePrimitiveValueNode.ts
758
+ var BasePrimitiveValueNode = class extends BaseValueNode {
759
+ constructor(id, name, schema, value, defaultValue, reactivity) {
760
+ super(id, name, schema);
761
+ this.reactivity = reactivity;
762
+ const schemaDefault = "default" in schema ? schema.default : void 0;
763
+ const initialValue = value ?? schemaDefault ?? defaultValue;
764
+ this._value = initialValue;
765
+ this._baseValue = initialValue;
766
+ }
767
+ _value;
768
+ _baseValue;
769
+ _formulaWarning = null;
770
+ initObservable() {
771
+ if (!this.reactivity) {
772
+ return;
773
+ }
774
+ this.reactivity.makeObservable(this, {
775
+ _value: "observable",
776
+ _baseValue: "observable",
777
+ _formulaWarning: "observable",
778
+ value: "computed",
779
+ baseValue: "computed",
780
+ isDirty: "computed",
781
+ errors: "computed",
782
+ warnings: "computed",
783
+ setValue: "action",
784
+ setFormulaWarning: "action",
785
+ commit: "action",
786
+ revert: "action"
787
+ });
788
+ }
789
+ get value() {
790
+ return this._value;
791
+ }
792
+ set value(newValue) {
793
+ if (this.isReadOnly) {
794
+ throw new Error(`Cannot set value on read-only field: ${this.name}`);
795
+ }
796
+ this._value = newValue;
797
+ }
798
+ get baseValue() {
799
+ return this._baseValue;
800
+ }
801
+ get isDirty() {
802
+ return this._value !== this._baseValue;
803
+ }
804
+ get formula() {
805
+ return extractFormulaDefinition(this.schema);
806
+ }
807
+ get formulaWarning() {
808
+ return this._formulaWarning;
809
+ }
810
+ get isReadOnly() {
811
+ const readOnly = "readOnly" in this.schema ? this.schema.readOnly : false;
812
+ return readOnly === true || this.formula !== void 0;
813
+ }
814
+ getPlainValue() {
815
+ return this._value;
816
+ }
817
+ setValue(value, options) {
818
+ if (this.isReadOnly && !options?.internal) {
819
+ throw new Error(`Cannot set value on read-only field: ${this.name}`);
820
+ }
821
+ this._value = this.coerceValue(value);
822
+ }
823
+ setFormulaWarning(warning) {
824
+ this._formulaWarning = warning;
825
+ }
826
+ commit() {
827
+ this._baseValue = this._value;
828
+ }
829
+ revert() {
830
+ this._value = this._baseValue;
831
+ }
832
+ isPrimitive() {
833
+ return true;
834
+ }
835
+ get errors() {
836
+ return this.computeErrors();
837
+ }
838
+ computeErrors() {
839
+ return [];
840
+ }
841
+ get warnings() {
842
+ if (!this._formulaWarning) {
843
+ return [];
844
+ }
845
+ return [
846
+ {
847
+ severity: "warning",
848
+ type: this._formulaWarning.type,
849
+ message: this._formulaWarning.message,
850
+ path: this.name,
851
+ params: {
852
+ expression: this._formulaWarning.expression,
853
+ computedValue: this._formulaWarning.computedValue
854
+ }
855
+ }
856
+ ];
857
+ }
858
+ };
859
+
860
+ // src/model/value-node/BooleanValueNode.ts
861
+ var BooleanValueNode = class extends BasePrimitiveValueNode {
862
+ type = "boolean" /* Boolean */;
863
+ constructor(id, name, schema, value, reactivity) {
864
+ super(id, name, schema, value, false, reactivity);
865
+ this.initObservable();
866
+ }
867
+ get defaultValue() {
868
+ return "default" in this.schema ? this.schema.default : false;
869
+ }
870
+ coerceValue(value) {
871
+ if (typeof value === "boolean") {
872
+ return value;
873
+ }
874
+ return Boolean(value);
875
+ }
876
+ };
877
+
878
+ // src/model/foreign-key-resolver/errors.ts
879
+ var ForeignKeyNotFoundError = class extends Error {
880
+ constructor(tableId, rowId) {
881
+ const message = rowId ? `Foreign key row not found: ${tableId}/${rowId}` : `Foreign key table not found: ${tableId}`;
882
+ super(message);
883
+ this.tableId = tableId;
884
+ this.rowId = rowId;
885
+ this.name = "ForeignKeyNotFoundError";
886
+ }
887
+ };
888
+ var ForeignKeyResolverNotConfiguredError = class extends Error {
889
+ constructor() {
890
+ super("ForeignKeyResolver is not configured with a loader");
891
+ this.name = "ForeignKeyResolverNotConfiguredError";
892
+ }
893
+ };
894
+
895
+ // src/model/value-node/StringValueNode.ts
896
+ var StringValueNode = class extends BasePrimitiveValueNode {
897
+ type = "string" /* String */;
898
+ constructor(id, name, schema, value, reactivity) {
899
+ super(id, name, schema, value, "", reactivity);
900
+ this.initObservable();
901
+ }
902
+ get defaultValue() {
903
+ return "default" in this.schema ? this.schema.default : "";
904
+ }
905
+ coerceValue(value) {
906
+ if (typeof value === "string") {
907
+ return value;
908
+ }
909
+ if (value === null || value === void 0) {
910
+ return "";
911
+ }
912
+ if (typeof value === "object") {
913
+ return JSON.stringify(value);
914
+ }
915
+ return String(value);
916
+ }
917
+ computeErrors() {
918
+ const errors = [];
919
+ this.validateRequired(errors);
920
+ this.validateForeignKey(errors);
921
+ this.validateMinLength(errors);
922
+ this.validateMaxLength(errors);
923
+ this.validatePattern(errors);
924
+ this.validateEnum(errors);
925
+ return errors;
926
+ }
927
+ validateRequired(errors) {
928
+ const stringSchema = this.schema;
929
+ if ("required" in stringSchema && stringSchema.required && this._value === "") {
930
+ errors.push({
931
+ severity: "error",
932
+ type: "required",
933
+ message: "Field is required",
934
+ path: this.name
935
+ });
936
+ }
937
+ }
938
+ validateForeignKey(errors) {
939
+ const stringSchema = this.schema;
940
+ const foreignKey = stringSchema.foreignKey;
941
+ if (foreignKey && this._value === "") {
942
+ errors.push({
943
+ severity: "error",
944
+ type: "foreignKey",
945
+ message: `Reference to ${foreignKey} is required`,
946
+ path: this.name,
947
+ params: { table: foreignKey }
948
+ });
949
+ }
950
+ }
951
+ validateMinLength(errors) {
952
+ const stringSchema = this.schema;
953
+ const minLength = stringSchema.minLength;
954
+ if (minLength !== void 0 && this._value.length > 0 && this._value.length < minLength) {
955
+ errors.push({
956
+ severity: "error",
957
+ type: "minLength",
958
+ message: `Minimum length is ${minLength}`,
959
+ path: this.name,
960
+ params: { min: minLength, actual: this._value.length }
961
+ });
962
+ }
963
+ }
964
+ validateMaxLength(errors) {
965
+ const stringSchema = this.schema;
966
+ const maxLength = stringSchema.maxLength;
967
+ if (maxLength !== void 0 && this._value.length > maxLength) {
968
+ errors.push({
969
+ severity: "error",
970
+ type: "maxLength",
971
+ message: `Maximum length is ${maxLength}`,
972
+ path: this.name,
973
+ params: { max: maxLength, actual: this._value.length }
974
+ });
975
+ }
976
+ }
977
+ validatePattern(errors) {
978
+ const stringSchema = this.schema;
979
+ const pattern = stringSchema.pattern;
980
+ if (!pattern || this._value.length === 0) {
981
+ return;
982
+ }
983
+ try {
984
+ if (!new RegExp(pattern).test(this._value)) {
985
+ errors.push({
986
+ severity: "error",
987
+ type: "pattern",
988
+ message: "Value does not match pattern",
989
+ path: this.name,
990
+ params: { pattern }
991
+ });
992
+ }
993
+ } catch {
994
+ errors.push({
995
+ severity: "error",
996
+ type: "invalidPattern",
997
+ message: "Invalid regex pattern in schema",
998
+ path: this.name,
999
+ params: { pattern }
1000
+ });
1001
+ }
1002
+ }
1003
+ validateEnum(errors) {
1004
+ const stringSchema = this.schema;
1005
+ const enumValues = stringSchema.enum;
1006
+ if (enumValues && enumValues.length > 0 && !enumValues.includes(this._value)) {
1007
+ errors.push({
1008
+ severity: "error",
1009
+ type: "enum",
1010
+ message: "Value is not in allowed list",
1011
+ path: this.name,
1012
+ params: { allowed: enumValues, actual: this._value }
1013
+ });
1014
+ }
1015
+ }
1016
+ };
1017
+
1018
+ // src/model/value-node/ForeignKeyValueNode.ts
1019
+ function isForeignKeyValueNode(node) {
1020
+ return node instanceof ForeignKeyValueNodeImpl || "foreignKey" in node && typeof node.foreignKey === "string";
1021
+ }
1022
+ var ForeignKeyValueNodeImpl = class extends StringValueNode {
1023
+ constructor(id, name, schema, value, reactivity, fkResolver) {
1024
+ super(id, name, schema, value, reactivity);
1025
+ this.fkResolver = fkResolver;
1026
+ const schemaFk = "foreignKey" in schema && typeof schema.foreignKey === "string" ? schema.foreignKey : void 0;
1027
+ if (!schemaFk) {
1028
+ throw new Error("ForeignKeyValueNode requires a schema with foreignKey property");
1029
+ }
1030
+ this._foreignKey = schemaFk;
1031
+ }
1032
+ _foreignKey;
1033
+ get foreignKey() {
1034
+ return this._foreignKey;
1035
+ }
1036
+ get isLoading() {
1037
+ if (!this.fkResolver || !this._value) {
1038
+ return false;
1039
+ }
1040
+ return this.fkResolver.isLoadingRow(this._foreignKey, this._value);
1041
+ }
1042
+ async getRow() {
1043
+ if (!this.fkResolver) {
1044
+ throw new ForeignKeyResolverNotConfiguredError();
1045
+ }
1046
+ if (!this._value) {
1047
+ throw new ForeignKeyNotFoundError(this._foreignKey, this._value);
1048
+ }
1049
+ return this.fkResolver.getRowData(this._foreignKey, this._value);
1050
+ }
1051
+ async getSchema() {
1052
+ if (!this.fkResolver) {
1053
+ throw new ForeignKeyResolverNotConfiguredError();
1054
+ }
1055
+ return this.fkResolver.getSchema(this._foreignKey);
1056
+ }
1057
+ };
1058
+
1059
+ // src/model/value-node/NumberValueNode.ts
1060
+ var NumberValueNode = class extends BasePrimitiveValueNode {
1061
+ type = "number" /* Number */;
1062
+ constructor(id, name, schema, value, reactivity) {
1063
+ super(id, name, schema, value, 0, reactivity);
1064
+ this.initObservable();
1065
+ }
1066
+ get defaultValue() {
1067
+ return "default" in this.schema ? this.schema.default : 0;
1068
+ }
1069
+ coerceValue(value) {
1070
+ if (typeof value === "number") {
1071
+ return value;
1072
+ }
1073
+ return Number(value) || 0;
1074
+ }
1075
+ computeErrors() {
1076
+ const errors = [];
1077
+ if (!("type" in this.schema) || this.schema.type !== "number" /* Number */) {
1078
+ return errors;
1079
+ }
1080
+ const numberSchema = this.schema;
1081
+ const minimum = numberSchema.minimum;
1082
+ if (minimum !== void 0 && this._value < minimum) {
1083
+ errors.push({
1084
+ severity: "error",
1085
+ type: "min",
1086
+ message: `Value must be at least ${minimum}`,
1087
+ path: this.name,
1088
+ params: { min: minimum, actual: this._value }
1089
+ });
1090
+ }
1091
+ const maximum = numberSchema.maximum;
1092
+ if (maximum !== void 0 && this._value > maximum) {
1093
+ errors.push({
1094
+ severity: "error",
1095
+ type: "max",
1096
+ message: `Value must be at most ${maximum}`,
1097
+ path: this.name,
1098
+ params: { max: maximum, actual: this._value }
1099
+ });
1100
+ }
1101
+ const enumValues = numberSchema.enum;
1102
+ if (enumValues && enumValues.length > 0 && !enumValues.includes(this._value)) {
1103
+ errors.push({
1104
+ severity: "error",
1105
+ type: "enum",
1106
+ message: "Value is not in allowed list",
1107
+ path: this.name,
1108
+ params: { allowed: enumValues, actual: this._value }
1109
+ });
1110
+ }
1111
+ return errors;
1112
+ }
1113
+ };
1114
+
1115
+ // src/model/value-node/ObjectValueNode.ts
1116
+ var ObjectValueNode = class extends BaseValueNode {
1117
+ constructor(id, name, schema, children, reactivity) {
1118
+ super(id, name, schema);
1119
+ this.reactivity = reactivity;
1120
+ this._children = reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
1121
+ this._baseChildren = /* @__PURE__ */ new Map();
1122
+ if (children) {
1123
+ for (const child of children) {
1124
+ this._children.set(child.name, child);
1125
+ child.parent = this;
1126
+ }
1127
+ }
1128
+ this._baseChildren = new Map(this._children);
1129
+ this.initObservable();
1130
+ }
1131
+ type = "object" /* Object */;
1132
+ _children;
1133
+ _baseChildren;
1134
+ initObservable() {
1135
+ if (!this.reactivity) {
1136
+ return;
1137
+ }
1138
+ this.reactivity.makeObservable(this, {
1139
+ _children: "observable",
1140
+ _baseChildren: "observable",
1141
+ value: "computed",
1142
+ children: "computed",
1143
+ isDirty: "computed",
1144
+ errors: "computed",
1145
+ warnings: "computed",
1146
+ addChild: "action",
1147
+ removeChild: "action",
1148
+ commit: "action",
1149
+ revert: "action"
1150
+ });
1151
+ }
1152
+ get value() {
1153
+ return Object.fromEntries(this._children);
1154
+ }
1155
+ get children() {
1156
+ return Array.from(this._children.values());
1157
+ }
1158
+ getPlainValue() {
1159
+ const result = {};
1160
+ for (const [key, node] of this._children) {
1161
+ result[key] = node.getPlainValue();
1162
+ }
1163
+ return result;
1164
+ }
1165
+ child(name) {
1166
+ return this._children.get(name);
1167
+ }
1168
+ hasChild(name) {
1169
+ return this._children.has(name);
1170
+ }
1171
+ addChild(node) {
1172
+ const existing = this._children.get(node.name);
1173
+ if (existing) {
1174
+ existing.parent = null;
1175
+ }
1176
+ node.parent = this;
1177
+ this._children.set(node.name, node);
1178
+ }
1179
+ removeChild(name) {
1180
+ const node = this._children.get(name);
1181
+ if (node) {
1182
+ node.parent = null;
1183
+ this._children.delete(name);
1184
+ }
1185
+ }
1186
+ get isDirty() {
1187
+ if (this._children.size !== this._baseChildren.size) {
1188
+ return true;
1189
+ }
1190
+ for (const [key, child] of this._children) {
1191
+ if (this._baseChildren.get(key) !== child) {
1192
+ return true;
1193
+ }
1194
+ }
1195
+ for (const child of this._children.values()) {
1196
+ if ("isDirty" in child && child.isDirty) {
1197
+ return true;
1198
+ }
1199
+ }
1200
+ return false;
1201
+ }
1202
+ commit() {
1203
+ this._baseChildren = new Map(this._children);
1204
+ for (const child of this._children.values()) {
1205
+ if ("commit" in child && typeof child.commit === "function") {
1206
+ child.commit();
1207
+ }
1208
+ }
1209
+ }
1210
+ revert() {
1211
+ for (const child of this._children.values()) {
1212
+ child.parent = null;
1213
+ }
1214
+ this._children = this.reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
1215
+ for (const [key, value] of this._baseChildren) {
1216
+ this._children.set(key, value);
1217
+ }
1218
+ for (const child of this._children.values()) {
1219
+ child.parent = this;
1220
+ if ("revert" in child && typeof child.revert === "function") {
1221
+ child.revert();
1222
+ }
1223
+ }
1224
+ }
1225
+ isObject() {
1226
+ return true;
1227
+ }
1228
+ get errors() {
1229
+ const errors = [];
1230
+ for (const child of this._children.values()) {
1231
+ errors.push(...child.errors);
1232
+ }
1233
+ return errors;
1234
+ }
1235
+ get warnings() {
1236
+ const warnings = [];
1237
+ for (const child of this._children.values()) {
1238
+ warnings.push(...child.warnings);
1239
+ }
1240
+ return warnings;
1241
+ }
1242
+ };
1243
+
1244
+ // src/model/value-node/NodeFactory.ts
1245
+ var NodeFactoryRegistry = class {
1246
+ factories = /* @__PURE__ */ new Map();
1247
+ register(schemaType, factory) {
1248
+ this.factories.set(schemaType, factory);
1249
+ return this;
1250
+ }
1251
+ get(schemaType) {
1252
+ return this.factories.get(schemaType);
1253
+ }
1254
+ has(schemaType) {
1255
+ return this.factories.has(schemaType);
1256
+ }
1257
+ };
1258
+ var NodeFactory2 = class {
1259
+ constructor(registry, options) {
1260
+ this.registry = registry;
1261
+ this.refSchemas = options?.refSchemas;
1262
+ }
1263
+ refSchemas;
1264
+ create(name, schema, value, id) {
1265
+ const resolvedSchema = this.resolveSchema(schema);
1266
+ const schemaType = this.getSchemaType(resolvedSchema);
1267
+ const factory = this.registry.get(schemaType);
1268
+ if (!factory) {
1269
+ throw new Error(`Unknown schema type: ${schemaType}`);
1270
+ }
1271
+ return factory(name, resolvedSchema, value, id);
1272
+ }
1273
+ createTree(schema, value) {
1274
+ return this.create("", schema, value);
1275
+ }
1276
+ getSchemaType(schema) {
1277
+ if ("type" in schema) {
1278
+ return schema.type;
1279
+ }
1280
+ return "object";
1281
+ }
1282
+ resolveSchema(schema) {
1283
+ if (!("$ref" in schema) || !this.refSchemas) {
1284
+ return schema;
1285
+ }
1286
+ const refSchema = schema;
1287
+ const resolved = this.refSchemas[refSchema.$ref];
1288
+ if (!resolved) {
1289
+ return schema;
1290
+ }
1291
+ return {
1292
+ ...resolved,
1293
+ $ref: refSchema.$ref,
1294
+ title: refSchema.title ?? ("title" in resolved ? resolved.title : void 0),
1295
+ description: refSchema.description ?? ("description" in resolved ? resolved.description : void 0),
1296
+ deprecated: refSchema.deprecated ?? ("deprecated" in resolved ? resolved.deprecated : void 0)
1297
+ };
1298
+ }
1299
+ };
1300
+ function createStringFactory(reactivity, fkResolver) {
1301
+ return (name, schema, value, id) => {
1302
+ const stringSchema = schema;
1303
+ if (stringSchema.foreignKey) {
1304
+ return new ForeignKeyValueNodeImpl(
1305
+ id,
1306
+ name,
1307
+ schema,
1308
+ value,
1309
+ reactivity,
1310
+ fkResolver
1311
+ );
1312
+ }
1313
+ return new StringValueNode(
1314
+ id,
1315
+ name,
1316
+ schema,
1317
+ value,
1318
+ reactivity
1319
+ );
1320
+ };
1321
+ }
1322
+ function createNumberFactory(reactivity) {
1323
+ return (name, schema, value, id) => {
1324
+ return new NumberValueNode(
1325
+ id,
1326
+ name,
1327
+ schema,
1328
+ value,
1329
+ reactivity
1330
+ );
1331
+ };
1332
+ }
1333
+ function createBooleanFactory(reactivity) {
1334
+ return (name, schema, value, id) => {
1335
+ return new BooleanValueNode(
1336
+ id,
1337
+ name,
1338
+ schema,
1339
+ value,
1340
+ reactivity
1341
+ );
1342
+ };
1343
+ }
1344
+ function createObjectFactory(nodeFactory, reactivity) {
1345
+ return (name, schema, value, id) => {
1346
+ const objValue = value ?? {};
1347
+ const children = [];
1348
+ const objectSchema = schema;
1349
+ const properties = objectSchema.properties ?? {};
1350
+ for (const [propName, propSchema] of Object.entries(properties)) {
1351
+ const propValue = objValue[propName];
1352
+ const childNode = nodeFactory.create(propName, propSchema, propValue);
1353
+ children.push(childNode);
1354
+ }
1355
+ return new ObjectValueNode(id, name, schema, children, reactivity);
1356
+ };
1357
+ }
1358
+ function createArrayFactory(nodeFactory, reactivity) {
1359
+ return (name, schema, value, id) => {
1360
+ const arrValue = value ?? [];
1361
+ const arraySchema = schema;
1362
+ const itemSchema = arraySchema.items ?? { type: "string", default: "" };
1363
+ const items = [];
1364
+ for (let i = 0; i < arrValue.length; i++) {
1365
+ const itemValue = arrValue[i];
1366
+ const itemNode = nodeFactory.create(String(i), itemSchema, itemValue);
1367
+ items.push(itemNode);
1368
+ }
1369
+ const arrayNode = new ArrayValueNode(id, name, schema, items, reactivity);
1370
+ arrayNode.setNodeFactory(nodeFactory);
1371
+ return arrayNode;
1372
+ };
1373
+ }
1374
+ function createDefaultRegistry(reactivity, fkResolver) {
1375
+ const registry = new NodeFactoryRegistry();
1376
+ registry.register("string", createStringFactory(reactivity, fkResolver));
1377
+ registry.register("number", createNumberFactory(reactivity));
1378
+ registry.register("boolean", createBooleanFactory(reactivity));
1379
+ return registry;
1380
+ }
1381
+ function createNodeFactory(options) {
1382
+ const registry = createDefaultRegistry(options?.reactivity, options?.fkResolver);
1383
+ const factory = new NodeFactory2(registry, options);
1384
+ registry.register("object", createObjectFactory(factory, options?.reactivity));
1385
+ registry.register("array", createArrayFactory(factory, options?.reactivity));
1386
+ return factory;
1387
+ }
1388
+
1389
+ // src/core/value-path/ValuePathSegment.ts
1390
+ var PropertySegment = class {
1391
+ constructor(name) {
1392
+ this.name = name;
1393
+ }
1394
+ isProperty() {
1395
+ return true;
1396
+ }
1397
+ isIndex() {
1398
+ return false;
1399
+ }
1400
+ propertyName() {
1401
+ return this.name;
1402
+ }
1403
+ indexValue() {
1404
+ throw new Error("Property segment has no index value");
1405
+ }
1406
+ equals(other) {
1407
+ return other.isProperty() && other.propertyName() === this.name;
1408
+ }
1409
+ };
1410
+ var IndexSegment = class {
1411
+ constructor(index) {
1412
+ this.index = index;
1413
+ }
1414
+ isProperty() {
1415
+ return false;
1416
+ }
1417
+ isIndex() {
1418
+ return true;
1419
+ }
1420
+ propertyName() {
1421
+ throw new Error("Index segment has no property name");
1422
+ }
1423
+ indexValue() {
1424
+ return this.index;
1425
+ }
1426
+ equals(other) {
1427
+ return other.isIndex() && other.indexValue() === this.index;
1428
+ }
1429
+ };
1430
+
1431
+ // src/core/value-path/ValuePath.ts
1432
+ var ValuePathImpl = class _ValuePathImpl extends chunkA4E524UU_cjs.AbstractBasePath {
1433
+ asString() {
1434
+ const parts = [];
1435
+ for (const seg of this.segs) {
1436
+ if (seg.isProperty()) {
1437
+ if (parts.length > 0) {
1438
+ parts.push(".");
1439
+ }
1440
+ parts.push(seg.propertyName());
1441
+ } else if (seg.isIndex()) {
1442
+ parts.push(`[${seg.indexValue()}]`);
1443
+ }
1444
+ }
1445
+ return parts.join("");
1446
+ }
1447
+ parent() {
1448
+ if (this.segs.length <= 1) {
1449
+ return EMPTY_VALUE_PATH;
1450
+ }
1451
+ return new _ValuePathImpl(this.segs.slice(0, -1));
1452
+ }
1453
+ child(name) {
1454
+ return new _ValuePathImpl([...this.segs, new PropertySegment(name)]);
1455
+ }
1456
+ childIndex(index) {
1457
+ return new _ValuePathImpl([...this.segs, new IndexSegment(index)]);
1458
+ }
1459
+ };
1460
+ var EMPTY_VALUE_PATH = new ValuePathImpl([]);
1461
+
1462
+ // src/core/value-path/ValuePathParser.ts
1463
+ function parseIndexSegment(path, startIndex) {
1464
+ let i = startIndex;
1465
+ let indexStr = "";
1466
+ while (i < path.length && path[i] !== "]") {
1467
+ indexStr += path[i];
1468
+ i++;
1469
+ }
1470
+ if (path[i] !== "]") {
1471
+ throw new Error(`Invalid path: missing closing bracket in "${path}"`);
1472
+ }
1473
+ if (indexStr === "" || !/^\d+$/.test(indexStr)) {
1474
+ throw new Error(
1475
+ `Invalid path: index must be a non-negative integer, got "${indexStr}" in "${path}"`
1476
+ );
1477
+ }
1478
+ return {
1479
+ segment: new IndexSegment(Number.parseInt(indexStr, 10)),
1480
+ nextIndex: i + 1
1481
+ };
1482
+ }
1483
+ function pushPropertyIfNotEmpty(segments, current) {
1484
+ if (current) {
1485
+ segments.push(new PropertySegment(current));
1486
+ }
1487
+ }
1488
+ function parseValuePath(path) {
1489
+ if (!path) {
1490
+ return [];
1491
+ }
1492
+ const segments = [];
1493
+ let current = "";
1494
+ let i = 0;
1495
+ while (i < path.length) {
1496
+ const char = path[i];
1497
+ if (char === ".") {
1498
+ pushPropertyIfNotEmpty(segments, current);
1499
+ current = "";
1500
+ i++;
1501
+ } else if (char === "[") {
1502
+ pushPropertyIfNotEmpty(segments, current);
1503
+ current = "";
1504
+ const result = parseIndexSegment(path, i + 1);
1505
+ segments.push(result.segment);
1506
+ i = result.nextIndex;
1507
+ } else {
1508
+ current += char;
1509
+ i++;
1510
+ }
1511
+ }
1512
+ pushPropertyIfNotEmpty(segments, current);
1513
+ return segments;
1514
+ }
1515
+
1516
+ // src/model/value-tree/ValueTree.ts
1517
+ var ValueTree = class {
1518
+ constructor(_root, _reactivity) {
1519
+ this._root = _root;
1520
+ this._reactivity = _reactivity;
1521
+ this.initObservable();
1522
+ }
1523
+ initObservable() {
1524
+ this._reactivity?.makeObservable(this, {
1525
+ isDirty: "computed",
1526
+ isValid: "computed",
1527
+ errors: "computed",
1528
+ commit: "action",
1529
+ revert: "action"
1530
+ });
1531
+ }
1532
+ get root() {
1533
+ return this._root;
1534
+ }
1535
+ get(path) {
1536
+ const segments = parseValuePath(path);
1537
+ if (segments.length === 0) {
1538
+ return this._root;
1539
+ }
1540
+ let current = this._root;
1541
+ for (const segment of segments) {
1542
+ if (!current) {
1543
+ return void 0;
1544
+ }
1545
+ if (segment.isProperty() && current.isObject()) {
1546
+ current = current.child(segment.propertyName());
1547
+ } else if (segment.isIndex() && current.isArray()) {
1548
+ current = current.at(segment.indexValue());
1549
+ } else {
1550
+ return void 0;
1551
+ }
1552
+ }
1553
+ return current;
1554
+ }
1555
+ getValue(path) {
1556
+ const node = this.get(path);
1557
+ return node?.getPlainValue();
1558
+ }
1559
+ setValue(path, value) {
1560
+ const node = this.get(path);
1561
+ if (!node) {
1562
+ throw new Error(`Path not found: ${path}`);
1563
+ }
1564
+ if (!node.isPrimitive()) {
1565
+ throw new Error(`Cannot set value on non-primitive node: ${path}`);
1566
+ }
1567
+ node.setValue(value);
1568
+ }
1569
+ getPlainValue() {
1570
+ return this._root.getPlainValue();
1571
+ }
1572
+ get isDirty() {
1573
+ const root = this._root;
1574
+ if ("isDirty" in root) {
1575
+ return root.isDirty;
1576
+ }
1577
+ return false;
1578
+ }
1579
+ get isValid() {
1580
+ return this.errors.length === 0;
1581
+ }
1582
+ get errors() {
1583
+ return this._root.errors;
1584
+ }
1585
+ getPatches() {
1586
+ return [];
1587
+ }
1588
+ commit() {
1589
+ const root = this._root;
1590
+ if ("commit" in root && typeof root.commit === "function") {
1591
+ root.commit();
1592
+ }
1593
+ }
1594
+ revert() {
1595
+ const root = this._root;
1596
+ if ("revert" in root && typeof root.revert === "function") {
1597
+ root.revert();
1598
+ }
1599
+ }
1600
+ };
1601
+
1602
+ // src/model/table/TableModelImpl.ts
1603
+ var TableModelImpl = class {
1604
+ _tableId;
1605
+ _baseTableId;
1606
+ _schema;
1607
+ _rows;
1608
+ _jsonSchema;
1609
+ _reactivity;
1610
+ _fkResolver;
1611
+ constructor(options, reactivity) {
1612
+ this._tableId = options.tableId;
1613
+ this._baseTableId = options.tableId;
1614
+ this._jsonSchema = options.schema;
1615
+ this._schema = createSchemaModel(options.schema, { reactivity });
1616
+ this._reactivity = reactivity;
1617
+ this._fkResolver = options.fkResolver;
1618
+ this._rows = reactivity?.observableArray() ?? [];
1619
+ if (options.rows) {
1620
+ for (const row of options.rows) {
1621
+ this._rows.push(this.createRowModel(row.rowId, row.data));
1622
+ }
1623
+ }
1624
+ this.initObservable();
1625
+ }
1626
+ initObservable() {
1627
+ this._reactivity?.makeObservable(this, {
1628
+ _tableId: "observable",
1629
+ _baseTableId: "observable",
1630
+ tableId: "computed",
1631
+ baseTableId: "computed",
1632
+ isRenamed: "computed",
1633
+ rows: "computed",
1634
+ rowCount: "computed",
1635
+ isDirty: "computed",
1636
+ rename: "action",
1637
+ addRow: "action",
1638
+ removeRow: "action",
1639
+ commit: "action",
1640
+ revert: "action"
1641
+ });
1642
+ }
1643
+ get tableId() {
1644
+ return this._tableId;
1645
+ }
1646
+ get baseTableId() {
1647
+ return this._baseTableId;
1648
+ }
1649
+ get isRenamed() {
1650
+ return this._tableId !== this._baseTableId;
1651
+ }
1652
+ get fk() {
1653
+ return this._fkResolver;
1654
+ }
1655
+ get schema() {
1656
+ return this._schema;
1657
+ }
1658
+ get rows() {
1659
+ return this._rows;
1660
+ }
1661
+ get rowCount() {
1662
+ return this._rows.length;
1663
+ }
1664
+ rename(newTableId) {
1665
+ this._tableId = newTableId;
1666
+ }
1667
+ addRow(rowId, data) {
1668
+ if (this.getRow(rowId)) {
1669
+ throw new Error(`Row with id already exists: ${rowId}`);
1670
+ }
1671
+ const rowModel = this.createRowModel(rowId, data);
1672
+ this._rows.push(rowModel);
1673
+ return rowModel;
1674
+ }
1675
+ removeRow(rowId) {
1676
+ const index = this._rows.findIndex((row) => row.rowId === rowId);
1677
+ if (index !== -1) {
1678
+ const row = this._rows[index];
1679
+ if (row instanceof RowModelImpl) {
1680
+ row.setTableModel(null);
1681
+ }
1682
+ this._rows.splice(index, 1);
1683
+ }
1684
+ }
1685
+ getRow(rowId) {
1686
+ return this._rows.find((row) => row.rowId === rowId);
1687
+ }
1688
+ getRowIndex(rowId) {
1689
+ return this._rows.findIndex((row) => row.rowId === rowId);
1690
+ }
1691
+ getRowAt(index) {
1692
+ return this._rows[index];
1693
+ }
1694
+ get isDirty() {
1695
+ if (this.isRenamed) {
1696
+ return true;
1697
+ }
1698
+ if (this._schema.isDirty()) {
1699
+ return true;
1700
+ }
1701
+ for (const row of this._rows) {
1702
+ if (row.isDirty) {
1703
+ return true;
1704
+ }
1705
+ }
1706
+ return false;
1707
+ }
1708
+ commit() {
1709
+ this._baseTableId = this._tableId;
1710
+ this._schema.markAsSaved();
1711
+ for (const row of this._rows) {
1712
+ row.commit();
1713
+ }
1714
+ }
1715
+ revert() {
1716
+ this._tableId = this._baseTableId;
1717
+ this._schema.revert();
1718
+ for (const row of this._rows) {
1719
+ row.revert();
1720
+ }
1721
+ }
1722
+ createRowModel(rowId, data) {
1723
+ const factory = createNodeFactory({
1724
+ reactivity: this._reactivity,
1725
+ fkResolver: this._fkResolver
1726
+ });
1727
+ const rowData = data ?? generateDefaultValue(this._jsonSchema);
1728
+ const rootNode = factory.createTree(this._jsonSchema, rowData);
1729
+ const valueTree = new ValueTree(rootNode, this._reactivity);
1730
+ const rowModel = new RowModelImpl(rowId, valueTree, this._reactivity);
1731
+ rowModel.setTableModel(this);
1732
+ return rowModel;
1733
+ }
1734
+ };
1735
+ function createTableModel(options, reactivity) {
1736
+ return new TableModelImpl(options, reactivity);
1737
+ }
1738
+
1739
+ // src/model/foreign-key-resolver/ForeignKeyResolverImpl.ts
1740
+ var ForeignKeyResolverImpl = class {
1741
+ _schemaCache;
1742
+ _tableCache;
1743
+ _loadingTables;
1744
+ _loadingRows;
1745
+ _pendingTableLoads;
1746
+ _pendingRowLoads;
1747
+ _prefetchEnabled;
1748
+ _disposed = false;
1749
+ loader;
1750
+ reactivity;
1751
+ constructor(options) {
1752
+ this.loader = options?.loader;
1753
+ this.reactivity = options?.reactivity;
1754
+ this._prefetchEnabled = options?.prefetch ?? false;
1755
+ this._schemaCache = this.reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
1756
+ this._tableCache = this.reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
1757
+ this._loadingTables = /* @__PURE__ */ new Set();
1758
+ this._loadingRows = /* @__PURE__ */ new Map();
1759
+ this._pendingTableLoads = /* @__PURE__ */ new Map();
1760
+ this._pendingRowLoads = /* @__PURE__ */ new Map();
1761
+ this.initObservable();
1762
+ }
1763
+ initObservable() {
1764
+ this.reactivity?.makeObservable(this, {
1765
+ _schemaCache: "observable",
1766
+ _tableCache: "observable",
1767
+ _prefetchEnabled: "observable",
1768
+ isPrefetchEnabled: "computed",
1769
+ addSchema: "action",
1770
+ addTable: "action",
1771
+ addRow: "action",
1772
+ setPrefetch: "action"
1773
+ });
1774
+ }
1775
+ get isPrefetchEnabled() {
1776
+ return this._prefetchEnabled;
1777
+ }
1778
+ setPrefetch(enabled) {
1779
+ this._prefetchEnabled = enabled;
1780
+ }
1781
+ hasSchema(tableId) {
1782
+ return this._schemaCache.has(tableId) || this._tableCache.has(tableId);
1783
+ }
1784
+ hasTable(tableId) {
1785
+ return this._tableCache.has(tableId);
1786
+ }
1787
+ hasRow(tableId, rowId) {
1788
+ const table = this._tableCache.get(tableId);
1789
+ return table?.rows.has(rowId) ?? false;
1790
+ }
1791
+ isLoading(tableId) {
1792
+ return this._loadingTables.has(tableId);
1793
+ }
1794
+ isLoadingRow(tableId, rowId) {
1795
+ const rowSet = this._loadingRows.get(tableId);
1796
+ return rowSet?.has(rowId) ?? false;
1797
+ }
1798
+ addSchema(tableId, schema) {
1799
+ if (this._disposed) {
1800
+ return;
1801
+ }
1802
+ if (this.reactivity) {
1803
+ this.reactivity.runInAction(() => {
1804
+ this._schemaCache.set(tableId, schema);
1805
+ });
1806
+ } else {
1807
+ this._schemaCache.set(tableId, schema);
1808
+ }
1809
+ }
1810
+ addTable(tableId, schema, rows) {
1811
+ if (this._disposed) {
1812
+ return;
1813
+ }
1814
+ const rowMap = this.reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
1815
+ for (const row of rows) {
1816
+ rowMap.set(row.rowId, row);
1817
+ }
1818
+ const cache = { schema, rows: rowMap };
1819
+ if (this.reactivity) {
1820
+ this.reactivity.runInAction(() => {
1821
+ this._tableCache.set(tableId, cache);
1822
+ this._schemaCache.set(tableId, schema);
1823
+ });
1824
+ } else {
1825
+ this._tableCache.set(tableId, cache);
1826
+ this._schemaCache.set(tableId, schema);
1827
+ }
1828
+ if (this._prefetchEnabled) {
1829
+ this.prefetchForeignKeysFromTable(tableId, schema, rows);
1830
+ }
1831
+ }
1832
+ addRow(tableId, rowId, data) {
1833
+ if (this._disposed) {
1834
+ return;
1835
+ }
1836
+ const table = this._tableCache.get(tableId);
1837
+ if (table) {
1838
+ const rowData = { rowId, data };
1839
+ if (this.reactivity) {
1840
+ this.reactivity.runInAction(() => {
1841
+ table.rows.set(rowId, rowData);
1842
+ });
1843
+ } else {
1844
+ table.rows.set(rowId, rowData);
1845
+ }
1846
+ if (this._prefetchEnabled) {
1847
+ this.prefetchForeignKeysFromRow(tableId, table.schema, data);
1848
+ }
1849
+ }
1850
+ }
1851
+ renameTable(oldTableId, newTableId) {
1852
+ if (this._disposed) {
1853
+ return;
1854
+ }
1855
+ const schema = this._schemaCache.get(oldTableId);
1856
+ const tableCache = this._tableCache.get(oldTableId);
1857
+ if (this.reactivity) {
1858
+ this.reactivity.runInAction(() => {
1859
+ if (schema) {
1860
+ this._schemaCache.delete(oldTableId);
1861
+ this._schemaCache.set(newTableId, schema);
1862
+ }
1863
+ if (tableCache) {
1864
+ this._tableCache.delete(oldTableId);
1865
+ this._tableCache.set(newTableId, tableCache);
1866
+ }
1867
+ });
1868
+ } else {
1869
+ if (schema) {
1870
+ this._schemaCache.delete(oldTableId);
1871
+ this._schemaCache.set(newTableId, schema);
1872
+ }
1873
+ if (tableCache) {
1874
+ this._tableCache.delete(oldTableId);
1875
+ this._tableCache.set(newTableId, tableCache);
1876
+ }
1877
+ }
1878
+ }
1879
+ async getSchema(tableId) {
1880
+ const cachedSchema = this._schemaCache.get(tableId);
1881
+ if (cachedSchema) {
1882
+ return cachedSchema;
1883
+ }
1884
+ const cachedTable = this._tableCache.get(tableId);
1885
+ if (cachedTable) {
1886
+ return cachedTable.schema;
1887
+ }
1888
+ if (!this.loader) {
1889
+ throw new ForeignKeyNotFoundError(tableId);
1890
+ }
1891
+ const pending = this._pendingTableLoads.get(tableId);
1892
+ if (pending) {
1893
+ return pending;
1894
+ }
1895
+ const loadPromise = this.loadSchemaInternal(tableId);
1896
+ this._pendingTableLoads.set(tableId, loadPromise);
1897
+ try {
1898
+ return await loadPromise;
1899
+ } finally {
1900
+ this._pendingTableLoads.delete(tableId);
1901
+ }
1902
+ }
1903
+ async getRowData(tableId, rowId) {
1904
+ const table = this._tableCache.get(tableId);
1905
+ if (table) {
1906
+ const row = table.rows.get(rowId);
1907
+ if (row) {
1908
+ return row;
1909
+ }
1910
+ }
1911
+ if (!this.loader) {
1912
+ throw new ForeignKeyNotFoundError(tableId, rowId);
1913
+ }
1914
+ const tableLoads = this._pendingRowLoads.get(tableId);
1915
+ const pending = tableLoads?.get(rowId);
1916
+ if (pending) {
1917
+ return pending;
1918
+ }
1919
+ const loadPromise = this.loadRowInternal(tableId, rowId);
1920
+ this.setPendingRowLoad(tableId, rowId, loadPromise);
1921
+ try {
1922
+ return await loadPromise;
1923
+ } finally {
1924
+ this.clearPendingRowLoad(tableId, rowId);
1925
+ }
1926
+ }
1927
+ dispose() {
1928
+ this._disposed = true;
1929
+ this._schemaCache.clear();
1930
+ this._tableCache.clear();
1931
+ this._loadingTables.clear();
1932
+ this._loadingRows.clear();
1933
+ this._pendingTableLoads.clear();
1934
+ this._pendingRowLoads.clear();
1935
+ }
1936
+ async loadSchemaInternal(tableId) {
1937
+ if (!this.loader) {
1938
+ throw new ForeignKeyResolverNotConfiguredError();
1939
+ }
1940
+ this._loadingTables.add(tableId);
1941
+ try {
1942
+ const schema = await this.loader.loadSchema(tableId);
1943
+ if (!this._disposed) {
1944
+ this.addSchema(tableId, schema);
1945
+ }
1946
+ return schema;
1947
+ } finally {
1948
+ this._loadingTables.delete(tableId);
1949
+ }
1950
+ }
1951
+ async loadRowInternal(tableId, rowId) {
1952
+ if (!this.loader) {
1953
+ throw new ForeignKeyResolverNotConfiguredError();
1954
+ }
1955
+ this.markRowAsLoading(tableId, rowId);
1956
+ try {
1957
+ const result = await this.loader.loadRow(tableId, rowId);
1958
+ if (!this._disposed) {
1959
+ this.addSchema(tableId, result.schema);
1960
+ this.ensureTableCache(tableId, result.schema);
1961
+ this.addRow(tableId, rowId, result.row.data);
1962
+ }
1963
+ return result.row;
1964
+ } finally {
1965
+ this.clearRowLoading(tableId, rowId);
1966
+ }
1967
+ }
1968
+ ensureTableCache(tableId, schema) {
1969
+ if (!this._tableCache.has(tableId)) {
1970
+ const rowMap = this.reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
1971
+ const cache = { schema, rows: rowMap };
1972
+ if (this.reactivity) {
1973
+ this.reactivity.runInAction(() => {
1974
+ this._tableCache.set(tableId, cache);
1975
+ });
1976
+ } else {
1977
+ this._tableCache.set(tableId, cache);
1978
+ }
1979
+ }
1980
+ }
1981
+ markRowAsLoading(tableId, rowId) {
1982
+ let rowSet = this._loadingRows.get(tableId);
1983
+ if (!rowSet) {
1984
+ rowSet = /* @__PURE__ */ new Set();
1985
+ this._loadingRows.set(tableId, rowSet);
1986
+ }
1987
+ rowSet.add(rowId);
1988
+ }
1989
+ clearRowLoading(tableId, rowId) {
1990
+ const rowSet = this._loadingRows.get(tableId);
1991
+ if (rowSet) {
1992
+ rowSet.delete(rowId);
1993
+ if (rowSet.size === 0) {
1994
+ this._loadingRows.delete(tableId);
1995
+ }
1996
+ }
1997
+ }
1998
+ setPendingRowLoad(tableId, rowId, promise) {
1999
+ let tableLoads = this._pendingRowLoads.get(tableId);
2000
+ if (!tableLoads) {
2001
+ tableLoads = /* @__PURE__ */ new Map();
2002
+ this._pendingRowLoads.set(tableId, tableLoads);
2003
+ }
2004
+ tableLoads.set(rowId, promise);
2005
+ }
2006
+ clearPendingRowLoad(tableId, rowId) {
2007
+ const tableLoads = this._pendingRowLoads.get(tableId);
2008
+ if (tableLoads) {
2009
+ tableLoads.delete(rowId);
2010
+ if (tableLoads.size === 0) {
2011
+ this._pendingRowLoads.delete(tableId);
2012
+ }
2013
+ }
2014
+ }
2015
+ prefetchForeignKeysFromTable(sourceTableId, schema, rows) {
2016
+ for (const row of rows) {
2017
+ this.prefetchForeignKeysFromRow(sourceTableId, schema, row.data);
2018
+ }
2019
+ }
2020
+ prefetchForeignKeysFromRow(_sourceTableId, schema, data) {
2021
+ const foreignKeys = this.extractForeignKeys(schema);
2022
+ if (foreignKeys.length === 0) {
2023
+ return;
2024
+ }
2025
+ const dataObj = data;
2026
+ const properties = schema.properties;
2027
+ for (const [fieldName, fieldSchema] of Object.entries(properties)) {
2028
+ const fk = this.getForeignKeyFromSchema(fieldSchema);
2029
+ if (!fk) {
2030
+ continue;
2031
+ }
2032
+ const fieldValue = dataObj[fieldName];
2033
+ if (typeof fieldValue !== "string" || !fieldValue) {
2034
+ continue;
2035
+ }
2036
+ if (!this.hasRow(fk, fieldValue) && !this.isLoadingRow(fk, fieldValue)) {
2037
+ this.prefetchRow(fk, fieldValue);
2038
+ }
2039
+ }
2040
+ }
2041
+ prefetchRow(tableId, rowId) {
2042
+ if (!this.loader) {
2043
+ return;
2044
+ }
2045
+ const prefetchPromise = this.getRowData(tableId, rowId);
2046
+ prefetchPromise.catch(() => {
2047
+ });
2048
+ }
2049
+ extractForeignKeys(schema) {
2050
+ const foreignKeys = [];
2051
+ for (const fieldSchema of Object.values(schema.properties)) {
2052
+ const fk = this.getForeignKeyFromSchema(fieldSchema);
2053
+ if (fk) {
2054
+ foreignKeys.push(fk);
2055
+ }
2056
+ }
2057
+ return foreignKeys;
2058
+ }
2059
+ getForeignKeyFromSchema(schema) {
2060
+ if ("type" in schema && schema.type === "string" /* String */) {
2061
+ return schema.foreignKey;
2062
+ }
2063
+ return void 0;
2064
+ }
2065
+ };
2066
+ function createForeignKeyResolver(options) {
2067
+ return new ForeignKeyResolverImpl(options);
2068
+ }
2069
+
2070
+ // src/model/data-model/DataModelImpl.ts
2071
+ var DataModelImpl = class {
2072
+ _tables;
2073
+ _fk;
2074
+ _ownsFkResolver;
2075
+ _reactivity;
2076
+ constructor(options) {
2077
+ this._reactivity = options?.reactivity;
2078
+ this._tables = this._reactivity?.observableMap() ?? /* @__PURE__ */ new Map();
2079
+ if (options?.fkResolver) {
2080
+ this._fk = options.fkResolver;
2081
+ this._ownsFkResolver = false;
2082
+ } else {
2083
+ this._fk = createForeignKeyResolver({ reactivity: this._reactivity });
2084
+ this._ownsFkResolver = true;
2085
+ }
2086
+ this.initObservable();
2087
+ }
2088
+ initObservable() {
2089
+ this._reactivity?.makeObservable(this, {
2090
+ _tables: "observable",
2091
+ tables: "computed",
2092
+ tableIds: "computed",
2093
+ isDirty: "computed",
2094
+ addTable: "action",
2095
+ removeTable: "action",
2096
+ renameTable: "action",
2097
+ commit: "action",
2098
+ revert: "action"
2099
+ });
2100
+ }
2101
+ get fk() {
2102
+ return this._fk;
2103
+ }
2104
+ get tables() {
2105
+ return Array.from(this._tables.values());
2106
+ }
2107
+ get tableIds() {
2108
+ return Array.from(this._tables.keys());
2109
+ }
2110
+ get isDirty() {
2111
+ for (const table of this._tables.values()) {
2112
+ if (table.isDirty) {
2113
+ return true;
2114
+ }
2115
+ }
2116
+ return false;
2117
+ }
2118
+ hasTable(tableId) {
2119
+ return this._tables.has(tableId);
2120
+ }
2121
+ getTable(tableId) {
2122
+ return this._tables.get(tableId);
2123
+ }
2124
+ addTable(tableId, schema, rows) {
2125
+ const tableModel = createTableModel(
2126
+ {
2127
+ tableId,
2128
+ schema,
2129
+ rows,
2130
+ fkResolver: this._fk
2131
+ },
2132
+ this._reactivity
2133
+ );
2134
+ this._tables.set(tableId, tableModel);
2135
+ this._fk.addSchema(tableId, schema);
2136
+ if (rows && rows.length > 0) {
2137
+ this._fk.addTable(tableId, schema, rows);
2138
+ }
2139
+ return tableModel;
2140
+ }
2141
+ removeTable(tableId) {
2142
+ this._tables.delete(tableId);
2143
+ }
2144
+ renameTable(oldTableId, newTableId) {
2145
+ const table = this._tables.get(oldTableId);
2146
+ if (!table) {
2147
+ return;
2148
+ }
2149
+ if (this._tables.has(newTableId)) {
2150
+ throw new Error(`Table with id '${newTableId}' already exists`);
2151
+ }
2152
+ table.rename(newTableId);
2153
+ this._tables.delete(oldTableId);
2154
+ this._tables.set(newTableId, table);
2155
+ this._fk.renameTable(oldTableId, newTableId);
2156
+ }
2157
+ commit() {
2158
+ for (const table of this._tables.values()) {
2159
+ table.commit();
2160
+ }
2161
+ }
2162
+ revert() {
2163
+ for (const table of this._tables.values()) {
2164
+ table.revert();
2165
+ }
2166
+ }
2167
+ dispose() {
2168
+ this._tables.clear();
2169
+ if (this._ownsFkResolver) {
2170
+ this._fk.dispose();
2171
+ }
2172
+ }
2173
+ };
2174
+ function createDataModel(options) {
2175
+ return new DataModelImpl(options);
2176
+ }
2177
+
2178
+ exports.ArrayValueNode = ArrayValueNode;
2179
+ exports.BasePrimitiveValueNode = BasePrimitiveValueNode;
2180
+ exports.BaseValueNode = BaseValueNode;
2181
+ exports.BooleanValueNode = BooleanValueNode;
2182
+ exports.DataModelImpl = DataModelImpl;
2183
+ exports.ForeignKeyNotFoundError = ForeignKeyNotFoundError;
2184
+ exports.ForeignKeyResolverImpl = ForeignKeyResolverImpl;
2185
+ exports.ForeignKeyResolverNotConfiguredError = ForeignKeyResolverNotConfiguredError;
2186
+ exports.ForeignKeyValueNodeImpl = ForeignKeyValueNodeImpl;
2187
+ exports.NodeFactory = NodeFactory;
2188
+ exports.NodeFactory2 = NodeFactory2;
2189
+ exports.NodeFactoryRegistry = NodeFactoryRegistry;
2190
+ exports.NumberValueNode = NumberValueNode;
2191
+ exports.ObjectValueNode = ObjectValueNode;
2192
+ exports.RowModelImpl = RowModelImpl;
2193
+ exports.SchemaParser = SchemaParser;
2194
+ exports.StringValueNode = StringValueNode;
2195
+ exports.TableModelImpl = TableModelImpl;
2196
+ exports.ValueType = ValueType;
2197
+ exports.createDataModel = createDataModel;
2198
+ exports.createDefaultRegistry = createDefaultRegistry;
2199
+ exports.createForeignKeyResolver = createForeignKeyResolver;
2200
+ exports.createNodeFactory = createNodeFactory;
2201
+ exports.createSchemaModel = createSchemaModel;
2202
+ exports.createTableModel = createTableModel;
2203
+ exports.extractFormulaDefinition = extractFormulaDefinition;
2204
+ exports.generateDefaultValue = generateDefaultValue;
2205
+ exports.generateNodeId = generateNodeId;
2206
+ exports.isForeignKeyValueNode = isForeignKeyValueNode;
2207
+ exports.resetNodeIdCounter = resetNodeIdCounter;
2208
+ //# sourceMappingURL=chunk-5WZ4YPH5.cjs.map
2209
+ //# sourceMappingURL=chunk-5WZ4YPH5.cjs.map