@prismicio/types-internal 3.12.0-alpha.1 → 3.12.0

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.
@@ -9,10 +9,7 @@ export declare const Document: t.RecordC<t.Type<string, string, unknown>, t.Unio
9
9
  __TYPE__: t.LiteralC<"EmptyContent">;
10
10
  }>>, t.ExactC<t.TypeC<{
11
11
  __TYPE__: t.LiteralC<"BooleanContent">;
12
- value: t.BooleanC; /**
13
- * `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
14
- * format used by Prismic DB, therefore, this function itself is not "legacy".
15
- */
12
+ value: t.BooleanC;
16
13
  }>>, t.IntersectionC<[t.ExactC<t.IntersectionC<[t.TypeC<{
17
14
  embed_url: t.StringC;
18
15
  type: t.StringC;
@@ -786,10 +783,7 @@ export declare const Document: t.RecordC<t.Type<string, string, unknown>, t.Unio
786
783
  __TYPE__: t.LiteralC<"EmptyContent">;
787
784
  }>>, t.ExactC<t.TypeC<{
788
785
  __TYPE__: t.LiteralC<"BooleanContent">;
789
- value: t.BooleanC; /**
790
- * `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
791
- * format used by Prismic DB, therefore, this function itself is not "legacy".
792
- */
786
+ value: t.BooleanC;
793
787
  }>>, t.IntersectionC<[t.ExactC<t.IntersectionC<[t.TypeC<{
794
788
  embed_url: t.StringC;
795
789
  type: t.StringC;
@@ -1556,10 +1550,7 @@ export declare const Document: t.RecordC<t.Type<string, string, unknown>, t.Unio
1556
1550
  __TYPE__: t.LiteralC<"EmptyContent">;
1557
1551
  }>>, t.ExactC<t.TypeC<{
1558
1552
  __TYPE__: t.LiteralC<"BooleanContent">;
1559
- value: t.BooleanC; /**
1560
- * `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
1561
- * format used by Prismic DB, therefore, this function itself is not "legacy".
1562
- */
1553
+ value: t.BooleanC;
1563
1554
  }>>, t.IntersectionC<[t.ExactC<t.IntersectionC<[t.TypeC<{
1564
1555
  embed_url: t.StringC;
1565
1556
  type: t.StringC;
@@ -2327,10 +2318,7 @@ export declare const Document: t.RecordC<t.Type<string, string, unknown>, t.Unio
2327
2318
  __TYPE__: t.LiteralC<"EmptyContent">;
2328
2319
  }>>, t.ExactC<t.TypeC<{
2329
2320
  __TYPE__: t.LiteralC<"BooleanContent">;
2330
- value: t.BooleanC; /**
2331
- * `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
2332
- * format used by Prismic DB, therefore, this function itself is not "legacy".
2333
- */
2321
+ value: t.BooleanC;
2334
2322
  }>>, t.IntersectionC<[t.ExactC<t.IntersectionC<[t.TypeC<{
2335
2323
  embed_url: t.StringC;
2336
2324
  type: t.StringC;
@@ -3097,10 +3085,7 @@ export declare const Document: t.RecordC<t.Type<string, string, unknown>, t.Unio
3097
3085
  __TYPE__: t.LiteralC<"EmptyContent">;
3098
3086
  }>>, t.ExactC<t.TypeC<{
3099
3087
  __TYPE__: t.LiteralC<"BooleanContent">;
3100
- value: t.BooleanC; /**
3101
- * `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
3102
- * format used by Prismic DB, therefore, this function itself is not "legacy".
3103
- */
3088
+ value: t.BooleanC;
3104
3089
  }>>, t.IntersectionC<[t.ExactC<t.IntersectionC<[t.TypeC<{
3105
3090
  embed_url: t.StringC;
3106
3091
  type: t.StringC;
@@ -3865,10 +3850,7 @@ export declare const Document: t.RecordC<t.Type<string, string, unknown>, t.Unio
3865
3850
  __TYPE__: t.LiteralC<"EmptyContent">;
3866
3851
  }>>, t.ExactC<t.TypeC<{
3867
3852
  __TYPE__: t.LiteralC<"BooleanContent">;
3868
- value: t.BooleanC; /**
3869
- * `DocumentLegacyCodec` handles decoding and encoding documents to the legacy
3870
- * format used by Prismic DB, therefore, this function itself is not "legacy".
3871
- */
3853
+ value: t.BooleanC;
3872
3854
  }>>, t.IntersectionC<[t.ExactC<t.IntersectionC<[t.TypeC<{
3873
3855
  embed_url: t.StringC;
3874
3856
  type: t.StringC;
@@ -8,6 +8,7 @@ const function_1 = require("fp-ts/lib/function");
8
8
  const t = (0, tslib_1.__importStar)(require("io-ts"));
9
9
  const utils_1 = require("../_internal/utils");
10
10
  const common_1 = require("../common");
11
+ const UUID_1 = require("../common/UUID");
11
12
  const customtypes_1 = require("../customtypes");
12
13
  const fields_1 = require("./fields");
13
14
  const LegacyContentCtx_1 = require("./LegacyContentCtx");
@@ -55,7 +56,7 @@ function extractMetadata(data) {
55
56
  }
56
57
  }
57
58
  if (k.endsWith("_KEY")) {
58
- const decodedValue = t.string.decode(v);
59
+ const decodedValue = UUID_1.UUID.decode(v);
59
60
  if ((0, Either_1.isRight)(decodedValue)) {
60
61
  return {
61
62
  ...acc,
@@ -165,17 +165,20 @@ function collectSharedSlices(customType) {
165
165
  exports.collectSharedSlices = collectSharedSlices;
166
166
  function traverseCustomType(args) {
167
167
  const { customType, onField } = args;
168
- const json = {};
168
+ let json;
169
169
  for (const [key, section] of Object.entries(customType.json)) {
170
- json[key] = (0, Section_1.traverseSection)({
170
+ const newSection = (0, Section_1.traverseSection)({
171
171
  path: [key],
172
172
  section,
173
173
  onField,
174
174
  });
175
+ if (newSection !== section) {
176
+ if (!json)
177
+ json = { ...customType.json };
178
+ json[key] = newSection;
179
+ }
175
180
  }
176
- return {
177
- ...customType,
178
- json,
179
- };
181
+ // returns the traversed model instead of a new one if it didn't change
182
+ return json ? { ...customType, json } : customType;
180
183
  }
181
184
  exports.traverseCustomType = traverseCustomType;
@@ -22,7 +22,7 @@ exports.Sections = {
22
22
  };
23
23
  function traverseSection(args) {
24
24
  const { path: prevPath, section: prevSection, onField } = args;
25
- const section = { ...prevSection };
25
+ let section;
26
26
  for (const [key, prevModel] of Object.entries(prevSection)) {
27
27
  const path = [...prevPath, key];
28
28
  let model;
@@ -54,8 +54,13 @@ function traverseSection(args) {
54
54
  });
55
55
  break;
56
56
  }
57
- section[key] = model;
57
+ if (model !== prevModel) {
58
+ if (!section)
59
+ section = { ...prevSection };
60
+ section[key] = model;
61
+ }
58
62
  }
59
- return section;
63
+ // returns the traversed model instead of a new one if it didn't change
64
+ return section !== null && section !== void 0 ? section : prevSection;
60
65
  }
61
66
  exports.traverseSection = traverseSection;
@@ -36,22 +36,22 @@ function traverseNestedGroup(args) {
36
36
  const { path: prevPath, group, onField } = args;
37
37
  if (!((_a = group.config) === null || _a === void 0 ? void 0 : _a.fields))
38
38
  return group;
39
- const fields = {};
40
- for (const [key, prevField] of Object.entries(group.config.fields)) {
39
+ let fields;
40
+ for (const [key, field] of Object.entries(group.config.fields)) {
41
41
  const path = [...prevPath, key];
42
- fields[key] = onField({
42
+ const newField = onField({
43
43
  path,
44
44
  key,
45
- field: prevField,
45
+ field,
46
46
  });
47
+ if (field !== newField) {
48
+ if (!fields)
49
+ fields = { ...group.config.fields };
50
+ fields[key] = newField;
51
+ }
47
52
  }
48
- return {
49
- ...group,
50
- config: {
51
- ...group.config,
52
- fields,
53
- },
54
- };
53
+ // returns the traversed model instead of a new one if it didn't change
54
+ return fields ? { ...group, config: { ...group.config, fields } } : group;
55
55
  }
56
56
  exports.traverseNestedGroup = traverseNestedGroup;
57
57
  function traverseGroup(args) {
@@ -59,7 +59,7 @@ function traverseGroup(args) {
59
59
  const { path: prevPath, group, onField } = args;
60
60
  if (!((_a = group.config) === null || _a === void 0 ? void 0 : _a.fields))
61
61
  return group;
62
- const fields = {};
62
+ let fields;
63
63
  for (const [key, prevField] of Object.entries(group.config.fields)) {
64
64
  const path = [...prevPath, key];
65
65
  let field;
@@ -75,18 +75,18 @@ function traverseGroup(args) {
75
75
  field = prevField;
76
76
  break;
77
77
  }
78
- fields[key] = onField({
78
+ const newField = onField({
79
79
  path,
80
80
  key,
81
81
  field,
82
82
  });
83
+ if (field !== newField) {
84
+ if (!fields)
85
+ fields = { ...group.config.fields };
86
+ fields[key] = newField;
87
+ }
83
88
  }
84
- return {
85
- ...group,
86
- config: {
87
- ...group.config,
88
- fields,
89
- },
90
- };
89
+ // returns the traversed model instead of a new one if it didn't change
90
+ return fields ? { ...group, config: { ...group.config, fields } } : group;
91
91
  }
92
92
  exports.traverseGroup = traverseGroup;
@@ -31,20 +31,33 @@ exports.isCompositeSlice = isCompositeSlice;
31
31
  function traverseCompositeSlice(args) {
32
32
  var _a, _b;
33
33
  const { path: prevPath, slice, onField } = args;
34
- const nonRepeat = {};
34
+ let nonRepeat;
35
35
  for (const [key, field] of Object.entries((_a = slice["non-repeat"]) !== null && _a !== void 0 ? _a : {})) {
36
36
  const path = [...prevPath, "non-repeat", key];
37
- nonRepeat[key] = onField({ path, key, field });
37
+ const newField = onField({ path, key, field });
38
+ if (field !== newField) {
39
+ if (!nonRepeat)
40
+ nonRepeat = { ...slice["non-repeat"] };
41
+ nonRepeat[key] = newField;
42
+ }
38
43
  }
39
- const repeat = {};
44
+ let repeat;
40
45
  for (const [key, field] of Object.entries((_b = slice.repeat) !== null && _b !== void 0 ? _b : {})) {
41
46
  const path = [...prevPath, "repeat", key];
42
- repeat[key] = onField({ path, key, field });
47
+ const newField = onField({ path, key, field });
48
+ if (field !== newField) {
49
+ if (!repeat)
50
+ repeat = { ...slice.repeat };
51
+ repeat[key] = newField;
52
+ }
43
53
  }
44
- return {
45
- ...slice,
46
- ...(slice["non-repeat"] && { "non-repeat": nonRepeat }),
47
- ...(slice.repeat && { repeat }),
48
- };
54
+ // returns the traversed model instead of a new one if it didn't change
55
+ return repeat || nonRepeat
56
+ ? {
57
+ ...slice,
58
+ ...(nonRepeat && { "non-repeat": nonRepeat }),
59
+ ...(repeat && { repeat }),
60
+ }
61
+ : slice;
49
62
  }
50
63
  exports.traverseCompositeSlice = traverseCompositeSlice;
@@ -50,7 +50,7 @@ exports.isDynamicSharedSlice = isDynamicSharedSlice;
50
50
  function traverseVariation(args) {
51
51
  var _a, _b;
52
52
  const { path: prevPath, variation, onField } = args;
53
- const primary = {};
53
+ let primary;
54
54
  for (const [key, prevField] of Object.entries((_a = variation.primary) !== null && _a !== void 0 ? _a : {})) {
55
55
  const path = [...prevPath, "primary", key];
56
56
  let field;
@@ -66,34 +66,53 @@ function traverseVariation(args) {
66
66
  field = prevField;
67
67
  break;
68
68
  }
69
- primary[key] = onField({ path, key, field });
69
+ const newField = onField({ path, key, field });
70
+ if (field !== newField) {
71
+ if (!primary)
72
+ primary = { ...variation.primary };
73
+ primary[key] = newField;
74
+ }
70
75
  }
71
- const items = {};
72
- for (const [key, field] of Object.entries((_b = variation.items) !== null && _b !== void 0 ? _b : {})) {
76
+ let items;
77
+ for (const [key, prevField] of Object.entries((_b = variation.items) !== null && _b !== void 0 ? _b : {})) {
73
78
  const path = [...prevPath, "items", key];
74
- items[key] = onField({ path, key, field });
79
+ const newField = onField({
80
+ path,
81
+ key,
82
+ field: prevField,
83
+ });
84
+ if (prevField !== newField) {
85
+ if (!items)
86
+ items = { ...variation.items };
87
+ items[key] = newField;
88
+ }
75
89
  }
76
- return {
77
- ...variation,
78
- ...(variation.primary && { primary }),
79
- ...(variation.items && { items }),
80
- };
90
+ // returns the traversed model instead of a new one if it didn't change
91
+ return primary || items
92
+ ? { ...variation, ...(primary && { primary }), ...(items && { items }) }
93
+ : variation;
81
94
  }
82
95
  exports.traverseVariation = traverseVariation;
83
96
  function traverseSharedSlice(args) {
84
97
  const { path: prevPath, slice, onField } = args;
85
- const variations = [];
86
- for (const variation of slice.variations) {
98
+ let variations;
99
+ for (let i = 0; i < slice.variations.length; i++) {
100
+ const variation = slice.variations[i];
101
+ if (!variation)
102
+ continue;
87
103
  const path = [...prevPath, variation.id];
88
- variations.push(traverseVariation({
104
+ const newVariation = traverseVariation({
89
105
  path,
90
106
  variation,
91
107
  onField,
92
- }));
108
+ });
109
+ if (newVariation !== variation) {
110
+ if (!variations)
111
+ variations = [...slice.variations];
112
+ variations[i] = newVariation;
113
+ }
93
114
  }
94
- return {
95
- ...slice,
96
- variations,
97
- };
115
+ // returns the traversed model instead of a new one if it didn't change
116
+ return variations ? { ...slice, variations } : slice;
98
117
  }
99
118
  exports.traverseSharedSlice = traverseSharedSlice;
@@ -84,7 +84,7 @@ function traverseSlices(args) {
84
84
  const { path: prevPath, slices, onField } = args;
85
85
  if (!((_a = slices.config) === null || _a === void 0 ? void 0 : _a.choices))
86
86
  return slices;
87
- const choices = {};
87
+ let choices;
88
88
  for (const [key, prevModel] of Object.entries(slices.config.choices)) {
89
89
  const path = [...prevPath, key];
90
90
  let model;
@@ -126,14 +126,21 @@ function traverseSlices(args) {
126
126
  });
127
127
  break;
128
128
  }
129
- choices[key] = model;
129
+ if (model !== prevModel) {
130
+ if (!choices)
131
+ choices = { ...slices.config.choices };
132
+ choices[key] = model;
133
+ }
130
134
  }
131
- return {
132
- ...slices,
133
- config: {
134
- ...slices.config,
135
- choices,
136
- },
137
- };
135
+ // returns the traversed model instead of a new one if it didn't change
136
+ return choices
137
+ ? {
138
+ ...slices,
139
+ config: {
140
+ ...slices.config,
141
+ choices,
142
+ },
143
+ }
144
+ : slices;
138
145
  }
139
146
  exports.traverseSlices = traverseSlices;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismicio/types-internal",
3
- "version": "3.12.0-alpha.1",
3
+ "version": "3.12.0",
4
4
  "description": "Prismic types for Custom Types and Prismic Data",
5
5
  "keywords": [
6
6
  "typescript",
@@ -9,6 +9,7 @@ import {
9
9
  TraverseWidgetContentFn,
10
10
  } from "../_internal/utils"
11
11
  import { WidgetKey } from "../common"
12
+ import { UUID } from "../common/UUID"
12
13
  import {
13
14
  type StaticWidget,
14
15
  collectSharedSlices,
@@ -114,7 +115,7 @@ function extractMetadata(data: { [p: string]: unknown }): {
114
115
  }
115
116
  }
116
117
  if (k.endsWith("_KEY")) {
117
- const decodedValue = t.string.decode(v)
118
+ const decodedValue = UUID.decode(v)
118
119
  if (isRight(decodedValue)) {
119
120
  return {
120
121
  ...acc,
@@ -261,17 +261,20 @@ export function traverseCustomType<
261
261
  }): T {
262
262
  const { customType, onField } = args
263
263
 
264
- const json: Record<string, typeof customType.json[string]> = {}
264
+ let json: Record<string, typeof customType.json[string]> | undefined
265
265
  for (const [key, section] of Object.entries(customType.json)) {
266
- json[key] = traverseSection({
266
+ const newSection = traverseSection({
267
267
  path: [key],
268
268
  section,
269
269
  onField,
270
270
  })
271
- }
272
271
 
273
- return {
274
- ...customType,
275
- json,
272
+ if (newSection !== section) {
273
+ if (!json) json = { ...customType.json }
274
+ json[key] = newSection
275
+ }
276
276
  }
277
+
278
+ // returns the traversed model instead of a new one if it didn't change
279
+ return json ? { ...customType, json } : customType
277
280
  }
@@ -52,7 +52,7 @@ export function traverseSection<
52
52
  }): T {
53
53
  const { path: prevPath, section: prevSection, onField } = args
54
54
 
55
- const section = { ...prevSection }
55
+ let section: T | undefined
56
56
  for (const [key, prevModel] of Object.entries(prevSection)) {
57
57
  const path = [...prevPath, key]
58
58
  let model
@@ -84,7 +84,13 @@ export function traverseSection<
84
84
  })
85
85
  break
86
86
  }
87
- section[key] = model
87
+
88
+ if (model !== prevModel) {
89
+ if (!section) section = { ...prevSection }
90
+ section[key] = model
91
+ }
88
92
  }
89
- return section
93
+
94
+ // returns the traversed model instead of a new one if it didn't change
95
+ return section ?? prevSection
90
96
  }
@@ -58,23 +58,23 @@ export function traverseNestedGroup(args: {
58
58
 
59
59
  if (!group.config?.fields) return group
60
60
 
61
- const fields: Record<string, NestableWidget> = {}
62
- for (const [key, prevField] of Object.entries(group.config.fields)) {
61
+ let fields: Record<string, NestableWidget> | undefined
62
+ for (const [key, field] of Object.entries(group.config.fields)) {
63
63
  const path = [...prevPath, key]
64
- fields[key] = onField({
64
+ const newField = onField({
65
65
  path,
66
66
  key,
67
- field: prevField,
67
+ field,
68
68
  })
69
- }
70
69
 
71
- return {
72
- ...group,
73
- config: {
74
- ...group.config,
75
- fields,
76
- },
70
+ if (field !== newField) {
71
+ if (!fields) fields = { ...group.config.fields }
72
+ fields[key] = newField
73
+ }
77
74
  }
75
+
76
+ // returns the traversed model instead of a new one if it didn't change
77
+ return fields ? { ...group, config: { ...group.config, fields } } : group
78
78
  }
79
79
 
80
80
  export function traverseGroup(args: {
@@ -86,7 +86,7 @@ export function traverseGroup(args: {
86
86
 
87
87
  if (!group.config?.fields) return group
88
88
 
89
- const fields: Record<string, NestableWidget | NestedGroup> = {}
89
+ let fields: Record<string, NestableWidget | NestedGroup> | undefined
90
90
  for (const [key, prevField] of Object.entries(group.config.fields)) {
91
91
  const path = [...prevPath, key]
92
92
  let field
@@ -102,18 +102,19 @@ export function traverseGroup(args: {
102
102
  field = prevField
103
103
  break
104
104
  }
105
- fields[key] = onField({
105
+
106
+ const newField = onField({
106
107
  path,
107
108
  key,
108
109
  field,
109
110
  })
110
- }
111
111
 
112
- return {
113
- ...group,
114
- config: {
115
- ...group.config,
116
- fields,
117
- },
112
+ if (field !== newField) {
113
+ if (!fields) fields = { ...group.config.fields }
114
+ fields[key] = newField
115
+ }
118
116
  }
117
+
118
+ // returns the traversed model instead of a new one if it didn't change
119
+ return fields ? { ...group, config: { ...group.config, fields } } : group
119
120
  }
@@ -46,21 +46,34 @@ export function traverseCompositeSlice(args: {
46
46
  }): CompositeSlice {
47
47
  const { path: prevPath, slice, onField } = args
48
48
 
49
- const nonRepeat: Record<string, NestableWidget> = {}
49
+ let nonRepeat: Record<string, NestableWidget> | undefined
50
50
  for (const [key, field] of Object.entries(slice["non-repeat"] ?? {})) {
51
51
  const path = [...prevPath, "non-repeat", key]
52
- nonRepeat[key] = onField({ path, key, field })
52
+ const newField = onField({ path, key, field })
53
+
54
+ if (field !== newField) {
55
+ if (!nonRepeat) nonRepeat = { ...slice["non-repeat"] }
56
+ nonRepeat[key] = newField
57
+ }
53
58
  }
54
59
 
55
- const repeat: Record<string, NestableWidget> = {}
60
+ let repeat: Record<string, NestableWidget> | undefined
56
61
  for (const [key, field] of Object.entries(slice.repeat ?? {})) {
57
62
  const path = [...prevPath, "repeat", key]
58
- repeat[key] = onField({ path, key, field })
59
- }
63
+ const newField = onField({ path, key, field })
60
64
 
61
- return {
62
- ...slice,
63
- ...(slice["non-repeat"] && { "non-repeat": nonRepeat }),
64
- ...(slice.repeat && { repeat }),
65
+ if (field !== newField) {
66
+ if (!repeat) repeat = { ...slice.repeat }
67
+ repeat[key] = newField
68
+ }
65
69
  }
70
+
71
+ // returns the traversed model instead of a new one if it didn't change
72
+ return repeat || nonRepeat
73
+ ? {
74
+ ...slice,
75
+ ...(nonRepeat && { "non-repeat": nonRepeat }),
76
+ ...(repeat && { repeat }),
77
+ }
78
+ : slice
66
79
  }
@@ -79,7 +79,7 @@ export function traverseVariation(args: {
79
79
  }): Variation {
80
80
  const { path: prevPath, variation, onField } = args
81
81
 
82
- const primary: Record<string, NestableWidget | Group> = {}
82
+ let primary: Record<string, NestableWidget | Group> | undefined
83
83
  for (const [key, prevField] of Object.entries(variation.primary ?? {})) {
84
84
  const path = [...prevPath, "primary", key]
85
85
  let field
@@ -95,20 +95,32 @@ export function traverseVariation(args: {
95
95
  field = prevField
96
96
  break
97
97
  }
98
- primary[key] = onField({ path, key, field })
98
+
99
+ const newField = onField({ path, key, field })
100
+ if (field !== newField) {
101
+ if (!primary) primary = { ...variation.primary }
102
+ primary[key] = newField
103
+ }
99
104
  }
100
105
 
101
- const items: Record<string, NestableWidget> = {}
102
- for (const [key, field] of Object.entries(variation.items ?? {})) {
106
+ let items: Record<string, NestableWidget> | undefined
107
+ for (const [key, prevField] of Object.entries(variation.items ?? {})) {
103
108
  const path = [...prevPath, "items", key]
104
- items[key] = (onField as OnFieldFn<NestableWidget>)({ path, key, field })
109
+ const newField = (onField as OnFieldFn<NestableWidget>)({
110
+ path,
111
+ key,
112
+ field: prevField,
113
+ })
114
+ if (prevField !== newField) {
115
+ if (!items) items = { ...variation.items }
116
+ items[key] = newField
117
+ }
105
118
  }
106
119
 
107
- return {
108
- ...variation,
109
- ...(variation.primary && { primary }),
110
- ...(variation.items && { items }),
111
- }
120
+ // returns the traversed model instead of a new one if it didn't change
121
+ return primary || items
122
+ ? { ...variation, ...(primary && { primary }), ...(items && { items }) }
123
+ : variation
112
124
  }
113
125
 
114
126
  export function traverseSharedSlice(args: {
@@ -118,20 +130,23 @@ export function traverseSharedSlice(args: {
118
130
  }): SharedSlice {
119
131
  const { path: prevPath, slice, onField } = args
120
132
 
121
- const variations: Variation[] = []
122
- for (const variation of slice.variations) {
133
+ let variations: Variation[] | undefined
134
+ for (let i = 0; i < slice.variations.length; i++) {
135
+ const variation = slice.variations[i]
136
+ if (!variation) continue
123
137
  const path = [...prevPath, variation.id]
124
- variations.push(
125
- traverseVariation({
126
- path,
127
- variation,
128
- onField,
129
- }),
130
- )
138
+ const newVariation = traverseVariation({
139
+ path,
140
+ variation,
141
+ onField,
142
+ })
143
+
144
+ if (newVariation !== variation) {
145
+ if (!variations) variations = [...slice.variations]
146
+ variations[i] = newVariation
147
+ }
131
148
  }
132
149
 
133
- return {
134
- ...slice,
135
- variations,
136
- }
150
+ // returns the traversed model instead of a new one if it didn't change
151
+ return variations ? { ...slice, variations } : slice
137
152
  }