@jasonshimmy/vite-plugin-cer-app 0.21.2 → 0.21.3

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/commits.txt +1 -1
  3. package/dist/cli/create/templates/spa/package.json.tpl +4 -4
  4. package/dist/cli/create/templates/ssg/package.json.tpl +4 -4
  5. package/dist/cli/create/templates/ssr/package.json.tpl +4 -4
  6. package/dist/plugin/dev-server.d.ts +1 -0
  7. package/dist/plugin/dev-server.d.ts.map +1 -1
  8. package/dist/plugin/dev-server.js.map +1 -1
  9. package/dist/plugin/index.d.ts.map +1 -1
  10. package/dist/plugin/index.js +12 -0
  11. package/dist/plugin/index.js.map +1 -1
  12. package/dist/plugin/virtual/content-components.d.ts +6 -0
  13. package/dist/plugin/virtual/content-components.d.ts.map +1 -0
  14. package/dist/plugin/virtual/content-components.js +70 -0
  15. package/dist/plugin/virtual/content-components.js.map +1 -0
  16. package/dist/runtime/app-template.d.ts +1 -1
  17. package/dist/runtime/app-template.d.ts.map +1 -1
  18. package/dist/runtime/app-template.js +1 -0
  19. package/dist/runtime/app-template.js.map +1 -1
  20. package/dist/runtime/entry-server-template.d.ts +1 -1
  21. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  22. package/dist/runtime/entry-server-template.js +1 -0
  23. package/dist/runtime/entry-server-template.js.map +1 -1
  24. package/docs/configuration.md +1 -1
  25. package/docs/content.md +39 -1
  26. package/e2e/cypress/e2e/content.cy.ts +21 -1
  27. package/e2e/kitchen-sink/content/docs/getting-started.md +2 -0
  28. package/package.json +1 -1
  29. package/src/__tests__/plugin/app-template.test.ts +4 -0
  30. package/src/__tests__/plugin/cer-app-plugin.test.ts +1 -0
  31. package/src/__tests__/plugin/entry-server-template.test.ts +4 -0
  32. package/src/__tests__/plugin/virtual/content-components.test.ts +66 -0
  33. package/src/cli/create/templates/spa/package.json.tpl +4 -4
  34. package/src/cli/create/templates/ssg/package.json.tpl +4 -4
  35. package/src/cli/create/templates/ssr/package.json.tpl +4 -4
  36. package/src/plugin/dev-server.ts +1 -0
  37. package/src/plugin/index.ts +12 -0
  38. package/src/plugin/virtual/content-components.ts +83 -0
  39. package/src/runtime/app-template.ts +1 -0
  40. package/src/runtime/entry-server-template.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
+ ## [v0.21.3] - 2026-04-13
5
+
6
+ - fix: enhance content layer with automatic component registration from markdown (62bcc04)
7
+
4
8
  ## [v0.21.2] - 2026-04-13
5
9
 
6
10
  - fix: enhance dev mode logging in runtime and update dependencies (57a5a7c)
package/commits.txt CHANGED
@@ -1 +1 @@
1
- - fix: enhance dev mode logging in runtime and update dependencies (57a5a7c)
1
+ - fix: enhance content layer with automatic component registration from markdown (62bcc04)
@@ -8,11 +8,11 @@
8
8
  "preview": "cer-app preview"
9
9
  },
10
10
  "dependencies": {
11
- "@jasonshimmy/custom-elements-runtime": "^3.7.2"
11
+ "@jasonshimmy/custom-elements-runtime": "^3.7.5"
12
12
  },
13
13
  "devDependencies": {
14
- "@jasonshimmy/vite-plugin-cer-app": "^0.19.3",
15
- "typescript": "^5.9.3",
16
- "vite": "^8.0.3"
14
+ "@jasonshimmy/vite-plugin-cer-app": "^0.21.3",
15
+ "typescript": "^6.0.2",
16
+ "vite": "^8.0.8"
17
17
  }
18
18
  }
@@ -9,11 +9,11 @@
9
9
  "preview": "cer-app preview"
10
10
  },
11
11
  "dependencies": {
12
- "@jasonshimmy/custom-elements-runtime": "^3.7.2"
12
+ "@jasonshimmy/custom-elements-runtime": "^3.7.5"
13
13
  },
14
14
  "devDependencies": {
15
- "@jasonshimmy/vite-plugin-cer-app": "^0.19.3",
16
- "typescript": "^5.9.3",
17
- "vite": "^8.0.3"
15
+ "@jasonshimmy/vite-plugin-cer-app": "^0.21.3",
16
+ "typescript": "^6.0.2",
17
+ "vite": "^8.0.8"
18
18
  }
19
19
  }
@@ -8,11 +8,11 @@
8
8
  "preview": "cer-app preview --ssr"
9
9
  },
10
10
  "dependencies": {
11
- "@jasonshimmy/custom-elements-runtime": "^3.7.2"
11
+ "@jasonshimmy/custom-elements-runtime": "^3.7.5"
12
12
  },
13
13
  "devDependencies": {
14
- "@jasonshimmy/vite-plugin-cer-app": "^0.19.3",
15
- "typescript": "^5.9.3",
16
- "vite": "^8.0.3"
14
+ "@jasonshimmy/vite-plugin-cer-app": "^0.21.3",
15
+ "typescript": "^6.0.2",
16
+ "vite": "^8.0.8"
17
17
  }
18
18
  }
@@ -3,6 +3,7 @@ export interface ResolvedCerConfig {
3
3
  mode: 'spa' | 'ssr' | 'ssg';
4
4
  srcDir: string;
5
5
  root: string;
6
+ contentDir: string;
6
7
  pagesDir: string;
7
8
  layoutsDir: string;
8
9
  componentsDir: string;
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/plugin/dev-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAOzC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAA;IAC1E,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAA;IAC9D,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAA;IACtD,WAAW,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;IACjG,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,oBAAoB,EAAE,oBAAoB,CAAA;KAAE,CAAA;IAC9G,IAAI,EAAE,OAAO,oBAAoB,EAAE,UAAU,GAAG,IAAI,CAAA;IACpD,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB,GAAG,WAAW,CAAA;KAAE,GAAG,IAAI,CAAA;CACtH;AAwID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,iBAAiB,GACxB,IAAI,CA2MN"}
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/plugin/dev-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAOzC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAA;IAC1E,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAA;IAC9D,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAA;IACtD,WAAW,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;IACjG,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,oBAAoB,EAAE,oBAAoB,CAAA;KAAE,CAAA;IAC9G,IAAI,EAAE,OAAO,oBAAoB,EAAE,UAAU,GAAG,IAAI,CAAA;IACpD,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB,GAAG,WAAW,CAAA;KAAE,GAAG,IAAI,CAAA;CACtH;AAwID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,iBAAiB,GACxB,IAAI,CA2MN"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../../src/plugin/dev-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../../src/plugin/dev-server.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AA+CxD;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,GAAE,MAAsB,GAAG,iBAAiB,CAqDvG;AAyID;;;GAGG;AACH,wBAAgB,MAAM,CAAC,UAAU,GAAE,YAAiB,GAAG,MAAM,EAAE,CAmS9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAiDxD;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,GAAE,MAAsB,GAAG,iBAAiB,CAsDvG;AAiJD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,UAAU,GAAE,YAAiB,GAAG,MAAM,EAAE,CAoS9D"}
@@ -15,6 +15,7 @@ import { generateServerApiCode } from './virtual/server-api.js';
15
15
  import { generateServerMiddlewareCode } from './virtual/server-middleware.js';
16
16
  import { generateLoadingCode } from './virtual/loading.js';
17
17
  import { generateErrorCode } from './virtual/error.js';
18
+ import { generateContentComponentsCode } from './virtual/content-components.js';
18
19
  import { createWatcher } from './scanner.js';
19
20
  import { cerContent } from './content/index.js';
20
21
  // Virtual module IDs (raw)
@@ -29,6 +30,7 @@ const VIRTUAL_IDS = {
29
30
  appConfig: 'virtual:cer-app-config',
30
31
  loading: 'virtual:cer-loading',
31
32
  error: 'virtual:cer-error',
33
+ contentComponents: 'virtual:cer-content-components',
32
34
  i18n: 'virtual:cer-i18n',
33
35
  };
34
36
  // Resolved virtual module IDs (prefixed with \0)
@@ -50,6 +52,7 @@ export function resolveConfig(userConfig, root = process.cwd()) {
50
52
  mode,
51
53
  srcDir,
52
54
  root,
55
+ contentDir: resolve(root, userConfig.content?.dir ?? 'content'),
53
56
  pagesDir: join(srcDir, 'pages'),
54
57
  layoutsDir: join(srcDir, 'layouts'),
55
58
  componentsDir: join(srcDir, 'components'),
@@ -121,6 +124,8 @@ async function generateVirtualModule(id, config, ssr = false) {
121
124
  return generateLoadingCode(config.srcDir);
122
125
  case RESOLVED_IDS.error:
123
126
  return generateErrorCode(config.srcDir);
127
+ case RESOLVED_IDS.contentComponents:
128
+ return generateContentComponentsCode(config.componentsDir, config.contentDir);
124
129
  case RESOLVED_IDS.i18n:
125
130
  return generateI18nModule(config.i18n);
126
131
  default:
@@ -198,6 +203,9 @@ function getDirtyVirtualIds(filePath, config) {
198
203
  if (filePath.startsWith(config.layoutsDir)) {
199
204
  dirty.push(RESOLVED_IDS.layouts);
200
205
  }
206
+ if (filePath.startsWith(config.componentsDir)) {
207
+ dirty.push(RESOLVED_IDS.contentComponents);
208
+ }
201
209
  if (filePath.startsWith(config.composablesDir)) {
202
210
  dirty.push(RESOLVED_IDS.composables);
203
211
  }
@@ -213,6 +221,9 @@ function getDirtyVirtualIds(filePath, config) {
213
221
  if (filePath.startsWith(config.serverMiddlewareDir)) {
214
222
  dirty.push(RESOLVED_IDS.serverMiddleware);
215
223
  }
224
+ if (filePath.startsWith(config.contentDir)) {
225
+ dirty.push(RESOLVED_IDS.contentComponents);
226
+ }
216
227
  return dirty;
217
228
  }
218
229
  /**
@@ -351,6 +362,7 @@ export function cerApp(userConfig = {}) {
351
362
  config.pagesDir,
352
363
  config.layoutsDir,
353
364
  config.componentsDir,
365
+ config.contentDir,
354
366
  config.composablesDir,
355
367
  config.pluginsDir,
356
368
  config.middlewareDir,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generates a side-effect virtual module that registers app components used
3
+ * inside rendered markdown bodies.
4
+ */
5
+ export declare function generateContentComponentsCode(componentsDir: string, contentDir: string): Promise<string>;
6
+ //# sourceMappingURL=content-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-components.d.ts","sourceRoot":"","sources":["../../../src/plugin/virtual/content-components.ts"],"names":[],"mappings":"AAsDA;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
@@ -0,0 +1,70 @@
1
+ import { extractComponentRegistrations, extractTemplateTagNames } from '@jasonshimmy/custom-elements-runtime/vite-plugin';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { parseContentFileAsync } from '../content/parser.js';
4
+ import { scanContentFiles } from '../content/scanner.js';
5
+ import { scanDirectory } from '../scanner.js';
6
+ function emptyModule() {
7
+ return `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\nexport {}\n`;
8
+ }
9
+ async function buildComponentManifest(componentsDir) {
10
+ const manifest = new Map();
11
+ if (!existsSync(componentsDir))
12
+ return manifest;
13
+ const files = await scanDirectory('**/*.ts', componentsDir);
14
+ for (const file of files) {
15
+ try {
16
+ const source = readFileSync(file, 'utf-8');
17
+ for (const tag of extractComponentRegistrations(source)) {
18
+ manifest.set(tag, file);
19
+ }
20
+ }
21
+ catch {
22
+ // Skip unreadable files.
23
+ }
24
+ }
25
+ return manifest;
26
+ }
27
+ async function collectMarkdownTags(contentDir) {
28
+ const tags = new Set();
29
+ if (!existsSync(contentDir))
30
+ return tags;
31
+ const files = await scanContentFiles(contentDir);
32
+ const markdownFiles = files.filter((file) => file.ext === 'md');
33
+ await Promise.all(markdownFiles.map(async (file) => {
34
+ try {
35
+ const item = await parseContentFileAsync(file, contentDir);
36
+ for (const tag of extractTemplateTagNames(item.body)) {
37
+ tags.add(tag);
38
+ }
39
+ }
40
+ catch (err) {
41
+ console.warn(`[cer-app] Skipping content file (parse error): ${file.filePath}\n ${err.message}`);
42
+ }
43
+ }));
44
+ return tags;
45
+ }
46
+ /**
47
+ * Generates a side-effect virtual module that registers app components used
48
+ * inside rendered markdown bodies.
49
+ */
50
+ export async function generateContentComponentsCode(componentsDir, contentDir) {
51
+ const [manifest, markdownTags] = await Promise.all([
52
+ buildComponentManifest(componentsDir),
53
+ collectMarkdownTags(contentDir),
54
+ ]);
55
+ const imports = [...markdownTags]
56
+ .sort()
57
+ .map((tag) => manifest.get(tag))
58
+ .filter((file) => typeof file === 'string');
59
+ if (imports.length === 0)
60
+ return emptyModule();
61
+ const lines = ['// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app', ''];
62
+ for (const file of imports) {
63
+ lines.push(`import ${JSON.stringify(file)}`);
64
+ }
65
+ lines.push('');
66
+ lines.push('export {}');
67
+ lines.push('');
68
+ return lines.join('\n');
69
+ }
70
+ //# sourceMappingURL=content-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-components.js","sourceRoot":"","sources":["../../../src/plugin/virtual/content-components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AACzH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,SAAS,WAAW;IAClB,OAAO,oEAAoE,CAAA;AAC7E,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,aAAqB;IACzD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC1C,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAA;IAE/C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAC3D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC1C,KAAK,MAAM,GAAG,IAAI,6BAA6B,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,UAAkB;IACnD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAA;IAChD,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAA;IAE/D,MAAM,OAAO,CAAC,GAAG,CACf,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;YAC1D,KAAK,MAAM,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACf,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACV,kDAAkD,IAAI,CAAC,QAAQ,OAAQ,GAAa,CAAC,OAAO,EAAE,CAC/F,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CACH,CAAA;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,aAAqB,EACrB,UAAkB;IAElB,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjD,sBAAsB,CAAC,aAAa,CAAC;QACrC,mBAAmB,CAAC,UAAU,CAAC;KAChC,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,CAAC,GAAG,YAAY,CAAC;SAC9B,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SAC/B,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAA;IAE7D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,EAAE,CAAA;IAE9C,MAAM,KAAK,GAAG,CAAC,uDAAuD,EAAE,EAAE,CAAC,CAAA;IAC3E,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC9C,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
@@ -5,5 +5,5 @@
5
5
  * automatically receive the latest bootstrap code on plugin update.
6
6
  * This file is gitignored and should never be edited directly.
7
7
  */
8
- export declare const APP_ENTRY_TEMPLATE = "// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app \u2014 do not edit.\n// Regenerated automatically on every dev server start and build.\n\nimport '@jasonshimmy/custom-elements-runtime/css'\nimport 'virtual:cer-jit-css'\nimport routes from 'virtual:cer-routes'\nimport layouts from 'virtual:cer-layouts'\nimport plugins from 'virtual:cer-plugins'\nimport { hasLoading, loadingTag } from 'virtual:cer-loading'\nimport { hasError, errorTag } from 'virtual:cer-error'\nimport { runtimeConfig } from 'virtual:cer-app-config'\nimport {\n component,\n ref,\n provide,\n setDevMode,\n useOnConnected,\n useOnDisconnected,\n registerBuiltinComponents,\n} from '@jasonshimmy/custom-elements-runtime'\nimport { initRouter } from '@jasonshimmy/custom-elements-runtime/router'\nimport { enableJITCSS } from '@jasonshimmy/custom-elements-runtime/jit-css'\nimport { initRuntimeConfig } from '@jasonshimmy/vite-plugin-cer-app/composables'\n\nconst _cerProcess = (globalThis).process\nconst _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE\nconst _cerRuntimeDev =\n typeof _cerNodeEnv === 'string'\n ? _cerNodeEnv !== 'production'\n : typeof import.meta.env?.DEV === 'boolean'\n ? import.meta.env.DEV\n : typeof import.meta.env?.PROD === 'boolean'\n ? !import.meta.env.PROD\n : typeof import.meta.env?.MODE === 'string'\n ? import.meta.env.MODE !== 'production'\n : false\n;(globalThis).__CE_RUNTIME_DEV__ = _cerRuntimeDev\n\nregisterBuiltinComponents()\nsetDevMode(_cerRuntimeDev)\nenableJITCSS()\ninitRuntimeConfig(runtimeConfig)\n\nconst router = initRouter({ routes })\n\n// Expose the router globally so useRoute() and navigateTo() can access it\n// from any composable without circular imports.\n;(globalThis).__cerRouter = router\n\n// \u2500\u2500\u2500 Page loader state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Holds the pre-loaded page tag and loader-derived attrs for the current route.\n// Set by _loadPageForPath before every navigation so cer-layout-view can render\n// the page element directly with the correct attributes (enabling useProps()).\nlet _currentPageTag = null\nlet _currentPageAttrs = {}\n// The pathname this tag was loaded for \u2014 used to detect router-internal\n// redirects (e.g. middleware returning '/login') so cer-layout-view falls\n// back to <router-view> when the current route differs from what was pre-loaded.\nlet _currentPagePath = null\n\nfunction _toLoaderAttrs(data) {\n if (data === undefined || data === null || typeof data !== 'object') return {}\n return Object.fromEntries(\n Object.entries(data).filter(([, v]) => v !== null && v !== undefined && typeof v !== 'object' && typeof v !== 'function')\n )\n}\n\n// Pre-loads the page module for `path`, calls its loader if present, and\n// stores the results so cer-layout-view can pass them as element attributes.\nasync function _loadPageForPath(path, options = {}) {\n try {\n const url = new URL(path, 'http://x')\n const query = Object.fromEntries(url.searchParams)\n const { runLoader = true, initialData } = options ?? {}\n const matched = router.matchRoute(url.pathname)\n const route = matched?.route\n if (!route?.load) {\n _currentPageTag = null\n _currentPageAttrs = {}\n _currentPagePath = url.pathname\n return\n }\n const mod = await route.load()\n _currentPageTag = mod.default ?? null\n _currentPagePath = url.pathname\n const params = matched.params ?? {}\n let loaderAttrs = { ...params }\n let loaderData = initialData\n if (typeof mod.loader === 'function' && runLoader) {\n try {\n const data = await mod.loader({ params, query })\n if (data !== undefined && data !== null) {\n loaderData = data\n // Make loader data available via usePageData() for this navigation.\n ;(globalThis).__CER_DATA__ = data\n }\n } catch (err) {\n // Loader errors are surfaced through currentError so the error boundary\n // (app/error.ts) can display a meaningful message \u2014 consistent with how\n // the server-side handler behaves when a loader throws.\n currentError.value = err instanceof Error ? err.message : String(err)\n }\n }\n // For the very first hydration pass in SSR/SSG we already have the server's\n // loader payload in globalThis.__CER_DATA__ / window.__CER_DATA__. Reuse it\n // instead of re-running the loader on the client, then derive primitive attrs\n // from that payload so useProps() stays consistent with usePageData().\n loaderAttrs = { ...loaderAttrs, ..._toLoaderAttrs(loaderData) }\n _currentPageAttrs = loaderAttrs\n } catch {\n _currentPageTag = null\n _currentPageAttrs = {}\n _currentPagePath = null\n }\n}\n\n// \u2500\u2500\u2500 Navigation state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst isNavigating = ref(false)\nconst currentError = ref(null)\n\nconst resetError = () => {\n currentError.value = null\n void router.replace(router.getCurrent().path)\n}\n;(globalThis).resetError = resetError\n\nconst _push = router.push.bind(router)\nconst _replace = router.replace.bind(router)\n\nrouter.push = async (path) => {\n isNavigating.value = true\n currentError.value = null\n try {\n // Clear stale loader data from the previous route before loading the new one.\n // If the new route has no loader, __CER_DATA__ stays undefined so usePageData()\n // correctly returns null instead of leaking the previous page's data.\n delete (globalThis).__CER_DATA__\n await _loadPageForPath(path)\n await _push(path)\n } catch (err) {\n currentError.value = err instanceof Error ? err.message : String(err)\n } finally {\n isNavigating.value = false\n }\n}\n\nrouter.replace = async (path) => {\n isNavigating.value = true\n currentError.value = null\n try {\n // Clear stale loader data from the previous route before loading the new one.\n delete (globalThis).__CER_DATA__\n await _loadPageForPath(path)\n await _replace(path)\n } catch (err) {\n currentError.value = err instanceof Error ? err.message : String(err)\n } finally {\n isNavigating.value = false\n }\n}\n\n// \u2500\u2500\u2500 Plugins \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Collect plugin-provided values so cer-layout-view can forward them into\n// the component context tree via the real provide() hook (which inject() walks).\n// Declared BEFORE component('cer-layout-view') to avoid a temporal dead zone\n// ReferenceError: customElements.define() upgrades existing DOM elements\n// synchronously, calling the render function immediately.\nconst _pluginProvides = new Map()\n// Expose plugin provides globally so page components can read them synchronously\n// regardless of render order.\n;(globalThis).__cerPluginProvides = _pluginProvides\n\n// \u2500\u2500\u2500 <cer-layout-view> \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// True until the initial page module has loaded and _replace has been called.\n// While true, cer-layout-view renders a <slot> so the SSR/SSG pre-rendered\n// light-DOM content stays visible and no FOUC occurs during the hydration gap.\n// Declared here (before component()) because customElements.define() upgrades\n// existing DOM elements synchronously, so the render function reads this ref\n// on the very first call \u2014 before _doHydrate has a chance to run.\nconst _cerHydrating = ref(true)\n\ncomponent('cer-layout-view', () => {\n // Forward plugin-provided values into the component context so inject() in\n // any descendant component can resolve them by walking up the DOM tree.\n for (const [key, value] of _pluginProvides) {\n provide(key, value)\n }\n\n const current = ref(router.getCurrent())\n let unsub\n let _sawInitialRouteState = false\n\n useOnConnected(() => {\n // store.subscribe() synchronously pushes the current route once on\n // subscription. That initial callback is not a real navigation and must not\n // tear down the SSR slot before _doHydrate has pre-loaded the page.\n // Subsequent callbacks are real navigations (including the initial _replace\n // in _doHydrate), so if they arrive during the hydration gap we drop the\n // slot immediately and let the live render take over.\n unsub = router.subscribe((s) => {\n const _isInitialSubscribePush = !_sawInitialRouteState\n _sawInitialRouteState = true\n if (_isInitialSubscribePush) {\n current.value = s\n return\n }\n if (_cerHydrating.value) _cerHydrating.value = false\n current.value = s\n })\n })\n useOnDisconnected(() => { unsub?.(); unsub = undefined })\n\n // While the initial page module is being loaded, keep the SSR/SSG\n // pre-rendered light-DOM content visible by forwarding it through a <slot>.\n // This prevents the intermediate blank state that occurs when the shadow DOM\n // renders layout-default with an empty <router-view> before the page chunk\n // has arrived. In SPA mode (no pre-rendered content) the slot is empty, which\n // is no worse than the current router-view behaviour.\n if (_cerHydrating.value) {\n return { tag: 'slot', props: {}, children: [] }\n }\n\n const matched = router.matchRoute(current.value.path)\n const routeMeta = matched?.route?.meta\n\n if (currentError.value !== null) {\n const routeErrorTag = routeMeta?.errorTag ?? null\n const effectiveErrorTag = routeErrorTag ?? (hasError ? errorTag : null)\n if (effectiveErrorTag) {\n return { tag: effectiveErrorTag, props: { attrs: { error: String(currentError.value) } }, children: [] }\n }\n return { tag: 'div', props: { attrs: { style: 'padding:2rem;font-family:monospace' } }, children: String(currentError.value) }\n }\n\n if (isNavigating.value && hasLoading && loadingTag) {\n return { tag: loadingTag, props: {}, children: [] }\n }\n\n // Render the page component directly when a pre-loaded tag is available AND\n // the loaded path matches the current route. The path guard detects\n // router-internal redirects (e.g. middleware returning '/login'): when the\n // router redirects to a different path, _currentPagePath won't match\n // current.value.path and we fall back to <router-view> so the correct page\n // is rendered without stale pre-loaded state.\n const _useDirectRender = _currentPageTag && _currentPagePath === current.value.path\n const pageVnode = _useDirectRender\n ? { tag: _currentPageTag, props: { attrs: _currentPageAttrs }, children: [] }\n : { tag: 'router-view', props: {}, children: [] }\n\n // Support nested layout chains: meta.layoutChain = ['default', 'admin']\n // renders <layout-default><layout-admin><page/></layout-admin></layout-default>\n const chain = routeMeta?.layoutChain\n ? routeMeta.layoutChain\n : [routeMeta?.layout ?? 'default']\n\n // Build nested vnodes from innermost to outermost.\n let vnode = pageVnode\n for (let i = chain.length - 1; i >= 0; i--) {\n const tag = layouts[chain[i]]\n if (tag) vnode = { tag, props: {}, children: [vnode] }\n }\n return vnode\n})\n\nfor (const plugin of plugins) {\n if (plugin && typeof plugin.setup === 'function') {\n await plugin.setup({\n router,\n provide: (key, value) => { _pluginProvides.set(key, value) },\n config: {},\n })\n }\n}\n\n// \u2500\u2500\u2500 Pre-load initial route + hydration strategy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Download the current page's route chunk AFTER plugins run so that\n// cer-layout-view's first render (which calls provide()) completes before\n// page components are defined and their renders are scheduled. This ensures\n// inject() in child components can find values stored by provide().\n//\n// meta.hydrate controls WHEN the initial page activates:\n// 'load' \u2014 immediately (default)\n// 'idle' \u2014 deferred until requestIdleCallback (browser idle)\n// 'visible' \u2014 deferred until cer-layout-view enters the viewport\n// 'none' \u2014 never: SSR HTML stays as-is, no JS activation\n\nif (typeof window !== 'undefined') {\n const _initMatch = router.matchRoute(window.location.pathname)\n const _hydrateStrategy = _initMatch?.route?.meta?.hydrate ?? 'load'\n\n if (_hydrateStrategy === 'none') {\n // Static HTML only \u2014 leave SSR output untouched, clean up data immediately.\n delete (globalThis).__CER_DATA__\n } else {\n const _doHydrate = async () => {\n const _initPath = window.location.pathname + window.location.search + window.location.hash\n const _hasInitialLoaderData = Object.prototype.hasOwnProperty.call(globalThis, '__CER_DATA__')\n // Pre-load the page module and run the loader so cer-layout-view renders\n // the page tag directly with loader attrs (enables useProps() on hydration).\n await _loadPageForPath(\n _initPath,\n _hasInitialLoaderData\n ? { runLoader: false, initialData: (globalThis).__CER_DATA__ }\n : undefined,\n )\n // Only activate the initial route if the URL hasn't changed while we were\n // loading the module asynchronously (e.g. a test or plugin navigated away\n // before _doHydrate finished). Calling _replace with a stale path would\n // override any navigation that happened during the async gap.\n const _currentPath = window.location.pathname + window.location.search + window.location.hash\n // Drop the hydration slot cover unconditionally: the page module is loaded\n // and cer-layout-view must switch from the <slot> to live rendering whether\n // or not a redirect changed the path during loading.\n _cerHydrating.value = false\n if (_currentPath === _initPath) {\n // Use the original (unwrapped) replace so isNavigating stays false during\n // the initial paint \u2014 the loading component must not flash over pre-rendered content.\n await _replace(_initPath)\n }\n // The client entry marks the already-rendered entry URL so generated\n // route middleware can skip the browser router's startup replay once.\n // Clear any leftover flag after the first hydrated route commits so later\n // navigations always run middleware normally.\n queueMicrotask(() => { delete (globalThis).__CER_HYDRATION_ENTRY__ })\n // Keep the initial route's SSR data available after hydration.\n // Browser engines do not all upgrade and re-render custom elements with\n // identical timing, so deleting __CER_DATA__ here can cause a later\n // hydration render to fall back to the client-only path. The next real\n // router.push/router.replace clears __CER_DATA__ before loading the new\n // route, so stale page data still does not leak across navigations.\n }\n\n if (_hydrateStrategy === 'idle') {\n // Defer until the browser has finished higher-priority work.\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(() => { void _doHydrate() })\n } else {\n // Safari / older environments fallback.\n setTimeout(() => { void _doHydrate() }, 1)\n }\n } else if (_hydrateStrategy === 'visible') {\n // Defer until cer-layout-view (or body as fallback) enters the viewport.\n const _el = document.querySelector('cer-layout-view') ?? document.body\n const _io = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) { _io.disconnect(); void _doHydrate() }\n })\n _io.observe(_el)\n } else {\n // 'load' \u2014 hydrate immediately (default behaviour).\n await _doHydrate()\n }\n }\n}\n\nexport { router }\n";
8
+ export declare const APP_ENTRY_TEMPLATE = "// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app \u2014 do not edit.\n// Regenerated automatically on every dev server start and build.\n\nimport '@jasonshimmy/custom-elements-runtime/css'\nimport 'virtual:cer-jit-css'\nimport 'virtual:cer-content-components'\nimport routes from 'virtual:cer-routes'\nimport layouts from 'virtual:cer-layouts'\nimport plugins from 'virtual:cer-plugins'\nimport { hasLoading, loadingTag } from 'virtual:cer-loading'\nimport { hasError, errorTag } from 'virtual:cer-error'\nimport { runtimeConfig } from 'virtual:cer-app-config'\nimport {\n component,\n ref,\n provide,\n setDevMode,\n useOnConnected,\n useOnDisconnected,\n registerBuiltinComponents,\n} from '@jasonshimmy/custom-elements-runtime'\nimport { initRouter } from '@jasonshimmy/custom-elements-runtime/router'\nimport { enableJITCSS } from '@jasonshimmy/custom-elements-runtime/jit-css'\nimport { initRuntimeConfig } from '@jasonshimmy/vite-plugin-cer-app/composables'\n\nconst _cerProcess = (globalThis).process\nconst _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE\nconst _cerRuntimeDev =\n typeof _cerNodeEnv === 'string'\n ? _cerNodeEnv !== 'production'\n : typeof import.meta.env?.DEV === 'boolean'\n ? import.meta.env.DEV\n : typeof import.meta.env?.PROD === 'boolean'\n ? !import.meta.env.PROD\n : typeof import.meta.env?.MODE === 'string'\n ? import.meta.env.MODE !== 'production'\n : false\n;(globalThis).__CE_RUNTIME_DEV__ = _cerRuntimeDev\n\nregisterBuiltinComponents()\nsetDevMode(_cerRuntimeDev)\nenableJITCSS()\ninitRuntimeConfig(runtimeConfig)\n\nconst router = initRouter({ routes })\n\n// Expose the router globally so useRoute() and navigateTo() can access it\n// from any composable without circular imports.\n;(globalThis).__cerRouter = router\n\n// \u2500\u2500\u2500 Page loader state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Holds the pre-loaded page tag and loader-derived attrs for the current route.\n// Set by _loadPageForPath before every navigation so cer-layout-view can render\n// the page element directly with the correct attributes (enabling useProps()).\nlet _currentPageTag = null\nlet _currentPageAttrs = {}\n// The pathname this tag was loaded for \u2014 used to detect router-internal\n// redirects (e.g. middleware returning '/login') so cer-layout-view falls\n// back to <router-view> when the current route differs from what was pre-loaded.\nlet _currentPagePath = null\n\nfunction _toLoaderAttrs(data) {\n if (data === undefined || data === null || typeof data !== 'object') return {}\n return Object.fromEntries(\n Object.entries(data).filter(([, v]) => v !== null && v !== undefined && typeof v !== 'object' && typeof v !== 'function')\n )\n}\n\n// Pre-loads the page module for `path`, calls its loader if present, and\n// stores the results so cer-layout-view can pass them as element attributes.\nasync function _loadPageForPath(path, options = {}) {\n try {\n const url = new URL(path, 'http://x')\n const query = Object.fromEntries(url.searchParams)\n const { runLoader = true, initialData } = options ?? {}\n const matched = router.matchRoute(url.pathname)\n const route = matched?.route\n if (!route?.load) {\n _currentPageTag = null\n _currentPageAttrs = {}\n _currentPagePath = url.pathname\n return\n }\n const mod = await route.load()\n _currentPageTag = mod.default ?? null\n _currentPagePath = url.pathname\n const params = matched.params ?? {}\n let loaderAttrs = { ...params }\n let loaderData = initialData\n if (typeof mod.loader === 'function' && runLoader) {\n try {\n const data = await mod.loader({ params, query })\n if (data !== undefined && data !== null) {\n loaderData = data\n // Make loader data available via usePageData() for this navigation.\n ;(globalThis).__CER_DATA__ = data\n }\n } catch (err) {\n // Loader errors are surfaced through currentError so the error boundary\n // (app/error.ts) can display a meaningful message \u2014 consistent with how\n // the server-side handler behaves when a loader throws.\n currentError.value = err instanceof Error ? err.message : String(err)\n }\n }\n // For the very first hydration pass in SSR/SSG we already have the server's\n // loader payload in globalThis.__CER_DATA__ / window.__CER_DATA__. Reuse it\n // instead of re-running the loader on the client, then derive primitive attrs\n // from that payload so useProps() stays consistent with usePageData().\n loaderAttrs = { ...loaderAttrs, ..._toLoaderAttrs(loaderData) }\n _currentPageAttrs = loaderAttrs\n } catch {\n _currentPageTag = null\n _currentPageAttrs = {}\n _currentPagePath = null\n }\n}\n\n// \u2500\u2500\u2500 Navigation state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst isNavigating = ref(false)\nconst currentError = ref(null)\n\nconst resetError = () => {\n currentError.value = null\n void router.replace(router.getCurrent().path)\n}\n;(globalThis).resetError = resetError\n\nconst _push = router.push.bind(router)\nconst _replace = router.replace.bind(router)\n\nrouter.push = async (path) => {\n isNavigating.value = true\n currentError.value = null\n try {\n // Clear stale loader data from the previous route before loading the new one.\n // If the new route has no loader, __CER_DATA__ stays undefined so usePageData()\n // correctly returns null instead of leaking the previous page's data.\n delete (globalThis).__CER_DATA__\n await _loadPageForPath(path)\n await _push(path)\n } catch (err) {\n currentError.value = err instanceof Error ? err.message : String(err)\n } finally {\n isNavigating.value = false\n }\n}\n\nrouter.replace = async (path) => {\n isNavigating.value = true\n currentError.value = null\n try {\n // Clear stale loader data from the previous route before loading the new one.\n delete (globalThis).__CER_DATA__\n await _loadPageForPath(path)\n await _replace(path)\n } catch (err) {\n currentError.value = err instanceof Error ? err.message : String(err)\n } finally {\n isNavigating.value = false\n }\n}\n\n// \u2500\u2500\u2500 Plugins \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Collect plugin-provided values so cer-layout-view can forward them into\n// the component context tree via the real provide() hook (which inject() walks).\n// Declared BEFORE component('cer-layout-view') to avoid a temporal dead zone\n// ReferenceError: customElements.define() upgrades existing DOM elements\n// synchronously, calling the render function immediately.\nconst _pluginProvides = new Map()\n// Expose plugin provides globally so page components can read them synchronously\n// regardless of render order.\n;(globalThis).__cerPluginProvides = _pluginProvides\n\n// \u2500\u2500\u2500 <cer-layout-view> \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// True until the initial page module has loaded and _replace has been called.\n// While true, cer-layout-view renders a <slot> so the SSR/SSG pre-rendered\n// light-DOM content stays visible and no FOUC occurs during the hydration gap.\n// Declared here (before component()) because customElements.define() upgrades\n// existing DOM elements synchronously, so the render function reads this ref\n// on the very first call \u2014 before _doHydrate has a chance to run.\nconst _cerHydrating = ref(true)\n\ncomponent('cer-layout-view', () => {\n // Forward plugin-provided values into the component context so inject() in\n // any descendant component can resolve them by walking up the DOM tree.\n for (const [key, value] of _pluginProvides) {\n provide(key, value)\n }\n\n const current = ref(router.getCurrent())\n let unsub\n let _sawInitialRouteState = false\n\n useOnConnected(() => {\n // store.subscribe() synchronously pushes the current route once on\n // subscription. That initial callback is not a real navigation and must not\n // tear down the SSR slot before _doHydrate has pre-loaded the page.\n // Subsequent callbacks are real navigations (including the initial _replace\n // in _doHydrate), so if they arrive during the hydration gap we drop the\n // slot immediately and let the live render take over.\n unsub = router.subscribe((s) => {\n const _isInitialSubscribePush = !_sawInitialRouteState\n _sawInitialRouteState = true\n if (_isInitialSubscribePush) {\n current.value = s\n return\n }\n if (_cerHydrating.value) _cerHydrating.value = false\n current.value = s\n })\n })\n useOnDisconnected(() => { unsub?.(); unsub = undefined })\n\n // While the initial page module is being loaded, keep the SSR/SSG\n // pre-rendered light-DOM content visible by forwarding it through a <slot>.\n // This prevents the intermediate blank state that occurs when the shadow DOM\n // renders layout-default with an empty <router-view> before the page chunk\n // has arrived. In SPA mode (no pre-rendered content) the slot is empty, which\n // is no worse than the current router-view behaviour.\n if (_cerHydrating.value) {\n return { tag: 'slot', props: {}, children: [] }\n }\n\n const matched = router.matchRoute(current.value.path)\n const routeMeta = matched?.route?.meta\n\n if (currentError.value !== null) {\n const routeErrorTag = routeMeta?.errorTag ?? null\n const effectiveErrorTag = routeErrorTag ?? (hasError ? errorTag : null)\n if (effectiveErrorTag) {\n return { tag: effectiveErrorTag, props: { attrs: { error: String(currentError.value) } }, children: [] }\n }\n return { tag: 'div', props: { attrs: { style: 'padding:2rem;font-family:monospace' } }, children: String(currentError.value) }\n }\n\n if (isNavigating.value && hasLoading && loadingTag) {\n return { tag: loadingTag, props: {}, children: [] }\n }\n\n // Render the page component directly when a pre-loaded tag is available AND\n // the loaded path matches the current route. The path guard detects\n // router-internal redirects (e.g. middleware returning '/login'): when the\n // router redirects to a different path, _currentPagePath won't match\n // current.value.path and we fall back to <router-view> so the correct page\n // is rendered without stale pre-loaded state.\n const _useDirectRender = _currentPageTag && _currentPagePath === current.value.path\n const pageVnode = _useDirectRender\n ? { tag: _currentPageTag, props: { attrs: _currentPageAttrs }, children: [] }\n : { tag: 'router-view', props: {}, children: [] }\n\n // Support nested layout chains: meta.layoutChain = ['default', 'admin']\n // renders <layout-default><layout-admin><page/></layout-admin></layout-default>\n const chain = routeMeta?.layoutChain\n ? routeMeta.layoutChain\n : [routeMeta?.layout ?? 'default']\n\n // Build nested vnodes from innermost to outermost.\n let vnode = pageVnode\n for (let i = chain.length - 1; i >= 0; i--) {\n const tag = layouts[chain[i]]\n if (tag) vnode = { tag, props: {}, children: [vnode] }\n }\n return vnode\n})\n\nfor (const plugin of plugins) {\n if (plugin && typeof plugin.setup === 'function') {\n await plugin.setup({\n router,\n provide: (key, value) => { _pluginProvides.set(key, value) },\n config: {},\n })\n }\n}\n\n// \u2500\u2500\u2500 Pre-load initial route + hydration strategy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Download the current page's route chunk AFTER plugins run so that\n// cer-layout-view's first render (which calls provide()) completes before\n// page components are defined and their renders are scheduled. This ensures\n// inject() in child components can find values stored by provide().\n//\n// meta.hydrate controls WHEN the initial page activates:\n// 'load' \u2014 immediately (default)\n// 'idle' \u2014 deferred until requestIdleCallback (browser idle)\n// 'visible' \u2014 deferred until cer-layout-view enters the viewport\n// 'none' \u2014 never: SSR HTML stays as-is, no JS activation\n\nif (typeof window !== 'undefined') {\n const _initMatch = router.matchRoute(window.location.pathname)\n const _hydrateStrategy = _initMatch?.route?.meta?.hydrate ?? 'load'\n\n if (_hydrateStrategy === 'none') {\n // Static HTML only \u2014 leave SSR output untouched, clean up data immediately.\n delete (globalThis).__CER_DATA__\n } else {\n const _doHydrate = async () => {\n const _initPath = window.location.pathname + window.location.search + window.location.hash\n const _hasInitialLoaderData = Object.prototype.hasOwnProperty.call(globalThis, '__CER_DATA__')\n // Pre-load the page module and run the loader so cer-layout-view renders\n // the page tag directly with loader attrs (enables useProps() on hydration).\n await _loadPageForPath(\n _initPath,\n _hasInitialLoaderData\n ? { runLoader: false, initialData: (globalThis).__CER_DATA__ }\n : undefined,\n )\n // Only activate the initial route if the URL hasn't changed while we were\n // loading the module asynchronously (e.g. a test or plugin navigated away\n // before _doHydrate finished). Calling _replace with a stale path would\n // override any navigation that happened during the async gap.\n const _currentPath = window.location.pathname + window.location.search + window.location.hash\n // Drop the hydration slot cover unconditionally: the page module is loaded\n // and cer-layout-view must switch from the <slot> to live rendering whether\n // or not a redirect changed the path during loading.\n _cerHydrating.value = false\n if (_currentPath === _initPath) {\n // Use the original (unwrapped) replace so isNavigating stays false during\n // the initial paint \u2014 the loading component must not flash over pre-rendered content.\n await _replace(_initPath)\n }\n // The client entry marks the already-rendered entry URL so generated\n // route middleware can skip the browser router's startup replay once.\n // Clear any leftover flag after the first hydrated route commits so later\n // navigations always run middleware normally.\n queueMicrotask(() => { delete (globalThis).__CER_HYDRATION_ENTRY__ })\n // Keep the initial route's SSR data available after hydration.\n // Browser engines do not all upgrade and re-render custom elements with\n // identical timing, so deleting __CER_DATA__ here can cause a later\n // hydration render to fall back to the client-only path. The next real\n // router.push/router.replace clears __CER_DATA__ before loading the new\n // route, so stale page data still does not leak across navigations.\n }\n\n if (_hydrateStrategy === 'idle') {\n // Defer until the browser has finished higher-priority work.\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(() => { void _doHydrate() })\n } else {\n // Safari / older environments fallback.\n setTimeout(() => { void _doHydrate() }, 1)\n }\n } else if (_hydrateStrategy === 'visible') {\n // Defer until cer-layout-view (or body as fallback) enters the viewport.\n const _el = document.querySelector('cer-layout-view') ?? document.body\n const _io = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) { _io.disconnect(); void _doHydrate() }\n })\n _io.observe(_el)\n } else {\n // 'load' \u2014 hydrate immediately (default behaviour).\n await _doHydrate()\n }\n }\n}\n\nexport { router }\n";
9
9
  //# sourceMappingURL=app-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-template.d.ts","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,qrhBAuW9B,CAAA"}
1
+ {"version":3,"file":"app-template.d.ts","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,8thBAwW9B,CAAA"}
@@ -10,6 +10,7 @@ export const APP_ENTRY_TEMPLATE = `// AUTO-GENERATED by @jasonshimmy/vite-plugin
10
10
 
11
11
  import '@jasonshimmy/custom-elements-runtime/css'
12
12
  import 'virtual:cer-jit-css'
13
+ import 'virtual:cer-content-components'
13
14
  import routes from 'virtual:cer-routes'
14
15
  import layouts from 'virtual:cer-layouts'
15
16
  import plugins from 'virtual:cer-plugins'
@@ -1 +1 @@
1
- {"version":3,"file":"app-template.js","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuWjC,CAAA"}
1
+ {"version":3,"file":"app-template.js","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwWjC,CAAA"}
@@ -11,5 +11,5 @@
11
11
  * - useHead() support via beginHeadCollection / endHeadCollection
12
12
  * - DSD polyfill injected at end of <body> after client-template merge
13
13
  */
14
- export declare const ENTRY_SERVER_TEMPLATE = "// Server-side entry \u2014 AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport routes from 'virtual:cer-routes'\nimport layouts from 'virtual:cer-layouts'\nimport plugins from 'virtual:cer-plugins'\nimport apiRoutes from 'virtual:cer-server-api'\nimport serverMiddleware from 'virtual:cer-server-middleware'\nimport { runtimeConfig, _runtimePrivateDefaults, _authSessionKey, _hooks } from 'virtual:cer-app-config'\nimport { registerBuiltinComponents, setDevMode } from '@jasonshimmy/custom-elements-runtime'\nimport { registerEntityMap, renderToStreamWithJITCSSDSD, DSD_POLYFILL_SCRIPT } from '@jasonshimmy/custom-elements-runtime/ssr'\nimport entitiesJson from '@jasonshimmy/custom-elements-runtime/entities.json'\nimport { initRouter } from '@jasonshimmy/custom-elements-runtime/router'\nimport { beginHeadCollection, endHeadCollection, serializeHeadTags, initRuntimeConfig, resolvePrivateConfig, useSession } from '@jasonshimmy/vite-plugin-cer-app/composables'\nimport { errorTag } from 'virtual:cer-error'\nimport { createIsrHandler } from '@jasonshimmy/vite-plugin-cer-app/isr'\n\nconst _cerProcess = (globalThis).process\nconst _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE\nconst _cerRuntimeDev =\n typeof _cerNodeEnv === 'string'\n ? _cerNodeEnv !== 'production'\n : typeof import.meta.env?.DEV === 'boolean'\n ? import.meta.env.DEV\n : typeof import.meta.env?.PROD === 'boolean'\n ? !import.meta.env.PROD\n : typeof import.meta.env?.MODE === 'string'\n ? import.meta.env.MODE !== 'production'\n : false\n;(globalThis).__CE_RUNTIME_DEV__ = _cerRuntimeDev\n\nregisterBuiltinComponents()\nsetDevMode(_cerRuntimeDev)\n\n// Resolve private config from environment variables at server startup.\n// Each key declared in runtimeConfig.private is looked up in process.env,\n// first as-is, then as ALL_CAPS. The declared default is used as fallback.\ninitRuntimeConfig({ ...runtimeConfig, private: resolvePrivateConfig(_runtimePrivateDefaults ?? {}) })\n\n// Pre-load the full HTML entity map so named entities like &mdash; decode\n// correctly during SSR. Without this the bundled runtime falls back to a\n// minimal set (&lt;, &gt;, &amp; \u2026) and re-escapes everything else.\nregisterEntityMap(entitiesJson)\n\n// Run plugins once at server startup so their provide() values are available\n// to useInject() during every SSR/SSG render pass. Stored on globalThis so all\n// dynamically-imported page chunks share the same reference.\nconst _pluginProvides = new Map()\n;(globalThis).__cerPluginProvides = _pluginProvides\nconst _pluginsReady = (async () => {\n const _bootstrapRouter = initRouter({ routes })\n for (const plugin of plugins) {\n if (plugin && typeof plugin.setup === 'function') {\n await plugin.setup({\n router: _bootstrapRouter,\n provide: (key, value) => _pluginProvides.set(key, value),\n config: {},\n })\n }\n }\n})()\n\n// Async-local storage for request-scoped SSR loader data.\n// Using AsyncLocalStorage ensures concurrent SSR renders (e.g. SSG with\n// concurrency > 1) never see each other's data \u2014 each request's async chain\n// carries its own store value, so usePageData() is always race-condition-free.\nconst _cerDataStore = new AsyncLocalStorage()\n// Expose the store so the usePageData() composable can read it server-side.\n;(globalThis).__CER_DATA_STORE__ = _cerDataStore\n\n// Async-local storage for request-scoped req/res access.\n// Allows isomorphic composables (e.g. useCookie) to read/write HTTP headers\n// without prop-drilling the request context through the component tree.\nconst _cerReqStore = new AsyncLocalStorage()\n;(globalThis).__CER_REQ_STORE__ = _cerReqStore\n\n// Async-local storage for the authenticated user resolved before each render.\n// useAuth() reads this store server-side to return the current user synchronously.\nconst _cerAuthStore = new AsyncLocalStorage()\n;(globalThis).__CER_AUTH_STORE__ = _cerAuthStore\n\n// Async-local storage for per-request useFetch() data.\n// useFetch() writes fetched results here; the handler serialises the map into\n// window.__CER_FETCH_DATA__ for client-side hydration.\nconst _cerFetchStore = new AsyncLocalStorage()\n;(globalThis).__CER_FETCH_STORE__ = _cerFetchStore\n\n// Async-local storage for the current route info (path, params, query, meta).\n// useRoute() reads this on the server so layouts and components can access\n// route metadata without prop-drilling.\nconst _cerRouteStore = new AsyncLocalStorage()\n;(globalThis).__CER_ROUTE_STORE__ = _cerRouteStore\n\n// Async-local storage for per-request useState() reactive state.\n// Each request gets a fresh Map so concurrent SSR/SSG renders never share\n// reactive state set by different pages or loaders.\nconst _cerStateStore = new AsyncLocalStorage()\n;(globalThis).__CER_STATE_STORE__ = _cerStateStore\n\n// Runs fn inside the per-request AsyncLocalStorage context so that isomorphic\n// composables (useCookie, useSession, etc.) can access req/res without prop-drilling.\n// Call this for every API handler invocation \u2014 not just SSR renders.\nexport function runWithRequestContext(req, res, fn) {\n return _cerReqStore.run({ req, res }, fn)\n}\n\n// Runs the server/middleware/ chain for a request.\n// Returns false if a middleware short-circuited the response; true to continue.\n// Exported so Netlify / Vercel / Cloudflare bridges can also call it for API routes.\n// P1-2: Middleware may throw { status: 401 } (or any numeric .status) to produce\n// a non-500 response \u2014 the status is extracted and forwarded to res.statusCode.\nexport async function runServerMiddleware(req, res) {\n for (const { handler: mw } of (serverMiddleware ?? [])) {\n if (typeof mw !== 'function') continue\n let calledNext = false\n try {\n await new Promise((resolve, reject) => {\n Promise.resolve(mw(req, res, (err) => {\n if (err) reject(err)\n else { calledNext = true; resolve() }\n })).catch(reject)\n })\n } catch (err) {\n if (_hooks?.onError) {\n try { await _hooks.onError(err, { type: 'middleware', path: new URL(req.url ?? '/', 'http://x').pathname, req }) } catch { /* hooks must not crash the handler */ }\n }\n if (!res.writableEnded) {\n const statusCode = (typeof err === 'object' && err !== null && 'status' in err && typeof err.status === 'number')\n ? (isNaN(err.status) ? 500 : err.status)\n : 500\n res.statusCode = statusCode\n res.end('Internal Server Error')\n }\n return false\n }\n if (res.writableEnded || !calledNext) return false\n }\n return true\n}\n\n// Load the Vite-built client index.html (dist/client/index.html) so every SSR\n// response includes the client-side scripts needed for hydration and routing.\n// The server bundle lives at dist/server/server.js, so ../client resolves correctly.\n//\n// Cloudflare Workers (and other runtimes without node:fs) can inject the\n// template before this module loads by setting globalThis.__CER_CLIENT_TEMPLATE__.\n// The Cloudflare adapter inlines dist/client/index.html as a string constant in\n// _worker.js and sets the global before dynamically importing the server bundle.\nlet _clientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? null\nif (!_clientTemplate) {\n try {\n const _clientTemplatePath = join(dirname(fileURLToPath(import.meta.url)), '../client/index.html')\n _clientTemplate = existsSync(_clientTemplatePath)\n ? readFileSync(_clientTemplatePath, 'utf-8')\n : null\n } catch {\n // node:fs not available in this runtime \u2014 Cloudflare adapter must set\n // globalThis.__CER_CLIENT_TEMPLATE__ before importing this bundle.\n }\n}\n\n// Merge the SSR rendered body with the Vite client shell so the final page\n// contains both pre-rendered DSD content and the client bundle scripts.\nfunction _mergeWithClientTemplate(ssrHtml, clientTemplate) {\n const headTag = '<head>', headCloseTag = '</head>'\n const bodyTag = '<body>', bodyCloseTag = '</body>'\n const headStart = ssrHtml.indexOf(headTag)\n const headEnd = ssrHtml.indexOf(headCloseTag)\n const bodyStart = ssrHtml.indexOf(bodyTag)\n const bodyEnd = ssrHtml.lastIndexOf(bodyCloseTag)\n const ssrHead = headStart >= 0 && headEnd > headStart\n ? ssrHtml.slice(headStart + headTag.length, headEnd).trim() : ''\n const ssrBody = bodyStart >= 0 && bodyEnd > bodyStart\n ? ssrHtml.slice(bodyStart + bodyTag.length, bodyEnd).trim() : ssrHtml\n // Hoist only top-level <style id=...> elements (cer-ssr-jit, cer-ssr-global)\n // from the SSR body into the document <head>. Plain <style> blocks without\n // an id attribute belong to shadow DOM templates and must stay in place \u2014\n // hoisting them to <head> breaks shadow DOM style encapsulation (document\n // styles do not pierce shadow roots), which is the root cause of FOUC.\n const headParts = ssrHead ? [ssrHead] : []\n let ssrBodyContent = ssrBody\n let pos = 0\n while (pos < ssrBodyContent.length) {\n const styleOpen = ssrBodyContent.indexOf('<style id=', pos)\n if (styleOpen < 0) break\n const styleClose = ssrBodyContent.indexOf('</style>', styleOpen)\n if (styleClose < 0) break\n headParts.push(ssrBodyContent.slice(styleOpen, styleClose + 8))\n ssrBodyContent = ssrBodyContent.slice(0, styleOpen) + ssrBodyContent.slice(styleClose + 8)\n pos = styleOpen\n }\n ssrBodyContent = ssrBodyContent.trim()\n // Inject the pre-rendered layout+page as light DOM of the app mount element\n // so it is visible before JS boots, then the client router takes over.\n let merged = clientTemplate\n if (merged.includes('<cer-layout-view></cer-layout-view>')) {\n merged = merged.replace('<cer-layout-view></cer-layout-view>',\n '<cer-layout-view>' + ssrBodyContent + '</cer-layout-view>')\n } else if (merged.includes('<div id=\"app\"></div>')) {\n merged = merged.replace('<div id=\"app\"></div>',\n '<div id=\"app\">' + ssrBodyContent + '</div>')\n }\n const headAdditions = headParts.filter(Boolean).join('\\n')\n if (headAdditions) {\n // If SSR provides a <title>, replace the client template's <title> so the\n // SSR title wins (client template title is the fallback default).\n if (headAdditions.includes('<title>')) {\n merged = merged.replace(/<title>[^<]*<\\/title>/, '')\n }\n merged = merged.replace('</head>', headAdditions + '\\n</head>')\n }\n return merged\n}\n\n// Per-request async setup: initialize a fresh router, resolve the matched\n// route and layout, pre-load the page module, and call the data loader.\n// Loader data is returned so the handler can scope it to _cerDataStore.run()\n// during rendering. (AsyncLocalStorage.enterWith() inside an awaited child\n// function does not propagate back to the parent continuation, so run() is\n// the only reliable approach.)\nconst _prepareRequest = async (req) => {\n await _pluginsReady\n const router = initRouter({ routes, initialUrl: req.url ?? '/' })\n const current = router.getCurrent()\n const { route, params } = router.matchRoute(current.path)\n\n // Store the current route info so useRoute() can read it synchronously\n // from any layout or component during this render pass.\n _cerRouteStore.enterWith({\n path: current.path,\n params,\n query: current.query ?? {},\n meta: route?.meta ?? null,\n })\n\n // Pre-load the page module so we can embed the component tag directly.\n // This avoids the async router-view (which injects content via script tags\n // and breaks Declarative Shadow DOM on initial parse).\n let pageVnode = { tag: 'div', props: {}, children: [] }\n let head\n // Loader data to pass to usePageData() during rendering. Declared here\n // (outside try/catch) so it's visible in all return paths.\n let loaderData = null\n if (route?.load) {\n try {\n const mod = await route.load()\n const pageTag = mod.default\n // P2-2: Route-level error tag (from co-located .error.ts or _error.ts).\n // Preferred over the global errorTag when rendering loader errors for this route.\n const routeErrorTag = mod.errorTag ?? null\n\n // P1-1: Synthetic 404 catch-all \u2014 no page component registered.\n if (!pageTag) {\n const notFoundErrorTag = routeErrorTag ?? errorTag\n const notFoundVnode = notFoundErrorTag\n ? { tag: notFoundErrorTag, props: { attrs: { error: 'Not Found', status: '404' } }, children: [] }\n : { tag: 'div', props: {}, children: [] }\n return { vnode: notFoundVnode, router, head: undefined, status: 404 }\n }\n\n // Run the loader before creating the page vnode so we can pass its\n // primitive return values as HTML attributes. useProps() in the page\n // component reads element attributes, so merging loader data here makes\n // both useProps() and usePageData() work in SSR / SSG.\n let loaderAttrs = {}\n if (typeof mod.loader === 'function') {\n const query = current.query ?? {}\n const data = await mod.loader({ params, query, req })\n if (data !== undefined && data !== null) {\n // Store loader data so the handler can pass it to _cerDataStore.run()\n // below. Using enterWith() here doesn't work because it only modifies\n // the async context *inside* this awaited function, not the outer\n // handler's continuation where renderToStreamWithJITCSSDSD runs.\n loaderData = data\n head = `<script>window.__CER_DATA__ = ${JSON.stringify(data)}</script>`\n // Expose primitive loader values as element attributes so useProps()\n // can read them. Complex objects are only accessible via usePageData().\n loaderAttrs = Object.fromEntries(\n Object.entries(data).filter(([, v]) => v !== null && v !== undefined && typeof v !== 'object' && typeof v !== 'function')\n )\n }\n }\n\n pageVnode = { tag: pageTag, props: { attrs: { ...params, ...loaderAttrs } }, children: [] }\n } catch (err) {\n // Loader threw \u2014 render the error page server-side if app/error.ts exists.\n const status = (err && typeof err === 'object' && 'status' in err && typeof err.status === 'number')\n ? err.status : 500\n const message = (err instanceof Error) ? err.message : String(err)\n if (_hooks?.onError) {\n try { await _hooks.onError(err, { type: 'loader', path: new URL(req.url ?? '/', 'http://x').pathname, req }) } catch { /* hooks must not crash the handler */ }\n }\n // P2-2: Prefer the route-level errorTag over the global one.\n // routeErrorTag is not in scope here; use route?.meta?.errorTag from the matched route.\n const effectiveErrorTag = route?.meta?.errorTag ?? errorTag\n if (!effectiveErrorTag) {\n console.error('[cer-app] Loader error (no app/error.ts defined):', err)\n }\n const errVnode = effectiveErrorTag\n ? { tag: effectiveErrorTag, props: { attrs: { error: message, status: String(status) } }, children: [] }\n : { tag: 'div', props: {}, children: [] }\n return { vnode: errVnode, router, head: undefined, status }\n }\n }\n\n // Resolve layout chain: nested layouts (meta.layoutChain) or single layout.\n const chain = route?.meta?.layoutChain\n ? route.meta.layoutChain\n : [route?.meta?.layout ?? 'default']\n\n // Wrap pageVnode in the layout chain from innermost to outermost.\n let vnode = pageVnode\n for (let i = chain.length - 1; i >= 0; i--) {\n const tag = layouts[chain[i]]\n if (tag) vnode = { tag, props: {}, children: [vnode] }\n }\n\n // Only framework-owned not-found routes should force a 404 status. A user\n // catch-all page ([...all].ts) may successfully resolve real content paths\n // and should stay 200 unless its loader explicitly throws a 404.\n const isNotFoundRoute = route?.meta?._cerNotFound === true\n return { vnode, router, head, status: isNotFoundRoute ? 404 : null, loaderData }\n}\n\nexport const handler = async (req, res) => {\n const _requestPath = new URL(req.url ?? '/', 'http://x').pathname\n const _requestStart = Date.now()\n if (_hooks?.onRequest) {\n try { await _hooks.onRequest({ path: _requestPath, method: req.method ?? 'GET', req }) } catch { /* hooks must not crash the handler */ }\n }\n await _cerStateStore.run(new Map(), async () => {\n await _cerReqStore.run({ req, res }, async () => {\n await _cerDataStore.run(null, async () => {\n // Fresh per-request fetch map \u2014 populated by useFetch() calls inside loaders.\n const _fetchMap = new Map()\n await _cerFetchStore.run(_fetchMap, async () => {\n // Pre-resolve the authenticated user so useAuth() works synchronously during rendering.\n let _authUser = null\n if (_authSessionKey) {\n try { _authUser = await useSession({ name: _authSessionKey }).get() } catch { /* no session secret */ }\n }\n await _cerAuthStore.run(_authUser, async () => {\n const { vnode, router, head, status, loaderData } = await _prepareRequest(req)\n if (status != null) res.statusCode = status\n\n let _headCollectionOpen = false\n // Wrap the entire render pass in _cerDataStore.run(loaderData) so that\n // usePageData() inside component renderFn calls sees the correct store\n // value. AsyncLocalStorage.enterWith() inside _prepareRequest does NOT\n // propagate back to this outer async continuation \u2014 it only affects the\n // async chain inside _prepareRequest itself. Using run() here is the only\n // reliable way to scope the data store to the synchronous render pass.\n await _cerDataStore.run(loaderData ?? null, async () => {\n try {\n // Begin collecting useHead() calls made during the synchronous render pass.\n // IMPORTANT: the stream's start() function runs synchronously on construction,\n // so ALL useHead() calls happen before the stream object is returned. We must\n // call endHeadCollection() immediately \u2014 before any await \u2014 to avoid a race\n // window where a concurrent request (e.g. SSG concurrency > 1) resets the\n // shared globalThis collector while this handler is suspended at an await.\n _headCollectionOpen = true\n beginHeadCollection()\n\n // dsdPolyfill: false \u2014 we inject the polyfill manually after merging so it\n // lands at the end of <body>, not inside <cer-layout-view> light DOM where\n // scripts may not execute.\n // The first chunk from the stream is the full synchronous render. Subsequent\n // chunks are async component swap scripts streamed as they resolve.\n const stream = renderToStreamWithJITCSSDSD(vnode, { dsdPolyfill: false, router })\n\n // Collect head tags synchronously \u2014 all useHead() calls have already fired\n // inside the stream constructor's start() before it returned.\n const headTags = serializeHeadTags(endHeadCollection())\n _headCollectionOpen = false\n\n const reader = stream.getReader()\n\n // Read the first (synchronous) chunk \u2014 rejects if the sync render failed.\n const { value: firstChunk = '' } = await reader.read()\n\n // Serialise useFetch() results collected during loader execution.\n const _fetchObj = Object.fromEntries(_fetchMap)\n const _fetchScript = Object.keys(_fetchObj).length > 0\n ? `<script>window.__CER_FETCH_DATA__ = ${JSON.stringify(_fetchObj)}</script>`\n : ''\n\n // Serialise the auth user for client-side hydration via useAuth().\n const _authScript = _authUser\n ? `<script>window.__CER_AUTH_USER__ = ${JSON.stringify(_authUser)}</script>`\n : ''\n\n // Serialise useState() values for client-side hydration.\n // The state Map is populated by loader calls (in _prepareRequest) and by component\n // render functions (during renderToStreamWithJITCSSDSD above). Both run before this\n // point. Injected as window.__CER_STATE_INIT__ so the client useState() can\n // pre-populate its singleton Map on first use \u2014 no flash to default values.\n const _stateMap = _cerStateStore.getStore()\n let _stateScript = ''\n if (_stateMap && _stateMap.size > 0) {\n const _stateObj = {}\n for (const [k, v] of _stateMap) { _stateObj[k] = v.value }\n _stateScript = `<script>window.__CER_STATE_INIT__ = ${JSON.stringify(_stateObj)}</script>`\n }\n\n // Merge loader data script + useHead() tags + fetch/auth/state hydration scripts.\n const headContent = [head, headTags, _fetchScript, _authScript, _stateScript].filter(Boolean).join('\\n')\n\n // Wrap the rendered body in a full HTML document and inject the head additions\n // (loader data script, useHead() tags, JIT styles). No polyfill in body yet.\n const ssrHtml = `<!DOCTYPE html><html><head>${headContent}</head><body>${firstChunk}</body></html>`\n\n // In dev mode the module-level _clientTemplate is null (only the\n // production dist/client/index.html path is searched at init time).\n // The dev server sets (globalThis).__CER_CLIENT_TEMPLATE__ per-request\n // after running server.transformIndexHtml so the Vite client scripts\n // (/@vite/client, HMR) are included in every SSR response.\n const _resolvedClientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? _clientTemplate\n const merged = _resolvedClientTemplate\n ? _mergeWithClientTemplate(ssrHtml, _resolvedClientTemplate)\n : ssrHtml\n\n // Split at </body> so async swap scripts and the DSD polyfill can be streamed\n // in before the document is closed.\n const bodyCloseIdx = merged.lastIndexOf('</body>')\n const beforeBodyClose = bodyCloseIdx >= 0 ? merged.slice(0, bodyCloseIdx) : merged\n const fromBodyClose = bodyCloseIdx >= 0 ? merged.slice(bodyCloseIdx) : ''\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.setHeader('Transfer-Encoding', 'chunked')\n res.write(beforeBodyClose)\n\n // Stream async component swap scripts through as-is.\n while (true) {\n const { value, done } = await reader.read()\n if (done) break\n res.write(value)\n }\n\n // Inject DSD polyfill immediately before </body>, then close the document.\n res.end(DSD_POLYFILL_SCRIPT + fromBodyClose)\n if (_hooks?.onResponse) {\n try { void _hooks.onResponse({ path: _requestPath, method: req.method ?? 'GET', statusCode: res.statusCode, duration: Date.now() - _requestStart, req }) } catch { /* ignore */ }\n }\n } catch (_renderErr) {\n if (_hooks?.onError) {\n try { await _hooks.onError(_renderErr, { type: 'render', path: _requestPath, req }) } catch { /* hooks must not crash the handler */ }\n }\n // Ensure the head collector is never left open on error.\n if (_headCollectionOpen) { try { endHeadCollection() } catch { /* ignore */ } }\n // If headers have not been flushed yet we can still send a proper 500 page.\n // If writing has already started we can only close the connection cleanly.\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end('<!DOCTYPE html><html><head></head><body><h1>500 Internal Server Error</h1><p>An unexpected error occurred while rendering this page.</p></body></html>')\n } else {\n res.end()\n }\n if (_hooks?.onResponse) {\n try { void _hooks.onResponse({ path: _requestPath, method: req.method ?? 'GET', statusCode: res.statusCode, duration: Date.now() - _requestStart, req }) } catch { /* ignore */ }\n }\n }\n }) // _cerDataStore.run(loaderData)\n }) // _cerAuthStore.run\n }) // _cerFetchStore.run\n }) // _cerDataStore.run\n }) // _cerReqStore.run\n }) // _cerStateStore.run\n}\n\n// ISR-wrapped handler for production integrations (Express, Hono, Fastify).\n// Routes with meta.ssg.revalidate are served stale-while-revalidate.\nexport const isrHandler = createIsrHandler(routes, handler)\n\nexport { apiRoutes, plugins, layouts, routes, serverMiddleware }\nexport default handler\n";
14
+ export declare const ENTRY_SERVER_TEMPLATE = "// Server-side entry \u2014 AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport 'virtual:cer-content-components'\nimport routes from 'virtual:cer-routes'\nimport layouts from 'virtual:cer-layouts'\nimport plugins from 'virtual:cer-plugins'\nimport apiRoutes from 'virtual:cer-server-api'\nimport serverMiddleware from 'virtual:cer-server-middleware'\nimport { runtimeConfig, _runtimePrivateDefaults, _authSessionKey, _hooks } from 'virtual:cer-app-config'\nimport { registerBuiltinComponents, setDevMode } from '@jasonshimmy/custom-elements-runtime'\nimport { registerEntityMap, renderToStreamWithJITCSSDSD, DSD_POLYFILL_SCRIPT } from '@jasonshimmy/custom-elements-runtime/ssr'\nimport entitiesJson from '@jasonshimmy/custom-elements-runtime/entities.json'\nimport { initRouter } from '@jasonshimmy/custom-elements-runtime/router'\nimport { beginHeadCollection, endHeadCollection, serializeHeadTags, initRuntimeConfig, resolvePrivateConfig, useSession } from '@jasonshimmy/vite-plugin-cer-app/composables'\nimport { errorTag } from 'virtual:cer-error'\nimport { createIsrHandler } from '@jasonshimmy/vite-plugin-cer-app/isr'\n\nconst _cerProcess = (globalThis).process\nconst _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE\nconst _cerRuntimeDev =\n typeof _cerNodeEnv === 'string'\n ? _cerNodeEnv !== 'production'\n : typeof import.meta.env?.DEV === 'boolean'\n ? import.meta.env.DEV\n : typeof import.meta.env?.PROD === 'boolean'\n ? !import.meta.env.PROD\n : typeof import.meta.env?.MODE === 'string'\n ? import.meta.env.MODE !== 'production'\n : false\n;(globalThis).__CE_RUNTIME_DEV__ = _cerRuntimeDev\n\nregisterBuiltinComponents()\nsetDevMode(_cerRuntimeDev)\n\n// Resolve private config from environment variables at server startup.\n// Each key declared in runtimeConfig.private is looked up in process.env,\n// first as-is, then as ALL_CAPS. The declared default is used as fallback.\ninitRuntimeConfig({ ...runtimeConfig, private: resolvePrivateConfig(_runtimePrivateDefaults ?? {}) })\n\n// Pre-load the full HTML entity map so named entities like &mdash; decode\n// correctly during SSR. Without this the bundled runtime falls back to a\n// minimal set (&lt;, &gt;, &amp; \u2026) and re-escapes everything else.\nregisterEntityMap(entitiesJson)\n\n// Run plugins once at server startup so their provide() values are available\n// to useInject() during every SSR/SSG render pass. Stored on globalThis so all\n// dynamically-imported page chunks share the same reference.\nconst _pluginProvides = new Map()\n;(globalThis).__cerPluginProvides = _pluginProvides\nconst _pluginsReady = (async () => {\n const _bootstrapRouter = initRouter({ routes })\n for (const plugin of plugins) {\n if (plugin && typeof plugin.setup === 'function') {\n await plugin.setup({\n router: _bootstrapRouter,\n provide: (key, value) => _pluginProvides.set(key, value),\n config: {},\n })\n }\n }\n})()\n\n// Async-local storage for request-scoped SSR loader data.\n// Using AsyncLocalStorage ensures concurrent SSR renders (e.g. SSG with\n// concurrency > 1) never see each other's data \u2014 each request's async chain\n// carries its own store value, so usePageData() is always race-condition-free.\nconst _cerDataStore = new AsyncLocalStorage()\n// Expose the store so the usePageData() composable can read it server-side.\n;(globalThis).__CER_DATA_STORE__ = _cerDataStore\n\n// Async-local storage for request-scoped req/res access.\n// Allows isomorphic composables (e.g. useCookie) to read/write HTTP headers\n// without prop-drilling the request context through the component tree.\nconst _cerReqStore = new AsyncLocalStorage()\n;(globalThis).__CER_REQ_STORE__ = _cerReqStore\n\n// Async-local storage for the authenticated user resolved before each render.\n// useAuth() reads this store server-side to return the current user synchronously.\nconst _cerAuthStore = new AsyncLocalStorage()\n;(globalThis).__CER_AUTH_STORE__ = _cerAuthStore\n\n// Async-local storage for per-request useFetch() data.\n// useFetch() writes fetched results here; the handler serialises the map into\n// window.__CER_FETCH_DATA__ for client-side hydration.\nconst _cerFetchStore = new AsyncLocalStorage()\n;(globalThis).__CER_FETCH_STORE__ = _cerFetchStore\n\n// Async-local storage for the current route info (path, params, query, meta).\n// useRoute() reads this on the server so layouts and components can access\n// route metadata without prop-drilling.\nconst _cerRouteStore = new AsyncLocalStorage()\n;(globalThis).__CER_ROUTE_STORE__ = _cerRouteStore\n\n// Async-local storage for per-request useState() reactive state.\n// Each request gets a fresh Map so concurrent SSR/SSG renders never share\n// reactive state set by different pages or loaders.\nconst _cerStateStore = new AsyncLocalStorage()\n;(globalThis).__CER_STATE_STORE__ = _cerStateStore\n\n// Runs fn inside the per-request AsyncLocalStorage context so that isomorphic\n// composables (useCookie, useSession, etc.) can access req/res without prop-drilling.\n// Call this for every API handler invocation \u2014 not just SSR renders.\nexport function runWithRequestContext(req, res, fn) {\n return _cerReqStore.run({ req, res }, fn)\n}\n\n// Runs the server/middleware/ chain for a request.\n// Returns false if a middleware short-circuited the response; true to continue.\n// Exported so Netlify / Vercel / Cloudflare bridges can also call it for API routes.\n// P1-2: Middleware may throw { status: 401 } (or any numeric .status) to produce\n// a non-500 response \u2014 the status is extracted and forwarded to res.statusCode.\nexport async function runServerMiddleware(req, res) {\n for (const { handler: mw } of (serverMiddleware ?? [])) {\n if (typeof mw !== 'function') continue\n let calledNext = false\n try {\n await new Promise((resolve, reject) => {\n Promise.resolve(mw(req, res, (err) => {\n if (err) reject(err)\n else { calledNext = true; resolve() }\n })).catch(reject)\n })\n } catch (err) {\n if (_hooks?.onError) {\n try { await _hooks.onError(err, { type: 'middleware', path: new URL(req.url ?? '/', 'http://x').pathname, req }) } catch { /* hooks must not crash the handler */ }\n }\n if (!res.writableEnded) {\n const statusCode = (typeof err === 'object' && err !== null && 'status' in err && typeof err.status === 'number')\n ? (isNaN(err.status) ? 500 : err.status)\n : 500\n res.statusCode = statusCode\n res.end('Internal Server Error')\n }\n return false\n }\n if (res.writableEnded || !calledNext) return false\n }\n return true\n}\n\n// Load the Vite-built client index.html (dist/client/index.html) so every SSR\n// response includes the client-side scripts needed for hydration and routing.\n// The server bundle lives at dist/server/server.js, so ../client resolves correctly.\n//\n// Cloudflare Workers (and other runtimes without node:fs) can inject the\n// template before this module loads by setting globalThis.__CER_CLIENT_TEMPLATE__.\n// The Cloudflare adapter inlines dist/client/index.html as a string constant in\n// _worker.js and sets the global before dynamically importing the server bundle.\nlet _clientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? null\nif (!_clientTemplate) {\n try {\n const _clientTemplatePath = join(dirname(fileURLToPath(import.meta.url)), '../client/index.html')\n _clientTemplate = existsSync(_clientTemplatePath)\n ? readFileSync(_clientTemplatePath, 'utf-8')\n : null\n } catch {\n // node:fs not available in this runtime \u2014 Cloudflare adapter must set\n // globalThis.__CER_CLIENT_TEMPLATE__ before importing this bundle.\n }\n}\n\n// Merge the SSR rendered body with the Vite client shell so the final page\n// contains both pre-rendered DSD content and the client bundle scripts.\nfunction _mergeWithClientTemplate(ssrHtml, clientTemplate) {\n const headTag = '<head>', headCloseTag = '</head>'\n const bodyTag = '<body>', bodyCloseTag = '</body>'\n const headStart = ssrHtml.indexOf(headTag)\n const headEnd = ssrHtml.indexOf(headCloseTag)\n const bodyStart = ssrHtml.indexOf(bodyTag)\n const bodyEnd = ssrHtml.lastIndexOf(bodyCloseTag)\n const ssrHead = headStart >= 0 && headEnd > headStart\n ? ssrHtml.slice(headStart + headTag.length, headEnd).trim() : ''\n const ssrBody = bodyStart >= 0 && bodyEnd > bodyStart\n ? ssrHtml.slice(bodyStart + bodyTag.length, bodyEnd).trim() : ssrHtml\n // Hoist only top-level <style id=...> elements (cer-ssr-jit, cer-ssr-global)\n // from the SSR body into the document <head>. Plain <style> blocks without\n // an id attribute belong to shadow DOM templates and must stay in place \u2014\n // hoisting them to <head> breaks shadow DOM style encapsulation (document\n // styles do not pierce shadow roots), which is the root cause of FOUC.\n const headParts = ssrHead ? [ssrHead] : []\n let ssrBodyContent = ssrBody\n let pos = 0\n while (pos < ssrBodyContent.length) {\n const styleOpen = ssrBodyContent.indexOf('<style id=', pos)\n if (styleOpen < 0) break\n const styleClose = ssrBodyContent.indexOf('</style>', styleOpen)\n if (styleClose < 0) break\n headParts.push(ssrBodyContent.slice(styleOpen, styleClose + 8))\n ssrBodyContent = ssrBodyContent.slice(0, styleOpen) + ssrBodyContent.slice(styleClose + 8)\n pos = styleOpen\n }\n ssrBodyContent = ssrBodyContent.trim()\n // Inject the pre-rendered layout+page as light DOM of the app mount element\n // so it is visible before JS boots, then the client router takes over.\n let merged = clientTemplate\n if (merged.includes('<cer-layout-view></cer-layout-view>')) {\n merged = merged.replace('<cer-layout-view></cer-layout-view>',\n '<cer-layout-view>' + ssrBodyContent + '</cer-layout-view>')\n } else if (merged.includes('<div id=\"app\"></div>')) {\n merged = merged.replace('<div id=\"app\"></div>',\n '<div id=\"app\">' + ssrBodyContent + '</div>')\n }\n const headAdditions = headParts.filter(Boolean).join('\\n')\n if (headAdditions) {\n // If SSR provides a <title>, replace the client template's <title> so the\n // SSR title wins (client template title is the fallback default).\n if (headAdditions.includes('<title>')) {\n merged = merged.replace(/<title>[^<]*<\\/title>/, '')\n }\n merged = merged.replace('</head>', headAdditions + '\\n</head>')\n }\n return merged\n}\n\n// Per-request async setup: initialize a fresh router, resolve the matched\n// route and layout, pre-load the page module, and call the data loader.\n// Loader data is returned so the handler can scope it to _cerDataStore.run()\n// during rendering. (AsyncLocalStorage.enterWith() inside an awaited child\n// function does not propagate back to the parent continuation, so run() is\n// the only reliable approach.)\nconst _prepareRequest = async (req) => {\n await _pluginsReady\n const router = initRouter({ routes, initialUrl: req.url ?? '/' })\n const current = router.getCurrent()\n const { route, params } = router.matchRoute(current.path)\n\n // Store the current route info so useRoute() can read it synchronously\n // from any layout or component during this render pass.\n _cerRouteStore.enterWith({\n path: current.path,\n params,\n query: current.query ?? {},\n meta: route?.meta ?? null,\n })\n\n // Pre-load the page module so we can embed the component tag directly.\n // This avoids the async router-view (which injects content via script tags\n // and breaks Declarative Shadow DOM on initial parse).\n let pageVnode = { tag: 'div', props: {}, children: [] }\n let head\n // Loader data to pass to usePageData() during rendering. Declared here\n // (outside try/catch) so it's visible in all return paths.\n let loaderData = null\n if (route?.load) {\n try {\n const mod = await route.load()\n const pageTag = mod.default\n // P2-2: Route-level error tag (from co-located .error.ts or _error.ts).\n // Preferred over the global errorTag when rendering loader errors for this route.\n const routeErrorTag = mod.errorTag ?? null\n\n // P1-1: Synthetic 404 catch-all \u2014 no page component registered.\n if (!pageTag) {\n const notFoundErrorTag = routeErrorTag ?? errorTag\n const notFoundVnode = notFoundErrorTag\n ? { tag: notFoundErrorTag, props: { attrs: { error: 'Not Found', status: '404' } }, children: [] }\n : { tag: 'div', props: {}, children: [] }\n return { vnode: notFoundVnode, router, head: undefined, status: 404 }\n }\n\n // Run the loader before creating the page vnode so we can pass its\n // primitive return values as HTML attributes. useProps() in the page\n // component reads element attributes, so merging loader data here makes\n // both useProps() and usePageData() work in SSR / SSG.\n let loaderAttrs = {}\n if (typeof mod.loader === 'function') {\n const query = current.query ?? {}\n const data = await mod.loader({ params, query, req })\n if (data !== undefined && data !== null) {\n // Store loader data so the handler can pass it to _cerDataStore.run()\n // below. Using enterWith() here doesn't work because it only modifies\n // the async context *inside* this awaited function, not the outer\n // handler's continuation where renderToStreamWithJITCSSDSD runs.\n loaderData = data\n head = `<script>window.__CER_DATA__ = ${JSON.stringify(data)}</script>`\n // Expose primitive loader values as element attributes so useProps()\n // can read them. Complex objects are only accessible via usePageData().\n loaderAttrs = Object.fromEntries(\n Object.entries(data).filter(([, v]) => v !== null && v !== undefined && typeof v !== 'object' && typeof v !== 'function')\n )\n }\n }\n\n pageVnode = { tag: pageTag, props: { attrs: { ...params, ...loaderAttrs } }, children: [] }\n } catch (err) {\n // Loader threw \u2014 render the error page server-side if app/error.ts exists.\n const status = (err && typeof err === 'object' && 'status' in err && typeof err.status === 'number')\n ? err.status : 500\n const message = (err instanceof Error) ? err.message : String(err)\n if (_hooks?.onError) {\n try { await _hooks.onError(err, { type: 'loader', path: new URL(req.url ?? '/', 'http://x').pathname, req }) } catch { /* hooks must not crash the handler */ }\n }\n // P2-2: Prefer the route-level errorTag over the global one.\n // routeErrorTag is not in scope here; use route?.meta?.errorTag from the matched route.\n const effectiveErrorTag = route?.meta?.errorTag ?? errorTag\n if (!effectiveErrorTag) {\n console.error('[cer-app] Loader error (no app/error.ts defined):', err)\n }\n const errVnode = effectiveErrorTag\n ? { tag: effectiveErrorTag, props: { attrs: { error: message, status: String(status) } }, children: [] }\n : { tag: 'div', props: {}, children: [] }\n return { vnode: errVnode, router, head: undefined, status }\n }\n }\n\n // Resolve layout chain: nested layouts (meta.layoutChain) or single layout.\n const chain = route?.meta?.layoutChain\n ? route.meta.layoutChain\n : [route?.meta?.layout ?? 'default']\n\n // Wrap pageVnode in the layout chain from innermost to outermost.\n let vnode = pageVnode\n for (let i = chain.length - 1; i >= 0; i--) {\n const tag = layouts[chain[i]]\n if (tag) vnode = { tag, props: {}, children: [vnode] }\n }\n\n // Only framework-owned not-found routes should force a 404 status. A user\n // catch-all page ([...all].ts) may successfully resolve real content paths\n // and should stay 200 unless its loader explicitly throws a 404.\n const isNotFoundRoute = route?.meta?._cerNotFound === true\n return { vnode, router, head, status: isNotFoundRoute ? 404 : null, loaderData }\n}\n\nexport const handler = async (req, res) => {\n const _requestPath = new URL(req.url ?? '/', 'http://x').pathname\n const _requestStart = Date.now()\n if (_hooks?.onRequest) {\n try { await _hooks.onRequest({ path: _requestPath, method: req.method ?? 'GET', req }) } catch { /* hooks must not crash the handler */ }\n }\n await _cerStateStore.run(new Map(), async () => {\n await _cerReqStore.run({ req, res }, async () => {\n await _cerDataStore.run(null, async () => {\n // Fresh per-request fetch map \u2014 populated by useFetch() calls inside loaders.\n const _fetchMap = new Map()\n await _cerFetchStore.run(_fetchMap, async () => {\n // Pre-resolve the authenticated user so useAuth() works synchronously during rendering.\n let _authUser = null\n if (_authSessionKey) {\n try { _authUser = await useSession({ name: _authSessionKey }).get() } catch { /* no session secret */ }\n }\n await _cerAuthStore.run(_authUser, async () => {\n const { vnode, router, head, status, loaderData } = await _prepareRequest(req)\n if (status != null) res.statusCode = status\n\n let _headCollectionOpen = false\n // Wrap the entire render pass in _cerDataStore.run(loaderData) so that\n // usePageData() inside component renderFn calls sees the correct store\n // value. AsyncLocalStorage.enterWith() inside _prepareRequest does NOT\n // propagate back to this outer async continuation \u2014 it only affects the\n // async chain inside _prepareRequest itself. Using run() here is the only\n // reliable way to scope the data store to the synchronous render pass.\n await _cerDataStore.run(loaderData ?? null, async () => {\n try {\n // Begin collecting useHead() calls made during the synchronous render pass.\n // IMPORTANT: the stream's start() function runs synchronously on construction,\n // so ALL useHead() calls happen before the stream object is returned. We must\n // call endHeadCollection() immediately \u2014 before any await \u2014 to avoid a race\n // window where a concurrent request (e.g. SSG concurrency > 1) resets the\n // shared globalThis collector while this handler is suspended at an await.\n _headCollectionOpen = true\n beginHeadCollection()\n\n // dsdPolyfill: false \u2014 we inject the polyfill manually after merging so it\n // lands at the end of <body>, not inside <cer-layout-view> light DOM where\n // scripts may not execute.\n // The first chunk from the stream is the full synchronous render. Subsequent\n // chunks are async component swap scripts streamed as they resolve.\n const stream = renderToStreamWithJITCSSDSD(vnode, { dsdPolyfill: false, router })\n\n // Collect head tags synchronously \u2014 all useHead() calls have already fired\n // inside the stream constructor's start() before it returned.\n const headTags = serializeHeadTags(endHeadCollection())\n _headCollectionOpen = false\n\n const reader = stream.getReader()\n\n // Read the first (synchronous) chunk \u2014 rejects if the sync render failed.\n const { value: firstChunk = '' } = await reader.read()\n\n // Serialise useFetch() results collected during loader execution.\n const _fetchObj = Object.fromEntries(_fetchMap)\n const _fetchScript = Object.keys(_fetchObj).length > 0\n ? `<script>window.__CER_FETCH_DATA__ = ${JSON.stringify(_fetchObj)}</script>`\n : ''\n\n // Serialise the auth user for client-side hydration via useAuth().\n const _authScript = _authUser\n ? `<script>window.__CER_AUTH_USER__ = ${JSON.stringify(_authUser)}</script>`\n : ''\n\n // Serialise useState() values for client-side hydration.\n // The state Map is populated by loader calls (in _prepareRequest) and by component\n // render functions (during renderToStreamWithJITCSSDSD above). Both run before this\n // point. Injected as window.__CER_STATE_INIT__ so the client useState() can\n // pre-populate its singleton Map on first use \u2014 no flash to default values.\n const _stateMap = _cerStateStore.getStore()\n let _stateScript = ''\n if (_stateMap && _stateMap.size > 0) {\n const _stateObj = {}\n for (const [k, v] of _stateMap) { _stateObj[k] = v.value }\n _stateScript = `<script>window.__CER_STATE_INIT__ = ${JSON.stringify(_stateObj)}</script>`\n }\n\n // Merge loader data script + useHead() tags + fetch/auth/state hydration scripts.\n const headContent = [head, headTags, _fetchScript, _authScript, _stateScript].filter(Boolean).join('\\n')\n\n // Wrap the rendered body in a full HTML document and inject the head additions\n // (loader data script, useHead() tags, JIT styles). No polyfill in body yet.\n const ssrHtml = `<!DOCTYPE html><html><head>${headContent}</head><body>${firstChunk}</body></html>`\n\n // In dev mode the module-level _clientTemplate is null (only the\n // production dist/client/index.html path is searched at init time).\n // The dev server sets (globalThis).__CER_CLIENT_TEMPLATE__ per-request\n // after running server.transformIndexHtml so the Vite client scripts\n // (/@vite/client, HMR) are included in every SSR response.\n const _resolvedClientTemplate = (globalThis).__CER_CLIENT_TEMPLATE__ ?? _clientTemplate\n const merged = _resolvedClientTemplate\n ? _mergeWithClientTemplate(ssrHtml, _resolvedClientTemplate)\n : ssrHtml\n\n // Split at </body> so async swap scripts and the DSD polyfill can be streamed\n // in before the document is closed.\n const bodyCloseIdx = merged.lastIndexOf('</body>')\n const beforeBodyClose = bodyCloseIdx >= 0 ? merged.slice(0, bodyCloseIdx) : merged\n const fromBodyClose = bodyCloseIdx >= 0 ? merged.slice(bodyCloseIdx) : ''\n\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.setHeader('Transfer-Encoding', 'chunked')\n res.write(beforeBodyClose)\n\n // Stream async component swap scripts through as-is.\n while (true) {\n const { value, done } = await reader.read()\n if (done) break\n res.write(value)\n }\n\n // Inject DSD polyfill immediately before </body>, then close the document.\n res.end(DSD_POLYFILL_SCRIPT + fromBodyClose)\n if (_hooks?.onResponse) {\n try { void _hooks.onResponse({ path: _requestPath, method: req.method ?? 'GET', statusCode: res.statusCode, duration: Date.now() - _requestStart, req }) } catch { /* ignore */ }\n }\n } catch (_renderErr) {\n if (_hooks?.onError) {\n try { await _hooks.onError(_renderErr, { type: 'render', path: _requestPath, req }) } catch { /* hooks must not crash the handler */ }\n }\n // Ensure the head collector is never left open on error.\n if (_headCollectionOpen) { try { endHeadCollection() } catch { /* ignore */ } }\n // If headers have not been flushed yet we can still send a proper 500 page.\n // If writing has already started we can only close the connection cleanly.\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n res.end('<!DOCTYPE html><html><head></head><body><h1>500 Internal Server Error</h1><p>An unexpected error occurred while rendering this page.</p></body></html>')\n } else {\n res.end()\n }\n if (_hooks?.onResponse) {\n try { void _hooks.onResponse({ path: _requestPath, method: req.method ?? 'GET', statusCode: res.statusCode, duration: Date.now() - _requestStart, req }) } catch { /* ignore */ }\n }\n }\n }) // _cerDataStore.run(loaderData)\n }) // _cerAuthStore.run\n }) // _cerFetchStore.run\n }) // _cerDataStore.run\n }) // _cerReqStore.run\n }) // _cerStateStore.run\n}\n\n// ISR-wrapped handler for production integrations (Express, Hono, Fastify).\n// Routes with meta.ssg.revalidate are served stale-while-revalidate.\nexport const isrHandler = createIsrHandler(routes, handler)\n\nexport { apiRoutes, plugins, layouts, routes, serverMiddleware }\nexport default handler\n";
15
15
  //# sourceMappingURL=entry-server-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entry-server-template.d.ts","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,s9vBA8djC,CAAA"}
1
+ {"version":3,"file":"entry-server-template.d.ts","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,+/vBA+djC,CAAA"}
@@ -16,6 +16,7 @@ import { readFileSync, existsSync } from 'node:fs'
16
16
  import { dirname, join } from 'node:path'
17
17
  import { fileURLToPath } from 'node:url'
18
18
  import { AsyncLocalStorage } from 'node:async_hooks'
19
+ import 'virtual:cer-content-components'
19
20
  import routes from 'virtual:cer-routes'
20
21
  import layouts from 'virtual:cer-layouts'
21
22
  import plugins from 'virtual:cer-plugins'
@@ -1 +1 @@
1
- {"version":3,"file":"entry-server-template.js","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8dpC,CAAA"}
1
+ {"version":3,"file":"entry-server-template.js","sourceRoot":"","sources":["../../src/runtime/entry-server-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+dpC,CAAA"}
@@ -288,7 +288,7 @@ See [cli.md](./cli.md#cer-app-adapt) for full details.
288
288
 
289
289
  ## `content` options
290
290
 
291
- Enables the file-based content layer. Drop Markdown or JSON files into `content/` at the project root and query them with `queryContent()` or search with `useContentSearch()`.
291
+ Enables the file-based content layer. Drop Markdown or JSON files into `content/` at the project root and query them with `queryContent()` or search with `useContentSearch()`. Custom elements referenced directly inside markdown are also auto-registered from `app/components/`.
292
292
 
293
293
  ```ts
294
294
  export default defineConfig({
package/docs/content.md CHANGED
@@ -7,7 +7,7 @@ CER Content is a file-based content layer built into `vite-plugin-cer-app`. It p
7
7
  ## Overview
8
8
 
9
9
  - **Zero config** — drop files into `content/` at the project root and they are available immediately.
10
- - **Markdown + JSON** — Markdown files are parsed with frontmatter, rendered to HTML, and have their headings extracted into a table of contents. JSON files are stored as raw string bodies.
10
+ - **Markdown + JSON** — Markdown files are parsed with frontmatter, rendered to HTML, have their headings extracted into a table of contents, and auto-register matching custom elements from `app/components/` when those tags appear in the markdown body. JSON files are stored as raw string bodies.
11
11
  - **Draft support** — items with `draft: true` in frontmatter are excluded from production builds by default.
12
12
  - **Excerpt extraction** — place `<!-- more -->` in a Markdown file to set the excerpt boundary.
13
13
  - **Full-text search** — a MiniSearch index is emitted at build time and loaded lazily on the client via `useContentSearch()`.
@@ -103,6 +103,19 @@ When `false`, any file with `draft: true` in its frontmatter is excluded from th
103
103
 
104
104
  Markdown files use [gray-matter](https://github.com/jonschlinkert/gray-matter) for YAML frontmatter. All frontmatter keys are stored in the content item. The body is rendered to HTML using [marked](https://marked.js.org). Heading elements receive an `id` attribute derived from their slug.
105
105
 
106
+ If the rendered markdown body contains custom-element tags that match components registered in `app/components/`, CER automatically imports those component modules for both client and server entry points. That means markdown like `<site-callout>Note</site-callout>` works in SPA, SSR, and SSG without adding manual imports to your page component.
107
+
108
+ Props passed from markdown follow normal HTML attribute rules:
109
+
110
+ - String props work directly: `<site-callout tone="info" heading="Heads up">…</site-callout>`
111
+ - Number and boolean props work when the component declares them via `useProps()` defaults, because the runtime coerces attribute values to the declared primitive type
112
+ - Boolean presence attributes are appropriate for flag-style props such as `<site-callout dismissible>`
113
+ - All markdown-supplied props are attribute-based, so they must be serializable as plain HTML attribute values
114
+ - Arrays, objects, and function props are not passed as rich JavaScript values from markdown
115
+ - CER template bindings and directives do not run inside markdown HTML, so syntax like `:bind`, `@click`, `:class`, or `${...}` is treated as plain text/attributes, not live bindings
116
+
117
+ In practice, components used from markdown should expose a string/number/boolean attribute API and read those values with `useProps()`.
118
+
106
119
  ```md
107
120
  ---
108
121
  title: Hello World
@@ -118,6 +131,31 @@ draft: false
118
131
  Everything below the excerpt boundary is in `body` but not in `excerpt`.
119
132
  ```
120
133
 
134
+ ```md
135
+ # Docs
136
+
137
+ <site-callout>Remember to configure your content directory.</site-callout>
138
+ ```
139
+
140
+ ```ts
141
+ component('site-callout', () => {
142
+ const props = useProps({ tone: 'info', heading: '', dismissible: false, priority: 0 })
143
+
144
+ return html`
145
+ <aside data-tone="${props.tone}">
146
+ ${props.heading ? html`<strong>${props.heading}</strong>` : ''}
147
+ <slot></slot>
148
+ </aside>
149
+ `
150
+ })
151
+ ```
152
+
153
+ ```md
154
+ <site-callout tone="warning" heading="Before You Start" dismissible priority="2">
155
+ Install dependencies first.
156
+ </site-callout>
157
+ ```
158
+
121
159
  Recognized frontmatter keys:
122
160
 
123
161
  | Key | Type | Description |
@@ -10,7 +10,7 @@
10
10
  * /content-fallback — title/description derived from body when frontmatter omits them
11
11
  */
12
12
 
13
- const mode = Cypress.env('mode') as 'spa' | 'ssr' | 'ssg'
13
+ const mode = Cypress.env('mode') as 'spa' | 'ssr' | 'ssg' | 'dev'
14
14
 
15
15
  // ─── /content-index ───────────────────────────────────────────────────────────
16
16
 
@@ -115,6 +115,18 @@ describe('Content doc — queryContent("/docs/getting-started").first()', () =>
115
115
  expect(response.body).to.include('Installation')
116
116
  })
117
117
  })
118
+
119
+ it('includes markdown component registration hints in initial HTML', () => {
120
+ cy.request('/content-doc').then((response) => {
121
+ expect(response.body).to.include('<ks-badge>Docs Badge</ks-badge>')
122
+ if (mode === 'dev') {
123
+ expect(response.body).to.include('/@cer/app.ts')
124
+ } else {
125
+ expect(response.body).to.match(/ks-badge-[^"']+\.js/)
126
+ }
127
+ expect(response.body).to.include('Docs Badge')
128
+ })
129
+ })
118
130
  }
119
131
 
120
132
  it('renders doc title after hydration', () => {
@@ -156,6 +168,14 @@ describe('Content doc — queryContent("/docs/getting-started").first()', () =>
156
168
  cy.visit('/content-doc')
157
169
  cy.get('[data-cy=content-doc-body]', { timeout: 8000 }).contains('h2', 'Installation')
158
170
  })
171
+
172
+ it('renders app components referenced inside markdown after hydration', () => {
173
+ cy.visit('/content-doc')
174
+ cy.get('[data-cy=content-doc-body]', { timeout: 8000 }).within(() => {
175
+ cy.get('ks-badge').should('contain', 'Docs Badge')
176
+ cy.get('[data-cy=ks-badge]').should('exist')
177
+ })
178
+ })
159
179
  })
160
180
 
161
181
  // ─── /content-guides ─────────────────────────────────────────────────────────
@@ -7,6 +7,8 @@ description: How to install and configure the content layer — tests TOC depth
7
7
 
8
8
  This guide walks you through installation and basic usage.
9
9
 
10
+ <ks-badge>Docs Badge</ks-badge>
11
+
10
12
  ## Installation
11
13
 
12
14
  Run the following command:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jasonshimmy/vite-plugin-cer-app",
3
- "version": "0.21.2",
3
+ "version": "0.21.3",
4
4
  "description": "Nuxt-style meta-framework for @jasonshimmy/custom-elements-runtime",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -52,6 +52,10 @@ describe('app-template (APP_ENTRY_TEMPLATE content)', () => {
52
52
  expect(src).toContain('virtual:cer-jit-css')
53
53
  })
54
54
 
55
+ it('imports virtual:cer-content-components for markdown-backed custom elements', () => {
56
+ expect(src).toContain('virtual:cer-content-components')
57
+ })
58
+
55
59
  it('exports router', () => {
56
60
  expect(src).toContain('export { router }')
57
61
  })
@@ -34,6 +34,7 @@ vi.mock('../../plugin/virtual/server-api.js', () => ({ generateServerApiCode: vi
34
34
  vi.mock('../../plugin/virtual/server-middleware.js', () => ({ generateServerMiddlewareCode: vi.fn().mockResolvedValue('// server-middleware') }))
35
35
  vi.mock('../../plugin/virtual/loading.js', () => ({ generateLoadingCode: vi.fn().mockResolvedValue('// loading') }))
36
36
  vi.mock('../../plugin/virtual/error.js', () => ({ generateErrorCode: vi.fn().mockResolvedValue('// error') }))
37
+ vi.mock('../../plugin/virtual/content-components.js', () => ({ generateContentComponentsCode: vi.fn().mockResolvedValue('// content-components') }))
37
38
  vi.mock('../../plugin/transforms/auto-import.js', () => ({ autoImportTransform: vi.fn().mockReturnValue(null) }))
38
39
 
39
40
  import { cerApp } from '../../plugin/index.js'
@@ -28,6 +28,10 @@ describe('entry-server-template (ENTRY_SERVER_TEMPLATE content)', () => {
28
28
  expect(src).toContain('virtual:cer-server-api')
29
29
  })
30
30
 
31
+ it('imports virtual:cer-content-components for markdown-backed custom elements', () => {
32
+ expect(src).toContain('virtual:cer-content-components')
33
+ })
34
+
31
35
  it('imports registerBuiltinComponents from custom-elements-runtime', () => {
32
36
  expect(src).toContain('registerBuiltinComponents')
33
37
  expect(src).toContain('setDevMode')
@@ -0,0 +1,66 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest'
2
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3
+ import { tmpdir } from 'node:os'
4
+ import { join } from 'pathe'
5
+ import { generateContentComponentsCode } from '../../../plugin/virtual/content-components.js'
6
+
7
+ let tmpRoot: string
8
+ let componentsDir: string
9
+ let contentDir: string
10
+
11
+ beforeAll(() => {
12
+ tmpRoot = mkdtempSync(join(tmpdir(), 'cer-content-components-'))
13
+ componentsDir = join(tmpRoot, 'app', 'components')
14
+ contentDir = join(tmpRoot, 'content')
15
+
16
+ mkdirSync(componentsDir, { recursive: true })
17
+ mkdirSync(contentDir, { recursive: true })
18
+
19
+ writeFileSync(
20
+ join(componentsDir, 'site-callout.ts'),
21
+ "component('site-callout', () => html`<div>Callout</div>`)",
22
+ )
23
+ writeFileSync(
24
+ join(componentsDir, 'site-alert.ts'),
25
+ "component('site-alert', () => html`<div>Alert</div>`)",
26
+ )
27
+
28
+ writeFileSync(
29
+ join(contentDir, 'guide.md'),
30
+ [
31
+ '# Guide',
32
+ '',
33
+ '<site-callout>Docs</site-callout>',
34
+ '',
35
+ '```html',
36
+ '<site-alert>Example only</site-alert>',
37
+ '```',
38
+ '',
39
+ '<unknown-widget>Ignored</unknown-widget>',
40
+ ].join('\n'),
41
+ )
42
+ })
43
+
44
+ afterAll(() => {
45
+ rmSync(tmpRoot, { recursive: true, force: true })
46
+ })
47
+
48
+ describe('generateContentComponentsCode', () => {
49
+ it('imports only registered components referenced by rendered markdown', async () => {
50
+ const code = await generateContentComponentsCode(componentsDir, contentDir)
51
+
52
+ expect(code).toContain(JSON.stringify(join(componentsDir, 'site-callout.ts')))
53
+ expect(code).not.toContain(JSON.stringify(join(componentsDir, 'site-alert.ts')))
54
+ expect(code).not.toContain('unknown-widget')
55
+ expect(code).toContain('export {}')
56
+ })
57
+
58
+ it('returns an empty module when no markdown-backed components are found', async () => {
59
+ const emptyContentDir = join(tmpRoot, 'empty-content')
60
+ mkdirSync(emptyContentDir, { recursive: true })
61
+ writeFileSync(join(emptyContentDir, 'plain.md'), '# Plain\n\nNo custom elements here.')
62
+
63
+ const code = await generateContentComponentsCode(componentsDir, emptyContentDir)
64
+ expect(code).toBe('// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\nexport {}\n')
65
+ })
66
+ })
@@ -8,11 +8,11 @@
8
8
  "preview": "cer-app preview"
9
9
  },
10
10
  "dependencies": {
11
- "@jasonshimmy/custom-elements-runtime": "^3.7.2"
11
+ "@jasonshimmy/custom-elements-runtime": "^3.7.5"
12
12
  },
13
13
  "devDependencies": {
14
- "@jasonshimmy/vite-plugin-cer-app": "^0.19.3",
15
- "typescript": "^5.9.3",
16
- "vite": "^8.0.3"
14
+ "@jasonshimmy/vite-plugin-cer-app": "^0.21.3",
15
+ "typescript": "^6.0.2",
16
+ "vite": "^8.0.8"
17
17
  }
18
18
  }
@@ -9,11 +9,11 @@
9
9
  "preview": "cer-app preview"
10
10
  },
11
11
  "dependencies": {
12
- "@jasonshimmy/custom-elements-runtime": "^3.7.2"
12
+ "@jasonshimmy/custom-elements-runtime": "^3.7.5"
13
13
  },
14
14
  "devDependencies": {
15
- "@jasonshimmy/vite-plugin-cer-app": "^0.19.3",
16
- "typescript": "^5.9.3",
17
- "vite": "^8.0.3"
15
+ "@jasonshimmy/vite-plugin-cer-app": "^0.21.3",
16
+ "typescript": "^6.0.2",
17
+ "vite": "^8.0.8"
18
18
  }
19
19
  }
@@ -8,11 +8,11 @@
8
8
  "preview": "cer-app preview --ssr"
9
9
  },
10
10
  "dependencies": {
11
- "@jasonshimmy/custom-elements-runtime": "^3.7.2"
11
+ "@jasonshimmy/custom-elements-runtime": "^3.7.5"
12
12
  },
13
13
  "devDependencies": {
14
- "@jasonshimmy/vite-plugin-cer-app": "^0.19.3",
15
- "typescript": "^5.9.3",
16
- "vite": "^8.0.3"
14
+ "@jasonshimmy/vite-plugin-cer-app": "^0.21.3",
15
+ "typescript": "^6.0.2",
16
+ "vite": "^8.0.8"
17
17
  }
18
18
  }
@@ -9,6 +9,7 @@ export interface ResolvedCerConfig {
9
9
  mode: 'spa' | 'ssr' | 'ssg'
10
10
  srcDir: string
11
11
  root: string
12
+ contentDir: string
12
13
  pagesDir: string
13
14
  layoutsDir: string
14
15
  componentsDir: string
@@ -18,6 +18,7 @@ import { generateServerApiCode } from './virtual/server-api.js'
18
18
  import { generateServerMiddlewareCode } from './virtual/server-middleware.js'
19
19
  import { generateLoadingCode } from './virtual/loading.js'
20
20
  import { generateErrorCode } from './virtual/error.js'
21
+ import { generateContentComponentsCode } from './virtual/content-components.js'
21
22
  import { createWatcher } from './scanner.js'
22
23
  import { cerContent } from './content/index.js'
23
24
 
@@ -33,6 +34,7 @@ const VIRTUAL_IDS = {
33
34
  appConfig: 'virtual:cer-app-config',
34
35
  loading: 'virtual:cer-loading',
35
36
  error: 'virtual:cer-error',
37
+ contentComponents: 'virtual:cer-content-components',
36
38
  i18n: 'virtual:cer-i18n',
37
39
  } as const
38
40
 
@@ -60,6 +62,7 @@ export function resolveConfig(userConfig: CerAppConfig, root: string = process.c
60
62
  mode,
61
63
  srcDir,
62
64
  root,
65
+ contentDir: resolve(root, userConfig.content?.dir ?? 'content'),
63
66
  pagesDir: join(srcDir, 'pages'),
64
67
  layoutsDir: join(srcDir, 'layouts'),
65
68
  componentsDir: join(srcDir, 'components'),
@@ -136,6 +139,8 @@ async function generateVirtualModule(
136
139
  return generateLoadingCode(config.srcDir)
137
140
  case RESOLVED_IDS.error:
138
141
  return generateErrorCode(config.srcDir)
142
+ case RESOLVED_IDS.contentComponents:
143
+ return generateContentComponentsCode(config.componentsDir, config.contentDir)
139
144
  case RESOLVED_IDS.i18n:
140
145
  return generateI18nModule(config.i18n)
141
146
  default:
@@ -223,6 +228,9 @@ function getDirtyVirtualIds(filePath: string, config: ResolvedCerConfig): string
223
228
  if (filePath.startsWith(config.layoutsDir)) {
224
229
  dirty.push(RESOLVED_IDS.layouts)
225
230
  }
231
+ if (filePath.startsWith(config.componentsDir)) {
232
+ dirty.push(RESOLVED_IDS.contentComponents)
233
+ }
226
234
  if (filePath.startsWith(config.composablesDir)) {
227
235
  dirty.push(RESOLVED_IDS.composables)
228
236
  }
@@ -238,6 +246,9 @@ function getDirtyVirtualIds(filePath: string, config: ResolvedCerConfig): string
238
246
  if (filePath.startsWith(config.serverMiddlewareDir)) {
239
247
  dirty.push(RESOLVED_IDS.serverMiddleware)
240
248
  }
249
+ if (filePath.startsWith(config.contentDir)) {
250
+ dirty.push(RESOLVED_IDS.contentComponents)
251
+ }
241
252
 
242
253
  return dirty
243
254
  }
@@ -393,6 +404,7 @@ export function cerApp(userConfig: CerAppConfig = {}): Plugin[] {
393
404
  config.pagesDir,
394
405
  config.layoutsDir,
395
406
  config.componentsDir,
407
+ config.contentDir,
396
408
  config.composablesDir,
397
409
  config.pluginsDir,
398
410
  config.middlewareDir,
@@ -0,0 +1,83 @@
1
+ import { extractComponentRegistrations, extractTemplateTagNames } from '@jasonshimmy/custom-elements-runtime/vite-plugin'
2
+ import { existsSync, readFileSync } from 'node:fs'
3
+ import { parseContentFileAsync } from '../content/parser.js'
4
+ import { scanContentFiles } from '../content/scanner.js'
5
+ import { scanDirectory } from '../scanner.js'
6
+
7
+ function emptyModule(): string {
8
+ return `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\nexport {}\n`
9
+ }
10
+
11
+ async function buildComponentManifest(componentsDir: string): Promise<Map<string, string>> {
12
+ const manifest = new Map<string, string>()
13
+ if (!existsSync(componentsDir)) return manifest
14
+
15
+ const files = await scanDirectory('**/*.ts', componentsDir)
16
+ for (const file of files) {
17
+ try {
18
+ const source = readFileSync(file, 'utf-8')
19
+ for (const tag of extractComponentRegistrations(source)) {
20
+ manifest.set(tag, file)
21
+ }
22
+ } catch {
23
+ // Skip unreadable files.
24
+ }
25
+ }
26
+
27
+ return manifest
28
+ }
29
+
30
+ async function collectMarkdownTags(contentDir: string): Promise<Set<string>> {
31
+ const tags = new Set<string>()
32
+ if (!existsSync(contentDir)) return tags
33
+
34
+ const files = await scanContentFiles(contentDir)
35
+ const markdownFiles = files.filter((file) => file.ext === 'md')
36
+
37
+ await Promise.all(
38
+ markdownFiles.map(async (file) => {
39
+ try {
40
+ const item = await parseContentFileAsync(file, contentDir)
41
+ for (const tag of extractTemplateTagNames(item.body)) {
42
+ tags.add(tag)
43
+ }
44
+ } catch (err) {
45
+ console.warn(
46
+ `[cer-app] Skipping content file (parse error): ${file.filePath}\n ${(err as Error).message}`,
47
+ )
48
+ }
49
+ }),
50
+ )
51
+
52
+ return tags
53
+ }
54
+
55
+ /**
56
+ * Generates a side-effect virtual module that registers app components used
57
+ * inside rendered markdown bodies.
58
+ */
59
+ export async function generateContentComponentsCode(
60
+ componentsDir: string,
61
+ contentDir: string,
62
+ ): Promise<string> {
63
+ const [manifest, markdownTags] = await Promise.all([
64
+ buildComponentManifest(componentsDir),
65
+ collectMarkdownTags(contentDir),
66
+ ])
67
+
68
+ const imports = [...markdownTags]
69
+ .sort()
70
+ .map((tag) => manifest.get(tag))
71
+ .filter((file): file is string => typeof file === 'string')
72
+
73
+ if (imports.length === 0) return emptyModule()
74
+
75
+ const lines = ['// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app', '']
76
+ for (const file of imports) {
77
+ lines.push(`import ${JSON.stringify(file)}`)
78
+ }
79
+ lines.push('')
80
+ lines.push('export {}')
81
+ lines.push('')
82
+ return lines.join('\n')
83
+ }
@@ -10,6 +10,7 @@ export const APP_ENTRY_TEMPLATE = `// AUTO-GENERATED by @jasonshimmy/vite-plugin
10
10
 
11
11
  import '@jasonshimmy/custom-elements-runtime/css'
12
12
  import 'virtual:cer-jit-css'
13
+ import 'virtual:cer-content-components'
13
14
  import routes from 'virtual:cer-routes'
14
15
  import layouts from 'virtual:cer-layouts'
15
16
  import plugins from 'virtual:cer-plugins'
@@ -16,6 +16,7 @@ import { readFileSync, existsSync } from 'node:fs'
16
16
  import { dirname, join } from 'node:path'
17
17
  import { fileURLToPath } from 'node:url'
18
18
  import { AsyncLocalStorage } from 'node:async_hooks'
19
+ import 'virtual:cer-content-components'
19
20
  import routes from 'virtual:cer-routes'
20
21
  import layouts from 'virtual:cer-layouts'
21
22
  import plugins from 'virtual:cer-plugins'