@absolutejs/absolute 0.20.0-beta.139 → 0.20.0-beta.140
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 +11 -0
- package/changelog.json +21 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +25 -6
- package/dist/build.js.map +6 -6
- package/dist/dev/client/hmrClient.ts +88 -36
- package/dist/dev/client/reconnect.ts +43 -0
- package/dist/index.js +25 -6
- package/dist/index.js.map +6 -6
- package/dist/src/build/buildReactVendor.d.ts +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ 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.140 — 2026-10-18
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Dev pages reconnect after a dropped connection without reloading, and keep trying through long outages**
|
|
14
|
+
When the dev-server socket dropped, `absolute dev` pages polled for about 18 seconds and reloaded as soon as the server answered. On weak wifi every network change became a full reload, refetching every stylesheet and script and losing the page's state, and an outage longer than 18 seconds left the page disconnected until a manual reload. The page now reconnects the socket for up to 30 minutes, backing off from half a second to ten, waits for the network instead of retrying while the browser is offline, and retries at once when the network or the tab returns. It reloads only if it missed something: the server restarted, or sent an update while the page was away. The server now includes when it started and when it last sent an update in the manifest it sends each connecting page. The banner says when the browser is offline.
|
|
15
|
+
- **Production builds ship React's production build (react-dom 903 KB → 400 KB, no development checks)**
|
|
16
|
+
Production builds bundled React into its vendor files without setting `process.env.NODE_ENV`, so React picked its development build: `react-dom_client.js` was 903 KB, and React ran its development checks in every production page. Production builds now set `process.env.NODE_ENV` to `"production"`: 400 KB, 81 KB gzipped. Only whitespace is minified; renaming identifiers or minifying syntax across the split vendor chunks makes Bun emit an export named `__INVALID__REF__`, which stopped compiled executables from hydrating. `absolute dev` is unchanged; Fast Refresh needs the development build.
|
|
17
|
+
- **Edits to class components and `memo`/`forwardRef` wrappers appear in `absolute dev` without a reload**
|
|
18
|
+
React Fast Refresh updates the components it registered. Editing a module that registers none (a class component, or a `memo`/`forwardRef` wrapper the transpiler does not register) re-ran only that module, and its importer kept rendering the old one, so the edit never showed until a reload. The update now also re-imports the module's importers up to the nearest one that registers a component, so the edit appears and the rest of the page keeps its state.
|
|
19
|
+
|
|
9
20
|
## 0.20.0-beta.139 — 2026-10-16
|
|
10
21
|
|
|
11
22
|
### Changed
|
package/changelog.json
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
"contract": 1,
|
|
3
3
|
"name": "@absolutejs/absolute",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"detail": "When the dev-server socket dropped, `absolute dev` pages polled for about 18 seconds and reloaded as soon as the server answered. On weak wifi every network change became a full reload, refetching every stylesheet and script and losing the page's state, and an outage longer than 18 seconds left the page disconnected until a manual reload. The page now reconnects the socket for up to 30 minutes, backing off from half a second to ten, waits for the network instead of retrying while the browser is offline, and retries at once when the network or the tab returns. It reloads only if it missed something: the server restarted, or sent an update while the page was away. The server now includes when it started and when it last sent an update in the manifest it sends each connecting page. The banner says when the browser is offline.",
|
|
9
|
+
"kind": "fixed",
|
|
10
|
+
"summary": "Dev pages reconnect after a dropped connection without reloading, and keep trying through long outages"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"detail": "Production builds bundled React into its vendor files without setting `process.env.NODE_ENV`, so React picked its development build: `react-dom_client.js` was 903 KB, and React ran its development checks in every production page. Production builds now set `process.env.NODE_ENV` to `\"production\"`: 400 KB, 81 KB gzipped. Only whitespace is minified; renaming identifiers or minifying syntax across the split vendor chunks makes Bun emit an export named `__INVALID__REF__`, which stopped compiled executables from hydrating. `absolute dev` is unchanged; Fast Refresh needs the development build.",
|
|
14
|
+
"kind": "fixed",
|
|
15
|
+
"summary": "Production builds ship React's production build (react-dom 903 KB → 400 KB, no development checks)"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"detail": "React Fast Refresh updates the components it registered. Editing a module that registers none (a class component, or a `memo`/`forwardRef` wrapper the transpiler does not register) re-ran only that module, and its importer kept rendering the old one, so the edit never showed until a reload. The update now also re-imports the module's importers up to the nearest one that registers a component, so the edit appears and the rest of the page keeps its state.",
|
|
19
|
+
"kind": "fixed",
|
|
20
|
+
"summary": "Edits to class components and `memo`/`forwardRef` wrappers appear in `absolute dev` without a reload"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"date": "2026-10-18",
|
|
24
|
+
"version": "0.20.0-beta.140"
|
|
25
|
+
},
|
|
5
26
|
{
|
|
6
27
|
"changes": [
|
|
7
28
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// .angular-partial-tmp-
|
|
2
|
+
// .angular-partial-tmp-UKvYic/src/core/streamingSlotRegistrar.ts
|
|
3
3
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
4
4
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
5
5
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// .angular-partial-tmp-
|
|
2
|
+
// .angular-partial-tmp-UKvYic/src/core/streamingSlotRegistrar.ts
|
|
3
3
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
4
4
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
5
5
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -46,7 +46,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
46
46
|
getWarningController()?.maybeWarn(primitiveName);
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
// .angular-partial-tmp-
|
|
49
|
+
// .angular-partial-tmp-UKvYic/src/core/streamingSlotRegistry.ts
|
|
50
50
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
51
51
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
52
52
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
package/dist/build.js
CHANGED
|
@@ -22361,7 +22361,7 @@ var resolveJsxDevRuntimeCompatPath = () => {
|
|
|
22361
22361
|
return `${lines.join(`
|
|
22362
22362
|
`)}
|
|
22363
22363
|
`;
|
|
22364
|
-
}, buildReactVendor = async (buildDir) => {
|
|
22364
|
+
}, buildReactVendor = async (buildDir, { production = false } = {}) => {
|
|
22365
22365
|
const vendorDir = join41(buildDir, "react", "vendor");
|
|
22366
22366
|
mkdirSync8(vendorDir, { recursive: true });
|
|
22367
22367
|
const tmpDir = join41(buildDir, "_vendor_tmp");
|
|
@@ -22375,9 +22375,10 @@ var resolveJsxDevRuntimeCompatPath = () => {
|
|
|
22375
22375
|
return entryPath;
|
|
22376
22376
|
}));
|
|
22377
22377
|
const result = await bunBuild3({
|
|
22378
|
+
...production ? { define: { "process.env.NODE_ENV": '"production"' } } : {},
|
|
22378
22379
|
entrypoints,
|
|
22379
22380
|
format: "esm",
|
|
22380
|
-
minify: false,
|
|
22381
|
+
minify: production ? { whitespace: true } : false,
|
|
22381
22382
|
naming: "[name].[ext]",
|
|
22382
22383
|
outdir: vendorDir,
|
|
22383
22384
|
splitting: true,
|
|
@@ -23893,7 +23894,7 @@ ${offenders.map((o) => ` \u2022 ${o}`).join(`
|
|
|
23893
23894
|
}
|
|
23894
23895
|
if (!hmr && reactDir) {
|
|
23895
23896
|
await Promise.resolve().then(() => init_buildReactVendor());
|
|
23896
|
-
await buildReactVendor(buildPath);
|
|
23897
|
+
await buildReactVendor(buildPath, { production: !isDev });
|
|
23897
23898
|
vendorPaths = computeVendorPaths();
|
|
23898
23899
|
setDevVendorPaths(vendorPaths);
|
|
23899
23900
|
}
|
|
@@ -26567,12 +26568,14 @@ var MAX_RETAINED_HMR_UPDATES = 100, normalizedHmrTarget = (value) => {
|
|
|
26567
26568
|
state.connectedClients.delete(client);
|
|
26568
26569
|
state.clientTargets.delete(client);
|
|
26569
26570
|
});
|
|
26570
|
-
}, handleClientConnect = (state, client, manifest) => {
|
|
26571
|
+
}, SERVER_STARTED_AT, handleClientConnect = (state, client, manifest) => {
|
|
26571
26572
|
state.connectedClients.add(canonicalClient(client));
|
|
26572
26573
|
const serverVersions = serializeModuleVersions(state.moduleVersions);
|
|
26573
26574
|
client.send(JSON.stringify({
|
|
26574
26575
|
data: {
|
|
26576
|
+
lastBroadcastAt: state.lastBroadcastTimestamp,
|
|
26575
26577
|
manifest,
|
|
26578
|
+
serverStartedAt: SERVER_STARTED_AT,
|
|
26576
26579
|
serverVersions
|
|
26577
26580
|
},
|
|
26578
26581
|
timestamp: Date.now(),
|
|
@@ -26692,6 +26695,7 @@ var init_webSocket = __esm(() => {
|
|
|
26692
26695
|
init_telemetryEvent();
|
|
26693
26696
|
init_logger();
|
|
26694
26697
|
canonicalClients = new WeakMap;
|
|
26698
|
+
SERVER_STARTED_AT = Math.round(performance.timeOrigin);
|
|
26695
26699
|
});
|
|
26696
26700
|
|
|
26697
26701
|
// src/utils/loadConfig.ts
|
|
@@ -35009,6 +35013,20 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, clearDevSs
|
|
|
35009
35013
|
return nearest;
|
|
35010
35014
|
const dependents = reactFiles.filter((candidate) => !edited.has(candidate) && isReactComponentPath(candidate) && isImportableModule(candidate));
|
|
35011
35015
|
return dependents.find((candidate) => !isReactPagePath(candidate)) ?? dependents[0] ?? file;
|
|
35016
|
+
}, MAX_REFRESH_BOUNDARY_HOPS = 8, registersRefreshComponent = (file) => /\$RefreshReg\$\(/u.test(getTransformed(resolvePath4(file)) ?? ""), refreshBoundaryUrls = async (targets) => {
|
|
35017
|
+
const urls = [];
|
|
35018
|
+
const seen = new Set(targets.map((file) => resolvePath4(file)));
|
|
35019
|
+
const climb = async (file, hops) => {
|
|
35020
|
+
const importer = findNearestComponent(resolvePath4(file));
|
|
35021
|
+
if (!importer || seen.has(importer) || hops >= MAX_REFRESH_BOUNDARY_HOPS)
|
|
35022
|
+
return;
|
|
35023
|
+
seen.add(importer);
|
|
35024
|
+
urls.push(await getReactModuleUrl(importer));
|
|
35025
|
+
if (!registersRefreshComponent(importer))
|
|
35026
|
+
await climb(importer, hops + 1);
|
|
35027
|
+
};
|
|
35028
|
+
await targets.reduce((previous, target) => previous.then(() => registersRefreshComponent(target) ? undefined : climb(target, 0)), Promise.resolve());
|
|
35029
|
+
return urls;
|
|
35012
35030
|
}, resolveReactUpdateTargets = (state, reactFiles) => {
|
|
35013
35031
|
const importable = reactFiles.filter(isImportableModule);
|
|
35014
35032
|
const userEdited = importable.filter((file) => state.lastUserEditedFiles?.has(resolvePath4(file)));
|
|
@@ -35041,7 +35059,8 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, clearDevSs
|
|
|
35041
35059
|
});
|
|
35042
35060
|
return state.manifest;
|
|
35043
35061
|
}
|
|
35044
|
-
const
|
|
35062
|
+
const targetUrls = await Promise.all(targets.map(getReactModuleUrl));
|
|
35063
|
+
const moduleUrls = fastRefreshSupported ? [...targetUrls, ...await refreshBoundaryUrls(targets)] : targetUrls;
|
|
35045
35064
|
await Promise.all(editedFiles.filter((file) => !targets.includes(file)).map(getReactModuleUrl));
|
|
35046
35065
|
const { getTransformError } = await getModuleServer();
|
|
35047
35066
|
const failed = [...new Set([...editedFiles, ...targets])].map((file) => ({ error: getTransformError(file), file })).find((entry) => entry.error !== undefined);
|
|
@@ -37625,5 +37644,5 @@ export {
|
|
|
37625
37644
|
devBuild
|
|
37626
37645
|
};
|
|
37627
37646
|
|
|
37628
|
-
//# debugId=
|
|
37647
|
+
//# debugId=FA2E655602E07F4664756E2164756E21
|
|
37629
37648
|
//# sourceMappingURL=build.js.map
|