signalium 0.2.2 → 0.2.3
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/dist/signals.d.ts +8 -12
- package/dist/signals.js +98 -261
- package/package.json +1 -1
- package/src/__tests__/async.test.ts +141 -11
- package/src/__tests__/subscription.test.ts +3 -3
- package/src/__tests__/utils/instrumented.ts +3 -3
- package/src/signals.ts +108 -322
@@ -1,5 +1,5 @@
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
2
|
-
import { state, asyncComputed } from './utils/instrumented.js';
|
2
|
+
import { state, asyncComputed, computed } from './utils/instrumented.js';
|
3
3
|
import { AsyncResult } from '../signals';
|
4
4
|
|
5
5
|
const sleep = (ms = 0) => new Promise(r => setTimeout(r, ms));
|
@@ -131,7 +131,7 @@ describe('Async Signal functionality', () => {
|
|
131
131
|
const result = a.get() + b.get();
|
132
132
|
|
133
133
|
if (result === 4) {
|
134
|
-
await sleep(
|
134
|
+
await sleep(10);
|
135
135
|
}
|
136
136
|
|
137
137
|
return result;
|
@@ -163,7 +163,7 @@ describe('Async Signal functionality', () => {
|
|
163
163
|
resolve: 1,
|
164
164
|
});
|
165
165
|
|
166
|
-
await sleep(
|
166
|
+
await sleep(20);
|
167
167
|
|
168
168
|
expect(c).toHaveValueAndCounts(result(5, 'success', 'resolved'), {
|
169
169
|
compute: 3,
|
@@ -179,7 +179,7 @@ describe('Async Signal functionality', () => {
|
|
179
179
|
async () => {
|
180
180
|
const result = a.get() + b.get();
|
181
181
|
|
182
|
-
await sleep(
|
182
|
+
await sleep(10);
|
183
183
|
|
184
184
|
return result;
|
185
185
|
},
|
@@ -200,7 +200,7 @@ describe('Async Signal functionality', () => {
|
|
200
200
|
resolve: 0,
|
201
201
|
});
|
202
202
|
|
203
|
-
await sleep(
|
203
|
+
await sleep(20);
|
204
204
|
|
205
205
|
expect(c).toHaveValueAndCounts(result(3, 'success', 'resolved'), {
|
206
206
|
compute: 1,
|
@@ -211,13 +211,13 @@ describe('Async Signal functionality', () => {
|
|
211
211
|
describe('Awaiting', () => {
|
212
212
|
test('Awaiting a computed will resolve the value', async () => {
|
213
213
|
const compA = asyncComputed(async () => {
|
214
|
-
await sleep(
|
214
|
+
await sleep(10);
|
215
215
|
|
216
216
|
return 1;
|
217
217
|
});
|
218
218
|
|
219
219
|
const compB = asyncComputed(async () => {
|
220
|
-
await sleep(
|
220
|
+
await sleep(10);
|
221
221
|
|
222
222
|
return 2;
|
223
223
|
});
|
@@ -243,7 +243,7 @@ describe('Async Signal functionality', () => {
|
|
243
243
|
resolve: 0,
|
244
244
|
});
|
245
245
|
|
246
|
-
await sleep(
|
246
|
+
await sleep(10);
|
247
247
|
|
248
248
|
// Check to make sure we don't resolve early after the first task completes
|
249
249
|
expect(compC).toHaveValueAndCounts(result(undefined, 'pending', 'initial'), {
|
@@ -251,7 +251,7 @@ describe('Async Signal functionality', () => {
|
|
251
251
|
resolve: 0,
|
252
252
|
});
|
253
253
|
|
254
|
-
await sleep(
|
254
|
+
await sleep(10);
|
255
255
|
|
256
256
|
expect(compC).toHaveValueAndCounts(result(3, 'success', 'resolved'), {
|
257
257
|
compute: 3,
|
@@ -261,7 +261,7 @@ describe('Async Signal functionality', () => {
|
|
261
261
|
|
262
262
|
test('Awaiting a computed can handle errors', async () => {
|
263
263
|
const compA = asyncComputed(async () => {
|
264
|
-
await sleep(
|
264
|
+
await sleep(10);
|
265
265
|
|
266
266
|
throw 'error';
|
267
267
|
});
|
@@ -285,12 +285,142 @@ describe('Async Signal functionality', () => {
|
|
285
285
|
resolve: 0,
|
286
286
|
});
|
287
287
|
|
288
|
-
await sleep(
|
288
|
+
await sleep(10);
|
289
|
+
|
290
|
+
expect(compC).toHaveValueAndCounts(result(undefined, 'error', 'initial', 'error'), {
|
291
|
+
compute: 2,
|
292
|
+
resolve: 0,
|
293
|
+
});
|
294
|
+
});
|
295
|
+
|
296
|
+
test('Awaiting a computed does not let valid values override errors', async () => {
|
297
|
+
const compA = asyncComputed(async () => {
|
298
|
+
await sleep(10);
|
299
|
+
|
300
|
+
throw 'error';
|
301
|
+
});
|
302
|
+
|
303
|
+
const compB = asyncComputed(async () => {
|
304
|
+
await sleep(20);
|
305
|
+
|
306
|
+
return 2;
|
307
|
+
});
|
308
|
+
|
309
|
+
const compC = asyncComputed(async () => {
|
310
|
+
const aResult = compA.get();
|
311
|
+
const bResult = compB.get();
|
312
|
+
|
313
|
+
const b = bResult.await();
|
314
|
+
const a = aResult.await();
|
315
|
+
|
316
|
+
return a + b;
|
317
|
+
});
|
318
|
+
|
319
|
+
// Pull once to start the computation, trigger the computation
|
320
|
+
expect(compC).toHaveValueAndCounts(result(undefined, 'pending', 'initial'), {
|
321
|
+
compute: 1,
|
322
|
+
resolve: 0,
|
323
|
+
});
|
324
|
+
|
325
|
+
await sleep(30);
|
289
326
|
|
290
327
|
expect(compC).toHaveValueAndCounts(result(undefined, 'error', 'initial', 'error'), {
|
291
328
|
compute: 2,
|
292
329
|
resolve: 0,
|
293
330
|
});
|
294
331
|
});
|
332
|
+
|
333
|
+
test('Await can be composed and nested', async () => {
|
334
|
+
const compA = asyncComputed('compA', async () => {
|
335
|
+
await sleep(20);
|
336
|
+
return 1;
|
337
|
+
});
|
338
|
+
|
339
|
+
const compB = asyncComputed('compB', async () => {
|
340
|
+
await sleep(20);
|
341
|
+
return 2;
|
342
|
+
});
|
343
|
+
|
344
|
+
const compC = computed('compC', () => {
|
345
|
+
const resultA = compA.get();
|
346
|
+
const resultB = compB.get();
|
347
|
+
|
348
|
+
return {
|
349
|
+
awaitA: resultA.await,
|
350
|
+
awaitB: resultB.await,
|
351
|
+
};
|
352
|
+
});
|
353
|
+
|
354
|
+
const compD = asyncComputed('compD', async () => {
|
355
|
+
const { awaitA, awaitB } = compC.get();
|
356
|
+
const a = awaitA();
|
357
|
+
const b = awaitB();
|
358
|
+
|
359
|
+
return a + b;
|
360
|
+
});
|
361
|
+
|
362
|
+
// Pull once to start the computation, trigger the computation
|
363
|
+
expect(compD).toHaveValueAndCounts(result(undefined, 'pending', 'initial'), {
|
364
|
+
compute: 1,
|
365
|
+
resolve: 0,
|
366
|
+
});
|
367
|
+
|
368
|
+
await sleep(30);
|
369
|
+
|
370
|
+
expect(compD).toHaveValueAndCounts(result(3, 'success', 'resolved'), {
|
371
|
+
compute: 3,
|
372
|
+
resolve: 1,
|
373
|
+
});
|
374
|
+
});
|
375
|
+
|
376
|
+
test('Await works with intermediate state', async () => {
|
377
|
+
const compA = asyncComputed('compA', async () => {
|
378
|
+
await sleep(20);
|
379
|
+
return 1;
|
380
|
+
});
|
381
|
+
|
382
|
+
const compB = asyncComputed('compB', async () => {
|
383
|
+
await sleep(40);
|
384
|
+
return 2;
|
385
|
+
});
|
386
|
+
|
387
|
+
const compC = computed('compC', () => {
|
388
|
+
const resultA = compA.get();
|
389
|
+
const resultB = compB.get();
|
390
|
+
|
391
|
+
return {
|
392
|
+
awaitA: resultA.await,
|
393
|
+
awaitB: resultB.await,
|
394
|
+
};
|
395
|
+
});
|
396
|
+
|
397
|
+
const compD = asyncComputed('compD', async () => {
|
398
|
+
const { awaitA, awaitB } = compC.get();
|
399
|
+
const a = awaitA();
|
400
|
+
const b = awaitB();
|
401
|
+
|
402
|
+
return a + b;
|
403
|
+
});
|
404
|
+
|
405
|
+
// Pull once to start the computation, trigger the computation
|
406
|
+
expect(compD).toHaveValueAndCounts(result(undefined, 'pending', 'initial'), {
|
407
|
+
compute: 1,
|
408
|
+
resolve: 0,
|
409
|
+
});
|
410
|
+
|
411
|
+
await sleep(30);
|
412
|
+
|
413
|
+
expect(compD).toHaveValueAndCounts(result(undefined, 'pending', 'initial'), {
|
414
|
+
compute: 2,
|
415
|
+
resolve: 0,
|
416
|
+
});
|
417
|
+
|
418
|
+
await sleep(30);
|
419
|
+
|
420
|
+
expect(compD).toHaveValueAndCounts(result(3, 'success', 'resolved'), {
|
421
|
+
compute: 3,
|
422
|
+
resolve: 1,
|
423
|
+
});
|
424
|
+
});
|
295
425
|
});
|
296
426
|
});
|
@@ -227,7 +227,7 @@ describe('Subscription Signal functionality', () => {
|
|
227
227
|
await nextTick();
|
228
228
|
|
229
229
|
expect(w).toHaveCounts({ effect: 2 });
|
230
|
-
expect(c).
|
230
|
+
expect(c).toHaveValueAndCounts(123, { get: 3, compute: 1 });
|
231
231
|
expect(s).toHaveValueAndCounts(123, {
|
232
232
|
subscribe: 1,
|
233
233
|
});
|
@@ -393,7 +393,7 @@ describe('Subscription Signal functionality', () => {
|
|
393
393
|
|
394
394
|
return {
|
395
395
|
update() {
|
396
|
-
set(a.get()
|
396
|
+
set(a.get());
|
397
397
|
},
|
398
398
|
};
|
399
399
|
},
|
@@ -419,7 +419,7 @@ describe('Subscription Signal functionality', () => {
|
|
419
419
|
|
420
420
|
await nextTick();
|
421
421
|
|
422
|
-
expect(s).toHaveValueAndCounts(
|
422
|
+
expect(s).toHaveValueAndCounts(1, {
|
423
423
|
subscribe: 1,
|
424
424
|
update: 1,
|
425
425
|
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { expect } from 'vitest';
|
1
|
+
import { expect, beforeEach, afterEach, vi } from 'vitest';
|
2
2
|
import {
|
3
3
|
state as createState,
|
4
4
|
computed as createComputed,
|
@@ -187,12 +187,12 @@ export function computed<T>(
|
|
187
187
|
return wrapper;
|
188
188
|
}
|
189
189
|
|
190
|
-
export function asyncComputed<T>(name: string, compute: SignalAsyncCompute<T>, opts?: SignalOptions<T>):
|
190
|
+
export function asyncComputed<T>(name: string, compute: SignalAsyncCompute<T>, opts?: SignalOptions<T>): AsyncSignal<T>;
|
191
191
|
export function asyncComputed<T>(
|
192
192
|
name: string,
|
193
193
|
compute: SignalAsyncCompute<T>,
|
194
194
|
opts: SignalOptionsWithInit<T>,
|
195
|
-
):
|
195
|
+
): AsyncSignal<T>;
|
196
196
|
export function asyncComputed<T>(compute: SignalAsyncCompute<T>, opts?: SignalOptions<T>): AsyncSignal<T>;
|
197
197
|
export function asyncComputed<T>(compute: SignalAsyncCompute<T>, opts: SignalOptionsWithInit<T>): AsyncSignal<T>;
|
198
198
|
export function asyncComputed<T>(
|