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

Commit f77fde6

Browse files
author
Je
committed
refactor: update types
1 parent 061ba06 commit f77fde6

File tree

8 files changed

+70
-72
lines changed

8 files changed

+70
-72
lines changed

aleph.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React, { ComponentType, useCallback, useEffect, useRef, useState } from '
22
import { DataContext, RouterContext } from './context.ts'
33
import { E400MissingDefaultExportAsComponent, E404Page, ErrorBoundary } from './error.ts'
44
import events from './events.ts'
5-
import { createPageProps, Routing } from './router.ts'
6-
import type { Module, RouterURL } from './types.ts'
5+
import { createPageProps, Module, Routing } from './router.ts'
6+
import type { RouterURL } from './types.ts'
77
import util, { hashShort, reModuleExt } from './util.ts'
88

99
export function ALEPH({ initial }: {

api.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,37 @@ export class AlephAPIRequest implements APIRequest {
99
#cookies: ReadonlyMap<string, string>
1010

1111
constructor(req: ServerRequest, url: RouterURL) {
12-
this.#req = req
13-
1412
const paramsMap = new Map<string, string>()
1513
for (const key in url.params) {
1614
paramsMap.set(key, url.params[key])
1715
}
16+
this.#req = req
1817
this.#url = {
18+
proto: this.#req.proto,
19+
protoMinor: this.#req.protoMinor,
20+
protoMajor: this.#req.protoMajor,
1921
pathname: url.pathname,
2022
params: paramsMap,
2123
query: url.query,
2224
}
2325
this.#cookies = new Map() // todo: parse cookies
2426
}
2527

26-
get url(): APIRequestURL {
27-
return this.#url
28-
}
29-
30-
get cookies(): ReadonlyMap<string, string> {
31-
return this.#cookies
32-
}
33-
3428
get method(): string {
3529
return this.#req.method
3630
}
3731

38-
get proto(): string {
39-
return this.#req.proto
40-
}
41-
42-
get protoMinor(): number {
43-
return this.#req.protoMinor
44-
}
45-
46-
get protoMajor(): number {
47-
return this.#req.protoMajor
32+
get url(): APIRequestURL {
33+
return this.#url
4834
}
4935

5036
get headers(): Headers {
5137
return this.#req.headers
5238
}
39+
40+
get cookies(): ReadonlyMap<string, string> {
41+
return this.#cookies
42+
}
5343
}
5444

5545
export class AlephAPIResponse implements APIResponse {
@@ -90,12 +80,12 @@ export class AlephAPIResponse implements APIResponse {
9080
}
9181

9282
async json(data: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number) {
93-
return this.send(JSON.stringify(data, replacer, space), 'application/json', true)
83+
return this.send(JSON.stringify(data, replacer, space), 'application/json')
9484
}
9585

96-
async send(data: string | Uint8Array | ArrayBuffer, contentType?: string, gzip = false) {
86+
async send(data: string | Uint8Array | ArrayBuffer, contentType?: string) {
9787
if (this.#sent) {
98-
log.warn('ServerRequest.respond: repeat send calls')
88+
log.warn('ServerRequest: repeat respond calls')
9989
return
10090
}
10191
let body: Uint8Array
@@ -110,8 +100,20 @@ export class AlephAPIResponse implements APIResponse {
110100
}
111101
if (contentType) {
112102
this.#headers.set('Content-Type', contentType)
103+
} else if (this.#headers.has('Content-Type')) {
104+
contentType = this.#headers.get('Content-Type')!
105+
}
106+
let isText = false
107+
if (contentType) {
108+
if (contentType.startsWith('text/')) {
109+
isText = true
110+
} else if (/^application\/(javascript|typecript|json|xml)/.test(contentType)) {
111+
isText = true
112+
} else if (/^image\/svg+xml/.test(contentType)) {
113+
isText = true
114+
}
113115
}
114-
if (gzip && this.#req.headers.get('accept-encoding')?.includes('gzip') && body.length > 1024) {
116+
if (isText && body.length > 1024 && this.#req.headers.get('accept-encoding')?.includes('gzip')) {
115117
this.#headers.set('Vary', 'Origin')
116118
this.#headers.set('Content-Encoding', 'gzip')
117119
body = gzipEncode(body)
@@ -127,7 +129,7 @@ export class AlephAPIResponse implements APIResponse {
127129

128130
async end(status: number) {
129131
if (this.#sent) {
130-
log.warn('ServerRequest.respond: repeat send calls')
132+
log.warn('ServerRequest: repeat respond calls')
131133
return
132134
}
133135
this.#headers.set('Date', (new Date).toUTCString())

bootstrap.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React, { ComponentType } from 'https://esm.sh/react'
22
import { hydrate, render } from 'https://esm.sh/react-dom'
33
import { ALEPH, getModuleImportUrl } from './aleph.ts'
4-
import { Routing } from './router.ts'
5-
import type { Module, Route } from './types.ts'
4+
import { Module, Route, Routing } from './router.ts'
65
import { reModuleExt } from './util.ts'
76

87
export default async function bootstrap({

head.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const serverHeadElements: Map<string, { type: string, props: Record<string, any>
66
const serverStyles: Map<string, { css: string, asLink: boolean }> = new Map()
77

88
export async function renderHead(styles?: { url: string, hash: string, async?: boolean }[]) {
9-
const { __appRoot, __buildID } = (window as any).ALEPH as AlephRuntime
9+
const { __appRoot, __buildMode, __buildTarget } = (window as any).ALEPH as AlephRuntime
1010
const tags: string[] = []
1111
serverHeadElements.forEach(({ type, props }) => {
1212
if (type === 'title') {
@@ -30,7 +30,7 @@ export async function renderHead(styles?: { url: string, hash: string, async?: b
3030
}
3131
})
3232
await Promise.all(styles?.filter(({ async }) => !!async).map(({ url, hash }) => {
33-
return import('file://' + util.cleanPath(`${__appRoot}/.aleph/${__buildID}/${url}.${hash.slice(0, hashShort)}.js`))
33+
return import('file://' + util.cleanPath(`${__appRoot}/.aleph/${__buildMode}.${__buildTarget}/${url}.${hash.slice(0, hashShort)}.js`))
3434
}) || [])
3535
styles?.forEach(({ url }) => {
3636
if (serverStyles.has(url)) {

project.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export class Project {
4444
readonly appRoot: string
4545
readonly config: Config
4646
readonly ready: Promise<void>
47-
readonly buildID: string
4847

4948
#modules: Map<string, Module> = new Map()
5049
#routing: Routing = new Routing()
@@ -71,12 +70,11 @@ export class Project {
7170
},
7271
env: {}
7372
}
74-
this.buildID = this.mode + '.' + this.config.buildTarget
7573
this.ready = (async () => {
7674
const t = performance.now()
7775
await this._loadConfig()
7876
await this._init(reload)
79-
log.debug('initialize project token ' + Math.round(performance.now() - t) + 'ms')
77+
log.debug('init project in ' + Math.round(performance.now() - t) + 'ms')
8078
})()
8179
}
8280

@@ -89,7 +87,7 @@ export class Project {
8987
}
9088

9189
get buildDir() {
92-
return path.join(this.appRoot, '.aleph', this.buildID)
90+
return path.join(this.appRoot, '.aleph', this.mode + '.' + this.config.buildTarget)
9391
}
9492

9593
isHMRable(moduleID: string) {
@@ -407,15 +405,13 @@ export class Project {
407405
try {
408406
const conf = JSON.parse(await Deno.readTextFile(p))
409407
Object.assign(config, conf)
410-
log.debug(name, config)
411408
} catch (e) {
412409
log.fatal('parse config.json:', e.message)
413410
}
414411
} else {
415412
const { default: conf } = await import('file://' + p)
416413
if (util.isPlainObject(conf)) {
417414
Object.assign(config, conf)
418-
log.debug(name, config)
419415
}
420416
}
421417
}
@@ -489,10 +485,11 @@ export class Project {
489485

490486
Object.assign(globalThis, {
491487
ALEPH: {
492-
env: this.config.env,
488+
env: { ...this.config.env },
493489
__version: version,
494490
__appRoot: this.appRoot,
495-
__buildID: this.buildID,
491+
__buildMode: this.mode,
492+
__buildTarget: this.config.buildTarget,
496493
} as AlephRuntime,
497494
document: new Document(),
498495
innerWidth: 1920,
@@ -857,7 +854,7 @@ export class Project {
857854
mod.sourceType = 'jsx'
858855
}
859856
}
860-
mod.sourceHash = getHash(sourceContent, true)
857+
mod.sourceHash = getHash(sourceContent)
861858
sourceContent = await resp.text()
862859
shouldCompile = true
863860
} catch (err) {
@@ -1011,7 +1008,7 @@ export class Project {
10111008
mod.hash = getHash(mod.jsContent)
10121009
}
10131010

1014-
log.debug(`${url} compiled in ${(performance.now() - t).toFixed(3)}ms`)
1011+
log.debug(`compile ${url} in ${Math.round(performance.now() - t)}ms`)
10151012

10161013
if (!fsync) {
10171014
fsync = true
@@ -1225,7 +1222,7 @@ export class Project {
12251222
if (url.pagePath === '') {
12261223
log.warn(`page '${url.pathname}' not found`)
12271224
} else if (this.isDev) {
1228-
log.debug(`render page '${url.pagePath}' in ${Math.round(performance.now() - start)}ms`)
1225+
log.debug(`render '${url.pagePath}' in ${Math.round(performance.now() - start)}ms`)
12291226
}
12301227
} catch (err) {
12311228
ret.status = 500

router.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
import { E400MissingDefaultExportAsComponent } from './error.ts'
2-
import type { Module, Route, RouterURL } from './types.ts'
2+
import type { RouterURL } from './types.ts'
33
import util, { reMDExt, reModuleExt } from './util.ts'
44

5+
export interface Module {
6+
readonly id: string
7+
readonly hash: string
8+
readonly asyncDeps?: { url: string, hash: string }[]
9+
}
10+
11+
export interface Route {
12+
path: string
13+
module: Module
14+
children?: Route[]
15+
}
16+
17+
export interface PageProps {
18+
Page: any
19+
pageProps: Partial<PageProps> & { name?: string }
20+
}
21+
522
const ghostRoute: Route = { path: '', module: { id: '', hash: '' } }
623

724
export class Routing {
@@ -192,11 +209,6 @@ function matchPath(routePath: string, locPath: string): [Record<string, string>,
192209
return [params, true]
193210
}
194211

195-
export interface PageProps {
196-
Page: any
197-
pageProps: Partial<PageProps> & { name?: string }
198-
}
199-
200212
export function createPageProps(componentTree: { id: string, Component?: any }[]): PageProps {
201213
const pageProps: PageProps = {
202214
Page: null,

server.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export async function start(appDir: string, port: number, isDev = false, reload
6262
continue
6363
}
6464

65-
// serve apis
65+
// serve APIs
6666
if (pathname.startsWith('/api/')) {
6767
project.callAPI(req, { pathname, search: url.search })
6868
continue
@@ -74,7 +74,7 @@ export async function start(appDir: string, port: number, isDev = false, reload
7474
const filePath = path.join(project.buildDir, util.trimPrefix(pathname, '/_aleph/'))
7575
if (existsFileSync(filePath)) {
7676
const body = await Deno.readFile(filePath)
77-
resp.send(body, 'text/css; charset=utf-8', true)
77+
resp.send(body, 'text/css; charset=utf-8')
7878
continue
7979
}
8080
} else {
@@ -110,7 +110,7 @@ export async function start(appDir: string, port: number, isDev = false, reload
110110
}
111111
}
112112
resp.setHeader('ETag', mod.hash)
113-
resp.send(body, `application/${reqSourceMap ? 'json' : 'javascript'}; charset=utf-8`, true)
113+
resp.send(body, `application/${reqSourceMap ? 'json' : 'javascript'}; charset=utf-8`)
114114
continue
115115
}
116116
}
@@ -126,21 +126,20 @@ export async function start(appDir: string, port: number, isDev = false, reload
126126
}
127127

128128
const body = await Deno.readFile(filePath)
129-
const ct = getContentType(filePath)
130129
resp.setHeader('Last-Modified', info.mtime!.toUTCString())
131-
resp.send(body, ct, ct.startsWith('text/') || /\.(m?js|json|xml|svg)$/i.test(filePath))
130+
resp.send(body, getContentType(filePath))
132131
continue
133132
}
134133

135134
// ssr
136135
const [status, html] = await project.getPageHtml({ pathname, search: url.search })
137-
resp.status(status).send(html, 'text/html', true)
136+
resp.status(status).send(html, 'text/html; charset=utf-8')
138137
} catch (err) {
139138
resp.status(500).send(createHtml({
140139
lang: 'en',
141140
head: ['<title>500 - internal server error</title>'],
142141
body: `<p><strong><code>500</code></strong><small> - </small><span>${err.message}</span></p>`
143-
}), 'text/html', true)
142+
}), 'text/html; charset=utf-8')
144143
}
145144
}
146145
} catch (err) {

types.ts

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ export interface AlephRuntime {
22
env: Record<string, string>
33
__version: string
44
__appRoot: string
5-
__buildID: string
5+
__buildMode: string
6+
__buildTarget: string
67
}
78

89
export interface SSROptions {
@@ -27,17 +28,17 @@ export interface Config {
2728
}
2829

2930
export interface APIRequestURL {
31+
readonly proto: string
32+
readonly protoMinor: number
33+
readonly protoMajor: number
3034
readonly pathname: string
3135
readonly params: ReadonlyMap<string, string>
3236
readonly query: URLSearchParams
3337
}
3438

3539
export interface APIRequest {
36-
readonly url: APIRequestURL
3740
readonly method: string
38-
readonly proto: string
39-
readonly protoMinor: number
40-
readonly protoMajor: number
41+
readonly url: APIRequestURL
4142
readonly headers: Headers
4243
readonly cookies: ReadonlyMap<string, string>
4344
}
@@ -55,18 +56,6 @@ export interface APIHandle {
5556
(req: APIRequest, res: APIResponse): void
5657
}
5758

58-
export interface Module {
59-
readonly id: string
60-
readonly hash: string
61-
readonly asyncDeps?: { url: string, hash: string }[]
62-
}
63-
64-
export interface Route {
65-
path: string
66-
module: Module
67-
children?: Route[]
68-
}
69-
7059
export interface RouterURL {
7160
readonly locale: string
7261
readonly pathname: string

0 commit comments

Comments
 (0)