@inglorious/ssx 0.4.0 ā 0.4.1
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 +2 -2
- package/src/build.js +8 -7
- package/src/dev.js +1 -1
- package/src/render.js +35 -18
- package/src/render.test.js +14 -10
- package/src/router.js +3 -1
- package/src/scripts/app.js +9 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/ssx",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Server-Side-X. Xecution? Xperience? Who knows.",
|
|
5
5
|
"author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"glob": "^13.0.0",
|
|
48
48
|
"rollup-plugin-minify-template-literals": "^1.1.7",
|
|
49
49
|
"vite": "^7.1.3",
|
|
50
|
-
"@inglorious/web": "4.0.
|
|
50
|
+
"@inglorious/web": "4.0.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"prettier": "^3.6.2",
|
package/src/build.js
CHANGED
|
@@ -27,7 +27,7 @@ export async function build(options = {}) {
|
|
|
27
27
|
const store = await generateStore(pages, options)
|
|
28
28
|
|
|
29
29
|
// Render all pages
|
|
30
|
-
const
|
|
30
|
+
const htmls = await renderPages(store, pages, options)
|
|
31
31
|
|
|
32
32
|
// Write all pages to disk
|
|
33
33
|
console.log("\nš¾ Writing files...\n")
|
|
@@ -35,10 +35,11 @@ export async function build(options = {}) {
|
|
|
35
35
|
const app = generateApp(store, pages)
|
|
36
36
|
await fs.writeFile(path.join(outDir, "main.js"), app, "utf-8")
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
pages.forEach(async (page, index) => {
|
|
39
|
+
const html = htmls[index]
|
|
39
40
|
const filePath = await writePageToDisk(page.path, html, outDir)
|
|
40
41
|
console.log(` ā ${filePath}`)
|
|
41
|
-
}
|
|
42
|
+
})
|
|
42
43
|
|
|
43
44
|
// Bundle with Vite
|
|
44
45
|
console.log("\nš¦ Bundling with Vite...\n")
|
|
@@ -50,10 +51,10 @@ export async function build(options = {}) {
|
|
|
50
51
|
|
|
51
52
|
console.log("\n⨠Build complete!\n")
|
|
52
53
|
|
|
53
|
-
return { pages:
|
|
54
|
+
return { pages: htmls.length, outDir }
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
async function
|
|
57
|
+
async function renderPages(store, pages, options = {}) {
|
|
57
58
|
const { renderOptions } = options
|
|
58
59
|
|
|
59
60
|
const renderedPages = []
|
|
@@ -62,11 +63,11 @@ async function generatePages(store, pages, options = {}) {
|
|
|
62
63
|
console.log(` Rendering ${page.path}...`)
|
|
63
64
|
|
|
64
65
|
const module = await import(pathToFileURL(page.filePath))
|
|
65
|
-
const html = await renderPage(store, module, {
|
|
66
|
+
const html = await renderPage(store, page, module, {
|
|
66
67
|
...renderOptions,
|
|
67
68
|
wrap: true,
|
|
68
69
|
})
|
|
69
|
-
renderedPages.push(
|
|
70
|
+
renderedPages.push(html)
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
return renderedPages
|
package/src/dev.js
CHANGED
|
@@ -48,7 +48,7 @@ export async function dev(options = {}) {
|
|
|
48
48
|
if (!page) return next()
|
|
49
49
|
|
|
50
50
|
const module = await viteServer.ssrLoadModule(page.filePath)
|
|
51
|
-
const html = await renderPage(store, module, {
|
|
51
|
+
const html = await renderPage(store, page, module, {
|
|
52
52
|
...renderOptions,
|
|
53
53
|
wrap: true,
|
|
54
54
|
})
|
package/src/render.js
CHANGED
|
@@ -1,31 +1,48 @@
|
|
|
1
1
|
import { toHTML } from "./html.js"
|
|
2
2
|
import { getModuleName } from "./module.js"
|
|
3
3
|
|
|
4
|
-
export async function renderPage(store,
|
|
5
|
-
const
|
|
4
|
+
export async function renderPage(store, page, module, options = {}) {
|
|
5
|
+
const { title = "", meta = {}, scripts = [], styles = [] } = options
|
|
6
|
+
|
|
7
|
+
const name = getModuleName(module)
|
|
6
8
|
const api = store._api
|
|
7
9
|
const entity = api.getEntity(name)
|
|
8
10
|
|
|
9
|
-
if (
|
|
10
|
-
await
|
|
11
|
+
if (module.load) {
|
|
12
|
+
await module.load(entity, page, store._api)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const pageTitle = module.title
|
|
16
|
+
? typeof module.title === "function"
|
|
17
|
+
? module.title(entity, api)
|
|
18
|
+
: module.title
|
|
19
|
+
: title
|
|
20
|
+
|
|
21
|
+
const pageMeta = {
|
|
22
|
+
...meta,
|
|
23
|
+
...(typeof module.meta === "function"
|
|
24
|
+
? module.meta(entity, api)
|
|
25
|
+
: (module.meta ?? {})),
|
|
11
26
|
}
|
|
12
27
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
const pageScripts = [
|
|
29
|
+
...scripts,
|
|
30
|
+
...(typeof module.scripts === "function"
|
|
31
|
+
? module.scripts(entity, api)
|
|
32
|
+
: (module.scripts ?? [])),
|
|
33
|
+
]
|
|
34
|
+
const pageStyles = [
|
|
35
|
+
...styles,
|
|
36
|
+
...(typeof module.styles === "function"
|
|
37
|
+
? module.styles(entity, api)
|
|
38
|
+
: (module.styles ?? [])),
|
|
39
|
+
]
|
|
23
40
|
|
|
24
41
|
return toHTML(store, (api) => api.render(name, { allowType: true }), {
|
|
25
42
|
...options,
|
|
26
|
-
title,
|
|
27
|
-
meta,
|
|
28
|
-
scripts,
|
|
29
|
-
styles,
|
|
43
|
+
title: pageTitle,
|
|
44
|
+
meta: pageMeta,
|
|
45
|
+
scripts: pageScripts,
|
|
46
|
+
styles: pageStyles,
|
|
30
47
|
})
|
|
31
48
|
}
|
package/src/render.test.js
CHANGED
|
@@ -11,6 +11,7 @@ const PAGES_DIR = path.join(ROOT_DIR, "pages")
|
|
|
11
11
|
const DEFAULT_OPTIONS = { stripLitMarkers: true }
|
|
12
12
|
|
|
13
13
|
it("should render a static page fragment", async () => {
|
|
14
|
+
const page = { path: "/" }
|
|
14
15
|
const module = await import(path.resolve(path.join(PAGES_DIR, "about.js")))
|
|
15
16
|
|
|
16
17
|
const store = createStore({
|
|
@@ -18,42 +19,45 @@ it("should render a static page fragment", async () => {
|
|
|
18
19
|
updateMode: "manual",
|
|
19
20
|
})
|
|
20
21
|
|
|
21
|
-
const html = await renderPage(store, module, DEFAULT_OPTIONS)
|
|
22
|
+
const html = await renderPage(store, page, module, DEFAULT_OPTIONS)
|
|
22
23
|
|
|
23
24
|
expect(html).toMatchSnapshot()
|
|
24
25
|
})
|
|
25
26
|
|
|
26
|
-
it("should render a
|
|
27
|
+
it("should render a page with entity", async () => {
|
|
28
|
+
const page = { path: "/about" }
|
|
27
29
|
const module = await import(path.resolve(path.join(PAGES_DIR, "about.js")))
|
|
28
30
|
|
|
29
31
|
const store = createStore({
|
|
30
32
|
types: { about: module.about },
|
|
33
|
+
entities: { about: { type: "about", name: "Us" } },
|
|
31
34
|
updateMode: "manual",
|
|
32
35
|
})
|
|
33
36
|
|
|
34
|
-
const html = await renderPage(store, module,
|
|
35
|
-
...DEFAULT_OPTIONS,
|
|
36
|
-
wrap: true,
|
|
37
|
-
})
|
|
37
|
+
const html = await renderPage(store, page, module, DEFAULT_OPTIONS)
|
|
38
38
|
|
|
39
39
|
expect(html).toMatchSnapshot()
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
-
it("should render a page with
|
|
42
|
+
it("should render a page with metadata", async () => {
|
|
43
|
+
const page = { path: "/about" }
|
|
43
44
|
const module = await import(path.resolve(path.join(PAGES_DIR, "about.js")))
|
|
44
45
|
|
|
45
46
|
const store = createStore({
|
|
46
47
|
types: { about: module.about },
|
|
47
|
-
entities: { about: { type: "about", name: "Us" } },
|
|
48
48
|
updateMode: "manual",
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
-
const html = await renderPage(store, module,
|
|
51
|
+
const html = await renderPage(store, page, module, {
|
|
52
|
+
...DEFAULT_OPTIONS,
|
|
53
|
+
wrap: true,
|
|
54
|
+
})
|
|
52
55
|
|
|
53
56
|
expect(html).toMatchSnapshot()
|
|
54
57
|
})
|
|
55
58
|
|
|
56
59
|
it("should render a page with pre-fetched data", async () => {
|
|
60
|
+
const page = { path: "/posts" }
|
|
57
61
|
const module = await import(path.resolve(path.join(PAGES_DIR, "posts.js")))
|
|
58
62
|
|
|
59
63
|
const store = createStore({
|
|
@@ -62,7 +66,7 @@ it("should render a page with pre-fetched data", async () => {
|
|
|
62
66
|
updateMode: "manual",
|
|
63
67
|
})
|
|
64
68
|
|
|
65
|
-
const html = await renderPage(store, module, DEFAULT_OPTIONS)
|
|
69
|
+
const html = await renderPage(store, page, module, DEFAULT_OPTIONS)
|
|
66
70
|
|
|
67
71
|
expect(html).toMatchSnapshot()
|
|
68
72
|
})
|
package/src/router.js
CHANGED
|
@@ -35,6 +35,7 @@ export async function getPages(pagesDir = "pages") {
|
|
|
35
35
|
const params = extractParams(route, urlPath)
|
|
36
36
|
|
|
37
37
|
pages.push({
|
|
38
|
+
pattern: route.pattern,
|
|
38
39
|
path: urlPath,
|
|
39
40
|
modulePath: route.modulePath,
|
|
40
41
|
filePath: route.filePath,
|
|
@@ -51,7 +52,8 @@ export async function getPages(pagesDir = "pages") {
|
|
|
51
52
|
} else {
|
|
52
53
|
// Static route - add directly
|
|
53
54
|
pages.push({
|
|
54
|
-
|
|
55
|
+
pattern: route.pattern,
|
|
56
|
+
path: route.pattern || "/",
|
|
55
57
|
modulePath: route.modulePath,
|
|
56
58
|
filePath: route.filePath,
|
|
57
59
|
moduleName,
|
package/src/scripts/app.js
CHANGED
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export function generateApp(store, pages) {
|
|
8
8
|
// Collect all unique page modules and their exports
|
|
9
|
-
const routes = pages
|
|
10
|
-
(page
|
|
11
|
-
|
|
9
|
+
const routes = pages
|
|
10
|
+
.filter((page, index) => {
|
|
11
|
+
return pages.findIndex((p) => p.pattern === page.pattern) === index
|
|
12
|
+
})
|
|
13
|
+
.map(
|
|
14
|
+
(page) =>
|
|
15
|
+
` "${page.pattern}": () => import("@/pages/${page.modulePath}")`,
|
|
16
|
+
)
|
|
12
17
|
|
|
13
18
|
return `import { createDevtools, createStore, mount } from "@inglorious/web"
|
|
14
19
|
import { getRoute, router, setRoutes } from "@inglorious/web/router"
|
|
@@ -37,7 +42,7 @@ setRoutes({
|
|
|
37
42
|
${routes.join(",\n")}
|
|
38
43
|
})
|
|
39
44
|
|
|
40
|
-
const module = await getRoute(page.
|
|
45
|
+
const module = await getRoute(page.pattern)()
|
|
41
46
|
const type = module[page.moduleName]
|
|
42
47
|
types[page.moduleName] = type
|
|
43
48
|
|