@modern-js/plugin-garfish 2.68.19-alpha.2 → 2.68.19-alpha.4

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.
@@ -55,13 +55,19 @@ function pathJoin(...args) {
55
55
  }, "");
56
56
  return res || "/";
57
57
  }
58
- function deepEqualExcludeFunctions(prev, next) {
58
+ function deepEqualExcludeFunctions(prev, next, visited) {
59
59
  if (prev === next)
60
60
  return true;
61
61
  if (!prev || !next)
62
62
  return false;
63
63
  if (typeof prev !== "object" || typeof next !== "object")
64
64
  return false;
65
+ const visitedSet = visited !== null && visited !== void 0 ? visited : /* @__PURE__ */ new WeakSet();
66
+ if (visitedSet.has(prev) || visitedSet.has(next)) {
67
+ return true;
68
+ }
69
+ visitedSet.add(prev);
70
+ visitedSet.add(next);
65
71
  const prevKeys = Object.keys(prev).filter((key) => typeof prev[key] !== "function");
66
72
  const nextKeys = Object.keys(next).filter((key) => typeof next[key] !== "function");
67
73
  if (prevKeys.length !== nextKeys.length)
@@ -75,7 +81,7 @@ function deepEqualExcludeFunctions(prev, next) {
75
81
  continue;
76
82
  }
77
83
  if (typeof prevVal === "object" && typeof nextVal === "object") {
78
- if (!deepEqualExcludeFunctions(prevVal, nextVal)) {
84
+ if (!deepEqualExcludeFunctions(prevVal, nextVal, visitedSet)) {
79
85
  return false;
80
86
  }
81
87
  } else if (prevVal !== nextVal) {
@@ -96,6 +102,7 @@ function getAppInstance(options, appInfo, manifest) {
96
102
  const previousPropsRef = (0, import_react.useRef)(props);
97
103
  const propsUpdateCounterRef = (0, import_react.useRef)(0);
98
104
  const domId = (0, import_util.generateSubAppContainerKey)(appInfo);
105
+ const componentRef = (0, import_react.useRef)(null);
99
106
  const [{ component: SubModuleComponent, isFromJupiter }, setSubModuleComponent] = (0, import_react.useState)({
100
107
  component: null,
101
108
  isFromJupiter: false
@@ -112,6 +119,8 @@ function getAppInstance(options, appInfo, manifest) {
112
119
  const useHistory = (_props_useHistory = props.useHistory) !== null && _props_useHistory !== void 0 ? _props_useHistory : context === null || context === void 0 ? void 0 : (_context_router3 = context.router) === null || _context_router3 === void 0 ? void 0 : _context_router3.useHistory;
113
120
  var _props_useHistory1;
114
121
  const useHref = (_props_useHistory1 = props.useHistory) !== null && _props_useHistory1 !== void 0 ? _props_useHistory1 : context === null || context === void 0 ? void 0 : (_context_router4 = context.router) === null || _context_router4 === void 0 ? void 0 : _context_router4.useHref;
122
+ const lastPropsUpdateKeyRef = (0, import_react.useRef)(0);
123
+ const isRemountingRef = (0, import_react.useRef)(false);
115
124
  const match = useRouteMatch === null || useRouteMatch === void 0 ? void 0 : useRouteMatch();
116
125
  const matchs = useMatches === null || useMatches === void 0 ? void 0 : useMatches();
117
126
  if (!useLocation) {
@@ -168,12 +177,24 @@ or directly pass the "basename":
168
177
  locationPathname
169
178
  ]);
170
179
  (0, import_react.useEffect)(() => {
180
+ if (previousPropsRef.current === props) {
181
+ return;
182
+ }
171
183
  const prevPropsForCompare = {
172
184
  ...previousPropsRef.current
173
185
  };
174
186
  const currentPropsForCompare = {
175
187
  ...props
176
188
  };
189
+ const ignoredKeysForRemount = [
190
+ "style",
191
+ "location",
192
+ "match",
193
+ "history",
194
+ "staticContext",
195
+ "guideState",
196
+ "guideConfig"
197
+ ];
177
198
  Object.keys(prevPropsForCompare).forEach((key) => {
178
199
  if (typeof prevPropsForCompare[key] === "function") {
179
200
  delete prevPropsForCompare[key];
@@ -184,11 +205,27 @@ or directly pass the "basename":
184
205
  delete currentPropsForCompare[key];
185
206
  }
186
207
  });
187
- if (!deepEqualExcludeFunctions(prevPropsForCompare, currentPropsForCompare)) {
208
+ const prevPropsForDeepCompare = {};
209
+ const currentPropsForDeepCompare = {};
210
+ Object.keys(prevPropsForCompare).forEach((key) => {
211
+ if (!ignoredKeysForRemount.includes(key)) {
212
+ prevPropsForDeepCompare[key] = prevPropsForCompare[key];
213
+ }
214
+ });
215
+ Object.keys(currentPropsForCompare).forEach((key) => {
216
+ if (!ignoredKeysForRemount.includes(key)) {
217
+ currentPropsForDeepCompare[key] = currentPropsForCompare[key];
218
+ }
219
+ });
220
+ const propsEqual = deepEqualExcludeFunctions(prevPropsForDeepCompare, currentPropsForDeepCompare);
221
+ if (!propsEqual) {
188
222
  previousPropsRef.current = props;
189
223
  propsRef.current = props;
190
224
  propsUpdateCounterRef.current += 1;
191
225
  setPropsUpdateKey((prev) => prev + 1);
226
+ } else {
227
+ previousPropsRef.current = props;
228
+ propsRef.current = props;
192
229
  }
193
230
  }, [
194
231
  props,
@@ -219,6 +256,7 @@ or directly pass the "basename":
219
256
  mount: (...props2) => {
220
257
  if (componetRenderMode && SubComponent) {
221
258
  if (componentSetterRegistry.current) {
259
+ componentRef.current = SubComponent;
222
260
  componentSetterRegistry.current({
223
261
  component: SubComponent,
224
262
  isFromJupiter: isFromJupiter2
@@ -315,6 +353,46 @@ or directly pass the "basename":
315
353
  propsUpdateKey,
316
354
  props
317
355
  ]);
356
+ (0, import_react.useEffect)(() => {
357
+ var _appRef_current;
358
+ const componetRenderMode = manifest === null || manifest === void 0 ? void 0 : manifest.componentRender;
359
+ if (propsUpdateKey === lastPropsUpdateKeyRef.current || isRemountingRef.current) {
360
+ return;
361
+ }
362
+ lastPropsUpdateKeyRef.current = propsUpdateKey;
363
+ if (componetRenderMode && ((_appRef_current = appRef.current) === null || _appRef_current === void 0 ? void 0 : _appRef_current.mounted)) {
364
+ const componentToUse = SubModuleComponent || componentRef.current;
365
+ if (componentToUse) {
366
+ const currentComponent = componentToUse;
367
+ const currentIsFromJupiter = isFromJupiter;
368
+ setSubModuleComponent({
369
+ component: null,
370
+ isFromJupiter: false
371
+ });
372
+ setTimeout(() => {
373
+ setSubModuleComponent({
374
+ component: currentComponent,
375
+ isFromJupiter: currentIsFromJupiter
376
+ });
377
+ }, 50);
378
+ } else {
379
+ var _appRef_current1;
380
+ if ((_appRef_current1 = appRef.current) === null || _appRef_current1 === void 0 ? void 0 : _appRef_current1.mounted) {
381
+ var _appRef_current2;
382
+ (_appRef_current2 = appRef.current) === null || _appRef_current2 === void 0 ? void 0 : _appRef_current2.hide();
383
+ setTimeout(() => {
384
+ var _appRef_current3;
385
+ (_appRef_current3 = appRef.current) === null || _appRef_current3 === void 0 ? void 0 : _appRef_current3.show();
386
+ setTimeout(() => {
387
+ isRemountingRef.current = false;
388
+ }, 100);
389
+ }, 10);
390
+ }
391
+ }
392
+ }
393
+ }, [
394
+ propsUpdateKey
395
+ ]);
318
396
  const { setLoadingState, ...renderProps } = props;
319
397
  const finalRenderProps = {
320
398
  ...renderProps,
@@ -32,13 +32,19 @@ function pathJoin() {
32
32
  }, "");
33
33
  return res || "/";
34
34
  }
35
- function deepEqualExcludeFunctions(prev, next) {
35
+ function deepEqualExcludeFunctions(prev, next, visited) {
36
36
  if (prev === next)
37
37
  return true;
38
38
  if (!prev || !next)
39
39
  return false;
40
40
  if ((typeof prev === "undefined" ? "undefined" : _type_of(prev)) !== "object" || (typeof next === "undefined" ? "undefined" : _type_of(next)) !== "object")
41
41
  return false;
42
+ var visitedSet = visited !== null && visited !== void 0 ? visited : /* @__PURE__ */ new WeakSet();
43
+ if (visitedSet.has(prev) || visitedSet.has(next)) {
44
+ return true;
45
+ }
46
+ visitedSet.add(prev);
47
+ visitedSet.add(next);
42
48
  var prevKeys = Object.keys(prev).filter(function(key2) {
43
49
  return typeof prev[key2] !== "function";
44
50
  });
@@ -59,7 +65,7 @@ function deepEqualExcludeFunctions(prev, next) {
59
65
  continue;
60
66
  }
61
67
  if ((typeof prevVal === "undefined" ? "undefined" : _type_of(prevVal)) === "object" && (typeof nextVal === "undefined" ? "undefined" : _type_of(nextVal)) === "object") {
62
- if (!deepEqualExcludeFunctions(prevVal, nextVal)) {
68
+ if (!deepEqualExcludeFunctions(prevVal, nextVal, visitedSet)) {
63
69
  return false;
64
70
  }
65
71
  } else if (prevVal !== nextVal) {
@@ -94,6 +100,7 @@ function getAppInstance(options, appInfo, manifest) {
94
100
  var previousPropsRef = useRef(props);
95
101
  var propsUpdateCounterRef = useRef(0);
96
102
  var domId = generateSubAppContainerKey(appInfo);
103
+ var componentRef = useRef(null);
97
104
  var _useState = _sliced_to_array(useState({
98
105
  component: null,
99
106
  isFromJupiter: false
@@ -110,6 +117,8 @@ function getAppInstance(options, appInfo, manifest) {
110
117
  var useHistory = (_props_useHistory = props.useHistory) !== null && _props_useHistory !== void 0 ? _props_useHistory : context === null || context === void 0 ? void 0 : (_context_router3 = context.router) === null || _context_router3 === void 0 ? void 0 : _context_router3.useHistory;
111
118
  var _props_useHistory1;
112
119
  var useHref = (_props_useHistory1 = props.useHistory) !== null && _props_useHistory1 !== void 0 ? _props_useHistory1 : context === null || context === void 0 ? void 0 : (_context_router4 = context.router) === null || _context_router4 === void 0 ? void 0 : _context_router4.useHref;
120
+ var lastPropsUpdateKeyRef = useRef(0);
121
+ var isRemountingRef = useRef(false);
113
122
  var match = useRouteMatch === null || useRouteMatch === void 0 ? void 0 : useRouteMatch();
114
123
  var matchs = useMatches === null || useMatches === void 0 ? void 0 : useMatches();
115
124
  if (!useLocation) {
@@ -164,8 +173,20 @@ or directly pass the "basename":
164
173
  locationPathname
165
174
  ]);
166
175
  useEffect(function() {
176
+ if (previousPropsRef.current === props) {
177
+ return;
178
+ }
167
179
  var prevPropsForCompare = _object_spread({}, previousPropsRef.current);
168
180
  var currentPropsForCompare = _object_spread({}, props);
181
+ var ignoredKeysForRemount = [
182
+ "style",
183
+ "location",
184
+ "match",
185
+ "history",
186
+ "staticContext",
187
+ "guideState",
188
+ "guideConfig"
189
+ ];
169
190
  Object.keys(prevPropsForCompare).forEach(function(key2) {
170
191
  if (typeof prevPropsForCompare[key2] === "function") {
171
192
  delete prevPropsForCompare[key2];
@@ -176,13 +197,29 @@ or directly pass the "basename":
176
197
  delete currentPropsForCompare[key2];
177
198
  }
178
199
  });
179
- if (!deepEqualExcludeFunctions(prevPropsForCompare, currentPropsForCompare)) {
200
+ var prevPropsForDeepCompare = {};
201
+ var currentPropsForDeepCompare = {};
202
+ Object.keys(prevPropsForCompare).forEach(function(key2) {
203
+ if (!ignoredKeysForRemount.includes(key2)) {
204
+ prevPropsForDeepCompare[key2] = prevPropsForCompare[key2];
205
+ }
206
+ });
207
+ Object.keys(currentPropsForCompare).forEach(function(key2) {
208
+ if (!ignoredKeysForRemount.includes(key2)) {
209
+ currentPropsForDeepCompare[key2] = currentPropsForCompare[key2];
210
+ }
211
+ });
212
+ var propsEqual = deepEqualExcludeFunctions(prevPropsForDeepCompare, currentPropsForDeepCompare);
213
+ if (!propsEqual) {
180
214
  previousPropsRef.current = props;
181
215
  propsRef.current = props;
182
216
  propsUpdateCounterRef.current += 1;
183
217
  setPropsUpdateKey(function(prev) {
184
218
  return prev + 1;
185
219
  });
220
+ } else {
221
+ previousPropsRef.current = props;
222
+ propsRef.current = props;
186
223
  }
187
224
  }, [
188
225
  props,
@@ -217,6 +254,7 @@ or directly pass the "basename":
217
254
  }
218
255
  if (componetRenderMode && SubComponent) {
219
256
  if (componentSetterRegistry.current) {
257
+ componentRef.current = SubComponent;
220
258
  componentSetterRegistry.current({
221
259
  component: SubComponent,
222
260
  isFromJupiter: isFromJupiter2
@@ -366,6 +404,46 @@ or directly pass the "basename":
366
404
  propsUpdateKey,
367
405
  props
368
406
  ]);
407
+ useEffect(function() {
408
+ var _appRef_current;
409
+ var componetRenderMode = manifest === null || manifest === void 0 ? void 0 : manifest.componentRender;
410
+ if (propsUpdateKey === lastPropsUpdateKeyRef.current || isRemountingRef.current) {
411
+ return;
412
+ }
413
+ lastPropsUpdateKeyRef.current = propsUpdateKey;
414
+ if (componetRenderMode && ((_appRef_current = appRef.current) === null || _appRef_current === void 0 ? void 0 : _appRef_current.mounted)) {
415
+ var componentToUse = SubModuleComponent || componentRef.current;
416
+ if (componentToUse) {
417
+ var currentComponent = componentToUse;
418
+ var currentIsFromJupiter = isFromJupiter;
419
+ setSubModuleComponent({
420
+ component: null,
421
+ isFromJupiter: false
422
+ });
423
+ setTimeout(function() {
424
+ setSubModuleComponent({
425
+ component: currentComponent,
426
+ isFromJupiter: currentIsFromJupiter
427
+ });
428
+ }, 50);
429
+ } else {
430
+ var _appRef_current1;
431
+ if ((_appRef_current1 = appRef.current) === null || _appRef_current1 === void 0 ? void 0 : _appRef_current1.mounted) {
432
+ var _appRef_current2;
433
+ (_appRef_current2 = appRef.current) === null || _appRef_current2 === void 0 ? void 0 : _appRef_current2.hide();
434
+ setTimeout(function() {
435
+ var _appRef_current3;
436
+ (_appRef_current3 = appRef.current) === null || _appRef_current3 === void 0 ? void 0 : _appRef_current3.show();
437
+ setTimeout(function() {
438
+ isRemountingRef.current = false;
439
+ }, 100);
440
+ }, 10);
441
+ }
442
+ }
443
+ }
444
+ }, [
445
+ propsUpdateKey
446
+ ]);
369
447
  var setLoadingState = props.setLoadingState, renderProps = _object_without_properties(props, [
370
448
  "setLoadingState"
371
449
  ]);
@@ -21,13 +21,19 @@ function pathJoin(...args) {
21
21
  }, "");
22
22
  return res || "/";
23
23
  }
24
- function deepEqualExcludeFunctions(prev, next) {
24
+ function deepEqualExcludeFunctions(prev, next, visited) {
25
25
  if (prev === next)
26
26
  return true;
27
27
  if (!prev || !next)
28
28
  return false;
29
29
  if (typeof prev !== "object" || typeof next !== "object")
30
30
  return false;
31
+ const visitedSet = visited !== null && visited !== void 0 ? visited : /* @__PURE__ */ new WeakSet();
32
+ if (visitedSet.has(prev) || visitedSet.has(next)) {
33
+ return true;
34
+ }
35
+ visitedSet.add(prev);
36
+ visitedSet.add(next);
31
37
  const prevKeys = Object.keys(prev).filter((key) => typeof prev[key] !== "function");
32
38
  const nextKeys = Object.keys(next).filter((key) => typeof next[key] !== "function");
33
39
  if (prevKeys.length !== nextKeys.length)
@@ -41,7 +47,7 @@ function deepEqualExcludeFunctions(prev, next) {
41
47
  continue;
42
48
  }
43
49
  if (typeof prevVal === "object" && typeof nextVal === "object") {
44
- if (!deepEqualExcludeFunctions(prevVal, nextVal)) {
50
+ if (!deepEqualExcludeFunctions(prevVal, nextVal, visitedSet)) {
45
51
  return false;
46
52
  }
47
53
  } else if (prevVal !== nextVal) {
@@ -62,6 +68,7 @@ function getAppInstance(options, appInfo, manifest) {
62
68
  const previousPropsRef = useRef(props);
63
69
  const propsUpdateCounterRef = useRef(0);
64
70
  const domId = generateSubAppContainerKey(appInfo);
71
+ const componentRef = useRef(null);
65
72
  const [{ component: SubModuleComponent, isFromJupiter }, setSubModuleComponent] = useState({
66
73
  component: null,
67
74
  isFromJupiter: false
@@ -78,6 +85,8 @@ function getAppInstance(options, appInfo, manifest) {
78
85
  const useHistory = (_props_useHistory = props.useHistory) !== null && _props_useHistory !== void 0 ? _props_useHistory : context === null || context === void 0 ? void 0 : (_context_router3 = context.router) === null || _context_router3 === void 0 ? void 0 : _context_router3.useHistory;
79
86
  var _props_useHistory1;
80
87
  const useHref = (_props_useHistory1 = props.useHistory) !== null && _props_useHistory1 !== void 0 ? _props_useHistory1 : context === null || context === void 0 ? void 0 : (_context_router4 = context.router) === null || _context_router4 === void 0 ? void 0 : _context_router4.useHref;
88
+ const lastPropsUpdateKeyRef = useRef(0);
89
+ const isRemountingRef = useRef(false);
81
90
  const match = useRouteMatch === null || useRouteMatch === void 0 ? void 0 : useRouteMatch();
82
91
  const matchs = useMatches === null || useMatches === void 0 ? void 0 : useMatches();
83
92
  if (!useLocation) {
@@ -134,12 +143,24 @@ or directly pass the "basename":
134
143
  locationPathname
135
144
  ]);
136
145
  useEffect(() => {
146
+ if (previousPropsRef.current === props) {
147
+ return;
148
+ }
137
149
  const prevPropsForCompare = {
138
150
  ...previousPropsRef.current
139
151
  };
140
152
  const currentPropsForCompare = {
141
153
  ...props
142
154
  };
155
+ const ignoredKeysForRemount = [
156
+ "style",
157
+ "location",
158
+ "match",
159
+ "history",
160
+ "staticContext",
161
+ "guideState",
162
+ "guideConfig"
163
+ ];
143
164
  Object.keys(prevPropsForCompare).forEach((key) => {
144
165
  if (typeof prevPropsForCompare[key] === "function") {
145
166
  delete prevPropsForCompare[key];
@@ -150,11 +171,27 @@ or directly pass the "basename":
150
171
  delete currentPropsForCompare[key];
151
172
  }
152
173
  });
153
- if (!deepEqualExcludeFunctions(prevPropsForCompare, currentPropsForCompare)) {
174
+ const prevPropsForDeepCompare = {};
175
+ const currentPropsForDeepCompare = {};
176
+ Object.keys(prevPropsForCompare).forEach((key) => {
177
+ if (!ignoredKeysForRemount.includes(key)) {
178
+ prevPropsForDeepCompare[key] = prevPropsForCompare[key];
179
+ }
180
+ });
181
+ Object.keys(currentPropsForCompare).forEach((key) => {
182
+ if (!ignoredKeysForRemount.includes(key)) {
183
+ currentPropsForDeepCompare[key] = currentPropsForCompare[key];
184
+ }
185
+ });
186
+ const propsEqual = deepEqualExcludeFunctions(prevPropsForDeepCompare, currentPropsForDeepCompare);
187
+ if (!propsEqual) {
154
188
  previousPropsRef.current = props;
155
189
  propsRef.current = props;
156
190
  propsUpdateCounterRef.current += 1;
157
191
  setPropsUpdateKey((prev) => prev + 1);
192
+ } else {
193
+ previousPropsRef.current = props;
194
+ propsRef.current = props;
158
195
  }
159
196
  }, [
160
197
  props,
@@ -185,6 +222,7 @@ or directly pass the "basename":
185
222
  mount: (...props2) => {
186
223
  if (componetRenderMode && SubComponent) {
187
224
  if (componentSetterRegistry.current) {
225
+ componentRef.current = SubComponent;
188
226
  componentSetterRegistry.current({
189
227
  component: SubComponent,
190
228
  isFromJupiter: isFromJupiter2
@@ -281,6 +319,46 @@ or directly pass the "basename":
281
319
  propsUpdateKey,
282
320
  props
283
321
  ]);
322
+ useEffect(() => {
323
+ var _appRef_current;
324
+ const componetRenderMode = manifest === null || manifest === void 0 ? void 0 : manifest.componentRender;
325
+ if (propsUpdateKey === lastPropsUpdateKeyRef.current || isRemountingRef.current) {
326
+ return;
327
+ }
328
+ lastPropsUpdateKeyRef.current = propsUpdateKey;
329
+ if (componetRenderMode && ((_appRef_current = appRef.current) === null || _appRef_current === void 0 ? void 0 : _appRef_current.mounted)) {
330
+ const componentToUse = SubModuleComponent || componentRef.current;
331
+ if (componentToUse) {
332
+ const currentComponent = componentToUse;
333
+ const currentIsFromJupiter = isFromJupiter;
334
+ setSubModuleComponent({
335
+ component: null,
336
+ isFromJupiter: false
337
+ });
338
+ setTimeout(() => {
339
+ setSubModuleComponent({
340
+ component: currentComponent,
341
+ isFromJupiter: currentIsFromJupiter
342
+ });
343
+ }, 50);
344
+ } else {
345
+ var _appRef_current1;
346
+ if ((_appRef_current1 = appRef.current) === null || _appRef_current1 === void 0 ? void 0 : _appRef_current1.mounted) {
347
+ var _appRef_current2;
348
+ (_appRef_current2 = appRef.current) === null || _appRef_current2 === void 0 ? void 0 : _appRef_current2.hide();
349
+ setTimeout(() => {
350
+ var _appRef_current3;
351
+ (_appRef_current3 = appRef.current) === null || _appRef_current3 === void 0 ? void 0 : _appRef_current3.show();
352
+ setTimeout(() => {
353
+ isRemountingRef.current = false;
354
+ }, 100);
355
+ }, 10);
356
+ }
357
+ }
358
+ }
359
+ }, [
360
+ propsUpdateKey
361
+ ]);
284
362
  const { setLoadingState, ...renderProps } = props;
285
363
  const finalRenderProps = {
286
364
  ...renderProps,
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.68.19-alpha.2",
18
+ "version": "2.68.19-alpha.4",
19
19
  "jsnext:source": "./src/cli/index.ts",
20
20
  "types": "./dist/types/cli/index.d.ts",
21
21
  "typesVersions": {
@@ -93,12 +93,12 @@
93
93
  "react-dom": "^18.3.1",
94
94
  "react-router-dom": "6.27.0",
95
95
  "typescript": "^5",
96
- "@modern-js/app-tools": "2.68.18",
97
96
  "@scripts/build": "2.66.0",
97
+ "@modern-js/app-tools": "2.68.18",
98
98
  "@modern-js/core": "2.68.18",
99
- "@modern-js/plugin-router-v5": "2.68.18",
100
99
  "@modern-js/types": "2.68.18",
101
100
  "@modern-js/runtime": "2.68.18",
101
+ "@modern-js/plugin-router-v5": "2.68.18",
102
102
  "@scripts/jest-config": "2.66.0"
103
103
  },
104
104
  "sideEffects": false,