@fluixi/core 1.0.0-alpha.53

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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +611 -0
  3. package/dist/cdn/core.global.js +3 -0
  4. package/dist/cli/generate.cjs +1814 -0
  5. package/dist/cli/generate.d.ts +7 -0
  6. package/dist/cli/generate.d.ts.map +1 -0
  7. package/dist/cli/generate.js +2580 -0
  8. package/dist/cli/generate.mjs +1814 -0
  9. package/dist/cli/index.cjs +1814 -0
  10. package/dist/cli/index.d.ts +7 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +2580 -0
  13. package/dist/cli/index.mjs +1814 -0
  14. package/dist/cli/run.cjs +2 -0
  15. package/dist/cli/run.d.ts +3 -0
  16. package/dist/cli/run.d.ts.map +1 -0
  17. package/dist/cli/run.js +62 -0
  18. package/dist/cli/run.mjs +2 -0
  19. package/dist/fluixi.d.ts +5 -0
  20. package/dist/src/cdn/chunk-PFM5O5UE.mjs +1 -0
  21. package/dist/src/cdn/core.cjs +1 -0
  22. package/dist/src/cdn/core.d.ts +16 -0
  23. package/dist/src/cdn/core.d.ts.map +1 -0
  24. package/dist/src/cdn/core.js +15 -0
  25. package/dist/src/cdn/core.mjs +1 -0
  26. package/dist/src/cdn/router-next-WNWCFVC2.mjs +1 -0
  27. package/dist/src/index.cjs +1 -0
  28. package/dist/src/index.d.ts +7 -0
  29. package/dist/src/index.d.ts.map +1 -0
  30. package/dist/src/index.js +26 -0
  31. package/dist/src/index.mjs +1 -0
  32. package/dist/src/jsx-dev-runtime.cjs +1 -0
  33. package/dist/src/jsx-dev-runtime.d.ts +2 -0
  34. package/dist/src/jsx-dev-runtime.d.ts.map +1 -0
  35. package/dist/src/jsx-dev-runtime.js +1 -0
  36. package/dist/src/jsx-dev-runtime.mjs +1 -0
  37. package/dist/src/jsx-runtime.cjs +1 -0
  38. package/dist/src/jsx-runtime.d.ts +7 -0
  39. package/dist/src/jsx-runtime.d.ts.map +1 -0
  40. package/dist/src/jsx-runtime.js +17 -0
  41. package/dist/src/jsx-runtime.mjs +1 -0
  42. package/dist/src/lib/client/chunk-D3VTWVNJ.mjs +1 -0
  43. package/dist/src/lib/client/index.cjs +1 -0
  44. package/dist/src/lib/client/index.d.ts +54 -0
  45. package/dist/src/lib/client/index.d.ts.map +1 -0
  46. package/dist/src/lib/client/index.js +142 -0
  47. package/dist/src/lib/client/index.mjs +1 -0
  48. package/dist/src/lib/client/router-next-UYIYMRJL.mjs +1 -0
  49. package/dist/src/lib/context/context.cjs +1 -0
  50. package/dist/src/lib/context/context.d.ts +337 -0
  51. package/dist/src/lib/context/context.d.ts.map +1 -0
  52. package/dist/src/lib/context/context.js +462 -0
  53. package/dist/src/lib/context/context.mjs +1 -0
  54. package/dist/src/lib/context/index.cjs +1 -0
  55. package/dist/src/lib/context/index.d.ts +3 -0
  56. package/dist/src/lib/context/index.d.ts.map +1 -0
  57. package/dist/src/lib/context/index.js +5 -0
  58. package/dist/src/lib/context/index.mjs +1 -0
  59. package/dist/src/lib/control-flow.cjs +1 -0
  60. package/dist/src/lib/control-flow.d.ts +4 -0
  61. package/dist/src/lib/control-flow.d.ts.map +1 -0
  62. package/dist/src/lib/control-flow.js +1 -0
  63. package/dist/src/lib/control-flow.mjs +1 -0
  64. package/dist/src/lib/core.cjs +1 -0
  65. package/dist/src/lib/core.d.ts +90 -0
  66. package/dist/src/lib/core.d.ts.map +1 -0
  67. package/dist/src/lib/core.js +181 -0
  68. package/dist/src/lib/core.mjs +1 -0
  69. package/dist/src/lib/directives/lit.cjs +1 -0
  70. package/dist/src/lib/directives/lit.d.ts +2 -0
  71. package/dist/src/lib/directives/lit.d.ts.map +1 -0
  72. package/dist/src/lib/directives/lit.js +31 -0
  73. package/dist/src/lib/directives/lit.mjs +0 -0
  74. package/dist/src/lib/env/index.cjs +1 -0
  75. package/dist/src/lib/env/index.d.ts +39 -0
  76. package/dist/src/lib/env/index.d.ts.map +1 -0
  77. package/dist/src/lib/env/index.js +50 -0
  78. package/dist/src/lib/env/index.mjs +1 -0
  79. package/dist/src/lib/i18n/index.cjs +1 -0
  80. package/dist/src/lib/i18n/index.d.ts +79 -0
  81. package/dist/src/lib/i18n/index.d.ts.map +1 -0
  82. package/dist/src/lib/i18n/index.js +127 -0
  83. package/dist/src/lib/i18n/index.mjs +1 -0
  84. package/dist/src/lib/index.cjs +1 -0
  85. package/dist/src/lib/index.d.ts +83 -0
  86. package/dist/src/lib/index.d.ts.map +1 -0
  87. package/dist/src/lib/index.js +147 -0
  88. package/dist/src/lib/index.mjs +1 -0
  89. package/dist/src/lib/isomorphic.cjs +1 -0
  90. package/dist/src/lib/isomorphic.d.ts +69 -0
  91. package/dist/src/lib/isomorphic.d.ts.map +1 -0
  92. package/dist/src/lib/isomorphic.js +92 -0
  93. package/dist/src/lib/isomorphic.mjs +1 -0
  94. package/dist/src/lib/jsx-runtime/index.cjs +1 -0
  95. package/dist/src/lib/jsx-runtime/index.d.ts +13 -0
  96. package/dist/src/lib/jsx-runtime/index.d.ts.map +1 -0
  97. package/dist/src/lib/jsx-runtime/index.js +23 -0
  98. package/dist/src/lib/jsx-runtime/index.mjs +1 -0
  99. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -0
  100. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts +2 -0
  101. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts.map +1 -0
  102. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.js +1 -0
  103. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -0
  104. package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +13 -0
  105. package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +21 -0
  106. package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -0
  107. package/dist/src/lib/plugins/fluixi-routes-plugin.js +102 -0
  108. package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +13 -0
  109. package/dist/src/lib/plugins/index.cjs +13 -0
  110. package/dist/src/lib/plugins/index.d.ts +4 -0
  111. package/dist/src/lib/plugins/index.d.ts.map +1 -0
  112. package/dist/src/lib/plugins/index.js +3 -0
  113. package/dist/src/lib/plugins/index.mjs +13 -0
  114. package/dist/src/lib/plugins/route-codegen.cjs +8 -0
  115. package/dist/src/lib/plugins/route-codegen.d.ts +13 -0
  116. package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -0
  117. package/dist/src/lib/plugins/route-codegen.js +81 -0
  118. package/dist/src/lib/plugins/route-codegen.mjs +8 -0
  119. package/dist/src/lib/plugins/route-scanner.cjs +1 -0
  120. package/dist/src/lib/plugins/route-scanner.d.ts +39 -0
  121. package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -0
  122. package/dist/src/lib/plugins/route-scanner.js +216 -0
  123. package/dist/src/lib/plugins/route-scanner.mjs +1 -0
  124. package/dist/src/lib/plugins/vite.cjs +1 -0
  125. package/dist/src/lib/plugins/vite.d.ts +3 -0
  126. package/dist/src/lib/plugins/vite.d.ts.map +1 -0
  127. package/dist/src/lib/plugins/vite.js +1 -0
  128. package/dist/src/lib/plugins/vite.mjs +1 -0
  129. package/dist/src/lib/render/component.cjs +1 -0
  130. package/dist/src/lib/render/component.d.ts +328 -0
  131. package/dist/src/lib/render/component.d.ts.map +1 -0
  132. package/dist/src/lib/render/component.js +520 -0
  133. package/dist/src/lib/render/component.mjs +1 -0
  134. package/dist/src/lib/render/index.cjs +1 -0
  135. package/dist/src/lib/render/index.d.ts +113 -0
  136. package/dist/src/lib/render/index.d.ts.map +1 -0
  137. package/dist/src/lib/render/index.js +201 -0
  138. package/dist/src/lib/render/index.mjs +1 -0
  139. package/dist/src/lib/render/lazy.cjs +1 -0
  140. package/dist/src/lib/render/lazy.d.ts +28 -0
  141. package/dist/src/lib/render/lazy.d.ts.map +1 -0
  142. package/dist/src/lib/render/lazy.js +62 -0
  143. package/dist/src/lib/render/lazy.mjs +1 -0
  144. package/dist/src/lib/render/suspense.cjs +1 -0
  145. package/dist/src/lib/render/suspense.d.ts +25 -0
  146. package/dist/src/lib/render/suspense.d.ts.map +1 -0
  147. package/dist/src/lib/render/suspense.js +139 -0
  148. package/dist/src/lib/render/suspense.mjs +1 -0
  149. package/dist/src/lib/router-next/data.cjs +1 -0
  150. package/dist/src/lib/router-next/data.d.ts +101 -0
  151. package/dist/src/lib/router-next/data.d.ts.map +1 -0
  152. package/dist/src/lib/router-next/data.js +179 -0
  153. package/dist/src/lib/router-next/data.mjs +1 -0
  154. package/dist/src/lib/router-next/index.cjs +1 -0
  155. package/dist/src/lib/router-next/index.d.ts +156 -0
  156. package/dist/src/lib/router-next/index.d.ts.map +1 -0
  157. package/dist/src/lib/router-next/index.js +464 -0
  158. package/dist/src/lib/router-next/index.mjs +1 -0
  159. package/dist/src/lib/server/hydration.cjs +1 -0
  160. package/dist/src/lib/server/hydration.d.ts +238 -0
  161. package/dist/src/lib/server/hydration.d.ts.map +1 -0
  162. package/dist/src/lib/server/hydration.js +384 -0
  163. package/dist/src/lib/server/hydration.mjs +1 -0
  164. package/dist/src/lib/server/index.cjs +16 -0
  165. package/dist/src/lib/server/index.d.ts +91 -0
  166. package/dist/src/lib/server/index.d.ts.map +1 -0
  167. package/dist/src/lib/server/index.js +141 -0
  168. package/dist/src/lib/server/index.mjs +16 -0
  169. package/dist/src/lib/server/reactive.cjs +1 -0
  170. package/dist/src/lib/server/reactive.d.ts +298 -0
  171. package/dist/src/lib/server/reactive.d.ts.map +1 -0
  172. package/dist/src/lib/server/reactive.js +472 -0
  173. package/dist/src/lib/server/reactive.mjs +1 -0
  174. package/dist/src/lib/theme/index.cjs +1 -0
  175. package/dist/src/lib/theme/index.d.ts +51 -0
  176. package/dist/src/lib/theme/index.d.ts.map +1 -0
  177. package/dist/src/lib/theme/index.js +79 -0
  178. package/dist/src/lib/theme/index.mjs +1 -0
  179. package/dist/src/lib/utils/index.cjs +1 -0
  180. package/dist/src/lib/utils/index.d.ts +379 -0
  181. package/dist/src/lib/utils/index.d.ts.map +1 -0
  182. package/dist/src/lib/utils/index.js +527 -0
  183. package/dist/src/lib/utils/index.mjs +1 -0
  184. package/dist/src/rx.cjs +1 -0
  185. package/dist/src/rx.d.ts +2 -0
  186. package/dist/src/rx.d.ts.map +1 -0
  187. package/dist/src/rx.js +101 -0
  188. package/dist/src/rx.mjs +0 -0
  189. package/dist/src/server.cjs +16 -0
  190. package/dist/src/server.d.ts +64 -0
  191. package/dist/src/server.d.ts.map +1 -0
  192. package/dist/src/server.js +63 -0
  193. package/dist/src/server.mjs +16 -0
  194. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  195. package/package.json +128 -0
  196. package/src/index.ts +31 -0
  197. package/types/fluixi.d.ts +5 -0
  198. package/types/vinxi.d.ts +50 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * @fileoverview Vite/Rollup plugin for file-system routing
3
+ * @module @fluixi/core/plugins/fluixi-routes-plugin
4
+ *
5
+ * Scans a routes directory at build time and generates a virtual module
6
+ * (virtual:fluixi-routes) containing the route tree. Replaces import.meta.glob.
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import { nodePolyfills } from 'vite-plugin-node-polyfills';
11
+ import { scanRoutes } from './route-scanner.js';
12
+ import { generateRouteModule } from './route-codegen.js';
13
+ const VIRTUAL_MODULE_ID = 'virtual:fluixi-routes';
14
+ const RESOLVED_VIRTUAL_ID = '\0' + VIRTUAL_MODULE_ID;
15
+ const VIRTUAL_ROUTES_TYPES = `// Auto-generated by @fluixi/core fluixiRoutesPlugin — do not edit manually
16
+ declare module 'virtual:fluixi-routes' {
17
+ import type { RouteDefinition } from '@fluixi/core/router-next';
18
+ export const routes: RouteDefinition[];
19
+ }
20
+ `;
21
+ function writeVirtualRouteTypes(root) {
22
+ const srcDir = path.join(root, 'src');
23
+ if (!fs.existsSync(srcDir))
24
+ return;
25
+ const dest = path.join(srcDir, 'fluixi-env.d.ts');
26
+ // Only write if content differs (avoids unnecessary TS invalidation)
27
+ const current = fs.existsSync(dest) ? fs.readFileSync(dest, 'utf8') : '';
28
+ if (current !== VIRTUAL_ROUTES_TYPES) {
29
+ fs.writeFileSync(dest, VIRTUAL_ROUTES_TYPES, 'utf8');
30
+ }
31
+ }
32
+ export function fluixiRoutesPlugin(options = {}) {
33
+ const routesDir = options.routesDir ?? 'src/routes';
34
+ const extensions = options.extensions ?? ['.tsx', '.ts', '.jsx', '.js'];
35
+ let projectRoot = '';
36
+ // nodePolyfills injects `vite-plugin-node-polyfills/shims/*` (browser polyfills for
37
+ // Buffer/process/global/fs/path) into transformed modules. It's needed by some apps
38
+ // for the BROWSER, but it BREAKS SSR — Node already has those globals, and the
39
+ // injected CJS shim can't be ESM-evaluated (and often can't be resolved at all:
40
+ // "Cannot find module .../shims/buffer"). So it's opt-out: on by default for
41
+ // back-compat, but SSR-first setups (e.g. @fluixi/start) pass `polyfills: false`.
42
+ const usePolyfills = options.polyfills !== false;
43
+ const polyfillsPlugin = usePolyfills
44
+ ? Object.assign({}, nodePolyfills({ include: ['fs', 'path'] }), { apply: 'serve' })
45
+ : null;
46
+ const routesPlugin = {
47
+ name: 'fluixi-routes',
48
+ enforce: 'pre',
49
+ configResolved(config) {
50
+ projectRoot = config.root || process.cwd();
51
+ writeVirtualRouteTypes(projectRoot);
52
+ },
53
+ resolveId(id) {
54
+ if (id === VIRTUAL_MODULE_ID) {
55
+ return RESOLVED_VIRTUAL_ID;
56
+ }
57
+ return null;
58
+ },
59
+ load(id) {
60
+ if (id !== RESOLVED_VIRTUAL_ID)
61
+ return null;
62
+ const root = projectRoot || process.cwd();
63
+ const absRoutesDir = path.resolve(root, routesDir);
64
+ const scanOpts = { extensions };
65
+ const routes = scanRoutes(absRoutesDir, scanOpts);
66
+ // Import paths are relative to project root, prefixed with ./
67
+ const importBase = './' + routesDir;
68
+ const code = generateRouteModule(routes, importBase);
69
+ return code;
70
+ },
71
+ // Vite dev server: watch routes directory for changes
72
+ configureServer(server) {
73
+ const root = projectRoot || process.cwd();
74
+ const absRoutesDir = path.resolve(root, routesDir);
75
+ // Watch the routes directory
76
+ server.watcher.add(absRoutesDir);
77
+ server.watcher.on('all', (event, filePath) => {
78
+ // Only react to file add/remove/rename in routes dir
79
+ if (!filePath.startsWith(absRoutesDir) ||
80
+ !['add', 'unlink', 'addDir', 'unlinkDir'].includes(event)) {
81
+ return;
82
+ }
83
+ // Check if the file has a valid extension
84
+ if (event !== 'addDir' &&
85
+ event !== 'unlinkDir' &&
86
+ !extensions.some((ext) => filePath.endsWith(ext))) {
87
+ return;
88
+ }
89
+ // Invalidate the virtual module so it regenerates
90
+ const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);
91
+ if (mod) {
92
+ server.moduleGraph.invalidateModule(mod);
93
+ // Trigger HMR
94
+ server.ws.send({ type: 'full-reload' });
95
+ }
96
+ });
97
+ },
98
+ };
99
+ // Vite flattens plugin arrays automatically — consumers just use:
100
+ // plugins: [fluixiRoutesPlugin({ routesDir: 'src/routes' })]
101
+ return polyfillsPlugin ? [polyfillsPlugin, routesPlugin] : [routesPlugin];
102
+ }
@@ -0,0 +1,13 @@
1
+ import*as m from"fs";import*as R from"path";import{nodePolyfills as U}from"vite-plugin-node-polyfills";import*as y from"fs";import*as h from"path";var T=[".tsx",".ts",".jsx",".js"];function A(t,e={}){let n=e.extensions??T,s=h.resolve(t);return y.existsSync(s)?I(s,s,"",n):[]}function I(t,e,n,s){let c=y.readdirSync(t,{withFileTypes:!0}),o=[],g=null,i=[],f=[];for(let r of c)r.isDirectory()?f.push(r):r.isFile()&&v(r.name,s)&&i.push(r);let a,u=[];for(let r of i)L(r.name)==="layout"?a=_(r.name,t,e,n,!0):u.push(r);let d=[];for(let r of u)d.push(_(r.name,t,e,n,!1));let l=[];for(let r of f){let p=r.name,O=G(p),j=O?"":V(p),D=j?W(n,j):n,b=I(h.join(t,p),e,D,s);if(O)l.push(...b);else{let S=b.find(x=>x.isLayout&&x.urlPath===D),P=b.filter(x=>!x.isLayout||x.urlPath!==D);S?(S.children=[...S.children,...P],l.push(S)):P.length>0&&l.push(...P)}}return a?(a.children=[...d,...l],o.push(a)):o.push(...d,...l),M(o)}function _(t,e,n,s,c){let o=L(t),g=h.relative(n,h.join(e,t)),i=o==="index",f=o.startsWith("[..."),a=!f&&o.startsWith("[")&&o.endsWith("]"),u;c?u="":i?u="/":f?u=`*${o.slice(4,-1)}`:a?u=`:${o.slice(1,-1)}`:u=o;let d=c||i?s||"/":W(s,u),l=h.join(e,t),r=!1;try{let p=y.readFileSync(l,"utf-8");r=/export\s+(const|function|async\s+function)\s+routeData\b/.test(p)}catch{}return{filePath:g.replace(/\\/g,"/"),urlSegment:u,urlPath:d,isLayout:c,isIndex:i,isDynamic:a,isCatchAll:f,isGroup:!1,children:[],parentUrlPath:s,hasRouteData:r,rootDir:n,dir:e}}function v(t,e){return e.some(n=>t.endsWith(n))}function L(t){let e=t.lastIndexOf(".");return e>0?t.slice(0,e):t}function G(t){return t.startsWith("(")&&t.endsWith(")")}function V(t){return t.startsWith("[...")&&t.endsWith("]")?"*"+t.slice(4,-1):t.startsWith("[")&&t.endsWith("]")?":"+t.slice(1,-1):t}function W(t,e){return(t.endsWith("/")?t:t+"/")+e}function M(t){return t.sort((e,n)=>e.isLayout&&!n.isLayout?-1:!e.isLayout&&n.isLayout?1:e.isIndex&&!n.isIndex?-1:!e.isIndex&&n.isIndex?1:!e.isDynamic&&!e.isCatchAll&&(n.isDynamic||n.isCatchAll)?-1:(e.isDynamic||e.isCatchAll)&&!n.isDynamic&&!n.isCatchAll?1:e.isDynamic&&n.isCatchAll?-1:e.isCatchAll&&n.isDynamic?1:e.urlSegment.localeCompare(n.urlSegment))}function C(t,e){let n=[];return n.push("// Auto-generated by @fluixi/core route plugin"),n.push("// Do not edit manually"),n.push(""),n.push("import { lazy } from '@fluixi/core/router-next';"),n.push(""),n.push(`export const routes = ${w(t,e,0)};`),n.push(""),n.join(`
2
+ `)}function w(t,e,n){if(t.length===0)return"[]";let s=" ".repeat(n);return`[
3
+ ${t.map(o=>N(o,e,n+1)).join(`,
4
+ `)}
5
+ ${s}]`}function N(t,e,n){let s=" ".repeat(n),c=[],o=J(t.filePath,e),g=k(t);if(c.push(`${s} path: ${JSON.stringify(g)}`),c.push(`${s} component: lazy(() => import(${JSON.stringify(o)}))`),t.hasRouteData&&c.push(`${s} data: (args, __owner, __isCancelled) => import(${JSON.stringify(o)}).then(m => { if (typeof __isCancelled === 'function' && __isCancelled()) return undefined; if (!m.routeData) return undefined; return __owner ? m.routeData(args) : m.routeData(args); })`),t.children.length>0){let i=w(t.children,e,n+1);c.push(`${s} children: ${i}`)}return`${s}{
6
+ ${c.join(`,
7
+ `)}
8
+ ${s}}`}function k(t){return t.urlPath}function J(t,e){return`${e.replace(/\\/g,"/").replace(/\/$/,"")}/${t}`}var E="virtual:fluixi-routes",$="\0"+E,F=`// Auto-generated by @fluixi/core fluixiRoutesPlugin — do not edit manually
9
+ declare module 'virtual:fluixi-routes' {
10
+ import type { RouteDefinition } from '@fluixi/core/router-next';
11
+ export const routes: RouteDefinition[];
12
+ }
13
+ `;function z(t){let e=R.join(t,"src");if(!m.existsSync(e))return;let n=R.join(e,"fluixi-env.d.ts");(m.existsSync(n)?m.readFileSync(n,"utf8"):"")!==F&&m.writeFileSync(n,F,"utf8")}function K(t={}){let e=t.routesDir??"src/routes",n=t.extensions??[".tsx",".ts",".jsx",".js"],s="",o=t.polyfills!==!1?Object.assign({},U({include:["fs","path"]}),{apply:"serve"}):null,g={name:"fluixi-routes",enforce:"pre",configResolved(i){s=i.root||process.cwd(),z(s)},resolveId(i){return i===E?$:null},load(i){if(i!==$)return null;let f=s||process.cwd(),a=R.resolve(f,e),d=A(a,{extensions:n}),l="./"+e;return C(d,l)},configureServer(i){let f=s||process.cwd(),a=R.resolve(f,e);i.watcher.add(a),i.watcher.on("all",(u,d)=>{if(!d.startsWith(a)||!["add","unlink","addDir","unlinkDir"].includes(u)||u!=="addDir"&&u!=="unlinkDir"&&!n.some(r=>d.endsWith(r)))return;let l=i.moduleGraph.getModuleById($);l&&(i.moduleGraph.invalidateModule(l),i.ws.send({type:"full-reload"}))})}};return o?[o,g]:[g]}export{K as fluixiRoutesPlugin};
@@ -0,0 +1,13 @@
1
+ "use strict";var k=Object.create;var D=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,B=Object.prototype.hasOwnProperty;var X=(t,n)=>{for(var e in n)D(t,e,{get:n[e],enumerable:!0})},L=(t,n,e,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of U(n))!B.call(t,o)&&o!==e&&D(t,o,{get:()=>n[o],enumerable:!(s=J(n,o))||s.enumerable});return t};var P=(t,n,e)=>(e=t!=null?k(z(t)):{},L(n||!t||!t.__esModule?D(e,"default",{value:t,enumerable:!0}):e,t)),Y=t=>L(D({},"__esModule",{value:!0}),t);var it={};X(it,{createVitePlugin:()=>b.createVitePlugin,fluixi:()=>b.fluixi,fluixiRoutesPlugin:()=>N});module.exports=Y(it);var b=require("@fluixi/vite-plugin");var m=P(require("fs"),1),x=P(require("path"),1),G=require("vite-plugin-node-polyfills");var y=P(require("fs"),1),h=P(require("path"),1),q=[".tsx",".ts",".jsx",".js"];function W(t,n={}){let e=n.extensions??q,s=h.resolve(t);return y.existsSync(s)?C(s,s,"",e):[]}function C(t,n,e,s){let o=y.readdirSync(t,{withFileTypes:!0}),r=[],g=null,i=[],f=[];for(let u of o)u.isDirectory()?f.push(u):u.isFile()&&H(u.name,s)&&i.push(u);let l,c=[];for(let u of i)w(u.name)==="layout"?l=F(u.name,t,n,e,!0):c.push(u);let p=[];for(let u of c)p.push(F(u.name,t,n,e,!1));let a=[];for(let u of f){let d=u.name,A=K(d),I=A?"":Q(d),O=I?E(e,I):e,$=C(h.join(t,d),n,O,s);if(A)a.push(...$);else{let S=$.find(R=>R.isLayout&&R.urlPath===O),j=$.filter(R=>!R.isLayout||R.urlPath!==O);S?(S.children=[...S.children,...j],a.push(S)):j.length>0&&a.push(...j)}}return l?(l.children=[...p,...a],r.push(l)):r.push(...p,...a),Z(r)}function F(t,n,e,s,o){let r=w(t),g=h.relative(e,h.join(n,t)),i=r==="index",f=r.startsWith("[..."),l=!f&&r.startsWith("[")&&r.endsWith("]"),c;o?c="":i?c="/":f?c=`*${r.slice(4,-1)}`:l?c=`:${r.slice(1,-1)}`:c=r;let p=o||i?s||"/":E(s,c),a=h.join(n,t),u=!1;try{let d=y.readFileSync(a,"utf-8");u=/export\s+(const|function|async\s+function)\s+routeData\b/.test(d)}catch{}return{filePath:g.replace(/\\/g,"/"),urlSegment:c,urlPath:p,isLayout:o,isIndex:i,isDynamic:l,isCatchAll:f,isGroup:!1,children:[],parentUrlPath:s,hasRouteData:u,rootDir:e,dir:n}}function H(t,n){return n.some(e=>t.endsWith(e))}function w(t){let n=t.lastIndexOf(".");return n>0?t.slice(0,n):t}function K(t){return t.startsWith("(")&&t.endsWith(")")}function Q(t){return t.startsWith("[...")&&t.endsWith("]")?"*"+t.slice(4,-1):t.startsWith("[")&&t.endsWith("]")?":"+t.slice(1,-1):t}function E(t,n){return(t.endsWith("/")?t:t+"/")+n}function Z(t){return t.sort((n,e)=>n.isLayout&&!e.isLayout?-1:!n.isLayout&&e.isLayout?1:n.isIndex&&!e.isIndex?-1:!n.isIndex&&e.isIndex?1:!n.isDynamic&&!n.isCatchAll&&(e.isDynamic||e.isCatchAll)?-1:(n.isDynamic||n.isCatchAll)&&!e.isDynamic&&!e.isCatchAll?1:n.isDynamic&&e.isCatchAll?-1:n.isCatchAll&&e.isDynamic?1:n.urlSegment.localeCompare(e.urlSegment))}function T(t,n){let e=[];return e.push("// Auto-generated by @fluixi/core route plugin"),e.push("// Do not edit manually"),e.push(""),e.push("import { lazy } from '@fluixi/core/router-next';"),e.push(""),e.push(`export const routes = ${v(t,n,0)};`),e.push(""),e.join(`
2
+ `)}function v(t,n,e){if(t.length===0)return"[]";let s=" ".repeat(e);return`[
3
+ ${t.map(r=>tt(r,n,e+1)).join(`,
4
+ `)}
5
+ ${s}]`}function tt(t,n,e){let s=" ".repeat(e),o=[],r=et(t.filePath,n),g=nt(t);if(o.push(`${s} path: ${JSON.stringify(g)}`),o.push(`${s} component: lazy(() => import(${JSON.stringify(r)}))`),t.hasRouteData&&o.push(`${s} data: (args, __owner, __isCancelled) => import(${JSON.stringify(r)}).then(m => { if (typeof __isCancelled === 'function' && __isCancelled()) return undefined; if (!m.routeData) return undefined; return __owner ? m.routeData(args) : m.routeData(args); })`),t.children.length>0){let i=v(t.children,n,e+1);o.push(`${s} children: ${i}`)}return`${s}{
6
+ ${o.join(`,
7
+ `)}
8
+ ${s}}`}function nt(t){return t.urlPath}function et(t,n){return`${n.replace(/\\/g,"/").replace(/\/$/,"")}/${t}`}var M="virtual:fluixi-routes",_="\0"+M,V=`// Auto-generated by @fluixi/core fluixiRoutesPlugin — do not edit manually
9
+ declare module 'virtual:fluixi-routes' {
10
+ import type { RouteDefinition } from '@fluixi/core/router-next';
11
+ export const routes: RouteDefinition[];
12
+ }
13
+ `;function st(t){let n=x.join(t,"src");if(!m.existsSync(n))return;let e=x.join(n,"fluixi-env.d.ts");(m.existsSync(e)?m.readFileSync(e,"utf8"):"")!==V&&m.writeFileSync(e,V,"utf8")}function N(t={}){let n=t.routesDir??"src/routes",e=t.extensions??[".tsx",".ts",".jsx",".js"],s="",r=t.polyfills!==!1?Object.assign({},(0,G.nodePolyfills)({include:["fs","path"]}),{apply:"serve"}):null,g={name:"fluixi-routes",enforce:"pre",configResolved(i){s=i.root||process.cwd(),st(s)},resolveId(i){return i===M?_:null},load(i){if(i!==_)return null;let f=s||process.cwd(),l=x.resolve(f,n),p=W(l,{extensions:e}),a="./"+n;return T(p,a)},configureServer(i){let f=s||process.cwd(),l=x.resolve(f,n);i.watcher.add(l),i.watcher.on("all",(c,p)=>{if(!p.startsWith(l)||!["add","unlink","addDir","unlinkDir"].includes(c)||c!=="addDir"&&c!=="unlinkDir"&&!e.some(u=>p.endsWith(u)))return;let a=i.moduleGraph.getModuleById(_);a&&(i.moduleGraph.invalidateModule(a),i.ws.send({type:"full-reload"}))})}};return r?[r,g]:[g]}
@@ -0,0 +1,4 @@
1
+ export * from './vite.js';
2
+ export { fluixiRoutesPlugin } from './fluixi-routes-plugin.js';
3
+ export type { FluixiRoutesPluginOptions } from './fluixi-routes-plugin.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './vite.js';
2
+ export { fluixiRoutesPlugin } from './fluixi-routes-plugin.js';
3
+ // fluixiElementPlugin moved to @fluixi/element/plugin (wc-element repo).
@@ -0,0 +1,13 @@
1
+ import{fluixi as q,createVitePlugin as H}from"@fluixi/vite-plugin";import*as m from"fs";import*as x from"path";import{nodePolyfills as U}from"vite-plugin-node-polyfills";import*as y from"fs";import*as h from"path";var T=[".tsx",".ts",".jsx",".js"];function A(t,e={}){let n=e.extensions??T,s=h.resolve(t);return y.existsSync(s)?I(s,s,"",n):[]}function I(t,e,n,s){let c=y.readdirSync(t,{withFileTypes:!0}),o=[],g=null,i=[],f=[];for(let r of c)r.isDirectory()?f.push(r):r.isFile()&&v(r.name,s)&&i.push(r);let l,u=[];for(let r of i)L(r.name)==="layout"?l=_(r.name,t,e,n,!0):u.push(r);let p=[];for(let r of u)p.push(_(r.name,t,e,n,!1));let a=[];for(let r of f){let d=r.name,$=V(d),j=$?"":G(d),D=j?F(n,j):n,P=I(h.join(t,d),e,D,s);if($)a.push(...P);else{let S=P.find(R=>R.isLayout&&R.urlPath===D),b=P.filter(R=>!R.isLayout||R.urlPath!==D);S?(S.children=[...S.children,...b],a.push(S)):b.length>0&&a.push(...b)}}return l?(l.children=[...p,...a],o.push(l)):o.push(...p,...a),M(o)}function _(t,e,n,s,c){let o=L(t),g=h.relative(n,h.join(e,t)),i=o==="index",f=o.startsWith("[..."),l=!f&&o.startsWith("[")&&o.endsWith("]"),u;c?u="":i?u="/":f?u=`*${o.slice(4,-1)}`:l?u=`:${o.slice(1,-1)}`:u=o;let p=c||i?s||"/":F(s,u),a=h.join(e,t),r=!1;try{let d=y.readFileSync(a,"utf-8");r=/export\s+(const|function|async\s+function)\s+routeData\b/.test(d)}catch{}return{filePath:g.replace(/\\/g,"/"),urlSegment:u,urlPath:p,isLayout:c,isIndex:i,isDynamic:l,isCatchAll:f,isGroup:!1,children:[],parentUrlPath:s,hasRouteData:r,rootDir:n,dir:e}}function v(t,e){return e.some(n=>t.endsWith(n))}function L(t){let e=t.lastIndexOf(".");return e>0?t.slice(0,e):t}function V(t){return t.startsWith("(")&&t.endsWith(")")}function G(t){return t.startsWith("[...")&&t.endsWith("]")?"*"+t.slice(4,-1):t.startsWith("[")&&t.endsWith("]")?":"+t.slice(1,-1):t}function F(t,e){return(t.endsWith("/")?t:t+"/")+e}function M(t){return t.sort((e,n)=>e.isLayout&&!n.isLayout?-1:!e.isLayout&&n.isLayout?1:e.isIndex&&!n.isIndex?-1:!e.isIndex&&n.isIndex?1:!e.isDynamic&&!e.isCatchAll&&(n.isDynamic||n.isCatchAll)?-1:(e.isDynamic||e.isCatchAll)&&!n.isDynamic&&!n.isCatchAll?1:e.isDynamic&&n.isCatchAll?-1:e.isCatchAll&&n.isDynamic?1:e.urlSegment.localeCompare(n.urlSegment))}function W(t,e){let n=[];return n.push("// Auto-generated by @fluixi/core route plugin"),n.push("// Do not edit manually"),n.push(""),n.push("import { lazy } from '@fluixi/core/router-next';"),n.push(""),n.push(`export const routes = ${C(t,e,0)};`),n.push(""),n.join(`
2
+ `)}function C(t,e,n){if(t.length===0)return"[]";let s=" ".repeat(n);return`[
3
+ ${t.map(o=>N(o,e,n+1)).join(`,
4
+ `)}
5
+ ${s}]`}function N(t,e,n){let s=" ".repeat(n),c=[],o=J(t.filePath,e),g=k(t);if(c.push(`${s} path: ${JSON.stringify(g)}`),c.push(`${s} component: lazy(() => import(${JSON.stringify(o)}))`),t.hasRouteData&&c.push(`${s} data: (args, __owner, __isCancelled) => import(${JSON.stringify(o)}).then(m => { if (typeof __isCancelled === 'function' && __isCancelled()) return undefined; if (!m.routeData) return undefined; return __owner ? m.routeData(args) : m.routeData(args); })`),t.children.length>0){let i=C(t.children,e,n+1);c.push(`${s} children: ${i}`)}return`${s}{
6
+ ${c.join(`,
7
+ `)}
8
+ ${s}}`}function k(t){return t.urlPath}function J(t,e){return`${e.replace(/\\/g,"/").replace(/\/$/,"")}/${t}`}var E="virtual:fluixi-routes",O="\0"+E,w=`// Auto-generated by @fluixi/core fluixiRoutesPlugin — do not edit manually
9
+ declare module 'virtual:fluixi-routes' {
10
+ import type { RouteDefinition } from '@fluixi/core/router-next';
11
+ export const routes: RouteDefinition[];
12
+ }
13
+ `;function z(t){let e=x.join(t,"src");if(!m.existsSync(e))return;let n=x.join(e,"fluixi-env.d.ts");(m.existsSync(n)?m.readFileSync(n,"utf8"):"")!==w&&m.writeFileSync(n,w,"utf8")}function B(t={}){let e=t.routesDir??"src/routes",n=t.extensions??[".tsx",".ts",".jsx",".js"],s="",o=t.polyfills!==!1?Object.assign({},U({include:["fs","path"]}),{apply:"serve"}):null,g={name:"fluixi-routes",enforce:"pre",configResolved(i){s=i.root||process.cwd(),z(s)},resolveId(i){return i===E?O:null},load(i){if(i!==O)return null;let f=s||process.cwd(),l=x.resolve(f,e),p=A(l,{extensions:n}),a="./"+e;return W(p,a)},configureServer(i){let f=s||process.cwd(),l=x.resolve(f,e);i.watcher.add(l),i.watcher.on("all",(u,p)=>{if(!p.startsWith(l)||!["add","unlink","addDir","unlinkDir"].includes(u)||u!=="addDir"&&u!=="unlinkDir"&&!n.some(r=>p.endsWith(r)))return;let a=i.moduleGraph.getModuleById(O);a&&(i.moduleGraph.invalidateModule(a),i.ws.send({type:"full-reload"}))})}};return o?[o,g]:[g]}export{H as createVitePlugin,q as fluixi,B as fluixiRoutesPlugin};
@@ -0,0 +1,8 @@
1
+ "use strict";var u=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var g=(n,e)=>{for(var t in e)u(n,t,{get:e[t],enumerable:!0})},d=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of p(e))!h.call(n,r)&&r!==t&&u(n,r,{get:()=>e[r],enumerable:!(i=l(e,r))||i.enumerable});return n};var f=n=>d(u({},"__esModule",{value:!0}),n);var S={};g(S,{generateRouteModule:()=>m});module.exports=f(S);function m(n,e){let t=[];return t.push("// Auto-generated by @fluixi/core route plugin"),t.push("// Do not edit manually"),t.push(""),t.push("import { lazy } from '@fluixi/core/router-next';"),t.push(""),t.push(`export const routes = ${s(n,e,0)};`),t.push(""),t.join(`
2
+ `)}function s(n,e,t){if(n.length===0)return"[]";let i=" ".repeat(t);return`[
3
+ ${n.map(o=>$(o,e,t+1)).join(`,
4
+ `)}
5
+ ${i}]`}function $(n,e,t){let i=" ".repeat(t),r=[],o=y(n.filePath,e),a=R(n);if(r.push(`${i} path: ${JSON.stringify(a)}`),r.push(`${i} component: lazy(() => import(${JSON.stringify(o)}))`),n.hasRouteData&&r.push(`${i} data: (args, __owner, __isCancelled) => import(${JSON.stringify(o)}).then(m => { if (typeof __isCancelled === 'function' && __isCancelled()) return undefined; if (!m.routeData) return undefined; return __owner ? m.routeData(args) : m.routeData(args); })`),n.children.length>0){let c=s(n.children,e,t+1);r.push(`${i} children: ${c}`)}return`${i}{
6
+ ${r.join(`,
7
+ `)}
8
+ ${i}}`}function R(n){return n.urlPath}function y(n,e){return`${e.replace(/\\/g,"/").replace(/\/$/,"")}/${n}`}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Route code generator
3
+ * @module @fluixi/core/plugins/route-codegen
4
+ *
5
+ * Generates an ES module from a ScannedRoute tree.
6
+ * Uses lazy() for code-split component loading with Suspense integration.
7
+ */
8
+ import type { ScannedRoute } from './route-scanner.js';
9
+ /**
10
+ * Generate a virtual ES module string from a scanned route tree.
11
+ */
12
+ export declare function generateRouteModule(routes: ScannedRoute[], routesDir: string): string;
13
+ //# sourceMappingURL=route-codegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-codegen.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/route-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAevD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EAAE,EACtB,SAAS,EAAE,MAAM,GAChB,MAAM,CAeR"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @fileoverview Route code generator
3
+ * @module @fluixi/core/plugins/route-codegen
4
+ *
5
+ * Generates an ES module from a ScannedRoute tree.
6
+ * Uses lazy() for code-split component loading with Suspense integration.
7
+ */
8
+ /**
9
+ * Collect all routes into a flat list for import generation.
10
+ */
11
+ function collectRoutes(routes, out = []) {
12
+ for (const route of routes) {
13
+ out.push(route);
14
+ if (route.children.length > 0) {
15
+ collectRoutes(route.children, out);
16
+ }
17
+ }
18
+ return out;
19
+ }
20
+ /**
21
+ * Generate a virtual ES module string from a scanned route tree.
22
+ */
23
+ export function generateRouteModule(routes, routesDir) {
24
+ const lines = [];
25
+ lines.push(`// Auto-generated by @fluixi/core route plugin`);
26
+ lines.push(`// Do not edit manually`);
27
+ lines.push(``);
28
+ // router-next is lit-free; the old './router' barrel imported @fluixi/lit (extends
29
+ // HTMLElement at module init) which crashed SSR/prod server bundles. (runWithOwner was
30
+ // imported here but never used in the generated output — dropped.)
31
+ lines.push(`import { lazy } from '@fluixi/core/router-next';`);
32
+ lines.push(``);
33
+ lines.push(`export const routes = ${generateRouteArray(routes, routesDir, 0)};`);
34
+ lines.push(``);
35
+ return lines.join('\n');
36
+ }
37
+ function generateRouteArray(routes, routesDir, depth) {
38
+ if (routes.length === 0)
39
+ return '[]';
40
+ const indent = ' '.repeat(depth);
41
+ const items = routes.map((route) => generateRouteObject(route, routesDir, depth + 1));
42
+ return `[\n${items.join(',\n')}\n${indent}]`;
43
+ }
44
+ function generateRouteObject(route, routesDir, depth) {
45
+ const indent = ' '.repeat(depth);
46
+ const props = [];
47
+ const importPath = buildImportPath(route.filePath, routesDir);
48
+ // Path
49
+ const routePath = computeRoutePath(route);
50
+ props.push(`${indent} path: ${JSON.stringify(routePath)}`);
51
+ // Component — lazy-loaded via dynamic import + Suspense
52
+ props.push(`${indent} component: lazy(() => import(${JSON.stringify(importPath)}))`);
53
+ // Data loader — only generated for routes that export `routeData`
54
+ // This prevents unnecessary async imports and avoids calling d.data() for
55
+ // levels that have no data, which kept the router's if (d.data) check clean.
56
+ if (route.hasRouteData) {
57
+ props.push(`${indent} data: (args, __owner, __isCancelled) => import(${JSON.stringify(importPath)}).then(m => { if (typeof __isCancelled === 'function' && __isCancelled()) return undefined; if (!m.routeData) return undefined; return __owner ? m.routeData(args) : m.routeData(args); })`);
58
+ // props.push(`${indent} data: (args) => import(${JSON.stringify(importPath)}).then(m => m.routeData ? m.routeData(args) : undefined)`);
59
+ }
60
+ // Children
61
+ if (route.children.length > 0) {
62
+ const childArray = generateRouteArray(route.children, routesDir, depth + 1);
63
+ props.push(`${indent} children: ${childArray}`);
64
+ }
65
+ return `${indent}{\n${props.join(',\n')}\n${indent}}`;
66
+ }
67
+ /**
68
+ * Compute the route path for a RouteDefinition.
69
+ * The scanner already resolves groups, dynamic segments, and index paths
70
+ * into the correct urlPath — just use it directly.
71
+ */
72
+ function computeRoutePath(route) {
73
+ return route.urlPath;
74
+ }
75
+ /**
76
+ * Build the import path for a route file.
77
+ */
78
+ function buildImportPath(filePath, routesDir) {
79
+ const base = routesDir.replace(/\\/g, '/').replace(/\/$/, '');
80
+ return `${base}/${filePath}`;
81
+ }
@@ -0,0 +1,8 @@
1
+ function h(t,e){let n=[];return n.push("// Auto-generated by @fluixi/core route plugin"),n.push("// Do not edit manually"),n.push(""),n.push("import { lazy } from '@fluixi/core/router-next';"),n.push(""),n.push(`export const routes = ${u(t,e,0)};`),n.push(""),n.join(`
2
+ `)}function u(t,e,n){if(t.length===0)return"[]";let r=" ".repeat(n);return`[
3
+ ${t.map(o=>c(o,e,n+1)).join(`,
4
+ `)}
5
+ ${r}]`}function c(t,e,n){let r=" ".repeat(n),i=[],o=p(t.filePath,e),s=l(t);if(i.push(`${r} path: ${JSON.stringify(s)}`),i.push(`${r} component: lazy(() => import(${JSON.stringify(o)}))`),t.hasRouteData&&i.push(`${r} data: (args, __owner, __isCancelled) => import(${JSON.stringify(o)}).then(m => { if (typeof __isCancelled === 'function' && __isCancelled()) return undefined; if (!m.routeData) return undefined; return __owner ? m.routeData(args) : m.routeData(args); })`),t.children.length>0){let a=u(t.children,e,n+1);i.push(`${r} children: ${a}`)}return`${r}{
6
+ ${i.join(`,
7
+ `)}
8
+ ${r}}`}function l(t){return t.urlPath}function p(t,e){return`${e.replace(/\\/g,"/").replace(/\/$/,"")}/${t}`}export{h as generateRouteModule};
@@ -0,0 +1 @@
1
+ "use strict";var P=Object.create;var S=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty;var $=(t,n)=>{for(var s in n)S(t,s,{get:n[s],enumerable:!0})},L=(t,n,s,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of O(n))!v.call(t,o)&&o!==s&&S(t,o,{get:()=>n[o],enumerable:!(i=G(n,o))||i.enumerable});return t};var b=(t,n,s)=>(s=t!=null?P(T(t)):{},L(n||!t||!t.__esModule?S(s,"default",{value:t,enumerable:!0}):s,t)),w=t=>L(S({},"__esModule",{value:!0}),t);var z={};$(z,{scanRoutes:()=>V});module.exports=w(z);var g=b(require("fs"),1),u=b(require("path"),1),N=[".tsx",".ts",".jsx",".js"];function V(t,n={}){let s=n.extensions??N,i=u.resolve(t);return g.existsSync(i)?F(i,i,"",s):[]}function F(t,n,s,i){let o=g.readdirSync(t,{withFileTypes:!0}),r=[],W=null,h=[],d=[];for(let e of o)e.isDirectory()?d.push(e):e.isFile()&&X(e.name,i)&&h.push(e);let l,c=[];for(let e of h)j(e.name)==="layout"?l=I(e.name,t,n,s,!0):c.push(e);let y=[];for(let e of c)y.push(I(e.name,t,n,s,!1));let f=[];for(let e of d){let a=e.name,A=_(a),C=A?"":k(a),R=C?E(s,C):s,x=F(u.join(t,a),n,R,i);if(A)f.push(...x);else{let m=x.find(p=>p.isLayout&&p.urlPath===R),D=x.filter(p=>!p.isLayout||p.urlPath!==R);m?(m.children=[...m.children,...D],f.push(m)):D.length>0&&f.push(...D)}}return l?(l.children=[...y,...f],r.push(l)):r.push(...y,...f),q(r)}function I(t,n,s,i,o){let r=j(t),W=u.relative(s,u.join(n,t)),h=r==="index",d=r.startsWith("[..."),l=!d&&r.startsWith("[")&&r.endsWith("]"),c;o?c="":h?c="/":d?c=`*${r.slice(4,-1)}`:l?c=`:${r.slice(1,-1)}`:c=r;let y=o||h?i||"/":E(i,c),f=u.join(n,t),e=!1;try{let a=g.readFileSync(f,"utf-8");e=/export\s+(const|function|async\s+function)\s+routeData\b/.test(a)}catch{}return{filePath:W.replace(/\\/g,"/"),urlSegment:c,urlPath:y,isLayout:o,isIndex:h,isDynamic:l,isCatchAll:d,isGroup:!1,children:[],parentUrlPath:i,hasRouteData:e,rootDir:s,dir:n}}function X(t,n){return n.some(s=>t.endsWith(s))}function j(t){let n=t.lastIndexOf(".");return n>0?t.slice(0,n):t}function _(t){return t.startsWith("(")&&t.endsWith(")")}function k(t){return t.startsWith("[...")&&t.endsWith("]")?"*"+t.slice(4,-1):t.startsWith("[")&&t.endsWith("]")?":"+t.slice(1,-1):t}function E(t,n){return(t.endsWith("/")?t:t+"/")+n}function q(t){return t.sort((n,s)=>n.isLayout&&!s.isLayout?-1:!n.isLayout&&s.isLayout?1:n.isIndex&&!s.isIndex?-1:!n.isIndex&&s.isIndex?1:!n.isDynamic&&!n.isCatchAll&&(s.isDynamic||s.isCatchAll)?-1:(n.isDynamic||n.isCatchAll)&&!s.isDynamic&&!s.isCatchAll?1:n.isDynamic&&s.isCatchAll?-1:n.isCatchAll&&s.isDynamic?1:n.urlSegment.localeCompare(s.urlSegment))}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview File-system route scanner
3
+ * @module @fluixi/core/plugins/route-scanner
4
+ *
5
+ * Scans a routes directory and builds a route tree following SolidStart conventions.
6
+ * Pure utility — no bundler dependency.
7
+ */
8
+ export interface ScannedRoute {
9
+ /** Relative file path from routes dir: 'users/[id].tsx' */
10
+ filePath: string;
11
+ /** URL segment for this route: ':id', 'about', '' (index) */
12
+ urlSegment: string;
13
+ /** Full URL path: '/users/:id' */
14
+ urlPath: string;
15
+ /** Whether this is a layout file (layout.tsx) */
16
+ isLayout: boolean;
17
+ /** Whether this is an index file (index.tsx) */
18
+ isIndex: boolean;
19
+ /** Whether this has dynamic params ([id]) */
20
+ isDynamic: boolean;
21
+ /** Whether this is a catch-all ([...rest]) */
22
+ isCatchAll: boolean;
23
+ /** Whether the parent directory is a route group ((name)) */
24
+ isGroup: boolean;
25
+ /** Nested child routes */
26
+ children: ScannedRoute[];
27
+ parentUrlPath: string;
28
+ /** Whether this route file exports a `routeData` function */
29
+ hasRouteData: boolean;
30
+ }
31
+ export interface ScanOptions {
32
+ /** File extensions to include */
33
+ extensions?: string[];
34
+ }
35
+ /**
36
+ * Scan a routes directory and return a tree of ScannedRoute nodes.
37
+ */
38
+ export declare function scanRoutes(routesDir: string, options?: ScanOptions): ScannedRoute[];
39
+ //# sourceMappingURL=route-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-scanner.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/route-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,UAAU,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAC;IACjB,0BAA0B;IAC1B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAQD;;GAEG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,WAAgB,GACxB,YAAY,EAAE,CAShB"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @fileoverview File-system route scanner
3
+ * @module @fluixi/core/plugins/route-scanner
4
+ *
5
+ * Scans a routes directory and builds a route tree following SolidStart conventions.
6
+ * Pure utility — no bundler dependency.
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ const DEFAULT_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js'];
11
+ // ============================================================================
12
+ // SCANNING
13
+ // ============================================================================
14
+ /**
15
+ * Scan a routes directory and return a tree of ScannedRoute nodes.
16
+ */
17
+ export function scanRoutes(routesDir, options = {}) {
18
+ const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
19
+ const absDir = path.resolve(routesDir);
20
+ if (!fs.existsSync(absDir)) {
21
+ return [];
22
+ }
23
+ return scanDirectory(absDir, absDir, '', extensions);
24
+ }
25
+ function scanDirectory(dir, rootDir, parentUrlPath, extensions) {
26
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
27
+ const routes = [];
28
+ const layoutRoute = null;
29
+ // Separate files and directories
30
+ const files = [];
31
+ const dirs = [];
32
+ for (const entry of entries) {
33
+ if (entry.isDirectory()) {
34
+ dirs.push(entry);
35
+ }
36
+ else if (entry.isFile() && hasValidExtension(entry.name, extensions)) {
37
+ files.push(entry);
38
+ }
39
+ }
40
+ // Find layout file first
41
+ let layout;
42
+ const nonLayoutFiles = [];
43
+ for (const file of files) {
44
+ const baseName = stripExtension(file.name);
45
+ if (baseName === 'layout') {
46
+ layout = buildFileRoute(file.name, dir, rootDir, parentUrlPath, true);
47
+ }
48
+ else {
49
+ nonLayoutFiles.push(file);
50
+ }
51
+ }
52
+ // Build routes for non-layout files
53
+ const fileRoutes = [];
54
+ for (const file of nonLayoutFiles) {
55
+ fileRoutes.push(buildFileRoute(file.name, dir, rootDir, parentUrlPath, false));
56
+ }
57
+ // Build routes for subdirectories
58
+ const dirRoutes = [];
59
+ for (const d of dirs) {
60
+ const dirName = d.name;
61
+ const isGroup = isRouteGroup(dirName);
62
+ const segment = isGroup ? '' : dirNameToSegment(dirName);
63
+ const childUrlPath = segment
64
+ ? joinUrlPath(parentUrlPath, segment)
65
+ : parentUrlPath;
66
+ const children = scanDirectory(path.join(dir, dirName), rootDir, childUrlPath, extensions);
67
+ if (isGroup) {
68
+ // Route groups: children are flattened to parent level
69
+ dirRoutes.push(...children);
70
+ }
71
+ else {
72
+ // Regular directory: becomes a nested route
73
+ // If there's a DIRECT layout in the children (urlPath matches this dir's path),
74
+ // it becomes the parent route. We must NOT pick up layouts from deeper descendants
75
+ // (e.g. campaigns/[id]/workspace/layout.tsx must not be the layout for campaigns/).
76
+ const childLayout = children.find((c) => c.isLayout && c.urlPath === childUrlPath);
77
+ const childNonLayout = children.filter((c) => !c.isLayout || c.urlPath !== childUrlPath);
78
+ if (childLayout) {
79
+ // Preserve children from recursive scan, add any non-layout siblings
80
+ childLayout.children = [...childLayout.children, ...childNonLayout];
81
+ dirRoutes.push(childLayout);
82
+ }
83
+ else if (childNonLayout.length > 0) {
84
+ // No layout — just add children with their full paths
85
+ dirRoutes.push(...childNonLayout);
86
+ }
87
+ }
88
+ }
89
+ // Combine: if there's a layout at this level, nest everything under it
90
+ if (layout) {
91
+ layout.children = [...fileRoutes, ...dirRoutes];
92
+ routes.push(layout);
93
+ }
94
+ else {
95
+ routes.push(...fileRoutes, ...dirRoutes);
96
+ }
97
+ // Sort: static routes first, then dynamic, then catch-all
98
+ return sortRoutes(routes);
99
+ }
100
+ // ============================================================================
101
+ // ROUTE BUILDING
102
+ // ============================================================================
103
+ function buildFileRoute(fileName, dir, rootDir, parentUrlPath, isLayout) {
104
+ const baseName = stripExtension(fileName);
105
+ const filePath = path.relative(rootDir, path.join(dir, fileName));
106
+ const isIndex = baseName === 'index';
107
+ const isCatchAll = baseName.startsWith('[...');
108
+ const isDynamic = !isCatchAll && baseName.startsWith('[') && baseName.endsWith(']');
109
+ let urlSegment;
110
+ if (isLayout) {
111
+ urlSegment = '';
112
+ }
113
+ else if (isIndex) {
114
+ urlSegment = '/';
115
+ }
116
+ else if (isCatchAll) {
117
+ // [...rest] → *rest
118
+ const paramName = baseName.slice(4, -1); // remove '[...' and ']'
119
+ urlSegment = `*${paramName}`;
120
+ }
121
+ else if (isDynamic) {
122
+ // [id] → :id
123
+ const paramName = baseName.slice(1, -1); // remove '[' and ']'
124
+ urlSegment = `:${paramName}`;
125
+ }
126
+ else {
127
+ urlSegment = baseName;
128
+ }
129
+ const urlPath = isLayout
130
+ ? parentUrlPath || '/'
131
+ : isIndex
132
+ ? parentUrlPath || '/'
133
+ : joinUrlPath(parentUrlPath, urlSegment);
134
+ // Detect if the file exports a `routeData` function (static analysis at scan time)
135
+ const absoluteFilePath = path.join(dir, fileName);
136
+ let hasRouteData = false;
137
+ try {
138
+ const content = fs.readFileSync(absoluteFilePath, 'utf-8');
139
+ hasRouteData = /export\s+(const|function|async\s+function)\s+routeData\b/.test(content);
140
+ }
141
+ catch {
142
+ // If file can't be read, assume no routeData
143
+ }
144
+ return {
145
+ filePath: filePath.replace(/\\/g, '/'), // normalize to forward slashes
146
+ urlSegment,
147
+ urlPath,
148
+ isLayout,
149
+ isIndex,
150
+ isDynamic,
151
+ isCatchAll,
152
+ isGroup: false,
153
+ children: [],
154
+ parentUrlPath,
155
+ hasRouteData,
156
+ rootDir,
157
+ dir
158
+ };
159
+ }
160
+ // ============================================================================
161
+ // UTILITIES
162
+ // ============================================================================
163
+ function hasValidExtension(fileName, extensions) {
164
+ return extensions.some((ext) => fileName.endsWith(ext));
165
+ }
166
+ function stripExtension(fileName) {
167
+ const lastDot = fileName.lastIndexOf('.');
168
+ return lastDot > 0 ? fileName.slice(0, lastDot) : fileName;
169
+ }
170
+ function isRouteGroup(dirName) {
171
+ return dirName.startsWith('(') && dirName.endsWith(')');
172
+ }
173
+ /** Convert a directory name to its URL segment, matching the same rules as file names. */
174
+ function dirNameToSegment(dirName) {
175
+ if (dirName.startsWith('[...') && dirName.endsWith(']')) {
176
+ return '*' + dirName.slice(4, -1); // [...rest] → *rest
177
+ }
178
+ if (dirName.startsWith('[') && dirName.endsWith(']')) {
179
+ return ':' + dirName.slice(1, -1); // [id] → :id
180
+ }
181
+ return dirName;
182
+ }
183
+ function joinUrlPath(parent, segment) {
184
+ const base = parent.endsWith('/') ? parent : parent + '/';
185
+ return base + segment;
186
+ }
187
+ /**
188
+ * Sort routes by specificity: static > dynamic > catch-all.
189
+ * Index routes come before non-index at the same level.
190
+ */
191
+ function sortRoutes(routes) {
192
+ return routes.sort((a, b) => {
193
+ // Layouts first (they wrap children)
194
+ if (a.isLayout && !b.isLayout)
195
+ return -1;
196
+ if (!a.isLayout && b.isLayout)
197
+ return 1;
198
+ // Index routes before others
199
+ if (a.isIndex && !b.isIndex)
200
+ return -1;
201
+ if (!a.isIndex && b.isIndex)
202
+ return 1;
203
+ // Static before dynamic
204
+ if (!a.isDynamic && !a.isCatchAll && (b.isDynamic || b.isCatchAll))
205
+ return -1;
206
+ if ((a.isDynamic || a.isCatchAll) && !b.isDynamic && !b.isCatchAll)
207
+ return 1;
208
+ // Dynamic before catch-all
209
+ if (a.isDynamic && b.isCatchAll)
210
+ return -1;
211
+ if (a.isCatchAll && b.isDynamic)
212
+ return 1;
213
+ // Alphabetical fallback
214
+ return a.urlSegment.localeCompare(b.urlSegment);
215
+ });
216
+ }
@@ -0,0 +1 @@
1
+ import*as d from"fs";import*as a from"path";var F=[".tsx",".ts",".jsx",".js"];function O(t,n={}){let s=n.extensions??F,i=a.resolve(t);return d.existsSync(i)?L(i,i,"",s):[]}function L(t,n,s,i){let g=d.readdirSync(t,{withFileTypes:!0}),o=[],D=null,f=[],h=[];for(let e of g)e.isDirectory()?h.push(e):e.isFile()&&j(e.name,i)&&f.push(e);let u,r=[];for(let e of f)b(e.name)==="layout"?u=C(e.name,t,n,s,!0):r.push(e);let y=[];for(let e of r)y.push(C(e.name,t,n,s,!1));let l=[];for(let e of h){let c=e.name,W=E(c),A=W?"":P(c),S=A?I(s,A):s,R=L(a.join(t,c),n,S,i);if(W)l.push(...R);else{let m=R.find(p=>p.isLayout&&p.urlPath===S),x=R.filter(p=>!p.isLayout||p.urlPath!==S);m?(m.children=[...m.children,...x],l.push(m)):x.length>0&&l.push(...x)}}return u?(u.children=[...y,...l],o.push(u)):o.push(...y,...l),G(o)}function C(t,n,s,i,g){let o=b(t),D=a.relative(s,a.join(n,t)),f=o==="index",h=o.startsWith("[..."),u=!h&&o.startsWith("[")&&o.endsWith("]"),r;g?r="":f?r="/":h?r=`*${o.slice(4,-1)}`:u?r=`:${o.slice(1,-1)}`:r=o;let y=g||f?i||"/":I(i,r),l=a.join(n,t),e=!1;try{let c=d.readFileSync(l,"utf-8");e=/export\s+(const|function|async\s+function)\s+routeData\b/.test(c)}catch{}return{filePath:D.replace(/\\/g,"/"),urlSegment:r,urlPath:y,isLayout:g,isIndex:f,isDynamic:u,isCatchAll:h,isGroup:!1,children:[],parentUrlPath:i,hasRouteData:e,rootDir:s,dir:n}}function j(t,n){return n.some(s=>t.endsWith(s))}function b(t){let n=t.lastIndexOf(".");return n>0?t.slice(0,n):t}function E(t){return t.startsWith("(")&&t.endsWith(")")}function P(t){return t.startsWith("[...")&&t.endsWith("]")?"*"+t.slice(4,-1):t.startsWith("[")&&t.endsWith("]")?":"+t.slice(1,-1):t}function I(t,n){return(t.endsWith("/")?t:t+"/")+n}function G(t){return t.sort((n,s)=>n.isLayout&&!s.isLayout?-1:!n.isLayout&&s.isLayout?1:n.isIndex&&!s.isIndex?-1:!n.isIndex&&s.isIndex?1:!n.isDynamic&&!n.isCatchAll&&(s.isDynamic||s.isCatchAll)?-1:(n.isDynamic||n.isCatchAll)&&!s.isDynamic&&!s.isCatchAll?1:n.isDynamic&&s.isCatchAll?-1:n.isCatchAll&&s.isDynamic?1:n.urlSegment.localeCompare(s.urlSegment))}export{O as scanRoutes};
@@ -0,0 +1 @@
1
+ "use strict";var p=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var n=(e,i)=>{for(var l in i)p(e,l,{get:i[l],enumerable:!0})},g=(e,i,l,r)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of x(i))!f.call(e,t)&&t!==l&&p(e,t,{get:()=>i[t],enumerable:!(r=u(i,t))||r.enumerable});return e};var m=e=>g(p({},"__esModule",{value:!0}),e);var V={};n(V,{createVitePlugin:()=>o.createVitePlugin,fluixi:()=>o.fluixi});module.exports=m(V);var o=require("@fluixi/vite-plugin");
@@ -0,0 +1,3 @@
1
+ export { fluixi, createVitePlugin } from '@fluixi/vite-plugin';
2
+ export type { FluixiViteOptions } from '@fluixi/vite-plugin';
3
+ //# sourceMappingURL=vite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export { fluixi, createVitePlugin } from '@fluixi/vite-plugin';
@@ -0,0 +1 @@
1
+ import{fluixi as t,createVitePlugin as l}from"@fluixi/vite-plugin";export{l as createVitePlugin,t as fluixi};
@@ -0,0 +1 @@
1
+ "use strict";var f=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var E=(e,o)=>{for(var n in o)f(e,n,{get:o[n],enumerable:!0})},O=(e,o,n,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let c of C(o))!T.call(e,c)&&c!==n&&f(e,c,{get:()=>o[c],enumerable:!(r=m(o,c))||r.enumerable});return e};var w=e=>O(f({},"__esModule",{value:!0}),e);var K={};E(K,{$component:()=>v,DEV:()=>a,batch:()=>t.batch,createComponent:()=>d,createEffect:()=>t.createEffect,createMemo:()=>t.createMemo,devOnly:()=>W,ensureIntegration:()=>L,getContextOwner:()=>b,getOwner:()=>t.getOwner,getSharedConfig:()=>h,hasLifecycleContext:()=>D,isDev:()=>_,onCleanup:()=>t.onCleanup,onMount:()=>R,onUnmount:()=>S,runWithOwner:()=>t.runWithOwner,setOwner:()=>g,useCallback:()=>k,useEffect:()=>y,useEventListener:()=>j,useMemo:()=>A,useReducer:()=>U,useRef:()=>M});module.exports=w(K);var u=require("@fluixi/dom"),t=require("@fluixi/reactive/signal"),i={context:null,owner:null};function h(){return i}function g(e){i.owner=e,i.context=e}function b(){return i.context||i.owner}var a=typeof process<"u"&&!1,s=Symbol.for("fluixi-lifecycle");function p(){let e=(0,t.getOwner)();if(!e)return null;if(!e[s]){let o={mounts:[],effects:[],scheduled:!1};e[s]=o}return e[s]}function l(e){if(e.scheduled)return;e.scheduled=!0;let o=(0,t.getOwner)();queueMicrotask(()=>{(0,t.runWithOwner)(o,()=>{for(let n of e.mounts)try{let r=n();typeof r=="function"&&(0,t.onCleanup)(r)}catch(r){console.error("Error in onMount callback:",r)}for(let n of e.effects){let r;(0,t.createEffect)(()=>{r&&r(),r=n()}),(0,t.onCleanup)(()=>{r&&r()})}e.mounts=[],e.effects=[]})})}function L(e){(0,u.registerCreateComponent)(d)}function d(e,o){return v(e,o)}function v(e,o){let n=typeof e=="function"?(0,t.untrack)(()=>e(o)):e;if(n!=null&&(typeof n=="function"||typeof n=="object")&&!(0,t.isSignal)(n)){try{n.$name=e.name}catch{}return(0,u.asComponent)(n)}return n}function R(e,o=!0){let n=p();if(n){if(!o){n.scheduled||e();return}n.mounts.push(e),l(n)}else{if(!o){e();return}(0,t.createEffect)(()=>{let r=(0,t.untrack)(e);typeof r=="function"&&(0,t.onCleanup)(r)})}}function S(e){(0,t.onCleanup)(e)}function y(e){let o=p();if(o)o.effects.push(e),l(o);else{let n;(0,t.createEffect)(()=>{n&&n(),n=e()}),(0,t.onCleanup)(()=>{n&&n()})}}function A(e){return(0,t.createMemo)(e)}function M(e){let o={current:e};return(0,t.onCleanup)(()=>{o.current=null}),o}function U(e,o){let[n,r]=(0,t.createSignal)(o);return[n,x=>{r(e(n(),x))}]}function j(e,o,n,r){y(()=>{let c=e&&"current"in e?e.current:e;if(c)return c.addEventListener(o,n,r),()=>{c.removeEventListener(o,n,r)}})}function k(e){return e}function D(){return(0,t.getOwner)()!==null}function _(){return a}function W(e){a&&e()}