@norskvideo/moq-json 0.1.2 → 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.
Files changed (93) hide show
  1. package/index.d.ts +13 -3
  2. package/index.d.ts.map +1 -1
  3. package/index.js +14 -3
  4. package/index.js.map +1 -1
  5. package/package.json +6 -5
  6. package/snapshot/consumer.d.ts +7 -5
  7. package/snapshot/consumer.d.ts.map +1 -1
  8. package/snapshot/consumer.js +31 -35
  9. package/snapshot/consumer.js.map +1 -1
  10. package/snapshot/decoder.d.ts +46 -0
  11. package/snapshot/decoder.d.ts.map +1 -0
  12. package/snapshot/decoder.js +76 -0
  13. package/snapshot/decoder.js.map +1 -0
  14. package/snapshot/encoder.d.ts +96 -0
  15. package/snapshot/encoder.d.ts.map +1 -0
  16. package/snapshot/encoder.js +196 -0
  17. package/snapshot/encoder.js.map +1 -0
  18. package/snapshot/index.d.ts +14 -1
  19. package/snapshot/index.d.ts.map +1 -1
  20. package/snapshot/index.js +13 -0
  21. package/snapshot/index.js.map +1 -1
  22. package/snapshot/producer.d.ts +22 -39
  23. package/snapshot/producer.d.ts.map +1 -1
  24. package/snapshot/producer.js +69 -185
  25. package/snapshot/producer.js.map +1 -1
  26. package/stream/consumer.d.ts +17 -0
  27. package/stream/consumer.d.ts.map +1 -0
  28. package/stream/consumer.js +46 -0
  29. package/stream/consumer.js.map +1 -0
  30. package/stream/decoder.d.ts +21 -0
  31. package/stream/decoder.d.ts.map +1 -0
  32. package/stream/decoder.js +28 -0
  33. package/stream/decoder.js.map +1 -0
  34. package/stream/encoder.d.ts +62 -0
  35. package/stream/encoder.d.ts.map +1 -0
  36. package/stream/encoder.js +78 -0
  37. package/stream/encoder.js.map +1 -0
  38. package/stream/index.d.ts +23 -0
  39. package/stream/index.d.ts.map +1 -0
  40. package/stream/index.js +24 -0
  41. package/stream/index.js.map +1 -0
  42. package/stream/producer.d.ts +18 -0
  43. package/stream/producer.d.ts.map +1 -0
  44. package/stream/producer.js +49 -0
  45. package/stream/producer.js.map +1 -0
  46. package/window/consumer.d.ts +26 -0
  47. package/window/consumer.d.ts.map +1 -0
  48. package/window/consumer.js +74 -0
  49. package/window/consumer.js.map +1 -0
  50. package/window/decoder.d.ts +57 -0
  51. package/window/decoder.d.ts.map +1 -0
  52. package/window/decoder.js +169 -0
  53. package/window/decoder.js.map +1 -0
  54. package/window/encoder.d.ts +72 -0
  55. package/window/encoder.d.ts.map +1 -0
  56. package/window/encoder.js +183 -0
  57. package/window/encoder.js.map +1 -0
  58. package/window/index.d.ts +39 -0
  59. package/window/index.d.ts.map +1 -0
  60. package/window/index.js +40 -0
  61. package/window/index.js.map +1 -0
  62. package/window/producer.d.ts +32 -0
  63. package/window/producer.d.ts.map +1 -0
  64. package/window/producer.js +90 -0
  65. package/window/producer.js.map +1 -0
  66. package/diff.test.d.ts +0 -2
  67. package/diff.test.d.ts.map +0 -1
  68. package/diff.test.js +0 -60
  69. package/diff.test.js.map +0 -1
  70. package/snapshot/compression.test.d.ts +0 -2
  71. package/snapshot/compression.test.d.ts.map +0 -1
  72. package/snapshot/compression.test.js +0 -132
  73. package/snapshot/compression.test.js.map +0 -1
  74. package/snapshot/producer.test.d.ts +0 -2
  75. package/snapshot/producer.test.d.ts.map +0 -1
  76. package/snapshot/producer.test.js +0 -75
  77. package/snapshot/producer.test.js.map +0 -1
  78. package/snapshot/snapshot.test.d.ts +0 -2
  79. package/snapshot/snapshot.test.d.ts.map +0 -1
  80. package/snapshot/snapshot.test.js +0 -185
  81. package/snapshot/snapshot.test.js.map +0 -1
  82. package/stream.d.ts +0 -54
  83. package/stream.d.ts.map +0 -1
  84. package/stream.js +0 -92
  85. package/stream.js.map +0 -1
  86. package/stream.test.d.ts +0 -2
  87. package/stream.test.d.ts.map +0 -1
  88. package/stream.test.js +0 -64
  89. package/stream.test.js.map +0 -1
  90. package/vectors.test.d.ts +0 -2
  91. package/vectors.test.d.ts.map +0 -1
  92. package/vectors.test.js +0 -18
  93. package/vectors.test.js.map +0 -1
package/stream.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lossless append-log JSON publishing over MoQ tracks: the counterpart to the lossy `Snapshot`\n * module. Instead of one value updated over time, a stream is an ordered log of self-contained\n * records that preserves everything; every {@link Producer.append} writes one JSON object as one\n * frame, nothing is ever superseded, and a {@link Consumer} yields every record in order.\n *\n * The whole log rides a **single group** that is never rolled: with {@link ProducerConfig.compression}\n * on, that one group is one DEFLATE window, so every record compresses against the earlier ones.\n * There is deliberately no group rolling (and so no catch-up machinery); a caller that wants to\n * bound the record rate throttles at the source. Interoperable on the wire with the Rust\n * `moq_json::stream`.\n *\n * @module\n */\n\nimport { Decoder, Encoder } from \"@moq/flate\";\nimport type * as Moq from \"@moq/net\";\n\n/** Options for a stream {@link Producer}. */\nexport interface ProducerConfig {\n\t/**\n\t * Compress the group as one sync-flushed `deflate-raw` stream, so each record reuses the earlier\n\t * ones as context and shrinks sharply. A {@link Consumer} reading the track must set the same\n\t * flag. Defaults to `false`.\n\t */\n\tcompression?: boolean;\n}\n\n/** Options for a stream {@link Consumer}. */\nexport interface ConsumerConfig {\n\t/** Whether the track's frames are `deflate-raw` compressed. Must match the producer. Defaults to `false`. */\n\tcompression?: boolean;\n}\n\n/**\n * Publishes an ordered log of JSON records to a track, one record per frame in a single group.\n */\nexport class Producer<T> {\n\t#track: Moq.Track;\n\t#compress: boolean;\n\n\t// The single group carrying the whole log, opened on the first append.\n\t#group?: Moq.Group;\n\t// The group's DEFLATE encoder (one window for the whole log), present while compressing.\n\t#encoder?: Encoder;\n\n\t/** Wrap a track to publish a record log into it. */\n\tconstructor(track: Moq.Track, config: ProducerConfig = {}) {\n\t\tthis.#track = track;\n\t\tthis.#compress = config.compression ?? false;\n\t}\n\n\t/** Append one record to the log. */\n\tappend(value: T): void {\n\t\tconst payload = new TextEncoder().encode(JSON.stringify(value));\n\n\t\tif (!this.#group) {\n\t\t\tthis.#group = this.#track.appendGroup();\n\t\t\tthis.#encoder = this.#compress ? new Encoder() : undefined;\n\t\t}\n\n\t\tthis.#group.writeFrame(this.#encoder ? this.#encoder.frame(payload) : payload);\n\t}\n\n\t/** Finish the track, closing the group. */\n\tfinish(): void {\n\t\tthis.#group?.close();\n\t\tthis.#group = undefined;\n\t\tthis.#track.close();\n\t}\n}\n\n/**\n * Consumes an ordered log of JSON records from a track, yielding every record in order.\n *\n * The log rides a single group, so this reads that group's frames in order; one record per frame.\n */\nexport class Consumer<T> {\n\t#track: Moq.Track;\n\t#decompress: boolean;\n\n\t#group?: Moq.Group;\n\t// The group's DEFLATE decoder (one window for the whole log), built on the first frame.\n\t#decoder?: Decoder;\n\n\tconstructor(track: Moq.Track, config: ConsumerConfig = {}) {\n\t\tthis.#track = track;\n\t\tthis.#decompress = config.compression ?? false;\n\t}\n\n\t/** Get the next record, or `undefined` once the track ends. */\n\tasync next(): Promise<T | undefined> {\n\t\tfor (;;) {\n\t\t\tif (!this.#group) {\n\t\t\t\tthis.#group = await this.#track.nextGroupOrdered();\n\t\t\t\tif (!this.#group) return undefined;\n\t\t\t\tthis.#decoder = this.#decompress ? new Decoder() : undefined;\n\t\t\t}\n\n\t\t\tconst frame = await this.#group.readFrame();\n\t\t\tif (frame === undefined) {\n\t\t\t\t// The group is finished; the log rides just this one, so the stream ends.\n\t\t\t\tthis.#group = undefined;\n\t\t\t\tthis.#decoder = undefined;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst plain = this.#decoder ? this.#decoder.frame(frame) : frame;\n\t\t\treturn JSON.parse(new TextDecoder().decode(plain));\n\t\t}\n\t}\n\n\tasync *[Symbol.asyncIterator](): AsyncIterator<T> {\n\t\tfor (;;) {\n\t\t\tconst value = await this.next();\n\t\t\tif (value === undefined) return;\n\t\t\tyield value;\n\t\t}\n\t}\n}\n"]}
package/stream.test.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=stream.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stream.test.d.ts","sourceRoot":"","sources":["../src/stream.test.ts"],"names":[],"mappings":""}
package/stream.test.js DELETED
@@ -1,64 +0,0 @@
1
- /* @ts-self-types="./stream.test.d.ts" */
2
- import { expect, test } from "bun:test";
3
- import { Track } from "@norskvideo/moq-net";
4
- import { Consumer, Producer } from "./stream.js";
5
- // Drain every record currently available from a fresh consumer over the (finished) track.
6
- async function drain(track, compression) {
7
- const consumer = new Consumer(track, { compression });
8
- const out = [];
9
- for (;;) {
10
- const record = await consumer.next();
11
- if (record === undefined)
12
- break;
13
- out.push(record.n);
14
- }
15
- return out;
16
- }
17
- test("plaintext roundtrip in order", async () => {
18
- const track = new Track("test");
19
- const producer = new Producer(track);
20
- for (let n = 0; n < 5; n++)
21
- producer.append({ n });
22
- producer.finish();
23
- expect(await drain(track, false)).toEqual([0, 1, 2, 3, 4]);
24
- });
25
- test("compressed roundtrip in order", async () => {
26
- const track = new Track("test");
27
- const producer = new Producer(track, { compression: true });
28
- for (let n = 0; n < 20; n++)
29
- producer.append({ n });
30
- producer.finish();
31
- expect(await drain(track, true)).toEqual(Array.from({ length: 20 }, (_, n) => n));
32
- });
33
- test("the whole log rides one group, never rolled", async () => {
34
- const track = new Track("test");
35
- const producer = new Producer(track, { compression: true });
36
- for (let n = 0; n < 50; n++)
37
- producer.append({ n });
38
- producer.finish();
39
- // A single group holds everything, and the consumer reads it all in order.
40
- const group0 = await track.nextGroupOrdered();
41
- expect(group0?.sequence).toBe(0);
42
- const group1 = await track.nextGroupOrdered();
43
- expect(group1).toBeUndefined();
44
- });
45
- test("records with embedded newlines round-trip (JSON escapes the newline)", async () => {
46
- // Each record is its own frame (one JSON object), and JSON.stringify escapes control characters,
47
- // so a string value containing a newline round-trips cleanly.
48
- const track = new Track("test");
49
- const producer = new Producer(track, { compression: true });
50
- const value = { s: "line1\nline2\ttab" };
51
- for (let i = 0; i < 4; i++)
52
- producer.append(value);
53
- producer.finish();
54
- const consumer = new Consumer(track, { compression: true });
55
- const out = [];
56
- for (;;) {
57
- const record = await consumer.next();
58
- if (record === undefined)
59
- break;
60
- out.push(record);
61
- }
62
- expect(out).toEqual([value, value, value, value]);
63
- });
64
- //# sourceMappingURL=stream.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stream.test.js","sourceRoot":"","sources":["../src/stream.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, test } from \"bun:test\";\nimport { Track } from \"@moq/net\";\nimport { Consumer, Producer } from \"./stream.ts\";\n\ntype Rec = { n: number };\n\n// Drain every record currently available from a fresh consumer over the (finished) track.\nasync function drain(track: Track, compression: boolean): Promise<number[]> {\n\tconst consumer = new Consumer<Rec>(track, { compression });\n\tconst out: number[] = [];\n\tfor (;;) {\n\t\tconst record = await consumer.next();\n\t\tif (record === undefined) break;\n\t\tout.push(record.n);\n\t}\n\treturn out;\n}\n\ntest(\"plaintext roundtrip in order\", async () => {\n\tconst track = new Track(\"test\");\n\tconst producer = new Producer<Rec>(track);\n\tfor (let n = 0; n < 5; n++) producer.append({ n });\n\tproducer.finish();\n\n\texpect(await drain(track, false)).toEqual([0, 1, 2, 3, 4]);\n});\n\ntest(\"compressed roundtrip in order\", async () => {\n\tconst track = new Track(\"test\");\n\tconst producer = new Producer<Rec>(track, { compression: true });\n\tfor (let n = 0; n < 20; n++) producer.append({ n });\n\tproducer.finish();\n\n\texpect(await drain(track, true)).toEqual(Array.from({ length: 20 }, (_, n) => n));\n});\n\ntest(\"the whole log rides one group, never rolled\", async () => {\n\tconst track = new Track(\"test\");\n\tconst producer = new Producer<Rec>(track, { compression: true });\n\tfor (let n = 0; n < 50; n++) producer.append({ n });\n\tproducer.finish();\n\n\t// A single group holds everything, and the consumer reads it all in order.\n\tconst group0 = await track.nextGroupOrdered();\n\texpect(group0?.sequence).toBe(0);\n\tconst group1 = await track.nextGroupOrdered();\n\texpect(group1).toBeUndefined();\n});\n\ntest(\"records with embedded newlines round-trip (JSON escapes the newline)\", async () => {\n\t// Each record is its own frame (one JSON object), and JSON.stringify escapes control characters,\n\t// so a string value containing a newline round-trips cleanly.\n\tconst track = new Track(\"test\");\n\tconst producer = new Producer<{ s: string }>(track, { compression: true });\n\tconst value = { s: \"line1\\nline2\\ttab\" };\n\tfor (let i = 0; i < 4; i++) producer.append(value);\n\tproducer.finish();\n\n\tconst consumer = new Consumer<{ s: string }>(track, { compression: true });\n\tconst out: { s: string }[] = [];\n\tfor (;;) {\n\t\tconst record = await consumer.next();\n\t\tif (record === undefined) break;\n\t\tout.push(record);\n\t}\n\texpect(out).toEqual([value, value, value, value]);\n});\n"]}
package/vectors.test.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=vectors.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vectors.test.d.ts","sourceRoot":"","sources":["../src/vectors.test.ts"],"names":[],"mappings":""}
package/vectors.test.js DELETED
@@ -1,18 +0,0 @@
1
- /* @ts-self-types="./vectors.test.d.ts" */
2
- import { expect, test } from "bun:test";
3
- import { diff, merge } from "./diff.js";
4
- // Shared cross-impl fixture, owned by the reference Rust crate. Both suites assert the same
5
- // vectors so the two implementations agree on every snapshot/delta decision and patch shape.
6
- const url = new URL("../../../rs/moq-json/tests/vectors.json", import.meta.url);
7
- const vectors = (await Bun.file(url).json());
8
- for (const vector of vectors) {
9
- test(`vector: ${vector.name}`, () => {
10
- const result = diff(vector.old, vector.new);
11
- expect(result.forcedSnapshot).toBe(vector.forced);
12
- if (!vector.forced) {
13
- expect(result.patch).toEqual(vector.patch);
14
- expect(merge(vector.old, result.patch)).toEqual(vector.new);
15
- }
16
- });
17
- }
18
- //# sourceMappingURL=vectors.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vectors.test.js","sourceRoot":"","sources":["../src/vectors.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAExC,4FAA4F;AAC5F,6FAA6F;AAC7F,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,yCAAyC,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAChF,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAMzC,CAAC;AAEH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;IAC9B,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAElD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAe,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAa,CAAC,CAAC;QACvE,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { expect, test } from \"bun:test\";\nimport { diff, merge } from \"./diff.ts\";\n\n// Shared cross-impl fixture, owned by the reference Rust crate. Both suites assert the same\n// vectors so the two implementations agree on every snapshot/delta decision and patch shape.\nconst url = new URL(\"../../../rs/moq-json/tests/vectors.json\", import.meta.url);\nconst vectors = (await Bun.file(url).json()) as Array<{\n\tname: string;\n\told: unknown;\n\tnew: unknown;\n\tforced: boolean;\n\tpatch?: unknown;\n}>;\n\nfor (const vector of vectors) {\n\ttest(`vector: ${vector.name}`, () => {\n\t\tconst result = diff(vector.old, vector.new);\n\t\texpect(result.forcedSnapshot).toBe(vector.forced);\n\n\t\tif (!vector.forced) {\n\t\t\texpect(result.patch).toEqual(vector.patch as object);\n\t\t\texpect(merge(vector.old, result.patch)).toEqual(vector.new as object);\n\t\t}\n\t});\n}\n"]}