@builder.io/sdk-react-native 0.2.0 → 0.2.2

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.
@@ -33,6 +33,7 @@ const render_content_1 = __importDefault(require("../../components/render-conten
33
33
  const builder_context_js_1 = __importDefault(require("../../context/builder.context.js"));
34
34
  const index_js_1 = require("../../functions/get-content/index.js");
35
35
  const target_1 = require("../../constants/target");
36
+ const logger_1 = require("../../helpers/logger");
36
37
  function Symbol(props) {
37
38
  var _a, _b, _c;
38
39
  const [className, setClassName] = (0, react_1.useState)(() => {
@@ -81,7 +82,7 @@ function Symbol(props) {
81
82
  }
82
83
  })
83
84
  .catch((err) => {
84
- console.error("[Builder.io]: Could not fetch symbol content: ", err);
85
+ logger_1.logger.error("Could not fetch symbol content: ", err);
85
86
  });
86
87
  }
87
88
  }
@@ -62,6 +62,9 @@ function BlockStyles(props) {
62
62
  const mediumStyles = styles === null || styles === void 0 ? void 0 : styles.medium;
63
63
  const smallStyles = styles === null || styles === void 0 ? void 0 : styles.small;
64
64
  const className = useBlock().id;
65
+ if (!className) {
66
+ return "";
67
+ }
65
68
  const largeStylesClass = largeStyles
66
69
  ? (0, css_js_1.createCssClass)({
67
70
  className,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEmptyHtmlElement = exports.getRepeatItemData = exports.getComponent = void 0;
3
+ exports.isEmptyHtmlElement = exports.getRepeatItemData = exports.getProxyState = exports.getComponent = void 0;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __defProps = Object.defineProperties;
6
6
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
@@ -107,3 +107,19 @@ const getRepeatItemData = ({ block, context }) => {
107
107
  return repeatArray;
108
108
  };
109
109
  exports.getRepeatItemData = getRepeatItemData;
110
+ const getProxyState = (context) => {
111
+ if (typeof Proxy === "undefined") {
112
+ console.error("no Proxy available in this environment, cannot proxy state.");
113
+ return context.state;
114
+ }
115
+ const useState = new Proxy(context.state, {
116
+ set: (obj, prop, value) => {
117
+ var _a;
118
+ obj[prop] = value;
119
+ (_a = context.setState) == null ? void 0 : _a.call(context, obj);
120
+ return true;
121
+ }
122
+ });
123
+ return useState;
124
+ };
125
+ exports.getProxyState = getProxyState;
@@ -32,7 +32,6 @@ const react_1 = require("react");
32
32
  const get_block_actions_js_1 = require("../../functions/get-block-actions.js");
33
33
  const get_block_component_options_js_1 = require("../../functions/get-block-component-options.js");
34
34
  const get_block_properties_js_1 = require("../../functions/get-block-properties.js");
35
- const get_block_tag_js_1 = require("../../functions/get-block-tag.js");
36
35
  const get_processed_block_js_1 = require("../../functions/get-processed-block.js");
37
36
  const block_styles_1 = __importDefault(require("./block-styles"));
38
37
  const render_block_helpers_js_1 = require("./render-block.helpers.js");
@@ -41,16 +40,16 @@ const target_js_1 = require("../../constants/target.js");
41
40
  const extract_text_styles_js_1 = require("../../functions/extract-text-styles.js");
42
41
  const render_component_1 = __importDefault(require("./render-component"));
43
42
  const get_react_native_block_styles_js_1 = require("../../functions/get-react-native-block-styles.js");
44
- const nullable_js_1 = require("../../helpers/nullable.js");
45
43
  function RenderBlock(props) {
46
44
  var _a, _b;
47
45
  const [component, setComponent] = (0, react_1.useState)(() => (0, render_block_helpers_js_1.getComponent)({
48
46
  block: props.block,
49
47
  context: props.context,
50
48
  }));
51
- function tag() {
52
- return (0, get_block_tag_js_1.getBlockTag)(useBlock());
53
- }
49
+ const [repeatItemData, setRepeatItemData] = (0, react_1.useState)(() => (0, render_block_helpers_js_1.getRepeatItemData)({
50
+ block: props.block,
51
+ context: props.context,
52
+ }));
54
53
  function useBlock() {
55
54
  return repeatItemData
56
55
  ? props.block
@@ -61,36 +60,21 @@ function RenderBlock(props) {
61
60
  shouldEvaluateBindings: true,
62
61
  });
63
62
  }
63
+ const [tag, setTag] = (0, react_1.useState)(() => props.block.tagName || "div");
64
64
  function canShowBlock() {
65
- if ((0, nullable_js_1.checkIsDefined)(useBlock().hide)) {
65
+ if ("hide" in useBlock()) {
66
66
  return !useBlock().hide;
67
67
  }
68
- if ((0, nullable_js_1.checkIsDefined)(useBlock().show)) {
68
+ if ("show" in useBlock()) {
69
69
  return useBlock().show;
70
70
  }
71
71
  return true;
72
72
  }
73
- function proxyState() {
74
- if (typeof Proxy === "undefined") {
75
- console.error("no Proxy available in this environment, cannot proxy state.");
76
- return props.context.state;
77
- }
78
- const useState = new Proxy(props.context.state, {
79
- set: (obj, prop, value) => {
80
- var _a, _b;
81
- // set the value on the state object, so that the event handler instantly gets the update.
82
- obj[prop] = value;
83
- // set the value in the context, so that the rest of the app gets the update.
84
- (_b = (_a = props.context).setState) === null || _b === void 0 ? void 0 : _b.call(_a, obj);
85
- return true;
86
- },
87
- });
88
- return useState;
89
- }
73
+ const [proxyState, setProxyState] = (0, react_1.useState)(() => (0, render_block_helpers_js_1.getProxyState)(props.context));
90
74
  function actions() {
91
75
  return (0, get_block_actions_js_1.getBlockActions)({
92
76
  block: useBlock(),
93
- state: proxyState(),
77
+ state: target_js_1.TARGET === "qwik" ? props.context.state : proxyState,
94
78
  context: props.context.context,
95
79
  });
96
80
  }
@@ -109,29 +93,6 @@ function RenderBlock(props) {
109
93
  : {}),
110
94
  };
111
95
  }
112
- function renderComponentProps() {
113
- var _a;
114
- return {
115
- blockChildren: (_a = useBlock().children) !== null && _a !== void 0 ? _a : [],
116
- componentRef: component === null || component === void 0 ? void 0 : component.component,
117
- componentOptions: {
118
- ...(0, get_block_component_options_js_1.getBlockComponentOptions)(useBlock()),
119
- /**
120
- * These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
121
- * they are provided to the component itself directly.
122
- */
123
- ...(!(component === null || component === void 0 ? void 0 : component.noWrap)
124
- ? {}
125
- : {
126
- attributes: {
127
- ...attributes(),
128
- ...actions(),
129
- },
130
- }),
131
- },
132
- context: childrenContext(),
133
- };
134
- }
135
96
  function childrenWithoutParentComponent() {
136
97
  var _a;
137
98
  /**
@@ -143,10 +104,6 @@ function RenderBlock(props) {
143
104
  const shouldRenderChildrenOutsideRef = !(component === null || component === void 0 ? void 0 : component.component) && !repeatItemData;
144
105
  return shouldRenderChildrenOutsideRef ? (_a = useBlock().children) !== null && _a !== void 0 ? _a : [] : [];
145
106
  }
146
- const [repeatItemData, setRepeatItemData] = (0, react_1.useState)(() => (0, render_block_helpers_js_1.getRepeatItemData)({
147
- block: props.block,
148
- context: props.context,
149
- }));
150
107
  function childrenContext() {
151
108
  const getInheritedTextStyles = () => {
152
109
  if (target_js_1.TARGET !== "reactNative") {
@@ -169,11 +126,34 @@ function RenderBlock(props) {
169
126
  inheritedStyles: getInheritedTextStyles(),
170
127
  };
171
128
  }
129
+ function renderComponentProps() {
130
+ var _a;
131
+ return {
132
+ blockChildren: (_a = useBlock().children) !== null && _a !== void 0 ? _a : [],
133
+ componentRef: component === null || component === void 0 ? void 0 : component.component,
134
+ componentOptions: {
135
+ ...(0, get_block_component_options_js_1.getBlockComponentOptions)(useBlock()),
136
+ /**
137
+ * These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
138
+ * they are provided to the component itself directly.
139
+ */
140
+ ...(!(component === null || component === void 0 ? void 0 : component.noWrap)
141
+ ? {}
142
+ : {
143
+ attributes: {
144
+ ...attributes(),
145
+ ...actions(),
146
+ },
147
+ }),
148
+ },
149
+ context: childrenContext(),
150
+ };
151
+ }
172
152
  return (React.createElement(React.Fragment, null, canShowBlock() ? (React.createElement(React.Fragment, null, !(component === null || component === void 0 ? void 0 : component.noWrap) ? (React.createElement(React.Fragment, null,
173
- (0, render_block_helpers_js_1.isEmptyHtmlElement)(tag()) ? (React.createElement(React.Fragment, null,
153
+ (0, render_block_helpers_js_1.isEmptyHtmlElement)(tag) ? (React.createElement(React.Fragment, null,
174
154
  React.createElement(react_native_1.View, { ...attributes(), ...actions() }))) : null,
175
- !(0, render_block_helpers_js_1.isEmptyHtmlElement)(tag()) && repeatItemData ? (React.createElement(React.Fragment, null, repeatItemData === null || repeatItemData === void 0 ? void 0 : repeatItemData.map((data, index) => (React.createElement(render_repeated_block_1.default, { key: index, repeatContext: data.context, block: data.block }))))) : null,
176
- !(0, render_block_helpers_js_1.isEmptyHtmlElement)(tag()) && !repeatItemData ? (React.createElement(React.Fragment, null,
155
+ !(0, render_block_helpers_js_1.isEmptyHtmlElement)(tag) && repeatItemData ? (React.createElement(React.Fragment, null, repeatItemData === null || repeatItemData === void 0 ? void 0 : repeatItemData.map((data, index) => (React.createElement(render_repeated_block_1.default, { key: index, repeatContext: data.context, block: data.block }))))) : null,
156
+ !(0, render_block_helpers_js_1.isEmptyHtmlElement)(tag) && !repeatItemData ? (React.createElement(React.Fragment, null,
177
157
  React.createElement(react_native_1.View, { ...attributes(), ...actions() },
178
158
  React.createElement(render_component_1.default, { ...renderComponentProps() }), (_a = childrenWithoutParentComponent()) === null || _a === void 0 ? void 0 :
179
159
  _a.map((child) => (React.createElement(RenderBlock, { key: "render-block-" + child.id, block: child, context: childrenContext() }))), (_b = childrenWithoutParentComponent()) === null || _b === void 0 ? void 0 :
@@ -46,6 +46,7 @@ const nullable_js_1 = require("../../helpers/nullable.js");
46
46
  const interaction_js_1 = require("../../functions/track/interaction.js");
47
47
  const render_content_helpers_js_1 = require("./render-content.helpers.js");
48
48
  const target_js_1 = require("../../constants/target.js");
49
+ const logger_js_1 = require("../../helpers/logger.js");
49
50
  function RenderContent(props) {
50
51
  var _a, _b, _c, _d, _e;
51
52
  const elementRef = (0, react_1.useRef)(null);
@@ -219,7 +220,7 @@ function RenderContent(props) {
219
220
  }
220
221
  (0, react_1.useEffect)(() => {
221
222
  if (!props.apiKey) {
222
- console.error("[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
223
+ logger_js_1.logger.error("No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
223
224
  }
224
225
  if ((0, is_browser_js_1.isBrowser)()) {
225
226
  if ((0, is_editing_js_1.isEditing)()) {
@@ -259,19 +260,19 @@ function RenderContent(props) {
259
260
  // override normal content in preview mode
260
261
  if ((0, is_previewing_js_1.isPreviewing)()) {
261
262
  const searchParams = new URL(location.href).searchParams;
262
- const searchParamPreview = searchParams.get("builder.preview");
263
+ const searchParamPreviewModel = searchParams.get("builder.preview");
264
+ const searchParamPreviewId = searchParams.get(`builder.preview.${searchParamPreviewModel}`);
263
265
  const previewApiKey = searchParams.get("apiKey") || searchParams.get("builder.space");
264
266
  /**
265
267
  * Make sure that:
266
268
  * - the preview model name is the same as the one we're rendering, since there can be multiple models rendered * at the same time, e.g. header/page/footer. * - the API key is the same, since we don't want to preview content from other organizations.
267
- *
268
- * TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
269
- * this break scenarios where the item is not published yet?
269
+ * - if there is content, that the preview ID is the same as that of the one we receive.
270
270
  *
271
271
  * TO-DO: should we only update the state when there is a change?
272
272
  **/
273
- if (searchParamPreview === props.model &&
274
- previewApiKey === props.apiKey) {
273
+ if (searchParamPreviewModel === props.model &&
274
+ previewApiKey === props.apiKey &&
275
+ (!props.content || searchParamPreviewId === props.content.id)) {
275
276
  (0, index_js_1.getContent)({
276
277
  model: props.model,
277
278
  apiKey: props.apiKey,
@@ -27,14 +27,14 @@ const React = __importStar(require("react"));
27
27
  const react_native_1 = require("react-native");
28
28
  const target_js_1 = require("../constants/target.js");
29
29
  function RenderInlinedStyles(props) {
30
- function injectedStyleScript() {
31
- return `<${tag()}>${props.styles}</${tag()}>`;
32
- }
33
30
  function tag() {
34
31
  // NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
35
32
  // https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
36
33
  return "sty" + "le";
37
34
  }
35
+ function injectedStyleScript() {
36
+ return `<${tag()}>${props.styles}</${tag()}>`;
37
+ }
38
38
  return (React.createElement(React.Fragment, null, target_js_1.TARGET === "svelte" || target_js_1.TARGET === "qwik" ? (React.createElement(React.Fragment, null,
39
39
  React.createElement(react_native_1.View, { dangerouslySetInnerHTML: { __html: props.styles } }))) : (React.createElement(react_native_1.View, null,
40
40
  React.createElement(react_native_1.Text, null, props.styles)))));
@@ -23,9 +23,12 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
23
  const target_js_1 = require("../constants/target.js");
24
24
  const css_js_1 = require("../helpers/css.js");
25
25
  const transform_block_properties_js_1 = require("./transform-block-properties.js");
26
+ const extractRelevantRootBlockProperties = (block) => {
27
+ return { href: block.href };
28
+ };
26
29
  function getBlockProperties(block) {
27
30
  var _a;
28
- const properties = __spreadProps(__spreadValues({}, block.properties), {
31
+ const properties = __spreadProps(__spreadValues(__spreadValues({}, extractRelevantRootBlockProperties(block)), block.properties), {
29
32
  "builder-id": block.id,
30
33
  style: getStyleAttribute(block.style),
31
34
  class: [block.id, "builder-block", block.class, (_a = block.properties) == null ? void 0 : _a.class].filter(Boolean).join(" ")
@@ -42,13 +42,14 @@ var __async = (__this, __arguments, generator) => {
42
42
  step((generator = generator.apply(__this, __arguments)).next());
43
43
  });
44
44
  };
45
+ const logger_js_1 = require("../../helpers/logger.js");
45
46
  const get_fetch_js_1 = require("../get-fetch.js");
46
47
  const ab_testing_js_1 = require("./ab-testing.js");
47
48
  const generate_content_url_js_1 = require("./generate-content-url.js");
48
49
  function getContent(options) {
49
50
  return __async(this, null, function* () {
50
51
  const allContent = yield getAllContent(__spreadProps(__spreadValues({}, options), { limit: 1 }));
51
- if ("results" in allContent) {
52
+ if (allContent && "results" in allContent) {
52
53
  return (allContent == null ? void 0 : allContent.results[0]) || null;
53
54
  }
54
55
  return null;
@@ -57,25 +58,31 @@ function getContent(options) {
57
58
  exports.getContent = getContent;
58
59
  function getAllContent(options) {
59
60
  return __async(this, null, function* () {
60
- const url = (0, generate_content_url_js_1.generateContentUrl)(options);
61
- const res = yield (0, get_fetch_js_1.fetch)(url.href);
62
- const content = yield res.json();
63
- if ("status" in content && !("results" in content)) {
64
- console.error("[Builder.io]: Error fetching data. ", content, options);
65
- return content;
66
- }
67
- const canTrack = options.canTrack !== false;
68
61
  try {
69
- if (canTrack && Array.isArray(content.results)) {
70
- for (const item of content.results) {
71
- yield (0, ab_testing_js_1.handleABTesting)({ item, canTrack });
62
+ const url = (0, generate_content_url_js_1.generateContentUrl)(options);
63
+ const res = yield (0, get_fetch_js_1.fetch)(url.href);
64
+ const content = yield res.json();
65
+ if ("status" in content && !("results" in content)) {
66
+ logger_js_1.logger.error("Error fetching data. ", content, options);
67
+ return content;
68
+ }
69
+ const canTrack = options.canTrack !== false;
70
+ try {
71
+ if (canTrack && Array.isArray(content.results)) {
72
+ for (const item of content.results) {
73
+ yield (0, ab_testing_js_1.handleABTesting)({ item, canTrack });
74
+ }
72
75
  }
73
76
  }
77
+ catch (e) {
78
+ logger_js_1.logger.error("Could not setup A/B testing. ", e);
79
+ }
80
+ return content;
74
81
  }
75
- catch (e) {
76
- console.error("[Builder.io]: Could not setup A/B testing. ", e);
82
+ catch (error) {
83
+ logger_js_1.logger.error("Error fetching data. ", error);
84
+ return null;
77
85
  }
78
- return content;
79
86
  });
80
87
  }
81
88
  exports.getAllContent = getAllContent;
@@ -55,6 +55,7 @@ var __async = (__this, __arguments, generator) => {
55
55
  });
56
56
  };
57
57
  const target_js_1 = require("../../constants/target.js");
58
+ const logger_js_1 = require("../../helpers/logger.js");
58
59
  const sessionId_js_1 = require("../../helpers/sessionId.js");
59
60
  const visitorId_js_1 = require("../../helpers/visitorId.js");
60
61
  const is_browser_js_1 = require("../is-browser.js");
@@ -93,7 +94,7 @@ const createEvent = (_a) => __async(void 0, null, function* () {
93
94
  function _track(eventProps) {
94
95
  return __async(this, null, function* () {
95
96
  if (!eventProps.apiKey) {
96
- console.error("[Builder.io]: Missing API key for track call. Please provide your API key.");
97
+ logger_js_1.logger.error("Missing API key for track call. Please provide your API key.");
97
98
  return;
98
99
  }
99
100
  if (!eventProps.canTrack) {
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = void 0;
4
+ const MSG_PREFIX = "[Builder.io]: ";
5
+ const logger = {
6
+ log: (...message) => console.log(MSG_PREFIX, ...message),
7
+ error: (...message) => console.error(MSG_PREFIX, ...message),
8
+ warn: (...message) => console.warn(MSG_PREFIX, ...message)
9
+ };
10
+ exports.logger = logger;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-react-native",
3
3
  "description": "Builder.io SDK for React Native",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -12,6 +12,7 @@ import RenderContent from "../../components/render-content/render-content";
12
12
  import BuilderContext from "../../context/builder.context.js";
13
13
  import { getContent } from "../../functions/get-content/index.js";
14
14
  import { TARGET } from "../../constants/target";
15
+ import { logger } from "../../helpers/logger";
15
16
 
16
17
  function Symbol(props) {
17
18
  const [className, setClassName] = useState(() =>
@@ -61,7 +62,7 @@ function Symbol(props) {
61
62
  }
62
63
  })
63
64
  .catch((err) => {
64
- console.error("[Builder.io]: Could not fetch symbol content: ", err);
65
+ logger.error("Could not fetch symbol content: ", err);
65
66
  });
66
67
  }
67
68
  }
@@ -48,6 +48,9 @@ function BlockStyles(props) {
48
48
  const mediumStyles = styles?.medium;
49
49
  const smallStyles = styles?.small;
50
50
  const className = useBlock().id;
51
+ if (!className) {
52
+ return "";
53
+ }
51
54
  const largeStylesClass = largeStyles
52
55
  ? createCssClass({
53
56
  className,
@@ -106,8 +106,24 @@ const getRepeatItemData = ({
106
106
  }));
107
107
  return repeatArray;
108
108
  };
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
+ };
109
124
  export {
110
125
  getComponent,
126
+ getProxyState,
111
127
  getRepeatItemData,
112
128
  isEmptyHtmlElement
113
129
  };
@@ -11,11 +11,11 @@ import { useState } from "react";
11
11
  import { getBlockActions } from "../../functions/get-block-actions.js";
12
12
  import { getBlockComponentOptions } from "../../functions/get-block-component-options.js";
13
13
  import { getBlockProperties } from "../../functions/get-block-properties.js";
14
- import { getBlockTag } from "../../functions/get-block-tag.js";
15
14
  import { getProcessedBlock } from "../../functions/get-processed-block.js";
16
15
  import BlockStyles from "./block-styles";
17
16
  import {
18
17
  getComponent,
18
+ getProxyState,
19
19
  getRepeatItemData,
20
20
  isEmptyHtmlElement,
21
21
  } from "./render-block.helpers.js";
@@ -24,7 +24,6 @@ import { TARGET } from "../../constants/target.js";
24
24
  import { extractTextStyles } from "../../functions/extract-text-styles.js";
25
25
  import RenderComponent from "./render-component";
26
26
  import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
27
- import { checkIsDefined } from "../../helpers/nullable.js";
28
27
 
29
28
  function RenderBlock(props) {
30
29
  const [component, setComponent] = useState(() =>
@@ -34,9 +33,12 @@ function RenderBlock(props) {
34
33
  })
35
34
  );
36
35
 
37
- function tag() {
38
- return getBlockTag(useBlock());
39
- }
36
+ const [repeatItemData, setRepeatItemData] = useState(() =>
37
+ getRepeatItemData({
38
+ block: props.block,
39
+ context: props.context,
40
+ })
41
+ );
40
42
 
41
43
  function useBlock() {
42
44
  return repeatItemData
@@ -49,40 +51,26 @@ function RenderBlock(props) {
49
51
  });
50
52
  }
51
53
 
54
+ const [tag, setTag] = useState(() => props.block.tagName || "div");
55
+
52
56
  function canShowBlock() {
53
- if (checkIsDefined(useBlock().hide)) {
57
+ if ("hide" in useBlock()) {
54
58
  return !useBlock().hide;
55
59
  }
56
- if (checkIsDefined(useBlock().show)) {
60
+ if ("show" in useBlock()) {
57
61
  return useBlock().show;
58
62
  }
59
63
  return true;
60
64
  }
61
65
 
62
- function proxyState() {
63
- if (typeof Proxy === "undefined") {
64
- console.error(
65
- "no Proxy available in this environment, cannot proxy state."
66
- );
67
- return props.context.state;
68
- }
69
- const useState = new Proxy(props.context.state, {
70
- set: (obj, prop, value) => {
71
- // set the value on the state object, so that the event handler instantly gets the update.
72
- obj[prop] = value;
73
-
74
- // set the value in the context, so that the rest of the app gets the update.
75
- props.context.setState?.(obj);
76
- return true;
77
- },
78
- });
79
- return useState;
80
- }
66
+ const [proxyState, setProxyState] = useState(() =>
67
+ getProxyState(props.context)
68
+ );
81
69
 
82
70
  function actions() {
83
71
  return getBlockActions({
84
72
  block: useBlock(),
85
- state: proxyState(),
73
+ state: TARGET === "qwik" ? props.context.state : proxyState,
86
74
  context: props.context.context,
87
75
  });
88
76
  }
@@ -103,29 +91,6 @@ function RenderBlock(props) {
103
91
  };
104
92
  }
105
93
 
106
- function renderComponentProps() {
107
- return {
108
- blockChildren: useBlock().children ?? [],
109
- componentRef: component?.component,
110
- componentOptions: {
111
- ...getBlockComponentOptions(useBlock()),
112
- /**
113
- * These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
114
- * they are provided to the component itself directly.
115
- */
116
- ...(!component?.noWrap
117
- ? {}
118
- : {
119
- attributes: {
120
- ...attributes(),
121
- ...actions(),
122
- },
123
- }),
124
- },
125
- context: childrenContext(),
126
- };
127
- }
128
-
129
94
  function childrenWithoutParentComponent() {
130
95
  /**
131
96
  * When there is no `componentRef`, there might still be children that need to be rendered. In this case,
@@ -138,13 +103,6 @@ function RenderBlock(props) {
138
103
  return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
139
104
  }
140
105
 
141
- const [repeatItemData, setRepeatItemData] = useState(() =>
142
- getRepeatItemData({
143
- block: props.block,
144
- context: props.context,
145
- })
146
- );
147
-
148
106
  function childrenContext() {
149
107
  const getInheritedTextStyles = () => {
150
108
  if (TARGET !== "reactNative") {
@@ -170,18 +128,41 @@ function RenderBlock(props) {
170
128
  };
171
129
  }
172
130
 
131
+ function renderComponentProps() {
132
+ return {
133
+ blockChildren: useBlock().children ?? [],
134
+ componentRef: component?.component,
135
+ componentOptions: {
136
+ ...getBlockComponentOptions(useBlock()),
137
+ /**
138
+ * These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
139
+ * they are provided to the component itself directly.
140
+ */
141
+ ...(!component?.noWrap
142
+ ? {}
143
+ : {
144
+ attributes: {
145
+ ...attributes(),
146
+ ...actions(),
147
+ },
148
+ }),
149
+ },
150
+ context: childrenContext(),
151
+ };
152
+ }
153
+
173
154
  return (
174
155
  <>
175
156
  {canShowBlock() ? (
176
157
  <>
177
158
  {!component?.noWrap ? (
178
159
  <>
179
- {isEmptyHtmlElement(tag()) ? (
160
+ {isEmptyHtmlElement(tag) ? (
180
161
  <>
181
162
  <View {...attributes()} {...actions()} />
182
163
  </>
183
164
  ) : null}
184
- {!isEmptyHtmlElement(tag()) && repeatItemData ? (
165
+ {!isEmptyHtmlElement(tag) && repeatItemData ? (
185
166
  <>
186
167
  {repeatItemData?.map((data, index) => (
187
168
  <RenderRepeatedBlock
@@ -192,7 +173,7 @@ function RenderBlock(props) {
192
173
  ))}
193
174
  </>
194
175
  ) : null}
195
- {!isEmptyHtmlElement(tag()) && !repeatItemData ? (
176
+ {!isEmptyHtmlElement(tag) && !repeatItemData ? (
196
177
  <>
197
178
  <View {...attributes()} {...actions()}>
198
179
  <RenderComponent {...renderComponentProps()} />
@@ -34,6 +34,7 @@ import {
34
34
  getContextStateInitialValue,
35
35
  } from "./render-content.helpers.js";
36
36
  import { TARGET } from "../../constants/target.js";
37
+ import { logger } from "../../helpers/logger.js";
37
38
 
38
39
  function RenderContent(props) {
39
40
  const elementRef = useRef(null);
@@ -241,8 +242,8 @@ function RenderContent(props) {
241
242
 
242
243
  useEffect(() => {
243
244
  if (!props.apiKey) {
244
- console.error(
245
- "[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
245
+ logger.error(
246
+ "No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
246
247
  );
247
248
  }
248
249
  if (isBrowser()) {
@@ -288,22 +289,24 @@ function RenderContent(props) {
288
289
  // override normal content in preview mode
289
290
  if (isPreviewing()) {
290
291
  const searchParams = new URL(location.href).searchParams;
291
- const searchParamPreview = searchParams.get("builder.preview");
292
+ const searchParamPreviewModel = searchParams.get("builder.preview");
293
+ const searchParamPreviewId = searchParams.get(
294
+ `builder.preview.${searchParamPreviewModel}`
295
+ );
292
296
  const previewApiKey =
293
297
  searchParams.get("apiKey") || searchParams.get("builder.space");
294
298
 
295
299
  /**
296
300
  * Make sure that:
297
301
  * - the preview model name is the same as the one we're rendering, since there can be multiple models rendered * at the same time, e.g. header/page/footer. * - the API key is the same, since we don't want to preview content from other organizations.
298
- *
299
- * TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
300
- * this break scenarios where the item is not published yet?
302
+ * - if there is content, that the preview ID is the same as that of the one we receive.
301
303
  *
302
304
  * TO-DO: should we only update the state when there is a change?
303
305
  **/
304
306
  if (
305
- searchParamPreview === props.model &&
306
- previewApiKey === props.apiKey
307
+ searchParamPreviewModel === props.model &&
308
+ previewApiKey === props.apiKey &&
309
+ (!props.content || searchParamPreviewId === props.content.id)
307
310
  ) {
308
311
  getContent({
309
312
  model: props.model,
@@ -10,16 +10,16 @@ import {
10
10
  import { TARGET } from "../constants/target.js";
11
11
 
12
12
  function RenderInlinedStyles(props) {
13
- function injectedStyleScript() {
14
- return `<${tag()}>${props.styles}</${tag()}>`;
15
- }
16
-
17
13
  function tag() {
18
14
  // NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
19
15
  // https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
20
16
  return "sty" + "le";
21
17
  }
22
18
 
19
+ function injectedStyleScript() {
20
+ return `<${tag()}>${props.styles}</${tag()}>`;
21
+ }
22
+
23
23
  return (
24
24
  <>
25
25
  {TARGET === "svelte" || TARGET === "qwik" ? (
@@ -20,9 +20,12 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
  import { TARGET } from "../constants/target.js";
21
21
  import { convertStyleMapToCSSArray } from "../helpers/css.js";
22
22
  import { transformBlockProperties } from "./transform-block-properties.js";
23
+ const extractRelevantRootBlockProperties = (block) => {
24
+ return { href: block.href };
25
+ };
23
26
  function getBlockProperties(block) {
24
27
  var _a;
25
- const properties = __spreadProps(__spreadValues({}, block.properties), {
28
+ const properties = __spreadProps(__spreadValues(__spreadValues({}, extractRelevantRootBlockProperties(block)), block.properties), {
26
29
  "builder-id": block.id,
27
30
  style: getStyleAttribute(block.style),
28
31
  class: [block.id, "builder-block", block.class, (_a = block.properties) == null ? void 0 : _a.class].filter(Boolean).join(" ")
@@ -37,13 +37,14 @@ var __async = (__this, __arguments, generator) => {
37
37
  step((generator = generator.apply(__this, __arguments)).next());
38
38
  });
39
39
  };
40
+ import { logger } from "../../helpers/logger.js";
40
41
  import { fetch } from "../get-fetch.js";
41
42
  import { handleABTesting } from "./ab-testing.js";
42
43
  import { generateContentUrl } from "./generate-content-url.js";
43
44
  function getContent(options) {
44
45
  return __async(this, null, function* () {
45
46
  const allContent = yield getAllContent(__spreadProps(__spreadValues({}, options), { limit: 1 }));
46
- if ("results" in allContent) {
47
+ if (allContent && "results" in allContent) {
47
48
  return (allContent == null ? void 0 : allContent.results[0]) || null;
48
49
  }
49
50
  return null;
@@ -51,24 +52,29 @@ function getContent(options) {
51
52
  }
52
53
  function getAllContent(options) {
53
54
  return __async(this, null, function* () {
54
- const url = generateContentUrl(options);
55
- const res = yield fetch(url.href);
56
- const content = yield res.json();
57
- if ("status" in content && !("results" in content)) {
58
- console.error("[Builder.io]: Error fetching data. ", content, options);
59
- return content;
60
- }
61
- const canTrack = options.canTrack !== false;
62
55
  try {
63
- if (canTrack && Array.isArray(content.results)) {
64
- for (const item of content.results) {
65
- yield handleABTesting({ item, canTrack });
56
+ const url = generateContentUrl(options);
57
+ const res = yield fetch(url.href);
58
+ const content = yield res.json();
59
+ if ("status" in content && !("results" in content)) {
60
+ logger.error("Error fetching data. ", content, options);
61
+ return content;
62
+ }
63
+ const canTrack = options.canTrack !== false;
64
+ try {
65
+ if (canTrack && Array.isArray(content.results)) {
66
+ for (const item of content.results) {
67
+ yield handleABTesting({ item, canTrack });
68
+ }
66
69
  }
70
+ } catch (e) {
71
+ logger.error("Could not setup A/B testing. ", e);
67
72
  }
68
- } catch (e) {
69
- console.error("[Builder.io]: Could not setup A/B testing. ", e);
73
+ return content;
74
+ } catch (error) {
75
+ logger.error("Error fetching data. ", error);
76
+ return null;
70
77
  }
71
- return content;
72
78
  });
73
79
  }
74
80
  export {
@@ -50,6 +50,7 @@ var __async = (__this, __arguments, generator) => {
50
50
  });
51
51
  };
52
52
  import { TARGET } from "../../constants/target.js";
53
+ import { logger } from "../../helpers/logger.js";
53
54
  import { getSessionId } from "../../helpers/sessionId.js";
54
55
  import { getVisitorId } from "../../helpers/visitorId.js";
55
56
  import { isBrowser } from "../is-browser.js";
@@ -95,7 +96,7 @@ const createEvent = (_a) => __async(void 0, null, function* () {
95
96
  function _track(eventProps) {
96
97
  return __async(this, null, function* () {
97
98
  if (!eventProps.apiKey) {
98
- console.error("[Builder.io]: Missing API key for track call. Please provide your API key.");
99
+ logger.error("Missing API key for track call. Please provide your API key.");
99
100
  return;
100
101
  }
101
102
  if (!eventProps.canTrack) {
@@ -0,0 +1,9 @@
1
+ const MSG_PREFIX = "[Builder.io]: ";
2
+ const logger = {
3
+ log: (...message) => console.log(MSG_PREFIX, ...message),
4
+ error: (...message) => console.error(MSG_PREFIX, ...message),
5
+ warn: (...message) => console.warn(MSG_PREFIX, ...message)
6
+ };
7
+ export {
8
+ logger
9
+ };
@@ -1,7 +0,0 @@
1
- import { View } from "react-native";
2
- function getBlockTag(_block) {
3
- return View;
4
- }
5
- export {
6
- getBlockTag
7
- };