@webstudio-is/react-sdk 0.75.0 → 0.77.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 (45) hide show
  1. package/lib/cjs/context.js +5 -1
  2. package/lib/cjs/css/normalize.js +51 -23
  3. package/lib/cjs/css/presets.js +111 -1
  4. package/lib/cjs/embed-template.js +68 -3
  5. package/lib/cjs/expression.js +213 -0
  6. package/lib/cjs/index.js +8 -1
  7. package/lib/cjs/props.js +28 -10
  8. package/lib/cjs/tree/create-elements-tree.js +14 -1
  9. package/lib/cjs/tree/root.js +38 -0
  10. package/lib/cjs/tree/webstudio-component.js +9 -2
  11. package/lib/context.js +5 -1
  12. package/lib/css/normalize.js +41 -23
  13. package/lib/css/presets.js +111 -1
  14. package/lib/embed-template.js +68 -3
  15. package/lib/expression.js +183 -0
  16. package/lib/index.js +15 -1
  17. package/lib/props.js +28 -10
  18. package/lib/tree/create-elements-tree.js +14 -1
  19. package/lib/tree/root.js +42 -1
  20. package/lib/tree/webstudio-component.js +9 -2
  21. package/lib/types/components/component-meta.d.ts +112 -0
  22. package/lib/types/context.d.ts +3 -0
  23. package/lib/types/css/normalize.d.ts +1836 -0
  24. package/lib/types/css/presets.d.ts +282 -0
  25. package/lib/types/embed-template.d.ts +512 -0
  26. package/lib/types/expression.d.ts +11 -0
  27. package/lib/types/expression.test.d.ts +1 -0
  28. package/lib/types/index.d.ts +2 -1
  29. package/lib/types/props.d.ts +8 -7
  30. package/lib/types/tree/create-elements-tree.d.ts +4 -2
  31. package/lib/types/tree/root.d.ts +6 -4
  32. package/lib/types/tree/webstudio-component.d.ts +1 -0
  33. package/package.json +10 -10
  34. package/src/context.tsx +11 -0
  35. package/src/css/normalize.ts +40 -23
  36. package/src/css/presets.ts +110 -0
  37. package/src/embed-template.test.ts +177 -1
  38. package/src/embed-template.ts +73 -2
  39. package/src/expression.test.ts +147 -0
  40. package/src/expression.ts +217 -0
  41. package/src/index.ts +8 -0
  42. package/src/props.ts +29 -10
  43. package/src/tree/create-elements-tree.tsx +20 -1
  44. package/src/tree/root.ts +61 -4
  45. package/src/tree/webstudio-component.tsx +7 -1
@@ -28,5 +28,9 @@ const ReactSdkContext = (0, import_react.createContext)({
28
28
  assetBaseUrl: "/",
29
29
  propsByInstanceIdStore: (0, import_nanostores.atom)(/* @__PURE__ */ new Map()),
30
30
  assetsStore: (0, import_nanostores.atom)(/* @__PURE__ */ new Map()),
31
- pagesStore: (0, import_nanostores.atom)(/* @__PURE__ */ new Map())
31
+ pagesStore: (0, import_nanostores.atom)(/* @__PURE__ */ new Map()),
32
+ dataSourceValuesStore: (0, import_nanostores.atom)(/* @__PURE__ */ new Map()),
33
+ setDataSourceValue: () => {
34
+ throw Error("React SDK setDataSourceValue is not implemented");
35
+ }
32
36
  });
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var normalize_exports = {};
20
30
  __export(normalize_exports, {
@@ -23,6 +33,7 @@ __export(normalize_exports, {
23
33
  article: () => article,
24
34
  aside: () => aside,
25
35
  b: () => b,
36
+ blockquote: () => blockquote,
26
37
  body: () => body,
27
38
  button: () => button,
28
39
  code: () => code,
@@ -67,17 +78,25 @@ __export(normalize_exports, {
67
78
  ul: () => ul
68
79
  });
69
80
  module.exports = __toCommonJS(normalize_exports);
70
- var import_presets = require("./presets");
81
+ var presets = __toESM(require("./presets"), 1);
71
82
  const boxSizing = {
72
83
  property: "boxSizing",
73
84
  value: { type: "keyword", value: "border-box" }
74
85
  };
75
- const baseStyle = [boxSizing, ...import_presets.borders, ...import_presets.outline];
86
+ const baseStyle = [
87
+ boxSizing,
88
+ ...presets.borders,
89
+ ...presets.outline
90
+ ];
76
91
  const div = baseStyle;
77
92
  const address = baseStyle;
78
93
  const article = baseStyle;
79
94
  const aside = baseStyle;
80
- const figure = baseStyle;
95
+ const blockquote = [
96
+ ...baseStyle,
97
+ ...presets.blockquote
98
+ ];
99
+ const figure = [...baseStyle, ...presets.margins];
81
100
  const footer = baseStyle;
82
101
  const header = baseStyle;
83
102
  const main = baseStyle;
@@ -85,19 +104,19 @@ const nav = baseStyle;
85
104
  const section = baseStyle;
86
105
  const form = baseStyle;
87
106
  const label = baseStyle;
88
- const h1 = baseStyle;
89
- const h2 = baseStyle;
90
- const h3 = baseStyle;
91
- const h4 = baseStyle;
92
- const h5 = baseStyle;
93
- const h6 = baseStyle;
107
+ const h1 = [...baseStyle, ...presets.h1];
108
+ const h2 = [...baseStyle, ...presets.h2];
109
+ const h3 = [...baseStyle, ...presets.h3];
110
+ const h4 = [...baseStyle, ...presets.h4];
111
+ const h5 = [...baseStyle, ...presets.h5];
112
+ const h6 = [...baseStyle, ...presets.h6];
94
113
  const i = baseStyle;
95
114
  const img = baseStyle;
96
115
  const a = baseStyle;
97
116
  const li = baseStyle;
98
117
  const ul = baseStyle;
99
118
  const ol = baseStyle;
100
- const p = baseStyle;
119
+ const p = [...baseStyle, ...presets.verticalMargins];
101
120
  const span = baseStyle;
102
121
  const html = [
103
122
  /* 1 */
@@ -116,7 +135,7 @@ const html = [
116
135
  value: { type: "unit", value: 4, unit: "number" }
117
136
  },
118
137
  boxSizing,
119
- ...import_presets.borders
138
+ ...presets.borders
120
139
  ];
121
140
  const body = [
122
141
  /* 1 */
@@ -141,11 +160,19 @@ const body = [
141
160
  property: "fontFamily",
142
161
  value: {
143
162
  type: "keyword",
144
- value: `system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'`
163
+ value: "Arial, sans-serif"
145
164
  }
146
165
  },
166
+ {
167
+ property: "fontSize",
168
+ value: { type: "unit", unit: "px", value: 16 }
169
+ },
170
+ {
171
+ property: "lineHeight",
172
+ value: { type: "unit", unit: "number", value: 1.2 }
173
+ },
147
174
  boxSizing,
148
- ...import_presets.borders
175
+ ...presets.borders
149
176
  ];
150
177
  const hr = [
151
178
  /* 1 */
@@ -159,7 +186,8 @@ const hr = [
159
186
  value: { type: "keyword", value: "inherit" }
160
187
  },
161
188
  boxSizing,
162
- ...import_presets.borders
189
+ ...presets.borders,
190
+ ...presets.margins
163
191
  ];
164
192
  const b = [
165
193
  {
@@ -167,7 +195,7 @@ const b = [
167
195
  value: { type: "keyword", value: "700" }
168
196
  },
169
197
  boxSizing,
170
- ...import_presets.borders
198
+ ...presets.borders
171
199
  ];
172
200
  const strong = b;
173
201
  const code = [
@@ -185,7 +213,7 @@ const code = [
185
213
  value: { type: "unit", value: 1, unit: "em" }
186
214
  },
187
215
  boxSizing,
188
- ...import_presets.borders
216
+ ...presets.borders
189
217
  ];
190
218
  const kbd = code;
191
219
  const samp = code;
@@ -196,7 +224,7 @@ const small = [
196
224
  value: { type: "unit", value: 80, unit: "%" }
197
225
  },
198
226
  boxSizing,
199
- ...import_presets.borders
227
+ ...presets.borders
200
228
  ];
201
229
  const subSupBase = [
202
230
  {
@@ -216,7 +244,7 @@ const subSupBase = [
216
244
  value: { type: "keyword", value: "baseline" }
217
245
  },
218
246
  boxSizing,
219
- ...import_presets.borders
247
+ ...presets.borders
220
248
  ];
221
249
  const sub = [
222
250
  ...subSupBase,
@@ -238,7 +266,7 @@ const table = [
238
266
  property: "textIndent",
239
267
  value: { type: "unit", value: 0, unit: "number" }
240
268
  },
241
- ...import_presets.borders,
269
+ ...presets.borders,
242
270
  /* 2 */
243
271
  {
244
272
  property: "borderTopColor",
@@ -290,7 +318,7 @@ const buttonBase = [
290
318
  value: { type: "unit", value: 0, unit: "number" }
291
319
  },
292
320
  boxSizing,
293
- ...import_presets.borders
321
+ ...presets.borders
294
322
  ];
295
323
  const input = buttonBase;
296
324
  const optgroup = buttonBase;
@@ -321,7 +349,7 @@ const legend = [
321
349
  value: { type: "unit", value: 0, unit: "number" }
322
350
  },
323
351
  boxSizing,
324
- ...import_presets.borders
352
+ ...presets.borders
325
353
  ];
326
354
  const progress = [
327
355
  {
@@ -329,7 +357,7 @@ const progress = [
329
357
  value: { type: "keyword", value: "baseline" }
330
358
  },
331
359
  boxSizing,
332
- ...import_presets.borders
360
+ ...presets.borders
333
361
  ];
334
362
  const summary = [
335
363
  {
@@ -337,5 +365,5 @@ const summary = [
337
365
  value: { type: "keyword", value: "list-item" }
338
366
  },
339
367
  boxSizing,
340
- ...import_presets.borders
368
+ ...presets.borders
341
369
  ];
@@ -18,8 +18,17 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var presets_exports = {};
20
20
  __export(presets_exports, {
21
+ blockquote: () => blockquote,
21
22
  borders: () => borders,
22
- outline: () => outline
23
+ h1: () => h1,
24
+ h2: () => h2,
25
+ h3: () => h3,
26
+ h4: () => h4,
27
+ h5: () => h5,
28
+ h6: () => h6,
29
+ margins: () => margins,
30
+ outline: () => outline,
31
+ verticalMargins: () => verticalMargins
23
32
  });
24
33
  module.exports = __toCommonJS(presets_exports);
25
34
  const borders = [
@@ -46,3 +55,104 @@ const outline = [
46
55
  value: { type: "unit", value: 1, unit: "px" }
47
56
  }
48
57
  ];
58
+ const margins = [
59
+ {
60
+ property: "marginTop",
61
+ value: { type: "unit", value: 0, unit: "px" }
62
+ },
63
+ {
64
+ property: "marginRight",
65
+ value: { type: "unit", value: 0, unit: "px" }
66
+ },
67
+ {
68
+ property: "marginBottom",
69
+ value: { type: "unit", value: 0, unit: "px" }
70
+ },
71
+ {
72
+ property: "marginLeft",
73
+ value: { type: "unit", value: 0, unit: "px" }
74
+ }
75
+ ];
76
+ const verticalMargins = [
77
+ {
78
+ property: "marginTop",
79
+ value: { type: "unit", value: 0, unit: "px" }
80
+ },
81
+ {
82
+ property: "marginBottom",
83
+ value: { type: "unit", value: 0, unit: "px" }
84
+ }
85
+ ];
86
+ const blockquote = [
87
+ ...margins,
88
+ {
89
+ property: "paddingTop",
90
+ value: { type: "unit", value: 10, unit: "px" }
91
+ },
92
+ {
93
+ property: "paddingBottom",
94
+ value: { type: "unit", value: 10, unit: "px" }
95
+ },
96
+ {
97
+ property: "paddingLeft",
98
+ value: { type: "unit", value: 20, unit: "px" }
99
+ },
100
+ {
101
+ property: "paddingRight",
102
+ value: { type: "unit", value: 20, unit: "px" }
103
+ },
104
+ {
105
+ property: "borderLeftWidth",
106
+ value: { type: "unit", value: 5, unit: "px" }
107
+ },
108
+ {
109
+ property: "borderLeftStyle",
110
+ value: { type: "keyword", value: "solid" }
111
+ },
112
+ {
113
+ property: "borderLeftColor",
114
+ value: { type: "rgb", r: 226, g: 226, b: 226, alpha: 1 }
115
+ }
116
+ ];
117
+ const h1 = [
118
+ ...verticalMargins,
119
+ {
120
+ property: "fontSize",
121
+ value: { type: "unit", value: 38, unit: "px" }
122
+ }
123
+ ];
124
+ const h2 = [
125
+ ...verticalMargins,
126
+ {
127
+ property: "fontSize",
128
+ value: { type: "unit", value: 32, unit: "px" }
129
+ }
130
+ ];
131
+ const h3 = [
132
+ ...verticalMargins,
133
+ {
134
+ property: "fontSize",
135
+ value: { type: "unit", value: 24, unit: "px" }
136
+ }
137
+ ];
138
+ const h4 = [
139
+ ...verticalMargins,
140
+ {
141
+ property: "fontSize",
142
+ value: { type: "unit", value: 18, unit: "px" }
143
+ }
144
+ ];
145
+ const h5 = [
146
+ ...verticalMargins,
147
+ {
148
+ property: "fontSize",
149
+ value: { type: "unit", value: 14, unit: "px" }
150
+ }
151
+ ];
152
+ const h6 = [
153
+ ...verticalMargins,
154
+ {
155
+ property: "fontSize",
156
+ value: { type: "unit", value: 12, unit: "px" }
157
+ }
158
+ ];
@@ -27,29 +27,45 @@ module.exports = __toCommonJS(embed_template_exports);
27
27
  var import_zod = require("zod");
28
28
  var import_nanoid = require("nanoid");
29
29
  var import_css_data = require("@webstudio-is/css-data");
30
+ var import_expression = require("./expression");
30
31
  const EmbedTemplateText = import_zod.z.object({
31
32
  type: import_zod.z.literal("text"),
32
33
  value: import_zod.z.string()
33
34
  });
35
+ const DataSourceRef = import_zod.z.union([
36
+ import_zod.z.object({
37
+ type: import_zod.z.literal("variable"),
38
+ name: import_zod.z.string()
39
+ }),
40
+ import_zod.z.object({
41
+ type: import_zod.z.literal("expression"),
42
+ name: import_zod.z.string(),
43
+ code: import_zod.z.string()
44
+ })
45
+ ]);
34
46
  const EmbedTemplateProp = import_zod.z.union([
35
47
  import_zod.z.object({
36
48
  type: import_zod.z.literal("number"),
37
49
  name: import_zod.z.string(),
50
+ dataSourceRef: import_zod.z.optional(DataSourceRef),
38
51
  value: import_zod.z.number()
39
52
  }),
40
53
  import_zod.z.object({
41
54
  type: import_zod.z.literal("string"),
42
55
  name: import_zod.z.string(),
56
+ dataSourceRef: import_zod.z.optional(DataSourceRef),
43
57
  value: import_zod.z.string()
44
58
  }),
45
59
  import_zod.z.object({
46
60
  type: import_zod.z.literal("boolean"),
47
61
  name: import_zod.z.string(),
62
+ dataSourceRef: import_zod.z.optional(DataSourceRef),
48
63
  value: import_zod.z.boolean()
49
64
  }),
50
65
  import_zod.z.object({
51
66
  type: import_zod.z.literal("string[]"),
52
67
  name: import_zod.z.string(),
68
+ dataSourceRef: import_zod.z.optional(DataSourceRef),
53
69
  value: import_zod.z.array(import_zod.z.string())
54
70
  })
55
71
  ]);
@@ -73,17 +89,52 @@ const EmbedTemplateInstance = import_zod.z.lazy(
73
89
  const WsEmbedTemplate = import_zod.z.lazy(
74
90
  () => import_zod.z.array(import_zod.z.union([EmbedTemplateInstance, EmbedTemplateText]))
75
91
  );
76
- const createInstancesFromTemplate = (treeTemplate, instances, props, styleSourceSelections, styleSources, styles, defaultBreakpointId) => {
92
+ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, defaultBreakpointId) => {
77
93
  const parentChildren = [];
78
94
  for (const item of treeTemplate) {
79
95
  if (item.type === "instance") {
80
96
  const instanceId = (0, import_nanoid.nanoid)();
81
97
  if (item.props) {
82
98
  for (const prop of item.props) {
99
+ const propId = (0, import_nanoid.nanoid)();
100
+ if (prop.dataSourceRef === void 0) {
101
+ props.push({ id: propId, instanceId, ...prop });
102
+ continue;
103
+ }
104
+ let dataSource = dataSourceByRef.get(prop.dataSourceRef.name);
105
+ if (dataSource === void 0) {
106
+ const id = (0, import_nanoid.nanoid)();
107
+ const { name: propName, dataSourceRef, ...rest } = prop;
108
+ if (dataSourceRef.type === "variable") {
109
+ dataSource = {
110
+ type: "variable",
111
+ id,
112
+ // the first instance where data source is appeared in becomes its scope
113
+ scopeInstanceId: instanceId,
114
+ name: dataSourceRef.name,
115
+ value: rest
116
+ };
117
+ dataSourceByRef.set(dataSourceRef.name, dataSource);
118
+ } else if (dataSourceRef.type === "expression") {
119
+ dataSource = {
120
+ type: "expression",
121
+ id,
122
+ scopeInstanceId: instanceId,
123
+ name: dataSourceRef.name,
124
+ code: dataSourceRef.code
125
+ };
126
+ dataSourceByRef.set(dataSourceRef.name, dataSource);
127
+ } else {
128
+ dataSourceRef;
129
+ continue;
130
+ }
131
+ }
83
132
  props.push({
84
- id: (0, import_nanoid.nanoid)(),
133
+ id: propId,
85
134
  instanceId,
86
- ...prop
135
+ type: "dataSource",
136
+ name: prop.name,
137
+ value: dataSource.id
87
138
  });
88
139
  }
89
140
  }
@@ -119,6 +170,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, styleSource
119
170
  item.children,
120
171
  instances,
121
172
  props,
173
+ dataSourceByRef,
122
174
  styleSourceSelections,
123
175
  styleSources,
124
176
  styles,
@@ -141,6 +193,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, styleSource
141
193
  const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
142
194
  const instances = [];
143
195
  const props = [];
196
+ const dataSourceByRef = /* @__PURE__ */ new Map();
144
197
  const styleSourceSelections = [];
145
198
  const styleSources = [];
146
199
  const styles = [];
@@ -148,15 +201,27 @@ const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
148
201
  treeTemplate,
149
202
  instances,
150
203
  props,
204
+ dataSourceByRef,
151
205
  styleSourceSelections,
152
206
  styleSources,
153
207
  styles,
154
208
  defaultBreakpointId
155
209
  );
210
+ const dataSources = [];
211
+ for (const dataSource of dataSourceByRef.values()) {
212
+ if (dataSource.type === "expression") {
213
+ dataSource.code = (0, import_expression.validateExpression)(dataSource.code, (ref) => {
214
+ const id = dataSourceByRef.get(ref)?.id ?? ref;
215
+ return (0, import_expression.encodeDataSourceVariable)(id);
216
+ });
217
+ }
218
+ dataSources.push(dataSource);
219
+ }
156
220
  return {
157
221
  children,
158
222
  instances,
159
223
  props,
224
+ dataSources,
160
225
  styleSourceSelections,
161
226
  styleSources,
162
227
  styles
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var expression_exports = {};
30
+ __export(expression_exports, {
31
+ decodeDataSourceVariable: () => decodeDataSourceVariable,
32
+ encodeDataSourceVariable: () => encodeDataSourceVariable,
33
+ executeExpressions: () => executeExpressions,
34
+ generateExpressionsComputation: () => generateExpressionsComputation,
35
+ validateExpression: () => validateExpression
36
+ });
37
+ module.exports = __toCommonJS(expression_exports);
38
+ var import_jsep = __toESM(require("jsep"), 1);
39
+ const generateCode = (node, failOnForbidden, transformIdentifier) => {
40
+ if (node.type === "Identifier") {
41
+ return transformIdentifier(node.name);
42
+ }
43
+ if (node.type === "MemberExpression") {
44
+ if (failOnForbidden) {
45
+ const object2 = generateCode(
46
+ node.object,
47
+ false,
48
+ transformIdentifier
49
+ );
50
+ const property2 = generateCode(
51
+ node.property,
52
+ false,
53
+ transformIdentifier
54
+ );
55
+ throw Error(`Cannot access "${property2}" of "${object2}"`);
56
+ }
57
+ const object = generateCode(
58
+ node.object,
59
+ failOnForbidden,
60
+ transformIdentifier
61
+ );
62
+ const property = generateCode(
63
+ node.property,
64
+ failOnForbidden,
65
+ transformIdentifier
66
+ );
67
+ return `${object}.${property}`;
68
+ }
69
+ if (node.type === "Literal") {
70
+ return node.raw;
71
+ }
72
+ if (node.type === "UnaryExpression") {
73
+ const arg = generateCode(
74
+ node.argument,
75
+ failOnForbidden,
76
+ transformIdentifier
77
+ );
78
+ return `${node.operator}${arg}`;
79
+ }
80
+ if (node.type === "BinaryExpression") {
81
+ const left = generateCode(
82
+ node.left,
83
+ failOnForbidden,
84
+ transformIdentifier
85
+ );
86
+ const right = generateCode(
87
+ node.right,
88
+ failOnForbidden,
89
+ transformIdentifier
90
+ );
91
+ return `${left} ${node.operator} ${right}`;
92
+ }
93
+ if (node.type === "ArrayExpression") {
94
+ const elements = node.elements.map(
95
+ (element) => generateCode(element, failOnForbidden, transformIdentifier)
96
+ );
97
+ return `[${elements.join(", ")}]`;
98
+ }
99
+ if (node.type === "CallExpression") {
100
+ if (failOnForbidden) {
101
+ const callee2 = generateCode(
102
+ node.callee,
103
+ false,
104
+ transformIdentifier
105
+ );
106
+ throw Error(`Cannot call "${callee2}"`);
107
+ }
108
+ const callee = generateCode(
109
+ node.callee,
110
+ failOnForbidden,
111
+ transformIdentifier
112
+ );
113
+ const args = node.arguments.map(
114
+ (arg) => generateCode(arg, failOnForbidden, transformIdentifier)
115
+ );
116
+ return `${callee}(${args.join(", ")})`;
117
+ }
118
+ if (node.type === "ThisExpression") {
119
+ if (failOnForbidden) {
120
+ throw Error(`"this" is not supported`);
121
+ }
122
+ return "this";
123
+ }
124
+ if (node.type === "ConditionalExpression") {
125
+ throw Error("Ternary operator is not supported");
126
+ }
127
+ if (node.type === "Compound") {
128
+ throw Error("Cannot use multiple expressions");
129
+ }
130
+ node;
131
+ return "";
132
+ };
133
+ const validateExpression = (code, transformIdentifier = (id) => id) => {
134
+ const expression = (0, import_jsep.default)(code);
135
+ return generateCode(expression, true, transformIdentifier);
136
+ };
137
+ const sortTopologically = (list, depsById, explored = /* @__PURE__ */ new Set(), sorted = []) => {
138
+ for (const id of list) {
139
+ if (explored.has(id)) {
140
+ continue;
141
+ }
142
+ explored.add(id);
143
+ const deps = depsById.get(id);
144
+ if (deps) {
145
+ sortTopologically(deps, depsById, explored, sorted);
146
+ }
147
+ sorted.push(id);
148
+ }
149
+ return sorted;
150
+ };
151
+ const generateExpressionsComputation = (variables, expressions) => {
152
+ const depsById = /* @__PURE__ */ new Map();
153
+ for (const [id, code] of expressions) {
154
+ const deps = /* @__PURE__ */ new Set();
155
+ validateExpression(code, (identifier) => {
156
+ if (variables.has(identifier)) {
157
+ return identifier;
158
+ }
159
+ if (expressions.has(identifier)) {
160
+ deps.add(identifier);
161
+ return identifier;
162
+ }
163
+ throw Error(`Unknown dependency "${identifier}"`);
164
+ });
165
+ depsById.set(id, deps);
166
+ }
167
+ const sortedExpressions = sortTopologically(
168
+ new Set(expressions.keys()),
169
+ depsById
170
+ );
171
+ let generatedCode = "";
172
+ for (const id of variables) {
173
+ generatedCode += `const ${id} = _variables.get('${id}');
174
+ `;
175
+ }
176
+ for (const id of sortedExpressions) {
177
+ const code = expressions.get(id);
178
+ if (code === void 0) {
179
+ continue;
180
+ }
181
+ generatedCode += `const ${id} = (${code});
182
+ `;
183
+ }
184
+ generatedCode += `return new Map([
185
+ `;
186
+ for (const id of sortedExpressions) {
187
+ generatedCode += ` ['${id}', ${id}],
188
+ `;
189
+ }
190
+ generatedCode += `]);`;
191
+ return generatedCode;
192
+ };
193
+ const executeExpressions = (variables, expressions) => {
194
+ const generatedCode = generateExpressionsComputation(
195
+ new Set(variables.keys()),
196
+ expressions
197
+ );
198
+ const executeFn = new Function("_variables", generatedCode);
199
+ const values = executeFn(variables);
200
+ return values;
201
+ };
202
+ const dataSourceVariablePrefix = "$ws$dataSource$";
203
+ const encodeDataSourceVariable = (id) => {
204
+ const encoded = id.replaceAll("-", "__DASH__");
205
+ return `${dataSourceVariablePrefix}${encoded}`;
206
+ };
207
+ const decodeDataSourceVariable = (name) => {
208
+ if (name.startsWith(dataSourceVariablePrefix)) {
209
+ const encoded = name.slice(dataSourceVariablePrefix.length);
210
+ return encoded.replaceAll("__DASH__", "-");
211
+ }
212
+ return;
213
+ };