@builder.io/sdk-solid 0.0.19 → 0.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 (39) hide show
  1. package/package.json +1 -1
  2. package/src/blocks/BaseText.jsx +0 -2
  3. package/src/blocks/button/button.jsx +1 -3
  4. package/src/blocks/columns/columns.jsx +1 -13
  5. package/src/blocks/columns/component-info.js +2 -2
  6. package/src/blocks/custom-code/custom-code.jsx +0 -8
  7. package/src/blocks/embed/component-info.js +2 -2
  8. package/src/blocks/embed/embed.jsx +0 -8
  9. package/src/blocks/form/form.jsx +9 -43
  10. package/src/blocks/fragment/fragment.jsx +0 -1
  11. package/src/blocks/image/component-info.js +2 -2
  12. package/src/blocks/image/image.jsx +4 -9
  13. package/src/blocks/img/img.jsx +2 -4
  14. package/src/blocks/input/input.jsx +0 -2
  15. package/src/blocks/raw-text/raw-text.jsx +0 -1
  16. package/src/blocks/section/section.jsx +0 -1
  17. package/src/blocks/select/select.jsx +0 -3
  18. package/src/blocks/submit-button/submit-button.jsx +1 -2
  19. package/src/blocks/symbol/symbol.jsx +4 -10
  20. package/src/blocks/text/text.jsx +0 -1
  21. package/src/blocks/textarea/textarea.jsx +0 -1
  22. package/src/blocks/util.js +6 -5
  23. package/src/blocks/video/video.jsx +4 -5
  24. package/src/components/render-block/block-styles.jsx +5 -7
  25. package/src/components/render-block/render-block.jsx +17 -39
  26. package/src/components/render-block/render-component-with-context.jsx +0 -8
  27. package/src/components/render-block/render-component.jsx +1 -6
  28. package/src/components/render-block/render-repeated-block.jsx +0 -8
  29. package/src/components/render-blocks.jsx +0 -7
  30. package/src/components/render-content/builder-editing.jsx +4 -0
  31. package/src/components/render-content/components/render-styles.jsx +2 -13
  32. package/src/components/render-content/render-content.jsx +29 -56
  33. package/src/components/render-inlined-styles.jsx +3 -7
  34. package/src/constants/device-sizes.js +29 -2
  35. package/src/functions/get-content/index.js +6 -2
  36. package/src/functions/register-component.js +1 -5
  37. package/src/functions/track.js +11 -8
  38. package/src/index.js +5 -1
  39. package/src/scripts/init-editing.js +7 -1
@@ -11,51 +11,46 @@ import { isBrowser } from "../../functions/is-browser.js";
11
11
  import { isEditing } from "../../functions/is-editing.js";
12
12
  import { isPreviewing } from "../../functions/is-previewing.js";
13
13
  import { components, createRegisterComponentMessage } from "../../functions/register-component.js";
14
- import { track } from "../../functions/track.js";
14
+ import { _track } from "../../functions/track.js";
15
15
  import RenderBlocks from "../render-blocks.jsx";
16
16
  import RenderContentStyles from "./components/render-styles.jsx";
17
17
  import { registerInsertMenu, setupBrowserForEditing } from "../../scripts/init-editing.js";
18
- import { markMutable } from "../../functions/mark-mutable.js";
19
-
20
18
  function RenderContent(props) {
21
19
  const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
22
20
  const [overrideContent, setOverrideContent] = createSignal(null);
23
21
  const [update, setUpdate] = createSignal(0);
24
22
  const [overrideState, setOverrideState] = createSignal({});
25
-
26
23
  function canTrackToUse() {
27
24
  return props.canTrack || true;
28
25
  }
29
-
30
26
  function contentState() {
31
- return { ...props.content?.data?.state,
27
+ return {
28
+ ...props.content?.data?.state,
32
29
  ...props.data,
33
30
  ...overrideState()
34
31
  };
35
32
  }
36
-
37
33
  function contextContext() {
38
34
  return props.context || {};
39
35
  }
40
-
41
36
  function allRegisteredComponents() {
42
- const allComponentsArray = [...getDefaultRegisteredComponents(), // While this `components` object is deprecated, we must maintain support for it.
37
+ const allComponentsArray = [...getDefaultRegisteredComponents(),
38
+ // While this `components` object is deprecated, we must maintain support for it.
43
39
  // Since users are able to override our default components, we need to make sure that we do not break such
44
40
  // existing usage.
45
41
  // This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
46
42
  // which is the new standard way of providing custom components, and must therefore take precedence.
47
43
  ...components, ...(props.customComponents || [])];
48
- const allComponents = allComponentsArray.reduce((acc, curr) => ({ ...acc,
44
+ const allComponents = allComponentsArray.reduce((acc, curr) => ({
45
+ ...acc,
49
46
  [curr.name]: curr
50
47
  }), {});
51
48
  return allComponents;
52
49
  }
53
-
54
50
  function processMessage(event) {
55
51
  const {
56
52
  data
57
53
  } = event;
58
-
59
54
  if (data) {
60
55
  switch (data.type) {
61
56
  case "builder.contentUpdate":
@@ -63,7 +58,6 @@ function RenderContent(props) {
63
58
  const messageContent = data.data;
64
59
  const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
65
60
  const contentData = messageContent.data;
66
-
67
61
  if (key === props.model) {
68
62
  setOverrideContent(contentData);
69
63
  setForceReRenderCount(forceReRenderCount() + 1); // This is a hack to force Qwik to re-render.
@@ -71,7 +65,6 @@ function RenderContent(props) {
71
65
 
72
66
  break;
73
67
  }
74
-
75
68
  case "builder.patchUpdates":
76
69
  {
77
70
  // TODO
@@ -80,11 +73,9 @@ function RenderContent(props) {
80
73
  }
81
74
  }
82
75
  }
83
-
84
76
  function evaluateJsCode() {
85
77
  // run any dynamic JS code attached to content
86
78
  const jsCode = useContent?.data?.jsCode;
87
-
88
79
  if (jsCode) {
89
80
  evaluate({
90
81
  code: jsCode,
@@ -93,22 +84,22 @@ function RenderContent(props) {
93
84
  });
94
85
  }
95
86
  }
96
-
97
87
  function httpReqsData() {
98
88
  return {};
99
89
  }
100
-
101
90
  function onClick(_event) {
102
91
  if (useContent) {
103
- track({
92
+ const variationId = useContent?.testVariationId;
93
+ const contentId = useContent?.id;
94
+ _track({
104
95
  type: "click",
105
96
  canTrack: canTrackToUse(),
106
- contentId: useContent?.id,
107
- orgId: props.apiKey
97
+ contentId,
98
+ apiKey: props.apiKey,
99
+ variationId: variationId !== contentId ? variationId : undefined
108
100
  });
109
101
  }
110
102
  }
111
-
112
103
  function evalExpression(expression) {
113
104
  return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
114
105
  code: group,
@@ -116,13 +107,13 @@ function RenderContent(props) {
116
107
  state: contentState()
117
108
  }));
118
109
  }
119
-
120
110
  function handleRequest({
121
111
  url,
122
112
  key
123
113
  }) {
124
114
  getFetch().then(fetch => fetch(url)).then(response => response.json()).then(json => {
125
- const newOverrideState = { ...overrideState(),
115
+ const newOverrideState = {
116
+ ...overrideState(),
126
117
  [key]: json
127
118
  };
128
119
  setOverrideState(newOverrideState);
@@ -130,7 +121,6 @@ function RenderContent(props) {
130
121
  console.log("error fetching dynamic data", url, err);
131
122
  });
132
123
  }
133
-
134
124
  function runHttpRequests() {
135
125
  const requests = useContent?.data?.httpRequests ?? {};
136
126
  Object.entries(requests).forEach(([key, url]) => {
@@ -143,7 +133,6 @@ function RenderContent(props) {
143
133
  }
144
134
  });
145
135
  }
146
-
147
136
  function emitStateUpdate() {
148
137
  if (isEditing()) {
149
138
  window.dispatchEvent(new CustomEvent("builder:component:stateChange", {
@@ -156,34 +145,31 @@ function RenderContent(props) {
156
145
  }));
157
146
  }
158
147
  }
159
-
160
148
  function shouldRenderContentStyles() {
161
149
  return Boolean((useContent?.data?.cssCode || useContent?.data?.customFonts?.length) && TARGET !== "reactNative");
162
150
  }
163
-
164
151
  const updateUseContent = function useContent() {
165
152
  if (!props.content && !overrideContent()) {
166
153
  return undefined;
167
154
  }
168
-
169
- const mergedContent = { ...props.content,
155
+ const mergedContent = {
156
+ ...props.content,
170
157
  ...overrideContent(),
171
- data: { ...props.content?.data,
158
+ data: {
159
+ ...props.content?.data,
172
160
  ...props.data,
173
161
  ...overrideContent()?.data
174
162
  }
175
163
  };
176
164
  return mergedContent;
177
165
  };
178
-
179
166
  const [useContent, setUseContent] = createStore(updateUseContent());
180
167
  createEffect(on(() => [overrideContent(), props.content, props.data], () => setUseContent(reconcile(updateUseContent()))));
181
168
  let elementRef;
182
169
  onMount(() => {
183
170
  if (isBrowser()) {
184
171
  if (isEditing()) {
185
- setForceReRenderCount(forceReRenderCount() + 1); // QWIK-REPLACE: _useMutableProps
186
-
172
+ setForceReRenderCount(forceReRenderCount() + 1);
187
173
  registerInsertMenu();
188
174
  setupBrowserForEditing();
189
175
  Object.values(allRegisteredComponents()).forEach(registeredComponent => {
@@ -193,23 +179,23 @@ function RenderContent(props) {
193
179
  window.addEventListener("message", processMessage);
194
180
  window.addEventListener("builder:component:stateChangeListenerActivated", emitStateUpdate);
195
181
  }
196
-
197
182
  if (useContent) {
198
- track({
183
+ const variationId = useContent?.testVariationId;
184
+ const contentId = useContent?.id;
185
+ _track({
199
186
  type: "impression",
200
187
  canTrack: canTrackToUse(),
201
- contentId: useContent?.id,
202
- orgId: props.apiKey
188
+ contentId,
189
+ apiKey: props.apiKey,
190
+ variationId: variationId !== contentId ? variationId : undefined
203
191
  });
204
- } // override normal content in preview mode
205
-
192
+ }
206
193
 
194
+ // override normal content in preview mode
207
195
  if (isPreviewing()) {
208
196
  const searchParams = new URL(location.href).searchParams;
209
-
210
197
  if (props.model && searchParams.get("builder.preview") === props.model) {
211
198
  const previewApiKey = searchParams.get("apiKey") || searchParams.get("builder.space");
212
-
213
199
  if (previewApiKey) {
214
200
  getContent({
215
201
  model: props.model,
@@ -222,61 +208,48 @@ function RenderContent(props) {
222
208
  }
223
209
  }
224
210
  }
225
-
226
211
  evaluateJsCode();
227
212
  runHttpRequests();
228
213
  emitStateUpdate();
229
214
  }
230
215
  });
231
-
232
216
  function onUpdateFn_0() {
233
217
  evaluateJsCode();
234
218
  }
235
-
236
219
  createEffect(on(() => [useContent?.data?.jsCode], onUpdateFn_0));
237
-
238
220
  function onUpdateFn_1() {
239
221
  runHttpRequests();
240
222
  }
241
-
242
223
  createEffect(on(() => [useContent?.data?.httpRequests], onUpdateFn_1));
243
-
244
224
  function onUpdateFn_2() {
245
225
  emitStateUpdate();
246
226
  }
247
-
248
227
  createEffect(on(() => [contentState()], onUpdateFn_2));
249
228
  return <Dynamic value={{
250
229
  get content() {
251
230
  return useContent;
252
231
  },
253
-
254
232
  get state() {
255
233
  return contentState();
256
234
  },
257
-
258
235
  get context() {
259
236
  return contextContext();
260
237
  },
261
-
262
238
  get apiKey() {
263
239
  return props.apiKey;
264
240
  },
265
-
266
241
  get registeredComponents() {
267
242
  return allRegisteredComponents();
268
243
  }
269
-
270
244
  }} component={BuilderContext.Provider}>
271
245
  <Show when={useContent}>
272
246
  <div ref={elementRef} onClick={event => onClick(event)} builder-content-id={useContent?.id} builder-model={props.model}>
273
247
  <Show when={shouldRenderContentStyles()}>
274
248
  <RenderContentStyles cssCode={useContent?.data?.cssCode} customFonts={useContent?.data?.customFonts}></RenderContentStyles>
275
249
  </Show>
276
- <RenderBlocks blocks={markMutable(useContent?.data?.blocks)} key={forceReRenderCount()}></RenderBlocks>
250
+ <RenderBlocks blocks={useContent?.data?.blocks} key={forceReRenderCount()}></RenderBlocks>
277
251
  </div>
278
252
  </Show>
279
253
  </Dynamic>;
280
254
  }
281
-
282
255
  export default RenderContent;
@@ -1,21 +1,17 @@
1
1
  import { Show } from "solid-js";
2
2
  import { Dynamic } from "solid-js/web";
3
3
  import { TARGET } from "../constants/target.js";
4
-
5
4
  function RenderInlinedStyles(props) {
6
5
  function injectedStyleScript() {
7
- return `<${tagName()}>${props.styles}</${tagName()}>`;
6
+ return `<${tag()}>${props.styles}</${tag()}>`;
8
7
  }
9
-
10
- function tagName() {
8
+ function tag() {
11
9
  // NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
12
10
  // https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
13
11
  return "sty" + "le";
14
12
  }
15
-
16
- return <Show fallback={<Dynamic component={tagName()}>{props.styles}</Dynamic>} when={TARGET === "svelte"}>
13
+ return <Show fallback={<Dynamic component={tag()}>{props.styles}</Dynamic>} when={TARGET === "svelte"}>
17
14
  <div innerHTML={injectedStyleScript()}></div>
18
15
  </Show>;
19
16
  }
20
-
21
17
  export default RenderInlinedStyles;
@@ -1,3 +1,4 @@
1
+ import { fastClone } from "../functions/fast-clone";
1
2
  const SIZES = {
2
3
  small: {
3
4
  min: 320,
@@ -15,7 +16,33 @@ const SIZES = {
15
16
  max: 1200
16
17
  }
17
18
  };
18
- const getMaxWidthQueryForSize = (size) => `@media (max-width: ${SIZES[size].max}px)`;
19
+ const getMaxWidthQueryForSize = (size, sizeValues = SIZES) => `@media (max-width: ${sizeValues[size].max}px)`;
20
+ const getSizesForBreakpoints = ({ small, medium }) => {
21
+ const newSizes = fastClone(SIZES);
22
+ if (!small || !medium) {
23
+ return newSizes;
24
+ }
25
+ const smallMin = Math.floor(small / 2);
26
+ newSizes.small = {
27
+ max: small,
28
+ min: smallMin,
29
+ default: smallMin + 1
30
+ };
31
+ const mediumMin = newSizes.small.max + 1;
32
+ newSizes.medium = {
33
+ max: medium,
34
+ min: mediumMin,
35
+ default: mediumMin + 1
36
+ };
37
+ const largeMin = newSizes.medium.max + 1;
38
+ newSizes.large = {
39
+ max: 2e3,
40
+ min: largeMin,
41
+ default: largeMin + 1
42
+ };
43
+ return newSizes;
44
+ };
19
45
  export {
20
- getMaxWidthQueryForSize
46
+ getMaxWidthQueryForSize,
47
+ getSizesForBreakpoints
21
48
  };
@@ -56,9 +56,13 @@ const generateContentUrl = (options) => {
56
56
  query,
57
57
  noTraverse = false,
58
58
  model,
59
- apiKey
59
+ apiKey,
60
+ includeRefs = true
60
61
  } = options;
61
- const url = new URL(`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}`);
62
+ if (!apiKey) {
63
+ throw new Error("Missing API key");
64
+ }
65
+ const url = new URL(`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}`);
62
66
  const queryOptions = __spreadValues(__spreadValues({}, getBuilderSearchParamsFromWindow()), normalizeSearchParams(options.options || {}));
63
67
  const flattened = flatten(queryOptions);
64
68
  for (const key in flattened) {
@@ -29,6 +29,7 @@ var __objRest = (source, exclude) => {
29
29
  }
30
30
  return target;
31
31
  };
32
+ import { serializeFn } from "../blocks/util.js";
32
33
  import { fastClone } from "./fast-clone.js";
33
34
  const components = [];
34
35
  function registerComponent(component, info) {
@@ -48,11 +49,6 @@ const createRegisterComponentMessage = (_a) => {
48
49
  };
49
50
  };
50
51
  const serializeValue = (value) => typeof value === "function" ? serializeFn(value) : fastClone(value);
51
- const serializeFn = (fnValue) => {
52
- const fnStr = fnValue.toString().trim();
53
- const appendFunction = !fnStr.startsWith("function") && !fnStr.startsWith("(");
54
- return `return (${appendFunction ? "function " : ""}${fnStr}).apply(this, arguments)`;
55
- };
56
52
  const prepareComponentInfoToSend = (_c) => {
57
53
  var _d = _c, {
58
54
  inputs
@@ -71,23 +71,24 @@ const createEvent = (_a) => __async(void 0, null, function* () {
71
71
  var _b = _a, {
72
72
  type: eventType,
73
73
  canTrack,
74
- orgId,
75
- contentId
74
+ apiKey,
75
+ metadata
76
76
  } = _b, properties = __objRest(_b, [
77
77
  "type",
78
78
  "canTrack",
79
- "orgId",
80
- "contentId"
79
+ "apiKey",
80
+ "metadata"
81
81
  ]);
82
82
  return {
83
83
  type: eventType,
84
- data: __spreadProps(__spreadValues(__spreadValues({}, properties), yield getTrackingEventData({ canTrack })), {
85
- ownerId: orgId,
86
- contentId
84
+ data: __spreadProps(__spreadValues(__spreadProps(__spreadValues({}, properties), {
85
+ metadata: JSON.stringify(metadata)
86
+ }), yield getTrackingEventData({ canTrack })), {
87
+ ownerId: apiKey
87
88
  })
88
89
  };
89
90
  });
90
- function track(eventProps) {
91
+ function _track(eventProps) {
91
92
  return __async(this, null, function* () {
92
93
  if (!eventProps.canTrack) {
93
94
  return;
@@ -112,6 +113,8 @@ function track(eventProps) {
112
113
  });
113
114
  });
114
115
  }
116
+ const track = (args) => _track(__spreadProps(__spreadValues({}, args), { canTrack: true }));
115
117
  export {
118
+ _track,
116
119
  track
117
120
  };
package/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import "./index-helpers/top-of-file.js";
1
+ export * from "./index-helpers/top-of-file.js";
2
2
  import "./scripts/init-editing.js";
3
3
  export * from "./index-helpers/blocks-exports.js";
4
4
  export * from "./functions/is-editing.js";
@@ -8,3 +8,7 @@ export * from "./functions/register.js";
8
8
  export * from "./functions/set-editor-settings.js";
9
9
  export * from "./functions/get-content/index.js";
10
10
  export * from "./functions/get-builder-search-params/index.js";
11
+ import { track } from "./functions/track";
12
+ export {
13
+ track
14
+ };
@@ -19,15 +19,21 @@ const registerInsertMenu = () => {
19
19
  ]
20
20
  });
21
21
  };
22
+ let isSetupForEditing = false;
22
23
  const setupBrowserForEditing = () => {
23
24
  var _a;
25
+ if (isSetupForEditing) {
26
+ return;
27
+ }
28
+ isSetupForEditing = true;
24
29
  if (isBrowser()) {
25
30
  (_a = window.parent) == null ? void 0 : _a.postMessage({
26
31
  type: "builder.sdkInfo",
27
32
  data: {
28
33
  target: TARGET,
29
34
  supportsPatchUpdates: false,
30
- supportsAddBlockScoping: true
35
+ supportsAddBlockScoping: true,
36
+ supportsCustomBreakpoints: true
31
37
  }
32
38
  }, "*");
33
39
  window.addEventListener("message", ({ data }) => {