@webstudio-is/react-sdk 0.90.0 → 0.92.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 (108) hide show
  1. package/lib/app/index.js +1 -0
  2. package/lib/app/root.js +2 -4
  3. package/lib/component-renderer.js +3 -5
  4. package/lib/components/component-meta.js +6 -11
  5. package/lib/components/components-utils.js +1 -0
  6. package/lib/context.js +2 -4
  7. package/lib/css/css.js +4 -9
  8. package/lib/css/global-rules.js +3 -5
  9. package/lib/css/index.js +1 -0
  10. package/lib/css/normalize-type-check.js +1 -0
  11. package/lib/css/normalize.js +48 -96
  12. package/lib/css/presets.js +3 -6
  13. package/lib/css/style-rules.js +3 -6
  14. package/{src/css/style-rules.test.ts → lib/css/style-rules.test.js} +23 -28
  15. package/lib/embed-template.js +7 -22
  16. package/{src/embed-template.test.ts → lib/embed-template.test.js} +165 -176
  17. package/lib/expression.js +11 -22
  18. package/{src/expression.test.ts → lib/expression.test.js} +55 -83
  19. package/lib/generator.js +2 -4
  20. package/{src/generator.test.ts → lib/generator.test.js} +28 -31
  21. package/lib/hook.js +2 -4
  22. package/{src/hook.test.ts → lib/hook.test.js} +4 -4
  23. package/lib/index.js +9 -31
  24. package/lib/instance-utils.js +2 -4
  25. package/{src/instance-utils.test.ts → lib/instance-utils.test.js} +19 -43
  26. package/lib/prop-meta.js +150 -0
  27. package/lib/props.js +8 -16
  28. package/{src/props.test.ts → lib/props.test.js} +39 -68
  29. package/lib/pubsub/create.js +2 -4
  30. package/lib/pubsub/index.js +1 -0
  31. package/lib/pubsub/raf-queue.js +2 -4
  32. package/lib/tree/create-elements-tree.js +2 -4
  33. package/lib/tree/index.js +1 -0
  34. package/lib/tree/root.js +2 -5
  35. package/lib/tree/webstudio-component.js +10 -20
  36. package/lib/types/component-renderer.d.ts +1 -1
  37. package/lib/types/components/component-meta.d.ts +526 -526
  38. package/lib/types/context.d.ts +1 -2
  39. package/lib/types/css/css.d.ts +22 -23
  40. package/lib/types/css/global-rules.d.ts +19 -19
  41. package/lib/types/css/normalize.d.ts +2444 -2444
  42. package/lib/types/css/style-rules.d.ts +2 -2
  43. package/lib/types/embed-template.d.ts +648 -648
  44. package/lib/types/generator.d.ts +1 -1
  45. package/lib/types/hook.d.ts +3 -3
  46. package/lib/types/index.d.ts +1 -0
  47. package/lib/types/instance-utils.d.ts +3 -3
  48. package/lib/types/prop-meta.d.ts +396 -0
  49. package/lib/types/props.d.ts +52 -53
  50. package/lib/types/tree/create-elements-tree.d.ts +3 -4
  51. package/lib/types/tree/root.d.ts +8 -8
  52. package/lib/types/tree/webstudio-component.d.ts +1 -1
  53. package/package.json +14 -22
  54. package/lib/cjs/app/index.js +0 -18
  55. package/lib/cjs/app/root.js +0 -40
  56. package/lib/cjs/component-renderer.js +0 -143
  57. package/lib/cjs/components/component-meta.js +0 -87
  58. package/lib/cjs/components/components-utils.js +0 -17
  59. package/lib/cjs/context.js +0 -43
  60. package/lib/cjs/css/css.js +0 -84
  61. package/lib/cjs/css/global-rules.js +0 -37
  62. package/lib/cjs/css/index.js +0 -20
  63. package/lib/cjs/css/normalize-type-check.js +0 -26
  64. package/lib/cjs/css/normalize.js +0 -349
  65. package/lib/cjs/css/presets.js +0 -48
  66. package/lib/cjs/css/style-rules.js +0 -86
  67. package/lib/cjs/embed-template.js +0 -368
  68. package/lib/cjs/expression.js +0 -371
  69. package/lib/cjs/generator.js +0 -128
  70. package/lib/cjs/hook.js +0 -34
  71. package/lib/cjs/index.js +0 -59
  72. package/lib/cjs/instance-utils.js +0 -65
  73. package/lib/cjs/package.json +0 -1
  74. package/lib/cjs/props.js +0 -204
  75. package/lib/cjs/pubsub/create.js +0 -78
  76. package/lib/cjs/pubsub/index.js +0 -18
  77. package/lib/cjs/pubsub/raf-queue.js +0 -42
  78. package/lib/cjs/tree/create-elements-tree.js +0 -152
  79. package/lib/cjs/tree/index.js +0 -20
  80. package/lib/cjs/tree/root.js +0 -100
  81. package/lib/cjs/tree/webstudio-component.js +0 -91
  82. package/src/app/index.ts +0 -1
  83. package/src/app/root.tsx +0 -25
  84. package/src/component-renderer.tsx +0 -146
  85. package/src/components/component-meta.ts +0 -86
  86. package/src/components/components-utils.ts +0 -13
  87. package/src/context.tsx +0 -73
  88. package/src/css/css.ts +0 -88
  89. package/src/css/global-rules.ts +0 -26
  90. package/src/css/index.ts +0 -3
  91. package/src/css/normalize-type-check.ts +0 -13
  92. package/src/css/normalize.ts +0 -507
  93. package/src/css/presets.ts +0 -27
  94. package/src/css/style-rules.ts +0 -101
  95. package/src/embed-template.ts +0 -438
  96. package/src/expression.ts +0 -401
  97. package/src/generator.ts +0 -147
  98. package/src/hook.ts +0 -52
  99. package/src/index.ts +0 -39
  100. package/src/instance-utils.ts +0 -65
  101. package/src/props.ts +0 -231
  102. package/src/pubsub/create.ts +0 -77
  103. package/src/pubsub/index.ts +0 -1
  104. package/src/pubsub/raf-queue.ts +0 -25
  105. package/src/tree/create-elements-tree.tsx +0 -186
  106. package/src/tree/index.ts +0 -3
  107. package/src/tree/root.ts +0 -131
  108. package/src/tree/webstudio-component.tsx +0 -97
package/src/expression.ts DELETED
@@ -1,401 +0,0 @@
1
- import jsep from "jsep";
2
- import jsepAssignment from "@jsep-plugin/assignment";
3
- import type {
4
- UpdateExpression,
5
- AssignmentExpression,
6
- } from "@jsep-plugin/assignment";
7
-
8
- jsep.plugins.register(jsepAssignment);
9
-
10
- type TransformIdentifier = (id: string, assignee: boolean) => string;
11
-
12
- type Node = jsep.CoreExpression | UpdateExpression | AssignmentExpression;
13
-
14
- const generateCode = (
15
- node: Node,
16
- failOnForbidden: boolean,
17
- effectful: boolean,
18
- transformIdentifier: TransformIdentifier
19
- ): string => {
20
- if (node.type === "Identifier") {
21
- return transformIdentifier(node.name, false);
22
- }
23
- if (node.type === "MemberExpression") {
24
- if (failOnForbidden) {
25
- const object = generateCode(
26
- node.object as Node,
27
- false,
28
- effectful,
29
- transformIdentifier
30
- );
31
- const property = generateCode(
32
- node.property as Node,
33
- false,
34
- effectful,
35
- transformIdentifier
36
- );
37
- throw Error(`Cannot access "${property}" of "${object}"`);
38
- }
39
- const object = generateCode(
40
- node.object as Node,
41
- failOnForbidden,
42
- effectful,
43
- transformIdentifier
44
- );
45
- const property = generateCode(
46
- node.property as Node,
47
- failOnForbidden,
48
- effectful,
49
- transformIdentifier
50
- );
51
- return `${object}.${property}`;
52
- }
53
- if (node.type === "Literal") {
54
- return node.raw;
55
- }
56
- if (node.type === "UnaryExpression") {
57
- const arg = generateCode(
58
- node.argument as Node,
59
- failOnForbidden,
60
- effectful,
61
- transformIdentifier
62
- );
63
- return `${node.operator}${arg}`;
64
- }
65
- if (node.type === "BinaryExpression") {
66
- const left = generateCode(
67
- node.left as Node,
68
- failOnForbidden,
69
- effectful,
70
- transformIdentifier
71
- );
72
- const right = generateCode(
73
- node.right as Node,
74
- failOnForbidden,
75
- effectful,
76
- transformIdentifier
77
- );
78
- return `${left} ${node.operator} ${right}`;
79
- }
80
- if (node.type === "ArrayExpression") {
81
- const elements = node.elements.map((element) =>
82
- generateCode(
83
- element as Node,
84
- failOnForbidden,
85
- effectful,
86
- transformIdentifier
87
- )
88
- );
89
- return `[${elements.join(", ")}]`;
90
- }
91
- if (node.type === "CallExpression") {
92
- if (failOnForbidden) {
93
- const callee = generateCode(
94
- node.callee as Node,
95
- false,
96
- effectful,
97
- transformIdentifier
98
- );
99
- throw Error(`Cannot call "${callee}"`);
100
- }
101
- const callee = generateCode(
102
- node.callee as Node,
103
- failOnForbidden,
104
- effectful,
105
- transformIdentifier
106
- );
107
- const args = node.arguments.map((arg) =>
108
- generateCode(arg as Node, failOnForbidden, effectful, transformIdentifier)
109
- );
110
- return `${callee}(${args.join(", ")})`;
111
- }
112
- if (node.type === "ThisExpression") {
113
- if (failOnForbidden) {
114
- throw Error(`"this" is not supported`);
115
- }
116
- return "this";
117
- }
118
- if (node.type === "ConditionalExpression") {
119
- throw Error("Ternary operator is not supported");
120
- }
121
- if (node.type === "Compound") {
122
- throw Error("Cannot use multiple expressions");
123
- }
124
- if (node.type === "AssignmentExpression") {
125
- if (node.operator !== "=") {
126
- throw Error(`Only "=" assignment operator is supported`);
127
- }
128
- if (effectful === false) {
129
- throw Error(`Cannot use assignment in this expression`);
130
- }
131
- const left = generateCode(
132
- node.left as Node,
133
- failOnForbidden,
134
- effectful,
135
- // override and mark all identifiers inside of left expression as assignee
136
- (id) => transformIdentifier(id, true)
137
- );
138
- const right = generateCode(
139
- node.right as Node,
140
- failOnForbidden,
141
- effectful,
142
- transformIdentifier
143
- );
144
- return `${left} ${node.operator} ${right}`;
145
- }
146
- if (node.type === "UpdateExpression") {
147
- throw Error(`"${node.operator}" operator is not supported`);
148
- }
149
- node satisfies never;
150
- return "";
151
- };
152
-
153
- export const validateExpression = (
154
- code: string,
155
- options?: { effectful?: boolean; transformIdentifier?: TransformIdentifier }
156
- ) => {
157
- const { effectful = false, transformIdentifier = (id: string) => id } =
158
- options ?? {};
159
- const expression = jsep(code) as Node;
160
- return generateCode(expression, true, effectful, transformIdentifier);
161
- };
162
-
163
- const sortTopologically = (
164
- list: Set<string>,
165
- depsById: Map<string, Set<string>>,
166
- explored = new Set<string>(),
167
- sorted: string[] = []
168
- ) => {
169
- for (const id of list) {
170
- if (explored.has(id)) {
171
- continue;
172
- }
173
- explored.add(id);
174
- const deps = depsById.get(id);
175
- if (deps) {
176
- sortTopologically(deps, depsById, explored, sorted);
177
- }
178
- sorted.push(id);
179
- }
180
- return sorted;
181
- };
182
-
183
- /**
184
- * Generates a function body expecting map as _variables argument
185
- * and outputing map of results
186
- */
187
- export const generateComputingExpressions = (
188
- expressions: Map<string, string>,
189
- allowedVariables: Set<string>
190
- ) => {
191
- const depsById = new Map<string, Set<string>>();
192
- const inputVariables = new Set<string>();
193
- for (const [id, code] of expressions) {
194
- const deps = new Set<string>();
195
- validateExpression(code, {
196
- transformIdentifier: (identifier) => {
197
- if (allowedVariables.has(identifier)) {
198
- inputVariables.add(identifier);
199
- return identifier;
200
- }
201
- if (expressions.has(identifier)) {
202
- deps.add(identifier);
203
- return identifier;
204
- }
205
- throw Error(`Unknown dependency "${identifier}"`);
206
- },
207
- });
208
- depsById.set(id, deps);
209
- }
210
-
211
- const sortedExpressions = sortTopologically(
212
- new Set(expressions.keys()),
213
- depsById
214
- );
215
-
216
- // generate code computing all expressions
217
- let generatedCode = "";
218
-
219
- for (const id of inputVariables) {
220
- generatedCode += `const ${id} = _variables.get('${id}');\n`;
221
- }
222
-
223
- for (const id of sortedExpressions) {
224
- const code = expressions.get(id);
225
- if (code === undefined) {
226
- continue;
227
- }
228
- generatedCode += `const ${id} = (${code});\n`;
229
- }
230
-
231
- generatedCode += `return new Map([\n`;
232
- for (const id of sortedExpressions) {
233
- generatedCode += ` ['${id}', ${id}],\n`;
234
- }
235
- generatedCode += `]);`;
236
-
237
- return generatedCode;
238
- };
239
-
240
- export const executeComputingExpressions = (
241
- expressions: Map<string, string>,
242
- variables: Map<string, unknown>
243
- ) => {
244
- const generatedCode = generateComputingExpressions(
245
- expressions,
246
- new Set(variables.keys())
247
- );
248
- const executeFn = new Function("_variables", generatedCode);
249
- const values = executeFn(variables) as Map<string, unknown>;
250
- return values;
251
- };
252
-
253
- export const generateEffectfulExpression = (
254
- code: string,
255
- args: Set<string>,
256
- allowedVariables: Set<string>
257
- ) => {
258
- const inputVariables = new Set<string>();
259
- const outputVariables = new Set<string>();
260
- validateExpression(code, {
261
- effectful: true,
262
- transformIdentifier: (identifier, assignee) => {
263
- if (args.has(identifier)) {
264
- return identifier;
265
- }
266
- if (allowedVariables.has(identifier)) {
267
- if (assignee) {
268
- outputVariables.add(identifier);
269
- } else {
270
- inputVariables.add(identifier);
271
- }
272
- return identifier;
273
- }
274
- throw Error(`Unknown dependency "${identifier}"`);
275
- },
276
- });
277
-
278
- // generate code computing all expressions
279
- let generatedCode = "";
280
-
281
- for (const id of args) {
282
- generatedCode += `let ${id} = _args.get('${id}');\n`;
283
- }
284
- for (const id of inputVariables) {
285
- generatedCode += `let ${id} = _variables.get('${id}');\n`;
286
- }
287
- for (const id of outputVariables) {
288
- if (inputVariables.has(id) === false) {
289
- generatedCode += `let ${id};\n`;
290
- }
291
- }
292
-
293
- generatedCode += `${code};\n`;
294
-
295
- generatedCode += `return new Map([\n`;
296
- for (const id of outputVariables) {
297
- generatedCode += ` ['${id}', ${id}],\n`;
298
- }
299
- generatedCode += `]);`;
300
-
301
- return generatedCode;
302
- };
303
-
304
- export const executeEffectfulExpression = (
305
- code: string,
306
- args: Map<string, unknown>,
307
- variables: Map<string, unknown>
308
- ) => {
309
- const generatedCode = generateEffectfulExpression(
310
- code,
311
- new Set(args.keys()),
312
- new Set(variables.keys())
313
- );
314
- const executeFn = new Function("_variables", "_args", generatedCode);
315
- const values = executeFn(variables, args) as Map<string, unknown>;
316
- return values;
317
- };
318
-
319
- const computeExpressionDependencies = (
320
- expressions: Map<string, string>,
321
- expressionId: string,
322
- dependencies: Map<string, Set<string>>
323
- ) => {
324
- // prevent recalculating expressions over again
325
- const depsById = dependencies.get(expressionId);
326
- if (depsById) {
327
- return depsById;
328
- }
329
- const parentDeps = new Set<string>();
330
- const code = expressions.get(expressionId);
331
- if (code === undefined) {
332
- return parentDeps;
333
- }
334
- // write before recursive call to avoid infinite cycle
335
- dependencies.set(expressionId, parentDeps);
336
- validateExpression(code, {
337
- transformIdentifier: (id) => {
338
- parentDeps.add(id);
339
- const childDeps = computeExpressionDependencies(
340
- expressions,
341
- id,
342
- dependencies
343
- );
344
- for (const depId of childDeps) {
345
- parentDeps.add(depId);
346
- }
347
- return id;
348
- },
349
- });
350
- return parentDeps;
351
- };
352
-
353
- export const computeExpressionsDependencies = (
354
- expressions: Map<string, string>
355
- ) => {
356
- const dependencies = new Map<string, Set<string>>();
357
- for (const id of expressions.keys()) {
358
- computeExpressionDependencies(expressions, id, dependencies);
359
- }
360
- return dependencies;
361
- };
362
-
363
- type Values = Map<string, unknown>;
364
-
365
- const dataSourceVariablePrefix = "$ws$dataSource$";
366
-
367
- // data source id is generated with nanoid which has "-" in alphabeta
368
- // here "-" is encoded with "__DASH__' in variable name
369
- // https://github.com/ai/nanoid/blob/047686abad8f15aff05f3a2eeedb7c98b6847392/url-alphabet/index.js
370
-
371
- export const encodeDataSourceVariable = (id: string) => {
372
- const encoded = id.replaceAll("-", "__DASH__");
373
- return `${dataSourceVariablePrefix}${encoded}`;
374
- };
375
-
376
- export const encodeVariablesMap = (values: Values) => {
377
- const encodedValues: Values = new Map();
378
- for (const [id, value] of values) {
379
- encodedValues.set(encodeDataSourceVariable(id), value);
380
- }
381
- return encodedValues;
382
- };
383
-
384
- export const decodeDataSourceVariable = (name: string) => {
385
- if (name.startsWith(dataSourceVariablePrefix)) {
386
- const encoded = name.slice(dataSourceVariablePrefix.length);
387
- return encoded.replaceAll("__DASH__", "-");
388
- }
389
- return;
390
- };
391
-
392
- export const decodeVariablesMap = (values: Values) => {
393
- const decodedValues: Values = new Map();
394
- for (const [name, value] of values) {
395
- const id = decodeDataSourceVariable(name);
396
- if (id !== undefined) {
397
- decodedValues.set(id, value);
398
- }
399
- }
400
- return decodedValues;
401
- };
package/src/generator.ts DELETED
@@ -1,147 +0,0 @@
1
- import type {
2
- DataSources,
3
- Instance,
4
- Instances,
5
- Page,
6
- Props,
7
- } from "@webstudio-is/project-build";
8
- import type { WsComponentMeta } from "./components/component-meta";
9
- import {
10
- getIndexesWithinAncestors,
11
- type IndexesWithinAncestors,
12
- } from "./instance-utils";
13
- import {
14
- encodeDataSourceVariable,
15
- generateComputingExpressions,
16
- generateEffectfulExpression,
17
- } from "./expression";
18
- import type { DataSourceValues } from "./context";
19
-
20
- type PageData = {
21
- page: Page;
22
- metas: Map<Instance["component"], WsComponentMeta>;
23
- instances: Instances;
24
- props: Props;
25
- dataSources: DataSources;
26
- };
27
-
28
- export type GeneratedUtils = {
29
- indexesWithinAncestors: IndexesWithinAncestors;
30
- executeComputingExpressions: (values: DataSourceValues) => DataSourceValues;
31
- executeEffectfulExpression: (
32
- expression: string,
33
- args: DataSourceValues,
34
- values: DataSourceValues
35
- ) => DataSourceValues;
36
- };
37
-
38
- /**
39
- * Generates data based utilities at build time
40
- * Requires this import statement in scope
41
- * import * as sdk from "@webstudio-is/react-sdk";
42
- */
43
- export const generateUtilsExport = (siteData: PageData) => {
44
- const indexesWithinAncestors = getIndexesWithinAncestors(
45
- siteData.metas,
46
- siteData.instances,
47
- [siteData.page.rootInstanceId]
48
- );
49
- let indexesWithinAncestorsEntries = "";
50
- for (const [key, value] of indexesWithinAncestors) {
51
- const keyString = JSON.stringify(key);
52
- const valueString = JSON.stringify(value);
53
- indexesWithinAncestorsEntries += `[${keyString}, ${valueString}],\n`;
54
- }
55
- const generatedIndexesWithinAncestors = `
56
- const indexesWithinAncestors = new Map<string, number>([
57
- ${indexesWithinAncestorsEntries}
58
- ]);
59
- `;
60
-
61
- const variables = new Set<string>();
62
- const expressions = new Map<string, string>();
63
- for (const dataSource of siteData.dataSources.values()) {
64
- if (dataSource.type === "variable") {
65
- variables.add(encodeDataSourceVariable(dataSource.id));
66
- }
67
- if (dataSource.type === "expression") {
68
- expressions.set(encodeDataSourceVariable(dataSource.id), dataSource.code);
69
- }
70
- }
71
- const generatedExecuteComputingExpressions = `
72
- const rawExecuteComputingExpressions = (
73
- _variables: Map<string, unknown>
74
- ): Map<string, unknown> => {
75
- ${generateComputingExpressions(expressions, variables)}
76
- };
77
- const executeComputingExpressions = (variables: Map<string, unknown>) => {
78
- const encodedvariables = sdk.encodeVariablesMap(variables);
79
- const encodedResult = rawExecuteComputingExpressions(encodedvariables);
80
- return sdk.decodeVariablesMap(encodedResult);
81
- };
82
- `;
83
-
84
- let effectfulExpressionsEntries = "";
85
- for (const prop of siteData.props.values()) {
86
- if (prop.type === "action") {
87
- for (const executableValue of prop.value) {
88
- const codeString = JSON.stringify(executableValue.code);
89
- const generatedCode = generateEffectfulExpression(
90
- executableValue.code,
91
- new Set(executableValue.args),
92
- variables
93
- );
94
- const generatedFunction = `(_args: Map<string, any>, _variables: Map<string, any>) => { ${generatedCode} }`;
95
-
96
- effectfulExpressionsEntries += `[${codeString}, ${generatedFunction}],\n`;
97
- }
98
- }
99
- }
100
- const generatedExecuteEffectfulExpression = `const generatedEffectfulExpressions = new Map<
101
- string,
102
- (args: Map<string, any>, variables: Map<string, any>) => Map<string, unknown>
103
- >([
104
- ${effectfulExpressionsEntries}
105
- ]);
106
-
107
- const rawExecuteEffectfulExpression = (
108
- code: string,
109
- args: Map<string, unknown>,
110
- variables: Map<string, unknown>
111
- ): Map<string, unknown> => {
112
- if(generatedEffectfulExpressions.has(code)) {
113
- return generatedEffectfulExpressions.get(code)!(args, variables);
114
- }
115
- console.error("Effectful expression not found", code);
116
- throw new Error("Effectful expression not found");
117
- };
118
-
119
- const executeEffectfulExpression = (
120
- code: string,
121
- args: Map<string, unknown>,
122
- variables: Map<string, unknown>
123
- ) => {
124
- const encodedvariables = sdk.encodeVariablesMap(variables);
125
- const encodedResult = rawExecuteEffectfulExpression(code, args, encodedvariables);
126
- return sdk.decodeVariablesMap(encodedResult);
127
- };
128
- `;
129
-
130
- return `
131
- /* eslint-disable */
132
-
133
- ${generatedIndexesWithinAncestors.trim()}
134
-
135
- ${generatedExecuteComputingExpressions.trim()}
136
-
137
- ${generatedExecuteEffectfulExpression.trim()}
138
-
139
- export const utils = {
140
- indexesWithinAncestors,
141
- executeComputingExpressions,
142
- executeEffectfulExpression,
143
- };
144
-
145
- /* eslint-enable */
146
- `;
147
- };
package/src/hook.ts DELETED
@@ -1,52 +0,0 @@
1
- import type { Instance, Prop } from "@webstudio-is/project-build";
2
- import type { IndexesWithinAncestors } from "./instance-utils";
3
-
4
- /**
5
- * Hooks are subscriptions to builder events
6
- * with limited way to interact with it.
7
- * Called independently from components.
8
- */
9
-
10
- export type HookContext = {
11
- indexesWithinAncestors: IndexesWithinAncestors;
12
- getPropValue: (instanceId: Instance["id"], propName: Prop["name"]) => unknown;
13
- setPropVariable: (
14
- instanceId: Instance["id"],
15
- propName: Prop["name"],
16
- value: unknown
17
- ) => void;
18
- };
19
-
20
- export type InstancePath = Instance[];
21
-
22
- type NavigatorEvent = {
23
- /**
24
- * List of instances from selected to the root
25
- */
26
- instancePath: InstancePath;
27
- };
28
-
29
- export type Hook = {
30
- onNavigatorSelect?: (context: HookContext, event: NavigatorEvent) => void;
31
- onNavigatorUnselect?: (context: HookContext, event: NavigatorEvent) => void;
32
- };
33
-
34
- /**
35
- * Find closest matching instance by component name
36
- * by lookup in instance path
37
- */
38
- export const getClosestInstance = (
39
- instancePath: InstancePath,
40
- currentInstance: Instance,
41
- closestComponent: Instance["component"]
42
- ) => {
43
- let matched = false;
44
- for (const instance of instancePath) {
45
- if (currentInstance === instance) {
46
- matched = true;
47
- }
48
- if (matched && instance.component === closestComponent) {
49
- return instance;
50
- }
51
- }
52
- };
package/src/index.ts DELETED
@@ -1,39 +0,0 @@
1
- export * from "./css";
2
- export * from "./tree";
3
- export * from "./pubsub";
4
- export * from "./app";
5
- export * from "./components/components-utils";
6
- export {
7
- type WsComponentPropsMeta,
8
- type WsComponentMeta,
9
- type ComponentState,
10
- type PresetStyle,
11
- componentCategories,
12
- stateCategories,
13
- defaultStates,
14
- } from "./components/component-meta";
15
- export * from "./embed-template";
16
- export {
17
- useInstanceProps,
18
- usePropUrl,
19
- usePropAsset,
20
- getInstanceIdFromComponentProps,
21
- getIndexWithinAncestorFromComponentProps,
22
- } from "./props";
23
- export { type Params, ReactSdkContext } from "./context";
24
- export {
25
- validateExpression,
26
- generateComputingExpressions,
27
- executeComputingExpressions,
28
- generateEffectfulExpression,
29
- executeEffectfulExpression,
30
- computeExpressionsDependencies,
31
- encodeDataSourceVariable,
32
- encodeVariablesMap,
33
- decodeDataSourceVariable,
34
- decodeVariablesMap,
35
- } from "./expression";
36
- export { renderComponentTemplate } from "./component-renderer";
37
- export { getIndexesWithinAncestors } from "./instance-utils";
38
- export * from "./hook";
39
- export { generateUtilsExport } from "./generator";
@@ -1,65 +0,0 @@
1
- import type { Instance, Instances } from "@webstudio-is/project-build";
2
- import type { WsComponentMeta } from "./components/component-meta";
3
-
4
- export type IndexesWithinAncestors = Map<Instance["id"], number>;
5
-
6
- export const getIndexesWithinAncestors = (
7
- metas: Map<Instance["component"], WsComponentMeta>,
8
- instances: Instances,
9
- rootIds: Instance["id"][]
10
- ) => {
11
- const ancestors = new Set<Instance["component"]>();
12
- for (const meta of metas.values()) {
13
- if (meta.indexWithinAncestor !== undefined) {
14
- ancestors.add(meta.indexWithinAncestor);
15
- }
16
- }
17
-
18
- const indexes: IndexesWithinAncestors = new Map();
19
-
20
- const traverseInstances = (
21
- instances: Instances,
22
- instanceId: Instance["id"],
23
- latestIndexes = new Map<
24
- Instance["component"],
25
- Map<Instance["component"], number>
26
- >()
27
- ) => {
28
- const instance = instances.get(instanceId);
29
- if (instance === undefined) {
30
- return;
31
- }
32
- const meta = metas.get(instance.component);
33
- if (meta === undefined) {
34
- return;
35
- }
36
-
37
- if (ancestors.has(instance.component)) {
38
- latestIndexes = new Map(latestIndexes);
39
- latestIndexes.set(instance.component, new Map());
40
- }
41
-
42
- if (meta.indexWithinAncestor !== undefined) {
43
- const ancestorIndexes = latestIndexes.get(meta.indexWithinAncestor);
44
- if (ancestorIndexes !== undefined) {
45
- let index = ancestorIndexes.get(instance.component) ?? -1;
46
- index += 1;
47
- ancestorIndexes.set(instance.component, index);
48
- indexes.set(instance.id, index);
49
- }
50
- }
51
-
52
- for (const child of instance.children) {
53
- if (child.type === "id") {
54
- traverseInstances(instances, child.value, latestIndexes);
55
- }
56
- }
57
- };
58
-
59
- const latestIndexes = new Map();
60
- for (const instanceId of rootIds) {
61
- traverseInstances(instances, instanceId, latestIndexes);
62
- }
63
-
64
- return indexes;
65
- };