@lukekaalim/act-recon 2.0.0 → 3.0.0-alpha.0
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/CHANGELOG.md +6 -0
- package/event.ts +16 -20
- package/package.json +1 -1
- package/reconciler.ts +13 -12
package/CHANGELOG.md
CHANGED
package/event.ts
CHANGED
|
@@ -1,34 +1,30 @@
|
|
|
1
1
|
export type Subscription = { cancel: () => void };
|
|
2
2
|
export type EventHandler<T> = (event: T) => unknown;
|
|
3
|
-
export type EventMap = Record<string, unknown>;
|
|
4
3
|
|
|
5
|
-
export type EventEmitter<T
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
4
|
+
export type EventEmitter<T> = {
|
|
5
|
+
subscribe(handler: EventHandler<T>): Subscription,
|
|
6
|
+
emit(event: T): void;
|
|
7
|
+
};
|
|
9
8
|
|
|
10
|
-
export const createEventEmitter = <T
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const handlers = new Map<keyof T, Set<AnyHandler>>();
|
|
9
|
+
export const createEventEmitter = <T>(): EventEmitter<T> => {
|
|
10
|
+
const handlers = new Map<number, EventHandler<T>>();
|
|
11
|
+
let counter = 0;
|
|
14
12
|
|
|
15
13
|
return {
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
handlers.set(
|
|
19
|
-
set.add(handler as AnyHandler);
|
|
14
|
+
subscribe(handler) {
|
|
15
|
+
const id = counter++;
|
|
16
|
+
handlers.set(id, handler);
|
|
20
17
|
return {
|
|
21
18
|
cancel() {
|
|
22
|
-
|
|
19
|
+
handlers.delete(id);
|
|
23
20
|
},
|
|
24
21
|
}
|
|
25
22
|
},
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
handler(event);
|
|
23
|
+
emit(event) {
|
|
24
|
+
for (const handler of handlers.values())
|
|
25
|
+
try {
|
|
26
|
+
handler(event);
|
|
27
|
+
} finally {}
|
|
32
28
|
},
|
|
33
29
|
}
|
|
34
30
|
};
|
package/package.json
CHANGED
package/reconciler.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type Reconciler = {
|
|
|
13
13
|
state: ReconcilerState,
|
|
14
14
|
tree: CommitTree,
|
|
15
15
|
elements: ElementService,
|
|
16
|
-
|
|
16
|
+
subscribe: EventEmitter<ReconcilerEvent>["subscribe"],
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export type ReconcilerState = {
|
|
@@ -25,14 +25,15 @@ export type ReconcilerState = {
|
|
|
25
25
|
pendingTargets: Map<CommitID, CommitRef>,
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export type
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
}
|
|
28
|
+
export type ReconcilerEvent =
|
|
29
|
+
| { type: 'thread:start', thread: WorkThread }
|
|
30
|
+
| { type: 'thread:update', thread: WorkThread }
|
|
31
|
+
| { type: 'thread:complete', thread: WorkThread }
|
|
32
|
+
| { type: 'thread:new-target', thread: WorkThread }
|
|
33
|
+
| { type: 'thread:new-root', thread: WorkThread }
|
|
33
34
|
|
|
34
35
|
export const createReconciler = (scheduler: Scheduler): Reconciler => {
|
|
35
|
-
const events = createEventEmitter<
|
|
36
|
+
const events = createEventEmitter<ReconcilerEvent>();
|
|
36
37
|
const state: ReconcilerState = {
|
|
37
38
|
thread: null,
|
|
38
39
|
work: null,
|
|
@@ -59,7 +60,7 @@ export const createReconciler = (scheduler: Scheduler): Reconciler => {
|
|
|
59
60
|
render(target);
|
|
60
61
|
|
|
61
62
|
WorkThread.apply(completedThread, tree);
|
|
62
|
-
events.
|
|
63
|
+
events.emit({ type: 'thread:complete', thread: completedThread });
|
|
63
64
|
|
|
64
65
|
// Run side effects
|
|
65
66
|
for (const effect of completedThread.pendingEffects) {
|
|
@@ -75,7 +76,7 @@ export const createReconciler = (scheduler: Scheduler): Reconciler => {
|
|
|
75
76
|
const start = () => {
|
|
76
77
|
if (!state.thread) {
|
|
77
78
|
state.thread = WorkThread.new();
|
|
78
|
-
events.
|
|
79
|
+
events.emit({ type: 'thread:start', thread: state.thread });
|
|
79
80
|
}
|
|
80
81
|
if (!state.work) {
|
|
81
82
|
state.work = scheduler.requestWork(work);
|
|
@@ -92,13 +93,13 @@ export const createReconciler = (scheduler: Scheduler): Reconciler => {
|
|
|
92
93
|
tree.roots.add(ref);
|
|
93
94
|
WorkThread.queueMount(thread, ref, element);
|
|
94
95
|
}
|
|
95
|
-
events.
|
|
96
|
+
events.emit({ type: 'thread:new-root', thread });
|
|
96
97
|
};
|
|
97
98
|
const render = (ref: CommitRef) => {
|
|
98
99
|
const thread = start();
|
|
99
100
|
|
|
100
101
|
if (WorkThread.queueTarget(thread, ref, tree)) {
|
|
101
|
-
events.
|
|
102
|
+
events.emit({ type: 'thread:new-target', thread });
|
|
102
103
|
} else {
|
|
103
104
|
state.pendingTargets.set(ref.id, ref);
|
|
104
105
|
}
|
|
@@ -107,5 +108,5 @@ export const createReconciler = (scheduler: Scheduler): Reconciler => {
|
|
|
107
108
|
const tree = CommitTree.new();
|
|
108
109
|
const elements = ElementService.create(tree, render);
|
|
109
110
|
|
|
110
|
-
return { mount, render, state, tree, elements,
|
|
111
|
+
return { mount, render, state, tree, elements, subscribe: events.subscribe };
|
|
111
112
|
}
|