@builder.io/sdk-solid 0.2.3 → 0.4.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 (32) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/package.json +2 -5
  3. package/src/blocks/columns/columns.jsx +1 -1
  4. package/src/blocks/symbol/symbol.jsx +1 -1
  5. package/src/components/render-block/block-styles.jsx +3 -1
  6. package/src/components/render-block/render-block.helpers.js +7 -19
  7. package/src/components/render-block/render-block.jsx +23 -23
  8. package/src/components/render-block/render-repeated-block.jsx +3 -2
  9. package/src/components/render-content/components/render-styles.jsx +4 -2
  10. package/src/components/render-content/render-content.jsx +52 -9
  11. package/src/components/render-content/wrap-component-ref.js +4 -0
  12. package/src/components/render-content-variants/helpers.js +139 -0
  13. package/src/components/render-content-variants/render-content-variants.jsx +94 -0
  14. package/src/components/render-inlined-styles.jsx +1 -23
  15. package/src/constants/sdk-version.js +1 -0
  16. package/src/context/builder.context.js +3 -2
  17. package/src/functions/evaluate.js +27 -3
  18. package/src/functions/evaluate.test.js +17 -0
  19. package/src/functions/get-block-actions-handler.js +3 -1
  20. package/src/functions/get-content/generate-content-url.js +2 -1
  21. package/src/functions/get-content/generate-content-url.test.js +15 -0
  22. package/src/functions/get-content/index.js +35 -18
  23. package/src/functions/get-processed-block.js +20 -4
  24. package/src/functions/get-processed-block.test.js +3 -1
  25. package/src/helpers/ab-tests.js +132 -10
  26. package/src/helpers/canTrack.js +5 -0
  27. package/src/helpers/cookie.js +9 -4
  28. package/src/helpers/logger.js +2 -1
  29. package/src/index-helpers/blocks-exports.js +10 -10
  30. package/src/index.js +18 -7
  31. package/src/scripts/init-editing.js +2 -0
  32. package/src/functions/get-content/ab-testing.js +0 -99
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ### 0.4.0
2
+
3
+ - Feature: A/B tests are now rendered correctly during server-side rendering (SSR) when applicable. This behaviour is backwards compatible with previous versions.
4
+
5
+ ### 0.3.1
6
+
7
+ - Feature: Added SDK version to data sent to visual editor for improved debugging.
8
+ - Fix: Columns block: removed redundant margin-left in first column.
9
+
10
+ ### 0.3.0
11
+
12
+ - No Changes.
13
+
1
14
  ### 0.2.3
2
15
 
3
16
  - No Changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-solid",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./solid-index.jsx",
@@ -12,10 +12,7 @@
12
12
  }
13
13
  },
14
14
  "scripts": {
15
- "build": "echo 'no need to build solid SDK'",
16
- "release:patch": "yarn run build && npm version patch && npm publish",
17
- "release:minor": "yarn run build && npm version minor && npm publish",
18
- "release:dev": "yarn run build && npm version prerelease && npm publish --tag dev"
15
+ "build": "echo 'no need to build solid SDK'"
19
16
  },
20
17
  "dependencies": {
21
18
  "solid-styled-components": "^0.27.6"
@@ -65,7 +65,7 @@ function Columns(props) {
65
65
  };
66
66
  }
67
67
  const width = getColumnCssWidth(index);
68
- const gutterPixels = `${gutterSize()}px`;
68
+ const gutterPixels = `${gutter}px`;
69
69
  const mobileWidth = "100%";
70
70
  const mobileMarginLeft = 0;
71
71
  return {
@@ -85,7 +85,7 @@ function Symbol(props) {
85
85
  customComponents={Object.values(builderContext.registeredComponents)}
86
86
  data={{
87
87
  ...props.symbol?.data,
88
- ...builderContext.state,
88
+ ...builderContext.localState,
89
89
  ...contentToUse()?.data?.state,
90
90
  }}
91
91
  model={props.symbol?.model}
@@ -14,7 +14,9 @@ function BlockStyles(props) {
14
14
  function useBlock() {
15
15
  return getProcessedBlock({
16
16
  block: props.block,
17
- state: props.context.state,
17
+ localState: props.context.localState,
18
+ rootState: props.context.rootState,
19
+ rootSetState: props.context.rootSetState,
18
20
  context: props.context.context,
19
21
  shouldEvaluateBindings: true,
20
22
  });
@@ -58,7 +58,9 @@ const getComponent = ({
58
58
  var _a;
59
59
  const componentName = (_a = getProcessedBlock({
60
60
  block,
61
- state: context.state,
61
+ localState: context.localState,
62
+ rootState: context.rootState,
63
+ rootSetState: context.rootSetState,
62
64
  context: context.context,
63
65
  shouldEvaluateBindings: false
64
66
  }).component) == null ? void 0 : _a.name;
@@ -85,7 +87,9 @@ const getRepeatItemData = ({
85
87
  }
86
88
  const itemsArray = evaluate({
87
89
  code: repeat.collection,
88
- state: context.state,
90
+ localState: context.localState,
91
+ rootState: context.rootState,
92
+ rootSetState: context.rootSetState,
89
93
  context: context.context
90
94
  });
91
95
  if (!Array.isArray(itemsArray)) {
@@ -95,7 +99,7 @@ const getRepeatItemData = ({
95
99
  const itemNameToUse = repeat.itemName || (collectionName ? collectionName + "Item" : "item");
96
100
  const repeatArray = itemsArray.map((item, index) => ({
97
101
  context: __spreadProps(__spreadValues({}, context), {
98
- state: __spreadProps(__spreadValues({}, context.state), {
102
+ localState: __spreadProps(__spreadValues({}, context.localState), {
99
103
  $index: index,
100
104
  $item: item,
101
105
  [itemNameToUse]: item,
@@ -106,24 +110,8 @@ const getRepeatItemData = ({
106
110
  }));
107
111
  return repeatArray;
108
112
  };
109
- const getProxyState = (context) => {
110
- if (typeof Proxy === "undefined") {
111
- console.error("no Proxy available in this environment, cannot proxy state.");
112
- return context.state;
113
- }
114
- const useState = new Proxy(context.state, {
115
- set: (obj, prop, value) => {
116
- var _a;
117
- obj[prop] = value;
118
- (_a = context.setState) == null ? void 0 : _a.call(context, obj);
119
- return true;
120
- }
121
- });
122
- return useState;
123
- };
124
113
  export {
125
114
  getComponent,
126
- getProxyState,
127
115
  getRepeatItemData,
128
116
  isEmptyHtmlElement
129
117
  };
@@ -8,7 +8,6 @@ import { getProcessedBlock } from "../../functions/get-processed-block.js";
8
8
  import BlockStyles from "./block-styles.jsx";
9
9
  import {
10
10
  getComponent,
11
- getProxyState,
12
11
  getRepeatItemData,
13
12
  isEmptyHtmlElement,
14
13
  } from "./render-block.helpers.js";
@@ -26,25 +25,23 @@ function RenderBlock(props) {
26
25
  })
27
26
  );
28
27
 
29
- const [repeatItemData, setRepeatItemData] = createSignal(
30
- getRepeatItemData({
28
+ const [Tag, setTag] = createSignal(props.block.tagName || "div");
29
+
30
+ function repeatItem() {
31
+ return getRepeatItemData({
31
32
  block: props.block,
32
33
  context: props.context,
33
- })
34
- );
35
-
36
- const [tag, setTag] = createSignal(props.block.tagName || "div");
37
-
38
- const [proxyState, setProxyState] = createSignal(
39
- getProxyState(props.context)
40
- );
34
+ });
35
+ }
41
36
 
42
37
  function useBlock() {
43
- return repeatItemData()
38
+ return repeatItem()
44
39
  ? props.block
45
40
  : getProcessedBlock({
46
41
  block: props.block,
47
- state: props.context.state,
42
+ localState: props.context.localState,
43
+ rootState: props.context.rootState,
44
+ rootSetState: props.context.rootSetState,
48
45
  context: props.context.context,
49
46
  shouldEvaluateBindings: true,
50
47
  });
@@ -63,7 +60,9 @@ function RenderBlock(props) {
63
60
  function actions() {
64
61
  return getBlockActions({
65
62
  block: useBlock(),
66
- state: TARGET === "qwik" ? props.context.state : proxyState(),
63
+ rootState: props.context.rootState,
64
+ rootSetState: props.context.rootSetState,
65
+ localState: props.context.localState,
67
66
  context: props.context.context,
68
67
  });
69
68
  }
@@ -92,7 +91,7 @@ function RenderBlock(props) {
92
91
  * blocks, and the children will be repeated within those blocks.
93
92
  */
94
93
  const shouldRenderChildrenOutsideRef =
95
- !component()?.component && !repeatItemData();
94
+ !component()?.component && !repeatItem();
96
95
  return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
97
96
  }
98
97
 
@@ -112,10 +111,11 @@ function RenderBlock(props) {
112
111
  return {
113
112
  apiKey: props.context.apiKey,
114
113
  apiVersion: props.context.apiVersion,
115
- state: props.context.state,
114
+ localState: props.context.localState,
115
+ rootState: props.context.rootState,
116
+ rootSetState: props.context.rootSetState,
116
117
  content: props.context.content,
117
118
  context: props.context.context,
118
- setState: props.context.setState,
119
119
  registeredComponents: props.context.registeredComponents,
120
120
  inheritedStyles: getInheritedTextStyles(),
121
121
  };
@@ -152,11 +152,11 @@ function RenderBlock(props) {
152
152
  }
153
153
  when={!component()?.noWrap}
154
154
  >
155
- <Show when={isEmptyHtmlElement(tag())}>
156
- <Dynamic {...attributes()} {...actions()} component={tag()}></Dynamic>
155
+ <Show when={isEmptyHtmlElement(Tag())}>
156
+ <Dynamic {...attributes()} {...actions()} component={Tag()}></Dynamic>
157
157
  </Show>
158
- <Show when={!isEmptyHtmlElement(tag()) && repeatItemData()}>
159
- <For each={repeatItemData()}>
158
+ <Show when={!isEmptyHtmlElement(Tag()) && repeatItem()}>
159
+ <For each={repeatItem()}>
160
160
  {(data, _index) => {
161
161
  const index = _index();
162
162
  return (
@@ -169,8 +169,8 @@ function RenderBlock(props) {
169
169
  }}
170
170
  </For>
171
171
  </Show>
172
- <Show when={!isEmptyHtmlElement(tag()) && !repeatItemData()}>
173
- <Dynamic {...attributes()} {...actions()} component={tag()}>
172
+ <Show when={!isEmptyHtmlElement(Tag()) && !repeatItem()}>
173
+ <Dynamic {...attributes()} {...actions()} component={Tag()}>
174
174
  <RenderComponent {...renderComponentProps()}></RenderComponent>
175
175
  <For each={childrenWithoutParentComponent()}>
176
176
  {(child, _index) => {
@@ -6,8 +6,9 @@ function RenderRepeatedBlock(props) {
6
6
  <BuilderContext.Provider
7
7
  value={{
8
8
  content: props.repeatContext.content,
9
- state: props.repeatContext.state,
10
- setState: props.repeatContext.setState,
9
+ localState: props.repeatContext.localState,
10
+ rootState: props.repeatContext.rootState,
11
+ rootSetState: props.repeatContext.rootSetState,
11
12
  context: props.repeatContext.context,
12
13
  apiKey: props.repeatContext.apiKey,
13
14
  registeredComponents: props.repeatContext.registeredComponents,
@@ -5,7 +5,8 @@ import { getCss } from "./render-styles.helpers";
5
5
  import { getFontCss } from "./render-styles.helpers";
6
6
 
7
7
  function RenderContentStyles(props) {
8
- const [injectedStyles, setInjectedStyles] = createSignal(`
8
+ const [injectedStyles, setInjectedStyles] = createSignal(
9
+ `
9
10
  ${getCss({
10
11
  cssCode: props.cssCode,
11
12
  contentId: props.contentId,
@@ -26,7 +27,8 @@ ${getFontCss({
26
27
  text-align: inherit;
27
28
  font-family: inherit;
28
29
  }
29
- `);
30
+ `.trim()
31
+ );
30
32
 
31
33
  return <RenderInlinedStyles styles={injectedStyles()}></RenderInlinedStyles>;
32
34
  }
@@ -29,6 +29,8 @@ import {
29
29
  } from "./render-content.helpers.js";
30
30
  import { TARGET } from "../../constants/target.js";
31
31
  import { logger } from "../../helpers/logger.js";
32
+ import { getRenderContentScriptString } from "../render-content-variants/helpers.js";
33
+ import { wrapComponentRef } from "./wrap-component-ref.js";
32
34
 
33
35
  function RenderContent(props) {
34
36
  const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
@@ -60,9 +62,13 @@ function RenderContent(props) {
60
62
  ...components,
61
63
  ...(props.customComponents || []),
62
64
  ].reduce(
63
- (acc, curr) => ({
65
+ (acc, { component, ...curr }) => ({
64
66
  ...acc,
65
- [curr.name]: curr,
67
+ [curr.name]: {
68
+ component:
69
+ TARGET === "vue3" ? wrapComponentRef(component) : component,
70
+ ...curr,
71
+ },
66
72
  }),
67
73
  {}
68
74
  )
@@ -72,6 +78,14 @@ function RenderContent(props) {
72
78
 
73
79
  const [clicked, setClicked] = createSignal(false);
74
80
 
81
+ const [scriptStr, setScriptStr] = createSignal(
82
+ getRenderContentScriptString({
83
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
84
+ contentId: props.content?.id,
85
+ parentContentId: props.parentContentId,
86
+ })
87
+ );
88
+
75
89
  function mergeNewContent(newContent) {
76
90
  setUseContent({
77
91
  ...useContent,
@@ -99,8 +113,8 @@ function RenderContent(props) {
99
113
  });
100
114
  }
101
115
 
102
- function setContextState(newState) {
103
- setContentState(newState);
116
+ function contentSetState(newRootState) {
117
+ setContentState(newRootState);
104
118
  }
105
119
 
106
120
  function processMessage(event) {
@@ -149,7 +163,9 @@ function RenderContent(props) {
149
163
  evaluate({
150
164
  code: jsCode,
151
165
  context: props.context || {},
152
- state: contentState(),
166
+ localState: undefined,
167
+ rootState: contentState(),
168
+ rootSetState: contentSetState,
153
169
  });
154
170
  }
155
171
  }
@@ -178,7 +194,9 @@ function RenderContent(props) {
178
194
  evaluate({
179
195
  code: group,
180
196
  context: props.context || {},
181
- state: contentState(),
197
+ localState: undefined,
198
+ rootState: contentState(),
199
+ rootSetState: contentSetState,
182
200
  })
183
201
  );
184
202
  }
@@ -191,7 +209,7 @@ function RenderContent(props) {
191
209
  ...contentState(),
192
210
  [key]: json,
193
211
  };
194
- setContextState(newState);
212
+ contentSetState(newState);
195
213
  })
196
214
  .catch((err) => {
197
215
  console.error("error fetching dynamic data", url, err);
@@ -255,6 +273,11 @@ function RenderContent(props) {
255
273
  includeRefs: props.includeRefs,
256
274
  }
257
275
  : {}),
276
+ ...(props.enrich
277
+ ? {
278
+ enrich: props.enrich,
279
+ }
280
+ : {}),
258
281
  });
259
282
  Object.values(allRegisteredComponents()).forEach(
260
283
  (registeredComponent) => {
@@ -349,8 +372,9 @@ function RenderContent(props) {
349
372
  <builderContext.Provider
350
373
  value={{
351
374
  content: useContent,
352
- state: contentState(),
353
- setState: setContextState,
375
+ localState: undefined,
376
+ rootState: contentState(),
377
+ rootSetState: TARGET === "qwik" ? undefined : contentSetState,
354
378
  context: props.context || {},
355
379
  apiKey: props.apiKey,
356
380
  apiVersion: props.apiVersion,
@@ -360,11 +384,30 @@ function RenderContent(props) {
360
384
  >
361
385
  <Show when={useContent}>
362
386
  <div
387
+ class={props.classNameProp}
363
388
  ref={elementRef}
364
389
  onClick={(event) => onClick(event)}
365
390
  builder-content-id={useContent?.id}
366
391
  builder-model={props.model}
392
+ {...(TARGET === "reactNative"
393
+ ? {
394
+ dataSet: {
395
+ // currently, we can't set the actual ID here.
396
+ // we don't need it right now, we just need to identify content divs for testing.
397
+ "builder-content-id": "",
398
+ },
399
+ }
400
+ : {})}
401
+ {...(props.hideContent
402
+ ? {
403
+ hidden: true,
404
+ "aria-hidden": true,
405
+ }
406
+ : {})}
367
407
  >
408
+ <Show when={props.isSsrAbTest}>
409
+ <script innerHTML={scriptStr()}></script>
410
+ </Show>
368
411
  <Show when={TARGET !== "reactNative"}>
369
412
  <RenderContentStyles
370
413
  contentId={useContent?.id}
@@ -0,0 +1,4 @@
1
+ const wrapComponentRef = (component) => component;
2
+ export {
3
+ wrapComponentRef
4
+ };
@@ -0,0 +1,139 @@
1
+ import { isBrowser } from "../../functions/is-browser";
2
+ const getVariants = (content) => Object.values((content == null ? void 0 : content.variations) || {});
3
+ const checkShouldRunVariants = ({
4
+ canTrack,
5
+ content
6
+ }) => {
7
+ const hasVariants = getVariants(content).length > 0;
8
+ if (!hasVariants) {
9
+ return false;
10
+ }
11
+ if (!canTrack) {
12
+ return false;
13
+ }
14
+ if (isBrowser()) {
15
+ return false;
16
+ }
17
+ return true;
18
+ };
19
+ function bldrAbTest(contentId, variants, isHydrationTarget2) {
20
+ function getAndSetVariantId() {
21
+ function setCookie(name, value, days) {
22
+ let expires = "";
23
+ if (days) {
24
+ const date = new Date();
25
+ date.setTime(date.getTime() + days * 24 * 60 * 60 * 1e3);
26
+ expires = "; expires=" + date.toUTCString();
27
+ }
28
+ document.cookie = name + "=" + (value || "") + expires + "; path=/; Secure; SameSite=None";
29
+ }
30
+ function getCookie(name) {
31
+ const nameEQ = name + "=";
32
+ const ca = document.cookie.split(";");
33
+ for (let i = 0; i < ca.length; i++) {
34
+ let c = ca[i];
35
+ while (c.charAt(0) === " ")
36
+ c = c.substring(1, c.length);
37
+ if (c.indexOf(nameEQ) === 0)
38
+ return c.substring(nameEQ.length, c.length);
39
+ }
40
+ return null;
41
+ }
42
+ const cookieName = `builder.tests.${contentId}`;
43
+ const variantInCookie = getCookie(cookieName);
44
+ const availableIDs = variants.map((vr) => vr.id).concat(contentId);
45
+ if (variantInCookie && availableIDs.includes(variantInCookie)) {
46
+ return variantInCookie;
47
+ }
48
+ let n = 0;
49
+ const random = Math.random();
50
+ for (let i = 0; i < variants.length; i++) {
51
+ const variant = variants[i];
52
+ const testRatio = variant.testRatio;
53
+ n += testRatio;
54
+ if (random < n) {
55
+ setCookie(cookieName, variant.id);
56
+ return variant.id;
57
+ }
58
+ }
59
+ setCookie(cookieName, contentId);
60
+ return contentId;
61
+ }
62
+ const winningVariantId = getAndSetVariantId();
63
+ const styleEl = document.getElementById(`variants-styles-${contentId}`);
64
+ if (isHydrationTarget2) {
65
+ styleEl.remove();
66
+ const thisScriptEl = document.getElementById(`variants-script-${contentId}`);
67
+ thisScriptEl == null ? void 0 : thisScriptEl.remove();
68
+ } else {
69
+ const newStyleStr = variants.concat({ id: contentId }).filter((variant) => variant.id !== winningVariantId).map((value) => {
70
+ return `.variant-${value.id} { display: none; }
71
+ `;
72
+ }).join("");
73
+ styleEl.innerHTML = newStyleStr;
74
+ }
75
+ }
76
+ function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget2) {
77
+ if (!navigator.cookieEnabled) {
78
+ return;
79
+ }
80
+ function getCookie(name) {
81
+ const nameEQ = name + "=";
82
+ const ca = document.cookie.split(";");
83
+ for (let i = 0; i < ca.length; i++) {
84
+ let c = ca[i];
85
+ while (c.charAt(0) === " ")
86
+ c = c.substring(1, c.length);
87
+ if (c.indexOf(nameEQ) === 0)
88
+ return c.substring(nameEQ.length, c.length);
89
+ }
90
+ return null;
91
+ }
92
+ const cookieName = `builder.tests.${defaultContentId}`;
93
+ const variantId = getCookie(cookieName);
94
+ const parentDiv = document.querySelector(`[builder-content-id="${variantContentId}"]`);
95
+ const variantIsDefaultContent = variantContentId === defaultContentId;
96
+ if (variantId === variantContentId) {
97
+ if (variantIsDefaultContent) {
98
+ return;
99
+ }
100
+ parentDiv == null ? void 0 : parentDiv.removeAttribute("hidden");
101
+ parentDiv == null ? void 0 : parentDiv.removeAttribute("aria-hidden");
102
+ } else {
103
+ if (variantIsDefaultContent) {
104
+ if (isHydrationTarget2) {
105
+ parentDiv == null ? void 0 : parentDiv.remove();
106
+ } else {
107
+ parentDiv == null ? void 0 : parentDiv.setAttribute("hidden", "true");
108
+ parentDiv == null ? void 0 : parentDiv.setAttribute("aria-hidden", "true");
109
+ }
110
+ }
111
+ return;
112
+ }
113
+ return;
114
+ }
115
+ const isHydrationTarget = (target) => target === "react" || target === "reactNative" || target === "vue3" || target === "vue2";
116
+ const AB_TEST_FN_NAME = "bldrAbTest";
117
+ const CONTENT_FN_NAME = "bldrCntntScrpt";
118
+ const getVariantsScriptString = (variants, contentId) => {
119
+ const fnStr = bldrAbTest.toString().replace(/\s+/g, " ");
120
+ const fnStr2 = bldrCntntScrpt.toString().replace(/\s+/g, " ");
121
+ return `
122
+ const ${AB_TEST_FN_NAME} = ${fnStr}
123
+ const ${CONTENT_FN_NAME} = ${fnStr2}
124
+ ${AB_TEST_FN_NAME}("${contentId}", ${JSON.stringify(variants)}, ${isHydrationTarget})
125
+ `;
126
+ };
127
+ const getRenderContentScriptString = ({
128
+ parentContentId,
129
+ contentId
130
+ }) => {
131
+ return `
132
+ ${CONTENT_FN_NAME}("${contentId}", "${parentContentId}", ${isHydrationTarget})`;
133
+ };
134
+ export {
135
+ checkShouldRunVariants,
136
+ getRenderContentScriptString,
137
+ getVariants,
138
+ getVariantsScriptString
139
+ };
@@ -0,0 +1,94 @@
1
+ import { Show, For, createSignal } from "solid-js";
2
+
3
+ import {
4
+ checkShouldRunVariants,
5
+ getVariants,
6
+ getVariantsScriptString,
7
+ } from "./helpers";
8
+ import RenderContent from "../render-content/render-content.jsx";
9
+ import { getDefaultCanTrack } from "../../helpers/canTrack";
10
+ import RenderInlinedStyles from "../render-inlined-styles.jsx";
11
+ import { handleABTestingSync } from "../../helpers/ab-tests";
12
+
13
+ function RenderContentVariants(props) {
14
+ const [variantScriptStr, setVariantScriptStr] = createSignal(
15
+ getVariantsScriptString(
16
+ getVariants(props.content).map((value) => ({
17
+ id: value.id,
18
+ testRatio: value.testRatio,
19
+ })),
20
+ props.content?.id || ""
21
+ )
22
+ );
23
+
24
+ const [shouldRenderVariants, setShouldRenderVariants] = createSignal(
25
+ checkShouldRunVariants({
26
+ canTrack: getDefaultCanTrack(props.canTrack),
27
+ content: props.content,
28
+ })
29
+ );
30
+
31
+ const [hideVariantsStyleString, setHideVariantsStyleString] = createSignal(
32
+ getVariants(props.content)
33
+ .map((value) => `.variant-${value.id} { display: none; } `)
34
+ .join("")
35
+ );
36
+
37
+ const [contentToRender, setContentToRender] = createSignal(
38
+ checkShouldRunVariants({
39
+ canTrack: getDefaultCanTrack(props.canTrack),
40
+ content: props.content,
41
+ })
42
+ ? props.content
43
+ : handleABTestingSync({
44
+ item: props.content,
45
+ canTrack: getDefaultCanTrack(props.canTrack),
46
+ })
47
+ );
48
+
49
+ return (
50
+ <>
51
+ <Show when={shouldRenderVariants()}>
52
+ <RenderInlinedStyles
53
+ id={`variants-styles-${props.content?.id}`}
54
+ styles={hideVariantsStyleString()}
55
+ ></RenderInlinedStyles>
56
+ <script
57
+ id={`variants-script-${props.content?.id}`}
58
+ innerHTML={variantScriptStr()}
59
+ ></script>
60
+ <For each={getVariants(props.content)}>
61
+ {(variant, _index) => {
62
+ const index = _index();
63
+ return (
64
+ <RenderContent
65
+ key={variant.id}
66
+ content={variant}
67
+ apiKey={props.apiKey}
68
+ apiVersion={props.apiVersion}
69
+ canTrack={props.canTrack}
70
+ customComponents={props.customComponents}
71
+ hideContent={true}
72
+ parentContentId={props.content?.id}
73
+ isSsrAbTest={shouldRenderVariants()}
74
+ ></RenderContent>
75
+ );
76
+ }}
77
+ </For>
78
+ </Show>
79
+ <RenderContent
80
+ model={props.model}
81
+ content={contentToRender()}
82
+ apiKey={props.apiKey}
83
+ apiVersion={props.apiVersion}
84
+ canTrack={props.canTrack}
85
+ customComponents={props.customComponents}
86
+ classNameProp={`variant-${props.content?.id}`}
87
+ parentContentId={props.content?.id}
88
+ isSsrAbTest={shouldRenderVariants()}
89
+ ></RenderContent>
90
+ </>
91
+ );
92
+ }
93
+
94
+ export default RenderContentVariants;
@@ -1,27 +1,5 @@
1
- import { Show, createSignal } from "solid-js";
2
- import { Dynamic } from "solid-js/web";
3
-
4
- import { TARGET } from "../constants/target.js";
5
-
6
1
  function RenderInlinedStyles(props) {
7
- function tag() {
8
- // NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
9
- // https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
10
- return "sty" + "le";
11
- }
12
-
13
- function injectedStyleScript() {
14
- return `<${tag()}>${props.styles}</${tag()}>`;
15
- }
16
-
17
- return (
18
- <Show
19
- fallback={<Dynamic component={tag()}>{props.styles}</Dynamic>}
20
- when={TARGET === "svelte" || TARGET === "qwik"}
21
- >
22
- <Dynamic innerHTML={props.styles} component={tag()}></Dynamic>
23
- </Show>
24
- );
2
+ return <style innerHTML={props.styles} id={props.id}></style>;
25
3
  }
26
4
 
27
5
  export default RenderInlinedStyles;
@@ -0,0 +1 @@
1
+ export const SDK_VERSION = "0.4.0"
@@ -2,9 +2,10 @@ import { createContext } from "solid-js";
2
2
  var stdin_default = createContext({
3
3
  content: null,
4
4
  context: {},
5
- state: {},
6
- setState() {
5
+ localState: void 0,
6
+ rootSetState() {
7
7
  },
8
+ rootState: {},
8
9
  apiKey: null,
9
10
  apiVersion: void 0,
10
11
  registeredComponents: {},