@apex-stack/core 0.1.16 → 0.1.18
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/dist/{build-UDFLTWY5.js → build-DXLV2X5C.js} +1 -1
- package/dist/{chunk-YO4UXWIY.js → chunk-VALQEQD3.js} +43 -6
- package/dist/cli.js +4 -4
- package/dist/{dev-PQRMJ7Z4.js → dev-W3D2FCEP.js} +1 -1
- package/dist/{make-62PPHZQY.js → make-JAW22LQZ.js} +26 -4
- package/dist/{server-GFQQABB4.js → server-VYF5SRVI.js} +5 -2
- package/dist/{start-EYEWMZXS.js → start-254YG2BY.js} +1 -1
- package/package.json +2 -2
|
@@ -153,10 +153,27 @@ function storesInitialState(stores) {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// src/dev/renderPage.ts
|
|
156
|
-
import { renderComponent, stateIsland } from "@apex-stack/kit";
|
|
156
|
+
import { renderComponent, renderFragment, stateIsland } from "@apex-stack/kit";
|
|
157
|
+
function escAttr(s) {
|
|
158
|
+
return String(s).replace(
|
|
159
|
+
/[&<>"]/g,
|
|
160
|
+
(c) => c === "&" ? "&" : c === "<" ? "<" : c === ">" ? ">" : """
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
function renderHead(head) {
|
|
164
|
+
const parts = [`<title>${head?.title ? escAttr(head.title) : "Apex JS"}</title>`];
|
|
165
|
+
for (const m of head?.meta ?? []) {
|
|
166
|
+
parts.push(`<meta ${Object.entries(m).map(([k, v]) => `${k}="${escAttr(v)}"`).join(" ")} />`);
|
|
167
|
+
}
|
|
168
|
+
for (const l of head?.link ?? []) {
|
|
169
|
+
parts.push(`<link ${Object.entries(l).map(([k, v]) => `${k}="${escAttr(v)}"`).join(" ")} />`);
|
|
170
|
+
}
|
|
171
|
+
return parts.join("\n ");
|
|
172
|
+
}
|
|
157
173
|
async function renderPage(opts) {
|
|
158
174
|
const mod = await opts.loadModule(opts.pageId);
|
|
159
175
|
const loaderData = await mod.loader({ params: opts.params ?? {}, url: opts.url }) ?? {};
|
|
176
|
+
const head = mod.head ? await mod.head({ data: loaderData, params: opts.params ?? {}, url: opts.url }) : void 0;
|
|
160
177
|
const stores = opts.stores ?? [];
|
|
161
178
|
const { html } = renderComponent({
|
|
162
179
|
template: mod.template,
|
|
@@ -168,18 +185,38 @@ async function renderPage(opts) {
|
|
|
168
185
|
stores: storesInitialState(stores),
|
|
169
186
|
authoredDefaults: mod.rootData ? mod.rootData() : void 0
|
|
170
187
|
});
|
|
188
|
+
const available = opts.layouts ?? [];
|
|
189
|
+
const layoutName = mod.layout === false ? null : typeof mod.layout === "string" ? mod.layout : available.includes("default") ? "default" : null;
|
|
190
|
+
let body = html;
|
|
191
|
+
let layoutCss = "";
|
|
192
|
+
if (layoutName && available.includes(layoutName)) {
|
|
193
|
+
const layoutMod = await opts.loadModule(`/layouts/${layoutName}.alpine`);
|
|
194
|
+
const chrome = renderFragment(layoutMod.template, {}, layoutMod.scopeId, opts.registry);
|
|
195
|
+
body = /<slot\b[^>]*>[\s\S]*?<\/slot>/.test(chrome) ? chrome.replace(/<slot\b[^>]*>[\s\S]*?<\/slot>/, () => html) : chrome + html;
|
|
196
|
+
layoutCss = layoutMod.css;
|
|
197
|
+
}
|
|
171
198
|
const doc = shell({
|
|
172
|
-
body
|
|
199
|
+
body,
|
|
173
200
|
island: stateIsland(mod.componentId, loaderData),
|
|
174
|
-
css: mod.css + (opts.componentCss ?? ""),
|
|
201
|
+
css: mod.css + layoutCss + (opts.componentCss ?? ""),
|
|
175
202
|
pageId: opts.pageId,
|
|
176
203
|
clientHref: opts.clientHref,
|
|
177
204
|
storeIds: stores.map((s) => s.id),
|
|
178
|
-
appCss: opts.appCss
|
|
205
|
+
appCss: opts.appCss,
|
|
206
|
+
headTags: renderHead(head)
|
|
179
207
|
});
|
|
180
208
|
return opts.transformHtml ? opts.transformHtml(opts.url, doc) : doc;
|
|
181
209
|
}
|
|
182
|
-
function shell({
|
|
210
|
+
function shell({
|
|
211
|
+
body,
|
|
212
|
+
island,
|
|
213
|
+
css,
|
|
214
|
+
pageId,
|
|
215
|
+
clientHref,
|
|
216
|
+
storeIds = [],
|
|
217
|
+
appCss,
|
|
218
|
+
headTags = "<title>Apex JS</title>"
|
|
219
|
+
}) {
|
|
183
220
|
const storeImports = storeIds.map((id, i) => ` import __s${i} from ${JSON.stringify(id)}`).join("\n");
|
|
184
221
|
const storeRegs = storeIds.map((_, i) => ` Alpine.store(__s${i}.name, __s${i}.factory())`).join("\n");
|
|
185
222
|
const clientScript = clientHref ? `<script type="module" src="${clientHref}"></script>` : `<script type="module">
|
|
@@ -196,7 +233,7 @@ ${storeRegs ? `${storeRegs}
|
|
|
196
233
|
<head>
|
|
197
234
|
<meta charset="utf-8" />
|
|
198
235
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
199
|
-
|
|
236
|
+
${headTags}
|
|
200
237
|
<style>${css}</style>
|
|
201
238
|
</head>
|
|
202
239
|
<body>
|
package/dist/cli.js
CHANGED
|
@@ -109,10 +109,10 @@ var main = defineCommand2({
|
|
|
109
109
|
},
|
|
110
110
|
subCommands: {
|
|
111
111
|
new: newCommand,
|
|
112
|
-
dev: () => import("./dev-
|
|
113
|
-
build: () => import("./build-
|
|
114
|
-
start: () => import("./start-
|
|
115
|
-
make: () => import("./make-
|
|
112
|
+
dev: () => import("./dev-W3D2FCEP.js").then((m) => m.devCommand),
|
|
113
|
+
build: () => import("./build-DXLV2X5C.js").then((m) => m.buildCommand),
|
|
114
|
+
start: () => import("./start-254YG2BY.js").then((m) => m.startCommand),
|
|
115
|
+
make: () => import("./make-JAW22LQZ.js").then((m) => m.makeCommand),
|
|
116
116
|
migrate: () => import("./migrate-NOGFOFV2.js").then((m) => m.migrateCommand),
|
|
117
117
|
mcp: () => import("./mcp-DL4J6JFJ.js").then((m) => m.mcpCommand)
|
|
118
118
|
},
|
|
@@ -20,7 +20,7 @@ var devCommand = defineCommand({
|
|
|
20
20
|
process.stdout.write(banner());
|
|
21
21
|
const sp = spinner(`Starting dev server${args.islands ? " (islands mode)" : ""}\u2026`);
|
|
22
22
|
try {
|
|
23
|
-
const { startDevServer } = await import("./server-
|
|
23
|
+
const { startDevServer } = await import("./server-VYF5SRVI.js");
|
|
24
24
|
const { port: actual } = await startDevServer({ root, port, islands: Boolean(args.islands) });
|
|
25
25
|
sp.succeed("Dev server ready");
|
|
26
26
|
ready([
|
|
@@ -33,6 +33,26 @@ function componentTemplate() {
|
|
|
33
33
|
</style>
|
|
34
34
|
`;
|
|
35
35
|
}
|
|
36
|
+
function layoutTemplate() {
|
|
37
|
+
return `<template>
|
|
38
|
+
<header class="site-header">
|
|
39
|
+
<nav><a href="/">Home</a></nav>
|
|
40
|
+
</header>
|
|
41
|
+
<main>
|
|
42
|
+
<slot></slot>
|
|
43
|
+
</main>
|
|
44
|
+
<footer class="site-footer">
|
|
45
|
+
<p>Built with Apex JS</p>
|
|
46
|
+
</footer>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<style scoped>
|
|
50
|
+
.site-header { padding: 1rem 1.5rem; border-bottom: 1px solid #e5e7eb; }
|
|
51
|
+
main { max-width: 60rem; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
52
|
+
.site-footer { padding: 1.5rem; border-top: 1px solid #e5e7eb; color: #6b7280; }
|
|
53
|
+
</style>
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
36
56
|
function storeTemplate(name) {
|
|
37
57
|
return `import { defineStore } from '@apex-stack/core'
|
|
38
58
|
|
|
@@ -69,20 +89,22 @@ function plan(kind, name, root) {
|
|
|
69
89
|
return { path: join(root, "server", "api", `${name}.ts`), contents: apiTemplate(name) };
|
|
70
90
|
case "store":
|
|
71
91
|
return { path: join(root, "stores", `${name}.ts`), contents: storeTemplate(name) };
|
|
92
|
+
case "layout":
|
|
93
|
+
return { path: join(root, "layouts", `${name}.alpine`), contents: layoutTemplate() };
|
|
72
94
|
}
|
|
73
95
|
}
|
|
74
96
|
var makeCommand = defineCommand({
|
|
75
|
-
meta: { name: "make", description: "Generate a page, component, API route, or
|
|
97
|
+
meta: { name: "make", description: "Generate a page, component, API route, store, or layout" },
|
|
76
98
|
args: {
|
|
77
|
-
kind: { type: "positional", required: true, description: "page | component | api | store" },
|
|
99
|
+
kind: { type: "positional", required: true, description: "page | component | api | store | layout" },
|
|
78
100
|
name: { type: "positional", required: true, description: "Name (about, Counter, todos, \u2026)" },
|
|
79
101
|
root: { type: "string", description: "Project root", default: "." }
|
|
80
102
|
},
|
|
81
103
|
run({ args }) {
|
|
82
104
|
const kind = args.kind;
|
|
83
|
-
if (kind !== "page" && kind !== "component" && kind !== "api" && kind !== "store") {
|
|
105
|
+
if (kind !== "page" && kind !== "component" && kind !== "api" && kind !== "store" && kind !== "layout") {
|
|
84
106
|
console.error(`
|
|
85
|
-
Unknown type "${args.kind}". Use: page | component | api | store
|
|
107
|
+
Unknown type "${args.kind}". Use: page | component | api | store | layout
|
|
86
108
|
`);
|
|
87
109
|
process.exit(1);
|
|
88
110
|
}
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
renderIslandsPage,
|
|
14
14
|
renderPage,
|
|
15
15
|
scanPages
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-VALQEQD3.js";
|
|
17
17
|
import "./chunk-MZVLRU3R.js";
|
|
18
18
|
|
|
19
19
|
// src/dev/server.ts
|
|
20
|
-
import { existsSync as existsSync2 } from "fs";
|
|
20
|
+
import { existsSync as existsSync2, readdirSync } from "fs";
|
|
21
21
|
import { createServer as createHttpServer } from "http";
|
|
22
22
|
import { createRequire } from "module";
|
|
23
23
|
import { join } from "path";
|
|
@@ -213,6 +213,8 @@ async function startDevServer(options) {
|
|
|
213
213
|
(id) => ssrLoad(id)
|
|
214
214
|
);
|
|
215
215
|
const stores = await loadStores(options.root, (id) => ssrLoad(id));
|
|
216
|
+
const layoutsDir = join(options.root, "layouts");
|
|
217
|
+
const layouts = existsSync2(layoutsDir) ? readdirSync(layoutsDir).filter((f) => f.endsWith(".alpine")).map((f) => f.replace(/\.alpine$/, "")) : [];
|
|
216
218
|
const render = options.islands ? renderIslandsPage : renderPage;
|
|
217
219
|
const html = await render({
|
|
218
220
|
loadModule: (id) => ssrLoad(id),
|
|
@@ -223,6 +225,7 @@ async function startDevServer(options) {
|
|
|
223
225
|
componentCss,
|
|
224
226
|
stores,
|
|
225
227
|
appCss,
|
|
228
|
+
layouts,
|
|
226
229
|
transformHtml: (u, doc) => vite.transformIndexHtml(u, doc)
|
|
227
230
|
});
|
|
228
231
|
setResponseHeader(event, "Content-Type", "text/html");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apex-stack/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "The full-stack meta-framework for Alpine.js — CLI and runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"vite": "^6.0.7",
|
|
47
47
|
"zod": "^4.4.3",
|
|
48
48
|
"@apex-stack/kit": "0.1.4",
|
|
49
|
-
"@apex-stack/vite": "0.1.
|
|
49
|
+
"@apex-stack/vite": "0.1.5"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"alpinejs": "^3.14.0"
|