@builder.io/sdk-solid 0.0.8-23 → 0.0.8-24

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.
@@ -1,6 +1,5 @@
1
- import { Show, onMount, on, createEffect } from "solid-js";
1
+ import { Show, onMount, on, createEffect, createSignal } from "solid-js";
2
2
  import { Dynamic } from "solid-js/web";
3
- import { createMutable } from "solid-js/store";
4
3
  import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
5
4
  import { TARGET } from "../../constants/target.js";
6
5
  import BuilderContext from "../../context/builder.context";
@@ -14,182 +13,186 @@ import { components, createRegisterComponentMessage } from "../../functions/regi
14
13
  import { track } from "../../functions/track.js";
15
14
  import RenderBlocks from "../render-blocks.jsx";
16
15
  import RenderContentStyles from "./components/render-styles.jsx";
16
+ import { registerInsertMenu, setupBrowserForEditing } from "../../scripts/init-editing.js";
17
17
 
18
18
  function RenderContent(props) {
19
- const state = createMutable({
20
- get useContent() {
21
- const mergedContent = { ...props.content,
22
- ...state.overrideContent,
23
- data: { ...props.content?.data,
24
- ...props.data,
25
- ...state.overrideContent?.data
26
- }
27
- };
28
- return mergedContent;
29
- },
30
-
31
- overrideContent: null,
32
- update: 0,
33
-
34
- get canTrackToUse() {
35
- return props.canTrack || true;
36
- },
37
-
38
- overrideState: {},
39
-
40
- get contentState() {
41
- return { ...props.content?.data?.state,
19
+ const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
20
+ const [overrideContent, setOverrideContent] = createSignal(null);
21
+ const [update, setUpdate] = createSignal(0);
22
+ const [overrideState, setOverrideState] = createSignal({});
23
+
24
+ function useContent() {
25
+ const mergedContent = { ...props.content,
26
+ ...overrideContent(),
27
+ data: { ...props.content?.data,
42
28
  ...props.data,
43
- ...state.overrideState
44
- };
45
- },
29
+ ...overrideContent()?.data
30
+ }
31
+ };
32
+ return mergedContent;
33
+ }
46
34
 
47
- get contextContext() {
48
- return props.context || {};
49
- },
35
+ function canTrackToUse() {
36
+ return props.canTrack || true;
37
+ }
50
38
 
51
- get allRegisteredComponents() {
52
- const allComponentsArray = [...getDefaultRegisteredComponents(), // While this `components` object is deprecated, we must maintain support for it.
53
- // Since users are able to override our default components, we need to make sure that we do not break such
54
- // existing usage.
55
- // This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
56
- // which is the new standard way of providing custom components, and must therefore take precedence.
57
- ...components, ...(props.customComponents || [])];
58
- const allComponents = allComponentsArray.reduce((acc, curr) => ({ ...acc,
59
- [curr.name]: curr
60
- }), {});
61
- return allComponents;
62
- },
39
+ function contentState() {
40
+ return { ...props.content?.data?.state,
41
+ ...props.data,
42
+ ...overrideState()
43
+ };
44
+ }
63
45
 
64
- processMessage(event) {
65
- const {
66
- data
67
- } = event;
68
-
69
- if (data) {
70
- switch (data.type) {
71
- case "builder.contentUpdate":
72
- {
73
- const messageContent = data.data;
74
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
75
- const contentData = messageContent.data;
76
-
77
- if (key === props.model) {
78
- state.overrideContent = contentData;
79
- }
46
+ function contextContext() {
47
+ return props.context || {};
48
+ }
80
49
 
81
- break;
82
- }
50
+ function allRegisteredComponents() {
51
+ const allComponentsArray = [...getDefaultRegisteredComponents(), // While this `components` object is deprecated, we must maintain support for it.
52
+ // Since users are able to override our default components, we need to make sure that we do not break such
53
+ // existing usage.
54
+ // This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
55
+ // which is the new standard way of providing custom components, and must therefore take precedence.
56
+ ...components, ...(props.customComponents || [])];
57
+ const allComponents = allComponentsArray.reduce((acc, curr) => ({ ...acc,
58
+ [curr.name]: curr
59
+ }), {});
60
+ return allComponents;
61
+ }
83
62
 
84
- case "builder.patchUpdates":
85
- {
86
- // TODO
87
- break;
63
+ function processMessage(event) {
64
+ const {
65
+ data
66
+ } = event;
67
+
68
+ if (data) {
69
+ switch (data.type) {
70
+ case "builder.contentUpdate":
71
+ {
72
+ const messageContent = data.data;
73
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
74
+ const contentData = messageContent.data;
75
+
76
+ if (key === props.model) {
77
+ setOverrideContent(contentData);
88
78
  }
89
- }
90
- }
91
- },
92
79
 
93
- evaluateJsCode() {
94
- // run any dynamic JS code attached to content
95
- const jsCode = state.useContent?.data?.jsCode;
80
+ break;
81
+ }
96
82
 
97
- if (jsCode) {
98
- evaluate({
99
- code: jsCode,
100
- context: state.contextContext,
101
- state: state.contentState
102
- });
83
+ case "builder.patchUpdates":
84
+ {
85
+ // TODO
86
+ break;
87
+ }
103
88
  }
104
- },
89
+ }
90
+ }
105
91
 
106
- get httpReqsData() {
107
- return {};
108
- },
92
+ function evaluateJsCode() {
93
+ // run any dynamic JS code attached to content
94
+ const jsCode = useContent()?.data?.jsCode;
109
95
 
110
- onClick(_event) {
111
- if (state.useContent) {
112
- track({
113
- type: "click",
114
- canTrack: state.canTrackToUse,
115
- contentId: state.useContent.id,
116
- orgId: props.apiKey
117
- });
118
- }
119
- },
96
+ if (jsCode) {
97
+ evaluate({
98
+ code: jsCode,
99
+ context: contextContext(),
100
+ state: contentState()
101
+ });
102
+ }
103
+ }
120
104
 
121
- evalExpression(expression) {
122
- return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
123
- code: group,
124
- context: state.contextContext,
125
- state: state.contentState
126
- }));
127
- },
105
+ function httpReqsData() {
106
+ return {};
107
+ }
128
108
 
129
- handleRequest({
130
- url,
131
- key
132
- }) {
133
- const fetchAndSetState = async () => {
134
- const fetch = await getFetch();
135
- const response = await fetch(url);
136
- const json = await response.json();
137
- const newOverrideState = { ...state.overrideState,
138
- [key]: json
139
- };
140
- state.overrideState = newOverrideState;
141
- };
109
+ function onClick(_event) {
110
+ if (useContent()) {
111
+ track({
112
+ type: "click",
113
+ canTrack: canTrackToUse(),
114
+ contentId: useContent().id,
115
+ orgId: props.apiKey
116
+ });
117
+ }
118
+ }
142
119
 
143
- fetchAndSetState();
144
- },
120
+ function evalExpression(expression) {
121
+ return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
122
+ code: group,
123
+ context: contextContext(),
124
+ state: contentState()
125
+ }));
126
+ }
145
127
 
146
- runHttpRequests() {
147
- const requests = state.useContent?.data?.httpRequests ?? {};
148
- Object.entries(requests).forEach(([key, url]) => {
149
- if (url && (!state.httpReqsData[key] || isEditing())) {
150
- const evaluatedUrl = state.evalExpression(url);
151
- state.handleRequest({
152
- url: evaluatedUrl,
153
- key
154
- });
155
- }
156
- });
157
- },
128
+ function handleRequest({
129
+ url,
130
+ key
131
+ }) {
132
+ const fetchAndSetState = async () => {
133
+ const fetch = await getFetch();
134
+ const response = await fetch(url);
135
+ const json = await response.json();
136
+ const newOverrideState = { ...overrideState(),
137
+ [key]: json
138
+ };
139
+ setOverrideState(newOverrideState);
140
+ };
158
141
 
159
- emitStateUpdate() {
160
- if (isEditing()) {
161
- window.dispatchEvent(new CustomEvent("builder:component:stateChange", {
162
- detail: {
163
- state: state.contentState,
164
- ref: {
165
- name: props.model
166
- }
167
- }
168
- }));
142
+ fetchAndSetState();
143
+ }
144
+
145
+ function runHttpRequests() {
146
+ const requests = useContent()?.data?.httpRequests ?? {};
147
+ Object.entries(requests).forEach(([key, url]) => {
148
+ if (url && (!httpReqsData()[key] || isEditing())) {
149
+ const evaluatedUrl = evalExpression(url);
150
+ handleRequest({
151
+ url: evaluatedUrl,
152
+ key
153
+ });
169
154
  }
170
- },
155
+ });
156
+ }
171
157
 
172
- get shouldRenderContentStyles() {
173
- return Boolean((state.useContent?.data?.cssCode || state.useContent?.data?.customFonts?.length) && TARGET !== "reactNative");
158
+ function emitStateUpdate() {
159
+ if (isEditing()) {
160
+ window.dispatchEvent(new CustomEvent("builder:component:stateChange", {
161
+ detail: {
162
+ state: contentState(),
163
+ ref: {
164
+ name: props.model
165
+ }
166
+ }
167
+ }));
174
168
  }
169
+ }
175
170
 
176
- });
171
+ function shouldRenderContentStyles() {
172
+ return Boolean((useContent()?.data?.cssCode || useContent()?.data?.customFonts?.length) && TARGET !== "reactNative");
173
+ }
174
+
175
+ let elementRef;
177
176
  onMount(() => {
178
177
  if (isBrowser()) {
179
178
  if (isEditing()) {
180
- Object.values(state.allRegisteredComponents).forEach(registeredComponent => {
179
+ setForceReRenderCount(forceReRenderCount() + 1); // QWIK-REPLACE: _useMutableProps
180
+
181
+ registerInsertMenu();
182
+ setupBrowserForEditing();
183
+ Object.values(allRegisteredComponents()).forEach(registeredComponent => {
181
184
  const message = createRegisterComponentMessage(registeredComponent);
182
185
  window.parent?.postMessage(message, "*");
183
186
  });
184
- window.addEventListener("message", state.processMessage);
185
- window.addEventListener("builder:component:stateChangeListenerActivated", state.emitStateUpdate);
187
+ window.addEventListener("message", processMessage);
188
+ window.addEventListener("builder:component:stateChangeListenerActivated", emitStateUpdate);
186
189
  }
187
190
 
188
- if (state.useContent) {
191
+ if (useContent()) {
189
192
  track({
190
193
  type: "impression",
191
- canTrack: state.canTrackToUse,
192
- contentId: state.useContent.id,
194
+ canTrack: canTrackToUse(),
195
+ contentId: useContent().id,
193
196
  orgId: props.apiKey
194
197
  });
195
198
  } // override normal content in preview mode
@@ -207,47 +210,47 @@ function RenderContent(props) {
207
210
  apiKey: previewApiKey
208
211
  }).then(content => {
209
212
  if (content) {
210
- state.overrideContent = content;
213
+ setOverrideContent(content);
211
214
  }
212
215
  });
213
216
  }
214
217
  }
215
218
  }
216
219
 
217
- state.evaluateJsCode();
218
- state.runHttpRequests();
219
- state.emitStateUpdate();
220
+ evaluateJsCode();
221
+ runHttpRequests();
222
+ emitStateUpdate();
220
223
  }
221
224
  });
222
225
 
223
226
  function onUpdateFn_0() {
224
- state.evaluateJsCode();
227
+ evaluateJsCode();
225
228
  }
226
229
 
227
- createEffect(on(() => [state.useContent?.data?.jsCode], onUpdateFn_0));
230
+ createEffect(on(() => [useContent()?.data?.jsCode], onUpdateFn_0));
228
231
 
229
232
  function onUpdateFn_1() {
230
- state.runHttpRequests();
233
+ runHttpRequests();
231
234
  }
232
235
 
233
- createEffect(on(() => [state.useContent?.data?.httpRequests], onUpdateFn_1));
236
+ createEffect(on(() => [useContent()?.data?.httpRequests], onUpdateFn_1));
234
237
 
235
238
  function onUpdateFn_2() {
236
- state.emitStateUpdate();
239
+ emitStateUpdate();
237
240
  }
238
241
 
239
- createEffect(on(() => [state.contentState], onUpdateFn_2));
242
+ createEffect(on(() => [contentState()], onUpdateFn_2));
240
243
  return <Dynamic value={{
241
244
  get content() {
242
- return state.useContent;
245
+ return useContent();
243
246
  },
244
247
 
245
248
  get state() {
246
- return state.contentState;
249
+ return contentState();
247
250
  },
248
251
 
249
252
  get context() {
250
- return state.contextContext;
253
+ return contextContext();
251
254
  },
252
255
 
253
256
  get apiKey() {
@@ -255,16 +258,16 @@ function RenderContent(props) {
255
258
  },
256
259
 
257
260
  get registeredComponents() {
258
- return state.allRegisteredComponents;
261
+ return allRegisteredComponents();
259
262
  }
260
263
 
261
264
  }} component={BuilderContext.Provider}>
262
- <Show when={state.useContent}>
263
- <div onClick={event => state.onClick(event)} builder-content-id={state.useContent?.id}>
264
- <Show when={state.shouldRenderContentStyles}>
265
- <RenderContentStyles cssCode={state.useContent?.data?.cssCode} customFonts={state.useContent?.data?.customFonts}></RenderContentStyles>
265
+ <Show when={useContent()}>
266
+ <div ref={elementRef} onClick={event => onClick(event)} builder-content-id={useContent()?.id}>
267
+ <Show when={shouldRenderContentStyles()}>
268
+ <RenderContentStyles cssCode={useContent()?.data?.cssCode} customFonts={useContent()?.data?.customFonts}></RenderContentStyles>
266
269
  </Show>
267
- <RenderBlocks blocks={state.useContent?.data?.blocks}></RenderBlocks>
270
+ <RenderBlocks blocks={useContent()?.data?.blocks} key={forceReRenderCount()}></RenderBlocks>
268
271
  </div>
269
272
  </Show>
270
273
  </Dynamic>;
@@ -1,23 +1,20 @@
1
1
  import { Show } from "solid-js";
2
2
  import { Dynamic } from "solid-js/web";
3
- import { createMutable } from "solid-js/store";
4
3
  import { TARGET } from "../constants/target.js";
5
4
 
6
5
  function RenderInlinedStyles(props) {
7
- const state = createMutable({
8
- get injectedStyleScript() {
9
- return `<${state.tagName}>${props.styles}</${state.tagName}>`;
10
- },
6
+ function injectedStyleScript() {
7
+ return `<${tagName()}>${props.styles}</${tagName()}>`;
8
+ }
11
9
 
12
- get tagName() {
13
- // NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
14
- // https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
15
- return "sty" + "le";
16
- }
10
+ function tagName() {
11
+ // NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
12
+ // https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
13
+ return "sty" + "le";
14
+ }
17
15
 
18
- });
19
- return <Show fallback={<Dynamic component={state.tagName}>{props.styles}</Dynamic>} when={TARGET === "svelte"}>
20
- <div innerHTML={state.injectedStyleScript}></div>
16
+ return <Show fallback={<Dynamic component={tagName()}>{props.styles}</Dynamic>} when={TARGET === "svelte"}>
17
+ <div innerHTML={injectedStyleScript()}></div>
21
18
  </Show>;
22
19
  }
23
20
 
@@ -32,9 +32,12 @@ import { componentInfo as videoComponentInfo } from "../blocks/video/component-i
32
32
  import { default as Video } from "../blocks/video/video.jsx";
33
33
  import { componentInfo as embedComponentInfo } from "../blocks/embed/component-info";
34
34
  import { default as embed } from "../blocks/embed/embed.jsx";
35
+ import { default as Img } from "../blocks/img/img.jsx";
36
+ import { componentInfo as imgComponentInfo } from "../blocks/img/component-info";
35
37
  const getDefaultRegisteredComponents = () => [
36
38
  __spreadValues({ component: Columns }, columnsComponentInfo),
37
39
  __spreadValues({ component: Image }, imageComponentInfo),
40
+ __spreadValues({ component: Img }, imgComponentInfo),
38
41
  __spreadValues({ component: Text }, textComponentInfo),
39
42
  __spreadValues({ component: Video }, videoComponentInfo),
40
43
  __spreadValues({ component: Symbol }, symbolComponentInfo),
@@ -24,9 +24,9 @@ function getFetch() {
24
24
  const globalFetch = getGlobalThis().fetch;
25
25
  if (typeof globalFetch === "undefined" && typeof global !== "undefined") {
26
26
  const nodeFetch = import("node-fetch").then((d) => d.default);
27
- return nodeFetch;
27
+ return nodeFetch.default || nodeFetch;
28
28
  }
29
- return globalFetch;
29
+ return globalFetch.default || globalFetch;
30
30
  });
31
31
  }
32
32
  export {
@@ -39,13 +39,17 @@ const evaluateBindings = ({
39
39
  }
40
40
  return copied;
41
41
  };
42
- function getProcessedBlock(options) {
43
- const { state, context } = options;
44
- const block = transformBlock(options.block);
45
- if (evaluateBindings) {
46
- return evaluateBindings({ block, state, context });
42
+ function getProcessedBlock({
43
+ block,
44
+ context,
45
+ shouldEvaluateBindings,
46
+ state
47
+ }) {
48
+ const transformedBlock = transformBlock(block);
49
+ if (shouldEvaluateBindings) {
50
+ return evaluateBindings({ block: transformedBlock, state, context });
47
51
  } else {
48
- return block;
52
+ return transformedBlock;
49
53
  }
50
54
  }
51
55
  export {
@@ -21,7 +21,7 @@ test("Can process bindings", () => {
21
21
  block,
22
22
  context: {},
23
23
  state: { test: "hello" },
24
- evaluateBindings: true
24
+ shouldEvaluateBindings: true
25
25
  });
26
26
  expect(processed).not.toEqual(block);
27
27
  expect((_a = processed.properties) == null ? void 0 : _a.foo).toEqual("baz");
@@ -1,6 +1,5 @@
1
1
  import { TARGET } from "../constants/target.js";
2
2
  import { isBrowser } from "../functions/is-browser.js";
3
- import { isEditing } from "../functions/is-editing.js";
4
3
  import { register } from "../functions/register.js";
5
4
  const registerInsertMenu = () => {
6
5
  register("insertMenu", {
@@ -74,7 +73,7 @@ const setupBrowserForEditing = () => {
74
73
  });
75
74
  }
76
75
  };
77
- if (isEditing()) {
78
- registerInsertMenu();
79
- setupBrowserForEditing();
80
- }
76
+ export {
77
+ registerInsertMenu,
78
+ setupBrowserForEditing
79
+ };