@s2-dev/streamstore 0.16.11 → 0.17.0

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 (123) hide show
  1. package/dist/cjs/basin.d.ts +9 -2
  2. package/dist/cjs/basin.d.ts.map +1 -1
  3. package/dist/cjs/basin.js +14 -5
  4. package/dist/cjs/basin.js.map +1 -1
  5. package/dist/cjs/batch-transform.d.ts +64 -0
  6. package/dist/cjs/batch-transform.d.ts.map +1 -0
  7. package/dist/cjs/batch-transform.js +144 -0
  8. package/dist/cjs/batch-transform.js.map +1 -0
  9. package/dist/cjs/generated/client/utils.gen.d.ts +1 -1
  10. package/dist/cjs/generated/client/utils.gen.d.ts.map +1 -1
  11. package/dist/cjs/generated/client/utils.gen.js +7 -6
  12. package/dist/cjs/generated/client/utils.gen.js.map +1 -1
  13. package/dist/cjs/generated/core/bodySerializer.gen.d.ts +12 -4
  14. package/dist/cjs/generated/core/bodySerializer.gen.d.ts.map +1 -1
  15. package/dist/cjs/generated/core/bodySerializer.gen.js.map +1 -1
  16. package/dist/cjs/generated/proto/s2.d.ts.map +1 -1
  17. package/dist/cjs/generated/proto/s2.js.map +1 -1
  18. package/dist/cjs/index.d.ts +4 -2
  19. package/dist/cjs/index.d.ts.map +1 -1
  20. package/dist/cjs/index.js +5 -1
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/cjs/lib/stream/factory.d.ts +15 -0
  23. package/dist/cjs/lib/stream/factory.d.ts.map +1 -0
  24. package/dist/cjs/lib/stream/factory.js +36 -0
  25. package/dist/cjs/lib/stream/factory.js.map +1 -0
  26. package/dist/cjs/lib/stream/runtime.d.ts +13 -0
  27. package/dist/cjs/lib/stream/runtime.d.ts.map +1 -0
  28. package/dist/cjs/lib/stream/runtime.js +50 -0
  29. package/dist/cjs/lib/stream/runtime.js.map +1 -0
  30. package/dist/cjs/lib/stream/transport/fetch/index.d.ts +79 -0
  31. package/dist/cjs/lib/stream/transport/fetch/index.d.ts.map +1 -0
  32. package/dist/cjs/lib/stream/transport/fetch/index.js +382 -0
  33. package/dist/cjs/lib/stream/transport/fetch/index.js.map +1 -0
  34. package/dist/cjs/lib/stream/transport/fetch/shared.d.ts +7 -0
  35. package/dist/cjs/lib/stream/transport/fetch/shared.d.ts.map +1 -0
  36. package/dist/cjs/lib/stream/transport/fetch/shared.js +170 -0
  37. package/dist/cjs/lib/stream/transport/fetch/shared.js.map +1 -0
  38. package/dist/cjs/lib/stream/transport/s2s/framing.d.ts +47 -0
  39. package/dist/cjs/lib/stream/transport/s2s/framing.d.ts.map +1 -0
  40. package/dist/cjs/lib/stream/transport/s2s/framing.js +123 -0
  41. package/dist/cjs/lib/stream/transport/s2s/framing.js.map +1 -0
  42. package/dist/cjs/lib/stream/transport/s2s/index.d.ts +23 -0
  43. package/dist/cjs/lib/stream/transport/s2s/index.d.ts.map +1 -0
  44. package/dist/cjs/lib/stream/transport/s2s/index.js +785 -0
  45. package/dist/cjs/lib/stream/transport/s2s/index.js.map +1 -0
  46. package/dist/cjs/lib/stream/types.d.ts +53 -0
  47. package/dist/cjs/lib/stream/types.d.ts.map +1 -0
  48. package/dist/cjs/lib/stream/types.js +3 -0
  49. package/dist/cjs/lib/stream/types.js.map +1 -0
  50. package/dist/cjs/s2.d.ts +1 -0
  51. package/dist/cjs/s2.d.ts.map +1 -1
  52. package/dist/cjs/s2.js +3 -0
  53. package/dist/cjs/s2.js.map +1 -1
  54. package/dist/cjs/stream.d.ts +22 -116
  55. package/dist/cjs/stream.d.ts.map +1 -1
  56. package/dist/cjs/stream.js +34 -549
  57. package/dist/cjs/stream.js.map +1 -1
  58. package/dist/cjs/utils.d.ts +32 -6
  59. package/dist/cjs/utils.d.ts.map +1 -1
  60. package/dist/cjs/utils.js +129 -34
  61. package/dist/cjs/utils.js.map +1 -1
  62. package/dist/esm/basin.d.ts +9 -2
  63. package/dist/esm/basin.d.ts.map +1 -1
  64. package/dist/esm/basin.js +14 -5
  65. package/dist/esm/basin.js.map +1 -1
  66. package/dist/esm/batch-transform.d.ts +64 -0
  67. package/dist/esm/batch-transform.d.ts.map +1 -0
  68. package/dist/esm/batch-transform.js +140 -0
  69. package/dist/esm/batch-transform.js.map +1 -0
  70. package/dist/esm/generated/client/utils.gen.d.ts +1 -1
  71. package/dist/esm/generated/client/utils.gen.d.ts.map +1 -1
  72. package/dist/esm/generated/client/utils.gen.js +7 -6
  73. package/dist/esm/generated/client/utils.gen.js.map +1 -1
  74. package/dist/esm/generated/core/bodySerializer.gen.d.ts +12 -4
  75. package/dist/esm/generated/core/bodySerializer.gen.d.ts.map +1 -1
  76. package/dist/esm/generated/core/bodySerializer.gen.js.map +1 -1
  77. package/dist/esm/generated/proto/s2.d.ts.map +1 -1
  78. package/dist/esm/generated/proto/s2.js.map +1 -1
  79. package/dist/esm/index.d.ts +4 -2
  80. package/dist/esm/index.d.ts.map +1 -1
  81. package/dist/esm/index.js +2 -1
  82. package/dist/esm/index.js.map +1 -1
  83. package/dist/esm/lib/stream/factory.d.ts +15 -0
  84. package/dist/esm/lib/stream/factory.d.ts.map +1 -0
  85. package/dist/esm/lib/stream/factory.js +33 -0
  86. package/dist/esm/lib/stream/factory.js.map +1 -0
  87. package/dist/esm/lib/stream/runtime.d.ts +13 -0
  88. package/dist/esm/lib/stream/runtime.d.ts.map +1 -0
  89. package/dist/esm/lib/stream/runtime.js +46 -0
  90. package/dist/esm/lib/stream/runtime.js.map +1 -0
  91. package/dist/esm/lib/stream/transport/fetch/index.d.ts +79 -0
  92. package/dist/esm/lib/stream/transport/fetch/index.d.ts.map +1 -0
  93. package/dist/esm/lib/stream/transport/fetch/index.js +376 -0
  94. package/dist/esm/lib/stream/transport/fetch/index.js.map +1 -0
  95. package/dist/esm/lib/stream/transport/fetch/shared.d.ts +7 -0
  96. package/dist/esm/lib/stream/transport/fetch/shared.d.ts.map +1 -0
  97. package/dist/esm/lib/stream/transport/fetch/shared.js +166 -0
  98. package/dist/esm/lib/stream/transport/fetch/shared.js.map +1 -0
  99. package/dist/esm/lib/stream/transport/s2s/framing.d.ts +47 -0
  100. package/dist/esm/lib/stream/transport/s2s/framing.d.ts.map +1 -0
  101. package/dist/esm/lib/stream/transport/s2s/framing.js +118 -0
  102. package/dist/esm/lib/stream/transport/s2s/framing.js.map +1 -0
  103. package/dist/esm/lib/stream/transport/s2s/index.d.ts +23 -0
  104. package/dist/esm/lib/stream/transport/s2s/index.d.ts.map +1 -0
  105. package/dist/esm/lib/stream/transport/s2s/index.js +781 -0
  106. package/dist/esm/lib/stream/transport/s2s/index.js.map +1 -0
  107. package/dist/esm/lib/stream/types.d.ts +53 -0
  108. package/dist/esm/lib/stream/types.d.ts.map +1 -0
  109. package/dist/esm/lib/stream/types.js +2 -0
  110. package/dist/esm/lib/stream/types.js.map +1 -0
  111. package/dist/esm/s2.d.ts +1 -0
  112. package/dist/esm/s2.d.ts.map +1 -1
  113. package/dist/esm/s2.js +3 -0
  114. package/dist/esm/s2.js.map +1 -1
  115. package/dist/esm/stream.d.ts +22 -116
  116. package/dist/esm/stream.d.ts.map +1 -1
  117. package/dist/esm/stream.js +36 -551
  118. package/dist/esm/stream.js.map +1 -1
  119. package/dist/esm/utils.d.ts +32 -6
  120. package/dist/esm/utils.d.ts.map +1 -1
  121. package/dist/esm/utils.js +126 -34
  122. package/dist/esm/utils.js.map +1 -1
  123. package/package.json +2 -4
@@ -0,0 +1,118 @@
1
+ /**
2
+ * S2S Protocol Message Framing
3
+ *
4
+ * Message format:
5
+ * - 3 bytes: Length prefix (total message length including flag byte, big-endian)
6
+ * - 1 byte: Flag byte [T][CC][RRRRR]
7
+ * - T (bit 7): Terminal flag (1 = stream ends after this message)
8
+ * - CC (bits 6-5): Compression (00=none, 01=zstd, 10=gzip)
9
+ * - RRRRR (bits 4-0): Reserved
10
+ * - Variable: Body (protobuf message or JSON error for terminal frames)
11
+ */
12
+ /**
13
+ * Frame a message for s2s protocol
14
+ */
15
+ export function frameMessage(opts) {
16
+ const compression = opts.compression ?? "none";
17
+ // Build flag byte
18
+ let flag = 0;
19
+ if (opts.terminal) {
20
+ flag |= 0x80; // Set bit 7
21
+ }
22
+ if (compression === "zstd") {
23
+ flag |= 0x20; // Set bit 5
24
+ }
25
+ else if (compression === "gzip") {
26
+ flag |= 0x40; // Set bit 6
27
+ }
28
+ // For terminal frames with status code, prepend 2-byte status code to body
29
+ let body = opts.body;
30
+ if (opts.terminal && opts.statusCode !== undefined) {
31
+ const statusBytes = new Uint8Array(2);
32
+ statusBytes[0] = (opts.statusCode >> 8) & 0xff;
33
+ statusBytes[1] = opts.statusCode & 0xff;
34
+ body = new Uint8Array(statusBytes.length + opts.body.length);
35
+ body.set(statusBytes, 0);
36
+ body.set(opts.body, statusBytes.length);
37
+ }
38
+ // Calculate total length (flag + body)
39
+ const length = 1 + body.length;
40
+ if (length > 0xffffff) {
41
+ throw new Error(`Message too large: ${length} bytes (max 16MB)`);
42
+ }
43
+ // Allocate frame buffer
44
+ const frame = new Uint8Array(3 + length);
45
+ // Write 3-byte length prefix (big-endian)
46
+ frame[0] = (length >> 16) & 0xff;
47
+ frame[1] = (length >> 8) & 0xff;
48
+ frame[2] = length & 0xff;
49
+ // Write flag byte
50
+ frame[3] = flag;
51
+ // Write body
52
+ frame.set(body, 4);
53
+ return frame;
54
+ }
55
+ /**
56
+ * Parser for reading s2s frames from a stream
57
+ */
58
+ export class S2SFrameParser {
59
+ buffer = new Uint8Array(0);
60
+ /**
61
+ * Add data to the parser buffer
62
+ */
63
+ push(data) {
64
+ const newBuffer = new Uint8Array(this.buffer.length + data.length);
65
+ newBuffer.set(this.buffer, 0);
66
+ newBuffer.set(data, this.buffer.length);
67
+ this.buffer = newBuffer;
68
+ }
69
+ /**
70
+ * Try to parse the next frame from the buffer
71
+ * Returns null if not enough data available
72
+ */
73
+ parseFrame() {
74
+ // Need at least 4 bytes (3-byte length + 1-byte flag)
75
+ if (this.buffer.length < 4) {
76
+ return null;
77
+ }
78
+ // Read 3-byte length prefix (big-endian)
79
+ const length = (this.buffer[0] << 16) | (this.buffer[1] << 8) | this.buffer[2];
80
+ // Check if we have the full message
81
+ if (this.buffer.length < 3 + length) {
82
+ return null;
83
+ }
84
+ // Read flag byte
85
+ const flag = this.buffer[3];
86
+ const terminal = (flag & 0x80) !== 0;
87
+ let compression = "none";
88
+ if ((flag & 0x20) !== 0) {
89
+ compression = "zstd";
90
+ }
91
+ else if ((flag & 0x40) !== 0) {
92
+ compression = "gzip";
93
+ }
94
+ // Extract body (length includes flag byte, so body is length - 1 bytes)
95
+ let body = this.buffer.slice(4, 4 + length - 1);
96
+ let statusCode;
97
+ // For terminal frames, check for status code
98
+ if (terminal && body.length >= 2) {
99
+ statusCode = (body[0] << 8) | body[1];
100
+ body = body.slice(2);
101
+ }
102
+ // Remove parsed frame from buffer
103
+ this.buffer = this.buffer.slice(3 + length);
104
+ return {
105
+ terminal,
106
+ compression,
107
+ body,
108
+ statusCode,
109
+ };
110
+ }
111
+ /**
112
+ * Check if parser has any buffered data
113
+ */
114
+ hasData() {
115
+ return this.buffer.length > 0;
116
+ }
117
+ }
118
+ //# sourceMappingURL=framing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framing.js","sourceRoot":"","sources":["../../../../../../src/lib/stream/transport/s2s/framing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * S2S HTTP/2 transport for Node.js
3
+ * Uses the s2s binary protocol over HTTP/2 for efficient streaming
4
+ *
5
+ * This file should only be imported in Node.js environments
6
+ */
7
+ import type { S2RequestOptions } from "../../../../common.js";
8
+ import type { AppendSession, AppendSessionOptions, ReadArgs, ReadSession, SessionTransport, TransportConfig } from "../../types.js";
9
+ export declare class S2STransport implements SessionTransport {
10
+ private readonly client;
11
+ private readonly transportConfig;
12
+ private connection?;
13
+ private connectionPromise?;
14
+ constructor(config: TransportConfig);
15
+ makeAppendSession(stream: string, sessionOptions?: AppendSessionOptions, requestOptions?: S2RequestOptions): Promise<AppendSession>;
16
+ makeReadSession<Format extends "string" | "bytes" = "string">(stream: string, args?: ReadArgs<Format>, options?: S2RequestOptions): Promise<ReadSession<Format>>;
17
+ /**
18
+ * Get or create HTTP/2 connection (one per transport)
19
+ */
20
+ private getConnection;
21
+ private createConnection;
22
+ }
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/stream/transport/s2s/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAgB9D,OAAO,KAAK,EAGX,aAAa,EACb,oBAAoB,EACpB,QAAQ,EAER,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,MAAM,gBAAgB,CAAC;AAGxB,qBAAa,YAAa,YAAW,gBAAgB;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,UAAU,CAAC,CAA2B;IAC9C,OAAO,CAAC,iBAAiB,CAAC,CAAoC;gBAElD,MAAM,EAAE,eAAe;IAU7B,iBAAiB,CACtB,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,oBAAoB,EACrC,cAAc,CAAC,EAAE,gBAAgB,GAC/B,OAAO,CAAC,aAAa,CAAC;IAWnB,eAAe,CAAC,MAAM,SAAS,QAAQ,GAAG,OAAO,GAAG,QAAQ,EACjE,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,OAAO,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAW/B;;OAEG;YACW,aAAa;YAyBb,gBAAgB;CA4B9B"}