@inglorious/ssx 1.5.12 → 1.6.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 +2 -2
- package/src/render/html.js +12 -17
- package/src/render/render.test.js +1 -0
- package/src/scripts/app.js +1 -1
- package/src/store/index.js +12 -7
- package/src/store/store.test.js +21 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/ssx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
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",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"svgo": "^4.0.0",
|
|
58
58
|
"vite": "^7.1.3",
|
|
59
59
|
"vite-plugin-image-optimizer": "^2.0.3",
|
|
60
|
-
"@inglorious/web": "4.
|
|
60
|
+
"@inglorious/web": "4.2.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"prettier": "^3.6.2",
|
package/src/render/html.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** @typedef {import('lit-html').TemplateResult} TemplateResult */
|
|
2
|
+
/** @typedef {import('@inglorious/store').Store} Store */
|
|
3
|
+
/** @typedef {import('@inglorious/web').Api} Api */
|
|
4
|
+
|
|
1
5
|
import { html } from "@inglorious/web"
|
|
2
6
|
import { render as ssrRender } from "@lit-labs/ssr"
|
|
3
7
|
import { collectResult } from "@lit-labs/ssr/lib/render-result.js"
|
|
@@ -8,8 +12,8 @@ import { layout as defaultLayout } from "./layout.js"
|
|
|
8
12
|
* Renders a page or component to HTML using the store state.
|
|
9
13
|
* It handles SSR rendering of Lit templates and optional HTML wrapping.
|
|
10
14
|
*
|
|
11
|
-
* @param {
|
|
12
|
-
* @param {
|
|
15
|
+
* @param {Store} store - The application store instance.
|
|
16
|
+
* @param {(api: Api) => TemplateResult | null} renderFn - The root render function.
|
|
13
17
|
* @param {Object} [options] - Rendering options.
|
|
14
18
|
* @param {boolean} [options.wrap=false] - Whether to wrap the output in a full HTML document.
|
|
15
19
|
* @param {Function} [options.layout] - Custom layout function.
|
|
@@ -52,26 +56,17 @@ function stripLitMarkers(html) {
|
|
|
52
56
|
|
|
53
57
|
// TODO: this was copied from @inglorious/web, maybe expose it?
|
|
54
58
|
/**
|
|
55
|
-
* Creates a render function
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* @
|
|
59
|
-
* @returns {Function} The render function.
|
|
59
|
+
* Creates a render function for the mount API.
|
|
60
|
+
* @param {Api} api - The mount API.
|
|
61
|
+
* @returns {Api['render']} A `render` function that can render an entity or a type by its ID.
|
|
62
|
+
* @private
|
|
60
63
|
*/
|
|
61
64
|
function createRender(api) {
|
|
62
|
-
return function (id
|
|
65
|
+
return function (id) {
|
|
63
66
|
const entity = api.getEntity(id)
|
|
64
67
|
|
|
65
68
|
if (!entity) {
|
|
66
|
-
|
|
67
|
-
if (!allowType) return ""
|
|
68
|
-
|
|
69
|
-
const type = api.getType(id)
|
|
70
|
-
if (!type?.render) {
|
|
71
|
-
console.warn(`No entity or type found: ${id}`)
|
|
72
|
-
return html`<div>Not found: ${id}</div>`
|
|
73
|
-
}
|
|
74
|
-
return type.render(api)
|
|
69
|
+
return ""
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
const type = api.getType(entity.type)
|
package/src/scripts/app.js
CHANGED
|
@@ -56,7 +56,7 @@ const module = await getRoute(page.pattern)()
|
|
|
56
56
|
const type = module[page.moduleName]
|
|
57
57
|
types[page.moduleName] = type
|
|
58
58
|
|
|
59
|
-
const store = createStore({ types, entities, middlewares })
|
|
59
|
+
const store = createStore({ types, entities, middlewares, autoCreateEntities: true })
|
|
60
60
|
|
|
61
61
|
const root = document.getElementById("root")
|
|
62
62
|
|
package/src/store/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from "node:fs"
|
|
1
2
|
import path from "node:path"
|
|
2
3
|
import { pathToFileURL } from "node:url"
|
|
3
4
|
|
|
@@ -33,14 +34,18 @@ export async function generateStore(pages = [], options = {}, loader) {
|
|
|
33
34
|
const extensions = ["js", "ts"]
|
|
34
35
|
|
|
35
36
|
for (const ext of extensions) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const fullPath = path.join(srcDir, "store", `entities.${ext}`)
|
|
38
|
+
|
|
39
|
+
if (existsSync(fullPath)) {
|
|
40
|
+
try {
|
|
41
|
+
const module = await load(fullPath)
|
|
42
|
+
entities = module.entities
|
|
43
|
+
break
|
|
44
|
+
} catch {
|
|
45
|
+
// ignore and try next extension
|
|
46
|
+
}
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
|
|
45
|
-
return createStore({ types, entities,
|
|
50
|
+
return createStore({ types, entities, autoCreateEntities: true })
|
|
46
51
|
}
|
package/src/store/store.test.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from "node:fs"
|
|
1
2
|
import path from "node:path"
|
|
2
3
|
|
|
3
4
|
import { describe, expect, it, vi } from "vitest"
|
|
@@ -7,6 +8,8 @@ import { generateStore } from "."
|
|
|
7
8
|
const ROOT_DIR = path.join(import.meta.dirname, "..", "__fixtures__")
|
|
8
9
|
const PAGES_DIR = path.join(ROOT_DIR, "src", "pages")
|
|
9
10
|
|
|
11
|
+
vi.mock("node:fs")
|
|
12
|
+
|
|
10
13
|
describe("generateStore", () => {
|
|
11
14
|
it("should generate the proper types and entities from a static page", async () => {
|
|
12
15
|
const page = {
|
|
@@ -55,25 +58,32 @@ describe("generateStore", () => {
|
|
|
55
58
|
expect(store.getState()).not.toHaveProperty("about")
|
|
56
59
|
})
|
|
57
60
|
|
|
58
|
-
it("should
|
|
61
|
+
it("should check for entities.js and entities.ts and load them if they exist", async () => {
|
|
62
|
+
vi.mocked(existsSync).mockReturnValue(true)
|
|
63
|
+
|
|
59
64
|
const loader = vi.fn(async (p) => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
if (p.includes("index.js")) {
|
|
66
|
+
return {
|
|
67
|
+
index: { render: () => "" },
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (p.includes("entities.js") || p.includes("entities.ts")) {
|
|
72
|
+
return {
|
|
73
|
+
entities: {},
|
|
74
|
+
}
|
|
63
75
|
}
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
|
|
77
|
+
return {}
|
|
66
78
|
})
|
|
67
79
|
|
|
68
80
|
const page = { filePath: path.join(PAGES_DIR, "index.js") }
|
|
69
|
-
|
|
81
|
+
|
|
82
|
+
await generateStore([page], { rootDir: ROOT_DIR }, loader)
|
|
70
83
|
|
|
71
84
|
expect(loader).toHaveBeenCalledWith(page.filePath)
|
|
72
85
|
expect(loader).toHaveBeenCalledWith(
|
|
73
|
-
path.join("src", "store", "entities.js"),
|
|
74
|
-
)
|
|
75
|
-
expect(loader).toHaveBeenCalledWith(
|
|
76
|
-
path.join("src", "store", "entities.ts"),
|
|
86
|
+
path.join(ROOT_DIR, "src", "store", "entities.js"),
|
|
77
87
|
)
|
|
78
88
|
})
|
|
79
89
|
})
|