plgg-bundle 0.0.1 → 0.0.3
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/bin/hook.d.mts +20 -0
- package/bin/hook.mjs +11 -2
- package/bin/plgg-bundle.mjs +9 -0
- package/bin/relocate.mjs +108 -0
- package/package.json +2 -5
- package/src/Dev/fixtures/aliasDir/index.ts +6 -0
- package/src/Dev/node/devServer.ts +5 -5
- package/src/Dev/node/httpAdapter.ts +1 -1
- package/src/Dev/node/scanGraph.ts +2 -2
- package/src/Dev/node/watch.ts +1 -1
- package/src/Dev/usecase/selfAliasResolve.spec.ts +68 -0
- package/src/domain/usecase/build.ts +2 -2
- package/src/domain/usecase/collectModules.ts +2 -2
- package/src/domain/usecase/deriveExternal.ts +2 -2
- package/src/domain/usecase/discoverWorkspace.ts +2 -2
- package/src/domain/usecase/emitDts.ts +4 -4
- package/src/domain/usecase/resolveSpecifier.ts +2 -2
- package/src/domain/usecase/resolveWorkspaceSpecifier.ts +1 -1
- package/src/domain/usecase/rewriteDtsAliases.ts +2 -2
- package/src/vendors/nodeFs.ts +22 -0
- package/src/vendors/nodeHttp.ts +14 -0
- package/src/vendors/nodePath.ts +15 -0
- package/src/vendors/nodeProc.ts +12 -0
- package/src/vendors/nodeUrl.ts +6 -0
- package/dist/Dev/fixtures/devPoc.spec.d.ts +0 -2
- package/dist/Dev/fixtures/devPoc.spec.d.ts.map +0 -1
- package/dist/Dev/fixtures/devPoc.spec.js +0 -145
- package/dist/Dev/fixtures/devPoc.spec.js.map +0 -1
- package/dist/Dev/model/Fetch.d.ts +0 -20
- package/dist/Dev/model/Fetch.d.ts.map +0 -1
- package/dist/Dev/model/Fetch.js +0 -8
- package/dist/Dev/model/Fetch.js.map +0 -1
- package/dist/Dev/model/ModuleGraph.d.ts +0 -27
- package/dist/Dev/model/ModuleGraph.d.ts.map +0 -1
- package/dist/Dev/model/ModuleGraph.js +0 -2
- package/dist/Dev/model/ModuleGraph.js.map +0 -1
- package/dist/Dev/model/Protocol.d.ts +0 -22
- package/dist/Dev/model/Protocol.d.ts.map +0 -1
- package/dist/Dev/model/Protocol.js +0 -31
- package/dist/Dev/model/Protocol.js.map +0 -1
- package/dist/Dev/node/devServer.d.ts +0 -21
- package/dist/Dev/node/devServer.d.ts.map +0 -1
- package/dist/Dev/node/devServer.js +0 -298
- package/dist/Dev/node/devServer.js.map +0 -1
- package/dist/Dev/node/httpAdapter.d.ts +0 -19
- package/dist/Dev/node/httpAdapter.d.ts.map +0 -1
- package/dist/Dev/node/httpAdapter.js +0 -76
- package/dist/Dev/node/httpAdapter.js.map +0 -1
- package/dist/Dev/node/scanGraph.d.ts +0 -21
- package/dist/Dev/node/scanGraph.d.ts.map +0 -1
- package/dist/Dev/node/scanGraph.js +0 -145
- package/dist/Dev/node/scanGraph.js.map +0 -1
- package/dist/Dev/node/watch.d.ts +0 -10
- package/dist/Dev/node/watch.d.ts.map +0 -1
- package/dist/Dev/node/watch.js +0 -44
- package/dist/Dev/node/watch.js.map +0 -1
- package/dist/Dev/usecase/allowedHost.d.ts +0 -16
- package/dist/Dev/usecase/allowedHost.d.ts.map +0 -1
- package/dist/Dev/usecase/allowedHost.js +0 -33
- package/dist/Dev/usecase/allowedHost.js.map +0 -1
- package/dist/Dev/usecase/allowedHost.spec.d.ts +0 -2
- package/dist/Dev/usecase/allowedHost.spec.d.ts.map +0 -1
- package/dist/Dev/usecase/allowedHost.spec.js +0 -13
- package/dist/Dev/usecase/allowedHost.spec.js.map +0 -1
- package/dist/Dev/usecase/buildGraph.d.ts +0 -12
- package/dist/Dev/usecase/buildGraph.d.ts.map +0 -1
- package/dist/Dev/usecase/buildGraph.js +0 -24
- package/dist/Dev/usecase/buildGraph.js.map +0 -1
- package/dist/Dev/usecase/buildGraph.spec.d.ts +0 -2
- package/dist/Dev/usecase/buildGraph.spec.d.ts.map +0 -1
- package/dist/Dev/usecase/buildGraph.spec.js +0 -16
- package/dist/Dev/usecase/buildGraph.spec.js.map +0 -1
- package/dist/Dev/usecase/decorateDevHtml.d.ts +0 -12
- package/dist/Dev/usecase/decorateDevHtml.d.ts.map +0 -1
- package/dist/Dev/usecase/decorateDevHtml.js +0 -15
- package/dist/Dev/usecase/decorateDevHtml.js.map +0 -1
- package/dist/Dev/usecase/decorateDevHtml.spec.d.ts +0 -2
- package/dist/Dev/usecase/decorateDevHtml.spec.d.ts.map +0 -1
- package/dist/Dev/usecase/decorateDevHtml.spec.js +0 -19
- package/dist/Dev/usecase/decorateDevHtml.spec.js.map +0 -1
- package/dist/Dev/usecase/invalidate.d.ts +0 -17
- package/dist/Dev/usecase/invalidate.d.ts.map +0 -1
- package/dist/Dev/usecase/invalidate.js +0 -57
- package/dist/Dev/usecase/invalidate.js.map +0 -1
- package/dist/Dev/usecase/invalidate.spec.d.ts +0 -2
- package/dist/Dev/usecase/invalidate.spec.d.ts.map +0 -1
- package/dist/Dev/usecase/invalidate.spec.js +0 -64
- package/dist/Dev/usecase/invalidate.spec.js.map +0 -1
- package/dist/Dev/usecase/parseImports.d.ts +0 -24
- package/dist/Dev/usecase/parseImports.d.ts.map +0 -1
- package/dist/Dev/usecase/parseImports.js +0 -40
- package/dist/Dev/usecase/parseImports.js.map +0 -1
- package/dist/Dev/usecase/parseImports.spec.d.ts +0 -2
- package/dist/Dev/usecase/parseImports.spec.d.ts.map +0 -1
- package/dist/Dev/usecase/parseImports.spec.js +0 -24
- package/dist/Dev/usecase/parseImports.spec.js.map +0 -1
- package/dist/Dev/usecase/reloadDecision.d.ts +0 -20
- package/dist/Dev/usecase/reloadDecision.d.ts.map +0 -1
- package/dist/Dev/usecase/reloadDecision.js +0 -52
- package/dist/Dev/usecase/reloadDecision.js.map +0 -1
- package/dist/Dev/usecase/reloadDecision.spec.d.ts +0 -2
- package/dist/Dev/usecase/reloadDecision.spec.d.ts.map +0 -1
- package/dist/Dev/usecase/reloadDecision.spec.js +0 -17
- package/dist/Dev/usecase/reloadDecision.spec.js.map +0 -1
- package/dist/domain/model/BundleConfig.d.ts +0 -136
- package/dist/domain/model/BundleConfig.d.ts.map +0 -1
- package/dist/domain/model/BundleConfig.js +0 -18
- package/dist/domain/model/BundleConfig.js.map +0 -1
- package/dist/domain/model/BundleConfig.spec.d.ts +0 -2
- package/dist/domain/model/BundleConfig.spec.d.ts.map +0 -1
- package/dist/domain/model/BundleConfig.spec.js +0 -8
- package/dist/domain/model/BundleConfig.spec.js.map +0 -1
- package/dist/domain/usecase/asBundleConfig.d.ts +0 -17
- package/dist/domain/usecase/asBundleConfig.d.ts.map +0 -1
- package/dist/domain/usecase/asBundleConfig.js +0 -179
- package/dist/domain/usecase/asBundleConfig.js.map +0 -1
- package/dist/domain/usecase/asBundleConfig.spec.d.ts +0 -2
- package/dist/domain/usecase/asBundleConfig.spec.d.ts.map +0 -1
- package/dist/domain/usecase/asBundleConfig.spec.js +0 -119
- package/dist/domain/usecase/asBundleConfig.spec.js.map +0 -1
- package/dist/domain/usecase/build.d.ts +0 -14
- package/dist/domain/usecase/build.d.ts.map +0 -1
- package/dist/domain/usecase/build.js +0 -177
- package/dist/domain/usecase/build.js.map +0 -1
- package/dist/domain/usecase/collectModules.d.ts +0 -53
- package/dist/domain/usecase/collectModules.d.ts.map +0 -1
- package/dist/domain/usecase/collectModules.js +0 -118
- package/dist/domain/usecase/collectModules.js.map +0 -1
- package/dist/domain/usecase/deriveExternal.d.ts +0 -25
- package/dist/domain/usecase/deriveExternal.d.ts.map +0 -1
- package/dist/domain/usecase/deriveExternal.js +0 -79
- package/dist/domain/usecase/deriveExternal.js.map +0 -1
- package/dist/domain/usecase/deriveExternal.spec.d.ts +0 -2
- package/dist/domain/usecase/deriveExternal.spec.d.ts.map +0 -1
- package/dist/domain/usecase/deriveExternal.spec.js +0 -56
- package/dist/domain/usecase/deriveExternal.spec.js.map +0 -1
- package/dist/domain/usecase/discoverWorkspace.d.ts +0 -27
- package/dist/domain/usecase/discoverWorkspace.d.ts.map +0 -1
- package/dist/domain/usecase/discoverWorkspace.js +0 -116
- package/dist/domain/usecase/discoverWorkspace.js.map +0 -1
- package/dist/domain/usecase/discoverWorkspace.spec.d.ts +0 -2
- package/dist/domain/usecase/discoverWorkspace.spec.d.ts.map +0 -1
- package/dist/domain/usecase/discoverWorkspace.spec.js +0 -23
- package/dist/domain/usecase/discoverWorkspace.spec.js.map +0 -1
- package/dist/domain/usecase/emitBundle.d.ts +0 -43
- package/dist/domain/usecase/emitBundle.d.ts.map +0 -1
- package/dist/domain/usecase/emitBundle.js +0 -157
- package/dist/domain/usecase/emitBundle.js.map +0 -1
- package/dist/domain/usecase/emitBundle.spec.d.ts +0 -2
- package/dist/domain/usecase/emitBundle.spec.d.ts.map +0 -1
- package/dist/domain/usecase/emitBundle.spec.js +0 -80
- package/dist/domain/usecase/emitBundle.spec.js.map +0 -1
- package/dist/domain/usecase/emitDts.d.ts +0 -32
- package/dist/domain/usecase/emitDts.d.ts.map +0 -1
- package/dist/domain/usecase/emitDts.js +0 -99
- package/dist/domain/usecase/emitDts.js.map +0 -1
- package/dist/domain/usecase/isExternal.d.ts +0 -12
- package/dist/domain/usecase/isExternal.d.ts.map +0 -1
- package/dist/domain/usecase/isExternal.js +0 -16
- package/dist/domain/usecase/isExternal.js.map +0 -1
- package/dist/domain/usecase/isExternal.spec.d.ts +0 -2
- package/dist/domain/usecase/isExternal.spec.d.ts.map +0 -1
- package/dist/domain/usecase/isExternal.spec.js +0 -16
- package/dist/domain/usecase/isExternal.spec.js.map +0 -1
- package/dist/domain/usecase/resolveSpecifier.d.ts +0 -35
- package/dist/domain/usecase/resolveSpecifier.d.ts.map +0 -1
- package/dist/domain/usecase/resolveSpecifier.js +0 -83
- package/dist/domain/usecase/resolveSpecifier.js.map +0 -1
- package/dist/domain/usecase/resolveSpecifier.spec.d.ts +0 -2
- package/dist/domain/usecase/resolveSpecifier.spec.d.ts.map +0 -1
- package/dist/domain/usecase/resolveSpecifier.spec.js +0 -44
- package/dist/domain/usecase/resolveSpecifier.spec.js.map +0 -1
- package/dist/domain/usecase/resolveWorkspaceSpecifier.d.ts +0 -29
- package/dist/domain/usecase/resolveWorkspaceSpecifier.d.ts.map +0 -1
- package/dist/domain/usecase/resolveWorkspaceSpecifier.js +0 -89
- package/dist/domain/usecase/resolveWorkspaceSpecifier.js.map +0 -1
- package/dist/domain/usecase/resolveWorkspaceSpecifier.spec.d.ts +0 -2
- package/dist/domain/usecase/resolveWorkspaceSpecifier.spec.d.ts.map +0 -1
- package/dist/domain/usecase/resolveWorkspaceSpecifier.spec.js +0 -27
- package/dist/domain/usecase/resolveWorkspaceSpecifier.spec.js.map +0 -1
- package/dist/domain/usecase/rewriteDtsAliases.d.ts +0 -25
- package/dist/domain/usecase/rewriteDtsAliases.d.ts.map +0 -1
- package/dist/domain/usecase/rewriteDtsAliases.js +0 -71
- package/dist/domain/usecase/rewriteDtsAliases.js.map +0 -1
- package/dist/domain/usecase/rewriteDtsAliases.spec.d.ts +0 -2
- package/dist/domain/usecase/rewriteDtsAliases.spec.d.ts.map +0 -1
- package/dist/domain/usecase/rewriteDtsAliases.spec.js +0 -35
- package/dist/domain/usecase/rewriteDtsAliases.spec.js.map +0 -1
- package/dist/entrypoints/cli.d.ts +0 -2
- package/dist/entrypoints/cli.d.ts.map +0 -1
- package/dist/entrypoints/cli.js +0 -79
- package/dist/entrypoints/cli.js.map +0 -1
- package/dist/index.d.ts +0 -21
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -28
- package/dist/index.js.map +0 -1
- package/dist/vendors/runner.d.ts +0 -20
- package/dist/vendors/runner.d.ts.map +0 -1
- package/dist/vendors/runner.js +0 -60
- package/dist/vendors/runner.js.map +0 -1
- package/dist/vendors/runner.spec.d.ts +0 -2
- package/dist/vendors/runner.spec.d.ts.map +0 -1
- package/dist/vendors/runner.spec.js +0 -20
- package/dist/vendors/runner.spec.js.map +0 -1
- package/dist/vendors/transpiler.d.ts +0 -19
- package/dist/vendors/transpiler.d.ts.map +0 -1
- package/dist/vendors/transpiler.js +0 -42
- package/dist/vendors/transpiler.js.map +0 -1
package/bin/hook.d.mts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Hand-written types for the JS loader hook (the hook must
|
|
2
|
+
// stay a plain `.mjs` — it runs as Node's ESM resolver
|
|
3
|
+
// before any type-stripping is active — so it carries no
|
|
4
|
+
// inferable types). Declared here so a `.ts` spec can drive
|
|
5
|
+
// `resolve` type-safely under `allowJs: false`.
|
|
6
|
+
|
|
7
|
+
/** A resolved module, as returned to Node's loader chain. */
|
|
8
|
+
export type Resolved = {
|
|
9
|
+
url: string;
|
|
10
|
+
shortCircuit?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const resolve: (
|
|
14
|
+
specifier: string,
|
|
15
|
+
context: { parentURL?: string | undefined },
|
|
16
|
+
nextResolve: (
|
|
17
|
+
specifier: string,
|
|
18
|
+
context: { parentURL?: string | undefined },
|
|
19
|
+
) => Promise<Resolved>,
|
|
20
|
+
) => Promise<Resolved>;
|
package/bin/hook.mjs
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
//
|
|
20
20
|
// Everything else (typescript, node:*) falls through to
|
|
21
21
|
// Node's default resolution.
|
|
22
|
-
import { existsSync } from "node:fs";
|
|
22
|
+
import { existsSync, statSync } from "node:fs";
|
|
23
23
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
24
24
|
import { dirname, join } from "node:path";
|
|
25
25
|
|
|
@@ -27,13 +27,22 @@ const here = dirname(fileURLToPath(import.meta.url));
|
|
|
27
27
|
const srcRoot = join(here, "..", "src");
|
|
28
28
|
const prefix = "plgg-bundle/";
|
|
29
29
|
|
|
30
|
+
// Resolve to a FILE, never a directory: a bare-directory
|
|
31
|
+
// self-alias (e.g. `plgg-bundle/foo`) must land on its
|
|
32
|
+
// `index.ts`, not the directory itself — Node would `read`
|
|
33
|
+
// the directory and throw EISDIR. So the raw `base` matches
|
|
34
|
+
// only when it is a real file; a directory falls through to
|
|
35
|
+
// `base/index.ts`.
|
|
36
|
+
const isFile = (c) =>
|
|
37
|
+
existsSync(c) && statSync(c).isFile();
|
|
38
|
+
|
|
30
39
|
const pick = (base) => {
|
|
31
40
|
const candidates = [
|
|
32
41
|
base,
|
|
33
42
|
`${base}.ts`,
|
|
34
43
|
join(base, "index.ts"),
|
|
35
44
|
];
|
|
36
|
-
return candidates.find(
|
|
45
|
+
return candidates.find(isFile);
|
|
37
46
|
};
|
|
38
47
|
|
|
39
48
|
// The `?v=<n>` dev version carried by an importer URL, or
|
package/bin/plgg-bundle.mjs
CHANGED
|
@@ -7,6 +7,15 @@
|
|
|
7
7
|
import { register } from "node:module";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
10
|
+
import { relocateOutOfNodeModules } from "./relocate.mjs";
|
|
11
|
+
|
|
12
|
+
// Node 24 refuses to strip types from `.ts` under `node_modules`. When this
|
|
13
|
+
// tool is installed from the registry, relocate a copy OUTSIDE `node_modules`
|
|
14
|
+
// and re-exec there; a no-op on a monorepo `file:` link.
|
|
15
|
+
relocateOutOfNodeModules(
|
|
16
|
+
import.meta.url,
|
|
17
|
+
"plgg-bundle.mjs",
|
|
18
|
+
);
|
|
10
19
|
|
|
11
20
|
register("./hook.mjs", import.meta.url);
|
|
12
21
|
|
package/bin/relocate.mjs
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Shared launcher preamble for the run-from-source plgg CLIs.
|
|
2
|
+
//
|
|
3
|
+
// These tools run their `src/**/*.ts` entry directly and rely on Node stripping
|
|
4
|
+
// types on load. Node refuses to strip types for `.ts` files under
|
|
5
|
+
// `node_modules`, so a registry-installed tool cannot run in place. This helper
|
|
6
|
+
// copies the package to a version-stamped dir OUTSIDE `node_modules` (with the
|
|
7
|
+
// tool's own deps reachable via a `node_modules` symlink) and re-execs the copy
|
|
8
|
+
// there. On a monorepo `file:` link the package realpath is already outside
|
|
9
|
+
// `node_modules`, so it is a no-op.
|
|
10
|
+
//
|
|
11
|
+
// Plain `.mjs`, Node built-ins only — it runs at process entry, before any
|
|
12
|
+
// resolver hook is registered.
|
|
13
|
+
import { spawnSync } from "node:child_process";
|
|
14
|
+
import {
|
|
15
|
+
cpSync,
|
|
16
|
+
existsSync,
|
|
17
|
+
mkdirSync,
|
|
18
|
+
readFileSync,
|
|
19
|
+
realpathSync,
|
|
20
|
+
rmSync,
|
|
21
|
+
symlinkSync,
|
|
22
|
+
writeFileSync,
|
|
23
|
+
} from "node:fs";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
import {
|
|
26
|
+
dirname,
|
|
27
|
+
join,
|
|
28
|
+
sep,
|
|
29
|
+
} from "node:path";
|
|
30
|
+
import { fileURLToPath } from "node:url";
|
|
31
|
+
|
|
32
|
+
const isUnderNodeModules = (p) =>
|
|
33
|
+
p.split(sep).includes("node_modules");
|
|
34
|
+
|
|
35
|
+
// Relocate the calling launcher's package out of node_modules and re-exec, or
|
|
36
|
+
// return (no-op) when already outside it. Exits the process on re-exec.
|
|
37
|
+
export const relocateOutOfNodeModules = (
|
|
38
|
+
launcherUrl,
|
|
39
|
+
launcherBinName,
|
|
40
|
+
) => {
|
|
41
|
+
const binDir = dirname(
|
|
42
|
+
fileURLToPath(launcherUrl),
|
|
43
|
+
);
|
|
44
|
+
const pkgRoot = realpathSync(
|
|
45
|
+
join(binDir, ".."),
|
|
46
|
+
);
|
|
47
|
+
if (!isUnderNodeModules(pkgRoot)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const pkg = JSON.parse(
|
|
52
|
+
readFileSync(
|
|
53
|
+
join(pkgRoot, "package.json"),
|
|
54
|
+
"utf8",
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
const dest = join(
|
|
58
|
+
tmpdir(),
|
|
59
|
+
`plgg-relocate-${pkg.name}-${pkg.version}`,
|
|
60
|
+
);
|
|
61
|
+
const ready = join(
|
|
62
|
+
dest,
|
|
63
|
+
".plgg-relocate-ready",
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
if (!existsSync(ready)) {
|
|
67
|
+
rmSync(dest, {
|
|
68
|
+
recursive: true,
|
|
69
|
+
force: true,
|
|
70
|
+
});
|
|
71
|
+
mkdirSync(dest, { recursive: true });
|
|
72
|
+
for (const dir of ["src", "bin"]) {
|
|
73
|
+
const from = join(pkgRoot, dir);
|
|
74
|
+
if (existsSync(from)) {
|
|
75
|
+
cpSync(from, join(dest, dir), {
|
|
76
|
+
recursive: true,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
cpSync(
|
|
81
|
+
join(pkgRoot, "package.json"),
|
|
82
|
+
join(dest, "package.json"),
|
|
83
|
+
);
|
|
84
|
+
// The tool's own deps (typescript; plgg for plgg-test) live in the
|
|
85
|
+
// node_modules that CONTAINS this package (npm hoists there). Symlink it so
|
|
86
|
+
// resolution from the relocated copy finds them.
|
|
87
|
+
try {
|
|
88
|
+
symlinkSync(
|
|
89
|
+
dirname(pkgRoot),
|
|
90
|
+
join(dest, "node_modules"),
|
|
91
|
+
"dir",
|
|
92
|
+
);
|
|
93
|
+
} catch {
|
|
94
|
+
// A pre-existing symlink from a concurrent run is fine.
|
|
95
|
+
}
|
|
96
|
+
writeFileSync(ready, "");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const child = spawnSync(
|
|
100
|
+
process.execPath,
|
|
101
|
+
[
|
|
102
|
+
join(dest, "bin", launcherBinName),
|
|
103
|
+
...process.argv.slice(2),
|
|
104
|
+
],
|
|
105
|
+
{ stdio: "inherit" },
|
|
106
|
+
);
|
|
107
|
+
process.exit(child.status ?? 1);
|
|
108
|
+
};
|
package/package.json
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plgg-bundle",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "In-house minimal library bundler for the plgg monorepo (ESM+CJS dual output, per-file .d.ts tree), zero new dependencies — reuses the project's own TypeScript, no native binding.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
|
-
"dist",
|
|
8
7
|
"src",
|
|
9
8
|
"bin"
|
|
10
9
|
],
|
|
11
10
|
"bin": {
|
|
12
11
|
"plgg-bundle": "bin/plgg-bundle.mjs"
|
|
13
12
|
},
|
|
14
|
-
"main": "dist/index.js",
|
|
15
|
-
"types": "dist/index.d.ts",
|
|
16
13
|
"scripts": {
|
|
17
14
|
"build": "tsc",
|
|
18
15
|
"tsc": "tsc --noEmit",
|
|
@@ -26,6 +23,6 @@
|
|
|
26
23
|
},
|
|
27
24
|
"devDependencies": {
|
|
28
25
|
"@types/node": "^25.6.0",
|
|
29
|
-
"plgg-test": "^0.0.
|
|
26
|
+
"plgg-test": "^0.0.4"
|
|
30
27
|
}
|
|
31
28
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Fixture: a directory whose only module is `index.ts`, so a
|
|
2
|
+
// bare-directory self-alias (`plgg-bundle/Dev/fixtures/aliasDir`)
|
|
3
|
+
// has an index to resolve to. Exercised by
|
|
4
|
+
// ../../usecase/selfAliasResolve.spec.ts to guard the loader
|
|
5
|
+
// hook against resolving to the directory itself (EISDIR).
|
|
6
|
+
export const marker = "aliasDir/index.ts";
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
resolve,
|
|
3
3
|
isAbsolute,
|
|
4
4
|
join,
|
|
5
|
-
} from "
|
|
6
|
-
import { existsSync } from "
|
|
7
|
-
import { pathToFileURL } from "
|
|
8
|
-
import { register } from "
|
|
9
|
-
import { type Server } from "
|
|
5
|
+
} from "plgg-bundle/vendors/nodePath";
|
|
6
|
+
import { existsSync } from "plgg-bundle/vendors/nodeFs";
|
|
7
|
+
import { pathToFileURL } from "plgg-bundle/vendors/nodeUrl";
|
|
8
|
+
import { register } from "plgg-bundle/vendors/nodeProc";
|
|
9
|
+
import { type Server } from "plgg-bundle/vendors/nodeHttp";
|
|
10
10
|
import { type Fetch } from "plgg-bundle/Dev/model/Fetch";
|
|
11
11
|
import { type ModuleGraph } from "plgg-bundle/Dev/model/ModuleGraph";
|
|
12
12
|
import {
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
readdirSync,
|
|
3
3
|
readFileSync,
|
|
4
4
|
statSync,
|
|
5
|
-
} from "
|
|
5
|
+
} from "plgg-bundle/vendors/nodeFs";
|
|
6
6
|
import {
|
|
7
7
|
resolve,
|
|
8
8
|
dirname,
|
|
9
9
|
join,
|
|
10
|
-
} from "
|
|
10
|
+
} from "plgg-bundle/vendors/nodePath";
|
|
11
11
|
import { parseImports } from "plgg-bundle/Dev/usecase/parseImports";
|
|
12
12
|
import { buildGraph } from "plgg-bundle/Dev/usecase/buildGraph";
|
|
13
13
|
import { type ModuleGraph } from "plgg-bundle/Dev/model/ModuleGraph";
|
package/src/Dev/node/watch.ts
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
test,
|
|
3
|
+
check,
|
|
4
|
+
all,
|
|
5
|
+
toBe,
|
|
6
|
+
} from "plgg-test";
|
|
7
|
+
import {
|
|
8
|
+
resolve,
|
|
9
|
+
type Resolved,
|
|
10
|
+
} from "../../../bin/hook.mjs";
|
|
11
|
+
|
|
12
|
+
// The loader hook's `resolve` rewrites `plgg-bundle/<sub>`
|
|
13
|
+
// self-alias specifiers to on-disk `src/<sub>` files. These
|
|
14
|
+
// drive it directly (the alias branch short-circuits before
|
|
15
|
+
// `nextResolve`, so a stub suffices).
|
|
16
|
+
|
|
17
|
+
const ctx = { parentURL: undefined };
|
|
18
|
+
const fallthrough = async (): Promise<Resolved> => ({
|
|
19
|
+
url: "file:///fallthrough",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test(
|
|
23
|
+
"bare-directory self-alias resolves to its index.ts, not the directory (EISDIR guard)",
|
|
24
|
+
async () => {
|
|
25
|
+
const r = await resolve(
|
|
26
|
+
"plgg-bundle/Dev/fixtures/aliasDir",
|
|
27
|
+
ctx,
|
|
28
|
+
fallthrough,
|
|
29
|
+
);
|
|
30
|
+
return all([
|
|
31
|
+
check(
|
|
32
|
+
r.url.endsWith("/aliasDir/index.ts"),
|
|
33
|
+
toBe(true),
|
|
34
|
+
),
|
|
35
|
+
check(r.shortCircuit ?? false, toBe(true)),
|
|
36
|
+
]);
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
test(
|
|
41
|
+
"file self-alias still resolves to the .ts file (no regression)",
|
|
42
|
+
async () => {
|
|
43
|
+
const r = await resolve(
|
|
44
|
+
"plgg-bundle/index",
|
|
45
|
+
ctx,
|
|
46
|
+
fallthrough,
|
|
47
|
+
);
|
|
48
|
+
return check(
|
|
49
|
+
r.url.endsWith("/src/index.ts"),
|
|
50
|
+
toBe(true),
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
test(
|
|
56
|
+
"a self-alias with no matching file falls through to nextResolve",
|
|
57
|
+
async () => {
|
|
58
|
+
const r = await resolve(
|
|
59
|
+
"plgg-bundle/does/not/exist",
|
|
60
|
+
ctx,
|
|
61
|
+
fallthrough,
|
|
62
|
+
);
|
|
63
|
+
return check(
|
|
64
|
+
r.url,
|
|
65
|
+
toBe("file:///fallthrough"),
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
);
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
rmSync,
|
|
5
5
|
renameSync,
|
|
6
6
|
existsSync,
|
|
7
|
-
} from "
|
|
8
|
-
import { join, dirname } from "
|
|
7
|
+
} from "plgg-bundle/vendors/nodeFs";
|
|
8
|
+
import { join, dirname } from "plgg-bundle/vendors/nodePath";
|
|
9
9
|
import {
|
|
10
10
|
type BundleConfig,
|
|
11
11
|
type Entry,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFileSync } from "
|
|
2
|
-
import { relative } from "
|
|
1
|
+
import { readFileSync } from "plgg-bundle/vendors/nodeFs";
|
|
2
|
+
import { relative } from "plgg-bundle/vendors/nodePath";
|
|
3
3
|
import { type External } from "plgg-bundle/domain/model/BundleConfig";
|
|
4
4
|
import { resolveSpecifier } from "plgg-bundle/domain/usecase/resolveSpecifier";
|
|
5
5
|
import { isExternal } from "plgg-bundle/domain/usecase/isExternal";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFileSync } from "
|
|
2
|
-
import { join } from "
|
|
1
|
+
import { readFileSync } from "plgg-bundle/vendors/nodeFs";
|
|
2
|
+
import { join } from "plgg-bundle/vendors/nodePath";
|
|
3
3
|
import { type External } from "plgg-bundle/domain/model/BundleConfig";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
readFileSync,
|
|
4
4
|
existsSync,
|
|
5
5
|
statSync,
|
|
6
|
-
} from "
|
|
7
|
-
import { join, dirname } from "
|
|
6
|
+
} from "plgg-bundle/vendors/nodeFs";
|
|
7
|
+
import { join, dirname } from "plgg-bundle/vendors/nodePath";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* A workspace sibling the app bundler can INLINE from
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { spawnSync } from "
|
|
1
|
+
import { spawnSync } from "plgg-bundle/vendors/nodeProc";
|
|
2
2
|
import {
|
|
3
3
|
join,
|
|
4
4
|
dirname,
|
|
5
5
|
basename,
|
|
6
6
|
relative,
|
|
7
|
-
} from "
|
|
7
|
+
} from "plgg-bundle/vendors/nodePath";
|
|
8
8
|
import {
|
|
9
9
|
existsSync,
|
|
10
10
|
writeFileSync,
|
|
11
11
|
rmSync,
|
|
12
|
-
} from "
|
|
13
|
-
import { createRequire } from "
|
|
12
|
+
} from "plgg-bundle/vendors/nodeFs";
|
|
13
|
+
import { createRequire } from "plgg-bundle/vendors/nodeProc";
|
|
14
14
|
import { rewriteDtsAliases } from "plgg-bundle/domain/usecase/rewriteDtsAliases";
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { existsSync, statSync } from "
|
|
1
|
+
import { existsSync, statSync } from "plgg-bundle/vendors/nodeFs";
|
|
2
2
|
import {
|
|
3
3
|
dirname,
|
|
4
4
|
resolve,
|
|
5
5
|
join,
|
|
6
|
-
} from "
|
|
6
|
+
} from "plgg-bundle/vendors/nodePath";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Resolve a bare import specifier to an absolute source
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
statSync,
|
|
4
4
|
readFileSync,
|
|
5
5
|
writeFileSync,
|
|
6
|
-
} from "
|
|
6
|
+
} from "plgg-bundle/vendors/nodeFs";
|
|
7
7
|
import {
|
|
8
8
|
join,
|
|
9
9
|
dirname,
|
|
10
10
|
relative,
|
|
11
|
-
} from "
|
|
11
|
+
} from "plgg-bundle/vendors/nodePath";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Rewrite the package self-alias (`<prefix>/<sub>`) in
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The filesystem anti-corruption layer for plgg-bundle — the
|
|
3
|
+
* ONLY place the bundler's build usecases reach `node:fs`, kept
|
|
4
|
+
* under `vendors/` so the domain speaks these named operations,
|
|
5
|
+
* not the driver. Re-exported (not re-wrapped) to preserve the
|
|
6
|
+
* exact node types; plgg-bundle's throw-at-the-boundary error
|
|
7
|
+
* model (see BundleConfig) means a failed fs call surfaces as a
|
|
8
|
+
* thrown Error the entrypoint catches — the seam is the import
|
|
9
|
+
* chokepoint, so the vendor-boundary gate holds unexempted.
|
|
10
|
+
*/
|
|
11
|
+
export {
|
|
12
|
+
writeFileSync,
|
|
13
|
+
mkdirSync,
|
|
14
|
+
rmSync,
|
|
15
|
+
renameSync,
|
|
16
|
+
existsSync,
|
|
17
|
+
readdirSync,
|
|
18
|
+
readFileSync,
|
|
19
|
+
statSync,
|
|
20
|
+
watch,
|
|
21
|
+
type FSWatcher,
|
|
22
|
+
} from "node:fs";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HTTP anti-corruption layer for plgg-bundle's DEV server —
|
|
3
|
+
* the ONLY place the node:http ⇄ Web-standard bridge reaches
|
|
4
|
+
* `node:http`. Confined here so the dev orchestration stays
|
|
5
|
+
* `node:`-free (the vendor-boundary gate); a plgg-free
|
|
6
|
+
* reimplementation of `serve` (the toolchain must not import a
|
|
7
|
+
* library it builds).
|
|
8
|
+
*/
|
|
9
|
+
export {
|
|
10
|
+
createServer,
|
|
11
|
+
type IncomingMessage,
|
|
12
|
+
type ServerResponse,
|
|
13
|
+
type Server,
|
|
14
|
+
} from "node:http";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The path anti-corruption layer for plgg-bundle — the ONLY
|
|
3
|
+
* place the build usecases reach `node:path`. Re-exported to
|
|
4
|
+
* preserve exact node types; confining the import here is what
|
|
5
|
+
* keeps the domain free of `node:` specifiers (the
|
|
6
|
+
* vendor-boundary gate).
|
|
7
|
+
*/
|
|
8
|
+
export {
|
|
9
|
+
join,
|
|
10
|
+
dirname,
|
|
11
|
+
relative,
|
|
12
|
+
basename,
|
|
13
|
+
resolve,
|
|
14
|
+
isAbsolute,
|
|
15
|
+
} from "node:path";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The process/module anti-corruption layer for plgg-bundle —
|
|
3
|
+
* the ONLY place the `.d.ts` emitter reaches `node:child_process`
|
|
4
|
+
* (to spawn the target's own `tsc`) and `node:module` (to
|
|
5
|
+
* resolve it against the target's node_modules). Confined here so
|
|
6
|
+
* the domain stays `node:`-free.
|
|
7
|
+
*/
|
|
8
|
+
export { spawnSync } from "node:child_process";
|
|
9
|
+
export {
|
|
10
|
+
createRequire,
|
|
11
|
+
register,
|
|
12
|
+
} from "node:module";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devPoc.spec.d.ts","sourceRoot":"","sources":["../../../src/Dev/fixtures/devPoc.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { test, check, all, toBe, } from "plgg-test";
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
3
|
-
import { mkdtempSync, writeFileSync, } from "node:fs";
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
|
-
// The end-to-end hot-reload PoC (ticket 041500). It runs
|
|
8
|
-
// the REAL toolchain — `node bin/plgg-bundle.mjs dev` on a
|
|
9
|
-
// throwaway fixture app — then edits a *deep* source module
|
|
10
|
-
// mid-run and proves the served output changes with NO
|
|
11
|
-
// process restart, and that the SSE reload channel opens.
|
|
12
|
-
// This is the fidelity oracle for the whole chain: bin +
|
|
13
|
-
// loader-hook version propagation + module-runner re-import
|
|
14
|
-
// + node:http serve + fs.watch + SSE.
|
|
15
|
-
/** This spec's dir → the package's bin/plgg-bundle.mjs. */
|
|
16
|
-
const BIN = join(fileURLToPath(import.meta.url), "..", "..", "..", "..", "bin", "plgg-bundle.mjs");
|
|
17
|
-
/** A dev entry that renders a deep child's message as HTML. */
|
|
18
|
-
const ENTRY_SRC = [
|
|
19
|
-
`import { message } from "./child.ts";`,
|
|
20
|
-
`export default () =>`,
|
|
21
|
-
` (_request) =>`,
|
|
22
|
-
` Promise.resolve(`,
|
|
23
|
-
` new Response(`,
|
|
24
|
-
' `<html><body>${message()}</body></html>`,',
|
|
25
|
-
` { headers: { "content-type": "text/html" } },`,
|
|
26
|
-
` ),`,
|
|
27
|
-
` );`,
|
|
28
|
-
].join("\n");
|
|
29
|
-
/** The deep child module the edit targets. */
|
|
30
|
-
const childSrc = (word) => `export const message = () => "${word}";\n`;
|
|
31
|
-
/** A minimal dev-only bundle config for the fixture app. */
|
|
32
|
-
const configSrc = (root) => `export default ${JSON.stringify({
|
|
33
|
-
root,
|
|
34
|
-
rootDir: ".",
|
|
35
|
-
outDir: "dist",
|
|
36
|
-
fileNamePattern: "[name].[format].js",
|
|
37
|
-
entries: [],
|
|
38
|
-
formats: ["es"],
|
|
39
|
-
alias: { prefix: "fixture", srcRoot: "." },
|
|
40
|
-
dev: {
|
|
41
|
-
entry: "entry.ts",
|
|
42
|
-
// Port 0 → ephemeral; the real port is read from
|
|
43
|
-
// the server's ready line.
|
|
44
|
-
port: 0,
|
|
45
|
-
watch: [root],
|
|
46
|
-
allowedHosts: [],
|
|
47
|
-
},
|
|
48
|
-
}, null, 2)};\n`;
|
|
49
|
-
/** Lay down the fixture app in a fresh temp dir. */
|
|
50
|
-
const writeFixture = () => {
|
|
51
|
-
const dir = mkdtempSync(join(tmpdir(), "plgg-dev-poc-"));
|
|
52
|
-
writeFileSync(join(dir, "child.ts"), childSrc("ALPHA"));
|
|
53
|
-
writeFileSync(join(dir, "entry.ts"), ENTRY_SRC);
|
|
54
|
-
writeFileSync(join(dir, "bundle.config.ts"), configSrc(dir));
|
|
55
|
-
return dir;
|
|
56
|
-
};
|
|
57
|
-
/** Sleep (test-only pacing for the watch/reload loop). */
|
|
58
|
-
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
59
|
-
/**
|
|
60
|
-
* Spawn `plgg-bundle dev` on the fixture and resolve the
|
|
61
|
-
* served URL once the ready line is printed.
|
|
62
|
-
*/
|
|
63
|
-
const startDev = (dir) => new Promise((resolve, reject) => {
|
|
64
|
-
const proc = spawn(process.execPath, [BIN, "dev", "bundle.config.ts"], { cwd: dir });
|
|
65
|
-
let out = "";
|
|
66
|
-
const onData = (chunk) => {
|
|
67
|
-
out += chunk.toString();
|
|
68
|
-
const m = out.match(/http:\/\/localhost:\d+\//);
|
|
69
|
-
if (m) {
|
|
70
|
-
proc.stdout?.off("data", onData);
|
|
71
|
-
resolve({ proc, url: m[0] });
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
proc.stdout?.on("data", onData);
|
|
75
|
-
proc.on("error", reject);
|
|
76
|
-
setTimeout(() => reject(new Error(`dev server did not start; output:\n${out}`)), 8000);
|
|
77
|
-
});
|
|
78
|
-
/** Fetch a URL's body text. */
|
|
79
|
-
const body = (url) => fetch(url).then((r) => r.text());
|
|
80
|
-
/**
|
|
81
|
-
* Poll `body(url)` until it contains `needle`, or throw on
|
|
82
|
-
* timeout. Proves the served output actually changed after
|
|
83
|
-
* the edit (not a fixed sleep guess).
|
|
84
|
-
*/
|
|
85
|
-
const pollFor = async (url, needle) => {
|
|
86
|
-
const deadline = 6000;
|
|
87
|
-
const step = 60;
|
|
88
|
-
for (let waited = 0; waited < deadline;) {
|
|
89
|
-
if ((await body(url)).includes(needle)) {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
await wait(step);
|
|
93
|
-
waited += step;
|
|
94
|
-
}
|
|
95
|
-
return false;
|
|
96
|
-
};
|
|
97
|
-
test("plgg-bundle dev hot-reloads a deep source edit with no restart", async () => {
|
|
98
|
-
const dir = writeFixture();
|
|
99
|
-
const { proc, url } = await startDev(dir);
|
|
100
|
-
try {
|
|
101
|
-
const first = await body(url);
|
|
102
|
-
// Rewrite the DEEP child (not the entry) mid-run.
|
|
103
|
-
writeFileSync(join(dir, "child.ts"), childSrc("BETA"));
|
|
104
|
-
const reloaded = await pollFor(url, "BETA");
|
|
105
|
-
const stillAlive = proc.exitCode === null;
|
|
106
|
-
return all([
|
|
107
|
-
// Initial render came from the child module.
|
|
108
|
-
check(first.includes("ALPHA"), toBe(true)),
|
|
109
|
-
// The dev server injected its live-reload client.
|
|
110
|
-
check(first.includes("EventSource"), toBe(true)),
|
|
111
|
-
// The deep edit re-evaluated and is now served …
|
|
112
|
-
check(reloaded, toBe(true)),
|
|
113
|
-
// … by the SAME process (no restart).
|
|
114
|
-
check(stillAlive, toBe(true)),
|
|
115
|
-
]);
|
|
116
|
-
}
|
|
117
|
-
finally {
|
|
118
|
-
proc.kill();
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
test("plgg-bundle dev opens an SSE reload channel", async () => {
|
|
122
|
-
const dir = writeFixture();
|
|
123
|
-
const { proc, url } = await startDev(dir);
|
|
124
|
-
try {
|
|
125
|
-
const res = await fetch(`${url}__plgg_reload`);
|
|
126
|
-
const contentType = res.headers.get("content-type") ?? "";
|
|
127
|
-
// Read the opener frame, then release the stream.
|
|
128
|
-
const reader = res.body?.getReader();
|
|
129
|
-
const firstChunk = reader
|
|
130
|
-
? await reader.read()
|
|
131
|
-
: { value: undefined };
|
|
132
|
-
await reader?.cancel();
|
|
133
|
-
const text = firstChunk.value
|
|
134
|
-
? new TextDecoder().decode(firstChunk.value)
|
|
135
|
-
: "";
|
|
136
|
-
return all([
|
|
137
|
-
check(contentType.includes("text/event-stream"), toBe(true)),
|
|
138
|
-
check(text.includes("connected"), toBe(true)),
|
|
139
|
-
]);
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
proc.kill();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
//# sourceMappingURL=devPoc.spec.js.map
|