@jasonshimmy/vite-plugin-cer-app 0.1.2 → 0.1.4

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 (91) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/commits.txt +1 -1
  3. package/cypress.config.ts +16 -0
  4. package/dist/cli/create/index.js +1 -1
  5. package/dist/cli/create/index.js.map +1 -1
  6. package/dist/plugin/build-ssg.d.ts +7 -0
  7. package/dist/plugin/build-ssg.d.ts.map +1 -1
  8. package/dist/plugin/build-ssg.js +2 -1
  9. package/dist/plugin/build-ssg.js.map +1 -1
  10. package/dist/plugin/build-ssr.d.ts.map +1 -1
  11. package/dist/plugin/build-ssr.js +26 -6
  12. package/dist/plugin/build-ssr.js.map +1 -1
  13. package/dist/runtime/composables/index.d.ts +1 -1
  14. package/dist/runtime/composables/index.d.ts.map +1 -1
  15. package/dist/runtime/composables/index.js +1 -1
  16. package/dist/runtime/composables/index.js.map +1 -1
  17. package/dist/runtime/composables/use-head.d.ts.map +1 -1
  18. package/dist/runtime/composables/use-head.js +12 -8
  19. package/dist/runtime/composables/use-head.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 +14 -4
  23. package/dist/runtime/entry-server-template.js.map +1 -1
  24. package/docs/cli.md +2 -0
  25. package/docs/components.md +57 -0
  26. package/docs/composables.md +9 -2
  27. package/docs/data-loading.md +45 -1
  28. package/docs/getting-started.md +71 -6
  29. package/docs/head-management.md +6 -0
  30. package/docs/plugins.md +25 -0
  31. package/docs/routing.md +48 -6
  32. package/e2e/cypress/e2e/api.cy.ts +81 -0
  33. package/e2e/cypress/e2e/data.cy.ts +111 -0
  34. package/e2e/cypress/e2e/fouc.cy.ts +65 -0
  35. package/e2e/cypress/e2e/head.cy.ts +89 -0
  36. package/e2e/cypress/e2e/interactive.cy.ts +122 -0
  37. package/e2e/cypress/e2e/routes.cy.ts +128 -0
  38. package/e2e/cypress/support/commands.ts +60 -0
  39. package/e2e/cypress/support/e2e.ts +10 -0
  40. package/{src/runtime/app-template.ts → e2e/kitchen-sink/app/app.ts} +43 -49
  41. package/e2e/kitchen-sink/app/components/ks-badge.ts +8 -0
  42. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +9 -0
  43. package/e2e/kitchen-sink/app/error.ts +13 -0
  44. package/e2e/kitchen-sink/app/layouts/default.ts +21 -0
  45. package/e2e/kitchen-sink/app/layouts/minimal.ts +7 -0
  46. package/e2e/kitchen-sink/app/loading.ts +9 -0
  47. package/e2e/kitchen-sink/app/middleware/auth.ts +13 -0
  48. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +13 -0
  49. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +20 -0
  50. package/e2e/kitchen-sink/app/pages/404.ts +9 -0
  51. package/e2e/kitchen-sink/app/pages/about.ts +17 -0
  52. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +54 -0
  53. package/e2e/kitchen-sink/app/pages/blog/index.ts +46 -0
  54. package/e2e/kitchen-sink/app/pages/counter.ts +17 -0
  55. package/e2e/kitchen-sink/app/pages/head.ts +20 -0
  56. package/e2e/kitchen-sink/app/pages/index.ts +27 -0
  57. package/e2e/kitchen-sink/app/pages/items/[id].ts +20 -0
  58. package/e2e/kitchen-sink/app/plugins/01.setup.ts +7 -0
  59. package/e2e/kitchen-sink/cer-auto-imports.d.ts +50 -0
  60. package/e2e/kitchen-sink/cer-env.d.ts +36 -0
  61. package/e2e/kitchen-sink/cer-tsconfig.json +30 -0
  62. package/e2e/kitchen-sink/cer.config.ts +6 -0
  63. package/e2e/kitchen-sink/index.html +12 -0
  64. package/e2e/kitchen-sink/server/api/health.ts +3 -0
  65. package/e2e/kitchen-sink/server/api/posts/[slug].ts +11 -0
  66. package/e2e/kitchen-sink/server/api/posts/index.ts +5 -0
  67. package/e2e/kitchen-sink/server/data/posts.ts +21 -0
  68. package/e2e/scripts/clean.mjs +8 -0
  69. package/package.json +19 -2
  70. package/src/__tests__/plugin/build-ssg-render.test.ts +110 -0
  71. package/src/__tests__/plugin/build-ssg.test.ts +47 -1
  72. package/src/__tests__/plugin/build-ssr.test.ts +93 -1
  73. package/src/__tests__/plugin/dev-server.test.ts +493 -0
  74. package/src/__tests__/plugin/scanner.test.ts +15 -1
  75. package/src/__tests__/plugin/transforms/auto-import.test.ts +63 -0
  76. package/src/cli/create/index.ts +1 -1
  77. package/src/cli/create/templates/spa/app/app.ts.tpl +23 -3
  78. package/src/cli/create/templates/ssg/app/app.ts.tpl +27 -3
  79. package/src/cli/create/templates/ssg/app/pages/index.ts.tpl +0 -9
  80. package/src/cli/create/templates/ssr/app/app.ts.tpl +27 -3
  81. package/src/plugin/build-ssg.ts +2 -1
  82. package/src/plugin/build-ssr.ts +26 -6
  83. package/src/runtime/composables/index.ts +1 -1
  84. package/src/runtime/composables/use-head.ts +12 -8
  85. package/src/runtime/entry-server-template.ts +14 -4
  86. package/vitest.config.ts +5 -1
  87. package/VITE_PLUGIN_FRAMEWORK_PLAN.md +0 -594
  88. package/dist/runtime/app-template.d.ts +0 -10
  89. package/dist/runtime/app-template.d.ts.map +0 -1
  90. package/dist/runtime/app-template.js +0 -149
  91. package/dist/runtime/app-template.js.map +0 -1
@@ -1,149 +0,0 @@
1
- /**
2
- * Template string for `app/app.ts`.
3
- *
4
- * This file is the main application bootstrap entry point.
5
- * It registers all auto-discovered components, initialises the router,
6
- * runs plugins, and registers the framework-level <cer-layout-view> component
7
- * that handles layout selection, loading indicators, and error pages.
8
- */
9
- export const APP_TEMPLATE = `import '@jasonshimmy/custom-elements-runtime/css'
10
- import 'virtual:cer-components'
11
- import routes from 'virtual:cer-routes'
12
- import layouts from 'virtual:cer-layouts'
13
- import plugins from 'virtual:cer-plugins'
14
- import { hasLoading, loadingTag } from 'virtual:cer-loading'
15
- import { hasError, errorTag } from 'virtual:cer-error'
16
- import {
17
- component,
18
- ref,
19
- useOnConnected,
20
- useOnDisconnected,
21
- registerBuiltinComponents,
22
- } from '@jasonshimmy/custom-elements-runtime'
23
- import { initRouter } from '@jasonshimmy/custom-elements-runtime/router'
24
- import { enableJITCSS } from '@jasonshimmy/custom-elements-runtime/jit-css'
25
- import { createDOMJITCSS } from '@jasonshimmy/custom-elements-runtime/dom-jit-css'
26
-
27
- registerBuiltinComponents()
28
-
29
- // Enable JIT CSS globally for all Shadow DOM components.
30
- enableJITCSS()
31
-
32
- // initRouter registers router-view/router-link, creates the router, and sets it as active.
33
- const router = initRouter({ routes })
34
-
35
- // ─── Navigation state ────────────────────────────────────────────────────────
36
-
37
- // isNavigating becomes true while a lazy route chunk is loading.
38
- const isNavigating = ref(false)
39
-
40
- // currentError holds the last uncaught navigation or render error.
41
- const currentError = ref(null)
42
-
43
- // Expose resetError globally so page-error components can call it.
44
- ;(globalThis as any).resetError = () => {
45
- currentError.value = null
46
- router.replace(router.getCurrent().path)
47
- }
48
-
49
- // Wrap push/replace to track navigation pending state.
50
- const _push = router.push.bind(router)
51
- const _replace = router.replace.bind(router)
52
-
53
- router.push = async (path) => {
54
- isNavigating.value = true
55
- currentError.value = null
56
- try {
57
- await _push(path)
58
- } catch (err) {
59
- currentError.value = err instanceof Error ? err.message : String(err)
60
- } finally {
61
- isNavigating.value = false
62
- }
63
- }
64
-
65
- router.replace = async (path) => {
66
- isNavigating.value = true
67
- currentError.value = null
68
- try {
69
- await _replace(path)
70
- } catch (err) {
71
- currentError.value = err instanceof Error ? err.message : String(err)
72
- } finally {
73
- isNavigating.value = false
74
- }
75
- }
76
-
77
- // ─── <cer-layout-view> ───────────────────────────────────────────────────────
78
- //
79
- // Wraps <router-view> in the layout appropriate for the current route.
80
- // Falls back to rendering <router-view> directly when no matching layout
81
- // exists. Also renders loading / error pages when those states are active.
82
- //
83
- // Layout stays mounted across navigations that share the same layout — the
84
- // vdom diff preserves the outer element when its tag name doesn't change.
85
-
86
- component('cer-layout-view', () => {
87
- const current = ref(router.getCurrent())
88
- let unsub: (() => void) | undefined
89
-
90
- useOnConnected(() => {
91
- unsub = router.subscribe((s: typeof current.value) => {
92
- current.value = s
93
- })
94
- })
95
-
96
- useOnDisconnected(() => {
97
- unsub?.()
98
- unsub = undefined
99
- })
100
-
101
- // Error state — show page-error if available, otherwise plain text.
102
- if (currentError.value !== null) {
103
- if (hasError && errorTag) {
104
- return { tag: errorTag, props: { attrs: { error: String(currentError.value) } }, children: [] }
105
- }
106
- return { tag: 'div', props: { attrs: { style: 'padding:2rem;font-family:monospace' } }, children: [String(currentError.value)] }
107
- }
108
-
109
- // Loading state — show page-loading while a route chunk is fetching.
110
- if (isNavigating.value && hasLoading && loadingTag) {
111
- return { tag: loadingTag, props: {}, children: [] }
112
- }
113
-
114
- // Normal state — wrap router-view in the active layout (if any).
115
- const matched = router.matchRoute(current.value.path)
116
- const layoutName = (matched?.route as any)?.meta?.layout ?? 'default'
117
- const layoutTag = (layouts as Record<string, string>)[layoutName]
118
- const routerView = { tag: 'router-view', props: {}, children: [] }
119
-
120
- if (layoutTag) {
121
- return { tag: layoutTag, props: {}, children: [routerView] }
122
- }
123
- return routerView
124
- })
125
-
126
- // ─── Plugins ─────────────────────────────────────────────────────────────────
127
-
128
- for (const plugin of plugins) {
129
- if (plugin && typeof plugin.setup === 'function') {
130
- await plugin.setup({ router, provide: (key, value) => { (globalThis as any)[key] = value }, config: {} })
131
- }
132
- }
133
-
134
- // ─── Initial navigation ──────────────────────────────────────────────────────
135
-
136
- if (typeof window !== 'undefined') {
137
- await router.replace(window.location.pathname + window.location.search + window.location.hash)
138
- // Clear SSR loader data after the initial navigation so that subsequent
139
- // client-side navigations don't accidentally reuse it. We wait until after
140
- // router.replace() so both the pre-rendered element (upgraded during
141
- // component registration) and the new element from router.replace() can
142
- // both call usePageData() and receive the hydration data.
143
- delete (globalThis as any).__CER_DATA__
144
- createDOMJITCSS().mount()
145
- }
146
-
147
- export { router }
148
- `;
149
- //# sourceMappingURL=app-template.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-template.js","sourceRoot":"","sources":["../../src/runtime/app-template.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2I3B,CAAA"}