@webstudio-is/react-sdk 0.82.0 → 0.84.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 (71) hide show
  1. package/LICENSE +661 -21
  2. package/lib/cjs/component-renderer.js +125 -0
  3. package/lib/cjs/components/component-meta.js +10 -0
  4. package/lib/cjs/components/components-utils.js +1 -0
  5. package/lib/cjs/context.js +2 -1
  6. package/lib/cjs/css/index.js +0 -1
  7. package/lib/cjs/css/style-rules.js +1 -1
  8. package/lib/cjs/embed-template.js +130 -55
  9. package/lib/cjs/expression.js +47 -4
  10. package/lib/cjs/hook.js +34 -0
  11. package/lib/cjs/index.js +7 -0
  12. package/lib/cjs/instance-utils.js +65 -0
  13. package/lib/cjs/props.js +18 -3
  14. package/lib/cjs/tree/create-elements-tree.js +5 -4
  15. package/lib/cjs/tree/root.js +7 -2
  16. package/lib/cjs/tree/webstudio-component.js +26 -10
  17. package/lib/component-renderer.js +111 -0
  18. package/lib/components/component-meta.js +10 -0
  19. package/lib/components/components-utils.js +1 -0
  20. package/lib/context.js +2 -1
  21. package/lib/css/index.js +0 -1
  22. package/lib/css/style-rules.js +1 -1
  23. package/lib/embed-template.js +138 -55
  24. package/lib/expression.js +47 -4
  25. package/lib/hook.js +14 -0
  26. package/lib/index.js +10 -1
  27. package/lib/instance-utils.js +45 -0
  28. package/lib/props.js +19 -4
  29. package/lib/tree/create-elements-tree.js +8 -5
  30. package/lib/tree/root.js +14 -4
  31. package/lib/tree/webstudio-component.js +27 -11
  32. package/lib/types/app/root.d.ts +1 -2
  33. package/lib/types/component-renderer.d.ts +8 -0
  34. package/lib/types/components/component-meta.d.ts +14 -8
  35. package/lib/types/context.d.ts +3 -1
  36. package/lib/types/css/css.d.ts +19 -19
  37. package/lib/types/css/global-rules.d.ts +19 -19
  38. package/lib/types/css/index.d.ts +0 -1
  39. package/lib/types/css/normalize.d.ts +47 -47
  40. package/lib/types/embed-template.d.ts +297 -174
  41. package/lib/types/expression.d.ts +3 -2
  42. package/lib/types/hook.d.ts +31 -0
  43. package/lib/types/index.d.ts +5 -2
  44. package/lib/types/instance-utils.d.ts +16 -0
  45. package/lib/types/instance-utils.test.d.ts +1 -0
  46. package/lib/types/props.d.ts +48 -46
  47. package/lib/types/tree/create-elements-tree.d.ts +9 -6
  48. package/lib/types/tree/root.d.ts +8 -5
  49. package/lib/types/tree/webstudio-component.d.ts +16 -7
  50. package/package.json +18 -19
  51. package/src/component-renderer.tsx +117 -0
  52. package/src/components/component-meta.ts +10 -0
  53. package/src/context.tsx +4 -0
  54. package/src/css/index.ts +0 -1
  55. package/src/css/style-rules.ts +1 -1
  56. package/src/embed-template.test.ts +113 -26
  57. package/src/embed-template.ts +149 -56
  58. package/src/expression.test.ts +74 -6
  59. package/src/expression.ts +55 -2
  60. package/src/hook.ts +42 -0
  61. package/src/index.ts +5 -0
  62. package/src/instance-utils.test.ts +89 -0
  63. package/src/instance-utils.ts +65 -0
  64. package/src/props.ts +19 -2
  65. package/src/tree/create-elements-tree.tsx +25 -8
  66. package/src/tree/root.ts +22 -3
  67. package/src/tree/webstudio-component.tsx +42 -14
  68. package/lib/cjs/css/get-browser-style.js +0 -83
  69. package/lib/css/get-browser-style.js +0 -65
  70. package/lib/types/css/get-browser-style.d.ts +0 -2
  71. package/src/css/get-browser-style.ts +0 -81
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var component_renderer_exports = {};
20
+ __export(component_renderer_exports, {
21
+ renderComponentTemplate: () => renderComponentTemplate
22
+ });
23
+ module.exports = __toCommonJS(component_renderer_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_project_build = require("@webstudio-is/project-build");
26
+ var import_embed_template = require("./embed-template");
27
+ var import_css = require("./css");
28
+ var import_tree = require("./tree");
29
+ var import_expression = require("./expression");
30
+ var import_instance_utils = require("./instance-utils");
31
+ const renderComponentTemplate = ({
32
+ name,
33
+ metas: metasRecord,
34
+ components
35
+ }) => {
36
+ const metas = new Map(Object.entries(metasRecord));
37
+ const data = (0, import_embed_template.generateDataFromEmbedTemplate)(
38
+ metas.get(name)?.template ?? [
39
+ {
40
+ type: "instance",
41
+ component: name,
42
+ children: []
43
+ }
44
+ ],
45
+ "base"
46
+ );
47
+ const instances = [
48
+ [
49
+ "root",
50
+ {
51
+ type: "instance",
52
+ id: "root",
53
+ component: "Box",
54
+ children: data.children
55
+ }
56
+ ],
57
+ ...data.instances.map(
58
+ (instance) => [instance.id, instance]
59
+ )
60
+ ];
61
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
62
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: (0, import_css.generateCssText)(
63
+ {
64
+ assets: [],
65
+ breakpoints: [["base", { id: "base", label: "base" }]],
66
+ styles: data.styles.map((item) => [(0, import_project_build.getStyleDeclKey)(item), item]),
67
+ styleSourceSelections: data.styleSourceSelections.map((item) => [
68
+ item.instanceId,
69
+ item
70
+ ]),
71
+ componentMetas: metas
72
+ },
73
+ { assetBaseUrl: "/" }
74
+ ) }),
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
76
+ import_tree.InstanceRoot,
77
+ {
78
+ data: {
79
+ page: {
80
+ path: "",
81
+ id: "",
82
+ name: "",
83
+ title: "",
84
+ meta: {},
85
+ rootInstanceId: "root"
86
+ },
87
+ pages: [],
88
+ assets: [],
89
+ build: {
90
+ instances,
91
+ props: data.props.map((prop) => [prop.id, prop]),
92
+ dataSources: data.dataSources.map((dataSource) => [
93
+ dataSource.id,
94
+ dataSource
95
+ ])
96
+ }
97
+ },
98
+ executeComputingExpressions: (values) => {
99
+ const expressions = /* @__PURE__ */ new Map();
100
+ for (const dataSource of data.dataSources) {
101
+ const name2 = (0, import_expression.encodeDataSourceVariable)(dataSource.id);
102
+ if (dataSource.type === "expression") {
103
+ expressions.set(name2, dataSource.code);
104
+ }
105
+ }
106
+ return (0, import_expression.decodeVariablesMap)(
107
+ (0, import_expression.executeComputingExpressions)(expressions, (0, import_expression.encodeVariablesMap)(values))
108
+ );
109
+ },
110
+ executeEffectfulExpression: (code, args, values) => {
111
+ return (0, import_expression.decodeVariablesMap)(
112
+ (0, import_expression.executeEffectfulExpression)(code, args, (0, import_expression.encodeVariablesMap)(values))
113
+ );
114
+ },
115
+ Component: import_tree.WebstudioComponent,
116
+ components: new Map(Object.entries(components)),
117
+ indexesWithinAncestors: (0, import_instance_utils.getIndexesWithinAncestors)(
118
+ metas,
119
+ new Map(instances),
120
+ ["root"]
121
+ )
122
+ }
123
+ )
124
+ ] });
125
+ };
@@ -37,6 +37,7 @@ const componentCategories = [
37
37
  "text",
38
38
  "media",
39
39
  "forms",
40
+ "radix",
40
41
  "hidden"
41
42
  ];
42
43
  const stateCategories = ["states", "component-states"];
@@ -61,7 +62,16 @@ const WsComponentMeta = import_zod.z.object({
61
62
  type: import_zod.z.enum(["container", "control", "embed", "rich-text-child"]),
62
63
  requiredAncestors: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
63
64
  invalidAncestors: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
65
+ // when this field is specified component receives
66
+ // prop with index of same components withiin specified ancestor
67
+ // important to automatically enumerate collections without
68
+ // naming every item manually
69
+ indexWithinAncestor: import_zod.z.optional(import_zod.z.string()),
64
70
  stylable: import_zod.z.optional(import_zod.z.boolean()),
71
+ // specifies whether the instance can be deleted,
72
+ // copied or dragged out of its parent instance
73
+ // true by default
74
+ detachable: import_zod.z.optional(import_zod.z.boolean()),
65
75
  label: import_zod.z.string(),
66
76
  description: import_zod.z.string().optional(),
67
77
  icon: import_zod.z.string(),
@@ -14,3 +14,4 @@ var __copyProps = (to, from, except, desc) => {
14
14
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
15
  var components_utils_exports = {};
16
16
  module.exports = __toCommonJS(components_utils_exports);
17
+ var import_tree = require("../tree");
@@ -38,5 +38,6 @@ const ReactSdkContext = (0, import_react.createContext)({
38
38
  },
39
39
  setBoundDataSourceValue: () => {
40
40
  throw Error("React SDK setBoundDataSourceValue is not implemented");
41
- }
41
+ },
42
+ indexesWithinAncestors: /* @__PURE__ */ new Map()
42
43
  });
@@ -15,7 +15,6 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
15
15
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
16
  var css_exports = {};
17
17
  module.exports = __toCommonJS(css_exports);
18
- __reExport(css_exports, require("./get-browser-style"), module.exports);
19
18
  __reExport(css_exports, require("./global-rules"), module.exports);
20
19
  __reExport(css_exports, require("./style-rules"), module.exports);
21
20
  __reExport(css_exports, require("./css"), module.exports);
@@ -73,7 +73,7 @@ const getPresetStyleRules = (component, presetStyle) => {
73
73
  const presetStyleRules = /* @__PURE__ */ new Map();
74
74
  for (const [tag, styles] of Object.entries(presetStyle)) {
75
75
  for (const styleDecl of styles) {
76
- const selector = `${tag}:where([${import_tree.componentAttribute}=${component}])${styleDecl.state ?? ""}`;
76
+ const selector = `${tag}:where([${import_tree.componentAttribute}="${component}"])${styleDecl.state ?? ""}`;
77
77
  let rule = presetStyleRules.get(selector);
78
78
  if (rule === void 0) {
79
79
  rule = {};
@@ -21,52 +21,58 @@ __export(embed_template_exports, {
21
21
  EmbedTemplateInstance: () => EmbedTemplateInstance,
22
22
  EmbedTemplateStyleDecl: () => EmbedTemplateStyleDecl,
23
23
  WsEmbedTemplate: () => WsEmbedTemplate,
24
- generateDataFromEmbedTemplate: () => generateDataFromEmbedTemplate
24
+ generateDataFromEmbedTemplate: () => generateDataFromEmbedTemplate,
25
+ namespaceMeta: () => namespaceMeta
25
26
  });
26
27
  module.exports = __toCommonJS(embed_template_exports);
27
28
  var import_zod = require("zod");
28
29
  var import_nanoid = require("nanoid");
30
+ var import_project_build = require("@webstudio-is/project-build");
29
31
  var import_css_data = require("@webstudio-is/css-data");
30
32
  var import_expression = require("./expression");
31
33
  const EmbedTemplateText = import_zod.z.object({
32
34
  type: import_zod.z.literal("text"),
33
35
  value: import_zod.z.string()
34
36
  });
35
- const DataSourceVariableRef = import_zod.z.object({
36
- type: import_zod.z.literal("variable"),
37
- name: import_zod.z.string()
38
- });
39
- const DataSourceRef = import_zod.z.union([
40
- DataSourceVariableRef,
37
+ const EmbedTemplateDataSource = import_zod.z.union([
38
+ import_zod.z.object({
39
+ type: import_zod.z.literal("variable"),
40
+ initialValue: import_zod.z.union([
41
+ import_zod.z.string(),
42
+ import_zod.z.number(),
43
+ import_zod.z.boolean(),
44
+ import_zod.z.array(import_zod.z.string())
45
+ ])
46
+ }),
41
47
  import_zod.z.object({
42
48
  type: import_zod.z.literal("expression"),
43
- name: import_zod.z.string(),
44
49
  code: import_zod.z.string()
45
50
  })
46
51
  ]);
47
52
  const EmbedTemplateProp = import_zod.z.union([
53
+ import_zod.z.object({
54
+ type: import_zod.z.literal("dataSource"),
55
+ name: import_zod.z.string(),
56
+ dataSourceName: import_zod.z.string()
57
+ }),
48
58
  import_zod.z.object({
49
59
  type: import_zod.z.literal("number"),
50
60
  name: import_zod.z.string(),
51
- dataSourceRef: import_zod.z.optional(DataSourceRef),
52
61
  value: import_zod.z.number()
53
62
  }),
54
63
  import_zod.z.object({
55
64
  type: import_zod.z.literal("string"),
56
65
  name: import_zod.z.string(),
57
- dataSourceRef: import_zod.z.optional(DataSourceRef),
58
66
  value: import_zod.z.string()
59
67
  }),
60
68
  import_zod.z.object({
61
69
  type: import_zod.z.literal("boolean"),
62
70
  name: import_zod.z.string(),
63
- dataSourceRef: import_zod.z.optional(DataSourceRef),
64
71
  value: import_zod.z.boolean()
65
72
  }),
66
73
  import_zod.z.object({
67
74
  type: import_zod.z.literal("string[]"),
68
75
  name: import_zod.z.string(),
69
- dataSourceRef: import_zod.z.optional(DataSourceRef),
70
76
  value: import_zod.z.array(import_zod.z.string())
71
77
  }),
72
78
  import_zod.z.object({
@@ -75,6 +81,7 @@ const EmbedTemplateProp = import_zod.z.union([
75
81
  value: import_zod.z.array(
76
82
  import_zod.z.object({
77
83
  type: import_zod.z.literal("execute"),
84
+ args: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
78
85
  code: import_zod.z.string()
79
86
  })
80
87
  )
@@ -92,6 +99,7 @@ const EmbedTemplateInstance = import_zod.z.lazy(
92
99
  type: import_zod.z.literal("instance"),
93
100
  component: import_zod.z.string(),
94
101
  label: import_zod.z.optional(import_zod.z.string()),
102
+ dataSources: import_zod.z.optional(import_zod.z.record(import_zod.z.string(), EmbedTemplateDataSource)),
95
103
  props: import_zod.z.optional(import_zod.z.array(EmbedTemplateProp)),
96
104
  styles: import_zod.z.optional(import_zod.z.array(EmbedTemplateStyleDecl)),
97
105
  children: WsEmbedTemplate
@@ -100,11 +108,58 @@ const EmbedTemplateInstance = import_zod.z.lazy(
100
108
  const WsEmbedTemplate = import_zod.z.lazy(
101
109
  () => import_zod.z.array(import_zod.z.union([EmbedTemplateInstance, EmbedTemplateText]))
102
110
  );
111
+ const getDataSourceValue = (value) => {
112
+ if (typeof value === "string") {
113
+ return { type: "string", value };
114
+ }
115
+ if (typeof value === "number") {
116
+ return { type: "number", value };
117
+ }
118
+ if (typeof value === "boolean") {
119
+ return { type: "boolean", value };
120
+ }
121
+ if (Array.isArray(value)) {
122
+ return { type: "string[]", value };
123
+ }
124
+ value;
125
+ throw Error("Impossible case");
126
+ };
103
127
  const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, defaultBreakpointId) => {
104
128
  const parentChildren = [];
105
129
  for (const item of treeTemplate) {
106
130
  if (item.type === "instance") {
107
131
  const instanceId = (0, import_nanoid.nanoid)();
132
+ if (item.dataSources) {
133
+ for (const [name, dataSource] of Object.entries(item.dataSources)) {
134
+ if (dataSourceByRef.has(name)) {
135
+ throw Error(`${name} data source already defined`);
136
+ }
137
+ if (dataSource.type === "variable") {
138
+ dataSourceByRef.set(name, {
139
+ type: "variable",
140
+ id: (0, import_nanoid.nanoid)(),
141
+ scopeInstanceId: instanceId,
142
+ name,
143
+ value: getDataSourceValue(dataSource.initialValue)
144
+ });
145
+ }
146
+ if (dataSource.type === "expression") {
147
+ dataSourceByRef.set(name, {
148
+ type: "expression",
149
+ id: (0, import_nanoid.nanoid)(),
150
+ scopeInstanceId: instanceId,
151
+ name,
152
+ // replace all references with variable names
153
+ code: (0, import_expression.validateExpression)(dataSource.code, {
154
+ transformIdentifier: (ref) => {
155
+ const id = dataSourceByRef.get(ref)?.id ?? ref;
156
+ return (0, import_expression.encodeDataSourceVariable)(id);
157
+ }
158
+ })
159
+ });
160
+ }
161
+ }
162
+ }
108
163
  if (item.props) {
109
164
  for (const prop of item.props) {
110
165
  const propId = (0, import_nanoid.nanoid)();
@@ -115,12 +170,17 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
115
170
  type: "action",
116
171
  name: prop.name,
117
172
  value: prop.value.map((value) => {
173
+ const args = value.args ?? [];
118
174
  return {
119
175
  type: "execute",
176
+ args,
120
177
  // replace all references with variable names
121
178
  code: (0, import_expression.validateExpression)(value.code, {
122
179
  effectful: true,
123
180
  transformIdentifier: (ref) => {
181
+ if (args.includes(ref)) {
182
+ return ref;
183
+ }
124
184
  const id = dataSourceByRef.get(ref)?.id ?? ref;
125
185
  return (0, import_expression.encodeDataSourceVariable)(id);
126
186
  }
@@ -130,51 +190,21 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
130
190
  });
131
191
  continue;
132
192
  }
133
- if (prop.dataSourceRef === void 0) {
134
- props.push({ id: propId, instanceId, ...prop });
135
- continue;
136
- }
137
- let dataSource = dataSourceByRef.get(prop.dataSourceRef.name);
138
- if (dataSource === void 0) {
139
- const id = (0, import_nanoid.nanoid)();
140
- const { name: propName, dataSourceRef, ...rest } = prop;
141
- if (dataSourceRef.type === "variable") {
142
- dataSource = {
143
- type: "variable",
144
- id,
145
- // the first instance where data source is appeared in becomes its scope
146
- scopeInstanceId: instanceId,
147
- name: dataSourceRef.name,
148
- value: rest
149
- };
150
- dataSourceByRef.set(dataSourceRef.name, dataSource);
151
- } else if (dataSourceRef.type === "expression") {
152
- dataSource = {
153
- type: "expression",
154
- id,
155
- scopeInstanceId: instanceId,
156
- name: dataSourceRef.name,
157
- // replace all references with variable names
158
- code: (0, import_expression.validateExpression)(dataSourceRef.code, {
159
- transformIdentifier: (ref) => {
160
- const id2 = dataSourceByRef.get(ref)?.id ?? ref;
161
- return (0, import_expression.encodeDataSourceVariable)(id2);
162
- }
163
- })
164
- };
165
- dataSourceByRef.set(dataSourceRef.name, dataSource);
166
- } else {
167
- dataSourceRef;
168
- continue;
193
+ if (prop.type === "dataSource") {
194
+ const dataSource = dataSourceByRef.get(prop.dataSourceName);
195
+ if (dataSource === void 0) {
196
+ throw Error(`${prop.dataSourceName} data source is not defined`);
169
197
  }
198
+ props.push({
199
+ id: propId,
200
+ instanceId,
201
+ type: "dataSource",
202
+ name: prop.name,
203
+ value: dataSource.id
204
+ });
205
+ continue;
170
206
  }
171
- props.push({
172
- id: propId,
173
- instanceId,
174
- type: "dataSource",
175
- name: prop.name,
176
- value: dataSource.id
177
- });
207
+ props.push({ id: propId, instanceId, ...prop });
178
208
  }
179
209
  }
180
210
  if (item.styles) {
@@ -256,3 +286,48 @@ const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
256
286
  styles
257
287
  };
258
288
  };
289
+ const namespaceEmbedTemplateComponents = (template, namespace, components) => {
290
+ return template.map((item) => {
291
+ if (item.type === "text") {
292
+ return item;
293
+ }
294
+ if (item.type === "instance") {
295
+ const prefix = components.has(item.component) ? `${namespace}:` : "";
296
+ return {
297
+ ...item,
298
+ component: `${prefix}${item.component}`,
299
+ children: namespaceEmbedTemplateComponents(
300
+ item.children,
301
+ namespace,
302
+ components
303
+ )
304
+ };
305
+ }
306
+ item;
307
+ throw Error("Impossible case");
308
+ });
309
+ };
310
+ const namespaceMeta = (meta, namespace, components) => {
311
+ const newMeta = { ...meta };
312
+ if (newMeta.requiredAncestors) {
313
+ newMeta.requiredAncestors = newMeta.requiredAncestors.map(
314
+ (component) => components.has(component) ? `${namespace}:${component}` : component
315
+ );
316
+ }
317
+ if (newMeta.invalidAncestors) {
318
+ newMeta.invalidAncestors = newMeta.invalidAncestors.map(
319
+ (component) => components.has(component) ? `${namespace}:${component}` : component
320
+ );
321
+ }
322
+ if (newMeta.indexWithinAncestor) {
323
+ newMeta.indexWithinAncestor = components.has(newMeta.indexWithinAncestor) ? `${namespace}:${newMeta.indexWithinAncestor}` : newMeta.indexWithinAncestor;
324
+ }
325
+ if (newMeta.template) {
326
+ newMeta.template = namespaceEmbedTemplateComponents(
327
+ newMeta.template,
328
+ namespace,
329
+ components
330
+ );
331
+ }
332
+ return newMeta;
333
+ };
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var expression_exports = {};
30
30
  __export(expression_exports, {
31
+ computeExpressionsDependencies: () => computeExpressionsDependencies,
31
32
  decodeDataSourceVariable: () => decodeDataSourceVariable,
32
33
  decodeVariablesMap: () => decodeVariablesMap,
33
34
  encodeDataSourceVariable: () => encodeDataSourceVariable,
@@ -249,12 +250,15 @@ const executeComputingExpressions = (expressions, variables) => {
249
250
  const values = executeFn(variables);
250
251
  return values;
251
252
  };
252
- const generateEffectfulExpression = (code, allowedVariables) => {
253
+ const generateEffectfulExpression = (code, args, allowedVariables) => {
253
254
  const inputVariables = /* @__PURE__ */ new Set();
254
255
  const outputVariables = /* @__PURE__ */ new Set();
255
256
  validateExpression(code, {
256
257
  effectful: true,
257
258
  transformIdentifier: (identifier, assignee) => {
259
+ if (args.has(identifier)) {
260
+ return identifier;
261
+ }
258
262
  if (allowedVariables.has(identifier)) {
259
263
  if (assignee) {
260
264
  outputVariables.add(identifier);
@@ -267,6 +271,10 @@ const generateEffectfulExpression = (code, allowedVariables) => {
267
271
  }
268
272
  });
269
273
  let generatedCode = "";
274
+ for (const id of args) {
275
+ generatedCode += `let ${id} = _args.get('${id}');
276
+ `;
277
+ }
270
278
  for (const id of inputVariables) {
271
279
  generatedCode += `let ${id} = _variables.get('${id}');
272
280
  `;
@@ -288,15 +296,50 @@ const generateEffectfulExpression = (code, allowedVariables) => {
288
296
  generatedCode += `]);`;
289
297
  return generatedCode;
290
298
  };
291
- const executeEffectfulExpression = (code, variables) => {
299
+ const executeEffectfulExpression = (code, args, variables) => {
292
300
  const generatedCode = generateEffectfulExpression(
293
301
  code,
302
+ new Set(args.keys()),
294
303
  new Set(variables.keys())
295
304
  );
296
- const executeFn = new Function("_variables", generatedCode);
297
- const values = executeFn(variables);
305
+ const executeFn = new Function("_variables", "_args", generatedCode);
306
+ const values = executeFn(variables, args);
298
307
  return values;
299
308
  };
309
+ const computeExpressionDependencies = (expressions, expressionId, dependencies) => {
310
+ const depsById = dependencies.get(expressionId);
311
+ if (depsById) {
312
+ return depsById;
313
+ }
314
+ const parentDeps = /* @__PURE__ */ new Set();
315
+ const code = expressions.get(expressionId);
316
+ if (code === void 0) {
317
+ return parentDeps;
318
+ }
319
+ dependencies.set(expressionId, parentDeps);
320
+ validateExpression(code, {
321
+ transformIdentifier: (id) => {
322
+ parentDeps.add(id);
323
+ const childDeps = computeExpressionDependencies(
324
+ expressions,
325
+ id,
326
+ dependencies
327
+ );
328
+ for (const depId of childDeps) {
329
+ parentDeps.add(depId);
330
+ }
331
+ return id;
332
+ }
333
+ });
334
+ return parentDeps;
335
+ };
336
+ const computeExpressionsDependencies = (expressions) => {
337
+ const dependencies = /* @__PURE__ */ new Map();
338
+ for (const id of expressions.keys()) {
339
+ computeExpressionDependencies(expressions, id, dependencies);
340
+ }
341
+ return dependencies;
342
+ };
300
343
  const dataSourceVariablePrefix = "$ws$dataSource$";
301
344
  const encodeDataSourceVariable = (id) => {
302
345
  const encoded = id.replaceAll("-", "__DASH__");
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var hook_exports = {};
20
+ __export(hook_exports, {
21
+ getClosestInstance: () => getClosestInstance
22
+ });
23
+ module.exports = __toCommonJS(hook_exports);
24
+ const getClosestInstance = (instanceSelection, currentInstance, closestComponent) => {
25
+ let matched = false;
26
+ for (const instance of instanceSelection) {
27
+ if (currentInstance === instance) {
28
+ matched = true;
29
+ }
30
+ if (matched && instance.component === closestComponent) {
31
+ return instance;
32
+ }
33
+ }
34
+ };
package/lib/cjs/index.js CHANGED
@@ -21,6 +21,7 @@ var src_exports = {};
21
21
  __export(src_exports, {
22
22
  ReactSdkContext: () => import_context.ReactSdkContext,
23
23
  componentCategories: () => import_component_meta.componentCategories,
24
+ computeExpressionsDependencies: () => import_expression.computeExpressionsDependencies,
24
25
  decodeDataSourceVariable: () => import_expression.decodeDataSourceVariable,
25
26
  decodeVariablesMap: () => import_expression.decodeVariablesMap,
26
27
  defaultStates: () => import_component_meta.defaultStates,
@@ -30,7 +31,10 @@ __export(src_exports, {
30
31
  executeEffectfulExpression: () => import_expression.executeEffectfulExpression,
31
32
  generateComputingExpressions: () => import_expression.generateComputingExpressions,
32
33
  generateEffectfulExpression: () => import_expression.generateEffectfulExpression,
34
+ getIndexWithinAncestorFromComponentProps: () => import_props.getIndexWithinAncestorFromComponentProps,
35
+ getIndexesWithinAncestors: () => import_instance_utils.getIndexesWithinAncestors,
33
36
  getInstanceIdFromComponentProps: () => import_props.getInstanceIdFromComponentProps,
37
+ renderComponentTemplate: () => import_component_renderer.renderComponentTemplate,
34
38
  stateCategories: () => import_component_meta.stateCategories,
35
39
  useInstanceProps: () => import_props.useInstanceProps,
36
40
  usePropAsset: () => import_props.usePropAsset,
@@ -48,3 +52,6 @@ __reExport(src_exports, require("./embed-template"), module.exports);
48
52
  var import_props = require("./props");
49
53
  var import_context = require("./context");
50
54
  var import_expression = require("./expression");
55
+ var import_component_renderer = require("./component-renderer");
56
+ var import_instance_utils = require("./instance-utils");
57
+ __reExport(src_exports, require("./hook"), module.exports);
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var instance_utils_exports = {};
20
+ __export(instance_utils_exports, {
21
+ getIndexesWithinAncestors: () => getIndexesWithinAncestors
22
+ });
23
+ module.exports = __toCommonJS(instance_utils_exports);
24
+ const getIndexesWithinAncestors = (metas, instances, rootIds) => {
25
+ const ancestors = /* @__PURE__ */ new Set();
26
+ for (const meta of metas.values()) {
27
+ if (meta.indexWithinAncestor !== void 0) {
28
+ ancestors.add(meta.indexWithinAncestor);
29
+ }
30
+ }
31
+ const indexes = /* @__PURE__ */ new Map();
32
+ const traverseInstances = (instances2, instanceId, latestIndexes2 = /* @__PURE__ */ new Map()) => {
33
+ const instance = instances2.get(instanceId);
34
+ if (instance === void 0) {
35
+ return;
36
+ }
37
+ const meta = metas.get(instance.component);
38
+ if (meta === void 0) {
39
+ return;
40
+ }
41
+ if (ancestors.has(instance.component)) {
42
+ latestIndexes2 = new Map(latestIndexes2);
43
+ latestIndexes2.set(instance.component, /* @__PURE__ */ new Map());
44
+ }
45
+ if (meta.indexWithinAncestor !== void 0) {
46
+ const ancestorIndexes = latestIndexes2.get(meta.indexWithinAncestor);
47
+ if (ancestorIndexes !== void 0) {
48
+ let index = ancestorIndexes.get(instance.component) ?? -1;
49
+ index += 1;
50
+ ancestorIndexes.set(instance.component, index);
51
+ indexes.set(instance.id, index);
52
+ }
53
+ }
54
+ for (const child of instance.children) {
55
+ if (child.type === "id") {
56
+ traverseInstances(instances2, child.value, latestIndexes2);
57
+ }
58
+ }
59
+ };
60
+ const latestIndexes = /* @__PURE__ */ new Map();
61
+ for (const instanceId of rootIds) {
62
+ traverseInstances(instances, instanceId, latestIndexes);
63
+ }
64
+ return indexes;
65
+ };