@builder.io/sdk-svelte 2.0.16 → 2.0.21

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 (63) hide show
  1. package/lib/browser/components/awaiter.svelte +16 -0
  2. package/lib/browser/components/awaiter.svelte.d.ts +23 -0
  3. package/lib/browser/components/block/components/interactive-element.svelte +14 -4
  4. package/lib/browser/components/content/components/enable-editor.svelte +9 -46
  5. package/lib/browser/components/content/content.svelte +25 -2
  6. package/lib/browser/components/content/content.svelte.d.ts +2 -2
  7. package/lib/browser/constants/sdk-version.d.ts +1 -1
  8. package/lib/browser/constants/sdk-version.js +1 -1
  9. package/lib/browser/context/component-reference-types.d.ts +17 -0
  10. package/lib/browser/context/component-reference-types.js +1 -0
  11. package/lib/browser/context/types.d.ts +2 -1
  12. package/lib/browser/functions/evaluate/browser-runtime/browser.d.ts +0 -6
  13. package/lib/browser/functions/evaluate/browser-runtime/browser.js +1 -30
  14. package/lib/browser/functions/evaluate/edge-runtime/edge-runtime.js +73 -34
  15. package/lib/browser/functions/evaluate/helpers.d.ts +5 -0
  16. package/lib/browser/functions/evaluate/helpers.js +29 -0
  17. package/lib/browser/functions/evaluate/node-runtime/node-runtime.js +1 -1
  18. package/lib/edge/components/awaiter.svelte +16 -0
  19. package/lib/edge/components/awaiter.svelte.d.ts +23 -0
  20. package/lib/edge/components/block/components/interactive-element.svelte +14 -4
  21. package/lib/edge/components/content/components/enable-editor.svelte +9 -46
  22. package/lib/edge/components/content/content.svelte +25 -2
  23. package/lib/edge/components/content/content.svelte.d.ts +2 -2
  24. package/lib/edge/constants/sdk-version.d.ts +1 -1
  25. package/lib/edge/constants/sdk-version.js +1 -1
  26. package/lib/edge/context/component-reference-types.d.ts +17 -0
  27. package/lib/edge/context/component-reference-types.js +1 -0
  28. package/lib/edge/context/types.d.ts +2 -1
  29. package/lib/edge/functions/evaluate/browser-runtime/browser.d.ts +0 -6
  30. package/lib/edge/functions/evaluate/browser-runtime/browser.js +1 -30
  31. package/lib/edge/functions/evaluate/edge-runtime/edge-runtime.js +73 -34
  32. package/lib/edge/functions/evaluate/helpers.d.ts +5 -0
  33. package/lib/edge/functions/evaluate/helpers.js +29 -0
  34. package/lib/edge/functions/evaluate/node-runtime/node-runtime.js +1 -1
  35. package/lib/node/components/awaiter.svelte +16 -0
  36. package/lib/node/components/awaiter.svelte.d.ts +23 -0
  37. package/lib/node/components/block/components/interactive-element.svelte +14 -4
  38. package/lib/node/components/content/components/enable-editor.svelte +9 -46
  39. package/lib/node/components/content/content.svelte +25 -2
  40. package/lib/node/components/content/content.svelte.d.ts +2 -2
  41. package/lib/node/constants/sdk-version.d.ts +1 -1
  42. package/lib/node/constants/sdk-version.js +1 -1
  43. package/lib/node/context/component-reference-types.d.ts +17 -0
  44. package/lib/node/context/component-reference-types.js +1 -0
  45. package/lib/node/context/types.d.ts +2 -1
  46. package/lib/node/functions/evaluate/browser-runtime/browser.d.ts +0 -6
  47. package/lib/node/functions/evaluate/browser-runtime/browser.js +1 -30
  48. package/lib/node/functions/evaluate/edge-runtime/edge-runtime.js +73 -34
  49. package/lib/node/functions/evaluate/helpers.d.ts +5 -0
  50. package/lib/node/functions/evaluate/helpers.js +29 -0
  51. package/lib/node/functions/evaluate/node-runtime/node-runtime.js +1 -1
  52. package/package.json +1 -1
  53. package/src/components/awaiter.svelte +20 -0
  54. package/src/components/block/components/interactive-element.svelte +14 -4
  55. package/src/components/content/components/enable-editor.svelte +9 -52
  56. package/src/components/content/content.svelte +28 -2
  57. package/src/constants/sdk-version.ts +1 -1
  58. package/src/context/component-reference-types.ts +18 -0
  59. package/src/context/types.ts +2 -1
  60. package/src/functions/evaluate/browser-runtime/browser.ts +1 -39
  61. package/src/functions/evaluate/edge-runtime/edge-runtime.ts +73 -35
  62. package/src/functions/evaluate/helpers.ts +37 -0
  63. package/src/functions/evaluate/node-runtime/node-runtime.ts +1 -1
@@ -3,7 +3,9 @@ import { writable } from "svelte/store";
3
3
  import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components";
4
4
  import { TARGET } from "../../constants/target";
5
5
  import ComponentsContext from "../../context/components.context";
6
+ import { evaluate } from "../../functions/evaluate/evaluate";
6
7
  import { serializeIncludingFunctions } from "../../functions/register-component";
8
+ import { logger } from "../../helpers/logger";
7
9
  import Blocks from "../blocks/blocks.svelte";
8
10
  import { getUpdateVariantVisibilityScript } from "../content-variants/helpers";
9
11
  import "../dynamic-div.svelte";
@@ -12,14 +14,14 @@ import EnableEditor from "./components/enable-editor.svelte";
12
14
  import ContentStyles from "./components/styles.svelte";
13
15
  import { getContentInitialValue, getRootStateInitialValue, } from "./content.helpers";
14
16
  import "./wrap-component-ref";
17
+ export let apiKey;
18
+ export let context = undefined;
15
19
  export let content = undefined;
16
20
  export let customComponents = undefined;
17
21
  export let model = undefined;
18
22
  export let data = undefined;
19
23
  export let locale = undefined;
20
- export let context = undefined;
21
24
  export let canTrack = undefined;
22
- export let apiKey;
23
25
  export let apiVersion = undefined;
24
26
  export let blocksWrapper = undefined;
25
27
  export let blocksWrapperProps = undefined;
@@ -91,6 +93,27 @@ let builderContextSignal = writable({
91
93
  BlocksWrapperProps: blocksWrapperProps || {},
92
94
  nonce: nonce || "",
93
95
  });
96
+ if (!apiKey) {
97
+ logger.error("No API key provided to `Content` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
98
+ }
99
+ // run any dynamic JS code attached to content
100
+ const jsCode = $builderContextSignal.content?.data?.jsCode;
101
+ if (jsCode) {
102
+ evaluate({
103
+ code: jsCode,
104
+ context: context || {},
105
+ localState: undefined,
106
+ rootState: $builderContextSignal.rootState,
107
+ rootSetState: (newState) => {
108
+ $builderContextSignal.rootSetState?.(newState);
109
+ },
110
+ isExpression: false,
111
+ /**
112
+ * We don't want to cache the result of the JS code, since it's arbitrary side effect code.
113
+ */
114
+ enableCache: false,
115
+ });
116
+ }
94
117
  setContext(ComponentsContext.key, {
95
118
  registeredComponents: registeredComponents,
96
119
  });
@@ -2,14 +2,14 @@ import { SvelteComponent } from "svelte";
2
2
  import type { ContentProps } from "./content.types";
3
3
  declare const __propDef: {
4
4
  props: {
5
+ apiKey: ContentProps["apiKey"];
6
+ context?: ContentProps["context"];
5
7
  content?: ContentProps["content"];
6
8
  customComponents?: ContentProps["customComponents"];
7
9
  model?: ContentProps["model"];
8
10
  data?: ContentProps["data"];
9
11
  locale?: ContentProps["locale"];
10
- context?: ContentProps["context"];
11
12
  canTrack?: ContentProps["canTrack"];
12
- apiKey: ContentProps["apiKey"];
13
13
  apiVersion?: ContentProps["apiVersion"];
14
14
  blocksWrapper?: ContentProps["blocksWrapper"];
15
15
  blocksWrapperProps?: ContentProps["blocksWrapperProps"];
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "2.0.16";
1
+ export declare const SDK_VERSION = "2.0.21";
@@ -1 +1 @@
1
- export const SDK_VERSION = "2.0.16";
1
+ export const SDK_VERSION = "2.0.21";
@@ -0,0 +1,17 @@
1
+ import type { SvelteComponent } from 'svelte';
2
+ export type ComponentReference = {
3
+ /**
4
+ * Either:
5
+ * - A dynamic import function pointing to the component.
6
+ * Example: `() => import('../components/my-component.svelte')`
7
+ * - A string representing the path to the component.
8
+ * Example: `'../components/my-component.svelte'`
9
+ */
10
+ load: string | (() => Promise<{
11
+ default: typeof SvelteComponent<any>;
12
+ }>);
13
+ /**
14
+ * An optional fallback component to render while the dynamic component is loading.
15
+ */
16
+ fallback?: typeof SvelteComponent<any>;
17
+ } | typeof SvelteComponent<any>;
@@ -0,0 +1 @@
1
+ export {};
@@ -3,9 +3,10 @@ import type { ApiVersion } from '../types/api-version';
3
3
  import type { BuilderContent } from '../types/builder-content';
4
4
  import type { ComponentInfo } from '../types/components';
5
5
  import type { Dictionary, Nullable } from '../types/typescript';
6
+ import type { ComponentReference } from './component-reference-types';
6
7
  import type { ExtraContextTypes } from './extra-context-types';
7
8
  export type RegisteredComponent = ComponentInfo & {
8
- component: any;
9
+ component: ComponentReference;
9
10
  };
10
11
  export type RegisteredComponents = Dictionary<RegisteredComponent>;
11
12
  export type BuilderRenderState = Record<string, unknown>;
@@ -1,8 +1,2 @@
1
- import type { BuilderRenderState } from '../../../context/types';
2
1
  import type { ExecutorArgs } from '../helpers';
3
2
  export declare const runInBrowser: ({ code, builder, context, event, localState, rootSetState, rootState }: ExecutorArgs) => any;
4
- export declare function flattenState({ rootState, localState, rootSetState }: {
5
- rootState: Record<string | symbol, any>;
6
- localState: Record<string | symbol, any> | undefined;
7
- rootSetState: ((rootState: BuilderRenderState) => void) | undefined;
8
- }): BuilderRenderState;
@@ -1,4 +1,4 @@
1
- import { getFunctionArguments } from '../helpers';
1
+ import { flattenState, getFunctionArguments } from '../helpers';
2
2
  export const runInBrowser = ({ code, builder, context, event, localState, rootSetState, rootState }) => {
3
3
  const functionArgs = getFunctionArguments({
4
4
  builder,
@@ -12,32 +12,3 @@ export const runInBrowser = ({ code, builder, context, event, localState, rootSe
12
12
  });
13
13
  return new Function(...functionArgs.map(([name]) => name), code)(...functionArgs.map(([, value]) => value));
14
14
  };
15
- export function flattenState({ rootState, localState, rootSetState }) {
16
- return new Proxy(rootState, {
17
- get: (target, prop) => {
18
- if (localState && prop in localState) {
19
- return localState[prop];
20
- }
21
- const val = target[prop];
22
- if (typeof val === 'object' && val !== null) {
23
- return flattenState({
24
- rootState: val,
25
- localState: undefined,
26
- rootSetState: rootSetState ? subState => {
27
- target[prop] = subState;
28
- rootSetState(target);
29
- } : undefined
30
- });
31
- }
32
- return val;
33
- },
34
- set: (target, prop, value) => {
35
- if (localState && prop in localState) {
36
- throw new Error('Writing to local state is not allowed as it is read-only.');
37
- }
38
- target[prop] = value;
39
- rootSetState?.(target);
40
- return true;
41
- }
42
- });
43
- }
@@ -1,32 +1,72 @@
1
1
  import { logger } from '../../../helpers/logger';
2
- import { set } from '../../set';
3
- import { getFunctionArguments } from '../helpers';
2
+ import { flattenState, getFunctionArguments } from '../helpers';
4
3
  import Interpreter from './acorn-interpreter';
4
+ /**
5
+ * https://stackoverflow.com/a/46503625
6
+ */
7
+ function patchInterpreter() {
8
+ const originalGetProperty = Interpreter.prototype.getProperty;
9
+ const originalSetProperty = Interpreter.prototype.setProperty;
10
+ function newGetProperty(obj, name) {
11
+ if (obj == null || !obj._connected) {
12
+ return originalGetProperty.call(this, obj, name);
13
+ }
14
+ const value = obj._connected[name];
15
+ if (Array.isArray(value)) {
16
+ return this.nativeToPseudo(value);
17
+ }
18
+ if (typeof value === 'object') {
19
+ // if the value is an object itself, create another connected object
20
+ return this.createConnectedObject(value);
21
+ }
22
+ return value;
23
+ }
24
+ function newSetProperty(obj, name, value, opt_descriptor) {
25
+ if (obj == null || !obj._connected) {
26
+ return originalSetProperty.call(this, obj, name, value, opt_descriptor);
27
+ }
28
+ obj._connected[name] = this.pseudoToNative(value);
29
+ }
30
+ const getKeys = [];
31
+ const setKeys = [];
32
+ for (const key of Object.keys(Interpreter.prototype)) {
33
+ if (Interpreter.prototype[key] === originalGetProperty) {
34
+ getKeys.push(key);
35
+ }
36
+ if (Interpreter.prototype[key] === originalSetProperty) {
37
+ setKeys.push(key);
38
+ }
39
+ }
40
+ for (const key of getKeys) {
41
+ Interpreter.prototype[key] = newGetProperty;
42
+ }
43
+ for (const key of setKeys) {
44
+ Interpreter.prototype[key] = newSetProperty;
45
+ }
46
+ Interpreter.prototype.createConnectedObject = function (obj) {
47
+ const connectedObject = this.createObject(this.OBJECT);
48
+ connectedObject._connected = obj;
49
+ return connectedObject;
50
+ };
51
+ }
52
+ patchInterpreter();
5
53
  const processCode = (code) => {
6
- return code.split('\n').map(line => {
7
- const trimmed = line.trim();
8
- // this async wrapper doesn't work in JS-interpreter, so we drop it.
9
- if (line.includes('__awaiter'))
10
- return undefined;
11
- // we find all state setter expressions and append a call to setRootState afterwards
12
- const isStateSetter = trimmed.startsWith('state.');
13
- if (!isStateSetter)
14
- return line;
15
- const [lhs, rhs] = trimmed.split('=');
16
- const setStr = lhs.replace('state.', '').trim();
17
- const setExpr = `setRootState('${setStr}', ${rhs.trim()})`;
18
- return `
19
- ${line}
20
- ${setExpr}
21
- `;
22
- }).filter(Boolean).join('\n');
54
+ return code
55
+ // strip async/await polyfill: remove anything before 'function main()'
56
+ .replace(/^.*?function main\(\)/, `
57
+ var __awaiter = function (e, t, n, r) {return r()},
58
+ __generator = function (e, t) { return t() };
59
+ function main()`)
60
+ // replace ?. with .
61
+ .replace(/\?\./g, '.');
23
62
  };
24
63
  const getJSONValName = (val) => val + 'JSON';
25
64
  export const runInEdge = ({ builder, context, event, rootState, localState, rootSetState, code }) => {
26
- const state = {
27
- ...rootState,
28
- ...localState
29
- };
65
+ const state = flattenState({
66
+ rootState,
67
+ localState,
68
+ rootSetState
69
+ });
30
70
  const properties = getFunctionArguments({
31
71
  builder,
32
72
  context,
@@ -38,6 +78,9 @@ export const runInEdge = ({ builder, context, event, rootState, localState, root
38
78
  */
39
79
  const prependedCode = properties.map(([key]) => {
40
80
  const jsonValName = getJSONValName(key);
81
+ if (key === 'state') {
82
+ return ``;
83
+ }
41
84
  return `var ${key} = ${jsonValName} === undefined ? undefined : JSON.parse(${jsonValName});`;
42
85
  }).join('\n');
43
86
  const cleanedCode = processCode(code);
@@ -53,23 +96,19 @@ function theFunction() {
53
96
  }
54
97
  theFunction();
55
98
  `;
56
- const setRootState = (prop, value) => {
57
- const newState = set(state, prop, value);
58
- rootSetState?.(newState);
59
- };
60
99
  const initFunc = function (interpreter, globalObject) {
61
100
  /**
62
101
  * serialize all function args to JSON strings
63
102
  */
64
103
  properties.forEach(([key, val]) => {
65
- const jsonVal = JSON.stringify(val);
66
- interpreter.setProperty(globalObject, getJSONValName(key), jsonVal);
104
+ if (key === 'state') {
105
+ interpreter.setProperty(globalObject, key, interpreter.createConnectedObject(val), interpreter.READONLY_DESCRIPTOR);
106
+ }
107
+ else {
108
+ const jsonVal = JSON.stringify(val);
109
+ interpreter.setProperty(globalObject, getJSONValName(key), jsonVal);
110
+ }
67
111
  });
68
- /**
69
- * Add a JavaScript function "setRootState" to the interpreter's global object, that will be called whenever a
70
- * state property is set. This function will update the state object.
71
- */
72
- interpreter.setProperty(globalObject, 'setRootState', interpreter.createNativeFunction(setRootState));
73
112
  };
74
113
  const myInterpreter = new Interpreter(transformed, initFunc);
75
114
  myInterpreter.run();
@@ -23,3 +23,8 @@ export declare const getFunctionArguments: ({ builder, context, event, state }:
23
23
  }) => [string, Event | BuilderRenderState | import("../../context/types").BuilderRenderContext | BuilderGlobals | undefined][];
24
24
  export declare const getBuilderGlobals: () => BuilderGlobals;
25
25
  export declare const parseCode: (code: string, { isExpression }: Pick<EvaluatorArgs, 'isExpression'>) => string;
26
+ export declare function flattenState({ rootState, localState, rootSetState }: {
27
+ rootState: Record<string | symbol, any>;
28
+ localState: Record<string | symbol, any> | undefined;
29
+ rootSetState: ((rootState: BuilderRenderState) => void) | undefined;
30
+ }): BuilderRenderState;
@@ -26,3 +26,32 @@ export const parseCode = (code, { isExpression = true }) => {
26
26
  const useCode = useReturn ? `return (${code});` : code;
27
27
  return useCode;
28
28
  };
29
+ export function flattenState({ rootState, localState, rootSetState }) {
30
+ return new Proxy(rootState, {
31
+ get: (target, prop) => {
32
+ if (localState && prop in localState) {
33
+ return localState[prop];
34
+ }
35
+ const val = target[prop];
36
+ if (typeof val === 'object' && val !== null) {
37
+ return flattenState({
38
+ rootState: val,
39
+ localState: undefined,
40
+ rootSetState: rootSetState ? subState => {
41
+ target[prop] = subState;
42
+ rootSetState(target);
43
+ } : undefined
44
+ });
45
+ }
46
+ return val;
47
+ },
48
+ set: (target, prop, value) => {
49
+ if (localState && prop in localState) {
50
+ throw new Error('Writing to local state is not allowed as it is read-only.');
51
+ }
52
+ target[prop] = value;
53
+ rootSetState?.(target);
54
+ return true;
55
+ }
56
+ });
57
+ }
@@ -67,7 +67,7 @@ export const setIvm = (ivm, options = {}) => {
67
67
  setIsolateContext(options);
68
68
  };
69
69
  // only mention the script for SDKs that have it.
70
- const SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === '@builder.io/sdk-react-nextjs' || SDK_NAME === '@builder.io/sdk-react' || SDK_NAME === '@builder.io/sdk-qwik';
70
+ const SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === '@builder.io/sdk-react-nextjs' || SDK_NAME === '@builder.io/sdk-react' || SDK_NAME === '@builder.io/sdk-qwik' || SDK_NAME === '@builder.io/sdk-vue';
71
71
  const getIvm = () => {
72
72
  try {
73
73
  if (IVM_INSTANCE)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-svelte",
3
3
  "description": "Builder.io SDK for Svelte",
4
- "version": "2.0.16",
4
+ "version": "2.0.21",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "lib",
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { SvelteComponent } from 'svelte';
3
+
4
+ export let load: () => Promise<{ default: typeof SvelteComponent<any> }>;
5
+ export let fallback: any;
6
+ export let props: any;
7
+ export let attributes: any;
8
+
9
+ const componentImport = typeof load === 'string' ? import(load) : load();
10
+ </script>
11
+
12
+ {#await componentImport}
13
+ {#if fallback}
14
+ <svelte:component this={fallback} />
15
+ {/if}
16
+ {:then { default: Component }}
17
+ <svelte:component this={Component} {...props} {attributes}>
18
+ <slot />
19
+ </svelte:component>
20
+ {/await}
@@ -15,13 +15,14 @@
15
15
  import { getBlockProperties } from "../../../functions/get-block-properties";
16
16
  import type { BuilderBlock } from "../../../types/builder-block";
17
17
  import type { Dictionary } from "../../../types/typescript";
18
+ import Awaiter from "../../awaiter.svelte";
18
19
  import type { Writable } from "svelte/store";
19
20
 
20
21
  export let includeBlockProps: InteractiveElementProps["includeBlockProps"];
21
22
  export let block: InteractiveElementProps["block"];
22
23
  export let context: InteractiveElementProps["context"];
23
- export let wrapperProps: InteractiveElementProps["wrapperProps"];
24
24
  export let Wrapper: InteractiveElementProps["Wrapper"];
25
+ export let wrapperProps: InteractiveElementProps["wrapperProps"];
25
26
 
26
27
  $: attributes = () => {
27
28
  return includeBlockProps
@@ -42,6 +43,15 @@
42
43
  };
43
44
  </script>
44
45
 
45
- <svelte:component this={Wrapper} {...wrapperProps} attributes={attributes()}
46
- ><slot /></svelte:component
47
- >
46
+ {#if Wrapper.load}
47
+ <Awaiter
48
+ load={Wrapper.load}
49
+ fallback={Wrapper.fallback}
50
+ props={wrapperProps}
51
+ attributes={attributes()}><slot /></Awaiter
52
+ >
53
+ {:else}
54
+ <svelte:component this={Wrapper} {...wrapperProps} attributes={attributes()}
55
+ ><slot /></svelte:component
56
+ >
57
+ {/if}
@@ -23,7 +23,6 @@
23
23
  import { evaluate } from "../../../functions/evaluate/index";
24
24
  import { fastClone } from "../../../functions/fast-clone";
25
25
  import { fetchOneEntry } from "../../../functions/get-content/index";
26
- import { fetch } from "../../../functions/get-fetch";
27
26
  import { isBrowser } from "../../../functions/is-browser";
28
27
  import { isEditing } from "../../../functions/is-editing";
29
28
  import { isPreviewing } from "../../../functions/is-previewing";
@@ -31,7 +30,6 @@
31
30
  import { _track } from "../../../functions/track/index";
32
31
  import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction";
33
32
  import { getDefaultCanTrack } from "../../../helpers/canTrack";
34
- import { logger } from "../../../helpers/logger";
35
33
  import { postPreviewContent } from "../../../helpers/preview-lru-cache/set";
36
34
  import { createEditorListener } from "../../../helpers/subscribe-to-editor";
37
35
  import {
@@ -121,23 +119,6 @@
121
119
  },
122
120
  })(event);
123
121
  }
124
- function evaluateJsCode() {
125
- // run any dynamic JS code attached to content
126
- const jsCode = $builderContextSignal.content?.data?.jsCode;
127
- if (jsCode) {
128
- evaluate({
129
- code: jsCode,
130
- context: context || {},
131
- localState: undefined,
132
- rootState: $builderContextSignal.rootState,
133
- rootSetState: $builderContextSignal.rootSetState,
134
- /**
135
- * We don't want to cache the result of the JS code, since it's arbitrary side effect code.
136
- */
137
- enableCache: false,
138
- });
139
- }
140
- }
141
122
  function onClick(event: any) {
142
123
  if ($builderContextSignal.content) {
143
124
  const variationId = $builderContextSignal.content?.testVariationId;
@@ -294,6 +275,8 @@
294
275
  let httpReqsData = {};
295
276
  let httpReqsPending = {};
296
277
  let clicked = false;
278
+ runHttpRequests();
279
+ emitStateUpdate();
297
280
 
298
281
  onMount(() => {
299
282
  if (isBrowser()) {
@@ -328,16 +311,6 @@
328
311
  }
329
312
  }
330
313
  });
331
- onMount(() => {
332
- if (!apiKey) {
333
- logger.error(
334
- "No API key provided to `Content` component. This can cause issues. Please provide an API key using the `apiKey` prop."
335
- );
336
- }
337
- evaluateJsCode();
338
- runHttpRequests();
339
- emitStateUpdate();
340
- });
341
314
 
342
315
  function onUpdateFn_0(..._args: any[]) {
343
316
  if (content) {
@@ -348,37 +321,21 @@
348
321
  $: onUpdateFn_0(...[content]);
349
322
 
350
323
  function onUpdateFn_1(..._args: any[]) {
351
- evaluateJsCode();
352
- }
353
- $: onUpdateFn_1_builderContextSignal_content__data__jsCode =
354
- $builderContextSignal.content?.data?.jsCode;
355
- $: onUpdateFn_1(...[onUpdateFn_1_builderContextSignal_content__data__jsCode]);
356
-
357
- function onUpdateFn_2(..._args: any[]) {
358
- runHttpRequests();
359
- }
360
- $: onUpdateFn_2_builderContextSignal_content__data__httpRequests =
361
- $builderContextSignal.content?.data?.httpRequests;
362
- $: onUpdateFn_2(
363
- ...[onUpdateFn_2_builderContextSignal_content__data__httpRequests]
364
- );
365
-
366
- function onUpdateFn_3(..._args: any[]) {
367
324
  emitStateUpdate();
368
325
  }
369
- $: onUpdateFn_3_builderContextSignal_rootState =
326
+ $: onUpdateFn_1_builderContextSignal_rootState =
370
327
  $builderContextSignal.rootState;
371
- $: onUpdateFn_3(...[onUpdateFn_3_builderContextSignal_rootState]);
328
+ $: onUpdateFn_1(...[onUpdateFn_1_builderContextSignal_rootState]);
372
329
 
373
- function onUpdateFn_4(..._args: any[]) {
330
+ function onUpdateFn_2(..._args: any[]) {
374
331
  if (data) {
375
332
  mergeNewRootState(data);
376
333
  }
377
334
  }
378
335
 
379
- $: onUpdateFn_4(...[data]);
336
+ $: onUpdateFn_2(...[data]);
380
337
 
381
- function onUpdateFn_5(..._args: any[]) {
338
+ function onUpdateFn_3(..._args: any[]) {
382
339
  if (locale) {
383
340
  mergeNewRootState({
384
341
  locale: locale,
@@ -386,7 +343,7 @@
386
343
  }
387
344
  }
388
345
 
389
- $: onUpdateFn_5(...[locale]);
346
+ $: onUpdateFn_3(...[locale]);
390
347
 
391
348
  setContext(builderContext.key, builderContextSignal);
392
349
 
@@ -411,10 +368,10 @@
411
368
  }}
412
369
  builder-content-id={$builderContextSignal.content?.id}
413
370
  builder-model={model}
371
+ className={getWrapperClassName(content?.testVariationId || content?.id)}
414
372
  {...{}}
415
373
  {...showContentProps()}
416
374
  {...contentWrapperProps}
417
- class={getWrapperClassName(content?.testVariationId || content?.id)}
418
375
  on:initeditingbldr={(event) => {
419
376
  elementRef_onIniteditingbldr(event);
420
377
  }}
@@ -10,7 +10,9 @@
10
10
  BuilderRenderState,
11
11
  RegisteredComponents,
12
12
  } from "../../context/types";
13
+ import { evaluate } from "../../functions/evaluate/evaluate";
13
14
  import { serializeIncludingFunctions } from "../../functions/register-component";
15
+ import { logger } from "../../helpers/logger";
14
16
  import type { ComponentInfo } from "../../types/components";
15
17
  import type { Dictionary } from "../../types/typescript";
16
18
  import Blocks from "../blocks/blocks.svelte";
@@ -26,14 +28,14 @@
26
28
  import type { ContentProps } from "./content.types";
27
29
  import { wrapComponentRef } from "./wrap-component-ref";
28
30
 
31
+ export let apiKey: ContentProps["apiKey"];
32
+ export let context: ContentProps["context"] = undefined;
29
33
  export let content: ContentProps["content"] = undefined;
30
34
  export let customComponents: ContentProps["customComponents"] = undefined;
31
35
  export let model: ContentProps["model"] = undefined;
32
36
  export let data: ContentProps["data"] = undefined;
33
37
  export let locale: ContentProps["locale"] = undefined;
34
- export let context: ContentProps["context"] = undefined;
35
38
  export let canTrack: ContentProps["canTrack"] = undefined;
36
- export let apiKey: ContentProps["apiKey"];
37
39
  export let apiVersion: ContentProps["apiVersion"] = undefined;
38
40
  export let blocksWrapper: ContentProps["blocksWrapper"] = undefined;
39
41
  export let blocksWrapperProps: ContentProps["blocksWrapperProps"] = undefined;
@@ -110,6 +112,30 @@
110
112
  BlocksWrapperProps: blocksWrapperProps || {},
111
113
  nonce: nonce || "",
112
114
  });
115
+ if (!apiKey) {
116
+ logger.error(
117
+ "No API key provided to `Content` component. This can cause issues. Please provide an API key using the `apiKey` prop."
118
+ );
119
+ }
120
+
121
+ // run any dynamic JS code attached to content
122
+ const jsCode = $builderContextSignal.content?.data?.jsCode;
123
+ if (jsCode) {
124
+ evaluate({
125
+ code: jsCode,
126
+ context: context || {},
127
+ localState: undefined,
128
+ rootState: $builderContextSignal.rootState,
129
+ rootSetState: (newState) => {
130
+ $builderContextSignal.rootSetState?.(newState);
131
+ },
132
+ isExpression: false,
133
+ /**
134
+ * We don't want to cache the result of the JS code, since it's arbitrary side effect code.
135
+ */
136
+ enableCache: false,
137
+ });
138
+ }
113
139
 
114
140
  setContext(ComponentsContext.key, {
115
141
  registeredComponents: registeredComponents,
@@ -1 +1 @@
1
- export const SDK_VERSION = "2.0.16"
1
+ export const SDK_VERSION = "2.0.21"
@@ -0,0 +1,18 @@
1
+ import type { SvelteComponent } from 'svelte';
2
+
3
+ export type ComponentReference =
4
+ | {
5
+ /**
6
+ * Either:
7
+ * - A dynamic import function pointing to the component.
8
+ * Example: `() => import('../components/my-component.svelte')`
9
+ * - A string representing the path to the component.
10
+ * Example: `'../components/my-component.svelte'`
11
+ */
12
+ load: string | (() => Promise<{ default: typeof SvelteComponent<any> }>);
13
+ /**
14
+ * An optional fallback component to render while the dynamic component is loading.
15
+ */
16
+ fallback?: typeof SvelteComponent<any>;
17
+ }
18
+ | typeof SvelteComponent<any>;
@@ -3,9 +3,10 @@ import type { ApiVersion } from '../types/api-version';
3
3
  import type { BuilderContent } from '../types/builder-content';
4
4
  import type { ComponentInfo } from '../types/components';
5
5
  import type { Dictionary, Nullable } from '../types/typescript';
6
+ import type { ComponentReference } from './component-reference-types';
6
7
  import type { ExtraContextTypes } from './extra-context-types';
7
8
  export type RegisteredComponent = ComponentInfo & {
8
- component: any;
9
+ component: ComponentReference;
9
10
  };
10
11
  export type RegisteredComponents = Dictionary<RegisteredComponent>;
11
12
  export type BuilderRenderState = Record<string, unknown>;