@lukekaalim/act-recon 2.0.0 → 3.0.0-alpha.1
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 +12 -0
- package/event.ts +16 -20
- package/package.json +1 -1
- package/reconciler.ts +13 -12
- package/thread.ts +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @lukekaalim/act-recon
|
|
2
2
|
|
|
3
|
+
## 3.0.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fdf1557: Fixed issue with multiple changes (where changes after first were children of first) being ignored due to "MustVisit" being misinput each time
|
|
8
|
+
|
|
9
|
+
## 3.0.0-alpha.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- b3f6c49: Added debug capabilities and protocol
|
|
14
|
+
|
|
3
15
|
## 2.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
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
|
}
|
package/thread.ts
CHANGED
|
@@ -185,8 +185,9 @@ const queueWorkThreadTarget = (thread: WorkThread, ref: CommitRef, tree: CommitT
|
|
|
185
185
|
// lead to this commit. If so, make sure ancestor commit
|
|
186
186
|
// is on the MustVisit so they should make their way down
|
|
187
187
|
// eventually
|
|
188
|
-
for (
|
|
189
|
-
|
|
188
|
+
for (let i = ref.path.length - 1; i >= 0; i--) {
|
|
189
|
+
const id = ref.path[i];
|
|
190
|
+
thread.mustVisit.add(id);
|
|
190
191
|
|
|
191
192
|
for (const update of thread.pendingUpdates) {
|
|
192
193
|
// Found an ancestor pending update - it should
|
|
@@ -221,7 +222,7 @@ export type WorkThread = {
|
|
|
221
222
|
reasons: WorkReason[],
|
|
222
223
|
|
|
223
224
|
mustRender: Map<CommitID, CommitRef>,
|
|
224
|
-
mustVisit:
|
|
225
|
+
mustVisit: Set<CommitID>,
|
|
225
226
|
|
|
226
227
|
pendingUpdates: Update[],
|
|
227
228
|
pendingEffects: EffectTask[],
|
|
@@ -242,7 +243,7 @@ export const cloneWorkThread = (thread: WorkThread): WorkThread => {
|
|
|
242
243
|
pendingUpdates: [...thread.pendingUpdates],
|
|
243
244
|
errorNotifications: new Map(thread.errorNotifications),
|
|
244
245
|
|
|
245
|
-
mustVisit: new
|
|
246
|
+
mustVisit: new Set(thread.mustVisit),
|
|
246
247
|
mustRender: new Map(thread.mustRender),
|
|
247
248
|
|
|
248
249
|
visited: new Map(thread.visited),
|
|
@@ -259,7 +260,7 @@ export const WorkThread = {
|
|
|
259
260
|
pendingUpdates: [],
|
|
260
261
|
errorNotifications: new Map(),
|
|
261
262
|
|
|
262
|
-
mustVisit: new
|
|
263
|
+
mustVisit: new Set(),
|
|
263
264
|
mustRender: new Map(),
|
|
264
265
|
|
|
265
266
|
visited: new Map(),
|