@builder.io/sdk-solid 0.4.4 → 0.4.5

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/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 0.4.5
2
+
3
+ - Fix: show dynamic symbols correctly in Preview mode.
4
+ - Feature: SSR A/B test Symbols nested inside page content.
5
+
6
+ ### 0.4.4
7
+
8
+ - Fix: tracking URL from `builder.io/api/v1/track` to `cdn.builder.io/api/v1/track` for improved reliability.
9
+
1
10
  ### 0.4.3
2
11
 
3
12
  - Fix: SSR A/B test environment check (`isHydrationTarget`) now accurately checks current environment.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-solid",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./solid-index.jsx",
@@ -4,7 +4,7 @@ import { css } from "solid-styled-components";
4
4
 
5
5
  import RenderBlocks from "../../components/render-blocks.jsx";
6
6
  import { getSizesForBreakpoints } from "../../constants/device-sizes";
7
- import RenderInlinedStyles from "../../components/render-inlined-styles.jsx";
7
+ import InlinedStyles from "../../components/inlined-styles.jsx";
8
8
  import { TARGET } from "../../constants/target.js";
9
9
  import BuilderContext from "../../context/builder.context.js";
10
10
 
@@ -143,7 +143,7 @@ function Columns(props) {
143
143
  }}
144
144
  >
145
145
  <Show when={TARGET !== "reactNative"}>
146
- <RenderInlinedStyles styles={columnsStyles()}></RenderInlinedStyles>
146
+ <InlinedStyles styles={columnsStyles()}></InlinedStyles>
147
147
  </Show>
148
148
  <For each={props.columns}>
149
149
  {(column, _index) => {
@@ -1,6 +1,6 @@
1
1
  import { useContext, onMount, on, createEffect, createSignal } from "solid-js";
2
2
 
3
- import RenderContent from "../../components/render-content/render-content.jsx";
3
+ import RenderContentVariants from "../../components/render-content-variants/render-content-variants.jsx";
4
4
  import BuilderContext from "../../context/builder.context.js";
5
5
  import { getContent } from "../../functions/get-content/index.js";
6
6
  import { TARGET } from "../../constants/target";
@@ -44,9 +44,11 @@ function Symbol(props) {
44
44
  model: props.symbol.model,
45
45
  apiKey: builderContext.apiKey,
46
46
  apiVersion: builderContext.apiVersion,
47
- query: {
48
- id: props.symbol.entry,
49
- },
47
+ ...(props.symbol?.entry && {
48
+ query: {
49
+ id: props.symbol.entry,
50
+ },
51
+ }),
50
52
  })
51
53
  .then((response) => {
52
54
  if (response) {
@@ -78,7 +80,8 @@ function Symbol(props) {
78
80
  class: className(),
79
81
  }}
80
82
  >
81
- <RenderContent
83
+ <RenderContentVariants
84
+ __isNestedRender={true}
82
85
  apiVersion={builderContext.apiVersion}
83
86
  apiKey={builderContext.apiKey}
84
87
  context={builderContext.context}
@@ -90,7 +93,7 @@ function Symbol(props) {
90
93
  }}
91
94
  model={props.symbol?.model}
92
95
  content={contentToUse()}
93
- ></RenderContent>
96
+ ></RenderContentVariants>
94
97
  </div>
95
98
  );
96
99
  }
@@ -2,7 +2,7 @@ function Text(props) {
2
2
  return (
3
3
  <span
4
4
  class="builder-text"
5
- innerHTML={props.text}
5
+ innerHTML={props.text?.toString()}
6
6
  style={{
7
7
  outline: "none",
8
8
  }}
@@ -0,0 +1,5 @@
1
+ function InlinedScript(props) {
2
+ return <script innerHTML={props.scriptStr} id={props.id}></script>;
3
+ }
4
+
5
+ export default InlinedScript;
@@ -0,0 +1,5 @@
1
+ function InlinedStyles(props) {
2
+ return <style innerHTML={props.styles} id={props.id}></style>;
3
+ }
4
+
5
+ export default InlinedStyles;
@@ -8,7 +8,7 @@ import { TARGET } from "../../constants/target.js";
8
8
  import { getProcessedBlock } from "../../functions/get-processed-block.js";
9
9
  import { createCssClass } from "../../helpers/css.js";
10
10
  import { checkIsDefined } from "../../helpers/nullable.js";
11
- import RenderInlinedStyles from "../render-inlined-styles.jsx";
11
+ import InlinedStyles from "../inlined-styles";
12
12
 
13
13
  function BlockStyles(props) {
14
14
  function useBlock() {
@@ -77,7 +77,7 @@ function BlockStyles(props) {
77
77
 
78
78
  return (
79
79
  <Show when={TARGET !== "reactNative" && css() && canShowBlock()}>
80
- <RenderInlinedStyles styles={css()}></RenderInlinedStyles>
80
+ <InlinedStyles styles={css()}></InlinedStyles>
81
81
  </Show>
82
82
  );
83
83
  }
@@ -1,6 +1,6 @@
1
1
  import { createSignal } from "solid-js";
2
2
 
3
- import RenderInlinedStyles from "../../render-inlined-styles.jsx";
3
+ import InlinedStyles from "../../inlined-styles.jsx";
4
4
  import { getCss } from "./render-styles.helpers";
5
5
  import { getFontCss } from "./render-styles.helpers";
6
6
 
@@ -30,7 +30,7 @@ ${getFontCss({
30
30
  `.trim()
31
31
  );
32
32
 
33
- return <RenderInlinedStyles styles={injectedStyles()}></RenderInlinedStyles>;
33
+ return <InlinedStyles styles={injectedStyles()}></InlinedStyles>;
34
34
  }
35
35
 
36
36
  export default RenderContentStyles;
@@ -29,6 +29,7 @@ import { TARGET } from "../../constants/target.js";
29
29
  import { logger } from "../../helpers/logger.js";
30
30
  import { getRenderContentScriptString } from "../render-content-variants/helpers.js";
31
31
  import { wrapComponentRef } from "./wrap-component-ref.js";
32
+ import InlinedScript from "../inlined-script";
32
33
 
33
34
  function RenderContent(props) {
34
35
  const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
@@ -47,9 +48,10 @@ function RenderContent(props) {
47
48
 
48
49
  const [scriptStr, setScriptStr] = createSignal(
49
50
  getRenderContentScriptString({
51
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
52
+ variationId: props.content?.testVariationId,
50
53
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
51
54
  contentId: props.content?.id,
52
- parentContentId: props.parentContentId,
53
55
  })
54
56
  );
55
57
 
@@ -403,15 +405,15 @@ function RenderContent(props) {
403
405
  },
404
406
  }
405
407
  : {})}
406
- {...(props.hideContent
407
- ? {
408
+ {...(props.showContent
409
+ ? {}
410
+ : {
408
411
  hidden: true,
409
412
  "aria-hidden": true,
410
- }
411
- : {})}
413
+ })}
412
414
  >
413
415
  <Show when={props.isSsrAbTest}>
414
- <script innerHTML={scriptStr()}></script>
416
+ <InlinedScript scriptStr={scriptStr()}></InlinedScript>
415
417
  </Show>
416
418
  <Show when={TARGET !== "reactNative"}>
417
419
  <RenderContentStyles
@@ -1,23 +1,47 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1
20
  import { TARGET } from "../../constants/target";
2
21
  import { isBrowser } from "../../functions/is-browser";
3
- const getVariants = (content) => Object.values((content == null ? void 0 : content.variations) || {});
22
+ const getVariants = (content) => Object.values((content == null ? void 0 : content.variations) || {}).map((variant) => __spreadProps(__spreadValues({}, variant), {
23
+ testVariationId: variant.id,
24
+ id: content == null ? void 0 : content.id
25
+ }));
4
26
  const checkShouldRunVariants = ({
5
27
  canTrack,
6
28
  content
7
29
  }) => {
8
30
  const hasVariants = getVariants(content).length > 0;
9
- if (!hasVariants) {
31
+ if (TARGET === "reactNative")
10
32
  return false;
11
- }
12
- if (!canTrack) {
33
+ if (!hasVariants)
13
34
  return false;
14
- }
15
- if (isBrowser()) {
35
+ if (!canTrack)
36
+ return false;
37
+ if (TARGET === "vue2" || TARGET === "vue3")
38
+ return true;
39
+ if (isBrowser())
16
40
  return false;
17
- }
18
41
  return true;
19
42
  };
20
43
  function bldrAbTest(contentId, variants, isHydrationTarget2) {
44
+ var _a;
21
45
  function getAndSetVariantId() {
22
46
  function setCookie(name, value, days) {
23
47
  let expires = "";
@@ -61,10 +85,10 @@ function bldrAbTest(contentId, variants, isHydrationTarget2) {
61
85
  return contentId;
62
86
  }
63
87
  const winningVariantId = getAndSetVariantId();
64
- const styleEl = document.getElementById(`variants-styles-${contentId}`);
88
+ const styleEl = (_a = document.currentScript) == null ? void 0 : _a.previousElementSibling;
65
89
  if (isHydrationTarget2) {
66
90
  styleEl.remove();
67
- const thisScriptEl = document.getElementById(`variants-script-${contentId}`);
91
+ const thisScriptEl = document.currentScript;
68
92
  thisScriptEl == null ? void 0 : thisScriptEl.remove();
69
93
  } else {
70
94
  const newStyleStr = variants.concat({ id: contentId }).filter((variant) => variant.id !== winningVariantId).map((value) => {
@@ -75,6 +99,7 @@ function bldrAbTest(contentId, variants, isHydrationTarget2) {
75
99
  }
76
100
  }
77
101
  function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget2) {
102
+ var _a;
78
103
  if (!navigator.cookieEnabled) {
79
104
  return;
80
105
  }
@@ -92,7 +117,7 @@ function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget2)
92
117
  }
93
118
  const cookieName = `builder.tests.${defaultContentId}`;
94
119
  const variantId = getCookie(cookieName);
95
- const parentDiv = document.querySelector(`[builder-content-id="${variantContentId}"]`);
120
+ const parentDiv = (_a = document.currentScript) == null ? void 0 : _a.parentElement;
96
121
  const variantIsDefaultContent = variantContentId === defaultContentId;
97
122
  if (variantId === variantContentId) {
98
123
  if (variantIsDefaultContent) {
@@ -113,29 +138,33 @@ function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget2)
113
138
  }
114
139
  return;
115
140
  }
116
- const getIsHydrationTarget = (target) => target === "react" || target === "reactNative" || target === "vue3" || target === "vue2";
141
+ const getIsHydrationTarget = (target) => target === "react" || target === "reactNative";
117
142
  const isHydrationTarget = getIsHydrationTarget(TARGET);
118
- const AB_TEST_FN_NAME = "bldrAbTest";
119
- const CONTENT_FN_NAME = "bldrCntntScrpt";
120
- const getVariantsScriptString = (variants, contentId) => {
143
+ const AB_TEST_FN_NAME = "builderIoAbTest";
144
+ const CONTENT_FN_NAME = "builderIoRenderContent";
145
+ const getScriptString = () => {
121
146
  const fnStr = bldrAbTest.toString().replace(/\s+/g, " ");
122
147
  const fnStr2 = bldrCntntScrpt.toString().replace(/\s+/g, " ");
123
148
  return `
124
- const ${AB_TEST_FN_NAME} = ${fnStr}
125
- const ${CONTENT_FN_NAME} = ${fnStr2}
126
- ${AB_TEST_FN_NAME}("${contentId}", ${JSON.stringify(variants)}, ${isHydrationTarget})
149
+ window.${AB_TEST_FN_NAME} = ${fnStr}
150
+ window.${CONTENT_FN_NAME} = ${fnStr2}
127
151
  `;
128
152
  };
153
+ const getVariantsScriptString = (variants, contentId) => {
154
+ return `
155
+ window.${AB_TEST_FN_NAME}("${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget})`;
156
+ };
129
157
  const getRenderContentScriptString = ({
130
- parentContentId,
131
- contentId
158
+ contentId,
159
+ variationId
132
160
  }) => {
133
161
  return `
134
- ${CONTENT_FN_NAME}("${contentId}", "${parentContentId}", ${isHydrationTarget})`;
162
+ window.${CONTENT_FN_NAME}("${variationId}", "${contentId}", ${isHydrationTarget})`;
135
163
  };
136
164
  export {
137
165
  checkShouldRunVariants,
138
166
  getRenderContentScriptString,
167
+ getScriptString,
139
168
  getVariants,
140
169
  getVariantsScriptString
141
170
  };
@@ -1,75 +1,81 @@
1
- import { Show, For, createSignal } from "solid-js";
1
+ import { Show, For, onMount, createSignal } from "solid-js";
2
2
 
3
3
  import {
4
4
  checkShouldRunVariants,
5
+ getScriptString,
5
6
  getVariants,
6
7
  getVariantsScriptString,
7
8
  } from "./helpers";
8
9
  import RenderContent from "../render-content/render-content.jsx";
9
10
  import { getDefaultCanTrack } from "../../helpers/canTrack";
10
- import RenderInlinedStyles from "../render-inlined-styles.jsx";
11
+ import InlinedStyles from "../inlined-styles.jsx";
11
12
  import { handleABTestingSync } from "../../helpers/ab-tests";
13
+ import InlinedScript from "../inlined-script.jsx";
14
+ import { TARGET } from "../../constants/target";
12
15
 
13
16
  function RenderContentVariants(props) {
17
+ const [shouldRenderVariants, setShouldRenderVariants] = createSignal(
18
+ checkShouldRunVariants({
19
+ canTrack: getDefaultCanTrack(props.canTrack),
20
+ content: props.content,
21
+ })
22
+ );
23
+
14
24
  const [variantScriptStr, setVariantScriptStr] = createSignal(
15
25
  getVariantsScriptString(
16
26
  getVariants(props.content).map((value) => ({
17
- id: value.id,
27
+ id: value.testVariationId,
18
28
  testRatio: value.testRatio,
19
29
  })),
20
30
  props.content?.id || ""
21
31
  )
22
32
  );
23
33
 
24
- const [shouldRenderVariants, setShouldRenderVariants] = createSignal(
25
- checkShouldRunVariants({
26
- canTrack: getDefaultCanTrack(props.canTrack),
27
- content: props.content,
28
- })
29
- );
30
-
31
34
  const [hideVariantsStyleString, setHideVariantsStyleString] = createSignal(
32
35
  getVariants(props.content)
33
- .map((value) => `.variant-${value.id} { display: none; } `)
36
+ .map((value) => `.variant-${value.testVariationId} { display: none; } `)
34
37
  .join("")
35
38
  );
36
39
 
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
- );
40
+ onMount(() => {
41
+ /**
42
+ * We unmount the non-winning variants post-hydration in Vue.
43
+ */
44
+ if (TARGET === "vue2" || TARGET === "vue3") {
45
+ setShouldRenderVariants(false);
46
+ }
47
+ });
48
48
 
49
49
  return (
50
50
  <>
51
+ <Show when={!props.__isNestedRender && TARGET !== "reactNative"}>
52
+ <InlinedScript scriptStr={getScriptString()}></InlinedScript>
53
+ </Show>
51
54
  <Show when={shouldRenderVariants()}>
52
- <RenderInlinedStyles
55
+ <InlinedStyles
53
56
  id={`variants-styles-${props.content?.id}`}
54
57
  styles={hideVariantsStyleString()}
55
- ></RenderInlinedStyles>
56
- <script
57
- id={`variants-script-${props.content?.id}`}
58
- innerHTML={variantScriptStr()}
59
- ></script>
58
+ ></InlinedStyles>
59
+ <InlinedScript scriptStr={variantScriptStr()}></InlinedScript>
60
60
  <For each={getVariants(props.content)}>
61
61
  {(variant, _index) => {
62
62
  const index = _index();
63
63
  return (
64
64
  <RenderContent
65
- key={variant.id}
65
+ key={variant.testVariationId}
66
66
  content={variant}
67
+ showContent={false}
68
+ classNameProp={undefined}
69
+ model={props.model}
70
+ data={props.data}
71
+ context={props.context}
67
72
  apiKey={props.apiKey}
68
73
  apiVersion={props.apiVersion}
69
- canTrack={props.canTrack}
70
74
  customComponents={props.customComponents}
71
- hideContent={true}
72
- parentContentId={props.content?.id}
75
+ canTrack={props.canTrack}
76
+ locale={props.locale}
77
+ includeRefs={props.includeRefs}
78
+ enrich={props.enrich}
73
79
  isSsrAbTest={shouldRenderVariants()}
74
80
  ></RenderContent>
75
81
  );
@@ -77,14 +83,27 @@ function RenderContentVariants(props) {
77
83
  </For>
78
84
  </Show>
79
85
  <RenderContent
86
+ {...{}}
87
+ content={
88
+ shouldRenderVariants()
89
+ ? props.content
90
+ : handleABTestingSync({
91
+ item: props.content,
92
+ canTrack: getDefaultCanTrack(props.canTrack),
93
+ })
94
+ }
95
+ classNameProp={`variant-${props.content?.id}`}
96
+ showContent={true}
80
97
  model={props.model}
81
- content={contentToRender()}
98
+ data={props.data}
99
+ context={props.context}
82
100
  apiKey={props.apiKey}
83
101
  apiVersion={props.apiVersion}
84
- canTrack={props.canTrack}
85
102
  customComponents={props.customComponents}
86
- classNameProp={`variant-${props.content?.id}`}
87
- parentContentId={props.content?.id}
103
+ canTrack={props.canTrack}
104
+ locale={props.locale}
105
+ includeRefs={props.includeRefs}
106
+ enrich={props.enrich}
88
107
  isSsrAbTest={shouldRenderVariants()}
89
108
  ></RenderContent>
90
109
  </>
@@ -1 +1 @@
1
- export const SDK_VERSION = "0.4.4"
1
+ export const SDK_VERSION = "0.4.5"
@@ -37,6 +37,7 @@ var __async = (__this, __arguments, generator) => {
37
37
  import { getCookie, getCookieSync, setCookie } from "./cookie.js";
38
38
  import { checkIsDefined } from "../helpers/nullable.js";
39
39
  import { logger } from "./logger.js";
40
+ import { TARGET } from "../constants/target.js";
40
41
  const BUILDER_STORE_PREFIX = "builder.tests";
41
42
  const getContentTestKey = (id) => `${BUILDER_STORE_PREFIX}.${id}`;
42
43
  const getContentVariationCookie = ({ contentId }) => getCookie({ name: getContentTestKey(contentId), canTrack: true });
@@ -94,6 +95,8 @@ const handleABTestingSync = ({
94
95
  item,
95
96
  canTrack
96
97
  }) => {
98
+ if (TARGET === "reactNative")
99
+ return item;
97
100
  if (!canTrack) {
98
101
  return item;
99
102
  }
File without changes
@@ -1,5 +0,0 @@
1
- function RenderInlinedStyles(props) {
2
- return <style innerHTML={props.styles} id={props.id}></style>;
3
- }
4
-
5
- export default RenderInlinedStyles;