Skip to content

Commit cfba033

Browse files
api
1 parent f9cf1bb commit cfba033

File tree

7 files changed

+193
-33
lines changed

7 files changed

+193
-33
lines changed

packages/myreact-reconciler/src/processHook/feature.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { __my_react_internal__ } from "@my-react/react";
22
import { HOOK_TYPE, ListTree, STATE_TYPE, include } from "@my-react/react-shared";
33

4+
import { listenerMap } from "../renderDispatch";
45
import { createHookNode, effectHookNode, updateHookNode } from "../runtimeHook";
5-
import { currentRenderDispatch } from "../share";
6+
import { currentRenderDispatch, safeCallWithFiber } from "../share";
67

78
import type { MyReactFiberNode } from "../runtimeFiber";
89
import type { MyReactHookNode } from "../runtimeHook";
@@ -47,9 +48,13 @@ export const processHookNode = ({ type, reducer, value, deps }: RenderHookParams
4748
// initial
4849
if (include(fiber.state, STATE_TYPE.__create__)) {
4950
currentHook = createHookNode({ type, reducer, value, deps }, fiber);
51+
52+
safeCallWithFiber({ fiber, action: () => listenerMap.get(renderDispatch)?.hookInitial?.forEach((cb) => cb(currentHook)) });
5053
} else {
5154
// update
5255
currentHook = updateHookNode({ type, reducer, value, deps }, fiber, __DEV__ && Boolean(include(fiber.state, STATE_TYPE.__hmr__)));
56+
57+
safeCallWithFiber({ fiber, action: () => listenerMap.get(renderDispatch)?.hookUpdate?.forEach((cb) => cb(currentHook)) });
5358
}
5459

5560
currentHookNodeIndex.current++;

packages/myreact-reconciler/src/processState/feature.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getInstanceOwnerFiber } from "../runtimeGenerate";
77
import { getCurrentDispatchFromFiber, getElementName, onceWarnWithKeyAndFiber, safeCallWithFiber, syncFlush } from "../share";
88

99
import type { MyReactFiberNode } from "../runtimeFiber";
10+
import type { MyReactHookNode } from "../runtimeHook";
1011
import type { MyReactInternalInstance, RenderFiber, UpdateQueue } from "@my-react/react";
1112

1213
export type UpdateQueueDev = UpdateQueue<{
@@ -44,7 +45,9 @@ export const processState = (_params: UpdateQueue) => {
4445

4546
const renderDispatch = getCurrentDispatchFromFiber(ownerFiber);
4647

47-
safeCallWithFiber({ fiber: ownerFiber, action: () => listenerMap.get(renderDispatch)?.fiberTrigger?.forEach((cb) => cb(ownerFiber, _params)) });
48+
if (renderDispatch?.enableUpdate) {
49+
safeCallWithFiber({ fiber: ownerFiber, action: () => listenerMap.get(renderDispatch)?.fiberTrigger?.forEach((cb) => cb(ownerFiber, _params)) });
50+
}
4851

4952
const isInitial = getInstanceOwnerFiber(_params.trigger as MyReactInternalInstance)?.mode === MODE_TYPE.__initial__;
5053

@@ -53,8 +56,6 @@ export const processState = (_params: UpdateQueue) => {
5356

5457
if (!ownerFiber || include(ownerFiber.state, STATE_TYPE.__unmount__)) return;
5558

56-
const renderDispatch = getCurrentDispatchFromFiber(ownerFiber);
57-
5859
// if current dispatch is a server || noop
5960
if (!renderDispatch.enableUpdate) return;
6061

@@ -108,8 +109,6 @@ export const processState = (_params: UpdateQueue) => {
108109

109110
if (!ownerFiber || include(ownerFiber?.state, STATE_TYPE.__unmount__)) return;
110111

111-
const renderDispatch = getCurrentDispatchFromFiber(ownerFiber);
112-
113112
if (!renderDispatch.enableUpdate) return;
114113

115114
if (__DEV__ && !syncFlush && currentComponentFiber.current) {
@@ -149,6 +148,10 @@ export const processState = (_params: UpdateQueue) => {
149148
lastRenderComponentTimeStep = now;
150149
}
151150

151+
const trigger = _params.trigger as MyReactHookNode;
152+
153+
safeCallWithFiber({ fiber: ownerFiber, action: () => listenerMap.get(renderDispatch)?.hookTrigger?.forEach((cb) => cb(trigger, _params)) });
154+
152155
ownerFiber.updateQueue = ownerFiber.updateQueue || new ListTree();
153156

154157
ownerFiber.updateQueue.push(_params);
@@ -159,8 +162,6 @@ export const processState = (_params: UpdateQueue) => {
159162

160163
if (!ownerFiber || include(ownerFiber.state, STATE_TYPE.__unmount__)) return;
161164

162-
const renderDispatch = getCurrentDispatchFromFiber(ownerFiber);
163-
164165
if (!renderDispatch.enableUpdate) return;
165166

166167
ownerFiber.updateQueue = ownerFiber.updateQueue || new ListTree();

packages/myreact-reconciler/src/renderDispatch/instance.ts

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,26 @@ import { MyWeakMap, NODE_TYPE, onceWarnWithKeyAndFiber, safeCall } from "../shar
1414

1515
import type { fiberKey, refKey, RenderDispatch, RuntimeMap } from "./interface";
1616
import type { MyReactFiberContainer, MyReactFiberNode } from "../runtimeFiber";
17+
import type { MyReactHookNode } from "../runtimeHook";
1718
import type { HMR } from "../share";
1819
import type { createContext, MyReactElementNode, UpdateQueue } from "@my-react/react";
1920

2021
type Listeners = {
2122
fiberInitial: Set<(fiber: MyReactFiberNode) => void>;
2223
fiberUpdate: Set<(fiber: MyReactFiberNode) => void>;
24+
fiberTrigger: Set<(fiber: MyReactFiberNode, updater: UpdateQueue) => void>;
2325
fiberUnmount: Set<(fiber: MyReactFiberNode) => void>;
2426
fiberHMR?: Set<(fiber: MyReactFiberNode) => void>;
27+
fiberWarn?: Set<(fiber: MyReactFiberNode, ...args: any) => void>;
28+
fiberError?: Set<(fiber: MyReactFiberNode, ...args: any) => void>;
2529
fiberHasChange: Set<(list: ListTree<MyReactFiberNode>) => void>;
26-
fiberTrigger: Set<(fiber: MyReactFiberNode, updater: UpdateQueue) => void>;
2730
performanceWarn?: Set<(fiber: MyReactFiberNode) => void>;
2831

32+
hookInitial: Set<(hook: MyReactHookNode) => void>;
33+
hookUpdate: Set<(hook: MyReactHookNode) => void>;
34+
hookTrigger: Set<(hook: MyReactHookNode, updater: UpdateQueue) => void>;
35+
hookUnmount: Set<(hook: MyReactHookNode) => void>;
36+
2937
beforeCommit: Set<() => void>;
3038
afterCommit: Set<() => void>;
3139
beforeUpdate: Set<() => void>;
@@ -42,8 +50,14 @@ const getInitialValue = (): Listeners => {
4250
fiberHasChange: new Set(),
4351
fiberUnmount: new Set(),
4452
fiberHMR: new Set(),
53+
fiberWarn: new Set(),
54+
fiberError: new Set(),
4555
fiberTrigger: new Set(),
4656
performanceWarn: new Set(),
57+
hookInitial: new Set(),
58+
hookUpdate: new Set(),
59+
hookTrigger: new Set(),
60+
hookUnmount: new Set(),
4761
beforeCommit: new Set(),
4862
afterCommit: new Set(),
4963
beforeUpdate: new Set(),
@@ -57,7 +71,10 @@ const getInitialValue = (): Listeners => {
5771
fiberHasChange: new Set(),
5872
fiberUnmount: new Set(),
5973
fiberTrigger: new Set(),
60-
performanceWarn: new Set(),
74+
hookInitial: new Set(),
75+
hookUpdate: new Set(),
76+
hookTrigger: new Set(),
77+
hookUnmount: new Set(),
6178
beforeCommit: new Set(),
6279
afterCommit: new Set(),
6380
beforeUpdate: new Set(),
@@ -285,12 +302,52 @@ export class CustomRenderDispatch implements RenderDispatch {
285302
set?.add?.(onceCb);
286303
}
287304

305+
onFiberWarn(cb: (_fiber: MyReactFiberNode, ...args: any) => void) {
306+
const set = listenerMap.get(this).fiberWarn;
307+
308+
set?.add?.(cb);
309+
310+
return () => set?.delete?.(cb);
311+
}
312+
313+
onceFiberWarn(cb: (_fiber: MyReactFiberNode, ...args: any) => void) {
314+
const set = listenerMap.get(this).fiberWarn;
315+
316+
const onceCb = (_fiber: MyReactFiberNode) => {
317+
cb(_fiber);
318+
319+
set?.delete?.(onceCb);
320+
};
321+
322+
set?.add?.(onceCb);
323+
}
324+
325+
onFiberError(cb: (_fiber: MyReactFiberNode, ...args: any) => void) {
326+
const set = listenerMap.get(this).fiberError;
327+
328+
set?.add?.(cb);
329+
330+
return () => set?.delete?.(cb);
331+
}
332+
333+
onceFiberError(cb: (_fiber: MyReactFiberNode, ...args: any) => void) {
334+
const set = listenerMap.get(this).fiberError;
335+
336+
const onceCb = (_fiber: MyReactFiberNode) => {
337+
cb(_fiber);
338+
339+
set?.delete?.(onceCb);
340+
};
341+
342+
set?.add?.(onceCb);
343+
}
344+
288345
onPerformanceWarn(cb: (_fiber: MyReactFiberNode) => void) {
289346
const set = listenerMap.get(this).performanceWarn;
290347

291-
set.add(cb);
348+
set?.add?.(cb);
292349

293-
return () => set.delete(cb);
350+
return () => set?.delete?.(cb);
294351
}
295352

296353
oncePerformanceWarn(cb: (_fiber: MyReactFiberNode) => void) {
@@ -299,6 +356,86 @@ export class CustomRenderDispatch implements RenderDispatch {
299356
const onceCb = (_fiber: MyReactFiberNode) => {
300357
cb(_fiber);
301358

359+
set?.delete?.(onceCb);
360+
};
361+
362+
set?.add?.(onceCb);
363+
}
364+
365+
onHookInitial(cb: (_hook: MyReactHookNode) => void) {
366+
const set = listenerMap.get(this).hookInitial;
367+
368+
set.add(cb);
369+
370+
return () => set.delete(cb);
371+
}
372+
373+
onceHookInitial(cb: (_hook: MyReactHookNode) => void) {
374+
const set = listenerMap.get(this).hookInitial;
375+
376+
const onceCb = (_hook: MyReactHookNode) => {
377+
cb(_hook);
378+
379+
set.delete(onceCb);
380+
};
381+
382+
set.add(onceCb);
383+
}
384+
385+
onHookUpdate(cb: (_hook: MyReactHookNode) => void) {
386+
const set = listenerMap.get(this).hookUpdate;
387+
388+
set.add(cb);
389+
390+
return () => set.delete(cb);
391+
}
392+
393+
onceHookUpdate(cb: (_hook: MyReactHookNode) => void) {
394+
const set = listenerMap.get(this).hookUpdate;
395+
396+
const onceCb = (_hook: MyReactHookNode) => {
397+
cb(_hook);
398+
399+
set.delete(onceCb);
400+
};
401+
402+
set.add(onceCb);
403+
}
404+
405+
onHookUnmount(cb: (_hook: MyReactHookNode) => void) {
406+
const set = listenerMap.get(this).hookUnmount;
407+
408+
set.add(cb);
409+
410+
return () => set.delete(cb);
411+
}
412+
413+
onceHookUnmount(cb: (_hook: MyReactHookNode) => void) {
414+
const set = listenerMap.get(this).hookUnmount;
415+
416+
const onceCb = (_hook: MyReactHookNode) => {
417+
cb(_hook);
418+
419+
set.delete(onceCb);
420+
};
421+
422+
set.add(onceCb);
423+
}
424+
425+
onHookTrigger(cb: (_hook: MyReactHookNode, _updater: UpdateQueue) => void) {
426+
const set = listenerMap.get(this).hookTrigger;
427+
428+
set.add(cb);
429+
430+
return () => set.delete(cb);
431+
}
432+
433+
onceHookTrigger(cb: (_hook: MyReactHookNode, _updater: UpdateQueue) => void) {
434+
const set = listenerMap.get(this).hookTrigger;
435+
436+
const onceCb = (_hook: MyReactHookNode, _updater: UpdateQueue) => {
437+
cb(_hook, _updater);
438+
302439
set.delete(onceCb);
303440
};
304441

packages/myreact-reconciler/src/renderUnmount/feature.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@ export const unmountList = (list: ListTree<MyReactFiberNode>, renderDispatch: Cu
1313
// will happen when app crash
1414
list.listToFoot((f) => unmountPending(f, renderDispatch));
1515

16-
list.listToFoot((f) =>
16+
list.listToFoot((f) => {
1717
safeCallWithFiber({
1818
fiber: f,
19-
action: () => {
20-
f._unmount();
21-
unmountFiberNode(f, renderDispatch);
22-
},
23-
})
24-
);
19+
action: () => f._unmount(() => unmountFiberNode(f, renderDispatch)),
20+
});
21+
});
2522
};
2623

2724
// unmount current fiber

packages/myreact-reconciler/src/runtimeHook/create.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export const createHookNode = ({ type, value, reducer, deps }: RenderHookParams,
168168
const line = i.getEnclosingLineNumber();
169169
const column = i.getEnclosingColumnNumber();
170170
const fileName = i.getFileName();
171-
const functionName = i.getFunctionName() || 'Anonymous';
171+
const functionName = i.getFunctionName() || "Anonymous";
172172
return { id: `${fileName}:${line}:${column}`, name: functionName };
173173
})
174174
.reverse();
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1+
import { listenerMap, type CustomRenderDispatch } from "../renderDispatch";
12
import { unmountInstance } from "../runtimeGenerate";
2-
import { safeCallWithFiber } from "../share";
3+
import { getCurrentDispatchFromFiber, safeCallWithFiber } from "../share";
34

45
import type { MyReactHookNode } from "./instance";
56
import type { MyReactFiberNode } from "../runtimeFiber";
67

7-
export const hookNodeUnmount = (hookNode: MyReactHookNode) => {
8+
export const hookNodeUnmount = (renderDispatch: CustomRenderDispatch, fiber: MyReactFiberNode, hookNode: MyReactHookNode) => {
89
hookNode.hasEffect = false;
910

1011
hookNode.cancel && hookNode.cancel();
1112

13+
safeCallWithFiber({ fiber, action: () => listenerMap.get(renderDispatch)?.hookUnmount?.forEach((cb) => cb(hookNode)) });
14+
1215
unmountInstance(hookNode);
1316
};
1417

1518
export const hookListUnmount = (fiber: MyReactFiberNode) => {
16-
fiber.hookList?.listToFoot?.((hookNode) => safeCallWithFiber({ fiber, action: () => hookNodeUnmount(hookNode as MyReactHookNode) }));
19+
const renderDispatch = getCurrentDispatchFromFiber(fiber);
20+
21+
fiber.hookList?.listToFoot?.((hookNode) => safeCallWithFiber({ fiber, action: () => hookNodeUnmount(renderDispatch, fiber, hookNode as MyReactHookNode) }));
1722
};

0 commit comments

Comments
 (0)