@webstudio-is/react-sdk 0.99.1-596a55d.0 → 0.99.1-6ad9b47.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/index.js CHANGED
@@ -29,13 +29,7 @@ var ReactSdkContext = createContext({
29
29
  propsByInstanceIdStore: atom(/* @__PURE__ */ new Map()),
30
30
  assetsStore: atom(/* @__PURE__ */ new Map()),
31
31
  pagesStore: atom(/* @__PURE__ */ new Map()),
32
- dataSourceValuesStore: atom(/* @__PURE__ */ new Map()),
33
- executeEffectfulExpression: () => {
34
- throw Error("React SDK executeEffectfulExpression is not implemented");
35
- },
36
- setDataSourceValues: () => {
37
- throw Error("React SDK setDataSourceValues is not implemented");
38
- },
32
+ dataSourcesLogicStore: atom(/* @__PURE__ */ new Map()),
39
33
  indexesWithinAncestors: /* @__PURE__ */ new Map()
40
34
  });
41
35
 
@@ -51,9 +45,7 @@ var createElementsTree = ({
51
45
  propsByInstanceIdStore,
52
46
  assetsStore,
53
47
  pagesStore,
54
- dataSourceValuesStore,
55
- executeEffectfulExpression: executeEffectfulExpression2,
56
- onDataSourceUpdate,
48
+ dataSourcesLogicStore,
57
49
  indexesWithinAncestors,
58
50
  Component,
59
51
  components,
@@ -90,14 +82,12 @@ var createElementsTree = ({
90
82
  propsByInstanceIdStore,
91
83
  assetsStore,
92
84
  pagesStore,
93
- dataSourceValuesStore,
85
+ dataSourcesLogicStore,
94
86
  renderer,
95
87
  imageLoader,
96
88
  assetBaseUrl,
97
89
  imageBaseUrl,
98
- indexesWithinAncestors,
99
- executeEffectfulExpression: executeEffectfulExpression2,
100
- setDataSourceValues: onDataSourceUpdate
90
+ indexesWithinAncestors
101
91
  },
102
92
  children: root
103
93
  }
@@ -160,8 +150,7 @@ var createInstanceElement = ({
160
150
 
161
151
  // src/tree/root.ts
162
152
  import {
163
- useRef,
164
- useCallback
153
+ useRef
165
154
  } from "react";
166
155
  import {
167
156
  atom as atom2,
@@ -190,16 +179,14 @@ var getPropsByInstanceId = (props) => {
190
179
  var useInstanceProps = (instanceId) => {
191
180
  const {
192
181
  propsByInstanceIdStore,
193
- dataSourceValuesStore,
194
- executeEffectfulExpression: executeEffectfulExpression2,
195
- setDataSourceValues,
182
+ dataSourcesLogicStore,
196
183
  indexesWithinAncestors
197
184
  } = useContext(ReactSdkContext);
198
185
  const index = indexesWithinAncestors.get(instanceId);
199
186
  const instancePropsObjectStore = useMemo(() => {
200
187
  return computed(
201
- [propsByInstanceIdStore, dataSourceValuesStore],
202
- (propsByInstanceId, dataSourceValues) => {
188
+ [propsByInstanceIdStore, dataSourcesLogicStore],
189
+ (propsByInstanceId, dataSourcesLogic) => {
203
190
  const instancePropsObject2 = {};
204
191
  if (index !== void 0) {
205
192
  instancePropsObject2[indexAttribute] = index.toString();
@@ -214,29 +201,17 @@ var useInstanceProps = (instanceId) => {
214
201
  }
215
202
  if (prop.type === "dataSource") {
216
203
  const dataSourceId = prop.value;
217
- const value = dataSourceValues.get(dataSourceId);
204
+ const value = dataSourcesLogic.get(dataSourceId);
218
205
  if (value !== void 0) {
219
206
  instancePropsObject2[prop.name] = value;
220
207
  }
221
208
  continue;
222
209
  }
223
210
  if (prop.type === "action") {
224
- instancePropsObject2[prop.name] = (...args) => {
225
- for (const value of prop.value) {
226
- if (value.type === "execute") {
227
- const argsMap = /* @__PURE__ */ new Map();
228
- for (const [i, name] of value.args.entries()) {
229
- argsMap.set(name, args[i]);
230
- }
231
- const newValues = executeEffectfulExpression2(
232
- value.code,
233
- argsMap,
234
- dataSourceValues
235
- );
236
- setDataSourceValues(newValues);
237
- }
238
- }
239
- };
211
+ const action = dataSourcesLogic.get(prop.id);
212
+ if (typeof action === "function") {
213
+ instancePropsObject2[prop.name] = action;
214
+ }
240
215
  continue;
241
216
  }
242
217
  instancePropsObject2[prop.name] = prop.value;
@@ -244,14 +219,7 @@ var useInstanceProps = (instanceId) => {
244
219
  return instancePropsObject2;
245
220
  }
246
221
  );
247
- }, [
248
- propsByInstanceIdStore,
249
- dataSourceValuesStore,
250
- instanceId,
251
- executeEffectfulExpression2,
252
- setDataSourceValues,
253
- index
254
- ]);
222
+ }, [propsByInstanceIdStore, dataSourcesLogicStore, instanceId, index]);
255
223
  const instancePropsObject = useStore(instancePropsObjectStore);
256
224
  return instancePropsObject;
257
225
  };
@@ -415,51 +383,35 @@ var InstanceRoot = ({
415
383
  scripts,
416
384
  imageLoader
417
385
  }) => {
418
- const {
419
- indexesWithinAncestors,
420
- executeComputingExpressions: executeComputingExpressions2,
421
- executeEffectfulExpression: executeEffectfulExpression2
422
- } = utils;
386
+ const { indexesWithinAncestors, getDataSourcesLogic } = utils;
423
387
  const dataSourceVariablesStoreRef = useRef(void 0);
424
388
  if (dataSourceVariablesStoreRef.current === void 0) {
425
389
  dataSourceVariablesStoreRef.current = atom2(/* @__PURE__ */ new Map());
426
390
  }
427
391
  const dataSourceVariablesStore = dataSourceVariablesStoreRef.current;
428
- const dataSourceValuesStoreRef = useRef(void 0);
429
- if (dataSourceValuesStoreRef.current === void 0) {
430
- dataSourceValuesStoreRef.current = computed2(
392
+ const dataSourcesLogicStoreRef = useRef(void 0);
393
+ if (dataSourcesLogicStoreRef.current === void 0) {
394
+ dataSourcesLogicStoreRef.current = computed2(
431
395
  dataSourceVariablesStore,
432
396
  (dataSourceVariables) => {
433
- const dataSourceValues = /* @__PURE__ */ new Map();
434
- for (const [dataSourceId, dataSource] of data.build.dataSources) {
435
- if (dataSource.type === "variable") {
436
- const value = dataSourceVariables.get(dataSourceId) ?? dataSource.value.value;
437
- dataSourceValues.set(dataSourceId, value);
438
- }
439
- }
440
397
  try {
441
- const result = executeComputingExpressions2(dataSourceValues);
442
- for (const [id, value] of result) {
443
- dataSourceValues.set(id, value);
444
- }
398
+ const getVariable = (id) => {
399
+ return dataSourceVariables.get(id);
400
+ };
401
+ const setVariable = (id, value) => {
402
+ const dataSourceVariables2 = new Map(dataSourceVariablesStore.get());
403
+ dataSourceVariables2.set(id, value);
404
+ dataSourceVariablesStore.set(dataSourceVariables2);
405
+ };
406
+ return getDataSourcesLogic(getVariable, setVariable);
445
407
  } catch (error) {
446
408
  console.error(error);
447
409
  }
448
- return dataSourceValues;
410
+ return /* @__PURE__ */ new Map();
449
411
  }
450
412
  );
451
413
  }
452
- const dataSourceValuesStore = dataSourceValuesStoreRef.current;
453
- const onDataSourceUpdate = useCallback(
454
- (newValues) => {
455
- const dataSourceVariables = new Map(dataSourceVariablesStore.get());
456
- for (const [dataSourceId, value] of newValues) {
457
- dataSourceVariables.set(dataSourceId, value);
458
- }
459
- dataSourceVariablesStore.set(dataSourceVariables);
460
- },
461
- [dataSourceVariablesStore]
462
- );
414
+ const dataSourcesLogicStore = dataSourcesLogicStoreRef.current;
463
415
  return createElementsTree({
464
416
  imageLoader,
465
417
  imageBaseUrl: data.params?.imageBaseUrl ?? "/",
@@ -472,9 +424,7 @@ var InstanceRoot = ({
472
424
  assetsStore: atom2(new Map(data.assets.map((asset) => [asset.id, asset]))),
473
425
  pagesStore: atom2(new Map(data.pages.map((page) => [page.id, page]))),
474
426
  indexesWithinAncestors,
475
- executeEffectfulExpression: executeEffectfulExpression2,
476
- dataSourceValuesStore,
477
- onDataSourceUpdate,
427
+ dataSourcesLogicStore,
478
428
  Component: Component ?? WebstudioComponent,
479
429
  components,
480
430
  scripts
@@ -937,117 +887,6 @@ var sortTopologically = (list, depsById, explored = /* @__PURE__ */ new Set(), s
937
887
  }
938
888
  return sorted;
939
889
  };
940
- var generateComputingExpressions = (expressions, allowedVariables) => {
941
- const depsById = /* @__PURE__ */ new Map();
942
- const inputVariables = /* @__PURE__ */ new Set();
943
- for (const [id, code] of expressions) {
944
- const deps = /* @__PURE__ */ new Set();
945
- validateExpression(code, {
946
- transformIdentifier: (identifier) => {
947
- if (allowedVariables.has(identifier)) {
948
- inputVariables.add(identifier);
949
- return identifier;
950
- }
951
- if (expressions.has(identifier)) {
952
- deps.add(identifier);
953
- return identifier;
954
- }
955
- throw Error(`Unknown dependency "${identifier}"`);
956
- }
957
- });
958
- depsById.set(id, deps);
959
- }
960
- const sortedExpressions = sortTopologically(
961
- new Set(expressions.keys()),
962
- depsById
963
- );
964
- let generatedCode = "";
965
- for (const id of inputVariables) {
966
- generatedCode += `const ${id} = _variables.get('${id}');
967
- `;
968
- }
969
- for (const id of sortedExpressions) {
970
- const code = expressions.get(id);
971
- if (code === void 0) {
972
- continue;
973
- }
974
- generatedCode += `const ${id} = (${code});
975
- `;
976
- }
977
- generatedCode += `return new Map([
978
- `;
979
- for (const id of sortedExpressions) {
980
- generatedCode += ` ['${id}', ${id}],
981
- `;
982
- }
983
- generatedCode += `]);`;
984
- return generatedCode;
985
- };
986
- var executeComputingExpressions = (expressions, variables) => {
987
- const generatedCode = generateComputingExpressions(
988
- expressions,
989
- new Set(variables.keys())
990
- );
991
- const executeFn = new Function("_variables", generatedCode);
992
- const values = executeFn(variables);
993
- return values;
994
- };
995
- var generateEffectfulExpression = (code, args, allowedVariables) => {
996
- const inputVariables = /* @__PURE__ */ new Set();
997
- const outputVariables = /* @__PURE__ */ new Set();
998
- validateExpression(code, {
999
- effectful: true,
1000
- transformIdentifier: (identifier, assignee) => {
1001
- if (args.has(identifier)) {
1002
- return identifier;
1003
- }
1004
- if (allowedVariables.has(identifier)) {
1005
- if (assignee) {
1006
- outputVariables.add(identifier);
1007
- } else {
1008
- inputVariables.add(identifier);
1009
- }
1010
- return identifier;
1011
- }
1012
- throw Error(`Unknown dependency "${identifier}"`);
1013
- }
1014
- });
1015
- let generatedCode = "";
1016
- for (const id of args) {
1017
- generatedCode += `let ${id} = _args.get('${id}');
1018
- `;
1019
- }
1020
- for (const id of inputVariables) {
1021
- generatedCode += `let ${id} = _variables.get('${id}');
1022
- `;
1023
- }
1024
- for (const id of outputVariables) {
1025
- if (inputVariables.has(id) === false) {
1026
- generatedCode += `let ${id};
1027
- `;
1028
- }
1029
- }
1030
- generatedCode += `${code};
1031
- `;
1032
- generatedCode += `return new Map([
1033
- `;
1034
- for (const id of outputVariables) {
1035
- generatedCode += ` ['${id}', ${id}],
1036
- `;
1037
- }
1038
- generatedCode += `]);`;
1039
- return generatedCode;
1040
- };
1041
- var executeEffectfulExpression = (code, args, variables) => {
1042
- const generatedCode = generateEffectfulExpression(
1043
- code,
1044
- new Set(args.keys()),
1045
- new Set(variables.keys())
1046
- );
1047
- const executeFn = new Function("_variables", "_args", generatedCode);
1048
- const values = executeFn(variables, args);
1049
- return values;
1050
- };
1051
890
  var computeExpressionDependencies = (expressions, expressionId, dependencies) => {
1052
891
  const depsById = dependencies.get(expressionId);
1053
892
  if (depsById) {
@@ -1087,13 +926,6 @@ var encodeDataSourceVariable = (id) => {
1087
926
  const encoded = id.replaceAll("-", "__DASH__");
1088
927
  return `${dataSourceVariablePrefix}${encoded}`;
1089
928
  };
1090
- var encodeVariablesMap = (values) => {
1091
- const encodedValues = /* @__PURE__ */ new Map();
1092
- for (const [id, value] of values) {
1093
- encodedValues.set(encodeDataSourceVariable(id), value);
1094
- }
1095
- return encodedValues;
1096
- };
1097
929
  var decodeDataSourceVariable = (name) => {
1098
930
  if (name.startsWith(dataSourceVariablePrefix)) {
1099
931
  const encoded = name.slice(dataSourceVariablePrefix.length);
@@ -1101,15 +933,117 @@ var decodeDataSourceVariable = (name) => {
1101
933
  }
1102
934
  return;
1103
935
  };
1104
- var decodeVariablesMap = (values) => {
1105
- const decodedValues = /* @__PURE__ */ new Map();
1106
- for (const [name, value] of values) {
1107
- const id = decodeDataSourceVariable(name);
1108
- if (id !== void 0) {
1109
- decodedValues.set(id, value);
936
+ var generateDataSources = ({
937
+ scope,
938
+ typed = false,
939
+ dataSources,
940
+ props
941
+ }) => {
942
+ const variables = /* @__PURE__ */ new Map();
943
+ let body = "";
944
+ const output = /* @__PURE__ */ new Map();
945
+ const depsById = /* @__PURE__ */ new Map();
946
+ const codeById = /* @__PURE__ */ new Map();
947
+ for (const dataSource of dataSources.values()) {
948
+ if (dataSource.type === "expression") {
949
+ const deps = /* @__PURE__ */ new Set();
950
+ const newCode = validateExpression(dataSource.code, {
951
+ transformIdentifier: (identifier) => {
952
+ const depId = decodeDataSourceVariable(identifier);
953
+ const dep = depId ? dataSources.get(depId) : void 0;
954
+ if (dep) {
955
+ deps.add(dep.id);
956
+ return scope.getName(dep.id, dep.name);
957
+ }
958
+ console.error(`Unknown dependency "${identifier}"`);
959
+ return identifier;
960
+ }
961
+ });
962
+ depsById.set(dataSource.id, deps);
963
+ codeById.set(dataSource.id, newCode);
964
+ }
965
+ }
966
+ const sortedDataSources = sortTopologically(
967
+ new Set(dataSources.keys()),
968
+ depsById
969
+ );
970
+ for (const dataSourceId of sortedDataSources) {
971
+ const dataSource = dataSources.get(dataSourceId);
972
+ if (dataSource?.type === "variable") {
973
+ const valueName = scope.getName(dataSource.id, dataSource.name);
974
+ const setterName = scope.getName(
975
+ `set$${dataSource.id}`,
976
+ `set$${dataSource.name}`
977
+ );
978
+ const initialValue = dataSource.value.value;
979
+ output.set(dataSource.id, valueName);
980
+ variables.set(dataSource.id, { valueName, setterName, initialValue });
981
+ }
982
+ if (dataSource?.type === "expression") {
983
+ const name = scope.getName(dataSource.id, dataSource.name);
984
+ const code = codeById.get(dataSourceId);
985
+ output.set(dataSource.id, name);
986
+ body += `let ${name} = (${code});
987
+ `;
988
+ }
989
+ }
990
+ for (const prop of props.values()) {
991
+ if (prop.type !== "action") {
992
+ continue;
993
+ }
994
+ const name = scope.getName(prop.id, prop.name);
995
+ output.set(prop.id, name);
996
+ const setters = /* @__PURE__ */ new Set();
997
+ let args = void 0;
998
+ let newCode = "";
999
+ for (const value of prop.value) {
1000
+ args = value.args;
1001
+ newCode += validateExpression(value.code, {
1002
+ effectful: true,
1003
+ transformIdentifier: (identifier, assignee) => {
1004
+ if (args?.includes(identifier)) {
1005
+ return identifier;
1006
+ }
1007
+ const depId = decodeDataSourceVariable(identifier);
1008
+ const dep = depId ? dataSources.get(depId) : void 0;
1009
+ if (dep) {
1010
+ const name2 = scope.getName(dep.id, dep.name);
1011
+ if (assignee) {
1012
+ setters.add(dep.id);
1013
+ }
1014
+ return name2;
1015
+ }
1016
+ console.error(`Unknown dependency "${identifier}"`);
1017
+ return identifier;
1018
+ }
1019
+ });
1020
+ newCode += `
1021
+ `;
1022
+ }
1023
+ if (args === void 0) {
1024
+ continue;
1025
+ }
1026
+ if (typed) {
1027
+ args = args.map((arg) => `${arg}: any`);
1110
1028
  }
1029
+ body += `let ${name} = (${args.join(", ")}) => {
1030
+ `;
1031
+ body += newCode;
1032
+ for (const dataSourceId of setters.values()) {
1033
+ const variable = variables.get(dataSourceId);
1034
+ if (variable) {
1035
+ body += `${variable.setterName}(${variable.valueName})
1036
+ `;
1037
+ }
1038
+ }
1039
+ body += `}
1040
+ `;
1111
1041
  }
1112
- return decodedValues;
1042
+ return {
1043
+ variables,
1044
+ body,
1045
+ output
1046
+ };
1113
1047
  };
1114
1048
 
1115
1049
  // src/embed-template.ts
@@ -1208,11 +1142,11 @@ var getDataSourceValue = (value) => {
1208
1142
  value;
1209
1143
  throw Error("Impossible case");
1210
1144
  };
1211
- var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, metas, defaultBreakpointId) => {
1145
+ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, metas, defaultBreakpointId, generateId) => {
1212
1146
  const parentChildren = [];
1213
1147
  for (const item of treeTemplate) {
1214
1148
  if (item.type === "instance") {
1215
- const instanceId = nanoid();
1149
+ const instanceId = generateId();
1216
1150
  if (item.dataSources) {
1217
1151
  for (const [name, dataSource] of Object.entries(item.dataSources)) {
1218
1152
  if (dataSourceByRef.has(name)) {
@@ -1221,7 +1155,7 @@ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByR
1221
1155
  if (dataSource.type === "variable") {
1222
1156
  dataSourceByRef.set(name, {
1223
1157
  type: "variable",
1224
- id: nanoid(),
1158
+ id: generateId(),
1225
1159
  scopeInstanceId: instanceId,
1226
1160
  name,
1227
1161
  value: getDataSourceValue(dataSource.initialValue)
@@ -1230,7 +1164,7 @@ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByR
1230
1164
  if (dataSource.type === "expression") {
1231
1165
  dataSourceByRef.set(name, {
1232
1166
  type: "expression",
1233
- id: nanoid(),
1167
+ id: generateId(),
1234
1168
  scopeInstanceId: instanceId,
1235
1169
  name,
1236
1170
  // replace all references with variable names
@@ -1246,7 +1180,7 @@ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByR
1246
1180
  }
1247
1181
  if (item.props) {
1248
1182
  for (const prop of item.props) {
1249
- const propId = nanoid();
1183
+ const propId = generateId();
1250
1184
  if (prop.type === "action") {
1251
1185
  props.push({
1252
1186
  id: propId,
@@ -1319,7 +1253,7 @@ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByR
1319
1253
  }
1320
1254
  }
1321
1255
  if (item.styles) {
1322
- const styleSourceId = nanoid();
1256
+ const styleSourceId = generateId();
1323
1257
  styleSources.push({
1324
1258
  type: "local",
1325
1259
  id: styleSourceId
@@ -1358,7 +1292,8 @@ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByR
1358
1292
  styleSources,
1359
1293
  styles,
1360
1294
  metas,
1361
- defaultBreakpointId
1295
+ defaultBreakpointId,
1296
+ generateId
1362
1297
  );
1363
1298
  parentChildren.push({
1364
1299
  type: "id",
@@ -1374,7 +1309,7 @@ var createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByR
1374
1309
  }
1375
1310
  return parentChildren;
1376
1311
  };
1377
- var generateDataFromEmbedTemplate = (treeTemplate, metas, defaultBreakpointId) => {
1312
+ var generateDataFromEmbedTemplate = (treeTemplate, metas, defaultBreakpointId, generateId = nanoid) => {
1378
1313
  const instances = [];
1379
1314
  const props = [];
1380
1315
  const dataSourceByRef = /* @__PURE__ */ new Map();
@@ -1390,7 +1325,8 @@ var generateDataFromEmbedTemplate = (treeTemplate, metas, defaultBreakpointId) =
1390
1325
  styleSources,
1391
1326
  styles,
1392
1327
  metas,
1393
- defaultBreakpointId
1328
+ defaultBreakpointId,
1329
+ generateId
1394
1330
  );
1395
1331
  return {
1396
1332
  children,
@@ -1501,16 +1437,15 @@ var WsComponentMeta = z3.object({
1501
1437
  label: z3.optional(z3.string()),
1502
1438
  description: z3.string().optional(),
1503
1439
  icon: z3.string(),
1504
- presetStyle: z3.optional(z3.record(z3.string(), EmbedTemplateStyleDecl)),
1440
+ presetStyle: z3.optional(
1441
+ z3.record(z3.string(), z3.array(EmbedTemplateStyleDecl))
1442
+ ),
1505
1443
  presetTokens: z3.optional(z3.record(z3.string(), ComponentToken)),
1506
1444
  states: z3.optional(z3.array(ComponentState)),
1507
1445
  template: z3.optional(WsEmbedTemplate),
1508
1446
  order: z3.number().optional()
1509
1447
  });
1510
1448
 
1511
- // src/component-renderer.tsx
1512
- import { getStyleDeclKey } from "@webstudio-is/sdk";
1513
-
1514
1449
  // src/instance-utils.ts
1515
1450
  var getIndexesWithinAncestors = (metas, instances, rootIds) => {
1516
1451
  const ancestors = /* @__PURE__ */ new Set();
@@ -1555,124 +1490,6 @@ var getIndexesWithinAncestors = (metas, instances, rootIds) => {
1555
1490
  return indexes;
1556
1491
  };
1557
1492
 
1558
- // src/component-renderer.tsx
1559
- import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1560
- var renderComponentTemplate = ({
1561
- name,
1562
- metas: metasRecord,
1563
- components,
1564
- props,
1565
- imageLoader
1566
- }) => {
1567
- const metas = new Map(Object.entries(metasRecord));
1568
- const template = metas.get(name)?.template ?? [
1569
- {
1570
- type: "instance",
1571
- component: name,
1572
- children: []
1573
- }
1574
- ];
1575
- if (template[0].type === "instance" && props !== void 0) {
1576
- template[0].props = Object.entries(props).map(([prop, value]) => {
1577
- if (typeof value === "string") {
1578
- return { type: "string", name: prop, value };
1579
- }
1580
- if (typeof value === "number") {
1581
- return { type: "number", name: prop, value };
1582
- }
1583
- if (typeof value === "boolean") {
1584
- return { type: "boolean", name: prop, value };
1585
- }
1586
- throw new Error(`Unsupported prop ${props} with value ${value}`);
1587
- });
1588
- }
1589
- const data = generateDataFromEmbedTemplate(template, metas, "base");
1590
- const instances = [
1591
- [
1592
- "root",
1593
- {
1594
- type: "instance",
1595
- id: "root",
1596
- component: "Box",
1597
- children: data.children
1598
- }
1599
- ],
1600
- ...data.instances.map(
1601
- (instance) => [instance.id, instance]
1602
- )
1603
- ];
1604
- return /* @__PURE__ */ jsxs4(Fragment4, { children: [
1605
- /* @__PURE__ */ jsx4("style", { children: generateCssText(
1606
- {
1607
- assets: [],
1608
- breakpoints: [["base", { id: "base", label: "base" }]],
1609
- styles: data.styles.map((item) => [getStyleDeclKey(item), item]),
1610
- styleSourceSelections: data.styleSourceSelections.map((item) => [
1611
- item.instanceId,
1612
- item
1613
- ]),
1614
- componentMetas: metas
1615
- },
1616
- { assetBaseUrl: "/" }
1617
- ) }),
1618
- /* @__PURE__ */ jsx4(
1619
- InstanceRoot,
1620
- {
1621
- data: {
1622
- page: {
1623
- path: "",
1624
- id: "",
1625
- name: "",
1626
- title: "",
1627
- meta: {},
1628
- rootInstanceId: "root"
1629
- },
1630
- pages: [],
1631
- assets: [],
1632
- build: {
1633
- instances,
1634
- props: data.props.map((prop) => [prop.id, prop]),
1635
- dataSources: data.dataSources.map((dataSource) => [
1636
- dataSource.id,
1637
- dataSource
1638
- ])
1639
- }
1640
- },
1641
- utils: {
1642
- indexesWithinAncestors: getIndexesWithinAncestors(
1643
- metas,
1644
- new Map(instances),
1645
- ["root"]
1646
- ),
1647
- executeComputingExpressions: (values) => {
1648
- const expressions = /* @__PURE__ */ new Map();
1649
- for (const dataSource of data.dataSources) {
1650
- const name2 = encodeDataSourceVariable(dataSource.id);
1651
- if (dataSource.type === "expression") {
1652
- expressions.set(name2, dataSource.code);
1653
- }
1654
- }
1655
- return decodeVariablesMap(
1656
- executeComputingExpressions(
1657
- expressions,
1658
- encodeVariablesMap(values)
1659
- )
1660
- );
1661
- },
1662
- executeEffectfulExpression: (code, args, values) => {
1663
- return decodeVariablesMap(
1664
- executeEffectfulExpression(code, args, encodeVariablesMap(values))
1665
- );
1666
- }
1667
- },
1668
- Component: WebstudioComponent,
1669
- components: new Map(Object.entries(components)),
1670
- imageLoader: imageLoader ?? (({ src }) => src)
1671
- }
1672
- )
1673
- ] });
1674
- };
1675
-
1676
1493
  // src/hook.ts
1677
1494
  var getClosestInstance = (instancePath, currentInstance, closestComponent) => {
1678
1495
  let matched = false;
@@ -1687,6 +1504,9 @@ var getClosestInstance = (instancePath, currentInstance, closestComponent) => {
1687
1504
  };
1688
1505
 
1689
1506
  // src/generator.ts
1507
+ import {
1508
+ createScope
1509
+ } from "@webstudio-is/sdk";
1690
1510
  var generateUtilsExport = (siteData) => {
1691
1511
  const indexesWithinAncestors = getIndexesWithinAncestors(
1692
1512
  siteData.metas,
@@ -1705,91 +1525,257 @@ var generateUtilsExport = (siteData) => {
1705
1525
  ${indexesWithinAncestorsEntries}
1706
1526
  ]);
1707
1527
  `;
1708
- const variables = /* @__PURE__ */ new Set();
1709
- const expressions = /* @__PURE__ */ new Map();
1710
- for (const dataSource of siteData.dataSources.values()) {
1711
- if (dataSource.type === "variable") {
1712
- variables.add(encodeDataSourceVariable(dataSource.id));
1713
- }
1714
- if (dataSource.type === "expression") {
1715
- expressions.set(encodeDataSourceVariable(dataSource.id), dataSource.code);
1716
- }
1528
+ const { variables, body, output } = generateDataSources({
1529
+ scope: createScope(["_getVariable", "_setVariable", "_output"]),
1530
+ typed: true,
1531
+ dataSources: siteData.dataSources,
1532
+ props: siteData.props
1533
+ });
1534
+ let generatedDataSources = "";
1535
+ generatedDataSources += `const getDataSourcesLogic = (
1536
+ `;
1537
+ generatedDataSources += ` _getVariable: (id: string) => unknown,
1538
+ `;
1539
+ generatedDataSources += ` _setVariable: (id: string, value: unknown) => void
1540
+ `;
1541
+ generatedDataSources += `) => {
1542
+ `;
1543
+ for (const [dataSourceId, variable] of variables) {
1544
+ const { valueName, setterName } = variable;
1545
+ const initialValue = JSON.stringify(variable.initialValue);
1546
+ generatedDataSources += `let ${valueName} = _getVariable("${dataSourceId}") ?? ${initialValue};
1547
+ `;
1548
+ generatedDataSources += `let ${setterName} = (value: unknown) => _setVariable("${dataSourceId}", value);
1549
+ `;
1717
1550
  }
1718
- const generatedExecuteComputingExpressions = `
1719
- const rawExecuteComputingExpressions = (
1720
- _variables: Map<string, unknown>
1721
- ): Map<string, unknown> => {
1722
- ${generateComputingExpressions(expressions, variables)}
1723
- };
1724
- const executeComputingExpressions = (variables: Map<string, unknown>) => {
1725
- const encodedvariables = sdk.encodeVariablesMap(variables);
1726
- const encodedResult = rawExecuteComputingExpressions(encodedvariables);
1727
- return sdk.decodeVariablesMap(encodedResult);
1728
- };
1729
- `;
1730
- let effectfulExpressionsEntries = "";
1731
- for (const prop of siteData.props.values()) {
1732
- if (prop.type === "action") {
1733
- for (const executableValue of prop.value) {
1734
- const codeString = JSON.stringify(executableValue.code);
1735
- const generatedCode = generateEffectfulExpression(
1736
- executableValue.code,
1737
- new Set(executableValue.args),
1738
- variables
1739
- );
1740
- const generatedFunction = `(_args: Map<string, any>, _variables: Map<string, any>) => { ${generatedCode} }`;
1741
- effectfulExpressionsEntries += `[${codeString}, ${generatedFunction}],
1551
+ generatedDataSources += body;
1552
+ generatedDataSources += `let _output = new Map();
1553
+ `;
1554
+ for (const [dataSourceId, variableName] of output) {
1555
+ generatedDataSources += `_output.set('${dataSourceId}', ${variableName})
1556
+ `;
1557
+ }
1558
+ generatedDataSources += `return _output
1559
+ `;
1560
+ generatedDataSources += `}
1742
1561
  `;
1562
+ const formsProperties = /* @__PURE__ */ new Map();
1563
+ for (const prop of siteData.props.values()) {
1564
+ if (prop.type === "string") {
1565
+ if (prop.name === "action" || prop.name === "method") {
1566
+ let properties = formsProperties.get(prop.instanceId);
1567
+ if (properties === void 0) {
1568
+ properties = {};
1569
+ }
1570
+ properties[prop.name] = prop.value;
1571
+ formsProperties.set(prop.instanceId, properties);
1743
1572
  }
1744
1573
  }
1745
1574
  }
1746
- const generatedExecuteEffectfulExpression = `const generatedEffectfulExpressions = new Map<
1747
- string,
1748
- (args: Map<string, any>, variables: Map<string, any>) => Map<string, unknown>
1749
- >([
1750
- ${effectfulExpressionsEntries}
1751
- ]);
1752
-
1753
- const rawExecuteEffectfulExpression = (
1754
- code: string,
1755
- args: Map<string, unknown>,
1756
- variables: Map<string, unknown>
1757
- ): Map<string, unknown> => {
1758
- if(generatedEffectfulExpressions.has(code)) {
1759
- return generatedEffectfulExpressions.get(code)!(args, variables);
1760
- }
1761
- console.error("Effectful expression not found", code);
1762
- throw new Error("Effectful expression not found");
1763
- };
1764
-
1765
- const executeEffectfulExpression = (
1766
- code: string,
1767
- args: Map<string, unknown>,
1768
- variables: Map<string, unknown>
1769
- ) => {
1770
- const encodedvariables = sdk.encodeVariablesMap(variables);
1771
- const encodedResult = rawExecuteEffectfulExpression(code, args, encodedvariables);
1772
- return sdk.decodeVariablesMap(encodedResult);
1773
- };
1774
- `;
1575
+ const generatedFormsProperties = `export const formsProperties = new Map<string, { method?: string, action?: string }>(${JSON.stringify(
1576
+ Array.from(formsProperties.entries())
1577
+ )})`;
1775
1578
  return `
1776
1579
  /* eslint-disable */
1777
1580
 
1778
1581
  ${generatedIndexesWithinAncestors.trim()}
1779
1582
 
1780
- ${generatedExecuteComputingExpressions.trim()}
1583
+ ${generatedDataSources}
1781
1584
 
1782
- ${generatedExecuteEffectfulExpression.trim()}
1585
+ ${generatedFormsProperties}
1783
1586
 
1784
1587
  export const utils = {
1785
1588
  indexesWithinAncestors,
1786
- executeComputingExpressions,
1787
- executeEffectfulExpression,
1589
+ getDataSourcesLogic,
1788
1590
  };
1789
1591
 
1790
1592
  /* eslint-enable */
1791
1593
  `;
1792
1594
  };
1595
+
1596
+ // src/component-generator.ts
1597
+ import { parseComponentName } from "@webstudio-is/sdk";
1598
+ var generateJsxElement = ({
1599
+ scope,
1600
+ instance,
1601
+ props,
1602
+ dataSources,
1603
+ indexesWithinAncestors,
1604
+ children
1605
+ }) => {
1606
+ let conditionVariableName;
1607
+ let generatedProps = "";
1608
+ generatedProps += `
1609
+ ${idAttribute}=${JSON.stringify(instance.id)}`;
1610
+ generatedProps += `
1611
+ ${componentAttribute}=${JSON.stringify(
1612
+ instance.component
1613
+ )}`;
1614
+ const index = indexesWithinAncestors.get(instance.id);
1615
+ if (index !== void 0) {
1616
+ generatedProps += `
1617
+ ${indexAttribute}="${index}"`;
1618
+ }
1619
+ for (const prop of props.values()) {
1620
+ if (prop.instanceId !== instance.id) {
1621
+ continue;
1622
+ }
1623
+ if (prop.name === showAttribute) {
1624
+ if (prop.type === "boolean" && prop.value === false) {
1625
+ return "";
1626
+ }
1627
+ if (prop.type === "dataSource") {
1628
+ const dataSourceId = prop.value;
1629
+ const dataSource = dataSources.get(dataSourceId);
1630
+ if (dataSource === void 0) {
1631
+ continue;
1632
+ }
1633
+ conditionVariableName = scope.getName(dataSource.id, dataSource.name);
1634
+ }
1635
+ continue;
1636
+ }
1637
+ if (prop.type === "string" || prop.type === "number" || prop.type === "boolean" || prop.type === "string[]") {
1638
+ generatedProps += `
1639
+ ${prop.name}={${JSON.stringify(prop.value)}}`;
1640
+ continue;
1641
+ }
1642
+ if (prop.type === "asset" || prop.type === "page") {
1643
+ continue;
1644
+ }
1645
+ if (prop.type === "dataSource") {
1646
+ const dataSourceId = prop.value;
1647
+ const dataSource = dataSources.get(dataSourceId);
1648
+ if (dataSource === void 0) {
1649
+ continue;
1650
+ }
1651
+ const dataSourceVariable = scope.getName(dataSource.id, dataSource.name);
1652
+ generatedProps += `
1653
+ ${prop.name}={${dataSourceVariable}}`;
1654
+ continue;
1655
+ }
1656
+ if (prop.type === "action") {
1657
+ const propVariable = scope.getName(prop.id, prop.name);
1658
+ generatedProps += `
1659
+ ${prop.name}={${propVariable}}`;
1660
+ continue;
1661
+ }
1662
+ prop;
1663
+ }
1664
+ let generatedElement = "";
1665
+ if (conditionVariableName) {
1666
+ generatedElement += `{${conditionVariableName} &&
1667
+ `;
1668
+ }
1669
+ const [_namespace, shortName] = parseComponentName(instance.component);
1670
+ const componentVariable = scope.getName(instance.component, shortName);
1671
+ if (instance.children.length === 0) {
1672
+ generatedElement += `<${componentVariable}${generatedProps} />
1673
+ `;
1674
+ } else {
1675
+ generatedElement += `<${componentVariable}${generatedProps}>
1676
+ `;
1677
+ generatedElement += children;
1678
+ generatedElement += `</${componentVariable}>
1679
+ `;
1680
+ }
1681
+ if (conditionVariableName) {
1682
+ generatedElement += `}
1683
+ `;
1684
+ }
1685
+ return generatedElement;
1686
+ };
1687
+ var generateJsxChildren = ({
1688
+ scope,
1689
+ children,
1690
+ instances,
1691
+ props,
1692
+ dataSources,
1693
+ indexesWithinAncestors
1694
+ }) => {
1695
+ let generatedChildren = "";
1696
+ for (const child of children) {
1697
+ if (child.type === "text") {
1698
+ generatedChildren += child.value.split("\n").map((line) => `{${JSON.stringify(line)}}
1699
+ `).join(`<br />
1700
+ `);
1701
+ continue;
1702
+ }
1703
+ if (child.type === "id") {
1704
+ const instanceId = child.value;
1705
+ const instance = instances.get(instanceId);
1706
+ if (instance === void 0) {
1707
+ continue;
1708
+ }
1709
+ generatedChildren += generateJsxElement({
1710
+ scope,
1711
+ instance,
1712
+ props,
1713
+ dataSources,
1714
+ indexesWithinAncestors,
1715
+ children: generateJsxChildren({
1716
+ scope,
1717
+ children: instance.children,
1718
+ instances,
1719
+ props,
1720
+ dataSources,
1721
+ indexesWithinAncestors
1722
+ })
1723
+ });
1724
+ continue;
1725
+ }
1726
+ child;
1727
+ }
1728
+ return generatedChildren;
1729
+ };
1730
+ var generatePageComponent = ({
1731
+ scope,
1732
+ rootInstanceId,
1733
+ instances,
1734
+ props,
1735
+ dataSources,
1736
+ indexesWithinAncestors
1737
+ }) => {
1738
+ const instance = instances.get(rootInstanceId);
1739
+ if (instance === void 0) {
1740
+ return "";
1741
+ }
1742
+ const { variables, body: dataSourcesBody } = generateDataSources({
1743
+ typed: true,
1744
+ scope,
1745
+ dataSources,
1746
+ props
1747
+ });
1748
+ let generatedDataSources = "";
1749
+ for (const { valueName, setterName, initialValue } of variables.values()) {
1750
+ const initialValueString = JSON.stringify(initialValue);
1751
+ generatedDataSources += `let [${valueName}, ${setterName}] = useState(${initialValueString})
1752
+ `;
1753
+ }
1754
+ generatedDataSources += dataSourcesBody;
1755
+ const generatedJsx = generateJsxElement({
1756
+ scope,
1757
+ instance,
1758
+ props,
1759
+ dataSources,
1760
+ indexesWithinAncestors,
1761
+ children: generateJsxChildren({
1762
+ scope,
1763
+ children: instance.children,
1764
+ instances,
1765
+ props,
1766
+ dataSources,
1767
+ indexesWithinAncestors
1768
+ }) + "{props.scripts}\n"
1769
+ });
1770
+ let generatedComponent = "";
1771
+ generatedComponent += `const Page = (props: { scripts?: ReactNode }) => {
1772
+ `;
1773
+ generatedComponent += `${generatedDataSources}`;
1774
+ generatedComponent += `return ${generatedJsx}`;
1775
+ generatedComponent += `}
1776
+ `;
1777
+ return generatedComponent;
1778
+ };
1793
1779
  export {
1794
1780
  EmbedTemplateInstance,
1795
1781
  EmbedTemplateStyleDecl,
@@ -1798,6 +1784,7 @@ export {
1798
1784
  ReactSdkContext,
1799
1785
  Root,
1800
1786
  WebstudioComponent,
1787
+ WsComponentMeta,
1801
1788
  WsEmbedTemplate,
1802
1789
  addGlobalRules,
1803
1790
  collapsedAttribute,
@@ -1807,16 +1794,12 @@ export {
1807
1794
  createElementsTree,
1808
1795
  createImageValueTransformer,
1809
1796
  decodeDataSourceVariable,
1810
- decodeVariablesMap,
1811
1797
  defaultStates,
1812
1798
  encodeDataSourceVariable,
1813
- encodeVariablesMap,
1814
- executeComputingExpressions,
1815
- executeEffectfulExpression,
1816
- generateComputingExpressions,
1817
1799
  generateCssText,
1818
1800
  generateDataFromEmbedTemplate,
1819
- generateEffectfulExpression,
1801
+ generateDataSources,
1802
+ generatePageComponent,
1820
1803
  generateUtilsExport,
1821
1804
  getClosestInstance,
1822
1805
  getIndexWithinAncestorFromComponentProps,
@@ -1827,7 +1810,6 @@ export {
1827
1810
  idAttribute,
1828
1811
  indexAttribute,
1829
1812
  namespaceMeta,
1830
- renderComponentTemplate,
1831
1813
  renderWebstudioComponentChildren,
1832
1814
  selectorIdAttribute,
1833
1815
  showAttribute,