@morlay/session-rdb 0.0.16-alpha.4 → 0.0.17

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 (48) hide show
  1. package/README.md +44 -10
  2. package/dist/artifact.d.mts +9 -2
  3. package/dist/artifact.mjs +3 -3
  4. package/dist/{import-BPEHfHNk.mjs → import-DZIAjOUr.mjs} +2 -1
  5. package/dist/import.d.mts +1 -1
  6. package/dist/import.mjs +1 -1
  7. package/dist/{index-CgAqCQAb.d.mts → index-BEKoV1Uy.d.mts} +11 -2
  8. package/dist/index.d.mts +3 -3
  9. package/dist/index.mjs +509 -6
  10. package/dist/{log-BIuXv09P.mjs → log-DO69NQnn.mjs} +16 -1
  11. package/dist/schema-Bo6Hy5gW.d.mts +3476 -0
  12. package/dist/{sqlite-IH5I48aL.mjs → sqlite-BIPdMNQb.mjs} +504 -6
  13. package/dist/storage.d.mts +10 -2
  14. package/dist/storage.mjs +2 -2
  15. package/dist/testing.d.mts +1 -1
  16. package/dist/testing.mjs +1 -1
  17. package/drizzle/postgres/20260910120001_v3_storage_tables/migration.sql +65 -0
  18. package/drizzle/postgres/20260910120001_v3_storage_tables/snapshot.json +1236 -0
  19. package/drizzle/postgres/20260910130001_v3_session_title_backfill/migration.sql +10 -0
  20. package/drizzle/postgres/20260910130001_v3_session_title_backfill/snapshot.json +1236 -0
  21. package/drizzle/sqlite/20260910120000_v3_storage_tables/migration.sql +66 -0
  22. package/drizzle/sqlite/20260910120000_v3_storage_tables/snapshot.json +958 -0
  23. package/drizzle/sqlite/20260910130000_v3_session_title_backfill/migration.sql +13 -0
  24. package/drizzle/sqlite/20260910130000_v3_session_title_backfill/snapshot.json +958 -0
  25. package/package.json +20 -18
  26. package/src/backend.ts +7 -0
  27. package/src/branch.ts +2 -0
  28. package/src/drizzle/postgres-v3.ts +5 -0
  29. package/src/drizzle/sqlite-v3.ts +5 -0
  30. package/src/entities/v3/index.ts +20 -0
  31. package/src/entities/v3/session-projcache-rows.ts +27 -0
  32. package/src/entities/v3/sessions.ts +6 -0
  33. package/src/entities/v3/storage-units.ts +10 -0
  34. package/src/entities/v3/workspace-sessions.ts +24 -0
  35. package/src/entities/v3/workspace-state.ts +18 -0
  36. package/src/entities/v3/workspaces.ts +19 -0
  37. package/src/import-storages.ts +173 -0
  38. package/src/index.ts +53 -0
  39. package/src/log.ts +19 -0
  40. package/src/postgres.ts +70 -2
  41. package/src/schema.ts +16 -2
  42. package/src/sqlite.ts +87 -4
  43. package/src/storage-takeover/index.ts +60 -0
  44. package/src/storage-takeover/projection-cache.ts +445 -0
  45. package/src/storage-takeover/repository.ts +420 -0
  46. package/src/storage-takeover/storage-backend.ts +177 -0
  47. package/src/storage-takeover/types.ts +82 -0
  48. package/dist/schema-COK7-wRV.d.mts +0 -104
package/README.md CHANGED
@@ -50,6 +50,8 @@ type Config =
50
50
  type: "postgres";
51
51
  /** node-postgres 连接串;首次打开自动建表并写入 store 身份。 */
52
52
  connectionString: string;
53
+ /** 目标 schema(默认 public,必须已存在);见 docs/schema.md。 */
54
+ schema?: string;
53
55
  };
54
56
  ```
55
57
 
@@ -59,17 +61,49 @@ type Config =
59
61
  provider 抽象并**随插件自动注册 `ctx.sessionBranch`**(`SessionBranchRdb`),
60
62
  在不修改上游代码的前提下提供 `rewind / retry / fork` 的持久化闭环:
61
63
 
62
- - **`forkFrom`**:走标准 handle 路径(`create` + `append`)从闭合边界
63
- 派生新会话(纯 append,`parentSession` / `seedLength` lineage);
64
- - **`rewind`**:直接操作后端事务截断到闭合边界(DELETE 尾部 + head 回退 +
65
- revision bump),并更新并发写检测 head;**支持 live 会话**(`ctx.sessions`
66
- owner 时同样就地工作:先 flush write-behind 缓冲 → 截断 RDB → 截断
67
- live 内存 log 并复位 surface/header/context/derived 派生缓存 → 重置 agent
68
- 请求头标记 → 对齐 handle cursor;不调用 `load`——live 时 load 会先 flush
69
- 撤销截断);
70
- - **`timeline`**:`parentSession` + `seedLength` 版本树投影(live 会话含
71
- 版本效果;cold 会话版本事件原样落库,效果详情可恢复)。
64
+ - `forkFrom`:纯 append 从闭合边界派生新会话(事件行复用,不复制);
65
+ - `rewind`:直接操作后端事务截断(只删桥接行),支持 live cold 会话;
66
+ - `timeline`:lineage 版本树投影。
67
+
68
+ 三个原语的完整语义(含 live 同步步骤、事件行复用机制、坐标论证与已知限制)
69
+ [docs/branch.md](docs/branch.md)。
72
70
 
73
71
  上层编排(edit / reroll / retry / rewind / fork 完整功能)由
74
72
  `@morlay/ui-conversation-message-actions` 提供,或直接在 `ctx.sessionBranch` /
75
73
  `ctx.sessionEditor` 之上编程。
74
+
75
+ ## storages 接管(workspace 与投影缓存)
76
+
77
+ `$DSH_HOME/storages` 不再产生文件:官方 `storage-json` 与
78
+ `session-projection-cache` 由 `@morlay/better-session` 的 patch 禁用,数据落本包
79
+ 的语义专用表(表结构见 [docs/schema.md](docs/schema.md),决策见
80
+ [docs/adr/0009](docs/adr/0009-接管storages到rdb语义表.md)):
81
+
82
+ - **workspace 域**:官方 `workspace` 插件保留,本包在 storage hub 注册 `rdb`
83
+ KV 后端(`storage-domain` 的 backend 路由为 `rdb`),记录、归属、显示顺序
84
+ 与归档分别落 `t_workspaces` / `t_workspace_sessions` / `t_workspace_state`
85
+ 与 `t_sessions.f_archived_at`;
86
+ - **投影 checkpoint**:本包提供 `ctx.sessionProjectionCache` 服务(替换官方
87
+ 插件,API 与语义逐一对齐),每个投影 key 一行落 `t_session_projcache_row`
88
+ (identity 直接复用 `t_sessions` 的会话行);SQLite 下读路径**直接查表**
89
+ (进程内不再维护 checkpoint 镜像),PostgreSQL 因驱动异步保留写穿镜像。
90
+ - **会话标题是会话数据**:`t_sessions.f_title` 由 rdb 按 `session/title` 事件
91
+ 维护(rewind 截断后重算),列表消费在没有 checkpoint 行时直接取该列。
92
+
93
+ 写节流参数(默认 200 / 5000,与官方 base 装配一致)可经 settings 覆盖:
94
+
95
+ ```yaml
96
+ session-rdb:
97
+ type: sqlite
98
+ path: /absolute/path/to/sessions.sqlite
99
+ projectionCache:
100
+ writeEveryEvents: 200
101
+ writeIntervalMs: 5000
102
+ ```
103
+
104
+ 旧 `storages` JSON 用显式命令导入(先停掉 dsh,旧文件保留不删):
105
+
106
+ ```sh
107
+ just import-storages --dsh-home apps/dsh-custom-next/.dsh-store \
108
+ --path apps/dsh-custom-next/.dsh-store/sessions/sessions.sqlite
109
+ ```
@@ -1,4 +1,4 @@
1
- import { v as EventRow, y as SessionRow } from "./schema-COK7-wRV.mjs";
1
+ import { C as EventRow, w as SessionRow } from "./schema-Bo6Hy5gW.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";
@@ -106,5 +106,12 @@ declare function scanRows(rows: readonly EventRow[], base?: number): {
106
106
  tornFrom?: number;
107
107
  };
108
108
  declare function toJsonlArtifact(meta: SessionHeader, inheritedEventCount: number, events: readonly SessionEvent[]): string;
109
+ /**
110
+ * 事件行 JSON → `session/title` 的标题文本。存储层写路径保证 `f_data` 是完整
111
+ * 事件 JSON;形状不符(或损坏)按「无标题」处理——标题是派生显示数据。
112
+ * @param data - `t_events.f_data` 原文。
113
+ * @returns 标题文本,或 `undefined`。
114
+ */
115
+ declare function titleOfEventData(data: string): string | undefined;
109
116
  //#endregion
110
- 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, toJsonlArtifact };
117
+ 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 };
package/dist/artifact.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { a as repairAssistantSettlement, c as repairRequestHeaders, d as rowToMeta, f as scanRows, g as toJsonlArtifact, 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-BIuXv09P.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-BPEHfHNk.mjs";
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, toJsonlArtifact };
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-DZIAjOUr.mjs";
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,4 +1,4 @@
1
- import { d as rowToMeta } from "./log-BIuXv09P.mjs";
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
4
  import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
@@ -171,6 +171,7 @@ var SessionBranchRdbProvider = class {
171
171
  await tx.updateSeedLength(id, denseBoundary + 1);
172
172
  shrunk = denseBoundary + 1;
173
173
  }
174
+ await tx.refreshTitle(id);
174
175
  await tx.bumpRevision(id);
175
176
  return shrunk;
176
177
  });
package/dist/import.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as SessionPersistenceRdb } from "./index-CgAqCQAb.mjs";
1
+ import { r as SessionPersistenceRdb } from "./index-BEKoV1Uy.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,2 @@
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-BPEHfHNk.mjs";
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-DZIAjOUr.mjs";
2
2
  export { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, parseImportZip, parseJsonlArtifact, persistImport, registerSessionImport };
@@ -1,4 +1,4 @@
1
- import { a as JournalMode, g as Backend, h as WriteGuard } from "./schema-COK7-wRV.mjs";
1
+ import { a as JournalMode, b as WriteGuard, x as Backend } from "./schema-Bo6Hy5gW.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";
@@ -81,15 +81,24 @@ interface SessionPersistenceRdbInternals {
81
81
  readStoredRevision(id: SessionId, signal?: AbortSignal): Promise<import("@deepseek-ai/dsh-session-persistence").SessionPersistenceRevision | undefined>;
82
82
  registerReuseEventIds(childId: SessionId, map: ReadonlyMap<number, string>): void;
83
83
  }
84
+ /** 投影 checkpoint 写节流(替换上游 `session-projection-cache` 的 Config)。 */
85
+ interface ProjectionCacheOptions {
86
+ /** 两次强制点之间累积多少已提交事件强制落盘(默认 200)。 */
87
+ writeEveryEvents?: number;
88
+ /** 脏 checkpoint 在强制点之间允许滞留的最长毫秒数(默认 5000)。 */
89
+ writeIntervalMs?: number;
90
+ }
84
91
  type Config = {
85
92
  type: "sqlite";
86
93
  path: string;
87
94
  journalMode?: JournalMode;
88
95
  busyTimeout?: number;
96
+ projectionCache?: ProjectionCacheOptions;
89
97
  } | {
90
98
  type: "postgres";
91
99
  connectionString: string;
92
100
  schema?: string;
101
+ projectionCache?: ProjectionCacheOptions;
93
102
  };
94
103
  /** 一个已创建但未 materialize 的会话(本进程可见,其他进程不可见)。 */
95
104
  interface PendingSession {
@@ -258,4 +267,4 @@ declare class SessionPersistenceRdb extends SessionPersistence {
258
267
  private ensureLiveHandle;
259
268
  }
260
269
  //#endregion
261
- export { SessionBranchRdbProvider as a, SessionBranchRdb as i, SessionPersistenceRdb as n, locateTurnEnd as o, SessionPersistenceRdbInternals as r, Config as t };
270
+ export { SessionBranchRdb as a, 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-COK7-wRV.mjs";
2
- import { a as SessionBranchRdbProvider, i as SessionBranchRdb, n as SessionPersistenceRdb, o as locateTurnEnd, r as SessionPersistenceRdbInternals, t as Config } from "./index-CgAqCQAb.mjs";
3
- export { Config, SCHEMA_VERSION, SessionBranchRdb, SessionBranchRdbProvider, SessionPersistenceRdb, SessionPersistenceRdb as default, SessionPersistenceRdbInternals, locateTurnEnd };
1
+ import { o as SCHEMA_VERSION } from "./schema-Bo6Hy5gW.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-BEKoV1Uy.mjs";
3
+ export { Config, ProjectionCacheOptions, SCHEMA_VERSION, SessionBranchRdb, SessionBranchRdbProvider, SessionPersistenceRdb, SessionPersistenceRdb as default, SessionPersistenceRdbInternals, locateTurnEnd };