-
Notifications
You must be signed in to change notification settings - Fork 187
/
create-env-delegate.ts
127 lines (100 loc) · 2.92 KB
/
create-env-delegate.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { EnvironmentDelegate } from '@glimmer/runtime';
import { Destroyable, Destructor, RenderResult } from '@glimmer/interfaces';
import setGlobalContext from '@glimmer/global-context';
type Queue = (() => void)[];
const scheduledDestructors: Queue = [];
const scheduledFinalizers: Queue = [];
function flush(queue: Queue) {
for (const fn of queue) fn();
queue.length = 0;
}
let result: RenderResult;
let resolveRender: () => void;
export function registerResult(_result: RenderResult, _resolveRender: () => void) {
result = _result;
resolveRender = _resolveRender;
}
let revalidateScheduled = false;
setGlobalContext({
scheduleRevalidate() {
if (!revalidateScheduled) {
Promise.resolve().then(() => {
const { env } = result;
env.begin();
result.rerender();
revalidateScheduled = false;
env.commit();
// only resolve if commit didn't dirty again
if (!revalidateScheduled && resolveRender !== undefined) {
resolveRender();
}
});
}
},
getProp(obj: unknown, prop: string) {
return (obj as Record<string, unknown>)[prop];
},
setProp(obj: unknown, prop: string, value: unknown) {
(obj as Record<string, unknown>)[prop] = value;
},
getPath(obj: unknown, path: string) {
let parts = path.split('.');
let current: unknown = obj;
for (let part of parts) {
if (typeof current === 'function' || (typeof current === 'object' && current !== null)) {
current = (current as Record<string, unknown>)[part];
}
}
return current;
},
setPath(obj: unknown, path: string, value: unknown) {
let parts = path.split('.');
let current: unknown = obj;
let pathToSet = parts.pop()!;
for (let part of parts) {
current = (current as Record<string, unknown>)[part];
}
(current as Record<string, unknown>)[pathToSet] = value;
},
toBool(value) {
return Boolean(value);
},
toIterator() {
return null;
},
warnIfStyleNotTrusted() {},
scheduleDestroy<T extends Destroyable>(destroyable: T, destructor: Destructor<T>) {
scheduledDestructors.push(() => destructor(destroyable));
},
scheduleDestroyed(fn: () => void) {
scheduledFinalizers.push(fn);
},
assert(test: unknown, msg: string) {
if (!test) {
throw new Error(msg);
}
},
deprecate(msg: string, test: unknown) {
if (!test) {
// eslint-disable-next-line no-console
console.warn(msg);
}
},
createClassicTrackedDecorator() {
throw new Error('Classic tracked decorators are not supported');
},
extendTrackedPropertyDesc() {},
});
export default function createEnvDelegate(isInteractive: boolean): EnvironmentDelegate {
return {
isInteractive,
enableDebugTooling: false,
scheduleEffects(_phase, callback) {
callback();
},
onTransactionCommit() {
flush(scheduledDestructors);
flush(scheduledFinalizers);
},
};
}