@kaskad/component-tree 0.0.1 → 0.0.3

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 (136) hide show
  1. package/fesm2022/kaskad-component-tree.mjs +2380 -0
  2. package/fesm2022/kaskad-component-tree.mjs.map +1 -0
  3. package/package.json +10 -10
  4. package/types/kaskad-component-tree.d.ts +582 -0
  5. package/esm2022/index.js +0 -12
  6. package/esm2022/index.js.map +0 -1
  7. package/esm2022/kaskad-component-tree.js +0 -5
  8. package/esm2022/kaskad-component-tree.js.map +0 -1
  9. package/esm2022/lib/component-lookup/index.js +0 -68
  10. package/esm2022/lib/component-lookup/index.js.map +0 -1
  11. package/esm2022/lib/component-lookup/traverses/array-traverser.js +0 -18
  12. package/esm2022/lib/component-lookup/traverses/array-traverser.js.map +0 -1
  13. package/esm2022/lib/component-lookup/traverses/component-traverser.js +0 -120
  14. package/esm2022/lib/component-lookup/traverses/component-traverser.js.map +0 -1
  15. package/esm2022/lib/component-lookup/traverses/index.js +0 -29
  16. package/esm2022/lib/component-lookup/traverses/index.js.map +0 -1
  17. package/esm2022/lib/component-lookup/traverses/object-traverser.js +0 -22
  18. package/esm2022/lib/component-lookup/traverses/object-traverser.js.map +0 -1
  19. package/esm2022/lib/component-lookup/types.js +0 -1
  20. package/esm2022/lib/component-lookup/types.js.map +0 -1
  21. package/esm2022/lib/component-tree-api.js +0 -121
  22. package/esm2022/lib/component-tree-api.js.map +0 -1
  23. package/esm2022/lib/computation/computation-frame.js +0 -27
  24. package/esm2022/lib/computation/computation-frame.js.map +0 -1
  25. package/esm2022/lib/computation/computation-stack.js +0 -83
  26. package/esm2022/lib/computation/computation-stack.js.map +0 -1
  27. package/esm2022/lib/computation/index.js +0 -3
  28. package/esm2022/lib/computation/index.js.map +0 -1
  29. package/esm2022/lib/config.js +0 -6
  30. package/esm2022/lib/config.js.map +0 -1
  31. package/esm2022/lib/mobx/component.js +0 -110
  32. package/esm2022/lib/mobx/component.js.map +0 -1
  33. package/esm2022/lib/mobx/create-root-node.js +0 -21
  34. package/esm2022/lib/mobx/create-root-node.js.map +0 -1
  35. package/esm2022/lib/mobx/ref-space.js +0 -25
  36. package/esm2022/lib/mobx/ref-space.js.map +0 -1
  37. package/esm2022/lib/mobx/store.js +0 -827
  38. package/esm2022/lib/mobx/store.js.map +0 -1
  39. package/esm2022/lib/node/create-node-options.js +0 -16
  40. package/esm2022/lib/node/create-node-options.js.map +0 -1
  41. package/esm2022/lib/node/creators/array-creator.js +0 -9
  42. package/esm2022/lib/node/creators/array-creator.js.map +0 -1
  43. package/esm2022/lib/node/creators/command-creator.js +0 -16
  44. package/esm2022/lib/node/creators/command-creator.js.map +0 -1
  45. package/esm2022/lib/node/creators/component-creator.js +0 -58
  46. package/esm2022/lib/node/creators/component-creator.js.map +0 -1
  47. package/esm2022/lib/node/creators/leaf-creator.js +0 -5
  48. package/esm2022/lib/node/creators/leaf-creator.js.map +0 -1
  49. package/esm2022/lib/node/creators/map-creator.js +0 -14
  50. package/esm2022/lib/node/creators/map-creator.js.map +0 -1
  51. package/esm2022/lib/node/creators/object-creator.js +0 -17
  52. package/esm2022/lib/node/creators/object-creator.js.map +0 -1
  53. package/esm2022/lib/node/creators/set-creator.js +0 -13
  54. package/esm2022/lib/node/creators/set-creator.js.map +0 -1
  55. package/esm2022/lib/node/creators/shape-creator.js +0 -15
  56. package/esm2022/lib/node/creators/shape-creator.js.map +0 -1
  57. package/esm2022/lib/node/creators/variant-shape-creator.js +0 -23
  58. package/esm2022/lib/node/creators/variant-shape-creator.js.map +0 -1
  59. package/esm2022/lib/node/guards.js +0 -5
  60. package/esm2022/lib/node/guards.js.map +0 -1
  61. package/esm2022/lib/node/node-creation.js +0 -47
  62. package/esm2022/lib/node/node-creation.js.map +0 -1
  63. package/esm2022/lib/node/node-type.js +0 -1
  64. package/esm2022/lib/node/node-type.js.map +0 -1
  65. package/esm2022/lib/node/node.js +0 -305
  66. package/esm2022/lib/node/node.js.map +0 -1
  67. package/esm2022/lib/parsers/index.js +0 -3
  68. package/esm2022/lib/parsers/index.js.map +0 -1
  69. package/esm2022/lib/parsers/node-selector.types.js +0 -1
  70. package/esm2022/lib/parsers/node-selector.types.js.map +0 -1
  71. package/esm2022/lib/parsers/parse-component-selector.js +0 -43
  72. package/esm2022/lib/parsers/parse-component-selector.js.map +0 -1
  73. package/esm2022/lib/parsers/parse-node-selector.js +0 -263
  74. package/esm2022/lib/parsers/parse-node-selector.js.map +0 -1
  75. package/esm2022/lib/types/command.js +0 -1
  76. package/esm2022/lib/types/command.js.map +0 -1
  77. package/esm2022/lib/types/index.js +0 -5
  78. package/esm2022/lib/types/index.js.map +0 -1
  79. package/esm2022/lib/types/node.guards.js +0 -7
  80. package/esm2022/lib/types/node.guards.js.map +0 -1
  81. package/esm2022/lib/types/schema.js +0 -1
  82. package/esm2022/lib/types/schema.js.map +0 -1
  83. package/esm2022/lib/util/extract-node-value.js +0 -45
  84. package/esm2022/lib/util/extract-node-value.js.map +0 -1
  85. package/esm2022/lib/util/format-source.js +0 -7
  86. package/esm2022/lib/util/format-source.js.map +0 -1
  87. package/esm2022/lib/util/get-component.js +0 -8
  88. package/esm2022/lib/util/get-component.js.map +0 -1
  89. package/esm2022/lib/util/id-generator.js +0 -10
  90. package/esm2022/lib/util/id-generator.js.map +0 -1
  91. package/esm2022/lib/util/traverse-node.js +0 -50
  92. package/esm2022/lib/util/traverse-node.js.map +0 -1
  93. package/index.d.ts +0 -11
  94. package/kaskad-component-tree.d.ts +0 -5
  95. package/lib/component-lookup/index.d.ts +0 -8
  96. package/lib/component-lookup/traverses/array-traverser.d.ts +0 -3
  97. package/lib/component-lookup/traverses/component-traverser.d.ts +0 -3
  98. package/lib/component-lookup/traverses/index.d.ts +0 -9
  99. package/lib/component-lookup/traverses/object-traverser.d.ts +0 -3
  100. package/lib/component-lookup/types.d.ts +0 -13
  101. package/lib/component-tree-api.d.ts +0 -21
  102. package/lib/computation/computation-frame.d.ts +0 -14
  103. package/lib/computation/computation-stack.d.ts +0 -48
  104. package/lib/computation/index.d.ts +0 -2
  105. package/lib/config.d.ts +0 -4
  106. package/lib/mobx/component.d.ts +0 -45
  107. package/lib/mobx/create-root-node.d.ts +0 -3
  108. package/lib/mobx/ref-space.d.ts +0 -10
  109. package/lib/mobx/store.d.ts +0 -238
  110. package/lib/node/create-node-options.d.ts +0 -12
  111. package/lib/node/creators/array-creator.d.ts +0 -4
  112. package/lib/node/creators/command-creator.d.ts +0 -4
  113. package/lib/node/creators/component-creator.d.ts +0 -4
  114. package/lib/node/creators/leaf-creator.d.ts +0 -4
  115. package/lib/node/creators/map-creator.d.ts +0 -4
  116. package/lib/node/creators/object-creator.d.ts +0 -4
  117. package/lib/node/creators/set-creator.d.ts +0 -4
  118. package/lib/node/creators/shape-creator.d.ts +0 -4
  119. package/lib/node/creators/variant-shape-creator.d.ts +0 -4
  120. package/lib/node/guards.d.ts +0 -3
  121. package/lib/node/node-creation.d.ts +0 -4
  122. package/lib/node/node-type.d.ts +0 -49
  123. package/lib/node/node.d.ts +0 -107
  124. package/lib/parsers/index.d.ts +0 -5
  125. package/lib/parsers/node-selector.types.d.ts +0 -25
  126. package/lib/parsers/parse-component-selector.d.ts +0 -8
  127. package/lib/parsers/parse-node-selector.d.ts +0 -87
  128. package/lib/types/command.d.ts +0 -3
  129. package/lib/types/index.d.ts +0 -4
  130. package/lib/types/node.guards.d.ts +0 -4
  131. package/lib/types/schema.d.ts +0 -13
  132. package/lib/util/extract-node-value.d.ts +0 -3
  133. package/lib/util/format-source.d.ts +0 -1
  134. package/lib/util/get-component.d.ts +0 -4
  135. package/lib/util/id-generator.d.ts +0 -5
  136. package/lib/util/traverse-node.d.ts +0 -26
@@ -0,0 +1,582 @@
1
+ import { ComputationSchema, ValueType, ComponentId, NodePosition, BindingSchema, CommandValueType, ArrayValueType, MapValueType, SetValueType, ObjectValueType, ShapeValueType, VariantShapeValueType, RefSpaceId, ComponentRef, NodeSchema } from '@kaskad/types';
2
+ import { IReactionDisposer } from 'mobx';
3
+
4
+ declare class ComputationFrame {
5
+ readonly schema: ComputationSchema;
6
+ readonly disposers: IReactionDisposer[];
7
+ activated: boolean;
8
+ constructor(schema: ComputationSchema, disposers?: IReactionDisposer[], activated?: boolean);
9
+ /**
10
+ * Mark this computation frame as activated.
11
+ * This is an action that ensures MobX compliance.
12
+ */
13
+ markActivated(): void;
14
+ dispose(): void;
15
+ }
16
+
17
+ /**
18
+ * Manages a stack of computation frames for nested computations.
19
+ * For example: formula → formula → template chain.
20
+ */
21
+ declare class ComputationStack {
22
+ /**
23
+ * Maximum allowed stack depth to prevent infinite recursion.
24
+ */
25
+ static readonly MAX_DEPTH = 10;
26
+ private readonly _frames;
27
+ constructor();
28
+ /**
29
+ * Get the topmost computation frame from the stack.
30
+ * Returns null if stack is empty.
31
+ */
32
+ get top(): ComputationFrame | null;
33
+ /**
34
+ * Returns true if all frames in the stack are activated.
35
+ * Empty stack returns true (vacuously).
36
+ */
37
+ get allActivated(): boolean;
38
+ /**
39
+ * Get the current stack depth.
40
+ */
41
+ get depth(): number;
42
+ /**
43
+ * Check if the stack is empty.
44
+ */
45
+ get isEmpty(): boolean;
46
+ /**
47
+ * Push a new computation frame onto the stack.
48
+ * Throws if depth limit is exceeded.
49
+ */
50
+ push(schema: ComputationSchema): ComputationFrame;
51
+ /**
52
+ * Pop all frames from the given depth onward.
53
+ * For example, if depth=2, this removes frames at indices 2, 3, 4, etc.
54
+ * Useful when a computation at a specific depth re-evaluates and needs
55
+ * to clear its results without affecting parent computations.
56
+ */
57
+ popFrom(depth: number): void;
58
+ /**
59
+ * Dispose all frames in the stack.
60
+ */
61
+ dispose(): void;
62
+ }
63
+
64
+ type NodeType = AbstractNode<ValueType>;
65
+ type NodeStructureMap = {
66
+ unknown: unknown;
67
+ boolean: boolean;
68
+ number: number;
69
+ string: string;
70
+ array: NodeType[];
71
+ map: Record<string, NodeType>;
72
+ set: Set<NodeType>;
73
+ object: Record<string, NodeType>;
74
+ shape: Record<string, NodeType>;
75
+ variantShape: {
76
+ kind: string;
77
+ fields: Record<string, NodeType>;
78
+ };
79
+ command: CommandNodeStructure;
80
+ component: string;
81
+ componentSchema: unknown;
82
+ };
83
+ type NodeExtractedValueMap = {
84
+ unknown: unknown;
85
+ boolean: boolean;
86
+ number: number;
87
+ string: string;
88
+ array: unknown[];
89
+ map: Record<string, unknown>;
90
+ set: Set<unknown>;
91
+ object: Record<string, unknown>;
92
+ shape: unknown;
93
+ variantShape: unknown;
94
+ command: unknown;
95
+ component: ComponentId;
96
+ componentSchema: unknown;
97
+ };
98
+ type CommandNodeViewModel = {
99
+ execute: (...args: unknown[]) => Promise<unknown>;
100
+ executing: boolean;
101
+ failed: boolean;
102
+ };
103
+ type NodeViewModelMap = NodeExtractedValueMap & {
104
+ command: CommandNodeViewModel;
105
+ };
106
+ type NodeStructure<T extends ValueType> = NodeStructureMap[T['type']];
107
+ type NodeExtractedValue<T extends ValueType> = NodeExtractedValueMap[T['type']];
108
+ type NodeViewModel<T extends ValueType> = NodeViewModelMap[T['type']];
109
+
110
+ declare abstract class AbstractNode<T extends ValueType> {
111
+ readonly valueType: T;
112
+ position: NodePosition;
113
+ readonly nodeType: T['type'];
114
+ readonly computationStack: ComputationStack;
115
+ bindingSchema: BindingSchema | null;
116
+ extraBinding?: BindingSchema | null;
117
+ disposers: IReactionDisposer[];
118
+ protected selfEvaluating: boolean;
119
+ protected selfFailed: boolean;
120
+ protected selfActivated: boolean;
121
+ protected constructor(valueType: T, structure: NodeStructure<T> | null, position: NodePosition);
122
+ private _structure;
123
+ get structure(): NodeStructure<T> | null;
124
+ set structure(value: NodeStructure<T>);
125
+ abstract get extractedValue(): NodeExtractedValue<T> | null;
126
+ get evaluating(): boolean;
127
+ set evaluating(evaluating: boolean);
128
+ get failed(): boolean;
129
+ set failed(failed: boolean);
130
+ get fullyActivated(): boolean;
131
+ get computationActivated(): boolean;
132
+ get isSelfActivated(): boolean;
133
+ get viewModel(): NodeViewModel<T> | null;
134
+ protected abstract get childrenEvaluating(): boolean;
135
+ protected abstract get childrenFailed(): boolean;
136
+ protected abstract get childrenActivated(): boolean;
137
+ markActivated(): void;
138
+ dispose(): void;
139
+ /**
140
+ * Find a sub-node by following a path of segments.
141
+ * @param path Array of strings/numbers representing the path to traverse
142
+ * @returns The found node or null if not found/traversal not possible
143
+ */
144
+ abstract getNodeByPath(path: (string | number)[]): AbstractNode<ValueType> | null;
145
+ protected abstract disposeChildren(): void;
146
+ }
147
+ declare class LeafNode<T extends ValueType> extends AbstractNode<T> {
148
+ constructor(valueType: T, structure: NodeStructure<T> | null, position: NodePosition);
149
+ get extractedValue(): NodeExtractedValue<T> | null;
150
+ protected get childrenEvaluating(): boolean;
151
+ protected get childrenFailed(): boolean;
152
+ protected get childrenActivated(): boolean;
153
+ getNodeByPath(path: (string | number)[]): AbstractNode<ValueType> | null;
154
+ protected disposeChildren(): void;
155
+ }
156
+ declare class CommandNode extends LeafNode<CommandValueType> {
157
+ #private;
158
+ inFlight: number;
159
+ constructor(valueType: CommandValueType, structure: NodeStructure<CommandValueType> | null, position: NodePosition);
160
+ get executing(): boolean;
161
+ get viewModel(): NodeViewModel<CommandValueType>;
162
+ }
163
+ declare class ArrayNode extends AbstractNode<ArrayValueType> {
164
+ constructor(valueType: ArrayValueType, structure: NodeStructure<ArrayValueType> | null, position: NodePosition);
165
+ get extractedValue(): NodeExtractedValue<ArrayValueType> | null;
166
+ protected get childrenEvaluating(): boolean;
167
+ protected get childrenFailed(): boolean;
168
+ protected get childrenActivated(): boolean;
169
+ getNodeByPath(path: (string | number)[]): AbstractNode<ValueType> | null;
170
+ protected disposeChildren(): void;
171
+ }
172
+ declare abstract class AbstractObjectLikeNode<T extends ValueType> extends AbstractNode<T> {
173
+ protected constructor(valueType: T, structure: NodeStructure<T> | null, position: NodePosition);
174
+ protected get childrenEvaluating(): boolean;
175
+ protected get childrenFailed(): boolean;
176
+ protected get childrenActivated(): boolean;
177
+ getNodeByPath(path: (string | number)[]): AbstractNode<ValueType> | null;
178
+ protected abstract object(): Record<string, AbstractNode<ValueType>> | null;
179
+ protected disposeChildren(): void;
180
+ protected mapObjectExtracted(): Record<string, unknown> | null;
181
+ }
182
+ declare class MapNode extends AbstractObjectLikeNode<MapValueType> {
183
+ constructor(valueType: MapValueType, structure: NodeStructure<MapValueType> | null, position: NodePosition);
184
+ get extractedValue(): Record<string, unknown> | null;
185
+ protected object(): Record<string, AbstractNode<ValueType>> | null;
186
+ }
187
+ declare class SetNode extends AbstractNode<SetValueType> {
188
+ constructor(valueType: SetValueType, structure: NodeStructure<SetValueType> | null, position: NodePosition);
189
+ get extractedValue(): NodeExtractedValue<SetValueType> | null;
190
+ protected get childrenEvaluating(): boolean;
191
+ protected get childrenFailed(): boolean;
192
+ protected get childrenActivated(): boolean;
193
+ getNodeByPath(path: (string | number)[]): AbstractNode<ValueType> | null;
194
+ protected disposeChildren(): void;
195
+ }
196
+ declare class ObjectNode extends AbstractObjectLikeNode<ObjectValueType> {
197
+ constructor(valueType: ObjectValueType, structure: NodeStructure<ObjectValueType> | null, position: NodePosition);
198
+ get extractedValue(): Record<string, unknown> | null;
199
+ protected object(): Record<string, AbstractNode<ValueType>> | null;
200
+ }
201
+ declare class ShapeNode extends AbstractObjectLikeNode<ShapeValueType> {
202
+ constructor(valueType: ShapeValueType, structure: NodeStructure<ShapeValueType> | null, position: NodePosition);
203
+ get extractedValue(): Record<string, unknown> | null;
204
+ protected object(): Record<string, AbstractNode<ValueType>> | null;
205
+ }
206
+ declare class VariantShapeNode extends AbstractObjectLikeNode<VariantShapeValueType> {
207
+ constructor(valueType: VariantShapeValueType, structure: NodeStructure<VariantShapeValueType> | null, position: NodePosition);
208
+ get extractedValue(): {
209
+ [x: string]: unknown;
210
+ } | null;
211
+ protected object(): Record<string, AbstractNode<ValueType>> | null;
212
+ }
213
+
214
+ interface CommandNodeStructure {
215
+ runnerType: string;
216
+ owner: ComponentId;
217
+ target: string;
218
+ init?: string;
219
+ finalize?: string;
220
+ }
221
+ interface NodeChangeHandler {
222
+ readonly selector: string;
223
+ readonly command: CommandNode;
224
+ }
225
+
226
+ interface CommandRef<_TParams = unknown[], TResult = unknown> {
227
+ execute(...params: unknown[]): Promise<TResult>;
228
+ }
229
+
230
+ declare function isArrayNode(node: AbstractNode<ValueType>): node is ArrayNode;
231
+ declare function isCommandNode(node: AbstractNode<ValueType>): node is CommandNode;
232
+
233
+ type SelectorSegmentModifier = null | ':' | '^' | '&';
234
+ interface SelectorSegment {
235
+ qualifier: string;
236
+ modifier: SelectorSegmentModifier;
237
+ conditions: string[][];
238
+ index?: number;
239
+ }
240
+
241
+ interface ComponentSelectorInfo {
242
+ /**
243
+ * Component selector segments (e.g., &ref, :Type, ^Parent with conditions).
244
+ */
245
+ selector: SelectorSegment[];
246
+ /**
247
+ * If true, uses ?-> instead of ->,
248
+ * meaning it should return null instead of throwing if the component is not found.
249
+ */
250
+ optional: boolean;
251
+ }
252
+ interface NodeSelector {
253
+ kind: 'property' | 'variable';
254
+ head: string;
255
+ tail: PathSegment[];
256
+ /**
257
+ * If present, the selector references another component.
258
+ */
259
+ component?: ComponentSelectorInfo;
260
+ }
261
+ interface PathSegment {
262
+ key: string | number;
263
+ optional: boolean;
264
+ }
265
+
266
+ interface ComponentCreateConfig {
267
+ id: ComponentId;
268
+ componentType: string;
269
+ position: NodePosition;
270
+ refSpaceId: RefSpaceId;
271
+ props: Map<string, AbstractNode<ValueType>>;
272
+ variables: Map<string, AbstractNode<ValueType>>;
273
+ onNodeChange: NodeChangeHandler[];
274
+ sourceUrl?: string;
275
+ }
276
+ declare class TComponent {
277
+ readonly id: ComponentId;
278
+ readonly position: NodePosition;
279
+ readonly refSpaceId: RefSpaceId;
280
+ sourceUrl: string | null;
281
+ componentType: string;
282
+ props: Map<string, AbstractNode<ValueType>>;
283
+ variables: Map<string, AbstractNode<ValueType>>;
284
+ onNodeChange: NodeChangeHandler[];
285
+ handlerDisposers: IReactionDisposer[];
286
+ constructor(config: ComponentCreateConfig);
287
+ setVariable(variableName: string, node: AbstractNode<ValueType>): void;
288
+ /**
289
+ * Find a node by selector. Returns null if the node is not found.
290
+ * This is an alias for getNode for consistency with ComponentStore's API.
291
+ */
292
+ findNode(nodeSelector: string): AbstractNode<ValueType> | null;
293
+ /**
294
+ * Get a node by selector. Throws an error if the node is not found.
295
+ * Use findNode() for optional lookups that return null instead of throwing.
296
+ *
297
+ * Note: Even if the selector contains optional chaining (?.), this method will throw
298
+ * if the node is not found. Use findNode() for optional chaining support.
299
+ */
300
+ getNode(nodeSelector: string): AbstractNode<ValueType>;
301
+ findNodeFromParsed(parsed: Omit<NodeSelector, 'componentSelector'>): AbstractNode<ValueType> | null;
302
+ getNodeFromParsed(parsed: Omit<NodeSelector, 'componentSelector'>): AbstractNode<ValueType>;
303
+ getNodeValue<T>(nodeSelector: string): T | null;
304
+ dispose(): void;
305
+ }
306
+
307
+ declare class RefSpace {
308
+ id: RefSpaceId;
309
+ parentRefSpaceId: RefSpaceId | null;
310
+ private readonly byRef;
311
+ constructor(id: RefSpaceId, parentRefSpaceId?: RefSpaceId | null);
312
+ get refs(): Map<string, string>;
313
+ addRefs(refs: Record<ComponentRef, ComponentId>): void;
314
+ getComponentIdByRef(ref: string): ComponentId | null;
315
+ }
316
+
317
+ declare class ComponentStore {
318
+ private static instance;
319
+ components: Map<ComponentId, TComponent>;
320
+ refSpaces: Map<RefSpaceId, RefSpace>;
321
+ componentsToPreload: Set<string>;
322
+ private componentsByRefSpace;
323
+ static getInstance(): ComponentStore;
324
+ static reset(): ComponentStore;
325
+ addRefSpace(refSpace: RefSpace): void;
326
+ addComponents(components: Record<ComponentId, TComponent>): void;
327
+ getRefSpace(refSpaceId: RefSpaceId): RefSpace | null;
328
+ getRefSpaceOrThrow(refSpaceId: RefSpaceId): RefSpace;
329
+ getComponent(componentId: string): TComponent | null;
330
+ getComponentOrThrow(componentId: string): TComponent;
331
+ findVariable(componentId: ComponentId, variableName: string): AbstractNode<ValueType> | null;
332
+ /**
333
+ * Find a single component using a selector relative to another component.
334
+ * Throws if multiple components match the selector.
335
+ *
336
+ * @param relativeTo - The component ID to search relative to
337
+ * @param selector - Component selector string (e.g., 'Button', '&myRef', '^parent', ':button', 'Button[disabled=true]')
338
+ * @returns The matching component or null if not found
339
+ * @throws If the selector matches multiple components
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * const button = store.findComponent(componentId, 'Button');
344
+ * const aliased = store.findComponent(componentId, '&myRef');
345
+ * const parent = store.findComponent(componentId, '^parent');
346
+ * const byType = store.findComponent(componentId, ':button');
347
+ * const filtered = store.findComponent(componentId, 'Button[disabled=true]');
348
+ * ```
349
+ */
350
+ findComponent(relativeTo: ComponentId, selector: string): TComponent | null;
351
+ /**
352
+ * Find all components matching a selector relative to another component.
353
+ *
354
+ * @param relativeTo - The component ID to search relative to
355
+ * @param selector - Component selector string (e.g., 'Button', '&myRef', ':button', 'Button[disabled=true]')
356
+ * @returns Array of matching components (empty if none found)
357
+ *
358
+ * @example
359
+ * ```typescript
360
+ * const buttons = store.findComponents(componentId, 'Button');
361
+ * const allOfType = store.findComponents(componentId, ':button');
362
+ * const filtered = store.findComponents(componentId, 'Button[disabled=true]');
363
+ * ```
364
+ */
365
+ findComponents(relativeTo: ComponentId, selector: string): TComponent[];
366
+ /**
367
+ * Get a node by selector relative to a component.
368
+ * Throws an error if the component or node is not found.
369
+ * Use findNode() for optional lookups that return null instead of throwing.
370
+ *
371
+ * Note: Even if the selector contains optional chaining (?.), this method will throw
372
+ * if the node is not found. Use findNode() for optional chaining support.
373
+ *
374
+ * Component selector behavior:
375
+ * - `&ref->value` - Throws if component with ref doesn't exist
376
+ * - `&ref?->value` - Throws if node not found, but allows missing component (returns null for the whole expression)
377
+ *
378
+ * @param relativeTo - The component ID to search relative to
379
+ * @param selector - Node selector string (e.g., 'prop', '$variable', '^Parent->prop', '&ref?->value')
380
+ * @returns The node
381
+ * @throws If the component or node is not found (unless using ?-> for component)
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const node = store.getNode(componentId, 'requiredProp'); // throws if not found
386
+ * const optionalNode = store.findNode(componentId, 'user?.profile'); // returns null if not found
387
+ * const optionalComponent = store.getNode(componentId, '&optional?->value'); // throws only if value missing, not if component missing
388
+ * ```
389
+ */
390
+ getNode<T extends AbstractNode<ValueType>>(relativeTo: ComponentId, selector: string): T;
391
+ /**
392
+ * Find a node by selector relative to a component.
393
+ * Returns null if the node is not found.
394
+ *
395
+ * Component selector behavior:
396
+ * - `&ref->value` - Throws if component doesn't exist (strict by default)
397
+ * - `&ref?->value` - Returns null if component doesn't exist (lenient when explicit)
398
+ *
399
+ * Use `?->` to explicitly indicate that a missing component is acceptable.
400
+ * This makes the code self-documenting and prevents accidental null returns.
401
+ *
402
+ * @param relativeTo - The component ID to search relative to
403
+ * @param selector - Node selector string (e.g., 'prop', '$variable', '^Parent->prop', '&ref?->value')
404
+ * @returns The node or null if not found
405
+ *
406
+ * @example
407
+ * ```typescript
408
+ * // Strict - throws if component missing
409
+ * const node = store.findNode(componentId, '&ref->value');
410
+ *
411
+ * // Lenient - returns null if component missing
412
+ * const optionalNode = store.findNode(componentId, '&ref?->value');
413
+ * if (optionalNode) {
414
+ * // Use the node
415
+ * }
416
+ * ```
417
+ */
418
+ findNode<T extends AbstractNode<ValueType>>(relativeTo: ComponentId, selector: string): T | null;
419
+ /**
420
+ * Collect node values from multiple components into an array.
421
+ * Maps over all components matching the selector and extracts a node value from each.
422
+ *
423
+ * @param relativeTo - The component ID to search relative to
424
+ * @param componentSelector - Selector for finding components (e.g., ':forms.Input', 'Button')
425
+ * @param nodeSelector - The node path to extract from each component (e.g., 'value', 'inputKey')
426
+ * @returns Array of node values from matched components
427
+ *
428
+ * @example
429
+ * ```typescript
430
+ * // Get all input values
431
+ * const values = store.collectValuesArray(componentId, ':forms.Input', 'value');
432
+ * // Returns: ['value1', 'value2', 'value3']
433
+ * ```
434
+ */
435
+ collectValuesArray<T = unknown[]>(relativeTo: ComponentId, componentSelector: string, nodeSelector: string): T;
436
+ /**
437
+ * Collect node values from multiple components into a map/object.
438
+ * Reduces over all components matching the selector, using one node as the key and another as the value.
439
+ *
440
+ * @param relativeTo - The component ID to search relative to
441
+ * @param componentSelector - Selector for finding components (e.g., ':forms.Input', 'Button')
442
+ * @param keyNodeSelector - The node path to use as the object key (e.g., 'inputKey', 'id')
443
+ * @param valueNodeSelector - The node path to use as the object value (e.g., 'value', 'label')
444
+ * @returns Object/map with keys and values from matched components
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * // Create a map from inputKey to value
449
+ * const map = store.collectValuesMap(componentId, ':forms.Input', 'inputKey', 'value');
450
+ * // Returns: { key1: 'value1', key2: 'value2' }
451
+ * ```
452
+ */
453
+ collectValuesMap<T = Record<string, unknown>>(relativeTo: ComponentId, componentSelector: string, keyNodeSelector: string, valueNodeSelector: string): T;
454
+ /**
455
+ * Set a node from a raw schema value.
456
+ * The raw schema will be unfolded before being applied.
457
+ * Handles structure, computation stack, and nested components.
458
+ *
459
+ * @param node - The node to update
460
+ * @param rawSchema - The raw schema value (will be unfolded into a NodeSchema)
461
+ */
462
+ setNodeRawSchema(node: AbstractNode<ValueType>, rawSchema: unknown): void;
463
+ /**
464
+ * Set a node from an already-unfolded schema.
465
+ * Use this when you already have a NodeSchema to avoid double-unfolding.
466
+ * Handles structure, nested components, and computation stack.
467
+ *
468
+ * @param node - The node to update
469
+ * @param schema - The unfolded NodeSchema to set
470
+ */
471
+ setNodeSchema(node: AbstractNode<ValueType>, schema: NodeSchema): void;
472
+ /**
473
+ * Remove an item from an array node.
474
+ * Handles cleanup of nested components in the removed item.
475
+ *
476
+ * @param arrayNode - The array node to remove from
477
+ * @param index - The index of the item to remove
478
+ */
479
+ removeArrayItem(arrayNode: ArrayNode, index: number): void;
480
+ /**
481
+ * Insert an item into an array node at a specific index.
482
+ * Creates a node structure from the raw value and inserts it at the specified position.
483
+ * Shifts existing items to the right.
484
+ *
485
+ * @param arrayNode - The array node to insert into
486
+ * @param index - The index at which to insert the item
487
+ * @param value - The raw value to insert (will be transformed into a node structure)
488
+ */
489
+ insertArrayItem(arrayNode: ArrayNode, index: number, value: unknown): void;
490
+ /**
491
+ * Replace an item in an array node at a specific index.
492
+ * Creates a node structure from the raw value and replaces the item at the specified position.
493
+ * Properly cleans up nested components in the replaced item.
494
+ *
495
+ * @param arrayNode - The array node containing the item to replace
496
+ * @param index - The index of the item to replace
497
+ * @param value - The raw value to set (will be transformed into a node structure)
498
+ */
499
+ replaceArrayItem(arrayNode: ArrayNode, index: number, value: unknown): void;
500
+ /**
501
+ * Append an item to the end of an array node.
502
+ * Creates a node structure from the raw value and appends it to the array.
503
+ *
504
+ * @param arrayNode - The array node to append to
505
+ * @param value - The raw value to append (will be transformed into a node structure)
506
+ */
507
+ appendArrayItem(arrayNode: ArrayNode, value: unknown): void;
508
+ /**
509
+ * Reconcile for-loop children using key-based diffing.
510
+ * Instead of destroying all children and recreating them,
511
+ * this method compares old vs new keys and only creates/destroys what's necessary.
512
+ *
513
+ * @param arrayNode - The array node containing for-loop children
514
+ * @param newSchemas - The new schemas to reconcile
515
+ * @returns Indices of newly added items for activation
516
+ */
517
+ reconcileForLoopChildren(arrayNode: ArrayNode, newSchemas: unknown[]): number[];
518
+ /**
519
+ * Apply for-loop reconciliation by building new structure and cleaning up removed components.
520
+ */
521
+ private applyForLoopReconciliation;
522
+ /**
523
+ * Update loop variables (including item variable) on components that have been repositioned or whose data changed.
524
+ */
525
+ private updateLoopVariables;
526
+ /**
527
+ * Check if schemas have explicit trackBy keys that can be used for diffing.
528
+ */
529
+ private checkForExplicitKeys;
530
+ /**
531
+ * Extract keys from existing children (RefSpace components with $trackBy variable)
532
+ */
533
+ private extractOldKeys;
534
+ /**
535
+ * Extract keys from new schemas (generated by repeat())
536
+ */
537
+ private extractNewKeys;
538
+ /**
539
+ * Find duplicate keys in an array
540
+ */
541
+ private findDuplicateKeys;
542
+ removeComponent(componentId: ComponentId): void;
543
+ /**
544
+ * Creates a new node for an array item from a raw value.
545
+ * Returns the created node and the options used (for registering components/refs).
546
+ * @throws If the array node has no parent component
547
+ */
548
+ private createArrayItemNode;
549
+ private collectRefSpacesToRemove;
550
+ }
551
+
552
+ declare function createRootNode(refSpaceId: RefSpaceId, schema: NodeSchema, ownerComponentId: ComponentId | null, parentRefSpaceId: RefSpaceId | null, sourceUrl?: string): AbstractNode<ValueType>;
553
+
554
+ declare function getComponent(node: AbstractNode<ValueType>): TComponent;
555
+
556
+ declare function formatSource(sourceUrl: string | null | undefined, path?: (string | number)[]): string;
557
+
558
+ declare const componentTreeConfig: {
559
+ runCommand: (_node: CommandNode, ..._args: unknown[]) => Promise<unknown>;
560
+ };
561
+
562
+ declare class ComponentTreeApi {
563
+ private static store;
564
+ static findComponent(relativeTo: ComponentId, componentSelector: string): TComponent | null;
565
+ static findComponentsIds(relativeTo: ComponentId, componentSelector: string): ComponentId[];
566
+ static findComponents(relativeTo: ComponentId, componentSelector: string): TComponent[];
567
+ static getComponent(relativeTo: ComponentId, componentSelector: string): TComponent;
568
+ static findNode(relativeTo: ComponentId, componentSelector: string): AbstractNode<ValueType> | null;
569
+ static getNode(relativeTo: ComponentId, componentSelector: string): AbstractNode<ValueType>;
570
+ static collectValuesArray<T>(componentId: ComponentId, componentSelector: string, nodeSelector: string): T;
571
+ static collectValuesMap<T>(componentId: ComponentId, componentSelector: string, keyNodeSelector: string, valueNodeSelector: string): T;
572
+ static isCommandRunning(componentId: ComponentId, selector: string): boolean;
573
+ static runCommandNode(componentId: ComponentId, selector: string, ...args: unknown[]): unknown;
574
+ static setNodeRawSchema(componentId: ComponentId, selector: string, value: unknown): void;
575
+ static appendArrayItem(componentId: ComponentId, selector: string, item: unknown): void;
576
+ static insertArrayItem(componentId: ComponentId, selector: string, index: number, item: unknown): void;
577
+ static removeArrayItem(componentId: ComponentId, selector: string, index: number): void;
578
+ static replaceArrayItem(componentId: ComponentId, selector: string, index: number, item: unknown): void;
579
+ }
580
+
581
+ export { AbstractNode, AbstractObjectLikeNode, ArrayNode, CommandNode, ComponentStore, ComponentTreeApi, ComputationFrame, ComputationStack, LeafNode, MapNode, ObjectNode, RefSpace, SetNode, ShapeNode, TComponent, VariantShapeNode, componentTreeConfig, createRootNode, formatSource, getComponent, isArrayNode, isCommandNode };
582
+ export type { CommandNodeStructure, CommandNodeViewModel, CommandRef, ComponentCreateConfig, NodeChangeHandler, NodeExtractedValue, NodeExtractedValueMap, NodeStructure, NodeStructureMap, NodeViewModel, NodeViewModelMap };
package/esm2022/index.js DELETED
@@ -1,12 +0,0 @@
1
- export * from './lib/types';
2
- export * from './lib/node/node';
3
- export * from './lib/node/node-type';
4
- export * from './lib/mobx/component';
5
- export * from './lib/mobx/ref-space';
6
- export * from './lib/mobx/store';
7
- export * from './lib/mobx/create-root-node';
8
- export * from './lib/util/get-component';
9
- export * from './lib/util/format-source';
10
- export * from './lib/config';
11
- export * from './lib/component-tree-api';
12
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/component-tree/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC","sourcesContent":["export * from './lib/types';\nexport * from './lib/node/node';\nexport * from './lib/node/node-type';\nexport * from './lib/mobx/component';\nexport * from './lib/mobx/ref-space';\nexport * from './lib/mobx/store';\nexport * from './lib/mobx/create-root-node';\nexport * from './lib/util/get-component';\nexport * from './lib/util/format-source';\nexport * from './lib/config';\nexport * from './lib/component-tree-api';\n"]}
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- export * from './index';
5
- //# sourceMappingURL=kaskad-component-tree.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"kaskad-component-tree.js","sourceRoot":"","sources":["../../../../libs/component-tree/src/kaskad-component-tree.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC","sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"]}
@@ -1,68 +0,0 @@
1
- import { ComponentStore } from '../mobx/store';
2
- import { parseComponentSelector } from '../parsers';
3
- import { traversesRegistry } from './traverses';
4
- export { parseComponentSelector };
5
- export function findComponent(relativeTo, selector) {
6
- const ids = findComponentsIds(relativeTo, selector);
7
- if (!ids.length) {
8
- return null;
9
- }
10
- if (ids.length > 1) {
11
- throw new Error(`Selector matched ${ids.length} components (expected 1): ${ids.join(', ')}`);
12
- }
13
- return ComponentStore.getInstance().getComponentOrThrow(ids[0]);
14
- }
15
- export function findComponents(relativeTo, selector) {
16
- const ids = findComponentsIds(relativeTo, selector);
17
- return ids.map((componentId) => ComponentStore.getInstance().getComponentOrThrow(componentId));
18
- }
19
- export function findComponentsIds(relativeTo, selector) {
20
- const selectors = [selector];
21
- const foundComponents = [];
22
- for (const parsedSelector of selectors) {
23
- if (parsedSelector.length === 0) {
24
- foundComponents.push(relativeTo);
25
- continue;
26
- }
27
- const startFrom = {
28
- currentNode: {
29
- valueType: { type: 'component' },
30
- value: relativeTo,
31
- },
32
- selectorSegments: parsedSelector,
33
- relativeTo,
34
- };
35
- const nodeQueue = [startFrom];
36
- while (nodeQueue.length > 0) {
37
- const ctx = nodeQueue.shift();
38
- if (!ctx)
39
- break;
40
- const traverser = traversesRegistry.get(ctx.currentNode.valueType.type);
41
- traverser(ctx, nodeQueue, foundComponents);
42
- }
43
- }
44
- const uniqueComponents = Array.from(new Set(foundComponents));
45
- // Apply :nth(N) filtering if the last segment has an index
46
- const lastSegment = selector[selector.length - 1];
47
- if (lastSegment && lastSegment.index !== undefined) {
48
- const index = lastSegment.index;
49
- const actualIndex = index < 0 ? uniqueComponents.length + index : index;
50
- if (actualIndex < 0 || actualIndex >= uniqueComponents.length) {
51
- const selectorStr = selector.map(formatSelectorSegment).join(' ');
52
- throw new Error(`Index ${index} out of bounds for selector "${selectorStr}" (found ${uniqueComponents.length} elements)`);
53
- }
54
- return [uniqueComponents[actualIndex]];
55
- }
56
- return uniqueComponents;
57
- }
58
- function formatSelectorSegment(segment) {
59
- let result = segment.modifier ? segment.modifier + segment.qualifier : segment.qualifier;
60
- if (segment.conditions.length > 0) {
61
- result += segment.conditions.map(([key, value]) => `[${key}=${value}]`).join('');
62
- }
63
- if (segment.index !== undefined) {
64
- result += `:nth(${segment.index})`;
65
- }
66
- return result;
67
- }
68
- //# sourceMappingURL=index.js.map