@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,242 @@
1
+ import { List, Map } from 'immutable';
2
+ /**
3
+ * Doctype runtime class with Immutable.js collections for HST change tracking.
4
+ * @public
5
+ */
6
+ export default class Doctype {
7
+ /**
8
+ * The doctype name
9
+ * @public
10
+ * @readonly
11
+ */
12
+ doctype;
13
+ /**
14
+ * Alias for doctype (for DoctypeLike interface compatibility)
15
+ * @public
16
+ * @readonly
17
+ */
18
+ get name() {
19
+ return this.doctype;
20
+ }
21
+ /**
22
+ * The doctype schema
23
+ * @public
24
+ * @readonly
25
+ */
26
+ schema;
27
+ /**
28
+ * The doctype workflow
29
+ * @public
30
+ * @readonly
31
+ */
32
+ workflow;
33
+ /**
34
+ * The doctype actions and field triggers
35
+ * @public
36
+ * @readonly
37
+ */
38
+ actions;
39
+ /**
40
+ * The doctype component
41
+ * @public
42
+ * @readonly
43
+ */
44
+ component;
45
+ /**
46
+ * Relationship links to other doctypes
47
+ * @public
48
+ * @readonly
49
+ */
50
+ links;
51
+ /**
52
+ * Creates a new Doctype instance
53
+ * @param doctype - The doctype name
54
+ * @param schema - The doctype schema definition
55
+ * @param workflow - The doctype workflow configuration (XState machine)
56
+ * @param actions - The doctype actions and field triggers
57
+ * @param component - Optional Vue component for rendering the doctype
58
+ * @param links - Optional relationship links to other doctypes
59
+ */
60
+ constructor(doctype, schema, workflow, actions, component, links) {
61
+ this.doctype = doctype;
62
+ this.schema = schema;
63
+ this.workflow = workflow;
64
+ this.actions = actions;
65
+ this.component = component;
66
+ this.links = links;
67
+ }
68
+ /**
69
+ * Creates a Doctype instance from a plain configuration object.
70
+ * Handles conversion of arrays to Immutable.js collections internally.
71
+ *
72
+ * This is the recommended way to create a Doctype from API responses
73
+ * or configuration files, as it encapsulates the Immutable.js construction
74
+ * that the framework uses internally.
75
+ *
76
+ * @param config - Plain object with doctype configuration (typically from API response)
77
+ * @returns A new Doctype instance with Immutable.js collections
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * // From an API response
82
+ * const response = await client.getMeta({ doctype: 'plan' })
83
+ * const doctype = Doctype.fromObject(response)
84
+ * registry.addDoctype(doctype)
85
+ * ```
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * // From a configuration object
90
+ * const planDoctype = Doctype.fromObject({
91
+ * name: 'Plan',
92
+ * fields: [
93
+ * { fieldname: 'title', label: 'Title', fieldtype: 'Data' },
94
+ * { fieldname: 'status', label: 'Status', fieldtype: 'Data' },
95
+ * ],
96
+ * workflow: {
97
+ * id: 'plan',
98
+ * initial: 'draft',
99
+ * states: { draft: {}, submitted: {} }
100
+ * }
101
+ * })
102
+ * ```
103
+ *
104
+ * @public
105
+ */
106
+ static fromObject(config) {
107
+ const schema = config.fields ? List(config.fields) : List();
108
+ const actions = config.actions ? Map(config.actions) : Map();
109
+ return new Doctype(config.name, schema, config.workflow, actions, undefined, config.links);
110
+ }
111
+ /**
112
+ * Returns the schema as a plain array for use with components that expect
113
+ * plain JavaScript arrays (e.g., AForm, ATable).
114
+ *
115
+ * @returns Array of schema fields
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * const schemaArray = doctype.getSchemaArray()
120
+ * // Use with AForm
121
+ * <AForm :schema="schemaArray" v-model:data="formData" />
122
+ * ```
123
+ *
124
+ * @public
125
+ */
126
+ getSchemaArray() {
127
+ if (!this.schema)
128
+ return [];
129
+ return this.schema.toArray();
130
+ }
131
+ /**
132
+ * Returns the actions as a plain object for use with components that expect
133
+ * plain JavaScript objects.
134
+ *
135
+ * @returns Object mapping action names to field trigger arrays
136
+ *
137
+ * @public
138
+ */
139
+ getActionsObject() {
140
+ if (!this.actions)
141
+ return {};
142
+ return this.actions.toObject();
143
+ }
144
+ /**
145
+ * Returns the transitions available from a given workflow state, derived from the
146
+ * doctype's workflow configuration. Supports both XState format and WorkflowMeta format.
147
+ *
148
+ * @param currentState - The state name to read transitions from
149
+ * @returns Array of transition descriptors with `name` and `targetState`
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const transitions = doctype.getAvailableTransitions('draft')
154
+ * // [{ name: 'SUBMIT', targetState: 'submitted' }]
155
+ * ```
156
+ *
157
+ * @public
158
+ */
159
+ getAvailableTransitions(currentState) {
160
+ const workflow = this.workflow;
161
+ if (!workflow)
162
+ return [];
163
+ // Check if this is WorkflowMeta format (states is an array) or XState format (states is an object)
164
+ if (Array.isArray(workflow.states)) {
165
+ // WorkflowMeta format: validate state exists and filter actions by allowedStates
166
+ const states = workflow.states;
167
+ if (!states.includes(currentState))
168
+ return [];
169
+ const actions = workflow.actions;
170
+ if (!actions)
171
+ return [];
172
+ return Object.entries(actions)
173
+ .filter(([, actionDef]) => {
174
+ const allowedStates = actionDef.allowedStates;
175
+ // If no allowedStates specified, action is available in all valid states
176
+ if (!allowedStates || allowedStates.length === 0)
177
+ return true;
178
+ return allowedStates.includes(currentState);
179
+ })
180
+ .map(([name]) => ({
181
+ name,
182
+ // WorkflowMeta doesn't define target states - transitions are handled server-side
183
+ targetState: currentState,
184
+ }));
185
+ }
186
+ // XState format: use the on property of the state
187
+ const states = workflow.states;
188
+ if (!states)
189
+ return [];
190
+ const stateConfig = states[currentState];
191
+ if (!stateConfig?.on)
192
+ return [];
193
+ return Object.entries(stateConfig.on).map(([name, target]) => ({
194
+ name,
195
+ targetState: typeof target === 'string' ? target : 'unknown',
196
+ }));
197
+ }
198
+ /**
199
+ * Returns metadata for a specific action, if available.
200
+ * Only works with WorkflowMeta format; returns undefined for XState format.
201
+ *
202
+ * @param actionName - The action name to get metadata for
203
+ * @returns Action metadata or undefined
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * const actionMeta = doctype.getActionMeta('submit')
208
+ * // { label: 'Submit', handler: 'plan:submit', allowedStates: ['draft'] }
209
+ * ```
210
+ *
211
+ * @public
212
+ */
213
+ getActionMeta(actionName) {
214
+ const workflow = this.workflow;
215
+ if (!workflow || !Array.isArray(workflow.states))
216
+ return undefined;
217
+ const actions = workflow.actions;
218
+ return actions?.[actionName];
219
+ }
220
+ /**
221
+ * Converts the registered doctype string to a slug (kebab-case). The following conversions are made:
222
+ * - It replaces camelCase and PascalCase with kebab-case strings
223
+ * - It replaces spaces and underscores with hyphens
224
+ * - It converts the string to lowercase
225
+ *
226
+ * @returns The slugified doctype string
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * const doctype = new Doctype('TaskItem', schema, workflow, actions)
231
+ * console.log(doctype.slug) // 'task-item'
232
+ * ```
233
+ *
234
+ * @public
235
+ */
236
+ get slug() {
237
+ return this.doctype
238
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
239
+ .replace(/[\s_]+/g, '-')
240
+ .toLowerCase();
241
+ }
242
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * NotImplementedError
3
+ * @param message {string} - The error message
4
+ * @class
5
+ * @description This error is thrown when a method has not been implemented
6
+ * @example
7
+ * throw new NotImplementedError('Method not implemented')
8
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error|Error}
9
+ * @public
10
+ */
11
+ export class NotImplementedError extends Error {
12
+ constructor(message = '') {
13
+ super(message);
14
+ this.name = 'NotImplemented';
15
+ }
16
+ }