@camstack/system 1.2.201 → 1.2.203
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/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +12 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +37 -3
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +37 -3
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/drain-ratchet.d.ts +104 -0
- package/dist/builtins/storage-orchestrator/drain-state-store.d.ts +13 -0
- package/dist/builtins/storage-orchestrator/location-occupancy-slice.d.ts +47 -0
- package/dist/builtins/storage-orchestrator/location-protection.d.ts +20 -0
- package/dist/builtins/storage-orchestrator/location-root-collision.d.ts +44 -0
- package/dist/builtins/storage-orchestrator/location-store.d.ts +12 -3
- package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +9 -9
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +47 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +865 -157
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +865 -157
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +75 -31
- package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +45 -0
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-CcV3k-hD.js → dist-BFvWv_bz.js} +933 -546
- package/dist/{dist-BmJNnb_s.mjs → dist-DcMUcdeq.mjs} +862 -547
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-nLVKlhe-.mjs → retired-settings-keys-CJfgnUSb.mjs} +1 -1
- package/dist/{retired-settings-keys-Bd8fuwO1.js → retired-settings-keys-Dd7K3K3r.js} +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IScopedLogger, IStorageProviderImpl, StorageAccess, StorageLocation, StorageLocationDeclaration, StorageLocationRef } from '@camstack/types';
|
|
2
|
+
import { ResolveRoot } from './location-root-collision.js';
|
|
2
3
|
import { ILocationStore } from './location-store.js';
|
|
3
4
|
export interface ListLocationsFilter {
|
|
4
5
|
readonly type?: string;
|
|
@@ -184,23 +185,37 @@ export declare class StorageOrchestratorService {
|
|
|
184
185
|
*/
|
|
185
186
|
attachStore(store: ILocationStore): Promise<void>;
|
|
186
187
|
/**
|
|
187
|
-
*
|
|
188
|
+
* ONE explicit migration onto the four-state model (D385), run once per boot
|
|
189
|
+
* against the rows that came off disk. Idempotent: the second boot finds
|
|
190
|
+
* nothing to do.
|
|
188
191
|
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* hand-edited store or a row written by another build can too. It matters
|
|
192
|
-
* because every bare-type ref still resolves through {@link getDefaultLocation}
|
|
193
|
-
* until Stage 5 of the enabled-write-set design: on such a row
|
|
194
|
-
* `storage.write({ location: 'eventMedia' })` and the migration coordinator's
|
|
195
|
-
* drain destination both point at a disk the operator turned off.
|
|
192
|
+
* Two steps, in order, and each one is a WRITE — the point is that "absent"
|
|
193
|
+
* stops existing rather than being re-interpreted on every read forever:
|
|
196
194
|
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
195
|
+
* 1. A row with no `mode` is stamped with the mode its legacy flags imply
|
|
196
|
+
* (`legacyModeOf`): `config.readOnly === true` → `readonly` and the
|
|
197
|
+
* config key is DELETED; `enabled === false` → `readonly` (the
|
|
198
|
+
* CONSERVATIVE direction — a state change must never start deleting
|
|
199
|
+
* footage on its own); everything else → `active`. `withLocationMode`
|
|
200
|
+
* derives `enabled` from the mode, so the two can never disagree, and
|
|
201
|
+
* this subsumes the D383 pass that stamped flagless rows `enabled: true`.
|
|
202
|
+
* 2. A type left with NO write target — only reachable from a hand-edited
|
|
203
|
+
* store or a row an older build wrote — gets one made `active`, chosen as
|
|
204
|
+
* the row the RETIRED default flag named, else the `:default`-slugged
|
|
205
|
+
* row, else the lexicographically first. Loudly: a class with no write
|
|
206
|
+
* target records nowhere, and refusing to repair it here would leave the
|
|
207
|
+
* hub silently unable to write with no operator action pending.
|
|
208
|
+
*
|
|
209
|
+
* An operator's explicit `readonly`/`drain`/`disabled` is never reversed by
|
|
210
|
+
* step 1 — only step 2 touches it, and only when the alternative is a class
|
|
211
|
+
* that cannot write at all.
|
|
212
|
+
*
|
|
213
|
+
* On the live hub every location is enabled with no `readOnly`, so step 1 is
|
|
214
|
+
* a no-op that stamps `active` and nothing else changes.
|
|
202
215
|
*/
|
|
203
|
-
private
|
|
216
|
+
private migrateOntoTheWriteSet;
|
|
217
|
+
/** Apply one migrated row in memory and mirror it to the store. */
|
|
218
|
+
private persistMigrated;
|
|
204
219
|
/**
|
|
205
220
|
* Inject the declaration-driven cardinality source. Called once by the
|
|
206
221
|
* addon after the kernel aggregates every addon's `storageLocations`
|
|
@@ -259,22 +274,36 @@ export declare class StorageOrchestratorService {
|
|
|
259
274
|
*/
|
|
260
275
|
backfillNodeIds(hubNodeId: string): Promise<void>;
|
|
261
276
|
listLocations(filter?: ListLocationsFilter): readonly StorageLocation[];
|
|
262
|
-
getDefaultLocation(type: string): StorageLocation | null;
|
|
263
277
|
/**
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
* a
|
|
267
|
-
* the
|
|
278
|
+
* The WRITE SET of a type: every enabled location of it, in stable id order.
|
|
279
|
+
* This replaced `getDefaultLocation` (D383) — a type does not have one write
|
|
280
|
+
* target any more, it has a pool, and every consumer that must pick one picks
|
|
281
|
+
* from here by its own rule (the recorder by headroom, a drain by an operator
|
|
282
|
+
* -named destination).
|
|
268
283
|
*/
|
|
269
|
-
|
|
284
|
+
writeTargets(type: string): readonly StorageLocation[];
|
|
270
285
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
286
|
+
* Change the WRITE SET as one compensated commit: each named location is
|
|
287
|
+
* enabled (it joins the pool) or disabled (it becomes read-only — still read,
|
|
288
|
+
* still played back, still age-swept, still drained).
|
|
289
|
+
*
|
|
290
|
+
* This is the cutover verb, and its only caller is the migration coordinator,
|
|
291
|
+
* which persists its `repointing` phase BEFORE calling so a crash mid-write
|
|
292
|
+
* is recovered by replaying the same idempotent set before writers resume.
|
|
274
293
|
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
294
|
+
* It moves ONLY the locations it is given: a cutover from A to C on a class
|
|
295
|
+
* that also writes to B leaves B in the pool, because the operator's pool is
|
|
296
|
+
* the authority and a migration is not a licence to shrink it. The commit is
|
|
297
|
+
* refused when it would leave a write-serving type with nothing enabled —
|
|
298
|
+
* the same refusal `upsertLocation` applies, judged on the RESULT so an
|
|
299
|
+
* enable and a disable in one commit are weighed together.
|
|
300
|
+
*/
|
|
301
|
+
setWriteTargets(enabledByLocationId: ReadonlyMap<string, boolean>): Promise<void>;
|
|
302
|
+
/**
|
|
303
|
+
* Insert or update a location.
|
|
304
|
+
*
|
|
305
|
+
* When a persistence store is wired (Task 6), the record is mirrored to it;
|
|
306
|
+
* the mirror is fire-and-forget and its errors reach the logger.
|
|
278
307
|
*/
|
|
279
308
|
/**
|
|
280
309
|
* Refuse a `(location kind, provider)` pair the kind cannot use.
|
|
@@ -310,8 +339,7 @@ export declare class StorageOrchestratorService {
|
|
|
310
339
|
/**
|
|
311
340
|
* Remove a location. Refuses the last location of a type and the last
|
|
312
341
|
* enabled location of a type. `isSystem` is informational — a frozen
|
|
313
|
-
* recordings `:default` is deletable once a sibling is live.
|
|
314
|
-
* the flagged default promotes an enabled sibling. Occupancy still
|
|
342
|
+
* recordings `:default` is deletable once a sibling is live. Occupancy still
|
|
315
343
|
* refuses unless `force` is set; force never overrides uniqueness /
|
|
316
344
|
* last-enabled.
|
|
317
345
|
*/
|
|
@@ -392,9 +420,11 @@ export declare class StorageOrchestratorService {
|
|
|
392
420
|
* declarations on a populated map is a no-op (each declared `id`
|
|
393
421
|
* already resolves to an existing `<id>:default`).
|
|
394
422
|
*
|
|
395
|
-
*
|
|
396
|
-
* `
|
|
397
|
-
*
|
|
423
|
+
* The seeded row is born ENABLED — a fresh install must be able to write the
|
|
424
|
+
* moment it boots, and `enabled` is the only write switch there is (D383).
|
|
425
|
+
* The `:default` suffix is a NAME kept for idempotency across existing
|
|
426
|
+
* installs, not a flag: the stored `id` is `'recordings:default'` so it
|
|
427
|
+
* satisfies the
|
|
398
428
|
* `^[a-z][a-z0-9-]*:[a-z0-9-]+$` regex on `StorageLocationSchema.id`.
|
|
399
429
|
*
|
|
400
430
|
* `basePath` is the storage root (e.g. `<CAMSTACK_DATA>`). Each
|
|
@@ -420,6 +450,20 @@ export declare class StorageOrchestratorService {
|
|
|
420
450
|
readonly backupBasePath?: string;
|
|
421
451
|
readonly declarations: readonly StorageLocationDeclaration[];
|
|
422
452
|
}): void;
|
|
453
|
+
/**
|
|
454
|
+
* The same-type physical-root refusal (D389).
|
|
455
|
+
*
|
|
456
|
+
* An unresolvable root — another node's disk, a remote provider, a path that
|
|
457
|
+
* does not exist yet — WARNS and lets the write through. Refusing on a read
|
|
458
|
+
* that could not be taken blocks the operator on a doubt, and the recorder's
|
|
459
|
+
* demotion still catches what slips past (D49's spirit).
|
|
460
|
+
*/
|
|
461
|
+
private refuseSameTypeRootCollision;
|
|
462
|
+
/** Injectable so a test can drive symlinks and unresolvable paths without
|
|
463
|
+
* touching a real filesystem. Production takes the shared derivation. */
|
|
464
|
+
private resolveRoot;
|
|
465
|
+
/** Test seam for {@link refuseSameTypeRootCollision}. */
|
|
466
|
+
setRootResolver(resolveRoot: ResolveRoot): void;
|
|
423
467
|
/** Internal: check whether any location of the given type exists. */
|
|
424
468
|
private hasAnyLocationOfType;
|
|
425
469
|
}
|
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
import { IScopedLogger, IStorageEvictableProvider } from '@camstack/types';
|
|
2
|
+
import { DrainProgress, DrainState } from './drain-ratchet.js';
|
|
3
|
+
/**
|
|
4
|
+
* One draining location and the ACTIVE locations of its class the drain is
|
|
5
|
+
* paced against (D386). Supplied by the orchestrator, which is the only thing
|
|
6
|
+
* that knows a location's mode.
|
|
7
|
+
*/
|
|
8
|
+
export interface DrainPlanEntry {
|
|
9
|
+
readonly locationId: string;
|
|
10
|
+
/** Locations of the SAME class whose growth the drain is matched to. Empty
|
|
11
|
+
* means the pace is unmeasurable and the cap stands still. */
|
|
12
|
+
readonly activePeerLocationIds: readonly string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Durable home for the ratchet state. It MUST survive a process restart: a cap
|
|
16
|
+
* recomputed from today's usage starts again at the top and silently undoes
|
|
17
|
+
* every byte of progress.
|
|
18
|
+
*/
|
|
19
|
+
export interface DrainStateStore {
|
|
20
|
+
load(): Promise<readonly DrainState[]>;
|
|
21
|
+
save(state: DrainState): Promise<void>;
|
|
22
|
+
clear(locationId: string): Promise<void>;
|
|
23
|
+
}
|
|
2
24
|
/**
|
|
3
25
|
* StoragePressureManager — core-owned TRIGGER for disk-space relief.
|
|
4
26
|
*
|
|
@@ -50,12 +72,35 @@ export interface PressureManagerDeps {
|
|
|
50
72
|
* independently), preserving prior single-disk behaviour.
|
|
51
73
|
*/
|
|
52
74
|
readonly getLocationDeviceKey?: (locationId: string) => Promise<string | null>;
|
|
75
|
+
/** Locations in `drain` mode, each with the active peers of its class.
|
|
76
|
+
* Absent → no drain (the behaviour before D386). */
|
|
77
|
+
readonly getDrainPlan?: () => Promise<readonly DrainPlanEntry[]>;
|
|
78
|
+
/** Where the ratchet state lives across restarts. Absent → drain is inert:
|
|
79
|
+
* without persistence the cap would reset on every boot, which is worse
|
|
80
|
+
* than not draining. */
|
|
81
|
+
readonly drainState?: DrainStateStore;
|
|
53
82
|
}
|
|
54
83
|
export declare class StoragePressureManager {
|
|
55
84
|
private readonly deps;
|
|
85
|
+
/** Last sweep's drain progress, by location. Read-only surface for the UI. */
|
|
86
|
+
private drainProgress;
|
|
56
87
|
constructor(deps: PressureManagerDeps);
|
|
57
88
|
/** Relieve every managed location currently under its threshold. */
|
|
58
89
|
sweep(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* The drain pass (D386). A `drain` location is excluded from nothing — it is
|
|
92
|
+
* given a monotonically descending effective usage cap and handed to the SAME
|
|
93
|
+
* `relieveToUsageCap` machinery every other cap uses. There is no second
|
|
94
|
+
* eviction path, and no operator-facing rate.
|
|
95
|
+
*/
|
|
96
|
+
private sweepDrains;
|
|
97
|
+
/** Progress for every draining location, as of the last sweep. The read a UI
|
|
98
|
+
* asks for — it never triggers work of its own. */
|
|
99
|
+
drainProgressSnapshot(): readonly DrainProgress[];
|
|
100
|
+
/** Evictable bytes on one location, summed across every provider. */
|
|
101
|
+
private evictableUsageOf;
|
|
102
|
+
/** Evictable bytes across a set of locations. */
|
|
103
|
+
private evictableUsageOfAll;
|
|
59
104
|
/** Evict oldest-first until the location's evictable usage fits `maxBytes`. */
|
|
60
105
|
private relieveToUsageCap;
|
|
61
106
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BFvWv_bz.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Jt as BaseAddon, dn as hydrateSchema, qt as errMsg } from "../../dist-DcMUcdeq.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BFvWv_bz.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Jt as BaseAddon, ht as logDestinationCapability } from "../../dist-DcMUcdeq.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|