@stonecrop/stonecrop 0.10.11 → 0.10.13

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 (58) hide show
  1. package/dist/composables/stonecrop.js +26 -110
  2. package/dist/field-triggers.js +5 -6
  3. package/dist/index.js +9 -6
  4. package/dist/plugins/index.js +4 -1
  5. package/dist/registry.js +62 -61
  6. package/dist/schema-validator.js +1 -13
  7. package/dist/src/composables/stonecrop.d.ts +2 -74
  8. package/dist/src/composables/stonecrop.d.ts.map +1 -1
  9. package/dist/src/doctype.d.ts +1 -27
  10. package/dist/src/doctype.d.ts.map +1 -1
  11. package/dist/src/field-triggers.d.ts.map +1 -1
  12. package/dist/src/index.d.ts +6 -9
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/plugins/index.d.ts.map +1 -1
  15. package/dist/src/registry.d.ts +13 -10
  16. package/dist/src/registry.d.ts.map +1 -1
  17. package/dist/src/schema-validator.d.ts +1 -62
  18. package/dist/src/schema-validator.d.ts.map +1 -1
  19. package/dist/src/stonecrop.d.ts +38 -17
  20. package/dist/src/stonecrop.d.ts.map +1 -1
  21. package/dist/src/stores/operation-log.d.ts +1 -1
  22. package/dist/src/types/composable.d.ts +230 -0
  23. package/dist/src/types/composable.d.ts.map +1 -0
  24. package/dist/src/types/doctype.d.ts +57 -0
  25. package/dist/src/types/doctype.d.ts.map +1 -0
  26. package/dist/src/types/index.d.ts +6 -67
  27. package/dist/src/types/index.d.ts.map +1 -1
  28. package/dist/src/types/plugin.d.ts +37 -0
  29. package/dist/src/types/plugin.d.ts.map +1 -0
  30. package/dist/src/types/schema-validator.d.ts +64 -0
  31. package/dist/src/types/schema-validator.d.ts.map +1 -0
  32. package/dist/src/types/stonecrop.d.ts +17 -0
  33. package/dist/src/types/stonecrop.d.ts.map +1 -0
  34. package/dist/stonecrop.css +1 -0
  35. package/dist/stonecrop.d.ts +206 -14
  36. package/dist/stonecrop.js +1751 -1631
  37. package/dist/stonecrop.js.map +1 -1
  38. package/dist/types/composable.js +0 -0
  39. package/dist/types/doctype.js +0 -0
  40. package/dist/types/index.js +7 -2
  41. package/dist/types/plugin.js +0 -0
  42. package/dist/types/schema-validator.js +13 -0
  43. package/dist/types/stonecrop.js +0 -0
  44. package/package.json +4 -4
  45. package/src/composables/stonecrop.ts +34 -218
  46. package/src/doctype.ts +2 -29
  47. package/src/field-triggers.ts +5 -6
  48. package/src/index.ts +12 -19
  49. package/src/plugins/index.ts +4 -1
  50. package/src/registry.ts +61 -66
  51. package/src/schema-validator.ts +3 -66
  52. package/src/stonecrop.ts +148 -17
  53. package/src/types/composable.ts +245 -0
  54. package/src/types/doctype.ts +60 -0
  55. package/src/types/index.ts +7 -74
  56. package/src/types/plugin.ts +38 -0
  57. package/src/types/schema-validator.ts +67 -0
  58. package/src/types/stonecrop.ts +17 -0
File without changes
File without changes
@@ -1,4 +1,9 @@
1
- // Re-export types
1
+ // Re-export all type files
2
+ export * from './composable';
3
+ export * from './doctype';
2
4
  export * from './field-triggers';
3
- export * from './registry';
4
5
  export * from './operation-log';
6
+ export * from './plugin';
7
+ export * from './registry';
8
+ export * from './schema-validator';
9
+ export * from './stonecrop';
File without changes
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Validation severity levels
3
+ * @public
4
+ */
5
+ export var ValidationSeverity;
6
+ (function (ValidationSeverity) {
7
+ /** Blocking error that prevents save */
8
+ ValidationSeverity["ERROR"] = "error";
9
+ /** Advisory warning that allows save */
10
+ ValidationSeverity["WARNING"] = "warning";
11
+ /** Informational message */
12
+ ValidationSeverity["INFO"] = "info";
13
+ })(ValidationSeverity || (ValidationSeverity = {}));
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stonecrop/stonecrop",
3
- "version": "0.10.11",
3
+ "version": "0.10.13",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "author": {
@@ -34,7 +34,7 @@
34
34
  "pinia-shared-state": "^1.0.1",
35
35
  "pinia-xstate": "^3.0.0",
36
36
  "xstate": "^5.25.0",
37
- "@stonecrop/schema": "0.10.11"
37
+ "@stonecrop/schema": "0.10.13"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "pinia": "^3.0.4",
@@ -60,9 +60,9 @@
60
60
  "vue-router": "^5.0.2",
61
61
  "vite": "^7.3.1",
62
62
  "vitest": "^4.0.18",
63
- "@stonecrop/atable": "0.10.11",
64
63
  "stonecrop-rig": "0.7.0",
65
- "@stonecrop/aform": "0.10.11"
64
+ "@stonecrop/atable": "0.10.13",
65
+ "@stonecrop/aform": "0.10.13"
66
66
  },
67
67
  "description": "Schema-driven framework with XState workflows and HST state management",
68
68
  "publishConfig": {
@@ -1,94 +1,14 @@
1
- import { inject, onMounted, Ref, ref, watch, provide, computed, ComputedRef } from 'vue'
1
+ import { type SchemaTypes } from '@stonecrop/aform'
2
+ import { storeToRefs } from 'pinia'
3
+ import { inject, onMounted, Ref, ref, watch, provide, computed } from 'vue'
2
4
 
5
+ import Doctype from '../doctype'
3
6
  import Registry from '../registry'
4
7
  import { Stonecrop } from '../stonecrop'
5
- import Doctype from '../doctype'
6
8
  import type { HSTNode } from '../stores/hst'
7
- import { RouteContext } from '../types/registry'
8
- import { storeToRefs } from 'pinia'
9
- import type { HSTOperation, OperationLogConfig, OperationLogSnapshot } from '../types/operation-log'
10
- import { SchemaTypes, DoctypeSchema } from '@stonecrop/aform'
11
-
12
- /**
13
- * Operation Log API - nested object containing all operation log functionality
14
- * @public
15
- */
16
- export type OperationLogAPI = {
17
- operations: Ref<HSTOperation[]>
18
- currentIndex: Ref<number>
19
- undoRedoState: ComputedRef<{
20
- canUndo: boolean
21
- canRedo: boolean
22
- undoCount: number
23
- redoCount: number
24
- currentIndex: number
25
- }>
26
- canUndo: ComputedRef<boolean>
27
- canRedo: ComputedRef<boolean>
28
- undoCount: ComputedRef<number>
29
- redoCount: ComputedRef<number>
30
- undo: (hstStore: HSTNode) => boolean
31
- redo: (hstStore: HSTNode) => boolean
32
- startBatch: () => void
33
- commitBatch: (description?: string) => string | null
34
- cancelBatch: () => void
35
- clear: () => void
36
- getOperationsFor: (doctype: string, recordId?: string) => HSTOperation[]
37
- getSnapshot: () => OperationLogSnapshot
38
- markIrreversible: (operationId: string, reason: string) => void
39
- logAction: (
40
- doctype: string,
41
- actionName: string,
42
- recordIds?: string[],
43
- result?: 'success' | 'failure' | 'pending',
44
- error?: string
45
- ) => string
46
- configure: (options: Partial<OperationLogConfig>) => void
47
- }
48
-
49
- /**
50
- * Base Stonecrop composable return type - includes operation log functionality
51
- * @public
52
- */
53
- export type BaseStonecropReturn = {
54
- stonecrop: Ref<Stonecrop | undefined>
55
- operationLog: OperationLogAPI
56
- }
57
-
58
- /**
59
- * HST-enabled Stonecrop composable return type
60
- * @public
61
- */
62
- export type HSTStonecropReturn = BaseStonecropReturn & {
63
- provideHSTPath: (fieldname: string, recordId?: string) => string
64
- handleHSTChange: (changeData: HSTChangeData) => void
65
- hstStore: Ref<HSTNode | undefined>
66
- formData: Ref<Record<string, any>>
67
- resolvedSchema: Ref<SchemaTypes[]>
68
- loadNestedData: (parentPath: string, childDoctype: Doctype, recordId?: string) => Record<string, any>
69
- saveRecursive: (doctype: Doctype, recordId: string) => Promise<Record<string, any>>
70
- createNestedContext: (
71
- basePath: string,
72
- childDoctype: Doctype
73
- ) => {
74
- provideHSTPath: (fieldname: string) => string
75
- handleHSTChange: (changeData: HSTChangeData) => void
76
- }
77
- isLoading: Ref<boolean>
78
- error: Ref<Error | null>
79
- resolvedDoctype: Ref<Doctype | undefined>
80
- }
81
-
82
- /**
83
- * HST Change data structure
84
- * @public
85
- */
86
- export type HSTChangeData = {
87
- path: string
88
- value: any
89
- fieldname: string
90
- recordId?: string
91
- }
9
+ import type { BaseStonecropReturn, HSTStonecropReturn, HSTChangeData, OperationLogAPI } from '../types/composable'
10
+ import type { HSTOperation, OperationLogConfig } from '../types/operation-log'
11
+ import type { RouteContext } from '../types/registry'
92
12
 
93
13
  /**
94
14
  * Unified Stonecrop composable - handles both general operations and HST reactive integration
@@ -122,7 +42,7 @@ export function useStonecrop(options?: {
122
42
 
123
43
  const registry = options.registry || inject<Registry>('$registry')
124
44
  const providedStonecrop = inject<Stonecrop>('$stonecrop')
125
- const stonecrop = ref<Stonecrop>()
45
+ const stonecrop = ref<Stonecrop | undefined>()
126
46
  const hstStore = ref<HSTNode>()
127
47
  const formData = ref<Record<string, any>>({})
128
48
 
@@ -138,6 +58,13 @@ export function useStonecrop(options?: {
138
58
  const error = ref<Error | null>(null)
139
59
  const resolvedDoctype = ref<Doctype | undefined>()
140
60
 
61
+ // Initialize stonecrop instance synchronously using singleton pattern
62
+ // Use injected instance if available, otherwise fall back to the singleton root
63
+ const stonecropInstance = providedStonecrop || Stonecrop._root
64
+ if (stonecropInstance) {
65
+ stonecrop.value = stonecropInstance
66
+ }
67
+
141
68
  // If doctype is a Doctype instance (not string), set resolved immediately
142
69
  if (options?.doctype && typeof options.doctype !== 'string') {
143
70
  resolvedDoctype.value = options.doctype
@@ -222,12 +149,10 @@ export function useStonecrop(options?: {
222
149
 
223
150
  // Initialize Stonecrop instance
224
151
  onMounted(async () => {
225
- if (!registry) {
152
+ if (!registry || !stonecrop.value) {
226
153
  return
227
154
  }
228
155
 
229
- stonecrop.value = providedStonecrop || new Stonecrop(registry)
230
-
231
156
  // Set up reactive refs from operation log store - only if Pinia is available
232
157
  try {
233
158
  const opLogStore = stonecrop.value.getOperationLogStore()
@@ -302,11 +227,11 @@ export function useStonecrop(options?: {
302
227
  formData.value = loadedRecord.get('') || {}
303
228
  }
304
229
  } catch {
305
- formData.value = initializeNewRecord(doctype)
230
+ formData.value = registry.initializeRecord(resolvedSchema.value)
306
231
  }
307
232
  }
308
233
  } else {
309
- formData.value = initializeNewRecord(doctype)
234
+ formData.value = registry.initializeRecord(resolvedSchema.value)
310
235
  }
311
236
 
312
237
  if (hstStore.value) {
@@ -389,11 +314,11 @@ export function useStonecrop(options?: {
389
314
  formData.value = loadedRecord.get('') || {}
390
315
  }
391
316
  } catch {
392
- formData.value = initializeNewRecord(doctype)
317
+ formData.value = registry.initializeRecord(resolvedSchema.value)
393
318
  }
394
319
  }
395
320
  } else {
396
- formData.value = initializeNewRecord(doctype)
321
+ formData.value = registry.initializeRecord(resolvedSchema.value)
397
322
  }
398
323
 
399
324
  if (hstStore.value) {
@@ -469,74 +394,31 @@ export function useStonecrop(options?: {
469
394
 
470
395
  /**
471
396
  * Load nested doctype data from API or initialize empty structure
397
+ * Delegates to Stonecrop.loadNestedData method
472
398
  * @param parentPath - The parent path (e.g., "customer.123.address")
473
399
  * @param childDoctype - The child doctype metadata
474
400
  * @param recordId - Optional record ID to load
475
- * @returns Promise resolving to the loaded or initialized data
401
+ * @returns The loaded or initialized data
476
402
  */
477
403
  const loadNestedData = (parentPath: string, childDoctype: Doctype, recordId?: string): Record<string, any> => {
478
404
  if (!stonecrop.value) {
479
- return initializeNewRecord(childDoctype)
480
- }
481
-
482
- // If recordId provided, try to load existing data
483
- if (recordId) {
484
- try {
485
- // Check if data already exists in HST
486
- const existingData = hstStore.value?.get(parentPath)
487
- if (existingData && typeof existingData === 'object') {
488
- return existingData as Record<string, any>
489
- }
490
-
491
- // TODO: Add API fetch logic here if needed
492
- // For now, initialize new record
493
- return initializeNewRecord(childDoctype)
494
- } catch {
495
- return initializeNewRecord(childDoctype)
496
- }
405
+ throw new Error('Stonecrop instance not available')
497
406
  }
498
-
499
- // Initialize new record
500
- return initializeNewRecord(childDoctype)
407
+ return stonecrop.value.loadNestedData(parentPath, childDoctype, recordId)
501
408
  }
502
409
 
503
410
  /**
504
- * Recursively save a record with all nested doctype fields
411
+ * Collect a record payload with all nested doctype fields from HST
412
+ * Delegates to Stonecrop.collectRecordPayload method
505
413
  * @param doctype - The doctype metadata
506
- * @param recordId - The record ID to save
507
- * @returns The complete save payload
414
+ * @param recordId - The record ID to collect
415
+ * @returns The complete record payload ready for API submission
508
416
  */
509
- const saveRecursive = (doctype: Doctype, recordId: string): Record<string, any> => {
510
- if (!hstStore.value || !stonecrop.value) {
511
- throw new Error('HST store not initialized')
512
- }
513
-
514
- const recordPath = `${doctype.slug}.${recordId}`
515
- const recordData = hstStore.value.get(recordPath) || {}
516
-
517
- // Build the save payload using resolved schema
518
- const payload: Record<string, any> = { ...recordData }
519
-
520
- // Use resolveSchema to get the full resolved tree, then walk Doctype fields
521
- const schemaArray = doctype.schema
522
- ? Array.isArray(doctype.schema)
523
- ? doctype.schema
524
- : Array.from(doctype.schema)
525
- : []
526
- const resolved = registry ? registry.resolveSchema(schemaArray) : schemaArray
527
- const doctypeFields = resolved.filter(
528
- field => 'fieldtype' in field && field.fieldtype === 'Doctype' && 'schema' in field && Array.isArray(field.schema)
529
- )
530
-
531
- // Recursively collect nested data from HST using resolved schemas
532
- for (const field of doctypeFields) {
533
- const doctypeField = field as DoctypeSchema
534
- const fieldPath = `${recordPath}.${doctypeField.fieldname}`
535
- const nestedData = collectNestedData(doctypeField.schema!, fieldPath, hstStore.value)
536
- payload[doctypeField.fieldname] = nestedData
417
+ const collectRecordPayload = (doctype: Doctype, recordId: string): Record<string, any> => {
418
+ if (!stonecrop.value) {
419
+ throw new Error('Stonecrop instance not available')
537
420
  }
538
-
539
- return payload
421
+ return stonecrop.value.collectRecordPayload(doctype, recordId)
540
422
  }
541
423
 
542
424
  /**
@@ -599,7 +481,7 @@ export function useStonecrop(options?: {
599
481
  formData,
600
482
  resolvedSchema,
601
483
  loadNestedData,
602
- saveRecursive,
484
+ collectRecordPayload,
603
485
  createNestedContext,
604
486
  isLoading,
605
487
  error,
@@ -616,7 +498,7 @@ export function useStonecrop(options?: {
616
498
  formData,
617
499
  resolvedSchema,
618
500
  loadNestedData,
619
- saveRecursive,
501
+ collectRecordPayload,
620
502
  createNestedContext,
621
503
  isLoading,
622
504
  error,
@@ -631,45 +513,6 @@ export function useStonecrop(options?: {
631
513
  } as BaseStonecropReturn
632
514
  }
633
515
 
634
- /**
635
- * Initialize new record structure based on doctype schema
636
- */
637
- function initializeNewRecord(doctype: Doctype): Record<string, any> {
638
- const initialData: Record<string, any> = {}
639
-
640
- if (!doctype.schema) {
641
- return initialData
642
- }
643
-
644
- doctype.schema.forEach(field => {
645
- const fieldtype = 'fieldtype' in field ? field.fieldtype : 'Data'
646
-
647
- switch (fieldtype) {
648
- case 'Data':
649
- case 'Text':
650
- initialData[field.fieldname] = ''
651
- break
652
- case 'Check':
653
- initialData[field.fieldname] = false
654
- break
655
- case 'Int':
656
- case 'Float':
657
- initialData[field.fieldname] = 0
658
- break
659
- case 'Table':
660
- initialData[field.fieldname] = []
661
- break
662
- case 'JSON':
663
- initialData[field.fieldname] = {}
664
- break
665
- default:
666
- initialData[field.fieldname] = null
667
- }
668
- })
669
-
670
- return initialData
671
- }
672
-
673
516
  /**
674
517
  * Setup deep reactivity between form data and HST store
675
518
  */
@@ -716,30 +559,3 @@ function updateNestedObject(obj: any, path: string[], value: any): void {
716
559
  const finalKey = path[path.length - 1]
717
560
  current[finalKey] = value
718
561
  }
719
-
720
- /**
721
- * Recursively collect nested data from HST using pre-resolved schemas
722
- * @param resolvedSchema - The already-resolved schema (with nested schemas embedded)
723
- * @param basePath - The base path in HST (e.g., "customer.123.address")
724
- * @param hstStore - The HST store instance
725
- * @returns The collected data object
726
- */
727
- function collectNestedData(resolvedSchema: SchemaTypes[], basePath: string, hstStore: HSTNode): Record<string, any> {
728
- const data = hstStore.get(basePath) || {}
729
- const payload: Record<string, any> = { ...data }
730
-
731
- // Find Doctype fields that have resolved child schemas
732
- const doctypeFields = resolvedSchema.filter(
733
- field => 'fieldtype' in field && field.fieldtype === 'Doctype' && 'schema' in field && Array.isArray(field.schema)
734
- )
735
-
736
- // Recursively collect nested data
737
- for (const field of doctypeFields) {
738
- const doctypeField = field as DoctypeSchema
739
- const fieldPath = `${basePath}.${doctypeField.fieldname}`
740
- const nestedData = collectNestedData(doctypeField.schema!, fieldPath, hstStore)
741
- payload[doctypeField.fieldname] = nestedData
742
- }
743
-
744
- return payload
745
- }
package/src/doctype.ts CHANGED
@@ -5,32 +5,7 @@ import { Component } from 'vue'
5
5
  import type { UnknownMachineConfig } from 'xstate'
6
6
 
7
7
  import type { ImmutableDoctype } from './types'
8
-
9
- /**
10
- * Plain object representation of doctype configuration for serialization/API responses.
11
- * Compatible with the DoctypeMeta type from \@stonecrop/schema.
12
- * @public
13
- */
14
- export type DoctypeConfig = {
15
- /** Display name of the doctype */
16
- name: string
17
- /** URL-friendly slug (kebab-case) */
18
- slug?: string
19
- /** Database table name */
20
- tableName?: string
21
- /** Field definitions */
22
- fields?: SchemaTypes[]
23
- /** Workflow configuration (XState format or simple WorkflowMeta) */
24
- workflow?: UnknownMachineConfig | WorkflowMeta
25
- /** Actions and their field triggers */
26
- actions?: Record<string, string[]>
27
- /** Parent doctype for inheritance */
28
- inherits?: string
29
- /** Doctype to use for list views */
30
- listDoctype?: string
31
- /** Parent doctype for child tables */
32
- parentDoctype?: string
33
- }
8
+ import type { DoctypeConfig } from './types/doctype'
34
9
 
35
10
  /**
36
11
  * Doctype runtime class with Immutable.js collections for HST change tracking.
@@ -249,9 +224,7 @@ export default class Doctype {
249
224
  *
250
225
  * @public
251
226
  */
252
- getActionMeta(
253
- actionName: string
254
- ):
227
+ getActionMeta(actionName: string):
255
228
  | {
256
229
  label: string
257
230
  handler: string
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-new-func, no-eval */
2
1
  import type { Map as ImmutableMap } from 'immutable'
3
2
  import { useOperationLogStore } from './stores/operation-log'
4
3
  import type {
@@ -101,11 +100,11 @@ export class FieldTriggerEngine {
101
100
  const transitionMap = new Map<string, string[]>()
102
101
 
103
102
  // Convert from different Map types to regular Map
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- if (typeof (actions as any).entrySeq === 'function') {
103
+ // Check for Immutable.js Map first (has entrySeq method)
104
+ const immutableActions = actions as ImmutableMap<string, string[]>
105
+ if (typeof immutableActions.entrySeq === 'function') {
106
106
  // Immutable Map
107
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
- ;(actions as any).entrySeq().forEach(([key, value]: [string, string[]]) => {
107
+ immutableActions.entrySeq().forEach(([key, value]: [string, string[]]) => {
109
108
  this.categorizeAction(key, value, actionMap, transitionMap)
110
109
  })
111
110
  } else if (actions instanceof Map) {
@@ -506,7 +505,7 @@ export class FieldTriggerEngine {
506
505
  })
507
506
  .catch(error => {
508
507
  clearTimeout(timeoutId)
509
- reject(error)
508
+ reject(error instanceof Error ? error : new Error(String(error)))
510
509
  })
511
510
  })
512
511
  }
package/src/index.ts CHANGED
@@ -3,8 +3,9 @@ export type * from '@stonecrop/atable/types'
3
3
 
4
4
  import { useStonecrop } from './composables/stonecrop'
5
5
  import { useOperationLog, useUndoRedoShortcuts, withBatch } from './composables/operation-log'
6
- import Doctype, { type DoctypeConfig } from './doctype'
6
+ import Doctype from './doctype'
7
7
  import {
8
+ FieldTriggerEngine,
8
9
  getGlobalTriggerEngine,
9
10
  markOperationIrreversible,
10
11
  registerGlobalAction,
@@ -14,39 +15,29 @@ import {
14
15
  } from './field-triggers'
15
16
  import plugin from './plugins'
16
17
  import Registry from './registry'
17
- import { type StonecropOptions, Stonecrop } from './stonecrop'
18
+ import { Stonecrop, collectNestedData } from './stonecrop'
18
19
  import { HST, createHST, type HSTNode } from './stores/hst'
19
20
  import { useOperationLogStore } from './stores/operation-log'
20
- // Export schema validator
21
21
  import { SchemaValidator, createValidator, validateSchema } from './schema-validator'
22
+ import { ValidationSeverity } from './types/schema-validator'
23
+
24
+ // Export all types from ./types
22
25
  export type * from './types'
23
- export type { BaseStonecropReturn, HSTChangeData, HSTStonecropReturn, OperationLogAPI } from './composables/stonecrop'
24
- export type { FieldTriggerEngine } from './field-triggers'
25
- export type {
26
- FieldChangeContext,
27
- TransitionChangeContext,
28
- FieldTriggerExecutionResult,
29
- ActionExecutionResult,
30
- TransitionExecutionResult,
31
- FieldActionFunction,
32
- TransitionActionFunction,
33
- } from './types/field-triggers'
34
- // Export schema validator types
35
- export type { ValidationIssue, ValidationResult, ValidatorOptions } from './schema-validator'
36
- export { ValidationSeverity } from './schema-validator'
26
+
27
+ // Export enum as value (enums need runtime export, not just type)
28
+ export { ValidationSeverity }
37
29
 
38
30
  export {
39
31
  Doctype,
40
- DoctypeConfig,
41
32
  Registry,
42
33
  Stonecrop,
43
- StonecropOptions,
44
34
  useStonecrop,
45
35
  // HST exports for advanced usage
46
36
  HST,
47
37
  createHST,
48
38
  HSTNode,
49
39
  // Field trigger system exports
40
+ FieldTriggerEngine,
50
41
  getGlobalTriggerEngine,
51
42
  registerGlobalAction,
52
43
  registerTransitionAction,
@@ -62,6 +53,8 @@ export {
62
53
  useOperationLogStore,
63
54
  useUndoRedoShortcuts,
64
55
  withBatch,
56
+ // Utility functions
57
+ collectNestedData,
65
58
  }
66
59
 
67
60
  // Default export is the Vue plugin
@@ -72,7 +72,10 @@ const plugin: Plugin = {
72
72
  app.config.globalProperties.$registry = registry
73
73
 
74
74
  // Create and provide a global Stonecrop instance
75
- const stonecrop = new Stonecrop(registry, undefined, options?.client ? { client: options.client } : undefined)
75
+ const stonecrop = new Stonecrop(registry)
76
+ if (options?.client) {
77
+ stonecrop.setClient(options.client)
78
+ }
76
79
  app.provide('$stonecrop', stonecrop)
77
80
  app.config.globalProperties.$stonecrop = stonecrop
78
81