@zukhruf/async 0.3.14 → 0.3.15
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/README.md +19 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/latch.d.ts +15 -0
- package/dist/latch.d.ts.map +1 -0
- package/dist/latch.js +21 -0
- package/dist/latch.js.map +1 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zukhruf/async
|
|
2
2
|
|
|
3
|
-
Helpers for code that waits for promises
|
|
3
|
+
Helpers for code that waits for promises: `untilAborted` cancels a wait, and `Latch` holds callers until something happened. `@zukhruf/mutex` and `@zukhruf/single-flight` use them.
|
|
4
4
|
|
|
5
5
|
The words in these documents have one meaning each. See the glossary in [CONTEXT.md](./CONTEXT.md).
|
|
6
6
|
|
|
@@ -35,3 +35,21 @@ An `AbortSignal` is an `EventTarget`. A listener of the `abort` event can call `
|
|
|
35
35
|
## No listener stays on the signal
|
|
36
36
|
|
|
37
37
|
When the promise settles, `untilAborted` removes its listener. Thus many waits on one signal that lives long, for example a signal that stops a server, do not add listeners to it.
|
|
38
|
+
|
|
39
|
+
## Wait until something happened, with a latch
|
|
40
|
+
|
|
41
|
+
A latch starts closed. It opens once, with a value. A wait on a closed latch ends when the latch opens, and gets the value. A wait on an open latch ends at once, with the same value. A latch never closes again, and a second `open` changes nothing.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { Latch } from '@zukhruf/async';
|
|
45
|
+
|
|
46
|
+
const released = new Latch(); // Carries no value.
|
|
47
|
+
const done = new Latch<string>(); // Carries a string.
|
|
48
|
+
|
|
49
|
+
done.open('report');
|
|
50
|
+
const value = await done.wait(); // 'report'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A latch never rejects. It keeps its value in a box, so it never adopts a promise, whatever its type. Thus a class can keep a latch in a field: the latch cannot fail before somebody awaits it. A latch whose type names a promise refuses one at compile time, because a wait would adopt the promise and could then reject. To share the outcome of work that can fail, give the latch a value that tells how the work ended, for example the `PromiseSettledResult` of `Promise.allSettled`. Each caller then throws the error for itself. See [ADR 0002](./docs/adr/0002-a-latch-carries-a-value-never-a-failure.md).
|
|
54
|
+
|
|
55
|
+
To stop a wait on a latch, cancel it: `untilAborted(latch.wait(), signal)`.
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/latch.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A gate that starts closed and opens once, with a value. It never closes
|
|
3
|
+
* again and never rejects, so a wait that starts after it opened ends at once
|
|
4
|
+
* with the same value.
|
|
5
|
+
*/
|
|
6
|
+
export declare class Latch<T = void> {
|
|
7
|
+
#private;
|
|
8
|
+
/**
|
|
9
|
+
* A later open changes nothing. A type that names a promise is refused: a
|
|
10
|
+
* wait would adopt the promise, and could then reject.
|
|
11
|
+
*/
|
|
12
|
+
open(value: T extends PromiseLike<unknown> ? never : T): void;
|
|
13
|
+
wait(): Promise<T>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=latch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latch.d.ts","sourceRoot":"","sources":["../src/latch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,KAAK,CAAC,CAAC,GAAG,IAAI;;IAKzB;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,WAAW,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI;IAI7D,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC;CAGnB"}
|
package/dist/latch.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A gate that starts closed and opens once, with a value. It never closes
|
|
3
|
+
* again and never rejects, so a wait that starts after it opened ends at once
|
|
4
|
+
* with the same value.
|
|
5
|
+
*/
|
|
6
|
+
export class Latch {
|
|
7
|
+
/** Holds the value in a box, so it never adopts a promise and never rejects, whatever `T` is. */
|
|
8
|
+
// eslint-disable-next-line zukhruf/no-promise-field -- A latch never rejects and is never replaced, so no hazard of the rule applies; it is the primitive the rule recommends.
|
|
9
|
+
#opened = Promise.withResolvers();
|
|
10
|
+
/**
|
|
11
|
+
* A later open changes nothing. A type that names a promise is refused: a
|
|
12
|
+
* wait would adopt the promise, and could then reject.
|
|
13
|
+
*/
|
|
14
|
+
open(value) {
|
|
15
|
+
this.#opened.resolve({ value });
|
|
16
|
+
}
|
|
17
|
+
wait() {
|
|
18
|
+
return this.#opened.promise.then(({ value }) => value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=latch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latch.js","sourceRoot":"","sources":["../src/latch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,KAAK;IAChB,iGAAiG;IACjG,+KAA+K;IACtK,OAAO,GAAG,OAAO,CAAC,aAAa,EAAgB,CAAC;IAEzD;;;OAGG;IACH,IAAI,CAAC,KAAiD;QACpD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zukhruf/async",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.15",
|
|
4
|
+
"description": "Helpers for code that waits for promises: cancel a wait when an AbortSignal aborts, and hold callers on a one-shot latch that never rejects.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"abortsignal",
|
|
18
18
|
"abortable",
|
|
19
19
|
"promise",
|
|
20
|
-
"async"
|
|
20
|
+
"async",
|
|
21
|
+
"latch"
|
|
21
22
|
],
|
|
22
23
|
"type": "module",
|
|
23
24
|
"types": "./dist/index.d.ts",
|