@stonecrop/stonecrop 0.10.16 → 0.11.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 (117) hide show
  1. package/README.md +72 -29
  2. package/dist/composable.js +1 -0
  3. package/dist/composables/lazy-link.js +125 -0
  4. package/dist/composables/stonecrop.js +123 -68
  5. package/dist/composables/use-lazy-link-state.js +125 -0
  6. package/dist/composables/use-stonecrop.js +476 -0
  7. package/dist/doctype.js +10 -2
  8. package/dist/field-triggers.js +15 -3
  9. package/dist/index.js +4 -3
  10. package/dist/operation-log-DB-dGNT9.js +593 -0
  11. package/dist/operation-log-DB-dGNT9.js.map +1 -0
  12. package/dist/registry.js +261 -101
  13. package/dist/schema-validator.js +105 -1
  14. package/dist/src/composable.d.ts +11 -0
  15. package/dist/src/composable.d.ts.map +1 -0
  16. package/dist/src/composable.js +477 -0
  17. package/dist/src/composables/lazy-link.d.ts +25 -0
  18. package/dist/src/composables/lazy-link.d.ts.map +1 -0
  19. package/dist/src/composables/operation-log.d.ts +5 -5
  20. package/dist/src/composables/operation-log.d.ts.map +1 -1
  21. package/dist/src/composables/operation-log.js +224 -0
  22. package/dist/src/composables/stonecrop.d.ts +11 -1
  23. package/dist/src/composables/stonecrop.d.ts.map +1 -1
  24. package/dist/src/composables/stonecrop.js +574 -0
  25. package/dist/src/composables/use-lazy-link-state.d.ts +25 -0
  26. package/dist/src/composables/use-lazy-link-state.d.ts.map +1 -0
  27. package/dist/src/composables/use-stonecrop.d.ts +93 -0
  28. package/dist/src/composables/use-stonecrop.d.ts.map +1 -0
  29. package/dist/src/composables/useNestedSchema.d.ts +110 -0
  30. package/dist/src/composables/useNestedSchema.d.ts.map +1 -0
  31. package/dist/src/composables/useNestedSchema.js +155 -0
  32. package/dist/src/doctype.d.ts +9 -1
  33. package/dist/src/doctype.d.ts.map +1 -1
  34. package/dist/src/doctype.js +234 -0
  35. package/dist/src/exceptions.js +16 -0
  36. package/dist/src/field-triggers.d.ts +6 -0
  37. package/dist/src/field-triggers.d.ts.map +1 -1
  38. package/dist/src/field-triggers.js +567 -0
  39. package/dist/src/index.d.ts +3 -2
  40. package/dist/src/index.d.ts.map +1 -1
  41. package/dist/src/index.js +23 -0
  42. package/dist/src/plugins/index.js +96 -0
  43. package/dist/src/registry.d.ts +102 -23
  44. package/dist/src/registry.d.ts.map +1 -1
  45. package/dist/src/registry.js +246 -0
  46. package/dist/src/schema-validator.d.ts +8 -1
  47. package/dist/src/schema-validator.d.ts.map +1 -1
  48. package/dist/src/schema-validator.js +315 -0
  49. package/dist/src/stonecrop.d.ts +73 -28
  50. package/dist/src/stonecrop.d.ts.map +1 -1
  51. package/dist/src/stonecrop.js +339 -0
  52. package/dist/src/stores/data.d.ts +11 -0
  53. package/dist/src/stores/data.d.ts.map +1 -0
  54. package/dist/src/stores/hst.d.ts +5 -75
  55. package/dist/src/stores/hst.d.ts.map +1 -1
  56. package/dist/src/stores/hst.js +495 -0
  57. package/dist/src/stores/index.js +12 -0
  58. package/dist/src/stores/operation-log.d.ts +14 -14
  59. package/dist/src/stores/operation-log.d.ts.map +1 -1
  60. package/dist/src/stores/operation-log.js +568 -0
  61. package/dist/src/stores/xstate.d.ts +31 -0
  62. package/dist/src/stores/xstate.d.ts.map +1 -0
  63. package/dist/src/tsdoc-metadata.json +11 -0
  64. package/dist/src/types/composable.d.ts +50 -12
  65. package/dist/src/types/composable.d.ts.map +1 -1
  66. package/dist/src/types/doctype.d.ts +6 -7
  67. package/dist/src/types/doctype.d.ts.map +1 -1
  68. package/dist/src/types/field-triggers.d.ts +1 -1
  69. package/dist/src/types/field-triggers.d.ts.map +1 -1
  70. package/dist/src/types/field-triggers.js +4 -0
  71. package/dist/src/types/hst.d.ts +70 -0
  72. package/dist/src/types/hst.d.ts.map +1 -0
  73. package/dist/src/types/index.d.ts +1 -0
  74. package/dist/src/types/index.d.ts.map +1 -1
  75. package/dist/src/types/index.js +4 -0
  76. package/dist/src/types/operation-log.d.ts +4 -4
  77. package/dist/src/types/operation-log.d.ts.map +1 -1
  78. package/dist/src/types/operation-log.js +0 -0
  79. package/dist/src/types/registry.js +0 -0
  80. package/dist/src/types/schema-validator.d.ts +2 -0
  81. package/dist/src/types/schema-validator.d.ts.map +1 -1
  82. package/dist/src/utils.d.ts +24 -0
  83. package/dist/src/utils.d.ts.map +1 -0
  84. package/dist/stonecrop.d.ts +317 -99
  85. package/dist/stonecrop.js +2191 -1897
  86. package/dist/stonecrop.js.map +1 -1
  87. package/dist/stonecrop.umd.cjs +6 -0
  88. package/dist/stonecrop.umd.cjs.map +1 -0
  89. package/dist/stores/data.js +7 -0
  90. package/dist/stores/hst.js +27 -25
  91. package/dist/stores/operation-log.js +59 -47
  92. package/dist/stores/xstate.js +29 -0
  93. package/dist/tests/setup.d.ts +5 -0
  94. package/dist/tests/setup.d.ts.map +1 -0
  95. package/dist/tests/setup.js +15 -0
  96. package/dist/types/hst.js +0 -0
  97. package/dist/types/index.js +1 -0
  98. package/dist/utils.js +46 -0
  99. package/package.json +5 -5
  100. package/src/composables/lazy-link.ts +146 -0
  101. package/src/composables/operation-log.ts +1 -1
  102. package/src/composables/stonecrop.ts +142 -73
  103. package/src/doctype.ts +13 -4
  104. package/src/field-triggers.ts +18 -4
  105. package/src/index.ts +4 -2
  106. package/src/registry.ts +289 -111
  107. package/src/schema-validator.ts +120 -1
  108. package/src/stonecrop.ts +230 -106
  109. package/src/stores/hst.ts +29 -104
  110. package/src/stores/operation-log.ts +64 -50
  111. package/src/types/composable.ts +55 -12
  112. package/src/types/doctype.ts +6 -7
  113. package/src/types/field-triggers.ts +1 -1
  114. package/src/types/hst.ts +77 -0
  115. package/src/types/index.ts +1 -0
  116. package/src/types/operation-log.ts +4 -4
  117. package/src/types/schema-validator.ts +2 -0
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Schema Validation Utilities
3
+ * Validates Stonecrop schemas for integrity and consistency
4
+ * @packageDocumentation
5
+ */
6
+ import { getGlobalTriggerEngine } from './field-triggers';
7
+ /**
8
+ * Validation severity levels
9
+ * @public
10
+ */
11
+ export var ValidationSeverity;
12
+ (function (ValidationSeverity) {
13
+ /** Blocking error that prevents save */
14
+ ValidationSeverity["ERROR"] = "error";
15
+ /** Advisory warning that allows save */
16
+ ValidationSeverity["WARNING"] = "warning";
17
+ /** Informational message */
18
+ ValidationSeverity["INFO"] = "info";
19
+ })(ValidationSeverity || (ValidationSeverity = {}));
20
+ /**
21
+ * Schema validator class
22
+ * @public
23
+ */
24
+ export class SchemaValidator {
25
+ options;
26
+ /**
27
+ * Creates a new SchemaValidator instance
28
+ * @param options - Validator configuration options
29
+ */
30
+ constructor(options = {}) {
31
+ this.options = {
32
+ registry: options.registry || null,
33
+ validateLinkTargets: options.validateLinkTargets ?? true,
34
+ validateActions: options.validateActions ?? true,
35
+ validateWorkflows: options.validateWorkflows ?? true,
36
+ validateRequiredProperties: options.validateRequiredProperties ?? true,
37
+ };
38
+ }
39
+ /**
40
+ * Validates a complete doctype schema
41
+ * @param doctype - Doctype name
42
+ * @param schema - Schema fields (List or Array)
43
+ * @param workflow - Optional workflow configuration
44
+ * @param actions - Optional actions map
45
+ * @returns Validation result
46
+ */
47
+ validate(doctype, schema, workflow, actions) {
48
+ const issues = [];
49
+ // Convert schema to array for easier iteration
50
+ const schemaArray = schema ? (Array.isArray(schema) ? schema : schema.toArray()) : [];
51
+ // Validate required properties
52
+ if (this.options.validateRequiredProperties) {
53
+ issues.push(...this.validateRequiredProperties(doctype, schemaArray));
54
+ }
55
+ // Validate Link field targets
56
+ if (this.options.validateLinkTargets && this.options.registry) {
57
+ issues.push(...this.validateLinkFields(doctype, schemaArray, this.options.registry));
58
+ }
59
+ // Validate workflow configuration
60
+ if (this.options.validateWorkflows && workflow) {
61
+ issues.push(...this.validateWorkflow(doctype, workflow));
62
+ }
63
+ // Validate action registration
64
+ if (this.options.validateActions && actions) {
65
+ const actionsMap = actions instanceof Map ? actions : actions.toObject();
66
+ issues.push(...this.validateActionRegistration(doctype, actionsMap));
67
+ }
68
+ // Calculate counts
69
+ const errorCount = issues.filter(i => i.severity === ValidationSeverity.ERROR).length;
70
+ const warningCount = issues.filter(i => i.severity === ValidationSeverity.WARNING).length;
71
+ const infoCount = issues.filter(i => i.severity === ValidationSeverity.INFO).length;
72
+ return {
73
+ valid: errorCount === 0,
74
+ issues,
75
+ errorCount,
76
+ warningCount,
77
+ infoCount,
78
+ };
79
+ }
80
+ /**
81
+ * Validates that required schema properties are present
82
+ * @internal
83
+ */
84
+ validateRequiredProperties(doctype, schema) {
85
+ const issues = [];
86
+ for (const field of schema) {
87
+ // Check for fieldname
88
+ if (!field.fieldname) {
89
+ issues.push({
90
+ severity: ValidationSeverity.ERROR,
91
+ rule: 'required-fieldname',
92
+ message: 'Field is missing required property: fieldname',
93
+ doctype,
94
+ context: { field },
95
+ });
96
+ continue;
97
+ }
98
+ // Check for component or fieldtype
99
+ if (!field.component && !('fieldtype' in field)) {
100
+ issues.push({
101
+ severity: ValidationSeverity.ERROR,
102
+ rule: 'required-component-or-fieldtype',
103
+ message: `Field "${field.fieldname}" must have either component or fieldtype property`,
104
+ doctype,
105
+ fieldname: field.fieldname,
106
+ });
107
+ }
108
+ // Validate nested schemas (recursively)
109
+ if ('schema' in field) {
110
+ const nestedSchema = field.schema;
111
+ const nestedArray = (Array.isArray(nestedSchema) ? nestedSchema : nestedSchema.toArray?.() || []);
112
+ issues.push(...this.validateRequiredProperties(doctype, nestedArray));
113
+ }
114
+ }
115
+ return issues;
116
+ }
117
+ /**
118
+ * Validates Link field targets exist in registry
119
+ * @internal
120
+ */
121
+ validateLinkFields(doctype, schema, registry) {
122
+ const issues = [];
123
+ for (const field of schema) {
124
+ const fieldtype = 'fieldtype' in field ? field.fieldtype : undefined;
125
+ // Check Link fields
126
+ if (fieldtype === 'Link') {
127
+ const options = 'options' in field ? field.options : undefined;
128
+ if (!options) {
129
+ issues.push({
130
+ severity: ValidationSeverity.ERROR,
131
+ rule: 'link-missing-options',
132
+ message: `Link field "${field.fieldname}" is missing options property (target doctype)`,
133
+ doctype,
134
+ fieldname: field.fieldname,
135
+ });
136
+ continue;
137
+ }
138
+ // Check if target doctype exists in registry
139
+ // Options should be a string representing the target doctype name
140
+ const targetDoctype = typeof options === 'string' ? options : '';
141
+ if (!targetDoctype) {
142
+ issues.push({
143
+ severity: ValidationSeverity.ERROR,
144
+ rule: 'link-invalid-options',
145
+ message: `Link field "${field.fieldname}" has invalid options format (expected string doctype name)`,
146
+ doctype,
147
+ fieldname: field.fieldname,
148
+ });
149
+ continue;
150
+ }
151
+ const targetMeta = registry.registry[targetDoctype] || registry.registry[targetDoctype.toLowerCase()];
152
+ if (!targetMeta) {
153
+ issues.push({
154
+ severity: ValidationSeverity.ERROR,
155
+ rule: 'link-invalid-target',
156
+ message: `Link field "${field.fieldname}" references non-existent doctype: "${targetDoctype}"`,
157
+ doctype,
158
+ fieldname: field.fieldname,
159
+ context: { targetDoctype },
160
+ });
161
+ }
162
+ }
163
+ // Recursively check nested schemas
164
+ if ('schema' in field) {
165
+ const nestedSchema = field.schema;
166
+ const nestedArray = (Array.isArray(nestedSchema) ? nestedSchema : nestedSchema.toArray?.() || []);
167
+ issues.push(...this.validateLinkFields(doctype, nestedArray, registry));
168
+ }
169
+ }
170
+ return issues;
171
+ }
172
+ /**
173
+ * Validates workflow state machine configuration
174
+ * @internal
175
+ */
176
+ validateWorkflow(doctype, workflow) {
177
+ const issues = [];
178
+ // Check for initial state
179
+ if (!workflow.initial && !workflow.type) {
180
+ issues.push({
181
+ severity: ValidationSeverity.WARNING,
182
+ rule: 'workflow-missing-initial',
183
+ message: 'Workflow is missing initial state property',
184
+ doctype,
185
+ });
186
+ }
187
+ // Check for states
188
+ if (!workflow.states || Object.keys(workflow.states).length === 0) {
189
+ issues.push({
190
+ severity: ValidationSeverity.WARNING,
191
+ rule: 'workflow-no-states',
192
+ message: 'Workflow has no states defined',
193
+ doctype,
194
+ });
195
+ return issues;
196
+ }
197
+ // Validate initial state exists
198
+ if (workflow.initial && typeof workflow.initial === 'string' && !workflow.states[workflow.initial]) {
199
+ issues.push({
200
+ severity: ValidationSeverity.ERROR,
201
+ rule: 'workflow-invalid-initial',
202
+ message: `Workflow initial state "${workflow.initial}" does not exist in states`,
203
+ doctype,
204
+ context: { initialState: workflow.initial },
205
+ });
206
+ }
207
+ // Check state reachability (simple check - all states should have at least one incoming transition or be initial)
208
+ const stateNames = Object.keys(workflow.states);
209
+ const reachableStates = new Set();
210
+ // Initial state is always reachable
211
+ if (workflow.initial && typeof workflow.initial === 'string') {
212
+ reachableStates.add(workflow.initial);
213
+ }
214
+ // Find all target states from transitions
215
+ for (const [_stateName, stateConfig] of Object.entries(workflow.states)) {
216
+ const state = stateConfig;
217
+ if (state.on) {
218
+ for (const [_event, transition] of Object.entries(state.on)) {
219
+ if (typeof transition === 'string') {
220
+ reachableStates.add(transition);
221
+ }
222
+ else if (transition && typeof transition === 'object') {
223
+ const target = 'target' in transition ? transition.target : undefined;
224
+ if (typeof target === 'string') {
225
+ reachableStates.add(target);
226
+ }
227
+ else if (Array.isArray(target)) {
228
+ target.forEach((t) => {
229
+ if (typeof t === 'string') {
230
+ reachableStates.add(t);
231
+ }
232
+ });
233
+ }
234
+ }
235
+ }
236
+ }
237
+ }
238
+ // Check for unreachable states
239
+ for (const stateName of stateNames) {
240
+ if (!reachableStates.has(stateName)) {
241
+ issues.push({
242
+ severity: ValidationSeverity.WARNING,
243
+ rule: 'workflow-unreachable-state',
244
+ message: `Workflow state "${stateName}" may not be reachable`,
245
+ doctype,
246
+ context: { stateName },
247
+ });
248
+ }
249
+ }
250
+ return issues;
251
+ }
252
+ /**
253
+ * Validates that actions are registered in the FieldTriggerEngine
254
+ * @internal
255
+ */
256
+ validateActionRegistration(doctype, actions) {
257
+ const issues = [];
258
+ const triggerEngine = getGlobalTriggerEngine();
259
+ for (const [triggerName, actionNames] of Object.entries(actions)) {
260
+ if (!Array.isArray(actionNames)) {
261
+ issues.push({
262
+ severity: ValidationSeverity.ERROR,
263
+ rule: 'action-invalid-format',
264
+ message: `Action configuration for "${triggerName}" must be an array`,
265
+ doctype,
266
+ context: { triggerName, actionNames },
267
+ });
268
+ continue;
269
+ }
270
+ // Check each action name
271
+ for (const actionName of actionNames) {
272
+ // Check if action is registered globally
273
+ const engine = triggerEngine;
274
+ const isRegistered = engine.globalActions?.has(actionName) || engine.globalTransitionActions?.has(actionName);
275
+ if (!isRegistered) {
276
+ issues.push({
277
+ severity: ValidationSeverity.WARNING,
278
+ rule: 'action-not-registered',
279
+ message: `Action "${actionName}" referenced in "${triggerName}" is not registered in FieldTriggerEngine`,
280
+ doctype,
281
+ context: { triggerName, actionName },
282
+ });
283
+ }
284
+ }
285
+ }
286
+ return issues;
287
+ }
288
+ }
289
+ /**
290
+ * Creates a validator with the given registry
291
+ * @param registry - Registry instance
292
+ * @param options - Additional validator options
293
+ * @returns SchemaValidator instance
294
+ * @public
295
+ */
296
+ export function createValidator(registry, options) {
297
+ return new SchemaValidator({
298
+ registry,
299
+ ...options,
300
+ });
301
+ }
302
+ /**
303
+ * Quick validation helper
304
+ * @param doctype - Doctype name
305
+ * @param schema - Schema fields
306
+ * @param registry - Registry instance
307
+ * @param workflow - Optional workflow configuration
308
+ * @param actions - Optional actions map
309
+ * @returns Validation result
310
+ * @public
311
+ */
312
+ export function validateSchema(doctype, schema, registry, workflow, actions) {
313
+ const validator = createValidator(registry);
314
+ return validator.validate(doctype, schema, workflow, actions);
315
+ }
@@ -1,4 +1,3 @@
1
- import { type SchemaTypes } from '@stonecrop/aform';
2
1
  import type { DataClient } from '@stonecrop/schema';
3
2
  import Doctype from './doctype';
4
3
  import Registry from './registry';
@@ -18,6 +17,7 @@ export declare class Stonecrop {
18
17
  * @internal
19
18
  */
20
19
  static _root: Stonecrop;
20
+ /** The HST store instance for reactive state management */
21
21
  private hstStore;
22
22
  private _operationLogStore?;
23
23
  private _operationLogConfig?;
@@ -77,8 +77,8 @@ export declare class Stonecrop {
77
77
  actionError?: string | undefined;
78
78
  userId?: string | undefined;
79
79
  metadata?: Record<string, any> | undefined;
80
- parentOperationId?: string | undefined;
81
- childOperationIds?: string[] | undefined;
80
+ ancestorOperationId?: string | undefined;
81
+ descendantOperationIds?: string[] | undefined;
82
82
  }[], import("./types").HSTOperation[] | {
83
83
  id: string;
84
84
  type: import("./types").HSTOperationType;
@@ -101,8 +101,8 @@ export declare class Stonecrop {
101
101
  actionError?: string | undefined;
102
102
  userId?: string | undefined;
103
103
  metadata?: Record<string, any> | undefined;
104
- parentOperationId?: string | undefined;
105
- childOperationIds?: string[] | undefined;
104
+ ancestorOperationId?: string | undefined;
105
+ descendantOperationIds?: string[] | undefined;
106
106
  }[]>;
107
107
  currentIndex: import("vue").Ref<number, number>;
108
108
  config: import("vue").Ref<{
@@ -140,7 +140,7 @@ export declare class Stonecrop {
140
140
  getSnapshot: () => import("./types").OperationLogSnapshot;
141
141
  markIrreversible: (operationId: string, reason: string) => void;
142
142
  logAction: (doctype: string, actionName: string, recordIds?: string[], result?: "success" | "failure" | "pending", error?: string) => string;
143
- }, "operations" | "clientId" | "currentIndex" | "config">, Pick<{
143
+ }, "operations" | "currentIndex" | "config" | "clientId">, Pick<{
144
144
  operations: import("vue").Ref<{
145
145
  id: string;
146
146
  type: import("./types").HSTOperationType;
@@ -163,8 +163,8 @@ export declare class Stonecrop {
163
163
  actionError?: string | undefined;
164
164
  userId?: string | undefined;
165
165
  metadata?: Record<string, any> | undefined;
166
- parentOperationId?: string | undefined;
167
- childOperationIds?: string[] | undefined;
166
+ ancestorOperationId?: string | undefined;
167
+ descendantOperationIds?: string[] | undefined;
168
168
  }[], import("./types").HSTOperation[] | {
169
169
  id: string;
170
170
  type: import("./types").HSTOperationType;
@@ -187,8 +187,8 @@ export declare class Stonecrop {
187
187
  actionError?: string | undefined;
188
188
  userId?: string | undefined;
189
189
  metadata?: Record<string, any> | undefined;
190
- parentOperationId?: string | undefined;
191
- childOperationIds?: string[] | undefined;
190
+ ancestorOperationId?: string | undefined;
191
+ descendantOperationIds?: string[] | undefined;
192
192
  }[]>;
193
193
  currentIndex: import("vue").Ref<number, number>;
194
194
  config: import("vue").Ref<{
@@ -249,8 +249,8 @@ export declare class Stonecrop {
249
249
  actionError?: string | undefined;
250
250
  userId?: string | undefined;
251
251
  metadata?: Record<string, any> | undefined;
252
- parentOperationId?: string | undefined;
253
- childOperationIds?: string[] | undefined;
252
+ ancestorOperationId?: string | undefined;
253
+ descendantOperationIds?: string[] | undefined;
254
254
  }[], import("./types").HSTOperation[] | {
255
255
  id: string;
256
256
  type: import("./types").HSTOperationType;
@@ -273,8 +273,8 @@ export declare class Stonecrop {
273
273
  actionError?: string | undefined;
274
274
  userId?: string | undefined;
275
275
  metadata?: Record<string, any> | undefined;
276
- parentOperationId?: string | undefined;
277
- childOperationIds?: string[] | undefined;
276
+ ancestorOperationId?: string | undefined;
277
+ descendantOperationIds?: string[] | undefined;
278
278
  }[]>;
279
279
  currentIndex: import("vue").Ref<number, number>;
280
280
  config: import("vue").Ref<{
@@ -370,7 +370,25 @@ export declare class Stonecrop {
370
370
  * @param action - The action to run
371
371
  * @param args - Action arguments (typically record IDs)
372
372
  */
373
- runAction(doctype: Doctype, action: string, args?: any[]): void;
373
+ runAction(doctype: Doctype, action: string, args?: string[]): void;
374
+ /**
375
+ * Get the effective blockWorkflows value for a link.
376
+ * Returns true if blockWorkflows is explicitly true, or if it's absent and fetch method is 'sync'.
377
+ * @param link - The link declaration
378
+ * @returns Whether workflows should be blocked until this link is loaded
379
+ */
380
+ private getEffectiveBlockWorkflows;
381
+ /**
382
+ * Check if workflow actions are ready to run (all required link data is loaded).
383
+ * A link's data is considered loaded if it exists in HST at `slug.recordId.linkname`.
384
+ * @param doctype - The doctype to check
385
+ * @param recordId - The record ID
386
+ * @returns Object with `ready: true` if all blocked links are loaded, or `ready: false` with `blockedLinks` array
387
+ */
388
+ isWorkflowReady(doctype: Doctype, recordId: string): {
389
+ ready: boolean;
390
+ blockedLinks?: string[];
391
+ };
374
392
  /**
375
393
  * Get records from server using the configured data client.
376
394
  * @param doctype - The doctype
@@ -438,23 +456,50 @@ export declare class Stonecrop {
438
456
  */
439
457
  collectRecordPayload(doctype: Doctype, recordId: string): Record<string, any>;
440
458
  /**
441
- * Load nested data from HST or initialize with defaults
442
- * @param parentPath - The HST path to check for existing data
443
- * @param childDoctype - The child doctype metadata
444
- * @param _recordId - Optional record ID to load
445
- * @returns The loaded or initialized data
459
+ * Scaffold empty descendant records from defaults for all descendant links.
460
+ *
461
+ * Initializes all scalar and link fields at their HST paths with default values.
462
+ * For new records, call this after setting up the doctype to ensure all paths exist.
463
+ *
464
+ * @param path - HST path (e.g., "customer.new")
465
+ * @param doctype - The doctype to initialize
466
+ * @public
467
+ */
468
+ initializeNestedData(path: string, doctype: Doctype): void;
469
+ /**
470
+ * Fetch a record and its nested data from the server.
471
+ *
472
+ * Calls `_client.getRecord()` with nested sub-selections and stores each scalar field at its own HST path
473
+ * (`slug.recordId.fieldname`), descendants at the link-level path (`slug.recordId.linkname`).
474
+ *
475
+ * @param path - HST path (e.g., "recipe.r1")
476
+ * @param doctype - The doctype to fetch
477
+ * @param recordId - Record ID to fetch
478
+ * @param options - Query options (includeNested to control which links are fetched)
479
+ * @throws Error with code `"CLIENT_REQUIRED"` if no data client is configured
480
+ * @throws Error with code `"RECORD_NOT_FOUND"` if the server returns null
446
481
  * @public
447
482
  */
448
- loadNestedData(parentPath: string, childDoctype: Doctype, _recordId?: string): Record<string, any>;
483
+ fetchNestedData(path: string, doctype: Doctype, recordId: string, options?: {
484
+ includeNested?: boolean | string[];
485
+ }): Promise<void>;
486
+ /**
487
+ * Recursively collect nested data from HST
488
+ * @param basePath - The base path in HST (e.g., "customer.123.address")
489
+ * @param doctype - The doctype whose links drive the recursive traversal
490
+ * @returns The collected data object
491
+ */
492
+ private collectNestedData;
449
493
  }
450
494
  /**
451
- * Recursively collect nested data from HST using pre-resolved schemas
452
- * @param resolvedSchema - The already-resolved schema (with nested schemas embedded)
453
- * @param basePath - The base path in HST (e.g., "customer.123.address")
454
- * @param hstStore - The HST store instance
455
- * @returns The collected data object
495
+ * Returns the global Stonecrop singleton instance, or `undefined` if no
496
+ * instance has been created yet.
497
+ *
498
+ * Use this when you need the Stonecrop instance outside a Vue component
499
+ * context (e.g., in workflow action handlers, plugin setup code, or
500
+ * non-component utilities). Inside a component, prefer `useStonecrop()`.
501
+ *
456
502
  * @public
457
503
  */
458
- declare function collectNestedData(resolvedSchema: SchemaTypes[], basePath: string, hstStore: HSTNode): Record<string, any>;
459
- export { collectNestedData };
504
+ export declare function getStonecrop(): Stonecrop | undefined;
460
505
  //# sourceMappingURL=stonecrop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stonecrop.d.ts","sourceRoot":"","sources":["../../src/stonecrop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stonecrop.d.ts","sourceRoot":"","sources":["../../src/stonecrop.ts"],"names":[],"mappings":"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"}