@akanjs/cli 3.0.0-beta.24 → 3.0.0-beta.26
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/.build-stamp +1 -1
- package/{CodeAgent-0dh9fzzg.js → CodeAgent-p65jja35.js} +2 -2
- package/{CodeTui-drwdvwg9.js → CodeTui-5xr8kxx4.js} +1 -1
- package/TunnelShare-cwh9ezsm.js +9 -0
- package/{agent.command-ttn09rx3.js → agent.command-rp505zxa.js} +7 -7
- package/akanCode.js +2 -2
- package/{application.command-z7a4bdrq.js → application.command-afajz1m5.js} +7 -7
- package/{applicationBuildRunner-n6xfexaa.js → applicationBuildRunner-412y0345.js} +4 -4
- package/buildBatch.proc.js +77 -23
- package/{cloud.command-j0fcz44z.js → cloud.command-yz0h8a2e.js} +12 -12
- package/cloud.script-zez2b8am.js +20 -0
- package/{code.command-1jgk14tc.js → code.command-jhrjttm1.js} +7 -7
- package/{context.command-4vpjmg22.js → context.command-xncdvv7n.js} +14 -14
- package/context.runner-pjy89k2s.js +21 -0
- package/{dependencyScanner-ye2e6pdz.js → dependencyScanner-06z2dmrr.js} +2 -2
- package/{fileSys-5ngz93ga.js → fileSys-wzzrntkw.js} +1 -1
- package/{guideline.command-7jk47fgq.js → guideline.command-d5qmxx29.js} +4 -4
- package/guidelines/conventions/conventions.instruction.md +7 -5
- package/incrementalBuilder.proc.js +544 -72
- package/{index-ga6hygxr.js → index-0n9q1f23.js} +3 -3
- package/{index-3t7g9e4r.js → index-2ahj896a.js} +1 -1
- package/{index-zabxte74.js → index-2wc41k5w.js} +1 -1
- package/{index-khpfpcsd.js → index-48k96p55.js} +27 -7
- package/{index-2gh9sndr.js → index-50rq2qms.js} +4 -4
- package/{index-5b6tavv3.js → index-52w0fvh8.js} +15 -1
- package/{index-zbc2q6a6.js → index-56xwsgyn.js} +3 -3
- package/{index-rmcw8yc8.js → index-58cyna2s.js} +2 -2
- package/{index-1db2cw0y.js → index-5mm3g24t.js} +2 -2
- package/{index-wp43xrjv.js → index-6dt6zft6.js} +4 -4
- package/{index-vj1cwwy5.js → index-7yxndzea.js} +7 -7
- package/{index-q44jbw48.js → index-860zjnr1.js} +1 -1
- package/{index-fzd22vjh.js → index-94s080qm.js} +3 -17
- package/index-cd9qt2t6.js +4110 -0
- package/{index-ymgtbmf1.js → index-cfj73ck1.js} +213 -62
- package/{index-yy4s1j72.js → index-d65fzxvd.js} +1 -1
- package/{index-m0ms3n1c.js → index-da72pfdv.js} +7 -7
- package/{index-4dn1p115.js → index-ggfhz9ab.js} +4 -4
- package/{index-9629w7ns.js → index-hzy4pe24.js} +3 -3
- package/{index-d4mfjgm0.js → index-mq74nzf8.js} +6 -6
- package/{index-mgfx3mfs.js → index-per2kqy9.js} +4 -4
- package/{index-aaz7n8s2.js → index-qm4fppfk.js} +4 -4
- package/{index-ya5qbmyg.js → index-t02g6dpn.js} +3 -3
- package/{index-hb8sgepf.js → index-tpdn30ya.js} +1 -1
- package/{index-rnt66vym.js → index-v4hnkqz9.js} +1 -1
- package/{index-ne50hc2m.js → index-wvebzf0y.js} +456 -1623
- package/{index-pp54p5zk.js → index-xfgdmm5d.js} +2 -2
- package/{index-tgjy8xf3.js → index-zazvn45w.js} +4 -4
- package/{index-0bq14vr1.js → index-zzvvc845.js} +1 -1
- package/index.js +22 -22
- package/{library.command-ccb1cp92.js → library.command-sv6g1h2g.js} +4 -4
- package/{localRegistry.command-gmj1k6q8.js → localRegistry.command-fm41vdtw.js} +11 -11
- package/{module.command-5k6h407d.js → module.command-ccdeder9.js} +6 -6
- package/{package.command-e6ntvpez.js → package.command-xmw605b1.js} +5 -5
- package/package.json +2 -2
- package/{page.command-v4f90wb8.js → page.command-ky7vafsn.js} +4 -4
- package/{primitive.command-g6km57q5.js → primitive.command-bh6j8nfs.js} +7 -7
- package/{prompter-ptaa3nk0.js → prompter-76k56b37.js} +2 -2
- package/{quality.command-de3p36pz.js → quality.command-rqqrpe98.js} +3 -3
- package/{repair.command-d3x1javq.js → repair.command-n9nsm9qe.js} +6 -6
- package/{scalar.command-7ezrac2b.js → scalar.command-t09gmck8.js} +5 -5
- package/{subspace.command-ksenprez.js → subspace.command-y1p56wyv.js} +6 -6
- package/{tunnel.command-54947jck.js → tunnel.command-4g95vhsn.js} +5 -5
- package/{workflow.command-z2p32nmf.js → workflow.command-b91ph8sx.js} +11 -11
- package/{workspace.command-tkn8g0bn.js → workspace.command-d8he10tv.js} +24 -24
- package/TunnelShare-pemaknmd.js +0 -9
- package/cloud.script-g2dcnr8c.js +0 -20
- package/context.runner-ehjs419v.js +0 -21
- package/index-fgq75haa.js +0 -2084
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
devHostStateOf,
|
|
12
12
|
isLegacyBackendFallbackFile,
|
|
13
13
|
shouldMarkBuildPhaseRecovered,
|
|
14
|
+
shouldKeepBuildFailure,
|
|
14
15
|
createBackendBuildStatus,
|
|
15
16
|
backendRestartReasonFromMessage,
|
|
16
17
|
mergeBackendRestartReasons,
|
|
@@ -32,20 +33,20 @@ import {
|
|
|
32
33
|
filesChangedSince,
|
|
33
34
|
HmrWatcher,
|
|
34
35
|
WatchRootResolver
|
|
35
|
-
} from "./index-
|
|
36
|
+
} from "./index-48k96p55.js";
|
|
36
37
|
import {
|
|
37
38
|
runner,
|
|
38
39
|
script
|
|
39
|
-
} from "./index-
|
|
40
|
+
} from "./index-58cyna2s.js";
|
|
40
41
|
import {
|
|
41
42
|
WorkspaceExecutor,
|
|
42
43
|
AppExecutor,
|
|
43
44
|
LibExecutor,
|
|
44
45
|
PkgExecutor
|
|
45
|
-
} from "./index-
|
|
46
|
+
} from "./index-0n9q1f23.js";
|
|
46
47
|
import {
|
|
47
48
|
LibraryScript
|
|
48
|
-
} from "./index-
|
|
49
|
+
} from "./index-5mm3g24t.js";
|
|
49
50
|
import {
|
|
50
51
|
resolveMobileTargets,
|
|
51
52
|
NativeApp
|
|
@@ -56,7 +57,7 @@ import {
|
|
|
56
57
|
import {
|
|
57
58
|
SlicePlanner,
|
|
58
59
|
formatSlicePlan
|
|
59
|
-
} from "./index-
|
|
60
|
+
} from "./index-860zjnr1.js";
|
|
60
61
|
import {
|
|
61
62
|
openBrowser
|
|
62
63
|
} from "./index-9dp031by.js";
|
|
@@ -66,9 +67,10 @@ import { confirm } from "@inquirer/prompts";
|
|
|
66
67
|
import { Logger as Logger6 } from "akanjs/common";
|
|
67
68
|
|
|
68
69
|
// pkgs/@akanjs/cli/application/application.runner.ts
|
|
69
|
-
import
|
|
70
|
+
import path5 from "path";
|
|
70
71
|
|
|
71
72
|
// pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
|
|
73
|
+
import path3 from "path";
|
|
72
74
|
import { Logger as Logger2 } from "akanjs/common";
|
|
73
75
|
|
|
74
76
|
// pkgs/@akanjs/devkit/sshTunnel.ts
|
|
@@ -199,8 +201,10 @@ var createTunnel = async (service, { app, environment, port = service === "postg
|
|
|
199
201
|
return `localhost:${port}`;
|
|
200
202
|
};
|
|
201
203
|
// pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.host.ts
|
|
204
|
+
import fs from "fs";
|
|
202
205
|
import path from "path";
|
|
203
206
|
import { Logger } from "akanjs/common";
|
|
207
|
+
import { CSR_DEV_DIRNAME, CSR_DEV_PATCHING_MARKER, SSR_DEV_DIRNAME } from "akanjs/server/hmr/csrDevManifest";
|
|
204
208
|
import { MemoryLimit } from "akanjs/server/memoryLimit";
|
|
205
209
|
var builderMsgTypeSet = new Set([
|
|
206
210
|
"build-route-res",
|
|
@@ -210,15 +214,17 @@ var builderMsgTypeSet = new Set([
|
|
|
210
214
|
"css-updated",
|
|
211
215
|
"pages-updated",
|
|
212
216
|
"csr-updated",
|
|
217
|
+
"ssr-updated",
|
|
213
218
|
"build-status",
|
|
214
|
-
"builder-metrics"
|
|
219
|
+
"builder-metrics",
|
|
220
|
+
"boot-armed"
|
|
215
221
|
]);
|
|
216
222
|
|
|
217
223
|
class IncrementalBuilderHost {
|
|
218
224
|
static #restartBaseDelayMs = 1000;
|
|
219
225
|
static #restartMaxDelayMs = 30000;
|
|
220
226
|
static #recycleDrainTimeoutMs = 30000;
|
|
221
|
-
static #devMaxRssBytes =
|
|
227
|
+
static #devMaxRssBytes = 2048 * 1024 * 1024;
|
|
222
228
|
logger = new Logger("IncrementalBuilderHost");
|
|
223
229
|
entry;
|
|
224
230
|
env;
|
|
@@ -234,20 +240,33 @@ class IncrementalBuilderHost {
|
|
|
234
240
|
#recycleTimer = null;
|
|
235
241
|
#recycleRequested = false;
|
|
236
242
|
#spawnAfterRecycle = false;
|
|
243
|
+
#patcherOff = false;
|
|
237
244
|
#manualStop = false;
|
|
238
245
|
#inFlight = new Map;
|
|
239
246
|
#startOptions = {};
|
|
240
|
-
constructor({
|
|
247
|
+
constructor({
|
|
248
|
+
app,
|
|
249
|
+
entry,
|
|
250
|
+
env,
|
|
251
|
+
stdio = "inherit",
|
|
252
|
+
onMessage,
|
|
253
|
+
onOutput,
|
|
254
|
+
patcherOff = false
|
|
255
|
+
}) {
|
|
241
256
|
this.app = app;
|
|
242
257
|
this.entry = entry;
|
|
243
258
|
this.env = env;
|
|
244
259
|
this.#stdio = stdio;
|
|
245
260
|
this.#onMessage = onMessage;
|
|
246
261
|
this.#onOutput = onOutput ?? null;
|
|
262
|
+
this.#patcherOff = patcherOff;
|
|
247
263
|
}
|
|
248
264
|
get status() {
|
|
249
265
|
return this.#status;
|
|
250
266
|
}
|
|
267
|
+
get patcherOff() {
|
|
268
|
+
return this.#patcherOff;
|
|
269
|
+
}
|
|
251
270
|
get pid() {
|
|
252
271
|
return this.#proc?.pid ?? null;
|
|
253
272
|
}
|
|
@@ -265,10 +284,16 @@ class IncrementalBuilderHost {
|
|
|
265
284
|
this.ready = false;
|
|
266
285
|
const afterRecycle = this.#spawnAfterRecycle;
|
|
267
286
|
this.#spawnAfterRecycle = false;
|
|
287
|
+
this.#checkPatchingMarker(isRestart && !afterRecycle);
|
|
268
288
|
let proc;
|
|
269
289
|
proc = Bun.spawn(["bun", this.entry], {
|
|
270
290
|
cwd: this.app.cwdPath,
|
|
271
|
-
env: {
|
|
291
|
+
env: {
|
|
292
|
+
...this.env,
|
|
293
|
+
AKAN_WATCH: "1",
|
|
294
|
+
...afterRecycle ? { AKAN_BUILDER_ANNOUNCE_BOOT: "1" } : {},
|
|
295
|
+
...this.#patcherOff ? { AKAN_DEV_CSR_PATCHER: "off" } : {}
|
|
296
|
+
},
|
|
272
297
|
stdio: ["ignore", this.#stdio, this.#stdio],
|
|
273
298
|
ipc: (msg) => {
|
|
274
299
|
if (this.#proc !== proc)
|
|
@@ -323,6 +348,17 @@ class IncrementalBuilderHost {
|
|
|
323
348
|
}
|
|
324
349
|
this.logger.verbose(`builder spawned pid=${proc.pid} entry=${this.entry}${isRestart ? " restart=1" : ""}`);
|
|
325
350
|
}
|
|
351
|
+
#checkPatchingMarker(afterCrash) {
|
|
352
|
+
const markers = [CSR_DEV_DIRNAME, SSR_DEV_DIRNAME].map((dirName) => path.join(this.app.cwdPath, ".akan/artifact", dirName, CSR_DEV_PATCHING_MARKER)).filter((marker) => fs.existsSync(marker));
|
|
353
|
+
if (markers.length === 0)
|
|
354
|
+
return;
|
|
355
|
+
if (afterCrash && !this.#patcherOff) {
|
|
356
|
+
this.#patcherOff = true;
|
|
357
|
+
this.logger.warn("the builder died while patching a dev module registry; registry saves go to a build worker until the next config or metadata restart (AKAN_DEV_CSR_PATCHER=off)");
|
|
358
|
+
}
|
|
359
|
+
for (const marker of markers)
|
|
360
|
+
fs.rmSync(marker, { force: true });
|
|
361
|
+
}
|
|
326
362
|
async#drain(stream, kind) {
|
|
327
363
|
if (!stream)
|
|
328
364
|
return;
|
|
@@ -428,7 +464,8 @@ class IncrementalBuilderHost {
|
|
|
428
464
|
}
|
|
429
465
|
static async create(app, env, onMessage, {
|
|
430
466
|
stdio = "inherit",
|
|
431
|
-
onOutput
|
|
467
|
+
onOutput,
|
|
468
|
+
patcherOff = false
|
|
432
469
|
} = {}) {
|
|
433
470
|
const candidates = [
|
|
434
471
|
path.join(app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts"),
|
|
@@ -438,7 +475,7 @@ class IncrementalBuilderHost {
|
|
|
438
475
|
];
|
|
439
476
|
for (const c of candidates)
|
|
440
477
|
if (await Bun.file(c).exists())
|
|
441
|
-
return new IncrementalBuilderHost({ app, entry: c, env, stdio, onMessage, onOutput });
|
|
478
|
+
return new IncrementalBuilderHost({ app, entry: c, env, stdio, onMessage, onOutput, patcherOff });
|
|
442
479
|
throw new Error(`[cli] frontend builder entry not found; looked in: ${candidates.join(", ")}`);
|
|
443
480
|
}
|
|
444
481
|
}
|
|
@@ -618,6 +655,41 @@ class BackendImportGraph {
|
|
|
618
655
|
}
|
|
619
656
|
}
|
|
620
657
|
|
|
658
|
+
// pkgs/@akanjs/devkit/akanApp/devBootLatch.ts
|
|
659
|
+
class DevBootLatch {
|
|
660
|
+
#onBooted;
|
|
661
|
+
#waitMs;
|
|
662
|
+
#ready = false;
|
|
663
|
+
#armed = false;
|
|
664
|
+
#booted = false;
|
|
665
|
+
#timer = null;
|
|
666
|
+
constructor(onBooted, { waitMs = 30000 } = {}) {
|
|
667
|
+
this.#onBooted = onBooted;
|
|
668
|
+
this.#waitMs = waitMs;
|
|
669
|
+
}
|
|
670
|
+
ready() {
|
|
671
|
+
this.#ready = true;
|
|
672
|
+
if (!this.#armed && !this.#timer) {
|
|
673
|
+
this.#timer = setTimeout(() => this.armed(), this.#waitMs);
|
|
674
|
+
this.#timer.unref?.();
|
|
675
|
+
}
|
|
676
|
+
this.#release();
|
|
677
|
+
}
|
|
678
|
+
armed() {
|
|
679
|
+
this.#armed = true;
|
|
680
|
+
this.#release();
|
|
681
|
+
}
|
|
682
|
+
#release() {
|
|
683
|
+
if (this.#booted || !this.#ready || !this.#armed)
|
|
684
|
+
return;
|
|
685
|
+
this.#booted = true;
|
|
686
|
+
if (this.#timer)
|
|
687
|
+
clearTimeout(this.#timer);
|
|
688
|
+
this.#timer = null;
|
|
689
|
+
this.#onBooted();
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
621
693
|
// pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
|
|
622
694
|
var backendMsgTypeSet = new Set(["build-route", "build-csr"]);
|
|
623
695
|
var asMib = (bytes) => Math.round(bytes / 1024 / 1024);
|
|
@@ -641,8 +713,10 @@ class AkanAppHost {
|
|
|
641
713
|
env;
|
|
642
714
|
#onDevEvent;
|
|
643
715
|
#lastDevState = null;
|
|
716
|
+
#bootLatch = new DevBootLatch(() => this.#onDevEvent?.({ app: this.app.name, booted: true }));
|
|
644
717
|
#backend = null;
|
|
645
718
|
#builder = null;
|
|
719
|
+
#patcherOff = false;
|
|
646
720
|
#backendReady = false;
|
|
647
721
|
#plannedBackendStops = new WeakSet;
|
|
648
722
|
#restartTimer = null;
|
|
@@ -652,6 +726,8 @@ class AkanAppHost {
|
|
|
652
726
|
#backendLifecycleState = "stopped";
|
|
653
727
|
#pendingRestartReason = null;
|
|
654
728
|
#pendingRecycle = null;
|
|
729
|
+
#restartFailedAfterApply = null;
|
|
730
|
+
#stopping = false;
|
|
655
731
|
#builderRecoveryTimer = null;
|
|
656
732
|
#builderRecoveryAttempts = 0;
|
|
657
733
|
#backendStartStatus = null;
|
|
@@ -679,6 +755,7 @@ class AkanAppHost {
|
|
|
679
755
|
#builderGapStamp = null;
|
|
680
756
|
#pendingBuilderMessages = [];
|
|
681
757
|
#builderRequests = new BuilderRequestRouter;
|
|
758
|
+
#builderGeneration = 0;
|
|
682
759
|
constructor(app, {
|
|
683
760
|
env,
|
|
684
761
|
stdio = "inherit",
|
|
@@ -695,6 +772,8 @@ class AkanAppHost {
|
|
|
695
772
|
return;
|
|
696
773
|
this.#lastDevState = state;
|
|
697
774
|
this.#onDevEvent({ app: this.app.name, state, ...detail ? { detail } : {} });
|
|
775
|
+
if (state === "ready")
|
|
776
|
+
this.#bootLatch.ready();
|
|
698
777
|
}
|
|
699
778
|
async start() {
|
|
700
779
|
if (this.#backend)
|
|
@@ -712,6 +791,8 @@ class AkanAppHost {
|
|
|
712
791
|
return this;
|
|
713
792
|
}
|
|
714
793
|
async stop() {
|
|
794
|
+
this.#stopping = true;
|
|
795
|
+
this.#pendingRecycle = null;
|
|
715
796
|
this.#cancelIdleSuspend();
|
|
716
797
|
this.#stopIdleWatcher();
|
|
717
798
|
this.#clearRestartTimers();
|
|
@@ -756,6 +837,7 @@ class AkanAppHost {
|
|
|
756
837
|
this.#setBackendLifecycleState("ready", `pid=${msg.pid}`);
|
|
757
838
|
this.#recordBackendReadyStatus();
|
|
758
839
|
this.logger.verbose(`backend ready pid=${msg.pid}`);
|
|
840
|
+
this.#forgetRouteBuildStatus();
|
|
759
841
|
this.#replayBuilderState();
|
|
760
842
|
return;
|
|
761
843
|
}
|
|
@@ -976,17 +1058,26 @@ ${this.#backendStderrTail.join(`
|
|
|
976
1058
|
});
|
|
977
1059
|
}
|
|
978
1060
|
async#handleBuilderMessage(message) {
|
|
1061
|
+
if (this.#stopping)
|
|
1062
|
+
return;
|
|
979
1063
|
this.#markDevActivity();
|
|
1064
|
+
this.#trackBuilderGeneration(message);
|
|
980
1065
|
if (message.type === "build-status") {
|
|
981
1066
|
this.#recordBuildStatus(message.data);
|
|
982
1067
|
this.#sendOrQueueBuildStatus(message.data);
|
|
983
1068
|
this.#reviveBackendAfterGreenBuild(message.data);
|
|
1069
|
+
await this.#resumeFailedRecycle(message.data);
|
|
984
1070
|
return;
|
|
985
1071
|
}
|
|
986
1072
|
if (message.type === "builder-metrics") {
|
|
987
1073
|
this.#handleBuilderMetrics(message.data);
|
|
988
1074
|
return;
|
|
989
1075
|
}
|
|
1076
|
+
if (message.type === "boot-armed") {
|
|
1077
|
+
this.logger.verbose("[builder] boot builds settled");
|
|
1078
|
+
this.#bootLatch.armed();
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
990
1081
|
if (message.type === "pages-updated" || message.type === "css-updated") {
|
|
991
1082
|
const recycled = message.data.reason === "builder-recycle";
|
|
992
1083
|
if (recycled && !this.#shouldRelayRecycledState(message))
|
|
@@ -1008,6 +1099,22 @@ ${this.#backendStderrTail.join(`
|
|
|
1008
1099
|
}
|
|
1009
1100
|
this.#sendToBackend(message);
|
|
1010
1101
|
}
|
|
1102
|
+
#trackBuilderGeneration(message) {
|
|
1103
|
+
const generation = AkanAppHost.#builderGenerationOf(message);
|
|
1104
|
+
if (generation === undefined || generation <= this.#builderGeneration)
|
|
1105
|
+
return;
|
|
1106
|
+
this.#builderGeneration = generation;
|
|
1107
|
+
Object.assign(this.env, { AKAN_BUILDER_INITIAL_GENERATION: String(generation) });
|
|
1108
|
+
}
|
|
1109
|
+
static #builderGenerationOf(message) {
|
|
1110
|
+
if (message.type === "invalidate")
|
|
1111
|
+
return message.generation;
|
|
1112
|
+
if (message.type === "build-status" || message.type === "builder-metrics")
|
|
1113
|
+
return message.data.generation;
|
|
1114
|
+
if (message.type === "pages-updated" || message.type === "css-updated")
|
|
1115
|
+
return message.data.generation;
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1011
1118
|
#shouldRelayRecycledState(message) {
|
|
1012
1119
|
const current = message.type === "pages-updated" ? this.#lastGoodFrontend.pages : this.#lastGoodFrontend.css;
|
|
1013
1120
|
if (shouldRelayRecycledFrontendState(current, message)) {
|
|
@@ -1266,9 +1373,7 @@ ${this.#backendStderrTail.join(`
|
|
|
1266
1373
|
if (shouldRefreshConfigOnIdleWake(batch)) {
|
|
1267
1374
|
this.logger.verbose("[idle-suspend] config changed while suspended; restarting the dev host");
|
|
1268
1375
|
this.#discardBuilderGap("config change replaces the backend anyway");
|
|
1269
|
-
await this.#
|
|
1270
|
-
refreshConfig: true
|
|
1271
|
-
});
|
|
1376
|
+
await this.#applyRecycle({ type: "invalidate", kinds: [...batch?.kinds ?? []], files }, true);
|
|
1272
1377
|
return;
|
|
1273
1378
|
}
|
|
1274
1379
|
if (files.length > 0)
|
|
@@ -1369,7 +1474,8 @@ ${this.#backendStderrTail.join(`
|
|
|
1369
1474
|
this.#armRssRecycle(this.#rssRecycleReason);
|
|
1370
1475
|
const wantsDevHostRestart = shouldRestartDevHostByDevPlan(message);
|
|
1371
1476
|
const pending = this.#pendingRecycle;
|
|
1372
|
-
|
|
1477
|
+
const resumes = !!pending && message.kinds.includes("code") && this.#touchesFailedRecycle(message.files);
|
|
1478
|
+
if (wantsDevHostRestart || shouldRestartBuilderByDevPlan(message) || resumes) {
|
|
1373
1479
|
const refreshConfig = wantsDevHostRestart || (pending?.refreshConfig ?? false);
|
|
1374
1480
|
const merged = pending ? mergeInvalidateMessages(pending.message, message) : message;
|
|
1375
1481
|
const generation = message.devPlan?.generation ?? message.generation;
|
|
@@ -1377,16 +1483,7 @@ ${this.#backendStderrTail.join(`
|
|
|
1377
1483
|
this.#deferRecycle(merged, { refreshConfig, generation });
|
|
1378
1484
|
return;
|
|
1379
1485
|
}
|
|
1380
|
-
this.#
|
|
1381
|
-
try {
|
|
1382
|
-
if (refreshConfig)
|
|
1383
|
-
await this.#restartDevHost(merged);
|
|
1384
|
-
else
|
|
1385
|
-
await this.#restartDevChildren(merged);
|
|
1386
|
-
} catch (err) {
|
|
1387
|
-
this.#recordDevHostRestartFailure(merged, err, refreshConfig ? "Config" : "Runtime metadata");
|
|
1388
|
-
this.#resurrectDevChildren(merged);
|
|
1389
|
-
}
|
|
1486
|
+
await this.#applyRecycle(merged, refreshConfig);
|
|
1390
1487
|
return;
|
|
1391
1488
|
}
|
|
1392
1489
|
if (await this.#shouldRestartBackend(message)) {
|
|
@@ -1395,6 +1492,41 @@ ${this.#backendStderrTail.join(`
|
|
|
1395
1492
|
}
|
|
1396
1493
|
this.#sendToBackend(message);
|
|
1397
1494
|
}
|
|
1495
|
+
async#applyRecycle(message, refreshConfig) {
|
|
1496
|
+
if (this.#stopping)
|
|
1497
|
+
return;
|
|
1498
|
+
this.#pendingRecycle = null;
|
|
1499
|
+
const progress = { applied: !refreshConfig };
|
|
1500
|
+
try {
|
|
1501
|
+
if (refreshConfig)
|
|
1502
|
+
await this.#restartDevHost(message, progress);
|
|
1503
|
+
else
|
|
1504
|
+
await this.#restartDevChildren(message);
|
|
1505
|
+
} catch (err) {
|
|
1506
|
+
const kind = refreshConfig ? "Config" : "Runtime metadata";
|
|
1507
|
+
const generation = this.#recordDevHostRestartFailure(message, err, kind, { applied: progress.applied });
|
|
1508
|
+
if (progress.applied)
|
|
1509
|
+
this.#restartFailedAfterApply = generation;
|
|
1510
|
+
else
|
|
1511
|
+
this.#pendingRecycle = { message, refreshConfig, failed: true, failedGeneration: generation };
|
|
1512
|
+
this.#resurrectDevChildren(message);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
async#resumeFailedRecycle(status) {
|
|
1516
|
+
const pending = this.#pendingRecycle;
|
|
1517
|
+
if (!pending?.failed || !status.ok || status.phase !== "pages" || !this.#touchesFailedRecycle(status.files))
|
|
1518
|
+
return;
|
|
1519
|
+
if (status.generation <= (pending.failedGeneration ?? -1))
|
|
1520
|
+
return;
|
|
1521
|
+
await this.#applyRecycle(pending.message, pending.refreshConfig);
|
|
1522
|
+
}
|
|
1523
|
+
#touchesFailedRecycle(files) {
|
|
1524
|
+
const pending = this.#pendingRecycle;
|
|
1525
|
+
if (!pending?.failed)
|
|
1526
|
+
return true;
|
|
1527
|
+
const changed = new Set(pending.message.files);
|
|
1528
|
+
return files.some((file) => changed.has(file));
|
|
1529
|
+
}
|
|
1398
1530
|
#deferRecycle(message, { refreshConfig, generation }) {
|
|
1399
1531
|
this.#pendingRecycle = { message, refreshConfig };
|
|
1400
1532
|
const kind = refreshConfig ? "Config" : "Runtime metadata";
|
|
@@ -1440,8 +1572,10 @@ ${this.#backendStderrTail.join(`
|
|
|
1440
1572
|
this.#builderRecoveryAttempts = 0;
|
|
1441
1573
|
this.logger.info("[builder-recovery] builder recovered");
|
|
1442
1574
|
this.#restartBackendForGapChanges();
|
|
1575
|
+
const failedAfterApply = this.#restartFailedAfterApply;
|
|
1576
|
+
this.#restartFailedAfterApply = null;
|
|
1443
1577
|
const status = {
|
|
1444
|
-
generation: reason.generation ?? this.#nextBackendBuildStatusGeneration(),
|
|
1578
|
+
generation: failedAfterApply !== null ? this.#nextBackendBuildStatusGeneration(failedAfterApply + 1) : reason.generation ?? this.#nextBackendBuildStatusGeneration(),
|
|
1445
1579
|
phase: "scan",
|
|
1446
1580
|
ok: true,
|
|
1447
1581
|
files: reason.files,
|
|
@@ -1465,12 +1599,12 @@ ${this.#backendStderrTail.join(`
|
|
|
1465
1599
|
this.logger.warn(`[dev-host] recycling builder/backend for runtime metadata generation=${generation ?? "(unknown)"} files=${message.files.length}`);
|
|
1466
1600
|
await this.#recycleDevChildren(message);
|
|
1467
1601
|
}
|
|
1468
|
-
async#restartDevHost(message) {
|
|
1602
|
+
async#restartDevHost(message, progress) {
|
|
1469
1603
|
const generation = message.devPlan?.generation ?? message.generation;
|
|
1470
1604
|
this.logger.warn(`[dev-host] config change detected; restarting dev host generation=${generation ?? "(unknown)"} files=${message.files.length}`);
|
|
1471
|
-
await this.#recycleDevChildren(message, { refreshConfig: true });
|
|
1605
|
+
await this.#recycleDevChildren(message, { refreshConfig: true, progress });
|
|
1472
1606
|
}
|
|
1473
|
-
async#recycleDevChildren(message, { refreshConfig = false } = {}) {
|
|
1607
|
+
async#recycleDevChildren(message, { refreshConfig = false, progress } = {}) {
|
|
1474
1608
|
const generation = message.devPlan?.generation ?? message.generation;
|
|
1475
1609
|
this.#clearRestartTimers();
|
|
1476
1610
|
this.#builderRecoveryAttempts = 0;
|
|
@@ -1480,10 +1614,13 @@ ${this.#backendStderrTail.join(`
|
|
|
1480
1614
|
this.#pendingBuildStatusReplay = [];
|
|
1481
1615
|
await this.#stopBackend();
|
|
1482
1616
|
this.#stopBuilder();
|
|
1617
|
+
this.#patcherOff = false;
|
|
1483
1618
|
if (refreshConfig) {
|
|
1484
1619
|
await this.app.getConfig({ refresh: true });
|
|
1485
1620
|
const { env } = await this.app.prepareCommand("start");
|
|
1486
1621
|
Object.assign(this.env, env);
|
|
1622
|
+
if (progress)
|
|
1623
|
+
progress.applied = true;
|
|
1487
1624
|
}
|
|
1488
1625
|
await this.#backendGraph.refresh();
|
|
1489
1626
|
await this.#startBuilder();
|
|
@@ -1502,22 +1639,27 @@ ${this.#backendStderrTail.join(`
|
|
|
1502
1639
|
this.#lastGoodFrontend.css = message;
|
|
1503
1640
|
this.logger.verbose(`[last-good] css generation=${message.data.generation ?? "(unknown)"} assets=${Object.keys(message.data.cssAssets).length}`);
|
|
1504
1641
|
}
|
|
1505
|
-
#recordDevHostRestartFailure(message, err, kind) {
|
|
1642
|
+
#recordDevHostRestartFailure(message, err, kind, { applied }) {
|
|
1506
1643
|
const generation = message.devPlan?.generation ?? message.generation ?? this.#nextBackendBuildStatusGeneration();
|
|
1507
1644
|
const detail = err instanceof Error ? err.message : String(err);
|
|
1508
1645
|
this.logger.warn(`[dev-host] ${kind.toLowerCase()} restart failed generation=${generation}: ${detail}`);
|
|
1646
|
+
const names = message.files.slice(0, 3).map((file) => path3.basename(file));
|
|
1647
|
+
const saved = names.length > 0 ? names.join(", ") : "the changed file";
|
|
1509
1648
|
const status = {
|
|
1510
1649
|
generation,
|
|
1511
1650
|
phase: "scan",
|
|
1512
1651
|
ok: false,
|
|
1513
1652
|
files: message.files,
|
|
1514
|
-
message: `${kind} change failed to
|
|
1653
|
+
message: applied ? `${kind} change applied, but the dev server failed to restart: ${detail}. It is recovering on its own.` : `${kind} change failed to apply: ${detail}. The dev server keeps running on the previous ${kind.toLowerCase()}; once it is fixed, save ${saved} again or restart the dev server to apply it.`
|
|
1515
1654
|
};
|
|
1516
1655
|
this.#recordBuildStatus(status);
|
|
1517
1656
|
this.#sendOrQueueBuildStatus(status);
|
|
1657
|
+
return generation;
|
|
1518
1658
|
}
|
|
1519
1659
|
#recordBuildStatus(status) {
|
|
1520
1660
|
const recovered = shouldMarkBuildPhaseRecovered(this.#buildStatusByPhase, status);
|
|
1661
|
+
if (shouldKeepBuildFailure(this.#buildStatusByPhase, status))
|
|
1662
|
+
return;
|
|
1521
1663
|
this.#buildStatusByPhase.set(status.phase, status);
|
|
1522
1664
|
const label = `[build-status] generation=${status.generation} phase=${status.phase} ok=${status.ok} files=${status.files.length}`;
|
|
1523
1665
|
if (status.ok)
|
|
@@ -1533,6 +1675,10 @@ ${this.#backendStderrTail.join(`
|
|
|
1533
1675
|
}
|
|
1534
1676
|
this.#sendToBackend({ type: "build-status", data: status });
|
|
1535
1677
|
}
|
|
1678
|
+
#forgetRouteBuildStatus() {
|
|
1679
|
+
this.#buildStatusByPhase.delete("route");
|
|
1680
|
+
this.#pendingBuildStatusReplay = this.#pendingBuildStatusReplay.filter((status) => status.phase !== "route");
|
|
1681
|
+
}
|
|
1536
1682
|
#replayBuilderState() {
|
|
1537
1683
|
if (!this.#backendReady)
|
|
1538
1684
|
return;
|
|
@@ -1584,7 +1730,8 @@ ${this.#backendStderrTail.join(`
|
|
|
1584
1730
|
this.#enqueueBuilderMessage(msg);
|
|
1585
1731
|
}, {
|
|
1586
1732
|
stdio: this.stdio,
|
|
1587
|
-
onOutput: (kind, text) => void (kind === "stderr" ? process.stderr : process.stdout).write(text)
|
|
1733
|
+
onOutput: (kind, text) => void (kind === "stderr" ? process.stderr : process.stdout).write(text),
|
|
1734
|
+
patcherOff: this.#patcherOff
|
|
1588
1735
|
});
|
|
1589
1736
|
try {
|
|
1590
1737
|
await this.#waitForBuilderReady(attempt, { announceBootState });
|
|
@@ -1670,21 +1817,23 @@ ${this.#backendStderrTail.join(`
|
|
|
1670
1817
|
this.#cancelRssRecycle();
|
|
1671
1818
|
if (!this.#builder)
|
|
1672
1819
|
return;
|
|
1820
|
+
if (this.#builder.patcherOff)
|
|
1821
|
+
this.#patcherOff = true;
|
|
1673
1822
|
this.#builder.stop();
|
|
1674
1823
|
this.#builder = null;
|
|
1675
1824
|
}
|
|
1676
1825
|
}
|
|
1677
1826
|
// pkgs/@akanjs/devkit/applicationTestPreload.ts
|
|
1678
|
-
import
|
|
1827
|
+
import path4 from "path";
|
|
1679
1828
|
var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
|
|
1680
1829
|
async function resolveSignalTestPreloadPath(target) {
|
|
1681
1830
|
const candidates = [];
|
|
1682
|
-
for (const basePath of [target.cwdPath, process.cwd(),
|
|
1831
|
+
for (const basePath of [target.cwdPath, process.cwd(), path4.dirname(Bun.main), import.meta.dir]) {
|
|
1683
1832
|
try {
|
|
1684
|
-
candidates.push(
|
|
1833
|
+
candidates.push(path4.join(path4.dirname(Bun.resolveSync("akanjs/package.json", basePath)), SIGNAL_TEST_PRELOAD_PATH));
|
|
1685
1834
|
} catch {}
|
|
1686
1835
|
}
|
|
1687
|
-
candidates.push(
|
|
1836
|
+
candidates.push(path4.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.join(path4.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path4.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
|
|
1688
1837
|
const uniqueCandidates = [...new Set(candidates)];
|
|
1689
1838
|
for (const candidate of uniqueCandidates)
|
|
1690
1839
|
if (await Bun.file(candidate).exists())
|
|
@@ -1697,7 +1846,7 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
|
1697
1846
|
|
|
1698
1847
|
// pkgs/@akanjs/cli/application/application.runner.ts
|
|
1699
1848
|
import { Logger as Logger3 } from "akanjs/common";
|
|
1700
|
-
var loadBuildRunner = async () => (await import("./applicationBuildRunner-
|
|
1849
|
+
var loadBuildRunner = async () => (await import("./applicationBuildRunner-412y0345.js")).ApplicationBuildRunner;
|
|
1701
1850
|
var loadPrompts = async () => await import("@inquirer/prompts");
|
|
1702
1851
|
|
|
1703
1852
|
class ApplicationRunner extends runner("application") {
|
|
@@ -1742,7 +1891,7 @@ class ApplicationRunner extends runner("application") {
|
|
|
1742
1891
|
});
|
|
1743
1892
|
}
|
|
1744
1893
|
#runtimeDirOf(app, override) {
|
|
1745
|
-
return
|
|
1894
|
+
return path5.resolve(override ?? process.env.AKAN_RUNTIME_DIR ?? path5.join(app.workspace.workspaceRoot, "local", "apps", app.name, "runtime"));
|
|
1746
1895
|
}
|
|
1747
1896
|
async runLogs(app, options) {
|
|
1748
1897
|
const { LogControlUnavailableError, LogTailClient } = await import("akanjs/server/logging/logTailClient");
|
|
@@ -1768,7 +1917,7 @@ class ApplicationRunner extends runner("application") {
|
|
|
1768
1917
|
});
|
|
1769
1918
|
} catch (error) {
|
|
1770
1919
|
if (error instanceof LogControlUnavailableError)
|
|
1771
|
-
throw new Error(`${app.name} is not running (no ${
|
|
1920
|
+
throw new Error(`${app.name} is not running (no ${path5.basename(socketPath)} in ${runtimeDir}). Start it with \`akan start ${app.name}\`, or pass --runtime-dir for a built app.`);
|
|
1772
1921
|
throw error;
|
|
1773
1922
|
}
|
|
1774
1923
|
const sinceMs = since ? LogQueryMatcher.parseSince(since) : undefined;
|
|
@@ -1833,7 +1982,7 @@ try {
|
|
|
1833
1982
|
const serverPath = `${app.cwdPath}/server.ts`;
|
|
1834
1983
|
if (!await app.exists("server.ts"))
|
|
1835
1984
|
throw new Error(`Server file not found: apps/${app.name}/server.ts`);
|
|
1836
|
-
const target =
|
|
1985
|
+
const target = path5.resolve(app.workspace.workspaceRoot, dir);
|
|
1837
1986
|
const code = `
|
|
1838
1987
|
const { server } = await import(${JSON.stringify(serverPath)});
|
|
1839
1988
|
const { DatabaseAdaptorRole, DocumentTransfer } = await import("akanjs/service");
|
|
@@ -2406,7 +2555,7 @@ import os from "os";
|
|
|
2406
2555
|
import { MemoryLimit as MemoryLimit2 } from "akanjs/server/memoryLimit";
|
|
2407
2556
|
|
|
2408
2557
|
class DevBootConcurrency {
|
|
2409
|
-
static perAppBytes =
|
|
2558
|
+
static perAppBytes = 1800 * 1024 * 1024;
|
|
2410
2559
|
static memoryShare = 0.5;
|
|
2411
2560
|
static coresPerApp = 4;
|
|
2412
2561
|
static budget() {
|
|
@@ -2440,7 +2589,7 @@ class DevBootConcurrency {
|
|
|
2440
2589
|
|
|
2441
2590
|
// pkgs/@akanjs/cli/application/devSessionLog.ts
|
|
2442
2591
|
import { mkdir, rename } from "fs/promises";
|
|
2443
|
-
import
|
|
2592
|
+
import path6 from "path";
|
|
2444
2593
|
import dayjs from "dayjs";
|
|
2445
2594
|
|
|
2446
2595
|
class DevSessionLog {
|
|
@@ -2464,19 +2613,19 @@ class DevSessionLog {
|
|
|
2464
2613
|
return [...this.#appNames];
|
|
2465
2614
|
}
|
|
2466
2615
|
pathOf(app) {
|
|
2467
|
-
return
|
|
2616
|
+
return path6.join(this.#runtimeDirOf(app), DevSessionLog.fileName);
|
|
2468
2617
|
}
|
|
2469
2618
|
previousPathOf(app) {
|
|
2470
|
-
return
|
|
2619
|
+
return path6.join(this.#runtimeDirOf(app), DevSessionLog.previousFileName);
|
|
2471
2620
|
}
|
|
2472
2621
|
relativePathOf(app) {
|
|
2473
|
-
return
|
|
2622
|
+
return path6.relative(this.#workspaceRoot, this.pathOf(app));
|
|
2474
2623
|
}
|
|
2475
2624
|
async open() {
|
|
2476
2625
|
const stamp = dayjs(this.#now()).format("YYYY-MM-DD HH:mm:ss");
|
|
2477
2626
|
for (const app of this.#appNames) {
|
|
2478
2627
|
const file = this.pathOf(app);
|
|
2479
|
-
await mkdir(
|
|
2628
|
+
await mkdir(path6.dirname(file), { recursive: true });
|
|
2480
2629
|
await rename(file, this.previousPathOf(app)).catch(() => {
|
|
2481
2630
|
return;
|
|
2482
2631
|
});
|
|
@@ -2520,7 +2669,7 @@ class DevSessionLog {
|
|
|
2520
2669
|
this.#writers.clear();
|
|
2521
2670
|
}
|
|
2522
2671
|
#runtimeDirOf(app) {
|
|
2523
|
-
return
|
|
2672
|
+
return path6.join(this.#workspaceRoot, "local", "apps", app, "runtime");
|
|
2524
2673
|
}
|
|
2525
2674
|
#writeLine(app, text) {
|
|
2526
2675
|
const writer = this.#writers.get(app);
|
|
@@ -2567,7 +2716,7 @@ class DevSupervisor {
|
|
|
2567
2716
|
}
|
|
2568
2717
|
};
|
|
2569
2718
|
}
|
|
2570
|
-
static
|
|
2719
|
+
static bootTimeoutMs = 180000;
|
|
2571
2720
|
static shutdownGraceMs = 12000;
|
|
2572
2721
|
#options;
|
|
2573
2722
|
#children = new Map;
|
|
@@ -2616,7 +2765,7 @@ class DevSupervisor {
|
|
|
2616
2765
|
return ports;
|
|
2617
2766
|
}
|
|
2618
2767
|
#makeChild(app, port) {
|
|
2619
|
-
const { promise:
|
|
2768
|
+
const { promise: booted, resolve: markBooted } = Promise.withResolvers();
|
|
2620
2769
|
return {
|
|
2621
2770
|
status: {
|
|
2622
2771
|
app,
|
|
@@ -2629,8 +2778,8 @@ class DevSupervisor {
|
|
|
2629
2778
|
exitCode: null
|
|
2630
2779
|
},
|
|
2631
2780
|
proc: null,
|
|
2632
|
-
|
|
2633
|
-
|
|
2781
|
+
booted,
|
|
2782
|
+
markBooted,
|
|
2634
2783
|
opened: false
|
|
2635
2784
|
};
|
|
2636
2785
|
}
|
|
@@ -2649,12 +2798,12 @@ class DevSupervisor {
|
|
|
2649
2798
|
for (const child of wave)
|
|
2650
2799
|
this.#spawnChild(child);
|
|
2651
2800
|
this.#publishStatus();
|
|
2652
|
-
await Promise.all(wave.map(async (child) => await this.#
|
|
2801
|
+
await Promise.all(wave.map(async (child) => await this.#waitForBoot(child)));
|
|
2653
2802
|
}
|
|
2654
2803
|
}
|
|
2655
|
-
async#
|
|
2656
|
-
if (await DevSupervisor.timesOut(child.
|
|
2657
|
-
this.#note(`${child.status.name} has not
|
|
2804
|
+
async#waitForBoot(child) {
|
|
2805
|
+
if (await DevSupervisor.timesOut(child.booted, DevSupervisor.bootTimeoutMs))
|
|
2806
|
+
this.#note(`${child.status.name} has not finished booting after ${Math.round(DevSupervisor.bootTimeoutMs / 1000)}s; starting the next app anyway`, "warn");
|
|
2658
2807
|
}
|
|
2659
2808
|
static async timesOut(work, ms) {
|
|
2660
2809
|
let timer;
|
|
@@ -2691,9 +2840,12 @@ class DevSupervisor {
|
|
|
2691
2840
|
},
|
|
2692
2841
|
stdio: ["ignore", "pipe", "pipe"],
|
|
2693
2842
|
ipc: (message) => {
|
|
2694
|
-
if (!message || typeof message !== "object"
|
|
2843
|
+
if (!message || typeof message !== "object")
|
|
2695
2844
|
return;
|
|
2696
|
-
|
|
2845
|
+
if ("booted" in message)
|
|
2846
|
+
child.markBooted();
|
|
2847
|
+
else if (typeof message.state === "string")
|
|
2848
|
+
this.#applyChildEvent(child, message);
|
|
2697
2849
|
},
|
|
2698
2850
|
serialization: "advanced",
|
|
2699
2851
|
onExit: (_proc, exitCode, signalCode) => {
|
|
@@ -2703,7 +2855,7 @@ class DevSupervisor {
|
|
|
2703
2855
|
return;
|
|
2704
2856
|
child.status.state = "stopped";
|
|
2705
2857
|
child.status.detail = signalCode ? `killed by ${signalCode}` : `exited with ${exitCode}`;
|
|
2706
|
-
child.
|
|
2858
|
+
child.markBooted();
|
|
2707
2859
|
this.#publishStatus();
|
|
2708
2860
|
}
|
|
2709
2861
|
});
|
|
@@ -2717,14 +2869,13 @@ class DevSupervisor {
|
|
|
2717
2869
|
child.status.state = event.state;
|
|
2718
2870
|
child.status.detail = event.detail ?? "";
|
|
2719
2871
|
if (event.state === "ready") {
|
|
2720
|
-
child.markReady();
|
|
2721
2872
|
if (this.#options.open && !child.opened) {
|
|
2722
2873
|
child.opened = true;
|
|
2723
2874
|
openBrowser(child.status.url);
|
|
2724
2875
|
}
|
|
2725
2876
|
}
|
|
2726
2877
|
if (event.state === "failed")
|
|
2727
|
-
child.
|
|
2878
|
+
child.markBooted();
|
|
2728
2879
|
this.#publishStatus();
|
|
2729
2880
|
}
|
|
2730
2881
|
async#drain(stream, name, kind) {
|
|
@@ -3125,7 +3276,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3125
3276
|
await Promise.all(shares.map(async (share) => await share.close()));
|
|
3126
3277
|
}, "Abandoning the tunnel release; the shares expire on their own.");
|
|
3127
3278
|
await Promise.all(apps.map(async (app) => {
|
|
3128
|
-
const { TunnelShare } = await import("./TunnelShare-
|
|
3279
|
+
const { TunnelShare } = await import("./TunnelShare-cwh9ezsm.js");
|
|
3129
3280
|
const share = await TunnelShare.open(app, { workspace: app.workspace });
|
|
3130
3281
|
shares.push(share);
|
|
3131
3282
|
urls.set(app.name, share.url);
|