dsh-config-manager 0.1.72 → 0.1.76
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.md +40 -4
- package/README.zh-CN.md +40 -4
- package/lib/adapters/index.d.ts +1 -0
- package/lib/adapters/index.js +5 -0
- package/lib/adapters/messages.d.ts +3 -0
- package/lib/adapters/messages.js +7 -0
- package/lib/adapters/plugin-data.d.ts +114 -0
- package/lib/adapters/plugin-data.js +309 -0
- package/lib/adapters/self.d.ts +1 -1
- package/lib/adapters/self.js +2 -1
- package/lib/adapters/test-helpers.d.ts +9 -0
- package/lib/adapters/test-helpers.js +14 -0
- package/lib/client.d.ts +103 -10
- package/lib/client.js +10748 -10119
- package/lib/core/analyzer.d.ts +11 -2
- package/lib/core/analyzer.js +31 -8
- package/lib/core/backup-plan.d.ts +10 -0
- package/lib/core/backup-plan.js +21 -3
- package/lib/core/backup.d.ts +20 -1
- package/lib/core/backup.js +48 -3
- package/lib/core/command-rollback.d.ts +6 -2
- package/lib/core/command-rollback.js +6 -2
- package/lib/core/messages-core.d.ts +2 -0
- package/lib/core/messages-core.js +4 -0
- package/lib/core/messages.d.ts +2 -1
- package/lib/core/messages.js +4 -2
- package/lib/core/plugin-data-registry.d.ts +124 -0
- package/lib/core/plugin-data-registry.js +198 -0
- package/lib/core/rollback-gate.d.ts +33 -0
- package/lib/core/rollback-gate.js +57 -0
- package/lib/core/rollback-ledger.d.ts +274 -0
- package/lib/core/rollback-ledger.js +1400 -0
- package/lib/core/rollback-point.d.ts +406 -5
- package/lib/core/rollback-point.js +1453 -306
- package/lib/core/rollback.js +6 -4
- package/lib/core/types.d.ts +19 -0
- package/lib/foreign/registry.d.ts +1 -1
- package/lib/foreign/registry.js +1 -1
- package/lib/index.d.ts +5 -1
- package/lib/index.js +83 -13
- package/lib/routes/messages.d.ts +1 -0
- package/lib/routes/messages.js +2 -0
- package/lib/routes/prefs.js +26 -3
- package/lib/routes/recovery.d.ts +21 -0
- package/lib/routes/recovery.js +127 -7
- package/lib/routes/sync.js +11 -1
- package/lib/schema/section-registry.d.ts +1 -1
- package/lib/schema/section-registry.js +32 -3
- package/lib/schema/types.d.ts +1 -1
- package/lib/sync/messages.d.ts +1 -0
- package/lib/sync/messages.js +3 -0
- package/lib/sync/sync-engine.d.ts +21 -7
- package/lib/sync/sync-engine.js +108 -18
- package/lib/sync/ui-prefs.d.ts +22 -0
- package/lib/sync/ui-prefs.js +28 -0
- package/lib/ui/diff-view.d.ts +10 -0
- package/lib/ui/diff-view.js +17 -0
- package/lib/ui/export-flow.js +2 -0
- package/lib/ui/i18n.d.ts +5 -3
- package/lib/ui/i18n.js +10 -6
- package/lib/ui/rollback-view.d.ts +59 -0
- package/lib/ui/rollback-view.js +14 -0
- package/lib/ui/test-helpers.js +2 -1
- package/lib/utils/bundle-scan.d.ts +5 -3
- package/lib/utils/bundle-scan.js +5 -3
- package/lib/utils/line-diff.d.ts +7 -1
- package/lib/utils/line-diff.js +8 -2
- package/package.json +1 -1
- package/src/adapters/index.ts +5 -0
- package/src/adapters/messages.ts +7 -0
- package/src/adapters/plugin-data.test.ts +225 -0
- package/src/adapters/plugin-data.ts +351 -0
- package/src/adapters/self.ts +2 -1
- package/src/adapters/test-helpers.ts +15 -0
- package/src/client/chat/ChatEntryView.tsx +59 -10
- package/src/client/chat/RollbackDiffTab.tsx +49 -2
- package/src/client/chat/RollbackFileIcon.tsx +7 -45
- package/src/client/chat/RollbackReviewDialog.tsx +20 -4
- package/src/client/chat/chat-entry-view.test.ts +164 -1
- package/src/client/chat/chat-entry-view.ts +127 -10
- package/src/client/chat/chat-node-registration.ts +40 -6
- package/src/client/chat/chat-point-window.ts +11 -1
- package/src/client/chat/rollback-diff-tab.ts +13 -3
- package/src/client/chat/rollback-entry-view.ts +5 -0
- package/src/client/chat/sidebar-slots.ts +24 -2
- package/src/client/common/DiffTable.tsx +54 -29
- package/src/client/common/client-route-parity.test.ts +6 -0
- package/src/client/common/host-primitives.ts +78 -0
- package/src/client/common/routes.ts +10 -0
- package/src/client/common/section-labels.test.ts +1 -0
- package/src/client/common/section-labels.ts +2 -0
- package/src/client/config-manager.module.css +138 -14
- package/src/client/environment/maintenance/DiskUsageCard.tsx +20 -3
- package/src/client/index.ts +54 -2
- package/src/client/library/RestorePlanView.tsx +0 -1
- package/src/client/locales.ts +8 -6
- package/src/client/recovery/RollbackCard.tsx +201 -7
- package/src/client/recovery/RollbackDiffPane.tsx +26 -8
- package/src/client/recovery/recovery-api.ts +28 -0
- package/src/client/recovery/recovery-locales.ts +36 -6
- package/src/client/recovery/rollback-enabled.ts +41 -0
- package/src/client/recovery/rollback-file-changes.test.ts +77 -0
- package/src/client/sync/PushPreviewCard.tsx +57 -0
- package/src/client/sync/SyncPanel.tsx +2 -37
- package/src/client/sync/SyncSettingsView.test.ts +3 -0
- package/src/client/sync/sync-push-preview.test.ts +14 -0
- package/src/client/sync/sync-view.test.ts +1 -1
- package/src/client/sync/sync-view.ts +9 -1
- package/src/core/analyzer.ts +31 -9
- package/src/core/backup-plan.test.ts +20 -5
- package/src/core/backup-plan.ts +22 -3
- package/src/core/backup.ts +50 -4
- package/src/core/command-rollback.ts +6 -2
- package/src/core/messages-core.ts +4 -0
- package/src/core/messages.ts +4 -2
- package/src/core/plugin-data-registry.test.ts +113 -0
- package/src/core/plugin-data-registry.ts +261 -0
- package/src/core/rollback-gate.test.ts +66 -0
- package/src/core/rollback-gate.ts +61 -0
- package/src/core/rollback-ledger.test.ts +655 -0
- package/src/core/rollback-ledger.ts +1430 -0
- package/src/core/rollback-point.test.ts +866 -41
- package/src/core/rollback-point.ts +1582 -291
- package/src/core/rollback.ts +5 -3
- package/src/core/types.ts +19 -0
- package/src/foreign/registry.test.ts +1 -1
- package/src/foreign/registry.ts +1 -1
- package/src/index.ts +73 -10
- package/src/routes/messages.ts +2 -0
- package/src/routes/prefs.ts +31 -2
- package/src/routes/recovery.ts +122 -7
- package/src/routes/sync.ts +15 -1
- package/src/schema/manifest-schema.test.ts +4 -4
- package/src/schema/registry.test.ts +9 -2
- package/src/schema/section-registry.ts +32 -3
- package/src/schema/types.ts +2 -1
- package/src/sync/messages.ts +3 -0
- package/src/sync/sync-credentials.test.ts +119 -0
- package/src/sync/sync-engine.ts +106 -18
- package/src/sync/sync-preview-push.test.ts +158 -0
- package/src/sync/transport.test.ts +1 -0
- package/src/sync/ui-prefs.test.ts +44 -1
- package/src/sync/ui-prefs.ts +39 -0
- package/src/ui/diff-view.test.ts +9 -1
- package/src/ui/diff-view.ts +22 -0
- package/src/ui/export-flow.ts +2 -0
- package/src/ui/i18n.ts +10 -6
- package/src/ui/rollback-view.test.ts +17 -0
- package/src/ui/rollback-view.ts +66 -0
- package/src/ui/test-helpers.ts +2 -1
- package/src/utils/bundle-scan.ts +5 -3
- package/src/utils/line-diff.test.ts +12 -0
- package/src/utils/line-diff.ts +9 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 回合自动留点开关的**进程内**语义(issue #88 / #89,src/core/rollback-gate.ts)。
|
|
3
|
+
*
|
|
4
|
+
* 钉住四条:① 缺省关闭;② 变化才通知(同值不通知,避免写偏好时抖动 attach/detach);
|
|
5
|
+
* ③ 监听器抛错不影响开关本身与其它监听器;④ 解绑幂等。
|
|
6
|
+
*
|
|
7
|
+
* 为什么值得单测:宿主那条 `session/event` 订阅链的 attach/detach 完全由这里驱动 ——
|
|
8
|
+
* 一旦「关了还通知」或「通知丢了」,就是「界面说关了、宿主还在每回合写台账」这类静默故障。
|
|
9
|
+
*/
|
|
10
|
+
import test from 'node:test'
|
|
11
|
+
import assert from 'node:assert/strict'
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
isRollbackEnabled,
|
|
15
|
+
onRollbackEnabledChange,
|
|
16
|
+
resetRollbackGateForTest,
|
|
17
|
+
setRollbackEnabled,
|
|
18
|
+
} from './rollback-gate.ts'
|
|
19
|
+
|
|
20
|
+
test('G-01 缺省关闭 + 置真置假都生效', () => {
|
|
21
|
+
resetRollbackGateForTest()
|
|
22
|
+
assert.equal(isRollbackEnabled(), false, '缺省必须是关闭(fail-closed)')
|
|
23
|
+
setRollbackEnabled(true)
|
|
24
|
+
assert.equal(isRollbackEnabled(), true)
|
|
25
|
+
setRollbackEnabled(false)
|
|
26
|
+
assert.equal(isRollbackEnabled(), false)
|
|
27
|
+
resetRollbackGateForTest()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('G-02 同值不通知;变化按顺序通知一次', () => {
|
|
31
|
+
resetRollbackGateForTest()
|
|
32
|
+
const seen: boolean[] = []
|
|
33
|
+
const off = onRollbackEnabledChange((value) => { seen.push(value) })
|
|
34
|
+
setRollbackEnabled(false) // 与缺省同值 → 不通知
|
|
35
|
+
assert.deepEqual(seen, [], '同值不得通知')
|
|
36
|
+
setRollbackEnabled(true)
|
|
37
|
+
setRollbackEnabled(true) // 重复同值
|
|
38
|
+
setRollbackEnabled(false)
|
|
39
|
+
assert.deepEqual(seen, [true, false], '只在真实变化时通知一次')
|
|
40
|
+
off()
|
|
41
|
+
resetRollbackGateForTest()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('G-03 监听器抛错不影响开关与其它监听器', () => {
|
|
45
|
+
resetRollbackGateForTest()
|
|
46
|
+
const seen: boolean[] = []
|
|
47
|
+
const offBad = onRollbackEnabledChange(() => { throw new Error('boom') })
|
|
48
|
+
const offGood = onRollbackEnabledChange((value) => { seen.push(value) })
|
|
49
|
+
setRollbackEnabled(true)
|
|
50
|
+
assert.equal(isRollbackEnabled(), true, '坏监听器不得拦住状态切换')
|
|
51
|
+
assert.deepEqual(seen, [true], '坏监听器不得吃掉后面监听器的通知')
|
|
52
|
+
offBad()
|
|
53
|
+
offGood()
|
|
54
|
+
resetRollbackGateForTest()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('G-04 解绑幂等:解绑后再改状态不通知已解绑者', () => {
|
|
58
|
+
resetRollbackGateForTest()
|
|
59
|
+
const seen: boolean[] = []
|
|
60
|
+
const off = onRollbackEnabledChange((value) => { seen.push(value) })
|
|
61
|
+
off()
|
|
62
|
+
off() // 幂等
|
|
63
|
+
setRollbackEnabled(true)
|
|
64
|
+
assert.deepEqual(seen, [])
|
|
65
|
+
resetRollbackGateForTest()
|
|
66
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 回合自动留点(回滚点)的**进程内开关**。
|
|
3
|
+
*
|
|
4
|
+
* 为什么需要它(issue #88 / #89):
|
|
5
|
+
* · #88:回滚点与插件主旨(配置备份 / 同步)无关,却随 bundle 默认启用、没有任何关闭入口;
|
|
6
|
+
* · #89:默认启用时,每个 `turn/start` 都要留点,而台账写入是「整份读改写」——
|
|
7
|
+
* 真机 `index.json` 涨到 451 MiB 后宿主反复 V8 heap OOM(exit 134)。
|
|
8
|
+
*
|
|
9
|
+
* 设计(三条,别简化):
|
|
10
|
+
* 1. **缺省关闭**:`readRollbackEnabledSync()` 读不到 / 形状不符一律 false —— fail-closed,
|
|
11
|
+
* 绝不因为「文件没写成功」就把功能打开。
|
|
12
|
+
* 2. **不订阅 = 真的不订阅**:宿主订阅 `session/event` 的那条链由这里驱动 attach / detach。
|
|
13
|
+
* 关闭时**必须解绑**,而不是「订阅了但回调里 return」(后者仍然吃事件分发路径)。
|
|
14
|
+
* 3. **活切换**:开关可以在不重载插件的前提下改变 —— 写偏好的一方调 `setRollbackEnabled`,
|
|
15
|
+
* 订阅方通过 `onRollbackEnabledChange` 收到通知。事件回调**不读文件**(每回合读一次磁盘
|
|
16
|
+
* 正是本 issue 要消灭的开销形态)。
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
let enabled = false
|
|
20
|
+
|
|
21
|
+
type RollbackEnabledListener = (enabled: boolean) => void
|
|
22
|
+
const listeners = new Set<RollbackEnabledListener>()
|
|
23
|
+
|
|
24
|
+
/** 当前是否启用(同步、零 I/O —— 事件回调用它做第一道门)。 */
|
|
25
|
+
export function isRollbackEnabled(): boolean {
|
|
26
|
+
return enabled
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 设置开关并通知订阅方。值未变化时**不通知**(避免每次保存偏好都触发一次 attach/detach 抖动)。
|
|
31
|
+
* 监听器里的异常一律吞掉:一个监听器写坏了不能影响开关本身,更不能影响宿主启动。
|
|
32
|
+
*/
|
|
33
|
+
export function setRollbackEnabled(value: boolean): void {
|
|
34
|
+
const next = value === true
|
|
35
|
+
if (next === enabled) return
|
|
36
|
+
enabled = next
|
|
37
|
+
for (const listener of [...listeners]) {
|
|
38
|
+
try {
|
|
39
|
+
listener(next)
|
|
40
|
+
} catch {
|
|
41
|
+
/* 监听器自己的问题;开关状态已生效 */
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** 注册开关变化监听;返回解绑函数(解绑幂等)。 */
|
|
47
|
+
export function onRollbackEnabledChange(listener: RollbackEnabledListener): () => void {
|
|
48
|
+
listeners.add(listener)
|
|
49
|
+
return () => {
|
|
50
|
+
listeners.delete(listener)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 测试专用:把开关与监听器一并复位。
|
|
56
|
+
* 生产路径**绝不**调用它 —— 重置监听器会让宿主那条订阅链永远收不到后续切换。
|
|
57
|
+
*/
|
|
58
|
+
export function resetRollbackGateForTest(): void {
|
|
59
|
+
enabled = false
|
|
60
|
+
listeners.clear()
|
|
61
|
+
}
|