@builder.io/sdk-svelte 2.0.8 → 2.0.13
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/README.md +1 -1
- package/lib/browser/blocks/slot/component-info.js +2 -1
- package/lib/browser/blocks/slot/slot.svelte +2 -0
- package/lib/browser/blocks/slot/slot.svelte.d.ts +3 -2
- package/lib/browser/components/block/block.helpers.d.ts +1 -2
- package/lib/browser/components/block/block.helpers.js +2 -10
- package/lib/browser/components/block/block.svelte +26 -11
- package/lib/browser/components/block/components/block-styles.svelte +2 -17
- package/lib/browser/components/blocks/blocks-wrapper.svelte +5 -1
- package/lib/browser/components/content/content.svelte +3 -3
- package/lib/browser/constants/sdk-version.d.ts +1 -1
- package/lib/browser/constants/sdk-version.js +1 -1
- package/lib/browser/functions/evaluate/evaluate.js +14 -1
- package/lib/browser/functions/evaluate/node-runtime/init.d.ts +1 -0
- package/lib/browser/functions/evaluate/node-runtime/init.js +1 -0
- package/lib/browser/functions/evaluate/node-runtime/node-runtime.js +2 -2
- package/lib/browser/functions/get-processed-block.d.ts +1 -0
- package/lib/browser/functions/get-processed-block.js +52 -10
- package/lib/browser/functions/register-component.d.ts +1 -1
- package/lib/browser/functions/register-component.js +2 -2
- package/lib/browser/functions/register.js +4 -0
- package/lib/edge/blocks/slot/component-info.js +2 -1
- package/lib/edge/blocks/slot/slot.svelte +2 -0
- package/lib/edge/blocks/slot/slot.svelte.d.ts +3 -2
- package/lib/edge/components/block/block.helpers.d.ts +1 -2
- package/lib/edge/components/block/block.helpers.js +2 -10
- package/lib/edge/components/block/block.svelte +26 -11
- package/lib/edge/components/block/components/block-styles.svelte +2 -17
- package/lib/edge/components/blocks/blocks-wrapper.svelte +5 -1
- package/lib/edge/components/content/content.svelte +3 -3
- package/lib/edge/constants/sdk-version.d.ts +1 -1
- package/lib/edge/constants/sdk-version.js +1 -1
- package/lib/edge/functions/evaluate/evaluate.js +14 -1
- package/lib/edge/functions/evaluate/node-runtime/init.d.ts +1 -0
- package/lib/edge/functions/evaluate/node-runtime/init.js +1 -0
- package/lib/edge/functions/evaluate/node-runtime/node-runtime.js +2 -2
- package/lib/edge/functions/get-processed-block.d.ts +1 -0
- package/lib/edge/functions/get-processed-block.js +52 -10
- package/lib/edge/functions/register-component.d.ts +1 -1
- package/lib/edge/functions/register-component.js +2 -2
- package/lib/edge/functions/register.js +4 -0
- package/lib/node/blocks/slot/component-info.js +2 -1
- package/lib/node/blocks/slot/slot.svelte +2 -0
- package/lib/node/blocks/slot/slot.svelte.d.ts +3 -2
- package/lib/node/components/block/block.helpers.d.ts +1 -2
- package/lib/node/components/block/block.helpers.js +2 -10
- package/lib/node/components/block/block.svelte +26 -11
- package/lib/node/components/block/components/block-styles.svelte +2 -17
- package/lib/node/components/blocks/blocks-wrapper.svelte +5 -1
- package/lib/node/components/content/content.svelte +3 -3
- package/lib/node/constants/sdk-version.d.ts +1 -1
- package/lib/node/constants/sdk-version.js +1 -1
- package/lib/node/functions/evaluate/evaluate.js +14 -1
- package/lib/node/functions/evaluate/node-runtime/init.d.ts +1 -0
- package/lib/node/functions/evaluate/node-runtime/init.js +1 -0
- package/lib/node/functions/evaluate/node-runtime/node-runtime.js +2 -2
- package/lib/node/functions/get-processed-block.d.ts +1 -0
- package/lib/node/functions/get-processed-block.js +52 -10
- package/lib/node/functions/register-component.d.ts +1 -1
- package/lib/node/functions/register-component.js +2 -2
- package/lib/node/functions/register.js +4 -0
- package/package.json +3 -3
- package/src/blocks/slot/component-info.ts +2 -1
- package/src/blocks/slot/slot.svelte +11 -5
- package/src/components/block/block.helpers.ts +1 -11
- package/src/components/block/block.svelte +28 -11
- package/src/components/block/components/block-styles.svelte +2 -17
- package/src/components/blocks/blocks-wrapper.svelte +7 -0
- package/src/components/content/content.svelte +3 -3
- package/src/constants/sdk-version.ts +1 -1
- package/src/functions/evaluate/evaluate.ts +15 -1
- package/src/functions/evaluate/node-runtime/init.ts +1 -0
- package/src/functions/evaluate/node-runtime/node-runtime.ts +2 -2
- package/src/functions/get-processed-block.ts +52 -10
- package/src/functions/register-component.ts +2 -2
- package/src/functions/register.ts +4 -0
|
@@ -1,21 +1,63 @@
|
|
|
1
|
+
import { TARGET } from '../constants/target';
|
|
2
|
+
import { omit } from '../helpers/omit';
|
|
1
3
|
import { evaluate } from './evaluate/index';
|
|
2
4
|
import { fastClone } from './fast-clone';
|
|
3
5
|
import { set } from './set';
|
|
4
6
|
import { transformBlock } from './transform-block';
|
|
7
|
+
// Deep clone a block but without cloning any child blocks
|
|
8
|
+
export function deepCloneWithConditions(obj) {
|
|
9
|
+
if (obj === null || typeof obj !== 'object') {
|
|
10
|
+
return obj;
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(obj)) {
|
|
13
|
+
return obj.map((item) => deepCloneWithConditions(item));
|
|
14
|
+
}
|
|
15
|
+
if (obj['@type'] === '@builder.io/sdk:Element') {
|
|
16
|
+
return obj;
|
|
17
|
+
}
|
|
18
|
+
const clonedObj = {};
|
|
19
|
+
for (const key in obj) {
|
|
20
|
+
if (key !== 'meta' && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
21
|
+
clonedObj[key] = deepCloneWithConditions(obj[key]);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return clonedObj;
|
|
25
|
+
}
|
|
26
|
+
const IS_SDK_WITHOUT_CACHED_PROCESSED_BLOCK = ['svelte', 'vue', 'angular', 'qwik', 'solid'].includes(TARGET);
|
|
27
|
+
const getCopy = (block) => {
|
|
28
|
+
if (IS_SDK_WITHOUT_CACHED_PROCESSED_BLOCK) {
|
|
29
|
+
const copy = fastClone(block);
|
|
30
|
+
const copied = {
|
|
31
|
+
...copy,
|
|
32
|
+
properties: {
|
|
33
|
+
...copy.properties
|
|
34
|
+
},
|
|
35
|
+
actions: {
|
|
36
|
+
...copy.actions
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return copied;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const copy = deepCloneWithConditions(omit(block, 'children', 'meta'));
|
|
43
|
+
return {
|
|
44
|
+
...copy,
|
|
45
|
+
properties: {
|
|
46
|
+
...copy.properties
|
|
47
|
+
},
|
|
48
|
+
actions: {
|
|
49
|
+
...copy.actions
|
|
50
|
+
},
|
|
51
|
+
children: block.children,
|
|
52
|
+
meta: block.meta
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
};
|
|
5
56
|
const evaluateBindings = ({ block, context, localState, rootState, rootSetState }) => {
|
|
6
57
|
if (!block.bindings) {
|
|
7
58
|
return block;
|
|
8
59
|
}
|
|
9
|
-
const
|
|
10
|
-
const copied = {
|
|
11
|
-
...copy,
|
|
12
|
-
properties: {
|
|
13
|
-
...copy.properties
|
|
14
|
-
},
|
|
15
|
-
actions: {
|
|
16
|
-
...copy.actions
|
|
17
|
-
}
|
|
18
|
-
};
|
|
60
|
+
const copied = getCopy(block);
|
|
19
61
|
for (const binding in block.bindings) {
|
|
20
62
|
const expression = block.bindings[binding];
|
|
21
63
|
const value = evaluate({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const createRegisterComponentMessage = (info) => ({
|
|
2
2
|
type: 'builder.registerComponent',
|
|
3
|
-
data:
|
|
3
|
+
data: serializeIncludingFunctions(info)
|
|
4
4
|
});
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
6
6
|
const serializeFn = (fnValue) => {
|
|
@@ -12,7 +12,7 @@ const serializeFn = (fnValue) => {
|
|
|
12
12
|
const appendFunction = !fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
13
13
|
return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`;
|
|
14
14
|
};
|
|
15
|
-
export function
|
|
15
|
+
export function serializeIncludingFunctions(info) {
|
|
16
16
|
return JSON.parse(JSON.stringify(info, (key, value) => {
|
|
17
17
|
if (typeof value === 'function') {
|
|
18
18
|
return serializeFn(value);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { isBrowser } from './is-browser';
|
|
2
|
+
import { serializeIncludingFunctions } from './register-component';
|
|
2
3
|
const registry = {};
|
|
3
4
|
export function register(type, info) {
|
|
5
|
+
if (type === 'plugin') {
|
|
6
|
+
info = serializeIncludingFunctions(info);
|
|
7
|
+
}
|
|
4
8
|
let typeList = registry[type];
|
|
5
9
|
if (!typeList) {
|
|
6
10
|
typeList = registry[type] = [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@builder.io/sdk-svelte",
|
|
3
3
|
"description": "Builder.io SDK for Svelte",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.13",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"lib",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"@sveltejs/adapter-auto": "^2.1.0",
|
|
55
55
|
"@sveltejs/kit": "^1.22.4",
|
|
56
56
|
"@sveltejs/package": "^2.2.0",
|
|
57
|
-
"nx": "
|
|
58
|
-
"nx-cloud": "
|
|
57
|
+
"nx": "^19.6.5",
|
|
58
|
+
"nx-cloud": "^19.0.0",
|
|
59
59
|
"svelte": "^4.1.2",
|
|
60
60
|
"svelte-check": "^3.4.6",
|
|
61
61
|
"svelte-preprocess": "^5.0.4",
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
<script context="module" lang="ts">
|
|
2
|
-
export type DropzoneProps = BuilderDataProps &
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export type DropzoneProps = BuilderDataProps &
|
|
3
|
+
BuilderComponentsProp & {
|
|
4
|
+
name: string;
|
|
5
|
+
attributes: any;
|
|
6
|
+
};
|
|
6
7
|
</script>
|
|
7
8
|
|
|
8
9
|
<script lang="ts">
|
|
9
10
|
import Blocks from "../../components/blocks/blocks.svelte";
|
|
10
11
|
import { deoptSignal } from "../../functions/deopt";
|
|
11
12
|
import type { BuilderBlock } from "../../types/builder-block";
|
|
12
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
BuilderComponentsProp,
|
|
15
|
+
BuilderDataProps,
|
|
16
|
+
} from "../../types/builder-props";
|
|
13
17
|
|
|
14
18
|
export let builderContext: DropzoneProps["builderContext"];
|
|
15
19
|
export let name: DropzoneProps["name"];
|
|
20
|
+
export let builderComponents: DropzoneProps["builderComponents"];
|
|
16
21
|
function stringifyStyles(stylesObj) {
|
|
17
22
|
let styles = "";
|
|
18
23
|
for (let key in stylesObj) {
|
|
@@ -37,6 +42,7 @@
|
|
|
37
42
|
parent={$builderContext.context?.symbolId}
|
|
38
43
|
path={`symbol.data.${name}`}
|
|
39
44
|
context={builderContext}
|
|
45
|
+
registeredComponents={builderComponents}
|
|
40
46
|
blocks={$builderContext.rootState?.[name]}
|
|
41
47
|
/>
|
|
42
48
|
</div>
|
|
@@ -2,27 +2,17 @@ import type { Writable } from "svelte/store";
|
|
|
2
2
|
import type { BuilderContextInterface, RegisteredComponent, RegisteredComponents } from '../../context/types';
|
|
3
3
|
import { evaluate } from '../../functions/evaluate/index';
|
|
4
4
|
import { extractTextStyles } from '../../functions/extract-text-styles';
|
|
5
|
-
import { getProcessedBlock } from '../../functions/get-processed-block';
|
|
6
5
|
import { getStyle } from '../../functions/get-style';
|
|
7
6
|
import type { BuilderBlock } from '../../types/builder-block';
|
|
8
7
|
import type { RepeatData } from './types';
|
|
9
8
|
export const getComponent = ({
|
|
10
9
|
block,
|
|
11
|
-
context,
|
|
12
10
|
registeredComponents
|
|
13
11
|
}: {
|
|
14
12
|
block: BuilderBlock;
|
|
15
|
-
context: BuilderContextInterface;
|
|
16
13
|
registeredComponents: RegisteredComponents;
|
|
17
14
|
}) => {
|
|
18
|
-
const componentName =
|
|
19
|
-
block,
|
|
20
|
-
localState: context.localState,
|
|
21
|
-
rootState: context.rootState,
|
|
22
|
-
rootSetState: context.rootSetState,
|
|
23
|
-
context: context.context,
|
|
24
|
-
shouldEvaluateBindings: false
|
|
25
|
-
}).component?.name;
|
|
15
|
+
const componentName = block.component?.name;
|
|
26
16
|
if (!componentName) {
|
|
27
17
|
return null;
|
|
28
18
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<script lang="ts">
|
|
11
|
-
import { onMount } from "svelte";
|
|
11
|
+
import { afterUpdate, onMount } from "svelte";
|
|
12
12
|
|
|
13
13
|
import { TARGET } from "../../constants/target";
|
|
14
14
|
import type {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
} from "../../context/types";
|
|
18
18
|
import { getBlockComponentOptions } from "../../functions/get-block-component-options";
|
|
19
19
|
import { getProcessedBlock } from "../../functions/get-processed-block";
|
|
20
|
+
import { isPreviewing } from "../../server-index";
|
|
20
21
|
import type { BuilderBlock } from "../../types/builder-block";
|
|
21
22
|
import DynamicDiv from "../dynamic-div.svelte";
|
|
22
23
|
import { bindAnimations } from "./animator";
|
|
@@ -41,13 +42,6 @@
|
|
|
41
42
|
export let registeredComponents: BlockProps["registeredComponents"];
|
|
42
43
|
export let linkComponent: BlockProps["linkComponent"];
|
|
43
44
|
|
|
44
|
-
$: blockComponent = () => {
|
|
45
|
-
return getComponent({
|
|
46
|
-
block: block,
|
|
47
|
-
context: $context,
|
|
48
|
-
registeredComponents: registeredComponents,
|
|
49
|
-
});
|
|
50
|
-
};
|
|
51
45
|
$: repeatItem = () => {
|
|
52
46
|
return getRepeatItemData({
|
|
53
47
|
block: block,
|
|
@@ -55,7 +49,7 @@
|
|
|
55
49
|
});
|
|
56
50
|
};
|
|
57
51
|
$: processedBlock = () => {
|
|
58
|
-
|
|
52
|
+
const blockToUse = block.repeat?.collection
|
|
59
53
|
? block
|
|
60
54
|
: getProcessedBlock({
|
|
61
55
|
block: block,
|
|
@@ -65,6 +59,13 @@
|
|
|
65
59
|
context: $context.context,
|
|
66
60
|
shouldEvaluateBindings: true,
|
|
67
61
|
});
|
|
62
|
+
return blockToUse;
|
|
63
|
+
};
|
|
64
|
+
$: blockComponent = () => {
|
|
65
|
+
return getComponent({
|
|
66
|
+
block: processedBlock(),
|
|
67
|
+
registeredComponents: registeredComponents,
|
|
68
|
+
});
|
|
68
69
|
};
|
|
69
70
|
$: Tag = () => {
|
|
70
71
|
const shouldUseLink =
|
|
@@ -120,6 +121,11 @@
|
|
|
120
121
|
};
|
|
121
122
|
};
|
|
122
123
|
|
|
124
|
+
let _processedBlock = {
|
|
125
|
+
value: null as BuilderBlock | null,
|
|
126
|
+
update: false,
|
|
127
|
+
};
|
|
128
|
+
|
|
123
129
|
onMount(() => {
|
|
124
130
|
const blockId = processedBlock().id;
|
|
125
131
|
const animations = processedBlock().animations;
|
|
@@ -132,10 +138,12 @@
|
|
|
132
138
|
);
|
|
133
139
|
}
|
|
134
140
|
});
|
|
141
|
+
|
|
142
|
+
afterUpdate(() => {});
|
|
135
143
|
</script>
|
|
136
144
|
|
|
137
145
|
{#if canShowBlock()}
|
|
138
|
-
<BlockStyles {
|
|
146
|
+
<BlockStyles block={processedBlock()} context={$context} />
|
|
139
147
|
|
|
140
148
|
{#if !blockComponent?.()?.noWrap}
|
|
141
149
|
{#if !repeatItem()}
|
|
@@ -170,7 +178,7 @@
|
|
|
170
178
|
/>
|
|
171
179
|
{/each}
|
|
172
180
|
{/if}
|
|
173
|
-
{:else}
|
|
181
|
+
{:else if !repeatItem()}
|
|
174
182
|
<ComponentRef
|
|
175
183
|
componentRef={componentRefProps().componentRef}
|
|
176
184
|
componentOptions={componentRefProps().componentOptions}
|
|
@@ -182,5 +190,14 @@
|
|
|
182
190
|
includeBlockProps={componentRefProps().includeBlockProps}
|
|
183
191
|
isInteractive={componentRefProps().isInteractive}
|
|
184
192
|
/>
|
|
193
|
+
{:else}
|
|
194
|
+
{#each repeatItem() as data, index (index)}
|
|
195
|
+
<RepeatedBlock
|
|
196
|
+
repeatContext={data.context}
|
|
197
|
+
block={data.block}
|
|
198
|
+
{registeredComponents}
|
|
199
|
+
{linkComponent}
|
|
200
|
+
/>
|
|
201
|
+
{/each}
|
|
185
202
|
{/if}
|
|
186
203
|
{/if}
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
import { TARGET } from "../../../constants/target";
|
|
14
14
|
import type { BuilderContextInterface } from "../../../context/types";
|
|
15
15
|
import { camelToKebabCase } from "../../../functions/camel-to-kebab-case";
|
|
16
|
-
import { getProcessedBlock } from "../../../functions/get-processed-block";
|
|
17
16
|
import { createCssClass } from "../../../helpers/css";
|
|
18
17
|
import { checkIsDefined } from "../../../helpers/nullable";
|
|
19
18
|
import type { BuilderBlock } from "../../../types/builder-block";
|
|
@@ -23,14 +22,7 @@
|
|
|
23
22
|
export let context: BlockStylesProps["context"];
|
|
24
23
|
|
|
25
24
|
$: canShowBlock = () => {
|
|
26
|
-
const processedBlock =
|
|
27
|
-
block: block,
|
|
28
|
-
localState: context.localState,
|
|
29
|
-
rootState: context.rootState,
|
|
30
|
-
rootSetState: context.rootSetState,
|
|
31
|
-
context: context.context,
|
|
32
|
-
shouldEvaluateBindings: true,
|
|
33
|
-
});
|
|
25
|
+
const processedBlock = block;
|
|
34
26
|
// only render styles for blocks that are visible
|
|
35
27
|
if (checkIsDefined(processedBlock.hide)) {
|
|
36
28
|
return !processedBlock.hide;
|
|
@@ -41,14 +33,7 @@
|
|
|
41
33
|
return true;
|
|
42
34
|
};
|
|
43
35
|
$: css = () => {
|
|
44
|
-
const processedBlock =
|
|
45
|
-
block: block,
|
|
46
|
-
localState: context.localState,
|
|
47
|
-
rootState: context.rootState,
|
|
48
|
-
rootSetState: context.rootSetState,
|
|
49
|
-
context: context.context,
|
|
50
|
-
shouldEvaluateBindings: true,
|
|
51
|
-
});
|
|
36
|
+
const processedBlock = block;
|
|
52
37
|
const styles = processedBlock.responsiveStyles;
|
|
53
38
|
const content = context.content;
|
|
54
39
|
const sizesWithUpdatedBreakpoints = getSizesForBreakpoints(
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
</script>
|
|
18
18
|
|
|
19
19
|
<script lang="ts">
|
|
20
|
+
import { onMount } from "svelte";
|
|
21
|
+
|
|
20
22
|
import { isEditing } from "../../functions/is-editing";
|
|
21
23
|
import type { BuilderBlock } from "../../types/builder-block";
|
|
22
24
|
|
|
@@ -69,11 +71,16 @@
|
|
|
69
71
|
$: className = () => {
|
|
70
72
|
return "builder-blocks" + (!blocks?.length ? " no-blocks" : "");
|
|
71
73
|
};
|
|
74
|
+
|
|
75
|
+
let blocksWrapperRef;
|
|
76
|
+
|
|
77
|
+
onMount(() => {});
|
|
72
78
|
</script>
|
|
73
79
|
|
|
74
80
|
<svelte:element
|
|
75
81
|
this={BlocksWrapper}
|
|
76
82
|
style={stringifyStyles(styleProp)}
|
|
83
|
+
bind:this={blocksWrapperRef}
|
|
77
84
|
class={className() + " svelte-element"}
|
|
78
85
|
builder-path={path}
|
|
79
86
|
builder-parent-id={parent}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
BuilderRenderState,
|
|
11
11
|
RegisteredComponents,
|
|
12
12
|
} from "../../context/types";
|
|
13
|
-
import {
|
|
13
|
+
import { serializeIncludingFunctions } from "../../functions/register-component";
|
|
14
14
|
import type { ComponentInfo } from "../../types/components";
|
|
15
15
|
import type { Dictionary } from "../../types/typescript";
|
|
16
16
|
import Blocks from "../blocks/blocks.svelte";
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
...acc,
|
|
71
71
|
[info.name]: {
|
|
72
72
|
component: component,
|
|
73
|
-
...
|
|
73
|
+
...serializeIncludingFunctions(info),
|
|
74
74
|
},
|
|
75
75
|
}),
|
|
76
76
|
{}
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
].reduce<Dictionary<ComponentInfo>>(
|
|
102
102
|
(acc, { component: _, ...info }) => ({
|
|
103
103
|
...acc,
|
|
104
|
-
[info.name]:
|
|
104
|
+
[info.name]: serializeIncludingFunctions(info),
|
|
105
105
|
}),
|
|
106
106
|
{}
|
|
107
107
|
),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "2.0.
|
|
1
|
+
export const SDK_VERSION = "2.0.13"
|
|
@@ -2,6 +2,20 @@ import { logger } from '../../helpers/logger';
|
|
|
2
2
|
import { chooseBrowserOrServerEval } from './choose-eval';
|
|
3
3
|
import type { EvaluatorArgs, ExecutorArgs } from './helpers';
|
|
4
4
|
import { getBuilderGlobals, parseCode } from './helpers';
|
|
5
|
+
|
|
6
|
+
// Caching is dangerous for several reasons
|
|
7
|
+
// - JSON.stringify is not safe to run on things like `context`
|
|
8
|
+
// because anything can be passed, including non-stringifiable objects,
|
|
9
|
+
// circiular references, etc.
|
|
10
|
+
// - JSON.stringify is expensive to run as a cache key
|
|
11
|
+
// - This likely only helped because we were running processBlock multiple times
|
|
12
|
+
// but that is not fixed, and this will cause bugs and issues if enabled
|
|
13
|
+
//
|
|
14
|
+
// Perhaps the best approach is to allow users to configure if caching is enabled or not
|
|
15
|
+
// for instance on edge runtimes with slower evaluation times via the interpreter
|
|
16
|
+
// That said, the repeat processBLock calls was making any evaluation time 10x+ slower
|
|
17
|
+
// which is now fixed, so this still may not be necessary
|
|
18
|
+
const DISABLE_CACHE = true;
|
|
5
19
|
type EvalValue = unknown;
|
|
6
20
|
class EvalCache {
|
|
7
21
|
static cacheLimit = 20;
|
|
@@ -53,7 +67,7 @@ export function evaluate({
|
|
|
53
67
|
rootState,
|
|
54
68
|
localState
|
|
55
69
|
};
|
|
56
|
-
if (enableCache) {
|
|
70
|
+
if (enableCache && !DISABLE_CACHE) {
|
|
57
71
|
const cacheKey = EvalCache.getCacheKey(args);
|
|
58
72
|
const cachedValue = EvalCache.getCachedValue(cacheKey);
|
|
59
73
|
if (cachedValue) {
|
|
@@ -22,6 +22,7 @@ import type { IsolateOptions } from 'isolated-vm';
|
|
|
22
22
|
* from a server-only location, such as:
|
|
23
23
|
* - The NextJS Pages router's `_document.tsx`
|
|
24
24
|
* - Your Remix route's `loader`
|
|
25
|
+
* - Qwik's `entry.ssr.tsx` file
|
|
25
26
|
*/
|
|
26
27
|
export const initializeNodeRuntime = (args?: {
|
|
27
28
|
ivmIsolateOptions?: IsolateOptions;
|
|
@@ -80,7 +80,7 @@ export const setIvm = (ivm: IsolatedVMImport, options: IsolateOptions = {}) => {
|
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
// only mention the script for SDKs that have it.
|
|
83
|
-
const SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === '@builder.io/sdk-react-nextjs' || SDK_NAME === '@builder.io/sdk-react';
|
|
83
|
+
const SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === '@builder.io/sdk-react-nextjs' || SDK_NAME === '@builder.io/sdk-react' || SDK_NAME === '@builder.io/sdk-qwik';
|
|
84
84
|
const getIvm = (): IsolatedVMImport => {
|
|
85
85
|
try {
|
|
86
86
|
if (IVM_INSTANCE) return IVM_INSTANCE;
|
|
@@ -93,7 +93,7 @@ const getIvm = (): IsolatedVMImport => {
|
|
|
93
93
|
|
|
94
94
|
SOLUTION: In a server-only execution path within your application, do one of the following:
|
|
95
95
|
|
|
96
|
-
${SHOULD_MENTION_INITIALIZE_SCRIPT ?
|
|
96
|
+
${SHOULD_MENTION_INITIALIZE_SCRIPT ? `- import and call \`initializeNodeRuntime()\` from "${SDK_NAME}/node/init".` : ''}
|
|
97
97
|
- add the following import: \`await import('isolated-vm')\`.
|
|
98
98
|
|
|
99
99
|
For more information, visit https://builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments`;
|
|
@@ -1,9 +1,60 @@
|
|
|
1
|
+
import { TARGET } from '../constants/target';
|
|
1
2
|
import type { BuilderContextInterface } from '../context/types';
|
|
3
|
+
import { omit } from '../helpers/omit';
|
|
2
4
|
import type { BuilderBlock } from '../types/builder-block';
|
|
3
5
|
import { evaluate } from './evaluate/index';
|
|
4
6
|
import { fastClone } from './fast-clone';
|
|
5
7
|
import { set } from './set';
|
|
6
8
|
import { transformBlock } from './transform-block';
|
|
9
|
+
|
|
10
|
+
// Deep clone a block but without cloning any child blocks
|
|
11
|
+
export function deepCloneWithConditions<T = any>(obj: T): T {
|
|
12
|
+
if (obj === null || typeof obj !== 'object') {
|
|
13
|
+
return obj;
|
|
14
|
+
}
|
|
15
|
+
if (Array.isArray(obj)) {
|
|
16
|
+
return (obj.map((item: any) => deepCloneWithConditions(item)) as T);
|
|
17
|
+
}
|
|
18
|
+
if ((obj as any)['@type'] === '@builder.io/sdk:Element') {
|
|
19
|
+
return obj;
|
|
20
|
+
}
|
|
21
|
+
const clonedObj: any = {};
|
|
22
|
+
for (const key in obj) {
|
|
23
|
+
if (key !== 'meta' && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
24
|
+
clonedObj[key] = deepCloneWithConditions(obj[key]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return clonedObj;
|
|
28
|
+
}
|
|
29
|
+
const IS_SDK_WITHOUT_CACHED_PROCESSED_BLOCK = ['svelte', 'vue', 'angular', 'qwik', 'solid'].includes(TARGET);
|
|
30
|
+
const getCopy = (block: BuilderBlock): BuilderBlock => {
|
|
31
|
+
if (IS_SDK_WITHOUT_CACHED_PROCESSED_BLOCK) {
|
|
32
|
+
const copy = fastClone(block);
|
|
33
|
+
const copied = {
|
|
34
|
+
...copy,
|
|
35
|
+
properties: {
|
|
36
|
+
...copy.properties
|
|
37
|
+
},
|
|
38
|
+
actions: {
|
|
39
|
+
...copy.actions
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return copied;
|
|
43
|
+
} else {
|
|
44
|
+
const copy = (deepCloneWithConditions(omit(block, 'children', 'meta')) as BuilderBlock);
|
|
45
|
+
return {
|
|
46
|
+
...copy,
|
|
47
|
+
properties: {
|
|
48
|
+
...copy.properties
|
|
49
|
+
},
|
|
50
|
+
actions: {
|
|
51
|
+
...copy.actions
|
|
52
|
+
},
|
|
53
|
+
children: block.children,
|
|
54
|
+
meta: block.meta
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
7
58
|
const evaluateBindings = ({
|
|
8
59
|
block,
|
|
9
60
|
context,
|
|
@@ -16,16 +67,7 @@ const evaluateBindings = ({
|
|
|
16
67
|
if (!block.bindings) {
|
|
17
68
|
return block;
|
|
18
69
|
}
|
|
19
|
-
const
|
|
20
|
-
const copied = {
|
|
21
|
-
...copy,
|
|
22
|
-
properties: {
|
|
23
|
-
...copy.properties
|
|
24
|
-
},
|
|
25
|
-
actions: {
|
|
26
|
-
...copy.actions
|
|
27
|
-
}
|
|
28
|
-
};
|
|
70
|
+
const copied = getCopy(block);
|
|
29
71
|
for (const binding in block.bindings) {
|
|
30
72
|
const expression = block.bindings[binding];
|
|
31
73
|
const value = evaluate({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentInfo } from '../types/components';
|
|
2
2
|
export const createRegisterComponentMessage = (info: ComponentInfo) => ({
|
|
3
3
|
type: 'builder.registerComponent',
|
|
4
|
-
data:
|
|
4
|
+
data: serializeIncludingFunctions(info)
|
|
5
5
|
});
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
@@ -15,7 +15,7 @@ const serializeFn = (fnValue: Function) => {
|
|
|
15
15
|
const appendFunction = !fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
16
16
|
return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`;
|
|
17
17
|
};
|
|
18
|
-
export function
|
|
18
|
+
export function serializeIncludingFunctions(info: ComponentInfo) {
|
|
19
19
|
return JSON.parse(JSON.stringify(info, (key, value) => {
|
|
20
20
|
if (typeof value === 'function') {
|
|
21
21
|
return serializeFn(value);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BuilderBlock } from '../types/builder-block';
|
|
2
2
|
import type { DeepPartial } from '../types/deep-partial';
|
|
3
3
|
import { isBrowser } from './is-browser';
|
|
4
|
+
import { serializeIncludingFunctions } from './register-component';
|
|
4
5
|
export interface InsertMenuItem {
|
|
5
6
|
name: string;
|
|
6
7
|
icon?: string;
|
|
@@ -19,6 +20,9 @@ const registry: {
|
|
|
19
20
|
export function register(type: 'insertMenu', info: InsertMenuConfig): void;
|
|
20
21
|
export function register(type: string, info: any): void;
|
|
21
22
|
export function register(type: string, info: any) {
|
|
23
|
+
if (type === 'plugin') {
|
|
24
|
+
info = serializeIncludingFunctions(info);
|
|
25
|
+
}
|
|
22
26
|
let typeList = registry[type];
|
|
23
27
|
if (!typeList) {
|
|
24
28
|
typeList = registry[type] = [];
|