conftree 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +143 -0
- package/dist/cache/cache.d.ts +23 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +95 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/change-bus.d.ts +16 -0
- package/dist/cache/change-bus.d.ts.map +1 -0
- package/dist/cache/change-bus.js +14 -0
- package/dist/cache/change-bus.js.map +1 -0
- package/dist/core/errors.d.ts +27 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +58 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/types.d.ts +52 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/engine/auditor.d.ts +8 -0
- package/dist/engine/auditor.d.ts.map +1 -0
- package/dist/engine/auditor.js +22 -0
- package/dist/engine/auditor.js.map +1 -0
- package/dist/engine/engine.d.ts +25 -0
- package/dist/engine/engine.d.ts.map +1 -0
- package/dist/engine/engine.js +24 -0
- package/dist/engine/engine.js.map +1 -0
- package/dist/engine/hierarchy-cache-sync.d.ts +4 -0
- package/dist/engine/hierarchy-cache-sync.d.ts.map +1 -0
- package/dist/engine/hierarchy-cache-sync.js +26 -0
- package/dist/engine/hierarchy-cache-sync.js.map +1 -0
- package/dist/engine/resolver.d.ts +24 -0
- package/dist/engine/resolver.d.ts.map +1 -0
- package/dist/engine/resolver.js +195 -0
- package/dist/engine/resolver.js.map +1 -0
- package/dist/engine/writer.d.ts +32 -0
- package/dist/engine/writer.d.ts.map +1 -0
- package/dist/engine/writer.js +178 -0
- package/dist/engine/writer.js.map +1 -0
- package/dist/hierarchy/scope-hierarchy.d.ts +15 -0
- package/dist/hierarchy/scope-hierarchy.d.ts.map +1 -0
- package/dist/hierarchy/scope-hierarchy.js +86 -0
- package/dist/hierarchy/scope-hierarchy.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +895 -0
- package/dist/index.mjs.map +1 -0
- package/dist/storage/memory-storage.d.ts +25 -0
- package/dist/storage/memory-storage.d.ts.map +1 -0
- package/dist/storage/memory-storage.js +176 -0
- package/dist/storage/memory-storage.js.map +1 -0
- package/dist/storage/storage-port.d.ts +93 -0
- package/dist/storage/storage-port.d.ts.map +1 -0
- package/dist/storage/storage-port.js +3 -0
- package/dist/storage/storage-port.js.map +1 -0
- package/dist/typed/registry.d.ts +7 -0
- package/dist/typed/registry.d.ts.map +1 -0
- package/dist/typed/registry.js +3 -0
- package/dist/typed/registry.js.map +1 -0
- package/dist/typed/typed-auditor.d.ts +12 -0
- package/dist/typed/typed-auditor.d.ts.map +1 -0
- package/dist/typed/typed-auditor.js +14 -0
- package/dist/typed/typed-auditor.js.map +1 -0
- package/dist/typed/typed-engine.d.ts +11 -0
- package/dist/typed/typed-engine.d.ts.map +1 -0
- package/dist/typed/typed-engine.js +14 -0
- package/dist/typed/typed-engine.js.map +1 -0
- package/dist/typed/typed-resolver.d.ts +23 -0
- package/dist/typed/typed-resolver.d.ts.map +1 -0
- package/dist/typed/typed-resolver.js +22 -0
- package/dist/typed/typed-resolver.js.map +1 -0
- package/dist/typed/typed-writer.d.ts +32 -0
- package/dist/typed/typed-writer.d.ts.map +1 -0
- package/dist/typed/typed-writer.js +20 -0
- package/dist/typed/typed-writer.js.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nekena RABEHARIVONJY
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# conftree
|
|
2
|
+
|
|
3
|
+
[](https://badge.socket.dev/npm/package/conftree/0.1.0)
|
|
4
|
+
|
|
5
|
+
Generic hierarchical configuration engine. Arbitrary scopes, inheritance, caching, audit trail. Zero required dependencies: works standalone or with any storage/pub-sub backend.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install conftree
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createEngine } from 'conftree';
|
|
17
|
+
|
|
18
|
+
const { storage, resolver, writer } = createEngine();
|
|
19
|
+
|
|
20
|
+
await storage.createDef({
|
|
21
|
+
key: 'ui.theme',
|
|
22
|
+
label: 'Theme',
|
|
23
|
+
type: 'ENUM',
|
|
24
|
+
options: ['light', 'dark', 'system'],
|
|
25
|
+
scopes: ['user'],
|
|
26
|
+
inherit: 'INDEPENDENT',
|
|
27
|
+
required: false,
|
|
28
|
+
status: 'STABLE',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await writer.set({
|
|
32
|
+
key: 'ui.theme',
|
|
33
|
+
scope: { kind: 'user', refId: 'u1' },
|
|
34
|
+
value: 'dark',
|
|
35
|
+
authorId: 'u1',
|
|
36
|
+
});
|
|
37
|
+
await resolver.get('ui.theme', { kind: 'user', refId: 'u1' }); // 'dark'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Revert a scope back to its inherited or default value:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
await writer.unset({
|
|
44
|
+
key: 'ui.theme',
|
|
45
|
+
scope: { kind: 'user', refId: 'u1' },
|
|
46
|
+
authorId: 'u1',
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Inspect the audit trail for a setting:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
const { auditor } = createEngine();
|
|
54
|
+
await auditor.history('ui.theme', { kind: 'user', refId: 'u1' });
|
|
55
|
+
// [{ action: 'created', authorId: 'u1', after: {...}, at: ... }, ...]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
List every setting explicitly set at a scope (paginated):
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const { entries, nextCursor } = await resolver.listAt({
|
|
62
|
+
kind: 'user',
|
|
63
|
+
refId: 'u1',
|
|
64
|
+
});
|
|
65
|
+
// { entries: { 'ui.theme': 'dark', 'ui.pageSize': 20 }, nextCursor: null }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Deprecate or retire a definition (retired definitions stop being readable and writable, but keep their audit history):
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await storage.updateDefStatus('ui.theme', 'RETIRED');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Bring your own storage or pub/sub backend:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const { resolver, writer } = createEngine({
|
|
78
|
+
storage: new MyPostgresAdapter(pool),
|
|
79
|
+
hierarchy: new MyClosureTableHierarchy(pool),
|
|
80
|
+
bus: new MyRedisBus(redisClient),
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Value types
|
|
85
|
+
|
|
86
|
+
`BOOLEAN`, `NUMERIC`, `TEXT`, `ENUM`, `JSON`, `DATE`.
|
|
87
|
+
|
|
88
|
+
### Hierarchy
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const { hierarchy } = createEngine();
|
|
92
|
+
await hierarchy.attach('org-1', null);
|
|
93
|
+
await hierarchy.attach('org-2', null);
|
|
94
|
+
await hierarchy.attach('team-1', 'org-1');
|
|
95
|
+
await hierarchy.move('team-1', 'org-2');
|
|
96
|
+
await hierarchy.detach('team-1');
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Typed settings registry
|
|
100
|
+
|
|
101
|
+
Get autocomplete and compile-time checking on keys, scopes, and value types by declaring your settings once and wrapping the engine:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { createEngine, createTypedEngine } from 'conftree';
|
|
105
|
+
|
|
106
|
+
interface Registry {
|
|
107
|
+
'ui.theme': { value: 'light' | 'dark' | 'system'; scope: 'user' };
|
|
108
|
+
'chama.contributionAmount': { value: number; scope: 'group' | 'member' };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const { resolver, writer } = createTypedEngine<Registry>(createEngine());
|
|
112
|
+
|
|
113
|
+
await writer.set({
|
|
114
|
+
key: 'ui.theme',
|
|
115
|
+
scope: { kind: 'user', refId: 'u1' },
|
|
116
|
+
value: 'dark', // only 'light' | 'dark' | 'system' is accepted
|
|
117
|
+
authorId: 'u1',
|
|
118
|
+
});
|
|
119
|
+
await resolver.get('ui.theme', { kind: 'user', refId: 'u1' }); // typed 'light' | 'dark' | 'system'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`Registry` must be a plain interface/type (not `extends` anything with an index signature) for key-level narrowing to work — see `src/typed/registry.ts` for the `SettingValue`/`SettingScopeKind` helpers this is built on.
|
|
123
|
+
|
|
124
|
+
### Writing an adapter
|
|
125
|
+
|
|
126
|
+
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.
|
|
127
|
+
|
|
128
|
+
## API
|
|
129
|
+
|
|
130
|
+
- `createEngine(options?)`: returns `{ storage, hierarchy, bus, cache, resolver, writer, auditor }`.
|
|
131
|
+
- `resolver.get(key, scope, asOf?)`, `resolver.getMany(keys, scope, asOf?)`, `resolver.listAt(scope, { limit?, cursor? })`
|
|
132
|
+
- `writer.set(params)`, `writer.setMany(paramsList)`, `writer.unset(params)`
|
|
133
|
+
- `auditor.history(key, scope?)`
|
|
134
|
+
- `storage.updateDefStatus(key, status)`
|
|
135
|
+
- `createTypedEngine<Registry>(engine)`: returns `{ resolver, writer, auditor }` typed against your own key/value/scope registry.
|
|
136
|
+
|
|
137
|
+
### Errors
|
|
138
|
+
|
|
139
|
+
All errors extend `ConfTreeError` and carry a stable `code` (e.g. `'CONFLICT'`, `'NOT_FOUND'`), in addition to a specific class (`ConflictError`, `NotFoundError`, ...) and `name`.
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Scope, ScopeHierarchy, Value } from '../core/types';
|
|
2
|
+
import type { ChangeBus } from './change-bus';
|
|
3
|
+
export interface CacheOptions {
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
ttlMs?: number;
|
|
6
|
+
maxEntries?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class Cache {
|
|
9
|
+
private readonly bus;
|
|
10
|
+
private readonly options;
|
|
11
|
+
private readonly hierarchy?;
|
|
12
|
+
private readonly store;
|
|
13
|
+
constructor(bus: ChangeBus, options?: CacheOptions, hierarchy?: ScopeHierarchy | undefined);
|
|
14
|
+
get(key: string, scope: Scope): Value | undefined;
|
|
15
|
+
set(key: string, scope: Scope, value: Value): void;
|
|
16
|
+
drop(key: string): void;
|
|
17
|
+
dropAll(): void;
|
|
18
|
+
dropForScopes(scopeRefIds: Iterable<string>): void;
|
|
19
|
+
private dropScoped;
|
|
20
|
+
private onChange;
|
|
21
|
+
private keyFor;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,qBAAa,KAAK;IAIhB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAL5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;gBAGhC,GAAG,EAAE,SAAS,EACd,OAAO,GAAE,YAAiB,EAC1B,SAAS,CAAC,EAAE,cAAc,YAAA;IAK5C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS;IAYjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAoBlD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMvB,OAAO,IAAI,IAAI;IAIf,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI;IAUlD,OAAO,CAAC,UAAU;YAaJ,QAAQ;IAatB,OAAO,CAAC,MAAM;CAGd"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Cache = void 0;
|
|
4
|
+
const DEFAULT_TTL_MS = 30_000;
|
|
5
|
+
const DEFAULT_MAX_ENTRIES = 50_000;
|
|
6
|
+
class Cache {
|
|
7
|
+
bus;
|
|
8
|
+
options;
|
|
9
|
+
hierarchy;
|
|
10
|
+
store = new Map();
|
|
11
|
+
constructor(bus, options = {}, hierarchy) {
|
|
12
|
+
this.bus = bus;
|
|
13
|
+
this.options = options;
|
|
14
|
+
this.hierarchy = hierarchy;
|
|
15
|
+
this.bus.subscribe((event) => this.onChange(event));
|
|
16
|
+
}
|
|
17
|
+
get(key, scope) {
|
|
18
|
+
if (this.options.enabled === false)
|
|
19
|
+
return undefined;
|
|
20
|
+
const cacheKey = this.keyFor(key, scope);
|
|
21
|
+
const entry = this.store.get(cacheKey);
|
|
22
|
+
if (!entry)
|
|
23
|
+
return undefined;
|
|
24
|
+
if (entry.expiresAt <= Date.now()) {
|
|
25
|
+
this.store.delete(cacheKey);
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return entry.value;
|
|
29
|
+
}
|
|
30
|
+
set(key, scope, value) {
|
|
31
|
+
if (this.options.enabled === false)
|
|
32
|
+
return;
|
|
33
|
+
const cacheKey = this.keyFor(key, scope);
|
|
34
|
+
if (!this.store.has(cacheKey) &&
|
|
35
|
+
this.store.size >= (this.options.maxEntries ?? DEFAULT_MAX_ENTRIES)) {
|
|
36
|
+
const oldest = this.store.keys().next().value;
|
|
37
|
+
if (oldest !== undefined)
|
|
38
|
+
this.store.delete(oldest);
|
|
39
|
+
}
|
|
40
|
+
const ttlMs = this.options.ttlMs ?? DEFAULT_TTL_MS;
|
|
41
|
+
this.store.set(cacheKey, {
|
|
42
|
+
key,
|
|
43
|
+
scopeKind: scope.kind,
|
|
44
|
+
scopeRefId: scope.refId,
|
|
45
|
+
value,
|
|
46
|
+
expiresAt: Date.now() + ttlMs,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
drop(key) {
|
|
50
|
+
for (const [cacheKey, entry] of this.store) {
|
|
51
|
+
if (entry.key === key)
|
|
52
|
+
this.store.delete(cacheKey);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
dropAll() {
|
|
56
|
+
this.store.clear();
|
|
57
|
+
}
|
|
58
|
+
dropForScopes(scopeRefIds) {
|
|
59
|
+
const targets = new Set(scopeRefIds);
|
|
60
|
+
if (targets.size === 0)
|
|
61
|
+
return;
|
|
62
|
+
for (const [cacheKey, entry] of this.store) {
|
|
63
|
+
if (entry.scopeRefId !== null && targets.has(entry.scopeRefId)) {
|
|
64
|
+
this.store.delete(cacheKey);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
dropScoped(key, scopeRefIds) {
|
|
69
|
+
const targets = new Set(scopeRefIds);
|
|
70
|
+
for (const [cacheKey, entry] of this.store) {
|
|
71
|
+
if (entry.key === key &&
|
|
72
|
+
entry.scopeRefId !== null &&
|
|
73
|
+
targets.has(entry.scopeRefId)) {
|
|
74
|
+
this.store.delete(cacheKey);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async onChange(event) {
|
|
79
|
+
if (this.hierarchy && event.scopeRefId !== null) {
|
|
80
|
+
const descendants = await this.hierarchy
|
|
81
|
+
.descendants(event.scopeRefId)
|
|
82
|
+
.catch(() => null);
|
|
83
|
+
if (descendants !== null) {
|
|
84
|
+
this.dropScoped(event.key, descendants);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.drop(event.key);
|
|
89
|
+
}
|
|
90
|
+
keyFor(key, scope) {
|
|
91
|
+
return JSON.stringify([key, scope.kind, scope.refId]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.Cache = Cache;
|
|
95
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/cache/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ChangeEvent {
|
|
2
|
+
definitionId: string;
|
|
3
|
+
key: string;
|
|
4
|
+
scopeKind: string;
|
|
5
|
+
scopeRefId: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface ChangeBus {
|
|
8
|
+
publish(event: ChangeEvent): Promise<void>;
|
|
9
|
+
subscribe(listener: (event: ChangeEvent) => void | Promise<void>): void;
|
|
10
|
+
}
|
|
11
|
+
export declare class LocalBus implements ChangeBus {
|
|
12
|
+
private readonly listeners;
|
|
13
|
+
publish(event: ChangeEvent): Promise<void>;
|
|
14
|
+
subscribe(listener: (event: ChangeEvent) => void | Promise<void>): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=change-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-bus.d.ts","sourceRoot":"","sources":["../../src/cache/change-bus.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxE;AAED,qBAAa,QAAS,YAAW,SAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAEtB;IAEE,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGvE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalBus = void 0;
|
|
4
|
+
class LocalBus {
|
|
5
|
+
listeners = new Set();
|
|
6
|
+
async publish(event) {
|
|
7
|
+
await Promise.all([...this.listeners].map((listener) => Promise.resolve(listener(event))));
|
|
8
|
+
}
|
|
9
|
+
subscribe(listener) {
|
|
10
|
+
this.listeners.add(listener);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.LocalBus = LocalBus;
|
|
14
|
+
//# sourceMappingURL=change-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-bus.js","sourceRoot":"","sources":["../../src/cache/change-bus.ts"],"names":[],"mappings":";;;AAYA,MAAa,QAAQ;IACH,SAAS,GAAG,IAAI,GAAG,EAEjC,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,KAAkB;QAC/B,MAAM,OAAO,CAAC,GAAG,CAChB,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CACpC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAChC,CACD,CAAC;IACH,CAAC;IAED,SAAS,CAAC,QAAsD;QAC/D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;CACD;AAhBD,4BAgBC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type ErrorCode = 'NOT_FOUND' | 'SCOPE' | 'REQUIRED' | 'VALUE' | 'CONFLICT' | 'CORRUPT' | 'CYCLE';
|
|
2
|
+
export declare class ConfTreeError extends Error {
|
|
3
|
+
readonly code: ErrorCode;
|
|
4
|
+
constructor(message: string, code: ErrorCode);
|
|
5
|
+
}
|
|
6
|
+
export declare class NotFoundError extends ConfTreeError {
|
|
7
|
+
constructor(key: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class ScopeError extends ConfTreeError {
|
|
10
|
+
constructor(key: string, scopeKind: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class RequiredError extends ConfTreeError {
|
|
13
|
+
constructor(key: string, scopeKind: string, scopeRefId: string | null);
|
|
14
|
+
}
|
|
15
|
+
export declare class ValueError extends ConfTreeError {
|
|
16
|
+
constructor(message: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class ConflictError extends ConfTreeError {
|
|
19
|
+
constructor(key: string, scopeKind: string, scopeRefId: string | null);
|
|
20
|
+
}
|
|
21
|
+
export declare class CorruptError extends ConfTreeError {
|
|
22
|
+
constructor(valueId: string);
|
|
23
|
+
}
|
|
24
|
+
export declare class CycleError extends ConfTreeError {
|
|
25
|
+
constructor(id: string, newParentId: string);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +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,CAAC;AAEX,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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CycleError = exports.CorruptError = exports.ConflictError = exports.ValueError = exports.RequiredError = exports.ScopeError = exports.NotFoundError = exports.ConfTreeError = void 0;
|
|
4
|
+
class ConfTreeError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = new.target.name;
|
|
10
|
+
Error.captureStackTrace?.(this, new.target);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.ConfTreeError = ConfTreeError;
|
|
14
|
+
class NotFoundError extends ConfTreeError {
|
|
15
|
+
constructor(key) {
|
|
16
|
+
super(`Unknown setting definition: "${key}"`, 'NOT_FOUND');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.NotFoundError = NotFoundError;
|
|
20
|
+
class ScopeError extends ConfTreeError {
|
|
21
|
+
constructor(key, scopeKind) {
|
|
22
|
+
super(`Setting "${key}" cannot be set or read at scope kind "${scopeKind}"`, 'SCOPE');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.ScopeError = ScopeError;
|
|
26
|
+
class RequiredError extends ConfTreeError {
|
|
27
|
+
constructor(key, scopeKind, scopeRefId) {
|
|
28
|
+
super(`Required setting "${key}" has no resolvable value for scope ${scopeKind}:${scopeRefId ?? 'null'} ` +
|
|
29
|
+
`and no default is defined`, 'REQUIRED');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.RequiredError = RequiredError;
|
|
33
|
+
class ValueError extends ConfTreeError {
|
|
34
|
+
constructor(message) {
|
|
35
|
+
super(message, 'VALUE');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.ValueError = ValueError;
|
|
39
|
+
class ConflictError extends ConfTreeError {
|
|
40
|
+
constructor(key, scopeKind, scopeRefId) {
|
|
41
|
+
super(`Setting "${key}" at scope ${scopeKind}:${scopeRefId ?? 'null'} was modified concurrently. ` +
|
|
42
|
+
`Reload the current value and retry.`, 'CONFLICT');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.ConflictError = ConflictError;
|
|
46
|
+
class CorruptError extends ConfTreeError {
|
|
47
|
+
constructor(valueId) {
|
|
48
|
+
super(`setting value row ${valueId} has no typed value set: data corruption`, 'CORRUPT');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.CorruptError = CorruptError;
|
|
52
|
+
class CycleError extends ConfTreeError {
|
|
53
|
+
constructor(id, newParentId) {
|
|
54
|
+
super(`Cannot attach/move scope "${id}" under "${newParentId}": would create a cycle`, 'CYCLE');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.CycleError = CycleError;
|
|
58
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":";;;AASA,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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
2
|
+
[key: string]: JsonValue;
|
|
3
|
+
};
|
|
4
|
+
export type Value = Date | JsonValue;
|
|
5
|
+
export interface Scope {
|
|
6
|
+
kind: string;
|
|
7
|
+
refId: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_SCOPE: Scope;
|
|
10
|
+
export type ValueType = 'BOOLEAN' | 'NUMERIC' | 'TEXT' | 'ENUM' | 'JSON' | 'DATE';
|
|
11
|
+
export type Inherit = 'LOCKED' | 'INHERITABLE_OVERRIDABLE' | 'INDEPENDENT';
|
|
12
|
+
export type Status = 'DRAFT' | 'STABLE' | 'DEPRECATED' | 'RETIRED';
|
|
13
|
+
export interface DefRecord {
|
|
14
|
+
id: string;
|
|
15
|
+
key: string;
|
|
16
|
+
version: number;
|
|
17
|
+
label: string;
|
|
18
|
+
description: string | null;
|
|
19
|
+
type: ValueType;
|
|
20
|
+
options: string[];
|
|
21
|
+
min: number | null;
|
|
22
|
+
max: number | null;
|
|
23
|
+
scopes: string[];
|
|
24
|
+
inherit: Inherit;
|
|
25
|
+
required: boolean;
|
|
26
|
+
secret: boolean;
|
|
27
|
+
status: Status;
|
|
28
|
+
category: string | null;
|
|
29
|
+
}
|
|
30
|
+
export interface ValueRecord {
|
|
31
|
+
id: string;
|
|
32
|
+
definitionId: string;
|
|
33
|
+
scopeKind: string;
|
|
34
|
+
scopeRefId: string | null;
|
|
35
|
+
bool: boolean | null;
|
|
36
|
+
num: number | null;
|
|
37
|
+
text: string | null;
|
|
38
|
+
json: unknown;
|
|
39
|
+
jsonSet: boolean;
|
|
40
|
+
date: Date | null;
|
|
41
|
+
version: number;
|
|
42
|
+
}
|
|
43
|
+
export interface ScopeHierarchy {
|
|
44
|
+
chain(scopeRefId: string): Promise<string[]>;
|
|
45
|
+
descendants(scopeRefId: string): Promise<string[]>;
|
|
46
|
+
children(scopeRefId: string): Promise<string[]>;
|
|
47
|
+
parent(scopeRefId: string): Promise<string | null>;
|
|
48
|
+
attach(id: string, parentId: string | null): Promise<void>;
|
|
49
|
+
move(id: string, newParentId: string | null): Promise<void>;
|
|
50
|
+
detach(id: string): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAClB,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEhC,MAAM,MAAM,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AAErC,MAAM,WAAW,KAAK;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,EAAE,KAAwC,CAAC;AAErE,MAAM,MAAM,SAAS,GACpB,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3D,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,yBAAyB,GAAG,aAAa,CAAC;AAE3E,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC9B,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":";;;AAea,QAAA,aAAa,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Scope } from '../core/types';
|
|
2
|
+
import type { AuditRecord, StorageReader } from '../storage/storage-port';
|
|
3
|
+
export declare class Auditor {
|
|
4
|
+
private readonly storage;
|
|
5
|
+
constructor(storage: StorageReader);
|
|
6
|
+
history(key: string, scope?: Scope): Promise<AuditRecord[]>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=auditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auditor.d.ts","sourceRoot":"","sources":["../../src/engine/auditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE1E,qBAAa,OAAO;IACP,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,aAAa;IAE7C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CAUjE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Auditor = void 0;
|
|
4
|
+
const errors_1 = require("../core/errors");
|
|
5
|
+
class Auditor {
|
|
6
|
+
storage;
|
|
7
|
+
constructor(storage) {
|
|
8
|
+
this.storage = storage;
|
|
9
|
+
}
|
|
10
|
+
async history(key, scope) {
|
|
11
|
+
const def = await this.storage.findAnyDef(key);
|
|
12
|
+
if (!def)
|
|
13
|
+
throw new errors_1.NotFoundError(key);
|
|
14
|
+
return this.storage.findAudit({
|
|
15
|
+
definitionId: def.id,
|
|
16
|
+
scopeKind: scope?.kind,
|
|
17
|
+
scopeRefId: scope?.refId,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.Auditor = Auditor;
|
|
22
|
+
//# sourceMappingURL=auditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auditor.js","sourceRoot":"","sources":["../../src/engine/auditor.ts"],"names":[],"mappings":";;;AACA,2CAA+C;AAG/C,MAAa,OAAO;IACU;IAA7B,YAA6B,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAAG,CAAC;IAEvD,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa;QACvC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,sBAAa,CAAC,GAAG,CAAC,CAAC;QAEvC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAC7B,YAAY,EAAE,GAAG,CAAC,EAAE;YACpB,SAAS,EAAE,KAAK,EAAE,IAAI;YACtB,UAAU,EAAE,KAAK,EAAE,KAAK;SACxB,CAAC,CAAC;IACJ,CAAC;CACD;AAbD,0BAaC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ChangeBus } from '../cache/change-bus';
|
|
2
|
+
import type { CacheOptions } from '../cache/cache';
|
|
3
|
+
import { Cache } from '../cache/cache';
|
|
4
|
+
import { Resolver } from './resolver';
|
|
5
|
+
import type { StorageAdapter } from '../storage/storage-port';
|
|
6
|
+
import type { ScopeHierarchy } from '../core/types';
|
|
7
|
+
import { Writer } from './writer';
|
|
8
|
+
import { Auditor } from './auditor';
|
|
9
|
+
export interface EngineOptions {
|
|
10
|
+
storage?: StorageAdapter;
|
|
11
|
+
hierarchy?: ScopeHierarchy;
|
|
12
|
+
bus?: ChangeBus;
|
|
13
|
+
cache?: CacheOptions | false;
|
|
14
|
+
}
|
|
15
|
+
export interface Engine {
|
|
16
|
+
storage: StorageAdapter;
|
|
17
|
+
hierarchy: ScopeHierarchy;
|
|
18
|
+
bus: ChangeBus;
|
|
19
|
+
cache: Cache;
|
|
20
|
+
resolver: Resolver;
|
|
21
|
+
writer: Writer;
|
|
22
|
+
auditor: Auditor;
|
|
23
|
+
}
|
|
24
|
+
export declare function createEngine(options?: EngineOptions): Engine;
|
|
25
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +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;AAGvC,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,CAYhE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEngine = createEngine;
|
|
4
|
+
const change_bus_1 = require("../cache/change-bus");
|
|
5
|
+
const cache_1 = require("../cache/cache");
|
|
6
|
+
const hierarchy_cache_sync_1 = require("./hierarchy-cache-sync");
|
|
7
|
+
const memory_storage_1 = require("../storage/memory-storage");
|
|
8
|
+
const resolver_1 = require("./resolver");
|
|
9
|
+
const scope_hierarchy_1 = require("../hierarchy/scope-hierarchy");
|
|
10
|
+
const writer_1 = require("./writer");
|
|
11
|
+
const auditor_1 = require("./auditor");
|
|
12
|
+
function createEngine(options = {}) {
|
|
13
|
+
const storage = options.storage ?? new memory_storage_1.MemoryStorageAdapter();
|
|
14
|
+
const rawHierarchy = options.hierarchy ?? new scope_hierarchy_1.LocalScopeHierarchy();
|
|
15
|
+
const bus = options.bus ?? new change_bus_1.LocalBus();
|
|
16
|
+
const cacheOptions = options.cache === false ? { enabled: false } : (options.cache ?? {});
|
|
17
|
+
const cache = new cache_1.Cache(bus, cacheOptions, rawHierarchy);
|
|
18
|
+
const hierarchy = (0, hierarchy_cache_sync_1.withHierarchyInvalidation)(rawHierarchy, cache);
|
|
19
|
+
const resolver = new resolver_1.Resolver(storage, hierarchy, cache);
|
|
20
|
+
const writer = new writer_1.Writer(storage, bus);
|
|
21
|
+
const auditor = new auditor_1.Auditor(storage);
|
|
22
|
+
return { storage, hierarchy, bus, cache, resolver, writer, auditor };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":";;AA8BA,oCAYC;AAzCD,oDAA+C;AAE/C,0CAAuC;AACvC,iEAAmE;AACnE,8DAAiE;AACjE,yCAAsC;AACtC,kEAAmE;AAGnE,qCAAkC;AAClC,uCAAoC;AAmBpC,SAAgB,YAAY,CAAC,UAAyB,EAAE;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,qCAAoB,EAAE,CAAC;IAC9D,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchy-cache-sync.d.ts","sourceRoot":"","sources":["../../src/engine/hierarchy-cache-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wBAAgB,yBAAyB,CACxC,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,KAAK,GACV,cAAc,CAqBhB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withHierarchyInvalidation = withHierarchyInvalidation;
|
|
4
|
+
function withHierarchyInvalidation(hierarchy, cache) {
|
|
5
|
+
return {
|
|
6
|
+
chain: (id) => hierarchy.chain(id),
|
|
7
|
+
descendants: (id) => hierarchy.descendants(id),
|
|
8
|
+
children: (id) => hierarchy.children(id),
|
|
9
|
+
parent: (id) => hierarchy.parent(id),
|
|
10
|
+
attach: async (id, parentId) => {
|
|
11
|
+
await hierarchy.attach(id, parentId);
|
|
12
|
+
cache.dropForScopes(await hierarchy.descendants(id));
|
|
13
|
+
},
|
|
14
|
+
move: async (id, newParentId) => {
|
|
15
|
+
const descendants = await hierarchy.descendants(id);
|
|
16
|
+
await hierarchy.move(id, newParentId);
|
|
17
|
+
cache.dropForScopes(descendants);
|
|
18
|
+
},
|
|
19
|
+
detach: async (id) => {
|
|
20
|
+
const descendants = await hierarchy.descendants(id);
|
|
21
|
+
await hierarchy.detach(id);
|
|
22
|
+
cache.dropForScopes(descendants);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=hierarchy-cache-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchy-cache-sync.js","sourceRoot":"","sources":["../../src/engine/hierarchy-cache-sync.ts"],"names":[],"mappings":";;AAGA,8DAwBC;AAxBD,SAAgB,yBAAyB,CACxC,SAAyB,EACzB,KAAY;IAEZ,OAAO;QACN,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9C,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;YAC9B,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACrC,KAAK,CAAC,aAAa,CAAC,MAAM,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE;YAC/B,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;YACtC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACpB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3B,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;KACD,CAAC;AACH,CAAC"}
|