@norskvideo/moq-net 0.1.3 → 0.1.4
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 +1 -0
- package/announced.d.ts +111 -21
- package/announced.d.ts.map +1 -1
- package/announced.js +213 -40
- package/announced.js.map +1 -1
- package/broadcast.d.ts +80 -25
- package/broadcast.d.ts.map +1 -1
- package/broadcast.js +270 -49
- package/broadcast.js.map +1 -1
- package/connection/accept.d.ts +6 -0
- package/connection/accept.d.ts.map +1 -1
- package/connection/accept.js +42 -13
- package/connection/accept.js.map +1 -1
- package/connection/browser.d.ts +5 -0
- package/connection/browser.d.ts.map +1 -0
- package/connection/browser.js +31 -0
- package/connection/browser.js.map +1 -0
- package/connection/connect.d.ts +43 -1
- package/connection/connect.d.ts.map +1 -1
- package/connection/connect.js +118 -123
- package/connection/connect.js.map +1 -1
- package/connection/established.d.ts +43 -16
- package/connection/established.d.ts.map +1 -1
- package/connection/established.js.map +1 -1
- package/connection/handshake.d.ts +12 -1
- package/connection/handshake.d.ts.map +1 -1
- package/connection/handshake.js +30 -14
- package/connection/handshake.js.map +1 -1
- package/connection/index.d.ts +8 -0
- package/connection/index.d.ts.map +1 -1
- package/connection/index.js +6 -0
- package/connection/index.js.map +1 -1
- package/connection/reload.d.ts +66 -9
- package/connection/reload.d.ts.map +1 -1
- package/connection/reload.js +192 -66
- package/connection/reload.js.map +1 -1
- package/connection/stats.d.ts +92 -0
- package/connection/stats.d.ts.map +1 -0
- package/connection/stats.js +35 -0
- package/connection/stats.js.map +1 -0
- package/connection/transport.d.ts +10 -0
- package/connection/transport.d.ts.map +1 -0
- package/connection/transport.js +12 -0
- package/connection/transport.js.map +1 -0
- package/consume.d.ts +44 -0
- package/consume.d.ts.map +1 -0
- package/consume.js +60 -0
- package/consume.js.map +1 -0
- package/datagram.d.ts +23 -0
- package/datagram.d.ts.map +1 -0
- package/datagram.js +3 -0
- package/datagram.js.map +1 -0
- package/error.d.ts +76 -0
- package/error.d.ts.map +1 -0
- package/error.js +107 -0
- package/error.js.map +1 -0
- package/group.d.ts +143 -38
- package/group.d.ts.map +1 -1
- package/group.js +270 -68
- package/group.js.map +1 -1
- package/ietf/adapter.d.ts +2 -2
- package/ietf/adapter.d.ts.map +1 -1
- package/ietf/adapter.js +20 -10
- package/ietf/adapter.js.map +1 -1
- package/ietf/aliases.d.ts +73 -5
- package/ietf/aliases.d.ts.map +1 -1
- package/ietf/aliases.js +121 -14
- package/ietf/aliases.js.map +1 -1
- package/ietf/cluster.d.ts +141 -0
- package/ietf/cluster.d.ts.map +1 -0
- package/ietf/cluster.js +204 -0
- package/ietf/cluster.js.map +1 -0
- package/ietf/connection.d.ts +39 -6
- package/ietf/connection.d.ts.map +1 -1
- package/ietf/connection.js +73 -12
- package/ietf/connection.js.map +1 -1
- package/ietf/fetch.d.ts +17 -0
- package/ietf/fetch.d.ts.map +1 -1
- package/ietf/fetch.js +21 -0
- package/ietf/fetch.js.map +1 -1
- package/ietf/filter.d.ts +87 -0
- package/ietf/filter.d.ts.map +1 -0
- package/ietf/filter.js +292 -0
- package/ietf/filter.js.map +1 -0
- package/ietf/index.d.ts +2 -0
- package/ietf/index.d.ts.map +1 -1
- package/ietf/index.js +3 -0
- package/ietf/index.js.map +1 -1
- package/ietf/namespace.d.ts +6 -0
- package/ietf/namespace.d.ts.map +1 -1
- package/ietf/namespace.js +27 -2
- package/ietf/namespace.js.map +1 -1
- package/ietf/object.d.ts +54 -6
- package/ietf/object.d.ts.map +1 -1
- package/ietf/object.js +178 -25
- package/ietf/object.js.map +1 -1
- package/ietf/parameters.d.ts +35 -10
- package/ietf/parameters.d.ts.map +1 -1
- package/ietf/parameters.js +236 -45
- package/ietf/parameters.js.map +1 -1
- package/ietf/priority.d.ts +5 -0
- package/ietf/priority.d.ts.map +1 -0
- package/ietf/priority.js +10 -0
- package/ietf/priority.js.map +1 -0
- package/ietf/properties.d.ts +13 -2
- package/ietf/properties.d.ts.map +1 -1
- package/ietf/properties.js +65 -8
- package/ietf/properties.js.map +1 -1
- package/ietf/publish.d.ts.map +1 -1
- package/ietf/publish.js +13 -3
- package/ietf/publish.js.map +1 -1
- package/ietf/publish_namespace.d.ts +16 -2
- package/ietf/publish_namespace.d.ts.map +1 -1
- package/ietf/publish_namespace.js +25 -6
- package/ietf/publish_namespace.js.map +1 -1
- package/ietf/publisher.d.ts +40 -7
- package/ietf/publisher.d.ts.map +1 -1
- package/ietf/publisher.js +751 -134
- package/ietf/publisher.js.map +1 -1
- package/ietf/request.js +1 -1
- package/ietf/request.js.map +1 -1
- package/ietf/solicit.d.ts +41 -0
- package/ietf/solicit.d.ts.map +1 -0
- package/ietf/solicit.js +47 -0
- package/ietf/solicit.js.map +1 -0
- package/ietf/subscribe.d.ts +41 -2
- package/ietf/subscribe.d.ts.map +1 -1
- package/ietf/subscribe.js +103 -22
- package/ietf/subscribe.js.map +1 -1
- package/ietf/subscribe_namespace.d.ts +21 -7
- package/ietf/subscribe_namespace.d.ts.map +1 -1
- package/ietf/subscribe_namespace.js +31 -14
- package/ietf/subscribe_namespace.js.map +1 -1
- package/ietf/subscriber.d.ts +20 -7
- package/ietf/subscriber.d.ts.map +1 -1
- package/ietf/subscriber.js +512 -142
- package/ietf/subscriber.js.map +1 -1
- package/ietf/version.d.ts +7 -1
- package/ietf/version.d.ts.map +1 -1
- package/ietf/version.js +7 -0
- package/ietf/version.js.map +1 -1
- package/index.d.ts +10 -5
- package/index.d.ts.map +1 -1
- package/index.js +10 -5
- package/index.js.map +1 -1
- package/internal.d.ts +29 -0
- package/internal.d.ts.map +1 -0
- package/internal.js +8 -0
- package/internal.js.map +1 -0
- package/lite/announce.d.ts +62 -15
- package/lite/announce.d.ts.map +1 -1
- package/lite/announce.js +230 -94
- package/lite/announce.js.map +1 -1
- package/lite/connection.d.ts +69 -20
- package/lite/connection.d.ts.map +1 -1
- package/lite/connection.js +128 -81
- package/lite/connection.js.map +1 -1
- package/lite/datagram.d.ts +23 -0
- package/lite/datagram.d.ts.map +1 -0
- package/lite/datagram.js +57 -0
- package/lite/datagram.js.map +1 -0
- package/lite/datagram_stream.d.ts +8 -0
- package/lite/datagram_stream.d.ts.map +1 -0
- package/lite/datagram_stream.js +44 -0
- package/lite/datagram_stream.js.map +1 -0
- package/lite/fetch.d.ts.map +1 -1
- package/lite/fetch.js +2 -2
- package/lite/fetch.js.map +1 -1
- package/lite/index.d.ts +3 -0
- package/lite/index.d.ts.map +1 -1
- package/lite/index.js +3 -0
- package/lite/index.js.map +1 -1
- package/lite/priority.d.ts +67 -0
- package/lite/priority.d.ts.map +1 -0
- package/lite/priority.js +114 -0
- package/lite/priority.js.map +1 -0
- package/lite/probe.d.ts +18 -2
- package/lite/probe.d.ts.map +1 -1
- package/lite/probe.js +24 -22
- package/lite/probe.js.map +1 -1
- package/lite/publisher.d.ts +14 -7
- package/lite/publisher.d.ts.map +1 -1
- package/lite/publisher.js +406 -84
- package/lite/publisher.js.map +1 -1
- package/lite/setup.d.ts +83 -6
- package/lite/setup.d.ts.map +1 -1
- package/lite/setup.js +203 -31
- package/lite/setup.js.map +1 -1
- package/lite/stream.d.ts +12 -3
- package/lite/stream.d.ts.map +1 -1
- package/lite/stream.js +7 -4
- package/lite/stream.js.map +1 -1
- package/lite/subscribe.d.ts +37 -23
- package/lite/subscribe.d.ts.map +1 -1
- package/lite/subscribe.js +70 -55
- package/lite/subscribe.js.map +1 -1
- package/lite/subscriber.d.ts +29 -23
- package/lite/subscriber.d.ts.map +1 -1
- package/lite/subscriber.js +689 -112
- package/lite/subscriber.js.map +1 -1
- package/lite/track.d.ts +25 -13
- package/lite/track.d.ts.map +1 -1
- package/lite/track.js +60 -35
- package/lite/track.js.map +1 -1
- package/lite/version.d.ts +39 -4
- package/lite/version.d.ts.map +1 -1
- package/lite/version.js +139 -17
- package/lite/version.js.map +1 -1
- package/mock.d.ts +53 -3
- package/mock.d.ts.map +1 -1
- package/mock.js +110 -21
- package/mock.js.map +1 -1
- package/{lite/origin.d.ts → origin.d.ts} +25 -1
- package/origin.d.ts.map +1 -0
- package/{lite/origin.js → origin.js} +25 -1
- package/origin.js.map +1 -0
- package/package.json +6 -4
- package/path.d.ts +67 -0
- package/path.d.ts.map +1 -1
- package/path.js +128 -0
- package/path.js.map +1 -1
- package/stream.d.ts +94 -4
- package/stream.d.ts.map +1 -1
- package/stream.js +128 -17
- package/stream.js.map +1 -1
- package/time.d.ts +109 -86
- package/time.d.ts.map +1 -1
- package/time.js +80 -30
- package/time.js.map +1 -1
- package/track.d.ts +298 -47
- package/track.d.ts.map +1 -1
- package/track.js +721 -109
- package/track.js.map +1 -1
- package/util/timeout.d.ts +5 -0
- package/util/timeout.d.ts.map +1 -0
- package/util/timeout.js +18 -0
- package/util/timeout.js.map +1 -0
- package/util/utf8.d.ts +3 -0
- package/util/utf8.d.ts.map +1 -0
- package/util/utf8.js +7 -0
- package/util/utf8.js.map +1 -0
- package/varint.d.ts +14 -3
- package/varint.d.ts.map +1 -1
- package/varint.js +23 -12
- package/varint.js.map +1 -1
- package/zod.d.ts +5 -5
- package/zod.d.ts.map +1 -1
- package/zod.js.map +1 -1
- package/bandwidth.d.ts +0 -11
- package/bandwidth.d.ts.map +0 -1
- package/bandwidth.js +0 -7
- package/bandwidth.js.map +0 -1
- package/connection/cert.test.d.ts +0 -2
- package/connection/cert.test.d.ts.map +0 -1
- package/connection/cert.test.js +0 -26
- package/connection/cert.test.js.map +0 -1
- package/connection/reload.test.d.ts +0 -2
- package/connection/reload.test.d.ts.map +0 -1
- package/connection/reload.test.js +0 -39
- package/connection/reload.test.js.map +0 -1
- package/group.test.d.ts +0 -2
- package/group.test.d.ts.map +0 -1
- package/group.test.js +0 -66
- package/group.test.js.map +0 -1
- package/ietf/aliases.test.d.ts +0 -2
- package/ietf/aliases.test.d.ts.map +0 -1
- package/ietf/aliases.test.js +0 -30
- package/ietf/aliases.test.js.map +0 -1
- package/ietf/ietf.test.d.ts +0 -2
- package/ietf/ietf.test.d.ts.map +0 -1
- package/ietf/ietf.test.js +0 -873
- package/ietf/ietf.test.js.map +0 -1
- package/integration.test.d.ts +0 -2
- package/integration.test.d.ts.map +0 -1
- package/integration.test.js +0 -90
- package/integration.test.js.map +0 -1
- package/lite/origin.d.ts.map +0 -1
- package/lite/origin.js.map +0 -1
- package/lite/subscriber.test.d.ts +0 -2
- package/lite/subscriber.test.d.ts.map +0 -1
- package/lite/subscriber.test.js +0 -30
- package/lite/subscriber.test.js.map +0 -1
- package/lite/track.test.d.ts +0 -2
- package/lite/track.test.d.ts.map +0 -1
- package/lite/track.test.js +0 -53
- package/lite/track.test.js.map +0 -1
- package/path.test.d.ts +0 -2
- package/path.test.d.ts.map +0 -1
- package/path.test.js +0 -169
- package/path.test.js.map +0 -1
- package/stream.test.d.ts +0 -2
- package/stream.test.d.ts.map +0 -1
- package/stream.test.js +0 -210
- package/stream.test.js.map +0 -1
- package/track.test.d.ts +0 -2
- package/track.test.d.ts.map +0 -1
- package/track.test.js +0 -56
- package/track.test.js.map +0 -1
- package/util/error.d.ts +0 -3
- package/util/error.d.ts.map +0 -1
- package/util/error.js +0 -9
- package/util/error.js.map +0 -1
- package/util/index.d.ts +0 -2
- package/util/index.d.ts.map +0 -1
- package/util/index.js +0 -3
- package/util/index.js.map +0 -1
- package/varint.test.d.ts +0 -2
- package/varint.test.d.ts.map +0 -1
- package/varint.test.js +0 -106
- package/varint.test.js.map +0 -1
package/consume.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,SAAS,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;;IAI1B,yFAAyF;IACzF,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,GAAG,SAAS,CAIpD;IAED;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAUzE;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAE5B;CACD"}
|
package/consume.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* @ts-self-types="./consume.d.ts" */
|
|
2
|
+
/**
|
|
3
|
+
* Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf
|
|
4
|
+
* subscribers.
|
|
5
|
+
*
|
|
6
|
+
* `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests
|
|
7
|
+
* for the same path (e.g. several renditions referencing one `broadcast: "./source"`) should
|
|
8
|
+
* share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:
|
|
9
|
+
* a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is
|
|
10
|
+
* re-consumed on the next request. Each handle is reference-counted, so the shared broadcast
|
|
11
|
+
* closes once every caller has closed its handle.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export class BroadcastCache {
|
|
16
|
+
// The base handle per path; callers get reference-counted clones of it.
|
|
17
|
+
#cache = new Map();
|
|
18
|
+
/** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */
|
|
19
|
+
get(path) {
|
|
20
|
+
const base = this.#cache.get(path);
|
|
21
|
+
if (base && base.closed.peek() === undefined)
|
|
22
|
+
return base.clone();
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.
|
|
27
|
+
* Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.
|
|
28
|
+
*/
|
|
29
|
+
insert(path, consumer) {
|
|
30
|
+
this.#cache.set(path, consumer);
|
|
31
|
+
// Drop the entry once the broadcast closes (every handle released), so the next request
|
|
32
|
+
// re-consumes rather than cloning a dead handle. Guard against a newer entry for the path.
|
|
33
|
+
void consumer.closed.then(() => {
|
|
34
|
+
if (this.#cache.get(path) === consumer)
|
|
35
|
+
this.#cache.delete(path);
|
|
36
|
+
});
|
|
37
|
+
return consumer;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.
|
|
41
|
+
*
|
|
42
|
+
* Call when the path's advertisement goes away. A handle only leaves the cache on its own
|
|
43
|
+
* once *every* holder has closed it, so one holder outliving the publisher (a second
|
|
44
|
+
* watcher, or a caller consuming the path directly) would otherwise keep the dead
|
|
45
|
+
* generation's cached tracks alive and hand them to whoever consumes the path next.
|
|
46
|
+
* Existing handles are left alone: they belong to their holders, and the wire resets
|
|
47
|
+
* whatever they still have open.
|
|
48
|
+
*
|
|
49
|
+
* Eviction is unconditional, which costs a dedup miss when two announcement streams watch
|
|
50
|
+
* one path: the second stream's retraction can arrive after the first has already seen the
|
|
51
|
+
* replacement, dropping the fresh entry so the next request subscribes again instead of
|
|
52
|
+
* sharing. Telling that stale retraction from a live one needs a generation id on the
|
|
53
|
+
* advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a
|
|
54
|
+
* duplicate subscription rather than risk handing out a dead one.
|
|
55
|
+
*/
|
|
56
|
+
evict(path) {
|
|
57
|
+
this.#cache.delete(path);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=consume.js.map
|
package/consume.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consume.js","sourceRoot":"","sources":["../src/consume.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAc;IAC1B,wEAAwE;IACxE,MAAM,GAAG,IAAI,GAAG,EAAkC,CAAC;IAEnD,yFAAyF;IACzF,GAAG,CAAC,IAAgB;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAgB,EAAE,QAA4B;QACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEhC,wFAAwF;QACxF,2FAA2F;QAC3F,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAgB;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACD","sourcesContent":["import type * as broadcast from \"./broadcast.ts\";\nimport type * as Path from \"./path.ts\";\n\n/**\n * Per-path dedup cache for consumed broadcasts, shared by the moq-lite and moq-ietf\n * subscribers.\n *\n * `Connection.consume(path)` must not mint a fresh subscription per call: repeat requests\n * for the same path (e.g. several renditions referencing one `broadcast: \"./source\"`) should\n * share a single upstream subscription. This mirrors the Rust `origin::Consumer` weak-cache:\n * a still-live path resolves to a shared {@link broadcast.Consumer.clone}, a closed one is\n * re-consumed on the next request. Each handle is reference-counted, so the shared broadcast\n * closes once every caller has closed its handle.\n *\n * @internal\n */\nexport class BroadcastCache {\n\t// The base handle per path; callers get reference-counted clones of it.\n\t#cache = new Map<Path.Valid, broadcast.Consumer>();\n\n\t/** A shared handle to the live broadcast cached for `path`, or `undefined` on a miss. */\n\tget(path: Path.Valid): broadcast.Consumer | undefined {\n\t\tconst base = this.#cache.get(path);\n\t\tif (base && base.closed.peek() === undefined) return base.clone();\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Cache `consumer` as the base handle for `path` (evicting it once it closes) and return it.\n\t * Call on a {@link get} miss, after wiring up the fresh consumer's subscribe loop.\n\t */\n\tinsert(path: Path.Valid, consumer: broadcast.Consumer): broadcast.Consumer {\n\t\tthis.#cache.set(path, consumer);\n\n\t\t// Drop the entry once the broadcast closes (every handle released), so the next request\n\t\t// re-consumes rather than cloning a dead handle. Guard against a newer entry for the path.\n\t\tvoid consumer.closed.then(() => {\n\t\t\tif (this.#cache.get(path) === consumer) this.#cache.delete(path);\n\t\t});\n\n\t\treturn consumer;\n\t}\n\n\t/**\n\t * Stop sharing the broadcast cached for `path`, so the next request subscribes fresh.\n\t *\n\t * Call when the path's advertisement goes away. A handle only leaves the cache on its own\n\t * once *every* holder has closed it, so one holder outliving the publisher (a second\n\t * watcher, or a caller consuming the path directly) would otherwise keep the dead\n\t * generation's cached tracks alive and hand them to whoever consumes the path next.\n\t * Existing handles are left alone: they belong to their holders, and the wire resets\n\t * whatever they still have open.\n\t *\n\t * Eviction is unconditional, which costs a dedup miss when two announcement streams watch\n\t * one path: the second stream's retraction can arrive after the first has already seen the\n\t * replacement, dropping the fresh entry so the next request subscribes again instead of\n\t * sharing. Telling that stale retraction from a live one needs a generation id on the\n\t * advertisement (moq-lite's `Epoch`, not yet on the wire), so until then this errs toward a\n\t * duplicate subscription rather than risk handing out a dead one.\n\t */\n\tevict(path: Path.Valid): void {\n\t\tthis.#cache.delete(path);\n\t}\n}\n"]}
|
package/datagram.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A datagram: a single unreliable payload on a track, parallel to groups.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { Timestamp } from "./time";
|
|
7
|
+
/**
|
|
8
|
+
* A single unreliable payload on a track: a sequence number, a presentation timestamp, and the bytes.
|
|
9
|
+
*
|
|
10
|
+
* Unlike a {@link Group} (an ordered stream of frames over a QUIC stream), a datagram is one
|
|
11
|
+
* self-contained payload carried in a single QUIC datagram: best-effort, unordered, never
|
|
12
|
+
* retransmitted. It shares the track's monotonic sequence-number namespace with groups but is
|
|
13
|
+
* otherwise independent. Mirrors the Rust `Datagram`.
|
|
14
|
+
*/
|
|
15
|
+
export interface Datagram {
|
|
16
|
+
/** Per-track sequence number, shared with the group namespace. */
|
|
17
|
+
sequence: number;
|
|
18
|
+
/** Presentation timestamp in the track's timescale. */
|
|
19
|
+
timestamp: Timestamp;
|
|
20
|
+
/** The datagram payload. */
|
|
21
|
+
payload: Uint8Array;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=datagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datagram.d.ts","sourceRoot":"","sources":["../src/datagram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACxB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,SAAS,EAAE,SAAS,CAAC;IACrB,4BAA4B;IAC5B,OAAO,EAAE,UAAU,CAAC;CACpB"}
|
package/datagram.js
ADDED
package/datagram.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datagram.js","sourceRoot":"","sources":["../src/datagram.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A datagram: a single unreliable payload on a track, parallel to groups.\n *\n * @module\n */\nimport type { Timestamp } from \"./time.ts\";\n\n/**\n * A single unreliable payload on a track: a sequence number, a presentation timestamp, and the bytes.\n *\n * Unlike a {@link Group} (an ordered stream of frames over a QUIC stream), a datagram is one\n * self-contained payload carried in a single QUIC datagram: best-effort, unordered, never\n * retransmitted. It shares the track's monotonic sequence-number namespace with groups but is\n * otherwise independent. Mirrors the Rust `Datagram`.\n */\nexport interface Datagram {\n\t/** Per-track sequence number, shared with the group namespace. */\n\tsequence: number;\n\t/** Presentation timestamp in the track's timescale. */\n\ttimestamp: Timestamp;\n\t/** The datagram payload. */\n\tpayload: Uint8Array;\n}\n"]}
|
package/error.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors, including the code a peer reports when it resets a stream.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* An error the peer reported by resetting a stream, carrying the raw code it sent.
|
|
8
|
+
*
|
|
9
|
+
* The codes are not standardized, so this deliberately does not translate one into a local
|
|
10
|
+
* error: the number means whatever the peer's implementation says it means. A read or write
|
|
11
|
+
* rejects with this on every transport, so branch on {@link code} rather than feature-detecting
|
|
12
|
+
* `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback
|
|
13
|
+
* never throws.
|
|
14
|
+
*
|
|
15
|
+
* Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* try {
|
|
19
|
+
* frame = await group.readFrame();
|
|
20
|
+
* } catch (err) {
|
|
21
|
+
* // Whatever this peer's code 2 means to it.
|
|
22
|
+
* if (err instanceof RemoteError && err.code === 2) return;
|
|
23
|
+
* throw err;
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export declare class RemoteError extends Error {
|
|
30
|
+
/** The code the peer sent, verbatim. */
|
|
31
|
+
readonly code: number;
|
|
32
|
+
constructor(code: number, options?: {
|
|
33
|
+
cause?: unknown;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A peer broke the protocol in a way the spec says must end the session.
|
|
38
|
+
*
|
|
39
|
+
* Thrown where the violation is detected, rather than handled there: a decoder has no session
|
|
40
|
+
* to close. The dispatch that owns the session watches for it and closes, so a nonconforming
|
|
41
|
+
* peer cannot repeat the violation on the next stream.
|
|
42
|
+
*
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export declare class ProtocolViolation extends Error {
|
|
46
|
+
constructor(message: string, options?: {
|
|
47
|
+
cause?: unknown;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,
|
|
52
|
+
* otherwise pass it through.
|
|
53
|
+
*
|
|
54
|
+
* Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error
|
|
55
|
+
* with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class
|
|
56
|
+
* covers both, and works in a runtime with no `WebTransportError` at all.
|
|
57
|
+
*
|
|
58
|
+
* @internal Called at the transport boundary so the raw error never reaches an application.
|
|
59
|
+
*/
|
|
60
|
+
export declare function fromTransport(err: unknown): Error;
|
|
61
|
+
/**
|
|
62
|
+
* Coerce an unknown thrown value into an `Error`.
|
|
63
|
+
*
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
export declare function error(err: unknown): Error;
|
|
67
|
+
/**
|
|
68
|
+
* Format an error into a non-empty, human-readable string for logging.
|
|
69
|
+
*
|
|
70
|
+
* Safari always leaves `WebTransportError.message` blank, so a bare `err.message` degrades to
|
|
71
|
+
* an empty string and the reason is lost. This falls back to the error type name and appends
|
|
72
|
+
* the WebTransport `source` and application `streamErrorCode`, so the log line always says
|
|
73
|
+
* something.
|
|
74
|
+
*/
|
|
75
|
+
export declare function reason(err: unknown): string;
|
|
76
|
+
//# sourceMappingURL=error.d.ts.map
|
package/error.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACrC,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAItD;CACD;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;CACD;AAcD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAIjD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAEzC;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAa3C"}
|
package/error.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* @ts-self-types="./error.d.ts" */
|
|
2
|
+
/**
|
|
3
|
+
* Errors, including the code a peer reports when it resets a stream.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* An error the peer reported by resetting a stream, carrying the raw code it sent.
|
|
9
|
+
*
|
|
10
|
+
* The codes are not standardized, so this deliberately does not translate one into a local
|
|
11
|
+
* error: the number means whatever the peer's implementation says it means. A read or write
|
|
12
|
+
* rejects with this on every transport, so branch on {@link code} rather than feature-detecting
|
|
13
|
+
* `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback
|
|
14
|
+
* never throws.
|
|
15
|
+
*
|
|
16
|
+
* Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* try {
|
|
20
|
+
* frame = await group.readFrame();
|
|
21
|
+
* } catch (err) {
|
|
22
|
+
* // Whatever this peer's code 2 means to it.
|
|
23
|
+
* if (err instanceof RemoteError && err.code === 2) return;
|
|
24
|
+
* throw err;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export class RemoteError extends Error {
|
|
31
|
+
/** The code the peer sent, verbatim. */
|
|
32
|
+
code;
|
|
33
|
+
constructor(code, options) {
|
|
34
|
+
super(`remote error: ${code}`, options);
|
|
35
|
+
this.name = "RemoteError";
|
|
36
|
+
this.code = code;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A peer broke the protocol in a way the spec says must end the session.
|
|
41
|
+
*
|
|
42
|
+
* Thrown where the violation is detected, rather than handled there: a decoder has no session
|
|
43
|
+
* to close. The dispatch that owns the session watches for it and closes, so a nonconforming
|
|
44
|
+
* peer cannot repeat the violation on the next stream.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export class ProtocolViolation extends Error {
|
|
49
|
+
constructor(message, options) {
|
|
50
|
+
super(message, options);
|
|
51
|
+
this.name = "ProtocolViolation";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function streamCode(err) {
|
|
55
|
+
if (typeof err !== "object" || err === null)
|
|
56
|
+
return undefined;
|
|
57
|
+
const { source, streamErrorCode } = err;
|
|
58
|
+
if (source !== "stream" || typeof streamErrorCode !== "number")
|
|
59
|
+
return undefined;
|
|
60
|
+
return streamErrorCode;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,
|
|
64
|
+
* otherwise pass it through.
|
|
65
|
+
*
|
|
66
|
+
* Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error
|
|
67
|
+
* with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class
|
|
68
|
+
* covers both, and works in a runtime with no `WebTransportError` at all.
|
|
69
|
+
*
|
|
70
|
+
* @internal Called at the transport boundary so the raw error never reaches an application.
|
|
71
|
+
*/
|
|
72
|
+
export function fromTransport(err) {
|
|
73
|
+
const code = streamCode(err);
|
|
74
|
+
if (code === undefined)
|
|
75
|
+
return error(err);
|
|
76
|
+
return new RemoteError(code, { cause: err });
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Coerce an unknown thrown value into an `Error`.
|
|
80
|
+
*
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export function error(err) {
|
|
84
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Format an error into a non-empty, human-readable string for logging.
|
|
88
|
+
*
|
|
89
|
+
* Safari always leaves `WebTransportError.message` blank, so a bare `err.message` degrades to
|
|
90
|
+
* an empty string and the reason is lost. This falls back to the error type name and appends
|
|
91
|
+
* the WebTransport `source` and application `streamErrorCode`, so the log line always says
|
|
92
|
+
* something.
|
|
93
|
+
*/
|
|
94
|
+
export function reason(err) {
|
|
95
|
+
const e = error(err);
|
|
96
|
+
// WebTransportError carries the failure origin and the peer's application error code,
|
|
97
|
+
// often the only identifying detail since WebKit leaves `message` empty.
|
|
98
|
+
if (typeof WebTransportError !== "undefined" && e instanceof WebTransportError) {
|
|
99
|
+
const parts = [`source=${e.source}`];
|
|
100
|
+
if (e.streamErrorCode !== null)
|
|
101
|
+
parts.push(`code=${e.streamErrorCode}`);
|
|
102
|
+
const detail = parts.join(" ");
|
|
103
|
+
return e.message ? `${e.message} (${detail})` : `WebTransportError: ${detail}`;
|
|
104
|
+
}
|
|
105
|
+
return e.message || e.name || "unknown error";
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=error.js.map
|
package/error.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACrC,wCAAwC;IAC/B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAA6B;QACtD,KAAK,CAAC,iBAAiB,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;CACD;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC3C,YAAY,OAAe,EAAE,OAA6B;QACzD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD;AAKD,SAAS,UAAU,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAE9D,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,GAAsB,CAAC;IAC3D,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,eAAe,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEjF,OAAO,eAAe,CAAC;AACxB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACzC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY;IACjC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAC,GAAY;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAErB,sFAAsF;IACtF,yEAAyE;IACzE,IAAI,OAAO,iBAAiB,KAAK,WAAW,IAAI,CAAC,YAAY,iBAAiB,EAAE,CAAC;QAChF,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC,eAAe,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,sBAAsB,MAAM,EAAE,CAAC;IAChF,CAAC;IAED,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;AAC/C,CAAC","sourcesContent":["/**\n * Errors, including the code a peer reports when it resets a stream.\n *\n * @module\n */\n\n/**\n * An error the peer reported by resetting a stream, carrying the raw code it sent.\n *\n * The codes are not standardized, so this deliberately does not translate one into a local\n * error: the number means whatever the peer's implementation says it means. A read or write\n * rejects with this on every transport, so branch on {@link code} rather than feature-detecting\n * `WebTransportError`, which a non-browser runtime never defines and the WebSocket fallback\n * never throws.\n *\n * Code 0 is what a transport sends when a stream is dropped or aborted with no code of its own.\n *\n * ```ts\n * try {\n * frame = await group.readFrame();\n * } catch (err) {\n * // Whatever this peer's code 2 means to it.\n * if (err instanceof RemoteError && err.code === 2) return;\n * throw err;\n * }\n * ```\n *\n * @public\n */\nexport class RemoteError extends Error {\n\t/** The code the peer sent, verbatim. */\n\treadonly code: number;\n\n\tconstructor(code: number, options?: { cause?: unknown }) {\n\t\tsuper(`remote error: ${code}`, options);\n\t\tthis.name = \"RemoteError\";\n\t\tthis.code = code;\n\t}\n}\n\n/**\n * A peer broke the protocol in a way the spec says must end the session.\n *\n * Thrown where the violation is detected, rather than handled there: a decoder has no session\n * to close. The dispatch that owns the session watches for it and closes, so a nonconforming\n * peer cannot repeat the violation on the next stream.\n *\n * @internal\n */\nexport class ProtocolViolation extends Error {\n\tconstructor(message: string, options?: { cause?: unknown }) {\n\t\tsuper(message, options);\n\t\tthis.name = \"ProtocolViolation\";\n\t}\n}\n\n/** The WebTransport-shaped fields a stream reset code arrives in. */\ntype StreamErrorLike = { source?: unknown; streamErrorCode?: unknown };\n\nfunction streamCode(err: unknown): number | undefined {\n\tif (typeof err !== \"object\" || err === null) return undefined;\n\n\tconst { source, streamErrorCode } = err as StreamErrorLike;\n\tif (source !== \"stream\" || typeof streamErrorCode !== \"number\") return undefined;\n\n\treturn streamErrorCode;\n}\n\n/**\n * Decode a transport failure into a {@link RemoteError} error when it carries a stream reset code,\n * otherwise pass it through.\n *\n * Native WebTransport rejects with a `WebTransportError`; the WebSocket fallback mints an error\n * with the same `source`/`streamErrorCode` fields. Reading the fields rather than the class\n * covers both, and works in a runtime with no `WebTransportError` at all.\n *\n * @internal Called at the transport boundary so the raw error never reaches an application.\n */\nexport function fromTransport(err: unknown): Error {\n\tconst code = streamCode(err);\n\tif (code === undefined) return error(err);\n\treturn new RemoteError(code, { cause: err });\n}\n\n/**\n * Coerce an unknown thrown value into an `Error`.\n *\n * @internal\n */\nexport function error(err: unknown): Error {\n\treturn err instanceof Error ? err : new Error(String(err));\n}\n\n/**\n * Format an error into a non-empty, human-readable string for logging.\n *\n * Safari always leaves `WebTransportError.message` blank, so a bare `err.message` degrades to\n * an empty string and the reason is lost. This falls back to the error type name and appends\n * the WebTransport `source` and application `streamErrorCode`, so the log line always says\n * something.\n */\nexport function reason(err: unknown): string {\n\tconst e = error(err);\n\n\t// WebTransportError carries the failure origin and the peer's application error code,\n\t// often the only identifying detail since WebKit leaves `message` empty.\n\tif (typeof WebTransportError !== \"undefined\" && e instanceof WebTransportError) {\n\t\tconst parts = [`source=${e.source}`];\n\t\tif (e.streamErrorCode !== null) parts.push(`code=${e.streamErrorCode}`);\n\t\tconst detail = parts.join(\" \");\n\t\treturn e.message ? `${e.message} (${detail})` : `WebTransportError: ${detail}`;\n\t}\n\n\treturn e.message || e.name || \"unknown error\";\n}\n"]}
|
package/group.d.ts
CHANGED
|
@@ -1,66 +1,171 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Group role handles: an ordered stream of frames within a track, delivered over one QUIC stream.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { type GetPromise, type Getter } from "@norskvideo/moq-signals";
|
|
7
|
+
import { Timestamp } from "./time";
|
|
8
|
+
/** Maximum bytes of frames cached in a group before old frames are evicted from the front. */
|
|
9
|
+
export declare const MAX_GROUP_CACHE_BYTES: number;
|
|
10
|
+
/** Maximum number of frames cached in a group before old frames are evicted from the front. */
|
|
11
|
+
export declare const MAX_GROUP_FRAMES = 1024;
|
|
12
|
+
/**
|
|
13
|
+
* A frame buffered in a group: its presentation {@link Timestamp} and payload bytes.
|
|
14
|
+
*
|
|
15
|
+
* The timestamp carries its own scale, so a track can pick its units; the wire layer
|
|
16
|
+
* converts it into the track's negotiated timescale.
|
|
17
|
+
*/
|
|
18
|
+
export interface Frame {
|
|
19
|
+
/** The frame payload. */
|
|
20
|
+
payload: Uint8Array;
|
|
21
|
+
/**
|
|
22
|
+
* Presentation timestamp. Required: for a payload with no presentation time of its own
|
|
23
|
+
* (a JSON catalog, control state) pass {@link Timestamp.now} explicitly.
|
|
24
|
+
*/
|
|
25
|
+
timestamp: Timestamp;
|
|
26
|
+
}
|
|
27
|
+
/** Options for a sequence-aware frame read. */
|
|
28
|
+
export interface ReadOptions {
|
|
29
|
+
/**
|
|
30
|
+
* The lowest sequence number the caller wants; defaults to the whole group.
|
|
31
|
+
*
|
|
32
|
+
* Frames below it are discarded instead of returned, and frames evicted below it are not
|
|
33
|
+
* a gap: the read resumes at the next retained frame rather than throwing {@link Lagged}.
|
|
34
|
+
* An eviction at or above it still throws, because the caller asked for that frame.
|
|
35
|
+
*/
|
|
36
|
+
from?: number;
|
|
37
|
+
}
|
|
38
|
+
/** Immutable group metadata. */
|
|
39
|
+
export interface Info {
|
|
40
|
+
/** Sequence number of this group within its track. */
|
|
41
|
+
sequence: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Thrown by a frame read when the reader fell behind the group's eviction window: frames
|
|
45
|
+
* it had not yet read were dropped to stay under the cache cap, so the stream has a gap.
|
|
46
|
+
*/
|
|
47
|
+
export declare class Lagged extends Error {
|
|
48
|
+
constructor();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The write side of an ordered stream of frames within a track.
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
export declare class Producer {
|
|
3
56
|
#private;
|
|
4
57
|
/** Sequence number of this group within its track. */
|
|
5
58
|
readonly sequence: number;
|
|
6
|
-
/** Resolves with the abort error (or undefined) once closed. */
|
|
7
|
-
readonly closed: Promise<Error | undefined>;
|
|
8
59
|
constructor(sequence: number);
|
|
9
60
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
61
|
+
* Settles once the group closes: `null` on a clean close, or the abort {@link Error}.
|
|
62
|
+
* Peek it synchronously (`undefined` while open), observe it reactively, or `await` it.
|
|
63
|
+
*/
|
|
64
|
+
get closed(): GetPromise<Error | null>;
|
|
65
|
+
/** A read handle for this group. */
|
|
66
|
+
consume(): Consumer;
|
|
67
|
+
/**
|
|
68
|
+
* Create an independent read handle that receives every frame written here.
|
|
69
|
+
*
|
|
70
|
+
* Frames written so far are replayed synchronously; later writes and close are teed
|
|
71
|
+
* in as they happen.
|
|
72
|
+
*
|
|
73
|
+
* @internal Track fan-out and fetch coalescing only. Use {@link consume} instead.
|
|
74
|
+
*/
|
|
75
|
+
mirror(): Consumer;
|
|
76
|
+
/**
|
|
77
|
+
* Whether any mirror reader is currently attached.
|
|
78
|
+
*
|
|
79
|
+
* Pairs with {@link unused}. Fetch coalescing watches it to cancel a download once every reader
|
|
80
|
+
* has gone: a group can stay open indefinitely (a catalog track, a JSON stream), so it can't
|
|
81
|
+
* rely on the stream ending on its own.
|
|
82
|
+
*
|
|
83
|
+
* @internal Track fan-out and fetch coalescing only.
|
|
84
|
+
*/
|
|
85
|
+
get used(): Getter<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* Resolves once no mirror reader remains (or the group closes).
|
|
88
|
+
*
|
|
89
|
+
* @internal Track fan-out and fetch coalescing only.
|
|
12
90
|
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
91
|
+
unused(): Promise<void>;
|
|
92
|
+
/** Writes a frame to the group. */
|
|
93
|
+
writeFrame(frame: Frame): void;
|
|
94
|
+
/** Write a string as a single UTF-8 encoded frame, stamped with {@link Timestamp.now}. */
|
|
15
95
|
writeString(str: string): void;
|
|
16
|
-
/** Write a value as a single JSON-encoded frame. */
|
|
96
|
+
/** Write a value as a single JSON-encoded frame, stamped with {@link Timestamp.now}. */
|
|
17
97
|
writeJson(json: unknown): void;
|
|
18
|
-
/** Write a boolean as a single one-byte frame. */
|
|
98
|
+
/** Write a boolean as a single one-byte frame, stamped with {@link Timestamp.now}. */
|
|
19
99
|
writeBool(bool: boolean): void;
|
|
100
|
+
/** True once the group has been closed. */
|
|
101
|
+
get isClosed(): boolean;
|
|
102
|
+
/** Closes the group, optionally with an error to abort readers. */
|
|
103
|
+
close(abort?: Error): void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The read side of an ordered stream of frames within a track.
|
|
107
|
+
*
|
|
108
|
+
* Created internally: obtain one from {@link Producer.consume} or a track subscriber's
|
|
109
|
+
* group reads.
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
export declare class Consumer {
|
|
114
|
+
#private;
|
|
115
|
+
/** Sequence number of this group within its track. */
|
|
116
|
+
readonly sequence: number;
|
|
117
|
+
private constructor();
|
|
118
|
+
/**
|
|
119
|
+
* Settles once the group closes: `null` on a clean close, or the abort {@link Error}.
|
|
120
|
+
* Peek it synchronously (`undefined` while open), observe it reactively, or `await` it.
|
|
121
|
+
*/
|
|
122
|
+
get closed(): GetPromise<Error | null>;
|
|
20
123
|
/** True once no further frames can be read: the group has closed and every buffered frame is read. */
|
|
21
124
|
get done(): boolean;
|
|
125
|
+
/** True once the group has been closed, regardless of whether buffered frames remain unread. Synchronous complement to the {@link closed} promise. */
|
|
126
|
+
get isClosed(): boolean;
|
|
127
|
+
/** True if frames were evicted from the front of this group before being read. */
|
|
128
|
+
get skipped(): boolean;
|
|
22
129
|
/**
|
|
23
|
-
*
|
|
130
|
+
* How many frames the group has held, including any already read or evicted.
|
|
24
131
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* Drain a backlog by looping until this returns `undefined`, then branch on {@link done}: if not
|
|
28
|
-
* done, {@link readable} resolves when the next frame arrives.
|
|
132
|
+
* It is also the next frame's sequence number, so `frameCount - 1` names the newest
|
|
133
|
+
* frame written so far. A publisher snapshots it to resolve the track's live edge.
|
|
29
134
|
*/
|
|
30
|
-
|
|
31
|
-
/** Like {@link tryReadFrame} but also reports the frame's sequence number within the group. */
|
|
32
|
-
tryReadFrameSequence(): {
|
|
33
|
-
sequence: number;
|
|
34
|
-
data: Uint8Array;
|
|
35
|
-
extensions?: Uint8Array;
|
|
36
|
-
} | undefined;
|
|
135
|
+
get frameCount(): number;
|
|
37
136
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* {@link done} to avoid re-waiting on a group that has nothing left.
|
|
137
|
+
* Reads the next already-buffered frame without blocking.
|
|
138
|
+
* Treat the returned frame bytes as read-only; they are shared with other consumers.
|
|
41
139
|
*
|
|
42
|
-
*
|
|
43
|
-
* group
|
|
140
|
+
* Returns `undefined` when nothing is buffered right now. That is not by itself
|
|
141
|
+
* end-of-group: check {@link done} to tell "no frame buffered yet" from "finished".
|
|
44
142
|
*/
|
|
143
|
+
tryReadFrame(): Frame | undefined;
|
|
144
|
+
/** Like {@link tryReadFrame} but also reports the frame's sequence number within the group. */
|
|
145
|
+
tryReadFrameSequence(): ({
|
|
146
|
+
sequence: number;
|
|
147
|
+
} & Frame) | undefined;
|
|
148
|
+
/** Resolves once {@link readFrame} would not block. */
|
|
45
149
|
readable(): Promise<void>;
|
|
46
150
|
/**
|
|
47
151
|
* Reads the next frame from the group.
|
|
48
|
-
*
|
|
152
|
+
* Treat the returned frame bytes as read-only; they are shared with other consumers.
|
|
153
|
+
*/
|
|
154
|
+
readFrame(): Promise<Frame | undefined>;
|
|
155
|
+
/**
|
|
156
|
+
* Reads the next frame along with its sequence number within the group.
|
|
157
|
+
* Treat the returned frame bytes as read-only; they are shared with other consumers.
|
|
49
158
|
*/
|
|
50
|
-
|
|
51
|
-
/** Reads the next frame along with its sequence number within the group. */
|
|
52
|
-
readFrameSequence(): Promise<{
|
|
159
|
+
readFrameSequence(options?: ReadOptions): Promise<({
|
|
53
160
|
sequence: number;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
} | undefined>;
|
|
57
|
-
/** Reads the next frame and decodes it as a UTF-8 string. */
|
|
161
|
+
} & Frame) | undefined>;
|
|
162
|
+
/** Reads the next frame and decodes its payload as a UTF-8 string. */
|
|
58
163
|
readString(): Promise<string | undefined>;
|
|
59
|
-
/** Reads the next frame and parses
|
|
164
|
+
/** Reads the next frame and parses its payload as JSON. */
|
|
60
165
|
readJson(): Promise<unknown | undefined>;
|
|
61
|
-
/** Reads the next frame and decodes
|
|
166
|
+
/** Reads the next frame and decodes its payload as a one-byte boolean. */
|
|
62
167
|
readBool(): Promise<boolean | undefined>;
|
|
63
|
-
/** Closes the group, optionally with an error to abort readers. */
|
|
168
|
+
/** Closes the group, optionally with an error to abort readers. Idempotent. */
|
|
64
169
|
close(abort?: Error): void;
|
|
65
170
|
}
|
|
66
171
|
//# sourceMappingURL=group.d.ts.map
|
package/group.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,MAAM,EAAgB,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,8FAA8F;AAC9F,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAEtD,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACrB,yBAAyB;IACzB,OAAO,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,SAAS,EAAE,SAAS,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gCAAgC;AAChC,MAAM,WAAW,IAAI;IACpB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,qBAAa,MAAO,SAAQ,KAAK;IAChC,cAGC;CACD;AA6CD;;;;GAIG;AACH,qBAAa,QAAQ;;IACpB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAU1B,YAAY,QAAQ,EAAE,MAAM,EAG3B;IAED;;;OAGG;IACH,IAAI,MAAM,IAAI,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,CAErC;IAED,oCAAoC;IACpC,OAAO,IAAI,QAAQ,CAElB;IAED;;;;;;;OAOG;IACH,MAAM,IAAI,QAAQ,CA8BjB;IAED;;;;;;;;OAQG;IACH,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,CAE1B;IAED;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAI5B;IAED,mCAAmC;IACnC,UAAU,CAAC,KAAK,EAAE,KAAK,QAStB;IAED,0FAA0F;IAC1F,WAAW,CAAC,GAAG,EAAE,MAAM,QAEtB;IAED,wFAAwF;IACxF,SAAS,CAAC,IAAI,EAAE,OAAO,QAEtB;IAED,sFAAsF;IACtF,SAAS,CAAC,IAAI,EAAE,OAAO,QAEtB;IAED,2CAA2C;IAC3C,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,mEAAmE;IACnE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,QAUlB;CACD;AAID;;;;;;;GAOG;AACH,qBAAa,QAAQ;;IACpB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAI1B,OAAO,eAGN;IAED;;;OAGG;IACH,IAAI,MAAM,IAAI,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,CAErC;IAeD,sGAAsG;IACtG,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,sJAAsJ;IACtJ,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,kFAAkF;IAClF,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;OAKG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;;;OAMG;IACH,YAAY,IAAI,KAAK,GAAG,SAAS,CAGhC;IAED,+FAA+F;IAC/F,oBAAoB,IAAI,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC,GAAG,SAAS,CAIjE;IAED,uDAAuD;IACjD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9B;IAED;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAa5C;IAED;;;OAGG;IACG,iBAAiB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC,CAkBlG;IAED,sEAAsE;IAChE,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAG9C;IAED,2DAA2D;IACrD,QAAQ,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAG7C;IAED,0EAA0E;IACpE,QAAQ,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAG7C;IAED,+EAA+E;IAC/E,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,QAGlB;CACD"}
|