@turingfocus/chat-runtime 0.1.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 @@
1
+ {"version":3,"file":"gateway-notification-queue.js","sourceRoot":"","sources":["../src/gateway-notification-queue.ts"],"names":[],"mappings":"AAgBA,qFAAqF;AACrF,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,QAAuC,EACb,EAAE;IAC5B,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,IAAI,UAA8B,CAAC;IACnC,IAAI,KAAK,GAAwC,WAAW,CAAC;IAE7D,MAAM,cAAc,GAAG,CAAC,YAAiC,EAAQ,EAAE;QACjE,IAAI,UAAU,KAAK,SAAS;YAAE,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACnE,CAAC,CAAC;IAEF,OAAO;QACL,OAAO,EAAE,CAAC,YAAY,EAAE,EAAE;YACxB,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,cAAc,CAAC,YAAY,CAAC,CAAC;QAC/B,CAAC;QACD,QAAQ,EAAE,CAAC,gBAAgB,EAAE,EAAE;YAC7B,IAAI,KAAK,KAAK,WAAW;gBAAE,OAAO;YAClC,UAAU,GAAG,gBAAgB,CAAC;YAC9B,KAAK,GAAG,UAAU,CAAC;YACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;gBACvD,cAAc,CAAC,OAAO,CAAC,KAAK,CAAE,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACnB,KAAK,GAAG,QAAQ,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** Clone normalized Protocol data and freeze every exposed object and array. */
2
+ export declare const cloneImmutable: <T>(value: T) => T;
3
+ export declare const deepEqual: (left: unknown, right: unknown) => boolean;
4
+ //# sourceMappingURL=immutable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"immutable.d.ts","sourceRoot":"","sources":["../src/immutable.ts"],"names":[],"mappings":"AA0BA,gFAAgF;AAChF,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CACM,CAAC;AAEpD,eAAO,MAAM,SAAS,GAAI,MAAM,OAAO,EAAE,OAAO,OAAO,KAAG,OA4BzD,CAAC"}
@@ -0,0 +1,53 @@
1
+ const cloneValue = (value, seen) => {
2
+ if (value === null || typeof value !== "object")
3
+ return value;
4
+ const existing = seen.get(value);
5
+ if (existing !== undefined)
6
+ return existing;
7
+ if (Array.isArray(value)) {
8
+ const clone = [];
9
+ seen.set(value, clone);
10
+ for (const entry of value)
11
+ clone.push(cloneValue(entry, seen));
12
+ return Object.freeze(clone);
13
+ }
14
+ const clone = {};
15
+ seen.set(value, clone);
16
+ for (const key of Object.keys(value)) {
17
+ Object.defineProperty(clone, key, {
18
+ configurable: true,
19
+ enumerable: true,
20
+ value: cloneValue(value[key], seen),
21
+ writable: true,
22
+ });
23
+ }
24
+ return Object.freeze(clone);
25
+ };
26
+ /** Clone normalized Protocol data and freeze every exposed object and array. */
27
+ export const cloneImmutable = (value) => cloneValue(value, new WeakMap());
28
+ export const deepEqual = (left, right) => {
29
+ if (Object.is(left, right))
30
+ return true;
31
+ if (left === null ||
32
+ right === null ||
33
+ typeof left !== "object" ||
34
+ typeof right !== "object") {
35
+ return false;
36
+ }
37
+ if (Array.isArray(left) || Array.isArray(right)) {
38
+ if (!Array.isArray(left) || !Array.isArray(right))
39
+ return false;
40
+ if (left.length !== right.length)
41
+ return false;
42
+ return left.every((entry, index) => deepEqual(entry, right[index]));
43
+ }
44
+ const leftRecord = left;
45
+ const rightRecord = right;
46
+ const leftKeys = Object.keys(leftRecord);
47
+ const rightKeys = Object.keys(rightRecord);
48
+ if (leftKeys.length !== rightKeys.length)
49
+ return false;
50
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(rightRecord, key) &&
51
+ deepEqual(leftRecord[key], rightRecord[key]));
52
+ };
53
+ //# sourceMappingURL=immutable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"immutable.js","sourceRoot":"","sources":["../src/immutable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { ChatClient, createChatClient, type ChatClientOptions, type ChatClientSubscription, type ChatSnapshotListener, type ChatClientUnhandledError, type ChatClientUnhandledErrorSource, } from "./chat-client.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,GACpC,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { ChatClient, createChatClient, } from "./chat-client.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,gBAAgB,GAMjB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type ChatError, type ChatSnapshot, type ChatUpdate } from "@turingfocus/chat-protocol";
2
+ import { type TimelineState } from "./timeline.js";
3
+ export interface SnapshotState {
4
+ readonly snapshot: ChatSnapshot;
5
+ readonly timeline: TimelineState;
6
+ }
7
+ export declare const createSnapshotState: (snapshot: ChatSnapshot) => SnapshotState;
8
+ export declare const updateSnapshotState: (state: SnapshotState, changes: Partial<Omit<ChatSnapshot, "timeline">> & {
9
+ readonly timeline?: TimelineState | undefined;
10
+ }) => SnapshotState;
11
+ /**
12
+ * Three-way merge a full reload with state published after that reload began.
13
+ * This keeps reload publication atomic without discarding newer subscription or
14
+ * history changes.
15
+ */
16
+ export declare const rebaseSnapshotState: (baseline: SnapshotState, loaded: SnapshotState, current: SnapshotState) => SnapshotState;
17
+ export declare const updateConversationId: (update: ChatUpdate) => string | undefined;
18
+ export declare const applySnapshotUpdate: (state: SnapshotState, update: ChatUpdate) => SnapshotState;
19
+ export declare const applySnapshotError: (state: SnapshotState, error: ChatError) => SnapshotState;
20
+ //# sourceMappingURL=snapshot-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-state.d.ts","sourceRoot":"","sources":["../src/snapshot-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAKD,eAAO,MAAM,mBAAmB,GAAI,UAAU,YAAY,KAAG,aAkB5D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,aAAa,EACpB,SAAS,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,GAAG;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;CAC/C,KACA,aAQF,CAAC;AA6BF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU,aAAa,EACvB,QAAQ,aAAa,EACrB,SAAS,aAAa,KACrB,aA+DF,CAAC;AA6GF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,UAAU,KACjB,MAAM,GAAG,SASX,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,aAAa,EACpB,QAAQ,UAAU,KACjB,aA4EF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,aAAa,EACpB,OAAO,SAAS,KACf,aAKF,CAAC"}
@@ -0,0 +1,238 @@
1
+ import { compareAgentEventTransitions, hasCompatibleAgentEventMetadata, } from "@turingfocus/chat-protocol";
2
+ import { cloneImmutable, deepEqual } from "./immutable.js";
3
+ import { createTimelineState, findEventTimelineItem, rebaseTimelineState, upsertTimelineItem, } from "./timeline.js";
4
+ const freezeSnapshot = (snapshot) => Object.freeze(snapshot);
5
+ export const createSnapshotState = (snapshot) => {
6
+ const timeline = createTimelineState(snapshot.timeline);
7
+ return {
8
+ timeline,
9
+ snapshot: freezeSnapshot({
10
+ conversation: cloneImmutable(snapshot.conversation),
11
+ timeline: timeline.items,
12
+ run: cloneImmutable(snapshot.run),
13
+ capabilities: cloneImmutable(snapshot.capabilities),
14
+ pageInfo: cloneImmutable(snapshot.pageInfo),
15
+ ...(snapshot.pendingInteraction === undefined
16
+ ? {}
17
+ : { pendingInteraction: cloneImmutable(snapshot.pendingInteraction) }),
18
+ ...(snapshot.error === undefined
19
+ ? {}
20
+ : { error: cloneImmutable(snapshot.error) }),
21
+ }),
22
+ };
23
+ };
24
+ export const updateSnapshotState = (state, changes) => {
25
+ const timeline = changes.timeline ?? state.timeline;
26
+ const snapshot = freezeSnapshot({
27
+ ...state.snapshot,
28
+ ...changes,
29
+ timeline: timeline.items,
30
+ });
31
+ return { timeline, snapshot };
32
+ };
33
+ const rebaseValue = (baseline, loaded, current) => deepEqual(current, baseline) ? loaded : current;
34
+ const interactionMetadataError = (conversationId) => cloneImmutable({
35
+ code: "validation",
36
+ message: "Conflicting metadata was received for an interaction revision",
37
+ retryable: false,
38
+ conversationId,
39
+ });
40
+ const hasSameInteractionIdentity = (left, right) => left !== undefined &&
41
+ right !== undefined &&
42
+ left.requestId === right.requestId &&
43
+ left.revision === right.revision;
44
+ const hasConflictingInteractionMetadata = (existing, incoming) => hasSameInteractionIdentity(existing, incoming) &&
45
+ !deepEqual(existing, incoming);
46
+ /**
47
+ * Three-way merge a full reload with state published after that reload began.
48
+ * This keeps reload publication atomic without discarding newer subscription or
49
+ * history changes.
50
+ */
51
+ export const rebaseSnapshotState = (baseline, loaded, current) => {
52
+ const timeline = rebaseTimelineState(baseline.timeline, loaded.timeline, current.timeline);
53
+ const rebasedError = rebaseValue(baseline.snapshot.error, loaded.snapshot.error, current.snapshot.error);
54
+ const pendingWasUnchanged = deepEqual(current.snapshot.pendingInteraction, baseline.snapshot.pendingInteraction);
55
+ const hasLoadedInteractionConflict = pendingWasUnchanged &&
56
+ hasConflictingInteractionMetadata(current.snapshot.pendingInteraction, loaded.snapshot.pendingInteraction);
57
+ const pendingInteraction = hasLoadedInteractionConflict
58
+ ? current.snapshot.pendingInteraction
59
+ : rebaseValue(baseline.snapshot.pendingInteraction, loaded.snapshot.pendingInteraction, current.snapshot.pendingInteraction);
60
+ const error = hasLoadedInteractionConflict
61
+ ? interactionMetadataError(current.snapshot.conversation.id)
62
+ : rebasedError;
63
+ const rebased = {
64
+ timeline,
65
+ snapshot: freezeSnapshot({
66
+ conversation: rebaseValue(baseline.snapshot.conversation, loaded.snapshot.conversation, current.snapshot.conversation),
67
+ timeline: timeline.items,
68
+ run: rebaseValue(baseline.snapshot.run, loaded.snapshot.run, current.snapshot.run),
69
+ capabilities: rebaseValue(baseline.snapshot.capabilities, loaded.snapshot.capabilities, current.snapshot.capabilities),
70
+ pageInfo: rebaseValue(baseline.snapshot.pageInfo, loaded.snapshot.pageInfo, current.snapshot.pageInfo),
71
+ ...(pendingInteraction === undefined ? {} : { pendingInteraction }),
72
+ ...(error === undefined ? {} : { error }),
73
+ }),
74
+ };
75
+ if (deepEqual(rebased.snapshot, current.snapshot))
76
+ return current;
77
+ if (deepEqual(rebased.snapshot, loaded.snapshot))
78
+ return loaded;
79
+ return rebased;
80
+ };
81
+ const eventMetadataError = (conversationId) => cloneImmutable({
82
+ code: "validation",
83
+ message: "Conflicting metadata was received for an existing agent event",
84
+ retryable: false,
85
+ conversationId,
86
+ });
87
+ const retainedEventFields = (existing) => existing?.raw === undefined ? {} : { raw: existing.raw };
88
+ const buildAgentEvent = (update, existing) => {
89
+ if (update.event.eventCategory === "tool") {
90
+ const byId = new Map(existing?.eventCategory === "tool"
91
+ ? existing.transitions.map((transition) => [transition.id, transition])
92
+ : []);
93
+ const transition = cloneImmutable(update.event.transition);
94
+ byId.set(transition.id, transition);
95
+ const transitions = Object.freeze([...byId.values()].sort(compareAgentEventTransitions));
96
+ const latest = transitions.at(-1);
97
+ return cloneImmutable({
98
+ kind: "agent-event",
99
+ eventCategory: "tool",
100
+ id: update.event.id,
101
+ conversationId: update.conversationId,
102
+ eventType: update.event.eventType,
103
+ status: latest.status,
104
+ createdAt: update.event.createdAt,
105
+ updatedAt: latest.occurredAt,
106
+ ...(update.event.sequence === undefined
107
+ ? {}
108
+ : { sequence: update.event.sequence }),
109
+ ...(latest.summary === undefined
110
+ ? existing?.summary === undefined
111
+ ? {}
112
+ : { summary: existing.summary }
113
+ : { summary: latest.summary }),
114
+ ...retainedEventFields(existing),
115
+ transitions,
116
+ });
117
+ }
118
+ const byId = new Map(existing?.eventCategory === "generic"
119
+ ? existing.transitions.map((transition) => [transition.id, transition])
120
+ : []);
121
+ const transition = cloneImmutable(update.event.transition);
122
+ byId.set(transition.id, transition);
123
+ const transitions = Object.freeze([...byId.values()].sort(compareAgentEventTransitions));
124
+ const latest = transitions.at(-1);
125
+ return cloneImmutable({
126
+ kind: "agent-event",
127
+ eventCategory: "generic",
128
+ id: update.event.id,
129
+ conversationId: update.conversationId,
130
+ eventType: update.event.eventType,
131
+ status: latest.status,
132
+ createdAt: update.event.createdAt,
133
+ updatedAt: latest.occurredAt,
134
+ ...(update.event.sequence === undefined
135
+ ? {}
136
+ : { sequence: update.event.sequence }),
137
+ ...(latest.summary === undefined
138
+ ? existing?.summary === undefined
139
+ ? {}
140
+ : { summary: existing.summary }
141
+ : { summary: latest.summary }),
142
+ ...retainedEventFields(existing),
143
+ transitions,
144
+ });
145
+ };
146
+ const applyTransition = (state, update) => {
147
+ const existing = findEventTimelineItem(state.timeline, update.event.id);
148
+ if (existing !== undefined &&
149
+ (existing.kind !== "agent-event" ||
150
+ !hasCompatibleAgentEventMetadata(existing, update))) {
151
+ const error = eventMetadataError(update.conversationId);
152
+ return deepEqual(state.snapshot.error, error)
153
+ ? state
154
+ : updateSnapshotState(state, { error });
155
+ }
156
+ const event = buildAgentEvent(update, existing);
157
+ const timeline = upsertTimelineItem(state.timeline, event);
158
+ return timeline === state.timeline
159
+ ? state
160
+ : updateSnapshotState(state, { timeline });
161
+ };
162
+ export const updateConversationId = (update) => {
163
+ if (update.kind === "snapshot.replace") {
164
+ return update.snapshot.conversation.id;
165
+ }
166
+ if (update.kind === "conversation.upsert")
167
+ return update.conversation.id;
168
+ if (update.kind === "error.reported") {
169
+ return update.conversationId ?? update.error.conversationId;
170
+ }
171
+ return update.conversationId;
172
+ };
173
+ export const applySnapshotUpdate = (state, update) => {
174
+ const activeConversationId = state.snapshot.conversation.id;
175
+ const targetConversationId = updateConversationId(update);
176
+ if (targetConversationId !== undefined &&
177
+ targetConversationId !== activeConversationId) {
178
+ return state;
179
+ }
180
+ switch (update.kind) {
181
+ case "snapshot.replace": {
182
+ const replacement = createSnapshotState(update.snapshot);
183
+ if (hasConflictingInteractionMetadata(state.snapshot.pendingInteraction, replacement.snapshot.pendingInteraction)) {
184
+ return updateSnapshotState(replacement, {
185
+ pendingInteraction: state.snapshot.pendingInteraction,
186
+ error: interactionMetadataError(activeConversationId),
187
+ });
188
+ }
189
+ return deepEqual(replacement.snapshot, state.snapshot)
190
+ ? state
191
+ : replacement;
192
+ }
193
+ case "conversation.upsert": {
194
+ const conversation = cloneImmutable(update.conversation);
195
+ return deepEqual(conversation, state.snapshot.conversation)
196
+ ? state
197
+ : updateSnapshotState(state, { conversation });
198
+ }
199
+ case "timeline.upsert": {
200
+ const timeline = upsertTimelineItem(state.timeline, update.item);
201
+ return timeline === state.timeline
202
+ ? state
203
+ : updateSnapshotState(state, { timeline });
204
+ }
205
+ case "event.transition.upsert":
206
+ return applyTransition(state, update);
207
+ case "run.replace": {
208
+ const run = cloneImmutable(update.run);
209
+ return deepEqual(run, state.snapshot.run)
210
+ ? state
211
+ : updateSnapshotState(state, { run });
212
+ }
213
+ case "capabilities.replace": {
214
+ const capabilities = cloneImmutable(update.capabilities);
215
+ return deepEqual(capabilities, state.snapshot.capabilities)
216
+ ? state
217
+ : updateSnapshotState(state, { capabilities });
218
+ }
219
+ case "interaction.replace": {
220
+ const pendingInteraction = cloneImmutable(update.interaction ?? undefined);
221
+ if (hasConflictingInteractionMetadata(state.snapshot.pendingInteraction, pendingInteraction)) {
222
+ return applySnapshotError(state, interactionMetadataError(activeConversationId));
223
+ }
224
+ return deepEqual(pendingInteraction, state.snapshot.pendingInteraction)
225
+ ? state
226
+ : updateSnapshotState(state, { pendingInteraction });
227
+ }
228
+ case "error.reported":
229
+ return applySnapshotError(state, update.error);
230
+ }
231
+ };
232
+ export const applySnapshotError = (state, error) => {
233
+ const immutableError = cloneImmutable(error);
234
+ return deepEqual(immutableError, state.snapshot.error)
235
+ ? state
236
+ : updateSnapshotState(state, { error: immutableError });
237
+ };
238
+ //# sourceMappingURL=snapshot-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-state.js","sourceRoot":"","sources":["../src/snapshot-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ChatSnapshot } from "@turingfocus/chat-protocol";
2
+ import type { SnapshotState } from "./snapshot-state.js";
3
+ export type SnapshotListener = (snapshot: ChatSnapshot) => void;
4
+ export interface SnapshotSubscription {
5
+ readonly closed: boolean;
6
+ dispose(): void;
7
+ }
8
+ export interface SnapshotStoreOptions {
9
+ readonly onListenerError?: ((error: unknown) => void) | undefined;
10
+ }
11
+ /** Owns immutable snapshot publication and shields listeners from reentrant writes. */
12
+ export declare class SnapshotStore {
13
+ #private;
14
+ constructor(options?: SnapshotStoreOptions);
15
+ get state(): SnapshotState | null;
16
+ getSnapshot(): ChatSnapshot | null;
17
+ subscribe(listener: SnapshotListener): SnapshotSubscription;
18
+ latestState(): SnapshotState | null;
19
+ commit(next: SnapshotState): void;
20
+ close(): void;
21
+ }
22
+ //# sourceMappingURL=snapshot-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-store.d.ts","sourceRoot":"","sources":["../src/snapshot-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAEhE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACnE;AAQD,uFAAuF;AACvF,qBAAa,aAAa;;gBAQZ,OAAO,GAAE,oBAAyB;IAI9C,IAAI,KAAK,IAAI,aAAa,GAAG,IAAI,CAEhC;IAED,WAAW,IAAI,YAAY,GAAG,IAAI;IAIlC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,oBAAoB;IA2B3D,WAAW,IAAI,aAAa,GAAG,IAAI;IAInC,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAqBjC,KAAK,IAAI,IAAI;CA0Bd"}
@@ -0,0 +1,99 @@
1
+ /** Owns immutable snapshot publication and shields listeners from reentrant writes. */
2
+ export class SnapshotStore {
3
+ #listeners = new Set();
4
+ #onListenerError;
5
+ #pendingCommits = [];
6
+ #closed = false;
7
+ #notifying = false;
8
+ #state = null;
9
+ constructor(options = {}) {
10
+ this.#onListenerError = options.onListenerError;
11
+ }
12
+ get state() {
13
+ return this.#state;
14
+ }
15
+ getSnapshot() {
16
+ return this.#state?.snapshot ?? null;
17
+ }
18
+ subscribe(listener) {
19
+ const registration = {
20
+ active: true,
21
+ lastSnapshot: null,
22
+ listener,
23
+ };
24
+ if (!this.#closed) {
25
+ this.#listeners.add(registration);
26
+ if (this.#state !== null) {
27
+ this.#callListener(registration, this.#state.snapshot);
28
+ }
29
+ }
30
+ else {
31
+ registration.active = false;
32
+ }
33
+ return Object.freeze({
34
+ get closed() {
35
+ return !registration.active;
36
+ },
37
+ dispose: () => {
38
+ if (!registration.active)
39
+ return;
40
+ registration.active = false;
41
+ this.#listeners.delete(registration);
42
+ },
43
+ });
44
+ }
45
+ latestState() {
46
+ return this.#pendingCommits.at(-1) ?? this.#state;
47
+ }
48
+ commit(next) {
49
+ const latest = this.latestState();
50
+ if (this.#closed || next === latest)
51
+ return;
52
+ this.#pendingCommits.push(next);
53
+ if (this.#notifying)
54
+ return;
55
+ this.#notifying = true;
56
+ try {
57
+ while (!this.#closed && this.#pendingCommits.length > 0) {
58
+ const state = this.#pendingCommits.shift();
59
+ this.#state = state;
60
+ for (const registration of [...this.#listeners]) {
61
+ this.#callListener(registration, state.snapshot);
62
+ }
63
+ }
64
+ }
65
+ finally {
66
+ this.#notifying = false;
67
+ if (this.#closed)
68
+ this.#pendingCommits.length = 0;
69
+ }
70
+ }
71
+ close() {
72
+ if (this.#closed)
73
+ return;
74
+ this.#closed = true;
75
+ this.#pendingCommits.length = 0;
76
+ for (const registration of this.#listeners)
77
+ registration.active = false;
78
+ this.#listeners.clear();
79
+ this.#state = null;
80
+ }
81
+ #callListener(registration, snapshot) {
82
+ if (!registration.active || registration.lastSnapshot === snapshot)
83
+ return;
84
+ registration.lastSnapshot = snapshot;
85
+ try {
86
+ registration.listener(snapshot);
87
+ }
88
+ catch (error) {
89
+ // One host listener must not prevent other subscribers from updating.
90
+ try {
91
+ this.#onListenerError?.(error);
92
+ }
93
+ catch {
94
+ // A diagnostic hook must not break publication to healthy listeners.
95
+ }
96
+ }
97
+ }
98
+ }
99
+ //# sourceMappingURL=snapshot-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-store.js","sourceRoot":"","sources":["../src/snapshot-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type TimelineItem } from "@turingfocus/chat-protocol";
2
+ export interface TimelineState {
3
+ readonly index: TimelineItemIndex;
4
+ readonly items: readonly TimelineItem[];
5
+ }
6
+ interface TimelineItemIndex {
7
+ readonly base: ReadonlyMap<string, TimelineItem>;
8
+ readonly overlay: ReadonlyMap<string, TimelineItem>;
9
+ }
10
+ export declare const createTimelineState: (items: readonly TimelineItem[]) => TimelineState;
11
+ export declare const findEventTimelineItem: (state: TimelineState, eventId: string) => TimelineItem | undefined;
12
+ export declare const upsertTimelineItem: (state: TimelineState, candidate: TimelineItem) => TimelineState;
13
+ /** Merge an older history page while preserving newer in-memory items. */
14
+ export declare const mergeHistoryTimeline: (current: TimelineState, history: readonly TimelineItem[]) => TimelineState;
15
+ /**
16
+ * Rebase a freshly loaded timeline onto changes published since the load began.
17
+ * Current changes win per stable item key; otherwise the loaded value (including
18
+ * a deletion) is adopted.
19
+ */
20
+ export declare const rebaseTimelineState: (baseline: TimelineState, loaded: TimelineState, current: TimelineState) => TimelineState;
21
+ export {};
22
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AAIpC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CACzC;AAED,UAAU,iBAAiB;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACrD;AAuCD,eAAO,MAAM,mBAAmB,GAC9B,OAAO,SAAS,YAAY,EAAE,KAC7B,aACkE,CAAC;AAEtE,eAAO,MAAM,qBAAqB,GAChC,OAAO,aAAa,EACpB,SAAS,MAAM,KACd,YAAY,GAAG,SAEjB,CAAC;AA6BF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,aAAa,EACpB,WAAW,YAAY,KACtB,aAsCF,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,oBAAoB,GAC/B,SAAS,aAAa,EACtB,SAAS,SAAS,YAAY,EAAE,KAC/B,aAYF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU,aAAa,EACvB,QAAQ,aAAa,EACrB,SAAS,aAAa,KACrB,aA+BF,CAAC"}