@grackle-ai/server 0.65.0 → 0.67.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,140 @@
1
+ /**
2
+ * Knowledge graph subsystem initialization and lifecycle management.
3
+ *
4
+ * Wires Neo4j, the local embedder, and event-driven reference node sync
5
+ * into the Grackle server. Opt-in via `GRACKLE_KNOWLEDGE_ENABLED=true`.
6
+ *
7
+ * @module
8
+ */
9
+ import { openNeo4j, initSchema, closeNeo4j, createLocalEmbedder, syncReferenceNode, deleteReferenceNodeBySource, deriveTaskText, deriveFindingText, } from "@grackle-ai/knowledge";
10
+ import { setKnowledgeEmbedder } from "@grackle-ai/mcp";
11
+ import { subscribe } from "./event-bus.js";
12
+ import * as taskStore from "./task-store.js";
13
+ import * as findingStore from "./finding-store.js";
14
+ import { safeParseJsonArray } from "./json-helpers.js";
15
+ import { logger } from "./logger.js";
16
+ // ---------------------------------------------------------------------------
17
+ // Configuration
18
+ // ---------------------------------------------------------------------------
19
+ /** Whether the knowledge graph subsystem is enabled. */
20
+ export function isKnowledgeEnabled() {
21
+ return process.env.GRACKLE_KNOWLEDGE_ENABLED === "true";
22
+ }
23
+ // ---------------------------------------------------------------------------
24
+ // Event handler
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Create an event bus subscriber that syncs reference nodes.
28
+ *
29
+ * Sync is fire-and-forget — errors are logged but never propagated.
30
+ */
31
+ function createEntitySyncHandler(embedder) {
32
+ return (event) => {
33
+ // Fire-and-forget async — errors handled inside handleEvent
34
+ handleEvent(embedder, event).catch(() => { });
35
+ };
36
+ }
37
+ /** Handle a single entity event. */
38
+ async function handleEvent(embedder, event) {
39
+ try {
40
+ const payload = event.payload;
41
+ switch (event.type) {
42
+ case "task.created":
43
+ case "task.updated": {
44
+ const taskId = payload.taskId;
45
+ if (typeof taskId !== "string" || !taskId) {
46
+ return;
47
+ }
48
+ const task = taskStore.getTask(taskId);
49
+ if (!task) {
50
+ logger.warn({ taskId }, "Knowledge sync: task not found, skipping");
51
+ return;
52
+ }
53
+ await syncReferenceNode(embedder, {
54
+ sourceType: "task",
55
+ sourceId: taskId,
56
+ label: task.title,
57
+ text: deriveTaskText(task.title, task.description),
58
+ workspaceId: task.workspaceId ?? "",
59
+ });
60
+ break;
61
+ }
62
+ case "task.deleted": {
63
+ const taskId = payload.taskId;
64
+ if (typeof taskId !== "string" || !taskId) {
65
+ return;
66
+ }
67
+ await deleteReferenceNodeBySource("task", taskId);
68
+ break;
69
+ }
70
+ case "finding.posted": {
71
+ const findingId = payload.findingId;
72
+ if (typeof findingId !== "string" || !findingId) {
73
+ return;
74
+ }
75
+ const workspaceId = typeof payload.workspaceId === "string" ? payload.workspaceId : "";
76
+ const findings = findingStore.queryFindings(workspaceId);
77
+ const finding = findings.find((f) => f.id === findingId);
78
+ if (!finding) {
79
+ logger.warn({ findingId }, "Knowledge sync: finding not found, skipping");
80
+ return;
81
+ }
82
+ const tags = safeParseJsonArray(typeof finding.tags === "string" ? finding.tags : null);
83
+ await syncReferenceNode(embedder, {
84
+ sourceType: "finding",
85
+ sourceId: findingId,
86
+ label: finding.title,
87
+ text: deriveFindingText(finding.title, finding.content, tags),
88
+ workspaceId,
89
+ });
90
+ break;
91
+ }
92
+ default:
93
+ // Ignore events we don't handle
94
+ break;
95
+ }
96
+ }
97
+ catch (err) {
98
+ logger.error({ err, eventType: event.type, eventId: event.id }, "Knowledge sync failed for entity event");
99
+ }
100
+ }
101
+ // ---------------------------------------------------------------------------
102
+ // Lifecycle
103
+ // ---------------------------------------------------------------------------
104
+ /**
105
+ * Initialize the knowledge graph subsystem.
106
+ *
107
+ * Opens Neo4j, initializes the schema, creates the local embedder,
108
+ * injects it into MCP tools, and subscribes to the event bus for
109
+ * automatic reference node sync.
110
+ *
111
+ * If any step after Neo4j connection fails, cleans up the connection
112
+ * before re-throwing.
113
+ *
114
+ * @returns A cleanup function that closes Neo4j and unsubscribes from events.
115
+ */
116
+ export async function initKnowledge() {
117
+ logger.info("Initializing knowledge graph subsystem");
118
+ await openNeo4j();
119
+ try {
120
+ await initSchema();
121
+ const embedder = createLocalEmbedder();
122
+ setKnowledgeEmbedder(embedder);
123
+ const unsubscribe = subscribe(createEntitySyncHandler(embedder));
124
+ logger.info("Knowledge graph subsystem ready");
125
+ return async () => {
126
+ logger.info("Shutting down knowledge graph subsystem");
127
+ unsubscribe();
128
+ setKnowledgeEmbedder(undefined);
129
+ await closeNeo4j();
130
+ logger.info("Knowledge graph subsystem stopped");
131
+ };
132
+ }
133
+ catch (err) {
134
+ // Clean up Neo4j if a later step fails
135
+ setKnowledgeEmbedder(undefined);
136
+ await closeNeo4j().catch(() => { });
137
+ throw err;
138
+ }
139
+ }
140
+ //# sourceMappingURL=knowledge-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-init.js","sourceRoot":"","sources":["../src/knowledge-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Lifecycle manager — auto-hibernates sessions when all their file descriptors are closed.
3
+ *
4
+ * When the last subscription (fd) for a session is removed from the stream-registry,
5
+ * the orphan callback fires and this module:
6
+ * 1. Sets the session status to HIBERNATING
7
+ * 2. Kills the PowerLine process (best-effort)
8
+ * 3. Broadcasts the status change to UI clients
9
+ * 4. Emits a task.updated event if the session has a task
10
+ *
11
+ * This is the foundation of the emergent lifecycle model: session alive/dead is
12
+ * determined by subscription state, not explicit status calls.
13
+ */
14
+ /**
15
+ * Initialize the lifecycle manager. Registers the orphan callback on the
16
+ * stream-registry so that sessions auto-hibernate when all fds are closed.
17
+ * Idempotent — safe to call multiple times.
18
+ */
19
+ export declare function initLifecycleManager(): void;
20
+ /**
21
+ * Clean up lifecycle stream for a session. Deletes the stream and all its
22
+ * subscriptions, which triggers the orphan callback (auto-hibernate).
23
+ *
24
+ * Called from killAgent when explicitly terminating a session. For sessions
25
+ * that complete normally, lifecycle streams persist until the UI or
26
+ * reconciliation loop closes them — this is intentional (the session stays
27
+ * "alive" and reanimate-safe until someone decides to close the fd).
28
+ */
29
+ export declare function cleanupLifecycleStream(sessionId: string): void;
30
+ /**
31
+ * Reset module state. For testing only.
32
+ * @internal
33
+ */
34
+ export declare function _resetForTesting(): void;
35
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAoD3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAK9D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Lifecycle manager — auto-hibernates sessions when all their file descriptors are closed.
3
+ *
4
+ * When the last subscription (fd) for a session is removed from the stream-registry,
5
+ * the orphan callback fires and this module:
6
+ * 1. Sets the session status to HIBERNATING
7
+ * 2. Kills the PowerLine process (best-effort)
8
+ * 3. Broadcasts the status change to UI clients
9
+ * 4. Emits a task.updated event if the session has a task
10
+ *
11
+ * This is the foundation of the emergent lifecycle model: session alive/dead is
12
+ * determined by subscription state, not explicit status calls.
13
+ */
14
+ import { create } from "@bufbuild/protobuf";
15
+ import { grackle, SESSION_STATUS, TERMINAL_SESSION_STATUSES } from "@grackle-ai/common";
16
+ import { powerline } from "@grackle-ai/common";
17
+ import * as streamRegistry from "./stream-registry.js";
18
+ import * as sessionStore from "./session-store.js";
19
+ import * as adapterManager from "./adapter-manager.js";
20
+ import * as streamHub from "./stream-hub.js";
21
+ import * as taskStore from "./task-store.js";
22
+ import { emit } from "./event-bus.js";
23
+ import { logger } from "./logger.js";
24
+ /** Whether the lifecycle manager has been initialized. */
25
+ let initialized = false;
26
+ /**
27
+ * Initialize the lifecycle manager. Registers the orphan callback on the
28
+ * stream-registry so that sessions auto-hibernate when all fds are closed.
29
+ * Idempotent — safe to call multiple times.
30
+ */
31
+ export function initLifecycleManager() {
32
+ if (initialized) {
33
+ return;
34
+ }
35
+ initialized = true;
36
+ streamRegistry.onSessionOrphaned((sessionId) => {
37
+ const session = sessionStore.getSession(sessionId);
38
+ if (!session) {
39
+ return;
40
+ }
41
+ // Don't hibernate if already in a terminal state
42
+ if (TERMINAL_SESSION_STATUSES.has(session.status)) {
43
+ return;
44
+ }
45
+ logger.info({ sessionId, previousStatus: session.status }, "Session orphaned (no remaining fds) — hibernating");
46
+ sessionStore.hibernateSession(sessionId);
47
+ // Kill the PowerLine process (best-effort — may have already exited)
48
+ const conn = adapterManager.getConnection(session.environmentId);
49
+ if (conn) {
50
+ conn.client.kill(create(powerline.SessionIdSchema, { id: sessionId })).catch((err) => {
51
+ logger.debug({ err, sessionId }, "Lifecycle: PowerLine kill failed (process may have already exited)");
52
+ });
53
+ }
54
+ // Broadcast status change to UI clients
55
+ streamHub.publish(create(grackle.SessionEventSchema, {
56
+ sessionId,
57
+ type: grackle.EventType.STATUS,
58
+ timestamp: new Date().toISOString(),
59
+ content: SESSION_STATUS.HIBERNATING,
60
+ raw: "",
61
+ }));
62
+ // Notify task system if this session belongs to a task
63
+ if (session.taskId) {
64
+ const task = taskStore.getTask(session.taskId);
65
+ if (task) {
66
+ emit("task.updated", { taskId: task.id, workspaceId: task.workspaceId || "" });
67
+ }
68
+ }
69
+ });
70
+ logger.info("Lifecycle manager initialized");
71
+ }
72
+ /**
73
+ * Clean up lifecycle stream for a session. Deletes the stream and all its
74
+ * subscriptions, which triggers the orphan callback (auto-hibernate).
75
+ *
76
+ * Called from killAgent when explicitly terminating a session. For sessions
77
+ * that complete normally, lifecycle streams persist until the UI or
78
+ * reconciliation loop closes them — this is intentional (the session stays
79
+ * "alive" and reanimate-safe until someone decides to close the fd).
80
+ */
81
+ export function cleanupLifecycleStream(sessionId) {
82
+ const lifecycleStream = streamRegistry.getStreamByName(`lifecycle:${sessionId}`);
83
+ if (lifecycleStream) {
84
+ streamRegistry.deleteStream(lifecycleStream.id);
85
+ }
86
+ }
87
+ /**
88
+ * Reset module state. For testing only.
89
+ * @internal
90
+ */
91
+ export function _resetForTesting() {
92
+ initialized = false;
93
+ }
94
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { PowerLineConnection } from "@grackle-ai/adapter-sdk";
2
+ /**
3
+ * Recover disconnected sessions for a newly reconnected environment.
4
+ *
5
+ * Finds sessions in SUSPENDED, RUNNING, or IDLE state (RUNNING/IDLE handles
6
+ * the "server died" scenario where sessions never got suspended). Drains
7
+ * buffered events from PowerLine, writes them to the session JSONL, then
8
+ * reanimates the first recoverable session. Remaining sessions are left
9
+ * SUSPENDED for later recovery (only one active session per environment).
10
+ *
11
+ * Fire-and-forget: logs errors but does not throw.
12
+ */
13
+ export declare function recoverSuspendedSessions(environmentId: string, connection: PowerLineConnection): Promise<void>;
14
+ /** @internal Reset the recovery lock for testing. */
15
+ export declare function _resetForTesting(): void;
16
+ //# sourceMappingURL=session-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-recovery.d.ts","sourceRoot":"","sources":["../src/session-recovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAanE;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,mBAAmB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA6Ff;AAWD,qDAAqD;AACrD,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
@@ -0,0 +1,115 @@
1
+ import { create } from "@bufbuild/protobuf";
2
+ import { grackle, powerline, eventTypeToEnum, SESSION_STATUS, LOGS_DIR } from "@grackle-ai/common";
3
+ import { join } from "node:path";
4
+ import * as sessionStore from "./session-store.js";
5
+ import * as taskStore from "./task-store.js";
6
+ import * as logWriter from "./log-writer.js";
7
+ import { reanimateAgent } from "./reanimate-agent.js";
8
+ import { grackleHome } from "./paths.js";
9
+ import { logger } from "./logger.js";
10
+ import { emit } from "./event-bus.js";
11
+ /** Set of environment IDs currently undergoing recovery to prevent concurrent attempts. */
12
+ const recoveringEnvironments = new Set();
13
+ /**
14
+ * Recover disconnected sessions for a newly reconnected environment.
15
+ *
16
+ * Finds sessions in SUSPENDED, RUNNING, or IDLE state (RUNNING/IDLE handles
17
+ * the "server died" scenario where sessions never got suspended). Drains
18
+ * buffered events from PowerLine, writes them to the session JSONL, then
19
+ * reanimates the first recoverable session. Remaining sessions are left
20
+ * SUSPENDED for later recovery (only one active session per environment).
21
+ *
22
+ * Fire-and-forget: logs errors but does not throw.
23
+ */
24
+ export async function recoverSuspendedSessions(environmentId, connection) {
25
+ if (recoveringEnvironments.has(environmentId)) {
26
+ logger.warn({ environmentId }, "Recovery already in progress — skipping");
27
+ return;
28
+ }
29
+ // Find sessions that need recovery: SUSPENDED (normal path) plus
30
+ // RUNNING/IDLE (server-died path where sessions were never suspended).
31
+ const suspended = sessionStore.getSuspendedForEnv(environmentId);
32
+ const active = sessionStore.getActiveForEnv(environmentId);
33
+ // Transition any stale active session to SUSPENDED first so reanimate accepts it.
34
+ if (active) {
35
+ sessionStore.suspendSession(active.id);
36
+ suspended.unshift(active);
37
+ }
38
+ if (suspended.length === 0) {
39
+ return;
40
+ }
41
+ recoveringEnvironments.add(environmentId);
42
+ logger.info({ environmentId, count: suspended.length }, "Beginning recovery of suspended sessions");
43
+ try {
44
+ // Only reanimate the first session — the one-active-session-per-env
45
+ // constraint means subsequent sessions would fail. Leave the rest
46
+ // SUSPENDED for manual reanimate or future recovery.
47
+ const session = suspended[0];
48
+ try {
49
+ // Step 1: Drain buffered events from PowerLine and append to JSONL
50
+ const logPath = session.logPath || join(grackleHome, LOGS_DIR, session.id);
51
+ const drainReq = create(powerline.DrainRequestSchema, {
52
+ sessionId: session.id,
53
+ });
54
+ let drainedCount = 0;
55
+ try {
56
+ const drainStream = connection.client.drainBufferedEvents(drainReq);
57
+ logWriter.ensureLogInitialized(logPath);
58
+ for await (const event of drainStream) {
59
+ // Skip internal events (e.g. runtime_session_id) that would map
60
+ // to UNSPECIFIED — those are handled by processEventStream, not the drain.
61
+ const eventType = eventTypeToEnum(event.type);
62
+ if (eventType === grackle.EventType.UNSPECIFIED) {
63
+ continue;
64
+ }
65
+ const sessionEvent = create(grackle.SessionEventSchema, {
66
+ sessionId: session.id,
67
+ type: eventType,
68
+ timestamp: event.timestamp,
69
+ content: event.content,
70
+ raw: event.raw,
71
+ });
72
+ logWriter.writeEvent(logPath, sessionEvent);
73
+ drainedCount++;
74
+ }
75
+ }
76
+ catch (drainErr) {
77
+ // Drain may fail if PowerLine was restarted (no parked events).
78
+ // This is expected — continue to reanimate anyway.
79
+ logger.info({ sessionId: session.id, err: drainErr }, "Drain returned no buffered events (PowerLine may have restarted)");
80
+ }
81
+ finally {
82
+ // Always close the log stream to avoid leaking file descriptors.
83
+ logWriter.endSession(logPath);
84
+ }
85
+ if (drainedCount > 0) {
86
+ logger.info({ sessionId: session.id, drainedCount }, "Drained buffered events for suspended session");
87
+ }
88
+ // Step 2: Reanimate the session (starts resume stream + processEventStream)
89
+ reanimateAgent(session.id);
90
+ logger.info({ sessionId: session.id }, "Successfully reanimated suspended session");
91
+ emitTaskUpdated(session.taskId);
92
+ }
93
+ catch (err) {
94
+ logger.error({ sessionId: session.id, err }, "Failed to recover suspended session — marking failed");
95
+ sessionStore.updateSession(session.id, SESSION_STATUS.FAILED, undefined, `Recovery failed: ${String(err)}`);
96
+ emitTaskUpdated(session.taskId);
97
+ }
98
+ }
99
+ finally {
100
+ recoveringEnvironments.delete(environmentId);
101
+ }
102
+ }
103
+ /** Emit a task.updated event with the correct workspaceId, if the session has a task. */
104
+ function emitTaskUpdated(taskId) {
105
+ if (!taskId) {
106
+ return;
107
+ }
108
+ const task = taskStore.getTask(taskId);
109
+ emit("task.updated", { taskId, workspaceId: task?.workspaceId || "" });
110
+ }
111
+ /** @internal Reset the recovery lock for testing. */
112
+ export function _resetForTesting() {
113
+ recoveringEnvironments.clear();
114
+ }
115
+ //# sourceMappingURL=session-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-recovery.js","sourceRoot":"","sources":["../src/session-recovery.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,10 @@ export declare function deleteByEnvironment(environmentId: string): void;
37
37
  export declare function setSessionTask(id: string, taskId: string): void;
38
38
  /** Persist the runtime-native session ID returned by the PowerLine. */
39
39
  export declare function updateRuntimeSessionId(id: string, runtimeSessionId: string): void;
40
+ /** Transition a session to SUSPENDED — transport lost, pending auto-recovery on reconnect. */
41
+ export declare function suspendSession(id: string): void;
42
+ /** Get all SUSPENDED sessions for an environment, ordered by startedAt (oldest first). */
43
+ export declare function getSuspendedForEnv(environmentId: string): SessionRow[];
40
44
  /** Clear terminal state for reanimate — reset status to running, clear endedAt/error/suspendedAt. */
41
45
  export declare function reanimateSession(id: string): void;
42
46
  /** List all sessions for a specific task, ordered chronologically (oldest first). */
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
@@ -136,6 +136,24 @@ export function updateRuntimeSessionId(id, runtimeSessionId) {
136
136
  .where(eq(sessions.id, id))
137
137
  .run();
138
138
  }
139
+ /** Transition a session to SUSPENDED — transport lost, pending auto-recovery on reconnect. */
140
+ export function suspendSession(id) {
141
+ db.update(sessions)
142
+ .set({
143
+ status: SESSION_STATUS.SUSPENDED,
144
+ suspendedAt: new Date().toISOString(),
145
+ error: null,
146
+ })
147
+ .where(eq(sessions.id, id))
148
+ .run();
149
+ }
150
+ /** Get all SUSPENDED sessions for an environment, ordered by startedAt (oldest first). */
151
+ export function getSuspendedForEnv(environmentId) {
152
+ return db.select().from(sessions)
153
+ .where(and(eq(sessions.environmentId, environmentId), eq(sessions.status, SESSION_STATUS.SUSPENDED)))
154
+ .orderBy(asc(sessions.startedAt))
155
+ .all();
156
+ }
139
157
  /** Clear terminal state for reanimate — reset status to running, clear endedAt/error/suspendedAt. */
140
158
  export function reanimateSession(id) {
141
159
  db.update(sessions)
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,8 @@ export interface Subscription {
42
42
  }
43
43
  /** Callback invoked when a message arrives on an async subscription. */
44
44
  export type AsyncMessageListener = (sub: Subscription, msg: StreamMessage) => void;
45
+ /** Callback invoked when a session has zero remaining subscriptions (orphaned). */
46
+ type OrphanCallback = (sessionId: string) => void;
45
47
  /** Create a new named stream. Names must be unique — throws if a stream with the same name exists. */
46
48
  export declare function createStream(name: string): Stream;
47
49
  /** Retrieve a stream by ID. */
@@ -71,6 +73,12 @@ export declare function hasUndeliveredMessages(subscriptionId: string): boolean;
71
73
  * for the given session. Returns an unsubscribe function.
72
74
  */
73
75
  export declare function registerAsyncListener(sessionId: string, callback: AsyncMessageListener): () => void;
76
+ /**
77
+ * Register a callback invoked when a session has zero remaining subscriptions.
78
+ * Used by the lifecycle manager to auto-hibernate orphaned sessions.
79
+ */
80
+ export declare function onSessionOrphaned(cb: OrphanCallback): void;
74
81
  /** Clear all state. For testing only. */
75
82
  export declare function _resetForTesting(): void;
83
+ export {};
76
84
  //# sourceMappingURL=stream-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-registry.d.ts","sourceRoot":"","sources":["../src/stream-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream-registry.d.ts","sourceRoot":"","sources":["../src/stream-registry.ts"],"names":[],"mappings":"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"}
@@ -65,6 +65,7 @@ const fdCounters = new Map();
65
65
  const asyncListeners = new Map();
66
66
  /** Blocking queues for sync subscriptions, keyed by subscription ID. */
67
67
  const syncQueues = new Map();
68
+ let orphanCallback;
68
69
  // ─── Internal Helpers ─────────────────────────────────────────────────────────
69
70
  /** Allocate the next fd number for a session. */
70
71
  function nextFd(sessionId) {
@@ -81,12 +82,23 @@ function getSessionFdMap(sessionId) {
81
82
  }
82
83
  return fdMap;
83
84
  }
84
- /** Clean up session state when it has no more subscriptions. */
85
+ /** Clean up session state when it has no more subscriptions. Fires orphan callback. */
85
86
  function cleanupSessionIfEmpty(sessionId) {
86
87
  const fdMap = subscriptionsBySession.get(sessionId);
87
88
  if (fdMap?.size === 0) {
88
89
  subscriptionsBySession.delete(sessionId);
89
90
  fdCounters.delete(sessionId);
91
+ try {
92
+ orphanCallback?.(sessionId);
93
+ }
94
+ catch (err) {
95
+ // Best-effort — orphan callback errors must not break stream-registry cleanup.
96
+ // Log at debug level for diagnosability.
97
+ try {
98
+ console.debug("stream-registry: orphan callback error for", sessionId, err);
99
+ }
100
+ catch { /* ignore */ }
101
+ }
90
102
  }
91
103
  }
92
104
  /** Check if a subscription can receive messages (has read permission). */
@@ -324,6 +336,14 @@ export function registerAsyncListener(sessionId, callback) {
324
336
  asyncListeners.delete(sessionId);
325
337
  };
326
338
  }
339
+ // ─── Lifecycle Callbacks ──────────────────────────────────────────────────────
340
+ /**
341
+ * Register a callback invoked when a session has zero remaining subscriptions.
342
+ * Used by the lifecycle manager to auto-hibernate orphaned sessions.
343
+ */
344
+ export function onSessionOrphaned(cb) {
345
+ orphanCallback = cb;
346
+ }
327
347
  // ─── Testing ──────────────────────────────────────────────────────────────────
328
348
  /** Clear all state. For testing only. */
329
349
  export function _resetForTesting() {
@@ -338,5 +358,6 @@ export function _resetForTesting() {
338
358
  queue.close();
339
359
  }
340
360
  syncQueues.clear();
361
+ orphanCallback = undefined;
341
362
  }
342
363
  //# sourceMappingURL=stream-registry.js.map