@morlay/session-rdb 0.0.19 → 0.0.20

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.
@@ -1,4 +1,4 @@
1
- import { C as EventRow, w as SessionRow } from "./schema-DPcuEh_a.mjs";
1
+ import { C as EventRow, w as SessionRow } from "./schema-BkQN5GyT.mjs";
2
2
  import { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, parseImportZip, parseJsonlArtifact, persistImport, registerSessionImport } from "./import.mjs";
3
3
  import { SessionStorageMetadata } from "@deepseek-ai/dsh-session-persistence";
4
4
  import { SessionEvent, SessionHeader } from "@deepseek-ai/dsh-session";
package/dist/artifact.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  import { _ as toJsonlArtifact, a as repairAssistantSettlement, c as repairRequestHeaders, d as rowToMeta, f as scanRows, g as titleOfEventData, h as syncMeteringRanges, i as renameLegacyPtcEvents, l as repairSurfaceOps, m as sessionInsertRow, n as orphanInboxSpliceSeqs, o as repairOrphanInboxSplices, p as sessionConflictRow, r as recomputeReplaceProvenance, s as repairReadView, t as findSurfaceRepairs, u as rowToEvent } from "./log-DO69NQnn.mjs";
2
- import { a as persistImport, i as parseJsonlArtifact, n as SESSION_LOG_ARTIFACT_FILENAME, o as registerSessionImport, r as parseImportZip, t as SESSION_IMPORT_PATH } from "./import-Bc2QQa5G.mjs";
2
+ import { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, parseImportZip, parseJsonlArtifact, persistImport, registerSessionImport } from "./import.mjs";
3
3
  export { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, findSurfaceRepairs, orphanInboxSpliceSeqs, parseImportZip, parseJsonlArtifact, persistImport, recomputeReplaceProvenance, registerSessionImport, renameLegacyPtcEvents, repairAssistantSettlement, repairOrphanInboxSplices, repairReadView, repairRequestHeaders, repairSurfaceOps, rowToEvent, rowToMeta, scanRows, sessionConflictRow, sessionInsertRow, syncMeteringRanges, titleOfEventData, toJsonlArtifact };
@@ -1,10 +1,7 @@
1
1
  import { d as rowToMeta } from "./log-DO69NQnn.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { SESSION_FORMAT_VERSION, SessionLogOffset } from "@deepseek-ai/dsh-session";
4
- import { parseSessionFormatLogFilename } from "@deepseek-ai/dsh-session-format";
5
- import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
6
4
  import { SessionBranch, SessionBranchError, balanceRewindPrefix, buildTimeline } from "@morlay/session-branch";
7
- import { unzipSync } from "fflate";
8
5
  //#region src/branch.ts
9
6
  function locateTurnEnd(events, atSeq, mode = "after") {
10
7
  const ends = events.filter((event) => event.type === "turn/end").map((event) => event.seq);
@@ -279,195 +276,4 @@ var SessionBranchRdb = class extends SessionBranch {
279
276
  }
280
277
  };
281
278
  //#endregion
282
- //#region src/import.ts
283
- /** 当前世代产物的文件名(读入侧接受任意 canonical 世代名,见 parseImportZip)。 */
284
- const SESSION_LOG_ARTIFACT_FILENAME = "session.jsonl";
285
- const SESSION_IMPORT_PATH = "/api/session.import";
286
- const MAX_IMPORT_ZIP_BYTES = 67108864;
287
- function parseJsonlArtifact(content) {
288
- const lines = content.split("\n");
289
- if (lines.length === 0 || lines[0] === "") throw new Error("imported session log is empty");
290
- let header;
291
- try {
292
- header = JSON.parse(lines[0]);
293
- } catch {
294
- throw new Error("imported session log has an unparsable header line");
295
- }
296
- let restore;
297
- try {
298
- restore = sessionFormatCatalog.createRestore(header, {
299
- recovery: "strict",
300
- validation: "transformed"
301
- });
302
- } catch (error) {
303
- throw new Error(`imported session log has an invalid header line: ${error instanceof Error ? error.message : String(error)}`);
304
- }
305
- for (let i = 1; i < lines.length; i++) {
306
- const line = lines[i];
307
- if (line === void 0 || line === "") continue;
308
- let parsed;
309
- try {
310
- parsed = JSON.parse(line);
311
- } catch {
312
- throw new Error(`imported session log has an unparsable event line at ${i}`);
313
- }
314
- try {
315
- restore.decodeRow(parsed);
316
- } catch (error) {
317
- throw new Error(`imported session log has an invalid event line at ${i}: ${error instanceof Error ? error.message : String(error)}`);
318
- }
319
- }
320
- let artifact;
321
- try {
322
- artifact = restore.finish();
323
- } catch (error) {
324
- throw new Error(`imported session log is incomplete: ${error instanceof Error ? error.message : String(error)}`);
325
- }
326
- const meta = artifact.header;
327
- const events = artifact.events;
328
- for (let i = 0; i < events.length; i++) if (events[i].seq !== i) throw new Error(`imported session log seq gap at ${i} (got ${events[i].seq}); import requires a dense log`);
329
- const inheritedEventCount = Math.min(artifact.inheritedEventCount, events.length);
330
- return {
331
- meta: {
332
- version: SESSION_FORMAT_VERSION,
333
- id: meta.id,
334
- createdAt: meta.createdAt,
335
- ...meta.cwd === void 0 ? {} : { cwd: meta.cwd },
336
- ...meta.parentSession === void 0 ? {} : { parentSession: meta.parentSession },
337
- isSeeded: meta.isSeeded,
338
- ...meta.origin === void 0 ? {} : { origin: meta.origin },
339
- ...meta.delegationDepth === void 0 ? {} : { delegationDepth: meta.delegationDepth },
340
- ...meta.agentPreset === void 0 ? {} : { agentPreset: meta.agentPreset }
341
- },
342
- inheritedEventCount: SessionLogOffset(inheritedEventCount),
343
- events
344
- };
345
- }
346
- function parseImportZip(zip) {
347
- let entries;
348
- try {
349
- entries = unzipSync(zip);
350
- } catch {
351
- throw new Error("imported zip is not a valid ZIP archive");
352
- }
353
- const artifact = Object.entries(entries).find(([name]) => parseSessionFormatLogFilename(name) !== void 0);
354
- if (artifact === void 0) throw new Error(`imported zip has no session log artifact (expected ${SESSION_LOG_ARTIFACT_FILENAME} or a canonical session.vN.jsonl)`);
355
- return parseJsonlArtifact(new TextDecoder().decode(artifact[1]));
356
- }
357
- async function stopAgentLoop(ctx, sessionId) {
358
- const agent = ctx.get("agents")?.get(sessionId);
359
- if (agent === void 0) return;
360
- agent.cancel?.({ kind: "user" }, { keepInbox: true });
361
- await agent.whenIdle();
362
- }
363
- async function persistImport(persistence, branch, imported, targetId, sessions, stopLoop) {
364
- const id = targetId ?? `session-${randomUUID()}`;
365
- if (targetId !== void 0) {
366
- if (branch === void 0) throw new Error("sessionBranch service is unavailable");
367
- if (stopLoop !== void 0) await stopLoop(targetId);
368
- await branch.rewind(targetId, -1);
369
- const liveHandle = persistence.tracker.writerOf(targetId);
370
- if (liveHandle !== void 0) {
371
- if (imported.events.length > 0) await liveHandle.append(imported.events);
372
- } else {
373
- const handle = await persistence.open(targetId, "write");
374
- try {
375
- if (imported.events.length > 0) await handle.append(imported.events);
376
- } finally {
377
- await handle.close();
378
- }
379
- }
380
- } else {
381
- const handle = await persistence.create({
382
- ...imported.meta,
383
- id
384
- }, { inheritedEventCount: imported.inheritedEventCount });
385
- if (imported.events.length > 0) await handle.append(imported.events);
386
- await handle.close();
387
- }
388
- if (targetId !== void 0) {
389
- const live = sessions?.get(targetId);
390
- if (live !== void 0) replaceLiveSessionLog(live, imported.events);
391
- }
392
- return id;
393
- }
394
- function registerSessionImport(ctx, persistence) {
395
- ctx.inject(["webServer", "connection"], (webCtx) => {
396
- const webServer = webCtx.webServer;
397
- const connection = webCtx.get("connection");
398
- return webCtx.effect(() => webServer.register({
399
- kind: "exact",
400
- path: SESSION_IMPORT_PATH,
401
- handler: async (req, res) => {
402
- const rejection = connection.requestRejection(req);
403
- if (rejection !== void 0) {
404
- res.writeHead(rejection);
405
- res.end(rejection === 401 ? "unauthorized" : "forbidden");
406
- return;
407
- }
408
- const chunks = [];
409
- for await (const chunk of req) chunks.push(chunk);
410
- const body = Buffer.concat(chunks);
411
- let envelope;
412
- try {
413
- envelope = JSON.parse(body.toString("utf8"));
414
- } catch {
415
- res.writeHead(400, { "content-type": "application/json" });
416
- res.end(JSON.stringify({ error: "request body is not JSON" }));
417
- return;
418
- }
419
- if (typeof envelope.zip !== "string" || envelope.zip === "") {
420
- res.writeHead(400, { "content-type": "application/json" });
421
- res.end(JSON.stringify({ error: "missing zip field" }));
422
- return;
423
- }
424
- if (envelope.sessionId !== void 0 && (typeof envelope.sessionId !== "string" || envelope.sessionId === "")) {
425
- res.writeHead(400, { "content-type": "application/json" });
426
- res.end(JSON.stringify({ error: "sessionId must be a non-empty string" }));
427
- return;
428
- }
429
- let zip;
430
- try {
431
- zip = Buffer.from(envelope.zip, "base64");
432
- } catch {
433
- res.writeHead(400, { "content-type": "application/json" });
434
- res.end(JSON.stringify({ error: "zip field is not valid base64" }));
435
- return;
436
- }
437
- if (zip.byteLength > MAX_IMPORT_ZIP_BYTES) {
438
- res.writeHead(413, { "content-type": "application/json" });
439
- res.end(JSON.stringify({ error: "imported zip exceeds the size limit" }));
440
- return;
441
- }
442
- let imported;
443
- try {
444
- imported = parseImportZip(zip);
445
- } catch (error) {
446
- res.writeHead(400, { "content-type": "application/json" });
447
- res.end(JSON.stringify({ error: error instanceof Error ? error.message : "imported zip is invalid" }));
448
- return;
449
- }
450
- const targetId = typeof envelope.sessionId === "string" ? envelope.sessionId : void 0;
451
- const branch = webCtx.get("sessionBranch");
452
- try {
453
- const sessions = webCtx.get("sessions");
454
- const id = await persistImport(persistence, branch, imported, targetId, sessions, (sessionId) => stopAgentLoop(webCtx, sessionId));
455
- res.writeHead(200, { "content-type": "application/json" });
456
- res.end(JSON.stringify({ sessionId: id }));
457
- } catch (error) {
458
- const message = error instanceof Error ? error.message : String(error);
459
- if (targetId !== void 0 && /not found/i.test(message)) {
460
- res.writeHead(404, { "content-type": "application/json" });
461
- res.end(JSON.stringify({ error: `session "${targetId}" not found` }));
462
- return;
463
- }
464
- res.writeHead(500, { "content-type": "application/json" });
465
- res.end(JSON.stringify({ error: error instanceof Error ? error.message : "import failed" }));
466
- return;
467
- }
468
- }
469
- }), `session-rdb: ${SESSION_IMPORT_PATH} route`);
470
- });
471
- }
472
- //#endregion
473
- export { persistImport as a, SessionBranchRdbProvider as c, parseJsonlArtifact as i, locateTurnEnd as l, SESSION_LOG_ARTIFACT_FILENAME as n, registerSessionImport as o, parseImportZip as r, SessionBranchRdb as s, SESSION_IMPORT_PATH as t };
279
+ export { truncateLiveSession as a, replaceLiveSessionLog as i, SessionBranchRdbProvider as n, locateTurnEnd as r, SessionBranchRdb as t };
package/dist/import.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as SessionPersistenceRdb } from "./index-CCcK9tia.mjs";
1
+ import { r as SessionPersistenceRdb } from "./index-D55G9n4k.mjs";
2
2
  import { SessionStorageMetadata } from "@deepseek-ai/dsh-session-persistence";
3
3
  import { Session, SessionEvent, SessionId } from "@deepseek-ai/dsh-session";
4
4
  import { Context } from "@deepseek-ai/cordis";
package/dist/import.mjs CHANGED
@@ -1,2 +1,198 @@
1
- import { a as persistImport, i as parseJsonlArtifact, n as SESSION_LOG_ARTIFACT_FILENAME, o as registerSessionImport, r as parseImportZip, t as SESSION_IMPORT_PATH } from "./import-Bc2QQa5G.mjs";
1
+ import { i as replaceLiveSessionLog } from "./branch-Co6xlbi0.mjs";
2
+ import { randomUUID } from "node:crypto";
3
+ import { SESSION_FORMAT_VERSION, SessionLogOffset } from "@deepseek-ai/dsh-session";
4
+ import { parseSessionFormatLogFilename } from "@deepseek-ai/dsh-session-format";
5
+ import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
6
+ import { unzipSync } from "fflate";
7
+ //#region src/import.ts
8
+ /** 当前世代产物的文件名(读入侧接受任意 canonical 世代名,见 parseImportZip)。 */
9
+ const SESSION_LOG_ARTIFACT_FILENAME = "session.jsonl";
10
+ const SESSION_IMPORT_PATH = "/api/session.import";
11
+ const MAX_IMPORT_ZIP_BYTES = 67108864;
12
+ function parseJsonlArtifact(content) {
13
+ const lines = content.split("\n");
14
+ if (lines.length === 0 || lines[0] === "") throw new Error("imported session log is empty");
15
+ let header;
16
+ try {
17
+ header = JSON.parse(lines[0]);
18
+ } catch {
19
+ throw new Error("imported session log has an unparsable header line");
20
+ }
21
+ let restore;
22
+ try {
23
+ restore = sessionFormatCatalog.createRestore(header, {
24
+ recovery: "strict",
25
+ validation: "transformed"
26
+ });
27
+ } catch (error) {
28
+ throw new Error(`imported session log has an invalid header line: ${error instanceof Error ? error.message : String(error)}`);
29
+ }
30
+ for (let i = 1; i < lines.length; i++) {
31
+ const line = lines[i];
32
+ if (line === void 0 || line === "") continue;
33
+ let parsed;
34
+ try {
35
+ parsed = JSON.parse(line);
36
+ } catch {
37
+ throw new Error(`imported session log has an unparsable event line at ${i}`);
38
+ }
39
+ try {
40
+ restore.decodeRow(parsed);
41
+ } catch (error) {
42
+ throw new Error(`imported session log has an invalid event line at ${i}: ${error instanceof Error ? error.message : String(error)}`);
43
+ }
44
+ }
45
+ let artifact;
46
+ try {
47
+ artifact = restore.finish();
48
+ } catch (error) {
49
+ throw new Error(`imported session log is incomplete: ${error instanceof Error ? error.message : String(error)}`);
50
+ }
51
+ const meta = artifact.header;
52
+ const events = artifact.events;
53
+ for (let i = 0; i < events.length; i++) if (events[i].seq !== i) throw new Error(`imported session log seq gap at ${i} (got ${events[i].seq}); import requires a dense log`);
54
+ const inheritedEventCount = Math.min(artifact.inheritedEventCount, events.length);
55
+ return {
56
+ meta: {
57
+ version: SESSION_FORMAT_VERSION,
58
+ id: meta.id,
59
+ createdAt: meta.createdAt,
60
+ ...meta.cwd === void 0 ? {} : { cwd: meta.cwd },
61
+ ...meta.parentSession === void 0 ? {} : { parentSession: meta.parentSession },
62
+ isSeeded: meta.isSeeded,
63
+ ...meta.origin === void 0 ? {} : { origin: meta.origin },
64
+ ...meta.delegationDepth === void 0 ? {} : { delegationDepth: meta.delegationDepth },
65
+ ...meta.agentPreset === void 0 ? {} : { agentPreset: meta.agentPreset }
66
+ },
67
+ inheritedEventCount: SessionLogOffset(inheritedEventCount),
68
+ events
69
+ };
70
+ }
71
+ function parseImportZip(zip) {
72
+ let entries;
73
+ try {
74
+ entries = unzipSync(zip);
75
+ } catch {
76
+ throw new Error("imported zip is not a valid ZIP archive");
77
+ }
78
+ const artifact = Object.entries(entries).find(([name]) => parseSessionFormatLogFilename(name) !== void 0);
79
+ if (artifact === void 0) throw new Error(`imported zip has no session log artifact (expected ${SESSION_LOG_ARTIFACT_FILENAME} or a canonical session.vN.jsonl)`);
80
+ return parseJsonlArtifact(new TextDecoder().decode(artifact[1]));
81
+ }
82
+ async function stopAgentLoop(ctx, sessionId) {
83
+ const agent = ctx.get("agents")?.get(sessionId);
84
+ if (agent === void 0) return;
85
+ agent.cancel?.({ kind: "user" }, { keepInbox: true });
86
+ await agent.whenIdle();
87
+ }
88
+ async function persistImport(persistence, branch, imported, targetId, sessions, stopLoop) {
89
+ const id = targetId ?? `session-${randomUUID()}`;
90
+ if (targetId !== void 0) {
91
+ if (branch === void 0) throw new Error("sessionBranch service is unavailable");
92
+ if (stopLoop !== void 0) await stopLoop(targetId);
93
+ await branch.rewind(targetId, -1);
94
+ const liveHandle = persistence.tracker.writerOf(targetId);
95
+ if (liveHandle !== void 0) {
96
+ if (imported.events.length > 0) await liveHandle.append(imported.events);
97
+ } else {
98
+ const handle = await persistence.open(targetId, "write");
99
+ try {
100
+ if (imported.events.length > 0) await handle.append(imported.events);
101
+ } finally {
102
+ await handle.close();
103
+ }
104
+ }
105
+ } else {
106
+ const handle = await persistence.create({
107
+ ...imported.meta,
108
+ id
109
+ }, { inheritedEventCount: imported.inheritedEventCount });
110
+ if (imported.events.length > 0) await handle.append(imported.events);
111
+ await handle.close();
112
+ }
113
+ if (targetId !== void 0) {
114
+ const live = sessions?.get(targetId);
115
+ if (live !== void 0) replaceLiveSessionLog(live, imported.events);
116
+ }
117
+ return id;
118
+ }
119
+ function registerSessionImport(ctx, persistence) {
120
+ ctx.inject(["webServer", "connection"], (webCtx) => {
121
+ const webServer = webCtx.webServer;
122
+ const connection = webCtx.get("connection");
123
+ return webCtx.effect(() => webServer.register({
124
+ kind: "exact",
125
+ path: SESSION_IMPORT_PATH,
126
+ handler: async (req, res) => {
127
+ const rejection = connection.requestRejection(req);
128
+ if (rejection !== void 0) {
129
+ res.writeHead(rejection);
130
+ res.end(rejection === 401 ? "unauthorized" : "forbidden");
131
+ return;
132
+ }
133
+ const chunks = [];
134
+ for await (const chunk of req) chunks.push(chunk);
135
+ const body = Buffer.concat(chunks);
136
+ let envelope;
137
+ try {
138
+ envelope = JSON.parse(body.toString("utf8"));
139
+ } catch {
140
+ res.writeHead(400, { "content-type": "application/json" });
141
+ res.end(JSON.stringify({ error: "request body is not JSON" }));
142
+ return;
143
+ }
144
+ if (typeof envelope.zip !== "string" || envelope.zip === "") {
145
+ res.writeHead(400, { "content-type": "application/json" });
146
+ res.end(JSON.stringify({ error: "missing zip field" }));
147
+ return;
148
+ }
149
+ if (envelope.sessionId !== void 0 && (typeof envelope.sessionId !== "string" || envelope.sessionId === "")) {
150
+ res.writeHead(400, { "content-type": "application/json" });
151
+ res.end(JSON.stringify({ error: "sessionId must be a non-empty string" }));
152
+ return;
153
+ }
154
+ let zip;
155
+ try {
156
+ zip = Buffer.from(envelope.zip, "base64");
157
+ } catch {
158
+ res.writeHead(400, { "content-type": "application/json" });
159
+ res.end(JSON.stringify({ error: "zip field is not valid base64" }));
160
+ return;
161
+ }
162
+ if (zip.byteLength > MAX_IMPORT_ZIP_BYTES) {
163
+ res.writeHead(413, { "content-type": "application/json" });
164
+ res.end(JSON.stringify({ error: "imported zip exceeds the size limit" }));
165
+ return;
166
+ }
167
+ let imported;
168
+ try {
169
+ imported = parseImportZip(zip);
170
+ } catch (error) {
171
+ res.writeHead(400, { "content-type": "application/json" });
172
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : "imported zip is invalid" }));
173
+ return;
174
+ }
175
+ const targetId = typeof envelope.sessionId === "string" ? envelope.sessionId : void 0;
176
+ const branch = webCtx.get("sessionBranch");
177
+ try {
178
+ const sessions = webCtx.get("sessions");
179
+ const id = await persistImport(persistence, branch, imported, targetId, sessions, (sessionId) => stopAgentLoop(webCtx, sessionId));
180
+ res.writeHead(200, { "content-type": "application/json" });
181
+ res.end(JSON.stringify({ sessionId: id }));
182
+ } catch (error) {
183
+ const message = error instanceof Error ? error.message : String(error);
184
+ if (targetId !== void 0 && /not found/i.test(message)) {
185
+ res.writeHead(404, { "content-type": "application/json" });
186
+ res.end(JSON.stringify({ error: `session "${targetId}" not found` }));
187
+ return;
188
+ }
189
+ res.writeHead(500, { "content-type": "application/json" });
190
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : "import failed" }));
191
+ return;
192
+ }
193
+ }
194
+ }), `session-rdb: ${SESSION_IMPORT_PATH} route`);
195
+ });
196
+ }
197
+ //#endregion
2
198
  export { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, parseImportZip, parseJsonlArtifact, persistImport, registerSessionImport };
@@ -1,4 +1,4 @@
1
- import { a as JournalMode, b as WriteGuard, x as Backend } from "./schema-DPcuEh_a.mjs";
1
+ import { a as JournalMode, b as WriteGuard, x as Backend } from "./schema-BkQN5GyT.mjs";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { SessionAccess, SessionHandle, SessionHandleAppendOptions, SessionHandleFlushOptions, SessionHandleReadOptions, SessionHandleReadResult, SessionPersistence, SessionPersistenceCreateOptions, SessionPersistenceListOptions, SessionPersistenceOpenOptions, SessionPersistenceRevision, SessionPersistenceSnapshot, SessionPersistenceStatOptions } from "@deepseek-ai/dsh-session-persistence";
4
4
  import { Session, SessionEvent, SessionHeader, SessionId, SessionLogOffset } from "@deepseek-ai/dsh-session";
@@ -32,6 +32,7 @@ interface LiveAgentLike {
32
32
  clear(): void;
33
33
  };
34
34
  }
35
+ declare function truncateLiveSession(session: Session, newLength: number): void;
35
36
  declare class SessionBranchRdbProvider implements SessionBranchProvider {
36
37
  private readonly persistence;
37
38
  private readonly live;
@@ -267,4 +268,4 @@ declare class SessionPersistenceRdb extends SessionPersistence {
267
268
  private ensureLiveHandle;
268
269
  }
269
270
  //#endregion
270
- export { SessionBranchRdb as a, SessionPersistenceRdbInternals as i, ProjectionCacheOptions as n, SessionBranchRdbProvider as o, SessionPersistenceRdb as r, locateTurnEnd as s, Config as t };
271
+ export { SessionBranchRdb as a, truncateLiveSession as c, SessionPersistenceRdbInternals as i, ProjectionCacheOptions as n, SessionBranchRdbProvider as o, SessionPersistenceRdb as r, locateTurnEnd as s, Config as t };
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { o as SCHEMA_VERSION } from "./schema-DPcuEh_a.mjs";
2
- import { a as SessionBranchRdb, i as SessionPersistenceRdbInternals, n as ProjectionCacheOptions, o as SessionBranchRdbProvider, r as SessionPersistenceRdb, s as locateTurnEnd, t as Config } from "./index-CCcK9tia.mjs";
1
+ import { o as SCHEMA_VERSION } from "./schema-BkQN5GyT.mjs";
2
+ import { a as SessionBranchRdb, i as SessionPersistenceRdbInternals, n as ProjectionCacheOptions, o as SessionBranchRdbProvider, r as SessionPersistenceRdb, s as locateTurnEnd, t as Config } from "./index-D55G9n4k.mjs";
3
3
  export { Config, ProjectionCacheOptions, SCHEMA_VERSION, SessionBranchRdb, SessionBranchRdbProvider, SessionPersistenceRdb, SessionPersistenceRdb as default, SessionPersistenceRdbInternals, locateTurnEnd };
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { S as WriteGuard, a as EVENT_ENCODING, b as postgresTableDefs, c as eventDimensions, i as DEFAULT_BUSY_TIMEOUT_MS, o as SCHEMA_VERSION, r as createStorageRepository, t as SqliteBackend, x as toPostgresSchema } from "./sqlite-DYExtbLo.mjs";
2
2
  import { _ as toJsonlArtifact, c as repairRequestHeaders, d as rowToMeta, f as scanRows, g as titleOfEventData, m as sessionInsertRow, p as sessionConflictRow, s as repairReadView } from "./log-DO69NQnn.mjs";
3
- import { c as SessionBranchRdbProvider, l as locateTurnEnd, o as registerSessionImport, s as SessionBranchRdb } from "./import-Bc2QQa5G.mjs";
3
+ import { n as SessionBranchRdbProvider, r as locateTurnEnd, t as SessionBranchRdb } from "./branch-Co6xlbi0.mjs";
4
+ import { registerSessionImport } from "./import.mjs";
4
5
  import z from "@deepseek-ai/schemastery";
5
6
  import { randomUUID } from "node:crypto";
6
7
  import { Pool } from "pg";
@@ -4,7 +4,7 @@ import { Session, SessionEvent, SessionHeader, SessionId, SessionLogOffset, Sess
4
4
  import { KvUnit } from "@deepseek-ai/dsh-storage";
5
5
  import { Context, Service } from "@deepseek-ai/cordis";
6
6
  import { SessionId as SessionId$1 } from "@deepseek-ai/dsh-session/types";
7
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/json-schema.d.cts
7
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/json-schema.d.cts
8
8
  type _JSONSchema = boolean | JSONSchema;
9
9
  type SchemaType = "object" | "array" | "string" | "number" | "boolean" | "null" | "integer";
10
10
  type JSONSchema = {
@@ -73,7 +73,7 @@ type JSONSchema = {
73
73
  };
74
74
  type BaseSchema = JSONSchema;
75
75
  //#endregion
76
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/standard-schema.d.cts
76
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/standard-schema.d.cts
77
77
  /** The Standard interface. */
78
78
  interface StandardTypedV1<Input = unknown, Output = Input> {
79
79
  /** The Standard properties. */
@@ -192,7 +192,7 @@ declare namespace StandardJSONSchemaV1 {
192
192
  }
193
193
  interface StandardSchemaWithJSONProps<Input = unknown, Output = Input> extends StandardSchemaV1.Props<Input, Output>, StandardJSONSchemaV1.Props<Input, Output> {}
194
194
  //#endregion
195
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/registries.d.cts
195
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/registries.d.cts
196
196
  declare const $output: unique symbol;
197
197
  type $output = typeof $output;
198
198
  declare const $input: unique symbol;
@@ -219,7 +219,7 @@ interface JSONSchemaMeta {
219
219
  }
220
220
  interface GlobalMeta extends JSONSchemaMeta {}
221
221
  //#endregion
222
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/to-json-schema.d.cts
222
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/to-json-schema.d.cts
223
223
  type Processor<T extends $ZodType = $ZodType> = (schema: T, ctx: ToJSONSchemaContext, json: BaseSchema, params: ProcessParams) => void;
224
224
  /**
225
225
  * Called for each schema that has no JSON Schema equivalent. Return a JSON Schema to use in its
@@ -341,7 +341,7 @@ interface ZodStandardJSONSchemaPayload<T> extends BaseSchema {
341
341
  "~standard": ZodStandardSchemaWithJSON$1<T>;
342
342
  }
343
343
  //#endregion
344
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/util.d.cts
344
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/util.d.cts
345
345
  type JWTAlgorithm = "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "ES256" | "ES384" | "ES512" | "PS256" | "PS384" | "PS512" | "EdDSA" | (string & {});
346
346
  type MimeTypes = "application/json" | "application/xml" | "application/x-www-form-urlencoded" | "application/javascript" | "application/pdf" | "application/zip" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-powerpoint" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/octet-stream" | "application/graphql" | "text/html" | "text/plain" | "text/css" | "text/javascript" | "text/csv" | "image/png" | "image/jpeg" | "image/gif" | "image/svg+xml" | "image/webp" | "audio/mpeg" | "audio/ogg" | "audio/wav" | "audio/webm" | "video/mp4" | "video/webm" | "video/ogg" | "font/woff" | "font/woff2" | "font/ttf" | "font/otf" | "multipart/form-data" | (string & {});
347
347
  type IsAny<T> = 0 extends 1 & T ? true : false;
@@ -384,14 +384,14 @@ declare abstract class Class {
384
384
  /** A trait's prototype members: a partial view of its own interface, with `this` typed as the instance. */
385
385
  type ProtoOf<T> = { [K in keyof T]?: (T[K] extends ((...args: infer A) => infer R) ? (...args: A) => R : T[K]) | undefined; } & ThisType<T>;
386
386
  //#endregion
387
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/versions.d.cts
387
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/versions.d.cts
388
388
  declare const version: {
389
389
  readonly major: 4;
390
390
  readonly minor: 6;
391
391
  readonly patch: number;
392
392
  };
393
393
  //#endregion
394
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/schemas.d.cts
394
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/schemas.d.cts
395
395
  interface ParseContext<T extends $ZodIssueBase = never> {
396
396
  /** Customize error messages. */
397
397
  readonly error?: $ZodErrorMap<T>;
@@ -1412,7 +1412,7 @@ interface $ZodCustom<O = unknown, I = unknown> extends $ZodType {
1412
1412
  declare const $ZodCustom: $constructor<$ZodCustom>;
1413
1413
  type $ZodTypes = $ZodString | $ZodNumber | $ZodBigInt | $ZodBoolean | $ZodDate | $ZodSymbol | $ZodUndefined | $ZodNullable | $ZodNull | $ZodAny | $ZodUnknown | $ZodNever | $ZodVoid | $ZodArray | $ZodObject | $ZodUnion | $ZodIntersection | $ZodTuple | $ZodRecord | $ZodMap | $ZodSet | $ZodLiteral | $ZodEnum | $ZodFunction | $ZodPromise | $ZodLazy | $ZodOptional | $ZodDefault | $ZodPrefault | $ZodTemplateLiteral | $ZodCustom | $ZodTransform | $ZodNonOptional | $ZodReadonly | $ZodNaN | $ZodPipe | $ZodSuccess | $ZodCatch | $ZodFile;
1414
1414
  //#endregion
1415
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/checks.d.cts
1415
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/checks.d.cts
1416
1416
  interface $ZodCheckDef {
1417
1417
  check: string;
1418
1418
  error?: $ZodErrorMap<never> | undefined;
@@ -1594,7 +1594,7 @@ interface $ZodCheckEndsWith extends $ZodCheckInternals<string> {
1594
1594
  }
1595
1595
  declare const $ZodCheckEndsWith: $constructor<$ZodCheckEndsWith>;
1596
1596
  //#endregion
1597
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/errors.d.cts
1597
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/errors.d.cts
1598
1598
  interface $ZodIssueBase {
1599
1599
  readonly code?: string;
1600
1600
  readonly input?: unknown;
@@ -1723,7 +1723,7 @@ type $ZodFormattedError<T, U = string> = {
1723
1723
  _errors: U[];
1724
1724
  } & Flatten<_ZodFormattedError<T, U>>;
1725
1725
  //#endregion
1726
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/core.d.cts
1726
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/core.d.cts
1727
1727
  type ZodTrait = {
1728
1728
  _zod: {
1729
1729
  def: any;
@@ -1769,7 +1769,7 @@ type output<T> = T extends {
1769
1769
  };
1770
1770
  } ? T["_zod"]["output"] : unknown;
1771
1771
  //#endregion
1772
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/core/api.d.cts
1772
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/api.d.cts
1773
1773
  type Params<T extends $ZodType | $ZodCheck, IssueTypes extends $ZodIssueBase, OmitKeys extends keyof T["_zod"]["def"] = never> = Flatten<Partial<EmptyToNever<Omit<T["_zod"]["def"], OmitKeys> & ([IssueTypes] extends [never] ? {} : {
1774
1774
  error?: string | $ZodErrorMap<IssueTypes> | undefined;
1775
1775
  /** @deprecated This parameter is deprecated. Use `error` instead. */
@@ -1841,7 +1841,7 @@ interface $ZodSuperRefineParams {
1841
1841
  when?: ((payload: ParsePayload) => boolean) | undefined;
1842
1842
  }
1843
1843
  //#endregion
1844
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/classic/errors.d.cts
1844
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/errors.d.cts
1845
1845
  /** An Error-like class used to store Zod validation issues. */
1846
1846
  interface ZodError<T = unknown> extends $ZodError<T> {
1847
1847
  /** @deprecated Use the `z.treeifyError(err)` function instead. */
@@ -1859,7 +1859,7 @@ interface ZodError<T = unknown> extends $ZodError<T> {
1859
1859
  }
1860
1860
  declare const ZodError: $constructor<ZodError>;
1861
1861
  //#endregion
1862
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/classic/parse.d.cts
1862
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/parse.d.cts
1863
1863
  type ZodSafeParseResult<T> = ZodSafeParseSuccess<T> | ZodSafeParseError<T>;
1864
1864
  type ZodSafeParseSuccess<T> = {
1865
1865
  success: true;
@@ -1872,7 +1872,7 @@ type ZodSafeParseError<T> = {
1872
1872
  error: ZodError<T>;
1873
1873
  };
1874
1874
  //#endregion
1875
- //#region ../../../node_modules/.pnpm/zod@4.6.4/node_modules/zod/v4/classic/schemas.d.cts
1875
+ //#region ../../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/schemas.d.cts
1876
1876
  type ZodStandardSchemaWithJSON<T> = StandardSchemaWithJSONProps<input<T>, output<T>>;
1877
1877
  interface ZodType<out Output = unknown, out Input = unknown, out Internals extends $ZodTypeInternals<Output, Input> = $ZodTypeInternals<Output, Input>> extends $ZodType<Output, Input, Internals> {
1878
1878
  def: Internals["def"];
@@ -1,4 +1,4 @@
1
- import { C as EventRow, S as BackendTx, T as StorageRepository, _ as tWorkspaceSessions, a as JournalMode, b as WriteGuard, c as eventDimensions, d as tPersistenceState, f as tSchemaMeta, g as tStorageUnits, h as tSessions, i as EventRole, l as eventKind, m as tSessionProjcacheRows, n as EVENT_ENCODING, o as SCHEMA_VERSION, p as tSessionEvents, r as EventKind, s as SESSION_PERSISTENCE_SQLITE_APPLICATION_ID, t as DEFAULT_BUSY_TIMEOUT_MS, u as tEvents, v as tWorkspaceState, w as SessionRow, x as Backend, y as tWorkspaces } from "./schema-DPcuEh_a.mjs";
1
+ import { C as EventRow, S as BackendTx, T as StorageRepository, _ as tWorkspaceSessions, a as JournalMode, b as WriteGuard, c as eventDimensions, d as tPersistenceState, f as tSchemaMeta, g as tStorageUnits, h as tSessions, i as EventRole, l as eventKind, m as tSessionProjcacheRows, n as EVENT_ENCODING, o as SCHEMA_VERSION, p as tSessionEvents, r as EventKind, s as SESSION_PERSISTENCE_SQLITE_APPLICATION_ID, t as DEFAULT_BUSY_TIMEOUT_MS, u as tEvents, v as tWorkspaceState, w as SessionRow, x as Backend, y as tWorkspaces } from "./schema-BkQN5GyT.mjs";
2
2
  import { SessionId } from "@deepseek-ai/dsh-session";
3
3
  import { DatabaseSync } from "node:sqlite";
4
4
  //#region src/sqlite.d.ts
@@ -1,3 +1,4 @@
1
+ import { c as truncateLiveSession } from "./index-D55G9n4k.mjs";
1
2
  import { SessionPersistence } from "@deepseek-ai/dsh-session-persistence";
2
3
  import { Session, SessionEvent, SessionHeader, SessionId } from "@deepseek-ai/dsh-session";
3
4
  import { Context, Fiber } from "@deepseek-ai/cordis";
@@ -57,4 +58,4 @@ interface CoordinatorFixture {
57
58
  */
58
59
  declare function runCoordinatorContract(name: string, makeFixture: () => Promise<CoordinatorFixture>): void;
59
60
  //#endregion
60
- export { type ContractBackend, type CoordinatorFixture, EmptySettings, appendLog, meta, oneTurnLog, runCoordinatorContract, runPersistenceContract };
61
+ export { type ContractBackend, type CoordinatorFixture, EmptySettings, appendLog, meta, oneTurnLog, runCoordinatorContract, runPersistenceContract, truncateLiveSession };
package/dist/testing.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { a as truncateLiveSession } from "./branch-Co6xlbi0.mjs";
1
2
  import { SessionAlreadyExistsError, SessionAlreadyOwnedError, SessionFormatUnsupportedError, SessionHandleClosedError, SessionPersistenceNotFoundError, SessionReadOnlyError } from "@deepseek-ai/dsh-session-persistence";
2
3
  import SessionStore, { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset, SessionSeq } from "@deepseek-ai/dsh-session";
3
4
  import { Context } from "@deepseek-ai/cordis";
@@ -14733,4 +14734,4 @@ function runCoordinatorContract(name, makeFixture) {
14733
14734
  });
14734
14735
  }
14735
14736
  //#endregion
14736
- export { EmptySettings, appendLog, meta, oneTurnLog, runCoordinatorContract, runPersistenceContract };
14737
+ export { EmptySettings, appendLog, meta, oneTurnLog, runCoordinatorContract, runPersistenceContract, truncateLiveSession };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morlay/session-rdb",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "RDB durable session backend for DeepSeek Harness: implements both session-persistence and session-branch (rewind / retry / fork) providers.",
5
5
  "keywords": [
6
6
  "branch",
@@ -35,7 +35,7 @@
35
35
  "./cordis.patch.yml": "./cordis.patch.yml"
36
36
  },
37
37
  "dependencies": {
38
- "@morlay/session-branch": "^0.0.7",
38
+ "@morlay/session-branch": "^0.0.8",
39
39
  "drizzle-orm": "^1.0.0-rc.5-ab785fc",
40
40
  "fflate": "^0.8.2",
41
41
  "pg": "^8.23.0"
@@ -82,7 +82,7 @@
82
82
  "magic-string": "0.30.21",
83
83
  "tinyrainbow": "3.1.1",
84
84
  "vitest": "4.1.11",
85
- "zod": "4.6.4"
85
+ "zod": "4.6.5"
86
86
  },
87
87
  "scripts": {
88
88
  "build": "pnpm exec tsdown",
package/src/testing.ts CHANGED
@@ -5,3 +5,6 @@ export type { ContractBackend } from "./testing/contract.ts";
5
5
  export { appendLog, meta, oneTurnLog, runPersistenceContract } from "./testing/contract.ts";
6
6
  export type { CoordinatorFixture } from "./testing/coordinator-contract.ts";
7
7
  export { runCoordinatorContract } from "./testing/coordinator-contract.ts";
8
+ // rewind 落到 live 会话上的那一件事:截断内存 log 并重置派生 surface / 折叠
9
+ // 缓存。跨包测试要构造「rewind 之后」的会话态时用它,不必拉起 RDB 装配。
10
+ export { truncateLiveSession } from "./branch.ts";