@deepseek-ai/dsh-session-projection-cache 0.1.2-alpha.5 → 0.1.3-alpha.2
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/README.i18n.yaml +2 -2
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/lib/index.js +70 -21
- package/lib/types/index.d.ts +20 -0
- package/lib/types/spec.d.ts +16 -10
- package/package.json +10 -10
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/session/session-projection-cache/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: ba90e838763787d28e5b6e278d868504fc672c5f
|
|
6
|
+
README.zh.md: 8b3fe4148d408af75194212e4787a7cdb9030507
|
package/README.md
CHANGED
|
@@ -58,13 +58,13 @@ Three mandatory points always write: session creation persists the seed-derived
|
|
|
58
58
|
|
|
59
59
|
### Reading cached values
|
|
60
60
|
|
|
61
|
-
`cachedSnapshot(meta, inheritedEventCount)` synchronously serves client values from the storage domain's in-memory tables with zero I/O. It accepts only an identity-matching record and version- and schema-matching keys, then returns a `{ asOfSeq, values }` cut at the lowest served-row watermark. An unseeded listing knows that its cut is zero; a seeded header-only listing does not know the numeric cut and
|
|
61
|
+
`cachedSnapshot(meta, inheritedEventCount)` synchronously serves client values from the storage domain's in-memory tables with zero I/O. It accepts only an identity-matching record and version- and schema-matching keys, then returns a `{ asOfSeq, values }` cut at the lowest served-row watermark. `cachedPredecessorTitle(meta, inheritedEventCount)` is the narrower listing-only exception: a structurally admitted predecessor record whose lifecycle matches may expose only a current-version-compatible `title` row. The title is a possibly stale fact from a durable prefix, not a fold seed; it carries the sentinel `asOfSeq: -1` because a cardinality-changing Session migration can invalidate the predecessor row's numeric sequence. All other predecessor rows remain unavailable. An unseeded listing knows that its cut is zero; a seeded header-only listing does not know the numeric cut and skips both fast paths until an authoritative body read supplies it. `coldSnapshot(meta, inheritedEventCount, events)` accepts the exact cut with a complete ordered log, skips the checkpointed prefix while folding, and refreshes the record without reading persistence itself.
|
|
62
62
|
|
|
63
63
|
### What the cache guarantees
|
|
64
64
|
|
|
65
|
-
The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row
|
|
65
|
+
The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`formatVersion`, `createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row folded from another Session format generation or fork cut cannot seed the caller. The JSON backend stores each record at `<root>/session_projcache/sessions/<id>.json` in an owner-only directory tree.
|
|
66
66
|
|
|
67
|
-
Upgrades never cost the boot or
|
|
67
|
+
Upgrades never cost the boot or expose an unproven fold. Records stamped with a version in the spec's `compatibleVersions` remain structurally readable for a current checkpoint rewrite, but a missing or older `formatVersion` never matches a current Session and therefore cannot seed hydration. A lifecycle-matching predecessor title remains available only through the listing hint above because title text is invariant across the adjacent Session-format edges and its row still passes the current projection `stateVersion` and schema. Once the format matches, absent lineage fields decode as the unseeded lineage — exact for unseeded sessions, while a seeded caller fails the identity match and refolds cold. A stored record that still fails schema validation is moved aside as `<id>.json.bak.<stamp>` under the domain's `invalidRecords: 'backup-and-skip'` policy, logged with its cause, and rebuilt by the next checkpoint.
|
|
68
68
|
|
|
69
69
|
-----
|
|
70
70
|
|
package/README.zh.md
CHANGED
|
@@ -58,13 +58,13 @@ kind: "package-reference"
|
|
|
58
58
|
|
|
59
59
|
### 读取缓存值
|
|
60
60
|
|
|
61
|
-
`cachedSnapshot(meta, inheritedEventCount)` 以零 I/O 从存储域的内存表同步提供客户端值。它只接受身份匹配的记录以及版本和 schema 均匹配的 key,再按所服务行的最低水位返回 `{ asOfSeq, values }`
|
|
61
|
+
`cachedSnapshot(meta, inheritedEventCount)` 以零 I/O 从存储域的内存表同步提供客户端值。它只接受身份匹配的记录以及版本和 schema 均匹配的 key,再按所服务行的最低水位返回 `{ asOfSeq, values }` 切面。`cachedPredecessorTitle(meta, inheritedEventCount)` 是更窄的列表专用例外:生命周期匹配且已通过结构准入的 predecessor record 只能公开与当前版本兼容的 `title` row。该 title 是 durable prefix 中可能过时的事实,而不是 fold seed;它携带 sentinel `asOfSeq: -1`,因为改变事件数量的 Session 迁移会使 predecessor row 的数字序号失效。其他 predecessor row 仍不可用。未 seeded 的列表知道切点为零;仅 header 的 seeded 列表不知道数字切点,因此两条快速路径都要跳过,直到权威正文读取提供它。`coldSnapshot(meta, inheritedEventCount, events)` 接受精确切点与完整有序日志,在折叠时跳过已检查点化的前缀,并在自身不读取持久化层的情况下刷新记录。
|
|
62
62
|
|
|
63
63
|
### 缓存保证什么
|
|
64
64
|
|
|
65
|
-
日志领先,缓存跟随:实时检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配实时单元 schema 与完整生命周期身份(`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount
|
|
65
|
+
日志领先,缓存跟随:实时检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配实时单元 schema 与完整生命周期身份(`formatVersion`、`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此从另一会话格式代或 fork 切点折叠出的行不能播种调用方。JSON 后端把每条记录存于仅所有者可访问的 `<root>/session_projcache/sessions/<id>.json` 目录树中。
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
升级绝不拖垮启动,也不会暴露未经证明的折叠结果。版本戳落在 spec `compatibleVersions` 集合内的记录仍可被结构化读取并等待当前检查点重写,但缺失或更旧的 `formatVersion` 绝不匹配当前 Session,因此不能作为 hydrate seed。生命周期匹配的 predecessor title 只能通过上述列表 hint 读取,因为 title 文本在相邻 Session format edge 之间保持不变,并且该 row 仍须通过当前 projection `stateVersion` 与 schema。格式匹配后,缺失的 lineage 字段解码为 unseeded lineage——对非 fork 会话精确无误,seeded 调用方则通不过身份比对、回落冷折叠。仍然通不过 schema 校验的存量记录会按域的 `invalidRecords: 'backup-and-skip'` 策略移出为 `<id>.json.bak.<时间戳>`、连同原因写入日志,并由下一次检查点重建。
|
|
68
68
|
|
|
69
69
|
-----
|
|
70
70
|
|
package/lib/index.js
CHANGED
|
@@ -38,14 +38,15 @@ const checkpointRow = z$1.object({
|
|
|
38
38
|
* unrelated log. Reads validate this against the live header (listing) or
|
|
39
39
|
* the stored header (cold read) before accepting any record.
|
|
40
40
|
*
|
|
41
|
-
* The lineage fields are optional because records admitted through
|
|
42
|
-
* `compatibleVersions` predate them. The reader (`identityMatches`)
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
41
|
+
* The format and lineage fields are optional because records admitted through
|
|
42
|
+
* `compatibleVersions` predate them. The reader (`identityMatches`) refuses an
|
|
43
|
+
* absent format generation because no current Session log can prove that
|
|
44
|
+
* record's fold semantics. It interprets absent lineage as unseeded only after
|
|
45
|
+
* the format generation matches. Current-version writes always store all three
|
|
46
46
|
* fields.
|
|
47
47
|
*/
|
|
48
48
|
const checkpointIdentity = z$1.object({
|
|
49
|
+
formatVersion: z$1.number().int().nonnegative().optional(),
|
|
49
50
|
createdAt: z$1.number().int().nonnegative(),
|
|
50
51
|
cwd: z$1.string().optional(),
|
|
51
52
|
isSeeded: z$1.boolean().optional(),
|
|
@@ -67,15 +68,18 @@ const checkpointRecord = z$1.object({
|
|
|
67
68
|
* open (cache semantics — a stale or unreadable cache costs a longer tail
|
|
68
69
|
* replay, never a wrong value) while the rest of the domain stays usable,
|
|
69
70
|
* instead of rejecting the whole medium. The `compatibleVersions` entries
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* read-compat Agent Note
|
|
71
|
+
* keep structurally valid predecessor records available for a later current
|
|
72
|
+
* checkpoint rewrite. Records without `formatVersion` remain unusable as fold
|
|
73
|
+
* shortcuts because they cannot prove which Session event semantics produced
|
|
74
|
+
* their rows; the per-record version map and disposition live in the read-compat Agent Note
|
|
75
75
|
* (.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.md).
|
|
76
76
|
* The per-row `ver` guard and the identity match still discard anything the
|
|
77
77
|
* current fold semantics cannot vouch for.
|
|
78
78
|
*
|
|
79
|
+
* A lifecycle-matching predecessor may still expose its version-compatible
|
|
80
|
+
* title through the cache service's listing-only hint; this never relaxes the
|
|
81
|
+
* format requirement for hydration or another fold shortcut.
|
|
82
|
+
*
|
|
79
83
|
* `invalidRecords: 'backup-and-skip'`: a stored record that fails the schema
|
|
80
84
|
* anyway is disposable derived data, so it must never cost the boot — the
|
|
81
85
|
* domain layer moves the document aside as `<key>.json.bak.<stamp>`, logs
|
|
@@ -84,8 +88,13 @@ const checkpointRecord = z$1.object({
|
|
|
84
88
|
*/
|
|
85
89
|
const projectionCacheDomainSpec = defineDomain({
|
|
86
90
|
name: "session_projcache",
|
|
87
|
-
version:
|
|
88
|
-
compatibleVersions: [
|
|
91
|
+
version: 7,
|
|
92
|
+
compatibleVersions: [
|
|
93
|
+
3,
|
|
94
|
+
4,
|
|
95
|
+
5,
|
|
96
|
+
6
|
|
97
|
+
],
|
|
89
98
|
invalidRecords: "backup-and-skip",
|
|
90
99
|
layout: "per-record",
|
|
91
100
|
tables: { sessions: domainTable(checkpointRecord) }
|
|
@@ -109,6 +118,7 @@ const projectionCacheDomainSpec = defineDomain({
|
|
|
109
118
|
* (.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md).
|
|
110
119
|
* @module @deepseek-ai/dsh-session-projection-cache
|
|
111
120
|
*/
|
|
121
|
+
const PREDECESSOR_TITLE_KEY = "title";
|
|
112
122
|
const Config = z.object({
|
|
113
123
|
writeEveryEvents: z.natural().min(1).required(),
|
|
114
124
|
writeIntervalMs: z.natural().min(1).required()
|
|
@@ -178,16 +188,46 @@ var SessionProjectionCache = class extends Service {
|
|
|
178
188
|
cachedSnapshot(meta, inheritedEventCount, keys) {
|
|
179
189
|
const record = this.recordFor(meta.id, identityOf(meta, inheritedEventCount));
|
|
180
190
|
if (record === void 0) return void 0;
|
|
191
|
+
return this.viewRecord(record, keys);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Read only a predecessor checkpoint's title as a zero-I/O listing hint.
|
|
195
|
+
*
|
|
196
|
+
* The authoritative Session header supplies the lifecycle identity. A cache
|
|
197
|
+
* checkpoint can lag that log but cannot lead it because writes flush the
|
|
198
|
+
* log first, so a matching predecessor title is a genuine (possibly stale)
|
|
199
|
+
* fact from this Session. The registry still requires the current title
|
|
200
|
+
* projection's row version and schema. No other predecessor projection is
|
|
201
|
+
* exposed: format normalization can change their current meaning, and the
|
|
202
|
+
* strict {@link cachedSnapshot} / hydration paths continue to reject them.
|
|
203
|
+
* @param meta - authoritative listed Session header.
|
|
204
|
+
* @param inheritedEventCount - exact inherited cut completing the lifecycle identity.
|
|
205
|
+
* @returns a title-only checkpoint view with `asOfSeq: -1`, or `undefined`
|
|
206
|
+
* when the record is current, newer, unrelated, missing, or incompatible
|
|
207
|
+
* with the title unit. The sentinel avoids reusing a sequence that a
|
|
208
|
+
* cardinality-changing Session migration may have remapped.
|
|
209
|
+
*/
|
|
210
|
+
cachedPredecessorTitle(meta, inheritedEventCount) {
|
|
211
|
+
const expected = identityOf(meta, inheritedEventCount);
|
|
212
|
+
const record = this.requireTable().get(meta.id);
|
|
213
|
+
if (record === void 0 || !predecessorIdentityMatches(record.identity, expected)) return void 0;
|
|
214
|
+
const title = this.viewRecord(record, [PREDECESSOR_TITLE_KEY]);
|
|
215
|
+
return title === void 0 ? void 0 : {
|
|
216
|
+
...title,
|
|
217
|
+
asOfSeq: -1
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/** View selected wire rows and bind them to their lowest served watermark. */
|
|
221
|
+
viewRecord(record, keys) {
|
|
181
222
|
const values = this.ctx.sessionProjections.viewCheckpoint(record.rows, keys);
|
|
182
223
|
const servedKeys = Object.keys(values);
|
|
183
224
|
if (servedKeys.length === 0) return void 0;
|
|
184
|
-
|
|
185
|
-
|
|
225
|
+
const firstKey = servedKeys[0];
|
|
226
|
+
let asOfSeq = record.rows[firstKey].seq;
|
|
227
|
+
for (const key of servedKeys.slice(1)) {
|
|
186
228
|
const row = record.rows[key];
|
|
187
|
-
if (row
|
|
229
|
+
if (row.seq < asOfSeq) asOfSeq = row.seq;
|
|
188
230
|
}
|
|
189
|
-
/* v8 ignore next -- A nonempty checkpoint view contains a stored row for every returned key. */
|
|
190
|
-
if (asOfSeq === void 0) return void 0;
|
|
191
231
|
return {
|
|
192
232
|
asOfSeq,
|
|
193
233
|
values
|
|
@@ -322,6 +362,7 @@ function identityOf(header, inheritedEventCount) {
|
|
|
322
362
|
const cut = SessionLogOffset(inheritedEventCount);
|
|
323
363
|
if (!header.isSeeded && cut !== 0) throw new Error("unseeded projection-cache identity inherited event count must be 0");
|
|
324
364
|
return {
|
|
365
|
+
formatVersion: header.version,
|
|
325
366
|
createdAt: header.createdAt,
|
|
326
367
|
...header.cwd === void 0 ? {} : { cwd: header.cwd },
|
|
327
368
|
isSeeded: header.isSeeded,
|
|
@@ -330,12 +371,20 @@ function identityOf(header, inheritedEventCount) {
|
|
|
330
371
|
}
|
|
331
372
|
/**
|
|
332
373
|
* Whether a stored record's bound identity names the caller's lifecycle.
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
* a
|
|
374
|
+
* An absent format generation cannot prove the fold semantics and never
|
|
375
|
+
* matches. Once the format matches, absent lineage fields (records admitted
|
|
376
|
+
* via `compatibleVersions` predate them) read as the unseeded lineage: exact
|
|
377
|
+
* for an unseeded caller, while a seeded caller fails the match.
|
|
337
378
|
*/
|
|
338
379
|
function identityMatches(stored, expected) {
|
|
380
|
+
return stored.formatVersion === expected.formatVersion && lifecycleIdentityMatches(stored, expected);
|
|
381
|
+
}
|
|
382
|
+
/** Match one predecessor cache record to the authoritative listed lifecycle. */
|
|
383
|
+
function predecessorIdentityMatches(stored, expected) {
|
|
384
|
+
return (stored.formatVersion === void 0 || stored.formatVersion < expected.formatVersion) && lifecycleIdentityMatches(stored, expected);
|
|
385
|
+
}
|
|
386
|
+
/** Match the format-independent fields that distinguish one Session lifecycle. */
|
|
387
|
+
function lifecycleIdentityMatches(stored, expected) {
|
|
339
388
|
return stored.createdAt === expected.createdAt && stored.cwd === expected.cwd && (stored.isSeeded ?? false) === expected.isSeeded && (stored.inheritedEventCount ?? 0) === expected.inheritedEventCount;
|
|
340
389
|
}
|
|
341
390
|
//#endregion
|
package/lib/types/index.d.ts
CHANGED
|
@@ -88,6 +88,26 @@ export declare class SessionProjectionCache extends Service {
|
|
|
88
88
|
* `undefined` when no usable row exists for this lifecycle.
|
|
89
89
|
*/
|
|
90
90
|
cachedSnapshot(meta: SessionHeader, inheritedEventCount: SessionLogOffset, keys?: readonly Extract<keyof SessionProjectionMap, string>[]): ProjectionSnapshot | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Read only a predecessor checkpoint's title as a zero-I/O listing hint.
|
|
93
|
+
*
|
|
94
|
+
* The authoritative Session header supplies the lifecycle identity. A cache
|
|
95
|
+
* checkpoint can lag that log but cannot lead it because writes flush the
|
|
96
|
+
* log first, so a matching predecessor title is a genuine (possibly stale)
|
|
97
|
+
* fact from this Session. The registry still requires the current title
|
|
98
|
+
* projection's row version and schema. No other predecessor projection is
|
|
99
|
+
* exposed: format normalization can change their current meaning, and the
|
|
100
|
+
* strict {@link cachedSnapshot} / hydration paths continue to reject them.
|
|
101
|
+
* @param meta - authoritative listed Session header.
|
|
102
|
+
* @param inheritedEventCount - exact inherited cut completing the lifecycle identity.
|
|
103
|
+
* @returns a title-only checkpoint view with `asOfSeq: -1`, or `undefined`
|
|
104
|
+
* when the record is current, newer, unrelated, missing, or incompatible
|
|
105
|
+
* with the title unit. The sentinel avoids reusing a sequence that a
|
|
106
|
+
* cardinality-changing Session migration may have remapped.
|
|
107
|
+
*/
|
|
108
|
+
cachedPredecessorTitle(meta: SessionHeader, inheritedEventCount: SessionLogOffset): ProjectionSnapshot | undefined;
|
|
109
|
+
/** View selected wire rows and bind them to their lowest served watermark. */
|
|
110
|
+
private viewRecord;
|
|
91
111
|
/**
|
|
92
112
|
* Hydrate projection cells for an already-prepared Session without another
|
|
93
113
|
* persistence read. The cache seeds matching rows; the supplied exact log
|
package/lib/types/spec.d.ts
CHANGED
|
@@ -34,14 +34,15 @@ export declare const checkpointRow: z.ZodObject<{
|
|
|
34
34
|
* unrelated log. Reads validate this against the live header (listing) or
|
|
35
35
|
* the stored header (cold read) before accepting any record.
|
|
36
36
|
*
|
|
37
|
-
* The lineage fields are optional because records admitted through
|
|
38
|
-
* `compatibleVersions` predate them. The reader (`identityMatches`)
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
37
|
+
* The format and lineage fields are optional because records admitted through
|
|
38
|
+
* `compatibleVersions` predate them. The reader (`identityMatches`) refuses an
|
|
39
|
+
* absent format generation because no current Session log can prove that
|
|
40
|
+
* record's fold semantics. It interprets absent lineage as unseeded only after
|
|
41
|
+
* the format generation matches. Current-version writes always store all three
|
|
42
42
|
* fields.
|
|
43
43
|
*/
|
|
44
44
|
export declare const checkpointIdentity: z.ZodObject<{
|
|
45
|
+
formatVersion: z.ZodOptional<z.ZodNumber>;
|
|
45
46
|
createdAt: z.ZodNumber;
|
|
46
47
|
cwd: z.ZodOptional<z.ZodString>;
|
|
47
48
|
isSeeded: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -57,6 +58,7 @@ export type CheckpointIdentity = z.infer<typeof checkpointIdentity>;
|
|
|
57
58
|
*/
|
|
58
59
|
export declare const checkpointRecord: z.ZodObject<{
|
|
59
60
|
identity: z.ZodObject<{
|
|
61
|
+
formatVersion: z.ZodOptional<z.ZodNumber>;
|
|
60
62
|
createdAt: z.ZodNumber;
|
|
61
63
|
cwd: z.ZodOptional<z.ZodString>;
|
|
62
64
|
isSeeded: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -76,15 +78,18 @@ export type CheckpointRecord = z.infer<typeof checkpointRecord>;
|
|
|
76
78
|
* open (cache semantics — a stale or unreadable cache costs a longer tail
|
|
77
79
|
* replay, never a wrong value) while the rest of the domain stays usable,
|
|
78
80
|
* instead of rejecting the whole medium. The `compatibleVersions` entries
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* read-compat Agent Note
|
|
81
|
+
* keep structurally valid predecessor records available for a later current
|
|
82
|
+
* checkpoint rewrite. Records without `formatVersion` remain unusable as fold
|
|
83
|
+
* shortcuts because they cannot prove which Session event semantics produced
|
|
84
|
+
* their rows; the per-record version map and disposition live in the read-compat Agent Note
|
|
84
85
|
* (.agents/notes/implemented/architecture/2026-09-02-projcache-cross-version-read-compat.md).
|
|
85
86
|
* The per-row `ver` guard and the identity match still discard anything the
|
|
86
87
|
* current fold semantics cannot vouch for.
|
|
87
88
|
*
|
|
89
|
+
* A lifecycle-matching predecessor may still expose its version-compatible
|
|
90
|
+
* title through the cache service's listing-only hint; this never relaxes the
|
|
91
|
+
* format requirement for hydration or another fold shortcut.
|
|
92
|
+
*
|
|
88
93
|
* `invalidRecords: 'backup-and-skip'`: a stored record that fails the schema
|
|
89
94
|
* anyway is disposable derived data, so it must never cost the boot — the
|
|
90
95
|
* domain layer moves the document aside as `<key>.json.bak.<stamp>`, logs
|
|
@@ -101,6 +106,7 @@ export declare const projectionCacheDomainSpec: {
|
|
|
101
106
|
sessions: import("@deepseek-ai/dsh-storage-domain").DomainTableSpec<SessionId, {
|
|
102
107
|
identity: {
|
|
103
108
|
createdAt: number;
|
|
109
|
+
formatVersion?: number | undefined;
|
|
104
110
|
cwd?: string | undefined;
|
|
105
111
|
isSeeded?: boolean | undefined;
|
|
106
112
|
inheritedEventCount?: SessionLogOffset | undefined;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-session-projection-cache",
|
|
3
3
|
"description": "Persisted projection cache (ctx.sessionProjectionCache): durable per-session checkpoint records on the session_projcache storage domain (per-record layout), throttled write-behind, and the cached listing read",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -28,21 +28,21 @@
|
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@deepseek-ai/dsh-util-values": "^0.1.
|
|
31
|
+
"@deepseek-ai/dsh-util-values": "^0.1.3-alpha.2",
|
|
32
32
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
36
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
37
|
-
"@deepseek-ai/dsh-session
|
|
38
|
-
"@deepseek-ai/dsh-storage-domain": "^0.1.
|
|
36
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.3-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
38
|
+
"@deepseek-ai/dsh-storage-domain": "^0.1.3-alpha.2"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
42
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
43
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.
|
|
44
|
-
"@deepseek-ai/dsh-storage": "^0.1.
|
|
45
|
-
"@deepseek-ai/dsh-storage-
|
|
46
|
-
"@deepseek-ai/dsh-storage-
|
|
42
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.3-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-storage": "^0.1.3-alpha.2",
|
|
45
|
+
"@deepseek-ai/dsh-storage-domain": "^0.1.3-alpha.2",
|
|
46
|
+
"@deepseek-ai/dsh-storage-json": "^0.1.3-alpha.2"
|
|
47
47
|
}
|
|
48
48
|
}
|