@absolutejs/absolute 0.19.0-beta.1028 → 0.19.0-beta.1029
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/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +186 -12
- package/dist/src/cli/discoverInstances.d.ts +5 -0
- package/dist/src/utils/portScan.d.ts +22 -0
- package/dist/types/cli.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-Ye9d69/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-Ye9d69/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
48
48
|
getWarningController()?.maybeWarn(primitiveName);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
// .angular-partial-tmp-
|
|
51
|
+
// .angular-partial-tmp-Ye9d69/src/core/streamingSlotRegistry.ts
|
|
52
52
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
53
53
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
54
54
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
package/dist/cli/index.js
CHANGED
|
@@ -652,8 +652,99 @@ var init_loadConfig = __esm(() => {
|
|
|
652
652
|
]);
|
|
653
653
|
});
|
|
654
654
|
|
|
655
|
-
// src/
|
|
655
|
+
// src/utils/portScan.ts
|
|
656
656
|
var {$ } = globalThis.Bun;
|
|
657
|
+
var parsePort = (address) => {
|
|
658
|
+
const match = address.replace(/\(LISTEN\)$/, "").match(/:(\d+)$/);
|
|
659
|
+
return match ? Number(match[1]) : null;
|
|
660
|
+
}, parseLsof = (text) => {
|
|
661
|
+
const seen = new Set;
|
|
662
|
+
const listeners = [];
|
|
663
|
+
for (const line of text.split(`
|
|
664
|
+
`)) {
|
|
665
|
+
if (line.length === 0 || line.startsWith("COMMAND"))
|
|
666
|
+
continue;
|
|
667
|
+
const tokens = line.trim().split(/\s+/);
|
|
668
|
+
const [, pidText] = tokens;
|
|
669
|
+
const pid = Number(pidText);
|
|
670
|
+
const address = tokens.find((token) => /:\d+$/.test(token));
|
|
671
|
+
const port = address ? parsePort(address) : null;
|
|
672
|
+
if (!Number.isInteger(pid) || port === null)
|
|
673
|
+
continue;
|
|
674
|
+
const key = `${pid}:${port}`;
|
|
675
|
+
if (seen.has(key))
|
|
676
|
+
continue;
|
|
677
|
+
seen.add(key);
|
|
678
|
+
listeners.push({ pid, port });
|
|
679
|
+
}
|
|
680
|
+
return listeners;
|
|
681
|
+
}, parseSs = (text) => {
|
|
682
|
+
const seen = new Set;
|
|
683
|
+
const listeners = [];
|
|
684
|
+
for (const line of text.split(`
|
|
685
|
+
`)) {
|
|
686
|
+
if (line.trim().length === 0)
|
|
687
|
+
continue;
|
|
688
|
+
const [, , , local] = line.trim().split(/\s+/);
|
|
689
|
+
const port = local ? parsePort(local) : null;
|
|
690
|
+
const pidMatch = line.match(/pid=(\d+)/);
|
|
691
|
+
if (port === null || !pidMatch)
|
|
692
|
+
continue;
|
|
693
|
+
const pid = Number(pidMatch[1]);
|
|
694
|
+
const key = `${pid}:${port}`;
|
|
695
|
+
if (seen.has(key))
|
|
696
|
+
continue;
|
|
697
|
+
seen.add(key);
|
|
698
|
+
listeners.push({ pid, port });
|
|
699
|
+
}
|
|
700
|
+
return listeners;
|
|
701
|
+
}, rawListeners = async () => {
|
|
702
|
+
const lsof = await $`lsof -nP -iTCP -sTCP:LISTEN`.quiet().nothrow().text();
|
|
703
|
+
if (lsof.trim().length > 0)
|
|
704
|
+
return parseLsof(lsof);
|
|
705
|
+
const ssOutput = await $`ss -ltnpH`.quiet().nothrow().text();
|
|
706
|
+
if (ssOutput.trim().length > 0)
|
|
707
|
+
return parseSs(ssOutput);
|
|
708
|
+
return [];
|
|
709
|
+
}, describeProcesses = async (pids) => {
|
|
710
|
+
const details = new Map;
|
|
711
|
+
if (pids.length === 0)
|
|
712
|
+
return details;
|
|
713
|
+
const output = await $`ps -o pid=,etimes=,args= -p ${pids.join(",")}`.quiet().nothrow().text();
|
|
714
|
+
for (const line of output.split(`
|
|
715
|
+
`)) {
|
|
716
|
+
const trimmed = line.trim();
|
|
717
|
+
if (trimmed.length === 0)
|
|
718
|
+
continue;
|
|
719
|
+
const match = trimmed.match(/^(\d+)\s+(\d+)\s+(.*)$/);
|
|
720
|
+
if (!match)
|
|
721
|
+
continue;
|
|
722
|
+
const [, pidText, etimesText, command = ""] = match;
|
|
723
|
+
details.set(Number(pidText), { command, etimes: Number(etimesText) });
|
|
724
|
+
}
|
|
725
|
+
return details;
|
|
726
|
+
}, scanListeners = async () => {
|
|
727
|
+
const listeners = await rawListeners();
|
|
728
|
+
const pids = [...new Set(listeners.map((listener) => listener.pid))].filter((pid) => pid !== process.pid && pid > 0);
|
|
729
|
+
const details = await describeProcesses(pids);
|
|
730
|
+
return listeners.flatMap((listener) => {
|
|
731
|
+
const detail = details.get(listener.pid);
|
|
732
|
+
if (!detail)
|
|
733
|
+
return [];
|
|
734
|
+
return [
|
|
735
|
+
{
|
|
736
|
+
command: detail.command,
|
|
737
|
+
etimes: detail.etimes,
|
|
738
|
+
pid: listener.pid,
|
|
739
|
+
port: listener.port
|
|
740
|
+
}
|
|
741
|
+
];
|
|
742
|
+
});
|
|
743
|
+
};
|
|
744
|
+
var init_portScan = () => {};
|
|
745
|
+
|
|
746
|
+
// src/cli/utils.ts
|
|
747
|
+
var {$: $2 } = globalThis.Bun;
|
|
657
748
|
import { execSync } from "child_process";
|
|
658
749
|
import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
|
|
659
750
|
import { resolve as resolve2 } from "path";
|
|
@@ -745,14 +836,14 @@ var COMPOSE_PATH = "db/docker-compose.db.yml", DEFAULT_SERVER_ENTRY = "src/backe
|
|
|
745
836
|
return { downCommand, upCommand };
|
|
746
837
|
}, startDatabase = async (scripts) => {
|
|
747
838
|
await timed("Starting database container...", async () => {
|
|
748
|
-
const { exitCode } = await
|
|
839
|
+
const { exitCode } = await $2`${{ raw: scripts.upCommand }}`.quiet().nothrow();
|
|
749
840
|
if (exitCode !== 0)
|
|
750
841
|
process.exit(exitCode);
|
|
751
842
|
});
|
|
752
843
|
}, stopDatabase = async (scripts) => {
|
|
753
844
|
console.log(`
|
|
754
845
|
Stopping database container...`);
|
|
755
|
-
await
|
|
846
|
+
await $2`${{ raw: scripts.downCommand }}`.quiet().nothrow();
|
|
756
847
|
}, timed = async (label, task) => {
|
|
757
848
|
process.stdout.write(label);
|
|
758
849
|
const start = performance.now();
|
|
@@ -170767,6 +170858,62 @@ var init_build = __esm(() => {
|
|
|
170767
170858
|
init_telemetryEvent();
|
|
170768
170859
|
});
|
|
170769
170860
|
|
|
170861
|
+
// src/cli/discoverInstances.ts
|
|
170862
|
+
var MS_PER_SECOND = 1000, isJsRuntime = (command) => /\b(bun|deno|node)\b/.test(command), untrackedName = (command) => {
|
|
170863
|
+
const entry = command.split(/\s+/).find((token) => /\.(cjs|js|mjs|ts)$/.test(token));
|
|
170864
|
+
if (entry === undefined)
|
|
170865
|
+
return "untracked";
|
|
170866
|
+
const segments = entry.split("/").filter(Boolean);
|
|
170867
|
+
segments.pop();
|
|
170868
|
+
let dir = segments.pop();
|
|
170869
|
+
if (dir === "build" || dir === "dist" || dir === "src")
|
|
170870
|
+
dir = segments.pop();
|
|
170871
|
+
return dir ?? "untracked";
|
|
170872
|
+
}, toUntrackedRecord = (listener) => ({
|
|
170873
|
+
command: listener.command.split(/\s+/),
|
|
170874
|
+
configPath: null,
|
|
170875
|
+
controllerPid: listener.pid,
|
|
170876
|
+
cwd: "",
|
|
170877
|
+
frameworks: [],
|
|
170878
|
+
host: "localhost",
|
|
170879
|
+
https: false,
|
|
170880
|
+
logFile: null,
|
|
170881
|
+
name: untrackedName(listener.command),
|
|
170882
|
+
pid: listener.pid,
|
|
170883
|
+
port: listener.port,
|
|
170884
|
+
ppid: 0,
|
|
170885
|
+
source: "untracked",
|
|
170886
|
+
startedAt: new Date(Date.now() - listener.etimes * MS_PER_SECOND).toISOString()
|
|
170887
|
+
}), compareInstances2 = (left, right) => {
|
|
170888
|
+
const leftPort = left.port ?? Number.MAX_SAFE_INTEGER;
|
|
170889
|
+
const rightPort = right.port ?? Number.MAX_SAFE_INTEGER;
|
|
170890
|
+
if (leftPort !== rightPort)
|
|
170891
|
+
return leftPort - rightPort;
|
|
170892
|
+
return left.name.localeCompare(right.name);
|
|
170893
|
+
}, discoverInstances = async () => {
|
|
170894
|
+
const registered = listLiveInstances();
|
|
170895
|
+
const knownPids = new Set(registered.flatMap((record) => [record.pid, record.controllerPid]));
|
|
170896
|
+
const knownPorts = new Set(registered.map((record) => record.port).filter((port) => port !== null));
|
|
170897
|
+
const listeners = await scanListeners();
|
|
170898
|
+
const untracked = [];
|
|
170899
|
+
const seen = new Set;
|
|
170900
|
+
for (const listener of listeners) {
|
|
170901
|
+
if (knownPids.has(listener.pid) || seen.has(listener.pid))
|
|
170902
|
+
continue;
|
|
170903
|
+
if (knownPorts.has(listener.port))
|
|
170904
|
+
continue;
|
|
170905
|
+
if (!isJsRuntime(listener.command))
|
|
170906
|
+
continue;
|
|
170907
|
+
seen.add(listener.pid);
|
|
170908
|
+
untracked.push(toUntrackedRecord(listener));
|
|
170909
|
+
}
|
|
170910
|
+
return [...registered, ...untracked].sort(compareInstances2);
|
|
170911
|
+
};
|
|
170912
|
+
var init_discoverInstances = __esm(() => {
|
|
170913
|
+
init_instanceRegistry();
|
|
170914
|
+
init_portScan();
|
|
170915
|
+
});
|
|
170916
|
+
|
|
170770
170917
|
// src/cli/instanceStatus.ts
|
|
170771
170918
|
import { createConnection as createConnection2 } from "net";
|
|
170772
170919
|
var displayHost = (host) => host === "0.0.0.0" || host === "::" ? "localhost" : host, probePort = (host, port) => {
|
|
@@ -170908,7 +171055,7 @@ var TUI_HEADERS, STATUS_INDEX = 5, URL_INDEX = 6, helpLines2, statusLevelColor =
|
|
|
170908
171055
|
};
|
|
170909
171056
|
const refresh = async () => {
|
|
170910
171057
|
const previousPid = selectedInstance()?.pid;
|
|
170911
|
-
instances = await enrichInstances(
|
|
171058
|
+
instances = await enrichInstances(await discoverInstances());
|
|
170912
171059
|
const foundIndex = previousPid === undefined ? 0 : instances.findIndex((instance) => instance.pid === previousPid);
|
|
170913
171060
|
selectedIndex = foundIndex >= 0 ? foundIndex : Math.min(selectedIndex, Math.max(0, instances.length - 1));
|
|
170914
171061
|
scheduleRender();
|
|
@@ -171309,7 +171456,7 @@ var TUI_HEADERS, STATUS_INDEX = 5, URL_INDEX = 6, helpLines2, statusLevelColor =
|
|
|
171309
171456
|
var init_listTui = __esm(() => {
|
|
171310
171457
|
init_constants();
|
|
171311
171458
|
init_getDurationString();
|
|
171312
|
-
|
|
171459
|
+
init_discoverInstances();
|
|
171313
171460
|
init_instanceStatus();
|
|
171314
171461
|
init_tuiPrimitives();
|
|
171315
171462
|
init_utils();
|
|
@@ -171341,7 +171488,14 @@ var exports_list = {};
|
|
|
171341
171488
|
__export(exports_list, {
|
|
171342
171489
|
runList: () => runList
|
|
171343
171490
|
});
|
|
171344
|
-
var
|
|
171491
|
+
var killPid = (pid) => {
|
|
171492
|
+
try {
|
|
171493
|
+
process.kill(pid, "SIGTERM");
|
|
171494
|
+
return true;
|
|
171495
|
+
} catch {
|
|
171496
|
+
return false;
|
|
171497
|
+
}
|
|
171498
|
+
}, TABLE_HEADERS, statusColor2 = (status2) => {
|
|
171345
171499
|
if (status2 === "ready")
|
|
171346
171500
|
return colors.green;
|
|
171347
171501
|
if (status2 === "starting")
|
|
@@ -171380,7 +171534,24 @@ var TABLE_HEADERS, statusColor2 = (status2) => {
|
|
|
171380
171534
|
await runListTui2();
|
|
171381
171535
|
return;
|
|
171382
171536
|
}
|
|
171383
|
-
const instances = await enrichInstances(
|
|
171537
|
+
const instances = await enrichInstances(await discoverInstances());
|
|
171538
|
+
if (args.includes("--kill-all")) {
|
|
171539
|
+
const killed = instances.filter((instance) => killPid(instance.pid));
|
|
171540
|
+
process.stdout.write(`${colors.dim}Killed ${killed.length} server${killed.length === 1 ? "" : "s"}.${colors.reset}
|
|
171541
|
+
`);
|
|
171542
|
+
return;
|
|
171543
|
+
}
|
|
171544
|
+
if (args.includes("--kill")) {
|
|
171545
|
+
const value = args[args.indexOf("--kill") + 1];
|
|
171546
|
+
const target = Number(value);
|
|
171547
|
+
const match = instances.find((instance) => instance.pid === target || instance.port === target);
|
|
171548
|
+
const pid = match?.pid ?? target;
|
|
171549
|
+
const killed = Number.isInteger(pid) && killPid(pid);
|
|
171550
|
+
const label = match ? `${match.name} (pid ${pid}${match.port === null ? "" : `, port ${match.port}`})` : `pid ${pid}`;
|
|
171551
|
+
process.stdout.write(`${colors.dim}${killed ? `Killed ${label}` : `No server found for \`--kill ${value ?? ""}\``}.${colors.reset}
|
|
171552
|
+
`);
|
|
171553
|
+
return;
|
|
171554
|
+
}
|
|
171384
171555
|
if (args.includes("--json")) {
|
|
171385
171556
|
process.stdout.write(`${JSON.stringify(instances, null, 2)}
|
|
171386
171557
|
`);
|
|
@@ -171391,7 +171562,7 @@ var TABLE_HEADERS, statusColor2 = (status2) => {
|
|
|
171391
171562
|
var init_list = __esm(() => {
|
|
171392
171563
|
init_constants();
|
|
171393
171564
|
init_getDurationString();
|
|
171394
|
-
|
|
171565
|
+
init_discoverInstances();
|
|
171395
171566
|
init_instanceStatus();
|
|
171396
171567
|
init_tuiPrimitives();
|
|
171397
171568
|
TABLE_HEADERS = [
|
|
@@ -172854,7 +173025,7 @@ var init_tunnelRelay = __esm(() => {
|
|
|
172854
173025
|
|
|
172855
173026
|
// src/cli/scripts/dev.ts
|
|
172856
173027
|
init_constants();
|
|
172857
|
-
var {$: $
|
|
173028
|
+
var {$: $3, env } = globalThis.Bun;
|
|
172858
173029
|
import { spawn as nodeSpawn } from "child_process";
|
|
172859
173030
|
import { createWriteStream, existsSync as existsSync5, readFileSync as readFileSync7 } from "fs";
|
|
172860
173031
|
import { resolve as resolve3 } from "path";
|
|
@@ -173287,6 +173458,7 @@ init_telemetryEvent();
|
|
|
173287
173458
|
init_buildDirectoryLock();
|
|
173288
173459
|
init_instanceRegistry();
|
|
173289
173460
|
init_loadConfig();
|
|
173461
|
+
init_portScan();
|
|
173290
173462
|
|
|
173291
173463
|
// src/utils/resolveDevPort.ts
|
|
173292
173464
|
import { createServer } from "net";
|
|
@@ -173435,7 +173607,9 @@ var dev = async (serverEntry, configPath2) => {
|
|
|
173435
173607
|
let { port } = initialPortProbe;
|
|
173436
173608
|
if (initialPortProbe.fellBack) {
|
|
173437
173609
|
const displayHost = resolvedDev.host === "0.0.0.0" ? "localhost" : resolvedDev.host;
|
|
173438
|
-
|
|
173610
|
+
const holders = (await scanListeners()).filter((listener) => listener.port === resolvedDev.port);
|
|
173611
|
+
const heldBy = holders.length > 0 ? ` (held by ${holders.map((holder) => `pid ${holder.pid} \u2014 ${holder.command.slice(0, 60)}`).join(", ")})` : "";
|
|
173612
|
+
console.log(cliTag("\x1B[33m", `Port ${resolvedDev.port} is in use${heldBy}, trying another one... \u2192 http://${displayHost}:${port}/`));
|
|
173439
173613
|
}
|
|
173440
173614
|
updateLockMetadata(buildDirectory, { port });
|
|
173441
173615
|
const instancePid = process.pid;
|
|
@@ -173835,7 +174009,7 @@ var dev = async (serverEntry, configPath2) => {
|
|
|
173835
174009
|
}
|
|
173836
174010
|
};
|
|
173837
174011
|
const runShellCommand2 = async (command) => {
|
|
173838
|
-
await $
|
|
174012
|
+
await $3`${{ raw: command }}`.env({ ...process.env, FORCE_COLOR: "1" }).nothrow();
|
|
173839
174013
|
};
|
|
173840
174014
|
const openInBrowser = async () => {
|
|
173841
174015
|
const url = `http://${resolvedDev.host === "0.0.0.0" ? "localhost" : resolvedDev.host}:${port}`;
|
|
@@ -176290,7 +176464,7 @@ if (command === "dev") {
|
|
|
176290
176464
|
console.error(" config [--port n] Open the unified config UI (ESLint, tsconfig, Prettier)");
|
|
176291
176465
|
console.error(" eslint Run ESLint (cached)");
|
|
176292
176466
|
console.error(" info Print system info for bug reports");
|
|
176293
|
-
console.error(" ls [--watch] [--json] List/manage running servers (alias: ps)");
|
|
176467
|
+
console.error(" ls [--watch] [--json] [--kill <pid|port>] [--kill-all] List/manage running servers (alias: ps)");
|
|
176294
176468
|
console.error(" prettier Run Prettier check (cached)");
|
|
176295
176469
|
console.error(" typecheck Run type checkers for all frameworks");
|
|
176296
176470
|
console.error(" telemetry Manage anonymous telemetry");
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { InstanceRecord } from '../../types/cli';
|
|
2
|
+
/** Registry-tracked instances unioned with any JS server listening on a port
|
|
3
|
+
* that the registry doesn't know about — so `absolute ps` shows orphans
|
|
4
|
+
* (dead controllers, hand-run builds) the file registry alone would miss. */
|
|
5
|
+
export declare const discoverInstances: () => Promise<InstanceRecord[]>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Process/port discovery for `absolute ps`, used to surface running servers
|
|
2
|
+
* the file-based instance registry can miss — orphans whose controller died,
|
|
3
|
+
* hand-run `bun dist/server.js` builds, anything that never registered.
|
|
4
|
+
*
|
|
5
|
+
* Shells out via Bun's `$` to the platform's socket lister (lsof, falling
|
|
6
|
+
* back to ss on Linux) rather than trusting a registry file, so a live
|
|
7
|
+
* listener is discoverable for as long as its process is alive. */
|
|
8
|
+
export type PortListener = {
|
|
9
|
+
command: string;
|
|
10
|
+
etimes: number;
|
|
11
|
+
pid: number;
|
|
12
|
+
port: number;
|
|
13
|
+
};
|
|
14
|
+
/** Listening TCP servers on the machine, each annotated with the owning
|
|
15
|
+
* process's full command and uptime. Skips this process and any listener
|
|
16
|
+
* whose owner we can't describe. */
|
|
17
|
+
export declare const scanListeners: () => Promise<{
|
|
18
|
+
command: string;
|
|
19
|
+
etimes: number;
|
|
20
|
+
pid: number;
|
|
21
|
+
port: number;
|
|
22
|
+
}[]>;
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export type InstanceRecord = {
|
|
|
28
28
|
source: InstanceSource;
|
|
29
29
|
startedAt: string;
|
|
30
30
|
};
|
|
31
|
-
export type InstanceSource = 'compiled' | 'dev' | 'standalone' | 'start' | 'workspace';
|
|
31
|
+
export type InstanceSource = 'compiled' | 'dev' | 'standalone' | 'start' | 'untracked' | 'workspace';
|
|
32
32
|
export type InstanceStatus = 'ready' | 'starting' | 'stopped';
|
|
33
33
|
export type InteractiveHandler = {
|
|
34
34
|
clearPrompt: () => void;
|
package/package.json
CHANGED