@bandeira-tech/b3nd-save 0.8.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/LICENSE +21 -0
- package/esm/_dnt.shims.d.ts +2 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +57 -0
- package/esm/byte-entity-shim.d.ts +47 -0
- package/esm/byte-entity-shim.d.ts.map +1 -0
- package/esm/byte-entity-shim.js +138 -0
- package/esm/clients/mod.d.ts +15 -0
- package/esm/clients/mod.d.ts.map +1 -0
- package/esm/clients/mod.js +14 -0
- package/esm/clients/save-client.d.ts +87 -0
- package/esm/clients/save-client.d.ts.map +1 -0
- package/esm/clients/save-client.js +174 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/mod.d.ts +40 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/mod.js +31 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/client-console/client.d.ts +30 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/client-console/client.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/client-console/client.js +70 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encoding/encoding.d.ts +16 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encoding/encoding.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encoding/encoding.js +50 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encrypt/mod.d.ts +235 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encrypt/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/encrypt/mod.js +619 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/functional-client/functional-client.d.ts +43 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/functional-client/functional-client.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/functional-client/functional-client.js +54 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/match-pattern/match-pattern.d.ts +47 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/match-pattern/match-pattern.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/match-pattern/match-pattern.js +134 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/decorators.d.ts +20 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/decorators.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/decorators.js +34 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/network.d.ts +46 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/network.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/network.js +131 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/peer.d.ts +27 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/peer.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/peer.js +25 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/flood.d.ts +59 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/flood.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/flood.js +188 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/path-vector.d.ts +35 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/path-vector.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/path-vector.js +57 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/tell-and-read.d.ts +117 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/tell-and-read.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/policies/tell-and-read.js +125 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/types.d.ts +112 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/network/types.js +21 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.d.ts +35 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.js +106 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.d.ts +88 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.js +86 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.d.ts +83 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.js +115 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/hooks.d.ts +164 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/hooks.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/hooks.js +67 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/identity.d.ts +99 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/identity.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/identity.js +190 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/operation-handle.d.ts +185 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/operation-handle.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/operation-handle.js +103 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/reactions.d.ts +58 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/reactions.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/reactions.js +64 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/rig.d.ts +295 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/rig.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/rig.js +898 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/types.d.ts +167 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/types.js +5 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.d.ts +278 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/types/types.js +89 -0
- package/esm/dispatch.d.ts +35 -0
- package/esm/dispatch.d.ts.map +1 -0
- package/esm/dispatch.js +40 -0
- package/esm/elasticsearch/mod.d.ts +31 -0
- package/esm/elasticsearch/mod.d.ts.map +1 -0
- package/esm/elasticsearch/mod.js +8 -0
- package/esm/elasticsearch/store.d.ts +44 -0
- package/esm/elasticsearch/store.d.ts.map +1 -0
- package/esm/elasticsearch/store.js +213 -0
- package/esm/entity-store.d.ts +106 -0
- package/esm/entity-store.d.ts.map +1 -0
- package/esm/entity-store.js +46 -0
- package/esm/entity.d.ts +125 -0
- package/esm/entity.d.ts.map +1 -0
- package/esm/entity.js +66 -0
- package/esm/errors.d.ts +23 -0
- package/esm/errors.d.ts.map +1 -0
- package/esm/errors.js +25 -0
- package/esm/fs/mod.d.ts +28 -0
- package/esm/fs/mod.d.ts.map +1 -0
- package/esm/fs/mod.js +13 -0
- package/esm/fs/store.d.ts +45 -0
- package/esm/fs/store.d.ts.map +1 -0
- package/esm/fs/store.js +194 -0
- package/esm/indexeddb/mod.d.ts +9 -0
- package/esm/indexeddb/mod.d.ts.map +1 -0
- package/esm/indexeddb/mod.js +8 -0
- package/esm/indexeddb/store.d.ts +47 -0
- package/esm/indexeddb/store.d.ts.map +1 -0
- package/esm/indexeddb/store.js +299 -0
- package/esm/ipfs/mod.d.ts +24 -0
- package/esm/ipfs/mod.d.ts.map +1 -0
- package/esm/ipfs/mod.js +13 -0
- package/esm/ipfs/store.d.ts +42 -0
- package/esm/ipfs/store.d.ts.map +1 -0
- package/esm/ipfs/store.js +197 -0
- package/esm/localstorage/mod.d.ts +9 -0
- package/esm/localstorage/mod.d.ts.map +1 -0
- package/esm/localstorage/mod.js +8 -0
- package/esm/localstorage/store.d.ts +45 -0
- package/esm/localstorage/store.d.ts.map +1 -0
- package/esm/localstorage/store.js +147 -0
- package/esm/memory/mod.d.ts +12 -0
- package/esm/memory/mod.d.ts.map +1 -0
- package/esm/memory/mod.js +11 -0
- package/esm/memory/store.d.ts +73 -0
- package/esm/memory/store.d.ts.map +1 -0
- package/esm/memory/store.js +300 -0
- package/esm/mod.d.ts +36 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +31 -0
- package/esm/mongo/mod.d.ts +35 -0
- package/esm/mongo/mod.d.ts.map +1 -0
- package/esm/mongo/mod.js +8 -0
- package/esm/mongo/store.d.ts +42 -0
- package/esm/mongo/store.d.ts.map +1 -0
- package/esm/mongo/store.js +185 -0
- package/esm/package.json +3 -0
- package/esm/payload.d.ts +24 -0
- package/esm/payload.d.ts.map +1 -0
- package/esm/payload.js +30 -0
- package/esm/postgres/columns.d.ts +33 -0
- package/esm/postgres/columns.d.ts.map +1 -0
- package/esm/postgres/columns.js +51 -0
- package/esm/postgres/mod.d.ts +19 -0
- package/esm/postgres/mod.d.ts.map +1 -0
- package/esm/postgres/mod.js +9 -0
- package/esm/postgres/store.d.ts +75 -0
- package/esm/postgres/store.d.ts.map +1 -0
- package/esm/postgres/store.js +364 -0
- package/esm/read.d.ts +40 -0
- package/esm/read.d.ts.map +1 -0
- package/esm/read.js +67 -0
- package/esm/s3/mod.d.ts +23 -0
- package/esm/s3/mod.d.ts.map +1 -0
- package/esm/s3/mod.js +13 -0
- package/esm/s3/store.d.ts +46 -0
- package/esm/s3/store.d.ts.map +1 -0
- package/esm/s3/store.js +183 -0
- package/esm/sqlite/mod.d.ts +18 -0
- package/esm/sqlite/mod.d.ts.map +1 -0
- package/esm/sqlite/mod.js +8 -0
- package/esm/sqlite/schema.d.ts +10 -0
- package/esm/sqlite/schema.d.ts.map +1 -0
- package/esm/sqlite/schema.js +26 -0
- package/esm/sqlite/store.d.ts +42 -0
- package/esm/sqlite/store.d.ts.map +1 -0
- package/esm/sqlite/store.js +184 -0
- package/esm/types.d.ts +101 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/types.js +21 -0
- package/esm/url.d.ts +108 -0
- package/esm/url.d.ts.map +1 -0
- package/esm/url.js +151 -0
- package/package.json +93 -0
package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type ObserveListener = (uri: string, data: unknown) => void;
|
|
2
|
+
/**
|
|
3
|
+
* Base class providing a write/delete listener bus and an async iterator
|
|
4
|
+
* for observing URI-pattern changes.
|
|
5
|
+
*
|
|
6
|
+
* Subclasses call `_emit(uri, data)` on successful writes and
|
|
7
|
+
* `_emitDeletes(uris)` on successful deletes. The emitter ignores
|
|
8
|
+
* `data` for INV-style notifications — observers receive only the
|
|
9
|
+
* uri and read it themselves.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ObserveEmitter {
|
|
12
|
+
protected _listeners: Set<ObserveListener>;
|
|
13
|
+
/**
|
|
14
|
+
* Notify all listeners of a URI change. `data` is accepted for
|
|
15
|
+
* compatibility with subclasses that may reuse the listener bus,
|
|
16
|
+
* but it is not surfaced to observe iterators.
|
|
17
|
+
*/
|
|
18
|
+
protected _emit(uri: string, data: unknown): void;
|
|
19
|
+
/** Notify all listeners that each URI was deleted. */
|
|
20
|
+
protected _emitDeletes(uris: readonly string[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Async iterator yielding `readonly string[]` batches of uris that
|
|
23
|
+
* changed under any input pattern. Runs until `signal` aborts.
|
|
24
|
+
*
|
|
25
|
+
* Default emission yields a singleton batch per matching change;
|
|
26
|
+
* subclasses with cheap batching can override to coalesce.
|
|
27
|
+
*
|
|
28
|
+
* The listener stays registered for the lifetime of the iteration;
|
|
29
|
+
* events fired while the consumer is processing a yielded value are
|
|
30
|
+
* buffered in a per-iterator queue so nothing is dropped across the
|
|
31
|
+
* yield boundary.
|
|
32
|
+
*/
|
|
33
|
+
observe(urls: string[], signal: AbortSignal): AsyncIterable<readonly string[]>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=observe-emitter.d.ts.map
|
package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe-emitter.d.ts","sourceRoot":"","sources":["../../../../../../../../src/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,KACV,IAAI,CAAC;AAEV;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,eAAe,CAAC,CAA8B;IAExE;;;;OAIG;IACH,SAAS,CAAC,KAAK,CACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,GACZ,IAAI;IAUP,sDAAsD;IACtD,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAIrD;;;;;;;;;;;OAWG;IACI,OAAO,CACZ,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,WAAW,GAClB,aAAa,CAAC,SAAS,MAAM,EAAE,CAAC;CA2CpC"}
|
package/esm/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/observe-emitter/observe-emitter.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* ObserveEmitter — the shared listener + async-iterator machinery
|
|
4
|
+
* `ProtocolInterfaceNode` implementations use to expose `observe()`.
|
|
5
|
+
*
|
|
6
|
+
* Observe is INV-style notification: each successful write or delete
|
|
7
|
+
* yields a `readonly string[]` — the batch of concrete uris that
|
|
8
|
+
* fired. The default emitter sends one uri per yield; backends with
|
|
9
|
+
* cheap batching can send several. A single change matching several
|
|
10
|
+
* input patterns yields once (not once per matching pattern); callers
|
|
11
|
+
* who need to know which of their patterns matched re-run the match
|
|
12
|
+
* locally, which is cheap and keeps the stream minimal.
|
|
13
|
+
*
|
|
14
|
+
* `observe(locators, signal)` accepts locators as opaque strings and
|
|
15
|
+
* matches them as segment-globs against emitted uris. The shared glob
|
|
16
|
+
* grammar (`*` for one segment, `**` for the rest) applies. Any
|
|
17
|
+
* normalization (e.g. stripping request-time directives before matching)
|
|
18
|
+
* is the executing client's responsibility.
|
|
19
|
+
*/
|
|
20
|
+
import { compilePattern, } from "../match-pattern/match-pattern.js";
|
|
21
|
+
/**
|
|
22
|
+
* Base class providing a write/delete listener bus and an async iterator
|
|
23
|
+
* for observing URI-pattern changes.
|
|
24
|
+
*
|
|
25
|
+
* Subclasses call `_emit(uri, data)` on successful writes and
|
|
26
|
+
* `_emitDeletes(uris)` on successful deletes. The emitter ignores
|
|
27
|
+
* `data` for INV-style notifications — observers receive only the
|
|
28
|
+
* uri and read it themselves.
|
|
29
|
+
*/
|
|
30
|
+
export class ObserveEmitter {
|
|
31
|
+
_listeners = new Set();
|
|
32
|
+
/**
|
|
33
|
+
* Notify all listeners of a URI change. `data` is accepted for
|
|
34
|
+
* compatibility with subclasses that may reuse the listener bus,
|
|
35
|
+
* but it is not surfaced to observe iterators.
|
|
36
|
+
*/
|
|
37
|
+
_emit(uri, data) {
|
|
38
|
+
for (const listener of this._listeners) {
|
|
39
|
+
try {
|
|
40
|
+
listener(uri, data);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Listener errors must never break the emitter.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Notify all listeners that each URI was deleted. */
|
|
48
|
+
_emitDeletes(uris) {
|
|
49
|
+
for (const uri of uris)
|
|
50
|
+
this._emit(uri, null);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Async iterator yielding `readonly string[]` batches of uris that
|
|
54
|
+
* changed under any input pattern. Runs until `signal` aborts.
|
|
55
|
+
*
|
|
56
|
+
* Default emission yields a singleton batch per matching change;
|
|
57
|
+
* subclasses with cheap batching can override to coalesce.
|
|
58
|
+
*
|
|
59
|
+
* The listener stays registered for the lifetime of the iteration;
|
|
60
|
+
* events fired while the consumer is processing a yielded value are
|
|
61
|
+
* buffered in a per-iterator queue so nothing is dropped across the
|
|
62
|
+
* yield boundary.
|
|
63
|
+
*/
|
|
64
|
+
async *observe(urls, signal) {
|
|
65
|
+
const matchers = urls.map(compilePattern);
|
|
66
|
+
const queue = [];
|
|
67
|
+
let wake = null;
|
|
68
|
+
const listener = (uri, _data) => {
|
|
69
|
+
for (let i = 0; i < matchers.length; i++) {
|
|
70
|
+
if (matchers[i](uri)) {
|
|
71
|
+
queue.push([uri]);
|
|
72
|
+
const w = wake;
|
|
73
|
+
if (w) {
|
|
74
|
+
wake = null;
|
|
75
|
+
w();
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const onAbort = () => {
|
|
82
|
+
const w = wake;
|
|
83
|
+
if (w) {
|
|
84
|
+
wake = null;
|
|
85
|
+
w();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
this._listeners.add(listener);
|
|
89
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
90
|
+
try {
|
|
91
|
+
while (true) {
|
|
92
|
+
while (queue.length > 0)
|
|
93
|
+
yield queue.shift();
|
|
94
|
+
if (signal.aborted)
|
|
95
|
+
return;
|
|
96
|
+
await new Promise((resolve) => {
|
|
97
|
+
wake = resolve;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
this._listeners.delete(listener);
|
|
103
|
+
signal.removeEventListener("abort", onAbort);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Connection — a client bound to a URI pattern list.
|
|
4
|
+
*
|
|
5
|
+
* A `Connection` wraps a `ProtocolInterfaceNode` with a set of URI
|
|
6
|
+
* filter patterns. Connections are bound into the rig's `routes`
|
|
7
|
+
* config (`receive`, `read`, `observe`) — each route gets its own
|
|
8
|
+
* ordered list of connections.
|
|
9
|
+
*
|
|
10
|
+
* The same connection value can be referenced from multiple routes
|
|
11
|
+
* (when one client serves writes, reads, and observes with the same
|
|
12
|
+
* filter); a different filter for a different op means a separate
|
|
13
|
+
* `connection(...)` call.
|
|
14
|
+
*
|
|
15
|
+
* Pattern syntax (same as observe and reactions):
|
|
16
|
+
* - `*` matches exactly one non-empty segment
|
|
17
|
+
* - `**` matches zero or more remaining segments (final segment only)
|
|
18
|
+
* - Literal segments must match exactly
|
|
19
|
+
*
|
|
20
|
+
* @example A single client serving all three ops
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { connection, Rig } from "@bandeira-tech/b3nd-core";
|
|
23
|
+
*
|
|
24
|
+
* const node = connection(httpClient, ["mutable://**", "hash://**"]);
|
|
25
|
+
*
|
|
26
|
+
* const rig = new Rig({
|
|
27
|
+
* routes: {
|
|
28
|
+
* receive: [node],
|
|
29
|
+
* read: [node],
|
|
30
|
+
* observe: [node],
|
|
31
|
+
* },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Asymmetric topology — write-mirror, read-cache, narrow observe
|
|
36
|
+
* ```ts
|
|
37
|
+
* const primary = connection(httpClient, ["mutable://**", "hash://**"], { id: "primary" });
|
|
38
|
+
* const mirror = connection(pgClient, ["mutable://**", "hash://**"], { id: "mirror" });
|
|
39
|
+
* const cache = connection(redisClient, ["mutable://accounts/**"], { id: "cache" });
|
|
40
|
+
* const obsNarrow = connection(httpClient, ["mutable://**"], { id: "primary-obs" });
|
|
41
|
+
*
|
|
42
|
+
* const rig = new Rig({
|
|
43
|
+
* routes: {
|
|
44
|
+
* receive: [primary, mirror], // broadcast both
|
|
45
|
+
* read: [cache, primary], // try cache first, then primary
|
|
46
|
+
* observe: [obsNarrow], // narrow namespace, primary only
|
|
47
|
+
* },
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
import type { ProtocolInterfaceNode } from "../types/types.js";
|
|
52
|
+
/** Optional configuration for a connection. */
|
|
53
|
+
export interface ConnectionOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Stable identifier for this connection. Surfaces in
|
|
56
|
+
* `route:success`/`route:error` events on the operation handle and
|
|
57
|
+
* lets operators tell replicas apart in observability data.
|
|
58
|
+
* Auto-generated as `conn-{N}` (registration order) when omitted.
|
|
59
|
+
*/
|
|
60
|
+
id?: string;
|
|
61
|
+
}
|
|
62
|
+
/** A connection: a client wrapped with a URI pattern list. */
|
|
63
|
+
export interface Connection {
|
|
64
|
+
/** Stable identifier (provided or auto-generated). */
|
|
65
|
+
readonly id: string;
|
|
66
|
+
/** The underlying client. */
|
|
67
|
+
readonly client: ProtocolInterfaceNode;
|
|
68
|
+
/**
|
|
69
|
+
* The raw patterns — serializable for wire protocols.
|
|
70
|
+
* Send this to a remote node so it knows what to push.
|
|
71
|
+
*/
|
|
72
|
+
readonly patterns: readonly string[];
|
|
73
|
+
/** Check if this connection's pattern list accepts a URI. */
|
|
74
|
+
accepts(uri: string): boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Wrap a client with a URI pattern list to create a connection.
|
|
78
|
+
*
|
|
79
|
+
* The connection is the gateway control — the rig uses it for
|
|
80
|
+
* routing within the route arrays it appears in, and the patterns
|
|
81
|
+
* can be published over the wire for remote filtering.
|
|
82
|
+
*
|
|
83
|
+
* Local enforcement is always applied. Remote enforcement is
|
|
84
|
+
* best-effort: the remote node may or may not honor the patterns,
|
|
85
|
+
* but the local rig always filters based on them.
|
|
86
|
+
*/
|
|
87
|
+
export declare function connection(client: ProtocolInterfaceNode, patterns: string[], options?: ConnectionOptions): Connection;
|
|
88
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../../../../../src/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/connection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAQ/D,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,6BAA6B;IAC7B,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAErC,6DAA6D;IAC7D,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAgBD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,UAAU,CAcZ"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Connection — a client bound to a URI pattern list.
|
|
4
|
+
*
|
|
5
|
+
* A `Connection` wraps a `ProtocolInterfaceNode` with a set of URI
|
|
6
|
+
* filter patterns. Connections are bound into the rig's `routes`
|
|
7
|
+
* config (`receive`, `read`, `observe`) — each route gets its own
|
|
8
|
+
* ordered list of connections.
|
|
9
|
+
*
|
|
10
|
+
* The same connection value can be referenced from multiple routes
|
|
11
|
+
* (when one client serves writes, reads, and observes with the same
|
|
12
|
+
* filter); a different filter for a different op means a separate
|
|
13
|
+
* `connection(...)` call.
|
|
14
|
+
*
|
|
15
|
+
* Pattern syntax (same as observe and reactions):
|
|
16
|
+
* - `*` matches exactly one non-empty segment
|
|
17
|
+
* - `**` matches zero or more remaining segments (final segment only)
|
|
18
|
+
* - Literal segments must match exactly
|
|
19
|
+
*
|
|
20
|
+
* @example A single client serving all three ops
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { connection, Rig } from "@bandeira-tech/b3nd-core";
|
|
23
|
+
*
|
|
24
|
+
* const node = connection(httpClient, ["mutable://**", "hash://**"]);
|
|
25
|
+
*
|
|
26
|
+
* const rig = new Rig({
|
|
27
|
+
* routes: {
|
|
28
|
+
* receive: [node],
|
|
29
|
+
* read: [node],
|
|
30
|
+
* observe: [node],
|
|
31
|
+
* },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Asymmetric topology — write-mirror, read-cache, narrow observe
|
|
36
|
+
* ```ts
|
|
37
|
+
* const primary = connection(httpClient, ["mutable://**", "hash://**"], { id: "primary" });
|
|
38
|
+
* const mirror = connection(pgClient, ["mutable://**", "hash://**"], { id: "mirror" });
|
|
39
|
+
* const cache = connection(redisClient, ["mutable://accounts/**"], { id: "cache" });
|
|
40
|
+
* const obsNarrow = connection(httpClient, ["mutable://**"], { id: "primary-obs" });
|
|
41
|
+
*
|
|
42
|
+
* const rig = new Rig({
|
|
43
|
+
* routes: {
|
|
44
|
+
* receive: [primary, mirror], // broadcast both
|
|
45
|
+
* read: [cache, primary], // try cache first, then primary
|
|
46
|
+
* observe: [obsNarrow], // narrow namespace, primary only
|
|
47
|
+
* },
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
import { compilePattern, } from "../match-pattern/match-pattern.js";
|
|
52
|
+
// ── Internals ──
|
|
53
|
+
function matchesAny(matchers, uri) {
|
|
54
|
+
for (let i = 0; i < matchers.length; i++) {
|
|
55
|
+
if (matchers[i](uri))
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
// ── connection ──
|
|
61
|
+
/** Module-level counter for auto-generated connection IDs. */
|
|
62
|
+
let _autoIdCounter = 0;
|
|
63
|
+
/**
|
|
64
|
+
* Wrap a client with a URI pattern list to create a connection.
|
|
65
|
+
*
|
|
66
|
+
* The connection is the gateway control — the rig uses it for
|
|
67
|
+
* routing within the route arrays it appears in, and the patterns
|
|
68
|
+
* can be published over the wire for remote filtering.
|
|
69
|
+
*
|
|
70
|
+
* Local enforcement is always applied. Remote enforcement is
|
|
71
|
+
* best-effort: the remote node may or may not honor the patterns,
|
|
72
|
+
* but the local rig always filters based on them.
|
|
73
|
+
*/
|
|
74
|
+
export function connection(client, patterns, options) {
|
|
75
|
+
const matchers = patterns.map(compilePattern);
|
|
76
|
+
const frozenPatterns = Object.freeze([...patterns]);
|
|
77
|
+
const id = options?.id ?? `conn-${_autoIdCounter++}`;
|
|
78
|
+
return {
|
|
79
|
+
id,
|
|
80
|
+
client,
|
|
81
|
+
patterns: frozenPatterns,
|
|
82
|
+
accepts(uri) {
|
|
83
|
+
return matchesAny(matchers, uri);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Typed event emitter for the Rig.
|
|
4
|
+
*
|
|
5
|
+
* Events are async, fire-and-forget — they run AFTER the operation
|
|
6
|
+
* completes (after post-hooks). They never block the caller.
|
|
7
|
+
*
|
|
8
|
+
* Handler errors are caught (never propagated) and surfaced via
|
|
9
|
+
* `onHandlerError` listeners. If no listener is registered, they
|
|
10
|
+
* fall back to `console.warn` so failures are never silent.
|
|
11
|
+
*
|
|
12
|
+
* On cleanup, pending event promises are returned to the caller
|
|
13
|
+
* so they can choose to await them or let them go.
|
|
14
|
+
*
|
|
15
|
+
* Pure module — no Rig dependency, testable in isolation.
|
|
16
|
+
*/
|
|
17
|
+
/** All possible rig event names. */
|
|
18
|
+
export type RigEventName = "send:success" | "send:error" | "receive:success" | "receive:error" | "read:success" | "read:error" | "*:success" | "*:error";
|
|
19
|
+
/** Payload delivered to event handlers. */
|
|
20
|
+
export interface RigEvent {
|
|
21
|
+
/** The operation that triggered this event. */
|
|
22
|
+
op: string;
|
|
23
|
+
/** The URI involved, if any. */
|
|
24
|
+
uri?: string;
|
|
25
|
+
/** The data involved (e.g., receive payload, send envelope). */
|
|
26
|
+
data?: unknown;
|
|
27
|
+
/** The operation result (on success). */
|
|
28
|
+
result?: unknown;
|
|
29
|
+
/** The error (on error). */
|
|
30
|
+
error?: unknown;
|
|
31
|
+
/** Timestamp when the event was emitted. */
|
|
32
|
+
ts: number;
|
|
33
|
+
}
|
|
34
|
+
/** Event handler function. */
|
|
35
|
+
export type EventHandler = (event: RigEvent) => void | Promise<void>;
|
|
36
|
+
/** Listener for errors thrown inside event handlers. */
|
|
37
|
+
export type HandlerErrorListener = (error: unknown, event: RigEventName) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Typed event emitter for Rig operations.
|
|
40
|
+
*
|
|
41
|
+
* - Handlers fire asynchronously (via microtask)
|
|
42
|
+
* - Handler errors are routed to `onHandlerError` listeners; if none are
|
|
43
|
+
* registered, they fall back to `console.warn`
|
|
44
|
+
* - Wildcard events (`*:success`, `*:error`) fire for all operations
|
|
45
|
+
* - `pending()` returns in-flight handler promises for drain-on-cleanup
|
|
46
|
+
*/
|
|
47
|
+
export declare class RigEventEmitter {
|
|
48
|
+
private handlers;
|
|
49
|
+
private errorListeners;
|
|
50
|
+
private inflight;
|
|
51
|
+
/** Register a handler. Returns an unsubscribe function. */
|
|
52
|
+
on(event: RigEventName, handler: EventHandler): () => void;
|
|
53
|
+
/** Remove a specific handler. */
|
|
54
|
+
off(event: RigEventName, handler: EventHandler): void;
|
|
55
|
+
/**
|
|
56
|
+
* Register a listener for errors thrown inside event handlers.
|
|
57
|
+
* Returns an unsubscribe function.
|
|
58
|
+
*
|
|
59
|
+
* When at least one listener is registered, the `console.warn` fallback
|
|
60
|
+
* is suppressed — the listener owns reporting. If a listener itself
|
|
61
|
+
* throws, that secondary error falls back to `console.warn` (no recursion).
|
|
62
|
+
*/
|
|
63
|
+
onHandlerError(listener: HandlerErrorListener): () => void;
|
|
64
|
+
/** Return handler counts per event name. */
|
|
65
|
+
counts(): Record<string, number>;
|
|
66
|
+
/**
|
|
67
|
+
* Fire an event. Handlers run asynchronously and never block.
|
|
68
|
+
* Errors in handlers are routed to `onHandlerError` listeners (or
|
|
69
|
+
* `console.warn` if none). Promises are tracked so `pending()` can
|
|
70
|
+
* return them, and self-evict once settled.
|
|
71
|
+
*/
|
|
72
|
+
emit(event: RigEventName, payload: RigEvent): void;
|
|
73
|
+
private dispatchHandlerError;
|
|
74
|
+
/**
|
|
75
|
+
* Return all in-flight event handler promises and clear the queue.
|
|
76
|
+
*
|
|
77
|
+
* The caller decides what to do with them:
|
|
78
|
+
* - `await Promise.allSettled(pending)` to drain before exit
|
|
79
|
+
* - Ignore them if you don't care about completion
|
|
80
|
+
*/
|
|
81
|
+
pending(): Promise<void>[];
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../../../../../src/deps/jsr.io/@bandeira-tech/b3nd-core/0.22.0/src/rig/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,oCAAoC;AACpC,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,YAAY,GACZ,iBAAiB,GACjB,eAAe,GACf,cAAc,GACd,YAAY,GACZ,WAAW,GACX,SAAS,CAAC;AAEd,2CAA2C;AAC3C,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yCAAyC;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,wDAAwD;AACxD,MAAM,MAAM,oBAAoB,GAAG,CACjC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,YAAY,KAChB,IAAI,CAAC;AAIV;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,QAAQ,CAA4B;IAE5C,2DAA2D;IAC3D,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,MAAM,IAAI;IAU1D,iCAAiC;IACjC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAIrD;;;;;;;OAOG;IACH,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAK1D,4CAA4C;IAC5C,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAQhC;;;;;OAKG;IACH,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,GAAG,IAAI;IAoBlD,OAAO,CAAC,oBAAoB;IAiB5B;;;;;;OAMG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;CAK3B"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Typed event emitter for the Rig.
|
|
4
|
+
*
|
|
5
|
+
* Events are async, fire-and-forget — they run AFTER the operation
|
|
6
|
+
* completes (after post-hooks). They never block the caller.
|
|
7
|
+
*
|
|
8
|
+
* Handler errors are caught (never propagated) and surfaced via
|
|
9
|
+
* `onHandlerError` listeners. If no listener is registered, they
|
|
10
|
+
* fall back to `console.warn` so failures are never silent.
|
|
11
|
+
*
|
|
12
|
+
* On cleanup, pending event promises are returned to the caller
|
|
13
|
+
* so they can choose to await them or let them go.
|
|
14
|
+
*
|
|
15
|
+
* Pure module — no Rig dependency, testable in isolation.
|
|
16
|
+
*/
|
|
17
|
+
// ── Emitter ──
|
|
18
|
+
/**
|
|
19
|
+
* Typed event emitter for Rig operations.
|
|
20
|
+
*
|
|
21
|
+
* - Handlers fire asynchronously (via microtask)
|
|
22
|
+
* - Handler errors are routed to `onHandlerError` listeners; if none are
|
|
23
|
+
* registered, they fall back to `console.warn`
|
|
24
|
+
* - Wildcard events (`*:success`, `*:error`) fire for all operations
|
|
25
|
+
* - `pending()` returns in-flight handler promises for drain-on-cleanup
|
|
26
|
+
*/
|
|
27
|
+
export class RigEventEmitter {
|
|
28
|
+
handlers = new Map();
|
|
29
|
+
errorListeners = new Set();
|
|
30
|
+
inflight = new Set();
|
|
31
|
+
/** Register a handler. Returns an unsubscribe function. */
|
|
32
|
+
on(event, handler) {
|
|
33
|
+
let set = this.handlers.get(event);
|
|
34
|
+
if (!set) {
|
|
35
|
+
set = new Set();
|
|
36
|
+
this.handlers.set(event, set);
|
|
37
|
+
}
|
|
38
|
+
set.add(handler);
|
|
39
|
+
return () => set.delete(handler);
|
|
40
|
+
}
|
|
41
|
+
/** Remove a specific handler. */
|
|
42
|
+
off(event, handler) {
|
|
43
|
+
this.handlers.get(event)?.delete(handler);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Register a listener for errors thrown inside event handlers.
|
|
47
|
+
* Returns an unsubscribe function.
|
|
48
|
+
*
|
|
49
|
+
* When at least one listener is registered, the `console.warn` fallback
|
|
50
|
+
* is suppressed — the listener owns reporting. If a listener itself
|
|
51
|
+
* throws, that secondary error falls back to `console.warn` (no recursion).
|
|
52
|
+
*/
|
|
53
|
+
onHandlerError(listener) {
|
|
54
|
+
this.errorListeners.add(listener);
|
|
55
|
+
return () => this.errorListeners.delete(listener);
|
|
56
|
+
}
|
|
57
|
+
/** Return handler counts per event name. */
|
|
58
|
+
counts() {
|
|
59
|
+
const result = {};
|
|
60
|
+
for (const [name, set] of this.handlers) {
|
|
61
|
+
if (set.size > 0)
|
|
62
|
+
result[name] = set.size;
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Fire an event. Handlers run asynchronously and never block.
|
|
68
|
+
* Errors in handlers are routed to `onHandlerError` listeners (or
|
|
69
|
+
* `console.warn` if none). Promises are tracked so `pending()` can
|
|
70
|
+
* return them, and self-evict once settled.
|
|
71
|
+
*/
|
|
72
|
+
emit(event, payload) {
|
|
73
|
+
const specific = this.handlers.get(event);
|
|
74
|
+
// Determine wildcard: "send:success" → "*:success"
|
|
75
|
+
const suffix = event.endsWith(":success") ? "*:success" : "*:error";
|
|
76
|
+
const wildcard = this.handlers.get(suffix);
|
|
77
|
+
const all = [
|
|
78
|
+
...(specific ? specific : []),
|
|
79
|
+
...(wildcard && event !== suffix ? wildcard : []),
|
|
80
|
+
];
|
|
81
|
+
for (const handler of all) {
|
|
82
|
+
const p = Promise.resolve()
|
|
83
|
+
.then(() => handler(payload))
|
|
84
|
+
.catch((err) => this.dispatchHandlerError(err, event));
|
|
85
|
+
this.inflight.add(p);
|
|
86
|
+
p.finally(() => this.inflight.delete(p));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
dispatchHandlerError(error, event) {
|
|
90
|
+
if (this.errorListeners.size === 0) {
|
|
91
|
+
console.warn(`[rig] event handler error on "${event}":`, error);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
for (const listener of this.errorListeners) {
|
|
95
|
+
try {
|
|
96
|
+
listener(error, event);
|
|
97
|
+
}
|
|
98
|
+
catch (listenerError) {
|
|
99
|
+
console.warn(`[rig] onHandlerError listener threw:`, listenerError);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Return all in-flight event handler promises and clear the queue.
|
|
105
|
+
*
|
|
106
|
+
* The caller decides what to do with them:
|
|
107
|
+
* - `await Promise.allSettled(pending)` to drain before exit
|
|
108
|
+
* - Ignore them if you don't care about completion
|
|
109
|
+
*/
|
|
110
|
+
pending() {
|
|
111
|
+
const result = [...this.inflight];
|
|
112
|
+
this.inflight.clear();
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
}
|