@restatedev/restate-sdk-integration-client 0.0.0-stage → 1.18.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.
- package/LICENSE +21 -0
- package/README.md +132 -2
- package/dist/_virtual/rolldown_runtime.cjs +25 -0
- package/dist/api.d.cts +219 -0
- package/dist/api.d.cts.map +1 -0
- package/dist/api.d.ts +219 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/client.cjs +101 -0
- package/dist/client.d.cts +26 -0
- package/dist/client.d.cts.map +1 -0
- package/dist/client.d.ts +26 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +99 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.cjs +52 -0
- package/dist/errors.d.cts +42 -0
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +51 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.cjs +137 -0
- package/dist/generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.d.cts +1 -0
- package/dist/generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.d.ts +2 -0
- package/dist/generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.js +131 -0
- package/dist/generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.js.map +1 -0
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/package.cjs +11 -0
- package/dist/package.js +6 -0
- package/dist/package.js.map +1 -0
- package/dist/producer.cjs +245 -0
- package/dist/producer.js +244 -0
- package/dist/producer.js.map +1 -0
- package/dist/proto.cjs +37 -0
- package/dist/proto.js +35 -0
- package/dist/proto.js.map +1 -0
- package/dist/queue.cjs +40 -0
- package/dist/queue.js +40 -0
- package/dist/queue.js.map +1 -0
- package/package.json +61 -3
package/dist/producer.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { DeduplicationMode, IngestionInvocationSchema, IngestionRequestSchema } from "./generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.js";
|
|
2
|
+
import { IntegrationClientError, errorFromProto, toSafeNumber } from "./errors.js";
|
|
3
|
+
import { toProtoDefaults, toProtoInvocation } from "./proto.js";
|
|
4
|
+
import { Queue } from "./queue.js";
|
|
5
|
+
import { create, toBinary } from "@bufbuild/protobuf";
|
|
6
|
+
|
|
7
|
+
//#region src/producer.ts
|
|
8
|
+
const INITIAL_WINDOW_BYTES = 32 * 1024;
|
|
9
|
+
const DEFAULT_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
10
|
+
/**
|
|
11
|
+
* Owns one ingestion stream.
|
|
12
|
+
*
|
|
13
|
+
* A record goes from `send` to the admission queue, where it waits in FIFO order while the
|
|
14
|
+
* buffer is full, then to the buffer, then to the request generator that Connect consumes. Connect
|
|
15
|
+
* pulls the next request only once HTTP/2 has accepted the previous one, and the buffer hands a
|
|
16
|
+
* record to the generator only while the Restate window has credit, so both transport and Restate
|
|
17
|
+
* backpressure propagate back to `send`.
|
|
18
|
+
*/
|
|
19
|
+
var ProducerImpl = class {
|
|
20
|
+
#producerId;
|
|
21
|
+
#exactlyOnce;
|
|
22
|
+
#bufferBytes;
|
|
23
|
+
#onCommitted;
|
|
24
|
+
#call = new AbortController();
|
|
25
|
+
#responsesDone;
|
|
26
|
+
#admission = new Queue();
|
|
27
|
+
#buffer = new Queue();
|
|
28
|
+
#bufferedBytes = 0;
|
|
29
|
+
#commitWaiters = new Queue();
|
|
30
|
+
#budget = INITIAL_WINDOW_BYTES;
|
|
31
|
+
#lastSent = -1;
|
|
32
|
+
#lastCommitted = -1;
|
|
33
|
+
#pull;
|
|
34
|
+
#requestsEnded = false;
|
|
35
|
+
#closing;
|
|
36
|
+
#failed = false;
|
|
37
|
+
#failure;
|
|
38
|
+
#writable;
|
|
39
|
+
#writableController;
|
|
40
|
+
constructor(config) {
|
|
41
|
+
const bufferBytes = config.options.bufferBytes ?? DEFAULT_BUFFER_BYTES;
|
|
42
|
+
if (!Number.isSafeInteger(bufferBytes) || bufferBytes < 0) throw new RangeError(`bufferBytes must be a non-negative integer, got ${bufferBytes}`);
|
|
43
|
+
this.#producerId = config.producerId;
|
|
44
|
+
this.#exactlyOnce = config.exactlyOnce;
|
|
45
|
+
this.#bufferBytes = bufferBytes;
|
|
46
|
+
this.#onCommitted = config.options.onCommitted;
|
|
47
|
+
const start = create(IngestionRequestSchema, { kind: {
|
|
48
|
+
case: "start",
|
|
49
|
+
value: {
|
|
50
|
+
producerId: config.producerId,
|
|
51
|
+
integration: config.integration,
|
|
52
|
+
deduplicationMode: config.exactlyOnce ? DeduplicationMode.OFFSET_BASED : DeduplicationMode.DISABLED,
|
|
53
|
+
defaults: config.options.defaults !== void 0 ? toProtoDefaults(config.options.defaults) : void 0
|
|
54
|
+
}
|
|
55
|
+
} });
|
|
56
|
+
const responses = config.rpc.ingest(this.#requests(start), {
|
|
57
|
+
signal: this.#call.signal,
|
|
58
|
+
headers: config.headers
|
|
59
|
+
});
|
|
60
|
+
this.#responsesDone = this.#readResponses(responses);
|
|
61
|
+
}
|
|
62
|
+
get producerId() {
|
|
63
|
+
return this.#producerId;
|
|
64
|
+
}
|
|
65
|
+
send(record, opts) {
|
|
66
|
+
if (this.#failed) return Promise.reject(this.#failure);
|
|
67
|
+
if (this.#closing !== void 0) return Promise.reject(/* @__PURE__ */ new Error("The producer is closed"));
|
|
68
|
+
let offset;
|
|
69
|
+
if (this.#exactlyOnce) {
|
|
70
|
+
offset = record.offset;
|
|
71
|
+
if (!Number.isSafeInteger(offset) || offset < 0) return Promise.reject(/* @__PURE__ */ new RangeError(`offset must be a non-negative safe integer, got ${offset}`));
|
|
72
|
+
if (offset <= this.#lastSent) return Promise.reject(/* @__PURE__ */ new RangeError(`offset must be strictly increasing: last sent ${this.#lastSent}, got ${offset}`));
|
|
73
|
+
} else {
|
|
74
|
+
offset = this.#lastSent + 1;
|
|
75
|
+
if (!Number.isSafeInteger(offset)) return Promise.reject(/* @__PURE__ */ new RangeError("The producer offset sequence is exhausted"));
|
|
76
|
+
}
|
|
77
|
+
let pending;
|
|
78
|
+
try {
|
|
79
|
+
const invocation = toProtoInvocation(record, offset);
|
|
80
|
+
pending = {
|
|
81
|
+
offset,
|
|
82
|
+
size: toBinary(IngestionInvocationSchema, invocation).byteLength,
|
|
83
|
+
request: create(IngestionRequestSchema, { kind: {
|
|
84
|
+
case: "invocation",
|
|
85
|
+
value: invocation
|
|
86
|
+
} })
|
|
87
|
+
};
|
|
88
|
+
} catch (e) {
|
|
89
|
+
return Promise.reject(e);
|
|
90
|
+
}
|
|
91
|
+
if (this.#bufferBytes > 0 && pending.size > this.#bufferBytes) return Promise.reject(/* @__PURE__ */ new RangeError(`The serialized record takes ${pending.size} bytes, more than bufferBytes (${this.#bufferBytes})`));
|
|
92
|
+
this.#lastSent = offset;
|
|
93
|
+
const accepted = new Promise((resolve, reject) => {
|
|
94
|
+
this.#admission.push({
|
|
95
|
+
record: pending,
|
|
96
|
+
resolve,
|
|
97
|
+
reject
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
this.#drive();
|
|
101
|
+
if (opts?.waitCommitted !== true) return accepted;
|
|
102
|
+
return Promise.all([accepted, this.#committed(offset)]).then(() => offset);
|
|
103
|
+
}
|
|
104
|
+
flush() {
|
|
105
|
+
return this.#committed(this.#lastSent);
|
|
106
|
+
}
|
|
107
|
+
close() {
|
|
108
|
+
this.#closing ??= this.#close();
|
|
109
|
+
return this.#closing;
|
|
110
|
+
}
|
|
111
|
+
abort(reason) {
|
|
112
|
+
this.#fail(reason ?? new IntegrationClientError("unknown", "The producer was aborted"));
|
|
113
|
+
}
|
|
114
|
+
get writable() {
|
|
115
|
+
this.#writable ??= new WritableStream({
|
|
116
|
+
start: (controller) => {
|
|
117
|
+
this.#writableController = controller;
|
|
118
|
+
if (this.#failed) controller.error(this.#failure);
|
|
119
|
+
},
|
|
120
|
+
write: async (record) => {
|
|
121
|
+
await this.send(record);
|
|
122
|
+
},
|
|
123
|
+
close: () => this.close(),
|
|
124
|
+
abort: (reason) => this.abort(reason)
|
|
125
|
+
});
|
|
126
|
+
return this.#writable;
|
|
127
|
+
}
|
|
128
|
+
async #close() {
|
|
129
|
+
if (this.#failed) throw this.#failure;
|
|
130
|
+
await this.flush();
|
|
131
|
+
this.#requestsEnded = true;
|
|
132
|
+
this.#drive();
|
|
133
|
+
await this.#responsesDone;
|
|
134
|
+
if (this.#failed) throw this.#failure;
|
|
135
|
+
}
|
|
136
|
+
async *#requests(start) {
|
|
137
|
+
yield start;
|
|
138
|
+
for (;;) {
|
|
139
|
+
const request = await new Promise((resolve) => {
|
|
140
|
+
this.#pull = resolve;
|
|
141
|
+
this.#drive();
|
|
142
|
+
});
|
|
143
|
+
if (request === void 0) return;
|
|
144
|
+
yield request;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Moves records along: hands the buffer head to the waiting generator, admits waiting sends. */
|
|
148
|
+
#drive() {
|
|
149
|
+
for (;;) {
|
|
150
|
+
if (this.#pull !== void 0) {
|
|
151
|
+
if (this.#failed || this.#requestsEnded && this.#buffer.length === 0) {
|
|
152
|
+
this.#takePull()(void 0);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (this.#budget > 0) {
|
|
156
|
+
const record = this.#buffer.shift();
|
|
157
|
+
if (record !== void 0) {
|
|
158
|
+
this.#bufferedBytes -= record.size;
|
|
159
|
+
this.#budget -= record.size;
|
|
160
|
+
this.#takePull()(record.request);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const waiter = this.#admission.peek();
|
|
166
|
+
if (waiter === void 0 || !this.#canAdmit(waiter.record.size)) return;
|
|
167
|
+
this.#admission.shift();
|
|
168
|
+
this.#buffer.push(waiter.record);
|
|
169
|
+
this.#bufferedBytes += waiter.record.size;
|
|
170
|
+
waiter.resolve(waiter.record.offset);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
#canAdmit(size) {
|
|
174
|
+
if (this.#failed) return false;
|
|
175
|
+
if (this.#bufferBytes === 0) return this.#pull !== void 0 && this.#budget > 0 && this.#buffer.length === 0;
|
|
176
|
+
return this.#bufferedBytes + size <= this.#bufferBytes;
|
|
177
|
+
}
|
|
178
|
+
#takePull() {
|
|
179
|
+
const pull = this.#pull;
|
|
180
|
+
this.#pull = void 0;
|
|
181
|
+
return pull;
|
|
182
|
+
}
|
|
183
|
+
#committed(offset) {
|
|
184
|
+
if (offset <= this.#lastCommitted) return Promise.resolve(this.#lastCommitted);
|
|
185
|
+
if (this.#failed) return Promise.reject(this.#failure);
|
|
186
|
+
return new Promise((resolve, reject) => {
|
|
187
|
+
this.#commitWaiters.push({
|
|
188
|
+
offset,
|
|
189
|
+
resolve,
|
|
190
|
+
reject
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
async #readResponses(responses) {
|
|
195
|
+
try {
|
|
196
|
+
for await (const response of responses) {
|
|
197
|
+
if (response.lastCommitted !== void 0) this.#advanceCommitted(toSafeNumber(response.lastCommitted));
|
|
198
|
+
if (this.#failed) return;
|
|
199
|
+
if (response.response.case === "windowUpdate") {
|
|
200
|
+
this.#budget += response.response.value.incrementBytes;
|
|
201
|
+
this.#drive();
|
|
202
|
+
} else if (response.response.case === "error") {
|
|
203
|
+
this.#fail(errorFromProto(response.response.value));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (!this.#requestsEnded) this.#fail(new IntegrationClientError("unknown", "The ingestion stream was closed by the server"));
|
|
208
|
+
} catch (e) {
|
|
209
|
+
this.#fail(new IntegrationClientError("unknown", `The ingestion stream failed: ${e instanceof Error ? e.message : String(e)}`, { cause: e }));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
#advanceCommitted(watermark) {
|
|
213
|
+
if (watermark <= this.#lastCommitted) return;
|
|
214
|
+
this.#lastCommitted = watermark;
|
|
215
|
+
for (let waiter = this.#commitWaiters.peek(); waiter !== void 0 && waiter.offset <= watermark; waiter = this.#commitWaiters.peek()) {
|
|
216
|
+
this.#commitWaiters.shift();
|
|
217
|
+
waiter.resolve(watermark);
|
|
218
|
+
}
|
|
219
|
+
if (this.#onCommitted !== void 0) try {
|
|
220
|
+
this.#onCommitted(watermark);
|
|
221
|
+
} catch (e) {
|
|
222
|
+
this.#fail(e);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** Makes the producer terminally failed: cancels the stream and rejects everything pending. */
|
|
226
|
+
#fail(reason) {
|
|
227
|
+
if (this.#failed) return;
|
|
228
|
+
this.#failed = true;
|
|
229
|
+
this.#failure = reason;
|
|
230
|
+
this.#buffer.drain();
|
|
231
|
+
this.#bufferedBytes = 0;
|
|
232
|
+
const admission = this.#admission.drain();
|
|
233
|
+
const commits = this.#commitWaiters.drain();
|
|
234
|
+
if (this.#pull !== void 0) this.#takePull()(void 0);
|
|
235
|
+
this.#call.abort(reason);
|
|
236
|
+
this.#writableController?.error(reason);
|
|
237
|
+
for (const waiter of admission) waiter.reject(reason);
|
|
238
|
+
for (const waiter of commits) waiter.reject(reason);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
export { ProducerImpl };
|
|
244
|
+
//# sourceMappingURL=producer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"producer.js","names":["#producerId","#exactlyOnce","#bufferBytes","#onCommitted","#call","#responsesDone","#admission","#buffer","#commitWaiters","#requests","#readResponses","#failed","#failure","#closing","offset: number","#lastSent","pending: PendingRecord","#drive","#committed","#close","#fail","#writable","#writableController","#requestsEnded","#pull","#takePull","#budget","#bufferedBytes","#canAdmit","#lastCommitted","#advanceCommitted"],"sources":["../src/producer.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2026 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport { create, toBinary } from \"@bufbuild/protobuf\";\nimport type { Client } from \"@connectrpc/connect\";\nimport type {\n ExactlyOnceInvocation,\n Invocation,\n ProducerBase,\n ProducerOptions,\n SendOptions,\n} from \"./api.js\";\nimport {\n errorFromProto,\n IntegrationClientError,\n toSafeNumber,\n} from \"./errors.js\";\nimport {\n DeduplicationMode,\n IngestionInvocationSchema,\n type IngestionRequest,\n IngestionRequestSchema,\n type IngestionResponse,\n type IngestionSvc,\n} from \"./generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.js\";\nimport { toProtoDefaults, toProtoInvocation } from \"./proto.js\";\nimport { Queue } from \"./queue.js\";\n\n// The protocol guarantees a minimum send window of 32 KiB. The client assumes it as its initial\n// credit instead of waiting for a first WindowUpdate; every WindowUpdate grows it from there.\nconst INITIAL_WINDOW_BYTES = 32 * 1024;\n\nconst DEFAULT_BUFFER_BYTES = 32 * 1024 * 1024;\n\nexport interface ProducerConfig {\n readonly rpc: Client<typeof IngestionSvc>;\n readonly headers: Record<string, string> | undefined;\n readonly integration: string;\n /** Empty for at-least-once producers. */\n readonly producerId: string;\n readonly exactlyOnce: boolean;\n readonly options: ProducerOptions;\n}\n\ninterface PendingRecord {\n readonly offset: number;\n readonly request: IngestionRequest;\n // Serialized size of the invocation, the unit of both bufferBytes and the Restate window.\n readonly size: number;\n}\n\ninterface AdmissionWaiter {\n readonly record: PendingRecord;\n readonly resolve: (offset: number) => void;\n readonly reject: (reason: unknown) => void;\n}\n\ninterface CommitWaiter {\n readonly offset: number;\n readonly resolve: (watermark: number) => void;\n readonly reject: (reason: unknown) => void;\n}\n\n/**\n * Owns one ingestion stream.\n *\n * A record goes from `send` to the admission queue, where it waits in FIFO order while the\n * buffer is full, then to the buffer, then to the request generator that Connect consumes. Connect\n * pulls the next request only once HTTP/2 has accepted the previous one, and the buffer hands a\n * record to the generator only while the Restate window has credit, so both transport and Restate\n * backpressure propagate back to `send`.\n */\nexport class ProducerImpl<R extends Invocation> implements ProducerBase<R> {\n readonly #producerId: string;\n readonly #exactlyOnce: boolean;\n readonly #bufferBytes: number;\n readonly #onCommitted: ((offset: number) => void) | undefined;\n readonly #call = new AbortController();\n readonly #responsesDone: Promise<void>;\n\n readonly #admission = new Queue<AdmissionWaiter>();\n readonly #buffer = new Queue<PendingRecord>();\n #bufferedBytes = 0;\n // Ordered by offset: send() and flush() register increasing offsets.\n readonly #commitWaiters = new Queue<CommitWaiter>();\n\n // Remaining Restate window; may go one record negative, as the protocol allows.\n #budget = INITIAL_WINDOW_BYTES;\n // Highest offset accepted by send(), including records still waiting for admission.\n #lastSent = -1;\n #lastCommitted = -1;\n // Set while the request generator waits for its next request.\n #pull: ((request: IngestionRequest | undefined) => void) | undefined;\n #requestsEnded = false;\n #closing: Promise<void> | undefined;\n #failed = false;\n #failure: unknown;\n\n #writable: WritableStream<R> | undefined;\n #writableController: WritableStreamDefaultController | undefined;\n\n constructor(config: ProducerConfig) {\n const bufferBytes = config.options.bufferBytes ?? DEFAULT_BUFFER_BYTES;\n if (!Number.isSafeInteger(bufferBytes) || bufferBytes < 0) {\n throw new RangeError(\n `bufferBytes must be a non-negative integer, got ${bufferBytes}`\n );\n }\n this.#producerId = config.producerId;\n this.#exactlyOnce = config.exactlyOnce;\n this.#bufferBytes = bufferBytes;\n this.#onCommitted = config.options.onCommitted;\n\n const start = create(IngestionRequestSchema, {\n kind: {\n case: \"start\",\n value: {\n producerId: config.producerId,\n integration: config.integration,\n deduplicationMode: config.exactlyOnce\n ? DeduplicationMode.OFFSET_BASED\n : DeduplicationMode.DISABLED,\n defaults:\n config.options.defaults !== undefined\n ? toProtoDefaults(config.options.defaults)\n : undefined,\n },\n },\n });\n const responses = config.rpc.ingest(this.#requests(start), {\n signal: this.#call.signal,\n headers: config.headers,\n });\n this.#responsesDone = this.#readResponses(responses);\n }\n\n get producerId(): string {\n return this.#producerId;\n }\n\n send(record: R, opts?: SendOptions): Promise<number> {\n if (this.#failed) {\n // The failure is an abort() reason, which, like AbortController's, can be any value.\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(this.#failure);\n }\n if (this.#closing !== undefined) {\n return Promise.reject(new Error(\"The producer is closed\"));\n }\n\n let offset: number;\n if (this.#exactlyOnce) {\n offset = (record as Invocation as ExactlyOnceInvocation).offset;\n if (!Number.isSafeInteger(offset) || offset < 0) {\n return Promise.reject(\n new RangeError(\n `offset must be a non-negative safe integer, got ${offset}`\n )\n );\n }\n if (offset <= this.#lastSent) {\n return Promise.reject(\n new RangeError(\n `offset must be strictly increasing: last sent ${this.#lastSent}, got ${offset}`\n )\n );\n }\n } else {\n offset = this.#lastSent + 1;\n if (!Number.isSafeInteger(offset)) {\n return Promise.reject(\n new RangeError(\"The producer offset sequence is exhausted\")\n );\n }\n }\n\n let pending: PendingRecord;\n try {\n const invocation = toProtoInvocation(record, offset);\n pending = {\n offset,\n size: toBinary(IngestionInvocationSchema, invocation).byteLength,\n request: create(IngestionRequestSchema, {\n kind: { case: \"invocation\", value: invocation },\n }),\n };\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(e);\n }\n if (this.#bufferBytes > 0 && pending.size > this.#bufferBytes) {\n return Promise.reject(\n new RangeError(\n `The serialized record takes ${pending.size} bytes, more than bufferBytes (${this.#bufferBytes})`\n )\n );\n }\n\n this.#lastSent = offset;\n const accepted = new Promise<number>((resolve, reject) => {\n this.#admission.push({ record: pending, resolve, reject });\n });\n this.#drive();\n if (opts?.waitCommitted !== true) {\n return accepted;\n }\n return Promise.all([accepted, this.#committed(offset)]).then(() => offset);\n }\n\n flush(): Promise<number> {\n return this.#committed(this.#lastSent);\n }\n\n close(): Promise<void> {\n this.#closing ??= this.#close();\n return this.#closing;\n }\n\n abort(reason?: unknown): void {\n this.#fail(\n reason ??\n new IntegrationClientError(\"unknown\", \"The producer was aborted\")\n );\n }\n\n get writable(): WritableStream<R> {\n // The default highWaterMark of one record is enough: the producer buffer is the real buffer,\n // and write() waits on it.\n this.#writable ??= new WritableStream<R>({\n start: (controller) => {\n this.#writableController = controller;\n if (this.#failed) {\n controller.error(this.#failure);\n }\n },\n write: async (record) => {\n await this.send(record);\n },\n close: () => this.close(),\n abort: (reason) => this.abort(reason),\n });\n return this.#writable;\n }\n\n async #close(): Promise<void> {\n if (this.#failed) {\n throw this.#failure;\n }\n await this.flush();\n // Half-close the request stream; Restate then ends the response stream.\n this.#requestsEnded = true;\n this.#drive();\n await this.#responsesDone;\n if (this.#failed) {\n throw this.#failure;\n }\n }\n\n async *#requests(start: IngestionRequest): AsyncGenerator<IngestionRequest> {\n yield start;\n for (;;) {\n const request = await new Promise<IngestionRequest | undefined>(\n (resolve) => {\n this.#pull = resolve;\n this.#drive();\n }\n );\n if (request === undefined) {\n return;\n }\n yield request;\n }\n }\n\n /** Moves records along: hands the buffer head to the waiting generator, admits waiting sends. */\n #drive(): void {\n for (;;) {\n if (this.#pull !== undefined) {\n if (\n this.#failed ||\n (this.#requestsEnded && this.#buffer.length === 0)\n ) {\n this.#takePull()(undefined);\n return;\n }\n if (this.#budget > 0) {\n const record = this.#buffer.shift();\n if (record !== undefined) {\n this.#bufferedBytes -= record.size;\n this.#budget -= record.size;\n this.#takePull()(record.request);\n continue;\n }\n }\n }\n const waiter = this.#admission.peek();\n if (waiter === undefined || !this.#canAdmit(waiter.record.size)) {\n return;\n }\n this.#admission.shift();\n this.#buffer.push(waiter.record);\n this.#bufferedBytes += waiter.record.size;\n waiter.resolve(waiter.record.offset);\n }\n }\n\n #canAdmit(size: number): boolean {\n if (this.#failed) {\n return false;\n }\n if (this.#bufferBytes === 0) {\n // Without a buffer, admit only what the generator can take right away.\n return (\n this.#pull !== undefined &&\n this.#budget > 0 &&\n this.#buffer.length === 0\n );\n }\n return this.#bufferedBytes + size <= this.#bufferBytes;\n }\n\n #takePull(): (request: IngestionRequest | undefined) => void {\n const pull = this.#pull!;\n this.#pull = undefined;\n return pull;\n }\n\n #committed(offset: number): Promise<number> {\n if (offset <= this.#lastCommitted) {\n return Promise.resolve(this.#lastCommitted);\n }\n if (this.#failed) {\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n return Promise.reject(this.#failure);\n }\n return new Promise((resolve, reject) => {\n this.#commitWaiters.push({ offset, resolve, reject });\n });\n }\n\n async #readResponses(\n responses: AsyncIterable<IngestionResponse>\n ): Promise<void> {\n try {\n for await (const response of responses) {\n if (response.lastCommitted !== undefined) {\n this.#advanceCommitted(toSafeNumber(response.lastCommitted));\n }\n if (this.#failed) {\n return;\n }\n if (response.response.case === \"windowUpdate\") {\n this.#budget += response.response.value.incrementBytes;\n this.#drive();\n } else if (response.response.case === \"error\") {\n // Always the last frame: Restate tears the stream down after it.\n this.#fail(errorFromProto(response.response.value));\n return;\n }\n }\n if (!this.#requestsEnded) {\n this.#fail(\n new IntegrationClientError(\n \"unknown\",\n \"The ingestion stream was closed by the server\"\n )\n );\n }\n } catch (e) {\n this.#fail(\n new IntegrationClientError(\n \"unknown\",\n `The ingestion stream failed: ${e instanceof Error ? e.message : String(e)}`,\n { cause: e }\n )\n );\n }\n }\n\n #advanceCommitted(watermark: number): void {\n if (watermark <= this.#lastCommitted) {\n return;\n }\n this.#lastCommitted = watermark;\n for (\n let waiter = this.#commitWaiters.peek();\n waiter !== undefined && waiter.offset <= watermark;\n waiter = this.#commitWaiters.peek()\n ) {\n this.#commitWaiters.shift();\n waiter.resolve(watermark);\n }\n if (this.#onCommitted !== undefined) {\n try {\n this.#onCommitted(watermark);\n } catch (e) {\n this.#fail(e);\n }\n }\n }\n\n /** Makes the producer terminally failed: cancels the stream and rejects everything pending. */\n #fail(reason: unknown): void {\n if (this.#failed) {\n return;\n }\n this.#failed = true;\n this.#failure = reason;\n this.#buffer.drain();\n this.#bufferedBytes = 0;\n const admission = this.#admission.drain();\n const commits = this.#commitWaiters.drain();\n if (this.#pull !== undefined) {\n this.#takePull()(undefined);\n }\n this.#call.abort(reason);\n this.#writableController?.error(reason);\n for (const waiter of admission) {\n waiter.reject(reason);\n }\n for (const waiter of commits) {\n waiter.reject(reason);\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/proto.cjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_ingestion_svc_pb = require('./generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.cjs');
|
|
3
|
+
let __bufbuild_protobuf = require("@bufbuild/protobuf");
|
|
4
|
+
__bufbuild_protobuf = require_rolldown_runtime.__toESM(__bufbuild_protobuf);
|
|
5
|
+
|
|
6
|
+
//#region src/proto.ts
|
|
7
|
+
const encoder = new TextEncoder();
|
|
8
|
+
function toProtoDefaults(defaults) {
|
|
9
|
+
return (0, __bufbuild_protobuf.create)(require_ingestion_svc_pb.IngestionDefaultsSchema, {
|
|
10
|
+
service: defaults.service,
|
|
11
|
+
handler: defaults.handler,
|
|
12
|
+
key: defaults.key,
|
|
13
|
+
scope: defaults.scope,
|
|
14
|
+
limitKey: defaults.limitKey,
|
|
15
|
+
headers: defaults.headers
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function toProtoInvocation(invocation, offset) {
|
|
19
|
+
return (0, __bufbuild_protobuf.create)(require_ingestion_svc_pb.IngestionInvocationSchema, {
|
|
20
|
+
offset: BigInt(offset),
|
|
21
|
+
service: invocation.service,
|
|
22
|
+
handler: invocation.handler,
|
|
23
|
+
key: invocation.key,
|
|
24
|
+
scope: invocation.scope,
|
|
25
|
+
limitKey: invocation.limitKey,
|
|
26
|
+
idempotencyKey: invocation.idempotencyKey,
|
|
27
|
+
additionalHeaders: invocation.headers,
|
|
28
|
+
invokeTimeTsMs: invocation.invokeAt !== void 0 ? BigInt(invocation.invokeAt.getTime()) : void 0,
|
|
29
|
+
traceparent: invocation.traceparent,
|
|
30
|
+
tracestate: invocation.tracestate,
|
|
31
|
+
payload: typeof invocation.body === "string" ? encoder.encode(invocation.body) : invocation.body
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.toProtoDefaults = toProtoDefaults;
|
|
37
|
+
exports.toProtoInvocation = toProtoInvocation;
|
package/dist/proto.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IngestionDefaultsSchema, IngestionInvocationSchema } from "./generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.js";
|
|
2
|
+
import { create } from "@bufbuild/protobuf";
|
|
3
|
+
|
|
4
|
+
//#region src/proto.ts
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
function toProtoDefaults(defaults) {
|
|
7
|
+
return create(IngestionDefaultsSchema, {
|
|
8
|
+
service: defaults.service,
|
|
9
|
+
handler: defaults.handler,
|
|
10
|
+
key: defaults.key,
|
|
11
|
+
scope: defaults.scope,
|
|
12
|
+
limitKey: defaults.limitKey,
|
|
13
|
+
headers: defaults.headers
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function toProtoInvocation(invocation, offset) {
|
|
17
|
+
return create(IngestionInvocationSchema, {
|
|
18
|
+
offset: BigInt(offset),
|
|
19
|
+
service: invocation.service,
|
|
20
|
+
handler: invocation.handler,
|
|
21
|
+
key: invocation.key,
|
|
22
|
+
scope: invocation.scope,
|
|
23
|
+
limitKey: invocation.limitKey,
|
|
24
|
+
idempotencyKey: invocation.idempotencyKey,
|
|
25
|
+
additionalHeaders: invocation.headers,
|
|
26
|
+
invokeTimeTsMs: invocation.invokeAt !== void 0 ? BigInt(invocation.invokeAt.getTime()) : void 0,
|
|
27
|
+
traceparent: invocation.traceparent,
|
|
28
|
+
tracestate: invocation.tracestate,
|
|
29
|
+
payload: typeof invocation.body === "string" ? encoder.encode(invocation.body) : invocation.body
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
export { toProtoDefaults, toProtoInvocation };
|
|
35
|
+
//# sourceMappingURL=proto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proto.js","names":[],"sources":["../src/proto.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2026 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport { create } from \"@bufbuild/protobuf\";\nimport type { Invocation, InvocationDefaults } from \"./api.js\";\nimport {\n type IngestionDefaults,\n IngestionDefaultsSchema,\n type IngestionInvocation,\n IngestionInvocationSchema,\n} from \"./generated/dev/restate/ingress/ingestion/v1/ingestion_svc_pb.js\";\n\nconst encoder = new TextEncoder();\n\n// `create` ignores fields initialized to `undefined`, so unset optional fields stay unset on\n// the wire and Restate falls back to the stream defaults for them.\n\nexport function toProtoDefaults(\n defaults: InvocationDefaults\n): IngestionDefaults {\n return create(IngestionDefaultsSchema, {\n service: defaults.service,\n handler: defaults.handler,\n key: defaults.key,\n scope: defaults.scope,\n limitKey: defaults.limitKey,\n headers: defaults.headers,\n });\n}\n\nexport function toProtoInvocation(\n invocation: Invocation,\n offset: number\n): IngestionInvocation {\n return create(IngestionInvocationSchema, {\n offset: BigInt(offset),\n service: invocation.service,\n handler: invocation.handler,\n key: invocation.key,\n scope: invocation.scope,\n limitKey: invocation.limitKey,\n idempotencyKey: invocation.idempotencyKey,\n additionalHeaders: invocation.headers,\n invokeTimeTsMs:\n invocation.invokeAt !== undefined\n ? BigInt(invocation.invokeAt.getTime())\n : undefined,\n traceparent: invocation.traceparent,\n tracestate: invocation.tracestate,\n payload:\n typeof invocation.body === \"string\"\n ? encoder.encode(invocation.body)\n : invocation.body,\n });\n}\n"],"mappings":";;;;AAoBA,MAAM,UAAU,IAAI,aAAa;AAKjC,SAAgB,gBACd,UACmB;AACnB,QAAO,OAAO,yBAAyB;EACrC,SAAS,SAAS;EAClB,SAAS,SAAS;EAClB,KAAK,SAAS;EACd,OAAO,SAAS;EAChB,UAAU,SAAS;EACnB,SAAS,SAAS;EACnB,CAAC;;AAGJ,SAAgB,kBACd,YACA,QACqB;AACrB,QAAO,OAAO,2BAA2B;EACvC,QAAQ,OAAO,OAAO;EACtB,SAAS,WAAW;EACpB,SAAS,WAAW;EACpB,KAAK,WAAW;EAChB,OAAO,WAAW;EAClB,UAAU,WAAW;EACrB,gBAAgB,WAAW;EAC3B,mBAAmB,WAAW;EAC9B,gBACE,WAAW,aAAa,SACpB,OAAO,WAAW,SAAS,SAAS,CAAC,GACrC;EACN,aAAa,WAAW;EACxB,YAAY,WAAW;EACvB,SACE,OAAO,WAAW,SAAS,WACvB,QAAQ,OAAO,WAAW,KAAK,GAC/B,WAAW;EAClB,CAAC"}
|
package/dist/queue.cjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/queue.ts
|
|
3
|
+
/** FIFO queue with O(1) amortized `shift`, unlike `Array.prototype.shift`. */
|
|
4
|
+
var Queue = class {
|
|
5
|
+
#items = [];
|
|
6
|
+
#head = 0;
|
|
7
|
+
get length() {
|
|
8
|
+
return this.#items.length - this.#head;
|
|
9
|
+
}
|
|
10
|
+
push(item) {
|
|
11
|
+
this.#items.push(item);
|
|
12
|
+
}
|
|
13
|
+
peek() {
|
|
14
|
+
return this.#items[this.#head];
|
|
15
|
+
}
|
|
16
|
+
shift() {
|
|
17
|
+
if (this.#head === this.#items.length) return;
|
|
18
|
+
const item = this.#items[this.#head];
|
|
19
|
+
this.#items[this.#head] = void 0;
|
|
20
|
+
this.#head++;
|
|
21
|
+
if (this.#head === this.#items.length) {
|
|
22
|
+
this.#items = [];
|
|
23
|
+
this.#head = 0;
|
|
24
|
+
} else if (this.#head >= 1024 && this.#head * 2 >= this.#items.length) {
|
|
25
|
+
this.#items = this.#items.slice(this.#head);
|
|
26
|
+
this.#head = 0;
|
|
27
|
+
}
|
|
28
|
+
return item;
|
|
29
|
+
}
|
|
30
|
+
/** Removes and returns every item. */
|
|
31
|
+
drain() {
|
|
32
|
+
const items = this.#items.slice(this.#head);
|
|
33
|
+
this.#items = [];
|
|
34
|
+
this.#head = 0;
|
|
35
|
+
return items;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
exports.Queue = Queue;
|
package/dist/queue.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/queue.ts
|
|
2
|
+
/** FIFO queue with O(1) amortized `shift`, unlike `Array.prototype.shift`. */
|
|
3
|
+
var Queue = class {
|
|
4
|
+
#items = [];
|
|
5
|
+
#head = 0;
|
|
6
|
+
get length() {
|
|
7
|
+
return this.#items.length - this.#head;
|
|
8
|
+
}
|
|
9
|
+
push(item) {
|
|
10
|
+
this.#items.push(item);
|
|
11
|
+
}
|
|
12
|
+
peek() {
|
|
13
|
+
return this.#items[this.#head];
|
|
14
|
+
}
|
|
15
|
+
shift() {
|
|
16
|
+
if (this.#head === this.#items.length) return;
|
|
17
|
+
const item = this.#items[this.#head];
|
|
18
|
+
this.#items[this.#head] = void 0;
|
|
19
|
+
this.#head++;
|
|
20
|
+
if (this.#head === this.#items.length) {
|
|
21
|
+
this.#items = [];
|
|
22
|
+
this.#head = 0;
|
|
23
|
+
} else if (this.#head >= 1024 && this.#head * 2 >= this.#items.length) {
|
|
24
|
+
this.#items = this.#items.slice(this.#head);
|
|
25
|
+
this.#head = 0;
|
|
26
|
+
}
|
|
27
|
+
return item;
|
|
28
|
+
}
|
|
29
|
+
/** Removes and returns every item. */
|
|
30
|
+
drain() {
|
|
31
|
+
const items = this.#items.slice(this.#head);
|
|
32
|
+
this.#items = [];
|
|
33
|
+
this.#head = 0;
|
|
34
|
+
return items;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Queue };
|
|
40
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","names":["#items","#head"],"sources":["../src/queue.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2026 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\n/** FIFO queue with O(1) amortized `shift`, unlike `Array.prototype.shift`. */\nexport class Queue<T> {\n #items: (T | undefined)[] = [];\n #head = 0;\n\n get length(): number {\n return this.#items.length - this.#head;\n }\n\n push(item: T): void {\n this.#items.push(item);\n }\n\n peek(): T | undefined {\n return this.#items[this.#head];\n }\n\n shift(): T | undefined {\n if (this.#head === this.#items.length) {\n return undefined;\n }\n const item = this.#items[this.#head];\n this.#items[this.#head] = undefined;\n this.#head++;\n if (this.#head === this.#items.length) {\n this.#items = [];\n this.#head = 0;\n } else if (this.#head >= 1024 && this.#head * 2 >= this.#items.length) {\n this.#items = this.#items.slice(this.#head);\n this.#head = 0;\n }\n return item;\n }\n\n /** Removes and returns every item. */\n drain(): T[] {\n const items = this.#items.slice(this.#head) as T[];\n this.#items = [];\n this.#head = 0;\n return items;\n }\n}\n"],"mappings":";;AAYA,IAAa,QAAb,MAAsB;CACpB,SAA4B,EAAE;CAC9B,QAAQ;CAER,IAAI,SAAiB;AACnB,SAAO,MAAKA,MAAO,SAAS,MAAKC;;CAGnC,KAAK,MAAe;AAClB,QAAKD,MAAO,KAAK,KAAK;;CAGxB,OAAsB;AACpB,SAAO,MAAKA,MAAO,MAAKC;;CAG1B,QAAuB;AACrB,MAAI,MAAKA,SAAU,MAAKD,MAAO,OAC7B;EAEF,MAAM,OAAO,MAAKA,MAAO,MAAKC;AAC9B,QAAKD,MAAO,MAAKC,QAAS;AAC1B,QAAKA;AACL,MAAI,MAAKA,SAAU,MAAKD,MAAO,QAAQ;AACrC,SAAKA,QAAS,EAAE;AAChB,SAAKC,OAAQ;aACJ,MAAKA,QAAS,QAAQ,MAAKA,OAAQ,KAAK,MAAKD,MAAO,QAAQ;AACrE,SAAKA,QAAS,MAAKA,MAAO,MAAM,MAAKC,KAAM;AAC3C,SAAKA,OAAQ;;AAEf,SAAO;;;CAIT,QAAa;EACX,MAAM,QAAQ,MAAKD,MAAO,MAAM,MAAKC,KAAM;AAC3C,QAAKD,QAAS,EAAE;AAChB,QAAKC,OAAQ;AACb,SAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@restatedev/restate-sdk-integration-client",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.18.0",
|
|
4
|
+
"description": "Client for the Restate ingress integration (ingestion) API",
|
|
5
|
+
"author": "Restate Developers",
|
|
6
|
+
"email": "code@restate.dev",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/restatedev/sdk-typescript#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/restatedev/sdk-typescript.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/restatedev/sdk-typescript/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.cjs",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.cts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"require": "./dist/index.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@bufbuild/protobuf": "^2.16.0",
|
|
36
|
+
"@connectrpc/connect": "^2.2.0",
|
|
37
|
+
"@connectrpc/connect-node": "^2.2.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@bufbuild/buf": "1.75.0",
|
|
41
|
+
"@bufbuild/protoc-gen-es": "^2.16.0",
|
|
42
|
+
"testcontainers": "^11.13.0",
|
|
43
|
+
"@restatedev/restate-sdk": "1.18.0",
|
|
44
|
+
"@restatedev/restate-sdk-clients": "1.18.0",
|
|
45
|
+
"@restatedev/restate-sdk-testcontainers": "1.18.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"test": "turbo run _test --filter={.}...",
|
|
49
|
+
"_test": "vitest run",
|
|
50
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
51
|
+
"generate:proto": "buf generate",
|
|
52
|
+
"build": "turbo run _build --filter={.}...",
|
|
53
|
+
"_build": "tsc --noEmit && tsdown",
|
|
54
|
+
"dev": "tsc --noEmit --watch",
|
|
55
|
+
"clean": "rm -rf dist *.tsbuildinfo .turbo",
|
|
56
|
+
"check:types": "turbo run _check:types --filter={.}...",
|
|
57
|
+
"_check:types": "tsc --noEmit --project tsconfig.build.json",
|
|
58
|
+
"lint": "eslint .",
|
|
59
|
+
"check:exports": "turbo run _check:exports --filter={.}...",
|
|
60
|
+
"_check:exports": "attw --pack .",
|
|
61
|
+
"check:api": "turbo run _check:api --filter={.}...",
|
|
62
|
+
"_check:api": "api-extractor run --local"
|
|
63
|
+
}
|
|
6
64
|
}
|