@camstack/server 1.0.2 → 1.0.3
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/api/addon-upload.js +17 -3
- package/dist/api/bridge-addons.router.js +1 -1
- package/dist/api/capabilities.router.js +3 -3
- package/dist/api/core/cap-providers.js +3 -3
- package/dist/api/core/logs.router.js +1 -1
- package/dist/api/core/notifications.router.js +1 -1
- package/dist/api/core/repl.router.js +1 -1
- package/dist/api/health/health.routes.js +7 -2
- package/dist/api/trpc/cap-route-error-formatter.js +3 -3
- package/dist/api/trpc/core-cap-bridge.js +2 -2
- package/dist/api/trpc/generated-cap-routers.js +4 -4
- package/dist/boot/boot-config.js +2 -2
- package/dist/boot/post-boot.service.js +2 -2
- package/dist/core/addon/addon-call-gateway.js +1 -1
- package/dist/core/addon/addon-package.service.js +37 -43
- package/dist/core/addon/addon-registry.service.js +61 -51
- package/dist/core/addon-bridge/addon-bridge.service.js +6 -6
- package/dist/core/addon-pages/addon-pages.service.js +1 -1
- package/dist/core/auth/auth.service.js +2 -2
- package/dist/core/config/config.schema.js +4 -4
- package/dist/core/config/config.service.js +2 -2
- package/dist/core/events/event-bus.service.js +2 -2
- package/dist/core/feature/feature.service.js +2 -2
- package/dist/core/lifecycle/lifecycle-state-machine.js +3 -3
- package/dist/core/logging/log-ring-buffer.js +3 -3
- package/dist/core/logging/logging.service.js +3 -3
- package/dist/core/logging/scoped-logger.js +3 -3
- package/dist/core/moleculer/cap-route-authority.js +2 -2
- package/dist/core/moleculer/moleculer.service.js +22 -22
- package/dist/core/network/network-quality.service.js +2 -2
- package/dist/core/notification/notification-wrapper.service.js +2 -2
- package/dist/core/notification/toast-wrapper.service.js +2 -2
- package/dist/core/repl/repl-engine.service.js +2 -2
- package/dist/core/storage/fs-storage-backend.js +3 -3
- package/dist/core/storage/storage-location-manager.js +3 -3
- package/dist/core/storage/storage.service.js +2 -2
- package/dist/launcher.js +18 -12
- package/dist/main.js +7 -4
- package/package.json +2 -3
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MoleculerService = void 0;
|
|
4
4
|
exports.buildChildUdsManifest = buildChildUdsManifest;
|
|
5
|
-
const
|
|
5
|
+
const system_1 = require("@camstack/system");
|
|
6
6
|
const cap_call_fn_js_1 = require("./cap-call-fn.js");
|
|
7
7
|
const cap_route_authority_js_1 = require("./cap-route-authority.js");
|
|
8
8
|
const types_1 = require("@camstack/types");
|
|
@@ -23,7 +23,7 @@ class MoleculerService {
|
|
|
23
23
|
* D3 authority: union of every node's manifest delivered via
|
|
24
24
|
* `$hub.registerNode`. Populated by `onRegisterNode` in `hubDeps`.
|
|
25
25
|
*/
|
|
26
|
-
nodeRegistry = new
|
|
26
|
+
nodeRegistry = new system_1.HubNodeRegistry();
|
|
27
27
|
nodeCallFns = new Map();
|
|
28
28
|
/**
|
|
29
29
|
* D3: callback invoked whenever a bare-ID agent node completes the
|
|
@@ -107,7 +107,7 @@ class MoleculerService {
|
|
|
107
107
|
// `no-unsafe-assignment`. Going via `unknown` documents the boundary.
|
|
108
108
|
this.clusterSecret =
|
|
109
109
|
process.env['CAMSTACK_CLUSTER_SECRET'] ?? this.config.get('cluster.secret');
|
|
110
|
-
const broker = (0,
|
|
110
|
+
const broker = (0, system_1.createBroker)({
|
|
111
111
|
nodeID: 'hub',
|
|
112
112
|
mode: 'hub',
|
|
113
113
|
logLevel: this.config.get('moleculer.logLevel') ?? 'warn',
|
|
@@ -182,10 +182,10 @@ class MoleculerService {
|
|
|
182
182
|
this.removeNodeFromRegistry(nodeId);
|
|
183
183
|
},
|
|
184
184
|
expectedClusterSecretHash: this.clusterSecret
|
|
185
|
-
? (0,
|
|
185
|
+
? (0, system_1.hashClusterSecret)(this.clusterSecret)
|
|
186
186
|
: undefined,
|
|
187
187
|
};
|
|
188
|
-
const hubService = (0,
|
|
188
|
+
const hubService = (0, system_1.createHubService)(hubDeps);
|
|
189
189
|
this.brokerSafe.createService(hubService);
|
|
190
190
|
// Forked addon-runner children must root their storage (addons-data,
|
|
191
191
|
// the sqlite settings DB) under the SAME data path as the hub's main
|
|
@@ -213,7 +213,7 @@ class MoleculerService {
|
|
|
213
213
|
// capabilities the resolver can see. Before F0 this fell through
|
|
214
214
|
// UDS_NO_ROUTE → the child's own brokerTransportLink; F1+F2 removes that
|
|
215
215
|
// child broker, so the parent must own this path.
|
|
216
|
-
const onUnownedCall = (0,
|
|
216
|
+
const onUnownedCall = (0, system_1.createParentUnownedCallHandler)({
|
|
217
217
|
getResolver: () => this.resolver,
|
|
218
218
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- moleculer types unresolvable; see `broker` getter docstring
|
|
219
219
|
broker: this.broker,
|
|
@@ -239,8 +239,8 @@ class MoleculerService {
|
|
|
239
239
|
: undefined),
|
|
240
240
|
},
|
|
241
241
|
});
|
|
242
|
-
const registry = new
|
|
243
|
-
server: (0,
|
|
242
|
+
const registry = new system_1.LocalChildRegistry({
|
|
243
|
+
server: (0, system_1.createLocalTransport)().createServer(nodeId),
|
|
244
244
|
onUnownedCall,
|
|
245
245
|
logger: {
|
|
246
246
|
info: (msg, meta) => logger.info(msg, meta !== null && meta !== undefined
|
|
@@ -284,7 +284,7 @@ class MoleculerService {
|
|
|
284
284
|
// This runs in PARALLEL with the existing $hub.log / onLog broker path —
|
|
285
285
|
// both stay active until Phase F removes the broker path.
|
|
286
286
|
registry.onChildLog((childId, entry) => {
|
|
287
|
-
this.logging.writeFromWorker((0,
|
|
287
|
+
this.logging.writeFromWorker((0, system_1.udsChildLogToWorkerEntry)(childId, entry));
|
|
288
288
|
});
|
|
289
289
|
// D1: answer readiness-snapshot requests from UDS children so they can
|
|
290
290
|
// hydrate without a `$readiness.getSnapshot` Moleculer call.
|
|
@@ -295,7 +295,7 @@ class MoleculerService {
|
|
|
295
295
|
// Keep `$readiness.getSnapshot` intact — Phase F removes it.
|
|
296
296
|
registry.onReadinessSnapshotRequest(() => this.readinessRegistry.getSnapshotForTransport());
|
|
297
297
|
this.localChildRegistry = registry;
|
|
298
|
-
parentUdsPath = (0,
|
|
298
|
+
parentUdsPath = (0, system_1.localEndpointPath)(nodeId);
|
|
299
299
|
logger.info('UDS child registry listening', { meta: { path: parentUdsPath } });
|
|
300
300
|
}
|
|
301
301
|
catch (err) {
|
|
@@ -303,7 +303,7 @@ class MoleculerService {
|
|
|
303
303
|
meta: { err: err instanceof Error ? err.message : String(err) },
|
|
304
304
|
});
|
|
305
305
|
}
|
|
306
|
-
const processService = (0,
|
|
306
|
+
const processService = (0, system_1.createProcessService)(this.brokerSafe.nodeID, dataDir, undefined, undefined, parentUdsPath);
|
|
307
307
|
this.brokerSafe.createService(processService);
|
|
308
308
|
// $addonHost — REMOVED (Sprint 6). Three-level settings are now
|
|
309
309
|
// served by the `addon-settings` singleton capability. Per-addon
|
|
@@ -319,19 +319,19 @@ class MoleculerService {
|
|
|
319
319
|
// handshake, not dynamically after post-start `createService()`.
|
|
320
320
|
// Without this, cross-node broadcasts (camstack.evt.<category>) would
|
|
321
321
|
// arrive unreliably for the first ~10s after each node joins.
|
|
322
|
-
(0,
|
|
322
|
+
(0, system_1.registerEventBusService)(this.broker);
|
|
323
323
|
// Register the hub-authoritative `$readiness.getSnapshot` service
|
|
324
324
|
// BEFORE broker.start() so workers / agents see it in their initial
|
|
325
325
|
// INFO packet — post-start `createService` calls propagate via
|
|
326
326
|
// heartbeat (several seconds) and would force workers to poll.
|
|
327
|
-
this.brokerSafe.createService((0,
|
|
327
|
+
this.brokerSafe.createService((0, system_1.createReadinessServiceForRegistry)(this.readinessRegistry));
|
|
328
328
|
// Register the hub-authoritative `$stream-probe` service —
|
|
329
329
|
// workers route RTSP probe + field-probe through this action when
|
|
330
330
|
// the tRPC WSS link isn't available (default path for forked
|
|
331
331
|
// workers). Keeps ffprobe + HTTP-reachability as a single
|
|
332
332
|
// hub-side implementation; see `createStreamProbeBrokerService`
|
|
333
333
|
// for the shape.
|
|
334
|
-
this.brokerSafe.createService((0,
|
|
334
|
+
this.brokerSafe.createService((0, system_1.createStreamProbeBrokerService)({
|
|
335
335
|
probe: (url, options) => this.streamProbe.probe(url, options),
|
|
336
336
|
probeField: (key, value) => this.streamProbe.probeField(key, value),
|
|
337
337
|
}));
|
|
@@ -340,7 +340,7 @@ class MoleculerService {
|
|
|
340
340
|
// returns the backend list for whichever host the caller targets.
|
|
341
341
|
// Admin UI uses this to show per-agent hwaccel info on the
|
|
342
342
|
// pipeline / NodeDetail pages.
|
|
343
|
-
this.brokerSafe.createService((0,
|
|
343
|
+
this.brokerSafe.createService((0, system_1.createHwAccelService)((0, system_1.createKernelHwAccel)()));
|
|
344
344
|
await this.brokerSafe.start();
|
|
345
345
|
logger.info('Moleculer broker started (TCP transport)');
|
|
346
346
|
// Construct the CapRouteResolver now that both the broker and
|
|
@@ -349,7 +349,7 @@ class MoleculerService {
|
|
|
349
349
|
// children connecting/disconnecting after this point are picked up
|
|
350
350
|
// correctly. The localChildRegistry reference is captured and may be
|
|
351
351
|
// null if UDS failed to start.
|
|
352
|
-
this.resolver = new
|
|
352
|
+
this.resolver = new system_1.CapRouteResolver({
|
|
353
353
|
hubNodeId: this.brokerSafe.nodeID,
|
|
354
354
|
broker: this.brokerSafe,
|
|
355
355
|
hubLocalRegistry: this.localChildRegistry,
|
|
@@ -376,7 +376,7 @@ class MoleculerService {
|
|
|
376
376
|
// shared broker bus and broker.broadcast is live.
|
|
377
377
|
if (this.localChildRegistry !== null) {
|
|
378
378
|
const hubNodeId = this.brokerSafe.nodeID;
|
|
379
|
-
this.udsEventBridgeDispose = (0,
|
|
379
|
+
this.udsEventBridgeDispose = (0, system_1.createUdsEventBridge)({
|
|
380
380
|
registry: this.localChildRegistry,
|
|
381
381
|
parentBus: this.eventBus,
|
|
382
382
|
parentNodeId: hubNodeId,
|
|
@@ -453,7 +453,7 @@ class MoleculerService {
|
|
|
453
453
|
return await resolver.dispatch(route, methodName, params);
|
|
454
454
|
}
|
|
455
455
|
catch (err) {
|
|
456
|
-
if (err instanceof
|
|
456
|
+
if (err instanceof system_1.CapRouteError &&
|
|
457
457
|
(err.reason === 'no-provider' || err.reason === 'node-offline')) {
|
|
458
458
|
// Resolver couldn't find the cap — try the legacy callFn store as a
|
|
459
459
|
// fallback. This covers caps registered in nodeCallFns (e.g. agent
|
|
@@ -488,7 +488,7 @@ class MoleculerService {
|
|
|
488
488
|
if (callFn) {
|
|
489
489
|
return callFn(methodName, params);
|
|
490
490
|
}
|
|
491
|
-
throw new
|
|
491
|
+
throw new system_1.CapRouteError(capabilityName, methodName, {
|
|
492
492
|
reason: 'no-provider',
|
|
493
493
|
nodeId,
|
|
494
494
|
rejected: [
|
|
@@ -568,7 +568,7 @@ class MoleculerService {
|
|
|
568
568
|
for (const addon of manifest) {
|
|
569
569
|
const registryKey = registryKeyFor(addon.addonId);
|
|
570
570
|
for (const capName of addon.capabilities) {
|
|
571
|
-
if ((0,
|
|
571
|
+
if ((0, system_1.isInfraCapability)(capName))
|
|
572
572
|
continue;
|
|
573
573
|
const capDef = registry.getDefinition(capName);
|
|
574
574
|
if (!capDef)
|
|
@@ -620,7 +620,7 @@ class MoleculerService {
|
|
|
620
620
|
udsChildId,
|
|
621
621
|
getLocalChildRegistry: () => this.localChildRegistry,
|
|
622
622
|
getResolver: () => this.resolver,
|
|
623
|
-
legacyBrokerCall: (method, methodParams, targetNode) => (0,
|
|
623
|
+
legacyBrokerCall: (method, methodParams, targetNode) => (0, system_1.callWithServiceDiscovery)(this.brokerSafe, addonId, (0, system_1.capActionName)(addonId, capName, method, false), (0, system_1.serializeTypedArrays)(methodParams), { nodeID: targetNode, timeout: 60_000 }),
|
|
624
624
|
onUdsRoute: (cap) => {
|
|
625
625
|
if (!this.udsRoutedCaps.has(cap)) {
|
|
626
626
|
this.udsRoutedCaps.add(cap);
|
|
@@ -784,7 +784,7 @@ class MoleculerService {
|
|
|
784
784
|
// Resolver found a route — proxy is reachable.
|
|
785
785
|
}
|
|
786
786
|
catch (err) {
|
|
787
|
-
if (err instanceof
|
|
787
|
+
if (err instanceof system_1.CapRouteError &&
|
|
788
788
|
(err.reason === 'no-provider' || err.reason === 'node-offline')) {
|
|
789
789
|
// Check legacy callFn store and hub-local child fallbacks.
|
|
790
790
|
if (!this.isReachableViaLegacy(nodeId, capabilityName))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NetworkQualityService = void 0;
|
|
4
|
-
const
|
|
5
|
-
class NetworkQualityService extends
|
|
4
|
+
const system_1 = require("@camstack/system");
|
|
5
|
+
class NetworkQualityService extends system_1.NetworkQualityTracker {
|
|
6
6
|
}
|
|
7
7
|
exports.NetworkQualityService = NetworkQualityService;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NotificationServiceWrapper = void 0;
|
|
4
|
-
const
|
|
4
|
+
const system_1 = require("@camstack/system");
|
|
5
5
|
/**
|
|
6
6
|
* NestJS-injectable wrapper around the core NotificationService.
|
|
7
7
|
*
|
|
@@ -18,7 +18,7 @@ class NotificationServiceWrapper {
|
|
|
18
18
|
}
|
|
19
19
|
get service() {
|
|
20
20
|
if (!this._service) {
|
|
21
|
-
this._service = new
|
|
21
|
+
this._service = new system_1.NotificationService(this.logging.createLogger('notifications'));
|
|
22
22
|
const registry = this.caps.getRegistry();
|
|
23
23
|
if (registry) {
|
|
24
24
|
this._service.setRegistry(registry);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ToastServiceWrapper = void 0;
|
|
4
|
-
const
|
|
4
|
+
const system_1 = require("@camstack/system");
|
|
5
5
|
/**
|
|
6
6
|
* NestJS-injectable wrapper around the core ToastService.
|
|
7
7
|
*
|
|
8
8
|
* Provides toast broadcasting to connected UI clients.
|
|
9
9
|
*/
|
|
10
10
|
class ToastServiceWrapper {
|
|
11
|
-
_service = new
|
|
11
|
+
_service = new system_1.ToastService();
|
|
12
12
|
get service() {
|
|
13
13
|
return this._service;
|
|
14
14
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ReplEngineService = void 0;
|
|
4
|
-
const
|
|
4
|
+
const system_1 = require("@camstack/system");
|
|
5
5
|
const types_1 = require("@camstack/types");
|
|
6
|
-
class ReplEngineService extends
|
|
6
|
+
class ReplEngineService extends system_1.ReplEngine {
|
|
7
7
|
/**
|
|
8
8
|
* Lazily-instantiated `SystemMirror` shared across REPL sessions.
|
|
9
9
|
* Holds a single warm-boot mirror that every `sm.getDeviceById(id)`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FsStorageBackend = void 0;
|
|
4
|
-
// Re-export from @camstack/
|
|
5
|
-
var
|
|
6
|
-
Object.defineProperty(exports, "FsStorageBackend", { enumerable: true, get: function () { return
|
|
4
|
+
// Re-export from @camstack/system
|
|
5
|
+
var system_1 = require("@camstack/system");
|
|
6
|
+
Object.defineProperty(exports, "FsStorageBackend", { enumerable: true, get: function () { return system_1.FsStorageBackend; } });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StorageLocationManager = void 0;
|
|
4
|
-
// Re-export from @camstack/
|
|
5
|
-
var
|
|
6
|
-
Object.defineProperty(exports, "StorageLocationManager", { enumerable: true, get: function () { return
|
|
4
|
+
// Re-export from @camstack/system
|
|
5
|
+
var system_1 = require("@camstack/system");
|
|
6
|
+
Object.defineProperty(exports, "StorageLocationManager", { enumerable: true, get: function () { return system_1.StorageLocationManager; } });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StorageService = void 0;
|
|
4
|
-
const
|
|
5
|
-
class StorageService extends
|
|
4
|
+
const system_1 = require("@camstack/system");
|
|
5
|
+
class StorageService extends system_1.StorageManager {
|
|
6
6
|
}
|
|
7
7
|
exports.StorageService = StorageService;
|
package/dist/launcher.js
CHANGED
|
@@ -36,18 +36,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
/**
|
|
37
37
|
* Launcher -- entry point that ensures required addons are installed
|
|
38
38
|
* before main.ts loads. This solves the chicken-and-egg problem:
|
|
39
|
-
* main.ts has static imports from @camstack/
|
|
39
|
+
* main.ts has static imports from @camstack/system, but core lives in
|
|
40
40
|
* data/addons/ and may not exist on first boot.
|
|
41
41
|
*
|
|
42
42
|
* 1. Run AddonInstaller.ensureRequiredPackages (zero core dependencies)
|
|
43
|
-
* 2. Create symlinks so @camstack/
|
|
44
|
-
* 3. Dynamically import main.ts (which has static @camstack/
|
|
43
|
+
* 2. Create symlinks so @camstack/system resolves from data/addons/
|
|
44
|
+
* 3. Dynamically import main.ts (which has static @camstack/system imports)
|
|
45
45
|
*/
|
|
46
46
|
const fs = __importStar(require("node:fs"));
|
|
47
47
|
const path = __importStar(require("node:path"));
|
|
48
48
|
const tar = __importStar(require("tar"));
|
|
49
49
|
const yaml = __importStar(require("js-yaml"));
|
|
50
|
-
const
|
|
50
|
+
const system_1 = require("@camstack/system");
|
|
51
51
|
/** Path of the manifest file embedded inside every archive. */
|
|
52
52
|
const ARCHIVE_MANIFEST_NAME = '.camstack-backup-manifest.json';
|
|
53
53
|
/** Resolve the data directory from env or default */
|
|
@@ -135,7 +135,7 @@ function parseInstallSource(value) {
|
|
|
135
135
|
/**
|
|
136
136
|
* Locate + parse `config.yaml` relative to the data dir. Returns the
|
|
137
137
|
* raw object on success, `null` when missing or unparseable. The
|
|
138
|
-
* launcher uses this BEFORE @camstack/
|
|
138
|
+
* launcher uses this BEFORE @camstack/system is imported so it must stay
|
|
139
139
|
* free of core deps — just js-yaml + the kernel's bootstrapSchema for
|
|
140
140
|
* shape validation by the call site.
|
|
141
141
|
*/
|
|
@@ -174,7 +174,7 @@ function readBootstrapInstallSource(dataDir) {
|
|
|
174
174
|
const raw = readConfigYaml(dataDir);
|
|
175
175
|
if (raw === null)
|
|
176
176
|
return undefined;
|
|
177
|
-
const validation =
|
|
177
|
+
const validation = system_1.bootstrapSchema.safeParse(raw);
|
|
178
178
|
if (!validation.success)
|
|
179
179
|
return undefined;
|
|
180
180
|
return parseInstallSource(validation.data.bootstrap.installSource);
|
|
@@ -186,7 +186,7 @@ function readBootstrapInstallSource(dataDir) {
|
|
|
186
186
|
* kernel's REQUIRED_PACKAGES constant).
|
|
187
187
|
*
|
|
188
188
|
* Inline YAML parse rather than going through ConfigManager: the
|
|
189
|
-
* launcher runs before @camstack/
|
|
189
|
+
* launcher runs before @camstack/system is imported and must stay free of
|
|
190
190
|
* core dependencies. Just yaml.load + bootstrapSchema (kernel) for
|
|
191
191
|
* shape validation.
|
|
192
192
|
*/
|
|
@@ -194,7 +194,7 @@ function readBootstrapRequiredAddons(dataDir) {
|
|
|
194
194
|
const raw = readConfigYaml(dataDir);
|
|
195
195
|
if (raw === null)
|
|
196
196
|
return null;
|
|
197
|
-
const validation =
|
|
197
|
+
const validation = system_1.bootstrapSchema.safeParse(raw);
|
|
198
198
|
if (!validation.success) {
|
|
199
199
|
console.warn(`[launcher] config.yaml failed bootstrapSchema validation: ${validation.error.message}`);
|
|
200
200
|
return null;
|
|
@@ -203,7 +203,13 @@ function readBootstrapRequiredAddons(dataDir) {
|
|
|
203
203
|
}
|
|
204
204
|
async function launch() {
|
|
205
205
|
const dataDir = DATA_DIR;
|
|
206
|
-
|
|
206
|
+
// Addons live in a real `node_modules`-shaped dir so ESM `import` resolves
|
|
207
|
+
// every @camstack/* (system + addon-*) from there via the standard
|
|
208
|
+
// walk-up — NODE_PATH only covers CJS, which is why forked ESM addon
|
|
209
|
+
// runners couldn't resolve `@camstack/types` from a plain `addons/` dir.
|
|
210
|
+
// `CAMSTACK_ADDONS_DIR` lets the Docker/Electron images point at their
|
|
211
|
+
// node_modules path (e.g. /data/node_modules); dev keeps `<dataDir>/addons`.
|
|
212
|
+
const addonsDir = process.env['CAMSTACK_ADDONS_DIR'] ?? path.resolve(dataDir, 'addons');
|
|
207
213
|
// Restore must happen first so the snapshot's `addons/` is what the
|
|
208
214
|
// installer + symlink step pick up — otherwise we'd install a stale
|
|
209
215
|
// set and overwrite it a step later.
|
|
@@ -235,14 +241,14 @@ async function launch() {
|
|
|
235
241
|
console.log(`[launcher] Using bundled addons from ${bundledDir}`);
|
|
236
242
|
}
|
|
237
243
|
else if (explicitSource === 'local' || explicitSource === 'symlink') {
|
|
238
|
-
workspaceDir = (0,
|
|
244
|
+
workspaceDir = (0, system_1.detectWorkspacePackagesDir)(__dirname);
|
|
239
245
|
if (workspaceDir === null) {
|
|
240
246
|
console.warn(`[launcher] installSource=${explicitSource} requested but no workspace ` +
|
|
241
247
|
`packages/ dir found from ${__dirname} — falling back to 'npm'`);
|
|
242
248
|
resolvedSource = 'npm';
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
|
-
const installer = new
|
|
251
|
+
const installer = new system_1.AddonInstaller({
|
|
246
252
|
addonsDir,
|
|
247
253
|
workspacePackagesDir: workspaceDir ?? undefined,
|
|
248
254
|
installSource: resolvedSource,
|
|
@@ -296,7 +302,7 @@ async function launch() {
|
|
|
296
302
|
Module._initPaths();
|
|
297
303
|
console.log(`[launcher] NODE_PATH extended with: ${extraNodePaths.join(sep)}`);
|
|
298
304
|
}
|
|
299
|
-
// Now safe to load main.ts (which has static imports from @camstack/
|
|
305
|
+
// Now safe to load main.ts (which has static imports from @camstack/system)
|
|
300
306
|
console.log('[launcher] Starting server...');
|
|
301
307
|
await Promise.resolve().then(() => __importStar(require('./main')));
|
|
302
308
|
}
|
package/dist/main.js
CHANGED
|
@@ -77,7 +77,7 @@ const auth_whoami_1 = require("./api/auth-whoami");
|
|
|
77
77
|
const session_cookie_js_1 = require("./auth/session-cookie.js");
|
|
78
78
|
const health_routes_1 = require("./api/health/health.routes");
|
|
79
79
|
const oauth2_routes_js_1 = require("./api/oauth2/oauth2-routes.js");
|
|
80
|
-
const
|
|
80
|
+
const system_1 = require("@camstack/system");
|
|
81
81
|
const boot_config_1 = require("./boot/boot-config");
|
|
82
82
|
const manual_boot_1 = require("./manual-boot");
|
|
83
83
|
const post_boot_service_1 = require("./boot/post-boot.service");
|
|
@@ -231,8 +231,8 @@ async function bootstrap() {
|
|
|
231
231
|
// If registration fails, start in degraded mode: serve a health warning endpoint.
|
|
232
232
|
// Instantiate new core services
|
|
233
233
|
const loggingService = app.get(logging_service_1.LoggingService);
|
|
234
|
-
const addonRouteRegistry = new
|
|
235
|
-
const dataPlaneRegistry = new
|
|
234
|
+
const addonRouteRegistry = new system_1.AddonRouteRegistry();
|
|
235
|
+
const dataPlaneRegistry = new system_1.DataPlaneRegistry();
|
|
236
236
|
// Use Fastify-managed notification/toast wrappers (globally provided by NotificationModule)
|
|
237
237
|
const { NotificationServiceWrapper } = await Promise.resolve().then(() => __importStar(require('./core/notification/notification-wrapper.service')));
|
|
238
238
|
const { ToastServiceWrapper } = await Promise.resolve().then(() => __importStar(require('./core/notification/toast-wrapper.service')));
|
|
@@ -296,6 +296,9 @@ async function bootstrap() {
|
|
|
296
296
|
moleculer,
|
|
297
297
|
agentRegistry: app.get(agent_registry_service_1.AgentRegistryService),
|
|
298
298
|
hubVersion,
|
|
299
|
+
// Read the live flag at request time — flips to true once the tRPC
|
|
300
|
+
// router finishes registering (see `trpcRegistered = true` below).
|
|
301
|
+
isReady: () => trpcRegistered,
|
|
299
302
|
});
|
|
300
303
|
console.log(`[bootstrap] Health routes registered (hub v${hubVersion})`);
|
|
301
304
|
}
|
|
@@ -713,7 +716,7 @@ async function bootstrap() {
|
|
|
713
716
|
const upstreamPath = `/${subPath}${query}`;
|
|
714
717
|
// Take over the socket — `proxyToUpstream` drives the raw response.
|
|
715
718
|
reply.hijack();
|
|
716
|
-
(0,
|
|
719
|
+
(0, system_1.proxyToUpstream)({
|
|
717
720
|
baseUrl: dpMatch.endpoint.baseUrl,
|
|
718
721
|
secret: dpMatch.endpoint.secret,
|
|
719
722
|
upstreamPath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -27,8 +27,7 @@
|
|
|
27
27
|
"@camstack/addon-pipeline": "*",
|
|
28
28
|
"@camstack/addon-pipeline-orchestrator": "*",
|
|
29
29
|
"@camstack/addon-post-analysis": "*",
|
|
30
|
-
"@camstack/
|
|
31
|
-
"@camstack/kernel": "*",
|
|
30
|
+
"@camstack/system": "*",
|
|
32
31
|
"@camstack/sdk": "*",
|
|
33
32
|
"@camstack/shm-ring": "*",
|
|
34
33
|
"@camstack/types": "*",
|