@goodandready/dsh-key-rotation 0.8.22 → 0.8.23
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/CHANGELOG.md +8 -0
- package/lib/config-compat.js +28 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to `@goodandready/dsh-key-rotation` are documented here.
|
|
4
4
|
User-facing feature notes also appear in README (en is source of truth).
|
|
5
5
|
|
|
6
|
+
## 0.8.23 - 2026-09-23
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- **Fix settings cache invalidation on Cordis traceable Proxies (#350)**:
|
|
10
|
+
- Removed `settings !== owner` reference equality check in `createProviderProfilesReader` (`lib/config-compat.js`). In Cordis, `ctx.get('settings')` creates and returns a fresh traceable `Proxy` wrapper on every single invocation, which was constantly triggering `dirty = true` and invalidating the cache per-request.
|
|
11
|
+
- Subscribed to `internal/service` event (for service name `'settings'`) alongside `settings/document-updated` to safely invalidate cache upon service replacement without comparing proxy identities.
|
|
12
|
+
- Added regression test suite verifying that when `ctx.get('settings')` returns a new `Proxy` instance on every call, 100 subsequent invocations of `buildRuntime()` or `readProfiles()` execute strictly 1 call to `settings.get()`.
|
|
13
|
+
|
|
6
14
|
## 0.8.22 - 2026-09-23
|
|
7
15
|
|
|
8
16
|
### Performance
|
package/lib/config-compat.js
CHANGED
|
@@ -45,36 +45,45 @@ export function createConfigReader(config, ctx) {
|
|
|
45
45
|
// Modern settings owns descriptors rather than the removed get(namespace) API.
|
|
46
46
|
// Cache by document invalidation; clone-producing describe() and tree-materializing
|
|
47
47
|
// settings.get() on 0.1.7+ must not execute on every request.
|
|
48
|
+
// Invalidation occurs strictly on settings/document-updated or internal/service ('settings').
|
|
49
|
+
// Never compare ctx.get('settings') by reference: Cordis wraps services in fresh
|
|
50
|
+
// traceable Proxies on every get() call, which would invalidate the cache on every request.
|
|
48
51
|
export function createProviderProfilesReader(ctx, namespace) {
|
|
49
|
-
let dirty = true, held = null
|
|
52
|
+
let dirty = true, held = null;
|
|
50
53
|
const markDirty = () => { dirty = true; };
|
|
51
54
|
if (typeof ctx?.effect === 'function') {
|
|
52
55
|
ctx.effect(() => ctx.on('settings/document-updated', markDirty));
|
|
56
|
+
ctx.effect(() => ctx.on('internal/service', (name) => {
|
|
57
|
+
if (!name || name === 'settings') markDirty();
|
|
58
|
+
}));
|
|
53
59
|
} else if (typeof ctx?.on === 'function') {
|
|
54
60
|
ctx.on('settings/document-updated', markDirty);
|
|
61
|
+
ctx.on('internal/service', (name) => {
|
|
62
|
+
if (!name || name === 'settings') markDirty();
|
|
63
|
+
});
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
return () => {
|
|
67
|
+
if (!dirty) {
|
|
68
|
+
return held;
|
|
69
|
+
}
|
|
58
70
|
const settings = ctx?.get?.('settings');
|
|
59
|
-
if (settings !== owner) { owner = settings; dirty = true; }
|
|
60
71
|
if (!settings) return null;
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
dirty = false;
|
|
77
|
-
}
|
|
72
|
+
if (typeof settings.get === 'function') {
|
|
73
|
+
try {
|
|
74
|
+
held = settings.get(namespace)?.providers ?? null;
|
|
75
|
+
dirty = false;
|
|
76
|
+
} catch (_) {
|
|
77
|
+
held = null;
|
|
78
|
+
dirty = false;
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
try {
|
|
82
|
+
held = settings.describe({ redactSecrets: true }).find(row => row.ns === namespace)?.value?.providers ?? null;
|
|
83
|
+
dirty = false;
|
|
84
|
+
} catch (_) {
|
|
85
|
+
held = null;
|
|
86
|
+
dirty = false;
|
|
78
87
|
}
|
|
79
88
|
}
|
|
80
89
|
return held;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-key-rotation",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.23",
|
|
4
4
|
"packageManager": "pnpm@10.33.2",
|
|
5
5
|
"description": "Per-provider API key rotation for DeepSeek Harness: a key pool per provider, auto-created clone routes, and switching to the next key on quota/rate-limit errors. Includes a Settings section (Key Rotation) to edit the key pools, cooldown and switch codes.",
|
|
6
6
|
"keywords": [
|