@reckona/mreact-compat 0.0.90 → 0.0.92
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 +20 -6
- package/dist/class-component.d.ts.map +1 -1
- package/dist/class-component.js +94 -51
- package/dist/class-component.js.map +1 -1
- package/dist/context.d.ts +19 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +55 -6
- package/dist/context.js.map +1 -1
- package/dist/dom-children.d.ts +2 -0
- package/dist/dom-children.d.ts.map +1 -1
- package/dist/dom-children.js +103 -1
- package/dist/dom-children.js.map +1 -1
- package/dist/dom-host-rules.d.ts +10 -0
- package/dist/dom-host-rules.d.ts.map +1 -0
- package/dist/dom-host-rules.js +86 -0
- package/dist/dom-host-rules.js.map +1 -0
- package/dist/dom-props.d.ts +3 -2
- package/dist/dom-props.d.ts.map +1 -1
- package/dist/dom-props.js +229 -33
- package/dist/dom-props.js.map +1 -1
- package/dist/element.d.ts +9 -4
- package/dist/element.d.ts.map +1 -1
- package/dist/element.js +101 -26
- package/dist/element.js.map +1 -1
- package/dist/event-listeners.d.ts +4 -4
- package/dist/event-listeners.d.ts.map +1 -1
- package/dist/event-listeners.js +1 -1
- package/dist/event-listeners.js.map +1 -1
- package/dist/event-types.d.ts +10 -0
- package/dist/event-types.d.ts.map +1 -1
- package/dist/event-types.js.map +1 -1
- package/dist/events.js +22 -1
- package/dist/events.js.map +1 -1
- package/dist/fiber-commit.d.ts +2 -1
- package/dist/fiber-commit.d.ts.map +1 -1
- package/dist/fiber-commit.js +13 -1
- package/dist/fiber-commit.js.map +1 -1
- package/dist/fiber-reconciler.d.ts.map +1 -1
- package/dist/fiber-reconciler.js +28 -7
- package/dist/fiber-reconciler.js.map +1 -1
- package/dist/fiber-work-loop.d.ts.map +1 -1
- package/dist/fiber-work-loop.js +4 -3
- package/dist/fiber-work-loop.js.map +1 -1
- package/dist/fiber.d.ts +5 -0
- package/dist/fiber.d.ts.map +1 -1
- package/dist/fiber.js +9 -0
- package/dist/fiber.js.map +1 -1
- package/dist/hooks-entry.d.ts +3 -0
- package/dist/hooks-entry.d.ts.map +1 -0
- package/dist/hooks-entry.js +2 -0
- package/dist/hooks-entry.js.map +1 -0
- package/dist/hooks.d.ts +39 -5
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +373 -326
- package/dist/hooks.js.map +1 -1
- package/dist/host-reconciler.d.ts +3 -0
- package/dist/host-reconciler.d.ts.map +1 -1
- package/dist/host-reconciler.js +1152 -64
- package/dist/host-reconciler.js.map +1 -1
- package/dist/hydration.d.ts +1 -1
- package/dist/hydration.d.ts.map +1 -1
- package/dist/hydration.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/react-default.d.ts +4 -4
- 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/reconciler.d.ts.map +1 -1
- package/dist/reconciler.js +38 -22
- package/dist/reconciler.js.map +1 -1
- package/dist/root.d.ts.map +1 -1
- package/dist/root.js +48 -13
- package/dist/root.js.map +1 -1
- package/dist/server-render.d.ts +6 -0
- package/dist/server-render.d.ts.map +1 -0
- package/dist/server-render.js +307 -0
- package/dist/server-render.js.map +1 -0
- package/package.json +6 -2
- package/src/class-component.ts +216 -51
- package/src/context.ts +108 -9
- package/src/dom-children.ts +155 -1
- package/src/dom-host-rules.ts +115 -0
- package/src/dom-props.ts +297 -46
- package/src/element.ts +141 -31
- package/src/event-listeners.ts +6 -6
- package/src/event-types.ts +10 -0
- package/src/events.ts +32 -10
- package/src/fiber-commit.ts +16 -1
- package/src/fiber-reconciler.ts +39 -6
- package/src/fiber-work-loop.ts +4 -3
- package/src/fiber.ts +14 -0
- package/src/hooks-entry.ts +24 -0
- package/src/hooks.ts +482 -479
- package/src/host-reconciler.ts +1628 -94
- package/src/hydration.ts +1 -1
- package/src/index.ts +1 -1
- package/src/react-default.ts +1 -1
- package/src/reconciler.ts +61 -22
- package/src/root.ts +55 -12
- package/src/server-render.ts +478 -0
package/src/element.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
export const REACT_COMPAT_ELEMENT_TYPE = Symbol.for("
|
|
1
|
+
export const REACT_COMPAT_ELEMENT_TYPE = Symbol.for("react.transitional.element");
|
|
2
2
|
export const ERROR_BOUNDARY_TYPE = Symbol.for("modular.react.error_boundary");
|
|
3
|
-
export const FORWARD_REF_TYPE = Symbol.for("
|
|
4
|
-
export const MEMO_TYPE = Symbol.for("
|
|
5
|
-
export const LAZY_TYPE = Symbol.for("
|
|
6
|
-
export const STRICT_MODE_TYPE = Symbol.for("
|
|
7
|
-
export const PORTAL_TYPE = Symbol.for("
|
|
8
|
-
const REACT_COMPAT_PROVIDER_TYPE = Symbol.for("
|
|
9
|
-
export const Fragment = Symbol.for("
|
|
10
|
-
export const Suspense = Symbol.for("
|
|
11
|
-
export const SuspenseList = Symbol.for("
|
|
12
|
-
export const Activity = Symbol.for("
|
|
13
|
-
export const Profiler = Symbol.for("
|
|
3
|
+
export const FORWARD_REF_TYPE = Symbol.for("react.forward_ref");
|
|
4
|
+
export const MEMO_TYPE = Symbol.for("react.memo");
|
|
5
|
+
export const LAZY_TYPE = Symbol.for("react.lazy");
|
|
6
|
+
export const STRICT_MODE_TYPE = Symbol.for("react.strict_mode");
|
|
7
|
+
export const PORTAL_TYPE = Symbol.for("react.portal");
|
|
8
|
+
const REACT_COMPAT_PROVIDER_TYPE = Symbol.for("react.context");
|
|
9
|
+
export const Fragment = Symbol.for("react.fragment");
|
|
10
|
+
export const Suspense = Symbol.for("react.suspense");
|
|
11
|
+
export const SuspenseList = Symbol.for("react.suspense_list");
|
|
12
|
+
export const Activity = Symbol.for("react.activity");
|
|
13
|
+
export const Profiler = Symbol.for("react.profiler");
|
|
14
|
+
export const HOST_OWN_PROPS_META = Symbol.for("modular.react.host_own_props_meta");
|
|
15
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
14
16
|
|
|
15
17
|
export interface ReactCompatProviderType {
|
|
16
18
|
$$typeof: symbol;
|
|
@@ -66,20 +68,38 @@ export interface ReactCompatPortal {
|
|
|
66
68
|
|
|
67
69
|
export function createElement<P extends Record<string, unknown>>(
|
|
68
70
|
type: ElementType<P>,
|
|
69
|
-
config: (P &
|
|
71
|
+
config: (P & ReactReservedProps) | null,
|
|
70
72
|
...children: ReactCompatNode[]
|
|
71
73
|
): ReactCompatElement<P> {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
if (typeof type === "string") {
|
|
75
|
+
const key = config?.key === undefined ? null : String(config.key);
|
|
76
|
+
const ref = config?.ref ?? null;
|
|
77
|
+
const props = copyElementProps(config) as P & { children?: ReactCompatNode };
|
|
78
|
+
|
|
79
|
+
if (children.length === 1) {
|
|
80
|
+
props.children = children[0];
|
|
81
|
+
} else if (children.length > 1) {
|
|
82
|
+
props.children = children;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
setHostOwnPropsMeta(props);
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
$$typeof: REACT_COMPAT_ELEMENT_TYPE,
|
|
89
|
+
type,
|
|
90
|
+
key,
|
|
91
|
+
ref,
|
|
92
|
+
props,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const normalizedType =
|
|
97
|
+
typeof type === "object" && type !== null ? normalizeElementType(type) : type;
|
|
98
|
+
const key = config?.key === undefined ? null : String(config.key);
|
|
99
|
+
const ref = config?.ref ?? null;
|
|
100
|
+
const props = applyDefaultProps(normalizedType, copyElementProps(config)) as P & {
|
|
74
101
|
children?: ReactCompatNode;
|
|
75
|
-
key?: unknown;
|
|
76
|
-
ref?: unknown;
|
|
77
102
|
};
|
|
78
|
-
const key = props.key === undefined ? null : String(props.key);
|
|
79
|
-
const ref = props.ref ?? null;
|
|
80
|
-
|
|
81
|
-
delete props.key;
|
|
82
|
-
delete props.ref;
|
|
83
103
|
|
|
84
104
|
if (children.length === 1) {
|
|
85
105
|
props.children = children[0];
|
|
@@ -87,6 +107,10 @@ export function createElement<P extends Record<string, unknown>>(
|
|
|
87
107
|
props.children = children;
|
|
88
108
|
}
|
|
89
109
|
|
|
110
|
+
if (typeof normalizedType === "string") {
|
|
111
|
+
setHostOwnPropsMeta(props);
|
|
112
|
+
}
|
|
113
|
+
|
|
90
114
|
return {
|
|
91
115
|
$$typeof: REACT_COMPAT_ELEMENT_TYPE,
|
|
92
116
|
type: normalizedType as ElementType<P>,
|
|
@@ -183,15 +207,12 @@ export function cloneElement<P extends Record<string, unknown>>(
|
|
|
183
207
|
props: Partial<P> | null,
|
|
184
208
|
...children: ReactCompatNode[]
|
|
185
209
|
): ReactCompatElement<P> {
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
delete nextProps.key;
|
|
194
|
-
delete nextProps.ref;
|
|
210
|
+
const key = props === null || props.key === undefined ? element.key : String(props.key);
|
|
211
|
+
const ref = props === null || props.ref === undefined ? element.ref : props.ref;
|
|
212
|
+
const nextProps = applyDefaultProps(
|
|
213
|
+
element.type,
|
|
214
|
+
copyElementProps(props, element.props),
|
|
215
|
+
) as P & { children?: ReactCompatNode };
|
|
195
216
|
|
|
196
217
|
if (children.length === 1) {
|
|
197
218
|
(nextProps as P & { children?: ReactCompatNode }).children = children[0];
|
|
@@ -208,6 +229,29 @@ export function cloneElement<P extends Record<string, unknown>>(
|
|
|
208
229
|
};
|
|
209
230
|
}
|
|
210
231
|
|
|
232
|
+
function copyElementProps(
|
|
233
|
+
source: Record<string, unknown> | null | undefined,
|
|
234
|
+
base?: Record<string, unknown>,
|
|
235
|
+
): Record<string, unknown> {
|
|
236
|
+
const props: Record<string, unknown> = base === undefined ? {} : { ...base };
|
|
237
|
+
|
|
238
|
+
if (source === null || source === undefined) {
|
|
239
|
+
return props;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
for (const name in source) {
|
|
243
|
+
if (!hasOwnProperty.call(source, name)) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (name !== "key" && name !== "ref" && name !== "__self" && name !== "__source") {
|
|
248
|
+
props[name] = source[name];
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return props;
|
|
253
|
+
}
|
|
254
|
+
|
|
211
255
|
function normalizeElementType<P>(type: ElementType<P>): ElementType<P> {
|
|
212
256
|
return isReactCompatContextProviderShorthand(type) ? (type.Provider as ElementType<P>) : type;
|
|
213
257
|
}
|
|
@@ -216,6 +260,10 @@ function applyDefaultProps(
|
|
|
216
260
|
type: unknown,
|
|
217
261
|
props: Record<string, unknown>,
|
|
218
262
|
): Record<string, unknown> {
|
|
263
|
+
if (typeof type !== "function" && (typeof type !== "object" || type === null)) {
|
|
264
|
+
return props;
|
|
265
|
+
}
|
|
266
|
+
|
|
219
267
|
const defaultProps = (type as { defaultProps?: Record<string, unknown> } | undefined)
|
|
220
268
|
?.defaultProps;
|
|
221
269
|
|
|
@@ -232,6 +280,13 @@ function applyDefaultProps(
|
|
|
232
280
|
return props;
|
|
233
281
|
}
|
|
234
282
|
|
|
283
|
+
interface ReactReservedProps {
|
|
284
|
+
key?: unknown;
|
|
285
|
+
ref?: unknown;
|
|
286
|
+
__self?: unknown;
|
|
287
|
+
__source?: unknown;
|
|
288
|
+
}
|
|
289
|
+
|
|
235
290
|
function isReactCompatContextProviderShorthand(
|
|
236
291
|
value: unknown,
|
|
237
292
|
): value is ReactCompatContextProviderShorthand {
|
|
@@ -248,6 +303,61 @@ function isReactCompatContextProviderShorthand(
|
|
|
248
303
|
);
|
|
249
304
|
}
|
|
250
305
|
|
|
306
|
+
function setHostOwnPropsMeta(props: Record<string, unknown>): void {
|
|
307
|
+
const dataKey = props["data-key"];
|
|
308
|
+
|
|
309
|
+
if (typeof dataKey !== "number" || !Number.isSafeInteger(dataKey) || dataKey < 0) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
let selectedState = 0;
|
|
314
|
+
|
|
315
|
+
for (const name in props) {
|
|
316
|
+
if (!hasOwnProperty.call(props, name) || name === "children") {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (name === "data-key") {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (name === "className") {
|
|
325
|
+
const value = props[name];
|
|
326
|
+
|
|
327
|
+
if (value === undefined) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (value !== "selected") {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
selectedState |= 1;
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (name === "data-selected") {
|
|
340
|
+
const value = props[name];
|
|
341
|
+
|
|
342
|
+
if (value === undefined) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (value !== "true") {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
selectedState |= 2;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
(props as { [HOST_OWN_PROPS_META]?: number })[HOST_OWN_PROPS_META] =
|
|
358
|
+
dataKey * 4 + selectedState;
|
|
359
|
+
}
|
|
360
|
+
|
|
251
361
|
export const isValidElement = isReactCompatElement;
|
|
252
362
|
|
|
253
363
|
export const Children = {
|
package/src/event-listeners.ts
CHANGED
|
@@ -2,26 +2,26 @@ import type { SyntheticEvent } from "./event-types.js";
|
|
|
2
2
|
|
|
3
3
|
export interface AppliedProps {
|
|
4
4
|
props: Record<string, unknown>;
|
|
5
|
-
listeners
|
|
5
|
+
listeners?: Map<string, AppliedEventListener>;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export interface AppliedEventListener {
|
|
9
9
|
handler: (event: SyntheticEvent) => void;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const appliedProps = new WeakMap<
|
|
12
|
+
const appliedProps = new WeakMap<Element, AppliedProps>();
|
|
13
13
|
|
|
14
|
-
export function getAppliedProps(element:
|
|
14
|
+
export function getAppliedProps(element: Element): AppliedProps | undefined {
|
|
15
15
|
return appliedProps.get(element);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export function setAppliedProps(element:
|
|
18
|
+
export function setAppliedProps(element: Element, props: AppliedProps): void {
|
|
19
19
|
appliedProps.set(element, props);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export function getAppliedEventHandler(
|
|
23
|
-
element:
|
|
23
|
+
element: Element,
|
|
24
24
|
name: string,
|
|
25
25
|
): ((event: SyntheticEvent) => void) | undefined {
|
|
26
|
-
return appliedProps.get(element)?.listeners
|
|
26
|
+
return appliedProps.get(element)?.listeners?.get(name)?.handler;
|
|
27
27
|
}
|
package/src/event-types.ts
CHANGED
|
@@ -9,6 +9,16 @@ export interface SyntheticEvent {
|
|
|
9
9
|
type: string;
|
|
10
10
|
target: EventTarget | null;
|
|
11
11
|
currentTarget: EventTarget | null;
|
|
12
|
+
clientX?: number;
|
|
13
|
+
clientY?: number;
|
|
14
|
+
pageX?: number;
|
|
15
|
+
pageY?: number;
|
|
16
|
+
screenX?: number;
|
|
17
|
+
screenY?: number;
|
|
18
|
+
relatedTarget?: EventTarget | null;
|
|
19
|
+
touches?: TouchList;
|
|
20
|
+
changedTouches?: TouchList;
|
|
21
|
+
key?: string;
|
|
12
22
|
persist(): void;
|
|
13
23
|
preventDefault(): void;
|
|
14
24
|
stopPropagation(): void;
|
package/src/events.ts
CHANGED
|
@@ -193,7 +193,7 @@ function dispatchDelegatedEvent(
|
|
|
193
193
|
};
|
|
194
194
|
|
|
195
195
|
for (let index = path.length - 1; index >= 0; index -= 1) {
|
|
196
|
-
const target = path[index]
|
|
196
|
+
const target = path[index]!;
|
|
197
197
|
dispatchEventPropNames(propNames, "capture", event, target, state);
|
|
198
198
|
|
|
199
199
|
if (state.propagationStopped) {
|
|
@@ -203,7 +203,7 @@ function dispatchDelegatedEvent(
|
|
|
203
203
|
|
|
204
204
|
if (eventName === "mouseover") {
|
|
205
205
|
for (let index = path.length - 1; index >= 0; index -= 1) {
|
|
206
|
-
const target = path[index]
|
|
206
|
+
const target = path[index]!;
|
|
207
207
|
dispatchMouseTransitionEvent("onMouseEnter", event, target, state);
|
|
208
208
|
|
|
209
209
|
if (state.propagationStopped) {
|
|
@@ -224,7 +224,7 @@ function dispatchDelegatedEvent(
|
|
|
224
224
|
|
|
225
225
|
if (eventName === "pointerover") {
|
|
226
226
|
for (let index = path.length - 1; index >= 0; index -= 1) {
|
|
227
|
-
const target = path[index]
|
|
227
|
+
const target = path[index]!;
|
|
228
228
|
dispatchPointerTransitionEvent("onPointerEnter", event, target, state);
|
|
229
229
|
|
|
230
230
|
if (state.propagationStopped) {
|
|
@@ -255,7 +255,7 @@ function dispatchDelegatedEvent(
|
|
|
255
255
|
function dispatchPointerTransitionEvent(
|
|
256
256
|
propName: "onPointerEnter" | "onPointerLeave",
|
|
257
257
|
event: Event,
|
|
258
|
-
target:
|
|
258
|
+
target: Element,
|
|
259
259
|
state: { defaultPrevented: boolean; propagationStopped: boolean },
|
|
260
260
|
): void {
|
|
261
261
|
if (isInternalMouseTransition(event, target)) {
|
|
@@ -273,7 +273,7 @@ function dispatchEventPropNames(
|
|
|
273
273
|
propNames: readonly string[],
|
|
274
274
|
phase: "capture" | "bubble",
|
|
275
275
|
event: Event,
|
|
276
|
-
target:
|
|
276
|
+
target: Element,
|
|
277
277
|
state: { defaultPrevented: boolean; propagationStopped: boolean },
|
|
278
278
|
): void {
|
|
279
279
|
for (const propName of propNames) {
|
|
@@ -293,7 +293,7 @@ function dispatchEventPropNames(
|
|
|
293
293
|
function dispatchMouseTransitionEvent(
|
|
294
294
|
propName: "onMouseEnter" | "onMouseLeave",
|
|
295
295
|
event: Event,
|
|
296
|
-
target:
|
|
296
|
+
target: Element,
|
|
297
297
|
state: { defaultPrevented: boolean; propagationStopped: boolean },
|
|
298
298
|
): void {
|
|
299
299
|
if (isInternalMouseTransition(event, target)) {
|
|
@@ -307,7 +307,7 @@ function dispatchMouseTransitionEvent(
|
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
function isInternalMouseTransition(event: Event, target:
|
|
310
|
+
function isInternalMouseTransition(event: Event, target: Element): boolean {
|
|
311
311
|
const relatedTarget =
|
|
312
312
|
event instanceof MouseEvent && event.relatedTarget instanceof Node
|
|
313
313
|
? event.relatedTarget
|
|
@@ -316,12 +316,12 @@ function isInternalMouseTransition(event: Event, target: HTMLElement): boolean {
|
|
|
316
316
|
return relatedTarget !== null && target.contains(relatedTarget);
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
-
function getEventPath(root: Element, event: Event):
|
|
320
|
-
const path:
|
|
319
|
+
function getEventPath(root: Element, event: Event): Element[] {
|
|
320
|
+
const path: Element[] = [];
|
|
321
321
|
let cursor = event.target instanceof Node ? event.target : null;
|
|
322
322
|
|
|
323
323
|
while (cursor !== null) {
|
|
324
|
-
if (cursor instanceof
|
|
324
|
+
if (cursor instanceof Element) {
|
|
325
325
|
path.push(cursor);
|
|
326
326
|
}
|
|
327
327
|
|
|
@@ -349,6 +349,10 @@ function createSyntheticEvent(
|
|
|
349
349
|
},
|
|
350
350
|
syntheticType = nativeEvent.type,
|
|
351
351
|
): SyntheticEvent {
|
|
352
|
+
const mouseEvent = nativeEvent instanceof MouseEvent ? nativeEvent : undefined;
|
|
353
|
+
const touchEvent = nativeEvent instanceof TouchEvent ? nativeEvent : undefined;
|
|
354
|
+
const keyboardEvent = nativeEvent instanceof KeyboardEvent ? nativeEvent : undefined;
|
|
355
|
+
|
|
352
356
|
return {
|
|
353
357
|
bubbles: nativeEvent.bubbles,
|
|
354
358
|
cancelable: nativeEvent.cancelable,
|
|
@@ -362,6 +366,24 @@ function createSyntheticEvent(
|
|
|
362
366
|
type: syntheticType,
|
|
363
367
|
target: nativeEvent.target,
|
|
364
368
|
currentTarget,
|
|
369
|
+
...(mouseEvent === undefined
|
|
370
|
+
? {}
|
|
371
|
+
: {
|
|
372
|
+
clientX: mouseEvent.clientX,
|
|
373
|
+
clientY: mouseEvent.clientY,
|
|
374
|
+
pageX: mouseEvent.pageX,
|
|
375
|
+
pageY: mouseEvent.pageY,
|
|
376
|
+
screenX: mouseEvent.screenX,
|
|
377
|
+
screenY: mouseEvent.screenY,
|
|
378
|
+
relatedTarget: mouseEvent.relatedTarget,
|
|
379
|
+
}),
|
|
380
|
+
...(touchEvent === undefined
|
|
381
|
+
? {}
|
|
382
|
+
: {
|
|
383
|
+
touches: touchEvent.touches,
|
|
384
|
+
changedTouches: touchEvent.changedTouches,
|
|
385
|
+
}),
|
|
386
|
+
...(keyboardEvent === undefined ? {} : { key: keyboardEvent.key }),
|
|
365
387
|
persist() {},
|
|
366
388
|
preventDefault() {
|
|
367
389
|
state.defaultPrevented = true;
|
package/src/fiber-commit.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Fiber, FiberRoot } from "./fiber.js";
|
|
2
2
|
import { commitHostFiberRoot } from "./fiber-host.js";
|
|
3
3
|
import { markRootFinished } from "./fiber-lanes.js";
|
|
4
|
+
import { runWithHostCommit } from "./hooks.js";
|
|
4
5
|
import type { RenderOptions } from "./hydration.js";
|
|
5
6
|
|
|
6
7
|
interface RefRecord {
|
|
@@ -18,7 +19,15 @@ export function commitFiberRoot(
|
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
if (
|
|
23
|
+
root.refCleanupKnown !== true ||
|
|
24
|
+
root.current.hasRefSubtree ||
|
|
25
|
+
finishedWork.hasRefSubtree
|
|
26
|
+
) {
|
|
27
|
+
runWithHostCommit(() => {
|
|
28
|
+
cleanupDeletedRefs(root.current, finishedWork);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
22
31
|
commitHostFiberRoot(root, finishedWork, options);
|
|
23
32
|
root.current = finishedWork;
|
|
24
33
|
root.current.stateNode = root;
|
|
@@ -29,6 +38,12 @@ export function commitFiberRoot(
|
|
|
29
38
|
root.workInProgressRootRenderLanes = 0;
|
|
30
39
|
}
|
|
31
40
|
|
|
41
|
+
export function detachFiberRefs(fiber: Fiber): void {
|
|
42
|
+
for (const record of collectRefRecords(fiber)) {
|
|
43
|
+
detachRef(record.ref);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
function cleanupDeletedRefs(previous: Fiber, next: Fiber): void {
|
|
33
48
|
const nextRefs = new Set<unknown>();
|
|
34
49
|
|
package/src/fiber-reconciler.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
type ReactCompatNode,
|
|
15
15
|
} from "./element.js";
|
|
16
16
|
import {
|
|
17
|
+
consumerContext,
|
|
17
18
|
isReactCompatConsumer,
|
|
18
19
|
isReactCompatProvider,
|
|
19
20
|
popContextProvider,
|
|
@@ -27,12 +28,20 @@ import { DidCapture } from "./fiber-flags.js";
|
|
|
27
28
|
import { mergeLanes, NoLanes } from "./fiber-lanes.js";
|
|
28
29
|
import { isThenable } from "./thenable.js";
|
|
29
30
|
import {
|
|
30
|
-
applyDerivedStateFromProps,
|
|
31
31
|
isClassComponentType,
|
|
32
|
+
resolveDerivedStateFromProps,
|
|
32
33
|
type ClassComponentInstance,
|
|
33
34
|
type ClassComponentType,
|
|
34
35
|
} from "./class-component.js";
|
|
35
36
|
import { areMemoPropsEqual } from "./prop-comparison.js";
|
|
37
|
+
import {
|
|
38
|
+
createHostElement,
|
|
39
|
+
hostElementMatches,
|
|
40
|
+
isHostElement,
|
|
41
|
+
namespaceForHostChildren,
|
|
42
|
+
namespaceForHostElement,
|
|
43
|
+
type HostNamespace,
|
|
44
|
+
} from "./dom-host-rules.js";
|
|
36
45
|
|
|
37
46
|
interface ContextProviderFiberState {
|
|
38
47
|
provider: ReactCompatProvider<unknown>;
|
|
@@ -159,7 +168,7 @@ export function beginWork(unit: Fiber): Fiber | undefined {
|
|
|
159
168
|
return reconcileChildFibers(
|
|
160
169
|
unit,
|
|
161
170
|
unit.alternate?.child,
|
|
162
|
-
render(useContext(unit.type
|
|
171
|
+
render(useContext(consumerContext(unit.type))),
|
|
163
172
|
);
|
|
164
173
|
}
|
|
165
174
|
|
|
@@ -288,13 +297,16 @@ export function completeWork(unit: Fiber): void {
|
|
|
288
297
|
|
|
289
298
|
if (unit.tag === "host-component") {
|
|
290
299
|
const current = unit.alternate;
|
|
300
|
+
const parentNamespace = parentHostNamespace(unit);
|
|
301
|
+
const elementNamespace = namespaceForHostElement(parentNamespace, String(unit.type));
|
|
291
302
|
|
|
292
303
|
unit.stateNode =
|
|
293
304
|
current?.tag === "host-component" &&
|
|
294
305
|
current.type === unit.type &&
|
|
295
|
-
current.stateNode
|
|
306
|
+
isHostElement(current.stateNode) &&
|
|
307
|
+
hostElementMatches(current.stateNode, String(unit.type), elementNamespace)
|
|
296
308
|
? current.stateNode
|
|
297
|
-
: document
|
|
309
|
+
: createHostElement(document, String(unit.type), parentNamespace);
|
|
298
310
|
return;
|
|
299
311
|
}
|
|
300
312
|
|
|
@@ -308,6 +320,27 @@ export function completeWork(unit: Fiber): void {
|
|
|
308
320
|
}
|
|
309
321
|
}
|
|
310
322
|
|
|
323
|
+
function parentHostNamespace(unit: Fiber): HostNamespace {
|
|
324
|
+
const ancestors: string[] = [];
|
|
325
|
+
let current = unit.return;
|
|
326
|
+
|
|
327
|
+
while (current !== undefined) {
|
|
328
|
+
if (current.tag === "host-component" && typeof current.type === "string") {
|
|
329
|
+
ancestors.push(current.type);
|
|
330
|
+
}
|
|
331
|
+
current = current.return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
let namespace: HostNamespace = "html";
|
|
335
|
+
for (let index = ancestors.length - 1; index >= 0; index -= 1) {
|
|
336
|
+
const tagName = ancestors[index] ?? "";
|
|
337
|
+
const elementNamespace = namespaceForHostElement(namespace, tagName);
|
|
338
|
+
namespace = namespaceForHostChildren(elementNamespace, tagName);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return namespace;
|
|
342
|
+
}
|
|
343
|
+
|
|
311
344
|
export function cleanupUnfinishedWork(unit: Fiber | undefined): void {
|
|
312
345
|
if (unit === undefined) {
|
|
313
346
|
return;
|
|
@@ -520,8 +553,7 @@ function beginClassComponent(
|
|
|
520
553
|
: undefined;
|
|
521
554
|
const instance = currentInstance ?? new type(nextProps);
|
|
522
555
|
const previousState = instance.state ?? {};
|
|
523
|
-
|
|
524
|
-
const nextState = instance.state ?? {};
|
|
556
|
+
const nextState = resolveDerivedStateFromProps(type, nextProps, previousState);
|
|
525
557
|
|
|
526
558
|
unit.stateNode = instance;
|
|
527
559
|
|
|
@@ -535,6 +567,7 @@ function beginClassComponent(
|
|
|
535
567
|
}
|
|
536
568
|
|
|
537
569
|
instance.props = nextProps;
|
|
570
|
+
instance.state = nextState;
|
|
538
571
|
return reconcileChildFibers(unit, unit.alternate?.child, instance.render());
|
|
539
572
|
}
|
|
540
573
|
|
package/src/fiber-work-loop.ts
CHANGED
|
@@ -177,9 +177,10 @@ export function performSyncWorkOnRoot(
|
|
|
177
177
|
fallbackFinishedWork.lanes = lanes;
|
|
178
178
|
fallbackFinishedWork.memoizedProps = { children: element };
|
|
179
179
|
const committedWork = commit();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
if (committedWork === undefined) {
|
|
181
|
+
root.current = fallbackFinishedWork;
|
|
182
|
+
root.current.stateNode = root;
|
|
183
|
+
}
|
|
183
184
|
root.finishedWork = undefined;
|
|
184
185
|
root.workInProgress = undefined;
|
|
185
186
|
root.workInProgressRootRenderLanes = 0;
|
package/src/fiber.ts
CHANGED
|
@@ -34,10 +34,14 @@ export interface Fiber {
|
|
|
34
34
|
stateNode: unknown;
|
|
35
35
|
flags: Flags;
|
|
36
36
|
subtreeFlags: Flags;
|
|
37
|
+
childListChanged: boolean;
|
|
38
|
+
subtreeChildListChanged: boolean;
|
|
37
39
|
deletions: Fiber[] | undefined;
|
|
38
40
|
lanes: Lanes;
|
|
39
41
|
childLanes: Lanes;
|
|
40
42
|
hydrateExisting: boolean;
|
|
43
|
+
hasRefSubtree: boolean;
|
|
44
|
+
hostChildListChanged: boolean;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
export interface FiberRoot {
|
|
@@ -55,6 +59,7 @@ export interface FiberRoot {
|
|
|
55
59
|
workInProgressRootRenderLanes: Lanes;
|
|
56
60
|
workInProgressElement: unknown;
|
|
57
61
|
hydrationState: FiberHydrationState | undefined;
|
|
62
|
+
refCleanupKnown: boolean;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
export interface FiberHydrationState {
|
|
@@ -84,10 +89,14 @@ export function createFiber(
|
|
|
84
89
|
stateNode: undefined,
|
|
85
90
|
flags: NoFlags,
|
|
86
91
|
subtreeFlags: NoFlags,
|
|
92
|
+
childListChanged: false,
|
|
93
|
+
subtreeChildListChanged: false,
|
|
87
94
|
deletions: undefined,
|
|
88
95
|
lanes: NoLanes,
|
|
89
96
|
childLanes: NoLanes,
|
|
90
97
|
hydrateExisting: false,
|
|
98
|
+
hasRefSubtree: false,
|
|
99
|
+
hostChildListChanged: false,
|
|
91
100
|
};
|
|
92
101
|
}
|
|
93
102
|
|
|
@@ -112,6 +121,7 @@ export function createFiberRoot(container: Element): FiberRoot {
|
|
|
112
121
|
workInProgressRootRenderLanes: NoLanes,
|
|
113
122
|
workInProgressElement: undefined,
|
|
114
123
|
hydrationState: undefined,
|
|
124
|
+
refCleanupKnown: false,
|
|
115
125
|
};
|
|
116
126
|
current.stateNode = root;
|
|
117
127
|
return root;
|
|
@@ -133,6 +143,8 @@ export function createWorkInProgress(
|
|
|
133
143
|
workInProgress.pendingProps = pendingProps;
|
|
134
144
|
workInProgress.flags = NoFlags;
|
|
135
145
|
workInProgress.subtreeFlags = NoFlags;
|
|
146
|
+
workInProgress.childListChanged = false;
|
|
147
|
+
workInProgress.subtreeChildListChanged = false;
|
|
136
148
|
workInProgress.deletions = undefined;
|
|
137
149
|
}
|
|
138
150
|
|
|
@@ -144,5 +156,7 @@ export function createWorkInProgress(
|
|
|
144
156
|
workInProgress.lanes = current.lanes;
|
|
145
157
|
workInProgress.childLanes = current.childLanes;
|
|
146
158
|
workInProgress.hydrateExisting = false;
|
|
159
|
+
workInProgress.hasRefSubtree = current.hasRefSubtree;
|
|
160
|
+
workInProgress.hostChildListChanged = current.hostChildListChanged;
|
|
147
161
|
return workInProgress;
|
|
148
162
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export {
|
|
2
|
+
useCallback,
|
|
3
|
+
useDebugValue,
|
|
4
|
+
useDeferredValue,
|
|
5
|
+
useEffectEvent,
|
|
6
|
+
useEffect,
|
|
7
|
+
useId,
|
|
8
|
+
useImperativeHandle,
|
|
9
|
+
useInsertionEffect,
|
|
10
|
+
useLayoutEffect,
|
|
11
|
+
useMemo,
|
|
12
|
+
useOptimistic,
|
|
13
|
+
useReducer,
|
|
14
|
+
useRef,
|
|
15
|
+
useState,
|
|
16
|
+
useSyncExternalStore,
|
|
17
|
+
use,
|
|
18
|
+
useActionState,
|
|
19
|
+
startTransition,
|
|
20
|
+
unstable_useCacheRefresh,
|
|
21
|
+
useTransition,
|
|
22
|
+
version,
|
|
23
|
+
} from "./hooks.js";
|
|
24
|
+
export type { StartTransition, TransitionScope } from "./hooks.js";
|