Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit 1d6d8c0

Browse files
authored
Merge pull request #462 from alephjs/upgrade-aleph
Upgrade aleph
2 parents 8cc94db + 1251077 commit 1d6d8c0

File tree

13 files changed

+95
-29
lines changed

13 files changed

+95
-29
lines changed

commands/init.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { isCanary, VERSION } from "../version.ts";
1212

1313
const templates = ["react", "preact", "vue", "svelte", "lit", "vanilla", "api"];
1414
const versions = {
15-
react: "18.0.0",
15+
react: "18.1.0",
1616
vue: "3.2.31",
1717
};
1818

deno.dom.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"./types.d.ts"
1111
],
1212
"jsx": "react-jsx",
13-
"jsxImportSource": "https://esm.sh/react@18.0.0"
13+
"jsxImportSource": "https://esm.sh/react@18.1.0"
1414
},
1515
"fmt": {
1616
"files": {

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
33
"jsx": "react-jsx",
4-
"jsxImportSource": "https://esm.sh/react@18.0.0"
4+
"jsxImportSource": "https://esm.sh/react@18.1.0"
55
},
66
"tasks": {
77
"test": "deno test -A --unstable --location=http://localhost --import-map=import_map.json",

examples/feature-apps/monaco-editor/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
</head>
3232

3333
<body>
34-
<div id="root"><!-- ssr-body --></div>
34+
<div id="root" data-ssr-root></div>
3535
<script type="module" src="./main.tsx"></script>
3636
</body>
3737

examples/feature-apps/suspense-ssr/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</head>
99

1010
<body>
11-
<div id="root"><!-- ssr-body --></div>
11+
<div id="root" data-ssr-root></div>
1212
<script type="module" src="./main.tsx"></script>
1313
</body>
1414

examples/feature-apps/unocss/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
</head>
3535

3636
<body>
37-
<div id="root"><!-- ssr-body --></div>
37+
<div id="root" data-ssr-root></div>
3838
<script type="module" src="./main.tsx"></script>
3939
</body>
4040

examples/react-app/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</head>
1010

1111
<body>
12-
<div id="root"><!-- ssr-body --></div>
12+
<div id="root" data-ssr-root></div>
1313
<script type="module" src="./main.tsx"></script>
1414
</body>
1515

examples/vue-app/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</head>
2020

2121
<body>
22-
<div id="root"><!-- ssr-body --></div>
22+
<div id="root" data-ssr-root></div>
2323
<script type="module" src="./main.js"></script>
2424
</body>
2525

framework/core/redirect.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import util from "../../lib/util.ts";
22
import events from "./events.ts";
33

44
let routerReady = false;
5-
let preRedirect: { url: URL; replace?: boolean } | null = null;
5+
let preRedirect: URL | null = null;
66

77
const onrouterready = (_: Record<string, unknown>) => {
88
events.off("routerready", onrouterready);
99
if (preRedirect) {
10-
events.emit("popstate", { type: "popstate", ...preRedirect });
10+
events.emit("popstate", { type: "popstate", url: preRedirect });
1111
preRedirect = null;
1212
}
1313
routerReady = true;
@@ -26,14 +26,20 @@ export function redirect(url: string, replace?: boolean) {
2626
return;
2727
}
2828

29-
const next = new URL(url, location.href);
30-
if (next.href === location.href) {
29+
const to = new URL(url, location.href);
30+
if (to.href === location.href) {
3131
return;
3232
}
3333

34+
if (replace) {
35+
history.replaceState(null, "", to);
36+
} else {
37+
history.pushState(null, "", to);
38+
}
39+
3440
if (routerReady) {
35-
events.emit("popstate", { type: "popstate", url: next, replace });
41+
events.emit("popstate", { type: "popstate", url: to });
3642
} else {
37-
preRedirect = { url: next, replace };
43+
preRedirect = to;
3844
}
3945
}

framework/react/router.ts

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export type RouterProps = {
2222
readonly suspense?: boolean;
2323
};
2424

25-
type DataCache = {
25+
type RouteData = {
2626
data?: unknown;
2727
dataCacheTtl?: number;
2828
dataExpires?: number;
@@ -35,7 +35,7 @@ export const Router: FC<RouterProps> = ({ ssrContext, suspense }) => {
3535
const [url, setUrl] = useState(() => ssrContext?.url || new URL(window.location?.href));
3636
const [modules, setModules] = useState(() => ssrContext?.routeModules || loadSSRModulesFromTag());
3737
const dataCache = useMemo(() => {
38-
const cache = new Map<string, DataCache>();
38+
const cache = new Map<string, RouteData>();
3939
modules.forEach(({ url, data, dataCacheTtl }) => {
4040
cache.set(url.pathname + url.search, {
4141
data,
@@ -108,7 +108,7 @@ export const Router: FC<RouterProps> = ({ ssrContext, suspense }) => {
108108
};
109109
const isSuspense = document.body.getAttribute("data-suspense") ?? suspense;
110110
const prefetchData = async (dataUrl: string) => {
111-
const cache: DataCache = {};
111+
const rd: RouteData = {};
112112
const fetchData = async () => {
113113
const res = await fetch(dataUrl, { headers: { "Accept": "application/json" }, redirect: "manual" });
114114
if (res.status === 404 || res.status === 405) {
@@ -125,16 +125,16 @@ export const Router: FC<RouterProps> = ({ ssrContext, suspense }) => {
125125
throw new FetchError(500, {}, "Missing the `Location` header");
126126
}
127127
const cc = res.headers.get("Cache-Control");
128-
cache.dataCacheTtl = cc?.includes("max-age=") ? parseInt(cc.split("max-age=")[1]) : undefined;
129-
cache.dataExpires = Date.now() + (cache.dataCacheTtl || 1) * 1000;
128+
rd.dataCacheTtl = cc?.includes("max-age=") ? parseInt(cc.split("max-age=")[1]) : undefined;
129+
rd.dataExpires = Date.now() + (rd.dataCacheTtl || 1) * 1000;
130130
return await res.json();
131131
};
132132
if (isSuspense) {
133-
cache.data = fetchData;
133+
rd.data = fetchData;
134134
} else {
135-
cache.data = await fetchData();
135+
rd.data = await fetchData();
136136
}
137-
dataCache.set(dataUrl, cache);
137+
dataCache.set(dataUrl, rd);
138138
};
139139
const onmoduleprefetch = (e: Record<string, unknown>) => {
140140
const pageUrl = new URL(e.href as string, location.href);
@@ -152,6 +152,12 @@ export const Router: FC<RouterProps> = ({ ssrContext, suspense }) => {
152152
const onpopstate = async (e: Record<string, unknown>) => {
153153
const url = (e.url as URL | undefined) || new URL(window.location.href);
154154
const matches = matchRoutes(url, routes);
155+
const loadingBar = getLoadingBar();
156+
let loading: number | null = setTimeout(() => {
157+
loading = null;
158+
loadingBar.style.opacity = "1";
159+
loadingBar.style.width = "50%";
160+
}, 200);
155161
const modules = await Promise.all(matches.map(async ([ret, meta]) => {
156162
const { filename } = meta;
157163
const rmod: RouteModule = {
@@ -173,12 +179,31 @@ export const Router: FC<RouterProps> = ({ ssrContext, suspense }) => {
173179
}));
174180
setModules(modules);
175181
setUrl(url);
176-
if (e.url) {
177-
if (e.replace) {
178-
history.replaceState(null, "", e.url as URL);
182+
setTimeout(() => {
183+
if (loading) {
184+
clearTimeout(loading);
185+
loadingBar.remove();
179186
} else {
180-
history.pushState(null, "", e.url as URL);
187+
const moveOutTime = 0.7;
188+
const fadeOutTime = 0.3;
189+
const t1 = setTimeout(() => {
190+
loadingBar.style.opacity = "0";
191+
}, moveOutTime * 1000);
192+
const t2 = setTimeout(() => {
193+
global.__loading_bar_cleanup = null;
194+
loadingBar.remove();
195+
}, (moveOutTime + fadeOutTime) * 1000);
196+
global.__loading_bar_cleanup = () => {
197+
clearTimeout(t1);
198+
clearTimeout(t2);
199+
};
200+
loadingBar.style.transition = `opacity ${fadeOutTime}s ease-out, width ${moveOutTime}s ease-in-out`;
201+
setTimeout(() => {
202+
loadingBar.style.width = "100%";
203+
}, 0);
181204
}
205+
}, 0);
206+
if (e.url) {
182207
window.scrollTo(0, 0);
183208
}
184209
};
@@ -291,6 +316,31 @@ function loadSSRModulesFromTag(): RouteModule[] {
291316
return [];
292317
}
293318

319+
function getLoadingBar(): HTMLDivElement {
320+
if (typeof global.__loading_bar_cleanup === "function") {
321+
global.__loading_bar_cleanup();
322+
global.__loading_bar_cleanup = null;
323+
}
324+
let bar = (document.getElementById("loading-bar") as HTMLDivElement | null);
325+
if (!bar) {
326+
bar = document.createElement("div");
327+
bar.id = "loading-bar";
328+
document.body.appendChild(bar);
329+
}
330+
Object.assign(bar.style, {
331+
position: "fixed",
332+
top: "0",
333+
left: "0",
334+
zIndex: "9999",
335+
width: "0",
336+
height: "1px",
337+
opacity: "0",
338+
background: "rgba(128, 128, 128, 0.9)",
339+
transition: "opacity 0.6s ease-in, width 3s ease-in",
340+
});
341+
return bar;
342+
}
343+
294344
function getRouteModules(): Record<string, { defaultExport?: unknown; withData?: boolean }> {
295345
return global.__ROUTE_MODULES || (global.__ROUTE_MODULES = {});
296346
}

0 commit comments

Comments
 (0)