iterate 0.2.7 → 0.3.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 +86 -76
- package/THIRD_PARTY_NOTICES.md +55 -0
- package/bin/iterate.js +11 -3
- package/dist/api-url-B6404M82.mjs +17 -0
- package/dist/api-url-B6404M82.mjs.map +1 -0
- package/dist/app-ref-BipL0feU.mjs +35 -0
- package/dist/app-ref-BipL0feU.mjs.map +1 -0
- package/dist/app-ref-C1CrgXqX.mjs +7 -0
- package/dist/app-ref-C1CrgXqX.mjs.map +1 -0
- package/dist/app-ref-DYai_om1.mjs +7 -0
- package/dist/app-ref-DYai_om1.mjs.map +1 -0
- package/dist/cli-D0c-pDL_.mjs +1010 -0
- package/dist/cli-D0c-pDL_.mjs.map +1 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.mjs +4 -0
- package/dist/cloudflare-BTm90gQ4.mjs +951 -0
- package/dist/cloudflare-BTm90gQ4.mjs.map +1 -0
- package/dist/contract-s4FW4eES.mjs +309 -0
- package/dist/contract-s4FW4eES.mjs.map +1 -0
- package/dist/document-review/index.d.ts +5 -0
- package/dist/document-review/types.d.ts +107 -0
- package/dist/document-review.mjs +7015 -0
- package/dist/document-review.mjs.map +1 -0
- package/dist/durable-object-processor-durability-CNsTjAJS.mjs +205 -0
- package/dist/durable-object-processor-durability-CNsTjAJS.mjs.map +1 -0
- package/dist/idempotency-DleloJNt.mjs +28 -0
- package/dist/idempotency-DleloJNt.mjs.map +1 -0
- package/dist/index.mjs +1 -1
- package/dist/itx/api-url.d.ts +6 -0
- package/dist/itx/itx-node-client.d.ts +65 -0
- package/dist/itx/itx-session.d.ts +215 -0
- package/dist/itx/owned-rpc-session.d.ts +14 -0
- package/dist/itx/query-client.d.ts +10 -0
- package/dist/itx-api.generated.d.ts +6195 -0
- package/dist/itx-session-sjud8GiT.mjs +534 -0
- package/dist/itx-session-sjud8GiT.mjs.map +1 -0
- package/dist/live-state-BJNqOwFw.mjs +299 -0
- package/dist/live-state-BJNqOwFw.mjs.map +1 -0
- package/dist/next/api.d.ts +479 -0
- package/dist/next/api.mjs +0 -0
- package/dist/next/app-server.d.ts +44 -0
- package/dist/next/app-server.mjs +479 -0
- package/dist/next/app-server.mjs.map +1 -0
- package/dist/next/app-session.d.ts +49 -0
- package/dist/next/app-session.mjs +238 -0
- package/dist/next/app-session.mjs.map +1 -0
- package/dist/next/app.d.ts +29 -0
- package/dist/next/app.mjs +141 -0
- package/dist/next/app.mjs.map +1 -0
- package/dist/next/client/live-state.d.ts +63 -0
- package/dist/next/client/oauth.d.ts +12 -0
- package/dist/next/client/react.d.ts +109 -0
- package/dist/next/client/socket.d.ts +6 -0
- package/dist/next/client.mjs +156 -0
- package/dist/next/client.mjs.map +1 -0
- package/dist/next/expression.d.ts +146 -0
- package/dist/next/expression.mjs +399 -0
- package/dist/next/expression.mjs.map +1 -0
- package/dist/next/lib.d.ts +56 -0
- package/dist/next/lib.mjs +199 -0
- package/dist/next/lib.mjs.map +1 -0
- package/dist/next/oauth-scopes.d.ts +32 -0
- package/dist/next/oauth-scopes.mjs +40 -0
- package/dist/next/oauth-scopes.mjs.map +1 -0
- package/dist/next/oauth.mjs +29 -0
- package/dist/next/oauth.mjs.map +1 -0
- package/dist/next/principal.d.ts +64 -0
- package/dist/next/principal.mjs +98 -0
- package/dist/next/principal.mjs.map +1 -0
- package/dist/next/project-ingress.d.ts +37 -0
- package/dist/next/project-ingress.mjs +75 -0
- package/dist/next/project-ingress.mjs.map +1 -0
- package/dist/next/react.mjs +285 -0
- package/dist/next/react.mjs.map +1 -0
- package/dist/next/sdk/auth.d.ts +5 -0
- package/dist/next/sdk/index.d.ts +112 -0
- package/dist/next/sdk.mjs +139 -0
- package/dist/next/sdk.mjs.map +1 -0
- package/dist/next/stream/processor.d.ts +378 -0
- package/dist/next/stream/processor.mjs +582 -0
- package/dist/next/stream/processor.mjs.map +1 -0
- package/dist/next/stream/run.d.ts +58 -0
- package/dist/next/stream/run.mjs +40 -0
- package/dist/next/stream/run.mjs.map +1 -0
- package/dist/next-node.d.ts +15 -0
- package/dist/next-node.mjs +51 -0
- package/dist/next-node.mjs.map +1 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.mjs +185 -0
- package/dist/node.mjs.map +1 -0
- package/dist/processor-host-capabilities-BMFH3KTM.mjs +56 -0
- package/dist/processor-host-capabilities-BMFH3KTM.mjs.map +1 -0
- package/dist/processors/cloudflare.d.ts +3 -0
- package/dist/processors/durable-object-processor-durability.d.ts +79 -0
- package/dist/processors/event-consumption-metrics.d.ts +82 -0
- package/dist/processors/idempotency.d.ts +13 -0
- package/dist/processors/index.d.ts +12 -0
- package/dist/processors/processor-contracts.d.ts +342 -0
- package/dist/processors/processor-facet.d.ts +186 -0
- package/dist/processors/processor-host-capabilities.d.ts +60 -0
- package/dist/processors/prompt-sections.d.ts +17 -0
- package/dist/processors/rpc-types.d.ts +515 -0
- package/dist/processors/schemas.d.ts +102 -0
- package/dist/processors/stream-handle.d.ts +45 -0
- package/dist/processors/stream-processor-keepalive.d.ts +95 -0
- package/dist/processors/stream-processor-registry.d.ts +233 -0
- package/dist/processors/stream-processor-runner.d.ts +289 -0
- package/dist/processors/stream-processor.d.ts +339 -0
- package/dist/processors/stream-runtime-metrics.d.ts +107 -0
- package/dist/processors/testing.d.ts +302 -0
- package/dist/processors-BoNyeBfQ.mjs +10 -0
- package/dist/processors-BoNyeBfQ.mjs.map +1 -0
- package/dist/processors-cloudflare.mjs +3 -0
- package/dist/processors-testing.mjs +435 -0
- package/dist/processors-testing.mjs.map +1 -0
- package/dist/processors.mjs +52 -0
- package/dist/processors.mjs.map +1 -0
- package/dist/protocol-DnK_f2m6.mjs +251 -0
- package/dist/protocol-DnK_f2m6.mjs.map +1 -0
- package/dist/sdk/capnweb/index.d.ts +2 -0
- package/dist/sdk/capnweb/live-state/compact.d.ts +5 -0
- package/dist/sdk/capnweb/live-state/diff.d.ts +41 -0
- package/dist/sdk/capnweb/live-state/engine.d.ts +44 -0
- package/dist/sdk/capnweb/live-state/index.d.ts +41 -0
- package/dist/sdk/capnweb/live-state/protocol.d.ts +87 -0
- package/dist/sdk/capnweb/live-state/retain.d.ts +23 -0
- package/dist/sdk/capnweb/live-state/store.d.ts +20 -0
- package/dist/sdk/capnweb/live-state/types.d.ts +11 -0
- package/dist/sdk/capnweb/react.d.ts +45 -0
- package/dist/sdk/capnweb/react.mjs +316 -0
- package/dist/sdk/capnweb/react.mjs.map +1 -0
- package/dist/sdk/capnweb.mjs +4 -0
- package/dist/sdk/itx/react.d.ts +191 -0
- package/dist/sdk/itx/react.mjs +383 -0
- package/dist/sdk/itx/react.mjs.map +1 -0
- package/dist/sdk-DMB-IM11.mjs +933 -0
- package/dist/sdk-DMB-IM11.mjs.map +1 -0
- package/dist/sdk.d.ts +339 -0
- package/dist/sdk.mjs +2 -0
- package/dist/serve-itx.d.ts +46 -0
- package/dist/starter-apps/flake-dashboard/app-ref.d.ts +31 -0
- package/dist/starter-apps/flake-dashboard/configured-worker.mjs +1055 -0
- package/dist/starter-apps/flake-dashboard/configured-worker.mjs.map +1 -0
- package/dist/starter-apps/flake-dashboard/contract.d.ts +4839 -0
- package/dist/starter-apps/flake-dashboard/contract.mjs +2 -0
- package/dist/starter-apps/flake-dashboard/index.d.ts +17 -0
- package/dist/starter-apps/flake-dashboard/index.mjs +56 -0
- package/dist/starter-apps/flake-dashboard/index.mjs.map +1 -0
- package/dist/starter-apps/flake-dashboard/worker.d.ts +4607 -0
- package/dist/starter-apps/github-ai-linter/ai-linter.d.ts +8914 -0
- package/dist/starter-apps/github-ai-linter/configured-worker.mjs +17987 -0
- package/dist/starter-apps/github-ai-linter/configured-worker.mjs.map +1 -0
- package/dist/starter-apps/github-ai-linter/contract.d.ts +9193 -0
- package/dist/starter-apps/github-ai-linter/index.d.ts +10 -0
- package/dist/starter-apps/github-ai-linter/index.mjs +36 -0
- package/dist/starter-apps/github-ai-linter/index.mjs.map +1 -0
- package/dist/starter-apps/github-ai-linter/prompt.d.ts +13 -0
- package/dist/starter-apps/github-ai-linter/review-bot.d.ts +808 -0
- package/dist/starter-apps/github-ai-linter/rules.d.ts +34 -0
- package/dist/starter-apps/github-ai-linter/worker-ref.d.ts +19 -0
- package/dist/starter-apps/github-ai-linter/worker.d.ts +19 -0
- package/dist/starter-apps/github-ai-linter/worker.mjs +947 -0
- package/dist/starter-apps/github-ai-linter/worker.mjs.map +1 -0
- package/dist/starter-apps/guestbook/app-ref.d.ts +27 -0
- package/dist/starter-apps/guestbook/client.d.ts +7 -0
- package/dist/starter-apps/guestbook/client.mjs +59 -0
- package/dist/starter-apps/guestbook/configured-worker.mjs +205 -0
- package/dist/starter-apps/guestbook/configured-worker.mjs.map +1 -0
- package/dist/starter-apps/guestbook/index.d.ts +9 -0
- package/dist/starter-apps/guestbook/index.mjs +31 -0
- package/dist/starter-apps/guestbook/index.mjs.map +1 -0
- package/dist/starter-apps/guestbook/processor.d.ts +2267 -0
- package/dist/starter-apps/guestbook/worker.d.ts +26 -0
- package/dist/starter-apps/guestbook/worker.mjs +191 -0
- package/dist/starter-apps/guestbook/worker.mjs.map +1 -0
- package/dist/starter-apps/media/configured-worker.mjs +577 -0
- package/dist/starter-apps/media/configured-worker.mjs.map +1 -0
- package/dist/starter-apps/media/index.mjs +36 -0
- package/dist/starter-apps/media/index.mjs.map +1 -0
- package/dist/starter-apps/media/ref.mjs +20 -0
- package/dist/starter-apps/media/ref.mjs.map +1 -0
- package/dist/starter-apps/media/worker.mjs +579 -0
- package/dist/starter-apps/media/worker.mjs.map +1 -0
- package/dist/starter-apps/notes/configured-worker.mjs +6134 -0
- package/dist/starter-apps/notes/configured-worker.mjs.map +1 -0
- package/dist/starter-apps/notes/index.mjs +23 -0
- package/dist/starter-apps/notes/index.mjs.map +1 -0
- package/dist/starter-apps/notes/ref.mjs +21 -0
- package/dist/starter-apps/notes/ref.mjs.map +1 -0
- package/dist/starter-apps/notes/worker.mjs +427 -0
- package/dist/starter-apps/notes/worker.mjs.map +1 -0
- package/dist/starter-apps/todo/client.mjs +59 -0
- package/dist/starter-apps/todo/configured-worker.mjs +2864 -0
- package/dist/starter-apps/todo/configured-worker.mjs.map +1 -0
- package/dist/starter-apps/todo/index.d.ts +8 -0
- package/dist/starter-apps/todo/index.mjs +29 -0
- package/dist/starter-apps/todo/index.mjs.map +1 -0
- package/dist/stream-processor-keepalive-DAQTP6m3.mjs +2082 -0
- package/dist/stream-processor-keepalive-DAQTP6m3.mjs.map +1 -0
- package/dist/usingCtx-inzbY1Qz.mjs +57 -0
- package/dist/usingCtx-mZx5nsAW.mjs +11800 -0
- package/dist/usingCtx-mZx5nsAW.mjs.map +1 -0
- package/dist/worker-ref-DZxPDmb_.mjs +390 -0
- package/dist/worker-ref-DZxPDmb_.mjs.map +1 -0
- package/menubar/Iterate.entitlements +12 -0
- package/menubar/Iterate.swift +914 -0
- package/menubar/IterateIcon.swift +145 -0
- package/menubar/README.md +28 -0
- package/menubar/build-menubar-app.sh +59 -0
- package/package.json +235 -18
- package/dist/cli-DMS4kJph.mjs +0 -868
- package/dist/cli-DMS4kJph.mjs.map +0 -1
- package/dist/config-DtnR7Lv7.mjs +0 -170
- package/dist/config-DtnR7Lv7.mjs.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/stream-tui/agent-chat-terminal.d.mts +0 -1
- package/dist/stream-tui/agent-chat-terminal.mjs +0 -933
- package/dist/stream-tui/agent-chat-terminal.mjs.map +0 -1
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { a as compactPatch, s as diff } from "./protocol-DnK_f2m6.mjs";
|
|
2
|
+
import { RpcTarget } from "@iterate-com/capnweb";
|
|
3
|
+
//#region src/sdk/capnweb/live-state/retain.ts
|
|
4
|
+
/**
|
|
5
|
+
* Retain a single-argument RPC callback so it survives past the call that
|
|
6
|
+
* carried it. `dup()` duplicates the underlying remote stub (that dup is what
|
|
7
|
+
* `[Symbol.dispose]` releases); `onRpcBroken` is forwarded defensively — Cap'n
|
|
8
|
+
* Web stubs expose no own property descriptors and a Workers RPC property access
|
|
9
|
+
* can fabricate a pipelined method that rejects at call time, so we wire whatever
|
|
10
|
+
* the stub claims and swallow registration failures. `onRpcBroken` is only a
|
|
11
|
+
* prompt hint; callers that need a terminal verdict must model one explicitly
|
|
12
|
+
* (for example, the durable wake lane's independent settlement capability).
|
|
13
|
+
*/
|
|
14
|
+
function retainCallback(callback) {
|
|
15
|
+
const retainable = callback;
|
|
16
|
+
const retained = retainable.dup?.() ?? retainable;
|
|
17
|
+
const dispose = retained[Symbol.dispose]?.bind(retained);
|
|
18
|
+
let disposed = false;
|
|
19
|
+
const wrapped = Object.assign((arg) => retained(arg), { [Symbol.dispose]() {
|
|
20
|
+
if (disposed) return;
|
|
21
|
+
disposed = true;
|
|
22
|
+
dispose?.();
|
|
23
|
+
} });
|
|
24
|
+
const onRpcBroken = retained.onRpcBroken;
|
|
25
|
+
if (typeof onRpcBroken === "function") wrapped.onRpcBroken = (handler) => {
|
|
26
|
+
try {
|
|
27
|
+
const result = onRpcBroken.call(retained, handler);
|
|
28
|
+
if (isThenable(result)) Promise.resolve(result).catch(() => {});
|
|
29
|
+
} catch {}
|
|
30
|
+
};
|
|
31
|
+
return wrapped;
|
|
32
|
+
}
|
|
33
|
+
/** Thenable probe: RPC stubs and their call results are thenable-shaped. */
|
|
34
|
+
function isThenable(value) {
|
|
35
|
+
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Dispose the result of an RPC call whose value the caller ignores. Reading a
|
|
39
|
+
* Cap'n Web / Workers RPC method yields a disposable stub even when unused, and
|
|
40
|
+
* dropping it without disposal leaks the remote reference.
|
|
41
|
+
*/
|
|
42
|
+
function disposeIgnoredRpcResult(result) {
|
|
43
|
+
if (result !== null && (typeof result === "object" || typeof result === "function") && Symbol.dispose in result) result[Symbol.dispose]();
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/sdk/capnweb/live-state/engine.ts
|
|
47
|
+
const DEFAULT_DEBOUNCE_MS = 100;
|
|
48
|
+
const ACK_TIMEOUT_MS = 1e4;
|
|
49
|
+
/**
|
|
50
|
+
* A source-agnostic live store: hold a state value, and when it changes push the
|
|
51
|
+
* minimal diff to every subscriber. It does not know or care where the state
|
|
52
|
+
* comes from — a Durable Object folds events into it, a stateless RpcTarget polls
|
|
53
|
+
* a third-party API into it — so ANY RpcTarget can expose live state by holding
|
|
54
|
+
* one and returning a read-only wrapper from a `.live` getter.
|
|
55
|
+
*
|
|
56
|
+
* Two rules make it cheap and correct:
|
|
57
|
+
* - Updates are IMMUTABLE (`setState`/`assign` build a new value, never mutate),
|
|
58
|
+
* so the diff short-circuits unchanged branches by identity — O(changed), not
|
|
59
|
+
* O(size). See `diff.ts`.
|
|
60
|
+
* - Push work runs only while a subscriber exists. Transient readers call
|
|
61
|
+
* `readSince` explicitly; a dormant engine schedules nothing.
|
|
62
|
+
*
|
|
63
|
+
* All subscribers share one revision line. Fast subscribers share a patch;
|
|
64
|
+
* slow subscribers receive a coalesced patch from their acknowledged state.
|
|
65
|
+
* A revision mismatch makes the client resync instead of applying stale data.
|
|
66
|
+
*/
|
|
67
|
+
var LiveState = class {
|
|
68
|
+
#current;
|
|
69
|
+
/** Latest flushed state — the shared diff baseline. */
|
|
70
|
+
#broadcast;
|
|
71
|
+
#revision = 0;
|
|
72
|
+
#epoch = crypto.randomUUID();
|
|
73
|
+
#lastUpdate;
|
|
74
|
+
#lastCompactUpdate;
|
|
75
|
+
#subscribers = /* @__PURE__ */ new Map();
|
|
76
|
+
#debounceMs;
|
|
77
|
+
#flushTimer;
|
|
78
|
+
constructor(initial, options = {}) {
|
|
79
|
+
this.#current = initial;
|
|
80
|
+
this.#broadcast = initial;
|
|
81
|
+
this.#debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
82
|
+
}
|
|
83
|
+
/** The current state — reflects every `setState`/`assign`, even while dormant. */
|
|
84
|
+
getState() {
|
|
85
|
+
return this.#current;
|
|
86
|
+
}
|
|
87
|
+
/** One retained delta bounds history while a single parent can pull incrementally.
|
|
88
|
+
* A late reader or a new incarnation receives an explicit snapshot instead. */
|
|
89
|
+
readSince(cursor, options = {}) {
|
|
90
|
+
if (this.#flushTimer !== void 0) clearTimeout(this.#flushTimer);
|
|
91
|
+
this.#flushTimer = void 0;
|
|
92
|
+
this.#flush();
|
|
93
|
+
if (cursor?.epoch === this.#epoch) {
|
|
94
|
+
if (cursor.revision === this.#revision) return {
|
|
95
|
+
epoch: this.#epoch,
|
|
96
|
+
update: null
|
|
97
|
+
};
|
|
98
|
+
if (cursor.revision === this.#lastUpdate?.from) return {
|
|
99
|
+
epoch: this.#epoch,
|
|
100
|
+
update: options.patchVersion === 3 ? this.#lastCompactUpdate : this.#lastUpdate
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
epoch: this.#epoch,
|
|
105
|
+
update: options.patchVersion === 3 ? { s: [this.#revision, this.#broadcast] } : {
|
|
106
|
+
type: "snapshot",
|
|
107
|
+
revision: this.#revision,
|
|
108
|
+
state: this.#broadcast
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** True while at least one live subscriber makes projection work observable. */
|
|
113
|
+
get observed() {
|
|
114
|
+
return this.#subscribers.size > 0;
|
|
115
|
+
}
|
|
116
|
+
/** Replace the state. Build a NEW value (don't mutate) so the diff stays cheap. */
|
|
117
|
+
setState(next) {
|
|
118
|
+
this.#current = typeof next === "function" ? next(this.#current) : next;
|
|
119
|
+
if (this.#subscribers.size > 0) this.#scheduleFlush();
|
|
120
|
+
}
|
|
121
|
+
/** Shallow-merge a partial into the state — sugar for `setState(p => ({ ...p, ...partial }))`. */
|
|
122
|
+
assign(partial) {
|
|
123
|
+
this.setState((prev) => ({
|
|
124
|
+
...prev,
|
|
125
|
+
...partial
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
subscribe(sink, options = {}) {
|
|
129
|
+
if (this.#subscribers.size === 0) this.#flush();
|
|
130
|
+
const retained = retainCallback(sink);
|
|
131
|
+
this.#subscribers.set(retained, {
|
|
132
|
+
version: options.patchVersion ?? 1,
|
|
133
|
+
state: this.#broadcast,
|
|
134
|
+
revision: this.#revision,
|
|
135
|
+
busy: false
|
|
136
|
+
});
|
|
137
|
+
retained.onRpcBroken?.(() => this.#drop(retained));
|
|
138
|
+
this.#deliver(retained, options.patchVersion === 3 ? { s: [this.#revision, this.#broadcast] } : {
|
|
139
|
+
type: "snapshot",
|
|
140
|
+
revision: this.#revision,
|
|
141
|
+
state: this.#broadcast
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
ping: () => this.#subscribers.has(retained),
|
|
145
|
+
unsubscribe: () => this.#drop(retained),
|
|
146
|
+
[Symbol.dispose]: () => this.#drop(retained)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
#scheduleFlush() {
|
|
150
|
+
this.#flushTimer ??= setTimeout(() => {
|
|
151
|
+
this.#flushTimer = void 0;
|
|
152
|
+
this.#flush();
|
|
153
|
+
}, this.#debounceMs);
|
|
154
|
+
}
|
|
155
|
+
#flush() {
|
|
156
|
+
const previous = this.#broadcast;
|
|
157
|
+
const patch = diff(previous, this.#current);
|
|
158
|
+
if (patch === void 0) return;
|
|
159
|
+
const from = this.#revision;
|
|
160
|
+
const to = this.#revision += 1;
|
|
161
|
+
this.#broadcast = this.#current;
|
|
162
|
+
const update = {
|
|
163
|
+
type: "patch",
|
|
164
|
+
from,
|
|
165
|
+
to,
|
|
166
|
+
patch
|
|
167
|
+
};
|
|
168
|
+
this.#lastUpdate = update;
|
|
169
|
+
this.#lastCompactUpdate = { p: [
|
|
170
|
+
from,
|
|
171
|
+
to,
|
|
172
|
+
compactPatch(previous, patch)
|
|
173
|
+
] };
|
|
174
|
+
for (const subscriber of this.#subscribers.keys()) this.#sendLatest(subscriber);
|
|
175
|
+
}
|
|
176
|
+
/** Slow subscribers hold one call and one baseline, never a queue of token updates. */
|
|
177
|
+
#sendLatest(subscriber) {
|
|
178
|
+
const held = this.#subscribers.get(subscriber);
|
|
179
|
+
if (!held || held.busy || held.revision === this.#revision) return;
|
|
180
|
+
if (held.version === 3) {
|
|
181
|
+
if (held.revision === this.#lastUpdate?.from) this.#deliver(subscriber, this.#lastCompactUpdate);
|
|
182
|
+
else {
|
|
183
|
+
const patch = diff(held.state, this.#broadcast);
|
|
184
|
+
this.#deliver(subscriber, { p: [
|
|
185
|
+
held.revision,
|
|
186
|
+
this.#revision,
|
|
187
|
+
patch ? compactPatch(held.state, patch) : {}
|
|
188
|
+
] });
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const patch = held.version === 2 && held.revision === this.#lastUpdate?.from ? this.#lastUpdate.patch : diff(held.state, this.#broadcast, { arrays: held.version === 2 });
|
|
193
|
+
this.#deliver(subscriber, {
|
|
194
|
+
type: "patch",
|
|
195
|
+
from: held.revision,
|
|
196
|
+
to: this.#revision,
|
|
197
|
+
patch: patch ?? {}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/** Only acknowledgement releases the next coalesced update; a dead sink is dropped. */
|
|
201
|
+
#deliver(subscriber, update) {
|
|
202
|
+
const held = this.#subscribers.get(subscriber);
|
|
203
|
+
if (!held) return;
|
|
204
|
+
held.state = this.#broadcast;
|
|
205
|
+
held.revision = this.#revision;
|
|
206
|
+
held.busy = true;
|
|
207
|
+
let result;
|
|
208
|
+
try {
|
|
209
|
+
result = subscriber(update);
|
|
210
|
+
} catch {
|
|
211
|
+
this.#drop(subscriber);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (isThenable(result)) {
|
|
215
|
+
held.timeout = setTimeout(() => {
|
|
216
|
+
console.warn("Live-state subscriber dropped: acknowledgement timed out", {
|
|
217
|
+
revision: held.revision,
|
|
218
|
+
timeoutMs: ACK_TIMEOUT_MS
|
|
219
|
+
});
|
|
220
|
+
this.#drop(subscriber);
|
|
221
|
+
}, ACK_TIMEOUT_MS);
|
|
222
|
+
Promise.resolve(result).then(() => {
|
|
223
|
+
if (held.timeout !== void 0) clearTimeout(held.timeout);
|
|
224
|
+
held.busy = false;
|
|
225
|
+
this.#sendLatest(subscriber);
|
|
226
|
+
}, () => this.#drop(subscriber)).finally(() => disposeIgnoredRpcResult(result));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
held.busy = false;
|
|
230
|
+
disposeIgnoredRpcResult(result);
|
|
231
|
+
}
|
|
232
|
+
#drop(subscriber) {
|
|
233
|
+
const timeout = this.#subscribers.get(subscriber)?.timeout;
|
|
234
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
235
|
+
if (!this.#subscribers.delete(subscriber)) return;
|
|
236
|
+
subscriber[Symbol.dispose]();
|
|
237
|
+
if (this.#subscribers.size === 0 && this.#flushTimer !== void 0) {
|
|
238
|
+
clearTimeout(this.#flushTimer);
|
|
239
|
+
this.#flushTimer = void 0;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/sdk/capnweb/live-state/index.ts
|
|
245
|
+
/**
|
|
246
|
+
* Expose mutable server state as a read-only Cap'n Web capability.
|
|
247
|
+
* Pass an in-memory `LiveState`, or a stream-processor registry whose engine
|
|
248
|
+
* must hydrate before its first snapshot.
|
|
249
|
+
*/
|
|
250
|
+
var LiveStateRpcTarget = class extends RpcTarget {
|
|
251
|
+
#live;
|
|
252
|
+
#beforeRead;
|
|
253
|
+
constructor(source) {
|
|
254
|
+
super();
|
|
255
|
+
if ("loadAndRefreshLive" in source) {
|
|
256
|
+
this.#live = source.live;
|
|
257
|
+
this.#beforeRead = () => source.loadAndRefreshLive();
|
|
258
|
+
} else {
|
|
259
|
+
this.#live = source;
|
|
260
|
+
this.#beforeRead = void 0;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async get() {
|
|
264
|
+
const loading = this.#beforeRead?.();
|
|
265
|
+
if (isThenable(loading)) await loading;
|
|
266
|
+
return this.#live.getState();
|
|
267
|
+
}
|
|
268
|
+
async subscribe(onUpdate, options) {
|
|
269
|
+
const loading = this.#beforeRead?.();
|
|
270
|
+
if (isThenable(loading)) await loading;
|
|
271
|
+
return new LiveStateSubscriptionRpcTarget(this.#live.subscribe(onUpdate, options));
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* The wire handle for one subscription — `ping`/`unsubscribe` over RPC.
|
|
276
|
+
* Exported for relays that build their subscription OUTSIDE a `LiveState`
|
|
277
|
+
* engine (the worker-local liveState-socket relay) but must hand back the
|
|
278
|
+
* same handle shape `LiveStateRpcTarget.subscribe` does.
|
|
279
|
+
*/
|
|
280
|
+
var LiveStateSubscriptionRpcTarget = class extends RpcTarget {
|
|
281
|
+
#subscription;
|
|
282
|
+
constructor(subscription) {
|
|
283
|
+
super();
|
|
284
|
+
this.#subscription = subscription;
|
|
285
|
+
}
|
|
286
|
+
ping() {
|
|
287
|
+
return this.#subscription.ping();
|
|
288
|
+
}
|
|
289
|
+
unsubscribe() {
|
|
290
|
+
this.#subscription.unsubscribe();
|
|
291
|
+
}
|
|
292
|
+
[Symbol.dispose]() {
|
|
293
|
+
this.#subscription.unsubscribe();
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
//#endregion
|
|
297
|
+
export { isThenable as a, disposeIgnoredRpcResult as i, LiveStateSubscriptionRpcTarget as n, retainCallback as o, LiveState as r, LiveStateRpcTarget as t };
|
|
298
|
+
|
|
299
|
+
//# sourceMappingURL=live-state-BJNqOwFw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-state-BJNqOwFw.mjs","names":["#epoch","#subscribers","#debounceMs","#current","#broadcast","#flushTimer","#flush","#revision","#lastUpdate","#lastCompactUpdate","#scheduleFlush","#drop","#deliver","#sendLatest","#live","#beforeRead","#subscription"],"sources":["../src/sdk/capnweb/live-state/retain.ts","../src/sdk/capnweb/live-state/engine.ts","../src/sdk/capnweb/live-state/index.ts"],"sourcesContent":["// Canonical retention for RPC callback stubs — the one place that knows a sink\n// might be a remote Cap'n Web / Workers RPC stub rather than a local function.\n//\n// A \"sink\" is a callback the server keeps calling AFTER the RPC method that\n// carried it returned (a live subscription's push). Retaining it means: dup the\n// underlying stub while the transport supports it, and dispose the dup on close.\n// Stream event delivery and the live-state engine both build on these primitives\n// instead of re-deriving the transport dance.\n\n/** An RPC callback after retention: still callable, plus disposable and (best-effort) broken-transport aware. */\nexport type RetainedCallback<Arg> = ((arg: Arg) => unknown) &\n Disposable & { onRpcBroken?(handler: (error: unknown) => void): void };\n\n/**\n * Retain a single-argument RPC callback so it survives past the call that\n * carried it. `dup()` duplicates the underlying remote stub (that dup is what\n * `[Symbol.dispose]` releases); `onRpcBroken` is forwarded defensively — Cap'n\n * Web stubs expose no own property descriptors and a Workers RPC property access\n * can fabricate a pipelined method that rejects at call time, so we wire whatever\n * the stub claims and swallow registration failures. `onRpcBroken` is only a\n * prompt hint; callers that need a terminal verdict must model one explicitly\n * (for example, the durable wake lane's independent settlement capability).\n */\nexport function retainCallback<Arg>(callback: (arg: Arg) => unknown): RetainedCallback<Arg> {\n const retainable = callback as ((arg: Arg) => unknown) &\n Partial<Disposable> & {\n dup?(): (arg: Arg) => unknown;\n onRpcBroken?(handler: (error: unknown) => void): void;\n };\n const retained = (retainable.dup?.() ?? retainable) as typeof retainable;\n const dispose = retained[Symbol.dispose]?.bind(retained);\n // Idempotent by contract: owners often dispose from several paths (engine\n // drop + connection teardown), and a double release of the underlying dup\n // would free someone else's reference.\n let disposed = false;\n const wrapped = Object.assign((arg: Arg) => retained(arg), {\n [Symbol.dispose]() {\n if (disposed) return;\n disposed = true;\n dispose?.();\n },\n }) as RetainedCallback<Arg>;\n const onRpcBroken = retained.onRpcBroken;\n if (typeof onRpcBroken === \"function\") {\n wrapped.onRpcBroken = (handler: (error: unknown) => void) => {\n try {\n const result = onRpcBroken.call(retained, handler);\n if (isThenable(result)) void Promise.resolve(result).catch(() => {});\n } catch {\n // Registration is best-effort.\n }\n };\n }\n return wrapped;\n}\n\n/** Thenable probe: RPC stubs and their call results are thenable-shaped. */\nexport function isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as PromiseLike<unknown>).then === \"function\"\n );\n}\n\n/**\n * Dispose the result of an RPC call whose value the caller ignores. Reading a\n * Cap'n Web / Workers RPC method yields a disposable stub even when unused, and\n * dropping it without disposal leaks the remote reference.\n */\nexport function disposeIgnoredRpcResult(result: unknown): void {\n if (\n result !== null &&\n (typeof result === \"object\" || typeof result === \"function\") &&\n Symbol.dispose in result\n ) {\n (result as Disposable)[Symbol.dispose]();\n }\n}\n","import {\n disposeIgnoredRpcResult,\n isThenable,\n retainCallback,\n type RetainedCallback,\n} from \"./retain.ts\";\nimport { diff } from \"./diff.ts\";\nimport { compactPatch } from \"./compact.ts\";\nimport type {\n LiveStateCursor,\n LiveStateRead,\n LiveStateSubscriptionOptions,\n LiveUpdate,\n} from \"./protocol.ts\";\n\n/** Handle returned by `LiveState.subscribe` — the ownership + liveness surface for one subscriber. */\nexport type LiveStateSubscription = {\n /** Still registered on a live engine? A dead DO incarnation also makes the call reject. */\n ping(): boolean;\n unsubscribe(): void;\n [Symbol.dispose](): void;\n};\n\nconst DEFAULT_DEBOUNCE_MS = 100;\nconst ACK_TIMEOUT_MS = 10_000;\n\ntype Subscriber<State> = {\n version: 1 | 2 | 3;\n state: State;\n revision: number;\n busy: boolean;\n timeout?: ReturnType<typeof setTimeout>;\n};\n\n/**\n * A source-agnostic live store: hold a state value, and when it changes push the\n * minimal diff to every subscriber. It does not know or care where the state\n * comes from — a Durable Object folds events into it, a stateless RpcTarget polls\n * a third-party API into it — so ANY RpcTarget can expose live state by holding\n * one and returning a read-only wrapper from a `.live` getter.\n *\n * Two rules make it cheap and correct:\n * - Updates are IMMUTABLE (`setState`/`assign` build a new value, never mutate),\n * so the diff short-circuits unchanged branches by identity — O(changed), not\n * O(size). See `diff.ts`.\n * - Push work runs only while a subscriber exists. Transient readers call\n * `readSince` explicitly; a dormant engine schedules nothing.\n *\n * All subscribers share one revision line. Fast subscribers share a patch;\n * slow subscribers receive a coalesced patch from their acknowledged state.\n * A revision mismatch makes the client resync instead of applying stale data.\n */\nexport class LiveState<State extends object> {\n #current: State;\n /** Latest flushed state — the shared diff baseline. */\n #broadcast: State;\n #revision = 0;\n readonly #epoch = crypto.randomUUID();\n #lastUpdate: Extract<LiveUpdate<State>, { type: \"patch\" }> | undefined;\n #lastCompactUpdate: Extract<LiveUpdate<State>, { p: unknown }> | undefined;\n readonly #subscribers = new Map<RetainedCallback<LiveUpdate<State>>, Subscriber<State>>();\n readonly #debounceMs: number;\n #flushTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(initial: State, options: { debounceMs?: number } = {}) {\n this.#current = initial;\n this.#broadcast = initial;\n this.#debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n }\n\n /** The current state — reflects every `setState`/`assign`, even while dormant. */\n getState(): State {\n return this.#current;\n }\n\n /** One retained delta bounds history while a single parent can pull incrementally.\n * A late reader or a new incarnation receives an explicit snapshot instead. */\n readSince(\n cursor?: LiveStateCursor,\n options: LiveStateSubscriptionOptions = {},\n ): LiveStateRead<State> {\n if (this.#flushTimer !== undefined) clearTimeout(this.#flushTimer);\n this.#flushTimer = undefined;\n this.#flush();\n if (cursor?.epoch === this.#epoch) {\n if (cursor.revision === this.#revision) return { epoch: this.#epoch, update: null };\n if (cursor.revision === this.#lastUpdate?.from) {\n return {\n epoch: this.#epoch,\n update: options.patchVersion === 3 ? this.#lastCompactUpdate! : this.#lastUpdate,\n };\n }\n }\n return {\n epoch: this.#epoch,\n update:\n options.patchVersion === 3\n ? { s: [this.#revision, this.#broadcast] }\n : { type: \"snapshot\", revision: this.#revision, state: this.#broadcast },\n };\n }\n\n /** True while at least one live subscriber makes projection work observable. */\n get observed(): boolean {\n return this.#subscribers.size > 0;\n }\n\n /** Replace the state. Build a NEW value (don't mutate) so the diff stays cheap. */\n setState(next: State | ((prev: State) => State)): void {\n this.#current = typeof next === \"function\" ? next(this.#current) : next;\n if (this.#subscribers.size > 0) this.#scheduleFlush();\n }\n\n /** Shallow-merge a partial into the state — sugar for `setState(p => ({ ...p, ...partial }))`. */\n assign(partial: Partial<State>): void {\n this.setState((prev) => ({ ...prev, ...partial }));\n }\n\n subscribe(\n sink: (update: LiveUpdate<State>) => unknown,\n options: LiveStateSubscriptionOptions = {},\n ): LiveStateSubscription {\n // First subscriber after dormancy: adopt the latest state as the shared\n // baseline. While subscribers exist, `#broadcast` only advances inside a\n // flush (with a patch to everyone), so it always matches what they've seen.\n if (this.#subscribers.size === 0) {\n this.#flush();\n }\n\n const retained = retainCallback(sink);\n this.#subscribers.set(retained, {\n version: options.patchVersion ?? 1,\n state: this.#broadcast,\n revision: this.#revision,\n busy: false,\n });\n retained.onRpcBroken?.(() => this.#drop(retained));\n // The initial snapshot is the first paint — delivered now, never debounced.\n // A synchronously-throwing sink is dropped here and never becomes live.\n this.#deliver(\n retained,\n options.patchVersion === 3\n ? { s: [this.#revision, this.#broadcast] }\n : { type: \"snapshot\", revision: this.#revision, state: this.#broadcast },\n );\n\n return {\n ping: () => this.#subscribers.has(retained),\n unsubscribe: () => this.#drop(retained),\n [Symbol.dispose]: () => this.#drop(retained),\n };\n }\n\n #scheduleFlush(): void {\n this.#flushTimer ??= setTimeout(() => {\n this.#flushTimer = undefined;\n this.#flush();\n }, this.#debounceMs);\n }\n\n #flush(): void {\n const previous = this.#broadcast;\n const patch = diff(previous, this.#current);\n if (patch === undefined) return;\n const from = this.#revision;\n const to = (this.#revision += 1);\n this.#broadcast = this.#current;\n const update = { type: \"patch\", from, to, patch } satisfies LiveUpdate<State>;\n this.#lastUpdate = update;\n this.#lastCompactUpdate = { p: [from, to, compactPatch(previous, patch)] };\n for (const subscriber of this.#subscribers.keys()) {\n this.#sendLatest(subscriber);\n }\n }\n\n /** Slow subscribers hold one call and one baseline, never a queue of token updates. */\n #sendLatest(subscriber: RetainedCallback<LiveUpdate<State>>): void {\n const held = this.#subscribers.get(subscriber);\n if (!held || held.busy || held.revision === this.#revision) return;\n if (held.version === 3) {\n if (held.revision === this.#lastUpdate?.from) {\n this.#deliver(subscriber, this.#lastCompactUpdate!);\n } else {\n const patch = diff(held.state, this.#broadcast);\n this.#deliver(subscriber, {\n p: [held.revision, this.#revision, patch ? compactPatch(held.state, patch) : {}],\n });\n }\n return;\n }\n const patch =\n held.version === 2 && held.revision === this.#lastUpdate?.from\n ? this.#lastUpdate.patch\n : diff(held.state, this.#broadcast, { arrays: held.version === 2 });\n // A coalesced sequence may return to the same value. An empty object patch\n // still advances its revision so the following shared update applies.\n this.#deliver(subscriber, {\n type: \"patch\",\n from: held.revision,\n to: this.#revision,\n patch: patch ?? {},\n });\n }\n\n /** Only acknowledgement releases the next coalesced update; a dead sink is dropped. */\n #deliver(subscriber: RetainedCallback<LiveUpdate<State>>, update: LiveUpdate<State>): void {\n const held = this.#subscribers.get(subscriber);\n if (!held) return;\n held.state = this.#broadcast;\n held.revision = this.#revision;\n held.busy = true;\n let result: unknown;\n try {\n result = subscriber(update);\n } catch {\n this.#drop(subscriber);\n return;\n }\n if (isThenable(result)) {\n held.timeout = setTimeout(() => {\n console.warn(\"Live-state subscriber dropped: acknowledgement timed out\", {\n revision: held.revision,\n timeoutMs: ACK_TIMEOUT_MS,\n });\n this.#drop(subscriber);\n }, ACK_TIMEOUT_MS);\n void Promise.resolve(result)\n .then(\n () => {\n if (held.timeout !== undefined) clearTimeout(held.timeout);\n held.busy = false;\n this.#sendLatest(subscriber);\n },\n () => this.#drop(subscriber),\n )\n .finally(() => disposeIgnoredRpcResult(result));\n return;\n }\n held.busy = false;\n disposeIgnoredRpcResult(result);\n }\n\n #drop(subscriber: RetainedCallback<LiveUpdate<State>>): void {\n const timeout = this.#subscribers.get(subscriber)?.timeout;\n if (timeout !== undefined) clearTimeout(timeout);\n if (!this.#subscribers.delete(subscriber)) return;\n subscriber[Symbol.dispose]();\n if (this.#subscribers.size === 0 && this.#flushTimer !== undefined) {\n clearTimeout(this.#flushTimer); // dormant again: no work until the next subscriber\n this.#flushTimer = undefined;\n }\n }\n}\n","// `iterate/sdk/capnweb` — live state end to end: the snapshot+patch wire\n// protocol, the structural diff that produces patches, the client store that\n// reassembles them, and the SERVER engine (`LiveState`) that holds a value\n// and pushes minimal diffs to retained RPC subscribers. No socket, no keeper\n// — a Worker or Durable Object can import it without dragging the browser\n// session machinery into its bundle.\nimport { RpcTarget } from \"@iterate-com/capnweb\";\nimport type { LiveState as LiveStateEngine, LiveStateSubscription } from \"./engine.ts\";\nimport type { LiveStateSubscriptionOptions, LiveUpdate } from \"./protocol.ts\";\nimport { isThenable } from \"./retain.ts\";\nimport type { LiveStateRpc, LiveStateSubscriptionHandle } from \"./types.ts\";\n\ntype LiveStateSource<State extends object> = Pick<LiveStateEngine<State>, \"getState\" | \"subscribe\">;\n\ntype RefreshingLiveStateSource<State extends object> = {\n readonly live: LiveStateSource<State>;\n loadAndRefreshLive(): void | PromiseLike<void>;\n};\n\nexport { createLiveStateStore, type LiveStateStore } from \"./store.ts\";\nexport { applyPatch, diff } from \"./diff.ts\";\nexport { compactPatch, applyCompactPatch } from \"./compact.ts\";\nexport { isLiveStateSnapshot, liveStateRevision } from \"./protocol.ts\";\nexport type {\n CompactLiveStatePatch,\n LiveStateCursor,\n LiveStateRead,\n LiveStatePatch,\n LiveStateSubscriptionOptions,\n LiveUpdate,\n} from \"./protocol.ts\";\nexport { LiveState, type LiveStateSubscription } from \"./engine.ts\";\nexport type { LiveStateRpc, LiveStateSubscriptionHandle } from \"./types.ts\";\nexport {\n disposeIgnoredRpcResult,\n isThenable,\n retainCallback,\n type RetainedCallback,\n} from \"./retain.ts\";\n\n/**\n * Expose mutable server state as a read-only Cap'n Web capability.\n * Pass an in-memory `LiveState`, or a stream-processor registry whose engine\n * must hydrate before its first snapshot.\n */\nexport class LiveStateRpcTarget<State extends object>\n extends RpcTarget\n implements LiveStateRpc<State>\n{\n readonly #live: LiveStateSource<State>;\n readonly #beforeRead: (() => void | PromiseLike<void>) | undefined;\n\n constructor(source: LiveStateSource<State> | RefreshingLiveStateSource<State>) {\n super();\n if (\"loadAndRefreshLive\" in source) {\n this.#live = source.live;\n this.#beforeRead = () => source.loadAndRefreshLive();\n } else {\n this.#live = source;\n this.#beforeRead = undefined;\n }\n }\n\n async get() {\n const loading = this.#beforeRead?.();\n if (isThenable(loading)) await loading;\n return this.#live.getState();\n }\n\n async subscribe(\n onUpdate: (update: LiveUpdate<State>) => unknown,\n options?: LiveStateSubscriptionOptions,\n ) {\n const loading = this.#beforeRead?.();\n if (isThenable(loading)) await loading;\n return new LiveStateSubscriptionRpcTarget(this.#live.subscribe(onUpdate, options));\n }\n}\n\n/**\n * The wire handle for one subscription — `ping`/`unsubscribe` over RPC.\n * Exported for relays that build their subscription OUTSIDE a `LiveState`\n * engine (the worker-local liveState-socket relay) but must hand back the\n * same handle shape `LiveStateRpcTarget.subscribe` does.\n */\nexport class LiveStateSubscriptionRpcTarget\n extends RpcTarget\n implements LiveStateSubscriptionHandle\n{\n readonly #subscription: LiveStateSubscription;\n\n constructor(subscription: LiveStateSubscription) {\n super();\n this.#subscription = subscription;\n }\n\n ping() {\n return this.#subscription.ping();\n }\n\n unsubscribe() {\n this.#subscription.unsubscribe();\n }\n\n [Symbol.dispose]() {\n this.#subscription.unsubscribe();\n }\n}\n"],"mappings":"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"}
|