@morlay/session-rdb 0.0.20 → 0.0.21-alpha.1

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.
Files changed (69) hide show
  1. package/README.md +59 -31
  2. package/dist/artifact.d.mts +25 -65
  3. package/dist/artifact.mjs +2 -2
  4. package/dist/{schema-BkQN5GyT.d.mts → backend-DpdtxYpz.d.mts} +346 -93
  5. package/dist/{branch-Co6xlbi0.mjs → branch-5JzX9rUq.mjs} +163 -52
  6. package/dist/deletion.d.mts +7 -0
  7. package/dist/deletion.mjs +2 -0
  8. package/dist/dist-vIVO6bA-.mjs +1524 -0
  9. package/dist/import.d.mts +4 -4
  10. package/dist/import.mjs +28 -11
  11. package/dist/index.d.mts +2 -3
  12. package/dist/index.mjs +4 -1631
  13. package/dist/{log-DO69NQnn.mjs → log-CnYct2Dv.mjs} +37 -82
  14. package/dist/{sqlite-DYExtbLo.mjs → sqlite-fpvm5Dzs.mjs} +205 -75
  15. package/dist/src-CWTWV7vx.mjs +1904 -0
  16. package/dist/storage.d.mts +14 -5
  17. package/dist/storage.mjs +2 -2
  18. package/dist/testing.d.mts +1 -26
  19. package/dist/testing.mjs +10503 -9614
  20. package/drizzle/postgres/20260918120000_v3_event_usage/migration.sql +14 -0
  21. package/drizzle/postgres/20260918120000_v3_event_usage/snapshot.json +1309 -0
  22. package/drizzle/sqlite/20260918120000_v3_event_usage/migration.sql +14 -0
  23. package/drizzle/sqlite/20260918120000_v3_event_usage/snapshot.json +1031 -0
  24. package/package.json +28 -29
  25. package/src/adapters/to-postgres.ts +1 -3
  26. package/src/adapters/to-sqlite.ts +0 -2
  27. package/src/adapters/types.ts +0 -3
  28. package/src/artifact.ts +0 -2
  29. package/src/backend.ts +31 -2
  30. package/src/branch.ts +223 -135
  31. package/src/deletion.ts +87 -0
  32. package/src/drizzle/postgres-v2.ts +0 -1
  33. package/src/drizzle/postgres-v3.ts +0 -1
  34. package/src/drizzle/sqlite-v2.ts +0 -1
  35. package/src/drizzle/sqlite-v3.ts +0 -1
  36. package/src/entities/v2/session-events.ts +0 -1
  37. package/src/entities/v3/event-usage.ts +25 -0
  38. package/src/entities/v3/events.ts +1 -3
  39. package/src/entities/v3/index.ts +4 -0
  40. package/src/entities/v3/session-events.ts +1 -2
  41. package/src/entities/v3/session-projcache-rows.ts +0 -8
  42. package/src/entities/v3/sessions.ts +3 -3
  43. package/src/entities/v3/storage-units.ts +0 -1
  44. package/src/entities/v3/workspace-sessions.ts +0 -5
  45. package/src/entities/v3/workspace-state.ts +0 -6
  46. package/src/entities/v3/workspaces.ts +0 -5
  47. package/src/export.ts +103 -0
  48. package/src/gc.ts +76 -0
  49. package/src/import-storages.ts +4 -37
  50. package/src/import.ts +54 -31
  51. package/src/index.ts +150 -114
  52. package/src/legacy.ts +4 -42
  53. package/src/log.ts +63 -106
  54. package/src/postgres.ts +249 -22
  55. package/src/schema.ts +6 -6
  56. package/src/session-query.ts +0 -4
  57. package/src/sqlite.ts +231 -55
  58. package/src/storage-takeover/index.ts +2 -28
  59. package/src/storage-takeover/projection-cache.ts +30 -134
  60. package/src/storage-takeover/repository.ts +20 -59
  61. package/src/storage-takeover/storage-backend.ts +3 -33
  62. package/src/storage-takeover/types.ts +14 -56
  63. package/src/storage.ts +0 -2
  64. package/src/testing/contract.ts +19 -50
  65. package/src/testing/coordinator-contract.ts +10 -25
  66. package/src/testing.ts +1 -4
  67. package/src/usage.ts +191 -0
  68. package/dist/index-D55G9n4k.d.mts +0 -271
  69. package/dist/magic-string.es-BgJoa-3K.mjs +0 -1017
package/dist/import.d.mts CHANGED
@@ -1,19 +1,19 @@
1
- import { r as SessionPersistenceRdb } from "./index-D55G9n4k.mjs";
1
+ import { u as SessionPersistenceRdb } from "./backend-DpdtxYpz.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";
5
5
  //#region src/import.d.ts
6
- /** 当前世代产物的文件名(读入侧接受任意 canonical 世代名,见 parseImportZip)。 */
7
6
  declare const SESSION_LOG_ARTIFACT_FILENAME = "session.jsonl";
8
7
  declare const SESSION_IMPORT_PATH = "/api/session.import";
9
8
  declare function parseJsonlArtifact(content: string): SessionStorageMetadata & {
10
9
  events: SessionEvent[];
11
10
  };
12
- declare function parseImportZip(zip: Uint8Array): SessionStorageMetadata & {
11
+ declare function parseImportZip(zip: Uint8Array): Promise<SessionStorageMetadata & {
13
12
  events: SessionEvent[];
14
- };
13
+ }>;
15
14
  declare function persistImport(persistence: SessionPersistenceRdb, branch: {
16
15
  rewind(id: SessionId, toBoundary: number): Promise<unknown>;
16
+ resetLiveDerivedState?(session: Session): void;
17
17
  } | undefined, imported: SessionStorageMetadata & {
18
18
  events: SessionEvent[];
19
19
  }, targetId?: SessionId, sessions?: {
package/dist/import.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import { i as replaceLiveSessionLog } from "./branch-Co6xlbi0.mjs";
1
+ import { i as replaceLiveSessionLog } from "./branch-5JzX9rUq.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { SESSION_FORMAT_VERSION, SessionLogOffset } from "@deepseek-ai/dsh-session";
4
4
  import { parseSessionFormatLogFilename } from "@deepseek-ai/dsh-session-format";
5
5
  import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
6
- import { unzipSync } from "fflate";
6
+ import { balanceRewindPrefix } from "@morlay/session-branch";
7
+ import { unzip } from "fflate";
7
8
  //#region src/import.ts
8
- /** 当前世代产物的文件名(读入侧接受任意 canonical 世代名,见 parseImportZip)。 */
9
9
  const SESSION_LOG_ARTIFACT_FILENAME = "session.jsonl";
10
10
  const SESSION_IMPORT_PATH = "/api/session.import";
11
11
  const MAX_IMPORT_ZIP_BYTES = 67108864;
@@ -68,10 +68,23 @@ function parseJsonlArtifact(content) {
68
68
  events
69
69
  };
70
70
  }
71
- function parseImportZip(zip) {
71
+ /**
72
+ * fflate 的 `unzip` 是回调式异步 API(node 侧内部走 worker_threads,浏览器侧走 Web Worker),
73
+ * 这里桥成 Promise。它与 `unzipSync` 的差异只在同步/异步:非法 zip 走的是同一段校验代码,
74
+ * 拒绝的错误对象与同步版一致,因此上层文案无需区分。
75
+ */
76
+ function unzipAsync(data) {
77
+ return new Promise((resolve, reject) => {
78
+ unzip(data, (error, entries) => {
79
+ if (error === null) resolve(entries);
80
+ else reject(error);
81
+ });
82
+ });
83
+ }
84
+ async function parseImportZip(zip) {
72
85
  let entries;
73
86
  try {
74
- entries = unzipSync(zip);
87
+ entries = await unzipAsync(zip);
75
88
  } catch {
76
89
  throw new Error("imported zip is not a valid ZIP archive");
77
90
  }
@@ -87,17 +100,18 @@ async function stopAgentLoop(ctx, sessionId) {
87
100
  }
88
101
  async function persistImport(persistence, branch, imported, targetId, sessions, stopLoop) {
89
102
  const id = targetId ?? `session-${randomUUID()}`;
103
+ const events = balanceRewindPrefix(imported.events, { keepOpenTail: true });
90
104
  if (targetId !== void 0) {
91
105
  if (branch === void 0) throw new Error("sessionBranch service is unavailable");
92
106
  if (stopLoop !== void 0) await stopLoop(targetId);
93
107
  await branch.rewind(targetId, -1);
94
108
  const liveHandle = persistence.tracker.writerOf(targetId);
95
109
  if (liveHandle !== void 0) {
96
- if (imported.events.length > 0) await liveHandle.append(imported.events);
110
+ if (events.length > 0) await liveHandle.append(events);
97
111
  } else {
98
112
  const handle = await persistence.open(targetId, "write");
99
113
  try {
100
- if (imported.events.length > 0) await handle.append(imported.events);
114
+ if (events.length > 0) await handle.append(events);
101
115
  } finally {
102
116
  await handle.close();
103
117
  }
@@ -106,13 +120,16 @@ async function persistImport(persistence, branch, imported, targetId, sessions,
106
120
  const handle = await persistence.create({
107
121
  ...imported.meta,
108
122
  id
109
- }, { inheritedEventCount: imported.inheritedEventCount });
110
- if (imported.events.length > 0) await handle.append(imported.events);
123
+ }, { inheritedEventCount: SessionLogOffset(Math.min(imported.inheritedEventCount, events.length)) });
124
+ if (events.length > 0) await handle.append(events);
111
125
  await handle.close();
112
126
  }
113
127
  if (targetId !== void 0) {
114
128
  const live = sessions?.get(targetId);
115
- if (live !== void 0) replaceLiveSessionLog(live, imported.events);
129
+ if (live !== void 0) {
130
+ replaceLiveSessionLog(live, events);
131
+ branch?.resetLiveDerivedState?.(live);
132
+ }
116
133
  }
117
134
  return id;
118
135
  }
@@ -166,7 +183,7 @@ function registerSessionImport(ctx, persistence) {
166
183
  }
167
184
  let imported;
168
185
  try {
169
- imported = parseImportZip(zip);
186
+ imported = await parseImportZip(zip);
170
187
  } catch (error) {
171
188
  res.writeHead(400, { "content-type": "application/json" });
172
189
  res.end(JSON.stringify({ error: error instanceof Error ? error.message : "imported zip is invalid" }));
package/dist/index.d.mts CHANGED
@@ -1,3 +1,2 @@
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
- export { Config, ProjectionCacheOptions, SCHEMA_VERSION, SessionBranchRdb, SessionBranchRdbProvider, SessionPersistenceRdb, SessionPersistenceRdb as default, SessionPersistenceRdbInternals, locateTurnEnd };
1
+ import { c as SessionDeletionError, d as SessionPersistenceRdbInternals, f as SessionBranchRdb, l as SessionDeletionErrorCode, m as locateTurnEnd, o as Config, p as SessionBranchRdbProvider, s as ProjectionCacheOptions, u as SessionPersistenceRdb, x as SCHEMA_VERSION } from "./backend-DpdtxYpz.mjs";
2
+ export { Config, ProjectionCacheOptions, SCHEMA_VERSION, SessionBranchRdb, SessionBranchRdbProvider, SessionDeletionError, SessionDeletionErrorCode, SessionPersistenceRdb, SessionPersistenceRdb as default, SessionPersistenceRdbInternals, locateTurnEnd };