@mutmutco/hub 4.4.12 → 4.4.14
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/index.cjs +58 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -282,7 +282,26 @@ var RELAY_INDENT = " ".repeat(TITLE_COLUMN - 1);
|
|
|
282
282
|
// ../installer/face/src/spinner.ts
|
|
283
283
|
var import_node_fs2 = require("node:fs");
|
|
284
284
|
var import_node_worker_threads = require("node:worker_threads");
|
|
285
|
-
|
|
285
|
+
|
|
286
|
+
// ../installer/face/src/encoding.ts
|
|
287
|
+
var UNICODE_SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
288
|
+
var ASCII_SPINNER_FRAMES = Object.freeze(["-", "\\", "|", "/"]);
|
|
289
|
+
function consoleRendersUnicode(env = process.env, platform = process.platform) {
|
|
290
|
+
if (env.MM_FACE_ASCII === "1" || env.NO_UNICODE === "1") return false;
|
|
291
|
+
const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
|
|
292
|
+
if (locale === "C" || locale === "POSIX" || /^C\./u.test(locale) || /^POSIX\./u.test(locale)) return false;
|
|
293
|
+
if (/cp437|ibm437|\b437\b/iu.test(locale)) return false;
|
|
294
|
+
if (/utf-?8/iu.test(locale)) return true;
|
|
295
|
+
if (platform === "win32") {
|
|
296
|
+
return Boolean(env.WT_SESSION) || env.TERM_PROGRAM === "vscode" || env.CHCP === "65001" || env.ConEmuANSI === "ON";
|
|
297
|
+
}
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
function spinnerFramesFor(env = process.env, platform = process.platform) {
|
|
301
|
+
return consoleRendersUnicode(env, platform) ? UNICODE_SPINNER_FRAMES : ASCII_SPINNER_FRAMES;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// ../installer/face/src/spinner.ts
|
|
286
305
|
var WORKER_SOURCE = `
|
|
287
306
|
const { parentPort, workerData } = require('node:worker_threads');
|
|
288
307
|
const { writeSync, appendFileSync } = require('node:fs');
|
|
@@ -307,8 +326,10 @@ parentPort.on('message', (next) => {
|
|
|
307
326
|
});
|
|
308
327
|
setInterval(draw, workerData.intervalMs);
|
|
309
328
|
`;
|
|
310
|
-
function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath }) {
|
|
329
|
+
function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath, env = process.env, platform = process.platform }) {
|
|
311
330
|
animate = animate && !face.nested && !face.emitsProgress;
|
|
331
|
+
const glyphs = spinnerFramesFor(env, platform);
|
|
332
|
+
const ascii = glyphs[0] === ASCII_SPINNER_FRAMES[0];
|
|
312
333
|
let timer = null;
|
|
313
334
|
let worker = null;
|
|
314
335
|
let control = null;
|
|
@@ -326,7 +347,8 @@ function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath
|
|
|
326
347
|
};
|
|
327
348
|
const render = (text, measure) => {
|
|
328
349
|
const line = face.step(text, measure ?? "__elapsed__", "note").split("\n")[0];
|
|
329
|
-
|
|
350
|
+
const prepared = line && ascii ? line.replaceAll(GLYPH.bar, "|") : line;
|
|
351
|
+
frames = prepared ? glyphs.map((glyph) => `\r\x1B[2K${prepared.replace(GLYPH.dot, glyph)}`) : [];
|
|
330
352
|
};
|
|
331
353
|
const draw = () => {
|
|
332
354
|
if (animate && !suspended && frames.length) write(frames[frame++ % frames.length].replace("__elapsed__", `${Math.floor((Date.now() - started) / 1e3)}s`));
|
|
@@ -403,7 +425,6 @@ function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath
|
|
|
403
425
|
}
|
|
404
426
|
};
|
|
405
427
|
}
|
|
406
|
-
var SPINNER_FRAMES = Object.freeze([...FRAMES]);
|
|
407
428
|
|
|
408
429
|
// ../installer/face/src/conformance.ts
|
|
409
430
|
var ALLOWED = new Set(Object.values(GLYPH));
|
|
@@ -634,6 +655,14 @@ var PHASES = {
|
|
|
634
655
|
doctor: ["Checking health", "Checked health"],
|
|
635
656
|
rollback: ["Restoring the previous version", "Restored the previous version"]
|
|
636
657
|
};
|
|
658
|
+
var UPDATE_CHECK_PHASES = /* @__PURE__ */ new Set([
|
|
659
|
+
"preflight",
|
|
660
|
+
"resolve",
|
|
661
|
+
"verify-release",
|
|
662
|
+
"download",
|
|
663
|
+
"sign-in",
|
|
664
|
+
"check"
|
|
665
|
+
]);
|
|
637
666
|
function createInstallerRun(value, options = {}) {
|
|
638
667
|
const declaration = validateInstallerProduct(value);
|
|
639
668
|
const env = options.env ?? process.env;
|
|
@@ -669,6 +698,7 @@ function createInstallerRun(value, options = {}) {
|
|
|
669
698
|
};
|
|
670
699
|
const spinner = createSpinner(face, {
|
|
671
700
|
animate: tty && env.TERM !== "dumb" && (options.animate ?? Boolean(process.stderr.isTTY)),
|
|
701
|
+
env,
|
|
672
702
|
...options.write ? { stream: { write: (text) => {
|
|
673
703
|
emit(String(text), "spinner");
|
|
674
704
|
return true;
|
|
@@ -687,6 +717,7 @@ function createInstallerRun(value, options = {}) {
|
|
|
687
717
|
};
|
|
688
718
|
let started = false;
|
|
689
719
|
let finished = false;
|
|
720
|
+
let operation = options.operation;
|
|
690
721
|
const start = () => {
|
|
691
722
|
if (started || finished) return;
|
|
692
723
|
started = true;
|
|
@@ -694,7 +725,7 @@ function createInstallerRun(value, options = {}) {
|
|
|
694
725
|
const welcome = face.welcome();
|
|
695
726
|
if (tty) lines(welcome);
|
|
696
727
|
else if (welcome.length) {
|
|
697
|
-
const warm =
|
|
728
|
+
const warm = operation === "install" ? face.identity.installWarm : face.identity.warm;
|
|
698
729
|
lines([`${face.identity.name} - Mutatis Mutandis`, warm.replaceAll("\u2014", "-").replaceAll("\u2026", "...")]);
|
|
699
730
|
}
|
|
700
731
|
};
|
|
@@ -710,13 +741,20 @@ function createInstallerRun(value, options = {}) {
|
|
|
710
741
|
get errors() {
|
|
711
742
|
return [...errors];
|
|
712
743
|
},
|
|
744
|
+
get operation() {
|
|
745
|
+
return operation;
|
|
746
|
+
},
|
|
747
|
+
set operation(value2) {
|
|
748
|
+
operation = value2;
|
|
749
|
+
},
|
|
713
750
|
start,
|
|
714
751
|
phase(id, facts = {}) {
|
|
715
752
|
if (finished) throw new Error("installer run already finished");
|
|
716
753
|
if (!Object.hasOwn(PHASES, id)) throw new Error("installer run: unknown phase");
|
|
717
754
|
start();
|
|
718
755
|
const state = facts.state ?? "ok";
|
|
719
|
-
const
|
|
756
|
+
const fold = operation === "update" && UPDATE_CHECK_PHASES.has(id) && state !== "fail";
|
|
757
|
+
const title = PHASES[fold ? "check" : id][state === "ok" ? 1 : 0];
|
|
720
758
|
if (state === "running") {
|
|
721
759
|
if (face.progress(title, facts.measure ?? null)) return;
|
|
722
760
|
if (activeTitle === title) spinner.say(title, facts.measure ?? null);
|
|
@@ -726,6 +764,10 @@ function createInstallerRun(value, options = {}) {
|
|
|
726
764
|
}
|
|
727
765
|
return;
|
|
728
766
|
}
|
|
767
|
+
if (fold && id !== "check") {
|
|
768
|
+
if (facts.detail) run.relay(facts.detail);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
729
771
|
if (!face.continues(id, state)) durable(title, facts.seconds ?? facts.measure ?? null, state);
|
|
730
772
|
if (facts.detail) run.relay(facts.detail);
|
|
731
773
|
},
|
|
@@ -881,6 +923,7 @@ async function runMaintenance(product, args, dependencies) {
|
|
|
881
923
|
quiet,
|
|
882
924
|
operation: installed ? "install" : "update"
|
|
883
925
|
});
|
|
926
|
+
if (run) run.operation = installed ? "install" : "update";
|
|
884
927
|
if (!quiet) run?.start();
|
|
885
928
|
let active;
|
|
886
929
|
let activeFacts;
|
|
@@ -3118,6 +3161,9 @@ async function reconcile(options) {
|
|
|
3118
3161
|
options.narrate?.(line);
|
|
3119
3162
|
options.onPhase?.(line);
|
|
3120
3163
|
};
|
|
3164
|
+
const phase = (id, state, detail) => {
|
|
3165
|
+
options.onPhaseEvent?.({ id, state, ...detail ? { detail } : {} });
|
|
3166
|
+
};
|
|
3121
3167
|
const run = `${(/* @__PURE__ */ new Date()).toISOString()}-${process.pid}`;
|
|
3122
3168
|
const paths = ensureState(env);
|
|
3123
3169
|
const repoUrl = env.MMI_UPDATER_REPO || REPO_URL_DEFAULT;
|
|
@@ -3139,6 +3185,7 @@ async function reconcile(options) {
|
|
|
3139
3185
|
say("acquiring single-writer lease");
|
|
3140
3186
|
const leaseWaitMs = Number(env.MMI_UPDATER_LEASE_WAIT_MS) || void 0;
|
|
3141
3187
|
return await withLease(paths.leasePath, async () => {
|
|
3188
|
+
phase("preflight", "running");
|
|
3142
3189
|
const journalEvents = parseJournal(paths.journalPath);
|
|
3143
3190
|
if (!options.dryRun) {
|
|
3144
3191
|
const pendingBefore = readPending(paths);
|
|
@@ -3150,6 +3197,8 @@ async function reconcile(options) {
|
|
|
3150
3197
|
summary.reap = reap({ paths, dryRun: options.dryRun, env });
|
|
3151
3198
|
for (const row of summary.reap) journal({ kind: "reap", surface: row.category, verdict: row.verdict, count: row.reaped, detail: row.detail, durationMs: row.durationMs });
|
|
3152
3199
|
for (const row of summary.reap.filter((entry) => entry.verdict !== "skip")) say(`reap ${row.category}: ${row.verdict}${row.detail ? " \u2014 " + row.detail : ""}`);
|
|
3200
|
+
phase("preflight", "ok");
|
|
3201
|
+
phase("resolve", "running");
|
|
3153
3202
|
if (shipped) {
|
|
3154
3203
|
say(`shipped target v${shipped} \u2014 the payload is the release; no npm poll, no gate`);
|
|
3155
3204
|
summary.target = shipped;
|
|
@@ -3208,7 +3257,9 @@ async function reconcile(options) {
|
|
|
3208
3257
|
}
|
|
3209
3258
|
}
|
|
3210
3259
|
say(`target v${summary.target} (${summary.gate})`);
|
|
3260
|
+
phase("resolve", "ok");
|
|
3211
3261
|
options.onTargetResolved?.(summary.target, summary.gate);
|
|
3262
|
+
phase("check", "running");
|
|
3212
3263
|
say("updater: self-bootstrap");
|
|
3213
3264
|
const selfStartedAt = import_node_perf_hooks2.performance.now();
|
|
3214
3265
|
const self = npmGlobalArm({
|
|
@@ -3271,6 +3322,7 @@ async function reconcile(options) {
|
|
|
3271
3322
|
journal({ kind: "surface", surface: probe.id, present: true, verdict: "skip", detail: `present, its converge arm has not landed yet (target ${summary.target})` });
|
|
3272
3323
|
}
|
|
3273
3324
|
}
|
|
3325
|
+
phase("check", "ok");
|
|
3274
3326
|
return summary;
|
|
3275
3327
|
}, leaseWaitMs);
|
|
3276
3328
|
} catch (error) {
|
package/package.json
CHANGED