@webstudio-is/react-sdk 0.79.0 → 0.80.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.
- package/lib/cjs/context.js +8 -2
- package/lib/cjs/css/normalize.js +1 -1
- package/lib/cjs/embed-template.js +45 -16
- package/lib/cjs/expression.js +137 -22
- package/lib/cjs/index.js +6 -2
- package/lib/cjs/props.js +32 -2
- package/lib/cjs/tree/create-elements-tree.js +7 -2
- package/lib/cjs/tree/root.js +15 -7
- package/lib/context.js +8 -2
- package/lib/css/normalize.js +1 -1
- package/lib/embed-template.js +45 -16
- package/lib/expression.js +137 -22
- package/lib/index.js +13 -5
- package/lib/props.js +32 -2
- package/lib/tree/create-elements-tree.js +10 -3
- package/lib/tree/root.js +16 -8
- package/lib/types/components/component-meta.d.ts +30 -0
- package/lib/types/context.d.ts +5 -2
- package/lib/types/embed-template.d.ts +38 -0
- package/lib/types/expression.d.ts +12 -4
- package/lib/types/index.d.ts +1 -1
- package/lib/types/props.d.ts +10 -0
- package/lib/types/tree/create-elements-tree.d.ts +6 -5
- package/lib/types/tree/root.d.ts +5 -5
- package/package.json +17 -16
- package/src/context.tsx +17 -4
- package/src/css/normalize.ts +1 -1
- package/src/embed-template.test.ts +84 -4
- package/src/embed-template.ts +51 -18
- package/src/expression.test.ts +106 -12
- package/src/expression.ts +157 -26
- package/src/index.ts +6 -2
- package/src/props.ts +33 -3
- package/src/tree/create-elements-tree.tsx +19 -10
- package/src/tree/root.ts +24 -13
package/lib/expression.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import jsep from "jsep";
|
|
2
|
-
|
|
2
|
+
import jsepAssignment from "@jsep-plugin/assignment";
|
|
3
|
+
jsep.plugins.register(jsepAssignment);
|
|
4
|
+
const generateCode = (node, failOnForbidden, effectful, transformIdentifier) => {
|
|
3
5
|
if (node.type === "Identifier") {
|
|
4
|
-
return transformIdentifier(node.name);
|
|
6
|
+
return transformIdentifier(node.name, false);
|
|
5
7
|
}
|
|
6
8
|
if (node.type === "MemberExpression") {
|
|
7
9
|
if (failOnForbidden) {
|
|
8
10
|
const object2 = generateCode(
|
|
9
11
|
node.object,
|
|
10
12
|
false,
|
|
13
|
+
effectful,
|
|
11
14
|
transformIdentifier
|
|
12
15
|
);
|
|
13
16
|
const property2 = generateCode(
|
|
14
17
|
node.property,
|
|
15
18
|
false,
|
|
19
|
+
effectful,
|
|
16
20
|
transformIdentifier
|
|
17
21
|
);
|
|
18
22
|
throw Error(`Cannot access "${property2}" of "${object2}"`);
|
|
@@ -20,11 +24,13 @@ const generateCode = (node, failOnForbidden, transformIdentifier) => {
|
|
|
20
24
|
const object = generateCode(
|
|
21
25
|
node.object,
|
|
22
26
|
failOnForbidden,
|
|
27
|
+
effectful,
|
|
23
28
|
transformIdentifier
|
|
24
29
|
);
|
|
25
30
|
const property = generateCode(
|
|
26
31
|
node.property,
|
|
27
32
|
failOnForbidden,
|
|
33
|
+
effectful,
|
|
28
34
|
transformIdentifier
|
|
29
35
|
);
|
|
30
36
|
return `${object}.${property}`;
|
|
@@ -36,6 +42,7 @@ const generateCode = (node, failOnForbidden, transformIdentifier) => {
|
|
|
36
42
|
const arg = generateCode(
|
|
37
43
|
node.argument,
|
|
38
44
|
failOnForbidden,
|
|
45
|
+
effectful,
|
|
39
46
|
transformIdentifier
|
|
40
47
|
);
|
|
41
48
|
return `${node.operator}${arg}`;
|
|
@@ -44,18 +51,25 @@ const generateCode = (node, failOnForbidden, transformIdentifier) => {
|
|
|
44
51
|
const left = generateCode(
|
|
45
52
|
node.left,
|
|
46
53
|
failOnForbidden,
|
|
54
|
+
effectful,
|
|
47
55
|
transformIdentifier
|
|
48
56
|
);
|
|
49
57
|
const right = generateCode(
|
|
50
58
|
node.right,
|
|
51
59
|
failOnForbidden,
|
|
60
|
+
effectful,
|
|
52
61
|
transformIdentifier
|
|
53
62
|
);
|
|
54
63
|
return `${left} ${node.operator} ${right}`;
|
|
55
64
|
}
|
|
56
65
|
if (node.type === "ArrayExpression") {
|
|
57
66
|
const elements = node.elements.map(
|
|
58
|
-
(element) => generateCode(
|
|
67
|
+
(element) => generateCode(
|
|
68
|
+
element,
|
|
69
|
+
failOnForbidden,
|
|
70
|
+
effectful,
|
|
71
|
+
transformIdentifier
|
|
72
|
+
)
|
|
59
73
|
);
|
|
60
74
|
return `[${elements.join(", ")}]`;
|
|
61
75
|
}
|
|
@@ -64,6 +78,7 @@ const generateCode = (node, failOnForbidden, transformIdentifier) => {
|
|
|
64
78
|
const callee2 = generateCode(
|
|
65
79
|
node.callee,
|
|
66
80
|
false,
|
|
81
|
+
effectful,
|
|
67
82
|
transformIdentifier
|
|
68
83
|
);
|
|
69
84
|
throw Error(`Cannot call "${callee2}"`);
|
|
@@ -71,10 +86,11 @@ const generateCode = (node, failOnForbidden, transformIdentifier) => {
|
|
|
71
86
|
const callee = generateCode(
|
|
72
87
|
node.callee,
|
|
73
88
|
failOnForbidden,
|
|
89
|
+
effectful,
|
|
74
90
|
transformIdentifier
|
|
75
91
|
);
|
|
76
92
|
const args = node.arguments.map(
|
|
77
|
-
(arg) => generateCode(arg, failOnForbidden, transformIdentifier)
|
|
93
|
+
(arg) => generateCode(arg, failOnForbidden, effectful, transformIdentifier)
|
|
78
94
|
);
|
|
79
95
|
return `${callee}(${args.join(", ")})`;
|
|
80
96
|
}
|
|
@@ -90,12 +106,38 @@ const generateCode = (node, failOnForbidden, transformIdentifier) => {
|
|
|
90
106
|
if (node.type === "Compound") {
|
|
91
107
|
throw Error("Cannot use multiple expressions");
|
|
92
108
|
}
|
|
109
|
+
if (node.type === "AssignmentExpression") {
|
|
110
|
+
if (node.operator !== "=") {
|
|
111
|
+
throw Error(`Only "=" assignment operator is supported`);
|
|
112
|
+
}
|
|
113
|
+
if (effectful === false) {
|
|
114
|
+
throw Error(`Cannot use assignment in this expression`);
|
|
115
|
+
}
|
|
116
|
+
const left = generateCode(
|
|
117
|
+
node.left,
|
|
118
|
+
failOnForbidden,
|
|
119
|
+
effectful,
|
|
120
|
+
// override and mark all identifiers inside of left expression as assignee
|
|
121
|
+
(id) => transformIdentifier(id, true)
|
|
122
|
+
);
|
|
123
|
+
const right = generateCode(
|
|
124
|
+
node.right,
|
|
125
|
+
failOnForbidden,
|
|
126
|
+
effectful,
|
|
127
|
+
transformIdentifier
|
|
128
|
+
);
|
|
129
|
+
return `${left} ${node.operator} ${right}`;
|
|
130
|
+
}
|
|
131
|
+
if (node.type === "UpdateExpression") {
|
|
132
|
+
throw Error(`"${node.operator}" operator is not supported`);
|
|
133
|
+
}
|
|
93
134
|
node;
|
|
94
135
|
return "";
|
|
95
136
|
};
|
|
96
|
-
const validateExpression = (code,
|
|
137
|
+
const validateExpression = (code, options) => {
|
|
138
|
+
const { effectful = false, transformIdentifier = (id) => id } = options ?? {};
|
|
97
139
|
const expression = jsep(code);
|
|
98
|
-
return generateCode(expression, true, transformIdentifier);
|
|
140
|
+
return generateCode(expression, true, effectful, transformIdentifier);
|
|
99
141
|
};
|
|
100
142
|
const sortTopologically = (list, depsById, explored = /* @__PURE__ */ new Set(), sorted = []) => {
|
|
101
143
|
for (const id of list) {
|
|
@@ -111,19 +153,23 @@ const sortTopologically = (list, depsById, explored = /* @__PURE__ */ new Set(),
|
|
|
111
153
|
}
|
|
112
154
|
return sorted;
|
|
113
155
|
};
|
|
114
|
-
const
|
|
156
|
+
const generateComputingExpressions = (expressions, allowedVariables) => {
|
|
115
157
|
const depsById = /* @__PURE__ */ new Map();
|
|
158
|
+
const inputVariables = /* @__PURE__ */ new Set();
|
|
116
159
|
for (const [id, code] of expressions) {
|
|
117
160
|
const deps = /* @__PURE__ */ new Set();
|
|
118
|
-
validateExpression(code,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
161
|
+
validateExpression(code, {
|
|
162
|
+
transformIdentifier: (identifier) => {
|
|
163
|
+
if (allowedVariables.has(identifier)) {
|
|
164
|
+
inputVariables.add(identifier);
|
|
165
|
+
return identifier;
|
|
166
|
+
}
|
|
167
|
+
if (expressions.has(identifier)) {
|
|
168
|
+
deps.add(identifier);
|
|
169
|
+
return identifier;
|
|
170
|
+
}
|
|
171
|
+
throw Error(`Unknown dependency "${identifier}"`);
|
|
125
172
|
}
|
|
126
|
-
throw Error(`Unknown dependency "${identifier}"`);
|
|
127
173
|
});
|
|
128
174
|
depsById.set(id, deps);
|
|
129
175
|
}
|
|
@@ -132,7 +178,7 @@ const generateExpressionsComputation = (variables, expressions) => {
|
|
|
132
178
|
depsById
|
|
133
179
|
);
|
|
134
180
|
let generatedCode = "";
|
|
135
|
-
for (const id of
|
|
181
|
+
for (const id of inputVariables) {
|
|
136
182
|
generatedCode += `const ${id} = _variables.get('${id}');
|
|
137
183
|
`;
|
|
138
184
|
}
|
|
@@ -153,10 +199,58 @@ const generateExpressionsComputation = (variables, expressions) => {
|
|
|
153
199
|
generatedCode += `]);`;
|
|
154
200
|
return generatedCode;
|
|
155
201
|
};
|
|
156
|
-
const
|
|
157
|
-
const generatedCode =
|
|
158
|
-
|
|
159
|
-
|
|
202
|
+
const executeComputingExpressions = (expressions, variables) => {
|
|
203
|
+
const generatedCode = generateComputingExpressions(
|
|
204
|
+
expressions,
|
|
205
|
+
new Set(variables.keys())
|
|
206
|
+
);
|
|
207
|
+
const executeFn = new Function("_variables", generatedCode);
|
|
208
|
+
const values = executeFn(variables);
|
|
209
|
+
return values;
|
|
210
|
+
};
|
|
211
|
+
const generateEffectfulExpression = (code, allowedVariables) => {
|
|
212
|
+
const inputVariables = /* @__PURE__ */ new Set();
|
|
213
|
+
const outputVariables = /* @__PURE__ */ new Set();
|
|
214
|
+
validateExpression(code, {
|
|
215
|
+
effectful: true,
|
|
216
|
+
transformIdentifier: (identifier, assignee) => {
|
|
217
|
+
if (allowedVariables.has(identifier)) {
|
|
218
|
+
if (assignee) {
|
|
219
|
+
outputVariables.add(identifier);
|
|
220
|
+
} else {
|
|
221
|
+
inputVariables.add(identifier);
|
|
222
|
+
}
|
|
223
|
+
return identifier;
|
|
224
|
+
}
|
|
225
|
+
throw Error(`Unknown dependency "${identifier}"`);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
let generatedCode = "";
|
|
229
|
+
for (const id of inputVariables) {
|
|
230
|
+
generatedCode += `let ${id} = _variables.get('${id}');
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
233
|
+
for (const id of outputVariables) {
|
|
234
|
+
if (inputVariables.has(id) === false) {
|
|
235
|
+
generatedCode += `let ${id};
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
generatedCode += `${code};
|
|
240
|
+
`;
|
|
241
|
+
generatedCode += `return new Map([
|
|
242
|
+
`;
|
|
243
|
+
for (const id of outputVariables) {
|
|
244
|
+
generatedCode += ` ['${id}', ${id}],
|
|
245
|
+
`;
|
|
246
|
+
}
|
|
247
|
+
generatedCode += `]);`;
|
|
248
|
+
return generatedCode;
|
|
249
|
+
};
|
|
250
|
+
const executeEffectfulExpression = (code, variables) => {
|
|
251
|
+
const generatedCode = generateEffectfulExpression(
|
|
252
|
+
code,
|
|
253
|
+
new Set(variables.keys())
|
|
160
254
|
);
|
|
161
255
|
const executeFn = new Function("_variables", generatedCode);
|
|
162
256
|
const values = executeFn(variables);
|
|
@@ -167,6 +261,13 @@ const encodeDataSourceVariable = (id) => {
|
|
|
167
261
|
const encoded = id.replaceAll("-", "__DASH__");
|
|
168
262
|
return `${dataSourceVariablePrefix}${encoded}`;
|
|
169
263
|
};
|
|
264
|
+
const encodeVariablesMap = (values) => {
|
|
265
|
+
const encodedValues = /* @__PURE__ */ new Map();
|
|
266
|
+
for (const [id, value] of values) {
|
|
267
|
+
encodedValues.set(encodeDataSourceVariable(id), value);
|
|
268
|
+
}
|
|
269
|
+
return encodedValues;
|
|
270
|
+
};
|
|
170
271
|
const decodeDataSourceVariable = (name) => {
|
|
171
272
|
if (name.startsWith(dataSourceVariablePrefix)) {
|
|
172
273
|
const encoded = name.slice(dataSourceVariablePrefix.length);
|
|
@@ -174,10 +275,24 @@ const decodeDataSourceVariable = (name) => {
|
|
|
174
275
|
}
|
|
175
276
|
return;
|
|
176
277
|
};
|
|
278
|
+
const decodeVariablesMap = (values) => {
|
|
279
|
+
const decodedValues = /* @__PURE__ */ new Map();
|
|
280
|
+
for (const [name, value] of values) {
|
|
281
|
+
const id = decodeDataSourceVariable(name);
|
|
282
|
+
if (id !== void 0) {
|
|
283
|
+
decodedValues.set(id, value);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return decodedValues;
|
|
287
|
+
};
|
|
177
288
|
export {
|
|
178
289
|
decodeDataSourceVariable,
|
|
290
|
+
decodeVariablesMap,
|
|
179
291
|
encodeDataSourceVariable,
|
|
180
|
-
|
|
181
|
-
|
|
292
|
+
encodeVariablesMap,
|
|
293
|
+
executeComputingExpressions,
|
|
294
|
+
executeEffectfulExpression,
|
|
295
|
+
generateComputingExpressions,
|
|
296
|
+
generateEffectfulExpression,
|
|
182
297
|
validateExpression
|
|
183
298
|
};
|
package/lib/index.js
CHANGED
|
@@ -18,19 +18,27 @@ import {
|
|
|
18
18
|
import { ReactSdkContext } from "./context";
|
|
19
19
|
import {
|
|
20
20
|
validateExpression,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
generateComputingExpressions,
|
|
22
|
+
executeComputingExpressions,
|
|
23
|
+
generateEffectfulExpression,
|
|
24
|
+
executeEffectfulExpression,
|
|
23
25
|
encodeDataSourceVariable,
|
|
24
|
-
|
|
26
|
+
encodeVariablesMap,
|
|
27
|
+
decodeDataSourceVariable,
|
|
28
|
+
decodeVariablesMap
|
|
25
29
|
} from "./expression";
|
|
26
30
|
export {
|
|
27
31
|
ReactSdkContext,
|
|
28
32
|
componentCategories,
|
|
29
33
|
decodeDataSourceVariable,
|
|
34
|
+
decodeVariablesMap,
|
|
30
35
|
defaultStates,
|
|
31
36
|
encodeDataSourceVariable,
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
encodeVariablesMap,
|
|
38
|
+
executeComputingExpressions,
|
|
39
|
+
executeEffectfulExpression,
|
|
40
|
+
generateComputingExpressions,
|
|
41
|
+
generateEffectfulExpression,
|
|
34
42
|
getInstanceIdFromComponentProps,
|
|
35
43
|
stateCategories,
|
|
36
44
|
useInstanceProps,
|
package/lib/props.js
CHANGED
|
@@ -16,7 +16,13 @@ const getPropsByInstanceId = (props) => {
|
|
|
16
16
|
return propsByInstanceId;
|
|
17
17
|
};
|
|
18
18
|
const useInstanceProps = (instanceId) => {
|
|
19
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
propsByInstanceIdStore,
|
|
21
|
+
dataSourceValuesStore,
|
|
22
|
+
executeEffectfulExpression,
|
|
23
|
+
setDataSourceValues,
|
|
24
|
+
renderer
|
|
25
|
+
} = useContext(ReactSdkContext);
|
|
20
26
|
const instancePropsObjectStore = useMemo(() => {
|
|
21
27
|
return computed(
|
|
22
28
|
[propsByInstanceIdStore, dataSourceValuesStore],
|
|
@@ -38,12 +44,36 @@ const useInstanceProps = (instanceId) => {
|
|
|
38
44
|
}
|
|
39
45
|
continue;
|
|
40
46
|
}
|
|
47
|
+
if (prop.type === "action") {
|
|
48
|
+
instancePropsObject2[prop.name] = () => {
|
|
49
|
+
if (renderer === "canvas") {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (const value of prop.value) {
|
|
53
|
+
if (value.type === "execute") {
|
|
54
|
+
const newValues = executeEffectfulExpression(
|
|
55
|
+
value.code,
|
|
56
|
+
dataSourceValues
|
|
57
|
+
);
|
|
58
|
+
setDataSourceValues(newValues);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
41
64
|
instancePropsObject2[prop.name] = prop.value;
|
|
42
65
|
}
|
|
43
66
|
return instancePropsObject2;
|
|
44
67
|
}
|
|
45
68
|
);
|
|
46
|
-
}, [
|
|
69
|
+
}, [
|
|
70
|
+
propsByInstanceIdStore,
|
|
71
|
+
dataSourceValuesStore,
|
|
72
|
+
instanceId,
|
|
73
|
+
renderer,
|
|
74
|
+
executeEffectfulExpression,
|
|
75
|
+
setDataSourceValues
|
|
76
|
+
]);
|
|
47
77
|
const instancePropsObject = useStore(instancePropsObjectStore);
|
|
48
78
|
return instancePropsObject;
|
|
49
79
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from "react";
|
|
3
3
|
import { Scripts, ScrollRestoration } from "@remix-run/react";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ReactSdkContext
|
|
6
|
+
} from "../context";
|
|
5
7
|
const createElementsTree = ({
|
|
6
8
|
renderer,
|
|
7
9
|
imageBaseUrl,
|
|
@@ -12,6 +14,7 @@ const createElementsTree = ({
|
|
|
12
14
|
assetsStore,
|
|
13
15
|
pagesStore,
|
|
14
16
|
dataSourceValuesStore,
|
|
17
|
+
executeEffectfulExpression,
|
|
15
18
|
onDataSourceUpdate,
|
|
16
19
|
Component,
|
|
17
20
|
components
|
|
@@ -52,7 +55,9 @@ const createElementsTree = ({
|
|
|
52
55
|
renderer,
|
|
53
56
|
imageBaseUrl,
|
|
54
57
|
assetBaseUrl,
|
|
55
|
-
|
|
58
|
+
executeEffectfulExpression,
|
|
59
|
+
setDataSourceValues: onDataSourceUpdate,
|
|
60
|
+
setBoundDataSourceValue: (instanceId, propName, value) => {
|
|
56
61
|
const propsByInstanceId = propsByInstanceIdStore.get();
|
|
57
62
|
const props = propsByInstanceId.get(instanceId);
|
|
58
63
|
const prop = props?.find((prop2) => prop2.name === propName);
|
|
@@ -60,7 +65,9 @@ const createElementsTree = ({
|
|
|
60
65
|
throw Error(`${propName} is not data source`);
|
|
61
66
|
}
|
|
62
67
|
const dataSourceId = prop.value;
|
|
63
|
-
|
|
68
|
+
const newValues = /* @__PURE__ */ new Map();
|
|
69
|
+
newValues.set(dataSourceId, value);
|
|
70
|
+
onDataSourceUpdate(newValues);
|
|
64
71
|
}
|
|
65
72
|
},
|
|
66
73
|
children: root
|
package/lib/tree/root.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef } from "react";
|
|
1
|
+
import { useRef, useCallback } from "react";
|
|
2
2
|
import {
|
|
3
3
|
atom,
|
|
4
4
|
computed
|
|
@@ -8,7 +8,8 @@ import { WebstudioComponent } from "./webstudio-component";
|
|
|
8
8
|
import { getPropsByInstanceId } from "../props";
|
|
9
9
|
const InstanceRoot = ({
|
|
10
10
|
data,
|
|
11
|
-
|
|
11
|
+
executeComputingExpressions,
|
|
12
|
+
executeEffectfulExpression,
|
|
12
13
|
Component,
|
|
13
14
|
components
|
|
14
15
|
}) => {
|
|
@@ -30,7 +31,7 @@ const InstanceRoot = ({
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
try {
|
|
33
|
-
const result =
|
|
34
|
+
const result = executeComputingExpressions(dataSourceValues);
|
|
34
35
|
for (const [id, value] of result) {
|
|
35
36
|
dataSourceValues.set(id, value);
|
|
36
37
|
}
|
|
@@ -42,6 +43,16 @@ const InstanceRoot = ({
|
|
|
42
43
|
);
|
|
43
44
|
}
|
|
44
45
|
const dataSourceValuesStore = dataSourceValuesStoreRef.current;
|
|
46
|
+
const onDataSourceUpdate = useCallback(
|
|
47
|
+
(newValues) => {
|
|
48
|
+
const dataSourceVariables = new Map(dataSourceVariablesStore.get());
|
|
49
|
+
for (const [dataSourceId, value] of newValues) {
|
|
50
|
+
dataSourceVariables.set(dataSourceId, value);
|
|
51
|
+
}
|
|
52
|
+
dataSourceVariablesStore.set(dataSourceVariables);
|
|
53
|
+
},
|
|
54
|
+
[dataSourceVariablesStore]
|
|
55
|
+
);
|
|
45
56
|
return createElementsTree({
|
|
46
57
|
imageBaseUrl: data.params?.imageBaseUrl ?? "/",
|
|
47
58
|
assetBaseUrl: data.params?.assetBaseUrl ?? "/",
|
|
@@ -52,12 +63,9 @@ const InstanceRoot = ({
|
|
|
52
63
|
),
|
|
53
64
|
assetsStore: atom(new Map(data.assets.map((asset) => [asset.id, asset]))),
|
|
54
65
|
pagesStore: atom(new Map(data.pages.map((page) => [page.id, page]))),
|
|
66
|
+
executeEffectfulExpression,
|
|
55
67
|
dataSourceValuesStore,
|
|
56
|
-
onDataSourceUpdate
|
|
57
|
-
const dataSourceVariables = new Map(dataSourceVariablesStore.get());
|
|
58
|
-
dataSourceVariables.set(dataSourceId, value);
|
|
59
|
-
dataSourceVariablesStore.set(dataSourceVariables);
|
|
60
|
-
},
|
|
68
|
+
onDataSourceUpdate,
|
|
61
69
|
Component: Component ?? WebstudioComponent,
|
|
62
70
|
components
|
|
63
71
|
});
|
|
@@ -366,6 +366,24 @@ declare const WsComponentPropsMeta: z.ZodObject<{
|
|
|
366
366
|
defaultValue?: string | undefined;
|
|
367
367
|
label?: string | undefined;
|
|
368
368
|
description?: string | undefined;
|
|
369
|
+
}>, z.ZodObject<{
|
|
370
|
+
control: z.ZodLiteral<"action">;
|
|
371
|
+
type: z.ZodLiteral<"action">;
|
|
372
|
+
label: z.ZodOptional<z.ZodString>;
|
|
373
|
+
description: z.ZodOptional<z.ZodString>;
|
|
374
|
+
required: z.ZodBoolean;
|
|
375
|
+
}, "strip", z.ZodTypeAny, {
|
|
376
|
+
type: "action";
|
|
377
|
+
required: boolean;
|
|
378
|
+
control: "action";
|
|
379
|
+
label?: string | undefined;
|
|
380
|
+
description?: string | undefined;
|
|
381
|
+
}, {
|
|
382
|
+
type: "action";
|
|
383
|
+
required: boolean;
|
|
384
|
+
control: "action";
|
|
385
|
+
label?: string | undefined;
|
|
386
|
+
description?: string | undefined;
|
|
369
387
|
}>]>>;
|
|
370
388
|
initialProps: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
371
389
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -490,6 +508,12 @@ declare const WsComponentPropsMeta: z.ZodObject<{
|
|
|
490
508
|
defaultValue?: string | undefined;
|
|
491
509
|
label?: string | undefined;
|
|
492
510
|
description?: string | undefined;
|
|
511
|
+
} | {
|
|
512
|
+
type: "action";
|
|
513
|
+
required: boolean;
|
|
514
|
+
control: "action";
|
|
515
|
+
label?: string | undefined;
|
|
516
|
+
description?: string | undefined;
|
|
493
517
|
}>;
|
|
494
518
|
initialProps?: string[] | undefined;
|
|
495
519
|
}, {
|
|
@@ -614,6 +638,12 @@ declare const WsComponentPropsMeta: z.ZodObject<{
|
|
|
614
638
|
defaultValue?: string | undefined;
|
|
615
639
|
label?: string | undefined;
|
|
616
640
|
description?: string | undefined;
|
|
641
|
+
} | {
|
|
642
|
+
type: "action";
|
|
643
|
+
required: boolean;
|
|
644
|
+
control: "action";
|
|
645
|
+
label?: string | undefined;
|
|
646
|
+
description?: string | undefined;
|
|
617
647
|
}>;
|
|
618
648
|
initialProps?: string[] | undefined;
|
|
619
649
|
}>;
|
package/lib/types/context.d.ts
CHANGED
|
@@ -29,10 +29,13 @@ export type Params = {
|
|
|
29
29
|
*/
|
|
30
30
|
assetBaseUrl: string;
|
|
31
31
|
};
|
|
32
|
+
export type DataSourceValues = Map<DataSource["id"], unknown>;
|
|
32
33
|
export declare const ReactSdkContext: import("react").Context<Params & {
|
|
33
34
|
propsByInstanceIdStore: ReadableAtom<PropsByInstanceId>;
|
|
34
35
|
assetsStore: ReadableAtom<Assets>;
|
|
35
36
|
pagesStore: ReadableAtom<Pages>;
|
|
36
|
-
dataSourceValuesStore: ReadableAtom<
|
|
37
|
-
|
|
37
|
+
dataSourceValuesStore: ReadableAtom<DataSourceValues>;
|
|
38
|
+
executeEffectfulExpression: (expression: string, values: DataSourceValues) => DataSourceValues;
|
|
39
|
+
setDataSourceValues: (newValues: DataSourceValues) => void;
|
|
40
|
+
setBoundDataSourceValue: (instanceId: Instance["id"], prop: Prop["name"], value: unknown) => void;
|
|
38
41
|
}>;
|
|
@@ -213,6 +213,33 @@ declare const EmbedTemplateProp: z.ZodUnion<[z.ZodObject<{
|
|
|
213
213
|
code: string;
|
|
214
214
|
type: "expression";
|
|
215
215
|
} | undefined;
|
|
216
|
+
}>, z.ZodObject<{
|
|
217
|
+
type: z.ZodLiteral<"action">;
|
|
218
|
+
name: z.ZodString;
|
|
219
|
+
value: z.ZodArray<z.ZodObject<{
|
|
220
|
+
type: z.ZodLiteral<"execute">;
|
|
221
|
+
code: z.ZodString;
|
|
222
|
+
}, "strip", z.ZodTypeAny, {
|
|
223
|
+
code: string;
|
|
224
|
+
type: "execute";
|
|
225
|
+
}, {
|
|
226
|
+
code: string;
|
|
227
|
+
type: "execute";
|
|
228
|
+
}>, "many">;
|
|
229
|
+
}, "strip", z.ZodTypeAny, {
|
|
230
|
+
name: string;
|
|
231
|
+
type: "action";
|
|
232
|
+
value: {
|
|
233
|
+
code: string;
|
|
234
|
+
type: "execute";
|
|
235
|
+
}[];
|
|
236
|
+
}, {
|
|
237
|
+
name: string;
|
|
238
|
+
type: "action";
|
|
239
|
+
value: {
|
|
240
|
+
code: string;
|
|
241
|
+
type: "execute";
|
|
242
|
+
}[];
|
|
216
243
|
}>]>;
|
|
217
244
|
type EmbedTemplateProp = z.infer<typeof EmbedTemplateProp>;
|
|
218
245
|
declare const EmbedTemplateStyleDeclRaw: z.ZodObject<{
|
|
@@ -2357,6 +2384,16 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
|
|
|
2357
2384
|
id: string;
|
|
2358
2385
|
instanceId: string;
|
|
2359
2386
|
required?: boolean | undefined;
|
|
2387
|
+
} | {
|
|
2388
|
+
name: string;
|
|
2389
|
+
type: "action";
|
|
2390
|
+
value: {
|
|
2391
|
+
code: string;
|
|
2392
|
+
type: "execute";
|
|
2393
|
+
}[];
|
|
2394
|
+
id: string;
|
|
2395
|
+
instanceId: string;
|
|
2396
|
+
required?: boolean | undefined;
|
|
2360
2397
|
})[];
|
|
2361
2398
|
dataSources: ({
|
|
2362
2399
|
name: string;
|
|
@@ -2611,4 +2648,5 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
|
|
|
2611
2648
|
property: "filter" | "float" | "fontFamily" | "width" | "height" | "clip" | "top" | "right" | `--${string}` | "accentColor" | "alignContent" | "alignItems" | "alignSelf" | "alignTracks" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationTimingFunction" | "animationTimeline" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPosition" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "blockOverflow" | "blockSize" | "borderBlockColor" | "borderBlockStyle" | "borderBlockWidth" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineColor" | "borderInlineStyle" | "borderInlineWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "bottom" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "color" | "printColorAdjust" | "colorScheme" | "columnCount" | "columnFill" | "columnGap" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "content" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "direction" | "display" | "emptyCells" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontVariationSettings" | "fontSize" | "fontSizeAdjust" | "fontStretch" | "fontStyle" | "fontSynthesis" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontWeight" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "inputSecurity" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "isolation" | "justifyContent" | "justifyItems" | "justifySelf" | "justifyTracks" | "left" | "letterSpacing" | "lineBreak" | "lineClamp" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "objectFit" | "objectPosition" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "opacity" | "order" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflow" | "overflowAnchor" | "overflowBlock" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overscrollBehavior" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "position" | "quotes" | "resize" | "rotate" | "rowGap" | "rubyAlign" | "rubyMerge" | "rubyPosition" | "scale" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "scrollBehavior" | "scrollMarginBlockStart" | "scrollMarginBlockEnd" | "scrollMarginBottom" | "scrollMarginInlineStart" | "scrollMarginInlineEnd" | "scrollMarginLeft" | "scrollMarginRight" | "scrollMarginTop" | "scrollPaddingBlockStart" | "scrollPaddingBlockEnd" | "scrollPaddingBottom" | "scrollPaddingInlineStart" | "scrollPaddingInlineEnd" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "tabSize" | "tableLayout" | "textAlign" | "textAlignLast" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textTransform" | "textUnderlineOffset" | "textUnderlinePosition" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "translate" | "unicodeBidi" | "userSelect" | "verticalAlign" | "visibility" | "whiteSpace" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "zIndex";
|
|
2612
2649
|
}[];
|
|
2613
2650
|
};
|
|
2651
|
+
export type EmbedTemplateData = ReturnType<typeof generateDataFromEmbedTemplate>;
|
|
2614
2652
|
export {};
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
type TransformIdentifier = (id: string) => string;
|
|
2
|
-
export declare const validateExpression: (code: string,
|
|
1
|
+
type TransformIdentifier = (id: string, assignee: boolean) => string;
|
|
2
|
+
export declare const validateExpression: (code: string, options?: {
|
|
3
|
+
effectful?: boolean;
|
|
4
|
+
transformIdentifier?: TransformIdentifier;
|
|
5
|
+
}) => string;
|
|
3
6
|
/**
|
|
4
7
|
* Generates a function body expecting map as _variables argument
|
|
5
8
|
* and outputing map of results
|
|
6
9
|
*/
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const
|
|
10
|
+
export declare const generateComputingExpressions: (expressions: Map<string, string>, allowedVariables: Set<string>) => string;
|
|
11
|
+
export declare const executeComputingExpressions: (expressions: Map<string, string>, variables: Map<string, unknown>) => Map<string, unknown>;
|
|
12
|
+
export declare const generateEffectfulExpression: (code: string, allowedVariables: Set<string>) => string;
|
|
13
|
+
export declare const executeEffectfulExpression: (code: string, variables: Map<string, unknown>) => Map<string, unknown>;
|
|
14
|
+
type Values = Map<string, unknown>;
|
|
9
15
|
export declare const encodeDataSourceVariable: (id: string) => string;
|
|
16
|
+
export declare const encodeVariablesMap: (values: Values) => Values;
|
|
10
17
|
export declare const decodeDataSourceVariable: (name: string) => string | undefined;
|
|
18
|
+
export declare const decodeVariablesMap: (values: Values) => Values;
|
|
11
19
|
export {};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export { type WsComponentPropsMeta, type WsComponentMeta, type ComponentState, t
|
|
|
7
7
|
export * from "./embed-template";
|
|
8
8
|
export { useInstanceProps, usePropUrl, usePropAsset, getInstanceIdFromComponentProps, } from "./props";
|
|
9
9
|
export { type Params, ReactSdkContext } from "./context";
|
|
10
|
-
export { validateExpression,
|
|
10
|
+
export { validateExpression, generateComputingExpressions, executeComputingExpressions, generateEffectfulExpression, executeEffectfulExpression, encodeDataSourceVariable, encodeVariablesMap, decodeDataSourceVariable, decodeVariablesMap, } from "./expression";
|
package/lib/types/props.d.ts
CHANGED
|
@@ -57,6 +57,16 @@ export declare const getPropsByInstanceId: (props: Map<string, {
|
|
|
57
57
|
id: string;
|
|
58
58
|
instanceId: string;
|
|
59
59
|
required?: boolean | undefined;
|
|
60
|
+
} | {
|
|
61
|
+
name: string;
|
|
62
|
+
type: "action";
|
|
63
|
+
value: {
|
|
64
|
+
code: string;
|
|
65
|
+
type: "execute";
|
|
66
|
+
}[];
|
|
67
|
+
id: string;
|
|
68
|
+
instanceId: string;
|
|
69
|
+
required?: boolean | undefined;
|
|
60
70
|
}>) => PropsByInstanceId;
|
|
61
71
|
export declare const useInstanceProps: (instanceId: Instance["id"]) => Record<string, unknown>;
|
|
62
72
|
export declare const usePropAsset: (instanceId: Instance["id"], name: string) => {
|