@builder.io/react 2.0.4-0 → 2.0.4-11
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/dist/builder-react-lite.cjs.js +1 -15
- package/dist/builder-react-lite.cjs.js.map +1 -1
- package/dist/builder-react-lite.esm.js +1 -15
- package/dist/builder-react-lite.esm.js.map +1 -1
- package/dist/builder-react.browser.js +1 -24
- package/dist/builder-react.browser.js.map +1 -1
- package/dist/builder-react.cjs.js +1 -15
- package/dist/builder-react.cjs.js.map +1 -1
- package/dist/builder-react.es5.js +1 -15
- package/dist/builder-react.es5.js.map +1 -1
- package/dist/builder-react.unpkg.js +1 -24
- package/dist/builder-react.unpkg.js.map +1 -1
- package/dist/lib/package.json +4 -2
- package/dist/lib/src/blocks/Embed.js.map +1 -1
- package/dist/lib/src/blocks/Section.js +2 -0
- package/dist/lib/src/blocks/Section.js.map +1 -1
- package/dist/lib/src/blocks/Symbol.js +2 -2
- package/dist/lib/src/blocks/Symbol.js.map +1 -1
- package/dist/lib/src/components/builder-block.component.js +3 -10
- package/dist/lib/src/components/builder-block.component.js.map +1 -1
- package/dist/lib/src/components/builder-blocks.component.js.map +1 -1
- package/dist/lib/src/components/builder-component.component.js +16 -6
- package/dist/lib/src/components/builder-component.component.js.map +1 -1
- package/dist/lib/src/components/builder-content.component.js +3 -3
- package/dist/lib/src/components/builder-content.component.js.map +1 -1
- package/dist/lib/src/constants/device-sizes.constant.js.map +1 -1
- package/dist/lib/src/functions/apply-patch-with-mutation.js +1 -1
- package/dist/lib/src/functions/apply-patch-with-mutation.js.map +1 -1
- package/dist/lib/src/functions/apply-patch-with-mutation.test.js +54 -0
- package/dist/lib/src/functions/apply-patch-with-mutation.test.js.map +1 -0
- package/dist/lib/src/scripts/init-editing.js +1 -1
- package/dist/types/src/blocks/Mutation.d.ts +1 -0
- package/dist/types/src/blocks/Slot.d.ts +1 -0
- package/dist/types/src/blocks/raw/RawText.d.ts +1 -0
- package/dist/types/src/components/builder-component.component.d.ts +6 -0
- package/dist/types/src/functions/apply-patch-with-mutation.d.ts +2 -2
- package/dist/types/src/functions/apply-patch-with-mutation.test.d.ts +1 -0
- package/package.json +4 -2
- package/src/blocks/Section.tsx +16 -11
- package/src/blocks/Symbol.tsx +1 -0
- package/src/components/builder-block.component.tsx +7 -13
- package/src/components/builder-blocks.component.tsx +10 -8
- package/src/components/builder-component.component.tsx +36 -21
- package/src/components/builder-content.component.tsx +3 -4
- package/src/functions/apply-patch-with-mutation.test.ts +55 -0
- package/src/functions/apply-patch-with-mutation.ts +5 -5
- package/src/scripts/init-editing.ts +1 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var apply_patch_with_mutation_1 = require("./apply-patch-with-mutation");
|
|
4
|
+
describe('applyPatchWithMinimalMutationChain', function () {
|
|
5
|
+
test('Basic shallow update', function () {
|
|
6
|
+
var obj = {
|
|
7
|
+
foo: 'bar',
|
|
8
|
+
};
|
|
9
|
+
var patch = {
|
|
10
|
+
op: 'replace',
|
|
11
|
+
path: '/foo',
|
|
12
|
+
value: '60px',
|
|
13
|
+
};
|
|
14
|
+
var applied = (0, apply_patch_with_mutation_1.applyPatchWithMinimalMutationChain)(obj, patch);
|
|
15
|
+
expect(applied.foo).toBe('60px');
|
|
16
|
+
expect(applied).not.toBe(obj);
|
|
17
|
+
});
|
|
18
|
+
test('Deep object updates', function () {
|
|
19
|
+
var obj = {
|
|
20
|
+
foo: {
|
|
21
|
+
bar: true,
|
|
22
|
+
},
|
|
23
|
+
baz: {},
|
|
24
|
+
};
|
|
25
|
+
var patch = {
|
|
26
|
+
op: 'replace',
|
|
27
|
+
path: '/foo/bar',
|
|
28
|
+
value: '60px',
|
|
29
|
+
};
|
|
30
|
+
var applied = (0, apply_patch_with_mutation_1.applyPatchWithMinimalMutationChain)(obj, patch);
|
|
31
|
+
expect(applied.foo.bar).toBe('60px');
|
|
32
|
+
expect(applied).not.toBe(obj);
|
|
33
|
+
expect(applied.foo).not.toBe(obj.foo);
|
|
34
|
+
expect(applied.baz).toBe(obj.baz);
|
|
35
|
+
});
|
|
36
|
+
test('Deep array updates', function () {
|
|
37
|
+
var obj = {
|
|
38
|
+
foo: [{ bar: true }],
|
|
39
|
+
baz: {},
|
|
40
|
+
};
|
|
41
|
+
var patch = {
|
|
42
|
+
op: 'replace',
|
|
43
|
+
path: '/foo/0/bar',
|
|
44
|
+
value: '60px',
|
|
45
|
+
};
|
|
46
|
+
var applied = (0, apply_patch_with_mutation_1.applyPatchWithMinimalMutationChain)(obj, patch);
|
|
47
|
+
expect(applied.foo[0].bar).toBe('60px');
|
|
48
|
+
expect(applied).not.toBe(obj);
|
|
49
|
+
expect(applied.foo).not.toBe(obj.foo);
|
|
50
|
+
expect(applied.foo[0]).not.toBe(obj.foo[0]);
|
|
51
|
+
expect(applied.baz).toBe(obj.baz);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=apply-patch-with-mutation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-patch-with-mutation.test.js","sourceRoot":"","sources":["../../../../src/functions/apply-patch-with-mutation.test.ts"],"names":[],"mappings":";;AAAA,yEAAiF;AAEjF,QAAQ,CAAC,oCAAoC,EAAE;IAC7C,IAAI,CAAC,sBAAsB,EAAE;QAC3B,IAAM,GAAG,GAAG;YACV,GAAG,EAAE,KAAK;SACX,CAAC;QACF,IAAM,KAAK,GAAG;YACZ,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;SACL,CAAC;QACX,IAAM,OAAO,GAAG,IAAA,8DAAkC,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,qBAAqB,EAAE;QAC1B,IAAM,GAAG,GAAG;YACV,GAAG,EAAE;gBACH,GAAG,EAAE,IAAI;aACV;YACD,GAAG,EAAE,EAAE;SACR,CAAC;QACF,IAAM,KAAK,GAAG;YACZ,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,MAAM;SACL,CAAC;QACX,IAAM,OAAO,GAAG,IAAA,8DAAkC,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oBAAoB,EAAE;QACzB,IAAM,GAAG,GAAG;YACV,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YACpB,GAAG,EAAE,EAAE;SACR,CAAC;QACF,IAAM,KAAK,GAAG;YACZ,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,MAAM;SACL,CAAC;QAEX,IAAM,OAAO,GAAG,IAAA,8DAAkC,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -181,6 +181,10 @@ export interface BuilderComponentProps {
|
|
|
181
181
|
* navigation to other pages unintended
|
|
182
182
|
*/
|
|
183
183
|
stopClickPropagationWhenEditing?: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Locale code, should match one of the locales in your spaces locale, wll auto resolve the localized inputs to the localized value
|
|
186
|
+
*/
|
|
187
|
+
locale?: string;
|
|
184
188
|
}
|
|
185
189
|
export interface BuilderComponentState {
|
|
186
190
|
state: any;
|
|
@@ -247,6 +251,7 @@ export declare class BuilderComponent extends React.Component<BuilderComponentPr
|
|
|
247
251
|
url?: string | undefined;
|
|
248
252
|
isChild?: boolean | undefined;
|
|
249
253
|
stopClickPropagationWhenEditing?: boolean | undefined;
|
|
254
|
+
locale?: string | undefined;
|
|
250
255
|
children?: React.ReactNode;
|
|
251
256
|
};
|
|
252
257
|
get name(): string | undefined;
|
|
@@ -295,6 +300,7 @@ export declare class BuilderComponent extends React.Component<BuilderComponentPr
|
|
|
295
300
|
checkStyles(data: any): void;
|
|
296
301
|
reload(): void;
|
|
297
302
|
get content(): Content | undefined;
|
|
303
|
+
get externalState(): any;
|
|
298
304
|
get useContent(): any;
|
|
299
305
|
render(): JSX.Element;
|
|
300
306
|
evalExpression(expression: string): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const applyPatchWithMinimalMutationChain: (obj:
|
|
1
|
+
export declare const applyPatchWithMinimalMutationChain: <T extends object>(obj: T, patch: {
|
|
2
2
|
path: string;
|
|
3
3
|
op: 'add' | 'remove' | 'replace';
|
|
4
4
|
value: any;
|
|
5
|
-
}, preserveRoot?: boolean) =>
|
|
5
|
+
}, preserveRoot?: boolean) => T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@builder.io/react",
|
|
3
|
-
"version": "2.0.4-
|
|
3
|
+
"version": "2.0.4-11",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"main": "dist/builder-react.cjs.js",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"@types/rollup-plugin-commonjs": "^9.2.0",
|
|
76
76
|
"@types/rollup-plugin-json": "^3.0.3",
|
|
77
77
|
"@types/rollup-plugin-node-resolve": "^4.1.0",
|
|
78
|
+
"@types/traverse": "^0.6.32",
|
|
78
79
|
"colors": "^1.1.2",
|
|
79
80
|
"commitizen": "^4.2.4",
|
|
80
81
|
"coveralls": "^3.0.0",
|
|
@@ -123,10 +124,11 @@
|
|
|
123
124
|
"react-dom": ">=16.8.0"
|
|
124
125
|
},
|
|
125
126
|
"dependencies": {
|
|
126
|
-
"@builder.io/sdk": "^1.1.
|
|
127
|
+
"@builder.io/sdk": "^1.1.28-2",
|
|
127
128
|
"@emotion/core": "^10.0.17",
|
|
128
129
|
"hash-sum": "^2.0.0",
|
|
129
130
|
"preact": "^10.1.0",
|
|
131
|
+
"traverse": "^0.6.6",
|
|
130
132
|
"vm2": "^3.9.10"
|
|
131
133
|
},
|
|
132
134
|
"gitHead": "4d96fbc32864698afbb355ab991c6d90be991951"
|
package/src/blocks/Section.tsx
CHANGED
|
@@ -40,18 +40,23 @@ class SectionComponent extends React.Component<SectionProps, { inView?: boolean
|
|
|
40
40
|
if (typeof IntersectionObserver === 'undefined' || !this.ref) {
|
|
41
41
|
this.setState({ inView: true });
|
|
42
42
|
} else {
|
|
43
|
-
const observer = new IntersectionObserver(
|
|
44
|
-
entries
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
const observer = new IntersectionObserver(
|
|
44
|
+
(entries, observer) => {
|
|
45
|
+
entries.forEach(entry => {
|
|
46
|
+
if (entry.intersectionRatio > 0) {
|
|
47
|
+
this.setState({
|
|
48
|
+
inView: true,
|
|
49
|
+
});
|
|
50
|
+
if (this.ref) {
|
|
51
|
+
observer.unobserve(this.ref);
|
|
52
|
+
}
|
|
51
53
|
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
rootMargin: '10px',
|
|
58
|
+
}
|
|
59
|
+
);
|
|
55
60
|
|
|
56
61
|
observer.observe(this.ref);
|
|
57
62
|
|
package/src/blocks/Symbol.tsx
CHANGED
|
@@ -121,6 +121,7 @@ class SymbolComponent extends React.Component<SymbolProps> {
|
|
|
121
121
|
this.placeholder
|
|
122
122
|
) : (
|
|
123
123
|
<BuilderComponent
|
|
124
|
+
{...(state.state?.locale && { locale: state.state.locale })}
|
|
124
125
|
isChild
|
|
125
126
|
ref={(ref: any) => (this.ref = ref)}
|
|
126
127
|
context={{ ...state.context, symbolId: this.props.builderBlock?.id }}
|
|
@@ -18,8 +18,8 @@ const camelCaseToKebabCase = (str?: string) =>
|
|
|
18
18
|
const kebabCaseToCamelCase = (str = '') =>
|
|
19
19
|
str.replace(/-([a-z])/g, match => match[1].toUpperCase());
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
const Device = { desktop: 0, tablet: 1, mobile: 2 };
|
|
22
|
-
const blocksMap: Record<string, BuilderElement> = {};
|
|
23
23
|
|
|
24
24
|
const voidElements = new Set([
|
|
25
25
|
'area',
|
|
@@ -136,7 +136,7 @@ export class BuilderBlock extends React.Component<
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
get block() {
|
|
139
|
-
return
|
|
139
|
+
return this.props.block;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
get emotionCss() {
|
|
@@ -249,17 +249,11 @@ export class BuilderBlock extends React.Component<
|
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
if (location.href.includes('builder.debug=true')) {
|
|
252
|
-
|
|
252
|
+
eval('debugger');
|
|
253
253
|
}
|
|
254
|
-
let newBlock = { ...this.block };
|
|
255
254
|
for (const patch of patches) {
|
|
256
|
-
|
|
257
|
-
// e.g. access it's parent hm. maybe do the listning mutations
|
|
258
|
-
// on hte parent element not the child (or rather
|
|
259
|
-
// send the message to the parent)
|
|
260
|
-
applyPatchWithMinimalMutationChain(newBlock, patch);
|
|
255
|
+
applyPatchWithMinimalMutationChain(this.props.block, patch, true);
|
|
261
256
|
}
|
|
262
|
-
blocksMap[this.props.block.id!] = newBlock;
|
|
263
257
|
this.setState({ updates: this.state.updates + 1 });
|
|
264
258
|
|
|
265
259
|
break;
|
|
@@ -460,9 +454,9 @@ export class BuilderBlock extends React.Component<
|
|
|
460
454
|
}
|
|
461
455
|
|
|
462
456
|
const innerComponentProperties = (options.component || options.options) && {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
457
|
+
...options.options,
|
|
458
|
+
...(options.component.options || options.component.data),
|
|
459
|
+
};
|
|
466
460
|
|
|
467
461
|
const isVoid = voidElements.has(TagName);
|
|
468
462
|
|
|
@@ -108,14 +108,16 @@ export class BuilderBlocks extends React.Component<BuilderBlocksProps, BuilderBl
|
|
|
108
108
|
// TODO: only fi in iframe?
|
|
109
109
|
builder-path={Builder.isIframe ? this.path : undefined}
|
|
110
110
|
builder-parent-id={this.parentId}
|
|
111
|
-
css={
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
css={
|
|
112
|
+
{
|
|
113
|
+
...(!this.props.emailMode && {
|
|
114
|
+
display: 'flex',
|
|
115
|
+
flexDirection: 'column',
|
|
116
|
+
alignItems: 'stretch',
|
|
117
|
+
}),
|
|
118
|
+
...this.props.style,
|
|
119
|
+
} as any
|
|
120
|
+
}
|
|
119
121
|
onClick={() => {
|
|
120
122
|
if (this.noBlocks) {
|
|
121
123
|
this.onClickEmptyBlocks();
|
|
@@ -98,7 +98,6 @@ const sizeMap = {
|
|
|
98
98
|
mobile: 'small',
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
|
|
102
101
|
const fetchCache: { [key: string]: any } = {};
|
|
103
102
|
|
|
104
103
|
export interface BuilderComponentProps {
|
|
@@ -277,6 +276,11 @@ export interface BuilderComponentProps {
|
|
|
277
276
|
* navigation to other pages unintended
|
|
278
277
|
*/
|
|
279
278
|
stopClickPropagationWhenEditing?: boolean;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Locale code, should match one of the locales in your spaces locale, wll auto resolve the localized inputs to the localized value
|
|
282
|
+
*/
|
|
283
|
+
locale?: string;
|
|
280
284
|
}
|
|
281
285
|
|
|
282
286
|
export interface BuilderComponentState {
|
|
@@ -841,7 +845,7 @@ export class BuilderComponent extends React.Component<
|
|
|
841
845
|
get data() {
|
|
842
846
|
const data = {
|
|
843
847
|
...(this.inlinedContent && this.inlinedContent.data?.state),
|
|
844
|
-
...this.
|
|
848
|
+
...this.externalState,
|
|
845
849
|
...this.state.state,
|
|
846
850
|
};
|
|
847
851
|
Object.assign(this.rootState, data);
|
|
@@ -852,7 +856,7 @@ export class BuilderComponent extends React.Component<
|
|
|
852
856
|
// TODO: shallow diff
|
|
853
857
|
if (this.props.data && prevProps.data !== this.props.data) {
|
|
854
858
|
this.state.update((state: any) => {
|
|
855
|
-
Object.assign(state, this.
|
|
859
|
+
Object.assign(state, this.externalState);
|
|
856
860
|
});
|
|
857
861
|
}
|
|
858
862
|
|
|
@@ -892,6 +896,13 @@ export class BuilderComponent extends React.Component<
|
|
|
892
896
|
return content;
|
|
893
897
|
}
|
|
894
898
|
|
|
899
|
+
get externalState() {
|
|
900
|
+
return {
|
|
901
|
+
...this.props.data,
|
|
902
|
+
...(this.props.locale ? { locale: this.props.locale } : {}),
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
895
906
|
get useContent() {
|
|
896
907
|
return this.content || this.state.context.builderContent;
|
|
897
908
|
}
|
|
@@ -900,7 +911,10 @@ export class BuilderComponent extends React.Component<
|
|
|
900
911
|
const content = this.content;
|
|
901
912
|
|
|
902
913
|
const dataString =
|
|
903
|
-
Builder.isBrowser &&
|
|
914
|
+
Builder.isBrowser &&
|
|
915
|
+
this.externalState &&
|
|
916
|
+
size(this.externalState) &&
|
|
917
|
+
hash(this.externalState);
|
|
904
918
|
let key = Builder.isEditing ? this.name : this.props.entry;
|
|
905
919
|
if (key && !Builder.isEditing && dataString && dataString.length < 300) {
|
|
906
920
|
key += ':' + dataString;
|
|
@@ -971,6 +985,7 @@ export class BuilderComponent extends React.Component<
|
|
|
971
985
|
!this.isPreviewing && { initialContent: [] }),
|
|
972
986
|
...(this.props.url && { url: this.props.url }),
|
|
973
987
|
...this.props.options,
|
|
988
|
+
...(this.props.locale ? { locale: this.props.locale } : {}),
|
|
974
989
|
...(this.options.codegen && {
|
|
975
990
|
format: 'react',
|
|
976
991
|
}),
|
|
@@ -1272,7 +1287,7 @@ export class BuilderComponent extends React.Component<
|
|
|
1272
1287
|
deviceSize: this.deviceSizeState,
|
|
1273
1288
|
device: this.device,
|
|
1274
1289
|
...data.state,
|
|
1275
|
-
...this.
|
|
1290
|
+
...this.externalState,
|
|
1276
1291
|
}),
|
|
1277
1292
|
};
|
|
1278
1293
|
if (this.mounted) {
|
|
@@ -1358,22 +1373,22 @@ export class BuilderComponent extends React.Component<
|
|
|
1358
1373
|
const builderModelRe = /builder\.io\/api\/v2\/([^\/\?]+)/i;
|
|
1359
1374
|
const builderModelMatch = url.match(builderModelRe);
|
|
1360
1375
|
const model = builderModelMatch && builderModelMatch[1];
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1376
|
+
this.handleRequest(key, finalUrl);
|
|
1377
|
+
const currentSubscription = this.httpSubscriptionPerKey[key];
|
|
1378
|
+
if (currentSubscription) {
|
|
1379
|
+
currentSubscription.unsubscribe();
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
// TODO: fix this
|
|
1383
|
+
const newSubscription = (this.httpSubscriptionPerKey[key] =
|
|
1384
|
+
this.onStateChange.subscribe(() => {
|
|
1385
|
+
const newUrl = this.evalExpression(url);
|
|
1386
|
+
if (newUrl !== finalUrl) {
|
|
1387
|
+
this.handleRequest(key, newUrl);
|
|
1388
|
+
this.lastHttpRequests[key] = newUrl;
|
|
1389
|
+
}
|
|
1390
|
+
}));
|
|
1391
|
+
this.subscriptions.add(newSubscription);
|
|
1377
1392
|
} else {
|
|
1378
1393
|
this.handleRequest(key, this.evalExpression(url));
|
|
1379
1394
|
}
|
|
@@ -140,18 +140,17 @@ export class BuilderContent<ContentType extends object = any> extends React.Comp
|
|
|
140
140
|
if (location.href.includes('builder.debug=true')) {
|
|
141
141
|
eval('debugger');
|
|
142
142
|
}
|
|
143
|
-
let newData;
|
|
143
|
+
let newData = this.state.data as any;
|
|
144
144
|
for (const patch of patches) {
|
|
145
|
-
newData = applyPatchWithMinimalMutationChain(
|
|
145
|
+
newData = applyPatchWithMinimalMutationChain(newData, patch, false);
|
|
146
146
|
}
|
|
147
147
|
this.setState({
|
|
148
148
|
updates: this.state.updates + 1,
|
|
149
149
|
data: newData,
|
|
150
150
|
});
|
|
151
151
|
if (this.props.contentLoaded) {
|
|
152
|
-
this.props.contentLoaded(newData,
|
|
152
|
+
this.props.contentLoaded(newData.data, newData);
|
|
153
153
|
}
|
|
154
|
-
|
|
155
154
|
break;
|
|
156
155
|
}
|
|
157
156
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { applyPatchWithMinimalMutationChain } from './apply-patch-with-mutation';
|
|
2
|
+
|
|
3
|
+
describe('applyPatchWithMinimalMutationChain', () => {
|
|
4
|
+
test('Basic shallow update', () => {
|
|
5
|
+
const obj = {
|
|
6
|
+
foo: 'bar',
|
|
7
|
+
};
|
|
8
|
+
const patch = {
|
|
9
|
+
op: 'replace',
|
|
10
|
+
path: '/foo',
|
|
11
|
+
value: '60px',
|
|
12
|
+
} as const;
|
|
13
|
+
const applied = applyPatchWithMinimalMutationChain(obj, patch);
|
|
14
|
+
expect(applied.foo).toBe('60px');
|
|
15
|
+
expect(applied).not.toBe(obj);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('Deep object updates', () => {
|
|
19
|
+
const obj = {
|
|
20
|
+
foo: {
|
|
21
|
+
bar: true,
|
|
22
|
+
},
|
|
23
|
+
baz: {},
|
|
24
|
+
};
|
|
25
|
+
const patch = {
|
|
26
|
+
op: 'replace',
|
|
27
|
+
path: '/foo/bar',
|
|
28
|
+
value: '60px',
|
|
29
|
+
} as const;
|
|
30
|
+
const applied = applyPatchWithMinimalMutationChain(obj, patch);
|
|
31
|
+
expect(applied.foo.bar).toBe('60px');
|
|
32
|
+
expect(applied).not.toBe(obj);
|
|
33
|
+
expect(applied.foo).not.toBe(obj.foo);
|
|
34
|
+
expect(applied.baz).toBe(obj.baz);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('Deep array updates', () => {
|
|
38
|
+
const obj = {
|
|
39
|
+
foo: [{ bar: true }],
|
|
40
|
+
baz: {},
|
|
41
|
+
};
|
|
42
|
+
const patch = {
|
|
43
|
+
op: 'replace',
|
|
44
|
+
path: '/foo/0/bar',
|
|
45
|
+
value: '60px',
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
const applied = applyPatchWithMinimalMutationChain(obj, patch);
|
|
49
|
+
expect(applied.foo[0].bar).toBe('60px');
|
|
50
|
+
expect(applied).not.toBe(obj);
|
|
51
|
+
expect(applied.foo).not.toBe(obj.foo);
|
|
52
|
+
expect(applied.foo[0]).not.toBe(obj.foo[0]);
|
|
53
|
+
expect(applied.baz).toBe(obj.baz);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export const applyPatchWithMinimalMutationChain = (
|
|
2
|
-
obj:
|
|
1
|
+
export const applyPatchWithMinimalMutationChain = <T extends object>(
|
|
2
|
+
obj: T,
|
|
3
3
|
patch: { path: string; op: 'add' | 'remove' | 'replace'; value: any },
|
|
4
|
-
preserveRoot =
|
|
5
|
-
) => {
|
|
4
|
+
preserveRoot = false
|
|
5
|
+
): T => {
|
|
6
6
|
if (Object(obj) !== obj) {
|
|
7
7
|
return obj;
|
|
8
8
|
}
|
|
@@ -13,7 +13,7 @@ export const applyPatchWithMinimalMutationChain = (
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const newObj = preserveRoot ? obj : { ...obj };
|
|
16
|
-
let objPart = newObj;
|
|
16
|
+
let objPart = newObj as any;
|
|
17
17
|
for (let i = 0; i < pathArr.length; i++) {
|
|
18
18
|
const isLast = i === pathArr.length - 1;
|
|
19
19
|
const property = pathArr[i];
|