@absolutejs/absolute 0.19.0-beta.123 → 0.19.0-beta.125
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/.absolutejs/tsconfig.tsbuildinfo +1 -1
- package/.claude/settings.local.json +8 -1
- package/HTTP2_STATUS.md +44 -0
- package/dist/build.js +97 -2
- package/dist/build.js.map +4 -4
- package/dist/index.js +127 -236
- package/dist/index.js.map +6 -7
- package/package.json +1 -1
- package/dist/src/dev/http2Bridge.d.ts +0 -3
|
@@ -240,7 +240,14 @@
|
|
|
240
240
|
"Bash(find /home/alexkahn/abs/absolutejs -name *.d.ts -path */node_modules/@types/node/*http2*)",
|
|
241
241
|
"Bash(fuser -k 3001/tcp)",
|
|
242
242
|
"WebFetch(domain:groups.google.com)",
|
|
243
|
-
"WebFetch(domain:developer.chrome.com)"
|
|
243
|
+
"WebFetch(domain:developer.chrome.com)",
|
|
244
|
+
"Bash(~/alex/bun-combined-patch/build/release/bun h2-benchmark.ts 3000)",
|
|
245
|
+
"Bash(~/alex/bun-combined-patch/build/release/bun h2-benchmark.ts 3000 https)",
|
|
246
|
+
"Bash(fuser -k 3000/tcp)",
|
|
247
|
+
"Bash(ALPN_BUN=~/alex/bun-alpn-patch/build/release/bun)",
|
|
248
|
+
"Bash(__NEW_LINE_54a38eed241da675__ echo:*)",
|
|
249
|
+
"Bash(__NEW_LINE_54a38eed241da675__ sleep:*)",
|
|
250
|
+
"Bash(timeout 5 $ALPN_BUN -e \":*)"
|
|
244
251
|
]
|
|
245
252
|
}
|
|
246
253
|
}
|
package/HTTP2_STATUS.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# HTTP/2 Dev Server — Status & Roadmap
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Serve dev module fetches over HTTP/2 multiplexed connections when configured to eliminate the
|
|
5
|
+
HTTP/1.1 6-connection bottleneck on import-heavy pages.
|
|
6
|
+
|
|
7
|
+
## What's Built & Ready
|
|
8
|
+
|
|
9
|
+
### HTTPS / TLS (shipping)
|
|
10
|
+
- `dev: { https: true }` config option
|
|
11
|
+
- `src/dev/devCert.ts` — mkcert + self-signed cert generation
|
|
12
|
+
- `src/plugins/networking.ts` — Bun.serve with TLS when HTTPS enabled
|
|
13
|
+
- `src/cli/scripts/dev.ts` — passes `ABSOLUTE_HTTPS=true` to server process
|
|
14
|
+
|
|
15
|
+
### HTTP/2 Plumbing (waiting on Bun)
|
|
16
|
+
- `src/core/prepare.ts` — exposes `globalThis.__http2Config` when `dev.https` is enabled
|
|
17
|
+
- `src/plugins/hmr.ts` — skips Elysia `.ws('/hmr')` when `__http2Config` is set (h2 mode uses RFC 8441 WebSocket instead)
|
|
18
|
+
- `types/globals.d.ts` — `__http2Config` type declaration
|
|
19
|
+
- `types/build.ts` — `dev.https` config type
|
|
20
|
+
|
|
21
|
+
## What's Blocking
|
|
22
|
+
|
|
23
|
+
### Bun Issue #14672 — HTTP/2 for Bun.serve()
|
|
24
|
+
**Critical blocker.** `Bun.serve()` only speaks HTTP/1.1. Using `node:http2`
|
|
25
|
+
as a JS-level bridge works but the per-request overhead through `app.fetch()`
|
|
26
|
+
negates the multiplexing gain at scale. HTTP/2 needs to happen at the native
|
|
27
|
+
Bun.serve level.
|
|
28
|
+
|
|
29
|
+
**Track:** https://github.com/oven-sh/bun/issues/14672
|
|
30
|
+
|
|
31
|
+
### Bun PR #28581 — enableConnectProtocol SETTINGS
|
|
32
|
+
`session.settings({ enableConnectProtocol: true })` is silently ignored —
|
|
33
|
+
the setting never reaches the SETTINGS frame. Browsers require
|
|
34
|
+
`SETTINGS_ENABLE_CONNECT_PROTOCOL=1` before using RFC 8441 Extended CONNECT
|
|
35
|
+
for WebSocket over HTTP/2.
|
|
36
|
+
|
|
37
|
+
**Track:** https://github.com/oven-sh/bun/pull/28581
|
|
38
|
+
|
|
39
|
+
## When Bun.serve Gets HTTP/2
|
|
40
|
+
|
|
41
|
+
1. **networking.ts** — pass h2 option to `app.listen()` / `Bun.serve()` config
|
|
42
|
+
2. **hmr.ts** — `__http2Config` check already skips `.ws()` in h2 mode
|
|
43
|
+
3. **WebSocket** — use RFC 8441 Extended CONNECT (requires #28581 or Bun adding it natively)
|
|
44
|
+
4. Remove `__http2Config` pattern if Bun.serve handles h2 + WS natively
|
package/dist/build.js
CHANGED
|
@@ -171220,6 +171220,28 @@ var isDev, extractBuildError = (logs, pass, label, frameworkNames, isIncremental
|
|
|
171220
171220
|
globalThis.__absoluteVersion = pkg.version;
|
|
171221
171221
|
return;
|
|
171222
171222
|
}
|
|
171223
|
+
}, scanWorkerReferences = async (dirs) => {
|
|
171224
|
+
const urlPattern = /new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g;
|
|
171225
|
+
const resolvePattern = /import\.meta\.resolve\(\s*["'](\.\.?\/[^"']+)["']\s*\)/g;
|
|
171226
|
+
const workerPaths = new Set;
|
|
171227
|
+
for (const dir of dirs) {
|
|
171228
|
+
const glob = new Glob5("**/*.{ts,tsx,js,jsx}");
|
|
171229
|
+
for await (const file3 of glob.scan({ absolute: true, cwd: dir })) {
|
|
171230
|
+
const content = readFileSync5(file3, "utf-8");
|
|
171231
|
+
for (const pattern of [urlPattern, resolvePattern]) {
|
|
171232
|
+
pattern.lastIndex = 0;
|
|
171233
|
+
let match;
|
|
171234
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
171235
|
+
const relPath = match[1];
|
|
171236
|
+
if (!relPath)
|
|
171237
|
+
continue;
|
|
171238
|
+
const absPath = resolve10(file3, "..", relPath);
|
|
171239
|
+
workerPaths.add(absPath);
|
|
171240
|
+
}
|
|
171241
|
+
}
|
|
171242
|
+
}
|
|
171243
|
+
}
|
|
171244
|
+
return [...workerPaths];
|
|
171223
171245
|
}, vueFeatureFlags, build = async ({
|
|
171224
171246
|
buildDirectory = "build",
|
|
171225
171247
|
assetsDirectory,
|
|
@@ -171632,6 +171654,68 @@ var isDev, extractBuildError = (logs, pass, label, frameworkNames, isIncremental
|
|
|
171632
171654
|
if (vueCssResult && !vueCssResult.success && vueCssResult.logs.length > 0) {
|
|
171633
171655
|
extractBuildError(vueCssResult.logs, "vue-css", "Vue CSS", frameworkNames, isIncremental, throwOnError);
|
|
171634
171656
|
}
|
|
171657
|
+
const frameworkDirs = [
|
|
171658
|
+
reactDir,
|
|
171659
|
+
svelteDir,
|
|
171660
|
+
vueDir,
|
|
171661
|
+
angularDir,
|
|
171662
|
+
htmlDir,
|
|
171663
|
+
htmxDir
|
|
171664
|
+
].filter((d) => Boolean(d));
|
|
171665
|
+
const workerEntryPoints = await scanWorkerReferences(frameworkDirs);
|
|
171666
|
+
let workerOutputs = [];
|
|
171667
|
+
if (workerEntryPoints.length > 0) {
|
|
171668
|
+
const workerResult = await bunBuild6({
|
|
171669
|
+
entrypoints: workerEntryPoints,
|
|
171670
|
+
format: "esm",
|
|
171671
|
+
minify: !isDev,
|
|
171672
|
+
naming: "[dir]/[name].[hash].[ext]",
|
|
171673
|
+
outdir: buildPath,
|
|
171674
|
+
root: commonAncestor(workerEntryPoints),
|
|
171675
|
+
target: "browser",
|
|
171676
|
+
throw: false
|
|
171677
|
+
});
|
|
171678
|
+
if (workerResult.success) {
|
|
171679
|
+
workerOutputs = workerResult.outputs;
|
|
171680
|
+
const workerUrlMap = new Map;
|
|
171681
|
+
for (const artifact of workerOutputs) {
|
|
171682
|
+
for (const ep of workerEntryPoints) {
|
|
171683
|
+
const epBase = basename5(ep).replace(/\.[^.]+$/, "");
|
|
171684
|
+
if (basename5(artifact.path).startsWith(epBase)) {
|
|
171685
|
+
workerUrlMap.set(ep, "/" + relative7(buildPath, artifact.path));
|
|
171686
|
+
}
|
|
171687
|
+
}
|
|
171688
|
+
}
|
|
171689
|
+
const allClientOutputPaths = [
|
|
171690
|
+
...reactClientOutputPaths,
|
|
171691
|
+
...nonReactClientOutputs.map((a) => a.path)
|
|
171692
|
+
];
|
|
171693
|
+
for (const outputPath of allClientOutputPaths) {
|
|
171694
|
+
let content = readFileSync5(outputPath, "utf-8");
|
|
171695
|
+
let changed = false;
|
|
171696
|
+
for (const [srcPath, hashedPath] of workerUrlMap) {
|
|
171697
|
+
const srcRelPatterns = [
|
|
171698
|
+
"./" + relative7(buildPath, srcPath),
|
|
171699
|
+
"../" + relative7(buildPath, srcPath),
|
|
171700
|
+
relative7(buildPath, srcPath)
|
|
171701
|
+
];
|
|
171702
|
+
for (const pattern of srcRelPatterns) {
|
|
171703
|
+
if (content.includes(pattern)) {
|
|
171704
|
+
content = content.replaceAll(pattern, hashedPath);
|
|
171705
|
+
changed = true;
|
|
171706
|
+
}
|
|
171707
|
+
}
|
|
171708
|
+
}
|
|
171709
|
+
if (changed)
|
|
171710
|
+
writeFileSync3(outputPath, content);
|
|
171711
|
+
}
|
|
171712
|
+
} else {
|
|
171713
|
+
const workerLogs = workerResult.logs;
|
|
171714
|
+
if (workerLogs.length > 0) {
|
|
171715
|
+
extractBuildError(workerLogs, "worker", "Worker", frameworkNames, isIncremental, throwOnError);
|
|
171716
|
+
}
|
|
171717
|
+
}
|
|
171718
|
+
}
|
|
171635
171719
|
const allLogs = [
|
|
171636
171720
|
...serverLogs,
|
|
171637
171721
|
...reactClientLogs,
|
|
@@ -171645,7 +171729,8 @@ var isDev, extractBuildError = (logs, pass, label, frameworkNames, isIncremental
|
|
|
171645
171729
|
...serverOutputs,
|
|
171646
171730
|
...reactClientOutputs,
|
|
171647
171731
|
...nonReactClientOutputs,
|
|
171648
|
-
...cssOutputs
|
|
171732
|
+
...cssOutputs,
|
|
171733
|
+
...workerOutputs
|
|
171649
171734
|
], buildPath)
|
|
171650
171735
|
};
|
|
171651
171736
|
for (const artifact of serverOutputs) {
|
|
@@ -202553,6 +202638,16 @@ ${stubs}
|
|
|
202553
202638
|
}
|
|
202554
202639
|
return _match;
|
|
202555
202640
|
});
|
|
202641
|
+
result = result.replace(/new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g, (_match, relPath) => {
|
|
202642
|
+
const absPath = resolve17(fileDir, relPath);
|
|
202643
|
+
const rel = relative8(projectRoot, absPath);
|
|
202644
|
+
return `new URL('/${srcUrl(rel, projectRoot)}', import.meta.url)`;
|
|
202645
|
+
});
|
|
202646
|
+
result = result.replace(/import\.meta\.resolve\(\s*["'](\.\.?\/[^"']+)["']\s*\)/g, (_match, relPath) => {
|
|
202647
|
+
const absPath = resolve17(fileDir, relPath);
|
|
202648
|
+
const rel = relative8(projectRoot, absPath);
|
|
202649
|
+
return `'${srcUrl(rel, projectRoot)}'`;
|
|
202650
|
+
});
|
|
202556
202651
|
return result;
|
|
202557
202652
|
}, HOOK_NAMES, REFRESH_PREAMBLE, JSX_AUTO_RE, JSXS_AUTO_RE, JSX_PROD_RE, FRAGMENT_RE, addJsxImport = (code) => {
|
|
202558
202653
|
const imports = [];
|
|
@@ -204938,5 +205033,5 @@ export {
|
|
|
204938
205033
|
build
|
|
204939
205034
|
};
|
|
204940
205035
|
|
|
204941
|
-
//# debugId=
|
|
205036
|
+
//# debugId=3F1CBCC76E25EDCC64756E2164756E21
|
|
204942
205037
|
//# sourceMappingURL=build.js.map
|