conftree 0.3.0 → 0.3.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.md +16 -0
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +1 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/engine/category-integrity.d.ts +3 -0
- package/dist/engine/category-integrity.d.ts.map +1 -0
- package/dist/engine/category-integrity.js +28 -0
- package/dist/engine/category-integrity.js.map +1 -0
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/engine.js +2 -1
- package/dist/engine/engine.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +81 -15
- package/dist/index.mjs.map +1 -1
- package/dist/typed/category-guard.d.ts +2 -0
- package/dist/typed/category-guard.d.ts.map +1 -1
- package/dist/typed/category-guard.js +18 -0
- package/dist/typed/category-guard.js.map +1 -1
- package/dist/typed/registry.d.ts +6 -0
- package/dist/typed/registry.d.ts.map +1 -1
- package/dist/typed/typed-auditor.d.ts +4 -4
- package/dist/typed/typed-auditor.d.ts.map +1 -1
- package/dist/typed/typed-auditor.js +2 -2
- package/dist/typed/typed-auditor.js.map +1 -1
- package/dist/typed/typed-engine.d.ts +5 -5
- package/dist/typed/typed-engine.d.ts.map +1 -1
- package/dist/typed/typed-engine.js.map +1 -1
- package/dist/typed/typed-resolver.d.ts +8 -8
- package/dist/typed/typed-resolver.d.ts.map +1 -1
- package/dist/typed/typed-resolver.js +11 -5
- package/dist/typed/typed-resolver.js.map +1 -1
- package/dist/typed/typed-writer.d.ts +13 -12
- package/dist/typed/typed-writer.d.ts.map +1 -1
- package/dist/typed/typed-writer.js +14 -6
- package/dist/typed/typed-writer.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -165,8 +165,24 @@ await chama.resolver.listAt({ kind: 'group', refId: 'g1' });
|
|
|
165
165
|
|
|
166
166
|
A key with no `category` in the registry (like `ui.theme` above) simply never shows up in any `category(...)` view.
|
|
167
167
|
|
|
168
|
+
Since a key must stay globally unique across every category, real key names tend to be prefixed with their category (`'chama.currency'`) — which becomes pure repetition once you're already inside `category('chama')`. So `get`/`set`/`unset`/`history` on a `category(...)` accessor also accept the key with that `${category}.` prefix stripped:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
await chama.writer.set({
|
|
172
|
+
key: 'currency', // same as 'chama.currency'
|
|
173
|
+
scope: { kind: 'group', refId: 'g1' },
|
|
174
|
+
value: 'KES',
|
|
175
|
+
authorId: 'admin',
|
|
176
|
+
});
|
|
177
|
+
await chama.resolver.get('currency', { kind: 'group', refId: 'g1' }); // 'KES'
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The full key (`'chama.currency'`) still works exactly as before on the same accessor — both forms address the same setting. If a given string happens to already be a real, existing key (regardless of category), it's treated as a full key as-is rather than guessed at; only when it doesn't match anything is it prefixed and treated as short. `getMany`'s result is keyed however you called it (short or full, per key).
|
|
181
|
+
|
|
168
182
|
`get`/`set`/`unset`/`history` on a `category(...)` accessor are narrowed at compile time — but if a caller bypasses that with `as any`, a runtime check still catches it and throws `CategoryError` (code `'CATEGORY'`) rather than silently touching a setting from another category.
|
|
169
183
|
|
|
184
|
+
`createEngine()` also guards `storage.createDef()` itself: if two unrelated features accidentally pick the same `key` string with different `category` values, the second `createDef()` call throws `CategoryError` instead of silently redefining the existing setting under the new category. Redefining a key with the _same_ category (a normal evolution of a setting) still works exactly as before. This guard is applied automatically to whatever `StorageAdapter` you pass in, not just `MemoryStorageAdapter`.
|
|
185
|
+
|
|
170
186
|
### Writing an adapter
|
|
171
187
|
|
|
172
188
|
Implement `StorageAdapter`, `ScopeHierarchy`, or `ChangeBus`, all defined in `src/storage/storage-port.ts`, `src/core/types.ts`, and `src/cache/change-bus.ts`. `MemoryStorageAdapter` and `LocalScopeHierarchy` are the reference implementations.
|
package/dist/core/errors.d.ts
CHANGED
|
@@ -25,6 +25,6 @@ export declare class CycleError extends ConfTreeError {
|
|
|
25
25
|
constructor(id: string, newParentId: string);
|
|
26
26
|
}
|
|
27
27
|
export declare class CategoryError extends ConfTreeError {
|
|
28
|
-
constructor(key: string, expectedCategory: string, actualCategory: string | null);
|
|
28
|
+
constructor(key: string, expectedCategory: string | null, actualCategory: string | null);
|
|
29
29
|
}
|
|
30
30
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAClB,WAAW,GACX,OAAO,GACP,UAAU,GACV,OAAO,GACP,UAAU,GACV,SAAS,GACT,OAAO,GACP,UAAU,CAAC;AAEd,qBAAa,aAAc,SAAQ,KAAK;aAGtB,IAAI,EAAE,SAAS;gBAD/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,SAAS;CAMhC;AAED,qBAAa,aAAc,SAAQ,aAAa;gBACnC,GAAG,EAAE,MAAM;CAGvB;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAChC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM1C;AAED,qBAAa,aAAc,SAAQ,aAAa;gBACnC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAOrE;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAChC,OAAO,EAAE,MAAM;CAG3B;AAED,qBAAa,aAAc,SAAQ,aAAa;gBACnC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAOrE;AAED,qBAAa,YAAa,SAAQ,aAAa;gBAClC,OAAO,EAAE,MAAM;CAM3B;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAChC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAM3C;AAED,qBAAa,aAAc,SAAQ,aAAa;gBAE9C,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAClB,WAAW,GACX,OAAO,GACP,UAAU,GACV,OAAO,GACP,UAAU,GACV,SAAS,GACT,OAAO,GACP,UAAU,CAAC;AAEd,qBAAa,aAAc,SAAQ,KAAK;aAGtB,IAAI,EAAE,SAAS;gBAD/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,SAAS;CAMhC;AAED,qBAAa,aAAc,SAAQ,aAAa;gBACnC,GAAG,EAAE,MAAM;CAGvB;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAChC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM1C;AAED,qBAAa,aAAc,SAAQ,aAAa;gBACnC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAOrE;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAChC,OAAO,EAAE,MAAM;CAG3B;AAED,qBAAa,aAAc,SAAQ,aAAa;gBACnC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAOrE;AAED,qBAAa,YAAa,SAAQ,aAAa;gBAClC,OAAO,EAAE,MAAM;CAM3B;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAChC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAM3C;AAED,qBAAa,aAAc,SAAQ,aAAa;gBAE9C,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,EAAE,MAAM,GAAG,IAAI;CAO9B"}
|
package/dist/core/errors.js
CHANGED
|
@@ -57,7 +57,7 @@ class CycleError extends ConfTreeError {
|
|
|
57
57
|
exports.CycleError = CycleError;
|
|
58
58
|
class CategoryError extends ConfTreeError {
|
|
59
59
|
constructor(key, expectedCategory, actualCategory) {
|
|
60
|
-
super(`Setting "${key}"
|
|
60
|
+
super(`Setting "${key}" has category "${actualCategory ?? 'none'}", which does not match "${expectedCategory ?? 'none'}"`, 'CATEGORY');
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
exports.CategoryError = CategoryError;
|
package/dist/core/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":";;;AAUA,MAAa,aAAc,SAAQ,KAAK;IAGtB;IAFjB,YACC,OAAe,EACC,IAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAW;QAG/B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,KAAK,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;CACD;AATD,sCASC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YAAY,GAAW;QACtB,KAAK,CAAC,gCAAgC,GAAG,GAAG,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;CACD;AAJD,sCAIC;AAED,MAAa,UAAW,SAAQ,aAAa;IAC5C,YAAY,GAAW,EAAE,SAAiB;QACzC,KAAK,CACJ,YAAY,GAAG,0CAA0C,SAAS,GAAG,EACrE,OAAO,CACP,CAAC;IACH,CAAC;CACD;AAPD,gCAOC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YAAY,GAAW,EAAE,SAAiB,EAAE,UAAyB;QACpE,KAAK,CACJ,qBAAqB,GAAG,uCAAuC,SAAS,IAAI,UAAU,IAAI,MAAM,GAAG;YAClG,2BAA2B,EAC5B,UAAU,CACV,CAAC;IACH,CAAC;CACD;AARD,sCAQC;AAED,MAAa,UAAW,SAAQ,aAAa;IAC5C,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;CACD;AAJD,gCAIC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YAAY,GAAW,EAAE,SAAiB,EAAE,UAAyB;QACpE,KAAK,CACJ,YAAY,GAAG,cAAc,SAAS,IAAI,UAAU,IAAI,MAAM,8BAA8B;YAC3F,qCAAqC,EACtC,UAAU,CACV,CAAC;IACH,CAAC;CACD;AARD,sCAQC;AAED,MAAa,YAAa,SAAQ,aAAa;IAC9C,YAAY,OAAe;QAC1B,KAAK,CACJ,qBAAqB,OAAO,0CAA0C,EACtE,SAAS,CACT,CAAC;IACH,CAAC;CACD;AAPD,oCAOC;AAED,MAAa,UAAW,SAAQ,aAAa;IAC5C,YAAY,EAAU,EAAE,WAAmB;QAC1C,KAAK,CACJ,6BAA6B,EAAE,YAAY,WAAW,yBAAyB,EAC/E,OAAO,CACP,CAAC;IACH,CAAC;CACD;AAPD,gCAOC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YACC,GAAW,EACX,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":";;;AAUA,MAAa,aAAc,SAAQ,KAAK;IAGtB;IAFjB,YACC,OAAe,EACC,IAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAW;QAG/B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,KAAK,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;CACD;AATD,sCASC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YAAY,GAAW;QACtB,KAAK,CAAC,gCAAgC,GAAG,GAAG,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;CACD;AAJD,sCAIC;AAED,MAAa,UAAW,SAAQ,aAAa;IAC5C,YAAY,GAAW,EAAE,SAAiB;QACzC,KAAK,CACJ,YAAY,GAAG,0CAA0C,SAAS,GAAG,EACrE,OAAO,CACP,CAAC;IACH,CAAC;CACD;AAPD,gCAOC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YAAY,GAAW,EAAE,SAAiB,EAAE,UAAyB;QACpE,KAAK,CACJ,qBAAqB,GAAG,uCAAuC,SAAS,IAAI,UAAU,IAAI,MAAM,GAAG;YAClG,2BAA2B,EAC5B,UAAU,CACV,CAAC;IACH,CAAC;CACD;AARD,sCAQC;AAED,MAAa,UAAW,SAAQ,aAAa;IAC5C,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;CACD;AAJD,gCAIC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YAAY,GAAW,EAAE,SAAiB,EAAE,UAAyB;QACpE,KAAK,CACJ,YAAY,GAAG,cAAc,SAAS,IAAI,UAAU,IAAI,MAAM,8BAA8B;YAC3F,qCAAqC,EACtC,UAAU,CACV,CAAC;IACH,CAAC;CACD;AARD,sCAQC;AAED,MAAa,YAAa,SAAQ,aAAa;IAC9C,YAAY,OAAe;QAC1B,KAAK,CACJ,qBAAqB,OAAO,0CAA0C,EACtE,SAAS,CACT,CAAC;IACH,CAAC;CACD;AAPD,oCAOC;AAED,MAAa,UAAW,SAAQ,aAAa;IAC5C,YAAY,EAAU,EAAE,WAAmB;QAC1C,KAAK,CACJ,6BAA6B,EAAE,YAAY,WAAW,yBAAyB,EAC/E,OAAO,CACP,CAAC;IACH,CAAC;CACD;AAPD,gCAOC;AAED,MAAa,aAAc,SAAQ,aAAa;IAC/C,YACC,GAAW,EACX,gBAA+B,EAC/B,cAA6B;QAE7B,KAAK,CACJ,YAAY,GAAG,mBAAmB,cAAc,IAAI,MAAM,4BAA4B,gBAAgB,IAAI,MAAM,GAAG,EACnH,UAAU,CACV,CAAC;IACH,CAAC;CACD;AAXD,sCAWC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category-integrity.d.ts","sourceRoot":"","sources":["../../src/engine/category-integrity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CA0B7E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withCategoryIntegrity = withCategoryIntegrity;
|
|
4
|
+
const errors_1 = require("../core/errors");
|
|
5
|
+
function withCategoryIntegrity(storage) {
|
|
6
|
+
return {
|
|
7
|
+
findDefs: (keys) => storage.findDefs(keys),
|
|
8
|
+
findDefsByIds: (ids) => storage.findDefsByIds(ids),
|
|
9
|
+
findAnyDef: (key) => storage.findAnyDef(key),
|
|
10
|
+
findValues: (query) => storage.findValues(query),
|
|
11
|
+
findChainValues: (query) => storage.findChainValues(query),
|
|
12
|
+
findAudit: (query) => storage.findAudit(query),
|
|
13
|
+
listValues: (query) => storage.listValues(query),
|
|
14
|
+
listDefs: (status, category) => storage.listDefs(status, category),
|
|
15
|
+
listCategories: () => storage.listCategories(),
|
|
16
|
+
updateDefStatus: (key, status) => storage.updateDefStatus(key, status),
|
|
17
|
+
transact: (fn) => storage.transact(fn),
|
|
18
|
+
createDef: async (input) => {
|
|
19
|
+
const existing = await storage.findAnyDef(input.key);
|
|
20
|
+
const newCategory = input.category ?? null;
|
|
21
|
+
if (existing && existing.category !== newCategory) {
|
|
22
|
+
throw new errors_1.CategoryError(input.key, existing.category, newCategory);
|
|
23
|
+
}
|
|
24
|
+
return storage.createDef(input);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=category-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category-integrity.js","sourceRoot":"","sources":["../../src/engine/category-integrity.ts"],"names":[],"mappings":";;AAGA,sDA0BC;AA7BD,2CAA+C;AAG/C,SAAgB,qBAAqB,CAAC,OAAuB;IAC5D,OAAO;QACN,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC1C,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC;QAClD,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAC5C,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;QAChD,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC;QAC1D,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;QAC9C,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;QAChD,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;QAClE,cAAc,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE;QAC9C,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC;QACtE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YAC1B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACrD,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC3C,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACnD,MAAM,IAAI,sBAAa,CACtB,KAAK,CAAC,GAAG,EACT,QAAQ,CAAC,QAAQ,EACjB,WAAW,CACX,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAIvC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC;CAC7B;AAED,MAAM,WAAW,MAAM;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,cAAc,CAAC;IAC1B,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAchE"}
|
package/dist/engine/engine.js
CHANGED
|
@@ -4,13 +4,14 @@ exports.createEngine = createEngine;
|
|
|
4
4
|
const change_bus_1 = require("../cache/change-bus");
|
|
5
5
|
const cache_1 = require("../cache/cache");
|
|
6
6
|
const hierarchy_cache_sync_1 = require("./hierarchy-cache-sync");
|
|
7
|
+
const category_integrity_1 = require("./category-integrity");
|
|
7
8
|
const memory_storage_1 = require("../storage/memory-storage");
|
|
8
9
|
const resolver_1 = require("./resolver");
|
|
9
10
|
const scope_hierarchy_1 = require("../hierarchy/scope-hierarchy");
|
|
10
11
|
const writer_1 = require("./writer");
|
|
11
12
|
const auditor_1 = require("./auditor");
|
|
12
13
|
function createEngine(options = {}) {
|
|
13
|
-
const storage = options.storage ?? new memory_storage_1.MemoryStorageAdapter();
|
|
14
|
+
const storage = (0, category_integrity_1.withCategoryIntegrity)(options.storage ?? new memory_storage_1.MemoryStorageAdapter());
|
|
14
15
|
const rawHierarchy = options.hierarchy ?? new scope_hierarchy_1.LocalScopeHierarchy();
|
|
15
16
|
const bus = options.bus ?? new change_bus_1.LocalBus();
|
|
16
17
|
const cacheOptions = options.cache === false ? { enabled: false } : (options.cache ?? {});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":";;AA+BA,oCAcC;AA5CD,oDAA+C;AAE/C,0CAAuC;AACvC,iEAAmE;AACnE,6DAA6D;AAC7D,8DAAiE;AACjE,yCAAsC;AACtC,kEAAmE;AAGnE,qCAAkC;AAClC,uCAAoC;AAmBpC,SAAgB,YAAY,CAAC,UAAyB,EAAE;IACvD,MAAM,OAAO,GAAG,IAAA,0CAAqB,EACpC,OAAO,CAAC,OAAO,IAAI,IAAI,qCAAoB,EAAE,CAC7C,CAAC;IACF,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,qCAAmB,EAAE,CAAC;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,qBAAQ,EAAE,CAAC;IAC1C,MAAM,YAAY,GACjB,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,GAAG,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAA,gDAAyB,EAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,mBAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACtE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './engine/resolver';
|
|
|
9
9
|
export * from './engine/writer';
|
|
10
10
|
export * from './engine/auditor';
|
|
11
11
|
export * from './engine/hierarchy-cache-sync';
|
|
12
|
+
export * from './engine/category-integrity';
|
|
12
13
|
export * from './engine/engine';
|
|
13
14
|
export * from './typed/registry';
|
|
14
15
|
export * from './typed/category-guard';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __exportStar(require("./engine/resolver"), exports);
|
|
|
25
25
|
__exportStar(require("./engine/writer"), exports);
|
|
26
26
|
__exportStar(require("./engine/auditor"), exports);
|
|
27
27
|
__exportStar(require("./engine/hierarchy-cache-sync"), exports);
|
|
28
|
+
__exportStar(require("./engine/category-integrity"), exports);
|
|
28
29
|
__exportStar(require("./engine/engine"), exports);
|
|
29
30
|
__exportStar(require("./typed/registry"), exports);
|
|
30
31
|
__exportStar(require("./typed/category-guard"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,gDAA8B;AAC9B,qDAAmC;AACnC,gDAA8B;AAC9B,8DAA4C;AAC5C,yDAAuC;AACvC,2DAAyC;AACzC,oDAAkC;AAClC,kDAAgC;AAChC,mDAAiC;AACjC,gEAA8C;AAC9C,kDAAgC;AAChC,mDAAiC;AACjC,yDAAuC;AACvC,yDAAuC;AACvC,uDAAqC;AACrC,wDAAsC;AACtC,uDAAqC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,gDAA8B;AAC9B,qDAAmC;AACnC,gDAA8B;AAC9B,8DAA4C;AAC5C,yDAAuC;AACvC,2DAAyC;AACzC,oDAAkC;AAClC,kDAAgC;AAChC,mDAAiC;AACjC,gEAA8C;AAC9C,8DAA4C;AAC5C,kDAAgC;AAChC,mDAAiC;AACjC,yDAAuC;AACvC,yDAAuC;AACvC,uDAAqC;AACrC,wDAAsC;AACtC,uDAAqC"}
|
package/dist/index.mjs
CHANGED
|
@@ -64,7 +64,7 @@ var CycleError = class extends ConfTreeError {
|
|
|
64
64
|
var CategoryError = class extends ConfTreeError {
|
|
65
65
|
constructor(key, expectedCategory, actualCategory) {
|
|
66
66
|
super(
|
|
67
|
-
`Setting "${key}"
|
|
67
|
+
`Setting "${key}" has category "${actualCategory ?? "none"}", which does not match "${expectedCategory ?? "none"}"`,
|
|
68
68
|
"CATEGORY"
|
|
69
69
|
);
|
|
70
70
|
}
|
|
@@ -859,9 +859,40 @@ function withHierarchyInvalidation(hierarchy, cache) {
|
|
|
859
859
|
};
|
|
860
860
|
}
|
|
861
861
|
|
|
862
|
+
// src/engine/category-integrity.ts
|
|
863
|
+
function withCategoryIntegrity(storage) {
|
|
864
|
+
return {
|
|
865
|
+
findDefs: (keys) => storage.findDefs(keys),
|
|
866
|
+
findDefsByIds: (ids) => storage.findDefsByIds(ids),
|
|
867
|
+
findAnyDef: (key) => storage.findAnyDef(key),
|
|
868
|
+
findValues: (query) => storage.findValues(query),
|
|
869
|
+
findChainValues: (query) => storage.findChainValues(query),
|
|
870
|
+
findAudit: (query) => storage.findAudit(query),
|
|
871
|
+
listValues: (query) => storage.listValues(query),
|
|
872
|
+
listDefs: (status, category) => storage.listDefs(status, category),
|
|
873
|
+
listCategories: () => storage.listCategories(),
|
|
874
|
+
updateDefStatus: (key, status) => storage.updateDefStatus(key, status),
|
|
875
|
+
transact: (fn) => storage.transact(fn),
|
|
876
|
+
createDef: async (input) => {
|
|
877
|
+
const existing = await storage.findAnyDef(input.key);
|
|
878
|
+
const newCategory = input.category ?? null;
|
|
879
|
+
if (existing && existing.category !== newCategory) {
|
|
880
|
+
throw new CategoryError(
|
|
881
|
+
input.key,
|
|
882
|
+
existing.category,
|
|
883
|
+
newCategory
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
return storage.createDef(input);
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
|
|
862
891
|
// src/engine/engine.ts
|
|
863
892
|
function createEngine(options = {}) {
|
|
864
|
-
const storage =
|
|
893
|
+
const storage = withCategoryIntegrity(
|
|
894
|
+
options.storage ?? new MemoryStorageAdapter()
|
|
895
|
+
);
|
|
865
896
|
const rawHierarchy = options.hierarchy ?? new LocalScopeHierarchy();
|
|
866
897
|
const bus = options.bus ?? new LocalBus();
|
|
867
898
|
const cacheOptions = options.cache === false ? { enabled: false } : options.cache ?? {};
|
|
@@ -890,6 +921,28 @@ var CategoryGuard = class {
|
|
|
890
921
|
async assertAll(keys) {
|
|
891
922
|
await Promise.all([...keys].map((key) => this.assert(key)));
|
|
892
923
|
}
|
|
924
|
+
async resolveKey(key) {
|
|
925
|
+
const direct = await this.storage.findAnyDef(key);
|
|
926
|
+
if (direct) {
|
|
927
|
+
if (direct.category !== this.category) {
|
|
928
|
+
throw new CategoryError(key, this.category, direct.category);
|
|
929
|
+
}
|
|
930
|
+
return key;
|
|
931
|
+
}
|
|
932
|
+
const prefixed = `${this.category}.${key}`;
|
|
933
|
+
const viaPrefix = await this.storage.findAnyDef(prefixed);
|
|
934
|
+
if (viaPrefix && viaPrefix.category !== this.category) {
|
|
935
|
+
throw new CategoryError(
|
|
936
|
+
prefixed,
|
|
937
|
+
this.category,
|
|
938
|
+
viaPrefix.category
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
return prefixed;
|
|
942
|
+
}
|
|
943
|
+
async resolveKeys(keys) {
|
|
944
|
+
return Promise.all([...keys].map((key) => this.resolveKey(key)));
|
|
945
|
+
}
|
|
893
946
|
};
|
|
894
947
|
|
|
895
948
|
// src/typed/typed-resolver.ts
|
|
@@ -903,13 +956,17 @@ var TypedResolver = class {
|
|
|
903
956
|
fixedCategory;
|
|
904
957
|
guard;
|
|
905
958
|
async get(key, scope, asOf) {
|
|
906
|
-
await this.guard?.
|
|
907
|
-
return this.resolver.get(
|
|
959
|
+
const resolvedKey = await this.guard?.resolveKey(key) ?? key;
|
|
960
|
+
return this.resolver.get(resolvedKey, scope, asOf);
|
|
908
961
|
}
|
|
909
962
|
async getMany(keys, scope, asOf) {
|
|
910
|
-
await this.guard
|
|
911
|
-
const result = await this.resolver.getMany(
|
|
912
|
-
|
|
963
|
+
const resolvedKeys = this.guard ? await this.guard.resolveKeys(keys) : [...keys];
|
|
964
|
+
const result = await this.resolver.getMany(resolvedKeys, scope, asOf);
|
|
965
|
+
const remapped = {};
|
|
966
|
+
keys.forEach((key, i) => {
|
|
967
|
+
remapped[key] = result[resolvedKeys[i]];
|
|
968
|
+
});
|
|
969
|
+
return remapped;
|
|
913
970
|
}
|
|
914
971
|
async listAt(scope, opts = {}) {
|
|
915
972
|
const page = await this.resolver.listAt(scope, {
|
|
@@ -929,16 +986,24 @@ var TypedWriter = class {
|
|
|
929
986
|
writer;
|
|
930
987
|
guard;
|
|
931
988
|
async set(params) {
|
|
932
|
-
await this.guard?.
|
|
933
|
-
return this.writer.set(
|
|
989
|
+
const resolvedKey = await this.guard?.resolveKey(params.key) ?? params.key;
|
|
990
|
+
return this.writer.set({
|
|
991
|
+
...params,
|
|
992
|
+
key: resolvedKey
|
|
993
|
+
});
|
|
934
994
|
}
|
|
935
995
|
async setMany(paramsList) {
|
|
936
|
-
|
|
937
|
-
|
|
996
|
+
const resolved = this.guard ? await Promise.all(
|
|
997
|
+
paramsList.map(async (params) => ({
|
|
998
|
+
...params,
|
|
999
|
+
key: await this.guard.resolveKey(params.key)
|
|
1000
|
+
}))
|
|
1001
|
+
) : paramsList;
|
|
1002
|
+
return this.writer.setMany(resolved);
|
|
938
1003
|
}
|
|
939
1004
|
async unset(params) {
|
|
940
|
-
await this.guard?.
|
|
941
|
-
return this.writer.unset(params);
|
|
1005
|
+
const resolvedKey = await this.guard?.resolveKey(params.key) ?? params.key;
|
|
1006
|
+
return this.writer.unset({ ...params, key: resolvedKey });
|
|
942
1007
|
}
|
|
943
1008
|
};
|
|
944
1009
|
|
|
@@ -951,8 +1016,8 @@ var TypedAuditor = class {
|
|
|
951
1016
|
auditor;
|
|
952
1017
|
guard;
|
|
953
1018
|
async history(key, scope) {
|
|
954
|
-
await this.guard?.
|
|
955
|
-
return this.auditor.history(
|
|
1019
|
+
const resolvedKey = await this.guard?.resolveKey(key) ?? key;
|
|
1020
|
+
return this.auditor.history(resolvedKey, scope);
|
|
956
1021
|
}
|
|
957
1022
|
};
|
|
958
1023
|
|
|
@@ -997,6 +1062,7 @@ export {
|
|
|
997
1062
|
Writer,
|
|
998
1063
|
createEngine,
|
|
999
1064
|
createTypedEngine,
|
|
1065
|
+
withCategoryIntegrity,
|
|
1000
1066
|
withHierarchyInvalidation
|
|
1001
1067
|
};
|
|
1002
1068
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/types.ts","../src/core/errors.ts","../src/cache/change-bus.ts","../src/cache/cache.ts","../src/hierarchy/scope-hierarchy.ts","../src/storage/memory-storage.ts","../src/engine/resolver.ts","../src/engine/writer.ts","../src/engine/auditor.ts","../src/engine/hierarchy-cache-sync.ts","../src/engine/engine.ts","../src/typed/category-guard.ts","../src/typed/typed-resolver.ts","../src/typed/typed-writer.ts","../src/typed/typed-auditor.ts","../src/typed/typed-engine.ts"],"sourcesContent":["export type JsonValue =\n\t| null\n\t| boolean\n\t| number\n\t| string\n\t| JsonValue[]\n\t| { [key: string]: JsonValue };\n\nexport type Value = Date | JsonValue;\n\nexport interface Scope {\n\tkind: string;\n\trefId: string | null;\n}\n\nexport const DEFAULT_SCOPE: Scope = { kind: 'default', refId: null };\n\nexport type ValueType =\n\t'BOOLEAN' | 'NUMERIC' | 'TEXT' | 'ENUM' | 'JSON' | 'DATE';\n\nexport type Inherit = 'LOCKED' | 'INHERITABLE_OVERRIDABLE' | 'INDEPENDENT';\n\nexport type Status = 'DRAFT' | 'STABLE' | 'DEPRECATED' | 'RETIRED';\n\nexport interface DefRecord {\n\tid: string;\n\tkey: string;\n\tversion: number;\n\tlabel: string;\n\tdescription: string | null;\n\ttype: ValueType;\n\toptions: string[];\n\tmin: number | null;\n\tmax: number | null;\n\tscopes: string[];\n\tinherit: Inherit;\n\trequired: boolean;\n\tsecret: boolean;\n\tstatus: Status;\n\tcategory: string | null;\n}\n\nexport interface ValueRecord {\n\tid: string;\n\tdefinitionId: string;\n\tscopeKind: string;\n\tscopeRefId: string | null;\n\tbool: boolean | null;\n\tnum: number | null;\n\ttext: string | null;\n\tjson: unknown;\n\tjsonSet: boolean;\n\tdate: Date | null;\n\tversion: number;\n}\n\nexport interface ScopeHierarchy {\n\tchain(scopeRefId: string): Promise<string[]>;\n\tdescendants(scopeRefId: string): Promise<string[]>;\n\tchildren(scopeRefId: string): Promise<string[]>;\n\tparent(scopeRefId: string): Promise<string | null>;\n\tattach(id: string, parentId: string | null): Promise<void>;\n\tmove(id: string, newParentId: string | null): Promise<void>;\n\tdetach(id: string): Promise<void>;\n}\n","export type ErrorCode =\n\t| 'NOT_FOUND'\n\t| 'SCOPE'\n\t| 'REQUIRED'\n\t| 'VALUE'\n\t| 'CONFLICT'\n\t| 'CORRUPT'\n\t| 'CYCLE'\n\t| 'CATEGORY';\n\nexport class ConfTreeError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly code: ErrorCode,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = new.target.name;\n\t\tError.captureStackTrace?.(this, new.target);\n\t}\n}\n\nexport class NotFoundError extends ConfTreeError {\n\tconstructor(key: string) {\n\t\tsuper(`Unknown setting definition: \"${key}\"`, 'NOT_FOUND');\n\t}\n}\n\nexport class ScopeError extends ConfTreeError {\n\tconstructor(key: string, scopeKind: string) {\n\t\tsuper(\n\t\t\t`Setting \"${key}\" cannot be set or read at scope kind \"${scopeKind}\"`,\n\t\t\t'SCOPE',\n\t\t);\n\t}\n}\n\nexport class RequiredError extends ConfTreeError {\n\tconstructor(key: string, scopeKind: string, scopeRefId: string | null) {\n\t\tsuper(\n\t\t\t`Required setting \"${key}\" has no resolvable value for scope ${scopeKind}:${scopeRefId ?? 'null'} ` +\n\t\t\t\t`and no default is defined`,\n\t\t\t'REQUIRED',\n\t\t);\n\t}\n}\n\nexport class ValueError extends ConfTreeError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'VALUE');\n\t}\n}\n\nexport class ConflictError extends ConfTreeError {\n\tconstructor(key: string, scopeKind: string, scopeRefId: string | null) {\n\t\tsuper(\n\t\t\t`Setting \"${key}\" at scope ${scopeKind}:${scopeRefId ?? 'null'} was modified concurrently. ` +\n\t\t\t\t`Reload the current value and retry.`,\n\t\t\t'CONFLICT',\n\t\t);\n\t}\n}\n\nexport class CorruptError extends ConfTreeError {\n\tconstructor(valueId: string) {\n\t\tsuper(\n\t\t\t`setting value row ${valueId} has no typed value set: data corruption`,\n\t\t\t'CORRUPT',\n\t\t);\n\t}\n}\n\nexport class CycleError extends ConfTreeError {\n\tconstructor(id: string, newParentId: string) {\n\t\tsuper(\n\t\t\t`Cannot attach/move scope \"${id}\" under \"${newParentId}\": would create a cycle`,\n\t\t\t'CYCLE',\n\t\t);\n\t}\n}\n\nexport class CategoryError extends ConfTreeError {\n\tconstructor(\n\t\tkey: string,\n\t\texpectedCategory: string,\n\t\tactualCategory: string | null,\n\t) {\n\t\tsuper(\n\t\t\t`Setting \"${key}\" belongs to category \"${actualCategory ?? 'none'}\", not \"${expectedCategory}\"`,\n\t\t\t'CATEGORY',\n\t\t);\n\t}\n}\n","export interface ChangeEvent {\n\tdefinitionId: string;\n\tkey: string;\n\tscopeKind: string;\n\tscopeRefId: string | null;\n}\n\nexport type ChangeListener = (event: ChangeEvent) => void | Promise<void>;\n\nexport interface ChangeBus {\n\tpublish(event: ChangeEvent): Promise<void>;\n\tsubscribe(listener: ChangeListener): void;\n\tunsubscribe(listener: ChangeListener): void;\n}\n\nexport class LocalBus implements ChangeBus {\n\tprivate readonly listeners = new Set<ChangeListener>();\n\n\tasync publish(event: ChangeEvent): Promise<void> {\n\t\tawait Promise.all(\n\t\t\t[...this.listeners].map((listener) =>\n\t\t\t\tPromise.resolve(listener(event)),\n\t\t\t),\n\t\t);\n\t}\n\n\tsubscribe(listener: ChangeListener): void {\n\t\tthis.listeners.add(listener);\n\t}\n\n\tunsubscribe(listener: ChangeListener): void {\n\t\tthis.listeners.delete(listener);\n\t}\n}\n","import type { Scope, ScopeHierarchy, Value } from '../core/types';\nimport type { ChangeBus, ChangeEvent, ChangeListener } from './change-bus';\n\nexport interface CacheOptions {\n\tenabled?: boolean;\n\tttlMs?: number;\n\tmaxEntries?: number;\n}\n\ninterface Entry {\n\tkey: string;\n\tscopeKind: string;\n\tscopeRefId: string | null;\n\tvalue: Value;\n\texpiresAt: number;\n}\n\nconst DEFAULT_TTL_MS = 30_000;\nconst DEFAULT_MAX_ENTRIES = 50_000;\n\nexport class Cache {\n\tprivate readonly store = new Map<string, Entry>();\n\tprivate readonly listener: ChangeListener = (event) => this.onChange(event);\n\n\tconstructor(\n\t\tprivate readonly bus: ChangeBus,\n\t\tprivate readonly options: CacheOptions = {},\n\t\tprivate readonly hierarchy?: ScopeHierarchy,\n\t) {\n\t\tthis.bus.subscribe(this.listener);\n\t}\n\n\tdispose(): void {\n\t\tthis.bus.unsubscribe(this.listener);\n\t}\n\n\tget(key: string, scope: Scope): Value | undefined {\n\t\tif (this.options.enabled === false) return undefined;\n\t\tconst cacheKey = this.keyFor(key, scope);\n\t\tconst entry = this.store.get(cacheKey);\n\t\tif (!entry) return undefined;\n\t\tif (entry.expiresAt <= Date.now()) {\n\t\t\tthis.store.delete(cacheKey);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn entry.value;\n\t}\n\n\tset(key: string, scope: Scope, value: Value): void {\n\t\tif (this.options.enabled === false) return;\n\t\tconst cacheKey = this.keyFor(key, scope);\n\t\tif (\n\t\t\t!this.store.has(cacheKey) &&\n\t\t\tthis.store.size >= (this.options.maxEntries ?? DEFAULT_MAX_ENTRIES)\n\t\t) {\n\t\t\tconst oldest = this.store.keys().next().value;\n\t\t\tif (oldest !== undefined) this.store.delete(oldest);\n\t\t}\n\t\tconst ttlMs = this.options.ttlMs ?? DEFAULT_TTL_MS;\n\t\tthis.store.set(cacheKey, {\n\t\t\tkey,\n\t\t\tscopeKind: scope.kind,\n\t\t\tscopeRefId: scope.refId,\n\t\t\tvalue,\n\t\t\texpiresAt: Date.now() + ttlMs,\n\t\t});\n\t}\n\n\tdrop(key: string): void {\n\t\tfor (const [cacheKey, entry] of this.store) {\n\t\t\tif (entry.key === key) this.store.delete(cacheKey);\n\t\t}\n\t}\n\n\tdropAll(): void {\n\t\tthis.store.clear();\n\t}\n\n\tdropForScopes(scopeRefIds: Iterable<string>): void {\n\t\tconst targets = new Set(scopeRefIds);\n\t\tif (targets.size === 0) return;\n\t\tfor (const [cacheKey, entry] of this.store) {\n\t\t\tif (entry.scopeRefId !== null && targets.has(entry.scopeRefId)) {\n\t\t\t\tthis.store.delete(cacheKey);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate dropScoped(key: string, scopeRefIds: Iterable<string>): void {\n\t\tconst targets = new Set(scopeRefIds);\n\t\tfor (const [cacheKey, entry] of this.store) {\n\t\t\tif (\n\t\t\t\tentry.key === key &&\n\t\t\t\tentry.scopeRefId !== null &&\n\t\t\t\ttargets.has(entry.scopeRefId)\n\t\t\t) {\n\t\t\t\tthis.store.delete(cacheKey);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async onChange(event: ChangeEvent): Promise<void> {\n\t\tif (this.hierarchy && event.scopeRefId !== null) {\n\t\t\tconst descendants = await this.hierarchy\n\t\t\t\t.descendants(event.scopeRefId)\n\t\t\t\t.catch(() => null);\n\t\t\tif (descendants !== null) {\n\t\t\t\tthis.dropScoped(event.key, descendants);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.drop(event.key);\n\t}\n\n\tprivate keyFor(key: string, scope: Scope): string {\n\t\treturn JSON.stringify([key, scope.kind, scope.refId]);\n\t}\n}\n","import { CycleError } from '../core/errors';\nimport type { ScopeHierarchy } from '../core/types';\n\nexport class LocalScopeHierarchy implements ScopeHierarchy {\n\tprivate readonly parentOf = new Map<string, string | null>();\n\tprivate readonly childrenOf = new Map<string, Set<string>>();\n\n\tasync chain(id: string): Promise<string[]> {\n\t\tconst result: string[] = [];\n\t\tconst seen = new Set<string>();\n\t\tlet current: string | null = id;\n\t\twhile (current !== null) {\n\t\t\tif (seen.has(current)) break;\n\t\t\tseen.add(current);\n\t\t\tresult.push(current);\n\t\t\tcurrent = this.parentOf.get(current) ?? null;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync descendants(id: string): Promise<string[]> {\n\t\tconst result: string[] = [];\n\t\tconst stack = [id];\n\t\tconst seen = new Set<string>();\n\t\twhile (stack.length > 0) {\n\t\t\tconst current = stack.pop()!;\n\t\t\tif (seen.has(current)) continue;\n\t\t\tseen.add(current);\n\t\t\tresult.push(current);\n\t\t\tconst kids = this.childrenOf.get(current);\n\t\t\tif (kids) stack.push(...kids);\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync children(id: string): Promise<string[]> {\n\t\treturn [...(this.childrenOf.get(id) ?? [])];\n\t}\n\n\tasync parent(id: string): Promise<string | null> {\n\t\treturn this.parentOf.get(id) ?? null;\n\t}\n\n\tasync attach(id: string, parentId: string | null): Promise<void> {\n\t\tif (parentId !== null) await this.assertNoCycle(id, parentId);\n\t\tconst oldParent = this.parentOf.get(id) ?? null;\n\t\tif (oldParent !== null) this.childrenOf.get(oldParent)?.delete(id);\n\t\tthis.parentOf.set(id, parentId);\n\t\tif (parentId !== null) this.addChild(parentId, id);\n\t\tif (!this.childrenOf.has(id)) this.childrenOf.set(id, new Set());\n\t}\n\n\tasync move(id: string, newParentId: string | null): Promise<void> {\n\t\tif (newParentId !== null) await this.assertNoCycle(id, newParentId);\n\t\tconst oldParent = this.parentOf.get(id) ?? null;\n\t\tif (oldParent !== null) this.childrenOf.get(oldParent)?.delete(id);\n\t\tthis.parentOf.set(id, newParentId);\n\t\tif (newParentId !== null) this.addChild(newParentId, id);\n\t}\n\n\tasync detach(id: string): Promise<void> {\n\t\tconst parentId = this.parentOf.get(id) ?? null;\n\t\tconst kids = [...(this.childrenOf.get(id) ?? [])];\n\t\tfor (const kid of kids) {\n\t\t\tawait this.move(kid, parentId);\n\t\t}\n\t\tif (parentId !== null) this.childrenOf.get(parentId)?.delete(id);\n\t\tthis.parentOf.delete(id);\n\t\tthis.childrenOf.delete(id);\n\t}\n\n\tprivate addChild(parentId: string, id: string): void {\n\t\tif (!this.childrenOf.has(parentId))\n\t\t\tthis.childrenOf.set(parentId, new Set());\n\t\tthis.childrenOf.get(parentId)!.add(id);\n\t}\n\n\tprivate async assertNoCycle(\n\t\tid: string,\n\t\tnewParentId: string,\n\t): Promise<void> {\n\t\tif (\n\t\t\tid === newParentId ||\n\t\t\t(await this.chain(newParentId)).includes(id)\n\t\t) {\n\t\t\tthrow new CycleError(id, newParentId);\n\t\t}\n\t}\n}\n","import type {\n\tAuditRecord,\n\tCreateAuditInput,\n\tCreateDefInput,\n\tCreateValueInput,\n\tFindAuditQuery,\n\tFindChainQuery,\n\tFindValuesQuery,\n\tListValuesQuery,\n\tListValuesResult,\n\tStorageAdapter,\n\tStorageTx,\n} from './storage-port';\nimport type {\n\tDefRecord,\n\tStatus,\n\tValue,\n\tValueRecord,\n\tValueType,\n} from '../core/types';\nimport { NotFoundError } from '../core/errors';\n\ninterface StoredValue extends ValueRecord {\n\tvalidFrom: Date;\n\tvalidTo: Date | null;\n}\n\nfunction toTypedColumns(type: ValueType, value: Value) {\n\treturn {\n\t\tbool: type === 'BOOLEAN' ? (value as boolean) : null,\n\t\tnum: type === 'NUMERIC' ? (value as number) : null,\n\t\ttext: type === 'TEXT' || type === 'ENUM' ? (value as string) : null,\n\t\tjson: type === 'JSON' ? value : null,\n\t\tjsonSet: type === 'JSON',\n\t\tdate: type === 'DATE' ? (value as Date) : null,\n\t};\n}\n\nexport class MemoryStorageAdapter implements StorageAdapter {\n\tprivate defs: DefRecord[] = [];\n\tprivate values: StoredValue[] = [];\n\tprivate auditLog: AuditRecord[] = [];\n\tprivate nextId = 1;\n\tprivate txQueue: Promise<unknown> = Promise.resolve();\n\n\tprivate newId(prefix: string): string {\n\t\treturn `${prefix}-${this.nextId++}`;\n\t}\n\n\tasync findDefs(keys: string[]): Promise<DefRecord[]> {\n\t\tconst result: DefRecord[] = [];\n\t\tfor (const key of keys) {\n\t\t\tconst found = this.latestByStatus(key, ['STABLE', 'DEPRECATED']);\n\t\t\tif (found) result.push(found);\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync findValues(query: FindValuesQuery): Promise<ValueRecord[]> {\n\t\tconst asOf = query.asOf ?? new Date();\n\t\tconst ids = new Set(query.definitionIds);\n\t\treturn this.values.filter(\n\t\t\t(v) =>\n\t\t\t\tids.has(v.definitionId) &&\n\t\t\t\tv.scopeKind === query.scopeKind &&\n\t\t\t\tv.scopeRefId === query.scopeRefId &&\n\t\t\t\tv.validFrom <= asOf &&\n\t\t\t\t(v.validTo === null || v.validTo > asOf),\n\t\t);\n\t}\n\n\tasync findChainValues(query: FindChainQuery): Promise<ValueRecord[]> {\n\t\tconst asOf = query.asOf ?? new Date();\n\t\tconst defIds = new Set(query.definitionIds);\n\t\tconst refIds = new Set(query.chain);\n\t\treturn this.values.filter(\n\t\t\t(v) =>\n\t\t\t\tdefIds.has(v.definitionId) &&\n\t\t\t\tv.scopeRefId !== null &&\n\t\t\t\trefIds.has(v.scopeRefId) &&\n\t\t\t\tv.validFrom <= asOf &&\n\t\t\t\t(v.validTo === null || v.validTo > asOf),\n\t\t);\n\t}\n\n\tasync findDefsByIds(ids: string[]): Promise<DefRecord[]> {\n\t\tconst idSet = new Set(ids);\n\t\treturn this.defs.filter((d) => idSet.has(d.id));\n\t}\n\n\tasync findAnyDef(key: string): Promise<DefRecord | null> {\n\t\treturn this.latestVersion(key) ?? null;\n\t}\n\n\tasync listValues(query: ListValuesQuery): Promise<ListValuesResult> {\n\t\tconst now = new Date();\n\t\tconst categoryDefIds =\n\t\t\tquery.category !== undefined\n\t\t\t\t? new Set(\n\t\t\t\t\t\tthis.defs\n\t\t\t\t\t\t\t.filter((d) => d.category === query.category)\n\t\t\t\t\t\t\t.map((d) => d.id),\n\t\t\t\t\t)\n\t\t\t\t: null;\n\t\tconst active = this.values\n\t\t\t.filter(\n\t\t\t\t(v) =>\n\t\t\t\t\tv.scopeKind === query.scopeKind &&\n\t\t\t\t\tv.scopeRefId === query.scopeRefId &&\n\t\t\t\t\t(categoryDefIds === null ||\n\t\t\t\t\t\tcategoryDefIds.has(v.definitionId)) &&\n\t\t\t\t\tv.validFrom <= now &&\n\t\t\t\t\t(v.validTo === null || v.validTo > now),\n\t\t\t)\n\t\t\t.sort((a, b) => a.id.localeCompare(b.id));\n\n\t\tconst startIndex = query.cursor\n\t\t\t? active.findIndex((v) => v.id === query.cursor) + 1\n\t\t\t: 0;\n\t\tconst limit = query.limit ?? active.length - startIndex;\n\t\tconst page = active.slice(startIndex, startIndex + limit);\n\t\tconst nextCursor =\n\t\t\tstartIndex + page.length < active.length\n\t\t\t\t? (page[page.length - 1]?.id ?? null)\n\t\t\t\t: null;\n\n\t\treturn { values: page, nextCursor };\n\t}\n\n\tasync findAudit(query: FindAuditQuery): Promise<AuditRecord[]> {\n\t\treturn this.auditLog\n\t\t\t.filter(\n\t\t\t\t(a) =>\n\t\t\t\t\ta.definitionId === query.definitionId &&\n\t\t\t\t\t(query.scopeKind === undefined ||\n\t\t\t\t\t\ta.scopeKind === query.scopeKind) &&\n\t\t\t\t\t(query.scopeRefId === undefined ||\n\t\t\t\t\t\ta.scopeRefId === query.scopeRefId),\n\t\t\t)\n\t\t\t.sort((a, b) => a.at.getTime() - b.at.getTime());\n\t}\n\n\tasync createDef(input: CreateDefInput): Promise<DefRecord> {\n\t\tconst existingVersions = this.defs.filter((d) => d.key === input.key);\n\t\tconst version =\n\t\t\texistingVersions.length > 0\n\t\t\t\t? Math.max(...existingVersions.map((d) => d.version)) + 1\n\t\t\t\t: 1;\n\t\tconst record: DefRecord = {\n\t\t\tid: this.newId('def'),\n\t\t\tkey: input.key,\n\t\t\tversion,\n\t\t\tlabel: input.label,\n\t\t\tdescription: input.description ?? null,\n\t\t\ttype: input.type,\n\t\t\toptions: input.options ?? [],\n\t\t\tmin: input.min ?? null,\n\t\t\tmax: input.max ?? null,\n\t\t\tscopes: input.scopes,\n\t\t\tinherit: input.inherit,\n\t\t\trequired: input.required,\n\t\t\tsecret: input.secret ?? false,\n\t\t\tstatus: input.status ?? 'DRAFT',\n\t\t\tcategory: input.category ?? null,\n\t\t};\n\t\tthis.defs.push(record);\n\t\treturn record;\n\t}\n\n\tasync updateDefStatus(key: string, status: Status): Promise<DefRecord> {\n\t\tconst current = this.latestVersion(key);\n\t\tif (!current) throw new NotFoundError(key);\n\n\t\tconst updated: DefRecord = { ...current, status };\n\t\tthis.defs = this.defs.map((d) => (d === current ? updated : d));\n\t\treturn updated;\n\t}\n\n\tasync listDefs(status?: Status, category?: string): Promise<DefRecord[]> {\n\t\tconst rows = this.allLatestVersions().filter(\n\t\t\t(d) =>\n\t\t\t\t(status === undefined || d.status === status) &&\n\t\t\t\t(category === undefined || d.category === category),\n\t\t);\n\t\treturn rows.sort(\n\t\t\t(a, b) =>\n\t\t\t\t(a.category ?? '').localeCompare(b.category ?? '') ||\n\t\t\t\ta.key.localeCompare(b.key),\n\t\t);\n\t}\n\n\tasync listCategories(): Promise<string[]> {\n\t\tconst categories = new Set(\n\t\t\tthis.allLatestVersions()\n\t\t\t\t.map((d) => d.category)\n\t\t\t\t.filter((c): c is string => c !== null),\n\t\t);\n\t\treturn [...categories].sort();\n\t}\n\n\tasync transact<T>(fn: (tx: StorageTx) => Promise<T>): Promise<T> {\n\t\tconst run = this.txQueue.then(async () => {\n\t\t\tconst valuesSnapshot = structuredClone(this.values);\n\t\t\tconst auditLogSnapshot = structuredClone(this.auditLog);\n\t\t\ttry {\n\t\t\t\treturn await fn(this.tx());\n\t\t\t} catch (err) {\n\t\t\t\tthis.values = valuesSnapshot;\n\t\t\t\tthis.auditLog = auditLogSnapshot;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t});\n\t\tthis.txQueue = run.catch(() => {});\n\t\treturn run;\n\t}\n\n\tprivate latestByStatus(\n\t\tkey: string,\n\t\tstatuses: Status[],\n\t): DefRecord | undefined {\n\t\tconst latest = this.latestVersion(key);\n\t\treturn latest && statuses.includes(latest.status) ? latest : undefined;\n\t}\n\n\tprivate latestVersion(key: string): DefRecord | undefined {\n\t\treturn this.defs\n\t\t\t.filter((d) => d.key === key)\n\t\t\t.sort((a, b) => b.version - a.version)[0];\n\t}\n\n\tprivate allLatestVersions(): DefRecord[] {\n\t\tconst byKey = new Map<string, DefRecord>();\n\t\tfor (const d of this.defs) {\n\t\t\tconst current = byKey.get(d.key);\n\t\t\tif (!current || d.version > current.version) byKey.set(d.key, d);\n\t\t}\n\t\treturn [...byKey.values()];\n\t}\n\n\tprivate tx(): StorageTx {\n\t\treturn {\n\t\t\tfindDef: async (key: string) =>\n\t\t\t\tthis.latestByStatus(key, ['STABLE']) ?? null,\n\n\t\t\tfindValue: async (definitionId, scopeKind, scopeRefId) =>\n\t\t\t\tthis.values.find(\n\t\t\t\t\t(v) =>\n\t\t\t\t\t\tv.definitionId === definitionId &&\n\t\t\t\t\t\tv.scopeKind === scopeKind &&\n\t\t\t\t\t\tv.scopeRefId === scopeRefId &&\n\t\t\t\t\t\tv.validTo === null,\n\t\t\t\t) ?? null,\n\n\t\t\tcloseValue: async (id: string) => {\n\t\t\t\tconst row = this.values.find((v) => v.id === id);\n\t\t\t\tif (!row) return;\n\t\t\t\tconst closed: StoredValue = { ...row, validTo: new Date() };\n\t\t\t\tthis.values = this.values.map((v) => (v === row ? closed : v));\n\t\t\t},\n\n\t\t\tcreateValue: async (input: CreateValueInput) => {\n\t\t\t\tconst record: StoredValue = {\n\t\t\t\t\tid: this.newId('val'),\n\t\t\t\t\tdefinitionId: input.definitionId,\n\t\t\t\t\tscopeKind: input.scopeKind,\n\t\t\t\t\tscopeRefId: input.scopeRefId,\n\t\t\t\t\tversion: input.version,\n\t\t\t\t\tvalidFrom: new Date(),\n\t\t\t\t\tvalidTo: null,\n\t\t\t\t\t...toTypedColumns(input.type, input.value),\n\t\t\t\t};\n\t\t\t\tthis.values.push(record);\n\t\t\t\treturn record;\n\t\t\t},\n\n\t\t\tcreateAudit: async (input: CreateAuditInput): Promise<void> => {\n\t\t\t\tthis.auditLog.push({\n\t\t\t\t\t...input,\n\t\t\t\t\tid: this.newId('audit'),\n\t\t\t\t\tat: new Date(),\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n}\n","import type {\n\tDefRecord,\n\tScope,\n\tScopeHierarchy,\n\tValue,\n\tValueRecord,\n} from '../core/types';\nimport { DEFAULT_SCOPE } from '../core/types';\nimport {\n\tCorruptError,\n\tRequiredError,\n\tScopeError,\n\tNotFoundError,\n} from '../core/errors';\nimport type { StorageReader } from '../storage/storage-port';\nimport type { Cache } from '../cache/cache';\n\nexport interface ListAtPage {\n\tentries: Record<string, Value>;\n\tnextCursor: string | null;\n}\n\nexport class Resolver {\n\tconstructor(\n\t\tprivate readonly storage: StorageReader,\n\t\tprivate readonly hierarchy?: ScopeHierarchy,\n\t\tprivate readonly cache?: Cache,\n\t) {}\n\n\tasync get(key: string, scope: Scope, asOf?: Date): Promise<Value> {\n\t\tconst result = await this.getMany([key], scope, asOf);\n\t\treturn result[key];\n\t}\n\n\tasync listAt(\n\t\tscope: Scope,\n\t\topts: { limit?: number; cursor?: string; category?: string } = {},\n\t): Promise<ListAtPage> {\n\t\tconst { values, nextCursor } = await this.storage.listValues({\n\t\t\tscopeKind: scope.kind,\n\t\t\tscopeRefId: scope.refId,\n\t\t\tcategory: opts.category,\n\t\t\tlimit: opts.limit,\n\t\t\tcursor: opts.cursor,\n\t\t});\n\t\tif (values.length === 0) return { entries: {}, nextCursor };\n\n\t\tconst defs = await this.storage.findDefsByIds([\n\t\t\t...new Set(values.map((v) => v.definitionId)),\n\t\t]);\n\t\tconst defById = new Map(defs.map((d) => [d.id, d]));\n\n\t\tconst entries: Record<string, Value> = {};\n\t\tfor (const row of values) {\n\t\t\tconst def = defById.get(row.definitionId);\n\t\t\tif (!def) continue;\n\t\t\tentries[def.key] = this.unwrap(def, row);\n\t\t}\n\t\treturn { entries, nextCursor };\n\t}\n\n\tasync getMany(\n\t\tkeys: string[],\n\t\tscope: Scope,\n\t\tasOf?: Date,\n\t): Promise<Record<string, Value>> {\n\t\tconst uniqueKeys = [...new Set(keys)];\n\t\tconst result: Record<string, Value> = {};\n\t\tconst uncached: string[] = [];\n\n\t\tif (asOf === undefined) {\n\t\t\tfor (const key of uniqueKeys) {\n\t\t\t\tconst cached = this.cache?.get(key, scope);\n\t\t\t\tif (cached !== undefined) result[key] = cached;\n\t\t\t\telse uncached.push(key);\n\t\t\t}\n\t\t} else {\n\t\t\tuncached.push(...uniqueKeys);\n\t\t}\n\t\tif (uncached.length === 0) return result;\n\n\t\tconst defByKey = await this.getDefs(uncached);\n\t\tfor (const key of uncached) {\n\t\t\tthis.checkScope(defByKey.get(key)!, scope);\n\t\t}\n\n\t\tconst exactDefs: DefRecord[] = [];\n\t\tconst chainDefs: DefRecord[] = [];\n\t\tfor (const key of uncached) {\n\t\t\tconst def = defByKey.get(key)!;\n\t\t\tconst climbsHierarchy =\n\t\t\t\tdef.inherit !== 'INDEPENDENT' &&\n\t\t\t\tscope.refId !== null &&\n\t\t\t\tthis.hierarchy;\n\t\t\t(climbsHierarchy ? chainDefs : exactDefs).push(def);\n\t\t}\n\n\t\tconst chain =\n\t\t\tchainDefs.length > 0 && scope.refId !== null && this.hierarchy\n\t\t\t\t? await this.hierarchy.chain(scope.refId)\n\t\t\t\t: [];\n\n\t\tconst [exactRows, chainRows] = await Promise.all([\n\t\t\texactDefs.length > 0\n\t\t\t\t? this.storage.findValues({\n\t\t\t\t\t\tdefinitionIds: exactDefs.map((d) => d.id),\n\t\t\t\t\t\tscopeKind: scope.kind,\n\t\t\t\t\t\tscopeRefId: scope.refId,\n\t\t\t\t\t\tasOf,\n\t\t\t\t\t})\n\t\t\t\t: Promise.resolve([] as ValueRecord[]),\n\t\t\tchainDefs.length > 0 && chain.length > 0\n\t\t\t\t? this.storage.findChainValues({\n\t\t\t\t\t\tdefinitionIds: chainDefs.map((d) => d.id),\n\t\t\t\t\t\tchain,\n\t\t\t\t\t\tasOf,\n\t\t\t\t\t})\n\t\t\t\t: Promise.resolve([] as ValueRecord[]),\n\t\t]);\n\n\t\tconst exactByDef = new Map(exactRows.map((r) => [r.definitionId, r]));\n\t\tconst chainByDef = new Map<string, ValueRecord[]>();\n\t\tfor (const row of chainRows) {\n\t\t\tconst list = chainByDef.get(row.definitionId) ?? [];\n\t\t\tlist.push(row);\n\t\t\tchainByDef.set(row.definitionId, list);\n\t\t}\n\t\tconst chainDefIds = new Set(chainDefs.map((d) => d.id));\n\n\t\tconst missing: DefRecord[] = [];\n\t\tfor (const key of uncached) {\n\t\t\tconst def = defByKey.get(key)!;\n\t\t\tlet row: ValueRecord | undefined;\n\t\t\tif (chainDefIds.has(def.id)) {\n\t\t\t\tconst byRef = new Map(\n\t\t\t\t\t(chainByDef.get(def.id) ?? []).map((v) => [\n\t\t\t\t\t\tv.scopeRefId,\n\t\t\t\t\t\tv,\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t\tfor (const ref of chain) {\n\t\t\t\t\trow = byRef.get(ref);\n\t\t\t\t\tif (row) break;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trow = exactByDef.get(def.id);\n\t\t\t}\n\t\t\tif (row) {\n\t\t\t\tresult[key] = this.unwrap(def, row);\n\t\t\t\tif (asOf === undefined)\n\t\t\t\t\tthis.cache?.set(key, scope, result[key]);\n\t\t\t} else {\n\t\t\t\tmissing.push(def);\n\t\t\t}\n\t\t}\n\n\t\tif (missing.length > 0)\n\t\t\tawait this.resolveMissing(\n\t\t\t\tmissing,\n\t\t\t\tscope,\n\t\t\t\tuncached,\n\t\t\t\tdefByKey,\n\t\t\t\tresult,\n\t\t\t\tasOf,\n\t\t\t);\n\n\t\treturn result;\n\t}\n\n\tprivate async resolveMissing(\n\t\tmissing: DefRecord[],\n\t\tscope: Scope,\n\t\tkeysInOrder: string[],\n\t\tdefByKey: Map<string, DefRecord>,\n\t\tresult: Record<string, Value>,\n\t\tasOf?: Date,\n\t): Promise<void> {\n\t\tconst defaultRows = await this.storage.findValues({\n\t\t\tdefinitionIds: missing.map((d) => d.id),\n\t\t\tscopeKind: DEFAULT_SCOPE.kind,\n\t\t\tscopeRefId: DEFAULT_SCOPE.refId,\n\t\t\tasOf,\n\t\t});\n\t\tconst defaultByDef = new Map(\n\t\t\tdefaultRows.map((r) => [r.definitionId, r]),\n\t\t);\n\t\tconst missingIds = new Set(missing.map((d) => d.id));\n\n\t\tfor (const key of keysInOrder) {\n\t\t\tconst def = defByKey.get(key)!;\n\t\t\tif (!missingIds.has(def.id)) continue;\n\t\t\tconst row = defaultByDef.get(def.id);\n\t\t\tif (!row) {\n\t\t\t\tthrow new RequiredError(def.key, scope.kind, scope.refId);\n\t\t\t}\n\t\t\tresult[key] = this.unwrap(def, row);\n\t\t\tif (asOf === undefined) this.cache?.set(key, scope, result[key]);\n\t\t}\n\t}\n\n\tprivate async getDefs(keys: string[]): Promise<Map<string, DefRecord>> {\n\t\tconst defs = await this.storage.findDefs(keys);\n\t\tconst byKey = new Map(defs.map((d) => [d.key, d]));\n\t\tfor (const key of keys) {\n\t\t\tif (!byKey.has(key)) throw new NotFoundError(key);\n\t\t}\n\t\treturn byKey;\n\t}\n\n\tprivate checkScope(def: DefRecord, scope: Scope): void {\n\t\tif (scope.kind === 'default') return;\n\t\tif (!def.scopes.includes(scope.kind)) {\n\t\t\tthrow new ScopeError(def.key, scope.kind);\n\t\t}\n\t}\n\n\tprivate unwrap(def: DefRecord, row: ValueRecord): Value {\n\t\tswitch (def.type) {\n\t\t\tcase 'BOOLEAN':\n\t\t\t\tif (row.bool === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.bool;\n\t\t\tcase 'NUMERIC':\n\t\t\t\tif (row.num === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.num;\n\t\t\tcase 'TEXT':\n\t\t\tcase 'ENUM':\n\t\t\t\tif (row.text === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.text;\n\t\t\tcase 'JSON':\n\t\t\t\tif (!row.jsonSet) throw new CorruptError(row.id);\n\t\t\t\treturn row.json as Value;\n\t\t\tcase 'DATE':\n\t\t\t\tif (row.date === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.date;\n\t\t}\n\t}\n}\n","import type { DefRecord, Scope, Value, ValueRecord } from '../core/types';\nimport {\n\tConflictError,\n\tScopeError,\n\tValueError,\n\tNotFoundError,\n} from '../core/errors';\nimport type { StorageAdapter, StorageTx } from '../storage/storage-port';\nimport type { ChangeBus } from '../cache/change-bus';\n\nexport interface SetParams {\n\tkey: string;\n\tscope: Scope;\n\tvalue: Value;\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nexport interface UnsetParams {\n\tkey: string;\n\tscope: Scope;\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nconst REDACTED = '[redacted]';\n\nexport class Writer {\n\tconstructor(\n\t\tprivate readonly storage: StorageAdapter,\n\t\tprivate readonly bus?: ChangeBus,\n\t) {}\n\n\tasync set(params: SetParams): Promise<ValueRecord> {\n\t\tconst created = await this.storage.transact((tx) =>\n\t\t\tthis.setInTx(tx, params),\n\t\t);\n\t\tawait this.emit(created, params.key);\n\t\treturn created;\n\t}\n\n\tasync setMany(paramsList: SetParams[]): Promise<ValueRecord[]> {\n\t\tconst created = await this.storage.transact(async (tx) => {\n\t\t\tconst results: ValueRecord[] = [];\n\t\t\tfor (const params of paramsList) {\n\t\t\t\tresults.push(await this.setInTx(tx, params));\n\t\t\t}\n\t\t\treturn results;\n\t\t});\n\t\tawait Promise.all(\n\t\t\tcreated.map((row, i) => this.emit(row, paramsList[i].key)),\n\t\t);\n\t\treturn created;\n\t}\n\n\tprivate async setInTx(\n\t\ttx: StorageTx,\n\t\tparams: SetParams,\n\t): Promise<ValueRecord> {\n\t\tconst def = await tx.findDef(params.key);\n\t\tif (!def) throw new NotFoundError(params.key);\n\n\t\tif (\n\t\t\tparams.scope.kind !== 'default' &&\n\t\t\t!def.scopes.includes(params.scope.kind)\n\t\t) {\n\t\t\tthrow new ScopeError(def.key, params.scope.kind);\n\t\t}\n\n\t\tthis.validate(def, params.value);\n\n\t\tconst current = await tx.findValue(\n\t\t\tdef.id,\n\t\t\tparams.scope.kind,\n\t\t\tparams.scope.refId,\n\t\t);\n\n\t\tconst currentVersion = current?.version ?? 0;\n\t\tconst expected = params.expectedVersion ?? 0;\n\t\tif (currentVersion !== expected) {\n\t\t\tthrow new ConflictError(\n\t\t\t\tdef.key,\n\t\t\t\tparams.scope.kind,\n\t\t\t\tparams.scope.refId,\n\t\t\t);\n\t\t}\n\n\t\tif (current) {\n\t\t\tawait tx.closeValue(current.id);\n\t\t}\n\n\t\tconst created = await tx.createValue({\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: params.scope.kind,\n\t\t\tscopeRefId: params.scope.refId,\n\t\t\tversion: currentVersion + 1,\n\t\t\tauthorId: params.authorId,\n\t\t\treason: params.reason,\n\t\t\ttype: def.type,\n\t\t\tvalue: params.value,\n\t\t});\n\n\t\tawait tx.createAudit({\n\t\t\tvalueId: created.id,\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: created.scopeKind,\n\t\t\tscopeRefId: created.scopeRefId,\n\t\t\taction: current ? 'superseded' : 'created',\n\t\t\tauthorId: params.authorId,\n\t\t\tbefore: current ? this.snapshotOf(def, current) : undefined,\n\t\t\tafter: this.snapshotOf(def, created),\n\t\t\treason: params.reason,\n\t\t});\n\n\t\treturn created;\n\t}\n\n\tasync unset(params: UnsetParams): Promise<void> {\n\t\tconst closed = await this.storage.transact((tx) =>\n\t\t\tthis.unsetInTx(tx, params),\n\t\t);\n\t\tif (closed) await this.emit(closed, params.key);\n\t}\n\n\tprivate async unsetInTx(\n\t\ttx: StorageTx,\n\t\tparams: UnsetParams,\n\t): Promise<ValueRecord | null> {\n\t\tconst def = await tx.findDef(params.key);\n\t\tif (!def) throw new NotFoundError(params.key);\n\n\t\tif (\n\t\t\tparams.scope.kind !== 'default' &&\n\t\t\t!def.scopes.includes(params.scope.kind)\n\t\t) {\n\t\t\tthrow new ScopeError(def.key, params.scope.kind);\n\t\t}\n\n\t\tconst current = await tx.findValue(\n\t\t\tdef.id,\n\t\t\tparams.scope.kind,\n\t\t\tparams.scope.refId,\n\t\t);\n\n\t\tconst currentVersion = current?.version ?? 0;\n\t\tconst expected = params.expectedVersion ?? 0;\n\t\tif (currentVersion !== expected) {\n\t\t\tthrow new ConflictError(\n\t\t\t\tdef.key,\n\t\t\t\tparams.scope.kind,\n\t\t\t\tparams.scope.refId,\n\t\t\t);\n\t\t}\n\t\tif (!current) return null;\n\n\t\tawait tx.closeValue(current.id);\n\t\tawait tx.createAudit({\n\t\t\tvalueId: current.id,\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: current.scopeKind,\n\t\t\tscopeRefId: current.scopeRefId,\n\t\t\taction: 'unset',\n\t\t\tauthorId: params.authorId,\n\t\t\tbefore: this.snapshotOf(def, current),\n\t\t\treason: params.reason,\n\t\t});\n\n\t\treturn current;\n\t}\n\n\tprivate async emit(created: ValueRecord, key: string): Promise<void> {\n\t\ttry {\n\t\t\tawait this.bus?.publish({\n\t\t\t\tdefinitionId: created.definitionId,\n\t\t\t\tkey,\n\t\t\t\tscopeKind: created.scopeKind,\n\t\t\t\tscopeRefId: created.scopeRefId,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error('conftree: change bus publish failed', err);\n\t\t}\n\t}\n\n\tprivate validate(def: DefRecord, value: Value): void {\n\t\tswitch (def.type) {\n\t\t\tcase 'BOOLEAN':\n\t\t\t\tif (typeof value !== 'boolean') {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a boolean`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'NUMERIC': {\n\t\t\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a finite number`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (def.min !== null && value < def.min) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" must be >= ${def.min}, got ${value}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (def.max !== null && value > def.max) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" must be <= ${def.max}, got ${value}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'TEXT':\n\t\t\t\tif (typeof value !== 'string') {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a string`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ENUM':\n\t\t\t\tif (typeof value !== 'string' || !def.options.includes(value)) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" must be one of: ${def.options.join(', ')}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'JSON': {\n\t\t\t\tlet serialized: string | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tserialized = JSON.stringify(value);\n\t\t\t\t} catch {\n\t\t\t\t\tserialized = undefined;\n\t\t\t\t}\n\t\t\t\tif (serialized === undefined) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a JSON-serializable value`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'DATE':\n\t\t\t\tif (!(value instanceof Date) || Number.isNaN(value.getTime())) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a valid Date`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate snapshotOf(def: DefRecord, row: ValueRecord) {\n\t\tif (def.secret) {\n\t\t\treturn {\n\t\t\t\tscopeKind: row.scopeKind,\n\t\t\t\tscopeRefId: row.scopeRefId,\n\t\t\t\tversion: row.version,\n\t\t\t\tvalue: REDACTED,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tscopeKind: row.scopeKind,\n\t\t\tscopeRefId: row.scopeRefId,\n\t\t\tversion: row.version,\n\t\t\tbool: row.bool,\n\t\t\tnum: row.num,\n\t\t\ttext: row.text,\n\t\t\tjson: row.jsonSet ? row.json : undefined,\n\t\t\tdate: row.date,\n\t\t};\n\t}\n}\n","import type { Scope } from '../core/types';\nimport { NotFoundError } from '../core/errors';\nimport type { AuditRecord, StorageReader } from '../storage/storage-port';\n\nexport class Auditor {\n\tconstructor(private readonly storage: StorageReader) {}\n\n\tasync history(key: string, scope?: Scope): Promise<AuditRecord[]> {\n\t\tconst def = await this.storage.findAnyDef(key);\n\t\tif (!def) throw new NotFoundError(key);\n\n\t\treturn this.storage.findAudit({\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: scope?.kind,\n\t\t\tscopeRefId: scope?.refId,\n\t\t});\n\t}\n}\n","import type { Cache } from '../cache/cache';\nimport type { ScopeHierarchy } from '../core/types';\n\nexport function withHierarchyInvalidation(\n\thierarchy: ScopeHierarchy,\n\tcache: Cache,\n): ScopeHierarchy {\n\treturn {\n\t\tchain: (id) => hierarchy.chain(id),\n\t\tdescendants: (id) => hierarchy.descendants(id),\n\t\tchildren: (id) => hierarchy.children(id),\n\t\tparent: (id) => hierarchy.parent(id),\n\t\tattach: async (id, parentId) => {\n\t\t\tawait hierarchy.attach(id, parentId);\n\t\t\tcache.dropForScopes(await hierarchy.descendants(id));\n\t\t},\n\t\tmove: async (id, newParentId) => {\n\t\t\tconst descendants = await hierarchy.descendants(id);\n\t\t\tawait hierarchy.move(id, newParentId);\n\t\t\tcache.dropForScopes(descendants);\n\t\t},\n\t\tdetach: async (id) => {\n\t\t\tconst descendants = await hierarchy.descendants(id);\n\t\t\tawait hierarchy.detach(id);\n\t\t\tcache.dropForScopes(descendants);\n\t\t},\n\t};\n}\n","import type { ChangeBus } from '../cache/change-bus';\nimport { LocalBus } from '../cache/change-bus';\nimport type { CacheOptions } from '../cache/cache';\nimport { Cache } from '../cache/cache';\nimport { withHierarchyInvalidation } from './hierarchy-cache-sync';\nimport { MemoryStorageAdapter } from '../storage/memory-storage';\nimport { Resolver } from './resolver';\nimport { LocalScopeHierarchy } from '../hierarchy/scope-hierarchy';\nimport type { StorageAdapter } from '../storage/storage-port';\nimport type { ScopeHierarchy } from '../core/types';\nimport { Writer } from './writer';\nimport { Auditor } from './auditor';\n\nexport interface EngineOptions {\n\tstorage?: StorageAdapter;\n\thierarchy?: ScopeHierarchy;\n\tbus?: ChangeBus;\n\tcache?: CacheOptions | false;\n}\n\nexport interface Engine {\n\tstorage: StorageAdapter;\n\thierarchy: ScopeHierarchy;\n\tbus: ChangeBus;\n\tcache: Cache;\n\tresolver: Resolver;\n\twriter: Writer;\n\tauditor: Auditor;\n}\n\nexport function createEngine(options: EngineOptions = {}): Engine {\n\tconst storage = options.storage ?? new MemoryStorageAdapter();\n\tconst rawHierarchy = options.hierarchy ?? new LocalScopeHierarchy();\n\tconst bus = options.bus ?? new LocalBus();\n\tconst cacheOptions =\n\t\toptions.cache === false ? { enabled: false } : (options.cache ?? {});\n\tconst cache = new Cache(bus, cacheOptions, rawHierarchy);\n\tconst hierarchy = withHierarchyInvalidation(rawHierarchy, cache);\n\tconst resolver = new Resolver(storage, hierarchy, cache);\n\tconst writer = new Writer(storage, bus);\n\tconst auditor = new Auditor(storage);\n\treturn { storage, hierarchy, bus, cache, resolver, writer, auditor };\n}\n","import { CategoryError } from '../core/errors';\nimport type { StorageReader } from '../storage/storage-port';\n\nexport class CategoryGuard {\n\tconstructor(\n\t\tprivate readonly storage: StorageReader,\n\t\tprivate readonly category: string,\n\t) {}\n\n\tasync assert(key: string): Promise<void> {\n\t\tconst def = await this.storage.findAnyDef(key);\n\t\tif (def && def.category !== this.category) {\n\t\t\tthrow new CategoryError(key, this.category, def.category);\n\t\t}\n\t}\n\n\tasync assertAll(keys: Iterable<string>): Promise<void> {\n\t\tawait Promise.all([...keys].map((key) => this.assert(key)));\n\t}\n}\n","import type { Scope } from '../core/types';\nimport type { Resolver } from '../engine/resolver';\nimport type { CategoryGuard } from './category-guard';\nimport type { SettingScopeKind, SettingValue } from './registry';\n\nexport class TypedResolver<Registry> {\n\tconstructor(\n\t\tprivate readonly resolver: Resolver,\n\t\tprivate readonly fixedCategory?: string,\n\t\tprivate readonly guard?: CategoryGuard,\n\t) {}\n\n\tasync get<K extends keyof Registry & string>(\n\t\tkey: K,\n\t\tscope: Scope & { kind: SettingScopeKind<Registry, K> },\n\t\tasOf?: Date,\n\t): Promise<SettingValue<Registry, K>> {\n\t\tawait this.guard?.assert(key);\n\t\treturn this.resolver.get(key, scope, asOf) as Promise<\n\t\t\tSettingValue<Registry, K>\n\t\t>;\n\t}\n\n\tasync getMany<K extends readonly (keyof Registry & string)[]>(\n\t\tkeys: K,\n\t\tscope: Scope,\n\t\tasOf?: Date,\n\t): Promise<{ [P in K[number]]: SettingValue<Registry, P> }> {\n\t\tawait this.guard?.assertAll(keys);\n\t\tconst result = await this.resolver.getMany([...keys], scope, asOf);\n\t\treturn result as { [P in K[number]]: SettingValue<Registry, P> };\n\t}\n\n\tasync listAt(\n\t\tscope: Scope,\n\t\topts: { limit?: number; cursor?: string } = {},\n\t): Promise<{\n\t\tentries: Partial<{\n\t\t\t[K in keyof Registry & string]: SettingValue<Registry, K>;\n\t\t}>;\n\t\tnextCursor: string | null;\n\t}> {\n\t\tconst page = await this.resolver.listAt(scope, {\n\t\t\t...opts,\n\t\t\tcategory: this.fixedCategory,\n\t\t});\n\t\treturn page as {\n\t\t\tentries: Partial<{\n\t\t\t\t[K in keyof Registry & string]: SettingValue<Registry, K>;\n\t\t\t}>;\n\t\t\tnextCursor: string | null;\n\t\t};\n\t}\n}\n","import type { Scope, ValueRecord } from '../core/types';\nimport type { SetParams, Writer } from '../engine/writer';\nimport type { CategoryGuard } from './category-guard';\nimport type { SettingScopeKind, SettingValue } from './registry';\n\nexport interface TypedSetParams<Registry, K extends keyof Registry & string> {\n\tkey: K;\n\tscope: Scope & { kind: SettingScopeKind<Registry, K> };\n\tvalue: SettingValue<Registry, K>;\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nexport interface TypedUnsetParams<Registry, K extends keyof Registry & string> {\n\tkey: K;\n\tscope: Scope & { kind: SettingScopeKind<Registry, K> };\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nexport class TypedWriter<Registry> {\n\tconstructor(\n\t\tprivate readonly writer: Writer,\n\t\tprivate readonly guard?: CategoryGuard,\n\t) {}\n\n\tasync set<K extends keyof Registry & string>(\n\t\tparams: TypedSetParams<Registry, K>,\n\t): Promise<ValueRecord> {\n\t\tawait this.guard?.assert(params.key);\n\t\treturn this.writer.set(params as unknown as SetParams);\n\t}\n\n\tasync setMany(\n\t\tparamsList: {\n\t\t\t[K in keyof Registry & string]: TypedSetParams<Registry, K>;\n\t\t}[keyof Registry & string][],\n\t): Promise<ValueRecord[]> {\n\t\tawait this.guard?.assertAll(paramsList.map((p) => p.key));\n\t\treturn this.writer.setMany(paramsList as unknown as SetParams[]);\n\t}\n\n\tasync unset<K extends keyof Registry & string>(\n\t\tparams: TypedUnsetParams<Registry, K>,\n\t): Promise<void> {\n\t\tawait this.guard?.assert(params.key);\n\t\treturn this.writer.unset(params);\n\t}\n}\n","import type { Scope } from '../core/types';\nimport type { Auditor } from '../engine/auditor';\nimport type { AuditRecord } from '../storage/storage-port';\nimport type { CategoryGuard } from './category-guard';\nimport type { SettingScopeKind } from './registry';\n\nexport class TypedAuditor<Registry> {\n\tconstructor(\n\t\tprivate readonly auditor: Auditor,\n\t\tprivate readonly guard?: CategoryGuard,\n\t) {}\n\n\tasync history<K extends keyof Registry & string>(\n\t\tkey: K,\n\t\tscope?: Scope & { kind: SettingScopeKind<Registry, K> },\n\t): Promise<AuditRecord[]> {\n\t\tawait this.guard?.assert(key);\n\t\treturn this.auditor.history(key, scope);\n\t}\n}\n","import type { Engine } from '../engine/engine';\nimport { TypedResolver } from './typed-resolver';\nimport { TypedWriter } from './typed-writer';\nimport { TypedAuditor } from './typed-auditor';\nimport { CategoryGuard } from './category-guard';\nimport type { KeysInCategory } from './registry';\n\nexport interface TypedEngine<Registry> {\n\tresolver: TypedResolver<Registry>;\n\twriter: TypedWriter<Registry>;\n\tauditor: TypedAuditor<Registry>;\n\tcategory<C extends string>(\n\t\tcategory: C,\n\t): TypedEngine<KeysInCategory<Registry, C>>;\n}\n\nexport function createTypedEngine<Registry>(\n\tengine: Engine,\n): TypedEngine<Registry> {\n\tfunction build<R>(fixedCategory?: string): TypedEngine<R> {\n\t\tconst guard = fixedCategory\n\t\t\t? new CategoryGuard(engine.storage, fixedCategory)\n\t\t\t: undefined;\n\t\treturn {\n\t\t\tresolver: new TypedResolver<R>(\n\t\t\t\tengine.resolver,\n\t\t\t\tfixedCategory,\n\t\t\t\tguard,\n\t\t\t),\n\t\t\twriter: new TypedWriter<R>(engine.writer, guard),\n\t\t\tauditor: new TypedAuditor<R>(engine.auditor, guard),\n\t\t\tcategory: <C extends string>(category: C) =>\n\t\t\t\tbuild<KeysInCategory<R, C>>(category),\n\t\t};\n\t}\n\treturn build<Registry>();\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/core/errors.ts","../src/cache/change-bus.ts","../src/cache/cache.ts","../src/hierarchy/scope-hierarchy.ts","../src/storage/memory-storage.ts","../src/engine/resolver.ts","../src/engine/writer.ts","../src/engine/auditor.ts","../src/engine/hierarchy-cache-sync.ts","../src/engine/category-integrity.ts","../src/engine/engine.ts","../src/typed/category-guard.ts","../src/typed/typed-resolver.ts","../src/typed/typed-writer.ts","../src/typed/typed-auditor.ts","../src/typed/typed-engine.ts"],"sourcesContent":["export type JsonValue =\n\t| null\n\t| boolean\n\t| number\n\t| string\n\t| JsonValue[]\n\t| { [key: string]: JsonValue };\n\nexport type Value = Date | JsonValue;\n\nexport interface Scope {\n\tkind: string;\n\trefId: string | null;\n}\n\nexport const DEFAULT_SCOPE: Scope = { kind: 'default', refId: null };\n\nexport type ValueType =\n\t'BOOLEAN' | 'NUMERIC' | 'TEXT' | 'ENUM' | 'JSON' | 'DATE';\n\nexport type Inherit = 'LOCKED' | 'INHERITABLE_OVERRIDABLE' | 'INDEPENDENT';\n\nexport type Status = 'DRAFT' | 'STABLE' | 'DEPRECATED' | 'RETIRED';\n\nexport interface DefRecord {\n\tid: string;\n\tkey: string;\n\tversion: number;\n\tlabel: string;\n\tdescription: string | null;\n\ttype: ValueType;\n\toptions: string[];\n\tmin: number | null;\n\tmax: number | null;\n\tscopes: string[];\n\tinherit: Inherit;\n\trequired: boolean;\n\tsecret: boolean;\n\tstatus: Status;\n\tcategory: string | null;\n}\n\nexport interface ValueRecord {\n\tid: string;\n\tdefinitionId: string;\n\tscopeKind: string;\n\tscopeRefId: string | null;\n\tbool: boolean | null;\n\tnum: number | null;\n\ttext: string | null;\n\tjson: unknown;\n\tjsonSet: boolean;\n\tdate: Date | null;\n\tversion: number;\n}\n\nexport interface ScopeHierarchy {\n\tchain(scopeRefId: string): Promise<string[]>;\n\tdescendants(scopeRefId: string): Promise<string[]>;\n\tchildren(scopeRefId: string): Promise<string[]>;\n\tparent(scopeRefId: string): Promise<string | null>;\n\tattach(id: string, parentId: string | null): Promise<void>;\n\tmove(id: string, newParentId: string | null): Promise<void>;\n\tdetach(id: string): Promise<void>;\n}\n","export type ErrorCode =\n\t| 'NOT_FOUND'\n\t| 'SCOPE'\n\t| 'REQUIRED'\n\t| 'VALUE'\n\t| 'CONFLICT'\n\t| 'CORRUPT'\n\t| 'CYCLE'\n\t| 'CATEGORY';\n\nexport class ConfTreeError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly code: ErrorCode,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = new.target.name;\n\t\tError.captureStackTrace?.(this, new.target);\n\t}\n}\n\nexport class NotFoundError extends ConfTreeError {\n\tconstructor(key: string) {\n\t\tsuper(`Unknown setting definition: \"${key}\"`, 'NOT_FOUND');\n\t}\n}\n\nexport class ScopeError extends ConfTreeError {\n\tconstructor(key: string, scopeKind: string) {\n\t\tsuper(\n\t\t\t`Setting \"${key}\" cannot be set or read at scope kind \"${scopeKind}\"`,\n\t\t\t'SCOPE',\n\t\t);\n\t}\n}\n\nexport class RequiredError extends ConfTreeError {\n\tconstructor(key: string, scopeKind: string, scopeRefId: string | null) {\n\t\tsuper(\n\t\t\t`Required setting \"${key}\" has no resolvable value for scope ${scopeKind}:${scopeRefId ?? 'null'} ` +\n\t\t\t\t`and no default is defined`,\n\t\t\t'REQUIRED',\n\t\t);\n\t}\n}\n\nexport class ValueError extends ConfTreeError {\n\tconstructor(message: string) {\n\t\tsuper(message, 'VALUE');\n\t}\n}\n\nexport class ConflictError extends ConfTreeError {\n\tconstructor(key: string, scopeKind: string, scopeRefId: string | null) {\n\t\tsuper(\n\t\t\t`Setting \"${key}\" at scope ${scopeKind}:${scopeRefId ?? 'null'} was modified concurrently. ` +\n\t\t\t\t`Reload the current value and retry.`,\n\t\t\t'CONFLICT',\n\t\t);\n\t}\n}\n\nexport class CorruptError extends ConfTreeError {\n\tconstructor(valueId: string) {\n\t\tsuper(\n\t\t\t`setting value row ${valueId} has no typed value set: data corruption`,\n\t\t\t'CORRUPT',\n\t\t);\n\t}\n}\n\nexport class CycleError extends ConfTreeError {\n\tconstructor(id: string, newParentId: string) {\n\t\tsuper(\n\t\t\t`Cannot attach/move scope \"${id}\" under \"${newParentId}\": would create a cycle`,\n\t\t\t'CYCLE',\n\t\t);\n\t}\n}\n\nexport class CategoryError extends ConfTreeError {\n\tconstructor(\n\t\tkey: string,\n\t\texpectedCategory: string | null,\n\t\tactualCategory: string | null,\n\t) {\n\t\tsuper(\n\t\t\t`Setting \"${key}\" has category \"${actualCategory ?? 'none'}\", which does not match \"${expectedCategory ?? 'none'}\"`,\n\t\t\t'CATEGORY',\n\t\t);\n\t}\n}\n","export interface ChangeEvent {\n\tdefinitionId: string;\n\tkey: string;\n\tscopeKind: string;\n\tscopeRefId: string | null;\n}\n\nexport type ChangeListener = (event: ChangeEvent) => void | Promise<void>;\n\nexport interface ChangeBus {\n\tpublish(event: ChangeEvent): Promise<void>;\n\tsubscribe(listener: ChangeListener): void;\n\tunsubscribe(listener: ChangeListener): void;\n}\n\nexport class LocalBus implements ChangeBus {\n\tprivate readonly listeners = new Set<ChangeListener>();\n\n\tasync publish(event: ChangeEvent): Promise<void> {\n\t\tawait Promise.all(\n\t\t\t[...this.listeners].map((listener) =>\n\t\t\t\tPromise.resolve(listener(event)),\n\t\t\t),\n\t\t);\n\t}\n\n\tsubscribe(listener: ChangeListener): void {\n\t\tthis.listeners.add(listener);\n\t}\n\n\tunsubscribe(listener: ChangeListener): void {\n\t\tthis.listeners.delete(listener);\n\t}\n}\n","import type { Scope, ScopeHierarchy, Value } from '../core/types';\nimport type { ChangeBus, ChangeEvent, ChangeListener } from './change-bus';\n\nexport interface CacheOptions {\n\tenabled?: boolean;\n\tttlMs?: number;\n\tmaxEntries?: number;\n}\n\ninterface Entry {\n\tkey: string;\n\tscopeKind: string;\n\tscopeRefId: string | null;\n\tvalue: Value;\n\texpiresAt: number;\n}\n\nconst DEFAULT_TTL_MS = 30_000;\nconst DEFAULT_MAX_ENTRIES = 50_000;\n\nexport class Cache {\n\tprivate readonly store = new Map<string, Entry>();\n\tprivate readonly listener: ChangeListener = (event) => this.onChange(event);\n\n\tconstructor(\n\t\tprivate readonly bus: ChangeBus,\n\t\tprivate readonly options: CacheOptions = {},\n\t\tprivate readonly hierarchy?: ScopeHierarchy,\n\t) {\n\t\tthis.bus.subscribe(this.listener);\n\t}\n\n\tdispose(): void {\n\t\tthis.bus.unsubscribe(this.listener);\n\t}\n\n\tget(key: string, scope: Scope): Value | undefined {\n\t\tif (this.options.enabled === false) return undefined;\n\t\tconst cacheKey = this.keyFor(key, scope);\n\t\tconst entry = this.store.get(cacheKey);\n\t\tif (!entry) return undefined;\n\t\tif (entry.expiresAt <= Date.now()) {\n\t\t\tthis.store.delete(cacheKey);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn entry.value;\n\t}\n\n\tset(key: string, scope: Scope, value: Value): void {\n\t\tif (this.options.enabled === false) return;\n\t\tconst cacheKey = this.keyFor(key, scope);\n\t\tif (\n\t\t\t!this.store.has(cacheKey) &&\n\t\t\tthis.store.size >= (this.options.maxEntries ?? DEFAULT_MAX_ENTRIES)\n\t\t) {\n\t\t\tconst oldest = this.store.keys().next().value;\n\t\t\tif (oldest !== undefined) this.store.delete(oldest);\n\t\t}\n\t\tconst ttlMs = this.options.ttlMs ?? DEFAULT_TTL_MS;\n\t\tthis.store.set(cacheKey, {\n\t\t\tkey,\n\t\t\tscopeKind: scope.kind,\n\t\t\tscopeRefId: scope.refId,\n\t\t\tvalue,\n\t\t\texpiresAt: Date.now() + ttlMs,\n\t\t});\n\t}\n\n\tdrop(key: string): void {\n\t\tfor (const [cacheKey, entry] of this.store) {\n\t\t\tif (entry.key === key) this.store.delete(cacheKey);\n\t\t}\n\t}\n\n\tdropAll(): void {\n\t\tthis.store.clear();\n\t}\n\n\tdropForScopes(scopeRefIds: Iterable<string>): void {\n\t\tconst targets = new Set(scopeRefIds);\n\t\tif (targets.size === 0) return;\n\t\tfor (const [cacheKey, entry] of this.store) {\n\t\t\tif (entry.scopeRefId !== null && targets.has(entry.scopeRefId)) {\n\t\t\t\tthis.store.delete(cacheKey);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate dropScoped(key: string, scopeRefIds: Iterable<string>): void {\n\t\tconst targets = new Set(scopeRefIds);\n\t\tfor (const [cacheKey, entry] of this.store) {\n\t\t\tif (\n\t\t\t\tentry.key === key &&\n\t\t\t\tentry.scopeRefId !== null &&\n\t\t\t\ttargets.has(entry.scopeRefId)\n\t\t\t) {\n\t\t\t\tthis.store.delete(cacheKey);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async onChange(event: ChangeEvent): Promise<void> {\n\t\tif (this.hierarchy && event.scopeRefId !== null) {\n\t\t\tconst descendants = await this.hierarchy\n\t\t\t\t.descendants(event.scopeRefId)\n\t\t\t\t.catch(() => null);\n\t\t\tif (descendants !== null) {\n\t\t\t\tthis.dropScoped(event.key, descendants);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.drop(event.key);\n\t}\n\n\tprivate keyFor(key: string, scope: Scope): string {\n\t\treturn JSON.stringify([key, scope.kind, scope.refId]);\n\t}\n}\n","import { CycleError } from '../core/errors';\nimport type { ScopeHierarchy } from '../core/types';\n\nexport class LocalScopeHierarchy implements ScopeHierarchy {\n\tprivate readonly parentOf = new Map<string, string | null>();\n\tprivate readonly childrenOf = new Map<string, Set<string>>();\n\n\tasync chain(id: string): Promise<string[]> {\n\t\tconst result: string[] = [];\n\t\tconst seen = new Set<string>();\n\t\tlet current: string | null = id;\n\t\twhile (current !== null) {\n\t\t\tif (seen.has(current)) break;\n\t\t\tseen.add(current);\n\t\t\tresult.push(current);\n\t\t\tcurrent = this.parentOf.get(current) ?? null;\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync descendants(id: string): Promise<string[]> {\n\t\tconst result: string[] = [];\n\t\tconst stack = [id];\n\t\tconst seen = new Set<string>();\n\t\twhile (stack.length > 0) {\n\t\t\tconst current = stack.pop()!;\n\t\t\tif (seen.has(current)) continue;\n\t\t\tseen.add(current);\n\t\t\tresult.push(current);\n\t\t\tconst kids = this.childrenOf.get(current);\n\t\t\tif (kids) stack.push(...kids);\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync children(id: string): Promise<string[]> {\n\t\treturn [...(this.childrenOf.get(id) ?? [])];\n\t}\n\n\tasync parent(id: string): Promise<string | null> {\n\t\treturn this.parentOf.get(id) ?? null;\n\t}\n\n\tasync attach(id: string, parentId: string | null): Promise<void> {\n\t\tif (parentId !== null) await this.assertNoCycle(id, parentId);\n\t\tconst oldParent = this.parentOf.get(id) ?? null;\n\t\tif (oldParent !== null) this.childrenOf.get(oldParent)?.delete(id);\n\t\tthis.parentOf.set(id, parentId);\n\t\tif (parentId !== null) this.addChild(parentId, id);\n\t\tif (!this.childrenOf.has(id)) this.childrenOf.set(id, new Set());\n\t}\n\n\tasync move(id: string, newParentId: string | null): Promise<void> {\n\t\tif (newParentId !== null) await this.assertNoCycle(id, newParentId);\n\t\tconst oldParent = this.parentOf.get(id) ?? null;\n\t\tif (oldParent !== null) this.childrenOf.get(oldParent)?.delete(id);\n\t\tthis.parentOf.set(id, newParentId);\n\t\tif (newParentId !== null) this.addChild(newParentId, id);\n\t}\n\n\tasync detach(id: string): Promise<void> {\n\t\tconst parentId = this.parentOf.get(id) ?? null;\n\t\tconst kids = [...(this.childrenOf.get(id) ?? [])];\n\t\tfor (const kid of kids) {\n\t\t\tawait this.move(kid, parentId);\n\t\t}\n\t\tif (parentId !== null) this.childrenOf.get(parentId)?.delete(id);\n\t\tthis.parentOf.delete(id);\n\t\tthis.childrenOf.delete(id);\n\t}\n\n\tprivate addChild(parentId: string, id: string): void {\n\t\tif (!this.childrenOf.has(parentId))\n\t\t\tthis.childrenOf.set(parentId, new Set());\n\t\tthis.childrenOf.get(parentId)!.add(id);\n\t}\n\n\tprivate async assertNoCycle(\n\t\tid: string,\n\t\tnewParentId: string,\n\t): Promise<void> {\n\t\tif (\n\t\t\tid === newParentId ||\n\t\t\t(await this.chain(newParentId)).includes(id)\n\t\t) {\n\t\t\tthrow new CycleError(id, newParentId);\n\t\t}\n\t}\n}\n","import type {\n\tAuditRecord,\n\tCreateAuditInput,\n\tCreateDefInput,\n\tCreateValueInput,\n\tFindAuditQuery,\n\tFindChainQuery,\n\tFindValuesQuery,\n\tListValuesQuery,\n\tListValuesResult,\n\tStorageAdapter,\n\tStorageTx,\n} from './storage-port';\nimport type {\n\tDefRecord,\n\tStatus,\n\tValue,\n\tValueRecord,\n\tValueType,\n} from '../core/types';\nimport { NotFoundError } from '../core/errors';\n\ninterface StoredValue extends ValueRecord {\n\tvalidFrom: Date;\n\tvalidTo: Date | null;\n}\n\nfunction toTypedColumns(type: ValueType, value: Value) {\n\treturn {\n\t\tbool: type === 'BOOLEAN' ? (value as boolean) : null,\n\t\tnum: type === 'NUMERIC' ? (value as number) : null,\n\t\ttext: type === 'TEXT' || type === 'ENUM' ? (value as string) : null,\n\t\tjson: type === 'JSON' ? value : null,\n\t\tjsonSet: type === 'JSON',\n\t\tdate: type === 'DATE' ? (value as Date) : null,\n\t};\n}\n\nexport class MemoryStorageAdapter implements StorageAdapter {\n\tprivate defs: DefRecord[] = [];\n\tprivate values: StoredValue[] = [];\n\tprivate auditLog: AuditRecord[] = [];\n\tprivate nextId = 1;\n\tprivate txQueue: Promise<unknown> = Promise.resolve();\n\n\tprivate newId(prefix: string): string {\n\t\treturn `${prefix}-${this.nextId++}`;\n\t}\n\n\tasync findDefs(keys: string[]): Promise<DefRecord[]> {\n\t\tconst result: DefRecord[] = [];\n\t\tfor (const key of keys) {\n\t\t\tconst found = this.latestByStatus(key, ['STABLE', 'DEPRECATED']);\n\t\t\tif (found) result.push(found);\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync findValues(query: FindValuesQuery): Promise<ValueRecord[]> {\n\t\tconst asOf = query.asOf ?? new Date();\n\t\tconst ids = new Set(query.definitionIds);\n\t\treturn this.values.filter(\n\t\t\t(v) =>\n\t\t\t\tids.has(v.definitionId) &&\n\t\t\t\tv.scopeKind === query.scopeKind &&\n\t\t\t\tv.scopeRefId === query.scopeRefId &&\n\t\t\t\tv.validFrom <= asOf &&\n\t\t\t\t(v.validTo === null || v.validTo > asOf),\n\t\t);\n\t}\n\n\tasync findChainValues(query: FindChainQuery): Promise<ValueRecord[]> {\n\t\tconst asOf = query.asOf ?? new Date();\n\t\tconst defIds = new Set(query.definitionIds);\n\t\tconst refIds = new Set(query.chain);\n\t\treturn this.values.filter(\n\t\t\t(v) =>\n\t\t\t\tdefIds.has(v.definitionId) &&\n\t\t\t\tv.scopeRefId !== null &&\n\t\t\t\trefIds.has(v.scopeRefId) &&\n\t\t\t\tv.validFrom <= asOf &&\n\t\t\t\t(v.validTo === null || v.validTo > asOf),\n\t\t);\n\t}\n\n\tasync findDefsByIds(ids: string[]): Promise<DefRecord[]> {\n\t\tconst idSet = new Set(ids);\n\t\treturn this.defs.filter((d) => idSet.has(d.id));\n\t}\n\n\tasync findAnyDef(key: string): Promise<DefRecord | null> {\n\t\treturn this.latestVersion(key) ?? null;\n\t}\n\n\tasync listValues(query: ListValuesQuery): Promise<ListValuesResult> {\n\t\tconst now = new Date();\n\t\tconst categoryDefIds =\n\t\t\tquery.category !== undefined\n\t\t\t\t? new Set(\n\t\t\t\t\t\tthis.defs\n\t\t\t\t\t\t\t.filter((d) => d.category === query.category)\n\t\t\t\t\t\t\t.map((d) => d.id),\n\t\t\t\t\t)\n\t\t\t\t: null;\n\t\tconst active = this.values\n\t\t\t.filter(\n\t\t\t\t(v) =>\n\t\t\t\t\tv.scopeKind === query.scopeKind &&\n\t\t\t\t\tv.scopeRefId === query.scopeRefId &&\n\t\t\t\t\t(categoryDefIds === null ||\n\t\t\t\t\t\tcategoryDefIds.has(v.definitionId)) &&\n\t\t\t\t\tv.validFrom <= now &&\n\t\t\t\t\t(v.validTo === null || v.validTo > now),\n\t\t\t)\n\t\t\t.sort((a, b) => a.id.localeCompare(b.id));\n\n\t\tconst startIndex = query.cursor\n\t\t\t? active.findIndex((v) => v.id === query.cursor) + 1\n\t\t\t: 0;\n\t\tconst limit = query.limit ?? active.length - startIndex;\n\t\tconst page = active.slice(startIndex, startIndex + limit);\n\t\tconst nextCursor =\n\t\t\tstartIndex + page.length < active.length\n\t\t\t\t? (page[page.length - 1]?.id ?? null)\n\t\t\t\t: null;\n\n\t\treturn { values: page, nextCursor };\n\t}\n\n\tasync findAudit(query: FindAuditQuery): Promise<AuditRecord[]> {\n\t\treturn this.auditLog\n\t\t\t.filter(\n\t\t\t\t(a) =>\n\t\t\t\t\ta.definitionId === query.definitionId &&\n\t\t\t\t\t(query.scopeKind === undefined ||\n\t\t\t\t\t\ta.scopeKind === query.scopeKind) &&\n\t\t\t\t\t(query.scopeRefId === undefined ||\n\t\t\t\t\t\ta.scopeRefId === query.scopeRefId),\n\t\t\t)\n\t\t\t.sort((a, b) => a.at.getTime() - b.at.getTime());\n\t}\n\n\tasync createDef(input: CreateDefInput): Promise<DefRecord> {\n\t\tconst existingVersions = this.defs.filter((d) => d.key === input.key);\n\t\tconst version =\n\t\t\texistingVersions.length > 0\n\t\t\t\t? Math.max(...existingVersions.map((d) => d.version)) + 1\n\t\t\t\t: 1;\n\t\tconst record: DefRecord = {\n\t\t\tid: this.newId('def'),\n\t\t\tkey: input.key,\n\t\t\tversion,\n\t\t\tlabel: input.label,\n\t\t\tdescription: input.description ?? null,\n\t\t\ttype: input.type,\n\t\t\toptions: input.options ?? [],\n\t\t\tmin: input.min ?? null,\n\t\t\tmax: input.max ?? null,\n\t\t\tscopes: input.scopes,\n\t\t\tinherit: input.inherit,\n\t\t\trequired: input.required,\n\t\t\tsecret: input.secret ?? false,\n\t\t\tstatus: input.status ?? 'DRAFT',\n\t\t\tcategory: input.category ?? null,\n\t\t};\n\t\tthis.defs.push(record);\n\t\treturn record;\n\t}\n\n\tasync updateDefStatus(key: string, status: Status): Promise<DefRecord> {\n\t\tconst current = this.latestVersion(key);\n\t\tif (!current) throw new NotFoundError(key);\n\n\t\tconst updated: DefRecord = { ...current, status };\n\t\tthis.defs = this.defs.map((d) => (d === current ? updated : d));\n\t\treturn updated;\n\t}\n\n\tasync listDefs(status?: Status, category?: string): Promise<DefRecord[]> {\n\t\tconst rows = this.allLatestVersions().filter(\n\t\t\t(d) =>\n\t\t\t\t(status === undefined || d.status === status) &&\n\t\t\t\t(category === undefined || d.category === category),\n\t\t);\n\t\treturn rows.sort(\n\t\t\t(a, b) =>\n\t\t\t\t(a.category ?? '').localeCompare(b.category ?? '') ||\n\t\t\t\ta.key.localeCompare(b.key),\n\t\t);\n\t}\n\n\tasync listCategories(): Promise<string[]> {\n\t\tconst categories = new Set(\n\t\t\tthis.allLatestVersions()\n\t\t\t\t.map((d) => d.category)\n\t\t\t\t.filter((c): c is string => c !== null),\n\t\t);\n\t\treturn [...categories].sort();\n\t}\n\n\tasync transact<T>(fn: (tx: StorageTx) => Promise<T>): Promise<T> {\n\t\tconst run = this.txQueue.then(async () => {\n\t\t\tconst valuesSnapshot = structuredClone(this.values);\n\t\t\tconst auditLogSnapshot = structuredClone(this.auditLog);\n\t\t\ttry {\n\t\t\t\treturn await fn(this.tx());\n\t\t\t} catch (err) {\n\t\t\t\tthis.values = valuesSnapshot;\n\t\t\t\tthis.auditLog = auditLogSnapshot;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t});\n\t\tthis.txQueue = run.catch(() => {});\n\t\treturn run;\n\t}\n\n\tprivate latestByStatus(\n\t\tkey: string,\n\t\tstatuses: Status[],\n\t): DefRecord | undefined {\n\t\tconst latest = this.latestVersion(key);\n\t\treturn latest && statuses.includes(latest.status) ? latest : undefined;\n\t}\n\n\tprivate latestVersion(key: string): DefRecord | undefined {\n\t\treturn this.defs\n\t\t\t.filter((d) => d.key === key)\n\t\t\t.sort((a, b) => b.version - a.version)[0];\n\t}\n\n\tprivate allLatestVersions(): DefRecord[] {\n\t\tconst byKey = new Map<string, DefRecord>();\n\t\tfor (const d of this.defs) {\n\t\t\tconst current = byKey.get(d.key);\n\t\t\tif (!current || d.version > current.version) byKey.set(d.key, d);\n\t\t}\n\t\treturn [...byKey.values()];\n\t}\n\n\tprivate tx(): StorageTx {\n\t\treturn {\n\t\t\tfindDef: async (key: string) =>\n\t\t\t\tthis.latestByStatus(key, ['STABLE']) ?? null,\n\n\t\t\tfindValue: async (definitionId, scopeKind, scopeRefId) =>\n\t\t\t\tthis.values.find(\n\t\t\t\t\t(v) =>\n\t\t\t\t\t\tv.definitionId === definitionId &&\n\t\t\t\t\t\tv.scopeKind === scopeKind &&\n\t\t\t\t\t\tv.scopeRefId === scopeRefId &&\n\t\t\t\t\t\tv.validTo === null,\n\t\t\t\t) ?? null,\n\n\t\t\tcloseValue: async (id: string) => {\n\t\t\t\tconst row = this.values.find((v) => v.id === id);\n\t\t\t\tif (!row) return;\n\t\t\t\tconst closed: StoredValue = { ...row, validTo: new Date() };\n\t\t\t\tthis.values = this.values.map((v) => (v === row ? closed : v));\n\t\t\t},\n\n\t\t\tcreateValue: async (input: CreateValueInput) => {\n\t\t\t\tconst record: StoredValue = {\n\t\t\t\t\tid: this.newId('val'),\n\t\t\t\t\tdefinitionId: input.definitionId,\n\t\t\t\t\tscopeKind: input.scopeKind,\n\t\t\t\t\tscopeRefId: input.scopeRefId,\n\t\t\t\t\tversion: input.version,\n\t\t\t\t\tvalidFrom: new Date(),\n\t\t\t\t\tvalidTo: null,\n\t\t\t\t\t...toTypedColumns(input.type, input.value),\n\t\t\t\t};\n\t\t\t\tthis.values.push(record);\n\t\t\t\treturn record;\n\t\t\t},\n\n\t\t\tcreateAudit: async (input: CreateAuditInput): Promise<void> => {\n\t\t\t\tthis.auditLog.push({\n\t\t\t\t\t...input,\n\t\t\t\t\tid: this.newId('audit'),\n\t\t\t\t\tat: new Date(),\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n}\n","import type {\n\tDefRecord,\n\tScope,\n\tScopeHierarchy,\n\tValue,\n\tValueRecord,\n} from '../core/types';\nimport { DEFAULT_SCOPE } from '../core/types';\nimport {\n\tCorruptError,\n\tRequiredError,\n\tScopeError,\n\tNotFoundError,\n} from '../core/errors';\nimport type { StorageReader } from '../storage/storage-port';\nimport type { Cache } from '../cache/cache';\n\nexport interface ListAtPage {\n\tentries: Record<string, Value>;\n\tnextCursor: string | null;\n}\n\nexport class Resolver {\n\tconstructor(\n\t\tprivate readonly storage: StorageReader,\n\t\tprivate readonly hierarchy?: ScopeHierarchy,\n\t\tprivate readonly cache?: Cache,\n\t) {}\n\n\tasync get(key: string, scope: Scope, asOf?: Date): Promise<Value> {\n\t\tconst result = await this.getMany([key], scope, asOf);\n\t\treturn result[key];\n\t}\n\n\tasync listAt(\n\t\tscope: Scope,\n\t\topts: { limit?: number; cursor?: string; category?: string } = {},\n\t): Promise<ListAtPage> {\n\t\tconst { values, nextCursor } = await this.storage.listValues({\n\t\t\tscopeKind: scope.kind,\n\t\t\tscopeRefId: scope.refId,\n\t\t\tcategory: opts.category,\n\t\t\tlimit: opts.limit,\n\t\t\tcursor: opts.cursor,\n\t\t});\n\t\tif (values.length === 0) return { entries: {}, nextCursor };\n\n\t\tconst defs = await this.storage.findDefsByIds([\n\t\t\t...new Set(values.map((v) => v.definitionId)),\n\t\t]);\n\t\tconst defById = new Map(defs.map((d) => [d.id, d]));\n\n\t\tconst entries: Record<string, Value> = {};\n\t\tfor (const row of values) {\n\t\t\tconst def = defById.get(row.definitionId);\n\t\t\tif (!def) continue;\n\t\t\tentries[def.key] = this.unwrap(def, row);\n\t\t}\n\t\treturn { entries, nextCursor };\n\t}\n\n\tasync getMany(\n\t\tkeys: string[],\n\t\tscope: Scope,\n\t\tasOf?: Date,\n\t): Promise<Record<string, Value>> {\n\t\tconst uniqueKeys = [...new Set(keys)];\n\t\tconst result: Record<string, Value> = {};\n\t\tconst uncached: string[] = [];\n\n\t\tif (asOf === undefined) {\n\t\t\tfor (const key of uniqueKeys) {\n\t\t\t\tconst cached = this.cache?.get(key, scope);\n\t\t\t\tif (cached !== undefined) result[key] = cached;\n\t\t\t\telse uncached.push(key);\n\t\t\t}\n\t\t} else {\n\t\t\tuncached.push(...uniqueKeys);\n\t\t}\n\t\tif (uncached.length === 0) return result;\n\n\t\tconst defByKey = await this.getDefs(uncached);\n\t\tfor (const key of uncached) {\n\t\t\tthis.checkScope(defByKey.get(key)!, scope);\n\t\t}\n\n\t\tconst exactDefs: DefRecord[] = [];\n\t\tconst chainDefs: DefRecord[] = [];\n\t\tfor (const key of uncached) {\n\t\t\tconst def = defByKey.get(key)!;\n\t\t\tconst climbsHierarchy =\n\t\t\t\tdef.inherit !== 'INDEPENDENT' &&\n\t\t\t\tscope.refId !== null &&\n\t\t\t\tthis.hierarchy;\n\t\t\t(climbsHierarchy ? chainDefs : exactDefs).push(def);\n\t\t}\n\n\t\tconst chain =\n\t\t\tchainDefs.length > 0 && scope.refId !== null && this.hierarchy\n\t\t\t\t? await this.hierarchy.chain(scope.refId)\n\t\t\t\t: [];\n\n\t\tconst [exactRows, chainRows] = await Promise.all([\n\t\t\texactDefs.length > 0\n\t\t\t\t? this.storage.findValues({\n\t\t\t\t\t\tdefinitionIds: exactDefs.map((d) => d.id),\n\t\t\t\t\t\tscopeKind: scope.kind,\n\t\t\t\t\t\tscopeRefId: scope.refId,\n\t\t\t\t\t\tasOf,\n\t\t\t\t\t})\n\t\t\t\t: Promise.resolve([] as ValueRecord[]),\n\t\t\tchainDefs.length > 0 && chain.length > 0\n\t\t\t\t? this.storage.findChainValues({\n\t\t\t\t\t\tdefinitionIds: chainDefs.map((d) => d.id),\n\t\t\t\t\t\tchain,\n\t\t\t\t\t\tasOf,\n\t\t\t\t\t})\n\t\t\t\t: Promise.resolve([] as ValueRecord[]),\n\t\t]);\n\n\t\tconst exactByDef = new Map(exactRows.map((r) => [r.definitionId, r]));\n\t\tconst chainByDef = new Map<string, ValueRecord[]>();\n\t\tfor (const row of chainRows) {\n\t\t\tconst list = chainByDef.get(row.definitionId) ?? [];\n\t\t\tlist.push(row);\n\t\t\tchainByDef.set(row.definitionId, list);\n\t\t}\n\t\tconst chainDefIds = new Set(chainDefs.map((d) => d.id));\n\n\t\tconst missing: DefRecord[] = [];\n\t\tfor (const key of uncached) {\n\t\t\tconst def = defByKey.get(key)!;\n\t\t\tlet row: ValueRecord | undefined;\n\t\t\tif (chainDefIds.has(def.id)) {\n\t\t\t\tconst byRef = new Map(\n\t\t\t\t\t(chainByDef.get(def.id) ?? []).map((v) => [\n\t\t\t\t\t\tv.scopeRefId,\n\t\t\t\t\t\tv,\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t\tfor (const ref of chain) {\n\t\t\t\t\trow = byRef.get(ref);\n\t\t\t\t\tif (row) break;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trow = exactByDef.get(def.id);\n\t\t\t}\n\t\t\tif (row) {\n\t\t\t\tresult[key] = this.unwrap(def, row);\n\t\t\t\tif (asOf === undefined)\n\t\t\t\t\tthis.cache?.set(key, scope, result[key]);\n\t\t\t} else {\n\t\t\t\tmissing.push(def);\n\t\t\t}\n\t\t}\n\n\t\tif (missing.length > 0)\n\t\t\tawait this.resolveMissing(\n\t\t\t\tmissing,\n\t\t\t\tscope,\n\t\t\t\tuncached,\n\t\t\t\tdefByKey,\n\t\t\t\tresult,\n\t\t\t\tasOf,\n\t\t\t);\n\n\t\treturn result;\n\t}\n\n\tprivate async resolveMissing(\n\t\tmissing: DefRecord[],\n\t\tscope: Scope,\n\t\tkeysInOrder: string[],\n\t\tdefByKey: Map<string, DefRecord>,\n\t\tresult: Record<string, Value>,\n\t\tasOf?: Date,\n\t): Promise<void> {\n\t\tconst defaultRows = await this.storage.findValues({\n\t\t\tdefinitionIds: missing.map((d) => d.id),\n\t\t\tscopeKind: DEFAULT_SCOPE.kind,\n\t\t\tscopeRefId: DEFAULT_SCOPE.refId,\n\t\t\tasOf,\n\t\t});\n\t\tconst defaultByDef = new Map(\n\t\t\tdefaultRows.map((r) => [r.definitionId, r]),\n\t\t);\n\t\tconst missingIds = new Set(missing.map((d) => d.id));\n\n\t\tfor (const key of keysInOrder) {\n\t\t\tconst def = defByKey.get(key)!;\n\t\t\tif (!missingIds.has(def.id)) continue;\n\t\t\tconst row = defaultByDef.get(def.id);\n\t\t\tif (!row) {\n\t\t\t\tthrow new RequiredError(def.key, scope.kind, scope.refId);\n\t\t\t}\n\t\t\tresult[key] = this.unwrap(def, row);\n\t\t\tif (asOf === undefined) this.cache?.set(key, scope, result[key]);\n\t\t}\n\t}\n\n\tprivate async getDefs(keys: string[]): Promise<Map<string, DefRecord>> {\n\t\tconst defs = await this.storage.findDefs(keys);\n\t\tconst byKey = new Map(defs.map((d) => [d.key, d]));\n\t\tfor (const key of keys) {\n\t\t\tif (!byKey.has(key)) throw new NotFoundError(key);\n\t\t}\n\t\treturn byKey;\n\t}\n\n\tprivate checkScope(def: DefRecord, scope: Scope): void {\n\t\tif (scope.kind === 'default') return;\n\t\tif (!def.scopes.includes(scope.kind)) {\n\t\t\tthrow new ScopeError(def.key, scope.kind);\n\t\t}\n\t}\n\n\tprivate unwrap(def: DefRecord, row: ValueRecord): Value {\n\t\tswitch (def.type) {\n\t\t\tcase 'BOOLEAN':\n\t\t\t\tif (row.bool === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.bool;\n\t\t\tcase 'NUMERIC':\n\t\t\t\tif (row.num === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.num;\n\t\t\tcase 'TEXT':\n\t\t\tcase 'ENUM':\n\t\t\t\tif (row.text === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.text;\n\t\t\tcase 'JSON':\n\t\t\t\tif (!row.jsonSet) throw new CorruptError(row.id);\n\t\t\t\treturn row.json as Value;\n\t\t\tcase 'DATE':\n\t\t\t\tif (row.date === null) throw new CorruptError(row.id);\n\t\t\t\treturn row.date;\n\t\t}\n\t}\n}\n","import type { DefRecord, Scope, Value, ValueRecord } from '../core/types';\nimport {\n\tConflictError,\n\tScopeError,\n\tValueError,\n\tNotFoundError,\n} from '../core/errors';\nimport type { StorageAdapter, StorageTx } from '../storage/storage-port';\nimport type { ChangeBus } from '../cache/change-bus';\n\nexport interface SetParams {\n\tkey: string;\n\tscope: Scope;\n\tvalue: Value;\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nexport interface UnsetParams {\n\tkey: string;\n\tscope: Scope;\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nconst REDACTED = '[redacted]';\n\nexport class Writer {\n\tconstructor(\n\t\tprivate readonly storage: StorageAdapter,\n\t\tprivate readonly bus?: ChangeBus,\n\t) {}\n\n\tasync set(params: SetParams): Promise<ValueRecord> {\n\t\tconst created = await this.storage.transact((tx) =>\n\t\t\tthis.setInTx(tx, params),\n\t\t);\n\t\tawait this.emit(created, params.key);\n\t\treturn created;\n\t}\n\n\tasync setMany(paramsList: SetParams[]): Promise<ValueRecord[]> {\n\t\tconst created = await this.storage.transact(async (tx) => {\n\t\t\tconst results: ValueRecord[] = [];\n\t\t\tfor (const params of paramsList) {\n\t\t\t\tresults.push(await this.setInTx(tx, params));\n\t\t\t}\n\t\t\treturn results;\n\t\t});\n\t\tawait Promise.all(\n\t\t\tcreated.map((row, i) => this.emit(row, paramsList[i].key)),\n\t\t);\n\t\treturn created;\n\t}\n\n\tprivate async setInTx(\n\t\ttx: StorageTx,\n\t\tparams: SetParams,\n\t): Promise<ValueRecord> {\n\t\tconst def = await tx.findDef(params.key);\n\t\tif (!def) throw new NotFoundError(params.key);\n\n\t\tif (\n\t\t\tparams.scope.kind !== 'default' &&\n\t\t\t!def.scopes.includes(params.scope.kind)\n\t\t) {\n\t\t\tthrow new ScopeError(def.key, params.scope.kind);\n\t\t}\n\n\t\tthis.validate(def, params.value);\n\n\t\tconst current = await tx.findValue(\n\t\t\tdef.id,\n\t\t\tparams.scope.kind,\n\t\t\tparams.scope.refId,\n\t\t);\n\n\t\tconst currentVersion = current?.version ?? 0;\n\t\tconst expected = params.expectedVersion ?? 0;\n\t\tif (currentVersion !== expected) {\n\t\t\tthrow new ConflictError(\n\t\t\t\tdef.key,\n\t\t\t\tparams.scope.kind,\n\t\t\t\tparams.scope.refId,\n\t\t\t);\n\t\t}\n\n\t\tif (current) {\n\t\t\tawait tx.closeValue(current.id);\n\t\t}\n\n\t\tconst created = await tx.createValue({\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: params.scope.kind,\n\t\t\tscopeRefId: params.scope.refId,\n\t\t\tversion: currentVersion + 1,\n\t\t\tauthorId: params.authorId,\n\t\t\treason: params.reason,\n\t\t\ttype: def.type,\n\t\t\tvalue: params.value,\n\t\t});\n\n\t\tawait tx.createAudit({\n\t\t\tvalueId: created.id,\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: created.scopeKind,\n\t\t\tscopeRefId: created.scopeRefId,\n\t\t\taction: current ? 'superseded' : 'created',\n\t\t\tauthorId: params.authorId,\n\t\t\tbefore: current ? this.snapshotOf(def, current) : undefined,\n\t\t\tafter: this.snapshotOf(def, created),\n\t\t\treason: params.reason,\n\t\t});\n\n\t\treturn created;\n\t}\n\n\tasync unset(params: UnsetParams): Promise<void> {\n\t\tconst closed = await this.storage.transact((tx) =>\n\t\t\tthis.unsetInTx(tx, params),\n\t\t);\n\t\tif (closed) await this.emit(closed, params.key);\n\t}\n\n\tprivate async unsetInTx(\n\t\ttx: StorageTx,\n\t\tparams: UnsetParams,\n\t): Promise<ValueRecord | null> {\n\t\tconst def = await tx.findDef(params.key);\n\t\tif (!def) throw new NotFoundError(params.key);\n\n\t\tif (\n\t\t\tparams.scope.kind !== 'default' &&\n\t\t\t!def.scopes.includes(params.scope.kind)\n\t\t) {\n\t\t\tthrow new ScopeError(def.key, params.scope.kind);\n\t\t}\n\n\t\tconst current = await tx.findValue(\n\t\t\tdef.id,\n\t\t\tparams.scope.kind,\n\t\t\tparams.scope.refId,\n\t\t);\n\n\t\tconst currentVersion = current?.version ?? 0;\n\t\tconst expected = params.expectedVersion ?? 0;\n\t\tif (currentVersion !== expected) {\n\t\t\tthrow new ConflictError(\n\t\t\t\tdef.key,\n\t\t\t\tparams.scope.kind,\n\t\t\t\tparams.scope.refId,\n\t\t\t);\n\t\t}\n\t\tif (!current) return null;\n\n\t\tawait tx.closeValue(current.id);\n\t\tawait tx.createAudit({\n\t\t\tvalueId: current.id,\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: current.scopeKind,\n\t\t\tscopeRefId: current.scopeRefId,\n\t\t\taction: 'unset',\n\t\t\tauthorId: params.authorId,\n\t\t\tbefore: this.snapshotOf(def, current),\n\t\t\treason: params.reason,\n\t\t});\n\n\t\treturn current;\n\t}\n\n\tprivate async emit(created: ValueRecord, key: string): Promise<void> {\n\t\ttry {\n\t\t\tawait this.bus?.publish({\n\t\t\t\tdefinitionId: created.definitionId,\n\t\t\t\tkey,\n\t\t\t\tscopeKind: created.scopeKind,\n\t\t\t\tscopeRefId: created.scopeRefId,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.error('conftree: change bus publish failed', err);\n\t\t}\n\t}\n\n\tprivate validate(def: DefRecord, value: Value): void {\n\t\tswitch (def.type) {\n\t\t\tcase 'BOOLEAN':\n\t\t\t\tif (typeof value !== 'boolean') {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a boolean`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'NUMERIC': {\n\t\t\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a finite number`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (def.min !== null && value < def.min) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" must be >= ${def.min}, got ${value}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (def.max !== null && value > def.max) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" must be <= ${def.max}, got ${value}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'TEXT':\n\t\t\t\tif (typeof value !== 'string') {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a string`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ENUM':\n\t\t\t\tif (typeof value !== 'string' || !def.options.includes(value)) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" must be one of: ${def.options.join(', ')}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'JSON': {\n\t\t\t\tlet serialized: string | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tserialized = JSON.stringify(value);\n\t\t\t\t} catch {\n\t\t\t\t\tserialized = undefined;\n\t\t\t\t}\n\t\t\t\tif (serialized === undefined) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a JSON-serializable value`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'DATE':\n\t\t\t\tif (!(value instanceof Date) || Number.isNaN(value.getTime())) {\n\t\t\t\t\tthrow new ValueError(\n\t\t\t\t\t\t`Setting \"${def.key}\" expects a valid Date`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate snapshotOf(def: DefRecord, row: ValueRecord) {\n\t\tif (def.secret) {\n\t\t\treturn {\n\t\t\t\tscopeKind: row.scopeKind,\n\t\t\t\tscopeRefId: row.scopeRefId,\n\t\t\t\tversion: row.version,\n\t\t\t\tvalue: REDACTED,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tscopeKind: row.scopeKind,\n\t\t\tscopeRefId: row.scopeRefId,\n\t\t\tversion: row.version,\n\t\t\tbool: row.bool,\n\t\t\tnum: row.num,\n\t\t\ttext: row.text,\n\t\t\tjson: row.jsonSet ? row.json : undefined,\n\t\t\tdate: row.date,\n\t\t};\n\t}\n}\n","import type { Scope } from '../core/types';\nimport { NotFoundError } from '../core/errors';\nimport type { AuditRecord, StorageReader } from '../storage/storage-port';\n\nexport class Auditor {\n\tconstructor(private readonly storage: StorageReader) {}\n\n\tasync history(key: string, scope?: Scope): Promise<AuditRecord[]> {\n\t\tconst def = await this.storage.findAnyDef(key);\n\t\tif (!def) throw new NotFoundError(key);\n\n\t\treturn this.storage.findAudit({\n\t\t\tdefinitionId: def.id,\n\t\t\tscopeKind: scope?.kind,\n\t\t\tscopeRefId: scope?.refId,\n\t\t});\n\t}\n}\n","import type { Cache } from '../cache/cache';\nimport type { ScopeHierarchy } from '../core/types';\n\nexport function withHierarchyInvalidation(\n\thierarchy: ScopeHierarchy,\n\tcache: Cache,\n): ScopeHierarchy {\n\treturn {\n\t\tchain: (id) => hierarchy.chain(id),\n\t\tdescendants: (id) => hierarchy.descendants(id),\n\t\tchildren: (id) => hierarchy.children(id),\n\t\tparent: (id) => hierarchy.parent(id),\n\t\tattach: async (id, parentId) => {\n\t\t\tawait hierarchy.attach(id, parentId);\n\t\t\tcache.dropForScopes(await hierarchy.descendants(id));\n\t\t},\n\t\tmove: async (id, newParentId) => {\n\t\t\tconst descendants = await hierarchy.descendants(id);\n\t\t\tawait hierarchy.move(id, newParentId);\n\t\t\tcache.dropForScopes(descendants);\n\t\t},\n\t\tdetach: async (id) => {\n\t\t\tconst descendants = await hierarchy.descendants(id);\n\t\t\tawait hierarchy.detach(id);\n\t\t\tcache.dropForScopes(descendants);\n\t\t},\n\t};\n}\n","import { CategoryError } from '../core/errors';\nimport type { StorageAdapter } from '../storage/storage-port';\n\nexport function withCategoryIntegrity(storage: StorageAdapter): StorageAdapter {\n\treturn {\n\t\tfindDefs: (keys) => storage.findDefs(keys),\n\t\tfindDefsByIds: (ids) => storage.findDefsByIds(ids),\n\t\tfindAnyDef: (key) => storage.findAnyDef(key),\n\t\tfindValues: (query) => storage.findValues(query),\n\t\tfindChainValues: (query) => storage.findChainValues(query),\n\t\tfindAudit: (query) => storage.findAudit(query),\n\t\tlistValues: (query) => storage.listValues(query),\n\t\tlistDefs: (status, category) => storage.listDefs(status, category),\n\t\tlistCategories: () => storage.listCategories(),\n\t\tupdateDefStatus: (key, status) => storage.updateDefStatus(key, status),\n\t\ttransact: (fn) => storage.transact(fn),\n\t\tcreateDef: async (input) => {\n\t\t\tconst existing = await storage.findAnyDef(input.key);\n\t\t\tconst newCategory = input.category ?? null;\n\t\t\tif (existing && existing.category !== newCategory) {\n\t\t\t\tthrow new CategoryError(\n\t\t\t\t\tinput.key,\n\t\t\t\t\texisting.category,\n\t\t\t\t\tnewCategory,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn storage.createDef(input);\n\t\t},\n\t};\n}\n","import type { ChangeBus } from '../cache/change-bus';\nimport { LocalBus } from '../cache/change-bus';\nimport type { CacheOptions } from '../cache/cache';\nimport { Cache } from '../cache/cache';\nimport { withHierarchyInvalidation } from './hierarchy-cache-sync';\nimport { withCategoryIntegrity } from './category-integrity';\nimport { MemoryStorageAdapter } from '../storage/memory-storage';\nimport { Resolver } from './resolver';\nimport { LocalScopeHierarchy } from '../hierarchy/scope-hierarchy';\nimport type { StorageAdapter } from '../storage/storage-port';\nimport type { ScopeHierarchy } from '../core/types';\nimport { Writer } from './writer';\nimport { Auditor } from './auditor';\n\nexport interface EngineOptions {\n\tstorage?: StorageAdapter;\n\thierarchy?: ScopeHierarchy;\n\tbus?: ChangeBus;\n\tcache?: CacheOptions | false;\n}\n\nexport interface Engine {\n\tstorage: StorageAdapter;\n\thierarchy: ScopeHierarchy;\n\tbus: ChangeBus;\n\tcache: Cache;\n\tresolver: Resolver;\n\twriter: Writer;\n\tauditor: Auditor;\n}\n\nexport function createEngine(options: EngineOptions = {}): Engine {\n\tconst storage = withCategoryIntegrity(\n\t\toptions.storage ?? new MemoryStorageAdapter(),\n\t);\n\tconst rawHierarchy = options.hierarchy ?? new LocalScopeHierarchy();\n\tconst bus = options.bus ?? new LocalBus();\n\tconst cacheOptions =\n\t\toptions.cache === false ? { enabled: false } : (options.cache ?? {});\n\tconst cache = new Cache(bus, cacheOptions, rawHierarchy);\n\tconst hierarchy = withHierarchyInvalidation(rawHierarchy, cache);\n\tconst resolver = new Resolver(storage, hierarchy, cache);\n\tconst writer = new Writer(storage, bus);\n\tconst auditor = new Auditor(storage);\n\treturn { storage, hierarchy, bus, cache, resolver, writer, auditor };\n}\n","import { CategoryError } from '../core/errors';\nimport type { StorageReader } from '../storage/storage-port';\n\nexport class CategoryGuard {\n\tconstructor(\n\t\tprivate readonly storage: StorageReader,\n\t\tprivate readonly category: string,\n\t) {}\n\n\tasync assert(key: string): Promise<void> {\n\t\tconst def = await this.storage.findAnyDef(key);\n\t\tif (def && def.category !== this.category) {\n\t\t\tthrow new CategoryError(key, this.category, def.category);\n\t\t}\n\t}\n\n\tasync assertAll(keys: Iterable<string>): Promise<void> {\n\t\tawait Promise.all([...keys].map((key) => this.assert(key)));\n\t}\n\n\tasync resolveKey(key: string): Promise<string> {\n\t\tconst direct = await this.storage.findAnyDef(key);\n\t\tif (direct) {\n\t\t\tif (direct.category !== this.category) {\n\t\t\t\tthrow new CategoryError(key, this.category, direct.category);\n\t\t\t}\n\t\t\treturn key;\n\t\t}\n\n\t\tconst prefixed = `${this.category}.${key}`;\n\t\tconst viaPrefix = await this.storage.findAnyDef(prefixed);\n\t\tif (viaPrefix && viaPrefix.category !== this.category) {\n\t\t\tthrow new CategoryError(\n\t\t\t\tprefixed,\n\t\t\t\tthis.category,\n\t\t\t\tviaPrefix.category,\n\t\t\t);\n\t\t}\n\t\treturn prefixed;\n\t}\n\n\tasync resolveKeys(keys: Iterable<string>): Promise<string[]> {\n\t\treturn Promise.all([...keys].map((key) => this.resolveKey(key)));\n\t}\n}\n","import type { Scope } from '../core/types';\nimport type { Resolver } from '../engine/resolver';\nimport type { CategoryGuard } from './category-guard';\nimport type {\n\tAcceptedKey,\n\tFullKeyFor,\n\tSettingScopeKind,\n\tSettingValue,\n} from './registry';\n\nexport class TypedResolver<\n\tRegistry,\n\tCategory extends string | undefined = undefined,\n> {\n\tconstructor(\n\t\tprivate readonly resolver: Resolver,\n\t\tprivate readonly fixedCategory?: Category,\n\t\tprivate readonly guard?: CategoryGuard,\n\t) {}\n\n\tasync get<K extends AcceptedKey<Registry, Category>>(\n\t\tkey: K,\n\t\tscope: Scope & {\n\t\t\tkind: SettingScopeKind<\n\t\t\t\tRegistry,\n\t\t\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t\t\t>;\n\t\t},\n\t\tasOf?: Date,\n\t): Promise<\n\t\tSettingValue<\n\t\t\tRegistry,\n\t\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t\t>\n\t> {\n\t\tconst resolvedKey = (await this.guard?.resolveKey(key)) ?? key;\n\t\treturn this.resolver.get(resolvedKey, scope, asOf) as Promise<\n\t\t\tSettingValue<\n\t\t\t\tRegistry,\n\t\t\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t\t\t>\n\t\t>;\n\t}\n\n\tasync getMany<K extends readonly AcceptedKey<Registry, Category>[]>(\n\t\tkeys: K,\n\t\tscope: Scope,\n\t\tasOf?: Date,\n\t): Promise<{\n\t\t[P in K[number]]: SettingValue<\n\t\t\tRegistry,\n\t\t\tFullKeyFor<Registry, Category, P> & keyof Registry\n\t\t>;\n\t}> {\n\t\tconst resolvedKeys = this.guard\n\t\t\t? await this.guard.resolveKeys(keys)\n\t\t\t: [...keys];\n\t\tconst result = await this.resolver.getMany(resolvedKeys, scope, asOf);\n\t\tconst remapped: Record<string, unknown> = {};\n\t\tkeys.forEach((key, i) => {\n\t\t\tremapped[key] = result[resolvedKeys[i]];\n\t\t});\n\t\treturn remapped as {\n\t\t\t[P in K[number]]: SettingValue<\n\t\t\t\tRegistry,\n\t\t\t\tFullKeyFor<Registry, Category, P> & keyof Registry\n\t\t\t>;\n\t\t};\n\t}\n\n\tasync listAt(\n\t\tscope: Scope,\n\t\topts: { limit?: number; cursor?: string } = {},\n\t): Promise<{\n\t\tentries: Partial<{\n\t\t\t[K in keyof Registry & string]: SettingValue<Registry, K>;\n\t\t}>;\n\t\tnextCursor: string | null;\n\t}> {\n\t\tconst page = await this.resolver.listAt(scope, {\n\t\t\t...opts,\n\t\t\tcategory: this.fixedCategory,\n\t\t});\n\t\treturn page as {\n\t\t\tentries: Partial<{\n\t\t\t\t[K in keyof Registry & string]: SettingValue<Registry, K>;\n\t\t\t}>;\n\t\t\tnextCursor: string | null;\n\t\t};\n\t}\n}\n","import type { Scope, ValueRecord } from '../core/types';\nimport type { SetParams, Writer } from '../engine/writer';\nimport type { CategoryGuard } from './category-guard';\nimport type {\n\tAcceptedKey,\n\tFullKeyFor,\n\tSettingScopeKind,\n\tSettingValue,\n} from './registry';\n\nexport interface TypedSetParams<\n\tRegistry,\n\tCategory extends string | undefined,\n\tK extends AcceptedKey<Registry, Category>,\n> {\n\tkey: K;\n\tscope: Scope & {\n\t\tkind: SettingScopeKind<\n\t\t\tRegistry,\n\t\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t\t>;\n\t};\n\tvalue: SettingValue<\n\t\tRegistry,\n\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t>;\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nexport type AnyTypedSetParams<Registry, Category extends string | undefined> = {\n\t[K in AcceptedKey<Registry, Category>]: TypedSetParams<\n\t\tRegistry,\n\t\tCategory,\n\t\tK\n\t>;\n}[AcceptedKey<Registry, Category>];\n\nexport interface TypedUnsetParams<\n\tRegistry,\n\tCategory extends string | undefined,\n\tK extends AcceptedKey<Registry, Category>,\n> {\n\tkey: K;\n\tscope: Scope & {\n\t\tkind: SettingScopeKind<\n\t\t\tRegistry,\n\t\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t\t>;\n\t};\n\texpectedVersion?: number;\n\tauthorId: string;\n\treason?: string;\n}\n\nexport class TypedWriter<\n\tRegistry,\n\tCategory extends string | undefined = undefined,\n> {\n\tconstructor(\n\t\tprivate readonly writer: Writer,\n\t\tprivate readonly guard?: CategoryGuard,\n\t) {}\n\n\tasync set<K extends AcceptedKey<Registry, Category>>(\n\t\tparams: TypedSetParams<Registry, Category, K>,\n\t): Promise<ValueRecord> {\n\t\tconst resolvedKey =\n\t\t\t(await this.guard?.resolveKey(params.key)) ?? params.key;\n\t\treturn this.writer.set({\n\t\t\t...params,\n\t\t\tkey: resolvedKey,\n\t\t} as unknown as SetParams);\n\t}\n\n\tasync setMany(\n\t\tparamsList: AnyTypedSetParams<Registry, Category>[],\n\t): Promise<ValueRecord[]> {\n\t\tconst resolved = this.guard\n\t\t\t? await Promise.all(\n\t\t\t\t\tparamsList.map(async (params) => ({\n\t\t\t\t\t\t...params,\n\t\t\t\t\t\tkey: await this.guard!.resolveKey(params.key),\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t: paramsList;\n\t\treturn this.writer.setMany(resolved as unknown as SetParams[]);\n\t}\n\n\tasync unset<K extends AcceptedKey<Registry, Category>>(\n\t\tparams: TypedUnsetParams<Registry, Category, K>,\n\t): Promise<void> {\n\t\tconst resolvedKey =\n\t\t\t(await this.guard?.resolveKey(params.key)) ?? params.key;\n\t\treturn this.writer.unset({ ...params, key: resolvedKey });\n\t}\n}\n","import type { Scope } from '../core/types';\nimport type { Auditor } from '../engine/auditor';\nimport type { AuditRecord } from '../storage/storage-port';\nimport type { CategoryGuard } from './category-guard';\nimport type { AcceptedKey, FullKeyFor, SettingScopeKind } from './registry';\n\nexport class TypedAuditor<\n\tRegistry,\n\tCategory extends string | undefined = undefined,\n> {\n\tconstructor(\n\t\tprivate readonly auditor: Auditor,\n\t\tprivate readonly guard?: CategoryGuard,\n\t) {}\n\n\tasync history<K extends AcceptedKey<Registry, Category>>(\n\t\tkey: K,\n\t\tscope?: Scope & {\n\t\t\tkind: SettingScopeKind<\n\t\t\t\tRegistry,\n\t\t\t\tFullKeyFor<Registry, Category, K> & keyof Registry\n\t\t\t>;\n\t\t},\n\t): Promise<AuditRecord[]> {\n\t\tconst resolvedKey = (await this.guard?.resolveKey(key)) ?? key;\n\t\treturn this.auditor.history(resolvedKey, scope);\n\t}\n}\n","import type { Engine } from '../engine/engine';\nimport { TypedResolver } from './typed-resolver';\nimport { TypedWriter } from './typed-writer';\nimport { TypedAuditor } from './typed-auditor';\nimport { CategoryGuard } from './category-guard';\nimport type { KeysInCategory } from './registry';\n\nexport interface TypedEngine<\n\tRegistry,\n\tCategory extends string | undefined = undefined,\n> {\n\tresolver: TypedResolver<Registry, Category>;\n\twriter: TypedWriter<Registry, Category>;\n\tauditor: TypedAuditor<Registry, Category>;\n\tcategory<C extends string>(\n\t\tcategory: C,\n\t): TypedEngine<KeysInCategory<Registry, C>, C>;\n}\n\nexport function createTypedEngine<Registry>(\n\tengine: Engine,\n): TypedEngine<Registry> {\n\tfunction build<R, C extends string | undefined>(\n\t\tfixedCategory?: C,\n\t): TypedEngine<R, C> {\n\t\tconst guard = fixedCategory\n\t\t\t? new CategoryGuard(engine.storage, fixedCategory)\n\t\t\t: undefined;\n\t\treturn {\n\t\t\tresolver: new TypedResolver<R, C>(\n\t\t\t\tengine.resolver,\n\t\t\t\tfixedCategory,\n\t\t\t\tguard,\n\t\t\t),\n\t\t\twriter: new TypedWriter<R, C>(engine.writer, guard),\n\t\t\tauditor: new TypedAuditor<R, C>(engine.auditor, guard),\n\t\t\tcategory: <C2 extends string>(category: C2) =>\n\t\t\t\tbuild<KeysInCategory<R, C2>, C2>(category),\n\t\t};\n\t}\n\treturn build<Registry, undefined>();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,5 +5,7 @@ export declare class CategoryGuard {
|
|
|
5
5
|
constructor(storage: StorageReader, category: string);
|
|
6
6
|
assert(key: string): Promise<void>;
|
|
7
7
|
assertAll(keys: Iterable<string>): Promise<void>;
|
|
8
|
+
resolveKey(key: string): Promise<string>;
|
|
9
|
+
resolveKeys(keys: Iterable<string>): Promise<string[]>;
|
|
8
10
|
}
|
|
9
11
|
//# sourceMappingURL=category-guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"category-guard.d.ts","sourceRoot":"","sources":["../../src/typed/category-guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,qBAAa,aAAa;IAExB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM;IAG5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"category-guard.d.ts","sourceRoot":"","sources":["../../src/typed/category-guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,qBAAa,aAAa;IAExB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM;IAG5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBxC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAG5D"}
|
|
@@ -18,6 +18,24 @@ class CategoryGuard {
|
|
|
18
18
|
async assertAll(keys) {
|
|
19
19
|
await Promise.all([...keys].map((key) => this.assert(key)));
|
|
20
20
|
}
|
|
21
|
+
async resolveKey(key) {
|
|
22
|
+
const direct = await this.storage.findAnyDef(key);
|
|
23
|
+
if (direct) {
|
|
24
|
+
if (direct.category !== this.category) {
|
|
25
|
+
throw new errors_1.CategoryError(key, this.category, direct.category);
|
|
26
|
+
}
|
|
27
|
+
return key;
|
|
28
|
+
}
|
|
29
|
+
const prefixed = `${this.category}.${key}`;
|
|
30
|
+
const viaPrefix = await this.storage.findAnyDef(prefixed);
|
|
31
|
+
if (viaPrefix && viaPrefix.category !== this.category) {
|
|
32
|
+
throw new errors_1.CategoryError(prefixed, this.category, viaPrefix.category);
|
|
33
|
+
}
|
|
34
|
+
return prefixed;
|
|
35
|
+
}
|
|
36
|
+
async resolveKeys(keys) {
|
|
37
|
+
return Promise.all([...keys].map((key) => this.resolveKey(key)));
|
|
38
|
+
}
|
|
21
39
|
}
|
|
22
40
|
exports.CategoryGuard = CategoryGuard;
|
|
23
41
|
//# sourceMappingURL=category-guard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"category-guard.js","sourceRoot":"","sources":["../../src/typed/category-guard.ts"],"names":[],"mappings":";;;AAAA,2CAA+C;AAG/C,MAAa,aAAa;IAEP;IACA;IAFlB,YACkB,OAAsB,EACtB,QAAgB;QADhB,YAAO,GAAP,OAAO,CAAe;QACtB,aAAQ,GAAR,QAAQ,CAAQ;IAC/B,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,GAAW;QACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,sBAAa,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAsB;QACrC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;CACD;
|
|
1
|
+
{"version":3,"file":"category-guard.js","sourceRoot":"","sources":["../../src/typed/category-guard.ts"],"names":[],"mappings":";;;AAAA,2CAA+C;AAG/C,MAAa,aAAa;IAEP;IACA;IAFlB,YACkB,OAAsB,EACtB,QAAgB;QADhB,YAAO,GAAP,OAAO,CAAe;QACtB,aAAQ,GAAR,QAAQ,CAAQ;IAC/B,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,GAAW;QACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,sBAAa,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAsB;QACrC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACZ,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvC,MAAM,IAAI,sBAAa,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1D,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,sBAAa,CACtB,QAAQ,EACR,IAAI,CAAC,QAAQ,EACb,SAAS,CAAC,QAAQ,CAClB,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAsB;QACvC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;CACD;AAzCD,sCAyCC"}
|
package/dist/typed/registry.d.ts
CHANGED
|
@@ -9,4 +9,10 @@ export type SettingCategory<Registry, K extends keyof Registry> = Registry[K] ex
|
|
|
9
9
|
export type KeysInCategory<Registry, C extends string> = {
|
|
10
10
|
[K in keyof Registry & string as SettingCategory<Registry, K> extends C ? K : never]: Registry[K];
|
|
11
11
|
};
|
|
12
|
+
export type StripCategoryPrefix<K extends string, Category extends string> = K extends `${Category}.${infer Rest}` ? Rest : never;
|
|
13
|
+
export type ShortKeys<Registry, Category extends string> = {
|
|
14
|
+
[K in keyof Registry & string as StripCategoryPrefix<K, Category>]: Registry[K];
|
|
15
|
+
};
|
|
16
|
+
export type AcceptedKey<Registry, Category extends string | undefined> = Category extends string ? (keyof Registry & string) | (keyof ShortKeys<Registry, Category> & string) : keyof Registry & string;
|
|
17
|
+
export type FullKeyFor<Registry, Category extends string | undefined, K extends string> = K extends keyof Registry ? K : Category extends string ? `${Category}.${K}` : never;
|
|
12
18
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/typed/registry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY,CAC5B,KAAK,GAAG,OAAO,EACf,SAAS,SAAS,MAAM,GAAG,MAAM,EACjC,QAAQ,SAAS,MAAM,GAAG,MAAM;IAEhC,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,QAAQ,IAC1D,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEvE,MAAM,MAAM,gBAAgB,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,QAAQ,IAC9D,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAExE,MAAM,MAAM,eAAe,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,QAAQ,IAC7D,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAExE,MAAM,MAAM,cAAc,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,IAAI;KAEvD,CAAC,IAAI,MAAM,QAAQ,GAAG,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,GACnE,CAAC,GACD,KAAK,GACN,QAAQ,CAAC,CAAC,CAAC;CACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/typed/registry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY,CAC5B,KAAK,GAAG,OAAO,EACf,SAAS,SAAS,MAAM,GAAG,MAAM,EACjC,QAAQ,SAAS,MAAM,GAAG,MAAM;IAEhC,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,QAAQ,IAC1D,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEvE,MAAM,MAAM,gBAAgB,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,QAAQ,IAC9D,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAExE,MAAM,MAAM,eAAe,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,QAAQ,IAC7D,QAAQ,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAExE,MAAM,MAAM,cAAc,CAAC,QAAQ,EAAE,CAAC,SAAS,MAAM,IAAI;KAEvD,CAAC,IAAI,MAAM,QAAQ,GAAG,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,GACnE,CAAC,GACD,KAAK,GACN,QAAQ,CAAC,CAAC,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAC9B,CAAC,SAAS,MAAM,EAChB,QAAQ,SAAS,MAAM,IACpB,CAAC,SAAS,GAAG,QAAQ,IAAI,MAAM,IAAI,EAAE,GAAG,IAAI,GAAG,KAAK,CAAC;AAEzD,MAAM,MAAM,SAAS,CAAC,QAAQ,EAAE,QAAQ,SAAS,MAAM,IAAI;KAEzD,CAAC,IAAI,MAAM,QAAQ,GAAG,MAAM,IAAI,mBAAmB,CAAC,CAAC,EAAE,QAAQ,CAAC,GAC9D,QAAQ,CAAC,CAAC,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,WAAW,CACtB,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,IAChC,QAAQ,SAAS,MAAM,GACxB,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,GAC1E,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE3B,MAAM,MAAM,UAAU,CACrB,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,EACnC,CAAC,SAAS,MAAM,IACb,CAAC,SAAS,MAAM,QAAQ,GACzB,CAAC,GACD,QAAQ,SAAS,MAAM,GACtB,GAAG,QAAQ,IAAI,CAAC,EAAE,GAClB,KAAK,CAAC"}
|
|
@@ -2,13 +2,13 @@ import type { Scope } from '../core/types';
|
|
|
2
2
|
import type { Auditor } from '../engine/auditor';
|
|
3
3
|
import type { AuditRecord } from '../storage/storage-port';
|
|
4
4
|
import type { CategoryGuard } from './category-guard';
|
|
5
|
-
import type { SettingScopeKind } from './registry';
|
|
6
|
-
export declare class TypedAuditor<Registry> {
|
|
5
|
+
import type { AcceptedKey, FullKeyFor, SettingScopeKind } from './registry';
|
|
6
|
+
export declare class TypedAuditor<Registry, Category extends string | undefined = undefined> {
|
|
7
7
|
private readonly auditor;
|
|
8
8
|
private readonly guard?;
|
|
9
9
|
constructor(auditor: Auditor, guard?: CategoryGuard | undefined);
|
|
10
|
-
history<K extends
|
|
11
|
-
kind: SettingScopeKind<Registry, K>;
|
|
10
|
+
history<K extends AcceptedKey<Registry, Category>>(key: K, scope?: Scope & {
|
|
11
|
+
kind: SettingScopeKind<Registry, FullKeyFor<Registry, Category, K> & keyof Registry>;
|
|
12
12
|
}): Promise<AuditRecord[]>;
|
|
13
13
|
}
|
|
14
14
|
//# sourceMappingURL=typed-auditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-auditor.d.ts","sourceRoot":"","sources":["../../src/typed/typed-auditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"typed-auditor.d.ts","sourceRoot":"","sources":["../../src/typed/typed-auditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE5E,qBAAa,YAAY,CACxB,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS;IAG9C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBADN,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,aAAa,YAAA;IAGjC,OAAO,CAAC,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EACtD,GAAG,EAAE,CAAC,EACN,KAAK,CAAC,EAAE,KAAK,GAAG;QACf,IAAI,EAAE,gBAAgB,CACrB,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD,CAAC;KACF,GACC,OAAO,CAAC,WAAW,EAAE,CAAC;CAIzB"}
|
|
@@ -9,8 +9,8 @@ class TypedAuditor {
|
|
|
9
9
|
this.guard = guard;
|
|
10
10
|
}
|
|
11
11
|
async history(key, scope) {
|
|
12
|
-
await this.guard?.
|
|
13
|
-
return this.auditor.history(
|
|
12
|
+
const resolvedKey = (await this.guard?.resolveKey(key)) ?? key;
|
|
13
|
+
return this.auditor.history(resolvedKey, scope);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
exports.TypedAuditor = TypedAuditor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-auditor.js","sourceRoot":"","sources":["../../src/typed/typed-auditor.ts"],"names":[],"mappings":";;;AAMA,MAAa,YAAY;
|
|
1
|
+
{"version":3,"file":"typed-auditor.js","sourceRoot":"","sources":["../../src/typed/typed-auditor.ts"],"names":[],"mappings":";;;AAMA,MAAa,YAAY;IAKN;IACA;IAFlB,YACkB,OAAgB,EAChB,KAAqB;QADrB,YAAO,GAAP,OAAO,CAAS;QAChB,UAAK,GAAL,KAAK,CAAgB;IACpC,CAAC;IAEJ,KAAK,CAAC,OAAO,CACZ,GAAM,EACN,KAKC;QAED,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;CACD;AArBD,oCAqBC"}
|
|
@@ -3,11 +3,11 @@ import { TypedResolver } from './typed-resolver';
|
|
|
3
3
|
import { TypedWriter } from './typed-writer';
|
|
4
4
|
import { TypedAuditor } from './typed-auditor';
|
|
5
5
|
import type { KeysInCategory } from './registry';
|
|
6
|
-
export interface TypedEngine<Registry> {
|
|
7
|
-
resolver: TypedResolver<Registry>;
|
|
8
|
-
writer: TypedWriter<Registry>;
|
|
9
|
-
auditor: TypedAuditor<Registry>;
|
|
10
|
-
category<C extends string>(category: C): TypedEngine<KeysInCategory<Registry, C
|
|
6
|
+
export interface TypedEngine<Registry, Category extends string | undefined = undefined> {
|
|
7
|
+
resolver: TypedResolver<Registry, Category>;
|
|
8
|
+
writer: TypedWriter<Registry, Category>;
|
|
9
|
+
auditor: TypedAuditor<Registry, Category>;
|
|
10
|
+
category<C extends string>(category: C): TypedEngine<KeysInCategory<Registry, C>, C>;
|
|
11
11
|
}
|
|
12
12
|
export declare function createTypedEngine<Registry>(engine: Engine): TypedEngine<Registry>;
|
|
13
13
|
//# sourceMappingURL=typed-engine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-engine.d.ts","sourceRoot":"","sources":["../../src/typed/typed-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,WAAW,
|
|
1
|
+
{"version":3,"file":"typed-engine.d.ts","sourceRoot":"","sources":["../../src/typed/typed-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,WAAW,CAC3B,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS;IAE/C,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxC,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,QAAQ,CAAC,CAAC,SAAS,MAAM,EACxB,QAAQ,EAAE,CAAC,GACT,WAAW,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC/C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EACzC,MAAM,EAAE,MAAM,GACZ,WAAW,CAAC,QAAQ,CAAC,CAoBvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-engine.js","sourceRoot":"","sources":["../../src/typed/typed-engine.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"typed-engine.js","sourceRoot":"","sources":["../../src/typed/typed-engine.ts"],"names":[],"mappings":";;AAmBA,8CAsBC;AAxCD,qDAAiD;AACjD,iDAA6C;AAC7C,mDAA+C;AAC/C,qDAAiD;AAejD,SAAgB,iBAAiB,CAChC,MAAc;IAEd,SAAS,KAAK,CACb,aAAiB;QAEjB,MAAM,KAAK,GAAG,aAAa;YAC1B,CAAC,CAAC,IAAI,8BAAa,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC;YAClD,CAAC,CAAC,SAAS,CAAC;QACb,OAAO;YACN,QAAQ,EAAE,IAAI,8BAAa,CAC1B,MAAM,CAAC,QAAQ,EACf,aAAa,EACb,KAAK,CACL;YACD,MAAM,EAAE,IAAI,0BAAW,CAAO,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;YACnD,OAAO,EAAE,IAAI,4BAAY,CAAO,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC;YACtD,QAAQ,EAAE,CAAoB,QAAY,EAAE,EAAE,CAC7C,KAAK,CAA4B,QAAQ,CAAC;SAC3C,CAAC;IACH,CAAC;IACD,OAAO,KAAK,EAAuB,CAAC;AACrC,CAAC"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { Scope } from '../core/types';
|
|
2
2
|
import type { Resolver } from '../engine/resolver';
|
|
3
3
|
import type { CategoryGuard } from './category-guard';
|
|
4
|
-
import type { SettingScopeKind, SettingValue } from './registry';
|
|
5
|
-
export declare class TypedResolver<Registry> {
|
|
4
|
+
import type { AcceptedKey, FullKeyFor, SettingScopeKind, SettingValue } from './registry';
|
|
5
|
+
export declare class TypedResolver<Registry, Category extends string | undefined = undefined> {
|
|
6
6
|
private readonly resolver;
|
|
7
7
|
private readonly fixedCategory?;
|
|
8
8
|
private readonly guard?;
|
|
9
|
-
constructor(resolver: Resolver, fixedCategory?:
|
|
10
|
-
get<K extends
|
|
11
|
-
kind: SettingScopeKind<Registry, K>;
|
|
12
|
-
}, asOf?: Date): Promise<SettingValue<Registry, K>>;
|
|
13
|
-
getMany<K extends readonly
|
|
14
|
-
[P in K[number]]: SettingValue<Registry, P>;
|
|
9
|
+
constructor(resolver: Resolver, fixedCategory?: Category | undefined, guard?: CategoryGuard | undefined);
|
|
10
|
+
get<K extends AcceptedKey<Registry, Category>>(key: K, scope: Scope & {
|
|
11
|
+
kind: SettingScopeKind<Registry, FullKeyFor<Registry, Category, K> & keyof Registry>;
|
|
12
|
+
}, asOf?: Date): Promise<SettingValue<Registry, FullKeyFor<Registry, Category, K> & keyof Registry>>;
|
|
13
|
+
getMany<K extends readonly AcceptedKey<Registry, Category>[]>(keys: K, scope: Scope, asOf?: Date): Promise<{
|
|
14
|
+
[P in K[number]]: SettingValue<Registry, FullKeyFor<Registry, Category, P> & keyof Registry>;
|
|
15
15
|
}>;
|
|
16
16
|
listAt(scope: Scope, opts?: {
|
|
17
17
|
limit?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-resolver.d.ts","sourceRoot":"","sources":["../../src/typed/typed-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"typed-resolver.d.ts","sourceRoot":"","sources":["../../src/typed/typed-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,MAAM,YAAY,CAAC;AAEpB,qBAAa,aAAa,CACzB,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS;IAG9C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAFN,QAAQ,EAAE,QAAQ,EAClB,aAAa,CAAC,EAAE,QAAQ,YAAA,EACxB,KAAK,CAAC,EAAE,aAAa,YAAA;IAGjC,GAAG,CAAC,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAClD,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,KAAK,GAAG;QACd,IAAI,EAAE,gBAAgB,CACrB,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD,CAAC;KACF,EACD,IAAI,CAAC,EAAE,IAAI,GACT,OAAO,CACT,YAAY,CACX,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD,CACD;IAUK,OAAO,CAAC,CAAC,SAAS,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EACjE,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,IAAI,GACT,OAAO,CAAC;SACT,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,YAAY,CAC7B,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD;KACD,CAAC;IAiBI,MAAM,CACX,KAAK,EAAE,KAAK,EACZ,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAC5C,OAAO,CAAC;QACV,OAAO,EAAE,OAAO,CAAC;aACf,CAAC,IAAI,MAAM,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;SACzD,CAAC,CAAC;QACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;CAYF"}
|
|
@@ -11,13 +11,19 @@ class TypedResolver {
|
|
|
11
11
|
this.guard = guard;
|
|
12
12
|
}
|
|
13
13
|
async get(key, scope, asOf) {
|
|
14
|
-
await this.guard?.
|
|
15
|
-
return this.resolver.get(
|
|
14
|
+
const resolvedKey = (await this.guard?.resolveKey(key)) ?? key;
|
|
15
|
+
return this.resolver.get(resolvedKey, scope, asOf);
|
|
16
16
|
}
|
|
17
17
|
async getMany(keys, scope, asOf) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const resolvedKeys = this.guard
|
|
19
|
+
? await this.guard.resolveKeys(keys)
|
|
20
|
+
: [...keys];
|
|
21
|
+
const result = await this.resolver.getMany(resolvedKeys, scope, asOf);
|
|
22
|
+
const remapped = {};
|
|
23
|
+
keys.forEach((key, i) => {
|
|
24
|
+
remapped[key] = result[resolvedKeys[i]];
|
|
25
|
+
});
|
|
26
|
+
return remapped;
|
|
21
27
|
}
|
|
22
28
|
async listAt(scope, opts = {}) {
|
|
23
29
|
const page = await this.resolver.listAt(scope, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-resolver.js","sourceRoot":"","sources":["../../src/typed/typed-resolver.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"typed-resolver.js","sourceRoot":"","sources":["../../src/typed/typed-resolver.ts"],"names":[],"mappings":";;;AAUA,MAAa,aAAa;IAKP;IACA;IACA;IAHlB,YACkB,QAAkB,EAClB,aAAwB,EACxB,KAAqB;QAFrB,aAAQ,GAAR,QAAQ,CAAU;QAClB,kBAAa,GAAb,aAAa,CAAW;QACxB,UAAK,GAAL,KAAK,CAAgB;IACpC,CAAC;IAEJ,KAAK,CAAC,GAAG,CACR,GAAM,EACN,KAKC,EACD,IAAW;QAOX,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QAC/D,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAKhD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,IAAO,EACP,KAAY,EACZ,IAAW;QAOX,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK;YAC9B,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;YACpC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACtE,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACvB,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,OAAO,QAKN,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CACX,KAAY,EACZ,OAA4C,EAAE;QAO9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE;YAC9C,GAAG,IAAI;YACP,QAAQ,EAAE,IAAI,CAAC,aAAa;SAC5B,CAAC,CAAC;QACH,OAAO,IAKN,CAAC;IACH,CAAC;CACD;AAhFD,sCAgFC"}
|
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
import type { Scope, ValueRecord } from '../core/types';
|
|
2
2
|
import type { Writer } from '../engine/writer';
|
|
3
3
|
import type { CategoryGuard } from './category-guard';
|
|
4
|
-
import type { SettingScopeKind, SettingValue } from './registry';
|
|
5
|
-
export interface TypedSetParams<Registry, K extends
|
|
4
|
+
import type { AcceptedKey, FullKeyFor, SettingScopeKind, SettingValue } from './registry';
|
|
5
|
+
export interface TypedSetParams<Registry, Category extends string | undefined, K extends AcceptedKey<Registry, Category>> {
|
|
6
6
|
key: K;
|
|
7
7
|
scope: Scope & {
|
|
8
|
-
kind: SettingScopeKind<Registry, K>;
|
|
8
|
+
kind: SettingScopeKind<Registry, FullKeyFor<Registry, Category, K> & keyof Registry>;
|
|
9
9
|
};
|
|
10
|
-
value: SettingValue<Registry, K>;
|
|
10
|
+
value: SettingValue<Registry, FullKeyFor<Registry, Category, K> & keyof Registry>;
|
|
11
11
|
expectedVersion?: number;
|
|
12
12
|
authorId: string;
|
|
13
13
|
reason?: string;
|
|
14
14
|
}
|
|
15
|
-
export
|
|
15
|
+
export type AnyTypedSetParams<Registry, Category extends string | undefined> = {
|
|
16
|
+
[K in AcceptedKey<Registry, Category>]: TypedSetParams<Registry, Category, K>;
|
|
17
|
+
}[AcceptedKey<Registry, Category>];
|
|
18
|
+
export interface TypedUnsetParams<Registry, Category extends string | undefined, K extends AcceptedKey<Registry, Category>> {
|
|
16
19
|
key: K;
|
|
17
20
|
scope: Scope & {
|
|
18
|
-
kind: SettingScopeKind<Registry, K>;
|
|
21
|
+
kind: SettingScopeKind<Registry, FullKeyFor<Registry, Category, K> & keyof Registry>;
|
|
19
22
|
};
|
|
20
23
|
expectedVersion?: number;
|
|
21
24
|
authorId: string;
|
|
22
25
|
reason?: string;
|
|
23
26
|
}
|
|
24
|
-
export declare class TypedWriter<Registry> {
|
|
27
|
+
export declare class TypedWriter<Registry, Category extends string | undefined = undefined> {
|
|
25
28
|
private readonly writer;
|
|
26
29
|
private readonly guard?;
|
|
27
30
|
constructor(writer: Writer, guard?: CategoryGuard | undefined);
|
|
28
|
-
set<K extends
|
|
29
|
-
setMany(paramsList:
|
|
30
|
-
|
|
31
|
-
}[keyof Registry & string][]): Promise<ValueRecord[]>;
|
|
32
|
-
unset<K extends keyof Registry & string>(params: TypedUnsetParams<Registry, K>): Promise<void>;
|
|
31
|
+
set<K extends AcceptedKey<Registry, Category>>(params: TypedSetParams<Registry, Category, K>): Promise<ValueRecord>;
|
|
32
|
+
setMany(paramsList: AnyTypedSetParams<Registry, Category>[]): Promise<ValueRecord[]>;
|
|
33
|
+
unset<K extends AcceptedKey<Registry, Category>>(params: TypedUnsetParams<Registry, Category, K>): Promise<void>;
|
|
33
34
|
}
|
|
34
35
|
//# sourceMappingURL=typed-writer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-writer.d.ts","sourceRoot":"","sources":["../../src/typed/typed-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAa,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"typed-writer.d.ts","sourceRoot":"","sources":["../../src/typed/typed-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAa,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,cAAc,CAC9B,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,EACnC,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAEzC,GAAG,EAAE,CAAC,CAAC;IACP,KAAK,EAAE,KAAK,GAAG;QACd,IAAI,EAAE,gBAAgB,CACrB,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD,CAAC;KACF,CAAC;IACF,KAAK,EAAE,YAAY,CAClB,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD,CAAC;IACF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,SAAS,MAAM,GAAG,SAAS,IAAI;KAC7E,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,cAAc,CACrD,QAAQ,EACR,QAAQ,EACR,CAAC,CACD;CACD,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEnC,MAAM,WAAW,gBAAgB,CAChC,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,EACnC,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAEzC,GAAG,EAAE,CAAC,CAAC;IACP,KAAK,EAAE,KAAK,GAAG;QACd,IAAI,EAAE,gBAAgB,CACrB,QAAQ,EACR,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,MAAM,QAAQ,CAClD,CAAC;KACF,CAAC;IACF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW,CACvB,QAAQ,EACR,QAAQ,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS;IAG9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBADN,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,aAAa,YAAA;IAGjC,GAAG,CAAC,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAClD,MAAM,EAAE,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAC3C,OAAO,CAAC,WAAW,CAAC;IASjB,OAAO,CACZ,UAAU,EAAE,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,GACjD,OAAO,CAAC,WAAW,EAAE,CAAC;IAYnB,KAAK,CAAC,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EACpD,MAAM,EAAE,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC;CAKhB"}
|
|
@@ -9,16 +9,24 @@ class TypedWriter {
|
|
|
9
9
|
this.guard = guard;
|
|
10
10
|
}
|
|
11
11
|
async set(params) {
|
|
12
|
-
await this.guard?.
|
|
13
|
-
return this.writer.set(
|
|
12
|
+
const resolvedKey = (await this.guard?.resolveKey(params.key)) ?? params.key;
|
|
13
|
+
return this.writer.set({
|
|
14
|
+
...params,
|
|
15
|
+
key: resolvedKey,
|
|
16
|
+
});
|
|
14
17
|
}
|
|
15
18
|
async setMany(paramsList) {
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const resolved = this.guard
|
|
20
|
+
? await Promise.all(paramsList.map(async (params) => ({
|
|
21
|
+
...params,
|
|
22
|
+
key: await this.guard.resolveKey(params.key),
|
|
23
|
+
})))
|
|
24
|
+
: paramsList;
|
|
25
|
+
return this.writer.setMany(resolved);
|
|
18
26
|
}
|
|
19
27
|
async unset(params) {
|
|
20
|
-
await this.guard?.
|
|
21
|
-
return this.writer.unset(params);
|
|
28
|
+
const resolvedKey = (await this.guard?.resolveKey(params.key)) ?? params.key;
|
|
29
|
+
return this.writer.unset({ ...params, key: resolvedKey });
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
exports.TypedWriter = TypedWriter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed-writer.js","sourceRoot":"","sources":["../../src/typed/typed-writer.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"typed-writer.js","sourceRoot":"","sources":["../../src/typed/typed-writer.ts"],"names":[],"mappings":";;;AAwDA,MAAa,WAAW;IAKL;IACA;IAFlB,YACkB,MAAc,EACd,KAAqB;QADrB,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAgB;IACpC,CAAC;IAEJ,KAAK,CAAC,GAAG,CACR,MAA6C;QAE7C,MAAM,WAAW,GAChB,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;QAC1D,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,MAAM;YACT,GAAG,EAAE,WAAW;SACQ,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,UAAmD;QAEnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK;YAC1B,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CACjB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjC,GAAG,MAAM;gBACT,GAAG,EAAE,MAAM,IAAI,CAAC,KAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;aAC7C,CAAC,CAAC,CACH;YACF,CAAC,CAAC,UAAU,CAAC;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAkC,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,KAAK,CACV,MAA+C;QAE/C,MAAM,WAAW,GAChB,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;QAC1D,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;CACD;AAzCD,kCAyCC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conftree",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Generic hierarchical configuration engine with arbitrary scopes, inheritance, caching, and audit. Zero required dependencies: works standalone or with any storage/pub-sub backend via simple ports.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|