@akanjs/cli 3.0.0-beta.19 → 3.0.0-beta.20
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-6cm97kay.js → CodeAgent-awv258wb.js} +2 -2
- package/{CodeTui-za4jsm41.js → CodeTui-1nqh35ez.js} +20 -22
- package/TunnelShare-scf4e4pd.js +9 -0
- package/{agent.command-e0wpbbyg.js → agent.command-1s9ag7sb.js} +8 -9
- package/akanCode.js +4 -4
- package/{application.command-8wyxqc8q.js → application.command-49hwy6va.js} +25 -56
- package/{applicationBuildRunner-n9gzaxd0.js → applicationBuildRunner-ybyp97pv.js} +33 -59
- package/{applicationReleasePackager-vpggfqgq.js → applicationReleasePackager-esnrphw8.js} +40 -60
- package/buildBatch.proc.js +19 -24
- package/{capacitorApp-q3z0qht0.js → capacitorApp-1synz4en.js} +3 -4
- package/{cloud.command-4zwa5dsx.js → cloud.command-d7rqtzt9.js} +16 -26
- package/cloud.script-bkbpcr96.js +19 -0
- package/{code.command-468c9d7s.js → code.command-nn48xzej.js} +22 -37
- package/context.command-s3mcmvpa.js +48 -0
- package/context.runner-k99nb5pk.js +21 -0
- package/{dependencyScanner-0z2h2tks.js → dependencyScanner-ye2e6pdz.js} +2 -2
- package/{devTui-ffjsarqa.js → devTui-q7k7bakd.js} +5 -9
- package/fileSys-5ngz93ga.js +9 -0
- package/{guideline.command-vhw13pqr.js → guideline.command-sct4qnt5.js} +4 -5
- package/guidelines/conventions/conventions.instruction.md +5 -1
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/incrementalBuilder.proc.js +30 -48
- package/{index-s5rhm04y.js → index-0bq14vr1.js} +1 -1
- package/{index-10dkrrww.js → index-13ffe9wp.js} +4 -4
- package/{index-srmay5jw.js → index-22d57v4c.js} +84 -67
- package/{index-53176s7j.js → index-31yr441d.js} +10 -17
- package/index-3hx1z96c.js +87 -0
- package/{index-4m929vvn.js → index-3sq321ak.js} +10 -18
- package/{index-bhtmj233.js → index-3t7g9e4r.js} +41 -78
- package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
- package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
- package/{index-7ep8qtvp.js → index-5pc1qrbv.js} +5 -8
- package/{index-esk82rvk.js → index-8mna0947.js} +34 -71
- package/{index-sq2dzkzm.js → index-8sf7wmdr.js} +6 -6
- package/{index-crmeqnmf.js → index-9d9bgcx4.js} +283 -722
- package/{index-bwf965h6.js → index-ahemdr5n.js} +6 -6
- package/{index-ab0c38ea.js → index-as7xmyz8.js} +20 -20
- package/{index-bc88j1ry.js → index-axzjaqve.js} +94 -142
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/{index-667w0yah.js → index-c6eggbee.js} +2 -5
- package/{index-a1w6934z.js → index-ddxvdd1p.js} +169 -305
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-22xtgmhn.js → index-dzf3r49a.js} +1 -1
- package/{index-89hy31kf.js → index-fgq75haa.js} +172 -287
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
- package/{index-vqx8bdxz.js → index-mxav6j3c.js} +78 -231
- package/{index-2446k7b4.js → index-myhc3c1j.js} +512 -588
- package/{index-3jrp517k.js → index-nv5976x3.js} +45 -128
- package/{index-zqgj2rt2.js → index-przybvy5.js} +69 -147
- package/{index-n3cv0tm4.js → index-smme4r47.js} +1 -1
- package/{index-qdgzsnhg.js → index-w2zdcw3k.js} +110 -231
- package/{index-14zrtgfa.js → index-wa5jbxj1.js} +6 -39
- package/{index-bftkz6cp.js → index-ww4z397j.js} +198 -555
- package/{index-kwaq3n9n.js → index-xqjwd384.js} +4 -7
- package/{index-txr7dj2g.js → index-xqpzbab5.js} +106 -240
- package/{index-e4v6vhxq.js → index-xsjh6nzh.js} +178 -165
- package/{index-18zybgkc.js → index-ygn77a5w.js} +47 -99
- package/{index-9d6nvkz2.js → index-ztp3e73t.js} +79 -35
- package/index.js +23 -24
- package/{library.command-cqr175dy.js → library.command-1gx04jgn.js} +4 -5
- package/{localRegistry.command-49z55qqz.js → localRegistry.command-zndxj1q6.js} +21 -42
- package/{module.command-9p8mm3b0.js → module.command-3waddk95.js} +6 -7
- package/{package.command-wxyz909t.js → package.command-zrc7br1y.js} +5 -6
- package/package.json +2 -2
- package/{page.command-gsrsfqqs.js → page.command-vpjgardh.js} +4 -5
- package/{primitive.command-ns1mptje.js → primitive.command-sz84tk4t.js} +9 -20
- package/{prompter-1f8d9pcc.js → prompter-ptaa3nk0.js} +2 -2
- package/{quality.command-e76k2q9k.js → quality.command-g869hafs.js} +129 -363
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-pkrsm3cw.js → repair.command-chsnjvvv.js} +11 -35
- package/{scalar.command-0cpt3fc8.js → scalar.command-2v21newx.js} +5 -6
- package/skills/akan-code/SKILL.md +12 -4
- package/{subspace.command-fktpwp0g.js → subspace.command-ckcbwfp1.js} +39 -58
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +3 -3
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +3 -3
- package/templates/client.ts +7 -30
- package/templates/lib/__lib/lib.dictionary.ts +0 -2
- package/templates/lib/__lib/lib.document.ts +0 -2
- package/templates/lib/sig.ts +8 -30
- package/templates/server.ts +0 -2
- package/{tunnel.command-d5jy9gk8.js → tunnel.command-kd2yr4fx.js} +5 -6
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-44252cqv.js +79 -0
- package/{workspace.command-gv84eh1p.js → workspace.command-fqcztt5p.js} +72 -107
- package/TunnelShare-2j6s511d.js +0 -9
- package/cloud.script-fwx3vb34.js +0 -20
- package/context.command-dsnw0jby.js +0 -80
- package/context.runner-rs4rj15d.js +0 -22
- package/devTuiView-1q1mdgrv.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/index-6wwzs1bc.js +0 -7
- package/workflow.command-6tkcysmx.js +0 -105
|
@@ -25,12 +25,13 @@ var scanRecipes2 = (sources) => {
|
|
|
25
25
|
const parsed = parseRecipeCall(declaration.initializer);
|
|
26
26
|
if (!parsed)
|
|
27
27
|
continue;
|
|
28
|
+
const doc = getLeadingDoc(source.content, statement);
|
|
28
29
|
recipes.push({
|
|
29
30
|
name: declaration.name.text,
|
|
30
31
|
importFrom: source.importFrom,
|
|
31
32
|
variants: parsed.variants,
|
|
32
33
|
...parsed.defaultVariants ? { defaultVariants: parsed.defaultVariants } : {},
|
|
33
|
-
...
|
|
34
|
+
...doc ? { doc } : {},
|
|
34
35
|
...parsed.base ? { base: parsed.base } : {}
|
|
35
36
|
});
|
|
36
37
|
}
|
|
@@ -1,11 +1,286 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// pkgs/@akanjs/devkit/applicationBuildReporter.ts
|
|
3
|
+
import { realpathSync } from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { Logger } from "akanjs/common";
|
|
6
|
+
|
|
7
|
+
class ApplicationBuildReporter {
|
|
8
|
+
static create() {
|
|
9
|
+
return {
|
|
10
|
+
phaseDone: (phase) => Logger.rawLog(ApplicationBuildReporter.formatPhaseLine(phase))
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
static printSummary(result) {
|
|
14
|
+
Logger.rawLog("");
|
|
15
|
+
Logger.rawLog(`Route artifacts: ${result.artifactDir}`);
|
|
16
|
+
Logger.rawLog(`Server output: ${result.outputDir}`);
|
|
17
|
+
Logger.rawLog(`Done in ${ApplicationBuildReporter.formatDuration(result.durationMs)}`);
|
|
18
|
+
}
|
|
19
|
+
static formatError(error, workspaceRoot = process.cwd()) {
|
|
20
|
+
if (error instanceof AggregateError) {
|
|
21
|
+
const nestedMessages = error.errors.map((nestedError, index) => ApplicationBuildReporter.formatError(nestedError, workspaceRoot).trim() || `Unknown error ${index + 1}`).map((message) => message.replace(/^/gm, " ")).join(`
|
|
22
|
+
`);
|
|
23
|
+
return nestedMessages ? `${error.message}
|
|
24
|
+
${nestedMessages}` : error.message;
|
|
25
|
+
}
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
const causeMessage = error.cause ? `
|
|
28
|
+
Caused by: ${ApplicationBuildReporter.formatError(error.cause, workspaceRoot)}` : "";
|
|
29
|
+
return `${ApplicationBuildReporter.#withLocation(error.message, error, workspaceRoot)}${causeMessage}`;
|
|
30
|
+
}
|
|
31
|
+
if (typeof error === "object" && error !== null && "message" in error)
|
|
32
|
+
return ApplicationBuildReporter.#withLocation(String(error.message), error, workspaceRoot);
|
|
33
|
+
return String(error);
|
|
34
|
+
}
|
|
35
|
+
static #withLocation(message, error, workspaceRoot) {
|
|
36
|
+
const { position } = error;
|
|
37
|
+
if (!position?.file)
|
|
38
|
+
return message;
|
|
39
|
+
const file = ApplicationBuildReporter.#relativeToWorkspace(position.file, workspaceRoot);
|
|
40
|
+
const location = position.line > 0 ? `${file}:${position.line}:${position.column}` : file;
|
|
41
|
+
return message.includes(location) ? message : message.replace(/^.*/, (headline) => `${headline} (${location})`);
|
|
42
|
+
}
|
|
43
|
+
static #relativeToWorkspace(file, workspaceRoot) {
|
|
44
|
+
if (!path.isAbsolute(file))
|
|
45
|
+
return file;
|
|
46
|
+
for (const root of [workspaceRoot, ApplicationBuildReporter.#realpathOf(workspaceRoot)]) {
|
|
47
|
+
const relative = path.relative(root, file);
|
|
48
|
+
if (!relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative))
|
|
49
|
+
return relative.replaceAll(path.sep, "/");
|
|
50
|
+
}
|
|
51
|
+
return file;
|
|
52
|
+
}
|
|
53
|
+
static #realpathOf(dir) {
|
|
54
|
+
try {
|
|
55
|
+
return realpathSync(dir);
|
|
56
|
+
} catch {
|
|
57
|
+
return dir;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
static formatDuration(ms) {
|
|
61
|
+
if (ms < 1000)
|
|
62
|
+
return `${ms}ms`;
|
|
63
|
+
if (ms < 60000)
|
|
64
|
+
return `${Math.round(ms / 100) / 10}s`;
|
|
65
|
+
const seconds = Math.floor(ms / 1000);
|
|
66
|
+
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
|
67
|
+
}
|
|
68
|
+
static formatPhaseLine(phase) {
|
|
69
|
+
const summary = phase.summary ? `: ${phase.summary}` : "";
|
|
70
|
+
return `\u2713 ${phase.label}${summary} (${ApplicationBuildReporter.formatDuration(phase.durationMs)})`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
2
74
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
3
75
|
import fs from "fs";
|
|
4
|
-
import
|
|
76
|
+
import path5 from "path";
|
|
5
77
|
|
|
6
78
|
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
7
|
-
import
|
|
79
|
+
import path3 from "path";
|
|
80
|
+
|
|
81
|
+
// pkgs/@akanjs/devkit/akanApp/devHostPolicy.ts
|
|
82
|
+
import path2 from "path";
|
|
83
|
+
var BACKEND_RECOVERY_MAX_ATTEMPTS = 5;
|
|
84
|
+
var HELD_BUILDER_REQUEST_LIMIT = 64;
|
|
85
|
+
var BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS = 30000;
|
|
86
|
+
var BUILDER_TIGHT_RSS_REPORT_LIMIT = 2;
|
|
87
|
+
var BUILDER_RSS_HARD_MULTIPLE = 1.5;
|
|
88
|
+
var DEV_IDLE_SUSPEND_MS = 300000;
|
|
89
|
+
var DEV_IDLE_MIN_UPTIME_MS = 30000;
|
|
8
90
|
var SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
91
|
+
var SERVER_SUFFIXES = [".service.ts", ".document.ts"];
|
|
92
|
+
var SHARED_SUFFIXES = [".constant.ts", ".dictionary.ts", ".signal.ts"];
|
|
93
|
+
var RUNTIME_METADATA_BASENAMES = new Set(["dict.ts", "sig.ts", "useClient.ts", "useServer.ts"]);
|
|
94
|
+
var shouldRestartBackendByDevPlan = (message) => {
|
|
95
|
+
if (!message.devPlan)
|
|
96
|
+
return null;
|
|
97
|
+
if (message.devPlan.actions.includes("report-error"))
|
|
98
|
+
return false;
|
|
99
|
+
if (message.devPlan.actions.includes("restart-builder"))
|
|
100
|
+
return false;
|
|
101
|
+
return message.devPlan.actions.includes("restart-backend");
|
|
102
|
+
};
|
|
103
|
+
var shouldRestartBuilderByDevPlan = (message) => message.devPlan?.actions.includes("restart-builder") ?? false;
|
|
104
|
+
var shouldAbandonBackendRecovery = (attempts, maxAttempts = BACKEND_RECOVERY_MAX_ATTEMPTS) => attempts >= maxAttempts;
|
|
105
|
+
var normalizeBackendReportedGeneration = (generation) => generation >= 0 ? generation : undefined;
|
|
106
|
+
var shouldRestartDevHostByDevPlan = (message) => message.devPlan?.actions.includes("restart-dev-host") ?? message.kinds.includes("config");
|
|
107
|
+
var devHostStateByBackendState = {
|
|
108
|
+
starting: "starting",
|
|
109
|
+
ready: "ready",
|
|
110
|
+
"restart-pending": "restarting",
|
|
111
|
+
recovering: "recovering",
|
|
112
|
+
stopping: "stopped",
|
|
113
|
+
stopped: "stopped"
|
|
114
|
+
};
|
|
115
|
+
var devHostStateOf = (state, gaveUp) => state === "stopped" && gaveUp ? "failed" : devHostStateByBackendState[state];
|
|
116
|
+
var RESTART_ROLE_ORDER = ["server", "shared", "barrel", "config"];
|
|
117
|
+
var generationValue = (generation) => generation ?? -1;
|
|
118
|
+
var isLegacyBackendFallbackFile = (file, workspaceRoot) => {
|
|
119
|
+
const abs = path2.resolve(file);
|
|
120
|
+
const ext = path2.extname(abs).toLowerCase();
|
|
121
|
+
if (!SOURCE_EXTS.has(ext))
|
|
122
|
+
return false;
|
|
123
|
+
const rel = path2.relative(path2.resolve(workspaceRoot), abs);
|
|
124
|
+
if (!rel || rel.startsWith("..") || path2.isAbsolute(rel))
|
|
125
|
+
return false;
|
|
126
|
+
const parts = rel.split(path2.sep).filter(Boolean);
|
|
127
|
+
const [scope] = parts;
|
|
128
|
+
if (scope !== "apps" && scope !== "libs" && scope !== "pkgs")
|
|
129
|
+
return false;
|
|
130
|
+
const base = path2.basename(abs);
|
|
131
|
+
return parts.includes("srvkit") || parts.includes("common") || SERVER_SUFFIXES.some((suffix) => base.endsWith(suffix)) || SHARED_SUFFIXES.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES.has(base) || base === "main.ts" || base === "server.ts";
|
|
132
|
+
};
|
|
133
|
+
var shouldMarkBuildPhaseRecovered = (previousByPhase, status) => {
|
|
134
|
+
const previous = previousByPhase.get(status.phase);
|
|
135
|
+
return Boolean(previous && status.ok && !previous.ok && generationValue(status.generation) >= previous.generation);
|
|
136
|
+
};
|
|
137
|
+
var createBackendBuildStatus = ({
|
|
138
|
+
generation,
|
|
139
|
+
ok,
|
|
140
|
+
files = [],
|
|
141
|
+
message
|
|
142
|
+
}) => ({
|
|
143
|
+
generation,
|
|
144
|
+
phase: "backend",
|
|
145
|
+
ok,
|
|
146
|
+
files,
|
|
147
|
+
message
|
|
148
|
+
});
|
|
149
|
+
var backendRestartReasonFromMessage = (message) => {
|
|
150
|
+
const roleSet = new Set;
|
|
151
|
+
for (const role of message.devPlan?.roles ?? []) {
|
|
152
|
+
if (role === "server" || role === "shared" || role === "barrel" || role === "config")
|
|
153
|
+
roleSet.add(role);
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
generation: message.devPlan?.generation ?? message.generation,
|
|
157
|
+
files: [...new Set(message.files)].sort(),
|
|
158
|
+
roles: RESTART_ROLE_ORDER.filter((role) => roleSet.has(role))
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
var mergeBackendRestartReasons = (current, next) => ({
|
|
162
|
+
generation: generationValue(next.generation) >= generationValue(current?.generation) ? next.generation : current?.generation,
|
|
163
|
+
files: [...new Set([...current?.files ?? [], ...next.files])].sort(),
|
|
164
|
+
roles: RESTART_ROLE_ORDER.filter((role) => current?.roles.includes(role) || next.roles.includes(role))
|
|
165
|
+
});
|
|
166
|
+
var shouldReplaceLastGoodMessage = (current, next) => !current || generationValue(next.data.generation) >= generationValue(current.data.generation);
|
|
167
|
+
var shouldQueueBuildStatusReplay = (backendReady, pendingReplayCount) => !backendReady || pendingReplayCount > 0;
|
|
168
|
+
var hasBuildFailureForGeneration = (statusByPhase, generation) => {
|
|
169
|
+
if (typeof generation !== "number")
|
|
170
|
+
return false;
|
|
171
|
+
for (const status of statusByPhase.values()) {
|
|
172
|
+
if (!status.ok && status.generation === generation)
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
};
|
|
177
|
+
var decideBuilderRssRecycle = ({
|
|
178
|
+
rssBytes,
|
|
179
|
+
ceilingBytes,
|
|
180
|
+
buildFailed,
|
|
181
|
+
msSinceLastRecycle,
|
|
182
|
+
minIntervalMs = BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS
|
|
183
|
+
}) => {
|
|
184
|
+
if (!ceilingBytes)
|
|
185
|
+
return "unbounded";
|
|
186
|
+
if (rssBytes < ceilingBytes)
|
|
187
|
+
return "below-ceiling";
|
|
188
|
+
if (buildFailed)
|
|
189
|
+
return "build-failed";
|
|
190
|
+
if (msSinceLastRecycle !== null && msSinceLastRecycle < minIntervalMs)
|
|
191
|
+
return "too-soon";
|
|
192
|
+
return "recycle";
|
|
193
|
+
};
|
|
194
|
+
var decideBuilderRssSettle = ({
|
|
195
|
+
rssBytes,
|
|
196
|
+
ceilingBytes,
|
|
197
|
+
hardMultiple = BUILDER_RSS_HARD_MULTIPLE
|
|
198
|
+
}) => rssBytes >= ceilingBytes * hardMultiple ? "recycle-now" : "wait-and-recheck";
|
|
199
|
+
var decideIdleSuspend = ({
|
|
200
|
+
enabled,
|
|
201
|
+
suspended,
|
|
202
|
+
builderReady,
|
|
203
|
+
backendReady,
|
|
204
|
+
buildFailed,
|
|
205
|
+
restartPending,
|
|
206
|
+
msSinceWake,
|
|
207
|
+
minUptimeMs = DEV_IDLE_MIN_UPTIME_MS
|
|
208
|
+
}) => {
|
|
209
|
+
if (!enabled)
|
|
210
|
+
return "disabled";
|
|
211
|
+
if (suspended)
|
|
212
|
+
return "already-suspended";
|
|
213
|
+
if (!builderReady)
|
|
214
|
+
return "builder-not-ready";
|
|
215
|
+
if (!backendReady)
|
|
216
|
+
return "backend-not-ready";
|
|
217
|
+
if (buildFailed)
|
|
218
|
+
return "build-failed";
|
|
219
|
+
if (restartPending)
|
|
220
|
+
return "restart-pending";
|
|
221
|
+
if (msSinceWake !== null && msSinceWake < minUptimeMs)
|
|
222
|
+
return "too-soon";
|
|
223
|
+
return "suspend";
|
|
224
|
+
};
|
|
225
|
+
var resolveIdleSuspendMs = (raw) => {
|
|
226
|
+
if (raw === undefined || raw === "")
|
|
227
|
+
return DEV_IDLE_SUSPEND_MS;
|
|
228
|
+
const parsed = Number(raw);
|
|
229
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
230
|
+
return null;
|
|
231
|
+
return Math.round(parsed);
|
|
232
|
+
};
|
|
233
|
+
var hasAnyBuildFailure = (statusByPhase) => [...statusByPhase.values()].some((status) => !status.ok);
|
|
234
|
+
var shouldRefreshConfigOnIdleWake = (batch) => !!batch && batch.kinds.has("config");
|
|
235
|
+
var RETURNING_BUILDER_STATUSES = new Set(["starting", "recycling", "restarting"]);
|
|
236
|
+
var shouldHoldForReturningBuilder = ({
|
|
237
|
+
status,
|
|
238
|
+
heldCount,
|
|
239
|
+
limit = HELD_BUILDER_REQUEST_LIMIT
|
|
240
|
+
}) => RETURNING_BUILDER_STATUSES.has(status) && heldCount < limit;
|
|
241
|
+
var shouldWarnBuilderRssCeilingTight = (reportsSinceRecycle, limit = BUILDER_TIGHT_RSS_REPORT_LIMIT) => reportsSinceRecycle >= limit;
|
|
242
|
+
var isRssCeilingUnreachable = (freshRssBytes, ceilingBytes) => freshRssBytes !== null && ceilingBytes !== null && freshRssBytes >= ceilingBytes;
|
|
243
|
+
var shouldRelayRecycledFrontendState = (current, next) => {
|
|
244
|
+
if (!current || current.type !== next.type)
|
|
245
|
+
return true;
|
|
246
|
+
if (current.type === "pages-updated" && next.type === "pages-updated")
|
|
247
|
+
return current.data.bundlePath !== next.data.bundlePath;
|
|
248
|
+
if (current.type === "css-updated" && next.type === "css-updated")
|
|
249
|
+
return JSON.stringify(current.data.cssAssets) !== JSON.stringify(next.data.cssAssets);
|
|
250
|
+
return true;
|
|
251
|
+
};
|
|
252
|
+
var mergeDevPlans = (current, next) => {
|
|
253
|
+
if (!current)
|
|
254
|
+
return next;
|
|
255
|
+
if (!next)
|
|
256
|
+
return current;
|
|
257
|
+
const reasonByFile = { ...current.reasonByFile };
|
|
258
|
+
for (const [file, reasons] of Object.entries(next.reasonByFile)) {
|
|
259
|
+
reasonByFile[file] = [...new Set([...reasonByFile[file] ?? [], ...reasons])].sort();
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
generation: Math.max(current.generation, next.generation),
|
|
263
|
+
files: [...new Set([...current.files, ...next.files])].sort(),
|
|
264
|
+
generatedFiles: [...new Set([...current.generatedFiles, ...next.generatedFiles])].sort(),
|
|
265
|
+
roles: [...new Set([...current.roles, ...next.roles])].sort(),
|
|
266
|
+
actions: [...new Set([...current.actions, ...next.actions])].sort(),
|
|
267
|
+
reasonByFile
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
var mergeInvalidateMessages = (current, next) => {
|
|
271
|
+
const generation = Math.max(generationValue(current.generation), generationValue(next.generation));
|
|
272
|
+
return {
|
|
273
|
+
type: "invalidate",
|
|
274
|
+
kinds: [...new Set([...current.kinds, ...next.kinds])].sort(),
|
|
275
|
+
files: [...new Set([...current.files, ...next.files])].sort(),
|
|
276
|
+
generation: generation >= 0 ? generation : undefined,
|
|
277
|
+
devPlan: mergeDevPlans(current.devPlan, next.devPlan)
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
var buildStatusReplaySequence = (pendingReplay, latestByPhase) => [...pendingReplay, ...latestByPhase.values()];
|
|
281
|
+
var filesChangedSince = (before, after) => [...before].filter(([file, stamp]) => after.get(file) !== stamp).map(([file]) => file);
|
|
282
|
+
|
|
283
|
+
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
9
284
|
var CSS_EXTS = new Set([".css"]);
|
|
10
285
|
var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
11
286
|
|
|
@@ -13,10 +288,10 @@ class HmrChangeClassifier {
|
|
|
13
288
|
classify(abs) {
|
|
14
289
|
if (this.#isUninteresting(abs))
|
|
15
290
|
return "ignore";
|
|
16
|
-
const base =
|
|
291
|
+
const base = path3.basename(abs);
|
|
17
292
|
if (CONFIG_BASENAMES.has(base))
|
|
18
293
|
return "config";
|
|
19
|
-
const ext =
|
|
294
|
+
const ext = path3.extname(abs).toLowerCase();
|
|
20
295
|
if (CSS_EXTS.has(ext))
|
|
21
296
|
return "css";
|
|
22
297
|
if (SOURCE_EXTS.has(ext))
|
|
@@ -24,16 +299,16 @@ class HmrChangeClassifier {
|
|
|
24
299
|
return "ignore";
|
|
25
300
|
}
|
|
26
301
|
#isUninteresting(abs) {
|
|
27
|
-
const base =
|
|
302
|
+
const base = path3.basename(abs);
|
|
28
303
|
if (!base)
|
|
29
304
|
return true;
|
|
30
305
|
if (base.startsWith("."))
|
|
31
306
|
return true;
|
|
32
307
|
if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
|
|
33
308
|
return true;
|
|
34
|
-
if (abs.includes(`${
|
|
309
|
+
if (abs.includes(`${path3.sep}node_modules${path3.sep}`))
|
|
35
310
|
return true;
|
|
36
|
-
if (abs.includes(`${
|
|
311
|
+
if (abs.includes(`${path3.sep}.akan${path3.sep}`))
|
|
37
312
|
return true;
|
|
38
313
|
return false;
|
|
39
314
|
}
|
|
@@ -41,7 +316,7 @@ class HmrChangeClassifier {
|
|
|
41
316
|
|
|
42
317
|
// pkgs/@akanjs/devkit/frontendBuild/sourceMtimeIndex.ts
|
|
43
318
|
import { readdir, stat } from "fs/promises";
|
|
44
|
-
import
|
|
319
|
+
import path4 from "path";
|
|
45
320
|
var UNREADABLE = Number.NaN;
|
|
46
321
|
|
|
47
322
|
class SourceMtimeIndex {
|
|
@@ -104,7 +379,7 @@ class SourceMtimeIndex {
|
|
|
104
379
|
if (!this.#primed)
|
|
105
380
|
return;
|
|
106
381
|
await Promise.all(paths.map(async (file) => {
|
|
107
|
-
const abs =
|
|
382
|
+
const abs = path4.resolve(file);
|
|
108
383
|
const stats = await stat(abs).catch(() => null);
|
|
109
384
|
if (!stats?.isFile()) {
|
|
110
385
|
this.#files.delete(abs);
|
|
@@ -190,7 +465,7 @@ class SourceMtimeIndex {
|
|
|
190
465
|
for (const entry of entries) {
|
|
191
466
|
if (SourceMtimeIndex.#skipDirent(entry.name))
|
|
192
467
|
continue;
|
|
193
|
-
const abs =
|
|
468
|
+
const abs = path4.join(dir, entry.name);
|
|
194
469
|
if (entry.isDirectory()) {
|
|
195
470
|
descend.push(abs);
|
|
196
471
|
continue;
|
|
@@ -217,7 +492,7 @@ class SourceMtimeIndex {
|
|
|
217
492
|
}
|
|
218
493
|
if (known) {
|
|
219
494
|
for (const abs of [...this.#files.keys()]) {
|
|
220
|
-
if (present.has(abs) ||
|
|
495
|
+
if (present.has(abs) || path4.dirname(abs) !== dir)
|
|
221
496
|
continue;
|
|
222
497
|
this.#files.delete(abs);
|
|
223
498
|
changed?.add(abs);
|
|
@@ -235,7 +510,7 @@ class SourceMtimeIndex {
|
|
|
235
510
|
this.#unsettled.delete(dir);
|
|
236
511
|
}
|
|
237
512
|
#forget(dir) {
|
|
238
|
-
const prefix = `${dir}${
|
|
513
|
+
const prefix = `${dir}${path4.sep}`;
|
|
239
514
|
this.#dirs.delete(dir);
|
|
240
515
|
this.#unreadable.delete(dir);
|
|
241
516
|
this.#unsettled.delete(dir);
|
|
@@ -273,8 +548,8 @@ class SourceMtimeIndex {
|
|
|
273
548
|
return !name || name.startsWith(".") || name === "node_modules";
|
|
274
549
|
}
|
|
275
550
|
static #pruneNestedRoots(roots) {
|
|
276
|
-
const resolved = [...new Set(roots.map((root) =>
|
|
277
|
-
return resolved.filter((root) => !resolved.some((other) => other !== root && root.startsWith(`${other}${
|
|
551
|
+
const resolved = [...new Set(roots.map((root) => path4.resolve(root)))].sort();
|
|
552
|
+
return resolved.filter((root) => !resolved.some((other) => other !== root && root.startsWith(`${other}${path4.sep}`)));
|
|
278
553
|
}
|
|
279
554
|
}
|
|
280
555
|
|
|
@@ -298,7 +573,7 @@ class HmrWatcher {
|
|
|
298
573
|
#reportedCompensating = false;
|
|
299
574
|
#reportedGaps = "";
|
|
300
575
|
constructor(opts) {
|
|
301
|
-
this.#roots = [...new Set(opts.roots.map((r) =>
|
|
576
|
+
this.#roots = [...new Set(opts.roots.map((r) => path5.resolve(r)))];
|
|
302
577
|
this.#debounceMs = opts.debounceMs ?? 80;
|
|
303
578
|
this.#verifyDelayMs = opts.verifyDelayMs ?? 250;
|
|
304
579
|
this.#onBatch = opts.onBatch;
|
|
@@ -314,7 +589,7 @@ class HmrWatcher {
|
|
|
314
589
|
const w = fs.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
315
590
|
if (!filename)
|
|
316
591
|
return;
|
|
317
|
-
const abs =
|
|
592
|
+
const abs = path5.resolve(root, filename.toString());
|
|
318
593
|
this.#queue(abs);
|
|
319
594
|
});
|
|
320
595
|
this.#watchers.push(w);
|
|
@@ -464,7 +739,7 @@ class HmrWatcher {
|
|
|
464
739
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
465
740
|
import fs2 from "fs";
|
|
466
741
|
import { readFile } from "fs/promises";
|
|
467
|
-
import
|
|
742
|
+
import path6 from "path";
|
|
468
743
|
|
|
469
744
|
class WatchRootResolver {
|
|
470
745
|
#app;
|
|
@@ -473,20 +748,20 @@ class WatchRootResolver {
|
|
|
473
748
|
}
|
|
474
749
|
async resolve() {
|
|
475
750
|
const tsconfig = await this.#app.getTsConfig();
|
|
476
|
-
const appDir =
|
|
477
|
-
const appsContainer =
|
|
478
|
-
const libsContainer =
|
|
479
|
-
const libRoots = await this.#
|
|
751
|
+
const appDir = path6.resolve(this.#app.cwdPath);
|
|
752
|
+
const appsContainer = path6.dirname(appDir);
|
|
753
|
+
const libsContainer = path6.resolve(this.#app.workspace.workspaceRoot, "libs");
|
|
754
|
+
const libRoots = (await this.#resolveLibDeps(libsContainer))?.map((name) => path6.join(libsContainer, name)).filter((dir) => fs2.existsSync(dir));
|
|
480
755
|
const set = new Set;
|
|
481
|
-
set.add(
|
|
756
|
+
set.add(path6.resolve(`${this.#app.cwdPath}/page`));
|
|
482
757
|
for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
|
|
483
758
|
for (const target of targets) {
|
|
484
759
|
if (!target)
|
|
485
760
|
continue;
|
|
486
|
-
if (
|
|
761
|
+
if (path6.isAbsolute(target))
|
|
487
762
|
continue;
|
|
488
763
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
489
|
-
const resolved =
|
|
764
|
+
const resolved = path6.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
490
765
|
if (resolved === libsContainer && libRoots) {
|
|
491
766
|
for (const root of libRoots)
|
|
492
767
|
set.add(root);
|
|
@@ -499,17 +774,11 @@ class WatchRootResolver {
|
|
|
499
774
|
}
|
|
500
775
|
return [...set];
|
|
501
776
|
}
|
|
502
|
-
async#resolveLibRoots(libsContainer) {
|
|
503
|
-
const libDeps = await this.#resolveLibDeps(libsContainer);
|
|
504
|
-
if (!libDeps)
|
|
505
|
-
return null;
|
|
506
|
-
return libDeps.map((name) => path4.join(libsContainer, name)).filter((dir) => fs2.existsSync(dir));
|
|
507
|
-
}
|
|
508
777
|
async#resolveLibDeps(libsContainer) {
|
|
509
778
|
const scanInfo = this.#app.getScanInfo({ allowEmpty: true });
|
|
510
779
|
if (scanInfo?.type === "app")
|
|
511
780
|
return scanInfo.libDeps;
|
|
512
|
-
const direct = await WatchRootResolver.#readManifestLibDeps(
|
|
781
|
+
const direct = await WatchRootResolver.#readManifestLibDeps(path6.join(this.#app.cwdPath, "akan.app.json"));
|
|
513
782
|
if (!direct)
|
|
514
783
|
return null;
|
|
515
784
|
const closure = new Set;
|
|
@@ -519,7 +788,7 @@ class WatchRootResolver {
|
|
|
519
788
|
if (!name || closure.has(name))
|
|
520
789
|
continue;
|
|
521
790
|
closure.add(name);
|
|
522
|
-
const nested = await WatchRootResolver.#readManifestLibDeps(
|
|
791
|
+
const nested = await WatchRootResolver.#readManifestLibDeps(path6.join(libsContainer, name, "akan.lib.json"));
|
|
523
792
|
if (!nested)
|
|
524
793
|
return null;
|
|
525
794
|
queue.push(...nested);
|
|
@@ -538,4 +807,4 @@ class WatchRootResolver {
|
|
|
538
807
|
}
|
|
539
808
|
}
|
|
540
809
|
|
|
541
|
-
export { HmrWatcher, WatchRootResolver };
|
|
810
|
+
export { ApplicationBuildReporter, BUILDER_MIN_RSS_RECYCLE_INTERVAL_MS, SOURCE_EXTS, shouldRestartBackendByDevPlan, shouldRestartBuilderByDevPlan, shouldAbandonBackendRecovery, normalizeBackendReportedGeneration, shouldRestartDevHostByDevPlan, devHostStateOf, isLegacyBackendFallbackFile, shouldMarkBuildPhaseRecovered, createBackendBuildStatus, backendRestartReasonFromMessage, mergeBackendRestartReasons, shouldReplaceLastGoodMessage, shouldQueueBuildStatusReplay, hasBuildFailureForGeneration, decideBuilderRssRecycle, decideBuilderRssSettle, decideIdleSuspend, resolveIdleSuspendMs, hasAnyBuildFailure, shouldRefreshConfigOnIdleWake, shouldHoldForReturningBuilder, shouldWarnBuilderRssCeilingTight, isRssCeilingUnreachable, shouldRelayRecycledFrontendState, mergeInvalidateMessages, buildStatusReplaySequence, filesChangedSince, HmrWatcher, WatchRootResolver };
|