@absolutejs/absolute 0.20.0-beta.122 → 0.20.0-beta.124
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/CHANGELOG.md +31 -0
- package/changelog.json +60 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +124 -46
- package/dist/build.js.map +5 -5
- package/dist/cli/{dev-pdefc9ac.js → dev-s7kct3xq.js} +6 -1
- package/dist/cli/index-hty8111z.js +410 -0
- package/dist/cli/index.js +6 -2
- package/dist/cli/patchedBun-zjtrn2s4.js +38 -0
- package/dist/dev/client/handlers/react.ts +31 -39
- package/dist/dev/client/hmrClient.ts +3 -0
- package/dist/dev/serverBootstrap.js +11 -0
- package/dist/index.js +126 -48
- package/dist/index.js.map +6 -6
- package/dist/mobile/remoteMacAgentEntry.js +1 -1
- package/dist/src/cli/patchedBun.d.ts +84 -0
- package/dist/src/dev/hotRejectionGuard.d.ts +1 -0
- package/dist/src/dev/moduleServer.d.ts +10 -3
- package/dist/src/mobile/emulatorDoctor.d.ts +1 -1
- package/dist/types/globals.d.ts +10 -0
- package/dist/types/websocket.d.ts +1 -0
- package/package.json +2 -2
- package/dist/cli/{mobile-00bqw12c.js → mobile-6kdsrhxy.js} +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,37 @@ This file is generated by `absolute-changelog` from the entries in
|
|
|
6
6
|
`changelog/`. Edit an entry, not this file — and add new ones under
|
|
7
7
|
`changelog/unreleased/`.
|
|
8
8
|
|
|
9
|
+
## 0.20.0-beta.124 — 2026-09-28
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Projects on a current `@absolutejs/auth` no longer get a second, older copy**
|
|
14
|
+
AbsoluteJS accepted `@absolutejs/auth` only below 0.77, so a project that added a current auth (0.77 to 0.96) got two copies: its own, plus 0.76.3 nested under AbsoluteJS for the mobile shell. The duplicate also doubled the auth type declarations TypeScript loads. AbsoluteJS now accepts auth up to 0.96. The `@absolutejs/auth/client/mobile` API it uses is byte-identical from 0.76.3 to 0.96.0, in both its declarations and its runtime.
|
|
15
|
+
- **`/hmr-status` no longer counts closed or duplicate HMR clients** (`HMRWebSocket`)
|
|
16
|
+
Elysia 2 hands every open, message and close event of a WebSocket a new wrapper object. The dev server tracked HMR clients by that wrapper, so a closed browser tab was never removed (it stayed until a broadcast send threw) and each `ready` message counted the same tab again under `connectedTargets`, so `/hmr-status` reported clients that were gone and more web targets than open sockets. Clients are now tracked by the underlying socket.
|
|
17
|
+
|
|
18
|
+
## 0.20.0-beta.123 — 2026-09-28
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **React Fast Refresh keeps component state: `absolute dev` can run on AbsoluteJS's patched Bun**
|
|
23
|
+
Stock Bun ignores `reactFastRefresh` on `Bun.Transpiler` (oven-sh/bun#32919), so React edits in `absolute dev` remounted the page and lost component state. AbsoluteJS now publishes Bun 1.4.0 with just that fix for every platform Bun ships (github.com/absolutejs/patched-bun). In React projects on stock Bun, `absolute dev` offers it once (Install now / Ask me later / Don't ask again); it installs to ~/.absolutejs/bun, is checked against a pinned SHA-256, and only the dev server uses it, so your `bun` is unchanged. `absolute bun-patch [status|install|remove|reset]` manages it; `ABSOLUTE_PATCHED_BUN=0` opts out.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **`absolute dev` keeps rebuilding after a syntax error in a React component or an unhandled rejection**
|
|
28
|
+
Under `bun --hot`, Bun counts unhandled rejections that no listener claims and never resets the count; while it is non-zero Bun parks the process in a loop that still serves requests and delivers file-watch events but never runs timers. The server entry imports React pages, so saving a React component with a syntax error made Bun's hot reload reject, and from then on the HMR debounce never fired: every edit was detected and queued, including the one that fixed the error, and nothing rebuilt until the dev server restarted. An unhandled rejection in app code did the same. The dev server now claims unhandled rejections and prints them as before, so its timers keep running.
|
|
29
|
+
- **The patched Bun is now a release build, not a canary build**
|
|
30
|
+
`absolute bun-patch install` and the `absolute dev` offer now install `bun-v1.4.0-absolute.2`. The first release was built as a Bun canary build (Bun's build default): it reported `1.4.0-canary.1`, enabled Bun's experimental "bake" server features and made `bun upgrade` track canary. absolute.2 is built with `--canary=off`, as Bun's own releases are; the React Fast Refresh fix is unchanged. Run `absolute bun-patch install` to replace an absolute.1 install.
|
|
31
|
+
- **Removed a React HMR CSS branch that only matched the example app**
|
|
32
|
+
The React HMR client had a CSS-only branch that looked up the example app's `ReactExampleCSS` manifest key, so it could never work in another app; the server never sends a CSS-only React update, so it was also unreachable. Removed. Stylesheet edits on React pages go through the general stylesheet swap, now covered by a browser test (the rule applies, component state and the document are kept).
|
|
33
|
+
- **React edits that add a component, touch a hook or utility, or create a folder now update the page in place**
|
|
34
|
+
The React fast path told the browser to re-import a single module: the first non-page file in the batch. A new component added to the page re-imported only the new file, so the page never rendered it; a folder created alongside a file became the target and its URL failed to load; and an edited hook or utility whose importer had not been fetched through the module server re-imported just itself, which updates nothing on screen. Every edited file now gets a target (hooks and utilities resolve to the nearest importing component, falling back to the dependents the dependency graph found), directories and deleted paths are skipped, and the client imports them all before refreshing. On stock Bun the remount fallback rendered the changed child in place of the whole page; it now re-imports the page module for the page on screen and ignores edits that do not reach it.
|
|
35
|
+
- **React Fast Refresh is used when Bun supports it, instead of always falling back to a remount**
|
|
36
|
+
The dev server decides between React Fast Refresh and the stock-Bun remount fallback by transpiling a probe component. The probe was named `__AbsoluteRefreshProbe`; React Fast Refresh registers only capitalized components, so it reported "unsupported" even on a Bun with the reactFastRefresh fix, and React edits always remounted with a warning. It now uses a capitalized name.
|
|
37
|
+
- **A syntax error in a React component shows the error overlay instead of reloading the page**
|
|
38
|
+
A React edit that failed to compile was still broadcast as an update. The browser imported a module that answered 500 and fell back to a full reload, which showed the last good page and no error. The dev server now checks the edited modules compile first and sends the error overlay (file, line and source line) instead; the save that fixes it applies as a normal in-place update. The module server handler and its transform errors also moved to globalThis: after a `bun --hot` reload failed part-way, later imports of the module server got a fresh instance that was never configured, so pre-transforming the changed module silently did nothing.
|
|
39
|
+
|
|
9
40
|
## 0.20.0-beta.122 — 2026-09-27
|
|
10
41
|
|
|
11
42
|
### Fixed
|
package/changelog.json
CHANGED
|
@@ -2,6 +2,66 @@
|
|
|
2
2
|
"contract": 1,
|
|
3
3
|
"name": "@absolutejs/absolute",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"detail": "AbsoluteJS accepted `@absolutejs/auth` only below 0.77, so a project that added a current auth (0.77 to 0.96) got two copies: its own, plus 0.76.3 nested under AbsoluteJS for the mobile shell. The duplicate also doubled the auth type declarations TypeScript loads. AbsoluteJS now accepts auth up to 0.96. The `@absolutejs/auth/client/mobile` API it uses is byte-identical from 0.76.3 to 0.96.0, in both its declarations and its runtime.",
|
|
9
|
+
"kind": "fixed",
|
|
10
|
+
"summary": "Projects on a current `@absolutejs/auth` no longer get a second, older copy"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"detail": "Elysia 2 hands every open, message and close event of a WebSocket a new wrapper object. The dev server tracked HMR clients by that wrapper, so a closed browser tab was never removed (it stayed until a broadcast send threw) and each `ready` message counted the same tab again under `connectedTargets`, so `/hmr-status` reported clients that were gone and more web targets than open sockets. Clients are now tracked by the underlying socket.",
|
|
14
|
+
"kind": "fixed",
|
|
15
|
+
"summary": "`/hmr-status` no longer counts closed or duplicate HMR clients",
|
|
16
|
+
"symbols": [
|
|
17
|
+
"HMRWebSocket"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"date": "2026-09-28",
|
|
22
|
+
"version": "0.20.0-beta.124"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"changes": [
|
|
26
|
+
{
|
|
27
|
+
"detail": "Under `bun --hot`, Bun counts unhandled rejections that no listener claims and never resets the count; while it is non-zero Bun parks the process in a loop that still serves requests and delivers file-watch events but never runs timers. The server entry imports React pages, so saving a React component with a syntax error made Bun's hot reload reject, and from then on the HMR debounce never fired: every edit was detected and queued, including the one that fixed the error, and nothing rebuilt until the dev server restarted. An unhandled rejection in app code did the same. The dev server now claims unhandled rejections and prints them as before, so its timers keep running.",
|
|
28
|
+
"kind": "fixed",
|
|
29
|
+
"summary": "`absolute dev` keeps rebuilding after a syntax error in a React component or an unhandled rejection"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"detail": "`absolute bun-patch install` and the `absolute dev` offer now install `bun-v1.4.0-absolute.2`. The first release was built as a Bun canary build (Bun's build default): it reported `1.4.0-canary.1`, enabled Bun's experimental \"bake\" server features and made `bun upgrade` track canary. absolute.2 is built with `--canary=off`, as Bun's own releases are; the React Fast Refresh fix is unchanged. Run `absolute bun-patch install` to replace an absolute.1 install.",
|
|
33
|
+
"kind": "fixed",
|
|
34
|
+
"summary": "The patched Bun is now a release build, not a canary build"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"detail": "Stock Bun ignores `reactFastRefresh` on `Bun.Transpiler` (oven-sh/bun#32919), so React edits in `absolute dev` remounted the page and lost component state. AbsoluteJS now publishes Bun 1.4.0 with just that fix for every platform Bun ships (github.com/absolutejs/patched-bun). In React projects on stock Bun, `absolute dev` offers it once (Install now / Ask me later / Don't ask again); it installs to ~/.absolutejs/bun, is checked against a pinned SHA-256, and only the dev server uses it, so your `bun` is unchanged. `absolute bun-patch [status|install|remove|reset]` manages it; `ABSOLUTE_PATCHED_BUN=0` opts out.",
|
|
38
|
+
"kind": "added",
|
|
39
|
+
"summary": "React Fast Refresh keeps component state: `absolute dev` can run on AbsoluteJS's patched Bun"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"detail": "The React HMR client had a CSS-only branch that looked up the example app's `ReactExampleCSS` manifest key, so it could never work in another app; the server never sends a CSS-only React update, so it was also unreachable. Removed. Stylesheet edits on React pages go through the general stylesheet swap, now covered by a browser test (the rule applies, component state and the document are kept).",
|
|
43
|
+
"kind": "fixed",
|
|
44
|
+
"summary": "Removed a React HMR CSS branch that only matched the example app"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"detail": "The React fast path told the browser to re-import a single module: the first non-page file in the batch. A new component added to the page re-imported only the new file, so the page never rendered it; a folder created alongside a file became the target and its URL failed to load; and an edited hook or utility whose importer had not been fetched through the module server re-imported just itself, which updates nothing on screen. Every edited file now gets a target (hooks and utilities resolve to the nearest importing component, falling back to the dependents the dependency graph found), directories and deleted paths are skipped, and the client imports them all before refreshing. On stock Bun the remount fallback rendered the changed child in place of the whole page; it now re-imports the page module for the page on screen and ignores edits that do not reach it.",
|
|
48
|
+
"kind": "fixed",
|
|
49
|
+
"summary": "React edits that add a component, touch a hook or utility, or create a folder now update the page in place"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"detail": "The dev server decides between React Fast Refresh and the stock-Bun remount fallback by transpiling a probe component. The probe was named `__AbsoluteRefreshProbe`; React Fast Refresh registers only capitalized components, so it reported \"unsupported\" even on a Bun with the reactFastRefresh fix, and React edits always remounted with a warning. It now uses a capitalized name.",
|
|
53
|
+
"kind": "fixed",
|
|
54
|
+
"summary": "React Fast Refresh is used when Bun supports it, instead of always falling back to a remount"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"detail": "A React edit that failed to compile was still broadcast as an update. The browser imported a module that answered 500 and fell back to a full reload, which showed the last good page and no error. The dev server now checks the edited modules compile first and sends the error overlay (file, line and source line) instead; the save that fixes it applies as a normal in-place update. The module server handler and its transform errors also moved to globalThis: after a `bun --hot` reload failed part-way, later imports of the module server got a fresh instance that was never configured, so pre-transforming the changed module silently did nothing.",
|
|
58
|
+
"kind": "fixed",
|
|
59
|
+
"summary": "A syntax error in a React component shows the error overlay instead of reloading the page"
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"date": "2026-09-28",
|
|
63
|
+
"version": "0.20.0-beta.123"
|
|
64
|
+
},
|
|
5
65
|
{
|
|
6
66
|
"changes": [
|
|
7
67
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-VA5kAM/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-VA5kAM/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-VA5kAM/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/build.js
CHANGED
|
@@ -21873,7 +21873,7 @@ var init_compileAngular = __esm(() => {
|
|
|
21873
21873
|
|
|
21874
21874
|
// node_modules/content-tag/pkg/node/content_tag.cjs
|
|
21875
21875
|
var require_content_tag = __commonJS(function(exports, module) {
|
|
21876
|
-
var __dirname = "/
|
|
21876
|
+
var __dirname = "/home/alexkahn/abs/absolutejs/.claude/worktrees/release/node_modules/content-tag/pkg/node";
|
|
21877
21877
|
var imports = {};
|
|
21878
21878
|
imports["__wbindgen_placeholder__"] = exports;
|
|
21879
21879
|
var wasm;
|
|
@@ -26173,15 +26173,6 @@ var init_fileHashTracker = __esm(() => {
|
|
|
26173
26173
|
});
|
|
26174
26174
|
|
|
26175
26175
|
// src/dev/transformCache.ts
|
|
26176
|
-
var exports_transformCache = {};
|
|
26177
|
-
__export(exports_transformCache, {
|
|
26178
|
-
findNearestComponent: () => findNearestComponent,
|
|
26179
|
-
getInvalidationVersion: () => getInvalidationVersion,
|
|
26180
|
-
getTransformed: () => getTransformed,
|
|
26181
|
-
invalidate: () => invalidate,
|
|
26182
|
-
invalidateAll: () => invalidateAll,
|
|
26183
|
-
setTransformed: () => setTransformed
|
|
26184
|
-
});
|
|
26185
26176
|
var cache, importers, getTransformed = (filePath) => cache.get(filePath)?.content, setTransformed = (filePath, content, mtime, imports) => {
|
|
26186
26177
|
const resolvedImports = imports ?? [];
|
|
26187
26178
|
cache.set(filePath, { content, imports: resolvedImports, mtime });
|
|
@@ -26233,10 +26224,6 @@ var cache, importers, getTransformed = (filePath) => cache.get(filePath)?.conten
|
|
|
26233
26224
|
queue.push(parent);
|
|
26234
26225
|
}
|
|
26235
26226
|
}
|
|
26236
|
-
}, invalidateAll = () => {
|
|
26237
|
-
cache.clear();
|
|
26238
|
-
importers.clear();
|
|
26239
|
-
invalidationVersions.clear();
|
|
26240
26227
|
};
|
|
26241
26228
|
var init_transformCache = __esm(() => {
|
|
26242
26229
|
cache = globalThis.__transformCache ?? new Map;
|
|
@@ -26816,6 +26803,15 @@ var MAX_RETAINED_HMR_UPDATES = 100, normalizedHmrTarget = (value) => {
|
|
|
26816
26803
|
const oldest = state.hmrUpdates.keys().next().value;
|
|
26817
26804
|
if (typeof oldest === "number")
|
|
26818
26805
|
state.hmrUpdates.delete(oldest);
|
|
26806
|
+
}, canonicalClients, canonicalClient = (client) => {
|
|
26807
|
+
const { raw } = client;
|
|
26808
|
+
if (!raw)
|
|
26809
|
+
return client;
|
|
26810
|
+
const known = canonicalClients.get(raw);
|
|
26811
|
+
if (known)
|
|
26812
|
+
return known;
|
|
26813
|
+
canonicalClients.set(raw, client);
|
|
26814
|
+
return client;
|
|
26819
26815
|
}, trySendMessage = (client, messageStr) => {
|
|
26820
26816
|
try {
|
|
26821
26817
|
client.send(messageStr);
|
|
@@ -26842,7 +26838,7 @@ var MAX_RETAINED_HMR_UPDATES = 100, normalizedHmrTarget = (value) => {
|
|
|
26842
26838
|
state.clientTargets.delete(client);
|
|
26843
26839
|
});
|
|
26844
26840
|
}, handleClientConnect = (state, client, manifest) => {
|
|
26845
|
-
state.connectedClients.add(client);
|
|
26841
|
+
state.connectedClients.add(canonicalClient(client));
|
|
26846
26842
|
const serverVersions = serializeModuleVersions(state.moduleVersions);
|
|
26847
26843
|
client.send(JSON.stringify({
|
|
26848
26844
|
data: {
|
|
@@ -26879,8 +26875,11 @@ var MAX_RETAINED_HMR_UPDATES = 100, normalizedHmrTarget = (value) => {
|
|
|
26879
26875
|
}));
|
|
26880
26876
|
}
|
|
26881
26877
|
}, handleClientDisconnect = (state, client) => {
|
|
26882
|
-
|
|
26883
|
-
state.
|
|
26878
|
+
const known = canonicalClient(client);
|
|
26879
|
+
state.connectedClients.delete(known);
|
|
26880
|
+
state.clientTargets.delete(known);
|
|
26881
|
+
if (client.raw)
|
|
26882
|
+
canonicalClients.delete(client.raw);
|
|
26884
26883
|
}, parseJsonSafe = (raw) => JSON.parse(raw), parseMessage = (message) => {
|
|
26885
26884
|
if (typeof message === "string") {
|
|
26886
26885
|
return parseJsonSafe(message);
|
|
@@ -26956,12 +26955,13 @@ var MAX_RETAINED_HMR_UPDATES = 100, normalizedHmrTarget = (value) => {
|
|
|
26956
26955
|
if (!isValidHMRClientMessage(parsedData)) {
|
|
26957
26956
|
return;
|
|
26958
26957
|
}
|
|
26959
|
-
handleParsedMessage(state, client, parsedData);
|
|
26958
|
+
handleParsedMessage(state, canonicalClient(client), parsedData);
|
|
26960
26959
|
} catch {}
|
|
26961
26960
|
};
|
|
26962
26961
|
var init_webSocket = __esm(() => {
|
|
26963
26962
|
init_telemetryEvent();
|
|
26964
26963
|
init_logger();
|
|
26964
|
+
canonicalClients = new WeakMap;
|
|
26965
26965
|
});
|
|
26966
26966
|
|
|
26967
26967
|
// src/utils/loadConfig.ts
|
|
@@ -33053,6 +33053,7 @@ __export(exports_moduleServer, {
|
|
|
33053
33053
|
SRC_URL_PREFIX: () => SRC_URL_PREFIX2,
|
|
33054
33054
|
createDevPageWarmer: () => createDevPageWarmer,
|
|
33055
33055
|
createModuleServer: () => createModuleServer,
|
|
33056
|
+
getTransformError: () => getTransformError,
|
|
33056
33057
|
importedBindingNames: () => importedBindingNames,
|
|
33057
33058
|
invalidateModule: () => invalidateModule,
|
|
33058
33059
|
isReactFastRefreshSupported: () => isReactFastRefreshSupported,
|
|
@@ -33253,7 +33254,7 @@ ${code2}`;
|
|
|
33253
33254
|
reactFastRefresh: true
|
|
33254
33255
|
};
|
|
33255
33256
|
const probe = new Bun.Transpiler(probeOptions);
|
|
33256
|
-
const out = probe.transformSync("export function
|
|
33257
|
+
const out = probe.transformSync("export function AbsoluteRefreshProbe(){return null;}");
|
|
33257
33258
|
return out.includes("$RefreshReg$");
|
|
33258
33259
|
} catch {
|
|
33259
33260
|
return false;
|
|
@@ -33262,7 +33263,7 @@ ${code2}`;
|
|
|
33262
33263
|
if (reactFastRefreshSupported || reactFastRefreshWarningEmitted)
|
|
33263
33264
|
return;
|
|
33264
33265
|
reactFastRefreshWarningEmitted = true;
|
|
33265
|
-
logWarn("React
|
|
33266
|
+
logWarn("React edits remount the page instead of keeping component state: " + "this Bun ignores `reactFastRefresh` on Bun.Transpiler " + "(https://github.com/oven-sh/bun/issues/32919). Run " + "`absolute bun-patch install` to use AbsoluteJS's patched Bun, " + "which has the fix; `absolute dev` then uses it automatically.");
|
|
33266
33267
|
}, transformReactFile = (filePath, projectRoot, rewriter) => {
|
|
33267
33268
|
const raw = readFileSync40(filePath, "utf-8");
|
|
33268
33269
|
const valueExports = tsxTranspiler.scan(raw).exports;
|
|
@@ -33812,7 +33813,27 @@ export default {};
|
|
|
33812
33813
|
const content = await transformVueFile(filePath, projectRoot, rewriter, vueDir, stylePreprocessors);
|
|
33813
33814
|
setTransformed(filePath, content, stat4.mtimeMs, extractImportedFiles(content, projectRoot));
|
|
33814
33815
|
return jsResponse(content);
|
|
33815
|
-
},
|
|
33816
|
+
}, transformErrors, readPosition = (value) => {
|
|
33817
|
+
if (!value || typeof value !== "object")
|
|
33818
|
+
return;
|
|
33819
|
+
const position = Reflect.get(value, "position");
|
|
33820
|
+
if (!position || typeof position !== "object")
|
|
33821
|
+
return;
|
|
33822
|
+
const line = Reflect.get(position, "line");
|
|
33823
|
+
const column = Reflect.get(position, "column");
|
|
33824
|
+
const lineText = Reflect.get(position, "lineText");
|
|
33825
|
+
return {
|
|
33826
|
+
column: typeof column === "number" ? column : undefined,
|
|
33827
|
+
line: typeof line === "number" ? line : undefined,
|
|
33828
|
+
lineText: typeof lineText === "string" ? lineText : undefined
|
|
33829
|
+
};
|
|
33830
|
+
}, describeTransformError = (err) => {
|
|
33831
|
+
const [first] = err instanceof AggregateError && Array.isArray(err.errors) ? err.errors : [err];
|
|
33832
|
+
const source = first ?? err;
|
|
33833
|
+
const ownMessage = source && typeof source === "object" ? Reflect.get(source, "message") : undefined;
|
|
33834
|
+
const message = typeof ownMessage === "string" ? ownMessage : String(source);
|
|
33835
|
+
return { message, ...readPosition(first) };
|
|
33836
|
+
}, getTransformError = (filePath) => transformErrors.get(resolve51(filePath)), transformErrorResponse = (err) => {
|
|
33816
33837
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
33817
33838
|
return new Response(`console.error('[ModuleServer] Transform error:', ${JSON.stringify(errMsg)});`, {
|
|
33818
33839
|
headers: { "Content-Type": "application/javascript" },
|
|
@@ -33840,8 +33861,11 @@ export default {};
|
|
|
33840
33861
|
return virtualCssResponse;
|
|
33841
33862
|
const { filePath, ext } = resolveSourcePath2(relPath, projectRoot);
|
|
33842
33863
|
try {
|
|
33843
|
-
|
|
33864
|
+
const response = await transformAndCache(filePath, ext, projectRoot, rewriter, frameworkDirs?.vue, stylePreprocessors);
|
|
33865
|
+
transformErrors.delete(resolve51(filePath));
|
|
33866
|
+
return response;
|
|
33844
33867
|
} catch (err) {
|
|
33868
|
+
transformErrors.set(resolve51(filePath), describeTransformError(err));
|
|
33845
33869
|
return transformErrorResponse(err);
|
|
33846
33870
|
}
|
|
33847
33871
|
};
|
|
@@ -33854,21 +33878,23 @@ export default {};
|
|
|
33854
33878
|
files.push(resolve51(projectRoot, match[1]));
|
|
33855
33879
|
}
|
|
33856
33880
|
return files;
|
|
33857
|
-
}, invalidateModule = (filePath) => {
|
|
33881
|
+
}, SRC_URL_PREFIX2, invalidateModule = (filePath) => {
|
|
33858
33882
|
const resolved = resolve51(filePath);
|
|
33883
|
+
transformErrors.delete(resolved);
|
|
33859
33884
|
invalidate(filePath);
|
|
33860
33885
|
if (resolved !== filePath)
|
|
33861
33886
|
invalidate(resolved);
|
|
33862
33887
|
mtimeCache.delete(filePath);
|
|
33863
33888
|
mtimeCache.delete(resolved);
|
|
33889
|
+
}, setGlobalModuleServer = (handler) => {
|
|
33890
|
+
globalThis.__absoluteModuleServer = handler ?? undefined;
|
|
33864
33891
|
}, warmCache = async (pathname) => {
|
|
33865
33892
|
if (!pathname.startsWith(SRC_PREFIX))
|
|
33866
33893
|
return;
|
|
33867
|
-
|
|
33894
|
+
const handler = globalThis.__absoluteModuleServer;
|
|
33895
|
+
if (!handler)
|
|
33868
33896
|
return;
|
|
33869
|
-
await
|
|
33870
|
-
}, globalModuleServer = null, SRC_URL_PREFIX2, setGlobalModuleServer = (handler) => {
|
|
33871
|
-
globalModuleServer = handler;
|
|
33897
|
+
await handler(pathname);
|
|
33872
33898
|
}, REBUILD_IDLE_POLL_MS = 10, getDevResult = () => globalThis.__hmrDevResult, resolveDevPageEntry = (keyOrPath) => {
|
|
33873
33899
|
const cached = getDevResult();
|
|
33874
33900
|
const lazy = cached?.hmrState.lazyPages;
|
|
@@ -34039,6 +34065,8 @@ export function __legacyDecorateParamTS(paramIndex, decorator) {
|
|
|
34039
34065
|
return function (target, key) { decorator(target, key, paramIndex); };
|
|
34040
34066
|
}
|
|
34041
34067
|
`.trim();
|
|
34068
|
+
transformErrors = globalThis.__absoluteTransformErrors ?? new Map;
|
|
34069
|
+
globalThis.__absoluteTransformErrors = transformErrors;
|
|
34042
34070
|
SRC_IMPORT_RE = /\/@src\/([^"'?\s]+)/g;
|
|
34043
34071
|
SRC_URL_PREFIX2 = SRC_PREFIX;
|
|
34044
34072
|
});
|
|
@@ -34343,7 +34371,7 @@ __export(exports_rebuildTrigger, {
|
|
|
34343
34371
|
queueFileChange: () => queueFileChange,
|
|
34344
34372
|
triggerRebuild: () => triggerRebuild
|
|
34345
34373
|
});
|
|
34346
|
-
import { existsSync as existsSync47, readdirSync as readdirSync13, rmSync as rmSync4 } from "fs";
|
|
34374
|
+
import { existsSync as existsSync47, readdirSync as readdirSync13, rmSync as rmSync4, statSync as statSync8 } from "fs";
|
|
34347
34375
|
import {
|
|
34348
34376
|
basename as basename21,
|
|
34349
34377
|
dirname as dirname36,
|
|
@@ -35488,28 +35516,76 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, clearDevSs
|
|
|
35488
35516
|
const url = `${SRC_URL_PREFIX3}${rel}`;
|
|
35489
35517
|
await warmCache2(url);
|
|
35490
35518
|
return url;
|
|
35491
|
-
}, getReactModuleUrl,
|
|
35492
|
-
|
|
35493
|
-
|
|
35494
|
-
|
|
35495
|
-
|
|
35496
|
-
|
|
35497
|
-
|
|
35519
|
+
}, getReactModuleUrl, isReactComponentPath = (file5) => file5.endsWith(".tsx") || file5.endsWith(".jsx"), isReactPagePath = (file5) => file5.replace(/\\/g, "/").includes("/pages/"), isImportableModule = (file5) => {
|
|
35520
|
+
try {
|
|
35521
|
+
return statSync8(file5).isFile();
|
|
35522
|
+
} catch {
|
|
35523
|
+
return false;
|
|
35524
|
+
}
|
|
35525
|
+
}, resolveComponentTarget = (file5, reactFiles, edited) => {
|
|
35526
|
+
if (isReactComponentPath(file5))
|
|
35527
|
+
return file5;
|
|
35528
|
+
const nearest = findNearestComponent(resolvePath4(file5));
|
|
35529
|
+
if (nearest && isImportableModule(nearest))
|
|
35530
|
+
return nearest;
|
|
35531
|
+
const dependents = reactFiles.filter((candidate) => !edited.has(candidate) && isReactComponentPath(candidate) && isImportableModule(candidate));
|
|
35532
|
+
return dependents.find((candidate) => !isReactPagePath(candidate)) ?? dependents[0] ?? file5;
|
|
35533
|
+
}, resolveReactUpdateTargets = (state, reactFiles) => {
|
|
35534
|
+
const importable = reactFiles.filter(isImportableModule);
|
|
35535
|
+
const userEdited = importable.filter((file5) => state.lastUserEditedFiles?.has(resolvePath4(file5)));
|
|
35536
|
+
const editedFiles = userEdited.length > 0 ? userEdited : importable;
|
|
35537
|
+
const edited = new Set(editedFiles);
|
|
35538
|
+
const ordered = [
|
|
35539
|
+
...editedFiles.filter((file5) => !isReactPagePath(file5)),
|
|
35540
|
+
...editedFiles.filter(isReactPagePath)
|
|
35541
|
+
];
|
|
35542
|
+
const targets = ordered.map((file5) => resolveComponentTarget(file5, reactFiles, edited));
|
|
35543
|
+
return { editedFiles, targets: [...new Set(targets)] };
|
|
35544
|
+
}, resolveAffectedPageModules = async (reactFiles) => {
|
|
35545
|
+
const pages = reactFiles.filter((file5) => isReactPagePath(file5) && isReactComponentPath(file5) && isImportableModule(file5));
|
|
35546
|
+
const entries = await Promise.all(pages.map(async (page) => [
|
|
35547
|
+
`${basename21(page).replace(/\.[jt]sx$/, "")}Index`,
|
|
35548
|
+
await getReactModuleUrl(page)
|
|
35549
|
+
]));
|
|
35550
|
+
return Object.fromEntries(entries);
|
|
35498
35551
|
}, handleReactModuleServerPath = async (state, reactFiles, startTime, fastRefreshSupported, onRebuildComplete) => {
|
|
35499
|
-
const
|
|
35500
|
-
|
|
35552
|
+
const { invalidateModule: invalidateModule2 } = await getModuleServer();
|
|
35553
|
+
for (const file5 of reactFiles) {
|
|
35554
|
+
invalidateModule2(file5);
|
|
35555
|
+
}
|
|
35556
|
+
const { editedFiles, targets } = resolveReactUpdateTargets(state, reactFiles);
|
|
35557
|
+
const [primaryTarget] = targets;
|
|
35558
|
+
if (!primaryTarget) {
|
|
35501
35559
|
onRebuildComplete({
|
|
35502
35560
|
hmrState: state,
|
|
35503
35561
|
manifest: state.manifest
|
|
35504
35562
|
});
|
|
35505
35563
|
return state.manifest;
|
|
35506
35564
|
}
|
|
35507
|
-
const
|
|
35508
|
-
|
|
35509
|
-
|
|
35565
|
+
const moduleUrls = await Promise.all(targets.map(getReactModuleUrl));
|
|
35566
|
+
await Promise.all(editedFiles.filter((file5) => !targets.includes(file5)).map(getReactModuleUrl));
|
|
35567
|
+
const { getTransformError: getTransformError2 } = await getModuleServer();
|
|
35568
|
+
const failed = [...new Set([...editedFiles, ...targets])].map((file5) => ({ error: getTransformError2(file5), file: file5 })).find((entry) => entry.error !== undefined);
|
|
35569
|
+
if (failed?.error) {
|
|
35570
|
+
broadcastToClients(state, {
|
|
35571
|
+
data: {
|
|
35572
|
+
affectedFrameworks: ["react"],
|
|
35573
|
+
column: failed.error.column,
|
|
35574
|
+
error: failed.error.message,
|
|
35575
|
+
file: failed.file,
|
|
35576
|
+
framework: "react",
|
|
35577
|
+
line: failed.error.line,
|
|
35578
|
+
lineText: failed.error.lineText
|
|
35579
|
+
},
|
|
35580
|
+
message: "React module failed to compile",
|
|
35581
|
+
type: "rebuild-error"
|
|
35582
|
+
});
|
|
35583
|
+
onRebuildComplete({ hmrState: state, manifest: state.manifest });
|
|
35584
|
+
return state.manifest;
|
|
35510
35585
|
}
|
|
35511
|
-
const
|
|
35512
|
-
const pageModuleUrl =
|
|
35586
|
+
const pageModuleUrls = fastRefreshSupported ? undefined : await resolveAffectedPageModules(reactFiles);
|
|
35587
|
+
const [pageModuleUrl] = moduleUrls;
|
|
35588
|
+
const primaryFile = reactFiles.find((file5) => isImportableModule(file5) && !isReactPagePath(file5)) ?? primaryTarget;
|
|
35513
35589
|
if (pageModuleUrl) {
|
|
35514
35590
|
const serverDuration = Date.now() - startTime;
|
|
35515
35591
|
state.lastHmrPath = relative24(process.cwd(), primaryFile).replace(/\\/g, "/");
|
|
@@ -35521,7 +35597,9 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, clearDevSs
|
|
|
35521
35597
|
hasComponentChanges: true,
|
|
35522
35598
|
hasCSSChanges: false,
|
|
35523
35599
|
manifest: state.manifest,
|
|
35600
|
+
moduleUrls,
|
|
35524
35601
|
pageModuleUrl,
|
|
35602
|
+
pageModuleUrls,
|
|
35525
35603
|
primarySource: primaryFile,
|
|
35526
35604
|
serverDuration,
|
|
35527
35605
|
sourceFiles: reactFiles
|
|
@@ -37532,7 +37610,7 @@ __export(exports_devBuild, {
|
|
|
37532
37610
|
devBuild: () => devBuild
|
|
37533
37611
|
});
|
|
37534
37612
|
import { readdir as readdir6 } from "fs/promises";
|
|
37535
|
-
import { existsSync as existsSync49, statSync as
|
|
37613
|
+
import { existsSync as existsSync49, statSync as statSync9 } from "fs";
|
|
37536
37614
|
import { resolve as resolve55 } from "path";
|
|
37537
37615
|
var FRAMEWORK_DIR_KEYS, devClientVendorSourceDir = () => resolve55(import.meta.dir, "../dev/client"), collectDepVendorSourceDirs = (config) => {
|
|
37538
37616
|
const configuredDirs = [
|
|
@@ -37672,7 +37750,7 @@ var FRAMEWORK_DIR_KEYS, devClientVendorSourceDir = () => resolve55(import.meta.d
|
|
|
37672
37750
|
});
|
|
37673
37751
|
}
|
|
37674
37752
|
}, handleCachedReload = async () => {
|
|
37675
|
-
const serverMtime =
|
|
37753
|
+
const serverMtime = statSync9(resolve55(Bun.main)).mtimeMs;
|
|
37676
37754
|
const lastMtime = globalThis.__hmrServerMtime;
|
|
37677
37755
|
globalThis.__hmrServerMtime = serverMtime;
|
|
37678
37756
|
const cached = globalThis.__hmrDevResult;
|
|
@@ -38053,7 +38131,7 @@ var FRAMEWORK_DIR_KEYS, devClientVendorSourceDir = () => resolve55(import.meta.d
|
|
|
38053
38131
|
manifest
|
|
38054
38132
|
};
|
|
38055
38133
|
globalThis.__hmrDevResult = result;
|
|
38056
|
-
globalThis.__hmrServerMtime =
|
|
38134
|
+
globalThis.__hmrServerMtime = statSync9(resolve55(Bun.main)).mtimeMs;
|
|
38057
38135
|
return result;
|
|
38058
38136
|
};
|
|
38059
38137
|
var init_devBuild = __esm(() => {
|
|
@@ -38094,5 +38172,5 @@ export {
|
|
|
38094
38172
|
devBuild
|
|
38095
38173
|
};
|
|
38096
38174
|
|
|
38097
|
-
//# debugId=
|
|
38175
|
+
//# debugId=CE51F4C6C3DEBBDF64756E2164756E21
|
|
38098
38176
|
//# sourceMappingURL=build.js.map
|