@camstack/server 1.1.71 → 1.1.73
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/core/cap-providers.js +0 -11
- package/dist/api/core/lifecycle-job-runner.js +0 -2
- package/dist/api/trpc/cap-mount-helpers.js +21 -9
- package/dist/api/trpc/generated-cap-routers.js +0 -8
- package/dist/api/trpc/trpc.router.js +49 -2
- package/dist/boot/post-boot.service.js +4 -17
- package/dist/boot/reconcile-lifecycle-jobs.js +6 -5
- package/dist/core/addon/addon-package.service.js +17 -388
- package/dist/launcher.js +9 -19
- package/dist/manual-boot.js +0 -27
- package/dist/server-root/index.js +68 -42
- package/package.json +8 -8
- package/dist/boot/resume-framework-swap.js +0 -119
- package/dist/launcher-framework-swap.js +0 -408
- package/dist/request-framework-swap.js +0 -41
|
@@ -371,6 +371,38 @@ var require_dist = __commonJS({
|
|
|
371
371
|
__name(validateVersionDir, "validateVersionDir");
|
|
372
372
|
var fs3 = __toESM2(require("fs"));
|
|
373
373
|
var path3 = __toESM2(require("path"));
|
|
374
|
+
function parse(version) {
|
|
375
|
+
const dashIdx = version.indexOf("-");
|
|
376
|
+
const base = dashIdx === -1 ? version : version.slice(0, dashIdx);
|
|
377
|
+
const prerelease = dashIdx === -1 ? null : version.slice(dashIdx + 1);
|
|
378
|
+
const nums = base.split(".").map((seg) => {
|
|
379
|
+
const n = Number.parseInt(seg, 10);
|
|
380
|
+
return Number.isNaN(n) ? 0 : n;
|
|
381
|
+
});
|
|
382
|
+
return {
|
|
383
|
+
nums,
|
|
384
|
+
prerelease
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
__name(parse, "parse");
|
|
388
|
+
function compareSemver(a, b) {
|
|
389
|
+
const pa = parse(a);
|
|
390
|
+
const pb = parse(b);
|
|
391
|
+
const len = Math.max(pa.nums.length, pb.nums.length);
|
|
392
|
+
for (let i = 0; i < len; i++) {
|
|
393
|
+
const na = pa.nums[i] ?? 0;
|
|
394
|
+
const nb = pb.nums[i] ?? 0;
|
|
395
|
+
if (na < nb) return -1;
|
|
396
|
+
if (na > nb) return 1;
|
|
397
|
+
}
|
|
398
|
+
if (pa.prerelease === null && pb.prerelease === null) return 0;
|
|
399
|
+
if (pa.prerelease === null) return 1;
|
|
400
|
+
if (pb.prerelease === null) return -1;
|
|
401
|
+
if (pa.prerelease < pb.prerelease) return -1;
|
|
402
|
+
if (pa.prerelease > pb.prerelease) return 1;
|
|
403
|
+
return 0;
|
|
404
|
+
}
|
|
405
|
+
__name(compareSemver, "compareSemver");
|
|
374
406
|
var CURRENT_DIRNAME = "current";
|
|
375
407
|
var PENDING_ROOT_SWAP_FILE = ".pending-root-swap.json";
|
|
376
408
|
var LEGACY_FRAMEWORK_MARKERS = [
|
|
@@ -566,17 +598,43 @@ var require_dist = __commonJS({
|
|
|
566
598
|
};
|
|
567
599
|
}
|
|
568
600
|
__name(applyPendingRootSwap, "applyPendingRootSwap");
|
|
601
|
+
function readClosureVersion(closureDir, spec) {
|
|
602
|
+
try {
|
|
603
|
+
const raw = JSON.parse(fs3.readFileSync(path3.join(rootPackageDir2(closureDir, spec), "package.json"), "utf-8"));
|
|
604
|
+
if (typeof raw === "object" && raw !== null) {
|
|
605
|
+
const version = raw["version"];
|
|
606
|
+
if (typeof version === "string") return version;
|
|
607
|
+
}
|
|
608
|
+
} catch {
|
|
609
|
+
}
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
__name(readClosureVersion, "readClosureVersion");
|
|
613
|
+
function isAdoptablePendingClosure(rootDir, version, nodeMajor, spec) {
|
|
614
|
+
const dir = versionDir(rootDir, version);
|
|
615
|
+
return validateClosureDir(dir, nodeMajor, spec, version) === null && findMissingNativePrebuilds(dir).length === 0;
|
|
616
|
+
}
|
|
617
|
+
__name(isAdoptablePendingClosure, "isAdoptablePendingClosure");
|
|
569
618
|
function migrateToSingleCopy(rootDir, spec, nodeMajor, now, log) {
|
|
570
619
|
const dest = currentDir(rootDir);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
620
|
+
const legacyState = readServerRootState(rootDir);
|
|
621
|
+
const pendingVersion = legacyState?.pendingBoot?.version ?? null;
|
|
622
|
+
const pendingAdoptable = pendingVersion !== null && isAdoptablePendingClosure(rootDir, pendingVersion, nodeMajor, spec);
|
|
623
|
+
const currentValid = fs3.existsSync(dest) && validateClosureDir(dest, nodeMajor, spec) === null;
|
|
624
|
+
if (currentValid) {
|
|
625
|
+
const currentVersion = readClosureVersion(dest, spec);
|
|
626
|
+
const pendingSupersedes = pendingAdoptable && pendingVersion !== null && (currentVersion === null || compareSemver(pendingVersion, currentVersion) > 0);
|
|
627
|
+
if (!pendingSupersedes) {
|
|
628
|
+
return {
|
|
629
|
+
migrated: false,
|
|
630
|
+
version: null,
|
|
631
|
+
reason: "current already present"
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
log(`[single-copy] in-flight pending ${pendingVersion} supersedes older current ${currentVersion ?? "?"}`);
|
|
577
635
|
}
|
|
578
636
|
const candidates = [];
|
|
579
|
-
|
|
637
|
+
if (pendingAdoptable && pendingVersion !== null) candidates.push(pendingVersion);
|
|
580
638
|
if (legacyState !== null) {
|
|
581
639
|
for (const v of [
|
|
582
640
|
legacyState.currentVersion,
|
|
@@ -662,38 +720,6 @@ var require_dist = __commonJS({
|
|
|
662
720
|
};
|
|
663
721
|
}
|
|
664
722
|
__name(planBoot, "planBoot");
|
|
665
|
-
function parse(version) {
|
|
666
|
-
const dashIdx = version.indexOf("-");
|
|
667
|
-
const base = dashIdx === -1 ? version : version.slice(0, dashIdx);
|
|
668
|
-
const prerelease = dashIdx === -1 ? null : version.slice(dashIdx + 1);
|
|
669
|
-
const nums = base.split(".").map((seg) => {
|
|
670
|
-
const n = Number.parseInt(seg, 10);
|
|
671
|
-
return Number.isNaN(n) ? 0 : n;
|
|
672
|
-
});
|
|
673
|
-
return {
|
|
674
|
-
nums,
|
|
675
|
-
prerelease
|
|
676
|
-
};
|
|
677
|
-
}
|
|
678
|
-
__name(parse, "parse");
|
|
679
|
-
function compareSemver(a, b) {
|
|
680
|
-
const pa = parse(a);
|
|
681
|
-
const pb = parse(b);
|
|
682
|
-
const len = Math.max(pa.nums.length, pb.nums.length);
|
|
683
|
-
for (let i = 0; i < len; i++) {
|
|
684
|
-
const na = pa.nums[i] ?? 0;
|
|
685
|
-
const nb = pb.nums[i] ?? 0;
|
|
686
|
-
if (na < nb) return -1;
|
|
687
|
-
if (na > nb) return 1;
|
|
688
|
-
}
|
|
689
|
-
if (pa.prerelease === null && pb.prerelease === null) return 0;
|
|
690
|
-
if (pa.prerelease === null) return 1;
|
|
691
|
-
if (pb.prerelease === null) return -1;
|
|
692
|
-
if (pa.prerelease < pb.prerelease) return -1;
|
|
693
|
-
if (pa.prerelease > pb.prerelease) return 1;
|
|
694
|
-
return 0;
|
|
695
|
-
}
|
|
696
|
-
__name(compareSemver, "compareSemver");
|
|
697
723
|
var fs4 = __toESM2(require("fs"));
|
|
698
724
|
var path4 = __toESM2(require("path"));
|
|
699
725
|
function detectWorkspaceRoot(fromDir) {
|
|
@@ -756,7 +782,7 @@ var require_dist = __commonJS({
|
|
|
756
782
|
registerHooks(hooks);
|
|
757
783
|
}
|
|
758
784
|
__name(registerActiveRootResolver, "registerActiveRootResolver");
|
|
759
|
-
function
|
|
785
|
+
function readClosureVersion2(closureDir, spec) {
|
|
760
786
|
try {
|
|
761
787
|
const raw = JSON.parse(fs5.readFileSync(path5.join(rootPackageDir2(closureDir, spec), "package.json"), "utf-8"));
|
|
762
788
|
if (typeof raw === "object" && raw !== null) {
|
|
@@ -767,7 +793,7 @@ var require_dist = __commonJS({
|
|
|
767
793
|
}
|
|
768
794
|
return null;
|
|
769
795
|
}
|
|
770
|
-
__name(
|
|
796
|
+
__name(readClosureVersion2, "readClosureVersion2");
|
|
771
797
|
function runNodeStarter(options) {
|
|
772
798
|
const env = options.env ?? process.env;
|
|
773
799
|
const now = options.now ?? Date.now;
|
|
@@ -800,7 +826,7 @@ var require_dist = __commonJS({
|
|
|
800
826
|
}
|
|
801
827
|
const plan = planBoot(invalid === null);
|
|
802
828
|
if (plan.kind === "current") {
|
|
803
|
-
const version =
|
|
829
|
+
const version = readClosureVersion2(activeRootDir, options.spec);
|
|
804
830
|
const entry = currentEntryPath(rootDir, options.spec);
|
|
805
831
|
console.log(`[starter] booting ${options.spec.packageName}@${version ?? "?"} from ${activeRootDir}`);
|
|
806
832
|
env[options.envNames.bootMode] = "data-root";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.73",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -23,19 +23,19 @@
|
|
|
23
23
|
"test:watch": "vitest"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@camstack/addon-admin-ui": "1.1.
|
|
26
|
+
"@camstack/addon-admin-ui": "1.1.60",
|
|
27
27
|
"@camstack/addon-advanced-notifier": "1.1.30",
|
|
28
28
|
"@camstack/addon-auth": "1.1.15",
|
|
29
29
|
"@camstack/addon-decoder-nodeav": "1.1.18",
|
|
30
30
|
"@camstack/addon-notifiers": "1.1.30",
|
|
31
|
-
"@camstack/addon-pipeline": "1.1.
|
|
32
|
-
"@camstack/addon-pipeline-orchestrator": "1.1.
|
|
33
|
-
"@camstack/addon-post-analysis": "1.1.
|
|
31
|
+
"@camstack/addon-pipeline": "1.1.66",
|
|
32
|
+
"@camstack/addon-pipeline-orchestrator": "1.1.55",
|
|
33
|
+
"@camstack/addon-post-analysis": "1.1.38",
|
|
34
34
|
"@camstack/sdk": "1.1.30",
|
|
35
35
|
"@camstack/shm-ring": "1.0.29",
|
|
36
|
-
"@camstack/system": "1.1.
|
|
37
|
-
"@camstack/types": "1.1.
|
|
38
|
-
"@camstack/ui-library": "1.1.
|
|
36
|
+
"@camstack/system": "1.1.59",
|
|
37
|
+
"@camstack/types": "1.1.53",
|
|
38
|
+
"@camstack/ui-library": "1.1.44",
|
|
39
39
|
"@fastify/compress": "^9.0.0",
|
|
40
40
|
"@fastify/cookie": "^11.0.2",
|
|
41
41
|
"@fastify/multipart": "^10.0.0",
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Boot-time framework-swap job resume + health confirm.
|
|
4
|
-
*
|
|
5
|
-
* After a framework swap reboot, `post-boot.service.ts` calls this once the
|
|
6
|
-
* hub is healthy. It:
|
|
7
|
-
* 1. Reads `.framework-swap-confirm.json` (written by the launcher on apply).
|
|
8
|
-
* 2. Marks the journal task `applied` → `done`, then finalises the job →
|
|
9
|
-
* `completed`.
|
|
10
|
-
* 3. Calls `confirmFrameworkSwapHealthy` to delete the confirm marker +
|
|
11
|
-
* backup dirs (disarms the crash-loop rollback).
|
|
12
|
-
*
|
|
13
|
-
* Best-effort: a missing/corrupt journal is tolerated — `confirmFrameworkSwapHealthy`
|
|
14
|
-
* is still called so the rollback is always disarmed when the hub boots healthy.
|
|
15
|
-
*/
|
|
16
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
-
}
|
|
22
|
-
Object.defineProperty(o, k2, desc);
|
|
23
|
-
}) : (function(o, m, k, k2) {
|
|
24
|
-
if (k2 === undefined) k2 = k;
|
|
25
|
-
o[k2] = m[k];
|
|
26
|
-
}));
|
|
27
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
-
}) : function(o, v) {
|
|
30
|
-
o["default"] = v;
|
|
31
|
-
});
|
|
32
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
-
var ownKeys = function(o) {
|
|
34
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
-
var ar = [];
|
|
36
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
-
return ar;
|
|
38
|
-
};
|
|
39
|
-
return ownKeys(o);
|
|
40
|
-
};
|
|
41
|
-
return function (mod) {
|
|
42
|
-
if (mod && mod.__esModule) return mod;
|
|
43
|
-
var result = {};
|
|
44
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
-
__setModuleDefault(result, mod);
|
|
46
|
-
return result;
|
|
47
|
-
};
|
|
48
|
-
})();
|
|
49
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.resumeFrameworkSwapJob = resumeFrameworkSwapJob;
|
|
51
|
-
const fs = __importStar(require("node:fs"));
|
|
52
|
-
const path = __importStar(require("node:path"));
|
|
53
|
-
const types_1 = require("@camstack/types");
|
|
54
|
-
const system_1 = require("@camstack/system");
|
|
55
|
-
const launcher_framework_swap_js_1 = require("../launcher-framework-swap.js");
|
|
56
|
-
const lifecycle_journal_path_js_1 = require("../lifecycle-journal-path.js");
|
|
57
|
-
const SWAP_CONFIRM_FILE = '.framework-swap-confirm.json';
|
|
58
|
-
/**
|
|
59
|
-
* Resume a framework-swap journal job to `done`/`completed` and confirm the
|
|
60
|
-
* hub is healthy (deletes the confirm marker + backups).
|
|
61
|
-
*
|
|
62
|
-
* @returns `{ resumed: false }` when no confirm marker exists.
|
|
63
|
-
* `{ resumed: true, jobId }` when the marker was found and processed.
|
|
64
|
-
* Never throws — errors are swallowed to avoid crashing the post-boot path.
|
|
65
|
-
*/
|
|
66
|
-
async function resumeFrameworkSwapJob(dataDir) {
|
|
67
|
-
try {
|
|
68
|
-
const confirmMarker = readConfirmMarker(dataDir);
|
|
69
|
-
if (confirmMarker === null) {
|
|
70
|
-
return { resumed: false };
|
|
71
|
-
}
|
|
72
|
-
const { jobId, taskId } = confirmMarker;
|
|
73
|
-
let journalPatched = false;
|
|
74
|
-
try {
|
|
75
|
-
const journal = new system_1.JobJournal((0, lifecycle_journal_path_js_1.lifecycleJobsDir)(dataDir));
|
|
76
|
-
const job = journal.getJob(jobId);
|
|
77
|
-
if (job !== null) {
|
|
78
|
-
const task = job.tasks.find((t) => t.taskId === taskId);
|
|
79
|
-
if (task !== undefined && task.phase === 'applied') {
|
|
80
|
-
journal.patchTask(jobId, taskId, { phase: 'done', finishedAtMs: Date.now() });
|
|
81
|
-
// Single-task framework job: if all tasks are now terminal and none
|
|
82
|
-
// failed, mark the job completed (mirrors the engine's finalize logic).
|
|
83
|
-
const updatedJob = journal.getJob(jobId);
|
|
84
|
-
if (updatedJob !== null) {
|
|
85
|
-
const allTerminal = updatedJob.tasks.every((t) => t.phase === 'done' || t.phase === 'failed' || t.phase === 'skipped');
|
|
86
|
-
const anyFailed = updatedJob.tasks.some((t) => t.phase === 'failed');
|
|
87
|
-
if (allTerminal && !anyFailed) {
|
|
88
|
-
journal.setJobState(jobId, 'completed');
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
journalPatched = true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
// Journal is missing or corrupt — still clean up the confirm marker so
|
|
97
|
-
// the rollback is disarmed on a healthy hub boot.
|
|
98
|
-
}
|
|
99
|
-
(0, launcher_framework_swap_js_1.confirmFrameworkSwapHealthy)(dataDir);
|
|
100
|
-
return journalPatched ? { resumed: true, jobId } : { resumed: false };
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
// Never crash the caller (post-boot service).
|
|
104
|
-
return { resumed: false };
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
/** Read and shape-check the confirm marker. Returns null on any error. */
|
|
108
|
-
function readConfirmMarker(dataDir) {
|
|
109
|
-
try {
|
|
110
|
-
const raw = JSON.parse(fs.readFileSync(path.join(dataDir, SWAP_CONFIRM_FILE), 'utf-8'));
|
|
111
|
-
const parsed = types_1.frameworkSwapConfirmSchema.safeParse(raw);
|
|
112
|
-
if (!parsed.success)
|
|
113
|
-
return null;
|
|
114
|
-
return { jobId: parsed.data.jobId, taskId: parsed.data.taskId };
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
}
|