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

Commit 3cdf548

Browse files
Craig DoremusCraig Doremus
authored andcommitted
Merge branch 'master' into add-test-redirect
2 parents 3005c10 + 8798587 commit 3cdf548

File tree

17 files changed

+206
-145
lines changed

17 files changed

+206
-145
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ deno test -A --location=http://127.0.0.1 --import-map=./import_map.json
3636

3737
## Project Structure
3838

39+
- **/bundler** bundler for production mode
3940
- **/cli** commands code
4041
- **/compiler** compiler in rust powered by swc
4142
- **/framework**

bundler/mod.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import {
1616

1717
export const bundlerRuntimeCode = (`
1818
window.__ALEPH = {
19-
baseURL: '/',
19+
basePath: '/',
2020
pack: {},
2121
bundledFiles: {},
2222
import: function(u, F) {
23-
var b = this.baseURL,
23+
var b = this.basePath,
2424
a = this.pack,
2525
l = this.bundledFiles;
2626
if (u in a) {

framework/core/hmr.ts

Lines changed: 83 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Module {
2222
this._isLocked = true
2323
}
2424

25-
accept(callback?: () => void): void {
25+
accept(callback?: Callback): void {
2626
if (this._isLocked) {
2727
return
2828
}
@@ -45,69 +45,94 @@ class Module {
4545
}
4646
}
4747

48-
const { location } = window as any
49-
const { protocol, host } = location
5048
const modules: Map<string, Module> = new Map()
51-
const messageQueue: any[] = []
52-
const url = (protocol === 'https:' ? 'wss' : 'ws') + '://' + host + '/_hmr'
53-
const socket = new WebSocket(url)
49+
const state: {
50+
socket: WebSocket | null
51+
messageQueue: string[]
52+
} = {
53+
socket: null,
54+
messageQueue: []
55+
}
5456

55-
socket.addEventListener('open', () => {
56-
messageQueue.forEach(msg => socket.send(JSON.stringify(msg)))
57-
messageQueue.splice(0, messageQueue.length)
58-
console.log('[HMR] listening for file changes...')
59-
})
57+
function sendMessage(msg: any) {
58+
const json = JSON.stringify(msg)
59+
if (!state.socket || state.socket.readyState !== WebSocket.OPEN) {
60+
state.messageQueue.push(json)
61+
} else {
62+
state.socket.send(json)
63+
}
64+
}
6065

61-
socket.addEventListener('close', () => {
62-
location.reload()
63-
})
66+
export function connect(basePath: string) {
67+
const { location } = window as any
68+
const { protocol, host } = location
69+
const url = (protocol === 'https:' ? 'wss' : 'ws') + '://' + host + basePath.replace(/\/+$/, '') + '/_hmr'
70+
const ws = new WebSocket(url)
6471

65-
socket.addEventListener('message', ({ data }: { data?: string }) => {
66-
if (data) {
67-
try {
68-
const {
69-
type,
70-
url,
71-
updateUrl,
72-
routePath,
73-
isIndex,
74-
useDeno,
75-
} = JSON.parse(data)
76-
switch (type) {
77-
case 'add':
78-
events.emit('add-module', {
79-
url,
80-
routePath,
81-
isIndex,
82-
useDeno,
83-
})
84-
break
85-
case 'update':
86-
const mod = modules.get(url)
87-
if (mod) {
88-
mod.applyUpdate(updateUrl)
89-
}
90-
break
91-
case 'remove':
92-
if (modules.has(url)) {
93-
modules.delete(url)
94-
events.emit('remove-module', url)
95-
}
96-
break
97-
}
98-
console.log(`[HMR] ${type} module '${url}'`)
99-
} catch (err) {
100-
console.warn(err)
72+
ws.addEventListener('open', () => {
73+
state.socket = ws
74+
state.messageQueue.splice(0, state.messageQueue.length).forEach(msg => ws.send(msg))
75+
console.log('[HMR] listening for file changes...')
76+
})
77+
78+
ws.addEventListener('close', () => {
79+
if (state.socket === null) {
80+
// re-connect
81+
setTimeout(() => {
82+
connect(basePath)
83+
}, 300)
84+
} else {
85+
state.socket = null
86+
console.log('[HMR] closed.')
87+
// reload the page when re-connected
88+
setInterval(() => {
89+
const ws = new WebSocket(url)
90+
ws.addEventListener('open', () => {
91+
location.reload()
92+
})
93+
}, 300)
10194
}
102-
}
103-
})
95+
})
10496

105-
function sendMessage(msg: any) {
106-
if (socket.readyState !== socket.OPEN) {
107-
messageQueue.push(msg)
108-
} else {
109-
socket.send(JSON.stringify(msg))
110-
}
97+
ws.addEventListener('message', ({ data }: { data?: string }) => {
98+
if (data) {
99+
try {
100+
const {
101+
type,
102+
url,
103+
updateUrl,
104+
routePath,
105+
isIndex,
106+
useDeno,
107+
} = JSON.parse(data)
108+
switch (type) {
109+
case 'add':
110+
events.emit('add-module', {
111+
url,
112+
routePath,
113+
isIndex,
114+
useDeno,
115+
})
116+
break
117+
case 'update':
118+
const mod = modules.get(url)
119+
if (mod) {
120+
mod.applyUpdate(updateUrl)
121+
}
122+
break
123+
case 'remove':
124+
if (modules.has(url)) {
125+
modules.delete(url)
126+
events.emit('remove-module', url)
127+
}
128+
break
129+
}
130+
console.log(`[HMR] ${type} module '${url}'`)
131+
} catch (err) {
132+
console.warn(err)
133+
}
134+
}
135+
})
111136
}
112137

113138
export function createHotContext(url: string) {

framework/core/module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ export function trimModuleExt(url: string) {
2525
return url
2626
}
2727

28-
export function importModule(baseUrl: string, url: string, forceRefetch = false): Promise<any> {
28+
export function importModule(basePath: string, url: string, forceRefetch = false): Promise<any> {
2929
const { __ALEPH: ALEPH } = window as any
3030

3131
if (ALEPH) {
3232
return ALEPH.import(url, forceRefetch)
3333
}
3434

35-
let src = util.cleanPath(baseUrl + '/_aleph/' + trimModuleExt(url) + '.js')
35+
let src = util.cleanPath(basePath + '/_aleph/' + trimModuleExt(url) + '.js')
3636
if (forceRefetch) {
3737
src += '?t=' + Date.now()
3838
}

framework/core/routing.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,36 @@ export type RouteModule = {
1616
}
1717

1818
export type RoutingOptions = {
19-
baseURL?: string
19+
basePath?: string
2020
defaultLocale?: string
2121
locales?: string[]
2222
routes?: Route[]
2323
rewrites?: Record<string, string>
2424
}
2525

2626
export class Routing {
27-
private _baseURL: string
27+
private _basePath: string
2828
private _defaultLocale: string
2929
private _locales: string[]
3030
private _routes: Route[]
3131
private _rewrites: Record<string, string>
3232

3333
constructor({
34-
baseURL = '/',
34+
basePath = '/',
3535
defaultLocale = 'en',
3636
locales = [],
3737
routes = [],
3838
rewrites = {}
3939
}: RoutingOptions) {
40-
this._baseURL = baseURL
40+
this._basePath = basePath
4141
this._defaultLocale = defaultLocale
4242
this._locales = locales
4343
this._routes = routes
4444
this._rewrites = rewrites
4545
}
4646

47-
get baseURL() {
48-
return this._baseURL
47+
get basePath() {
48+
return this._basePath
4949
}
5050

5151
get paths() {
@@ -128,7 +128,7 @@ export class Routing {
128128

129129
createRouter(location?: { pathname: string, search?: string }): [RouterURL, RouteModule[]] {
130130
const loc = location || (window as any).location || { pathname: '/' }
131-
const url = rewriteURL(loc.pathname + (loc.search || ''), this._baseURL, this._rewrites)
131+
const url = rewriteURL(loc.pathname + (loc.search || ''), this._basePath, this._rewrites)
132132

133133
let locale = this._defaultLocale
134134
let pathname = decodeURI(url.pathname)
@@ -163,7 +163,7 @@ export class Routing {
163163

164164
return [
165165
{
166-
baseURL: this._baseURL,
166+
basePath: this._basePath,
167167
locale,
168168
pathname,
169169
routePath,
@@ -235,9 +235,9 @@ function matchPath(routePath: string, locPath: string): [Record<string, string>,
235235
return [params, true]
236236
}
237237

238-
export function createBlankRouterURL(baseURL = '/', locale = 'en'): RouterURL {
238+
export function createBlankRouterURL(basePath = '/', locale = 'en'): RouterURL {
239239
return {
240-
baseURL,
240+
basePath,
241241
locale,
242242
routePath: '',
243243
pathname: '/',
@@ -249,10 +249,10 @@ export function createBlankRouterURL(baseURL = '/', locale = 'en'): RouterURL {
249249
}
250250

251251
/** `rewriteURL` returns a rewrited URL */
252-
export function rewriteURL(reqUrl: string, baseURL: string, rewrites: Record<string, string>): URL {
252+
export function rewriteURL(reqUrl: string, basePath: string, rewrites: Record<string, string>): URL {
253253
const url = new URL('http://localhost' + reqUrl)
254-
if (baseURL !== '/') {
255-
url.pathname = util.trimPrefix(decodeURI(url.pathname), baseURL)
254+
if (basePath !== '/') {
255+
url.pathname = util.trimPrefix(decodeURI(url.pathname), basePath)
256256
}
257257
for (const path in rewrites) {
258258
const to = rewrites[path]

framework/react/bootstrap.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ type BootstrapOptions = Required<RoutingOptions> & {
1212
}
1313

1414
export default async function bootstrap(options: BootstrapOptions) {
15-
const { baseURL, defaultLocale, locales, routes, rewrites, sharedModules, renderMode } = options
15+
const { basePath, defaultLocale, locales, routes, rewrites, sharedModules, renderMode } = options
1616
const { document } = window as any
1717
const customComponents: Record<string, { C: ComponentType, useDeno?: boolean }> = {}
1818
await Promise.all(sharedModules.map(async ({ url, useDeno }) => {
19-
const { default: C } = await importModule(baseURL, url)
19+
const { default: C } = await importModule(basePath, url)
2020
switch (trimModuleExt(url)) {
2121
case '/404':
2222
customComponents['E404'] = { C, useDeno }
@@ -26,10 +26,10 @@ export default async function bootstrap(options: BootstrapOptions) {
2626
break
2727
}
2828
}))
29-
const routing = new Routing({ routes, rewrites, baseURL, defaultLocale, locales })
29+
const routing = new Routing({ routes, rewrites, basePath, defaultLocale, locales })
3030
const [url, nestedModules] = routing.createRouter()
3131
const imports = nestedModules.map(async mod => {
32-
const { default: Component } = await importModule(baseURL, mod.url)
32+
const { default: Component } = await importModule(basePath, mod.url)
3333
return {
3434
url: mod.url,
3535
Component

framework/react/components/ErrorBoundary.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { Component, createElement, CSSProperties } from 'react'
22

3-
export class ErrorBoundary extends Component {
4-
state: { error: Error | null }
5-
3+
export class ErrorBoundary extends Component<{}, { error: Error | null }> {
64
constructor(props: any) {
75
super(props)
86
this.state = { error: null }

framework/react/components/Router.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ export default function Router({
4747
})
4848
const [route, setRoute] = useState<PageRoute>(pageRoute)
4949
const onpopstate = useCallback(async (e: any) => {
50-
const { baseURL } = routing
50+
const { basePath } = routing
5151
const [url, nestedModules] = routing.createRouter()
5252
if (url.routePath !== '') {
5353
const imports = nestedModules.map(async mod => {
54-
const { default: Component } = await importModule(baseURL, mod.url, e.forceRefetch)
54+
const { default: Component } = await importModule(basePath, mod.url, e.forceRefetch)
5555
return {
5656
url: mod.url,
5757
Component
@@ -81,11 +81,11 @@ export default function Router({
8181

8282
useEffect(() => {
8383
const isDev = !('__ALEPH' in window)
84-
const { baseURL } = routing
84+
const { basePath } = routing
8585
const onAddModule = async (mod: RouteModule & { routePath?: string, isIndex?: boolean }) => {
8686
switch (mod.url) {
8787
case '/404.js': {
88-
const { default: Component } = await importModule(baseURL, mod.url, true)
88+
const { default: Component } = await importModule(basePath, mod.url, true)
8989
if (isLikelyReactComponent(Component)) {
9090
setE404({ Component })
9191
} else {
@@ -94,7 +94,7 @@ export default function Router({
9494
break
9595
}
9696
case '/app.js': {
97-
const { default: Component } = await importModule(baseURL, mod.url, true)
97+
const { default: Component } = await importModule(basePath, mod.url, true)
9898
if (isLikelyReactComponent(Component)) {
9999
setApp({ Component })
100100
} else {
@@ -133,7 +133,7 @@ export default function Router({
133133
const [url, nestedModules] = routing.createRouter({ pathname })
134134
if (url.routePath !== '') {
135135
nestedModules.map(mod => {
136-
importModule(baseURL, mod.url)
136+
importModule(basePath, mod.url)
137137
})
138138
if (appUseDeno || nestedModules.findIndex(mod => !!mod.useDeno) > -1) {
139139
loadPageData(url)

framework/react/pagedata.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { RouterURL } from '../../types.ts'
33

44
const global = window as any
55

6-
export async function loadPageData({ baseURL, pathname }: RouterURL) {
6+
export async function loadPageData({ basePath, pathname }: RouterURL) {
77
const url = `pagedata://${pathname}`
88
if (url in global) {
99
const { expires, keys } = global[url]
@@ -15,7 +15,7 @@ export async function loadPageData({ baseURL, pathname }: RouterURL) {
1515
delete global[`${url}#${key}`]
1616
})
1717
}
18-
const dataUrl = `${util.trimSuffix(baseURL, '/')}/_aleph/data${pathname === '/' ? '/index' : pathname}.json`
18+
const dataUrl = `${util.trimSuffix(basePath, '/')}/_aleph/data${pathname === '/' ? '/index' : pathname}.json`
1919
const data = await (await fetch(dataUrl)).json()
2020
if (util.isPlainObject(data)) {
2121
storeData(data, pathname)

0 commit comments

Comments
 (0)