@camstack/server 1.2.93 → 1.2.95
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/agent/addon-scan.js +131 -0
- package/dist/agent/main.js +35 -40
- package/dist/api/core/cap-providers.js +53 -9
- package/dist/api/trpc/generated-cap-mounts.js +3 -1
- package/dist/api/trpc/generated-cap-routers.js +471 -309
- package/dist/core/addon/addon-package.service.js +17 -2
- package/package.json +14 -14
- package/dist/agent/builtins-seed.js +0 -89
- package/dist/api/addons-custom.router.js +0 -99
- package/dist/api/core/bulk-update-coordinator.js +0 -229
- package/dist/api/core/settings-backend.router.js +0 -121
- package/dist/boot/resume-framework-swap.js +0 -119
- package/dist/core/addon/framework-live-sync.js +0 -344
- package/dist/launcher-framework-swap.js +0 -408
- package/dist/request-framework-swap.js +0 -41
- package/dist/server-root/boot-plan.js +0 -110
- package/dist/server-root/semver-compare.js +0 -45
- package/dist/server-root/server-root-state.js +0 -220
- package/dist/server-root/workspace-detect.js +0 -73
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.BUILTINS_PACKAGE = void 0;
|
|
37
|
+
exports.resolveAddonPackageDirs = resolveAddonPackageDirs;
|
|
38
|
+
exports.planAgentAddonScan = planAgentAddonScan;
|
|
39
|
+
/**
|
|
40
|
+
* Which directories the agent scans for addons — decided as pure data.
|
|
41
|
+
*
|
|
42
|
+
* ── The single-copy collapse, finally on the agent ─────────────────────────
|
|
43
|
+
* The hub stopped loading framework builtins from a physical
|
|
44
|
+
* `<addonsDir>/@camstack/system` on 2026-07-18: it loads them from the ACTIVE
|
|
45
|
+
* CLOSURE it is itself running (`addon-registry.service.ts`, `loadFromAddonDir`
|
|
46
|
+
* on the closure dir, then `loadFromDirectory(addonsDir, ['@camstack/system'])`
|
|
47
|
+
* so the copy is skipped). The reason is in that file's comment — *"that copy
|
|
48
|
+
* drifted because no update channel refreshed it"*.
|
|
49
|
+
*
|
|
50
|
+
* The agent never got the change, and drifted exactly as predicted. Measured
|
|
51
|
+
* 2026-08-11: little-unraid carried `@camstack/system@1.2.61` and macmini
|
|
52
|
+
* `1.2.62` in their addon roots while both ran a `1.2.78` closure. Nothing
|
|
53
|
+
* refreshed them, because `seedBuiltinsFromClosure` (now deleted) only wrote
|
|
54
|
+
* the copy when it was ABSENT — a self-heal that guaranteed a copy existed and
|
|
55
|
+
* never that it was current. It also contradicted
|
|
56
|
+
* `AddonInstaller.shouldSkipClosureProvidedSeed`, which already refused to
|
|
57
|
+
* plant that copy for this very reason.
|
|
58
|
+
*
|
|
59
|
+
* ── Why the skip is correctness, not tidiness ──────────────────────────────
|
|
60
|
+
* `AddonLoader` keys its map on `declaration.id`, so loading the closure AND a
|
|
61
|
+
* stale copy through one loader is not a duplicate — it is LAST-LOAD-WINS. The
|
|
62
|
+
* builtins a node runs would depend on directory iteration order. The copy must
|
|
63
|
+
* be skipped, not merely deprioritized.
|
|
64
|
+
*
|
|
65
|
+
* ── The fallback ──────────────────────────────────────────────────────────
|
|
66
|
+
* If the closure cannot be resolved, the copy is NOT skipped and the node boots
|
|
67
|
+
* from it. In a running agent this is near-impossible — `agent/main.ts`
|
|
68
|
+
* statically imports `@camstack/system`, so if the process exists the walk-up
|
|
69
|
+
* resolves — but a node with neither source must fail through the D87 guard
|
|
70
|
+
* (`assertRequiredInfraResolved`, which names every missing required cap),
|
|
71
|
+
* never through a silent "no addon packages found" early return.
|
|
72
|
+
*/
|
|
73
|
+
const fs = __importStar(require("node:fs"));
|
|
74
|
+
const path = __importStar(require("node:path"));
|
|
75
|
+
/** The framework builtins package. Loaded from the closure, never from a copy. */
|
|
76
|
+
exports.BUILTINS_PACKAGE = '@camstack/system';
|
|
77
|
+
function isDir(p) {
|
|
78
|
+
try {
|
|
79
|
+
return fs.statSync(p).isDirectory();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Every installed addon package under `addonsDir`, minus `skipPackages`.
|
|
87
|
+
*
|
|
88
|
+
* Matching mirrors `AddonLoader.loadFromDirectory`'s skip list exactly —
|
|
89
|
+
* `<scope>/<name>` for a scoped directory, the bare name for a flat one — so
|
|
90
|
+
* the hub and the agent exclude the same thing given the same list.
|
|
91
|
+
*/
|
|
92
|
+
function resolveAddonPackageDirs(addonsDir, skipPackages = []) {
|
|
93
|
+
const dirs = [];
|
|
94
|
+
if (!fs.existsSync(addonsDir))
|
|
95
|
+
return dirs;
|
|
96
|
+
const skip = new Set(skipPackages);
|
|
97
|
+
for (const name of fs.readdirSync(addonsDir)) {
|
|
98
|
+
const full = path.join(addonsDir, name);
|
|
99
|
+
if (name.startsWith('@') && isDir(full)) {
|
|
100
|
+
// Scoped packages: @camstack/addon-xyz
|
|
101
|
+
for (const sub of fs.readdirSync(full)) {
|
|
102
|
+
const subFull = path.join(full, sub);
|
|
103
|
+
if (skip.has(`${name}/${sub}`))
|
|
104
|
+
continue;
|
|
105
|
+
if (isDir(subFull) && fs.existsSync(path.join(subFull, 'package.json'))) {
|
|
106
|
+
dirs.push(subFull);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (isDir(full) && fs.existsSync(path.join(full, 'package.json'))) {
|
|
111
|
+
if (skip.has(name))
|
|
112
|
+
continue;
|
|
113
|
+
dirs.push(full);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return dirs;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The ordered directory list `bootCoreAddons` loads, closure first.
|
|
120
|
+
*
|
|
121
|
+
* `closureSystemDir` is `resolveHubClosurePackageDir(BUILTINS_PACKAGE)` — null
|
|
122
|
+
* only when the builtins are not resolvable from the running closure at all.
|
|
123
|
+
*/
|
|
124
|
+
function planAgentAddonScan(addonsDir, closureSystemDir) {
|
|
125
|
+
if (closureSystemDir === null) {
|
|
126
|
+
// No closure copy: fall back to whatever is on disk, including the
|
|
127
|
+
// addon-root builtins, rather than booting with no infra at all.
|
|
128
|
+
return resolveAddonPackageDirs(addonsDir);
|
|
129
|
+
}
|
|
130
|
+
return [closureSystemDir, ...resolveAddonPackageDirs(addonsDir, [exports.BUILTINS_PACKAGE])];
|
|
131
|
+
}
|
package/dist/agent/main.js
CHANGED
|
@@ -47,7 +47,8 @@ const agent_update_service_js_1 = require("./agent-update-service.js");
|
|
|
47
47
|
const server_management_provider_js_1 = require("../api/core/server-management.provider.js");
|
|
48
48
|
const infra_boot_guard_js_1 = require("./infra-boot-guard.js");
|
|
49
49
|
const infra_boot_plan_js_1 = require("./infra-boot-plan.js");
|
|
50
|
-
const
|
|
50
|
+
const package_dir_utils_js_1 = require("../core/addon/package-dir-utils.js");
|
|
51
|
+
const addon_scan_js_1 = require("./addon-scan.js");
|
|
51
52
|
const agent_service_js_1 = require("./agent-service.js");
|
|
52
53
|
const agent_group_runner_js_1 = require("./agent-group-runner.js");
|
|
53
54
|
const register_agent_cap_dispatch_js_1 = require("./register-agent-cap-dispatch.js");
|
|
@@ -769,13 +770,21 @@ async function startAgent(configPath) {
|
|
|
769
770
|
// Core infra addons to load on agent — all infra including log-destination (hub-forwarder)
|
|
770
771
|
const AGENT_INFRA = system_1.INFRA_CAPABILITIES;
|
|
771
772
|
async function bootCoreAddons(broker, config, registry, loadedAddons, loggerFactory) {
|
|
772
|
-
//
|
|
773
|
-
//
|
|
774
|
-
//
|
|
775
|
-
|
|
776
|
-
//
|
|
777
|
-
//
|
|
778
|
-
const
|
|
773
|
+
// Builtins come from the CLOSURE this process is running, exactly as the hub
|
|
774
|
+
// has done since 2026-07-18 — never from a `<addonsDir>/@camstack/system`
|
|
775
|
+
// copy, which nothing refreshes and which therefore drifts (both agents were
|
|
776
|
+
// 17 versions behind on 2026-08-11). `planAgentAddonScan` owns the decision
|
|
777
|
+
// and the fallback; see `addon-scan.ts`. Non-framework infra providers
|
|
778
|
+
// (e.g. `@camstack/addon-platform-probe-native`) still come from the scan.
|
|
779
|
+
const closureSystemDir = (0, package_dir_utils_js_1.resolveHubClosurePackageDir)(addon_scan_js_1.BUILTINS_PACKAGE);
|
|
780
|
+
if (closureSystemDir === null) {
|
|
781
|
+
// Louder than the hub's warn: on an agent the builtins ARE the infra, so
|
|
782
|
+
// this is pre-fatal. Boot continues to the D87 guard, which names every
|
|
783
|
+
// required cap it could not resolve.
|
|
784
|
+
console.error(`[Agent] ${addon_scan_js_1.BUILTINS_PACKAGE} not resolvable from the running closure — ` +
|
|
785
|
+
'falling back to the addon-root copy, if there is one');
|
|
786
|
+
}
|
|
787
|
+
const packageDirs = (0, addon_scan_js_1.planAgentAddonScan)(config.addonsDir, closureSystemDir);
|
|
779
788
|
if (packageDirs.length === 0) {
|
|
780
789
|
console.warn('[Agent] No addon packages found — running without infrastructure addons');
|
|
781
790
|
return;
|
|
@@ -876,7 +885,13 @@ async function bootCoreAddons(broker, config, registry, loadedAddons, loggerFact
|
|
|
876
885
|
// Phase 1.5: Load cluster-capable addon packages
|
|
877
886
|
// ---------------------------------------------------------------------------
|
|
878
887
|
async function loadClusterCapableAddons(broker, config, capabilityRegistry, loadedAddons) {
|
|
879
|
-
|
|
888
|
+
// Builtins are in-process infra, never group-spawned, and they come from the
|
|
889
|
+
// closure — so the addon-root copy is skipped here too. Leaving it in would
|
|
890
|
+
// import a stale entry module during the scan below, which is the whole thing
|
|
891
|
+
// the single-copy collapse removes. The closure dir is deliberately NOT added:
|
|
892
|
+
// adding it would newly expose `hub-forwarder` / `platform-probe` (the only
|
|
893
|
+
// builtins carrying `execution`) as spawn candidates.
|
|
894
|
+
const addonPackageDirs = (0, addon_scan_js_1.resolveAddonPackageDirs)(config.addonsDir, systemSkipList());
|
|
880
895
|
if (addonPackageDirs.length === 0)
|
|
881
896
|
return;
|
|
882
897
|
// ── Phase 0 (cross-package): collect every group-eligible addon
|
|
@@ -974,7 +989,9 @@ async function loadDeployedAddons(broker, addonsDir, dataDir, loadedAddons, stor
|
|
|
974
989
|
// the agent MAIN thread is what wedged `$agent.reload` and dropped the node
|
|
975
990
|
// from topology. A group-runner addon only needs its declaration to be
|
|
976
991
|
// (re)dispatched to a subprocess, which loads the real module itself.
|
|
977
|
-
|
|
992
|
+
// Same skip: a `$agent.deploy` of `@camstack/system` still lands bytes in the
|
|
993
|
+
// addon root, but a reload must not adopt them over the closure.
|
|
994
|
+
const packageDirs = (0, addon_scan_js_1.resolveAddonPackageDirs)(addonsDir, systemSkipList());
|
|
978
995
|
const groupCandidates = [];
|
|
979
996
|
// Dirs holding a deployable NON-group addon — and ONLY these — need the
|
|
980
997
|
// importing loader. None exist under the default `hub-only` placement
|
|
@@ -1118,36 +1135,14 @@ function readAgentVersion() {
|
|
|
1118
1135
|
}
|
|
1119
1136
|
return 'unknown';
|
|
1120
1137
|
}
|
|
1121
|
-
/**
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
}
|
|
1130
|
-
/** Scan addonsDir for addon packages (scoped and unscoped, follows symlinks) */
|
|
1131
|
-
function resolveAddonPackageDirs(addonsDir) {
|
|
1132
|
-
const dirs = [];
|
|
1133
|
-
if (!fs.existsSync(addonsDir))
|
|
1134
|
-
return dirs;
|
|
1135
|
-
for (const name of fs.readdirSync(addonsDir)) {
|
|
1136
|
-
const full = path.join(addonsDir, name);
|
|
1137
|
-
if (name.startsWith('@') && isDir(full)) {
|
|
1138
|
-
// Scoped packages: @camstack/addon-xyz
|
|
1139
|
-
for (const sub of fs.readdirSync(full)) {
|
|
1140
|
-
const subFull = path.join(full, sub);
|
|
1141
|
-
if (isDir(subFull) && fs.existsSync(path.join(subFull, 'package.json'))) {
|
|
1142
|
-
dirs.push(subFull);
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
else if (isDir(full) && fs.existsSync(path.join(full, 'package.json'))) {
|
|
1147
|
-
dirs.push(full);
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
return dirs;
|
|
1138
|
+
/**
|
|
1139
|
+
* Skip the addon-root builtins copy — but ONLY when the closure can supply
|
|
1140
|
+
* them. Same condition `planAgentAddonScan` applies, kept in one place so the
|
|
1141
|
+
* infra scan and the two deployable-addon scans can never disagree about which
|
|
1142
|
+
* copy is authoritative.
|
|
1143
|
+
*/
|
|
1144
|
+
function systemSkipList() {
|
|
1145
|
+
return (0, package_dir_utils_js_1.resolveHubClosurePackageDir)(addon_scan_js_1.BUILTINS_PACKAGE) === null ? [] : [addon_scan_js_1.BUILTINS_PACKAGE];
|
|
1151
1146
|
}
|
|
1152
1147
|
// ---------------------------------------------------------------------------
|
|
1153
1148
|
// E1 helper — agent-local UDS child manifest adaptation
|
|
@@ -1176,14 +1176,24 @@ function isHubNode(nodeId) {
|
|
|
1176
1176
|
* agent reports its addon roster (id + status + version + packageName);
|
|
1177
1177
|
* we keep only entries that carry both a package name and a version so
|
|
1178
1178
|
* the hub can diff them against npm.
|
|
1179
|
+
*
|
|
1180
|
+
* `@camstack/system` is KEPT, and it is one of the most important entries here.
|
|
1181
|
+
* On an agent, `addons/@camstack/system` is the only copy of the builtin infra
|
|
1182
|
+
* ([D87](../../../../docs/decisions/adr-0087.md)), so a pending update on it is
|
|
1183
|
+
* a true, actionable signal: the node's infra is behind the closure it runs
|
|
1184
|
+
* against. Both agents sat 17 versions behind that way until 2026-08-11. Do not
|
|
1185
|
+
* filter it out to make the list look clean — the number reaching zero is the
|
|
1186
|
+
* point of the number.
|
|
1179
1187
|
*/
|
|
1180
1188
|
async function fetchAgentInstalledPackages(broker, nodeId) {
|
|
1181
1189
|
const status = await broker.call('$agent.status', {}, { nodeID: nodeId, timeout: 5_000 });
|
|
1182
1190
|
const out = [];
|
|
1183
1191
|
for (const a of status.addons ?? []) {
|
|
1184
|
-
if (typeof a.packageName
|
|
1185
|
-
|
|
1186
|
-
|
|
1192
|
+
if (typeof a.packageName !== 'string' || typeof a.version !== 'string')
|
|
1193
|
+
continue;
|
|
1194
|
+
if ((0, addon_package_service_js_1.isFrameworkPackage)(a.packageName))
|
|
1195
|
+
continue;
|
|
1196
|
+
out.push({ name: a.packageName, version: a.version });
|
|
1187
1197
|
}
|
|
1188
1198
|
return out;
|
|
1189
1199
|
}
|
|
@@ -1253,6 +1263,22 @@ function buildAddonsProvider(ar, ps, ls, moleculer, configService, ctx) {
|
|
|
1253
1263
|
}
|
|
1254
1264
|
return { success: false, error: task?.error ?? 'update failed', jobId };
|
|
1255
1265
|
}
|
|
1266
|
+
// `@camstack/system` DELIBERATELY travels this way to an agent, and it is
|
|
1267
|
+
// the only way it can. On the hub, `addons/@camstack/system` is a shadow
|
|
1268
|
+
// of the closure; on an AGENT it is THE ONLY COPY of the builtin infra —
|
|
1269
|
+
// `bootCoreAddons` scans the addon root and nothing else, and the image
|
|
1270
|
+
// seed excludes the framework set on purpose ([D87](../../../../docs/decisions/adr-0087.md)).
|
|
1271
|
+
// Removing it on 2026-08-07 left the node with no `filesystem-storage`,
|
|
1272
|
+
// `sqlite-settings`, `storage-orchestrator`, `hub-forwarder`,
|
|
1273
|
+
// `metrics-native` or `platform-probe`, and the outage was unobservable
|
|
1274
|
+
// because the log shipper was in the same package.
|
|
1275
|
+
//
|
|
1276
|
+
// So do NOT add a framework guard here. A 2026-08-11 attempt to do so read
|
|
1277
|
+
// the launcher's `resolved @camstack/system@… from <activeRoot>` line as
|
|
1278
|
+
// proof that nothing loads the addon-root copy. That line answers which
|
|
1279
|
+
// copy the LAUNCHER resolves for its own imports — a different consumer
|
|
1280
|
+
// from `bootCoreAddons`. Same trap D45 names: a version is a property of a
|
|
1281
|
+
// path, and a path is only evidence about the consumer that reads it.
|
|
1256
1282
|
// Agent target: the hub packs the resolved version and ships the
|
|
1257
1283
|
// tarball over `$agent.deploy` — the agent has no npm runtime.
|
|
1258
1284
|
// The reload re-instantiates the changed package's addons; for a large
|
|
@@ -1349,12 +1375,30 @@ function buildAddonsProvider(ar, ps, ls, moleculer, configService, ctx) {
|
|
|
1349
1375
|
return { success: true };
|
|
1350
1376
|
},
|
|
1351
1377
|
// ── Lifecycle job engine ─────────────────────────────────────────
|
|
1352
|
-
startJob: async (input) =>
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1378
|
+
startJob: async (input) => {
|
|
1379
|
+
// The engine is HUB-LOCAL: `StartJobInput.nodeIds` is declared
|
|
1380
|
+
// "reserved for future cluster jobs" and nothing reads it. Passing an
|
|
1381
|
+
// agent id therefore used to apply every target to the HUB while the
|
|
1382
|
+
// job, its per-task `nodeId` and the UI all reported the agent — so
|
|
1383
|
+
// "Update all" on a selected agent silently updated the wrong node and
|
|
1384
|
+
// left the agent pending forever. That is how two agents sat at 8
|
|
1385
|
+
// pending addons across several sessions (2026-08-11). Refuse instead:
|
|
1386
|
+
// an agent converges one package at a time through `updatePackage`,
|
|
1387
|
+
// which has a real `$agent.deploy` path.
|
|
1388
|
+
const offNode = (input.nodeIds ?? []).filter((id) => !isHubNode(id));
|
|
1389
|
+
if (offNode.length > 0) {
|
|
1390
|
+
throw new server_1.TRPCError({
|
|
1391
|
+
code: 'BAD_REQUEST',
|
|
1392
|
+
message: `The lifecycle job engine is hub-local; it cannot target ${offNode.join(', ')}. Update an agent's packages via updatePackage({ nodeId }).`,
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
return lifecycleRunner.startJob({
|
|
1396
|
+
kind: input.kind,
|
|
1397
|
+
targets: input.targets,
|
|
1398
|
+
nodeIds: input.nodeIds,
|
|
1399
|
+
createdBy: lifecycleCreatedBy,
|
|
1400
|
+
});
|
|
1401
|
+
},
|
|
1358
1402
|
getJob: async (input) => lifecycleRunner.getJob(input.jobId),
|
|
1359
1403
|
listJobs: async (input) => lifecycleRunner.listJobs({ activeOnly: input.activeOnly }),
|
|
1360
1404
|
cancelJob: async (input) => lifecycleRunner.cancelJob(input.jobId),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// AUTO-GENERATED by scripts/generate-cap-mounts.ts — DO NOT EDIT
|
|
3
3
|
// Re-run: npx tsx scripts/generate-cap-mounts.ts
|
|
4
4
|
//
|
|
5
|
-
// Mounted:
|
|
5
|
+
// Mounted: 146 Skipped (legacy): 3
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.LEGACY_SHAPE_SKIP = void 0;
|
|
8
8
|
exports.mountAllCaps = mountAllCaps;
|
|
@@ -406,6 +406,8 @@ function mountAllCaps(services) {
|
|
|
406
406
|
const entries = reg.getCollectionEntries('storage-evictable');
|
|
407
407
|
return entries[0]?.[1] ?? null;
|
|
408
408
|
}, remoteCapProxy),
|
|
409
|
+
storageMigration: (0, generated_cap_routers_js_1.createCapRouter_storageMigration)((_ctx) => reg?.getSingleton('storage-migration') ??
|
|
410
|
+
null, remoteCapProxy),
|
|
409
411
|
storageProvider: (0, generated_cap_routers_js_1.createCapRouter_storageProvider)((_ctx, addonId) => {
|
|
410
412
|
if (!reg)
|
|
411
413
|
return null;
|