@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.
- package/fesm2022/kaskad-component-tree.mjs +2380 -0
- package/fesm2022/kaskad-component-tree.mjs.map +1 -0
- package/package.json +10 -10
- package/types/kaskad-component-tree.d.ts +582 -0
- package/esm2022/index.js +0 -12
- package/esm2022/index.js.map +0 -1
- package/esm2022/kaskad-component-tree.js +0 -5
- package/esm2022/kaskad-component-tree.js.map +0 -1
- package/esm2022/lib/component-lookup/index.js +0 -68
- package/esm2022/lib/component-lookup/index.js.map +0 -1
- package/esm2022/lib/component-lookup/traverses/array-traverser.js +0 -18
- package/esm2022/lib/component-lookup/traverses/array-traverser.js.map +0 -1
- package/esm2022/lib/component-lookup/traverses/component-traverser.js +0 -120
- package/esm2022/lib/component-lookup/traverses/component-traverser.js.map +0 -1
- package/esm2022/lib/component-lookup/traverses/index.js +0 -29
- package/esm2022/lib/component-lookup/traverses/index.js.map +0 -1
- package/esm2022/lib/component-lookup/traverses/object-traverser.js +0 -22
- package/esm2022/lib/component-lookup/traverses/object-traverser.js.map +0 -1
- package/esm2022/lib/component-lookup/types.js +0 -1
- package/esm2022/lib/component-lookup/types.js.map +0 -1
- package/esm2022/lib/component-tree-api.js +0 -121
- package/esm2022/lib/component-tree-api.js.map +0 -1
- package/esm2022/lib/computation/computation-frame.js +0 -27
- package/esm2022/lib/computation/computation-frame.js.map +0 -1
- package/esm2022/lib/computation/computation-stack.js +0 -83
- package/esm2022/lib/computation/computation-stack.js.map +0 -1
- package/esm2022/lib/computation/index.js +0 -3
- package/esm2022/lib/computation/index.js.map +0 -1
- package/esm2022/lib/config.js +0 -6
- package/esm2022/lib/config.js.map +0 -1
- package/esm2022/lib/mobx/component.js +0 -110
- package/esm2022/lib/mobx/component.js.map +0 -1
- package/esm2022/lib/mobx/create-root-node.js +0 -21
- package/esm2022/lib/mobx/create-root-node.js.map +0 -1
- package/esm2022/lib/mobx/ref-space.js +0 -25
- package/esm2022/lib/mobx/ref-space.js.map +0 -1
- package/esm2022/lib/mobx/store.js +0 -827
- package/esm2022/lib/mobx/store.js.map +0 -1
- package/esm2022/lib/node/create-node-options.js +0 -16
- package/esm2022/lib/node/create-node-options.js.map +0 -1
- package/esm2022/lib/node/creators/array-creator.js +0 -9
- package/esm2022/lib/node/creators/array-creator.js.map +0 -1
- package/esm2022/lib/node/creators/command-creator.js +0 -16
- package/esm2022/lib/node/creators/command-creator.js.map +0 -1
- package/esm2022/lib/node/creators/component-creator.js +0 -58
- package/esm2022/lib/node/creators/component-creator.js.map +0 -1
- package/esm2022/lib/node/creators/leaf-creator.js +0 -5
- package/esm2022/lib/node/creators/leaf-creator.js.map +0 -1
- package/esm2022/lib/node/creators/map-creator.js +0 -14
- package/esm2022/lib/node/creators/map-creator.js.map +0 -1
- package/esm2022/lib/node/creators/object-creator.js +0 -17
- package/esm2022/lib/node/creators/object-creator.js.map +0 -1
- package/esm2022/lib/node/creators/set-creator.js +0 -13
- package/esm2022/lib/node/creators/set-creator.js.map +0 -1
- package/esm2022/lib/node/creators/shape-creator.js +0 -15
- package/esm2022/lib/node/creators/shape-creator.js.map +0 -1
- package/esm2022/lib/node/creators/variant-shape-creator.js +0 -23
- package/esm2022/lib/node/creators/variant-shape-creator.js.map +0 -1
- package/esm2022/lib/node/guards.js +0 -5
- package/esm2022/lib/node/guards.js.map +0 -1
- package/esm2022/lib/node/node-creation.js +0 -47
- package/esm2022/lib/node/node-creation.js.map +0 -1
- package/esm2022/lib/node/node-type.js +0 -1
- package/esm2022/lib/node/node-type.js.map +0 -1
- package/esm2022/lib/node/node.js +0 -305
- package/esm2022/lib/node/node.js.map +0 -1
- package/esm2022/lib/parsers/index.js +0 -3
- package/esm2022/lib/parsers/index.js.map +0 -1
- package/esm2022/lib/parsers/node-selector.types.js +0 -1
- package/esm2022/lib/parsers/node-selector.types.js.map +0 -1
- package/esm2022/lib/parsers/parse-component-selector.js +0 -43
- package/esm2022/lib/parsers/parse-component-selector.js.map +0 -1
- package/esm2022/lib/parsers/parse-node-selector.js +0 -263
- package/esm2022/lib/parsers/parse-node-selector.js.map +0 -1
- package/esm2022/lib/types/command.js +0 -1
- package/esm2022/lib/types/command.js.map +0 -1
- package/esm2022/lib/types/index.js +0 -5
- package/esm2022/lib/types/index.js.map +0 -1
- package/esm2022/lib/types/node.guards.js +0 -7
- package/esm2022/lib/types/node.guards.js.map +0 -1
- package/esm2022/lib/types/schema.js +0 -1
- package/esm2022/lib/types/schema.js.map +0 -1
- package/esm2022/lib/util/extract-node-value.js +0 -45
- package/esm2022/lib/util/extract-node-value.js.map +0 -1
- package/esm2022/lib/util/format-source.js +0 -7
- package/esm2022/lib/util/format-source.js.map +0 -1
- package/esm2022/lib/util/get-component.js +0 -8
- package/esm2022/lib/util/get-component.js.map +0 -1
- package/esm2022/lib/util/id-generator.js +0 -10
- package/esm2022/lib/util/id-generator.js.map +0 -1
- package/esm2022/lib/util/traverse-node.js +0 -50
- package/esm2022/lib/util/traverse-node.js.map +0 -1
- package/index.d.ts +0 -11
- package/kaskad-component-tree.d.ts +0 -5
- package/lib/component-lookup/index.d.ts +0 -8
- package/lib/component-lookup/traverses/array-traverser.d.ts +0 -3
- package/lib/component-lookup/traverses/component-traverser.d.ts +0 -3
- package/lib/component-lookup/traverses/index.d.ts +0 -9
- package/lib/component-lookup/traverses/object-traverser.d.ts +0 -3
- package/lib/component-lookup/types.d.ts +0 -13
- package/lib/component-tree-api.d.ts +0 -21
- package/lib/computation/computation-frame.d.ts +0 -14
- package/lib/computation/computation-stack.d.ts +0 -48
- package/lib/computation/index.d.ts +0 -2
- package/lib/config.d.ts +0 -4
- package/lib/mobx/component.d.ts +0 -45
- package/lib/mobx/create-root-node.d.ts +0 -3
- package/lib/mobx/ref-space.d.ts +0 -10
- package/lib/mobx/store.d.ts +0 -238
- package/lib/node/create-node-options.d.ts +0 -12
- package/lib/node/creators/array-creator.d.ts +0 -4
- package/lib/node/creators/command-creator.d.ts +0 -4
- package/lib/node/creators/component-creator.d.ts +0 -4
- package/lib/node/creators/leaf-creator.d.ts +0 -4
- package/lib/node/creators/map-creator.d.ts +0 -4
- package/lib/node/creators/object-creator.d.ts +0 -4
- package/lib/node/creators/set-creator.d.ts +0 -4
- package/lib/node/creators/shape-creator.d.ts +0 -4
- package/lib/node/creators/variant-shape-creator.d.ts +0 -4
- package/lib/node/guards.d.ts +0 -3
- package/lib/node/node-creation.d.ts +0 -4
- package/lib/node/node-type.d.ts +0 -49
- package/lib/node/node.d.ts +0 -107
- package/lib/parsers/index.d.ts +0 -5
- package/lib/parsers/node-selector.types.d.ts +0 -25
- package/lib/parsers/parse-component-selector.d.ts +0 -8
- package/lib/parsers/parse-node-selector.d.ts +0 -87
- package/lib/types/command.d.ts +0 -3
- package/lib/types/index.d.ts +0 -4
- package/lib/types/node.guards.d.ts +0 -4
- package/lib/types/schema.d.ts +0 -13
- package/lib/util/extract-node-value.d.ts +0 -3
- package/lib/util/format-source.d.ts +0 -1
- package/lib/util/get-component.d.ts +0 -4
- package/lib/util/id-generator.d.ts +0 -5
- 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
|
package/esm2022/index.js.map
DELETED
|
@@ -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 +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
|