iterate 0.3.0 → 0.4.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/README.md +164 -82
- package/dist/{next/api.d.ts → api.d.ts} +197 -33
- package/dist/{next/app-server.d.ts → app-server.d.ts} +7 -0
- package/dist/{next/app-server.mjs → app-server.mjs} +17 -15
- package/dist/app-server.mjs.map +1 -0
- package/dist/{next/app-session.mjs → app-session.mjs} +12 -15
- package/dist/app-session.mjs.map +1 -0
- package/dist/{next/app.mjs → app.mjs} +53 -14
- package/dist/app.mjs.map +1 -0
- package/dist/{next/client → client}/live-state.d.ts +11 -11
- package/dist/client/oauth.d.ts +17 -0
- package/dist/{next/client → client}/react.d.ts +10 -42
- package/dist/{next/client → client}/socket.d.ts +1 -0
- package/dist/client.mjs +156 -4
- package/dist/client.mjs.map +1 -0
- package/dist/{next/expression.d.ts → expression.d.ts} +11 -69
- package/dist/{next/expression.mjs → expression.mjs} +11 -109
- package/dist/expression.mjs.map +1 -0
- package/dist/lib-BWr-5mFO.mjs +36 -0
- package/dist/lib-BWr-5mFO.mjs.map +1 -0
- package/dist/{next/lib.d.ts → lib.d.ts} +16 -2
- package/dist/{next/lib.mjs → lib.mjs} +32 -3
- package/dist/lib.mjs.map +1 -0
- package/dist/node.d.ts +15 -3
- package/dist/node.mjs +36 -174
- package/dist/node.mjs.map +1 -1
- package/dist/{next/oauth-scopes.mjs → oauth-scopes.mjs} +1 -1
- package/dist/oauth-scopes.mjs.map +1 -0
- package/dist/{next/oauth.mjs → oauth.mjs} +14 -2
- package/dist/oauth.mjs.map +1 -0
- package/dist/principal.d.ts +8 -0
- package/dist/principal.mjs +8 -0
- package/dist/principal.mjs.map +1 -0
- package/dist/project-ingress.d.ts +58 -0
- package/dist/project-ingress.mjs +104 -0
- package/dist/project-ingress.mjs.map +1 -0
- package/dist/{next/react.mjs → react.mjs} +12 -12
- package/dist/react.mjs.map +1 -0
- package/dist/sdk/auth.d.ts +25 -0
- package/dist/sdk/index.d.ts +155 -0
- package/dist/sdk/record-pipelined-steps.d.ts +19 -0
- package/dist/sdk.mjs +245 -2
- package/dist/sdk.mjs.map +1 -0
- package/dist/{next/stream → stream}/processor.d.ts +28 -23
- package/dist/{next/stream → stream}/processor.mjs +48 -25
- package/dist/stream/processor.mjs.map +1 -0
- package/dist/{next/stream → stream}/run.d.ts +9 -6
- package/dist/{next/stream → stream}/run.mjs +13 -8
- package/dist/stream/run.mjs.map +1 -0
- package/dist/stream/test-support.d.ts +45 -0
- package/dist/stream/test-support.mjs +196 -0
- package/dist/stream/test-support.mjs.map +1 -0
- package/package.json +65 -219
- package/THIRD_PARTY_NOTICES.md +0 -55
- package/bin/iterate.js +0 -94
- package/dist/api-url-B6404M82.mjs +0 -17
- package/dist/api-url-B6404M82.mjs.map +0 -1
- package/dist/app-ref-BipL0feU.mjs +0 -35
- package/dist/app-ref-BipL0feU.mjs.map +0 -1
- package/dist/app-ref-C1CrgXqX.mjs +0 -7
- package/dist/app-ref-C1CrgXqX.mjs.map +0 -1
- package/dist/app-ref-DYai_om1.mjs +0 -7
- package/dist/app-ref-DYai_om1.mjs.map +0 -1
- package/dist/cli-D0c-pDL_.mjs +0 -1010
- package/dist/cli-D0c-pDL_.mjs.map +0 -1
- package/dist/client.d.ts +0 -3
- package/dist/cloudflare-BTm90gQ4.mjs +0 -951
- package/dist/cloudflare-BTm90gQ4.mjs.map +0 -1
- package/dist/contract-s4FW4eES.mjs +0 -309
- package/dist/contract-s4FW4eES.mjs.map +0 -1
- package/dist/document-review/index.d.ts +0 -5
- package/dist/document-review/types.d.ts +0 -107
- package/dist/document-review.mjs +0 -7015
- package/dist/document-review.mjs.map +0 -1
- package/dist/durable-object-processor-durability-CNsTjAJS.mjs +0 -205
- package/dist/durable-object-processor-durability-CNsTjAJS.mjs.map +0 -1
- package/dist/idempotency-DleloJNt.mjs +0 -28
- package/dist/idempotency-DleloJNt.mjs.map +0 -1
- package/dist/index.d.mts +0 -5
- package/dist/index.mjs +0 -8
- package/dist/index.mjs.map +0 -1
- package/dist/itx/api-url.d.ts +0 -6
- package/dist/itx/itx-node-client.d.ts +0 -65
- package/dist/itx/itx-session.d.ts +0 -215
- package/dist/itx/owned-rpc-session.d.ts +0 -14
- package/dist/itx/query-client.d.ts +0 -10
- package/dist/itx-api.generated.d.ts +0 -6195
- package/dist/itx-session-sjud8GiT.mjs +0 -534
- package/dist/itx-session-sjud8GiT.mjs.map +0 -1
- package/dist/live-state-BJNqOwFw.mjs +0 -299
- package/dist/live-state-BJNqOwFw.mjs.map +0 -1
- package/dist/next/app-server.mjs.map +0 -1
- package/dist/next/app-session.mjs.map +0 -1
- package/dist/next/app.mjs.map +0 -1
- package/dist/next/client/oauth.d.ts +0 -12
- package/dist/next/client.mjs +0 -156
- package/dist/next/client.mjs.map +0 -1
- package/dist/next/expression.mjs.map +0 -1
- package/dist/next/lib.mjs.map +0 -1
- package/dist/next/oauth-scopes.mjs.map +0 -1
- package/dist/next/oauth.mjs.map +0 -1
- package/dist/next/principal.d.ts +0 -64
- package/dist/next/principal.mjs +0 -98
- package/dist/next/principal.mjs.map +0 -1
- package/dist/next/project-ingress.d.ts +0 -37
- package/dist/next/project-ingress.mjs +0 -75
- package/dist/next/project-ingress.mjs.map +0 -1
- package/dist/next/react.mjs.map +0 -1
- package/dist/next/sdk/auth.d.ts +0 -5
- package/dist/next/sdk/index.d.ts +0 -112
- package/dist/next/sdk.mjs +0 -139
- package/dist/next/sdk.mjs.map +0 -1
- package/dist/next/stream/processor.mjs.map +0 -1
- package/dist/next/stream/run.mjs.map +0 -1
- package/dist/next-node.d.ts +0 -15
- package/dist/next-node.mjs +0 -51
- package/dist/next-node.mjs.map +0 -1
- package/dist/processor-host-capabilities-BMFH3KTM.mjs +0 -56
- package/dist/processor-host-capabilities-BMFH3KTM.mjs.map +0 -1
- package/dist/processors/cloudflare.d.ts +0 -3
- package/dist/processors/durable-object-processor-durability.d.ts +0 -79
- package/dist/processors/event-consumption-metrics.d.ts +0 -82
- package/dist/processors/idempotency.d.ts +0 -13
- package/dist/processors/index.d.ts +0 -12
- package/dist/processors/processor-contracts.d.ts +0 -342
- package/dist/processors/processor-facet.d.ts +0 -186
- package/dist/processors/processor-host-capabilities.d.ts +0 -60
- package/dist/processors/prompt-sections.d.ts +0 -17
- package/dist/processors/rpc-types.d.ts +0 -515
- package/dist/processors/schemas.d.ts +0 -102
- package/dist/processors/stream-handle.d.ts +0 -45
- package/dist/processors/stream-processor-keepalive.d.ts +0 -95
- package/dist/processors/stream-processor-registry.d.ts +0 -233
- package/dist/processors/stream-processor-runner.d.ts +0 -289
- package/dist/processors/stream-processor.d.ts +0 -339
- package/dist/processors/stream-runtime-metrics.d.ts +0 -107
- package/dist/processors/testing.d.ts +0 -302
- package/dist/processors-BoNyeBfQ.mjs +0 -10
- package/dist/processors-BoNyeBfQ.mjs.map +0 -1
- package/dist/processors-cloudflare.mjs +0 -3
- package/dist/processors-testing.mjs +0 -435
- package/dist/processors-testing.mjs.map +0 -1
- package/dist/processors.mjs +0 -52
- package/dist/processors.mjs.map +0 -1
- package/dist/protocol-DnK_f2m6.mjs +0 -251
- package/dist/protocol-DnK_f2m6.mjs.map +0 -1
- package/dist/sdk/capnweb/index.d.ts +0 -2
- package/dist/sdk/capnweb/live-state/compact.d.ts +0 -5
- package/dist/sdk/capnweb/live-state/diff.d.ts +0 -41
- package/dist/sdk/capnweb/live-state/engine.d.ts +0 -44
- package/dist/sdk/capnweb/live-state/index.d.ts +0 -41
- package/dist/sdk/capnweb/live-state/protocol.d.ts +0 -87
- package/dist/sdk/capnweb/live-state/retain.d.ts +0 -23
- package/dist/sdk/capnweb/live-state/store.d.ts +0 -20
- package/dist/sdk/capnweb/live-state/types.d.ts +0 -11
- package/dist/sdk/capnweb/react.d.ts +0 -45
- package/dist/sdk/capnweb/react.mjs +0 -316
- package/dist/sdk/capnweb/react.mjs.map +0 -1
- package/dist/sdk/capnweb.mjs +0 -4
- package/dist/sdk/itx/react.d.ts +0 -191
- package/dist/sdk/itx/react.mjs +0 -383
- package/dist/sdk/itx/react.mjs.map +0 -1
- package/dist/sdk-DMB-IM11.mjs +0 -933
- package/dist/sdk-DMB-IM11.mjs.map +0 -1
- package/dist/sdk.d.ts +0 -339
- package/dist/serve-itx.d.ts +0 -46
- package/dist/starter-apps/flake-dashboard/app-ref.d.ts +0 -31
- package/dist/starter-apps/flake-dashboard/configured-worker.mjs +0 -1055
- package/dist/starter-apps/flake-dashboard/configured-worker.mjs.map +0 -1
- package/dist/starter-apps/flake-dashboard/contract.d.ts +0 -4839
- package/dist/starter-apps/flake-dashboard/contract.mjs +0 -2
- package/dist/starter-apps/flake-dashboard/index.d.ts +0 -17
- package/dist/starter-apps/flake-dashboard/index.mjs +0 -56
- package/dist/starter-apps/flake-dashboard/index.mjs.map +0 -1
- package/dist/starter-apps/flake-dashboard/worker.d.ts +0 -4607
- package/dist/starter-apps/github-ai-linter/ai-linter.d.ts +0 -8914
- package/dist/starter-apps/github-ai-linter/configured-worker.mjs +0 -17987
- package/dist/starter-apps/github-ai-linter/configured-worker.mjs.map +0 -1
- package/dist/starter-apps/github-ai-linter/contract.d.ts +0 -9193
- package/dist/starter-apps/github-ai-linter/index.d.ts +0 -10
- package/dist/starter-apps/github-ai-linter/index.mjs +0 -36
- package/dist/starter-apps/github-ai-linter/index.mjs.map +0 -1
- package/dist/starter-apps/github-ai-linter/prompt.d.ts +0 -13
- package/dist/starter-apps/github-ai-linter/review-bot.d.ts +0 -808
- package/dist/starter-apps/github-ai-linter/rules.d.ts +0 -34
- package/dist/starter-apps/github-ai-linter/worker-ref.d.ts +0 -19
- package/dist/starter-apps/github-ai-linter/worker.d.ts +0 -19
- package/dist/starter-apps/github-ai-linter/worker.mjs +0 -947
- package/dist/starter-apps/github-ai-linter/worker.mjs.map +0 -1
- package/dist/starter-apps/guestbook/app-ref.d.ts +0 -27
- package/dist/starter-apps/guestbook/client.d.ts +0 -7
- package/dist/starter-apps/guestbook/client.mjs +0 -59
- package/dist/starter-apps/guestbook/configured-worker.mjs +0 -205
- package/dist/starter-apps/guestbook/configured-worker.mjs.map +0 -1
- package/dist/starter-apps/guestbook/index.d.ts +0 -9
- package/dist/starter-apps/guestbook/index.mjs +0 -31
- package/dist/starter-apps/guestbook/index.mjs.map +0 -1
- package/dist/starter-apps/guestbook/processor.d.ts +0 -2267
- package/dist/starter-apps/guestbook/worker.d.ts +0 -26
- package/dist/starter-apps/guestbook/worker.mjs +0 -191
- package/dist/starter-apps/guestbook/worker.mjs.map +0 -1
- package/dist/starter-apps/media/configured-worker.mjs +0 -577
- package/dist/starter-apps/media/configured-worker.mjs.map +0 -1
- package/dist/starter-apps/media/index.mjs +0 -36
- package/dist/starter-apps/media/index.mjs.map +0 -1
- package/dist/starter-apps/media/ref.mjs +0 -20
- package/dist/starter-apps/media/ref.mjs.map +0 -1
- package/dist/starter-apps/media/worker.mjs +0 -579
- package/dist/starter-apps/media/worker.mjs.map +0 -1
- package/dist/starter-apps/notes/configured-worker.mjs +0 -6134
- package/dist/starter-apps/notes/configured-worker.mjs.map +0 -1
- package/dist/starter-apps/notes/index.mjs +0 -23
- package/dist/starter-apps/notes/index.mjs.map +0 -1
- package/dist/starter-apps/notes/ref.mjs +0 -21
- package/dist/starter-apps/notes/ref.mjs.map +0 -1
- package/dist/starter-apps/notes/worker.mjs +0 -427
- package/dist/starter-apps/notes/worker.mjs.map +0 -1
- package/dist/starter-apps/todo/client.mjs +0 -59
- package/dist/starter-apps/todo/configured-worker.mjs +0 -2864
- package/dist/starter-apps/todo/configured-worker.mjs.map +0 -1
- package/dist/starter-apps/todo/index.d.ts +0 -8
- package/dist/starter-apps/todo/index.mjs +0 -29
- package/dist/starter-apps/todo/index.mjs.map +0 -1
- package/dist/stream-processor-keepalive-DAQTP6m3.mjs +0 -2082
- package/dist/stream-processor-keepalive-DAQTP6m3.mjs.map +0 -1
- package/dist/usingCtx-mZx5nsAW.mjs +0 -11800
- package/dist/usingCtx-mZx5nsAW.mjs.map +0 -1
- package/dist/worker-ref-DZxPDmb_.mjs +0 -390
- package/dist/worker-ref-DZxPDmb_.mjs.map +0 -1
- package/dist/worker.d.mts +0 -33
- package/dist/worker.mjs +0 -18
- package/dist/worker.mjs.map +0 -1
- package/menubar/Iterate.entitlements +0 -12
- package/menubar/Iterate.swift +0 -914
- package/menubar/IterateIcon.swift +0 -145
- package/menubar/README.md +0 -28
- package/menubar/build-menubar-app.sh +0 -59
- /package/dist/{next/api.mjs → api.mjs} +0 -0
- /package/dist/{next/app-session.d.ts → app-session.d.ts} +0 -0
- /package/dist/{next/app.d.ts → app.d.ts} +0 -0
- /package/dist/{next/oauth-scopes.d.ts → oauth-scopes.d.ts} +0 -0
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
import { RpcTarget } from "@iterate-com/capnweb";
|
|
2
|
-
import type { z } from "zod";
|
|
3
|
-
import { type ProcessorStream } from "./stream-handle.ts";
|
|
4
|
-
import type { StreamEvent } from "./schemas.ts";
|
|
5
|
-
import type { ProcessorRuntimeState, ProcessorSnapshot } from "./rpc-types.ts";
|
|
6
|
-
import type { DeliveryContext } from "./stream-processor-runner.ts";
|
|
7
|
-
import { EventConsumptionMetrics } from "./event-consumption-metrics.ts";
|
|
8
|
-
import { type ConsumedEvent, type EmittedInput, type EventCatalog, type ProcessorState } from "./processor-contracts.ts";
|
|
9
|
-
export type MaybePromise<T> = T | Promise<T>;
|
|
10
|
-
export declare function awaitKeepAliveBacked<T>(keepAliveWhile: ((work: () => Promise<unknown>) => void) | undefined, work: () => Promise<T>): Promise<T>;
|
|
11
|
-
/**
|
|
12
|
-
* The structural slice of a processor contract that the class needs. Contracts
|
|
13
|
-
* built with `defineProcessorContract(...)` satisfy this; the full contract
|
|
14
|
-
* type flows through the `Contract` type parameter so event/state inference
|
|
15
|
-
* reaches the hooks.
|
|
16
|
-
*/
|
|
17
|
-
export type StreamProcessorContract = {
|
|
18
|
-
slug: string;
|
|
19
|
-
version: string;
|
|
20
|
-
stateSchema: z.ZodType;
|
|
21
|
-
events: EventCatalog;
|
|
22
|
-
processorDeps?: readonly unknown[];
|
|
23
|
-
consumes: readonly string[];
|
|
24
|
-
emits: readonly string[];
|
|
25
|
-
parseEvent(event: StreamEvent): StreamEvent;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Constructor dependencies shared by every processor: the stream append
|
|
29
|
-
* capability and the home stream's identity (`path` / `projectId`, stamped as
|
|
30
|
-
* provenance onto every emitted event), plus an optional `keepAliveWhile`
|
|
31
|
-
* hook for processors whose own out-of-band work (a DO verb like the
|
|
32
|
-
* scheduler's `triggerDue`) must keep the runtime alive while it runs.
|
|
33
|
-
* Delivery, cursors, and checkpoints are NOT deps: the StreamProcessorRunner
|
|
34
|
-
* (stream-processor-runner.ts) owns all of that and drives the processor from
|
|
35
|
-
* outside.
|
|
36
|
-
*/
|
|
37
|
-
export type StreamProcessorBaseDeps = {
|
|
38
|
-
stream: ProcessorStream;
|
|
39
|
-
/** Path of the stream this processor runs on (the stream `stream` points at). */
|
|
40
|
-
path: string;
|
|
41
|
-
/** Owning project, or null on a global (deployment-root) stream. */
|
|
42
|
-
projectId: string | null;
|
|
43
|
-
keepAliveWhile?: (work: () => Promise<unknown>) => void;
|
|
44
|
-
};
|
|
45
|
-
type ReducedEvent<Contract> = {
|
|
46
|
-
event: ConsumedEvent<Contract>;
|
|
47
|
-
previousState: ProcessorState<Contract>;
|
|
48
|
-
state: ProcessorState<Contract>;
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* A consumed-type event whose shape failed the contract parse. Distinguished
|
|
52
|
-
* from `undefined` (type not consumed at all) so the runner can skip the event
|
|
53
|
-
* AND record the skip durably instead of silently dropping it.
|
|
54
|
-
*/
|
|
55
|
-
type ConsumedEventParseFailure = {
|
|
56
|
-
parseError: z.ZodError;
|
|
57
|
-
};
|
|
58
|
-
/** What `reduce` receives: one consumed event and the state to fold it into. */
|
|
59
|
-
export type ReduceArgs<Contract> = {
|
|
60
|
-
event: ConsumedEvent<Contract>;
|
|
61
|
-
state: ProcessorState<Contract>;
|
|
62
|
-
};
|
|
63
|
-
/**
|
|
64
|
-
* Side-effect scheduling helpers handed to the `process*` hooks. Two
|
|
65
|
-
* primitives, two guarantees — every side effect must pick one deliberately:
|
|
66
|
-
*
|
|
67
|
-
* - `blockProcessorWhile` — SHORT work the next event must not overtake.
|
|
68
|
-
* At-least-once: the cursor is held, a crash resends the event batch, and
|
|
69
|
-
* append idempotency keys collapse the re-run. Long work does NOT belong
|
|
70
|
-
* here: it head-of-line-blocks every later event (including cancellations).
|
|
71
|
-
*
|
|
72
|
-
* - `runInBackground` — a DROPPABLE ATTEMPT. The cursor advances
|
|
73
|
-
* immediately; an eviction loses the closure silently. Every callsite must
|
|
74
|
-
* answer "what recovers the OUTCOME if this attempt drops?" — legitimate
|
|
75
|
-
* answers are "an at-head pass (`processEvent` under
|
|
76
|
-
* `delivery.caughtUp`), via stream-backed requested/completed evidence" (LLM
|
|
77
|
-
* calls, scripts, debounce timers) or
|
|
78
|
-
* "nothing, the outcome genuinely doesn't matter" (telemetry). A naked
|
|
79
|
-
* runInBackground around consequential work with no recovery pass is the bug
|
|
80
|
-
* class the 2026-06-10 / 2026-07-07 incidents came from.
|
|
81
|
-
*
|
|
82
|
-
* Both are keepalive-backed: while either kind of work is in flight the
|
|
83
|
-
* runner's recovery adapter parks a durable alarm ahead of it, so an
|
|
84
|
-
* incarnation that dies owing work is revived and the processors get their
|
|
85
|
-
* at-head pass (docs/writing-stream-processors.md has the full doctrine).
|
|
86
|
-
*/
|
|
87
|
-
type SideEffectHelpers = {
|
|
88
|
-
/** Hold the cursor (and the next event) until this work completes.
|
|
89
|
-
* Blocking is the EXCEPTION, not the default — justify it at the call site
|
|
90
|
-
* with a comment explaining why the next event must wait (i.e. why losing
|
|
91
|
-
* this append would lose a per-event consequence forever).
|
|
92
|
-
* Registrations run STRICTLY IN REGISTRATION ORDER: each blocker starts
|
|
93
|
-
* only after the previous one settles, so a later registration in the same
|
|
94
|
-
* `processEvent` body observes the earlier work's appends. Order
|
|
95
|
-
* state-derived work after per-event work by writing it later in the
|
|
96
|
-
* function — no separate lane needed. */
|
|
97
|
-
blockProcessorWhile: (work: () => Promise<unknown>) => void;
|
|
98
|
-
/** A droppable attempt; failures are caught and logged, evictions lose it. */
|
|
99
|
-
runInBackground: (work: () => Promise<unknown>) => void;
|
|
100
|
-
};
|
|
101
|
-
/** What `processEvent` receives: one reduction result plus delivery context and helpers. */
|
|
102
|
-
export type ProcessEventArgs<Contract> = Omit<ReducedEvent<Contract>, "event"> & SideEffectHelpers & {
|
|
103
|
-
/**
|
|
104
|
-
* The consumed event being processed — or `null` for an eventless call where
|
|
105
|
-
* `delivery.caughtUp` is true. The runner makes that call when a batch scans
|
|
106
|
-
* through the highest observed offset but no consumed event carried `caughtUp`
|
|
107
|
-
* (for example, the final row is stream/connection-closed). The processor
|
|
108
|
-
* still needs a chance to act on the complete observed fold. A per-event switch MUST guard on
|
|
109
|
-
* `event !== null`; the caught-up processing reads `state` and needs no event.
|
|
110
|
-
*/
|
|
111
|
-
event: ReducedEvent<Contract>["event"] | null;
|
|
112
|
-
/**
|
|
113
|
-
* Append one or more events listed in `contract.emits` to this stream,
|
|
114
|
-
* stamped with `source.processor` provenance pointing at THIS event as
|
|
115
|
-
* `whileProcessing` (unstamped on the event-less caught-up call). The binding
|
|
116
|
-
* is a closure, so appends made later from
|
|
117
|
-
* `blockProcessorWhile`/`runInBackground` work scheduled here still stamp
|
|
118
|
-
* the event that was being processed.
|
|
119
|
-
*/
|
|
120
|
-
append: (...input: EmittedInput<Contract>[]) => Promise<StreamEvent[]>;
|
|
121
|
-
/** Like `append`, onto a sibling stream (resolved via `stream.at(path)`). */
|
|
122
|
-
appendTo: (path: string, ...input: EmittedInput<Contract>[]) => Promise<StreamEvent[]>;
|
|
123
|
-
/**
|
|
124
|
-
* Honest event-time context (delivery phase, highest observed offset, cursor
|
|
125
|
-
* revision) supplied by the StreamProcessorRunner, the only driver.
|
|
126
|
-
*/
|
|
127
|
-
delivery: DeliveryContext;
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* What the PROCESSOR contributes to the published {@link ProcessorRuntimeState}:
|
|
131
|
-
* the operational `runtime` bag only — subclass debug data, never cursor
|
|
132
|
-
* state. The SNAPSHOT half is supplied by the StreamProcessorRunner (the
|
|
133
|
-
* cursor owner) when a host assembles the full runtime state
|
|
134
|
-
* (stream-processor-registry.ts `reads`/`wakeStreamProcessor`, the browser
|
|
135
|
-
* host's capabilities), and self-measured event-consumption metrics are merged
|
|
136
|
-
* in host-side so an override cannot accidentally drop them.
|
|
137
|
-
*/
|
|
138
|
-
export type ProcessorRuntimeContribution = {
|
|
139
|
-
runtime?: Record<string, unknown>;
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* The read surface a `StreamProcessorRpcTarget` (rpc-targets.ts) serves — the
|
|
143
|
-
* three inspection reads of the public `StreamProcessorRpc` contract. The
|
|
144
|
-
* provider is the hosting registry's `reads(processor)`
|
|
145
|
-
* (stream-processor-registry.ts): the runner owns both cursors, so snapshot /
|
|
146
|
-
* waitUntilEvent answer from the runner's committed progress and
|
|
147
|
-
* `getRuntimeState` pins the runner's snapshot under the processor's own
|
|
148
|
-
* runtime bag.
|
|
149
|
-
*/
|
|
150
|
-
export type ProcessorReads<State> = {
|
|
151
|
-
snapshot(): Promise<ProcessorSnapshot<State>>;
|
|
152
|
-
getRuntimeState(): Promise<ProcessorRuntimeState<State>>;
|
|
153
|
-
waitUntilEvent(input: {
|
|
154
|
-
offset: number;
|
|
155
|
-
timeoutMs?: number;
|
|
156
|
-
}): Promise<void>;
|
|
157
|
-
};
|
|
158
|
-
/**
|
|
159
|
-
* Constructor args are the base deps plus the subclass's own `Deps` flattened
|
|
160
|
-
* into one object, e.g. `new BrowserRawEventsProcessor({ stream, path,
|
|
161
|
-
* projectId, sql })`.
|
|
162
|
-
*/
|
|
163
|
-
export type StreamProcessorConstructorArgs<Deps extends object = object> = StreamProcessorBaseDeps & Deps;
|
|
164
|
-
/** The provenance stamp shape (`source.processor`) carried by processor appends. */
|
|
165
|
-
type ProcessorSourceStamp = NonNullable<NonNullable<StreamEvent["source"]>["processor"]>;
|
|
166
|
-
/**
|
|
167
|
-
* @internal The narrow drive surface {@link StreamProcessor.runnerHooks}
|
|
168
|
-
* hands the StreamProcessorRunner (stream-processor-runner.ts): exactly the
|
|
169
|
-
* protected hooks and append methods the event-processing loop needs, nothing an author
|
|
170
|
-
* or operator could reach for. This is how the runner invokes protected
|
|
171
|
-
* members without widening the author-facing surface — authors still only
|
|
172
|
-
* implement `reduce`/`processEvent` (fold-derived side effects ride
|
|
173
|
-
* `processEvent` under `delivery.caughtUp`), and the runner never sees
|
|
174
|
-
* processor-internal state (it owns its own two-cursor progress).
|
|
175
|
-
*/
|
|
176
|
-
export type StreamProcessorRunnerHooks<Contract extends StreamProcessorContract> = {
|
|
177
|
-
readonly contract: Contract;
|
|
178
|
-
/** The schema default — the fold of the empty journal prefix. */
|
|
179
|
-
initialState(): ProcessorState<Contract>;
|
|
180
|
-
/** Validate a persisted fold against the CURRENT state schema (cache-key check). */
|
|
181
|
-
parseState(value: unknown): {
|
|
182
|
-
success: true;
|
|
183
|
-
state: ProcessorState<Contract>;
|
|
184
|
-
} | {
|
|
185
|
-
success: false;
|
|
186
|
-
error: z.ZodError;
|
|
187
|
-
};
|
|
188
|
-
/** The pure fold step: `undefined` = type not consumed, `parseError` = consumed type, bad shape. */
|
|
189
|
-
reduceRawEvent(args: {
|
|
190
|
-
event: StreamEvent;
|
|
191
|
-
state: ProcessorState<Contract>;
|
|
192
|
-
}): ReducedEvent<Contract> | ConsumedEventParseFailure | undefined;
|
|
193
|
-
/** Whether this event will reach `processEvent` — a consumed type whose
|
|
194
|
-
* payload parses. Stateless (no fold), so the runner can find the last
|
|
195
|
-
* DELIVERED offset of a batch (for `caughtUp`) without pre-folding, and
|
|
196
|
-
* without letting a malformed final event steal the flag. */
|
|
197
|
-
isDeliverable(event: StreamEvent): boolean;
|
|
198
|
-
/** The synchronous per-event side-effect hook (virtual — subclass overrides
|
|
199
|
-
* dispatch). The caught-up processing rides it under `delivery.caughtUp`. */
|
|
200
|
-
processEvent(args: ProcessEventArgs<Contract>): undefined;
|
|
201
|
-
/**
|
|
202
|
-
* Feed the processor's self-measured consumption metrics
|
|
203
|
-
* (`eventConsumptionMetrics.noteBatchIngested`) after a durably committed batch.
|
|
204
|
-
* Without it the wake capability's consumption-lag samples
|
|
205
|
-
* (`runtime.metrics`) go empty under runner drive: appends alone only feed
|
|
206
|
-
* the other half of the consume-your-own-appends loop.
|
|
207
|
-
*/
|
|
208
|
-
noteBatchIngested(args: {
|
|
209
|
-
ingestedThroughOffset: number;
|
|
210
|
-
ingestedOffsets: readonly number[];
|
|
211
|
-
newestEventCreatedAtMs?: number;
|
|
212
|
-
ingestStartedAtMs: number;
|
|
213
|
-
atMs: number;
|
|
214
|
-
}): void;
|
|
215
|
-
/** The processor's semantic key — `<slug>/<key>[@<path>:<offset>]`. */
|
|
216
|
-
idempotencyKey(key: string, whileProcessing?: Pick<StreamEvent, "offset" | "path">): string;
|
|
217
|
-
/** The `source.processor` provenance stamp for runner-authored raw appends. */
|
|
218
|
-
processorStamp(streamId: string, whileProcessing?: Pick<StreamEvent, "offset" | "type">): ProcessorSourceStamp;
|
|
219
|
-
/** Emits-checked, provenance-stamped append to the processor's home stream. */
|
|
220
|
-
append(opts: {
|
|
221
|
-
streamId: string;
|
|
222
|
-
whileProcessing?: ConsumedEvent<Contract>;
|
|
223
|
-
}, input: EmittedInput<Contract>[]): Promise<StreamEvent[]>;
|
|
224
|
-
/** Like `append`, onto a sibling stream (resolved via `stream.at(path)`). */
|
|
225
|
-
appendTo(path: string, opts: {
|
|
226
|
-
streamId: string;
|
|
227
|
-
whileProcessing?: ConsumedEvent<Contract>;
|
|
228
|
-
}, input: EmittedInput<Contract>[]): Promise<StreamEvent[]>;
|
|
229
|
-
};
|
|
230
|
-
/**
|
|
231
|
-
* Class-based stream processor.
|
|
232
|
-
*
|
|
233
|
-
* The model in one sentence: the StreamProcessorRunner
|
|
234
|
-
* (stream-processor-runner.ts) delivers ordered events, folds each consumed
|
|
235
|
-
* event into state through `reduce`, hands each reduction to the side-effect
|
|
236
|
-
* hooks, and owns cursors, checkpoints, retry, and recovery — the processor
|
|
237
|
-
* itself is only the hooks.
|
|
238
|
-
*
|
|
239
|
-
* Subclasses override up to two hooks:
|
|
240
|
-
*
|
|
241
|
-
* - `reduce` — pure projection of one consumed event into the next state
|
|
242
|
-
* - `processEvent` — synchronous per-event side effects; what most processors
|
|
243
|
-
* implement. Side effects derived from the whole fold (rather than the
|
|
244
|
-
* delivered event) belong here too, guarded by `args.delivery.caughtUp`.
|
|
245
|
-
* `args.event` is `null` only when a caught-up scan contained no
|
|
246
|
-
* consumed event; authors skip their per-event switch but can still act on
|
|
247
|
-
* the fold.
|
|
248
|
-
*
|
|
249
|
-
* Every hook runs inside the runner's serialized delivery chain: a later
|
|
250
|
-
* batch never starts until the previous one has completed or failed, and the
|
|
251
|
-
* cursor is only committed after the hooks (plus any `blockProcessorWhile`
|
|
252
|
-
* work) succeed.
|
|
253
|
-
*/
|
|
254
|
-
export declare abstract class StreamProcessor<Contract extends StreamProcessorContract, Deps extends object = object> extends RpcTarget {
|
|
255
|
-
#private;
|
|
256
|
-
abstract readonly contract: Contract;
|
|
257
|
-
protected readonly stream: ProcessorStream;
|
|
258
|
-
/** Path of the home stream — the one `this.stream` points at. */
|
|
259
|
-
protected readonly path: string;
|
|
260
|
-
/** Owning project, or null on a global (deployment-root) stream. */
|
|
261
|
-
protected readonly projectId: string | null;
|
|
262
|
-
protected readonly deps: Deps;
|
|
263
|
-
/**
|
|
264
|
-
* Self-measured consumption metrics (see event-consumption-metrics.ts): every
|
|
265
|
-
* home-stream append and every committed event batch feeds it (the
|
|
266
|
-
* latter through the driver's `noteBatchIngested`), closing the
|
|
267
|
-
* consume-your-own-appends loop on the processor's own clock. HOSTS merge
|
|
268
|
-
* `eventConsumptionMetrics.report()` into the `getRuntimeState` answer they give
|
|
269
|
-
* the stream (`runtime.metrics`) — merged host-side so a subclass
|
|
270
|
-
* overriding `getRuntimeState` with its own `runtime` bag cannot
|
|
271
|
-
* accidentally drop it. In-memory; resets with the isolate.
|
|
272
|
-
*/
|
|
273
|
-
readonly eventConsumptionMetrics: EventConsumptionMetrics;
|
|
274
|
-
constructor(args: StreamProcessorConstructorArgs<Deps>);
|
|
275
|
-
/**
|
|
276
|
-
* @internal Hands the StreamProcessorRunner its {@link StreamProcessorRunnerHooks}.
|
|
277
|
-
* A STATIC accessor on purpose: statics may reach protected/private members
|
|
278
|
-
* of instances of their own class, so the runner gets the hooks without any
|
|
279
|
-
* new public instance member (nothing for subclasses to see, shadow, or
|
|
280
|
-
* call). Authors never touch this; the runner is its only caller.
|
|
281
|
-
*/
|
|
282
|
-
static runnerHooks<Contract extends StreamProcessorContract, Deps extends object>(processor: StreamProcessor<Contract, Deps>): StreamProcessorRunnerHooks<Contract>;
|
|
283
|
-
/**
|
|
284
|
-
* The processor-contributed slice of the published runtime state: the
|
|
285
|
-
* operational `runtime` bag only (see {@link ProcessorRuntimeContribution}).
|
|
286
|
-
* Subclasses override to expose debug data; the base contributes nothing.
|
|
287
|
-
* The snapshot half comes from the runner, and event-consumption metrics are
|
|
288
|
-
* merged in host-side — never read cursor state here.
|
|
289
|
-
*/
|
|
290
|
-
getRuntimeState(): Promise<ProcessorRuntimeContribution>;
|
|
291
|
-
/**
|
|
292
|
-
* Pure projection of one consumed event into the next state. Defaults to
|
|
293
|
-
* identity; returning `null`/`undefined` also keeps the current state.
|
|
294
|
-
*/
|
|
295
|
-
protected reduce(args: ReduceArgs<Contract>): ProcessorState<Contract> | null | undefined;
|
|
296
|
-
/**
|
|
297
|
-
* Synchronous side-effect hook, called by the runner once per consumed event
|
|
298
|
-
* and, when necessary, once more with `event: null` for a caught-up scan
|
|
299
|
-
* that consumed nothing. It is ALSO the caught-up processing: when
|
|
300
|
-
* `args.delivery.caughtUp` is true (`args.state` is the whole observed fold),
|
|
301
|
-
* an obligation processor
|
|
302
|
-
* drives its undriven obligations and settles dead ones — scheduling that
|
|
303
|
-
* async work via `args.blockProcessorWhile`, keyed by STABLE obligation keys
|
|
304
|
-
* (`this.idempotencyKey(<obligation>)` with the deciding state folded into
|
|
305
|
-
* the key and NO event bound, so a redelivery/revival does not rotate the
|
|
306
|
-
* key and re-run the effect).
|
|
307
|
-
* The runner never sets `caughtUp` below its highest observed offset — no override
|
|
308
|
-
* needs its own mid-catch-up gate. Simple processors ignore the flag.
|
|
309
|
-
*/
|
|
310
|
-
protected processEvent(_args: ProcessEventArgs<Contract>): undefined;
|
|
311
|
-
/**
|
|
312
|
-
* Fire-and-forget async work backed by the injected keep-alive, with
|
|
313
|
-
* failures logged. For work launched OUTSIDE a delivery hook (DO verbs,
|
|
314
|
-
* alarm handlers); inside `processEvent`, use the `runInBackground` helper
|
|
315
|
-
* from the hook args — that one rides the runner's recovery keepalive.
|
|
316
|
-
*/
|
|
317
|
-
protected runInBackground(work: () => Promise<unknown>): void;
|
|
318
|
-
/**
|
|
319
|
-
* Append events listed in `contract.emits` to this processor's own stream,
|
|
320
|
-
* stamped with `source.processor` provenance (no `whileProcessing`: this
|
|
321
|
-
* overload is for appends outside any event batch — alarm handlers, DO methods —
|
|
322
|
-
* and for decisions derived from the whole fold). Inside `processEvent`,
|
|
323
|
-
* prefer the event-bound `args.append`.
|
|
324
|
-
*/
|
|
325
|
-
protected append(...input: EmittedInput<Contract>[]): Promise<StreamEvent[]>;
|
|
326
|
-
/** Like {@link append}, onto a sibling stream (resolved via `stream.at(path)`). */
|
|
327
|
-
protected appendTo(path: string, ...input: EmittedInput<Contract>[]): Promise<StreamEvent[]>;
|
|
328
|
-
/**
|
|
329
|
-
* Processor-scoped idempotency key: `<slug>/<key>`, plus `@<path>:<offset>`
|
|
330
|
-
* when the append is a deterministic consequence of processing one event —
|
|
331
|
-
* a resent event batch then dedupes instead of double-appending. The path
|
|
332
|
-
* makes fan-in safe: two same-slug processors on different streams
|
|
333
|
-
* forwarding into one target can never collide. Omit `whileProcessing` for
|
|
334
|
-
* state-derived appends and fold the deciding state into `key` instead
|
|
335
|
-
* (e.g. a generation counter).
|
|
336
|
-
*/
|
|
337
|
-
protected idempotencyKey(key: string, whileProcessing?: Pick<StreamEvent, "offset" | "path">): string;
|
|
338
|
-
}
|
|
339
|
-
export {};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/** Serializable summary of a {@link LatencyRing}; `null` until a sample exists. */
|
|
2
|
-
export type LatencyStats = {
|
|
3
|
-
/** Most recent sample (ms). */
|
|
4
|
-
last: number;
|
|
5
|
-
p50: number;
|
|
6
|
-
p95: number;
|
|
7
|
-
/** Samples currently in the ring (caps at the ring size). */
|
|
8
|
-
samples: number;
|
|
9
|
-
/** Epoch ms of the most recent sample. */
|
|
10
|
-
lastAt: number;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Fixed-capacity ring of latency samples. `stats()` is `null` until the first
|
|
14
|
-
* sample — surfaces render "—" instead of a made-up number.
|
|
15
|
-
*/
|
|
16
|
-
export declare class LatencyRing {
|
|
17
|
-
#private;
|
|
18
|
-
constructor(capacity?: number);
|
|
19
|
-
record(ms: number, atMs: number): void;
|
|
20
|
-
stats(): LatencyStats | null;
|
|
21
|
-
}
|
|
22
|
-
/** One rolling-minute throughput window. */
|
|
23
|
-
export type MinuteWindow = {
|
|
24
|
-
/** Events in the last 60 seconds. */
|
|
25
|
-
count: number;
|
|
26
|
-
/** Payload bytes in the last 60 seconds. */
|
|
27
|
-
bytes: number;
|
|
28
|
-
/** `count / 60` — the "events/s over the last minute" number. */
|
|
29
|
-
perSecond: number;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* 60 one-second buckets of {count, bytes}. Stale slots (lapped by the ring)
|
|
33
|
-
* are ignored at read time, so a burst followed by silence decays to zero
|
|
34
|
-
* without a sweeper.
|
|
35
|
-
*/
|
|
36
|
-
export declare class MinuteBuckets {
|
|
37
|
-
#private;
|
|
38
|
-
bump(atMs: number, count: number, bytes: number): void;
|
|
39
|
-
lastMinute(nowMs: number): MinuteWindow;
|
|
40
|
-
/** Totals over the trailing `seconds` (≤60) — short windows make responsive rates. */
|
|
41
|
-
window(nowMs: number, seconds: number): {
|
|
42
|
-
count: number;
|
|
43
|
-
bytes: number;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* The raw per-second buckets, oldest→newest, always exactly 60 entries
|
|
47
|
-
* (silent seconds are zero) — what a UI graphs directly, so the graph is
|
|
48
|
-
* the measurement rather than a client-side reconstruction of it.
|
|
49
|
-
*/
|
|
50
|
-
series(nowMs: number): ThroughputSeries;
|
|
51
|
-
}
|
|
52
|
-
/** Per-second buckets over the trailing minute, oldest→newest, length 60. */
|
|
53
|
-
export type ThroughputSeries = {
|
|
54
|
-
counts: number[];
|
|
55
|
-
bytes: number[];
|
|
56
|
-
};
|
|
57
|
-
/**
|
|
58
|
-
* One direction's throughput report: a responsive trailing-5s rate (the
|
|
59
|
-
* number UIs show), the full-minute totals, and the raw 1s series for graphs.
|
|
60
|
-
*/
|
|
61
|
-
export type ThroughputReport = {
|
|
62
|
-
/** Events per second over the trailing 5 seconds. */
|
|
63
|
-
perSecond5s: number;
|
|
64
|
-
/** Payload bytes per second over the trailing 5 seconds. */
|
|
65
|
-
bytesPerSecond5s: number;
|
|
66
|
-
lastMinute: MinuteWindow;
|
|
67
|
-
series: ThroughputSeries;
|
|
68
|
-
};
|
|
69
|
-
/** What a stream runtime snapshot reports for the stream's own throughput. */
|
|
70
|
-
export type StreamThroughputMetrics = {
|
|
71
|
-
/** ISO timestamp when this incarnation started measuring (metrics reset on eviction). */
|
|
72
|
-
measuredSince: string;
|
|
73
|
-
/** ISO timestamp anchoring the trailing windows and final series bucket. */
|
|
74
|
-
reportedAt: string;
|
|
75
|
-
/** Appends committed (all producers). */
|
|
76
|
-
ingress: ThroughputReport;
|
|
77
|
-
/** Event batches sent to all receiving streams and open callbacks. */
|
|
78
|
-
egress: ThroughputReport;
|
|
79
|
-
};
|
|
80
|
-
/** The stream Durable Object's in-memory throughput accounting. */
|
|
81
|
-
export declare class StreamRuntimeMetrics {
|
|
82
|
-
#private;
|
|
83
|
-
readonly ingress: MinuteBuckets;
|
|
84
|
-
readonly egress: MinuteBuckets;
|
|
85
|
-
constructor(nowMs: number);
|
|
86
|
-
report(nowMs: number): StreamThroughputMetrics;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Age an event-driven throughput snapshot against the local wall clock. This
|
|
90
|
-
* keeps trailing windows truthful during silence without polling the stream.
|
|
91
|
-
*/
|
|
92
|
-
export declare function ageStreamThroughputMetrics(metrics: StreamThroughputMetrics, nowMs: number): StreamThroughputMetrics;
|
|
93
|
-
/**
|
|
94
|
-
* The mutual ping's NTP-style math, shared by both requesters (a stream
|
|
95
|
-
* pinging a callback owner; anything pinging the stream). The requester stamps
|
|
96
|
-
* `t0` and observes `t3`; the responder reports receive/reply-send times on
|
|
97
|
-
* ITS clock. RTT excludes responder processing time; `clockOffsetMs`
|
|
98
|
-
* estimates `responderClock - requesterClock`.
|
|
99
|
-
*/
|
|
100
|
-
export declare function pingRoundTrip(reply: {
|
|
101
|
-
t0: number;
|
|
102
|
-
t1: number;
|
|
103
|
-
t2: number;
|
|
104
|
-
}, t3: number): {
|
|
105
|
-
rttMs: number;
|
|
106
|
-
clockOffsetMs: number;
|
|
107
|
-
};
|