@lynx-js/react 0.111.1 → 0.111.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/components/lib/DeferredListItem.d.ts +3 -1
  3. package/components/lib/DeferredListItem.jsx +4 -2
  4. package/components/lib/DeferredListItem.jsx.map +1 -1
  5. package/components/src/DeferredListItem.tsx +5 -3
  6. package/package.json +6 -1
  7. package/refresh/.turbo/turbo-build.log +1 -1
  8. package/runtime/debug/index.cjs +8 -0
  9. package/runtime/debug/index.d.ts +4 -0
  10. package/runtime/debug/index.js +5 -0
  11. package/runtime/lib/alog/index.d.ts +1 -0
  12. package/runtime/lib/alog/index.js +8 -0
  13. package/runtime/lib/alog/index.js.map +1 -0
  14. package/runtime/lib/alog/render.d.ts +1 -0
  15. package/runtime/lib/alog/render.js +19 -0
  16. package/runtime/lib/alog/render.js.map +1 -0
  17. package/runtime/lib/backgroundSnapshot.d.ts +1 -0
  18. package/runtime/lib/backgroundSnapshot.js +31 -17
  19. package/runtime/lib/backgroundSnapshot.js.map +1 -1
  20. package/runtime/lib/debug/component-stack.d.ts +33 -0
  21. package/runtime/lib/debug/component-stack.js +145 -0
  22. package/runtime/lib/debug/component-stack.js.map +1 -0
  23. package/runtime/lib/debug/formatPatch.d.ts +2 -0
  24. package/runtime/lib/debug/formatPatch.js +27 -0
  25. package/runtime/lib/debug/formatPatch.js.map +1 -0
  26. package/runtime/lib/debug/printSnapshot.d.ts +1 -1
  27. package/runtime/lib/debug/printSnapshot.js +0 -4
  28. package/runtime/lib/debug/printSnapshot.js.map +1 -1
  29. package/runtime/lib/debug/profile.js +1 -3
  30. package/runtime/lib/debug/profile.js.map +1 -1
  31. package/runtime/lib/hydrate.js +11 -7
  32. package/runtime/lib/hydrate.js.map +1 -1
  33. package/runtime/lib/lifecycle/patch/commit.js +1 -1
  34. package/runtime/lib/lifecycle/patch/commit.js.map +1 -1
  35. package/runtime/lib/lifecycle/patch/snapshotPatch.d.ts +4 -0
  36. package/runtime/lib/lifecycle/patch/snapshotPatch.js +28 -0
  37. package/runtime/lib/lifecycle/patch/snapshotPatch.js.map +1 -1
  38. package/runtime/lib/lynx.js +9 -0
  39. package/runtime/lib/lynx.js.map +1 -1
  40. package/runtime/lib/pendingListUpdates.d.ts +2 -1
  41. package/runtime/lib/pendingListUpdates.js +16 -4
  42. package/runtime/lib/pendingListUpdates.js.map +1 -1
  43. package/runtime/lib/renderToOpcodes/constants.d.ts +2 -0
  44. package/runtime/lib/renderToOpcodes/constants.js +2 -0
  45. package/runtime/lib/renderToOpcodes/constants.js.map +1 -1
  46. package/runtime/lib/root.d.ts +6 -0
  47. package/runtime/lib/root.js +4 -0
  48. package/runtime/lib/root.js.map +1 -1
  49. package/runtime/lib/snapshot/platformInfo.js +5 -3
  50. package/runtime/lib/snapshot/platformInfo.js.map +1 -1
  51. package/runtime/lib/snapshot/ref.d.ts +2 -2
  52. package/runtime/lib/snapshot/spread.js +3 -1
  53. package/runtime/lib/snapshot/spread.js.map +1 -1
  54. package/runtime/lib/snapshot.js +13 -7
  55. package/runtime/lib/snapshot.js.map +1 -1
  56. package/runtime/lib/utils.d.ts +2 -0
  57. package/runtime/lib/utils.js +23 -2
  58. package/runtime/lib/utils.js.map +1 -1
  59. package/testing-library/dist/env/vitest.js +12 -4
  60. package/types/react.d.ts +13 -1
  61. package/runtime/src/backgroundSnapshot.ts +0 -501
  62. package/runtime/src/compat/componentIs.ts +0 -30
  63. package/runtime/src/compat/initData.ts +0 -150
  64. package/runtime/src/compat/lynxComponent.ts +0 -79
  65. package/runtime/src/debug/debug.ts +0 -9
  66. package/runtime/src/debug/printSnapshot.ts +0 -28
  67. package/runtime/src/debug/profile.ts +0 -55
  68. package/runtime/src/document.ts +0 -84
  69. package/runtime/src/gesture/processGesture.ts +0 -89
  70. package/runtime/src/gesture/processGestureBagkround.ts +0 -19
  71. package/runtime/src/gesture/types.ts +0 -44
  72. package/runtime/src/hooks/react.ts +0 -62
  73. package/runtime/src/hooks/useLynxGlobalEventListener.ts +0 -59
  74. package/runtime/src/hydrate.ts +0 -368
  75. package/runtime/src/index.ts +0 -94
  76. package/runtime/src/internal.ts +0 -63
  77. package/runtime/src/legacy-react-runtime/index.ts +0 -42
  78. package/runtime/src/lifecycle/destroy.ts +0 -34
  79. package/runtime/src/lifecycle/event/delayEvents.ts +0 -11
  80. package/runtime/src/lifecycle/event/delayLifecycleEvents.ts +0 -15
  81. package/runtime/src/lifecycle/event/jsReady.ts +0 -34
  82. package/runtime/src/lifecycle/pass.ts +0 -14
  83. package/runtime/src/lifecycle/patch/commit.ts +0 -214
  84. package/runtime/src/lifecycle/patch/error.ts +0 -61
  85. package/runtime/src/lifecycle/patch/isMainThreadHydrationFinished.ts +0 -13
  86. package/runtime/src/lifecycle/patch/snapshotPatch.ts +0 -65
  87. package/runtime/src/lifecycle/patch/snapshotPatchApply.ts +0 -145
  88. package/runtime/src/lifecycle/patch/updateMainThread.ts +0 -64
  89. package/runtime/src/lifecycle/ref/delay.ts +0 -99
  90. package/runtime/src/lifecycle/reload.ts +0 -97
  91. package/runtime/src/lifecycle/render.ts +0 -54
  92. package/runtime/src/lifecycleConstant.ts +0 -21
  93. package/runtime/src/list.ts +0 -307
  94. package/runtime/src/listUpdateInfo.ts +0 -221
  95. package/runtime/src/lynx/calledByNative.ts +0 -160
  96. package/runtime/src/lynx/component.ts +0 -113
  97. package/runtime/src/lynx/dynamic-js.ts +0 -36
  98. package/runtime/src/lynx/env.ts +0 -109
  99. package/runtime/src/lynx/injectLepusMethods.ts +0 -53
  100. package/runtime/src/lynx/lazy-bundle.ts +0 -175
  101. package/runtime/src/lynx/performance.ts +0 -148
  102. package/runtime/src/lynx/runWithForce.ts +0 -67
  103. package/runtime/src/lynx/tt.ts +0 -215
  104. package/runtime/src/lynx-api.ts +0 -455
  105. package/runtime/src/lynx.ts +0 -58
  106. package/runtime/src/opcodes.ts +0 -155
  107. package/runtime/src/pendingListUpdates.ts +0 -18
  108. package/runtime/src/renderToOpcodes/constants.ts +0 -24
  109. package/runtime/src/renderToOpcodes/index.ts +0 -306
  110. package/runtime/src/root.ts +0 -23
  111. package/runtime/src/snapshot/dynamicPartType.ts +0 -16
  112. package/runtime/src/snapshot/event.ts +0 -33
  113. package/runtime/src/snapshot/gesture.ts +0 -30
  114. package/runtime/src/snapshot/list.ts +0 -36
  115. package/runtime/src/snapshot/platformInfo.ts +0 -62
  116. package/runtime/src/snapshot/ref.ts +0 -139
  117. package/runtime/src/snapshot/spread.ts +0 -330
  118. package/runtime/src/snapshot/workletEvent.ts +0 -35
  119. package/runtime/src/snapshot/workletRef.ts +0 -88
  120. package/runtime/src/snapshot.ts +0 -634
  121. package/runtime/src/snapshotInstanceHydrationMap.ts +0 -17
  122. package/runtime/src/utils.ts +0 -44
  123. package/runtime/src/worklet/ctx.ts +0 -22
  124. package/runtime/src/worklet/destroy.ts +0 -16
  125. package/runtime/src/worklet/execMap.ts +0 -51
  126. package/runtime/src/worklet/functionCall.ts +0 -42
  127. package/runtime/src/worklet/functionality.ts +0 -29
  128. package/runtime/src/worklet/hmr.ts +0 -34
  129. package/runtime/src/worklet/indexMap.ts +0 -23
  130. package/runtime/src/worklet/runOnBackground.ts +0 -147
  131. package/runtime/src/worklet/runOnMainThread.ts +0 -50
  132. package/runtime/src/worklet/transformToWorklet.ts +0 -26
  133. package/runtime/src/worklet/workletRef.ts +0 -231
  134. package/runtime/src/worklet/workletRefPool.ts +0 -29
@@ -1,5 +1,6 @@
1
1
  import { builtinEnvironments } from "vitest/environments";
2
2
  import events from "events";
3
+ import { Console } from "console";
3
4
  function util_define(object, properties) {
4
5
  for (const name of Object.getOwnPropertyNames(properties)){
5
6
  const propDesc = Object.getOwnPropertyDescriptor(properties, name);
@@ -357,6 +358,13 @@ function createPolyfills() {
357
358
  __LoadLepusChunk
358
359
  };
359
360
  }
361
+ function createPreconfiguredConsole() {
362
+ const console1 = new Console(process.stdout, process.stderr);
363
+ console1.profile = ()=>{};
364
+ console1.profileEnd = ()=>{};
365
+ console1.alog = ()=>{};
366
+ return console1;
367
+ }
360
368
  function injectMainThreadGlobals(target, polyfills) {
361
369
  var _globalThis_onInjectMainThreadGlobals, _globalThis;
362
370
  __injectElementApi(target);
@@ -364,6 +372,7 @@ function injectMainThreadGlobals(target, polyfills) {
364
372
  if (void 0 === target) target = globalThis;
365
373
  target.__DEV__ = true;
366
374
  target.__PROFILE__ = true;
375
+ target.__ALOG__ = true;
367
376
  target.__JS__ = false;
368
377
  target.__LEPUS__ = true;
369
378
  target.__BACKGROUND__ = false;
@@ -383,8 +392,7 @@ function injectMainThreadGlobals(target, polyfills) {
383
392
  };
384
393
  target.requestAnimationFrame = setTimeout;
385
394
  target.cancelAnimationFrame = clearTimeout;
386
- target.console.profile = ()=>{};
387
- target.console.profileEnd = ()=>{};
395
+ target.console = createPreconfiguredConsole();
388
396
  target.__LoadLepusChunk = __LoadLepusChunk;
389
397
  null == (_globalThis_onInjectMainThreadGlobals = (_globalThis = globalThis).onInjectMainThreadGlobals) || _globalThis_onInjectMainThreadGlobals.call(_globalThis, target);
390
398
  }
@@ -418,6 +426,7 @@ function injectBackgroundThreadGlobals(target, polyfills) {
418
426
  if (void 0 === target) target = globalThis;
419
427
  target.__DEV__ = true;
420
428
  target.__PROFILE__ = true;
429
+ target.__ALOG__ = true;
421
430
  target.__JS__ = true;
422
431
  target.__LEPUS__ = false;
423
432
  target.__BACKGROUND__ = true;
@@ -457,8 +466,7 @@ function injectBackgroundThreadGlobals(target, polyfills) {
457
466
  };
458
467
  target.requestAnimationFrame = setTimeout;
459
468
  target.cancelAnimationFrame = clearTimeout;
460
- target.console.profile = ()=>{};
461
- target.console.profileEnd = ()=>{};
469
+ target.console = createPreconfiguredConsole();
462
470
  target.SystemInfo = {
463
471
  platform: 'iOS',
464
472
  pixelRatio: 3,
package/types/react.d.ts CHANGED
@@ -161,8 +161,20 @@ declare module '@lynx-js/types' {
161
161
  * <HeavyComponent />
162
162
  * </list-item>
163
163
  * ```
164
+ *
165
+ * @example
166
+ *
167
+ * Turn on the `unmountRecycled` switch to uninstall invisible JSX nodes.
168
+ * If they are components, related lifecycle (e.g. `componentWillUnmount` and cleanup of `useEffect`) will be executed accordingly.
169
+ * If they are intrinsic element, they will be `unref`-ed (`ref` will be set to `null` or cleanup of `ref` will be executed).
170
+ *
171
+ * ```tsx
172
+ * <list-item defer={{ unmountRecycled: true }} item-key="some-item">
173
+ * <WillBeUnmountIfRecycled />
174
+ * </list-item>
175
+ * ```
164
176
  */
165
- 'defer'?: boolean | undefined;
177
+ 'defer'?: boolean | { unmountRecycled?: boolean } | undefined;
166
178
  }
167
179
 
168
180
  export interface FrameworkRenderingTimings {
@@ -1,501 +0,0 @@
1
- // Copyright 2024 The Lynx Authors. All rights reserved.
2
- // Licensed under the Apache License Version 2.0 that can be found in the
3
- // LICENSE file in the root directory of this source tree.
4
-
5
- /**
6
- * Background snapshot implementation that runs in the background thread.
7
- *
8
- * This is the mirror of main thread's {@link SnapshotInstance}:
9
- */
10
-
11
- import type { Worklet } from '@lynx-js/react/worklet-runtime/bindings';
12
-
13
- import { processGestureBackground } from './gesture/processGestureBagkround.js';
14
- import type { GestureKind } from './gesture/types.js';
15
- import { diffArrayAction, diffArrayLepus } from './hydrate.js';
16
- import { globalBackgroundSnapshotInstancesToRemove } from './lifecycle/patch/commit.js';
17
- import type { SnapshotPatch } from './lifecycle/patch/snapshotPatch.js';
18
- import {
19
- SnapshotOperation,
20
- __globalSnapshotPatch,
21
- initGlobalSnapshotPatch,
22
- takeGlobalSnapshotPatch,
23
- } from './lifecycle/patch/snapshotPatch.js';
24
- import { globalPipelineOptions } from './lynx/performance.js';
25
- import { DynamicPartType } from './snapshot/dynamicPartType.js';
26
- import { clearQueuedRefs, queueRefAttrUpdate } from './snapshot/ref.js';
27
- import type { Ref } from './snapshot/ref.js';
28
- import { transformSpread } from './snapshot/spread.js';
29
- import type { SerializedSnapshotInstance, Snapshot } from './snapshot.js';
30
- import { backgroundSnapshotInstanceManager, snapshotManager, traverseSnapshotInstance } from './snapshot.js';
31
- import { hydrationMap } from './snapshotInstanceHydrationMap.js';
32
- import { isDirectOrDeepEqual } from './utils.js';
33
- import { onPostWorkletCtx } from './worklet/ctx.js';
34
-
35
- export class BackgroundSnapshotInstance {
36
- constructor(public type: string) {
37
- this.__snapshot_def = snapshotManager.values.get(type)!;
38
- const id = this.__id = backgroundSnapshotInstanceManager.nextId += 1;
39
- backgroundSnapshotInstanceManager.values.set(id, this);
40
-
41
- __globalSnapshotPatch?.push(SnapshotOperation.CreateElement, type, id);
42
- }
43
-
44
- __id: number;
45
- __values: any[] | undefined;
46
- __snapshot_def: Snapshot;
47
- __extraProps?: Record<string, unknown> | undefined;
48
-
49
- private __parent: BackgroundSnapshotInstance | null = null;
50
- private __firstChild: BackgroundSnapshotInstance | null = null;
51
- private __lastChild: BackgroundSnapshotInstance | null = null;
52
- private __previousSibling: BackgroundSnapshotInstance | null = null;
53
- private __nextSibling: BackgroundSnapshotInstance | null = null;
54
-
55
- get parentNode(): BackgroundSnapshotInstance | null {
56
- return this.__parent;
57
- }
58
-
59
- get nextSibling(): BackgroundSnapshotInstance | null {
60
- return this.__nextSibling;
61
- }
62
-
63
- // get isConnected() {
64
- // return !!this.__parent;
65
- // }
66
-
67
- contains(child: BackgroundSnapshotInstance): boolean {
68
- return child.parentNode === this;
69
- }
70
-
71
- // TODO: write tests for this
72
- // This will be called in `lazy`/`Suspense`.
73
- // We currently ignore this since we did not find a way to test.
74
- /* v8 ignore start */
75
- appendChild(child: BackgroundSnapshotInstance): void {
76
- return this.insertBefore(child);
77
- }
78
- /* v8 ignore stop */
79
-
80
- insertBefore(
81
- node: BackgroundSnapshotInstance,
82
- beforeNode?: BackgroundSnapshotInstance,
83
- ): void {
84
- __globalSnapshotPatch?.push(
85
- SnapshotOperation.InsertBefore,
86
- this.__id,
87
- node.__id,
88
- beforeNode?.__id,
89
- );
90
-
91
- // If the node already has a parent, remove it from its current parent
92
- const p = node.__parent;
93
- if (p) {
94
- if (node.__previousSibling) {
95
- node.__previousSibling.__nextSibling = node.__nextSibling;
96
- } else {
97
- p.__firstChild = node.__nextSibling;
98
- }
99
-
100
- if (node.__nextSibling) {
101
- node.__nextSibling.__previousSibling = node.__previousSibling;
102
- } else {
103
- p.__lastChild = node.__previousSibling;
104
- }
105
- }
106
-
107
- // If beforeNode is not provided, add the new node as the last child
108
- if (beforeNode) {
109
- // If beforeNode is provided, insert the new node before beforeNode
110
- if (beforeNode.__previousSibling) {
111
- beforeNode.__previousSibling.__nextSibling = node;
112
- node.__previousSibling = beforeNode.__previousSibling;
113
- } else {
114
- this.__firstChild = node;
115
- node.__previousSibling = null;
116
- }
117
- beforeNode.__previousSibling = node;
118
- node.__nextSibling = beforeNode;
119
- node.__parent = this;
120
- } else {
121
- if (this.__lastChild) {
122
- this.__lastChild.__nextSibling = node;
123
- node.__previousSibling = this.__lastChild;
124
- } else {
125
- this.__firstChild = node;
126
- node.__previousSibling = null;
127
- }
128
- this.__lastChild = node;
129
- node.__parent = this;
130
- node.__nextSibling = null;
131
- }
132
- }
133
-
134
- removeChild(node: BackgroundSnapshotInstance): void {
135
- __globalSnapshotPatch?.push(
136
- SnapshotOperation.RemoveChild,
137
- this.__id,
138
- node.__id,
139
- );
140
-
141
- if (node.__parent !== this) {
142
- throw new Error('The node to be removed is not a child of this node.');
143
- }
144
-
145
- if (node.__previousSibling) {
146
- node.__previousSibling.__nextSibling = node.__nextSibling;
147
- } else {
148
- this.__firstChild = node.__nextSibling;
149
- }
150
-
151
- if (node.__nextSibling) {
152
- node.__nextSibling.__previousSibling = node.__previousSibling;
153
- } else {
154
- this.__lastChild = node.__previousSibling;
155
- }
156
-
157
- node.__parent = null;
158
- node.__previousSibling = null;
159
- node.__nextSibling = null;
160
-
161
- traverseSnapshotInstance(node, v => {
162
- v.__parent = null;
163
- v.__previousSibling = null;
164
- v.__nextSibling = null;
165
- if (v.__values) {
166
- v.__snapshot_def.refAndSpreadIndexes?.forEach((i) => {
167
- const value = v.__values![i] as unknown;
168
- if (value && (typeof value === 'object' || typeof value === 'function')) {
169
- if ('__spread' in value && 'ref' in value) {
170
- queueRefAttrUpdate(value.ref as Ref, null, v.__id, i);
171
- } else if ('__ref' in value) {
172
- queueRefAttrUpdate(value as Ref, null, v.__id, i);
173
- }
174
- }
175
- });
176
- }
177
- globalBackgroundSnapshotInstancesToRemove.push(v.__id);
178
- });
179
- }
180
-
181
- get childNodes(): BackgroundSnapshotInstance[] {
182
- const nodes: BackgroundSnapshotInstance[] = [];
183
- let node = this.__firstChild;
184
- while (node) {
185
- nodes.push(node);
186
- if (node === this.__lastChild) {
187
- break;
188
- }
189
- node = node.__nextSibling;
190
- }
191
- return nodes;
192
- }
193
-
194
- setAttribute(key: string | number, value: unknown): void {
195
- if (__PROFILE__) {
196
- console.profile('setAttribute');
197
- }
198
- if (key === 'values') {
199
- if (__globalSnapshotPatch) {
200
- const oldValues = this.__values;
201
- if (oldValues) {
202
- for (let index = 0; index < (value as unknown[]).length; index++) {
203
- const { needUpdate, valueToCommit } = this.setAttributeImpl(
204
- (value as unknown[])[index],
205
- oldValues[index],
206
- index,
207
- );
208
- if (needUpdate) {
209
- __globalSnapshotPatch.push(
210
- SnapshotOperation.SetAttribute,
211
- this.__id,
212
- index,
213
- valueToCommit,
214
- );
215
- }
216
- }
217
- } else {
218
- const patch = [];
219
- const length = (value as unknown[]).length;
220
- for (let index = 0; index < length; ++index) {
221
- const { valueToCommit } = this.setAttributeImpl((value as unknown[])[index], null, index);
222
- patch[index] = valueToCommit;
223
- }
224
- __globalSnapshotPatch.push(
225
- SnapshotOperation.SetAttributes,
226
- this.__id,
227
- patch,
228
- );
229
- }
230
- } else {
231
- this.__snapshot_def.refAndSpreadIndexes?.forEach((index) => {
232
- const v = (value as unknown[])[index];
233
- if (v && (typeof v === 'object' || typeof v === 'function')) {
234
- if ('__spread' in v && 'ref' in v) {
235
- queueRefAttrUpdate(null, v.ref as Ref, this.__id, index);
236
- } else if ('__ref' in v) {
237
- queueRefAttrUpdate(null, v as Ref, this.__id, index);
238
- }
239
- }
240
- });
241
- }
242
- this.__values = value as unknown[];
243
- if (__PROFILE__) {
244
- console.profileEnd();
245
- }
246
- return;
247
- }
248
-
249
- if (typeof key === 'string') {
250
- (this.__extraProps ??= {})[key] = value;
251
- } else {
252
- // old path (`this.setAttribute(0, xxx)`)
253
- // is reserved as slow path
254
- (this.__values ??= [])[key] = value;
255
- }
256
- __globalSnapshotPatch?.push(
257
- SnapshotOperation.SetAttribute,
258
- this.__id,
259
- key,
260
- value,
261
- );
262
- if (__PROFILE__) {
263
- console.profileEnd();
264
- }
265
- }
266
-
267
- private setAttributeImpl(newValue: unknown, oldValue: unknown, index: number): {
268
- needUpdate: boolean;
269
- valueToCommit: unknown;
270
- } {
271
- if (!newValue) {
272
- // `oldValue` can't be a spread.
273
- if (oldValue && typeof oldValue === 'object' && '__ref' in oldValue) {
274
- queueRefAttrUpdate(oldValue as Ref, null, this.__id, index);
275
- }
276
- return { needUpdate: oldValue !== newValue, valueToCommit: newValue };
277
- }
278
-
279
- const newType = typeof newValue;
280
- if (newType === 'object') {
281
- const newValueObj = newValue as Record<string, unknown>;
282
- if ('__spread' in newValueObj) {
283
- const oldSpread = (oldValue as { __spread?: Record<string, unknown> } | undefined)?.__spread;
284
- const newSpread = transformSpread(this, index, newValueObj);
285
- const needUpdate = !isDirectOrDeepEqual(oldSpread, newSpread);
286
- // use __spread to cache the transform result for next diff
287
- newValueObj['__spread'] = newSpread;
288
- queueRefAttrUpdate(
289
- oldSpread && ((oldValue as { ref?: Ref }).ref),
290
- newValueObj['ref'] as Ref,
291
- this.__id,
292
- index,
293
- );
294
- if (needUpdate) {
295
- for (const key in newSpread) {
296
- const newSpreadValue = newSpread[key];
297
- if (!newSpreadValue) {
298
- continue;
299
- }
300
- if ((newSpreadValue as { _wkltId?: string })._wkltId) {
301
- newSpread[key] = onPostWorkletCtx(newSpreadValue as Worklet);
302
- } else if ((newSpreadValue as { __isGesture?: boolean }).__isGesture) {
303
- processGestureBackground(newSpreadValue as GestureKind);
304
- } else if (key == '__lynx_timing_flag' && oldSpread?.[key] != newSpreadValue && globalPipelineOptions) {
305
- globalPipelineOptions.needTimestamps = true;
306
- }
307
- }
308
- }
309
- return { needUpdate, valueToCommit: newSpread };
310
- }
311
- if ('__ref' in newValueObj) {
312
- queueRefAttrUpdate(oldValue as Ref, newValueObj as Ref, this.__id, index);
313
- return { needUpdate: false, valueToCommit: 1 };
314
- }
315
- if ('_wkltId' in newValueObj) {
316
- return { needUpdate: true, valueToCommit: onPostWorkletCtx(newValueObj as Worklet) };
317
- }
318
- if ('__isGesture' in newValueObj) {
319
- processGestureBackground(newValueObj as unknown as GestureKind);
320
- return { needUpdate: true, valueToCommit: newValue };
321
- }
322
- if ('__ltf' in newValueObj) {
323
- // __lynx_timing_flag
324
- if (globalPipelineOptions && (oldValue as { __ltf?: unknown } | undefined)?.__ltf != newValueObj['__ltf']) {
325
- globalPipelineOptions.needTimestamps = true;
326
- return { needUpdate: true, valueToCommit: newValue };
327
- }
328
- return { needUpdate: false, valueToCommit: newValue };
329
- }
330
- return { needUpdate: !isDirectOrDeepEqual(oldValue, newValue), valueToCommit: newValue };
331
- }
332
- if (newType === 'function') {
333
- if ((newValue as { __ref?: unknown }).__ref) {
334
- queueRefAttrUpdate(oldValue as Ref, newValue as Ref, this.__id, index);
335
- return { needUpdate: false, valueToCommit: 1 };
336
- }
337
- /* event */
338
- return { needUpdate: !oldValue, valueToCommit: 1 };
339
- }
340
- return { needUpdate: oldValue !== newValue, valueToCommit: newValue };
341
- }
342
- }
343
-
344
- export function hydrate(
345
- before: SerializedSnapshotInstance,
346
- after: BackgroundSnapshotInstance,
347
- ): SnapshotPatch {
348
- initGlobalSnapshotPatch();
349
-
350
- const helper2 = (afters: BackgroundSnapshotInstance[], parentId: number, targetId?: number) => {
351
- for (const child of afters) {
352
- const id = child.__id;
353
- __globalSnapshotPatch!.push(SnapshotOperation.CreateElement, child.type, id);
354
- const values = child.__values;
355
- if (values) {
356
- child.__values = undefined;
357
- child.setAttribute('values', values);
358
- }
359
- const extraProps = child.__extraProps;
360
- for (const key in extraProps) {
361
- child.setAttribute(key, extraProps[key]);
362
- }
363
- helper2(child.childNodes, id);
364
- __globalSnapshotPatch!.push(SnapshotOperation.InsertBefore, parentId, id, targetId);
365
- }
366
- };
367
-
368
- const helper = (
369
- before: SerializedSnapshotInstance,
370
- after: BackgroundSnapshotInstance,
371
- ) => {
372
- hydrationMap.set(after.__id, before.id);
373
- backgroundSnapshotInstanceManager.updateId(after.__id, before.id);
374
- after.__values?.forEach((value: unknown, index) => {
375
- const old: unknown = before.values![index];
376
-
377
- if (value) {
378
- if (typeof value === 'object') {
379
- if ('__spread' in value) {
380
- // `value.__spread` my contain event ids using snapshot ids before hydration. Remove it.
381
- delete value.__spread;
382
- const __spread = transformSpread(after, index, value);
383
- for (const key in __spread) {
384
- const v = __spread[key];
385
- if (v && typeof v === 'object') {
386
- if ('_wkltId' in v) {
387
- onPostWorkletCtx(v as Worklet);
388
- } else if ('__isGesture' in v) {
389
- processGestureBackground(v as GestureKind);
390
- }
391
- }
392
- }
393
- (after.__values![index]! as Record<string, unknown>)['__spread'] = __spread;
394
- value = __spread;
395
- } else if ('__ref' in value) {
396
- // skip patch
397
- value = old;
398
- } else if ('_wkltId' in value) {
399
- onPostWorkletCtx(value as Worklet);
400
- } else if ('__isGesture' in value) {
401
- processGestureBackground(value as GestureKind);
402
- }
403
- } else if (typeof value === 'function') {
404
- if ('__ref' in value) {
405
- // skip patch
406
- value = old;
407
- } else {
408
- value = `${after.__id}:${index}:`;
409
- }
410
- }
411
- }
412
-
413
- if (!isDirectOrDeepEqual(value, old)) {
414
- __globalSnapshotPatch!.push(
415
- SnapshotOperation.SetAttribute,
416
- after.__id,
417
- index,
418
- value,
419
- );
420
- }
421
- });
422
-
423
- if (after.__extraProps) {
424
- for (const key in after.__extraProps) {
425
- const value = after.__extraProps[key];
426
- const old = before.extraProps?.[key];
427
- if (!isDirectOrDeepEqual(value, old)) {
428
- __globalSnapshotPatch!.push(
429
- SnapshotOperation.SetAttribute,
430
- after.__id,
431
- key,
432
- value,
433
- );
434
- }
435
- }
436
- }
437
-
438
- const { slot } = after.__snapshot_def;
439
-
440
- const beforeChildNodes = before.children ?? [];
441
- const afterChildNodes = after.childNodes;
442
-
443
- if (!slot) {
444
- return;
445
- }
446
-
447
- slot.forEach(([type], index) => {
448
- switch (type) {
449
- case DynamicPartType.Slot:
450
- case DynamicPartType.MultiChildren: {
451
- // TODO: the following null assertions are not 100% safe
452
- const v1 = beforeChildNodes[index]!;
453
- const v2 = afterChildNodes[index]!;
454
- helper(v1, v2);
455
- break;
456
- }
457
- case DynamicPartType.Children:
458
- case DynamicPartType.ListChildren: {
459
- const diffResult = diffArrayLepus(
460
- beforeChildNodes,
461
- afterChildNodes,
462
- (a, b) => a.type === b.type,
463
- (a, b) => {
464
- helper(a, b);
465
- },
466
- );
467
- diffArrayAction(
468
- beforeChildNodes,
469
- diffResult,
470
- (node, target) => {
471
- helper2([node], before.id, target?.id);
472
- return undefined as unknown as SerializedSnapshotInstance;
473
- },
474
- node => {
475
- __globalSnapshotPatch!.push(
476
- SnapshotOperation.RemoveChild,
477
- before.id,
478
- node.id,
479
- );
480
- },
481
- (node, target) => {
482
- // changedList.push([SnapshotOperation.RemoveChild, before.id, node.id]);
483
- __globalSnapshotPatch!.push(
484
- SnapshotOperation.InsertBefore,
485
- before.id,
486
- node.id,
487
- target?.id,
488
- );
489
- },
490
- );
491
- break;
492
- }
493
- }
494
- });
495
- };
496
-
497
- helper(before, after);
498
- // Hydration should not trigger ref updates. They were incorrectly triggered when using `setAttribute` to add values to the patch list.
499
- clearQueuedRefs();
500
- return takeGlobalSnapshotPatch()!;
501
- }
@@ -1,30 +0,0 @@
1
- // Copyright 2024 The Lynx Authors. All rights reserved.
2
- // Licensed under the Apache License Version 2.0 that can be found in the
3
- // LICENSE file in the root directory of this source tree.
4
-
5
- import type { FC } from 'react';
6
-
7
- // for better reuse if runtime is changed
8
- export function factory(
9
- { createElement, useMemo, Suspense, lazy }: typeof import('react'),
10
- loadLazyBundle: any,
11
- ): FC<{ is: string }> {
12
- /**
13
- * @internal a polyfill for <component is=? />
14
- */
15
- const __ComponentIsPolyfill: FC<{ is: string }> = ({ is, ...props }) => {
16
- if (typeof is !== 'string') {
17
- lynx.reportError(
18
- new Error(
19
- 'You must provide a string to props `is` when using syntax `<component is=? />`.',
20
- ),
21
- );
22
- return null;
23
- }
24
- // @ts-ignore
25
- const D = useMemo(() => lazy(() => loadLazyBundle(is)), [is]);
26
- return createElement(Suspense, { key: is }, createElement(D, props));
27
- };
28
-
29
- return __ComponentIsPolyfill;
30
- }