@kaathewise/ssg 0.2.0 → 0.3.0
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/package.json +1 -1
- package/src/build.ts +14 -8
- package/src/render.ts +6 -6
- package/src/server.ts +34 -12
package/package.json
CHANGED
package/src/build.ts
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises"
|
|
2
|
-
import
|
|
2
|
+
import * as path from "node:path"
|
|
3
3
|
import { Glob, write } from "bun"
|
|
4
4
|
import { type Page, renderAll } from "./render"
|
|
5
5
|
|
|
6
6
|
const glob = new Glob("**/*.{js,jsx,ts,tsx}")
|
|
7
7
|
|
|
8
8
|
export async function build(pagesDir: string, outDir: string = "dist/") {
|
|
9
|
-
pagesDir = join(process.cwd(), pagesDir)
|
|
10
|
-
outDir = join(process.cwd(), outDir)
|
|
9
|
+
pagesDir = path.join(process.cwd(), pagesDir)
|
|
10
|
+
outDir = path.join(process.cwd(), outDir)
|
|
11
11
|
|
|
12
12
|
const pages: Page[] = []
|
|
13
|
-
for await (const
|
|
14
|
-
const modulePath = join(pagesDir,
|
|
13
|
+
for await (const relPath of glob.scan(pagesDir)) {
|
|
14
|
+
const modulePath = path.join(pagesDir, relPath)
|
|
15
15
|
const p = await renderAll(modulePath, pagesDir)
|
|
16
16
|
pages.push(...p)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
await fs.rm(outDir, { recursive: true, force: true })
|
|
20
|
-
|
|
21
|
-
await fs.mkdir(outDir, { recursive: true })
|
|
20
|
+
await fs.mkdir(outDir)
|
|
22
21
|
|
|
23
22
|
for (const page of pages) {
|
|
24
|
-
const
|
|
23
|
+
const destPath = path.join(outDir, page.path)
|
|
24
|
+
const dir = path.dirname(destPath)
|
|
25
|
+
if (!(await fs.exists(dir))) {
|
|
26
|
+
await fs.mkdir(path.dirname(destPath), {
|
|
27
|
+
recursive: true,
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
const file = Bun.file(destPath)
|
|
25
31
|
await write(file, page.html)
|
|
26
32
|
}
|
|
27
33
|
}
|
package/src/render.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as path from "node:path"
|
|
2
2
|
|
|
3
3
|
interface Params {
|
|
4
|
-
[name: string]: string
|
|
4
|
+
[name: string]: string
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export type Page = {
|
|
@@ -58,11 +58,11 @@ export async function renderAll(
|
|
|
58
58
|
function substituteParams(inputPath: string, params: Params): string {
|
|
59
59
|
let path = inputPath
|
|
60
60
|
for (const [key, value] of Object.entries(params)) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const single = `[${key}]`
|
|
62
|
+
const multiple = `[[...${key}]]`
|
|
63
|
+
|
|
64
|
+
path = path.replace(single, value)
|
|
65
|
+
path = path.replace(multiple, value)
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
path = path.replace(/\.tsx?$/, "")
|
package/src/server.ts
CHANGED
|
@@ -8,23 +8,28 @@ const EVENT_PATH = "/__ssg_dev_sse"
|
|
|
8
8
|
|
|
9
9
|
export class Server {
|
|
10
10
|
pagesDir: string
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
sourceDir: string
|
|
12
|
+
assetDir?: string
|
|
13
13
|
port?: number = 3001
|
|
14
14
|
|
|
15
|
+
router: Bun.FileSystemRouter
|
|
16
|
+
|
|
15
17
|
constructor(options: {
|
|
16
18
|
pagesDir: string
|
|
17
|
-
|
|
19
|
+
sourceDir: string
|
|
20
|
+
assetDir?: string
|
|
18
21
|
port?: number
|
|
19
22
|
}) {
|
|
20
23
|
this.pagesDir = path.join(process.cwd(), options.pagesDir)
|
|
21
|
-
this.
|
|
24
|
+
this.sourceDir = path.join(process.cwd(), options.sourceDir)
|
|
22
25
|
|
|
23
26
|
this.router = new Bun.FileSystemRouter({
|
|
24
27
|
style: "nextjs",
|
|
25
28
|
dir: options.pagesDir,
|
|
26
29
|
})
|
|
27
30
|
|
|
31
|
+
this.assetDir ??= options.assetDir
|
|
32
|
+
|
|
28
33
|
this.port ??= options?.port
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -43,14 +48,32 @@ export class Server {
|
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
const route = this.router.match(request.url)
|
|
46
|
-
|
|
51
|
+
if (route) {
|
|
52
|
+
return createHtml(this.pagesDir, route)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (this.assetDir) {
|
|
56
|
+
// TODO: .. escapes
|
|
57
|
+
const assetPath = path.join(
|
|
58
|
+
this.assetDir,
|
|
59
|
+
url.pathname.slice(1),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return new Response(Bun.file(assetPath))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return new Response("Not found", {
|
|
66
|
+
headers: {
|
|
67
|
+
"Content-Type": "text/html",
|
|
68
|
+
},
|
|
69
|
+
})
|
|
47
70
|
},
|
|
48
71
|
})
|
|
49
72
|
|
|
50
|
-
const watcher = watch(this.
|
|
73
|
+
const watcher = watch(this.sourceDir, { recursive: true })
|
|
51
74
|
for await (const _ of watcher) {
|
|
52
75
|
this.router.reload()
|
|
53
|
-
clearCache(this.
|
|
76
|
+
clearCache(this.sourceDir)
|
|
54
77
|
for (const client of clients) {
|
|
55
78
|
client.enqueue("data: RELOAD\n\n")
|
|
56
79
|
}
|
|
@@ -94,11 +117,10 @@ const RELOAD_SCRIPT = `
|
|
|
94
117
|
</script>
|
|
95
118
|
`
|
|
96
119
|
|
|
97
|
-
async function createHtml(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
120
|
+
async function createHtml(
|
|
121
|
+
pagesDir: string,
|
|
122
|
+
route: MatchedRoute,
|
|
123
|
+
): Promise<Response> {
|
|
102
124
|
const page = await render(route.filePath, pagesDir, route.params)
|
|
103
125
|
|
|
104
126
|
const response = new Response(page.html, {
|