@nifrajs/client 1.4.0 → 1.5.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/dist/client.d.ts.map +1 -1
- package/dist/client.js +169 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/treaty.d.ts +36 -1
- package/dist/treaty.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +197 -1
- package/src/index.ts +7 -1
- package/src/treaty.ts +41 -1
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,KAAK,EAAgB,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAa3E;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE9E,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;AAClF,wBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAClD,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,aAAa,GACtB,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAerC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,GAAG,SAAS;IAAE,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAE,EACrE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAgB/D;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,wBAAkB,CAAA"}
|
package/dist/client.js
CHANGED
|
@@ -75,6 +75,12 @@ function createProxy(base, path, options) {
|
|
|
75
75
|
if (HTTP_VERBS.has(key.toLowerCase())) {
|
|
76
76
|
return (...args) => execute(base, path, key.toLowerCase(), args, options);
|
|
77
77
|
}
|
|
78
|
+
// Typed SSE subscription for `app.sse()` routes. Like `fetch` on the in-process client,
|
|
79
|
+
// `subscribe` is a reserved proxy key — a literal `/subscribe` path segment is unreachable
|
|
80
|
+
// through the typed proxy (no nifra app defines one reached this way).
|
|
81
|
+
if (key === "subscribe") {
|
|
82
|
+
return (onEvent, subscribeOptions) => subscribeSse(base, path, onEvent, subscribeOptions, options);
|
|
83
|
+
}
|
|
78
84
|
// `index` addresses the root path "/" and adds no segment.
|
|
79
85
|
return createProxy(base, key === "index" ? path : `${path}/${key}`, options);
|
|
80
86
|
},
|
|
@@ -127,6 +133,169 @@ async function execute(base, path, verb, args, options) {
|
|
|
127
133
|
// `error` is the server's normalized `{ error, issues }` summary.
|
|
128
134
|
return { ok: false, status: response.status, data, error: toApiError(data) };
|
|
129
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Incrementally parse a `text/event-stream` body, invoking `onFrame` per dispatched event.
|
|
138
|
+
* Implements the SSE wire format: `data:` accumulates multi-line, `id:`/`retry:` update stream
|
|
139
|
+
* state, `:` lines are comments, a blank line dispatches.
|
|
140
|
+
*/
|
|
141
|
+
async function readSseStream(body, onFrame) {
|
|
142
|
+
const reader = body.getReader();
|
|
143
|
+
const decoder = new TextDecoder();
|
|
144
|
+
let buffer = "";
|
|
145
|
+
let dataLines = [];
|
|
146
|
+
let frame = {};
|
|
147
|
+
const dispatch = () => {
|
|
148
|
+
if (dataLines.length > 0)
|
|
149
|
+
frame.data = dataLines.join("\n");
|
|
150
|
+
if (frame.data !== undefined || frame.id !== undefined || frame.retry !== undefined) {
|
|
151
|
+
onFrame(frame);
|
|
152
|
+
}
|
|
153
|
+
dataLines = [];
|
|
154
|
+
frame = {};
|
|
155
|
+
};
|
|
156
|
+
const handleLine = (line) => {
|
|
157
|
+
if (line === "") {
|
|
158
|
+
dispatch();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (line.startsWith(":"))
|
|
162
|
+
return; // comment / keep-alive
|
|
163
|
+
const colon = line.indexOf(":");
|
|
164
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
165
|
+
let value = colon === -1 ? "" : line.slice(colon + 1);
|
|
166
|
+
if (value.startsWith(" "))
|
|
167
|
+
value = value.slice(1);
|
|
168
|
+
if (field === "data")
|
|
169
|
+
dataLines.push(value);
|
|
170
|
+
else if (field === "id")
|
|
171
|
+
frame.id = value;
|
|
172
|
+
else if (field === "retry") {
|
|
173
|
+
const parsed = Number(value);
|
|
174
|
+
if (Number.isFinite(parsed))
|
|
175
|
+
frame.retry = parsed;
|
|
176
|
+
}
|
|
177
|
+
// `event:` names pass through untyped for now — the contract types the data payload.
|
|
178
|
+
};
|
|
179
|
+
try {
|
|
180
|
+
for (;;) {
|
|
181
|
+
const { done, value } = await reader.read();
|
|
182
|
+
if (done)
|
|
183
|
+
break;
|
|
184
|
+
buffer += decoder.decode(value, { stream: true });
|
|
185
|
+
for (;;) {
|
|
186
|
+
const newline = buffer.indexOf("\n");
|
|
187
|
+
if (newline === -1)
|
|
188
|
+
break;
|
|
189
|
+
const line = buffer.slice(0, newline).replace(/\r$/, "");
|
|
190
|
+
buffer = buffer.slice(newline + 1);
|
|
191
|
+
handleLine(line);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
buffer += decoder.decode();
|
|
195
|
+
if (buffer !== "")
|
|
196
|
+
handleLine(buffer.replace(/\r$/, ""));
|
|
197
|
+
dispatch(); // an unterminated final frame still dispatches
|
|
198
|
+
}
|
|
199
|
+
finally {
|
|
200
|
+
reader.releaseLock();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The `.subscribe()` runtime for `app.sse()` routes. fetch-based (never `EventSource`), so it
|
|
205
|
+
* streams over the configured fetcher — network, an in-process bridge, or a test mock — with
|
|
206
|
+
* EventSource semantics where they matter: auto-reconnect with backoff + jitter (honoring the
|
|
207
|
+
* server's `retry:` hint), `Last-Event-ID` resumption, JSON-parsed typed events. Never throws:
|
|
208
|
+
* failures reach `onError`; a terminal end reaches `onClose`.
|
|
209
|
+
*/
|
|
210
|
+
function subscribeSse(base, path, onEvent, callOptions, options) {
|
|
211
|
+
const controller = new AbortController();
|
|
212
|
+
let closed = false;
|
|
213
|
+
let lastEventId;
|
|
214
|
+
let serverRetryMs;
|
|
215
|
+
const reconnectConfig = callOptions?.reconnect ?? true;
|
|
216
|
+
const reconnectEnabled = reconnectConfig !== false;
|
|
217
|
+
const baseDelayMs = (typeof reconnectConfig === "object" ? reconnectConfig.baseDelayMs : undefined) ?? 1_000;
|
|
218
|
+
const maxDelayMs = (typeof reconnectConfig === "object" ? reconnectConfig.maxDelayMs : undefined) ?? 15_000;
|
|
219
|
+
if (callOptions?.signal !== undefined) {
|
|
220
|
+
if (callOptions.signal.aborted)
|
|
221
|
+
closed = true;
|
|
222
|
+
else
|
|
223
|
+
callOptions.signal.addEventListener("abort", () => close(), { once: true });
|
|
224
|
+
}
|
|
225
|
+
const close = () => {
|
|
226
|
+
if (closed)
|
|
227
|
+
return;
|
|
228
|
+
closed = true;
|
|
229
|
+
controller.abort();
|
|
230
|
+
callOptions?.onClose?.();
|
|
231
|
+
};
|
|
232
|
+
let url = base + (path === "" ? "/" : path);
|
|
233
|
+
const query = callOptions?.query ? buildQuery(callOptions.query) : "";
|
|
234
|
+
if (query !== "")
|
|
235
|
+
url += `?${query}`;
|
|
236
|
+
const doFetch = options.fetch ?? fetch;
|
|
237
|
+
const delay = (ms) => new Promise((resolve) => {
|
|
238
|
+
const timer = setTimeout(resolve, ms);
|
|
239
|
+
timer.unref?.();
|
|
240
|
+
controller.signal.addEventListener("abort", () => {
|
|
241
|
+
clearTimeout(timer);
|
|
242
|
+
resolve();
|
|
243
|
+
}, { once: true });
|
|
244
|
+
});
|
|
245
|
+
void (async () => {
|
|
246
|
+
let attempt = 0;
|
|
247
|
+
while (!closed) {
|
|
248
|
+
try {
|
|
249
|
+
const headers = {
|
|
250
|
+
...options.headers,
|
|
251
|
+
...callOptions?.headers,
|
|
252
|
+
accept: "text/event-stream",
|
|
253
|
+
...(lastEventId !== undefined ? { "last-event-id": lastEventId } : {}),
|
|
254
|
+
};
|
|
255
|
+
const response = await doFetch(url, { headers, signal: controller.signal });
|
|
256
|
+
if (!response.ok || response.body === null) {
|
|
257
|
+
throw new Error(`sse_http_${response.status}`);
|
|
258
|
+
}
|
|
259
|
+
attempt = 0; // a successful connect resets the backoff
|
|
260
|
+
await readSseStream(response.body, (frame) => {
|
|
261
|
+
if (frame.id !== undefined)
|
|
262
|
+
lastEventId = frame.id;
|
|
263
|
+
if (frame.retry !== undefined)
|
|
264
|
+
serverRetryMs = frame.retry;
|
|
265
|
+
if (frame.data !== undefined) {
|
|
266
|
+
try {
|
|
267
|
+
onEvent(JSON.parse(frame.data));
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
callOptions?.onError?.(error);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
// Clean server-side end: a finite stream (`reconnect: false`) completes here.
|
|
275
|
+
if (!reconnectEnabled) {
|
|
276
|
+
close();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
if (closed || controller.signal.aborted)
|
|
282
|
+
return;
|
|
283
|
+
callOptions?.onError?.(error);
|
|
284
|
+
if (!reconnectEnabled) {
|
|
285
|
+
close();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (closed)
|
|
290
|
+
return;
|
|
291
|
+
const backoff = Math.min(maxDelayMs, baseDelayMs * 2 ** attempt);
|
|
292
|
+
attempt = Math.min(attempt + 1, 10);
|
|
293
|
+
const wait = serverRetryMs ?? backoff / 2 + Math.random() * (backoff / 2);
|
|
294
|
+
await delay(wait);
|
|
295
|
+
}
|
|
296
|
+
})();
|
|
297
|
+
return { close };
|
|
298
|
+
}
|
|
130
299
|
function buildQuery(query) {
|
|
131
300
|
const params = new URLSearchParams();
|
|
132
301
|
for (const [key, value] of Object.entries(query)) {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,SAAS;CACV,CAAC,CAAA;AACF,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;AA0CzE,MAAM,UAAU,MAAM,CACpB,IAA4B,EAC5B,IAA6B,EAC7B,IAAoB;IAEpB,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAAe,CAAA;IAClE,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAkC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;IAC7F,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;IACnE,+EAA+E;IAC/E,6EAA6E;IAC7E,oCAAoC;IACpC,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACvC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAE7B,GAAQ,EAAE,OAAsC;IAChD,oGAAoG;IACpG,kGAAkG;IAClG,kCAAkC;IAClC,MAAM,MAAM,GAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IACzF,MAAM,KAAK,GAAG,MAAM,CAAM,uBAAuB,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACjF,gGAAgG;IAChG,iGAAiG;IACjG,mGAAmG;IACnG,6FAA6F;IAC7F,OAAO,IAAI,KAAK,CAAC,KAAe,EAAE;QAChC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ;YAC5B,IAAI,GAAG,KAAK,OAAO;gBAAE,OAAO,MAAM,CAAA;YAClC,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QAChD,CAAC;KACF,CAAgB,CAAA;AACnB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CAAA;AAEzC,SAAS,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,OAAsB;IACrE,MAAM,MAAM,GAAG,GAAS,EAAE,GAAE,CAAC,CAAA;IAC7B,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,GAAG,CAAC,OAAO,EAAE,GAAG;YACd,4EAA4E;YAC5E,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAA;YAC/D,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBACtC,OAAO,CAAC,GAAG,IAAe,EAA4B,EAAE,CACtD,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;YACzD,CAAC;YACD,2DAA2D;YAC3D,OAAO,WAAW,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;QAC9E,CAAC;QACD,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI;YAC3B,sFAAsF;YACtF,wFAAwF;YACxF,yFAAyF;YACzF,8FAA8F;YAC9F,6FAA6F;YAC7F,2FAA2F;YAC3F,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACrB,MAAM,KAAK,GACT,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;gBACzC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC,CAAC,CAAC,CAAC;gBACpD,CAAC,CAAC,KAAK,CAAA;YACX,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;YAClF,OAAO,WAAW,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACnF,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,IAAe,EACf,OAAsB;IAEtB,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7C,MAAM,WAAW,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAA4B,CAAA;IAE/E,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACrE,IAAI,KAAK,KAAK,EAAE;QAAE,GAAG,IAAI,IAAI,KAAK,EAAE,CAAA;IAEpC,MAAM,OAAO,GAA2B,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE,OAAO,EAAE,CAAA;IACvF,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAA;IACjE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAChC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAA;IAC9C,CAAC;IACD,IAAI,WAAW,EAAE,MAAM;QAAE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAA;IAEzD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAA;IACtC,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,CAAA;IAChF,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAA;IACtC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACjE,CAAC;IACD,+FAA+F;IAC/F,kEAAkE;IAClE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAA;AAC9E,CAAC;AAED,SAAS,UAAU,CAAC,KAA8B;IAChD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAA;AAC1B,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,QAAkB;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,SAAS,CAAA;IAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAClC,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA,CAAC,iEAAiE;IAC/E,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAa;IAC/B,IACE,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,OAAO,IAAI,IAAI;QACf,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAC9B,CAAC;QACD,wEAAwE;QACxE,MAAM,MAAM,GACV,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5C,CAAC,CAAE,IAAI,CAAC,MAA6B;YACrC,CAAC,CAAC,SAAS,CAAA;QACf,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;IACrF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAA;AACpC,CAAC"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,5 +8,5 @@ export { type ClientOptions, client, type FetchFn, inProcessClient, testClient,
|
|
|
8
8
|
export type { Jsonify } from "./jsonify.js";
|
|
9
9
|
export type { ApiError, Result } from "./result.js";
|
|
10
10
|
export type { ActionArgs, ActionData, ApiProxy, LoaderArgs, LoaderData } from "./routes.js";
|
|
11
|
-
export type { RegistryOf, Treaty, TreatyFromRegistry } from "./treaty.js";
|
|
11
|
+
export type { RegistryOf, SubscribeOptions, Subscription, Treaty, TreatyFromRegistry, } from "./treaty.js";
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,KAAK,aAAa,EAClB,MAAM,EACN,KAAK,OAAO,EACZ,eAAe,EACf,UAAU,GACX,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3F,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,KAAK,aAAa,EAClB,MAAM,EACN,KAAK,OAAO,EACZ,eAAe,EACf,UAAU,GACX,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3F,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,kBAAkB,GACnB,MAAM,aAAa,CAAA"}
|
package/dist/treaty.d.ts
CHANGED
|
@@ -25,9 +25,44 @@ type IsBodyVerb<M extends string> = M extends "POST" | "PUT" | "PATCH" ? true :
|
|
|
25
25
|
* (`Jsonify`).
|
|
26
26
|
*/
|
|
27
27
|
type MethodCall<I extends RouteInfo, BodyVerb extends boolean> = BodyVerb extends true ? [I["body"]] extends [never] ? (body?: undefined, options?: CallOptions<I>) => Promise<Result<Jsonify<I["output"]>, Jsonify<I["errors"]>>> : (body: I["body"], options?: CallOptions<I>) => Promise<Result<Jsonify<I["output"]>, Jsonify<I["errors"]>>> : (options?: CallOptions<I>) => Promise<Result<Jsonify<I["output"]>, Jsonify<I["errors"]>>>;
|
|
28
|
+
/** The SSE event payload of a route (from `app.sse()`'s `sse` schema); `never` for ordinary routes. */
|
|
29
|
+
type SseOf<I> = I extends {
|
|
30
|
+
sse: infer E;
|
|
31
|
+
} ? ([E] extends [never] ? never : E) : never;
|
|
32
|
+
export interface SubscribeOptions<I extends RouteInfo> {
|
|
33
|
+
query?: [I["query"]] extends [never] ? QueryNotTyped : I["query"];
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
/** Abort to close the subscription (same effect as calling `close()`). */
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
/**
|
|
38
|
+
* Reconnect after a dropped/errored stream (default true — EventSource semantics, so a proxy
|
|
39
|
+
* closing an idle feed doesn't silently kill it). A FINITE stream should pass `false` so a clean
|
|
40
|
+
* server-side end completes the subscription instead of replaying it. Delays follow exponential
|
|
41
|
+
* backoff with jitter, honoring the server's `retry:` hint when sent.
|
|
42
|
+
*/
|
|
43
|
+
reconnect?: boolean | {
|
|
44
|
+
baseDelayMs?: number;
|
|
45
|
+
maxDelayMs?: number;
|
|
46
|
+
};
|
|
47
|
+
/** Stream-level failures (network drop, non-2xx, bad JSON). Reconnection continues regardless. */
|
|
48
|
+
onError?: (error: unknown) => void;
|
|
49
|
+
/** The stream ended and no reconnect will follow (clean end with `reconnect: false`, or closed). */
|
|
50
|
+
onClose?: () => void;
|
|
51
|
+
}
|
|
52
|
+
export interface Subscription {
|
|
53
|
+
/** Stop the subscription: aborts the live stream and cancels any pending reconnect. */
|
|
54
|
+
close(): void;
|
|
55
|
+
}
|
|
56
|
+
type SubscribeCall<I extends RouteInfo> = (onEvent: (event: Jsonify<SseOf<I>>) => void, options?: SubscribeOptions<I>) => Subscription;
|
|
57
|
+
/** Routes declared via `app.sse()` grow a `.subscribe()` beside their verbs. */
|
|
58
|
+
type SseMethods<MethodMap> = MethodMap extends {
|
|
59
|
+
GET: infer G;
|
|
60
|
+
} ? [SseOf<G>] extends [never] ? unknown : {
|
|
61
|
+
subscribe: SubscribeCall<G & RouteInfo>;
|
|
62
|
+
} : unknown;
|
|
28
63
|
type Methods<MethodMap> = {
|
|
29
64
|
[M in keyof MethodMap as Lowercase<M & string>]: MethodCall<MethodMap[M] & RouteInfo, IsBodyVerb<M & string>>;
|
|
30
|
-
}
|
|
65
|
+
} & SseMethods<MethodMap>;
|
|
31
66
|
type Sub<R, Prefix extends string> = Extract<keyof R, `${Prefix}/${string}`>;
|
|
32
67
|
type NextSeg<Prefix extends string, Path extends string> = Path extends `${Prefix}/${infer Seg}/${string}` ? Seg : Path extends `${Prefix}/${infer Seg}` ? Seg : never;
|
|
33
68
|
type NextSegs<R, Prefix extends string> = {
|
package/dist/treaty.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treaty.d.ts","sourceRoot":"","sources":["../src/treaty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,mHAAmH;AACnH,MAAM,MAAM,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAIjF;;;;;GAKG;AACH,KAAK,aAAa,GAChB,sHAAsH,CAAA;AAExH,KAAK,WAAW,CAAC,CAAC,SAAS,SAAS,IAAI;IACtC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AAED,KAAK,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAA;AAErF;;;;;;;GAOG;AACH,KAAK,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,QAAQ,SAAS,OAAO,IAAI,QAAQ,SAAS,IAAI,GAClF,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACzB,CACE,IAAI,CAAC,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KACrB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAChE,CACE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EACf,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KACrB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAClE,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"treaty.d.ts","sourceRoot":"","sources":["../src/treaty.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Browser-safe, end-to-end-typed client for @nifrajs/core servers (Eden-style proxy).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@nifrajs/core": "^1.
|
|
42
|
+
"@nifrajs/core": "^1.5.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@nifrajs/core": "workspace:*",
|
package/src/client.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ContractShape, RegistryFor } from "@nifrajs/core"
|
|
2
2
|
import type { ApiError, Result } from "./result.ts"
|
|
3
|
-
import type { Treaty, TreatyFromRegistry } from "./treaty.ts"
|
|
3
|
+
import type { Subscription, Treaty, TreatyFromRegistry } from "./treaty.ts"
|
|
4
4
|
|
|
5
5
|
const HTTP_VERBS: ReadonlySet<string> = new Set([
|
|
6
6
|
"get",
|
|
@@ -128,6 +128,13 @@ function createProxy(base: string, path: string, options: ClientOptions): unknow
|
|
|
128
128
|
return (...args: unknown[]): Promise<Result<unknown>> =>
|
|
129
129
|
execute(base, path, key.toLowerCase(), args, options)
|
|
130
130
|
}
|
|
131
|
+
// Typed SSE subscription for `app.sse()` routes. Like `fetch` on the in-process client,
|
|
132
|
+
// `subscribe` is a reserved proxy key — a literal `/subscribe` path segment is unreachable
|
|
133
|
+
// through the typed proxy (no nifra app defines one reached this way).
|
|
134
|
+
if (key === "subscribe") {
|
|
135
|
+
return (onEvent: (event: unknown) => void, subscribeOptions?: SubscribeCallOptions) =>
|
|
136
|
+
subscribeSse(base, path, onEvent, subscribeOptions, options)
|
|
137
|
+
}
|
|
131
138
|
// `index` addresses the root path "/" and adds no segment.
|
|
132
139
|
return createProxy(base, key === "index" ? path : `${path}/${key}`, options)
|
|
133
140
|
},
|
|
@@ -189,6 +196,195 @@ async function execute(
|
|
|
189
196
|
return { ok: false, status: response.status, data, error: toApiError(data) }
|
|
190
197
|
}
|
|
191
198
|
|
|
199
|
+
// --- typed SSE subscriptions (fetch-based, so it works over ANY fetcher: network, in-process, tests) ---
|
|
200
|
+
|
|
201
|
+
interface SubscribeCallOptions {
|
|
202
|
+
readonly query?: Record<string, unknown>
|
|
203
|
+
readonly headers?: Record<string, string>
|
|
204
|
+
readonly signal?: AbortSignal
|
|
205
|
+
readonly reconnect?: boolean | { baseDelayMs?: number; maxDelayMs?: number }
|
|
206
|
+
readonly onError?: (error: unknown) => void
|
|
207
|
+
readonly onClose?: () => void
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** One parsed SSE frame (the fields the client consumes). */
|
|
211
|
+
interface SseFrame {
|
|
212
|
+
data?: string
|
|
213
|
+
id?: string
|
|
214
|
+
retry?: number
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Incrementally parse a `text/event-stream` body, invoking `onFrame` per dispatched event.
|
|
219
|
+
* Implements the SSE wire format: `data:` accumulates multi-line, `id:`/`retry:` update stream
|
|
220
|
+
* state, `:` lines are comments, a blank line dispatches.
|
|
221
|
+
*/
|
|
222
|
+
async function readSseStream(
|
|
223
|
+
body: ReadableStream<Uint8Array>,
|
|
224
|
+
onFrame: (frame: SseFrame) => void,
|
|
225
|
+
): Promise<void> {
|
|
226
|
+
const reader = body.getReader()
|
|
227
|
+
const decoder = new TextDecoder()
|
|
228
|
+
let buffer = ""
|
|
229
|
+
let dataLines: string[] = []
|
|
230
|
+
let frame: SseFrame = {}
|
|
231
|
+
|
|
232
|
+
const dispatch = (): void => {
|
|
233
|
+
if (dataLines.length > 0) frame.data = dataLines.join("\n")
|
|
234
|
+
if (frame.data !== undefined || frame.id !== undefined || frame.retry !== undefined) {
|
|
235
|
+
onFrame(frame)
|
|
236
|
+
}
|
|
237
|
+
dataLines = []
|
|
238
|
+
frame = {}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const handleLine = (line: string): void => {
|
|
242
|
+
if (line === "") {
|
|
243
|
+
dispatch()
|
|
244
|
+
return
|
|
245
|
+
}
|
|
246
|
+
if (line.startsWith(":")) return // comment / keep-alive
|
|
247
|
+
const colon = line.indexOf(":")
|
|
248
|
+
const field = colon === -1 ? line : line.slice(0, colon)
|
|
249
|
+
let value = colon === -1 ? "" : line.slice(colon + 1)
|
|
250
|
+
if (value.startsWith(" ")) value = value.slice(1)
|
|
251
|
+
if (field === "data") dataLines.push(value)
|
|
252
|
+
else if (field === "id") frame.id = value
|
|
253
|
+
else if (field === "retry") {
|
|
254
|
+
const parsed = Number(value)
|
|
255
|
+
if (Number.isFinite(parsed)) frame.retry = parsed
|
|
256
|
+
}
|
|
257
|
+
// `event:` names pass through untyped for now — the contract types the data payload.
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
for (;;) {
|
|
262
|
+
const { done, value } = await reader.read()
|
|
263
|
+
if (done) break
|
|
264
|
+
buffer += decoder.decode(value, { stream: true })
|
|
265
|
+
for (;;) {
|
|
266
|
+
const newline = buffer.indexOf("\n")
|
|
267
|
+
if (newline === -1) break
|
|
268
|
+
const line = buffer.slice(0, newline).replace(/\r$/, "")
|
|
269
|
+
buffer = buffer.slice(newline + 1)
|
|
270
|
+
handleLine(line)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
buffer += decoder.decode()
|
|
274
|
+
if (buffer !== "") handleLine(buffer.replace(/\r$/, ""))
|
|
275
|
+
dispatch() // an unterminated final frame still dispatches
|
|
276
|
+
} finally {
|
|
277
|
+
reader.releaseLock()
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* The `.subscribe()` runtime for `app.sse()` routes. fetch-based (never `EventSource`), so it
|
|
283
|
+
* streams over the configured fetcher — network, an in-process bridge, or a test mock — with
|
|
284
|
+
* EventSource semantics where they matter: auto-reconnect with backoff + jitter (honoring the
|
|
285
|
+
* server's `retry:` hint), `Last-Event-ID` resumption, JSON-parsed typed events. Never throws:
|
|
286
|
+
* failures reach `onError`; a terminal end reaches `onClose`.
|
|
287
|
+
*/
|
|
288
|
+
function subscribeSse(
|
|
289
|
+
base: string,
|
|
290
|
+
path: string,
|
|
291
|
+
onEvent: (event: unknown) => void,
|
|
292
|
+
callOptions: SubscribeCallOptions | undefined,
|
|
293
|
+
options: ClientOptions,
|
|
294
|
+
): Subscription {
|
|
295
|
+
const controller = new AbortController()
|
|
296
|
+
let closed = false
|
|
297
|
+
let lastEventId: string | undefined
|
|
298
|
+
let serverRetryMs: number | undefined
|
|
299
|
+
|
|
300
|
+
const reconnectConfig = callOptions?.reconnect ?? true
|
|
301
|
+
const reconnectEnabled = reconnectConfig !== false
|
|
302
|
+
const baseDelayMs =
|
|
303
|
+
(typeof reconnectConfig === "object" ? reconnectConfig.baseDelayMs : undefined) ?? 1_000
|
|
304
|
+
const maxDelayMs =
|
|
305
|
+
(typeof reconnectConfig === "object" ? reconnectConfig.maxDelayMs : undefined) ?? 15_000
|
|
306
|
+
|
|
307
|
+
if (callOptions?.signal !== undefined) {
|
|
308
|
+
if (callOptions.signal.aborted) closed = true
|
|
309
|
+
else callOptions.signal.addEventListener("abort", () => close(), { once: true })
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const close = (): void => {
|
|
313
|
+
if (closed) return
|
|
314
|
+
closed = true
|
|
315
|
+
controller.abort()
|
|
316
|
+
callOptions?.onClose?.()
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let url = base + (path === "" ? "/" : path)
|
|
320
|
+
const query = callOptions?.query ? buildQuery(callOptions.query) : ""
|
|
321
|
+
if (query !== "") url += `?${query}`
|
|
322
|
+
const doFetch = options.fetch ?? fetch
|
|
323
|
+
|
|
324
|
+
const delay = (ms: number): Promise<void> =>
|
|
325
|
+
new Promise((resolve) => {
|
|
326
|
+
const timer = setTimeout(resolve, ms)
|
|
327
|
+
;(timer as { unref?: () => void }).unref?.()
|
|
328
|
+
controller.signal.addEventListener(
|
|
329
|
+
"abort",
|
|
330
|
+
() => {
|
|
331
|
+
clearTimeout(timer)
|
|
332
|
+
resolve()
|
|
333
|
+
},
|
|
334
|
+
{ once: true },
|
|
335
|
+
)
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
void (async () => {
|
|
339
|
+
let attempt = 0
|
|
340
|
+
while (!closed) {
|
|
341
|
+
try {
|
|
342
|
+
const headers: Record<string, string> = {
|
|
343
|
+
...options.headers,
|
|
344
|
+
...callOptions?.headers,
|
|
345
|
+
accept: "text/event-stream",
|
|
346
|
+
...(lastEventId !== undefined ? { "last-event-id": lastEventId } : {}),
|
|
347
|
+
}
|
|
348
|
+
const response = await doFetch(url, { headers, signal: controller.signal })
|
|
349
|
+
if (!response.ok || response.body === null) {
|
|
350
|
+
throw new Error(`sse_http_${response.status}`)
|
|
351
|
+
}
|
|
352
|
+
attempt = 0 // a successful connect resets the backoff
|
|
353
|
+
await readSseStream(response.body, (frame) => {
|
|
354
|
+
if (frame.id !== undefined) lastEventId = frame.id
|
|
355
|
+
if (frame.retry !== undefined) serverRetryMs = frame.retry
|
|
356
|
+
if (frame.data !== undefined) {
|
|
357
|
+
try {
|
|
358
|
+
onEvent(JSON.parse(frame.data))
|
|
359
|
+
} catch (error) {
|
|
360
|
+
callOptions?.onError?.(error)
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
})
|
|
364
|
+
// Clean server-side end: a finite stream (`reconnect: false`) completes here.
|
|
365
|
+
if (!reconnectEnabled) {
|
|
366
|
+
close()
|
|
367
|
+
return
|
|
368
|
+
}
|
|
369
|
+
} catch (error) {
|
|
370
|
+
if (closed || controller.signal.aborted) return
|
|
371
|
+
callOptions?.onError?.(error)
|
|
372
|
+
if (!reconnectEnabled) {
|
|
373
|
+
close()
|
|
374
|
+
return
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (closed) return
|
|
378
|
+
const backoff = Math.min(maxDelayMs, baseDelayMs * 2 ** attempt)
|
|
379
|
+
attempt = Math.min(attempt + 1, 10)
|
|
380
|
+
const wait = serverRetryMs ?? backoff / 2 + Math.random() * (backoff / 2)
|
|
381
|
+
await delay(wait)
|
|
382
|
+
}
|
|
383
|
+
})()
|
|
384
|
+
|
|
385
|
+
return { close }
|
|
386
|
+
}
|
|
387
|
+
|
|
192
388
|
function buildQuery(query: Record<string, unknown>): string {
|
|
193
389
|
const params = new URLSearchParams()
|
|
194
390
|
for (const [key, value] of Object.entries(query)) {
|
package/src/index.ts
CHANGED
|
@@ -14,4 +14,10 @@ export {
|
|
|
14
14
|
export type { Jsonify } from "./jsonify.ts"
|
|
15
15
|
export type { ApiError, Result } from "./result.ts"
|
|
16
16
|
export type { ActionArgs, ActionData, ApiProxy, LoaderArgs, LoaderData } from "./routes.ts"
|
|
17
|
-
export type {
|
|
17
|
+
export type {
|
|
18
|
+
RegistryOf,
|
|
19
|
+
SubscribeOptions,
|
|
20
|
+
Subscription,
|
|
21
|
+
Treaty,
|
|
22
|
+
TreatyFromRegistry,
|
|
23
|
+
} from "./treaty.ts"
|
package/src/treaty.ts
CHANGED
|
@@ -44,12 +44,52 @@ type MethodCall<I extends RouteInfo, BodyVerb extends boolean> = BodyVerb extend
|
|
|
44
44
|
) => Promise<Result<Jsonify<I["output"]>, Jsonify<I["errors"]>>>
|
|
45
45
|
: (options?: CallOptions<I>) => Promise<Result<Jsonify<I["output"]>, Jsonify<I["errors"]>>>
|
|
46
46
|
|
|
47
|
+
// --- typed SSE subscriptions ---
|
|
48
|
+
|
|
49
|
+
/** The SSE event payload of a route (from `app.sse()`'s `sse` schema); `never` for ordinary routes. */
|
|
50
|
+
type SseOf<I> = I extends { sse: infer E } ? ([E] extends [never] ? never : E) : never
|
|
51
|
+
|
|
52
|
+
export interface SubscribeOptions<I extends RouteInfo> {
|
|
53
|
+
query?: [I["query"]] extends [never] ? QueryNotTyped : I["query"]
|
|
54
|
+
headers?: Record<string, string>
|
|
55
|
+
/** Abort to close the subscription (same effect as calling `close()`). */
|
|
56
|
+
signal?: AbortSignal
|
|
57
|
+
/**
|
|
58
|
+
* Reconnect after a dropped/errored stream (default true — EventSource semantics, so a proxy
|
|
59
|
+
* closing an idle feed doesn't silently kill it). A FINITE stream should pass `false` so a clean
|
|
60
|
+
* server-side end completes the subscription instead of replaying it. Delays follow exponential
|
|
61
|
+
* backoff with jitter, honoring the server's `retry:` hint when sent.
|
|
62
|
+
*/
|
|
63
|
+
reconnect?: boolean | { baseDelayMs?: number; maxDelayMs?: number }
|
|
64
|
+
/** Stream-level failures (network drop, non-2xx, bad JSON). Reconnection continues regardless. */
|
|
65
|
+
onError?: (error: unknown) => void
|
|
66
|
+
/** The stream ended and no reconnect will follow (clean end with `reconnect: false`, or closed). */
|
|
67
|
+
onClose?: () => void
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface Subscription {
|
|
71
|
+
/** Stop the subscription: aborts the live stream and cancels any pending reconnect. */
|
|
72
|
+
close(): void
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type SubscribeCall<I extends RouteInfo> = (
|
|
76
|
+
onEvent: (event: Jsonify<SseOf<I>>) => void,
|
|
77
|
+
options?: SubscribeOptions<I>,
|
|
78
|
+
) => Subscription
|
|
79
|
+
|
|
80
|
+
/** Routes declared via `app.sse()` grow a `.subscribe()` beside their verbs. */
|
|
81
|
+
type SseMethods<MethodMap> = MethodMap extends { GET: infer G }
|
|
82
|
+
? [SseOf<G>] extends [never]
|
|
83
|
+
? unknown
|
|
84
|
+
: { subscribe: SubscribeCall<G & RouteInfo> }
|
|
85
|
+
: unknown
|
|
86
|
+
|
|
47
87
|
type Methods<MethodMap> = {
|
|
48
88
|
[M in keyof MethodMap as Lowercase<M & string>]: MethodCall<
|
|
49
89
|
MethodMap[M] & RouteInfo,
|
|
50
90
|
IsBodyVerb<M & string>
|
|
51
91
|
>
|
|
52
|
-
}
|
|
92
|
+
} & SseMethods<MethodMap>
|
|
53
93
|
|
|
54
94
|
// --- path-tree construction over the registry ---
|
|
55
95
|
|