@stonecrop/stonecrop 0.12.7 → 0.13.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 (55) hide show
  1. package/dist/composable.js +1 -0
  2. package/dist/composables/lazy-link.js +125 -0
  3. package/dist/composables/operation-log.js +224 -0
  4. package/dist/composables/stonecrop.js +504 -0
  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 +242 -0
  8. package/dist/exceptions.js +16 -0
  9. package/dist/field-triggers.js +575 -0
  10. package/dist/index.js +27 -0
  11. package/dist/operation-log-DB-dGNT9.js +593 -0
  12. package/dist/operation-log-DB-dGNT9.js.map +1 -0
  13. package/dist/plugins/index.js +99 -0
  14. package/dist/registry.js +423 -0
  15. package/dist/schema-validator.js +407 -0
  16. package/dist/src/composable.d.ts +11 -0
  17. package/dist/src/composable.d.ts.map +1 -0
  18. package/dist/src/composable.js +477 -0
  19. package/dist/src/composables/use-lazy-link-state.d.ts +25 -0
  20. package/dist/src/composables/use-lazy-link-state.d.ts.map +1 -0
  21. package/dist/src/composables/use-stonecrop.d.ts +93 -0
  22. package/dist/src/composables/use-stonecrop.d.ts.map +1 -0
  23. package/dist/src/composables/useNestedSchema.d.ts +110 -0
  24. package/dist/src/composables/useNestedSchema.d.ts.map +1 -0
  25. package/dist/src/composables/useNestedSchema.js +155 -0
  26. package/dist/src/stores/data.d.ts +11 -0
  27. package/dist/src/stores/data.d.ts.map +1 -0
  28. package/dist/src/stores/xstate.d.ts +31 -0
  29. package/dist/src/stores/xstate.d.ts.map +1 -0
  30. package/dist/src/tsdoc-metadata.json +11 -0
  31. package/dist/src/utils.d.ts +24 -0
  32. package/dist/src/utils.d.ts.map +1 -0
  33. package/dist/stonecrop.css +1 -0
  34. package/dist/stonecrop.umd.cjs +6 -0
  35. package/dist/stonecrop.umd.cjs.map +1 -0
  36. package/dist/stores/data.js +7 -0
  37. package/dist/stores/hst.js +496 -0
  38. package/dist/stores/index.js +12 -0
  39. package/dist/stores/operation-log.js +580 -0
  40. package/dist/stores/xstate.js +29 -0
  41. package/dist/tests/setup.d.ts +5 -0
  42. package/dist/tests/setup.d.ts.map +1 -0
  43. package/dist/tests/setup.js +15 -0
  44. package/dist/types/composable.js +0 -0
  45. package/dist/types/doctype.js +0 -0
  46. package/dist/types/field-triggers.js +4 -0
  47. package/dist/types/hst.js +0 -0
  48. package/dist/types/index.js +10 -0
  49. package/dist/types/operation-log.js +0 -0
  50. package/dist/types/plugin.js +0 -0
  51. package/dist/types/registry.js +0 -0
  52. package/dist/types/schema-validator.js +13 -0
  53. package/dist/types/stonecrop.js +0 -0
  54. package/dist/utils.js +46 -0
  55. package/package.json +4 -4
@@ -0,0 +1,575 @@
1
+ import { useOperationLogStore } from './stores/operation-log';
2
+ /**
3
+ * Field trigger execution engine integrated with Registry
4
+ * Singleton pattern following Registry implementation
5
+ * @public
6
+ */
7
+ export class FieldTriggerEngine {
8
+ /**
9
+ * The root FieldTriggerEngine instance
10
+ */
11
+ static _root;
12
+ options;
13
+ doctypeActions = new Map(); // doctype -> action/field -> functions
14
+ doctypeTransitions = new Map(); // doctype -> transition -> functions
15
+ fieldRollbackConfig = new Map(); // doctype -> field -> rollback enabled
16
+ globalActions = new Map(); // action name -> function
17
+ globalTransitionActions = new Map(); // transition action name -> function
18
+ /**
19
+ * Creates a new FieldTriggerEngine instance (singleton pattern)
20
+ * @param options - Configuration options for the field trigger engine
21
+ */
22
+ constructor(options = {}) {
23
+ if (FieldTriggerEngine._root) {
24
+ return FieldTriggerEngine._root;
25
+ }
26
+ FieldTriggerEngine._root = this;
27
+ this.options = {
28
+ defaultTimeout: options.defaultTimeout ?? 5000,
29
+ debug: options.debug ?? false,
30
+ enableRollback: options.enableRollback ?? true,
31
+ errorHandler: options.errorHandler,
32
+ };
33
+ }
34
+ /**
35
+ * Register a global action function
36
+ * @param name - The name of the action
37
+ * @param fn - The action function
38
+ */
39
+ registerAction(name, fn) {
40
+ this.globalActions.set(name, fn);
41
+ }
42
+ /**
43
+ * Look up a registered action function by name.
44
+ * Returns `undefined` if the action has not been registered.
45
+ * @param name - The action name
46
+ */
47
+ getAction(name) {
48
+ return this.globalActions.get(name);
49
+ }
50
+ /**
51
+ * Register a global XState transition action function
52
+ * @param name - The name of the transition action
53
+ * @param fn - The transition action function
54
+ */
55
+ registerTransitionAction(name, fn) {
56
+ this.globalTransitionActions.set(name, fn);
57
+ }
58
+ /**
59
+ * Configure rollback behavior for a specific field trigger
60
+ * @param doctype - The doctype name
61
+ * @param fieldname - The field name
62
+ * @param enableRollback - Whether to enable rollback
63
+ */
64
+ setFieldRollback(doctype, fieldname, enableRollback) {
65
+ if (!this.fieldRollbackConfig.has(doctype)) {
66
+ this.fieldRollbackConfig.set(doctype, new Map());
67
+ }
68
+ this.fieldRollbackConfig.get(doctype).set(fieldname, enableRollback);
69
+ }
70
+ /**
71
+ * Get rollback configuration for a specific field trigger
72
+ */
73
+ getFieldRollback(doctype, fieldname) {
74
+ return this.fieldRollbackConfig.get(doctype)?.get(fieldname);
75
+ }
76
+ /**
77
+ * Register actions from a doctype - both regular actions and field triggers
78
+ * Separates XState transitions (uppercase) from field triggers (lowercase)
79
+ * @param doctype - The doctype name
80
+ * @param actions - The actions to register (supports Immutable Map, Map, or plain object)
81
+ */
82
+ registerDoctypeActions(doctype, actions) {
83
+ if (!actions)
84
+ return;
85
+ const actionMap = new Map();
86
+ const transitionMap = new Map();
87
+ // Convert from different Map types to regular Map
88
+ // Check for Immutable.js Map first (has entrySeq method)
89
+ const immutableActions = actions;
90
+ if (typeof immutableActions.entrySeq === 'function') {
91
+ // Immutable Map
92
+ immutableActions.entrySeq().forEach(([key, value]) => {
93
+ this.categorizeAction(key, value, actionMap, transitionMap);
94
+ });
95
+ }
96
+ else if (actions instanceof Map) {
97
+ // Regular Map
98
+ for (const [key, value] of actions) {
99
+ this.categorizeAction(key, value, actionMap, transitionMap);
100
+ }
101
+ }
102
+ else if (actions && typeof actions === 'object') {
103
+ // Plain object
104
+ Object.entries(actions).forEach(([key, value]) => {
105
+ this.categorizeAction(key, value, actionMap, transitionMap);
106
+ });
107
+ }
108
+ // Always set the maps, even if empty
109
+ this.doctypeActions.set(doctype, actionMap);
110
+ this.doctypeTransitions.set(doctype, transitionMap);
111
+ }
112
+ /**
113
+ * Categorize an action as either a field trigger or XState transition
114
+ * Uses uppercase convention: UPPERCASE = transition, lowercase/mixed = field trigger
115
+ */
116
+ categorizeAction(key, value, actionMap, transitionMap) {
117
+ // Check if the key is all uppercase (XState transition convention)
118
+ if (this.isTransitionKey(key)) {
119
+ transitionMap.set(key, value);
120
+ }
121
+ else {
122
+ actionMap.set(key, value);
123
+ }
124
+ }
125
+ /**
126
+ * Determine if a key represents an XState transition
127
+ * Transitions are identified by being all uppercase
128
+ */
129
+ isTransitionKey(key) {
130
+ // Must be all uppercase letters/numbers/underscores
131
+ return /^[A-Z0-9_]+$/.test(key) && key.length > 0;
132
+ }
133
+ /**
134
+ * Execute field triggers for a changed field
135
+ * @param context - The field change context
136
+ * @param options - Execution options (timeout and enableRollback)
137
+ */
138
+ async executeFieldTriggers(context, options = {}) {
139
+ const { doctype, fieldname } = context;
140
+ const triggers = this.findFieldTriggers(doctype, fieldname);
141
+ if (triggers.length === 0) {
142
+ return {
143
+ path: context.path,
144
+ actionResults: [],
145
+ totalExecutionTime: 0,
146
+ allSucceeded: true,
147
+ stoppedOnError: false,
148
+ rolledBack: false,
149
+ };
150
+ }
151
+ const startTime = performance.now();
152
+ const actionResults = [];
153
+ let stoppedOnError = false;
154
+ let rolledBack = false;
155
+ let snapshot = undefined;
156
+ // Determine if rollback is enabled (priority: execution option > field config > global setting)
157
+ const fieldRollbackConfig = this.getFieldRollback(doctype, fieldname);
158
+ const rollbackEnabled = options.enableRollback ?? fieldRollbackConfig ?? this.options.enableRollback;
159
+ // Capture snapshot before executing actions if rollback is enabled
160
+ if (rollbackEnabled && context.store) {
161
+ snapshot = this.captureSnapshot(context);
162
+ }
163
+ // Execute actions sequentially
164
+ for (const actionName of triggers) {
165
+ try {
166
+ const actionResult = await this.executeAction(actionName, context, options.timeout);
167
+ actionResults.push(actionResult);
168
+ if (!actionResult.success) {
169
+ stoppedOnError = true;
170
+ break;
171
+ }
172
+ }
173
+ catch (error) {
174
+ const actionError = error instanceof Error ? error : new Error(String(error));
175
+ const errorResult = {
176
+ success: false,
177
+ error: actionError,
178
+ executionTime: 0,
179
+ action: actionName,
180
+ };
181
+ actionResults.push(errorResult);
182
+ stoppedOnError = true;
183
+ break;
184
+ }
185
+ }
186
+ // Perform rollback if enabled, errors occurred, and we have a snapshot
187
+ if (rollbackEnabled && stoppedOnError && snapshot && context.store) {
188
+ try {
189
+ this.restoreSnapshot(context, snapshot);
190
+ rolledBack = true;
191
+ }
192
+ catch (rollbackError) {
193
+ // eslint-disable-next-line no-console
194
+ console.error('[FieldTriggers] Rollback failed:', rollbackError);
195
+ }
196
+ }
197
+ const totalExecutionTime = performance.now() - startTime;
198
+ // Call global error handler if configured and errors occurred
199
+ const failedResults = actionResults.filter(r => !r.success && r.error != null);
200
+ if (failedResults.length > 0 && this.options.errorHandler) {
201
+ for (const failedResult of failedResults) {
202
+ try {
203
+ if (failedResult.error) {
204
+ this.options.errorHandler(failedResult.error, context, failedResult.action);
205
+ }
206
+ }
207
+ catch (handlerError) {
208
+ // eslint-disable-next-line no-console
209
+ console.error('[FieldTriggers] Error in global error handler:', handlerError);
210
+ }
211
+ }
212
+ }
213
+ const result = {
214
+ path: context.path,
215
+ actionResults,
216
+ totalExecutionTime,
217
+ allSucceeded: actionResults.every(r => r.success),
218
+ stoppedOnError,
219
+ rolledBack,
220
+ snapshot: this.options.debug && rollbackEnabled ? snapshot : undefined, // Only include snapshot in debug mode if rollback is enabled
221
+ };
222
+ return result;
223
+ }
224
+ /**
225
+ * Execute XState transition actions
226
+ * Similar to field triggers but specifically for FSM state transitions
227
+ * @param context - The transition change context
228
+ * @param options - Execution options (timeout)
229
+ */
230
+ async executeTransitionActions(context, options = {}) {
231
+ const { doctype, transition } = context;
232
+ const transitionActions = this.findTransitionActions(doctype, transition);
233
+ if (transitionActions.length === 0) {
234
+ return [];
235
+ }
236
+ const results = [];
237
+ // Execute transition actions sequentially
238
+ for (const actionName of transitionActions) {
239
+ try {
240
+ const actionResult = await this.executeTransitionAction(actionName, context, options.timeout);
241
+ results.push(actionResult);
242
+ if (!actionResult.success) {
243
+ // Stop on first error for transitions
244
+ break;
245
+ }
246
+ }
247
+ catch (error) {
248
+ const actionError = error instanceof Error ? error : new Error(String(error));
249
+ const errorResult = {
250
+ success: false,
251
+ error: actionError,
252
+ executionTime: 0,
253
+ action: actionName,
254
+ transition,
255
+ };
256
+ results.push(errorResult);
257
+ break;
258
+ }
259
+ }
260
+ // Call global error handler if configured and errors occurred
261
+ const failedResults = results.filter(r => !r.success);
262
+ if (failedResults.length > 0 && this.options.errorHandler) {
263
+ for (const failedResult of failedResults) {
264
+ try {
265
+ // Call with FieldChangeContext (base context type)
266
+ if (failedResult.error) {
267
+ this.options.errorHandler(failedResult.error, context, failedResult.action);
268
+ }
269
+ }
270
+ catch (handlerError) {
271
+ // eslint-disable-next-line no-console
272
+ console.error('[FieldTriggers] Error in global error handler:', handlerError);
273
+ }
274
+ }
275
+ }
276
+ return results;
277
+ }
278
+ /**
279
+ * Find transition actions for a specific doctype and transition
280
+ */
281
+ findTransitionActions(doctype, transition) {
282
+ const doctypeTransitions = this.doctypeTransitions.get(doctype);
283
+ if (!doctypeTransitions)
284
+ return [];
285
+ return doctypeTransitions.get(transition) || [];
286
+ }
287
+ /**
288
+ * Execute a single transition action by name
289
+ */
290
+ async executeTransitionAction(actionName, context, timeout) {
291
+ const startTime = performance.now();
292
+ const actionTimeout = timeout ?? this.options.defaultTimeout;
293
+ try {
294
+ // Look up action in transition-specific registry first, then fall back to global
295
+ let actionFn = this.globalTransitionActions.get(actionName);
296
+ // If not found in transition registry, try regular action registry
297
+ // This allows sharing actions between field triggers and transitions
298
+ if (!actionFn) {
299
+ const regularActionFn = this.globalActions.get(actionName);
300
+ if (regularActionFn) {
301
+ // Wrap regular action to accept TransitionChangeContext
302
+ actionFn = regularActionFn;
303
+ }
304
+ }
305
+ if (!actionFn) {
306
+ throw new Error(`Transition action "${actionName}" not found in registry`);
307
+ }
308
+ await this.executeWithTimeout(actionFn, context, actionTimeout);
309
+ const executionTime = performance.now() - startTime;
310
+ return {
311
+ success: true,
312
+ executionTime,
313
+ action: actionName,
314
+ transition: context.transition,
315
+ };
316
+ }
317
+ catch (error) {
318
+ const executionTime = performance.now() - startTime;
319
+ const actionError = error instanceof Error ? error : new Error(String(error));
320
+ return {
321
+ success: false,
322
+ error: actionError,
323
+ executionTime,
324
+ action: actionName,
325
+ transition: context.transition,
326
+ };
327
+ }
328
+ }
329
+ /**
330
+ * Find field triggers for a specific doctype and field
331
+ * Field triggers are identified by keys that look like field paths (contain dots or match field names)
332
+ */
333
+ findFieldTriggers(doctype, fieldname) {
334
+ const doctypeActions = this.doctypeActions.get(doctype);
335
+ if (!doctypeActions)
336
+ return [];
337
+ const triggers = [];
338
+ for (const [key, actionNames] of doctypeActions) {
339
+ // Check if this key is a field trigger pattern
340
+ if (this.isFieldTriggerKey(key, fieldname)) {
341
+ triggers.push(...actionNames);
342
+ }
343
+ }
344
+ return triggers;
345
+ }
346
+ /**
347
+ * Determine if an action key represents a field trigger
348
+ * Field triggers can be:
349
+ * - Exact field name match: "emailAddress"
350
+ * - Wildcard patterns: "emailAddress.*", "*.is_primary"
351
+ * - Nested field paths: "address.street", "contact.email"
352
+ */
353
+ isFieldTriggerKey(key, fieldname) {
354
+ // Exact match
355
+ if (key === fieldname)
356
+ return true;
357
+ // Contains dots - likely a field path pattern
358
+ if (key.includes('.')) {
359
+ return this.matchFieldPattern(key, fieldname);
360
+ }
361
+ // Contains wildcards
362
+ if (key.includes('*')) {
363
+ return this.matchFieldPattern(key, fieldname);
364
+ }
365
+ return false;
366
+ }
367
+ /**
368
+ * Match a field pattern against a field name
369
+ * Supports wildcards (*) for dynamic segments
370
+ */
371
+ matchFieldPattern(pattern, fieldname) {
372
+ const patternParts = pattern.split('.');
373
+ const fieldParts = fieldname.split('.');
374
+ if (patternParts.length !== fieldParts.length) {
375
+ return false;
376
+ }
377
+ for (let i = 0; i < patternParts.length; i++) {
378
+ const patternPart = patternParts[i];
379
+ const fieldPart = fieldParts[i];
380
+ if (patternPart === '*') {
381
+ // Wildcard matches any segment
382
+ continue;
383
+ }
384
+ else if (patternPart !== fieldPart) {
385
+ // Exact match required
386
+ return false;
387
+ }
388
+ }
389
+ return true;
390
+ }
391
+ /**
392
+ * Execute a single action by name
393
+ */
394
+ async executeAction(actionName, context, timeout) {
395
+ const startTime = performance.now();
396
+ const actionTimeout = timeout ?? this.options.defaultTimeout;
397
+ try {
398
+ // Look up action in global registry
399
+ const actionFn = this.globalActions.get(actionName);
400
+ if (!actionFn) {
401
+ throw new Error(`Action "${actionName}" not found in registry`);
402
+ }
403
+ await this.executeWithTimeout(actionFn, context, actionTimeout);
404
+ const executionTime = performance.now() - startTime;
405
+ return {
406
+ success: true,
407
+ executionTime,
408
+ action: actionName,
409
+ };
410
+ }
411
+ catch (error) {
412
+ const executionTime = performance.now() - startTime;
413
+ const actionError = error instanceof Error ? error : new Error(String(error));
414
+ return {
415
+ success: false,
416
+ error: actionError,
417
+ executionTime,
418
+ action: actionName,
419
+ };
420
+ }
421
+ }
422
+ /**
423
+ * Execute a function with timeout
424
+ */
425
+ async executeWithTimeout(fn, context, timeout) {
426
+ return new Promise((resolve, reject) => {
427
+ const timeoutId = setTimeout(() => {
428
+ reject(new Error(`Action timeout after ${timeout}ms`));
429
+ }, timeout);
430
+ Promise.resolve(fn(context))
431
+ .then(result => {
432
+ clearTimeout(timeoutId);
433
+ resolve(result);
434
+ })
435
+ .catch(error => {
436
+ clearTimeout(timeoutId);
437
+ reject(error instanceof Error ? error : new Error(String(error)));
438
+ });
439
+ });
440
+ }
441
+ /**
442
+ * Capture a snapshot of the record state before executing actions
443
+ * This creates a deep copy of the record data for potential rollback
444
+ */
445
+ captureSnapshot(context) {
446
+ if (!context.store || !context.doctype || !context.recordId) {
447
+ return undefined;
448
+ }
449
+ try {
450
+ // Get the record path (doctype.recordId)
451
+ const recordPath = `${context.doctype}.${context.recordId}`;
452
+ // Get the current record data
453
+ const recordData = context.store.get(recordPath);
454
+ if (!recordData || typeof recordData !== 'object') {
455
+ return undefined;
456
+ }
457
+ // Create a deep copy to avoid reference issues
458
+ return JSON.parse(JSON.stringify(recordData));
459
+ }
460
+ catch (error) {
461
+ if (this.options.debug) {
462
+ // eslint-disable-next-line no-console
463
+ console.warn('[FieldTriggers] Failed to capture snapshot:', error);
464
+ }
465
+ return undefined;
466
+ }
467
+ }
468
+ /**
469
+ * Restore a previously captured snapshot
470
+ * This reverts the record to its state before actions were executed
471
+ */
472
+ restoreSnapshot(context, snapshot) {
473
+ if (!context.store || !context.doctype || !context.recordId || !snapshot) {
474
+ return;
475
+ }
476
+ try {
477
+ // Get the record path (doctype.recordId)
478
+ const recordPath = `${context.doctype}.${context.recordId}`;
479
+ // Restore the entire record from snapshot
480
+ context.store.set(recordPath, snapshot);
481
+ if (this.options.debug) {
482
+ // eslint-disable-next-line no-console
483
+ console.log(`[FieldTriggers] Rolled back ${recordPath} to previous state`);
484
+ }
485
+ }
486
+ catch (error) {
487
+ // eslint-disable-next-line no-console
488
+ console.error('[FieldTriggers] Failed to restore snapshot:', error);
489
+ throw error;
490
+ }
491
+ }
492
+ }
493
+ /**
494
+ * Get or create the global field trigger engine singleton
495
+ * @param options - Optional configuration for the field trigger engine
496
+ * @public
497
+ */
498
+ export function getGlobalTriggerEngine(options) {
499
+ return new FieldTriggerEngine(options);
500
+ }
501
+ /**
502
+ * Register a global action function that can be used in field triggers
503
+ * @param name - The name of the action to register
504
+ * @param fn - The action function to execute when the trigger fires
505
+ * @public
506
+ */
507
+ export function registerGlobalAction(name, fn) {
508
+ const engine = getGlobalTriggerEngine();
509
+ engine.registerAction(name, fn);
510
+ }
511
+ /**
512
+ * Register a global XState transition action function
513
+ * @param name - The name of the transition action to register
514
+ * @param fn - The transition action function to execute
515
+ * @public
516
+ */
517
+ export function registerTransitionAction(name, fn) {
518
+ const engine = getGlobalTriggerEngine();
519
+ engine.registerTransitionAction(name, fn);
520
+ }
521
+ /**
522
+ * Configure rollback behavior for a specific field trigger
523
+ * @param doctype - The doctype name
524
+ * @param fieldname - The field name
525
+ * @param enableRollback - Whether to enable automatic rollback for this field
526
+ * @public
527
+ */
528
+ export function setFieldRollback(doctype, fieldname, enableRollback) {
529
+ const engine = getGlobalTriggerEngine();
530
+ engine.setFieldRollback(doctype, fieldname, enableRollback);
531
+ }
532
+ /**
533
+ * Manually trigger an XState transition for a specific doctype/record
534
+ * This can be called directly when you need to execute transition actions programmatically
535
+ * @param doctype - The doctype name
536
+ * @param transition - The XState transition name to trigger
537
+ * @param options - Optional configuration for the transition
538
+ * @public
539
+ */
540
+ export async function triggerTransition(doctype, transition, options) {
541
+ const engine = getGlobalTriggerEngine();
542
+ const context = {
543
+ path: options?.path || (options?.recordId ? `${doctype}.${options.recordId}` : doctype),
544
+ fieldname: '',
545
+ beforeValue: undefined,
546
+ afterValue: undefined,
547
+ operation: 'set',
548
+ doctype,
549
+ recordId: options?.recordId,
550
+ timestamp: new Date(),
551
+ transition,
552
+ currentState: options?.currentState,
553
+ targetState: options?.targetState,
554
+ fsmContext: options?.fsmContext,
555
+ };
556
+ return await engine.executeTransitionActions(context);
557
+ }
558
+ /**
559
+ * Mark a specific operation as irreversible.
560
+ * Used to prevent undo of critical operations like publishing or deletion.
561
+ * @param operationId - The ID of the operation to mark as irreversible
562
+ * @param reason - Human-readable reason why the operation cannot be undone
563
+ * @public
564
+ */
565
+ export function markOperationIrreversible(operationId, reason) {
566
+ if (!operationId)
567
+ return;
568
+ try {
569
+ const store = useOperationLogStore();
570
+ store.markIrreversible(operationId, reason);
571
+ }
572
+ catch {
573
+ // Operation log is optional
574
+ }
575
+ }
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ import { useLazyLink } from './composables/lazy-link';
2
+ import { useStonecrop } from './composables/stonecrop';
3
+ import { useOperationLog, useUndoRedoShortcuts, withBatch } from './composables/operation-log';
4
+ import Doctype from './doctype';
5
+ import { FieldTriggerEngine, getGlobalTriggerEngine, markOperationIrreversible, registerGlobalAction, registerTransitionAction, setFieldRollback, triggerTransition, } from './field-triggers';
6
+ import plugin from './plugins';
7
+ import Registry from './registry';
8
+ import { Stonecrop, getStonecrop } from './stonecrop';
9
+ import { HST, createHST } from './stores/hst';
10
+ import { useOperationLogStore } from './stores/operation-log';
11
+ import { SchemaValidator, createValidator, validateSchema } from './schema-validator';
12
+ import { ValidationSeverity } from './types/schema-validator';
13
+ // Export enum as value (enums need runtime export, not just type)
14
+ export { ValidationSeverity };
15
+ export { Doctype, Registry, Stonecrop, useLazyLink, useStonecrop,
16
+ // HST exports for advanced usage
17
+ HST, createHST,
18
+ // Field trigger system exports
19
+ FieldTriggerEngine, getGlobalTriggerEngine, registerGlobalAction, registerTransitionAction, setFieldRollback, triggerTransition, markOperationIrreversible,
20
+ // Schema validator exports
21
+ SchemaValidator, createValidator, validateSchema,
22
+ // Operation log exports
23
+ useOperationLog, useOperationLogStore, useUndoRedoShortcuts, withBatch,
24
+ // Utility functions
25
+ getStonecrop, };
26
+ // Default export is the Vue plugin
27
+ export default plugin;