@stonecrop/stonecrop 0.4.37 → 0.6.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 (78) hide show
  1. package/README.md +92 -3
  2. package/dist/src/composable.d.ts +74 -8
  3. package/dist/src/composable.d.ts.map +1 -1
  4. package/dist/src/composable.js +348 -0
  5. package/dist/src/composables/operation-log.d.ts +136 -0
  6. package/dist/src/composables/operation-log.d.ts.map +1 -0
  7. package/dist/src/composables/operation-log.js +221 -0
  8. package/dist/src/doctype.d.ts +9 -1
  9. package/dist/src/doctype.d.ts.map +1 -1
  10. package/dist/{doctype.js → src/doctype.js} +9 -3
  11. package/dist/src/field-triggers.d.ts +178 -0
  12. package/dist/src/field-triggers.d.ts.map +1 -0
  13. package/dist/src/field-triggers.js +564 -0
  14. package/dist/src/index.d.ts +12 -4
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +18 -0
  17. package/dist/src/plugins/index.d.ts +11 -13
  18. package/dist/src/plugins/index.d.ts.map +1 -1
  19. package/dist/src/plugins/index.js +90 -0
  20. package/dist/src/registry.d.ts +9 -3
  21. package/dist/src/registry.d.ts.map +1 -1
  22. package/dist/{registry.js → src/registry.js} +14 -1
  23. package/dist/src/stonecrop.d.ts +350 -114
  24. package/dist/src/stonecrop.d.ts.map +1 -1
  25. package/dist/src/stonecrop.js +251 -0
  26. package/dist/src/stores/hst.d.ts +157 -0
  27. package/dist/src/stores/hst.d.ts.map +1 -0
  28. package/dist/src/stores/hst.js +483 -0
  29. package/dist/src/stores/index.d.ts +5 -1
  30. package/dist/src/stores/index.d.ts.map +1 -1
  31. package/dist/{stores → src/stores}/index.js +4 -1
  32. package/dist/src/stores/operation-log.d.ts +268 -0
  33. package/dist/src/stores/operation-log.d.ts.map +1 -0
  34. package/dist/src/stores/operation-log.js +571 -0
  35. package/dist/src/types/field-triggers.d.ts +186 -0
  36. package/dist/src/types/field-triggers.d.ts.map +1 -0
  37. package/dist/src/types/field-triggers.js +4 -0
  38. package/dist/src/types/index.d.ts +13 -2
  39. package/dist/src/types/index.d.ts.map +1 -1
  40. package/dist/src/types/index.js +4 -0
  41. package/dist/src/types/operation-log.d.ts +165 -0
  42. package/dist/src/types/operation-log.d.ts.map +1 -0
  43. package/dist/src/types/registry.d.ts +11 -0
  44. package/dist/src/types/registry.d.ts.map +1 -0
  45. package/dist/src/types/registry.js +0 -0
  46. package/dist/stonecrop.d.ts +1555 -159
  47. package/dist/stonecrop.js +1974 -7028
  48. package/dist/stonecrop.js.map +1 -1
  49. package/dist/stonecrop.umd.cjs +4 -8
  50. package/dist/stonecrop.umd.cjs.map +1 -1
  51. package/dist/tests/setup.d.ts +5 -0
  52. package/dist/tests/setup.d.ts.map +1 -0
  53. package/dist/tests/setup.js +15 -0
  54. package/package.json +6 -5
  55. package/src/composable.ts +481 -31
  56. package/src/composables/operation-log.ts +254 -0
  57. package/src/doctype.ts +9 -3
  58. package/src/field-triggers.ts +671 -0
  59. package/src/index.ts +50 -4
  60. package/src/plugins/index.ts +70 -22
  61. package/src/registry.ts +18 -3
  62. package/src/stonecrop.ts +246 -155
  63. package/src/stores/hst.ts +703 -0
  64. package/src/stores/index.ts +6 -1
  65. package/src/stores/operation-log.ts +671 -0
  66. package/src/types/field-triggers.ts +201 -0
  67. package/src/types/index.ts +17 -6
  68. package/src/types/operation-log.ts +205 -0
  69. package/src/types/registry.ts +10 -0
  70. package/dist/composable.js +0 -50
  71. package/dist/index.js +0 -6
  72. package/dist/plugins/index.js +0 -49
  73. package/dist/src/stores/data.d.ts +0 -11
  74. package/dist/src/stores/data.d.ts.map +0 -1
  75. package/dist/stores/data.js +0 -7
  76. package/src/stores/data.ts +0 -8
  77. /package/dist/{exceptions.js → src/exceptions.js} +0 -0
  78. /package/dist/{types/index.js → src/types/operation-log.js} +0 -0
@@ -0,0 +1,90 @@
1
+ import { nextTick } from 'vue';
2
+ import Registry from '../registry';
3
+ import { Stonecrop } from '../stonecrop';
4
+ import { useOperationLogStore } from '../stores/operation-log';
5
+ /**
6
+ * Setup auto-initialization for user-defined initialization logic
7
+ * This function handles the post-mount initialization automatically
8
+ */
9
+ async function setupAutoInitialization(registry, stonecrop, onRouterInitialized) {
10
+ // Wait for the next tick to ensure the app is mounted
11
+ await nextTick();
12
+ try {
13
+ await onRouterInitialized(registry, stonecrop);
14
+ }
15
+ catch {
16
+ // Silent error handling - application should handle initialization errors
17
+ }
18
+ }
19
+ /**
20
+ * Stonecrop Vue plugin
21
+ * @param app - The Vue app instance
22
+ * @param options - The plugin options
23
+ * @example
24
+ * ```ts
25
+ * import { createApp } from 'vue'
26
+ * import Stonecrop from '@stonecrop/stonecrop'
27
+ * import router from './router'
28
+ *
29
+ * const app = createApp(App)
30
+ * app.use(Stonecrop, {
31
+ * router,
32
+ * getMeta: async (routeContext) => {
33
+ * // routeContext contains: { path, segments }
34
+ * // fetch doctype meta from your API using the route context
35
+ * },
36
+ * autoInitializeRouter: true,
37
+ * onRouterInitialized: async (registry, stonecrop) => {
38
+ * // your custom initialization logic here
39
+ * }
40
+ * })
41
+ * app.mount('#app')
42
+ * ```
43
+ * @public
44
+ */
45
+ const plugin = {
46
+ install: (app, options) => {
47
+ // Check for existing router installation
48
+ const existingRouter = app.config.globalProperties.$router;
49
+ const providedRouter = options?.router;
50
+ const router = existingRouter || providedRouter;
51
+ if (!existingRouter && providedRouter) {
52
+ app.use(providedRouter);
53
+ }
54
+ // Create registry with available router
55
+ const registry = new Registry(router, options?.getMeta);
56
+ app.provide('$registry', registry);
57
+ app.config.globalProperties.$registry = registry;
58
+ // Create and provide a global Stonecrop instance
59
+ const stonecrop = new Stonecrop(registry);
60
+ app.provide('$stonecrop', stonecrop);
61
+ app.config.globalProperties.$stonecrop = stonecrop;
62
+ // Initialize operation log store if Pinia is available
63
+ // This ensures the store is created with the app's Pinia instance
64
+ try {
65
+ const pinia = app.config.globalProperties.$pinia;
66
+ if (pinia) {
67
+ // Initialize the operation log store with the app's Pinia instance
68
+ const operationLogStore = useOperationLogStore(pinia);
69
+ // Provide the store so components can access it
70
+ app.provide('$operationLogStore', operationLogStore);
71
+ app.config.globalProperties.$operationLogStore = operationLogStore;
72
+ }
73
+ }
74
+ catch (error) {
75
+ // Pinia not available - operation log won't work, but app should still function
76
+ console.warn('Pinia not available - operation log features will be disabled:', error);
77
+ }
78
+ // Register custom components
79
+ if (options?.components) {
80
+ for (const [tag, component] of Object.entries(options.components)) {
81
+ app.component(tag, component);
82
+ }
83
+ }
84
+ // Setup auto-initialization if requested
85
+ if (options?.autoInitializeRouter && options.onRouterInitialized) {
86
+ void setupAutoInitialization(registry, stonecrop, options.onRouterInitialized);
87
+ }
88
+ },
89
+ };
90
+ export default plugin;
@@ -1,5 +1,6 @@
1
1
  import { Router } from 'vue-router';
2
2
  import DoctypeMeta from './doctype';
3
+ import { RouteContext } from './types/registry';
3
4
  /**
4
5
  * Stonecrop Registry class
5
6
  * @public
@@ -25,12 +26,17 @@ export default class Registry {
25
26
  * @see {@link https://router.vuejs.org/}
26
27
  */
27
28
  readonly router?: Router;
28
- constructor(router?: Router, getMeta?: (doctype: string) => DoctypeMeta | Promise<DoctypeMeta>);
29
29
  /**
30
- * The getMeta function fetches doctype metadata from an API
30
+ * Creates a new Registry instance (singleton pattern)
31
+ * @param router - Optional Vue router instance for route management
32
+ * @param getMeta - Optional function to fetch doctype metadata from an API
33
+ */
34
+ constructor(router?: Router, getMeta?: (routeContext: RouteContext) => DoctypeMeta | Promise<DoctypeMeta>);
35
+ /**
36
+ * The getMeta function fetches doctype metadata from an API based on route context
31
37
  * @see {@link DoctypeMeta}
32
38
  */
33
- getMeta?: (doctype: string) => DoctypeMeta | Promise<DoctypeMeta>;
39
+ getMeta?: (routeContext: RouteContext) => DoctypeMeta | Promise<DoctypeMeta>;
34
40
  /**
35
41
  * Get doctype metadata
36
42
  * @param doctype - The doctype to fetch metadata for
@@ -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;;;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;gBAEZ,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAW9F;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAEjE;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW;CA0B/B"}
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,3 +1,4 @@
1
+ import { getGlobalTriggerEngine } from './field-triggers';
1
2
  /**
2
3
  * Stonecrop Registry class
3
4
  * @public
@@ -23,6 +24,11 @@ export default class Registry {
23
24
  * @see {@link https://router.vuejs.org/}
24
25
  */
25
26
  router;
27
+ /**
28
+ * Creates a new Registry instance (singleton pattern)
29
+ * @param router - Optional Vue router instance for route management
30
+ * @param getMeta - Optional function to fetch doctype metadata from an API
31
+ */
26
32
  constructor(router, getMeta) {
27
33
  if (Registry._root) {
28
34
  return Registry._root;
@@ -34,7 +40,7 @@ export default class Registry {
34
40
  this.getMeta = getMeta;
35
41
  }
36
42
  /**
37
- * The getMeta function fetches doctype metadata from an API
43
+ * The getMeta function fetches doctype metadata from an API based on route context
38
44
  * @see {@link DoctypeMeta}
39
45
  */
40
46
  getMeta;
@@ -48,6 +54,13 @@ export default class Registry {
48
54
  if (!(doctype.doctype in Object.keys(this.registry))) {
49
55
  this.registry[doctype.slug] = doctype;
50
56
  }
57
+ // Register actions (including field triggers) with the field trigger engine
58
+ const triggerEngine = getGlobalTriggerEngine();
59
+ // Register under both doctype name and slug to handle different lookup patterns
60
+ triggerEngine.registerDoctypeActions(doctype.doctype, doctype.actions);
61
+ if (doctype.slug !== doctype.doctype) {
62
+ triggerEngine.registerDoctypeActions(doctype.slug, doctype.actions);
63
+ }
51
64
  if (doctype.component && this.router && !this.router.hasRoute(doctype.doctype)) {
52
65
  this.router.addRoute({
53
66
  path: `/${doctype.slug}`,
@@ -1,135 +1,371 @@
1
1
  import DoctypeMeta from './doctype';
2
2
  import Registry from './registry';
3
- import { useDataStore } from './stores/data';
3
+ import { type HSTNode } from './stores/hst';
4
+ import type { OperationLogConfig } from './types/operation-log';
5
+ import type { RouteContext } from './types/registry';
4
6
  /**
5
- * Stonecrop class
7
+ * Main Stonecrop class with HST integration and built-in Operation Log
6
8
  * @public
7
9
  */
8
10
  export declare class Stonecrop {
11
+ private hstStore;
12
+ private _operationLogStore?;
13
+ private _operationLogConfig?;
14
+ /** The registry instance containing all doctype definitions */
15
+ readonly registry: Registry;
9
16
  /**
10
- * The root Stonecrop instance
11
- */
12
- static _root: Stonecrop;
13
- /**
14
- * The name of the Stonecrop instance
15
- * @readonly
16
- *
17
- * @defaultValue 'Stonecrop'
18
- */
19
- readonly name = "Stonecrop";
20
- /**
21
- * The registry is an immutable collection of doctypes
22
- * @example
23
- * ```ts
24
- * {
25
- * 'task': {
26
- * doctype: 'Task',
27
- * schema: {
28
- * title: 'string',
29
- * description: 'string',
30
- * ...
31
- * }
32
- * },
33
- * ...
34
- * }
35
- * ```
36
- * @see {@link Registry}
37
- * @see {@link DoctypeMeta}
17
+ * Creates a new Stonecrop instance with HST integration
18
+ * @param registry - The Registry instance containing doctype definitions
19
+ * @param operationLogConfig - Optional configuration for the operation log
38
20
  */
39
- readonly registry: Registry;
21
+ constructor(registry: Registry, operationLogConfig?: Partial<OperationLogConfig>);
22
+ /**
23
+ * Get the operation log store (lazy initialization)
24
+ * @internal
25
+ */
26
+ getOperationLogStore(): import("pinia").Store<"hst-operation-log", Pick<{
27
+ operations: import("vue").Ref<{
28
+ id: string;
29
+ type: import("./types").HSTOperationType;
30
+ path: string;
31
+ fieldname: string;
32
+ beforeValue: any;
33
+ afterValue: any;
34
+ doctype: string;
35
+ recordId?: string | undefined;
36
+ timestamp: Date;
37
+ source?: import("./types").OperationSource | undefined;
38
+ reversible: boolean;
39
+ irreversibleReason?: string | undefined;
40
+ transition?: string | undefined;
41
+ currentState?: string | undefined;
42
+ targetState?: string | undefined;
43
+ actionName?: string | undefined;
44
+ actionRecordIds?: string[] | undefined;
45
+ actionResult?: "success" | "failure" | "pending" | undefined;
46
+ actionError?: string | undefined;
47
+ userId?: string | undefined;
48
+ metadata?: Record<string, any> | undefined;
49
+ parentOperationId?: string | undefined;
50
+ childOperationIds?: string[] | undefined;
51
+ }[], import("./types").HSTOperation[] | {
52
+ id: string;
53
+ type: import("./types").HSTOperationType;
54
+ path: string;
55
+ fieldname: string;
56
+ beforeValue: any;
57
+ afterValue: any;
58
+ doctype: string;
59
+ recordId?: string | undefined;
60
+ timestamp: Date;
61
+ source?: import("./types").OperationSource | undefined;
62
+ reversible: boolean;
63
+ irreversibleReason?: string | undefined;
64
+ transition?: string | undefined;
65
+ currentState?: string | undefined;
66
+ targetState?: string | undefined;
67
+ actionName?: string | undefined;
68
+ actionRecordIds?: string[] | undefined;
69
+ actionResult?: "success" | "failure" | "pending" | undefined;
70
+ actionError?: string | undefined;
71
+ userId?: string | undefined;
72
+ metadata?: Record<string, any> | undefined;
73
+ parentOperationId?: string | undefined;
74
+ childOperationIds?: string[] | undefined;
75
+ }[]>;
76
+ currentIndex: import("vue").Ref<number, number>;
77
+ config: import("vue").Ref<{
78
+ maxOperations?: number | undefined;
79
+ enableCrossTabSync?: boolean | undefined;
80
+ autoSyncInterval?: number | undefined;
81
+ enablePersistence?: boolean | undefined;
82
+ persistenceKeyPrefix?: string | undefined;
83
+ userId?: string | undefined;
84
+ operationFilter?: ((operation: import("./types").HSTOperation) => boolean) | undefined;
85
+ }, OperationLogConfig | {
86
+ maxOperations?: number | undefined;
87
+ enableCrossTabSync?: boolean | undefined;
88
+ autoSyncInterval?: number | undefined;
89
+ enablePersistence?: boolean | undefined;
90
+ persistenceKeyPrefix?: string | undefined;
91
+ userId?: string | undefined;
92
+ operationFilter?: ((operation: import("./types").HSTOperation) => boolean) | undefined;
93
+ }>;
94
+ clientId: import("vue").Ref<string, string>;
95
+ undoRedoState: import("vue").ComputedRef<import("./types").UndoRedoState>;
96
+ canUndo: import("vue").ComputedRef<boolean>;
97
+ canRedo: import("vue").ComputedRef<boolean>;
98
+ undoCount: import("vue").ComputedRef<number>;
99
+ redoCount: import("vue").ComputedRef<number>;
100
+ configure: (options: Partial<OperationLogConfig>) => void;
101
+ addOperation: (operation: import("./types").HSTOperationInput, source?: import("./types").OperationSource) => string;
102
+ startBatch: () => void;
103
+ commitBatch: (description?: string) => string | null;
104
+ cancelBatch: () => void;
105
+ undo: (store: HSTNode) => boolean;
106
+ redo: (store: HSTNode) => boolean;
107
+ clear: () => void;
108
+ getOperationsFor: (doctype: string, recordId?: string) => import("./types").HSTOperation[];
109
+ getSnapshot: () => import("./types").OperationLogSnapshot;
110
+ markIrreversible: (operationId: string, reason: string) => void;
111
+ logAction: (doctype: string, actionName: string, recordIds?: string[], result?: "success" | "failure" | "pending", error?: string) => string;
112
+ }, "operations" | "clientId" | "currentIndex" | "config">, Pick<{
113
+ operations: import("vue").Ref<{
114
+ id: string;
115
+ type: import("./types").HSTOperationType;
116
+ path: string;
117
+ fieldname: string;
118
+ beforeValue: any;
119
+ afterValue: any;
120
+ doctype: string;
121
+ recordId?: string | undefined;
122
+ timestamp: Date;
123
+ source?: import("./types").OperationSource | undefined;
124
+ reversible: boolean;
125
+ irreversibleReason?: string | undefined;
126
+ transition?: string | undefined;
127
+ currentState?: string | undefined;
128
+ targetState?: string | undefined;
129
+ actionName?: string | undefined;
130
+ actionRecordIds?: string[] | undefined;
131
+ actionResult?: "success" | "failure" | "pending" | undefined;
132
+ actionError?: string | undefined;
133
+ userId?: string | undefined;
134
+ metadata?: Record<string, any> | undefined;
135
+ parentOperationId?: string | undefined;
136
+ childOperationIds?: string[] | undefined;
137
+ }[], import("./types").HSTOperation[] | {
138
+ id: string;
139
+ type: import("./types").HSTOperationType;
140
+ path: string;
141
+ fieldname: string;
142
+ beforeValue: any;
143
+ afterValue: any;
144
+ doctype: string;
145
+ recordId?: string | undefined;
146
+ timestamp: Date;
147
+ source?: import("./types").OperationSource | undefined;
148
+ reversible: boolean;
149
+ irreversibleReason?: string | undefined;
150
+ transition?: string | undefined;
151
+ currentState?: string | undefined;
152
+ targetState?: string | undefined;
153
+ actionName?: string | undefined;
154
+ actionRecordIds?: string[] | undefined;
155
+ actionResult?: "success" | "failure" | "pending" | undefined;
156
+ actionError?: string | undefined;
157
+ userId?: string | undefined;
158
+ metadata?: Record<string, any> | undefined;
159
+ parentOperationId?: string | undefined;
160
+ childOperationIds?: string[] | undefined;
161
+ }[]>;
162
+ currentIndex: import("vue").Ref<number, number>;
163
+ config: import("vue").Ref<{
164
+ maxOperations?: number | undefined;
165
+ enableCrossTabSync?: boolean | undefined;
166
+ autoSyncInterval?: number | undefined;
167
+ enablePersistence?: boolean | undefined;
168
+ persistenceKeyPrefix?: string | undefined;
169
+ userId?: string | undefined;
170
+ operationFilter?: ((operation: import("./types").HSTOperation) => boolean) | undefined;
171
+ }, OperationLogConfig | {
172
+ maxOperations?: number | undefined;
173
+ enableCrossTabSync?: boolean | undefined;
174
+ autoSyncInterval?: number | undefined;
175
+ enablePersistence?: boolean | undefined;
176
+ persistenceKeyPrefix?: string | undefined;
177
+ userId?: string | undefined;
178
+ operationFilter?: ((operation: import("./types").HSTOperation) => boolean) | undefined;
179
+ }>;
180
+ clientId: import("vue").Ref<string, string>;
181
+ undoRedoState: import("vue").ComputedRef<import("./types").UndoRedoState>;
182
+ canUndo: import("vue").ComputedRef<boolean>;
183
+ canRedo: import("vue").ComputedRef<boolean>;
184
+ undoCount: import("vue").ComputedRef<number>;
185
+ redoCount: import("vue").ComputedRef<number>;
186
+ configure: (options: Partial<OperationLogConfig>) => void;
187
+ addOperation: (operation: import("./types").HSTOperationInput, source?: import("./types").OperationSource) => string;
188
+ startBatch: () => void;
189
+ commitBatch: (description?: string) => string | null;
190
+ cancelBatch: () => void;
191
+ undo: (store: HSTNode) => boolean;
192
+ redo: (store: HSTNode) => boolean;
193
+ clear: () => void;
194
+ getOperationsFor: (doctype: string, recordId?: string) => import("./types").HSTOperation[];
195
+ getSnapshot: () => import("./types").OperationLogSnapshot;
196
+ markIrreversible: (operationId: string, reason: string) => void;
197
+ logAction: (doctype: string, actionName: string, recordIds?: string[], result?: "success" | "failure" | "pending", error?: string) => string;
198
+ }, "undoRedoState" | "canUndo" | "canRedo" | "undoCount" | "redoCount">, Pick<{
199
+ operations: import("vue").Ref<{
200
+ id: string;
201
+ type: import("./types").HSTOperationType;
202
+ path: string;
203
+ fieldname: string;
204
+ beforeValue: any;
205
+ afterValue: any;
206
+ doctype: string;
207
+ recordId?: string | undefined;
208
+ timestamp: Date;
209
+ source?: import("./types").OperationSource | undefined;
210
+ reversible: boolean;
211
+ irreversibleReason?: string | undefined;
212
+ transition?: string | undefined;
213
+ currentState?: string | undefined;
214
+ targetState?: string | undefined;
215
+ actionName?: string | undefined;
216
+ actionRecordIds?: string[] | undefined;
217
+ actionResult?: "success" | "failure" | "pending" | undefined;
218
+ actionError?: string | undefined;
219
+ userId?: string | undefined;
220
+ metadata?: Record<string, any> | undefined;
221
+ parentOperationId?: string | undefined;
222
+ childOperationIds?: string[] | undefined;
223
+ }[], import("./types").HSTOperation[] | {
224
+ id: string;
225
+ type: import("./types").HSTOperationType;
226
+ path: string;
227
+ fieldname: string;
228
+ beforeValue: any;
229
+ afterValue: any;
230
+ doctype: string;
231
+ recordId?: string | undefined;
232
+ timestamp: Date;
233
+ source?: import("./types").OperationSource | undefined;
234
+ reversible: boolean;
235
+ irreversibleReason?: string | undefined;
236
+ transition?: string | undefined;
237
+ currentState?: string | undefined;
238
+ targetState?: string | undefined;
239
+ actionName?: string | undefined;
240
+ actionRecordIds?: string[] | undefined;
241
+ actionResult?: "success" | "failure" | "pending" | undefined;
242
+ actionError?: string | undefined;
243
+ userId?: string | undefined;
244
+ metadata?: Record<string, any> | undefined;
245
+ parentOperationId?: string | undefined;
246
+ childOperationIds?: string[] | undefined;
247
+ }[]>;
248
+ currentIndex: import("vue").Ref<number, number>;
249
+ config: import("vue").Ref<{
250
+ maxOperations?: number | undefined;
251
+ enableCrossTabSync?: boolean | undefined;
252
+ autoSyncInterval?: number | undefined;
253
+ enablePersistence?: boolean | undefined;
254
+ persistenceKeyPrefix?: string | undefined;
255
+ userId?: string | undefined;
256
+ operationFilter?: ((operation: import("./types").HSTOperation) => boolean) | undefined;
257
+ }, OperationLogConfig | {
258
+ maxOperations?: number | undefined;
259
+ enableCrossTabSync?: boolean | undefined;
260
+ autoSyncInterval?: number | undefined;
261
+ enablePersistence?: boolean | undefined;
262
+ persistenceKeyPrefix?: string | undefined;
263
+ userId?: string | undefined;
264
+ operationFilter?: ((operation: import("./types").HSTOperation) => boolean) | undefined;
265
+ }>;
266
+ clientId: import("vue").Ref<string, string>;
267
+ undoRedoState: import("vue").ComputedRef<import("./types").UndoRedoState>;
268
+ canUndo: import("vue").ComputedRef<boolean>;
269
+ canRedo: import("vue").ComputedRef<boolean>;
270
+ undoCount: import("vue").ComputedRef<number>;
271
+ redoCount: import("vue").ComputedRef<number>;
272
+ configure: (options: Partial<OperationLogConfig>) => void;
273
+ addOperation: (operation: import("./types").HSTOperationInput, source?: import("./types").OperationSource) => string;
274
+ startBatch: () => void;
275
+ commitBatch: (description?: string) => string | null;
276
+ cancelBatch: () => void;
277
+ undo: (store: HSTNode) => boolean;
278
+ redo: (store: HSTNode) => boolean;
279
+ clear: () => void;
280
+ getOperationsFor: (doctype: string, recordId?: string) => import("./types").HSTOperation[];
281
+ getSnapshot: () => import("./types").OperationLogSnapshot;
282
+ markIrreversible: (operationId: string, reason: string) => void;
283
+ logAction: (doctype: string, actionName: string, recordIds?: string[], result?: "success" | "failure" | "pending", error?: string) => string;
284
+ }, "undo" | "redo" | "configure" | "addOperation" | "startBatch" | "commitBatch" | "cancelBatch" | "clear" | "getOperationsFor" | "getSnapshot" | "markIrreversible" | "logAction">>;
285
+ /**
286
+ * Initialize the HST store structure
287
+ */
288
+ private initializeHSTStore;
289
+ /**
290
+ * Setup automatic sync with Registry when doctypes are added
291
+ */
292
+ private setupRegistrySync;
293
+ /**
294
+ * Get records hash for a doctype
295
+ * @param doctype - The doctype to get records for
296
+ * @returns HST node containing records hash
297
+ */
298
+ records(doctype: string | DoctypeMeta): HSTNode;
299
+ /**
300
+ * Add a record to the store
301
+ * @param doctype - The doctype
302
+ * @param recordId - The record ID
303
+ * @param recordData - The record data
304
+ */
305
+ addRecord(doctype: string | DoctypeMeta, recordId: string, recordData: any): void;
306
+ /**
307
+ * Get a specific record
308
+ * @param doctype - The doctype
309
+ * @param recordId - The record ID
310
+ * @returns HST node for the record or undefined
311
+ */
312
+ getRecordById(doctype: string | DoctypeMeta, recordId: string): HSTNode | undefined;
40
313
  /**
41
- * The Pinia store that manages the mutable records
314
+ * Remove a record from the store
315
+ * @param doctype - The doctype
316
+ * @param recordId - The record ID
42
317
  */
43
- store: ReturnType<typeof useDataStore>;
318
+ removeRecord(doctype: string | DoctypeMeta, recordId: string): void;
44
319
  /**
45
- * @param registry - The immutable registry
46
- * @param store - The mutable Pinia store
47
- * @returns The Stonecrop instance with the given registry and store. If a Stonecrop instance has already been created, it returns the existing instance instead of creating a new one.
48
- * @example
49
- * ```ts
50
- * const registry = new Registry()
51
- * const store = useDataStore()
52
- * const stonecrop = new Stonecrop(registry, store)
53
- * ```
320
+ * Get all record IDs for a doctype
321
+ * @param doctype - The doctype
322
+ * @returns Array of record IDs
54
323
  */
55
- constructor(registry: Registry, store: ReturnType<typeof useDataStore>);
324
+ getRecordIds(doctype: string | DoctypeMeta): string[];
56
325
  /**
57
- * Sets up the Stonecrop instance with the given doctype
326
+ * Clear all records for a doctype
327
+ * @param doctype - The doctype
328
+ */
329
+ clearRecords(doctype: string | DoctypeMeta): void;
330
+ /**
331
+ * Setup method for doctype initialization
58
332
  * @param doctype - The doctype to setup
59
- * @example
60
- * ```ts
61
- * const doctype = await registry.getMeta('Task')
62
- * stonecrop.setup(doctype)
63
- * ```
64
333
  */
65
334
  setup(doctype: DoctypeMeta): void;
66
335
  /**
67
- * Gets the meta for the given doctype
68
- * @param doctype - The doctype to get meta for
69
- * @returns The meta for the given doctype
70
- * @throws `NotImplementedError` if the `getMeta` function is not implemented for the doctype in the registry
71
- * @example
72
- * ```ts
73
- * const doctype = await registry.getMeta('Task')
74
- * const meta = stonecrop.getMeta(doctype)
75
- * ```
76
- * @see {@link DoctypeMeta}
336
+ * Run action on doctype
337
+ * Executes the action and logs it to the operation log for audit tracking
338
+ * @param doctype - The doctype
339
+ * @param action - The action to run
340
+ * @param args - Action arguments (typically record IDs)
77
341
  */
78
- getMeta(doctype: string): Promise<DoctypeMeta> | never;
342
+ runAction(doctype: DoctypeMeta, action: string, args?: any[]): void;
79
343
  /**
80
- * Gets the records for the given doctype
81
- * @param doctype - The doctype to get records for
82
- * @param filters - The filters to apply to the records
83
- * @example
84
- * ```ts
85
- * const doctype = await registry.getMeta('Task')
86
- * await stonecrop.getRecords(doctype)
87
- * ```
88
- * @example
89
- * ```ts
90
- * const doctype = await registry.getMeta('Task')
91
- * const filters = JSON.stringify({ status: 'Open' })
92
- * await stonecrop.getRecords(doctype, { body: filters })
93
- * ```
94
- */
95
- getRecords(doctype: DoctypeMeta, filters?: RequestInit): Promise<void>;
96
- /**
97
- * Gets the record for the given doctype and id
98
- * @param doctype - The doctype to get record for
99
- * @param id - The id of the record to get
100
- * @example
101
- * ```ts
102
- * const doctype = await registry.getMeta('Task')
103
- * await stonecrop.getRecord(doctype, 'TASK-00001')
104
- * ```
105
- */
106
- getRecord(doctype: DoctypeMeta, id: string): Promise<void>;
107
- /**
108
- * Runs the action for the given doctype and id
109
- * @param doctype - The doctype to run action for
110
- * @param action - The action to run
111
- * @param id - The id(s) of the record(s) to run action on
112
- * @example
113
- * ```ts
114
- * const doctype = await registry.getMeta('Task')
115
- * stonecrop.runAction(doctype, 'create')
116
- * ```
117
- * @example
118
- * ```ts
119
- * const doctype = await registry.getMeta('Task')
120
- * stonecrop.runAction(doctype, 'update', ['TASK-00001'])
121
- * ```
122
- * @example
123
- * ```ts
124
- * const doctype = await registry.getMeta('Task')
125
- * stonecrop.runAction(doctype, 'delete', ['TASK-00001'])
126
- * ```
127
- * @example
128
- * ```ts
129
- * const doctype = await registry.getMeta('Task')
130
- * stonecrop.runAction(doctype, 'merge', ['TASK-00001', 'TASK-00002'])
131
- * ```
132
- */
133
- runAction(doctype: DoctypeMeta, action: string, id?: string[]): void;
344
+ * Get records from server (maintains compatibility)
345
+ * @param doctype - The doctype
346
+ */
347
+ getRecords(doctype: DoctypeMeta): Promise<void>;
348
+ /**
349
+ * Get single record from server (maintains compatibility)
350
+ * @param doctype - The doctype
351
+ * @param recordId - The record ID
352
+ */
353
+ getRecord(doctype: DoctypeMeta, recordId: string): Promise<void>;
354
+ /**
355
+ * Ensure doctype section exists in HST store
356
+ * @param slug - The doctype slug
357
+ */
358
+ private ensureDoctypeExists;
359
+ /**
360
+ * Get doctype metadata from the registry
361
+ * @param context - The route context
362
+ * @returns The doctype metadata
363
+ */
364
+ getMeta(context: RouteContext): Promise<any>;
365
+ /**
366
+ * Get the root HST store node for advanced usage
367
+ * @returns Root HST node
368
+ */
369
+ getStore(): HSTNode;
134
370
  }
135
371
  //# sourceMappingURL=stonecrop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stonecrop.d.ts","sourceRoot":"","sources":["../../src/stonecrop.ts"],"names":[],"mappings":"AAEA,OAAO,WAAW,MAAM,WAAW,CAAA;AAEnC,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C;;;GAGG;AACH,qBAAa,SAAS;IACrB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,SAAS,CAAA;IAEvB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,eAAc;IAE3B;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAE3B;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;IAEtC;;;;;;;;;;OAUG;gBACS,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC;IAStE;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIjC;;;;;;;;;;;OAWG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,KAAK;IAO5D;;;;;;;;;;;;;;;OAeG;IACG,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5E;;;;;;;;;OASG;IACG,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;CA6BpE"}
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"}