@whispering233/ai-editor-db 0.0.29 → 0.0.32
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.
- package/dist/connection.js +1 -1
- package/dist/connection.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/migrations/003_timepoint.js +1 -1
- package/dist/migrations/003_timepoint.js.map +1 -1
- package/dist/migrations/004_setting_tags.js +2 -2
- package/dist/migrations/004_setting_tags.js.map +1 -1
- package/dist/migrations/005_reference.js +2 -2
- package/dist/migrations/005_reference.js.map +1 -1
- package/dist/migrations/006_sessions_jsonl.d.ts +4 -0
- package/dist/migrations/006_sessions_jsonl.d.ts.map +1 -0
- package/dist/migrations/006_sessions_jsonl.js +95 -0
- package/dist/migrations/006_sessions_jsonl.js.map +1 -0
- package/dist/migrations/index.d.ts +8 -3
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +13 -5
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/legacy-sessions.d.ts +24 -0
- package/dist/migrations/legacy-sessions.d.ts.map +1 -0
- package/dist/migrations/legacy-sessions.js +69 -0
- package/dist/migrations/legacy-sessions.js.map +1 -0
- package/dist/queries/compute-state.d.ts +3 -3
- package/dist/queries/compute-state.js +5 -5
- package/dist/queries/delta.d.ts +4 -4
- package/dist/queries/delta.d.ts.map +1 -1
- package/dist/queries/delta.js +5 -5
- package/dist/queries/delta.js.map +1 -1
- package/dist/queries/entity.d.ts +11 -11
- package/dist/queries/entity.d.ts.map +1 -1
- package/dist/queries/entity.js +30 -30
- package/dist/queries/entity.js.map +1 -1
- package/dist/queries/migration.d.ts +13 -9
- package/dist/queries/migration.d.ts.map +1 -1
- package/dist/queries/migration.js +16 -11
- package/dist/queries/migration.js.map +1 -1
- package/dist/queries/outline-ops.d.ts +11 -11
- package/dist/queries/outline-ops.d.ts.map +1 -1
- package/dist/queries/outline-ops.js +15 -15
- package/dist/queries/outline-ops.js.map +1 -1
- package/dist/queries/relation.d.ts +6 -6
- package/dist/queries/relation.d.ts.map +1 -1
- package/dist/queries/relation.js +9 -9
- package/dist/queries/relation.js.map +1 -1
- package/dist/queries/trash.d.ts +3 -3
- package/dist/queries/trash.d.ts.map +1 -1
- package/dist/queries/trash.js +3 -3
- package/dist/queries/trash.js.map +1 -1
- package/dist/query-db.js +1 -1
- package/dist/query-db.js.map +1 -1
- package/dist/schema.d.ts +5 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +6 -4
- package/dist/schema.js.map +1 -1
- package/dist/storage/atomic.d.ts +1 -1
- package/dist/storage/atomic.js +3 -3
- package/dist/storage/atomic.js.map +1 -1
- package/dist/storage/outline.js +1 -1
- package/dist/storage/project.d.ts +2 -2
- package/dist/storage/project.js +3 -3
- package/dist/storage/project.js.map +1 -1
- package/dist/tables.d.ts +3 -162
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +14 -40
- package/dist/tables.js.map +1 -1
- package/package.json +3 -4
- package/dist/queries/chat.d.ts +0 -85
- package/dist/queries/chat.d.ts.map +0 -1
- package/dist/queries/chat.js +0 -248
- package/dist/queries/chat.js.map +0 -1
package/dist/connection.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @whispering233/ai-editor-db 连接与事务管理(T2.1)
|
|
2
2
|
//
|
|
3
3
|
// better-sqlite3 为同步 API(架构选型:内嵌零配置、同步简单可靠,见 第 11 行)。
|
|
4
|
-
//
|
|
4
|
+
// 持久化语义(第 51 行):WAL 模式 + synchronous=FULL,写入即时落盘。
|
|
5
5
|
import Database from "better-sqlite3";
|
|
6
6
|
import { createTables } from "./schema.js";
|
|
7
7
|
/**
|
package/dist/connection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,sDAAsD;AACtD,
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,sDAAsD;AACtD,kDAAkD;AAElD,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,aAAa,CAAC,EAAM;IAClC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACZ,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAI,EAAM,EAAE,EAAW;IACpD,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ export * from "./connection.js";
|
|
|
3
3
|
export * from "./storage/atomic.js";
|
|
4
4
|
export * from "./storage/outline.js";
|
|
5
5
|
export * from "./storage/project.js";
|
|
6
|
-
export * from "./queries/chat.js";
|
|
7
6
|
export * from "./queries/migration.js";
|
|
8
7
|
export * from "./migrations/index.js";
|
|
9
8
|
export * from "./queries/outline-ops.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
// @whispering233/ai-editor-db 入口:导出建表(schema)、连接(connection
|
|
1
|
+
// @whispering233/ai-editor-db 入口:导出建表(schema)、连接(connection)、
|
|
2
2
|
// JSON 存储(storage/:outline.json / project.json 原子读写,T2.2)、增量迁移(migrations/)
|
|
3
|
+
//
|
|
4
|
+
// 会话文件(sessions/*.jsonl)不在本包:新格式(pi session v3)的读写归 pi SessionManager
|
|
5
|
+
// (agent 包的 pi 运行时),旧 v1 格式只剩迁移 006 用一次的导出辅助(migrations/legacy-sessions.ts,不导出)
|
|
3
6
|
export * from "./schema.js";
|
|
4
7
|
export * from "./connection.js";
|
|
5
8
|
export * from "./storage/atomic.js";
|
|
6
9
|
export * from "./storage/outline.js";
|
|
7
10
|
export * from "./storage/project.js";
|
|
8
|
-
export * from "./queries/chat.js";
|
|
9
11
|
export * from "./queries/migration.js";
|
|
10
12
|
export * from "./migrations/index.js";
|
|
11
13
|
export * from "./queries/outline-ops.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,4EAA4E;AAC5E,EAAE;AACF,sEAAsE;AACtE,gFAAgF;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC"}
|
|
@@ -55,7 +55,7 @@ export default {
|
|
|
55
55
|
db.exec("DROP TABLE entities");
|
|
56
56
|
// 4. 新表更名为 entities(此后才能 prepare 针对 entities 的语句)
|
|
57
57
|
db.exec("ALTER TABLE entities_v3 RENAME TO entities");
|
|
58
|
-
// 迁移时间戳:应用层 ISO 8601
|
|
58
|
+
// 迁移时间戳:应用层 ISO 8601 统一写入(时间约定,不用 SQLite datetime('now'))
|
|
59
59
|
const now = nowIso();
|
|
60
60
|
// 5. 数据迁移:time_label → timepoint + occurs_at(全部在 runMigrations 事务内)
|
|
61
61
|
const events = db
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"003_timepoint.js","sourceRoot":"","sources":["../../src/migrations/003_timepoint.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,8DAA8D;AAC9D,EAAE;AACF,4DAA4D;AAC5D,uDAAuD;AACvD,uEAAuE;AACvE,8CAA8C;AAC9C,EAAE;AACF,uEAAuE;AACvE,iEAAiE;AACjE,kEAAkE;AAClE,iDAAiD;AACjD,EAAE;AACF,2CAA2C;AAC3C,2DAA2D;AAC3D,8CAA8C;AAC9C,mEAAmE;AACnE,2BAA2B;AAC3B,8DAA8D;AAC9D,qEAAqE;AACrE,yBAAyB;AACzB,iEAAiE;AACjE,6CAA6C;AAC7C,4DAA4D;AAC5D,oBAAoB;AACpB,EAAE;AACF,4DAA4D;AAC5D,EAAE;AACF,uDAAuD;AACvD,2DAA2D;AAI3D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,6HAA6H;AAC7H,MAAM,eAAe,GAAG;;;;;;;;;;;CAWvB,CAAC;AAEF,eAAe;IACb,OAAO,EAAE,CAAC;IACV,EAAE,EAAE,CAAC,EAAM,EAAE,EAAE;QAChB,kCAAkC;QAC/B,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,qDAAqD;QAClD,EAAE,CAAC,IAAI,CACL;iGAC2F,CAC5F,CAAC;QACL,SAAS;QACN,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,kDAAkD;QAC/C,EAAE,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAEzD,
|
|
1
|
+
{"version":3,"file":"003_timepoint.js","sourceRoot":"","sources":["../../src/migrations/003_timepoint.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,8DAA8D;AAC9D,EAAE;AACF,4DAA4D;AAC5D,uDAAuD;AACvD,uEAAuE;AACvE,8CAA8C;AAC9C,EAAE;AACF,uEAAuE;AACvE,iEAAiE;AACjE,kEAAkE;AAClE,iDAAiD;AACjD,EAAE;AACF,2CAA2C;AAC3C,2DAA2D;AAC3D,8CAA8C;AAC9C,mEAAmE;AACnE,2BAA2B;AAC3B,8DAA8D;AAC9D,qEAAqE;AACrE,yBAAyB;AACzB,iEAAiE;AACjE,6CAA6C;AAC7C,4DAA4D;AAC5D,oBAAoB;AACpB,EAAE;AACF,4DAA4D;AAC5D,EAAE;AACF,uDAAuD;AACvD,2DAA2D;AAI3D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,6HAA6H;AAC7H,MAAM,eAAe,GAAG;;;;;;;;;;;CAWvB,CAAC;AAEF,eAAe;IACb,OAAO,EAAE,CAAC;IACV,EAAE,EAAE,CAAC,EAAM,EAAE,EAAE;QAChB,kCAAkC;QAC/B,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,qDAAqD;QAClD,EAAE,CAAC,IAAI,CACL;iGAC2F,CAC5F,CAAC;QACL,SAAS;QACN,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,kDAAkD;QAC/C,EAAE,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAEzD,0DAA0D;QACvD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;QAExB,oEAAoE;QACjE,MAAM,MAAM,GAAG,EAAE;aACd,OAAO,CACN;6DACqD,CACtD;aACA,GAAG,EAA0C,CAAC;QAEjD,MAAM,eAAe,GAAG,EAAE,CAAC,OAAO,CAChC;iDAC2C,CAC5C,CAAC;QACF,MAAM,cAAc,GAAG,EAAE,CAAC,OAAO,CAC/B;iEAC2D,CAC5D,CAAC;QACF,MAAM,eAAe,GAAG,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC;QAEnG,sCAAsC;QACnC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;QACnD,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAChC,sDAAsD;YACjD,IAAI,MAAM,GAAY,IAAI,CAAC;YAC3B,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,GAAG,IAAI,CAAC;gBAChB,CAAC;YACH,CAAC;YACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,SAAS;YACrF,MAAM,MAAM,GAAG,MAAiC,CAAC;YACjD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;YACrC,iDAAiD;YAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,SAAS;YAC/D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAE1B,IAAI,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9B,6EAA6E;gBACtE,IAAI,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;gBACrC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACjC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBACrD,SAAS,IAAI,CAAC,CAAC;YACjB,CAAC;YACN,yEAAyE;YACpE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACtE,6DAA6D;YACxD,OAAO,MAAM,CAAC,UAAU,CAAC;YACzB,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;CACkB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// 迁移 004:设定分类字段 tags 落地 + rules 恢复规则条款语义(
|
|
1
|
+
// 迁移 004:设定分类字段 tags 落地 + rules 恢复规则条款语义(K2 修订,2026-08)
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// 背景:J1 曾把 setting.data.rules 复用为分类标签(UI 显示「标签」);用户复核
|
|
4
4
|
// 裁决(K2):分类与规则条款是两种语义——**tags 承接分类(新字段 data.tags: string[]),
|
|
5
5
|
// rules 恢复规则条款语义**(仅设定详情页编辑)。本迁移把旧 rules 数据按用户裁决
|
|
6
6
|
// 「视为分类标签」复制到 data.tags 并移除 data.rules。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"004_setting_tags.js","sourceRoot":"","sources":["../../src/migrations/004_setting_tags.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"004_setting_tags.js","sourceRoot":"","sources":["../../src/migrations/004_setting_tags.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,sDAAsD;AACtD,6DAA6D;AAC7D,iDAAiD;AACjD,wCAAwC;AACxC,EAAE;AACF,8CAA8C;AAC9C,iDAAiD;AACjD,4DAA4D;AAC5D,+CAA+C;AAC/C,+CAA+C;AAC/C,oDAAoD;AAIpD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,oDAAoD;AACpD,MAAM,YAAY,GAAc;IAC9B,OAAO,EAAE,CAAC;IACV,EAAE,CAAC,EAAM;QACP,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CAAC,sDAAsD,CAAC;aAC/D,GAAG,EAAyC,CAAC;QAChD,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC;QACvF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,MAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,CAAC,gBAAgB;YAC5B,CAAC;YACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,SAAS;YACrF,MAAM,GAAG,GAAG,MAAiC,CAAC;YAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC9F,SAAS,CAAC,8CAA8C;YAC1D,CAAC;YACN,uDAAuD;YAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,IAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5G,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAI,KAAkB,CAAC,CAAC;YACjD,OAAO,GAAG,CAAC,KAAK,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// 迁移 005
|
|
1
|
+
// 迁移 005:参考资料实体——entities 表 type CHECK 扩为 7 种(含 'reference')
|
|
2
2
|
//
|
|
3
3
|
// 背景:v4 的 entities.type CHECK 不含 'reference'(第 7 种实体类型,参考资料:外部素材/灵感笔记,
|
|
4
|
-
//
|
|
4
|
+
// 非本书正文,边界)。SQLite 的 CHECK 约束无法 ALTER 修改——必须「建新表 → 拷数据 →
|
|
5
5
|
// drop 旧表 → rename」四步(与 002/003 同款模式)。
|
|
6
6
|
//
|
|
7
7
|
// 安全性:entities 无外键引用(relation_records/delta_records 均无 FOREIGN KEY 子句),四步换表
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"005_reference.js","sourceRoot":"","sources":["../../src/migrations/005_reference.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"005_reference.js","sourceRoot":"","sources":["../../src/migrations/005_reference.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,uEAAuE;AACvE,yDAAyD;AACzD,uCAAuC;AACvC,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAC9E,kDAAkD;AAKlD,mFAAmF;AACnF,MAAM,eAAe,GAAG;;;;;;;;;;;CAWvB,CAAC;AAEF,MAAM,YAAY,GAAc;IAC9B,OAAO,EAAE,CAAC;IACV,EAAE,CAAC,EAAM;QACV,kCAAkC;QAC/B,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,oDAAoD;QACjD,EAAE,CAAC,IAAI,CACL;iGAC2F,CAC5F,CAAC;QACL,SAAS;QACN,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,oBAAoB;QACjB,EAAE,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACxD,CAAC;CACF,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"006_sessions_jsonl.d.ts","sourceRoot":"","sources":["../../src/migrations/006_sessions_jsonl.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAqD5C,QAAA,MAAM,YAAY,EAAE,SAwBnB,CAAC;AAgBF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// 迁移 006:对话历史出库——`chat_messages` 表导出为 `sessions/<session_id>.jsonl` 后 DROP
|
|
2
|
+
//
|
|
3
|
+
// 背景:对话历史从 data.db 迁到项目目录(一 session 一 JSONL,契约见 docs/db/schema.md)。
|
|
4
|
+
// 好处:会话随书目录走(备份/导入/改名/移动天然携带)、追加写可读可 diff、思维链等扩展纯追加。
|
|
5
|
+
//
|
|
6
|
+
// 安全性/幂等性:
|
|
7
|
+
// - 导出是「按表内容整文件重写」(writeLegacySessionFile 原子写,输出仅由入参决定)——文件写不可回滚,
|
|
8
|
+
// 靠完整性收敛:崩溃在提交前 ⇒ 下次重跑按同一张表重写同内容;提交后 ⇒ 表已消失不再重跑
|
|
9
|
+
// - 事务由 runMigrations 保证(up + setUserVersion 原子提交,抛错整体回滚)
|
|
10
|
+
// - session_id 不合法(不匹配 `^sess_[A-Za-z0-9_-]{1,64}$`,无法直接作文件名)的旧会话
|
|
11
|
+
// 以 `sess_legacy_<sha256 前 16 位>` 为文件名落盘(**保数据不丢,会话 id 变更**)——
|
|
12
|
+
// 确定性映射 ⇒ 重跑产出同一文件名,幂等性不受影响
|
|
13
|
+
//
|
|
14
|
+
// 本迁移需要项目目录(写文件)——经 MigrationContext.projectRoot 取得(迁移框架透传)。
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
import { isValidLegacySessionId, writeLegacySessionFile } from "./legacy-sessions.js";
|
|
17
|
+
/** tool_calls TEXT 列 → 数组;NULL / 非法 JSON / 非数组 → null(与旧 parseToolCalls 同口径) */
|
|
18
|
+
function parseToolCallsColumn(json) {
|
|
19
|
+
if (json === null)
|
|
20
|
+
return null;
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(json);
|
|
23
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 读全表并按 session_id 分组(组内保持查询序:created_at 升序、同时间戳按 rowid 插入序)。
|
|
31
|
+
* 直接 `prepare` 属迁移管线(AGENTS 硬约束「查询层统一经 queryDb」的明确例外)。
|
|
32
|
+
*/
|
|
33
|
+
function readLegacyRowsBySession(db) {
|
|
34
|
+
const rows = db
|
|
35
|
+
.prepare(`SELECT id, session_id, role, content, tool_calls, tool_call_id, created_at
|
|
36
|
+
FROM chat_messages
|
|
37
|
+
ORDER BY session_id ASC, created_at ASC, rowid ASC`)
|
|
38
|
+
.all();
|
|
39
|
+
const bySession = new Map();
|
|
40
|
+
for (const r of rows) {
|
|
41
|
+
const list = bySession.get(r.session_id);
|
|
42
|
+
const row = {
|
|
43
|
+
id: r.id,
|
|
44
|
+
role: r.role,
|
|
45
|
+
content: r.content,
|
|
46
|
+
tool_calls: parseToolCallsColumn(r.tool_calls),
|
|
47
|
+
tool_call_id: r.tool_call_id,
|
|
48
|
+
created_at: r.created_at,
|
|
49
|
+
};
|
|
50
|
+
if (list === undefined)
|
|
51
|
+
bySession.set(r.session_id, [row]);
|
|
52
|
+
else
|
|
53
|
+
list.push(row);
|
|
54
|
+
}
|
|
55
|
+
return bySession;
|
|
56
|
+
}
|
|
57
|
+
const migration006 = {
|
|
58
|
+
version: 6,
|
|
59
|
+
up(db, ctx) {
|
|
60
|
+
// 旧库无 chat_messages(新库从未建过该表 / 已迁移过)→ 无事可做(不因缺表中断迁移链)
|
|
61
|
+
if (!tableExists(db, "chat_messages"))
|
|
62
|
+
return;
|
|
63
|
+
const bySession = readLegacyRowsBySession(db);
|
|
64
|
+
const exportable = [...bySession.keys()].filter((id) => isValidLegacySessionId(id));
|
|
65
|
+
if (exportable.length > 0 && ctx.projectRoot === "") {
|
|
66
|
+
// 防御:有会话要导出却无项目目录(ensureSchemaCompatible 恒传 dir;纯逻辑调用才缺失)
|
|
67
|
+
throw new Error("迁移 006 需要项目目录(projectRoot)才能导出会话文件");
|
|
68
|
+
}
|
|
69
|
+
let remapped = 0;
|
|
70
|
+
for (const [sessionId, rows] of bySession) {
|
|
71
|
+
const targetId = isValidLegacySessionId(sessionId) ? sessionId : legacySessionId(sessionId);
|
|
72
|
+
if (targetId !== sessionId)
|
|
73
|
+
remapped += 1;
|
|
74
|
+
writeLegacySessionFile(ctx.projectRoot, targetId, rows);
|
|
75
|
+
}
|
|
76
|
+
if (remapped > 0) {
|
|
77
|
+
console.warn(`[db] 迁移 006:${remapped} 个 session_id 非法的旧会话已以 sess_legacy_<hash> 文件名导出(数据未丢,id 已变更)`);
|
|
78
|
+
}
|
|
79
|
+
db.exec("DROP TABLE chat_messages");
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* 非法旧 id → 稳定的合法文件名 id:`sess_legacy_` + sha256 前 16 位十六进制。
|
|
84
|
+
* 同一输入恒同输出(迁移重跑幂等);碰撞概率可忽略;原始 id 不再保留(旧 id 仅作文件名,无对外语义)。
|
|
85
|
+
*/
|
|
86
|
+
function legacySessionId(originalId) {
|
|
87
|
+
return `sess_legacy_${createHash("sha256").update(originalId).digest("hex").slice(0, 16)}`;
|
|
88
|
+
}
|
|
89
|
+
/** 表是否存在(sqlite_master 查询;迁移内的存在性判定) */
|
|
90
|
+
function tableExists(db, name) {
|
|
91
|
+
const row = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(name);
|
|
92
|
+
return row !== undefined;
|
|
93
|
+
}
|
|
94
|
+
export default migration006;
|
|
95
|
+
//# sourceMappingURL=006_sessions_jsonl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"006_sessions_jsonl.js","sourceRoot":"","sources":["../../src/migrations/006_sessions_jsonl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,oEAAoE;AACpE,qDAAqD;AACrD,EAAE;AACF,WAAW;AACX,kEAAkE;AAClE,kDAAkD;AAClD,0DAA0D;AAC1D,kEAAkE;AAClE,iEAAiE;AACjE,8BAA8B;AAC9B,EAAE;AACF,6DAA6D;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AActF,gFAAgF;AAChF,SAAS,oBAAoB,CAAC,IAAmB;IAC/C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,uBAAuB,CAAC,EAAM;IACrC,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;0DAEoD,CACrD;SACA,GAAG,EAAqB,CAAC;IAC5B,MAAM,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;IACxD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,GAAG,GAAqB;YAC5B,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC;YAC9C,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC;QACF,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;;YACtD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,YAAY,GAAc;IAC9B,OAAO,EAAE,CAAC;IACV,EAAE,CAAC,EAAM,EAAE,GAAG;QACf,sDAAsD;QACnD,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,eAAe,CAAC;YAAE,OAAO;QAC9C,MAAM,SAAS,GAAG,uBAAuB,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC;QACpF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE,EAAE,CAAC;YACpD,0DAA0D;YAC1D,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC5F,IAAI,QAAQ,KAAK,SAAS;gBAAE,QAAQ,IAAI,CAAC,CAAC;YAC1C,sBAAsB,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CACV,eAAe,QAAQ,8DAA8D,CACtF,CAAC;QACJ,CAAC;QACD,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACtC,CAAC;CACF,CAAC;AAEF;;;GAGG;AACH,SAAS,eAAe,CAAC,UAAkB;IACzC,OAAO,eAAe,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC7F,CAAC;AAED,wCAAwC;AACxC,SAAS,WAAW,CAAC,EAAM,EAAE,IAAY;IACvC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrG,OAAO,GAAG,KAAK,SAAS,CAAC;AAC3B,CAAC;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { Db } from "../connection.js";
|
|
2
|
+
/** 迁移运行上下文(写文件类迁移需要项目目录:006 的会话 JSONL 导出) */
|
|
3
|
+
export interface MigrationContext {
|
|
4
|
+
/** 项目根目录(books/<书名>/;会话文件写在 `<projectRoot>/sessions/`) */
|
|
5
|
+
projectRoot: string;
|
|
6
|
+
}
|
|
2
7
|
/** 单条增量迁移(version = 迁移完成后 data.db 的 user_version) */
|
|
3
8
|
export interface Migration {
|
|
4
9
|
version: number;
|
|
5
|
-
/** 迁移逻辑(DDL
|
|
6
|
-
up: (db: Db) => void;
|
|
10
|
+
/** 迁移逻辑(DDL/数据变更/文件导出);抛错 → 该迁移事务整体回滚,版本号不变 */
|
|
11
|
+
up: (db: Db, ctx: MigrationContext) => void;
|
|
7
12
|
}
|
|
8
13
|
/** 全量迁移集(按 version 升序:002 时间轴事件、003 时间标签点实体化(G2)、
|
|
9
|
-
* 004 设定分类字段 tags(
|
|
14
|
+
* 004 设定分类字段 tags(K2 修订)、005 参考资料 reference、006 对话历史出库) */
|
|
10
15
|
export declare const MIGRATIONS: readonly Migration[];
|
|
11
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAO3C,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAChC,0DAA0D;IACzD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC9C,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC7C;AAED;2DAC2D;AAC3D,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAM1C,CAAC"}
|
package/dist/migrations/index.js
CHANGED
|
@@ -16,15 +16,23 @@
|
|
|
16
16
|
// - 失败 → 该迁移回滚 + 版本停在前一迁移后,下次 open 重试
|
|
17
17
|
// - 无迁移路径的旧版本(如 v0 且无 0→1 条目)保持删库重建兜底
|
|
18
18
|
//
|
|
19
|
-
// **当前状态**:SCHEMA_VERSION =
|
|
20
|
-
// sort_order
|
|
21
|
-
// event.data.time_label 迁移为 timepoint 实体 + occurs_at 挂载关系,G2
|
|
19
|
+
// **当前状态**:SCHEMA_VERSION = 6;真实迁移 002(v1→v2:entities 表 CHECK 扩为 5 种 +
|
|
20
|
+
// sort_order 列,时间轴)、003(v2→v3:entities CHECK 扩 6 种含 timepoint +
|
|
21
|
+
// event.data.time_label 迁移为 timepoint 实体 + occurs_at 挂载关系,G2)、
|
|
22
|
+
// 006(v5→v6:对话历史出库——chat_messages 导出为 sessions/<id>.jsonl 后 DROP 表)。
|
|
22
23
|
// v0 库无 0→1 迁移条目,仍走删库重建兜底。
|
|
23
24
|
import migration002 from "./002_event_timeline.js";
|
|
24
25
|
import migration003 from "./003_timepoint.js";
|
|
25
26
|
import migration004 from "./004_setting_tags.js";
|
|
26
27
|
import migration005 from "./005_reference.js";
|
|
28
|
+
import migration006 from "./006_sessions_jsonl.js";
|
|
27
29
|
/** 全量迁移集(按 version 升序:002 时间轴事件、003 时间标签点实体化(G2)、
|
|
28
|
-
* 004 设定分类字段 tags(
|
|
29
|
-
export const MIGRATIONS = [
|
|
30
|
+
* 004 设定分类字段 tags(K2 修订)、005 参考资料 reference、006 对话历史出库) */
|
|
31
|
+
export const MIGRATIONS = [
|
|
32
|
+
migration002,
|
|
33
|
+
migration003,
|
|
34
|
+
migration004,
|
|
35
|
+
migration005,
|
|
36
|
+
migration006,
|
|
37
|
+
];
|
|
30
38
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yDAAyD;AACzD,uCAAuC;AACvC,EAAE;AACF,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,8DAA8D;AAC9D,EAAE;AACF,kDAAkD;AAClD,wDAAwD;AACxD,uDAAuD;AACvD,sCAAsC;AACtC,sCAAsC;AACtC,EAAE;AACF,uEAAuE;AACvE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yDAAyD;AACzD,uCAAuC;AACvC,EAAE;AACF,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,8DAA8D;AAC9D,EAAE;AACF,kDAAkD;AAClD,wDAAwD;AACxD,uDAAuD;AACvD,sCAAsC;AACtC,sCAAsC;AACtC,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,+DAA+D;AAC/D,qEAAqE;AACrE,2BAA2B;AAG3B,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,yBAAyB,CAAC;AAenD;2DAC2D;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;CACb,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** 旧会话行(`chat_messages` 表行形态;tool_calls 已在调用方解析为数组) */
|
|
2
|
+
export interface LegacySessionRow {
|
|
3
|
+
id: string;
|
|
4
|
+
role: string;
|
|
5
|
+
content: string | null;
|
|
6
|
+
tool_calls: unknown[] | null;
|
|
7
|
+
tool_call_id: string | null;
|
|
8
|
+
created_at: string;
|
|
9
|
+
}
|
|
10
|
+
/** 旧 session_id 是否合法(迁移判定「可直接作文件名」) */
|
|
11
|
+
export declare function isValidLegacySessionId(id: string): boolean;
|
|
12
|
+
/** 旧会话目录绝对路径(`<projectRoot>/sessions`) */
|
|
13
|
+
export declare function legacySessionsDirPath(projectRoot: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* 整文件重写一个旧会话文件(header + 全部消息行)——**迁移 006 专用**。
|
|
16
|
+
*
|
|
17
|
+
* 幂等:输出仅由入参决定(不生成时间/随机 id)⇒ 迁移事务回滚后重跑结果一致
|
|
18
|
+
* (文件写不可回滚,靠「按表内容重写」收敛)。原子写(临时文件 + fsync + rename)。
|
|
19
|
+
* 空 rows 也写出仅 header 的文件(created_at 为空串)。
|
|
20
|
+
*
|
|
21
|
+
* @throws Error session_id 非法(调用方必须先经 isValidLegacySessionId 判定/改名)
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeLegacySessionFile(projectRoot: string, sessionId: string, rows: readonly LegacySessionRow[]): void;
|
|
24
|
+
//# sourceMappingURL=legacy-sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-sessions.d.ts","sourceRoot":"","sources":["../../src/migrations/legacy-sessions.ts"],"names":[],"mappings":"AAsBA,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,uCAAuC;AACvC,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,0CAA0C;AAC1C,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAChC,IAAI,CAaN"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// 旧会话格式(v1 扁平 JSONL)导出辅助 —— **仅服务已发布的迁移 006**(对话历史出库)。
|
|
2
|
+
//
|
|
3
|
+
// 为什么留在这里而不是 db 的公开出口:新会话格式(pi session v3)的读写全部归 pi
|
|
4
|
+
// `SessionManager`(见 docs/db/schema.md「sessions/*.jsonl」),本仓生产链路**不再读写**
|
|
5
|
+
// 旧格式;只有迁移 006 需要把 `chat_messages` 表按旧格式落盘一次(已发布迁移不可改语义)。
|
|
6
|
+
//
|
|
7
|
+
// 因此:本模块不进 db 包入口导出、不提供读接口(读断言由测试自行用 node:fs 完成)。
|
|
8
|
+
// 旧格式行:header(`type/version/id/created_at`)+ 消息行(`type=message`)。
|
|
9
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { writeTextAtomic } from "../storage/atomic.js";
|
|
12
|
+
/** 会话目录名(项目目录内) */
|
|
13
|
+
const LEGACY_SESSIONS_DIR_NAME = "sessions";
|
|
14
|
+
/** 旧会话行格式版本(header.version 不为该值 → 老读侧整文件跳过) */
|
|
15
|
+
const LEGACY_SESSION_FILE_VERSION = 1;
|
|
16
|
+
/** 旧 session_id 硬约束(同时是文件名校验——客户端传入值不得含路径分隔符/`..`) */
|
|
17
|
+
const LEGACY_SESSION_ID_PATTERN = /^sess_[A-Za-z0-9_-]{1,64}$/;
|
|
18
|
+
/** 旧 session_id 是否合法(迁移判定「可直接作文件名」) */
|
|
19
|
+
export function isValidLegacySessionId(id) {
|
|
20
|
+
return LEGACY_SESSION_ID_PATTERN.test(id);
|
|
21
|
+
}
|
|
22
|
+
/** 旧会话目录绝对路径(`<projectRoot>/sessions`) */
|
|
23
|
+
export function legacySessionsDirPath(projectRoot) {
|
|
24
|
+
return join(projectRoot, LEGACY_SESSIONS_DIR_NAME);
|
|
25
|
+
}
|
|
26
|
+
/** 旧会话文件绝对路径(路径只由已校验的 id 拼出) */
|
|
27
|
+
function legacySessionFilePath(projectRoot, sessionId) {
|
|
28
|
+
return join(legacySessionsDirPath(projectRoot), `${sessionId}.jsonl`);
|
|
29
|
+
}
|
|
30
|
+
/** 消息行序列化(可选字段仅非空时写入,与旧读写实现逐字节一致) */
|
|
31
|
+
function serializeMessageLine(row) {
|
|
32
|
+
const line = {
|
|
33
|
+
type: "message",
|
|
34
|
+
id: row.id,
|
|
35
|
+
role: row.role,
|
|
36
|
+
content: row.content ?? null,
|
|
37
|
+
created_at: row.created_at,
|
|
38
|
+
};
|
|
39
|
+
if (row.tool_calls != null)
|
|
40
|
+
line.tool_calls = row.tool_calls;
|
|
41
|
+
if (row.tool_call_id != null)
|
|
42
|
+
line.tool_call_id = row.tool_call_id;
|
|
43
|
+
return `${JSON.stringify(line)}\n`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 整文件重写一个旧会话文件(header + 全部消息行)——**迁移 006 专用**。
|
|
47
|
+
*
|
|
48
|
+
* 幂等:输出仅由入参决定(不生成时间/随机 id)⇒ 迁移事务回滚后重跑结果一致
|
|
49
|
+
* (文件写不可回滚,靠「按表内容重写」收敛)。原子写(临时文件 + fsync + rename)。
|
|
50
|
+
* 空 rows 也写出仅 header 的文件(created_at 为空串)。
|
|
51
|
+
*
|
|
52
|
+
* @throws Error session_id 非法(调用方必须先经 isValidLegacySessionId 判定/改名)
|
|
53
|
+
*/
|
|
54
|
+
export function writeLegacySessionFile(projectRoot, sessionId, rows) {
|
|
55
|
+
if (!isValidLegacySessionId(sessionId)) {
|
|
56
|
+
throw new Error(`旧会话 id 非法(应为 ^sess_[A-Za-z0-9_-]{1,64}$):${sessionId}`);
|
|
57
|
+
}
|
|
58
|
+
const dir = legacySessionsDirPath(projectRoot);
|
|
59
|
+
if (!existsSync(dir))
|
|
60
|
+
mkdirSync(dir, { recursive: true });
|
|
61
|
+
const header = `${JSON.stringify({
|
|
62
|
+
type: "session",
|
|
63
|
+
version: LEGACY_SESSION_FILE_VERSION,
|
|
64
|
+
id: sessionId,
|
|
65
|
+
created_at: rows[0]?.created_at ?? "",
|
|
66
|
+
})}\n`;
|
|
67
|
+
writeTextAtomic(legacySessionFilePath(projectRoot, sessionId), header + rows.map(serializeMessageLine).join(""));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=legacy-sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-sessions.js","sourceRoot":"","sources":["../../src/migrations/legacy-sessions.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,oDAAoD;AACpD,yEAAyE;AACzE,0DAA0D;AAC1D,EAAE;AACF,kDAAkD;AAClD,kEAAkE;AAElE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,mBAAmB;AACnB,MAAM,wBAAwB,GAAG,UAAU,CAAC;AAE5C,+CAA+C;AAC/C,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAEtC,sDAAsD;AACtD,MAAM,yBAAyB,GAAG,4BAA4B,CAAC;AAY/D,uCAAuC;AACvC,MAAM,UAAU,sBAAsB,CAAC,EAAU;IAC/C,OAAO,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,OAAO,IAAI,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;AACrD,CAAC;AAED,gCAAgC;AAChC,SAAS,qBAAqB,CAAC,WAAmB,EAAE,SAAiB;IACnE,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,GAAG,SAAS,QAAQ,CAAC,CAAC;AACxE,CAAC;AAED,qCAAqC;AACrC,SAAS,oBAAoB,CAAC,GAAqB;IACjD,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;QAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;KAC3B,CAAC;IACF,IAAI,GAAG,CAAC,UAAU,IAAI,IAAI;QAAE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;IAC7D,IAAI,GAAG,CAAC,YAAY,IAAI,IAAI;QAAE,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;IACnE,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,WAAmB,EACnB,SAAiB,EACjB,IAAiC;IAEjC,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,4CAA4C,SAAS,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,GAAG,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC;QAC/B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,2BAA2B;QACpC,EAAE,EAAE,SAAS;QACb,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,EAAE;KACtC,CAAC,IAAI,CAAC;IACP,eAAe,CAAC,qBAAqB,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACnH,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { ComputeStateResult } from "@whispering233/ai-editor-shared";
|
|
2
2
|
import type { Db } from "../connection.js";
|
|
3
3
|
/**
|
|
4
|
-
* 计算实体到达指定大纲节点时的累积状态(POST /api/v1/delta/compute
|
|
4
|
+
* 计算实体到达指定大纲节点时的累积状态(POST /api/v1/delta/compute)。
|
|
5
5
|
*
|
|
6
6
|
* **前置约定**:
|
|
7
7
|
* - atNodeId 必须存在——路由层先校验节点存在性并映射 404 OUTLINE_NODE_NOT_FOUND 后调用;
|
|
8
8
|
* getOutlinePathIds 对缺失节点抛错,视为调用方 bug,本模块不捕获。
|
|
9
9
|
* - 目标实体不存在(或已软删,getEntity 过滤)→ 返回 **null**,路由层映射 404 ENTITY_NOT_FOUND。
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* 累积流程:
|
|
12
12
|
* 1. state 基座 = 实体初始 data 深拷贝(structuredClone,不污染 getEntity 返回行)
|
|
13
13
|
* 2. 树路径 = getOutlinePathIds(tree, atNodeId)(根 → at_node,含 root 哨兵——无 delta 挂它,
|
|
14
14
|
* 无害);路径上每节点调 listDeltasByNode(内置可见性三态过滤与 order ASC),
|
|
@@ -19,7 +19,7 @@ import type { Db } from "../connection.js";
|
|
|
19
19
|
* 有跳过时出现)};conflicts 为跨全部 delta 的扁平数组
|
|
20
20
|
*
|
|
21
21
|
* target_type 不参与过滤(仅回显):id 前缀体系(char-/set-/loc-/hook-/sc-/ch-/vol- 等)保证
|
|
22
|
-
* target_id 全局唯一,targetId 即足以定位目标;
|
|
22
|
+
* target_id 全局唯一,targetId 即足以定位目标;Req 携带 target_type 用于响应回显。
|
|
23
23
|
*
|
|
24
24
|
* @param outlineDir 项目根目录(outline.json 读取:树路径 + 节点软删校验)
|
|
25
25
|
* @returns ComputeStateResult;目标实体不存在/已软删返回 null
|
|
@@ -15,7 +15,7 @@ import { listDeltasByNode } from "./delta.js";
|
|
|
15
15
|
import { getEntity } from "./entity.js";
|
|
16
16
|
import { getOutlinePathIds, readOutlineFile } from "../storage/outline.js";
|
|
17
17
|
/**
|
|
18
|
-
* 应用单条 change 到 state(四段规则
|
|
18
|
+
* 应用单条 change 到 state(四段规则 +):
|
|
19
19
|
* - `set`:state[field] = to(直接替换)
|
|
20
20
|
* - `update`:state[field] === from → state[field] = to;否则**跳过该 change**——
|
|
21
21
|
* 在 skipped 追加 { index, field, expected: from, actual } 且 conflicts 追加
|
|
@@ -25,7 +25,7 @@ import { getOutlinePathIds, readOutlineFile } from "../storage/outline.js";
|
|
|
25
25
|
* 仅定义 update 冲突)
|
|
26
26
|
* - `remove`:state[field] 为数组 → 按值匹配移除**首个**匹配;值不存在静默忽略;
|
|
27
27
|
* 非数组静默跳过
|
|
28
|
-
*
|
|
28
|
+
* 字段约定:add/remove 用 value,set/update 用 to。
|
|
29
29
|
* 防御:非对象 change 静默忽略(changes 列来自 JSON 解析,坏项不打挂整条计算)。
|
|
30
30
|
*/
|
|
31
31
|
function applyChange(state, change, index, deltaId, skipped, conflicts) {
|
|
@@ -62,14 +62,14 @@ function applyChange(state, change, index, deltaId, skipped, conflicts) {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
* 计算实体到达指定大纲节点时的累积状态(POST /api/v1/delta/compute
|
|
65
|
+
* 计算实体到达指定大纲节点时的累积状态(POST /api/v1/delta/compute)。
|
|
66
66
|
*
|
|
67
67
|
* **前置约定**:
|
|
68
68
|
* - atNodeId 必须存在——路由层先校验节点存在性并映射 404 OUTLINE_NODE_NOT_FOUND 后调用;
|
|
69
69
|
* getOutlinePathIds 对缺失节点抛错,视为调用方 bug,本模块不捕获。
|
|
70
70
|
* - 目标实体不存在(或已软删,getEntity 过滤)→ 返回 **null**,路由层映射 404 ENTITY_NOT_FOUND。
|
|
71
71
|
*
|
|
72
|
-
*
|
|
72
|
+
* 累积流程:
|
|
73
73
|
* 1. state 基座 = 实体初始 data 深拷贝(structuredClone,不污染 getEntity 返回行)
|
|
74
74
|
* 2. 树路径 = getOutlinePathIds(tree, atNodeId)(根 → at_node,含 root 哨兵——无 delta 挂它,
|
|
75
75
|
* 无害);路径上每节点调 listDeltasByNode(内置可见性三态过滤与 order ASC),
|
|
@@ -80,7 +80,7 @@ function applyChange(state, change, index, deltaId, skipped, conflicts) {
|
|
|
80
80
|
* 有跳过时出现)};conflicts 为跨全部 delta 的扁平数组
|
|
81
81
|
*
|
|
82
82
|
* target_type 不参与过滤(仅回显):id 前缀体系(char-/set-/loc-/hook-/sc-/ch-/vol- 等)保证
|
|
83
|
-
* target_id 全局唯一,targetId 即足以定位目标;
|
|
83
|
+
* target_id 全局唯一,targetId 即足以定位目标;Req 携带 target_type 用于响应回显。
|
|
84
84
|
*
|
|
85
85
|
* @param outlineDir 项目根目录(outline.json 读取:树路径 + 节点软删校验)
|
|
86
86
|
* @returns ComputeStateResult;目标实体不存在/已软删返回 null
|
package/dist/queries/delta.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DeltaChange, DeltaRecord, DeltaRow } from "@whispering233/ai-editor-shared";
|
|
2
2
|
import { type Db } from "../connection.js";
|
|
3
|
-
/**
|
|
3
|
+
/** 追加入参(无 order 字段——服务端生成) */
|
|
4
4
|
export interface InsertDeltaInput {
|
|
5
5
|
/** 触发变更的大纲节点 ID */
|
|
6
6
|
nodeId: string;
|
|
@@ -11,7 +11,7 @@ export interface InsertDeltaInput {
|
|
|
11
11
|
description: string;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* 追加属性变更记录(POST /api/v1/delta
|
|
14
|
+
* 追加属性变更记录(POST /api/v1/delta):
|
|
15
15
|
* - **order 服务端生成、全局单调递增**:SELECT COALESCE(MAX("order"), 0) + 1,包单库事务
|
|
16
16
|
* (better-sqlite3 同步单连接下读-写无竞态,事务保证跨语句原子与回滚语义)
|
|
17
17
|
* - **前置约定:本层不校验触发节点/目标存在性**—— POST /delta 未定义
|
|
@@ -19,7 +19,7 @@ export interface InsertDeltaInput {
|
|
|
19
19
|
* 不可见、目标缺失仅省略 name)永久不可见。存在性校验由 S5.3 路由层负责。
|
|
20
20
|
* - id = shared generateId("delta-")(与关系 generateId("rel-") 同构;mapping.test.ts
|
|
21
21
|
* 的 "delta-1" 形状一致;前缀 + nanoid 全局唯一)
|
|
22
|
-
* - created_at = updated_at = nowIso
|
|
22
|
+
* - created_at = updated_at = nowIso(应用层写时间约定)
|
|
23
23
|
* @returns 完整行(DeltaRow,changes 已解析为数组)
|
|
24
24
|
*/
|
|
25
25
|
export declare function insertDelta(db: Db, input: InsertDeltaInput): DeltaRow;
|
|
@@ -34,7 +34,7 @@ export declare function insertDelta(db: Db, input: InsertDeltaInput): DeltaRow;
|
|
|
34
34
|
*/
|
|
35
35
|
export declare function getDeltaRow(db: Db, id: string): DeltaRow | null;
|
|
36
36
|
/**
|
|
37
|
-
* 按触发节点查询 Delta(GET /api/v1/delta/node/:nodeId
|
|
37
|
+
* 按触发节点查询 Delta(GET /api/v1/delta/node/:nodeId):
|
|
38
38
|
* - SQL:node_id = ? AND deleted_at IS NULL,按 "order" 递增(computeState 同节点内应用序)
|
|
39
39
|
* - **可见性三态过滤(AND)**:见 filterVisibleDeltas(本函数行同属一个
|
|
40
40
|
* 触发节点,仍逐行判定——与 listDeltasByTarget 共用同一实现,语义幂等)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta.d.ts","sourceRoot":"","sources":["../../src/queries/delta.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAmB,MAAM,iCAAiC,CAAC;AAK3G,OAAO,EAAmB,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AA2C5D
|
|
1
|
+
{"version":3,"file":"delta.d.ts","sourceRoot":"","sources":["../../src/queries/delta.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAmB,MAAM,iCAAiC,CAAC;AAK3G,OAAO,EAAmB,KAAK,EAAE,EAAE,MAAM,kBAAkB,CAAC;AA2C5D,8BAA8B;AAC9B,MAAM,WAAW,gBAAgB;IAChC,mBAAmB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,gBAAgB,GAAG,QAAQ,CAuCrE;AAwED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAS/D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CAiB1F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CAY9F;AAID,sCAAsC;AACtC,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAE9G,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAsElF"}
|
package/dist/queries/delta.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// 大纲节点 target 走 outline.json
|
|
14
14
|
// - name 联表同路径:实体 → entities.name、大纲节点 → outline.json title
|
|
15
15
|
//
|
|
16
|
-
//
|
|
16
|
+
// 查询经 queryDb 走 drizzle 构建器(混合风格 4A)。
|
|
17
17
|
// 语义逐句对照旧实现(git show 52c7c13^:packages/db/src/queries/delta.ts):
|
|
18
18
|
// - order 全局单调:SELECT COALESCE(MAX("order"),0)+1 ↔ select({ next: sql<number> }) 聚合模板
|
|
19
19
|
// (MAX 聚合无法用 builder 列表达,用 sql 模板;COALESCE 保证恒有行——聚合无分组恒单行)
|
|
@@ -54,7 +54,7 @@ function rowToDeltaRow(row) {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* changes 列解析防御:非法 JSON / 非数组 → [](单条坏行不打挂整表查询;
|
|
57
|
-
* 与 entity.ts parseDataColumn
|
|
57
|
+
* 与 entity.ts parseDataColumn 防御风格一致)
|
|
58
58
|
*/
|
|
59
59
|
function parseChanges(value) {
|
|
60
60
|
if (typeof value !== "string")
|
|
@@ -68,7 +68,7 @@ function parseChanges(value) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
* 追加属性变更记录(POST /api/v1/delta
|
|
71
|
+
* 追加属性变更记录(POST /api/v1/delta):
|
|
72
72
|
* - **order 服务端生成、全局单调递增**:SELECT COALESCE(MAX("order"), 0) + 1,包单库事务
|
|
73
73
|
* (better-sqlite3 同步单连接下读-写无竞态,事务保证跨语句原子与回滚语义)
|
|
74
74
|
* - **前置约定:本层不校验触发节点/目标存在性**—— POST /delta 未定义
|
|
@@ -76,7 +76,7 @@ function parseChanges(value) {
|
|
|
76
76
|
* 不可见、目标缺失仅省略 name)永久不可见。存在性校验由 S5.3 路由层负责。
|
|
77
77
|
* - id = shared generateId("delta-")(与关系 generateId("rel-") 同构;mapping.test.ts
|
|
78
78
|
* 的 "delta-1" 形状一致;前缀 + nanoid 全局唯一)
|
|
79
|
-
* - created_at = updated_at = nowIso
|
|
79
|
+
* - created_at = updated_at = nowIso(应用层写时间约定)
|
|
80
80
|
* @returns 完整行(DeltaRow,changes 已解析为数组)
|
|
81
81
|
*/
|
|
82
82
|
export function insertDelta(db, input) {
|
|
@@ -211,7 +211,7 @@ export function getDeltaRow(db, id) {
|
|
|
211
211
|
return rowToDeltaRow(row);
|
|
212
212
|
}
|
|
213
213
|
/**
|
|
214
|
-
* 按触发节点查询 Delta(GET /api/v1/delta/node/:nodeId
|
|
214
|
+
* 按触发节点查询 Delta(GET /api/v1/delta/node/:nodeId):
|
|
215
215
|
* - SQL:node_id = ? AND deleted_at IS NULL,按 "order" 递增(computeState 同节点内应用序)
|
|
216
216
|
* - **可见性三态过滤(AND)**:见 filterVisibleDeltas(本函数行同属一个
|
|
217
217
|
* 触发节点,仍逐行判定——与 listDeltasByTarget 共用同一实现,语义幂等)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../src/queries/delta.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,EAAE;AACF,EAAE;AACF,+DAA+D;AAC/D,6EAA6E;AAC7E,iCAAiC;AACjC,EAAE;AACF,mBAAmB;AACnB,sCAAsC;AACtC,kDAAkD;AAClD,qCAAqC;AACrC,gDAAgD;AAChD,6BAA6B;AAC7B,4DAA4D;AAC5D,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../src/queries/delta.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,EAAE;AACF,EAAE;AACF,+DAA+D;AAC/D,6EAA6E;AAC7E,iCAAiC;AACjC,EAAE;AACF,mBAAmB;AACnB,sCAAsC;AACtC,kDAAkD;AAClD,qCAAqC;AACrC,gDAAgD;AAChD,6BAA6B;AAC7B,4DAA4D;AAC5D,EAAE;AACF,sCAAsC;AACtC,iEAAiE;AACjE,sFAAsF;AACtF,4DAA4D;AAC5D,qEAAqE;AACrE,gFAAgF;AAChF,8EAA8E;AAC9E,kEAAkE;AAClE,2CAA2C;AAG3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAW,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAE3F,uEAAuE;AACvE,SAAS,aAAa,CAAC,GAA4B;IACjD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAY;QACpB,OAAO,EAAE,GAAG,CAAC,OAAiB;QAC9B,WAAW,EAAE,GAAG,CAAC,WAAqB;QACtC,SAAS,EAAE,GAAG,CAAC,SAAmB;QAClC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;QAClC,WAAW,EAAE,GAAG,CAAC,WAAqB;QACtC,KAAK,EAAE,GAAG,CAAC,KAAe;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAoB;QACpC,UAAU,EAAE,GAAG,CAAC,UAAoB;QACpC,UAAU,EAAG,GAAG,CAAC,UAA4B,IAAI,IAAI;KACtD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAaD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,EAAM,EAAE,KAAuB;IACzD,OAAO,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QACtB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;QACxB,qDAAqD;QACrD,8CAA8C;QAC3C,MAAM,IAAI,GACR,CAAC;aACE,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAQ,gBAAgB,YAAY,CAAC,KAAK,WAAW,EAAE,CAAC;aAC1E,IAAI,CAAC,YAAY,CAAC;aAClB,GAAG,EACP,CAAC,IAAI,CAAC;QACP,MAAM,GAAG,GAAa;YACpB,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;YACxB,OAAO,EAAE,KAAK,CAAC,MAAM;YACrB,WAAW,EAAE,KAAK,CAAC,UAAU;YAC7B,SAAS,EAAE,KAAK,CAAC,QAAQ;YACzB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,IAAI;SACjB,CAAC;QACF,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;aACnB,MAAM,CAAC;YACN,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,mBAAmB;YACzD,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;SAC3B,CAAC;aACD,GAAG,EAAE,CAAC;QACT,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,mBAAmB,CAAC,EAAM,EAAE,IAAoC,EAAE,IAAqB;IAC9F,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACvB,2CAA2C;IAC3C,uDAAuD;IACvD,sCAAsC;IACrC,MAAM,SAAS,GAAG;QAChB,GAAG,IAAI,GAAG,CACR,IAAI;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,mBAAyC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAqB,CAAC,CAAC;aAC3F,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAmB,CAAC,CACrC;KACF,CAAC;IACF,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,oDAAoD;QACjD,MAAM,QAAQ,GAAG,CAAC;aACf,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;aAC3B,IAAI,CAAC,QAAQ,CAAC;aACd,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;aAC3E,GAAG,EAAE,CAAC;QACT,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,yBAAyB;QACtB,MAAM,QAAQ,GAAG,CAAC;aACf,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;aAChD,IAAI,CAAC,QAAQ,CAAC;aACd,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;aACtC,GAAG,EAAE,CAAC;QACT,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,iCAAiC;QAC9B,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI;YAAE,SAAS;QACnE,WAAW;QACR,IAAI,iBAA0B,CAAC;QAC/B,IAAI,UAA8B,CAAC;QACnC,IAAK,mBAAyC,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACzE,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACzD,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YAClD,iBAAiB,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;YAChE,IAAI,IAAI,KAAK,SAAS;gBAAE,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC;QAClD,CAAC;QACD,IAAI,iBAAiB;YAAE,SAAS;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,2CAA2C;QAC9E,IAAI,UAAU,KAAK,SAAS;YAAE,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,EAAM,EAAE,EAAU;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,CAAC;SACV,MAAM,EAAE;SACR,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;SACpE,GAAG,EAAE,CAAC;IACT,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAM,EAAE,MAAc,EAAE,UAAkB;IACzE,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,CAAC;SACX,MAAM,EAAE;SACR,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;SAC7E,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;SAChC,GAAG,EAAE,CAAC;IACT,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1C,mCAAmC;IACnC,yBAAyB;IACxB,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAEjE,OAAO,mBAAmB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAM,EAAE,QAAgB,EAAE,UAAkB;IAC7E,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,CAAC;SACX,MAAM,EAAE;SACR,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;SACjF,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;SAChC,GAAG,EAAE,CAAC;IACT,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IACzC,OAAO,mBAAmB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAiBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAM,EAAE,UAAkB;IAC3D,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,CAAC;SACX,MAAM,EAAE;SACR,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;SACtC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;SAChC,GAAG,EAAE,CAAC;IACT,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1C,qEAAqE;IACpE,MAAM,SAAS,GAAG;QAChB,GAAG,IAAI,GAAG,CACR,IAAI;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,mBAAyC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAqB,CAAC,CAAC;aAC3F,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAmB,CAAC,CACrC;KACF,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAwC,CAAC;IACrE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,CAAC;aACZ,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;aAC5D,IAAI,CAAC,QAAQ,CAAC;aACd,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;aACtC,GAAG,EAAE,CAAC;QACT,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACtB,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAE,CAAC;gBAC1C,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,yBAAyB;QACtB,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAC7J,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;YAC7J,SAAS;QACX,CAAC;QACJ,0BAA0B;QACvB,IAAI,WAAyC,CAAC;QAC9C,IAAK,mBAAyC,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACzE,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YAClD,WAAW,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1F,CAAC;QACD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC;gBACP,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,GAAG,CAAC,OAAO;gBACnB,UAAU,EAAE,GAAG,CAAC,WAAW;gBAC3B,QAAQ,EAAE,GAAG,CAAC,SAAS;gBACvB,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,MAAM,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB;aACxE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|