@reckona/mreact-compat 0.0.152 → 0.0.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/class-component.d.ts +2 -2
- package/dist/class-component.d.ts.map +1 -1
- package/dist/class-component.js +29 -3
- package/dist/class-component.js.map +1 -1
- package/dist/dom-props.d.ts.map +1 -1
- package/dist/dom-props.js +0 -21
- package/dist/dom-props.js.map +1 -1
- package/dist/element.d.ts +0 -1
- package/dist/element.d.ts.map +1 -1
- package/dist/element.js +2 -41
- package/dist/element.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -1
- package/dist/fiber-reconciler.js +45 -3
- package/dist/fiber-reconciler.js.map +1 -1
- package/dist/hooks.d.ts +5 -2
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +38 -15
- package/dist/hooks.js.map +1 -1
- package/dist/host-reconciler.d.ts.map +1 -1
- package/dist/host-reconciler.js +37 -32
- package/dist/host-reconciler.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react-default.d.ts +2 -1
- package/dist/react-default.d.ts.map +1 -1
- package/dist/react-default.js +2 -1
- package/dist/react-default.js.map +1 -1
- package/dist/server-render.d.ts +1 -0
- package/dist/server-render.d.ts.map +1 -1
- package/dist/server-render.js +103 -39
- package/dist/server-render.js.map +1 -1
- package/package.json +3 -3
- package/src/class-component.ts +35 -2
- package/src/dom-props.ts +0 -30
- package/src/element.ts +4 -57
- package/src/events.ts +2 -0
- package/src/fiber-reconciler.ts +54 -2
- package/src/hooks.ts +43 -15
- package/src/host-reconciler.ts +43 -36
- package/src/index.ts +1 -1
- package/src/react-default.ts +2 -1
- package/src/server-render.ts +120 -46
package/src/element.ts
CHANGED
|
@@ -11,7 +11,6 @@ export const Suspense = Symbol.for("react.suspense");
|
|
|
11
11
|
export const SuspenseList = Symbol.for("react.suspense_list");
|
|
12
12
|
export const Activity = Symbol.for("react.activity");
|
|
13
13
|
export const Profiler = Symbol.for("react.profiler");
|
|
14
|
-
export const HOST_OWN_PROPS_META = Symbol.for("modular.react.host_own_props_meta");
|
|
15
14
|
export const HOST_CHILDREN_ONLY_PROPS_META = Symbol.for(
|
|
16
15
|
"modular.react.host_children_only_props_meta",
|
|
17
16
|
);
|
|
@@ -376,63 +375,11 @@ function isReactCompatContextProviderShorthand(
|
|
|
376
375
|
}
|
|
377
376
|
|
|
378
377
|
function setHostOwnPropsMeta(props: Record<string, unknown>): void {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
(props as { [HOST_CHILDREN_ONLY_PROPS_META]?: true })[
|
|
384
|
-
HOST_CHILDREN_ONLY_PROPS_META
|
|
385
|
-
] = true;
|
|
386
|
-
}
|
|
387
|
-
return;
|
|
378
|
+
if (hostPropsAreChildrenOnly(props)) {
|
|
379
|
+
(props as { [HOST_CHILDREN_ONLY_PROPS_META]?: true })[
|
|
380
|
+
HOST_CHILDREN_ONLY_PROPS_META
|
|
381
|
+
] = true;
|
|
388
382
|
}
|
|
389
|
-
|
|
390
|
-
let selectedState = 0;
|
|
391
|
-
|
|
392
|
-
for (const name in props) {
|
|
393
|
-
if (!hasOwnProperty.call(props, name) || name === "children") {
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (name === "data-key") {
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (name === "className") {
|
|
402
|
-
const value = props[name];
|
|
403
|
-
|
|
404
|
-
if (value === undefined) {
|
|
405
|
-
continue;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (value !== "selected") {
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
selectedState |= 1;
|
|
413
|
-
continue;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (name === "data-selected") {
|
|
417
|
-
const value = props[name];
|
|
418
|
-
|
|
419
|
-
if (value === undefined) {
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
if (value !== "true") {
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
selectedState |= 2;
|
|
428
|
-
continue;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
(props as { [HOST_OWN_PROPS_META]?: number })[HOST_OWN_PROPS_META] =
|
|
435
|
-
dataKey * 4 + selectedState;
|
|
436
383
|
}
|
|
437
384
|
|
|
438
385
|
function hostPropsAreChildrenOnly(props: Record<string, unknown>): boolean {
|
package/src/events.ts
CHANGED
|
@@ -18,6 +18,7 @@ const reactPropToNativeEvent = new Map<string, string[]>([
|
|
|
18
18
|
["onCompositionUpdate", ["compositionupdate"]],
|
|
19
19
|
["onContextMenu", ["contextmenu"]],
|
|
20
20
|
["onDoubleClick", ["dblclick"]],
|
|
21
|
+
["onDrag", ["drag"]],
|
|
21
22
|
["onDragEnd", ["dragend"]],
|
|
22
23
|
["onDragEnter", ["dragenter"]],
|
|
23
24
|
["onDragExit", ["dragexit"]],
|
|
@@ -57,6 +58,7 @@ const nativeEventToReactProps = new Map<string, string[]>([
|
|
|
57
58
|
["compositionupdate", ["onCompositionUpdate"]],
|
|
58
59
|
["contextmenu", ["onContextMenu"]],
|
|
59
60
|
["dblclick", ["onDoubleClick"]],
|
|
61
|
+
["drag", ["onDrag"]],
|
|
60
62
|
["dragend", ["onDragEnd"]],
|
|
61
63
|
["dragenter", ["onDragEnter"]],
|
|
62
64
|
["dragexit", ["onDragExit"]],
|
package/src/fiber-reconciler.ts
CHANGED
|
@@ -529,7 +529,7 @@ function captureThrownValue(
|
|
|
529
529
|
}
|
|
530
530
|
|
|
531
531
|
if (!isThenable(thrownValue) && boundary.tag === "class-component") {
|
|
532
|
-
const captured = captureClassErrorBoundary(root, boundary, thrownValue);
|
|
532
|
+
const captured = captureClassErrorBoundary(root, boundary, source, thrownValue);
|
|
533
533
|
|
|
534
534
|
if (captured !== undefined) {
|
|
535
535
|
return captured;
|
|
@@ -574,6 +574,7 @@ function beginClassComponent(
|
|
|
574
574
|
function captureClassErrorBoundary(
|
|
575
575
|
root: FiberRoot,
|
|
576
576
|
boundary: Fiber,
|
|
577
|
+
source: Fiber,
|
|
577
578
|
thrownValue: unknown,
|
|
578
579
|
): Fiber | undefined {
|
|
579
580
|
if (!isClassComponentType(boundary.type)) {
|
|
@@ -598,7 +599,9 @@ function captureClassErrorBoundary(
|
|
|
598
599
|
};
|
|
599
600
|
}
|
|
600
601
|
|
|
601
|
-
instance.componentDidCatch?.(error, {
|
|
602
|
+
instance.componentDidCatch?.(error, {
|
|
603
|
+
componentStack: componentStackFromFiber(source, boundary),
|
|
604
|
+
});
|
|
602
605
|
boundary.child = reconcileChildFibers(
|
|
603
606
|
boundary,
|
|
604
607
|
boundary.alternate?.child,
|
|
@@ -607,6 +610,55 @@ function captureClassErrorBoundary(
|
|
|
607
610
|
return boundary.child ?? completeUnitOfWork(root, boundary);
|
|
608
611
|
}
|
|
609
612
|
|
|
613
|
+
function componentStackFromFiber(source: Fiber, boundary: Fiber): string {
|
|
614
|
+
const names: string[] = [];
|
|
615
|
+
let cursor: Fiber | undefined = source;
|
|
616
|
+
|
|
617
|
+
while (cursor !== undefined) {
|
|
618
|
+
const name = componentNameForFiber(cursor);
|
|
619
|
+
if (name !== undefined) {
|
|
620
|
+
names.push(name);
|
|
621
|
+
}
|
|
622
|
+
if (cursor === boundary) {
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
cursor = cursor.return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
return names.length === 0
|
|
629
|
+
? "\n at Anonymous"
|
|
630
|
+
: names.map((name) => `\n at ${name}`).join("");
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function componentNameForFiber(fiber: Fiber): string | undefined {
|
|
634
|
+
if (fiber.tag === "host-component") {
|
|
635
|
+
return String(fiber.type);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
if (fiber.tag === "function-component" || fiber.tag === "class-component") {
|
|
639
|
+
return componentNameFromType(fiber.type);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
if (fiber.tag === "memo" && isMemoType(fiber.type)) {
|
|
643
|
+
return componentNameFromType(fiber.type.type);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (fiber.tag === "forward-ref" && isForwardRefType(fiber.type)) {
|
|
647
|
+
return componentNameFromType(fiber.type.render);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
return undefined;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
function componentNameFromType(type: unknown): string {
|
|
654
|
+
const displayName = (type as { displayName?: unknown } | undefined)?.displayName;
|
|
655
|
+
if (typeof displayName === "string" && displayName !== "") {
|
|
656
|
+
return displayName;
|
|
657
|
+
}
|
|
658
|
+
const name = (type as { name?: unknown } | undefined)?.name;
|
|
659
|
+
return typeof name === "string" && name !== "" ? name : "Anonymous";
|
|
660
|
+
}
|
|
661
|
+
|
|
610
662
|
function isClassErrorBoundary(
|
|
611
663
|
type: ClassComponentType,
|
|
612
664
|
instance: ClassComponentInstance,
|
package/src/hooks.ts
CHANGED
|
@@ -24,6 +24,7 @@ export interface RootRuntime {
|
|
|
24
24
|
profilerBaseDurations: Map<string, number>;
|
|
25
25
|
pendingProfilerCommits: PendingProfilerCommit[];
|
|
26
26
|
pendingInsertionEffects: PendingEffect[];
|
|
27
|
+
pendingImperativeHandleEffects: PendingEffect[];
|
|
27
28
|
pendingLayoutEffects: PendingEffect[];
|
|
28
29
|
pendingEffects: PendingEffect[];
|
|
29
30
|
externalStoreChecks: ExternalStoreCheck[];
|
|
@@ -39,7 +40,7 @@ export interface RootRuntime {
|
|
|
39
40
|
strictMemoReplay: { values: readonly unknown[]; index: number } | undefined;
|
|
40
41
|
strictMemoReplayByHook: ReadonlyMap<string, unknown> | undefined;
|
|
41
42
|
profilerFlushDepth: number;
|
|
42
|
-
effectFlushPhase: "insertion" | "layout" | "normal" | undefined;
|
|
43
|
+
effectFlushPhase: "insertion" | "imperative-handle" | "layout" | "normal" | undefined;
|
|
43
44
|
externalStoreUpdate: boolean;
|
|
44
45
|
renderPhaseUpdate: boolean;
|
|
45
46
|
rerender(priority?: RenderPriority): void;
|
|
@@ -147,7 +148,7 @@ type HookSlot =
|
|
|
147
148
|
| { kind: "debug"; value: unknown }
|
|
148
149
|
| {
|
|
149
150
|
kind: "effect";
|
|
150
|
-
effectKind: "insertion" | "layout" | "normal";
|
|
151
|
+
effectKind: "insertion" | "imperative-handle" | "layout" | "normal";
|
|
151
152
|
callback: EffectCallback;
|
|
152
153
|
deps?: readonly unknown[];
|
|
153
154
|
cleanup?: () => void;
|
|
@@ -191,7 +192,6 @@ let automaticRerenderScheduled = false;
|
|
|
191
192
|
let effectFlushRerenderDepth = 0;
|
|
192
193
|
let strictMemoOwnerId = 0;
|
|
193
194
|
const strictMemoObjectOwnerIds = new WeakMap<object, number>();
|
|
194
|
-
const strictMemoPrimitiveOwnerIds = new Map<unknown, number>();
|
|
195
195
|
const queuedTransitionRerenders = new Map<RootRuntime, TransitionContext>();
|
|
196
196
|
const queuedEventRerenders = new Set<RootRuntime>();
|
|
197
197
|
export const version = "19.2.6";
|
|
@@ -285,6 +285,7 @@ export interface RuntimeSnapshot {
|
|
|
285
285
|
portalContainers: Set<Element>;
|
|
286
286
|
portalNodes: Map<Element, Set<Node>>;
|
|
287
287
|
pendingInsertionEffectsLength: number;
|
|
288
|
+
pendingImperativeHandleEffectsLength: number;
|
|
288
289
|
pendingLayoutEffectsLength: number;
|
|
289
290
|
pendingEffectsLength: number;
|
|
290
291
|
pendingProfilerCommitsLength: number;
|
|
@@ -314,6 +315,7 @@ export function createRootRuntime(
|
|
|
314
315
|
profilerBaseDurations: new Map(),
|
|
315
316
|
pendingProfilerCommits: [],
|
|
316
317
|
pendingInsertionEffects: [],
|
|
318
|
+
pendingImperativeHandleEffects: [],
|
|
317
319
|
pendingLayoutEffects: [],
|
|
318
320
|
pendingEffects: [],
|
|
319
321
|
externalStoreChecks: [],
|
|
@@ -338,6 +340,7 @@ export function createRootRuntime(
|
|
|
338
340
|
this.activeProfilerPaths = new Set();
|
|
339
341
|
this.pendingProfilerCommits = [];
|
|
340
342
|
this.pendingInsertionEffects = [];
|
|
343
|
+
this.pendingImperativeHandleEffects = [];
|
|
341
344
|
this.pendingLayoutEffects = [];
|
|
342
345
|
this.pendingEffects = [];
|
|
343
346
|
this.externalStoreChecks = [];
|
|
@@ -368,6 +371,8 @@ export function createRootRuntime(
|
|
|
368
371
|
try {
|
|
369
372
|
this.effectFlushPhase = "insertion";
|
|
370
373
|
flushPendingEffects(this.pendingInsertionEffects);
|
|
374
|
+
this.effectFlushPhase = "imperative-handle";
|
|
375
|
+
flushPendingEffects(this.pendingImperativeHandleEffects);
|
|
371
376
|
this.effectFlushPhase = "layout";
|
|
372
377
|
const strictLayoutEffects = flushPendingEffects(this.pendingLayoutEffects);
|
|
373
378
|
this.effectFlushPhase = "normal";
|
|
@@ -662,6 +667,7 @@ export function takeRuntimeSnapshot(runtime: RootRuntime): RuntimeSnapshot {
|
|
|
662
667
|
portalContainers: new Set(runtime.portalContainers),
|
|
663
668
|
portalNodes: clonePortalNodes(runtime.portalNodes),
|
|
664
669
|
pendingInsertionEffectsLength: runtime.pendingInsertionEffects.length,
|
|
670
|
+
pendingImperativeHandleEffectsLength: runtime.pendingImperativeHandleEffects.length,
|
|
665
671
|
pendingLayoutEffectsLength: runtime.pendingLayoutEffects.length,
|
|
666
672
|
pendingEffectsLength: runtime.pendingEffects.length,
|
|
667
673
|
pendingProfilerCommitsLength: runtime.pendingProfilerCommits.length,
|
|
@@ -684,6 +690,7 @@ export function restoreRuntimeSnapshot(
|
|
|
684
690
|
snapshot: RuntimeSnapshot,
|
|
685
691
|
): void {
|
|
686
692
|
runtime.pendingInsertionEffects.length = snapshot.pendingInsertionEffectsLength;
|
|
693
|
+
runtime.pendingImperativeHandleEffects.length = snapshot.pendingImperativeHandleEffectsLength;
|
|
687
694
|
runtime.pendingLayoutEffects.length = snapshot.pendingLayoutEffectsLength;
|
|
688
695
|
runtime.pendingEffects.length = snapshot.pendingEffectsLength;
|
|
689
696
|
runtime.pendingProfilerCommits.length = snapshot.pendingProfilerCommitsLength;
|
|
@@ -908,16 +915,20 @@ export function useReducer<TState, TAction, TInitial = TState>(
|
|
|
908
915
|
),
|
|
909
916
|
);
|
|
910
917
|
const reducerRef = runWithoutDevToolsHookTracking(() => useRef(reducer));
|
|
918
|
+
const stateRef = runWithoutDevToolsHookTracking(() => useRef(state));
|
|
911
919
|
const dispatchRef = runWithoutDevToolsHookTracking(() =>
|
|
912
920
|
useRef<((action: TAction) => void) | undefined>(
|
|
913
921
|
undefined,
|
|
914
922
|
)
|
|
915
923
|
);
|
|
916
924
|
reducerRef.current = reducer;
|
|
925
|
+
stateRef.current = state;
|
|
917
926
|
|
|
918
927
|
if (dispatchRef.current === undefined) {
|
|
919
928
|
dispatchRef.current = (action: TAction): void => {
|
|
920
|
-
|
|
929
|
+
const nextState = reducerRef.current(stateRef.current, action);
|
|
930
|
+
stateRef.current = nextState;
|
|
931
|
+
setState(nextState);
|
|
921
932
|
};
|
|
922
933
|
}
|
|
923
934
|
|
|
@@ -995,7 +1006,7 @@ export function useImperativeHandle<T>(
|
|
|
995
1006
|
deps?: readonly unknown[],
|
|
996
1007
|
): void {
|
|
997
1008
|
runWithoutDevToolsHookTracking(() =>
|
|
998
|
-
|
|
1009
|
+
useEffectImpl("imperative-handle", () => {
|
|
999
1010
|
const handle = create();
|
|
1000
1011
|
assignRef(ref, handle);
|
|
1001
1012
|
return () => {
|
|
@@ -1076,10 +1087,14 @@ function getStrictMemoHookKey(
|
|
|
1076
1087
|
instance: ComponentInstance,
|
|
1077
1088
|
index: number,
|
|
1078
1089
|
): string {
|
|
1079
|
-
return `${instance.path}:${
|
|
1090
|
+
return `${instance.path}:${getStrictMemoOwnerKey(instance.owner)}:${index}`;
|
|
1080
1091
|
}
|
|
1081
1092
|
|
|
1082
|
-
function
|
|
1093
|
+
export function __getStrictMemoOwnerKeyForTesting(owner: unknown): string {
|
|
1094
|
+
return getStrictMemoOwnerKey(owner);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
function getStrictMemoOwnerKey(owner: unknown): string {
|
|
1083
1098
|
if ((typeof owner === "object" && owner !== null) || typeof owner === "function") {
|
|
1084
1099
|
const objectOwner = owner as object;
|
|
1085
1100
|
let ownerId = strictMemoObjectOwnerIds.get(objectOwner);
|
|
@@ -1087,15 +1102,17 @@ function getStrictMemoOwnerId(owner: unknown): number {
|
|
|
1087
1102
|
ownerId = strictMemoOwnerId++;
|
|
1088
1103
|
strictMemoObjectOwnerIds.set(objectOwner, ownerId);
|
|
1089
1104
|
}
|
|
1090
|
-
return ownerId
|
|
1105
|
+
return `o:${ownerId}`;
|
|
1091
1106
|
}
|
|
1092
1107
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1108
|
+
if (typeof owner === "symbol") {
|
|
1109
|
+
const globalKey = Symbol.keyFor(owner);
|
|
1110
|
+
return globalKey === undefined
|
|
1111
|
+
? `p:symbol:${String(owner)}`
|
|
1112
|
+
: `p:symbol-global:${globalKey}`;
|
|
1097
1113
|
}
|
|
1098
|
-
|
|
1114
|
+
|
|
1115
|
+
return `p:${typeof owner}:${String(owner)}`;
|
|
1099
1116
|
}
|
|
1100
1117
|
|
|
1101
1118
|
function assignRef<T>(ref: unknown, value: T | null): void {
|
|
@@ -1567,6 +1584,7 @@ export function runWithHostCommit<T>(callback: () => T): T {
|
|
|
1567
1584
|
}
|
|
1568
1585
|
|
|
1569
1586
|
export function useTransition(): [boolean, StartTransition] {
|
|
1587
|
+
const instance = requireInstance();
|
|
1570
1588
|
const [pending, setPending] = runWithoutDevToolsHookTracking(() => useState(false));
|
|
1571
1589
|
const startTransitionWithPending: StartTransition = (scope) => {
|
|
1572
1590
|
setPending(true);
|
|
@@ -1575,6 +1593,10 @@ export function useTransition(): [boolean, StartTransition] {
|
|
|
1575
1593
|
transitionVersion: ++transitionVersion,
|
|
1576
1594
|
};
|
|
1577
1595
|
scheduleCallback("low", () => {
|
|
1596
|
+
if (instance.disposed === true) {
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1578
1600
|
if (!isTransitionContextCurrent(context)) {
|
|
1579
1601
|
setPending(false);
|
|
1580
1602
|
return;
|
|
@@ -1582,6 +1604,9 @@ export function useTransition(): [boolean, StartTransition] {
|
|
|
1582
1604
|
|
|
1583
1605
|
runTransitionScope(() => {
|
|
1584
1606
|
scope();
|
|
1607
|
+
if (instance.disposed === true) {
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1585
1610
|
setPending(false);
|
|
1586
1611
|
}, context);
|
|
1587
1612
|
});
|
|
@@ -1721,7 +1746,7 @@ function isTransitionContextCurrent(context: TransitionContext): boolean {
|
|
|
1721
1746
|
}
|
|
1722
1747
|
|
|
1723
1748
|
function useEffectImpl(
|
|
1724
|
-
effectKind: "insertion" | "layout" | "normal",
|
|
1749
|
+
effectKind: "insertion" | "imperative-handle" | "layout" | "normal",
|
|
1725
1750
|
callback: EffectCallback,
|
|
1726
1751
|
deps?: readonly unknown[],
|
|
1727
1752
|
): void {
|
|
@@ -1763,12 +1788,15 @@ function useEffectImpl(
|
|
|
1763
1788
|
|
|
1764
1789
|
slot.strictReplay =
|
|
1765
1790
|
(runtime.strictModeDepth > 0 || runtime.strictReplayDepth > 0) &&
|
|
1766
|
-
effectKind !== "insertion"
|
|
1791
|
+
effectKind !== "insertion" &&
|
|
1792
|
+
effectKind !== "imperative-handle";
|
|
1767
1793
|
|
|
1768
1794
|
if (shouldRun) {
|
|
1769
1795
|
const queue =
|
|
1770
1796
|
effectKind === "insertion"
|
|
1771
1797
|
? runtime.pendingInsertionEffects
|
|
1798
|
+
: effectKind === "imperative-handle"
|
|
1799
|
+
? runtime.pendingImperativeHandleEffects
|
|
1772
1800
|
: effectKind === "layout"
|
|
1773
1801
|
? runtime.pendingLayoutEffects
|
|
1774
1802
|
: runtime.pendingEffects;
|
package/src/host-reconciler.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
FORWARD_REF_TYPE,
|
|
5
5
|
Fragment,
|
|
6
6
|
HOST_CHILDREN_ONLY_PROPS_META,
|
|
7
|
-
HOST_OWN_PROPS_META,
|
|
8
7
|
LAZY_TYPE,
|
|
9
8
|
MEMO_TYPE,
|
|
10
9
|
Profiler,
|
|
@@ -571,8 +570,8 @@ function getReusableKeyedRowHostFiber(
|
|
|
571
570
|
const previousRecord = previousProps as Record<string, unknown>;
|
|
572
571
|
|
|
573
572
|
if (
|
|
574
|
-
|
|
575
|
-
|
|
573
|
+
getDirectHostTextChild(previousRecord.children) !== row.text ||
|
|
574
|
+
!hostOwnPropsEqual(previousRecord, row.element.props)
|
|
576
575
|
) {
|
|
577
576
|
return undefined;
|
|
578
577
|
}
|
|
@@ -591,7 +590,6 @@ interface KeyedRowHostElement {
|
|
|
591
590
|
element: ReactCompatElement;
|
|
592
591
|
key: string;
|
|
593
592
|
type: string;
|
|
594
|
-
meta: number;
|
|
595
593
|
text: string;
|
|
596
594
|
}
|
|
597
595
|
|
|
@@ -600,7 +598,6 @@ function createKeyedRowHostElementScratch(): KeyedRowHostElement {
|
|
|
600
598
|
element: undefined as unknown as ReactCompatElement,
|
|
601
599
|
key: "",
|
|
602
600
|
type: "",
|
|
603
|
-
meta: 0,
|
|
604
601
|
text: "",
|
|
605
602
|
};
|
|
606
603
|
}
|
|
@@ -618,18 +615,17 @@ function readKeyedRowHostElement(
|
|
|
618
615
|
return false;
|
|
619
616
|
}
|
|
620
617
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const text =
|
|
618
|
+
// Any keyed host row whose children collapse to a single text value
|
|
619
|
+
// qualifies; row props are compared per reuse with hostOwnPropsEqual.
|
|
620
|
+
const text = getDirectHostTextChild((node.props as Record<string, unknown>).children);
|
|
624
621
|
|
|
625
|
-
if (
|
|
622
|
+
if (text === undefined) {
|
|
626
623
|
return false;
|
|
627
624
|
}
|
|
628
625
|
|
|
629
626
|
row.element = node;
|
|
630
627
|
row.key = node.key;
|
|
631
628
|
row.type = node.type;
|
|
632
|
-
row.meta = meta;
|
|
633
629
|
row.text = text;
|
|
634
630
|
return true;
|
|
635
631
|
}
|
|
@@ -667,13 +663,9 @@ function createKeyedRowHostFiber(
|
|
|
667
663
|
}
|
|
668
664
|
|
|
669
665
|
const previousProps = current.memoizedProps ?? current.pendingProps;
|
|
670
|
-
const previousMeta =
|
|
671
|
-
typeof previousProps === "object" && previousProps !== null
|
|
672
|
-
? getHostOwnPropsMeta(previousProps as Record<string, unknown>)
|
|
673
|
-
: undefined;
|
|
674
666
|
const previousText = getDirectHostTextChild(hostFiberChildrenProp(previousProps));
|
|
675
667
|
|
|
676
|
-
if (
|
|
668
|
+
if (previousText !== row.text || !hostOwnPropsEqual(previousProps, row.element.props)) {
|
|
677
669
|
fiber.flags |= Update;
|
|
678
670
|
}
|
|
679
671
|
|
|
@@ -1642,6 +1634,8 @@ function commitHostDirtyFiber(
|
|
|
1642
1634
|
hostPropsAreChildrenOnly(fiber.memoizedProps) &&
|
|
1643
1635
|
hostPropsAreChildrenOnly(props));
|
|
1644
1636
|
const textOnlyRowUpdate =
|
|
1637
|
+
!propsAreUnchanged &&
|
|
1638
|
+
!propsAreChildrenOnly &&
|
|
1645
1639
|
fiber.hydrateExisting !== true &&
|
|
1646
1640
|
isRowTextOnlyUpdate(fiber.memoizedProps, props);
|
|
1647
1641
|
|
|
@@ -2032,6 +2026,8 @@ function commitHostFiber(
|
|
|
2032
2026
|
hostPropsAreChildrenOnly(fiber.memoizedProps) &&
|
|
2033
2027
|
hostPropsAreChildrenOnly(props));
|
|
2034
2028
|
const textOnlyRowUpdate =
|
|
2029
|
+
!propsAreUnchanged &&
|
|
2030
|
+
!propsAreChildrenOnly &&
|
|
2035
2031
|
fiber.hydrateExisting !== true &&
|
|
2036
2032
|
isRowTextOnlyUpdate(fiber.memoizedProps, props);
|
|
2037
2033
|
|
|
@@ -2243,12 +2239,6 @@ function hostOwnPropsEqual(previous: unknown, next: Record<string, unknown>): bo
|
|
|
2243
2239
|
}
|
|
2244
2240
|
|
|
2245
2241
|
const previousProps = previous as Record<string, unknown>;
|
|
2246
|
-
const previousMeta = getHostOwnPropsMeta(previousProps);
|
|
2247
|
-
const nextMeta = getHostOwnPropsMeta(next);
|
|
2248
|
-
|
|
2249
|
-
if (previousMeta !== undefined && nextMeta !== undefined) {
|
|
2250
|
-
return previousMeta === nextMeta;
|
|
2251
|
-
}
|
|
2252
2242
|
|
|
2253
2243
|
let previousCount = 0;
|
|
2254
2244
|
let nextCount = 0;
|
|
@@ -2276,10 +2266,6 @@ function hostOwnPropsEqual(previous: unknown, next: Record<string, unknown>): bo
|
|
|
2276
2266
|
return previousCount === nextCount;
|
|
2277
2267
|
}
|
|
2278
2268
|
|
|
2279
|
-
function getHostOwnPropsMeta(props: Record<string, unknown>): number | undefined {
|
|
2280
|
-
return (props as { [HOST_OWN_PROPS_META]?: number })[HOST_OWN_PROPS_META];
|
|
2281
|
-
}
|
|
2282
|
-
|
|
2283
2269
|
function hostDirectTextChildChanged(previous: unknown, next: Record<string, unknown>): boolean {
|
|
2284
2270
|
const previousText = getDirectHostTextChild(hostFiberChildrenProp(previous));
|
|
2285
2271
|
const nextText = getDirectHostTextChild(next.children);
|
|
@@ -2379,17 +2365,15 @@ function isRowTextOnlyUpdate(previous: unknown, next: Record<string, unknown>):
|
|
|
2379
2365
|
}
|
|
2380
2366
|
|
|
2381
2367
|
const previousProps = previous as Record<string, unknown>;
|
|
2382
|
-
const previousMeta = getHostOwnPropsMeta(previousProps);
|
|
2383
|
-
const nextMeta = getHostOwnPropsMeta(next);
|
|
2384
|
-
|
|
2385
|
-
if (previousMeta === undefined || previousMeta !== nextMeta) {
|
|
2386
|
-
return false;
|
|
2387
|
-
}
|
|
2388
|
-
|
|
2389
2368
|
const previousText = getDirectHostTextChild(previousProps.children);
|
|
2390
2369
|
const nextText = getDirectHostTextChild(next.children);
|
|
2391
2370
|
|
|
2392
|
-
return
|
|
2371
|
+
return (
|
|
2372
|
+
previousText !== undefined &&
|
|
2373
|
+
nextText !== undefined &&
|
|
2374
|
+
previousText !== nextText &&
|
|
2375
|
+
hostOwnPropsEqual(previousProps, next)
|
|
2376
|
+
);
|
|
2393
2377
|
}
|
|
2394
2378
|
|
|
2395
2379
|
function hostFiberChildrenProp(props: unknown): unknown {
|
|
@@ -2404,10 +2388,33 @@ function getDirectHostTextChild(children: unknown): string | undefined {
|
|
|
2404
2388
|
: undefined;
|
|
2405
2389
|
}
|
|
2406
2390
|
|
|
2391
|
+
// This package has no Node type dependency; declare the minimal process
|
|
2392
|
+
// shape needed for the literal process.env.NODE_ENV expression below.
|
|
2393
|
+
declare const process: { env: Record<string, string | undefined> };
|
|
2394
|
+
|
|
2395
|
+
type HostFastPathMode = "static-fast" | "dynamic";
|
|
2396
|
+
|
|
2397
|
+
const hostFastPathMode: HostFastPathMode = (() => {
|
|
2398
|
+
try {
|
|
2399
|
+
// The literal process.env.NODE_ENV member expression is what bundler
|
|
2400
|
+
// define rewriting matches; a globalThis.process indirection is never
|
|
2401
|
+
// rewritten and leaves deployed browser bundles without any fast path.
|
|
2402
|
+
return process.env.NODE_ENV === "production" ? "static-fast" : "dynamic";
|
|
2403
|
+
} catch {
|
|
2404
|
+
// No process global at all: an unbundled browser runtime. Treat it as
|
|
2405
|
+
// production rather than running every host update on the slow path.
|
|
2406
|
+
return "static-fast";
|
|
2407
|
+
}
|
|
2408
|
+
})();
|
|
2409
|
+
|
|
2407
2410
|
function shouldUseDirectHostTextChild(): boolean {
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
+
if (hostFastPathMode === "static-fast") {
|
|
2412
|
+
return true;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// Node dev/test environments keep the per-call env read so test harnesses
|
|
2416
|
+
// can flip NODE_ENV (vi.stubEnv) without re-importing this module.
|
|
2417
|
+
return process.env.NODE_ENV === "production";
|
|
2411
2418
|
}
|
|
2412
2419
|
|
|
2413
2420
|
function syncDirectHostTextChild(element: Element, text: string): Text {
|
package/src/index.ts
CHANGED
|
@@ -91,6 +91,6 @@ export {
|
|
|
91
91
|
useTransition,
|
|
92
92
|
version,
|
|
93
93
|
} from "./hooks.js";
|
|
94
|
-
export { renderToString } from "./server-render.js";
|
|
94
|
+
export { renderChildToString, renderToString } from "./server-render.js";
|
|
95
95
|
export type { StartTransition, TransitionScope } from "./hooks.js";
|
|
96
96
|
export { default } from "./react-default.js";
|
package/src/react-default.ts
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
useTransition,
|
|
67
67
|
version,
|
|
68
68
|
} from "./hooks.js";
|
|
69
|
-
import { renderToString } from "./server-render.js";
|
|
69
|
+
import { renderChildToString, renderToString } from "./server-render.js";
|
|
70
70
|
|
|
71
71
|
const ReactCompat = {
|
|
72
72
|
Component,
|
|
@@ -123,6 +123,7 @@ const ReactCompat = {
|
|
|
123
123
|
cache,
|
|
124
124
|
cacheSignal,
|
|
125
125
|
captureOwnerStack,
|
|
126
|
+
renderChildToString,
|
|
126
127
|
renderToString,
|
|
127
128
|
startTransition,
|
|
128
129
|
unstable_useCacheRefresh,
|