@rindle/api-server 0.7.11 → 0.8.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.
@@ -0,0 +1,373 @@
1
+ import type { StreamFrame, StreamStatus } from "@rindle/client";
2
+ import type { Authorizer, ServerSql, SqlDialect } from "./index.ts";
3
+ export { STREAM_STATUS_STREAMING, assembleDurableText, frameResumePoint, spliceStreamText, } from "@rindle/client";
4
+ export type { StreamFrame, StreamStatus } from "@rindle/client";
5
+ /** What a checkpoint hands the durable plane when the app supplies its own {@link StreamCommit}. */
6
+ export type StreamCommitInput =
7
+ /** The pointer is marked live. The app's own mutator created the row (it owns `chatId`, `role`,
8
+ * the model name…); this only flips it to `streaming`. */
9
+ {
10
+ kind: "open";
11
+ streamId: string;
12
+ meta: unknown;
13
+ hostId?: string;
14
+ startedAt: number;
15
+ }
16
+ /** A prefix advance carrying ONLY its own slice. `text.length === seq - from`, and `from` is the
17
+ * last append the PLANE saw confirmed — so appends are contiguous in the fault-free run, but an
18
+ * append that committed while its ack was lost makes the next one RE-COVER (its `from` lags what
19
+ * the app already applied). See {@link StreamCommit} for the two ways to stay idempotent. */
20
+ | {
21
+ kind: "append";
22
+ streamId: string;
23
+ from: number;
24
+ seq: number;
25
+ text: string;
26
+ }
27
+ /** The seal. `body` is the producer's retained text and `bodyFrom` its absolute start offset:
28
+ * `bodyFrom === 0` — and `body` is the WHOLE response — unless the app opted into trimming via
29
+ * `retainChars` (`commit` mode only). A compacting app requires `bodyFrom === 0` and writes
30
+ * `body` wholesale; a non-compacting app appends the outstanding tail —
31
+ * `body.slice(from - bodyFrom)` — as a final chunk. `seq === bodyFrom + body.length`, always. */
32
+ | {
33
+ kind: "close";
34
+ streamId: string;
35
+ from: number;
36
+ seq: number;
37
+ body: string;
38
+ bodyFrom: number;
39
+ status: StreamStatus;
40
+ error?: string;
41
+ };
42
+ /** The escape hatch: persist the checkpoint however the app likes. Retried on throw (§3.3), so it
43
+ * must be idempotent under a repeated `(from, seq)` — AND under a RE-COVER: an append whose write
44
+ * committed but whose ack was lost leaves the plane believing less than the store holds, so the
45
+ * next append's `(from, seq)` can OVERLAP text already applied. Apply only the unseen suffix
46
+ * (`text.slice(applied - from)` when `applied > from`), or better, return `{seq: applied}` — the
47
+ * authoritative applied length — and the plane resynchronizes instead of re-covering at all.
48
+ * Return `{cancelRequested: true}` to tell the producer the reader asked it to stop (§6). */
49
+ export type StreamCommit = (input: StreamCommitInput) => Promise<void | {
50
+ cancelRequested?: boolean;
51
+ seq?: number;
52
+ }>;
53
+ /** Which columns of the app's own tables the plane reads and writes. Every entry has a default
54
+ * except `cancel`, `error`, and `host`, which are opt-in BY NAMING: the plane never emits SQL
55
+ * against a column the app did not ask it to use. */
56
+ export interface StreamColumns {
57
+ /** The message row's primary key, matched against `streamId`. Default `id`. */
58
+ key?: string;
59
+ /** The compacted response text. Default `body`. */
60
+ body?: string;
61
+ /** {@link STREAM_STATUS_STREAMING} then a {@link StreamStatus}. Default `status`. */
62
+ status?: string;
63
+ /** Total durable length — `length(body) + Σ chunk lengths`. The CAS column (§3.2). Default `seq`. */
64
+ seq?: string;
65
+ /** Opt-in (§6): a truthy value here stops the generation at the next checkpoint. No default —
66
+ * naming it is what turns cancellation on. */
67
+ cancel?: string;
68
+ /** Opt-in: where a failed generation's message is recorded. No default. */
69
+ error?: string;
70
+ /** Opt-in: where the open write records this producer's identity ({@link RindleStreamOptions.hostId}).
71
+ * Naming it upgrades the row-level single-flight guard from check-then-act to a true
72
+ * compare-and-swap — the open write turns conditional and a read-back names the winner (§5.1) —
73
+ * and gives multi-instance subscribe routing a column to read (§4). No default. */
74
+ host?: string;
75
+ /** Chunk primary key; the plane writes the deterministic `"<streamId>:<seq>"`. Default `id`. */
76
+ chunkKey?: string;
77
+ /** Chunk → message reference. Default `streamId`. */
78
+ chunkStream?: string;
79
+ /** The chunk's END offset — the ordering key. Default `seq`. */
80
+ chunkSeq?: string;
81
+ /** The chunk's slice of the response. Default `text`. */
82
+ chunkText?: string;
83
+ }
84
+ /**
85
+ * The app's tables (§5). The app authors and migrates BOTH — the message row is unambiguously
86
+ * app-owned (it has `chatId`, `role`, token counts) and the chunk row must be reachable from the
87
+ * app's own query as a `related` subquery, which a Rindle system table would make awkward. The plane
88
+ * only needs to be told where things live. Use {@link streamChunkTableDdl} for the chunk table's
89
+ * migration.
90
+ *
91
+ * The message table carries WHATEVER ELSE the app wants; the plane's hard requirements are only:
92
+ *
93
+ * | mapped column | requirement | why |
94
+ * | --- | --- | --- |
95
+ * | `key` | UNIQUE (normally the pk) | every checkpoint targets one row by it |
96
+ * | `seq` | integer, **NOT NULL DEFAULT 0** | the CAS column — nothing matches NULL (§3.2) |
97
+ * | `body` | text, empty at open | compaction overwrites it with the whole response |
98
+ * | `status` | text accepting `streaming`/`complete`/`cancelled`/`error`/`interrupted` | a CHECK
99
+ * constraint that omits one of these turns a seal into an infra failure |
100
+ * | `cancel` | truthy-readable, if mapped | read on the checkpoint round-trip (§6) |
101
+ * | `error` | nullable text, if mapped | compaction writes `NULL` when there is no error |
102
+ * | `host` | text, if mapped | written at open with the producer's token; the read-back decides the open race (§5.1) |
103
+ *
104
+ * `body` is PLANE-OWNED and always a bare string. Rich content (an array of content blocks, tool
105
+ * calls, attachments) belongs in SIBLING columns the app's own mutators write — `flush()` orders the
106
+ * text before them. For genuinely multi-block streaming, point `message` at a per-BLOCK table
107
+ * instead: `streamId` is just an app key, so one stream per block needs nothing from this plane.
108
+ */
109
+ export interface StreamTables {
110
+ /** The app's message table. Must already contain the row when {@link StreamPlane.open} runs. */
111
+ message: string;
112
+ /** The append-only chunk table. */
113
+ chunks: string;
114
+ columns?: StreamColumns;
115
+ }
116
+ export type StreamCheckpointTarget = {
117
+ tables: StreamTables;
118
+ } | {
119
+ commit: StreamCommit;
120
+ };
121
+ /** When a checkpoint fires — the FIRST of these wins (§3.1). Checkpoints are serialized, so a slow
122
+ * store degrades to fewer, larger checkpoints, never to a queue of them. */
123
+ export interface StreamCheckpointPolicy {
124
+ /** Produced-but-uncommitted characters that force a checkpoint. Default 512. */
125
+ chars?: number;
126
+ /** Milliseconds since the last checkpoint that force one. Default 750. */
127
+ intervalMs?: number;
128
+ /** Retries for a failing commit before the slice is left for the next trigger. Default 3. */
129
+ retries?: number;
130
+ }
131
+ export interface AuthorizeStreamInput<User> {
132
+ user: User;
133
+ streamId: string;
134
+ /** Where the subscriber claims to be. */
135
+ from: number;
136
+ /** The `meta` this stream was opened with — `undefined` when the stream is not hosted here, which
137
+ * is precisely when the app must decide from `streamId` and its own durable state. */
138
+ meta: unknown;
139
+ request?: unknown;
140
+ }
141
+ export interface RindleStreamOptions<User> {
142
+ /** Where checkpoints land: the app's tables (the default path) or a raw `commit` callback. */
143
+ checkpoint: StreamCheckpointTarget;
144
+ /** REQUIRED. Subscribing to a stream is reading someone's chat, so there is no default-allow.
145
+ * Runs BEFORE existence is checked, so a denial cannot be used to probe for stream ids. */
146
+ authorize: Authorizer<AuthorizeStreamInput<User>>;
147
+ policy?: StreamCheckpointPolicy;
148
+ /** This process's identity — it must be UNIQUE per producer process, because the open CAS trusts
149
+ * it to distinguish rivals (§5.1). In `tables` mode, map {@link StreamColumns.host} and the open
150
+ * write persists it on the message row (so the app can route later subscribers to the hosting
151
+ * instance, §4) and uses it as the single-flight token; setting it WITHOUT a mapped `host` column
152
+ * is refused at construction. In `commit` mode it rides the `open` input. When a `host` column is
153
+ * mapped and no hostId is given, a random per-plane token is used — the CAS still holds, routing
154
+ * just has no stable name to read. */
155
+ hostId?: string;
156
+ /** Slack retained BELOW `durableSeq` so a client whose IVM view lags a checkpoint can still join
157
+ * without a `stale` round trip. Text at or above `durableSeq` is never trimmed. Default 64 KiB.
158
+ * `commit`-mode only — REFUSED (a construction-time `TypeError`) in `tables` mode, where
159
+ * compaction needs the whole produced text at close (§3.4), so the buffer is retained in full. */
160
+ retainChars?: number;
161
+ /** How long a sealed stream stays joinable before eviction. Default 30s. */
162
+ lingerMs?: number;
163
+ /** Per-subscriber frame queue cap; overflow drops that subscriber with `stale` (§4). Default 1024. */
164
+ maxQueuedFrames?: number;
165
+ /** A checkpoint that exhausted its retries. The stream keeps streaming — this is a durability
166
+ * stall, not a stream stall — so the error must not vanish. Absent ⇒ `console.error`. */
167
+ onCheckpointError?: (err: unknown, info: {
168
+ streamId: string;
169
+ from: number;
170
+ seq: number;
171
+ }) => void;
172
+ }
173
+ export interface OpenStreamInput<User> {
174
+ user: User;
175
+ /** The app's message-row id: the durable pointer AND the live plane's key. The row must already
176
+ * exist (the app's own mutator wrote it, alongside the user's prompt) with `seq = 0`. */
177
+ streamId: string;
178
+ /** Opaque app payload, passed through to a `commit` callback. Unused in `tables` mode. */
179
+ meta?: unknown;
180
+ request?: unknown;
181
+ }
182
+ /** The producer's handle (§2). One writer per stream, by construction. */
183
+ export interface StreamHandle {
184
+ readonly streamId: string;
185
+ /** Total produced code units. */
186
+ readonly seq: number;
187
+ /** Total code units the store has committed. Never exceeds {@link seq} (contract P). */
188
+ readonly durableSeq: number;
189
+ /** True once a checkpoint round-trip has seen the reader's cancel flag (§6). `pump` stops on it;
190
+ * a hand-rolled generation loop should check it. */
191
+ readonly cancelled: boolean;
192
+ /** Append a delta: fanned to subscribers synchronously, checkpointed on policy. */
193
+ push(text: string): void;
194
+ /** Force a checkpoint and resolve once the store holds every character produced so far. This is
195
+ * the ORDERING primitive: `await flush()` before writing a discrete row (a tool call, a stop
196
+ * reason) so the text precedes it in the store (§1). Rejects if the checkpoint cannot commit. */
197
+ flush(): Promise<number>;
198
+ /** Drain a delta iterable into the stream (the shape every LLM SDK's text stream already has),
199
+ * stopping early — and closing the iterator, which aborts the underlying request — once the
200
+ * reader has cancelled. */
201
+ pump(deltas: AsyncIterable<string>): Promise<void>;
202
+ /** Seal the stream: `cancelled` if the reader asked it to stop, else `complete`. In `tables` mode
203
+ * this is the compaction (§3.4) — it writes the whole body and drops the chunk rows in one
204
+ * transaction, so it also REPAIRS any checkpoint that failed along the way. */
205
+ close(): Promise<void>;
206
+ /** Seal `error` at whatever was produced. Never throws for the reason it is sealing. */
207
+ fail(error: unknown): Promise<void>;
208
+ }
209
+ export interface SubscribeStreamInput<User> {
210
+ user: User;
211
+ streamId: string;
212
+ /** "I already have this many characters" — from the client's IVM view, or a `Last-Event-ID`.
213
+ * A non-negative integer; default 0. */
214
+ from?: number;
215
+ request?: unknown;
216
+ }
217
+ export interface StreamSubscription {
218
+ readonly streamId: string;
219
+ /** Terminates after exactly one of `end` / `stale` / `absent`. */
220
+ readonly frames: AsyncIterable<StreamFrame>;
221
+ /** Detach early (a disconnected client). Idempotent. */
222
+ close(): void;
223
+ }
224
+ /** Every mapped column, defaults applied. `cancel`/`error` stay `undefined` unless named. */
225
+ export interface ResolvedStreamColumns {
226
+ key: string;
227
+ body: string;
228
+ status: string;
229
+ seq: string;
230
+ cancel?: string;
231
+ error?: string;
232
+ host?: string;
233
+ chunkKey: string;
234
+ chunkStream: string;
235
+ chunkSeq: string;
236
+ chunkText: string;
237
+ }
238
+ export declare function resolveStreamColumns(columns: StreamColumns | undefined): ResolvedStreamColumns;
239
+ /** The chunk row's deterministic id: a replayed checkpoint collides with itself and is absorbed by
240
+ * `ON CONFLICT DO NOTHING` — idempotency without an envelope or a dedup ledger (§3.3). */
241
+ export declare function streamChunkId(streamId: string, seq: number): string;
242
+ /**
243
+ * The chunk table's DDL, for the app's migration. The app owns the message table (this only states
244
+ * the three columns the plane needs on it); the chunk table is entirely protocol-shaped, so it is
245
+ * generated rather than hand-written.
246
+ */
247
+ export declare function streamChunkTableDdl(tables: StreamTables, dialect: SqlDialect): string[];
248
+ /** What the plane needs from the api-server to write a checkpoint: the backend's OUTSIDE-transaction
249
+ * SQL surface (`batch` is one transaction on every backend) and its dialect. Deliberately narrow so
250
+ * `streams.ts` never imports the server (no cycle). */
251
+ export interface StreamSqlSink {
252
+ readonly dialect: SqlDialect;
253
+ readonly sql: ServerSql;
254
+ }
255
+ export declare class StreamPlane<User> {
256
+ readonly chars: number;
257
+ readonly intervalMs: number;
258
+ readonly retries: number;
259
+ readonly retainChars: number;
260
+ readonly lingerMs: number;
261
+ readonly maxQueuedFrames: number;
262
+ private readonly live;
263
+ private readonly opts;
264
+ private readonly sink;
265
+ private readonly mapped;
266
+ private readonly tables;
267
+ /** The open CAS token (§5.1): `hostId`, or a random per-plane stand-in when only the CAS — not
268
+ * routing — needs it. */
269
+ private readonly openToken;
270
+ constructor(opts: RindleStreamOptions<User>, sink?: StreamSqlSink);
271
+ /** Open a stream on an EXISTING message row (§5): the app's own mutator wrote it, alongside the
272
+ * user's prompt, so the pointer is already durable and every client's query already shows the
273
+ * message. This verifies it and flips it to `streaming`. */
274
+ open(input: OpenStreamInput<User>): Promise<StreamHandle>;
275
+ /**
276
+ * The read-only precondition on the app's message row, checked ONCE per `open` (§5.1). Read-only on
277
+ * purpose: it is a decision about the app's data, so re-deciding it per write attempt would let a
278
+ * lost ack turn a success into a refusal.
279
+ *
280
+ * The `streaming` check is the **single-flight guard**, and it lives at the ROW rather than in this
281
+ * process's map because the thing it defends against is distributed: the kick that starts a
282
+ * generation is an at-least-once effect (a retried mutation envelope re-runs its post-commit code,
283
+ * §10.5), so a second kick can land on another instance, where the in-memory map is empty. Two
284
+ * producers on one `streamId` would interleave: both CAS the same length, one stalls, and whichever
285
+ * closes last overwrites the body with ITS buffer. Cheap to refuse; expensive to debug.
286
+ *
287
+ * This probe alone is check-then-act — it and the open write are separate round trips, so two
288
+ * SIMULTANEOUS kicks can both pass it. Mapping a `host` column closes that window: the open write
289
+ * turns conditional and {@link verifyOpenWinner}'s read-back names the winner.
290
+ */
291
+ private assertOpenable;
292
+ subscribe(input: SubscribeStreamInput<User>): Promise<StreamSubscription>;
293
+ /** Seal every live stream `interrupted`. In mapped-table mode the seal IS the compaction, so a
294
+ * graceful drain loses nothing PRODUCED; the status still says the response was cut short rather
295
+ * than claiming completion (§5). Wire it to SIGTERM. */
296
+ drainStreams(): Promise<void>;
297
+ /** Teardown: drop readers and timers WITHOUT a durable write (that is `drainStreams`). */
298
+ closeSync(): void;
299
+ /** A sealed stream stays joinable for the linger window, so a subscribe that races the last token
300
+ * still gets `end` (and the tail it missed) rather than a bare `absent`. */
301
+ retire(streamId: string): void;
302
+ reportCheckpointError(err: unknown, info: {
303
+ streamId: string;
304
+ from: number;
305
+ seq: number;
306
+ }): void;
307
+ /** Drive ONE checkpoint, retrying on failure. Every statement it emits is idempotent under replay
308
+ * — the chunk insert dedups on its deterministic id, the length CAS refuses to apply twice, the
309
+ * compaction is a whole-row overwrite — so "retry until it sticks" needs no dedup ledger and no
310
+ * `lmid` (§3.3). */
311
+ commit(input: StreamCommitInput): Promise<{
312
+ cancelRequested?: boolean;
313
+ seq?: number;
314
+ } | void>;
315
+ private commitOnce;
316
+ /** The read-back half of the open CAS, run only when a `host` column is mapped. The probe in
317
+ * `assertOpenable` and the open write are separate round trips, so bare check-then-act leaves a
318
+ * window where two simultaneous kicks both pass the probe; the conditional `markStreaming`
319
+ * matches nothing when a rival got there first, and whichever token the row now holds names the
320
+ * winner — a true CAS with no row counts needed. A replayed open (lost ack) reads back its OWN
321
+ * token and proceeds. */
322
+ private verifyOpenWinner;
323
+ /** The post-append read-back (§3.2): the row's authoritative length — which both CONFIRMS an
324
+ * append (the guarded batch reports no row count) and absorbs a committed-but-ack-lost one —
325
+ * plus the reader's cancel flag when mapped (§6), riding the same indexed point read. This read
326
+ * is LOAD-BEARING: a failure here fails the append attempt (retried, then stalled), because
327
+ * claiming durability the store did not confirm is the one dishonesty this plane refuses. */
328
+ private readAppendState;
329
+ /** The store's word on how much is durable — for resynchronizing after a FAILED append, where a
330
+ * lost ack may have left the store ahead of the plane. `undefined` in `commit` mode (no readable
331
+ * authority) or when the read itself fails (the next attempt retries the resync too). */
332
+ probeDurableSeq(streamId: string): Promise<number | undefined>;
333
+ }
334
+ /** The open probe's verdict: the message row is missing or already advanced. Not retried — it is a
335
+ * settled statement about the app's data, and retrying re-asks a question already answered. */
336
+ export declare class StreamOpenRefused extends Error {
337
+ constructor(message: string);
338
+ }
339
+ /** Refused by {@link RindleStreamOptions.authorize}. Distinct from the api-server's own
340
+ * `RindleApiError` so this module stays importable without the server (no cycle); the server
341
+ * translates it to a 403 at the handler seam. */
342
+ export declare class StreamForbidden extends Error {
343
+ readonly streamId: string;
344
+ constructor(streamId: string);
345
+ }
346
+ /** Headers for the SSE response. `x-accel-buffering` is the nginx-family opt-out — without it a
347
+ * buffering proxy holds the tokens and hands the user a paragraph at a time. */
348
+ export declare const STREAM_SSE_HEADERS: Record<string, string>;
349
+ /** Pull a subscribe request out of a fetch-style GET: `?streamId=…&from=…`, with `Last-Event-ID`
350
+ * winning over an explicit `from` (a reconnecting `EventSource` knows better than its own URL —
351
+ * the URL is the ORIGINAL join point, the header is where it actually got to). */
352
+ export declare function streamRequestFromHttp(req: {
353
+ url: string;
354
+ headers: {
355
+ get(name: string): string | null;
356
+ };
357
+ }): {
358
+ streamId: string;
359
+ from: number;
360
+ };
361
+ /**
362
+ * Encode a subscription as an SSE body. Each positional frame carries `id: <seq>`, so a browser
363
+ * `EventSource` that drops the connection resumes at exactly the right offset with no application
364
+ * code — its own `Last-Event-ID` header is the `from` of the next subscribe ({@link
365
+ * streamRequestFromHttp}).
366
+ *
367
+ * The reader must close the `EventSource` on the `end` frame: `EventSource` reconnects on ANY close,
368
+ * including a clean one.
369
+ */
370
+ export declare function streamFramesToSse(sub: StreamSubscription, opts?: {
371
+ keepAliveMs?: number;
372
+ }): ReadableStream<Uint8Array>;
373
+ //# sourceMappingURL=streams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streams.d.ts","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"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"}