@stonecrop/stonecrop 0.7.8 → 0.8.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.
@@ -4,6 +4,7 @@ import { Stonecrop } from './stonecrop';
4
4
  import DoctypeMeta from './doctype';
5
5
  import type { HSTNode } from './stores/hst';
6
6
  import type { HSTOperation, OperationLogConfig, OperationLogSnapshot } from './types/operation-log';
7
+ import { SchemaTypes } from '@stonecrop/aform';
7
8
  /**
8
9
  * Operation Log API - nested object containing all operation log functionality
9
10
  * @public
@@ -51,6 +52,13 @@ export type HSTStonecropReturn = BaseStonecropReturn & {
51
52
  handleHSTChange: (changeData: HSTChangeData) => void;
52
53
  hstStore: Ref<HSTNode | undefined>;
53
54
  formData: Ref<Record<string, any>>;
55
+ resolvedSchema: Ref<SchemaTypes[]>;
56
+ loadNestedData: (parentPath: string, childDoctype: DoctypeMeta, recordId?: string) => Record<string, any>;
57
+ saveRecursive: (doctype: DoctypeMeta, recordId: string) => Promise<Record<string, any>>;
58
+ createNestedContext: (basePath: string, childDoctype: DoctypeMeta) => {
59
+ provideHSTPath: (fieldname: string) => string;
60
+ handleHSTChange: (changeData: HSTChangeData) => void;
61
+ };
54
62
  };
55
63
  /**
56
64
  * HST Change data structure
@@ -1 +1 @@
1
- {"version":3,"file":"composable.d.ts","sourceRoot":"","sources":["../../src/composable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"composable.d.ts","sourceRoot":"","sources":["../../src/composable.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,17 @@ export function useStonecrop(options) {
16
16
  // Use refs for router-loaded doctype to maintain reactivity
17
17
  const routerDoctype = ref();
18
18
  const routerRecordId = ref();
19
+ // Resolved schema with nested Doctype fields expanded
20
+ const resolvedSchema = ref([]);
21
+ // Auto-resolve schema when doctype is available
22
+ if (options.doctype && registry) {
23
+ const schemaArray = options.doctype.schema
24
+ ? Array.isArray(options.doctype.schema)
25
+ ? options.doctype.schema
26
+ : Array.from(options.doctype.schema)
27
+ : [];
28
+ resolvedSchema.value = registry.resolveSchema(schemaArray);
29
+ }
19
30
  // Operation log state and methods - will be populated after stonecrop instance is created
20
31
  const operations = ref([]);
21
32
  const currentIndex = ref(-1);
@@ -116,6 +127,15 @@ export function useStonecrop(options) {
116
127
  routerDoctype.value = doctype;
117
128
  routerRecordId.value = recordId;
118
129
  hstStore.value = stonecrop.value.getStore();
130
+ // Resolve schema for router-loaded doctype
131
+ if (registry) {
132
+ const schemaArray = doctype.schema
133
+ ? Array.isArray(doctype.schema)
134
+ ? doctype.schema
135
+ : Array.from(doctype.schema)
136
+ : [];
137
+ resolvedSchema.value = registry.resolveSchema(schemaArray);
138
+ }
119
139
  if (recordId && recordId !== 'new') {
120
140
  const existingRecord = stonecrop.value.getRecordById(doctype, recordId);
121
141
  if (existingRecord) {
@@ -230,6 +250,86 @@ export function useStonecrop(options) {
230
250
  provide('hstPathProvider', provideHSTPath);
231
251
  provide('hstChangeHandler', handleHSTChange);
232
252
  }
253
+ /**
254
+ * Load nested doctype data from API or initialize empty structure
255
+ * @param parentPath - The parent path (e.g., "customer.123.address")
256
+ * @param childDoctype - The child doctype metadata
257
+ * @param recordId - Optional record ID to load
258
+ * @returns Promise resolving to the loaded or initialized data
259
+ */
260
+ const loadNestedData = (parentPath, childDoctype, recordId) => {
261
+ if (!stonecrop.value) {
262
+ return initializeNewRecord(childDoctype);
263
+ }
264
+ // If recordId provided, try to load existing data
265
+ if (recordId) {
266
+ try {
267
+ // Check if data already exists in HST
268
+ const existingData = hstStore.value?.get(parentPath);
269
+ if (existingData && typeof existingData === 'object') {
270
+ return existingData;
271
+ }
272
+ // TODO: Add API fetch logic here if needed
273
+ // For now, initialize new record
274
+ return initializeNewRecord(childDoctype);
275
+ }
276
+ catch {
277
+ return initializeNewRecord(childDoctype);
278
+ }
279
+ }
280
+ // Initialize new record
281
+ return initializeNewRecord(childDoctype);
282
+ };
283
+ /**
284
+ * Recursively save a record with all nested doctype fields
285
+ * @param doctype - The doctype metadata
286
+ * @param recordId - The record ID to save
287
+ * @returns Promise resolving to the complete save payload
288
+ */
289
+ const saveRecursive = async (doctype, recordId) => {
290
+ if (!hstStore.value || !stonecrop.value) {
291
+ throw new Error('HST store not initialized');
292
+ }
293
+ const recordPath = `${doctype.slug}.${recordId}`;
294
+ const recordData = hstStore.value.get(recordPath) || {};
295
+ // Build the save payload using resolved schema
296
+ const payload = { ...recordData };
297
+ // Use resolveSchema to get the full resolved tree, then walk Doctype fields
298
+ const schemaArray = (doctype.schema ? (Array.isArray(doctype.schema) ? doctype.schema : Array.from(doctype.schema)) : []);
299
+ const resolved = registry ? registry.resolveSchema(schemaArray) : schemaArray;
300
+ const doctypeFields = resolved.filter(field => 'fieldtype' in field && field.fieldtype === 'Doctype' && 'schema' in field && Array.isArray(field.schema));
301
+ // Recursively collect nested data from HST using resolved schemas
302
+ for (const field of doctypeFields) {
303
+ const doctypeField = field;
304
+ const fieldPath = `${recordPath}.${doctypeField.fieldname}`;
305
+ const nestedData = collectNestedData(doctypeField.schema, fieldPath, hstStore.value);
306
+ payload[doctypeField.fieldname] = nestedData;
307
+ }
308
+ return payload;
309
+ };
310
+ /**
311
+ * Create a nested context for child forms
312
+ * @param basePath - The base path for the nested context (e.g., "customer.123.address")
313
+ * @param _childDoctype - The child doctype metadata (unused but kept for API consistency)
314
+ * @returns Object with scoped provideHSTPath and handleHSTChange
315
+ */
316
+ const createNestedContext = (basePath, _childDoctype) => {
317
+ const nestedProvideHSTPath = (fieldname) => {
318
+ return `${basePath}.${fieldname}`;
319
+ };
320
+ const nestedHandleHSTChange = (changeData) => {
321
+ // Update the path to be relative to the nested base path
322
+ const nestedPath = changeData.path.startsWith(basePath) ? changeData.path : `${basePath}.${changeData.fieldname}`;
323
+ handleHSTChange({
324
+ ...changeData,
325
+ path: nestedPath,
326
+ });
327
+ };
328
+ return {
329
+ provideHSTPath: nestedProvideHSTPath,
330
+ handleHSTChange: nestedHandleHSTChange,
331
+ };
332
+ };
233
333
  // Create operation log API object
234
334
  const operationLog = {
235
335
  operations,
@@ -261,6 +361,10 @@ export function useStonecrop(options) {
261
361
  handleHSTChange,
262
362
  hstStore,
263
363
  formData,
364
+ resolvedSchema,
365
+ loadNestedData,
366
+ saveRecursive,
367
+ createNestedContext,
264
368
  };
265
369
  }
266
370
  else if (!options.doctype && registry?.router) {
@@ -272,6 +376,10 @@ export function useStonecrop(options) {
272
376
  handleHSTChange,
273
377
  hstStore,
274
378
  formData,
379
+ resolvedSchema,
380
+ loadNestedData,
381
+ saveRecursive,
382
+ createNestedContext,
275
383
  };
276
384
  }
277
385
  // No doctype and no router - basic mode
@@ -346,3 +454,24 @@ function updateNestedObject(obj, path, value) {
346
454
  const finalKey = path[path.length - 1];
347
455
  current[finalKey] = value;
348
456
  }
457
+ /**
458
+ * Recursively collect nested data from HST using pre-resolved schemas
459
+ * @param resolvedSchema - The already-resolved schema (with nested schemas embedded)
460
+ * @param basePath - The base path in HST (e.g., "customer.123.address")
461
+ * @param hstStore - The HST store instance
462
+ * @returns The collected data object
463
+ */
464
+ function collectNestedData(resolvedSchema, basePath, hstStore) {
465
+ const data = hstStore.get(basePath) || {};
466
+ const payload = { ...data };
467
+ // Find Doctype fields that have resolved child schemas
468
+ const doctypeFields = resolvedSchema.filter(field => 'fieldtype' in field && field.fieldtype === 'Doctype' && 'schema' in field && Array.isArray(field.schema));
469
+ // Recursively collect nested data
470
+ for (const field of doctypeFields) {
471
+ const doctypeField = field;
472
+ const fieldPath = `${basePath}.${doctypeField.fieldname}`;
473
+ const nestedData = collectNestedData(doctypeField.schema, fieldPath, hstStore);
474
+ payload[doctypeField.fieldname] = nestedData;
475
+ }
476
+ return payload;
477
+ }
@@ -1,3 +1,4 @@
1
+ import type { SchemaTypes } from '@stonecrop/aform';
1
2
  import { Router } from 'vue-router';
2
3
  import DoctypeMeta from './doctype';
3
4
  import { RouteContext } from './types/registry';
@@ -44,5 +45,63 @@ export default class Registry {
44
45
  * @see {@link DoctypeMeta}
45
46
  */
46
47
  addDoctype(doctype: DoctypeMeta): void;
48
+ /**
49
+ * Resolve nested Doctype and Table fields in a schema by embedding child schemas inline.
50
+ *
51
+ * @remarks
52
+ * Walks the schema array and for each field with `fieldtype: 'Doctype'` and a string
53
+ * `options` value, looks up the referenced doctype in the registry and embeds its schema
54
+ * as the field's `schema` property. Recurses for deeply nested doctypes.
55
+ *
56
+ * For fields with `fieldtype: 'Table'`, looks up the referenced child doctype and
57
+ * auto-derives `columns` from its schema fields (unless columns are already provided).
58
+ * Also sets sensible defaults for `component` (`'ATable'`) and `config` (`{ view: 'list' }`).
59
+ * Row data is expected to come from the parent form's data model at `data[fieldname]`.
60
+ *
61
+ * Returns a new array — does not mutate the original schema.
62
+ *
63
+ * @param schema - The schema array to resolve
64
+ * @returns A new schema array with nested Doctype fields resolved
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * registry.addDoctype(addressDoctype)
69
+ * registry.addDoctype(customerDoctype)
70
+ *
71
+ * // Before: customer schema has { fieldname: 'address', fieldtype: 'Doctype', options: 'address' }
72
+ * const resolved = registry.resolveSchema(customerSchema)
73
+ * // After: address field now has schema: [...address fields...]
74
+ * ```
75
+ *
76
+ * @public
77
+ */
78
+ resolveSchema(schema: SchemaTypes[], visited?: Set<string>): SchemaTypes[];
79
+ /**
80
+ * Initialize a new record with default values based on a schema.
81
+ *
82
+ * @remarks
83
+ * Creates a plain object with keys from the schema's fieldnames and default values
84
+ * derived from each field's `fieldtype`:
85
+ * - Data, Text → `''`
86
+ * - Check → `false`
87
+ * - Int, Float, Decimal, Currency, Quantity → `0`
88
+ * - Table → `[]`
89
+ * - JSON, Doctype → `{}`
90
+ * - All others → `null`
91
+ *
92
+ * For Doctype fields with a resolved `schema` array, recursively initializes the nested record.
93
+ *
94
+ * @param schema - The schema array to derive defaults from
95
+ * @returns A plain object with default values for each field
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * const defaults = registry.initializeRecord(addressSchema)
100
+ * // { street: '', city: '', state: '', zip_code: '' }
101
+ * ```
102
+ *
103
+ * @public
104
+ */
105
+ initializeRecord(schema: SchemaTypes[]): Record<string, any>;
47
106
  }
48
107
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnC,OAAO,WAAW,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/C;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC5B;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAA;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAE9C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAWzG;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAE5E;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW;CAkC/B"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnC,OAAO,WAAW,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/C;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC5B;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAA;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAE9C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAWzG;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAE5E;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW;IAsB/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,WAAW,EAAE;IAwF1E;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAwD5D"}
@@ -69,4 +69,170 @@ export default class Registry {
69
69
  });
70
70
  }
71
71
  }
72
+ /**
73
+ * Resolve nested Doctype and Table fields in a schema by embedding child schemas inline.
74
+ *
75
+ * @remarks
76
+ * Walks the schema array and for each field with `fieldtype: 'Doctype'` and a string
77
+ * `options` value, looks up the referenced doctype in the registry and embeds its schema
78
+ * as the field's `schema` property. Recurses for deeply nested doctypes.
79
+ *
80
+ * For fields with `fieldtype: 'Table'`, looks up the referenced child doctype and
81
+ * auto-derives `columns` from its schema fields (unless columns are already provided).
82
+ * Also sets sensible defaults for `component` (`'ATable'`) and `config` (`{ view: 'list' }`).
83
+ * Row data is expected to come from the parent form's data model at `data[fieldname]`.
84
+ *
85
+ * Returns a new array — does not mutate the original schema.
86
+ *
87
+ * @param schema - The schema array to resolve
88
+ * @returns A new schema array with nested Doctype fields resolved
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * registry.addDoctype(addressDoctype)
93
+ * registry.addDoctype(customerDoctype)
94
+ *
95
+ * // Before: customer schema has { fieldname: 'address', fieldtype: 'Doctype', options: 'address' }
96
+ * const resolved = registry.resolveSchema(customerSchema)
97
+ * // After: address field now has schema: [...address fields...]
98
+ * ```
99
+ *
100
+ * @public
101
+ */
102
+ resolveSchema(schema, visited) {
103
+ const seen = visited || new Set();
104
+ return schema.map(field => {
105
+ // Check for Doctype fieldtype with a string options (slug reference)
106
+ if ('fieldtype' in field &&
107
+ field.fieldtype === 'Doctype' &&
108
+ 'options' in field &&
109
+ typeof field.options === 'string') {
110
+ const doctypeSlug = field.options;
111
+ // Circular reference protection
112
+ if (seen.has(doctypeSlug)) {
113
+ return { ...field };
114
+ }
115
+ const doctype = this.registry[doctypeSlug];
116
+ if (doctype && doctype.schema) {
117
+ // Convert Immutable.List to plain array if needed
118
+ const childSchema = Array.isArray(doctype.schema) ? doctype.schema : Array.from(doctype.schema);
119
+ // Recurse into child schema to resolve deeply nested doctypes
120
+ seen.add(doctypeSlug);
121
+ const resolvedChild = this.resolveSchema(childSchema, seen);
122
+ seen.delete(doctypeSlug);
123
+ return { ...field, schema: resolvedChild };
124
+ }
125
+ }
126
+ // Resolve Table fieldtype — 1:many child doctype rendered as ATable
127
+ if ('fieldtype' in field &&
128
+ field.fieldtype === 'Table' &&
129
+ 'options' in field &&
130
+ typeof field.options === 'string') {
131
+ const doctypeSlug = field.options;
132
+ // Circular reference protection
133
+ if (seen.has(doctypeSlug)) {
134
+ return { ...field };
135
+ }
136
+ const doctype = this.registry[doctypeSlug];
137
+ if (doctype && doctype.schema) {
138
+ const childSchema = Array.isArray(doctype.schema) ? doctype.schema : Array.from(doctype.schema);
139
+ const resolved = { ...field };
140
+ // Auto-derive columns from child schema fields if not already provided
141
+ if (!('columns' in field) || !field.columns) {
142
+ resolved.columns = childSchema.map(childField => ({
143
+ name: childField.fieldname,
144
+ fieldname: childField.fieldname,
145
+ label: ('label' in childField && childField.label) || childField.fieldname,
146
+ fieldtype: 'fieldtype' in childField ? childField.fieldtype : 'Data',
147
+ align: ('align' in childField && childField.align) || 'left',
148
+ edit: 'edit' in childField ? childField.edit : true,
149
+ width: ('width' in childField && childField.width) || '20ch',
150
+ }));
151
+ }
152
+ // Set default component if not already specified
153
+ if (!resolved.component) {
154
+ resolved.component = 'ATable';
155
+ }
156
+ // Set default config if not already specified
157
+ if (!('config' in field) || !field.config) {
158
+ resolved.config = { view: 'list' };
159
+ }
160
+ // Initialize rows to empty array so componentProps fallback
161
+ // routes data from the form's dataModel[fieldname]
162
+ if (!('rows' in field) || !field.rows) {
163
+ resolved.rows = [];
164
+ }
165
+ return resolved;
166
+ }
167
+ }
168
+ return { ...field };
169
+ });
170
+ }
171
+ /**
172
+ * Initialize a new record with default values based on a schema.
173
+ *
174
+ * @remarks
175
+ * Creates a plain object with keys from the schema's fieldnames and default values
176
+ * derived from each field's `fieldtype`:
177
+ * - Data, Text → `''`
178
+ * - Check → `false`
179
+ * - Int, Float, Decimal, Currency, Quantity → `0`
180
+ * - Table → `[]`
181
+ * - JSON, Doctype → `{}`
182
+ * - All others → `null`
183
+ *
184
+ * For Doctype fields with a resolved `schema` array, recursively initializes the nested record.
185
+ *
186
+ * @param schema - The schema array to derive defaults from
187
+ * @returns A plain object with default values for each field
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * const defaults = registry.initializeRecord(addressSchema)
192
+ * // { street: '', city: '', state: '', zip_code: '' }
193
+ * ```
194
+ *
195
+ * @public
196
+ */
197
+ initializeRecord(schema) {
198
+ const record = {};
199
+ schema.forEach(field => {
200
+ const fieldtype = 'fieldtype' in field ? field.fieldtype : 'Data';
201
+ switch (fieldtype) {
202
+ case 'Data':
203
+ case 'Text':
204
+ case 'Code':
205
+ record[field.fieldname] = '';
206
+ break;
207
+ case 'Check':
208
+ record[field.fieldname] = false;
209
+ break;
210
+ case 'Int':
211
+ case 'Float':
212
+ case 'Decimal':
213
+ case 'Currency':
214
+ case 'Quantity':
215
+ record[field.fieldname] = 0;
216
+ break;
217
+ case 'Table':
218
+ record[field.fieldname] = [];
219
+ break;
220
+ case 'JSON':
221
+ record[field.fieldname] = {};
222
+ break;
223
+ case 'Doctype':
224
+ // If nested schema is resolved, recursively initialize
225
+ if ('schema' in field && Array.isArray(field.schema)) {
226
+ record[field.fieldname] = this.initializeRecord(field.schema);
227
+ }
228
+ else {
229
+ record[field.fieldname] = {};
230
+ }
231
+ break;
232
+ default:
233
+ record[field.fieldname] = null;
234
+ }
235
+ });
236
+ return record;
237
+ }
72
238
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stonecrop.d.ts","sourceRoot":"","sources":["../../src/stonecrop.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,WAAW,CAAA;AACnC,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;;GAGG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAC,CAAyC;IACpE,OAAO,CAAC,mBAAmB,CAAC,CAA6B;IAEzD,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAE3B;;;;OAIG;gBACS,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAWhF;;;OAGG;IACH,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO;IAM/C;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,IAAI;IASjF;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAoBnF;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUnE;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,EAAE;IAYrD;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAWjD;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAKjC;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IAkCnE;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrD;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IAOlD;;;OAGG;IACH,QAAQ,IAAI,OAAO;CAGnB"}
1
+ {"version":3,"file":"stonecrop.d.ts","sourceRoot":"","sources":["../../src/stonecrop.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,WAAW,CAAA;AACnC,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;;GAGG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAC,CAAyC;IACpE,OAAO,CAAC,mBAAmB,CAAC,CAA6B;IAEzD,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAE3B;;;;OAIG;gBACS,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAWhF;;;OAGG;IACH,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO;IAM/C;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,IAAI;IASjF;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAoBnF;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUnE;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,EAAE;IAYrD;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAWjD;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAKjC;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IAkCnE;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrD;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IAOlD;;;OAGG;IACH,QAAQ,IAAI,OAAO;CAGnB"}
@@ -1,3 +1,4 @@
1
+ import { reactive } from 'vue';
1
2
  import { createHST } from './stores/hst';
2
3
  import { useOperationLogStore } from './stores/operation-log';
3
4
  /**
@@ -45,7 +46,9 @@ export class Stonecrop {
45
46
  Object.keys(this.registry.registry).forEach(doctypeSlug => {
46
47
  initialStoreStructure[doctypeSlug] = {};
47
48
  });
48
- this.hstStore = createHST(initialStoreStructure, 'StonecropStore');
49
+ // Wrap the store in Vue's reactive() for automatic change detection
50
+ // This enables Vue computed properties to track HST store changes
51
+ this.hstStore = createHST(reactive(initialStoreStructure), 'StonecropStore');
49
52
  }
50
53
  /**
51
54
  * Setup automatic sync with Registry when doctypes are added
@@ -202,9 +205,9 @@ export class Stonecrop {
202
205
  */
203
206
  async getRecords(doctype) {
204
207
  const response = await fetch(`/${doctype.slug}`);
205
- const records = await response.json();
208
+ const records = (await response.json());
206
209
  // Store each record in HST
207
- records.forEach((record) => {
210
+ records.forEach(record => {
208
211
  if (record.id) {
209
212
  this.addRecord(doctype, record.id, record);
210
213
  }
@@ -139,6 +139,11 @@ declare class HSTProxy implements HSTNode {
139
139
  private isPiniaStore;
140
140
  private isImmutable;
141
141
  private isPrimitive;
142
+ /**
143
+ * Parse a path string into segments, handling both dot notation and array bracket notation
144
+ * @param path - The path string to parse (e.g., "order.456.line_items[0].product")
145
+ * @returns Array of path segments (e.g., ['order', '456', 'line_items', '0', 'product'])
146
+ */
142
147
  private parsePath;
143
148
  }
144
149
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"hst.d.ts","sourceRoot":"","sources":["../../../src/stores/hst.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hst.d.ts","sourceRoot":"","sources":["../../../src/stores/hst.ts"],"names":[],"mappings":"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"}
@@ -141,7 +141,6 @@ class HSTProxy {
141
141
  // Detect if this is a DELETE operation (setting to undefined when a value existed)
142
142
  const isDelete = value === undefined && beforeValue !== undefined;
143
143
  const operationType = isDelete ? 'delete' : 'set';
144
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
145
144
  logStore.addOperation({
146
145
  type: operationType,
147
146
  path: fullPath,
@@ -254,7 +253,6 @@ class HSTProxy {
254
253
  // Log FSM transition operation
255
254
  const logStore = getOperationLogStore();
256
255
  if (logStore && typeof logStore.addOperation === 'function') {
257
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
258
256
  logStore.addOperation({
259
257
  type: 'transition',
260
258
  path: this.parentPath,
@@ -459,10 +457,19 @@ class HSTProxy {
459
457
  typeof value === 'symbol' ||
460
458
  typeof value === 'bigint');
461
459
  }
460
+ /**
461
+ * Parse a path string into segments, handling both dot notation and array bracket notation
462
+ * @param path - The path string to parse (e.g., "order.456.line_items[0].product")
463
+ * @returns Array of path segments (e.g., ['order', '456', 'line_items', '0', 'product'])
464
+ */
462
465
  parsePath(path) {
463
466
  if (!path)
464
467
  return [];
465
- return path.split('.').filter(segment => segment.length > 0);
468
+ // Replace array bracket notation with dot notation
469
+ // items[0] → items.0
470
+ // items[0][1] → items.0.1
471
+ const normalizedPath = path.replace(/\[(\d+)\]/g, '.$1');
472
+ return normalizedPath.split('.').filter(segment => segment.length > 0);
466
473
  }
467
474
  }
468
475
  /**