signalium 0.2.8 → 0.3.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/.turbo/turbo-build.log +12 -0
- package/CHANGELOG.md +12 -0
- package/dist/cjs/config.d.ts +14 -5
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +23 -14
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/debug.d.ts +3 -0
- package/dist/cjs/debug.d.ts.map +1 -0
- package/dist/cjs/debug.js +16 -0
- package/dist/cjs/debug.js.map +1 -0
- package/dist/cjs/hooks.d.ts +45 -0
- package/dist/cjs/hooks.d.ts.map +1 -0
- package/dist/cjs/hooks.js +263 -0
- package/dist/cjs/hooks.js.map +1 -0
- package/dist/cjs/index.d.ts +5 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +21 -8
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/context.d.ts +4 -0
- package/dist/cjs/react/context.d.ts.map +1 -0
- package/dist/cjs/react/context.js +10 -0
- package/dist/cjs/react/context.js.map +1 -0
- package/dist/cjs/react/index.d.ts +5 -0
- package/dist/cjs/react/index.d.ts.map +1 -0
- package/dist/cjs/react/index.js +12 -0
- package/dist/cjs/react/index.js.map +1 -0
- package/dist/cjs/react/provider.d.ts +7 -0
- package/dist/cjs/react/provider.d.ts.map +1 -0
- package/dist/cjs/react/provider.js +13 -0
- package/dist/cjs/react/provider.js.map +1 -0
- package/dist/cjs/react/setup.d.ts +2 -0
- package/dist/cjs/react/setup.d.ts.map +1 -0
- package/dist/cjs/react/setup.js +13 -0
- package/dist/cjs/react/setup.js.map +1 -0
- package/dist/cjs/react/signal-value.d.ts +2 -0
- package/dist/cjs/react/signal-value.d.ts.map +1 -0
- package/dist/cjs/react/signal-value.js +35 -0
- package/dist/cjs/react/signal-value.js.map +1 -0
- package/dist/cjs/react/state.d.ts +3 -0
- package/dist/cjs/react/state.d.ts.map +1 -0
- package/dist/cjs/react/state.js +13 -0
- package/dist/cjs/react/state.js.map +1 -0
- package/dist/cjs/scheduling.d.ts +5 -0
- package/dist/cjs/scheduling.d.ts.map +1 -1
- package/dist/cjs/scheduling.js +59 -5
- package/dist/cjs/scheduling.js.map +1 -1
- package/dist/cjs/signals.d.ts +28 -68
- package/dist/cjs/signals.d.ts.map +1 -1
- package/dist/cjs/signals.js +223 -76
- package/dist/cjs/signals.js.map +1 -1
- package/dist/cjs/trace.d.ts +127 -0
- package/dist/cjs/trace.d.ts.map +1 -0
- package/dist/cjs/trace.js +319 -0
- package/dist/cjs/trace.js.map +1 -0
- package/dist/cjs/types.d.ts +66 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.d.ts +4 -0
- package/dist/cjs/utils.d.ts.map +1 -0
- package/dist/cjs/utils.js +80 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/config.d.ts +14 -5
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +19 -11
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/debug.d.ts +3 -0
- package/dist/esm/debug.d.ts.map +1 -0
- package/dist/esm/debug.js +3 -0
- package/dist/esm/debug.js.map +1 -0
- package/dist/esm/hooks.d.ts +45 -0
- package/dist/esm/hooks.d.ts.map +1 -0
- package/dist/esm/hooks.js +246 -0
- package/dist/esm/hooks.js.map +1 -0
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/context.d.ts +4 -0
- package/dist/esm/react/context.d.ts.map +1 -0
- package/dist/esm/react/context.js +6 -0
- package/dist/esm/react/context.js.map +1 -0
- package/dist/esm/react/index.d.ts +5 -0
- package/dist/esm/react/index.d.ts.map +1 -0
- package/dist/esm/react/index.js +5 -0
- package/dist/esm/react/index.js.map +1 -0
- package/dist/esm/react/provider.d.ts +7 -0
- package/dist/esm/react/provider.d.ts.map +1 -0
- package/dist/esm/react/provider.js +10 -0
- package/dist/esm/react/provider.js.map +1 -0
- package/dist/esm/react/setup.d.ts +2 -0
- package/dist/esm/react/setup.d.ts.map +1 -0
- package/dist/esm/react/setup.js +10 -0
- package/dist/esm/react/setup.js.map +1 -0
- package/dist/esm/react/signal-value.d.ts +2 -0
- package/dist/esm/react/signal-value.d.ts.map +1 -0
- package/dist/esm/react/signal-value.js +32 -0
- package/dist/esm/react/signal-value.js.map +1 -0
- package/dist/esm/react/state.d.ts +3 -0
- package/dist/esm/react/state.d.ts.map +1 -0
- package/dist/esm/react/state.js +10 -0
- package/dist/esm/react/state.js.map +1 -0
- package/dist/esm/scheduling.d.ts +5 -0
- package/dist/esm/scheduling.d.ts.map +1 -1
- package/dist/esm/scheduling.js +51 -1
- package/dist/esm/scheduling.js.map +1 -1
- package/dist/esm/signals.d.ts +28 -68
- package/dist/esm/signals.d.ts.map +1 -1
- package/dist/esm/signals.js +215 -72
- package/dist/esm/signals.js.map +1 -1
- package/dist/esm/trace.d.ts +127 -0
- package/dist/esm/trace.d.ts.map +1 -0
- package/dist/esm/trace.js +311 -0
- package/dist/esm/trace.js.map +1 -0
- package/dist/esm/types.d.ts +66 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +4 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +75 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +43 -2
- package/src/__tests__/hooks/async-computed.test.ts +190 -0
- package/src/__tests__/hooks/async-task.test.ts +227 -0
- package/src/__tests__/hooks/computed.test.ts +126 -0
- package/src/__tests__/hooks/context.test.ts +527 -0
- package/src/__tests__/hooks/nesting.test.ts +303 -0
- package/src/__tests__/hooks/params-and-state.test.ts +168 -0
- package/src/__tests__/hooks/subscription.test.ts +97 -0
- package/src/__tests__/signals/async.test.ts +416 -0
- package/src/__tests__/signals/basic.test.ts +399 -0
- package/src/__tests__/signals/subscription.test.ts +632 -0
- package/src/__tests__/signals/watcher.test.ts +253 -0
- package/src/__tests__/utils/async.ts +6 -0
- package/src/__tests__/utils/builders.ts +22 -0
- package/src/__tests__/utils/instrumented-hooks.ts +309 -0
- package/src/__tests__/utils/instrumented-signals.ts +281 -0
- package/src/__tests__/utils/permute.ts +74 -0
- package/src/config.ts +32 -17
- package/src/debug.ts +14 -0
- package/src/hooks.ts +433 -0
- package/src/index.ts +28 -3
- package/src/react/__tests__/react.test.tsx +227 -0
- package/src/react/context.ts +8 -0
- package/src/react/index.ts +4 -0
- package/src/react/provider.tsx +18 -0
- package/src/react/setup.ts +10 -0
- package/src/react/signal-value.ts +49 -0
- package/src/react/state.ts +13 -0
- package/src/scheduling.ts +69 -1
- package/src/signals.ts +328 -169
- package/src/trace.ts +449 -0
- package/src/types.ts +86 -0
- package/src/utils.ts +83 -0
- package/tsconfig.json +2 -1
- package/vitest.workspace.ts +24 -0
- package/src/__tests__/async.test.ts +0 -426
- package/src/__tests__/basic.test.ts +0 -378
- package/src/__tests__/subscription.test.ts +0 -645
- package/src/__tests__/utils/instrumented.ts +0 -326
@@ -0,0 +1,281 @@
|
|
1
|
+
import { expect, beforeEach, afterEach, vi } from 'vitest';
|
2
|
+
import {
|
3
|
+
createStateSignal as _createStateSignal,
|
4
|
+
createComputedSignal as _createComputedSignal,
|
5
|
+
createAsyncComputedSignal as _createAsyncComputedSignal,
|
6
|
+
createSubscriptionSignal as _createSubscriptionSignal,
|
7
|
+
createWatcherSignal as _createWatcherSignal,
|
8
|
+
SignalOptions,
|
9
|
+
Signal,
|
10
|
+
WriteableSignal,
|
11
|
+
SignalSubscription,
|
12
|
+
Watcher,
|
13
|
+
} from '../../index.js';
|
14
|
+
|
15
|
+
class SignalCounts {
|
16
|
+
name: string;
|
17
|
+
|
18
|
+
get = 0;
|
19
|
+
set = 0;
|
20
|
+
compute = 0;
|
21
|
+
|
22
|
+
resolve = 0;
|
23
|
+
|
24
|
+
subscribe = 0;
|
25
|
+
update = 0;
|
26
|
+
unsubscribe = 0;
|
27
|
+
internalGet = 0;
|
28
|
+
internalSet = 0;
|
29
|
+
|
30
|
+
effect = 0;
|
31
|
+
|
32
|
+
constructor(name: string) {
|
33
|
+
this.name = name;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
const countsKeys = Object.keys(new SignalCounts('')).filter(k => k !== 'name') as (keyof SignalCounts)[];
|
38
|
+
|
39
|
+
let currentOrder: string[] | undefined = [];
|
40
|
+
const COUNTS = new WeakMap<Signal<any> | Watcher<any>, SignalCounts>();
|
41
|
+
|
42
|
+
interface CustomMatchers<R = unknown> {
|
43
|
+
toHaveSignalValue: (v: any) => R;
|
44
|
+
toHaveSignalCounts: (counts: Partial<SignalCounts>) => R;
|
45
|
+
toHaveSignalValueAndCounts: (v: any, counts: Partial<SignalCounts>) => R;
|
46
|
+
toHaveComputedOrder: (order: string[]) => R;
|
47
|
+
}
|
48
|
+
|
49
|
+
declare module 'vitest' {
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
51
|
+
interface Assertion<T = any> extends CustomMatchers<T> {}
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
53
|
+
interface AsymmetricMatchersContaining extends CustomMatchers {}
|
54
|
+
}
|
55
|
+
|
56
|
+
function toHaveSignalValue(this: { equals(a: unknown, b: unknown): boolean }, signal: Signal<any>, value: any) {
|
57
|
+
const signalValue = signal.get();
|
58
|
+
|
59
|
+
return {
|
60
|
+
pass: this.equals(signalValue, value),
|
61
|
+
message: () => `Expected signal value to be ${JSON.stringify(value)}, but got ${JSON.stringify(signalValue)}`,
|
62
|
+
};
|
63
|
+
}
|
64
|
+
|
65
|
+
function toHaveSignalCounts(signal: Signal<any>, counts: SignalCounts) {
|
66
|
+
const signalCounts = COUNTS.get(signal);
|
67
|
+
|
68
|
+
if (!signalCounts) {
|
69
|
+
return {
|
70
|
+
pass: false,
|
71
|
+
message: () => 'Signal not found in counts map',
|
72
|
+
};
|
73
|
+
}
|
74
|
+
|
75
|
+
for (const key of countsKeys) {
|
76
|
+
const count = counts[key];
|
77
|
+
|
78
|
+
if (count !== undefined && signalCounts[key] !== count) {
|
79
|
+
return {
|
80
|
+
pass: false,
|
81
|
+
message: () => `Expected ${key} count to be ${count} but got ${signalCounts[key]}`,
|
82
|
+
};
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
return {
|
87
|
+
pass: true,
|
88
|
+
message: () => 'Counts match',
|
89
|
+
};
|
90
|
+
}
|
91
|
+
|
92
|
+
expect.extend({
|
93
|
+
toHaveSignalValue,
|
94
|
+
toHaveSignalCounts,
|
95
|
+
|
96
|
+
toHaveSignalValueAndCounts(signal, value, counts) {
|
97
|
+
const valueResult = toHaveSignalValue.call(this, signal, value);
|
98
|
+
const countsResult = toHaveSignalCounts.call(this, signal, counts);
|
99
|
+
|
100
|
+
return {
|
101
|
+
pass: valueResult.pass && countsResult.pass,
|
102
|
+
message: () => {
|
103
|
+
const messages = [
|
104
|
+
!valueResult.pass && valueResult.message(),
|
105
|
+
!countsResult.pass && countsResult.message(),
|
106
|
+
].filter(m => m);
|
107
|
+
|
108
|
+
return messages.join('\n');
|
109
|
+
},
|
110
|
+
};
|
111
|
+
},
|
112
|
+
|
113
|
+
toHaveComputedOrder(fn: () => void, expectedOrder: string[]) {
|
114
|
+
const order = (currentOrder = []);
|
115
|
+
|
116
|
+
fn();
|
117
|
+
|
118
|
+
currentOrder = undefined;
|
119
|
+
|
120
|
+
return {
|
121
|
+
pass: this.equals(order, expectedOrder),
|
122
|
+
message: () => `Expected compute count to be ${expectedOrder.toString()} but got ${order.toString()}`,
|
123
|
+
};
|
124
|
+
},
|
125
|
+
});
|
126
|
+
|
127
|
+
export const createStateSignal = <T>(initialValue: T, opts?: SignalOptions<T>): WriteableSignal<T> => {
|
128
|
+
const desc = opts?.desc || 'unlabeled';
|
129
|
+
const s = _createStateSignal(initialValue, opts);
|
130
|
+
|
131
|
+
const counts = new SignalCounts(desc);
|
132
|
+
|
133
|
+
const wrapper = {
|
134
|
+
get() {
|
135
|
+
counts.get++;
|
136
|
+
return s.get();
|
137
|
+
},
|
138
|
+
|
139
|
+
set(value: T) {
|
140
|
+
counts.set++;
|
141
|
+
s.set(value);
|
142
|
+
},
|
143
|
+
};
|
144
|
+
|
145
|
+
COUNTS.set(wrapper, counts);
|
146
|
+
|
147
|
+
return wrapper;
|
148
|
+
};
|
149
|
+
|
150
|
+
export const createComputedSignal: typeof _createComputedSignal = (compute, opts) => {
|
151
|
+
const desc = opts?.desc || 'unlabeled';
|
152
|
+
const counts = new SignalCounts(desc);
|
153
|
+
|
154
|
+
const s = _createComputedSignal(v => {
|
155
|
+
counts.compute++;
|
156
|
+
|
157
|
+
if (desc) {
|
158
|
+
currentOrder?.push(desc);
|
159
|
+
}
|
160
|
+
|
161
|
+
return compute(v);
|
162
|
+
}, opts);
|
163
|
+
|
164
|
+
const wrapper = {
|
165
|
+
get() {
|
166
|
+
counts.get++;
|
167
|
+
|
168
|
+
// Get twice to ensure idempotency
|
169
|
+
s.get();
|
170
|
+
|
171
|
+
return s.get();
|
172
|
+
},
|
173
|
+
};
|
174
|
+
|
175
|
+
COUNTS.set(wrapper, counts);
|
176
|
+
|
177
|
+
return wrapper;
|
178
|
+
};
|
179
|
+
|
180
|
+
export const createAsyncComputedSignal: typeof _createAsyncComputedSignal = (compute, opts) => {
|
181
|
+
const desc = opts?.desc || 'unlabeled';
|
182
|
+
const counts = new SignalCounts(desc);
|
183
|
+
|
184
|
+
const s = _createAsyncComputedSignal(async v => {
|
185
|
+
counts.compute++;
|
186
|
+
|
187
|
+
if (desc) {
|
188
|
+
currentOrder?.push(desc);
|
189
|
+
}
|
190
|
+
|
191
|
+
const result = await compute(v);
|
192
|
+
|
193
|
+
counts.resolve++;
|
194
|
+
|
195
|
+
return result;
|
196
|
+
}, opts);
|
197
|
+
|
198
|
+
const wrapper = {
|
199
|
+
get() {
|
200
|
+
counts.get++;
|
201
|
+
return s.get();
|
202
|
+
},
|
203
|
+
};
|
204
|
+
|
205
|
+
COUNTS.set(wrapper, counts);
|
206
|
+
|
207
|
+
return wrapper;
|
208
|
+
};
|
209
|
+
|
210
|
+
export const createSubscriptionSignal: typeof _createSubscriptionSignal = (subscribe, opts) => {
|
211
|
+
const desc = opts?.desc || 'unlabeled';
|
212
|
+
const counts = new SignalCounts(desc);
|
213
|
+
|
214
|
+
const s = _createSubscriptionSignal((get, set) => {
|
215
|
+
counts.subscribe++;
|
216
|
+
|
217
|
+
if (desc) {
|
218
|
+
currentOrder?.push(desc);
|
219
|
+
}
|
220
|
+
|
221
|
+
const result = subscribe(
|
222
|
+
() => {
|
223
|
+
counts.internalGet++;
|
224
|
+
return get();
|
225
|
+
},
|
226
|
+
v => {
|
227
|
+
counts.internalSet++;
|
228
|
+
set(v);
|
229
|
+
},
|
230
|
+
);
|
231
|
+
|
232
|
+
const subscriptionWrapper: SignalSubscription = {
|
233
|
+
unsubscribe() {
|
234
|
+
counts.unsubscribe++;
|
235
|
+
result?.unsubscribe?.();
|
236
|
+
},
|
237
|
+
|
238
|
+
update() {
|
239
|
+
counts.update++;
|
240
|
+
result?.update?.();
|
241
|
+
},
|
242
|
+
};
|
243
|
+
|
244
|
+
return subscriptionWrapper;
|
245
|
+
}, opts);
|
246
|
+
|
247
|
+
const wrapper = {
|
248
|
+
get() {
|
249
|
+
counts.get++;
|
250
|
+
return s.get();
|
251
|
+
},
|
252
|
+
};
|
253
|
+
|
254
|
+
COUNTS.set(wrapper, counts);
|
255
|
+
|
256
|
+
return wrapper;
|
257
|
+
};
|
258
|
+
|
259
|
+
export function createWatcherSignal<T>(fn: () => T, opts?: SignalOptions<T>): Watcher<T> {
|
260
|
+
const desc = opts?.desc || 'unlabeled';
|
261
|
+
const counts = new SignalCounts(desc);
|
262
|
+
|
263
|
+
const w = _createWatcherSignal<T>(() => {
|
264
|
+
counts.compute++;
|
265
|
+
return fn();
|
266
|
+
}, opts);
|
267
|
+
|
268
|
+
const wrapper: Watcher<T> = {
|
269
|
+
addListener: (fn, opts) => {
|
270
|
+
counts.subscribe++;
|
271
|
+
return w.addListener(v => {
|
272
|
+
counts.effect++;
|
273
|
+
return fn(v);
|
274
|
+
}, opts);
|
275
|
+
},
|
276
|
+
};
|
277
|
+
|
278
|
+
COUNTS.set(wrapper, counts);
|
279
|
+
|
280
|
+
return wrapper;
|
281
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { describe } from 'vitest';
|
2
|
+
import { asyncComputed, computed, subscription, wrapHook } from './instrumented-hooks.js';
|
3
|
+
import { SignalOptionsWithInit } from '../../types.js';
|
4
|
+
|
5
|
+
const createMethods = [
|
6
|
+
{
|
7
|
+
name: 'createComputed',
|
8
|
+
create: computed,
|
9
|
+
},
|
10
|
+
{
|
11
|
+
name: 'createAsyncComputed',
|
12
|
+
create: <T, Args extends unknown[]>(
|
13
|
+
fn: (...args: Args) => T | Promise<T>,
|
14
|
+
opts?: Partial<SignalOptionsWithInit<T, Args>>,
|
15
|
+
) => {
|
16
|
+
const computed = asyncComputed(fn, opts);
|
17
|
+
|
18
|
+
return wrapHook(computed, (...args: Args) => {
|
19
|
+
return computed(...args).result;
|
20
|
+
});
|
21
|
+
},
|
22
|
+
},
|
23
|
+
{
|
24
|
+
name: 'createSubscription',
|
25
|
+
create: function _createSubscription<T, Args extends unknown[]>(
|
26
|
+
fn: (...args: Args) => T,
|
27
|
+
opts?: Partial<SignalOptionsWithInit<T, Args>>,
|
28
|
+
): (...args: Args) => T {
|
29
|
+
return subscription(({ set }, ...args) => {
|
30
|
+
set(fn(...args));
|
31
|
+
|
32
|
+
return {
|
33
|
+
update: () => {
|
34
|
+
set(fn(...args));
|
35
|
+
},
|
36
|
+
};
|
37
|
+
}, opts);
|
38
|
+
},
|
39
|
+
},
|
40
|
+
];
|
41
|
+
|
42
|
+
function generatePermutations(n: number, m: number): number[][] {
|
43
|
+
const results: number[][] = [];
|
44
|
+
|
45
|
+
function generate(current: number[], remaining: number) {
|
46
|
+
if (remaining === 0) {
|
47
|
+
results.push([...current]);
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
|
51
|
+
for (let i = 0; i < n; i++) {
|
52
|
+
current.push(i);
|
53
|
+
generate(current, remaining - 1);
|
54
|
+
current.pop();
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
generate([], m);
|
59
|
+
return results;
|
60
|
+
}
|
61
|
+
|
62
|
+
type CreateMethod = (typeof createMethods)[number]['create'];
|
63
|
+
|
64
|
+
export function permute(m: number, fn: (...args: CreateMethod[]) => void) {
|
65
|
+
const testCases = generatePermutations(createMethods.length, m);
|
66
|
+
|
67
|
+
for (const testCase of testCases) {
|
68
|
+
const testMethods = [createMethods[testCase[0]], ...testCase.slice(1).map(i => createMethods[i])];
|
69
|
+
|
70
|
+
describe(`${testMethods.map(m => m.name).join(', ')}`, () => {
|
71
|
+
fn(...testMethods.map(m => m.create));
|
72
|
+
});
|
73
|
+
}
|
74
|
+
}
|
package/src/config.ts
CHANGED
@@ -1,27 +1,42 @@
|
|
1
|
-
|
1
|
+
import { SignalScope } from './hooks.js';
|
2
|
+
import { getCurrentConsumer } from './signals.js';
|
2
3
|
|
3
|
-
export type FlushCallback = () =>
|
4
|
+
export type FlushCallback = () => void;
|
4
5
|
|
5
|
-
export type FlushFn = (fn:
|
6
|
-
|
7
|
-
export let scheduleFlush: FlushFn = flushWatchers => {
|
8
|
-
if (currentFlush !== null) return;
|
6
|
+
export type FlushFn = (fn: FlushCallback) => void;
|
7
|
+
export type BatchFn = (fn: () => void) => void;
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
interface SignalHooksConfig {
|
10
|
+
scheduleFlush: FlushFn;
|
11
|
+
runBatch: BatchFn;
|
12
|
+
getFrameworkScope: () => SignalScope | undefined;
|
13
|
+
useSignalValue: <T>(key: string, fn: () => T) => T;
|
14
|
+
}
|
12
15
|
|
16
|
+
export let scheduleFlush: FlushFn = flushWatchers => {
|
17
|
+
setTimeout(() => {
|
13
18
|
flushWatchers();
|
14
19
|
}, 0);
|
15
20
|
};
|
16
21
|
|
17
|
-
export const setScheduleFlush = (flushFn: FlushFn) => {
|
18
|
-
scheduleFlush = flushFn;
|
19
|
-
};
|
20
|
-
|
21
|
-
export type BatchFn = (fn: () => void) => void;
|
22
|
-
|
23
22
|
export let runBatch: BatchFn = fn => fn();
|
24
23
|
|
25
|
-
export
|
26
|
-
|
27
|
-
|
24
|
+
export let getFrameworkScope: () => SignalScope | undefined = () => undefined;
|
25
|
+
|
26
|
+
let useFrameworkSignalValue: <T>(key: string, fn: () => T) => T = (key, fn) => fn();
|
27
|
+
|
28
|
+
export function useSignalValue<T>(key: string, fn: () => T): T {
|
29
|
+
if (getCurrentConsumer()) {
|
30
|
+
return fn();
|
31
|
+
} else {
|
32
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
33
|
+
return useFrameworkSignalValue(key, fn);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
export function setConfig(cfg: Partial<SignalHooksConfig>) {
|
38
|
+
scheduleFlush = cfg.scheduleFlush ?? scheduleFlush;
|
39
|
+
runBatch = cfg.runBatch ?? runBatch;
|
40
|
+
getFrameworkScope = cfg.getFrameworkScope ?? getFrameworkScope;
|
41
|
+
useFrameworkSignalValue = cfg.useSignalValue ?? useFrameworkSignalValue;
|
42
|
+
}
|
package/src/debug.ts
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
export {
|
2
|
+
setTracing,
|
3
|
+
createTracer,
|
4
|
+
createTracerFromId,
|
5
|
+
removeTracer,
|
6
|
+
VisualizerNode,
|
7
|
+
type VisualizerLink,
|
8
|
+
VisualizerNodeType,
|
9
|
+
TracerEventType,
|
10
|
+
Tracer,
|
11
|
+
TRACER,
|
12
|
+
} from './trace.js';
|
13
|
+
|
14
|
+
export { scheduleTracer } from './scheduling.js';
|