dsh-session-guard 0.4.0 → 3.0.0

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/src/store.js CHANGED
@@ -1,77 +1,77 @@
1
- /**
2
- * dsh-session-guard — 每会话持久化状态存储(学 dsh-task-control 的独立存储模式,D4)。
3
- *
4
- * 暂停/锁定状态不写 session log(harness 持久化 reader 只认已知事件类型),
5
- * 改为插件自有 JSON 文件:`$DSH_HOME/.dsh/session-guard/<sessionId>.json`
6
- * (可用 DSH_SESSION_GUARD_STATE_DIR 覆盖根目录)。原子写:tmp + rename。
7
- */
8
- import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs'
9
- import { dirname, join } from 'node:path'
10
-
11
- /** 状态根目录。 */
12
- export function storeRoot() {
13
- return (
14
- process.env.DSH_SESSION_GUARD_STATE_DIR ||
15
- join(process.env.DSH_HOME || process.env.HOME || process.cwd(), '.dsh', 'session-guard')
16
- )
17
- }
18
-
19
- /** 会话 id → 安全文件名。 */
20
- function encodeSessionId(id) {
21
- return String(id).replace(/[^a-zA-Z0-9._-]/g, '_')
22
- }
23
-
24
- /** 每会话状态文件路径。 */
25
- export function stateFilePath(id) {
26
- return join(storeRoot(), `${encodeSessionId(id)}.json`)
27
- }
28
-
29
- /** 未锁定基线。 */
30
- export function idleState(id) {
31
- return { sessionId: String(id), queueLocked: false, lockReason: null, updatedAt: null }
32
- }
33
-
34
- /**
35
- * 创建存储(内存缓存 + 磁盘持久化)。
36
- */
37
- export function createStore() {
38
- const cache = new Map()
39
- return {
40
- /** 读一会话状态;无记录返回 null(调用方自行 fallback idleState)。 */
41
- get(id) {
42
- if (cache.has(id)) return cache.get(id)
43
- try {
44
- const f = stateFilePath(id)
45
- if (!existsSync(f)) return null
46
- const v = JSON.parse(readFileSync(f, 'utf8'))
47
- cache.set(id, v)
48
- return v
49
- } catch {
50
- return null
51
- }
52
- },
53
- /** 原子写。 */
54
- set(id, value) {
55
- cache.set(id, value)
56
- try {
57
- const f = stateFilePath(id)
58
- mkdirSync(dirname(f), { recursive: true })
59
- const tmp = `${f}.tmp`
60
- writeFileSync(tmp, JSON.stringify(value, null, 2))
61
- renameSync(tmp, f)
62
- } catch (e) {
63
- // 落盘失败仅影响重启恢复,内存态仍可用。
64
- console.error(`[session-guard] store write failed: ${String(e && e.message || e)}`)
65
- }
66
- },
67
- /** 清除(解锁时)。 */
68
- clear(id) {
69
- cache.delete(id)
70
- try {
71
- rmSync(stateFilePath(id), { force: true })
72
- } catch {
73
- /* ignore */
74
- }
75
- },
76
- }
77
- }
1
+ /**
2
+ * dsh-session-guard — 每会话持久化状态存储(学 dsh-task-control 的独立存储模式,D4)。
3
+ *
4
+ * 暂停/锁定状态不写 session log(harness 持久化 reader 只认已知事件类型),
5
+ * 改为插件自有 JSON 文件:`$DSH_HOME/.dsh/session-guard/<sessionId>.json`
6
+ * (可用 DSH_SESSION_GUARD_STATE_DIR 覆盖根目录)。原子写:tmp + rename。
7
+ */
8
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs'
9
+ import { dirname, join } from 'node:path'
10
+
11
+ /** 状态根目录。 */
12
+ export function storeRoot() {
13
+ return (
14
+ process.env.DSH_SESSION_GUARD_STATE_DIR ||
15
+ join(process.env.DSH_HOME || process.env.HOME || process.cwd(), '.dsh', 'session-guard')
16
+ )
17
+ }
18
+
19
+ /** 会话 id → 安全文件名。 */
20
+ function encodeSessionId(id) {
21
+ return String(id).replace(/[^a-zA-Z0-9._-]/g, '_')
22
+ }
23
+
24
+ /** 每会话状态文件路径。 */
25
+ export function stateFilePath(id) {
26
+ return join(storeRoot(), `${encodeSessionId(id)}.json`)
27
+ }
28
+
29
+ /** 未锁定基线。 */
30
+ export function idleState(id) {
31
+ return { sessionId: String(id), queueLocked: false, lockReason: null, updatedAt: null }
32
+ }
33
+
34
+ /**
35
+ * 创建存储(内存缓存 + 磁盘持久化)。
36
+ */
37
+ export function createStore() {
38
+ const cache = new Map()
39
+ return {
40
+ /** 读一会话状态;无记录返回 null(调用方自行 fallback idleState)。 */
41
+ get(id) {
42
+ if (cache.has(id)) return cache.get(id)
43
+ try {
44
+ const f = stateFilePath(id)
45
+ if (!existsSync(f)) return null
46
+ const v = JSON.parse(readFileSync(f, 'utf8'))
47
+ cache.set(id, v)
48
+ return v
49
+ } catch {
50
+ return null
51
+ }
52
+ },
53
+ /** 原子写。 */
54
+ set(id, value) {
55
+ cache.set(id, value)
56
+ try {
57
+ const f = stateFilePath(id)
58
+ mkdirSync(dirname(f), { recursive: true })
59
+ const tmp = `${f}.tmp`
60
+ writeFileSync(tmp, JSON.stringify(value, null, 2))
61
+ renameSync(tmp, f)
62
+ } catch (e) {
63
+ // 落盘失败仅影响重启恢复,内存态仍可用。
64
+ console.error(`[session-guard] store write failed: ${String(e && e.message || e)}`)
65
+ }
66
+ },
67
+ /** 清除(解锁时)。 */
68
+ clear(id) {
69
+ cache.delete(id)
70
+ try {
71
+ rmSync(stateFilePath(id), { force: true })
72
+ } catch {
73
+ /* ignore */
74
+ }
75
+ },
76
+ }
77
+ }