@fluixi/core 1.0.0-alpha.100

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 (253) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +334 -0
  3. package/dist/cdn/core.global.js +2 -0
  4. package/dist/cli/generate.cjs +5639 -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 +5644 -0
  9. package/dist/cli/index.cjs +5639 -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 +5644 -0
  14. package/dist/cli/run.cjs +64 -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 +40 -0
  19. package/dist/fluixi.d.ts +5 -0
  20. package/dist/src/cdn/chunk-RKBFEFZP.mjs +987 -0
  21. package/dist/src/cdn/core.cjs +1592 -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 +714 -0
  26. package/dist/src/cdn/router-V2THK27H.mjs +74 -0
  27. package/dist/src/index.cjs +1711 -0
  28. package/dist/src/index.d.ts +4 -0
  29. package/dist/src/index.d.ts.map +1 -0
  30. package/dist/src/index.js +11 -0
  31. package/dist/src/index.mjs +1833 -0
  32. package/dist/src/jsx-dev-runtime.cjs +26 -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 +24 -0
  37. package/dist/src/jsx-runtime.cjs +26 -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 +8 -0
  41. package/dist/src/jsx-runtime.mjs +24 -0
  42. package/dist/src/lib/client/chunk-FDOPDB6Z.mjs +53 -0
  43. package/dist/src/lib/client/index.cjs +1210 -0
  44. package/dist/src/lib/client/index.d.ts +51 -0
  45. package/dist/src/lib/client/index.d.ts.map +1 -0
  46. package/dist/src/lib/client/index.js +174 -0
  47. package/dist/src/lib/client/index.mjs +293 -0
  48. package/dist/src/lib/client/router-4PTBPZLQ.mjs +891 -0
  49. package/dist/src/lib/context/context.cjs +81 -0
  50. package/dist/src/lib/context/context.d.ts +73 -0
  51. package/dist/src/lib/context/context.d.ts.map +1 -0
  52. package/dist/src/lib/context/context.js +93 -0
  53. package/dist/src/lib/context/context.mjs +64 -0
  54. package/dist/src/lib/context/index.cjs +83 -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 +1 -0
  58. package/dist/src/lib/context/index.mjs +64 -0
  59. package/dist/src/lib/control-flow.cjs +35 -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 +25 -0
  64. package/dist/src/lib/core.cjs +1710 -0
  65. package/dist/src/lib/core.d.ts +91 -0
  66. package/dist/src/lib/core.d.ts.map +1 -0
  67. package/dist/src/lib/core.js +158 -0
  68. package/dist/src/lib/core.mjs +1833 -0
  69. package/dist/src/lib/env/index.cjs +44 -0
  70. package/dist/src/lib/env/index.d.ts +26 -0
  71. package/dist/src/lib/env/index.d.ts.map +1 -0
  72. package/dist/src/lib/env/index.js +31 -0
  73. package/dist/src/lib/env/index.mjs +23 -0
  74. package/dist/src/lib/i18n/index.cjs +123 -0
  75. package/dist/src/lib/i18n/index.d.ts +110 -0
  76. package/dist/src/lib/i18n/index.d.ts.map +1 -0
  77. package/dist/src/lib/i18n/index.js +164 -0
  78. package/dist/src/lib/i18n/index.mjs +103 -0
  79. package/dist/src/lib/index.cjs +598 -0
  80. package/dist/src/lib/index.d.ts +81 -0
  81. package/dist/src/lib/index.d.ts.map +1 -0
  82. package/dist/src/lib/index.js +130 -0
  83. package/dist/src/lib/index.mjs +688 -0
  84. package/dist/src/lib/isomorphic.cjs +90 -0
  85. package/dist/src/lib/isomorphic.d.ts +114 -0
  86. package/dist/src/lib/isomorphic.d.ts.map +1 -0
  87. package/dist/src/lib/isomorphic.js +132 -0
  88. package/dist/src/lib/isomorphic.mjs +69 -0
  89. package/dist/src/lib/jsx-runtime/index.cjs +21 -0
  90. package/dist/src/lib/jsx-runtime/index.d.ts +13 -0
  91. package/dist/src/lib/jsx-runtime/index.d.ts.map +1 -0
  92. package/dist/src/lib/jsx-runtime/index.js +13 -0
  93. package/dist/src/lib/jsx-runtime/index.mjs +4 -0
  94. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +21 -0
  95. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts +2 -0
  96. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts.map +1 -0
  97. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.js +1 -0
  98. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +4 -0
  99. package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +302 -0
  100. package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +35 -0
  101. package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -0
  102. package/dist/src/lib/plugins/fluixi-routes-plugin.js +118 -0
  103. package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +271 -0
  104. package/dist/src/lib/plugins/index.cjs +311 -0
  105. package/dist/src/lib/plugins/index.d.ts +6 -0
  106. package/dist/src/lib/plugins/index.d.ts.map +1 -0
  107. package/dist/src/lib/plugins/index.js +7 -0
  108. package/dist/src/lib/plugins/index.mjs +279 -0
  109. package/dist/src/lib/plugins/route-codegen.cjs +73 -0
  110. package/dist/src/lib/plugins/route-codegen.d.ts +12 -0
  111. package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -0
  112. package/dist/src/lib/plugins/route-codegen.js +80 -0
  113. package/dist/src/lib/plugins/route-codegen.mjs +52 -0
  114. package/dist/src/lib/plugins/route-scanner.cjs +189 -0
  115. package/dist/src/lib/plugins/route-scanner.d.ts +38 -0
  116. package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -0
  117. package/dist/src/lib/plugins/route-scanner.js +215 -0
  118. package/dist/src/lib/plugins/route-scanner.mjs +158 -0
  119. package/dist/src/lib/plugins/vite.cjs +27 -0
  120. package/dist/src/lib/plugins/vite.d.ts +3 -0
  121. package/dist/src/lib/plugins/vite.d.ts.map +1 -0
  122. package/dist/src/lib/plugins/vite.js +1 -0
  123. package/dist/src/lib/plugins/vite.mjs +6 -0
  124. package/dist/src/lib/render/await.cjs +38 -0
  125. package/dist/src/lib/render/await.d.ts +26 -0
  126. package/dist/src/lib/render/await.d.ts.map +1 -0
  127. package/dist/src/lib/render/await.js +45 -0
  128. package/dist/src/lib/render/await.mjs +17 -0
  129. package/dist/src/lib/render/component.cjs +221 -0
  130. package/dist/src/lib/render/component.d.ts +296 -0
  131. package/dist/src/lib/render/component.d.ts.map +1 -0
  132. package/dist/src/lib/render/component.js +514 -0
  133. package/dist/src/lib/render/component.mjs +214 -0
  134. package/dist/src/lib/render/deferred.cjs +175 -0
  135. package/dist/src/lib/render/deferred.d.ts +36 -0
  136. package/dist/src/lib/render/deferred.d.ts.map +1 -0
  137. package/dist/src/lib/render/deferred.js +141 -0
  138. package/dist/src/lib/render/deferred.mjs +158 -0
  139. package/dist/src/lib/render/index.cjs +573 -0
  140. package/dist/src/lib/render/index.d.ts +98 -0
  141. package/dist/src/lib/render/index.d.ts.map +1 -0
  142. package/dist/src/lib/render/index.js +180 -0
  143. package/dist/src/lib/render/index.mjs +590 -0
  144. package/dist/src/lib/render/lazy.cjs +67 -0
  145. package/dist/src/lib/render/lazy.d.ts +49 -0
  146. package/dist/src/lib/render/lazy.d.ts.map +1 -0
  147. package/dist/src/lib/render/lazy.js +105 -0
  148. package/dist/src/lib/render/lazy.mjs +50 -0
  149. package/dist/src/lib/render/suspense.cjs +141 -0
  150. package/dist/src/lib/render/suspense.d.ts +65 -0
  151. package/dist/src/lib/render/suspense.d.ts.map +1 -0
  152. package/dist/src/lib/render/suspense.js +196 -0
  153. package/dist/src/lib/render/suspense.mjs +136 -0
  154. package/dist/src/lib/render/versions.cjs +35 -0
  155. package/dist/src/lib/render/versions.d.ts +2 -0
  156. package/dist/src/lib/render/versions.d.ts.map +1 -0
  157. package/dist/src/lib/render/versions.js +21 -0
  158. package/dist/src/lib/render/versions.mjs +14 -0
  159. package/dist/src/lib/router/data.cjs +228 -0
  160. package/dist/src/lib/router/data.d.ts +142 -0
  161. package/dist/src/lib/router/data.d.ts.map +1 -0
  162. package/dist/src/lib/router/data.js +258 -0
  163. package/dist/src/lib/router/data.mjs +214 -0
  164. package/dist/src/lib/router/index.cjs +921 -0
  165. package/dist/src/lib/router/index.d.ts +274 -0
  166. package/dist/src/lib/router/index.d.ts.map +1 -0
  167. package/dist/src/lib/router/index.js +904 -0
  168. package/dist/src/lib/router/index.mjs +938 -0
  169. package/dist/src/lib/router/scroll.cjs +79 -0
  170. package/dist/src/lib/router/scroll.d.ts +19 -0
  171. package/dist/src/lib/router/scroll.d.ts.map +1 -0
  172. package/dist/src/lib/router/scroll.js +68 -0
  173. package/dist/src/lib/router/scroll.mjs +58 -0
  174. package/dist/src/lib/router/transition.cjs +75 -0
  175. package/dist/src/lib/router/transition.d.ts +81 -0
  176. package/dist/src/lib/router/transition.d.ts.map +1 -0
  177. package/dist/src/lib/router/transition.js +136 -0
  178. package/dist/src/lib/router/transition.mjs +54 -0
  179. package/dist/src/lib/server/hydration.cjs +169 -0
  180. package/dist/src/lib/server/hydration.d.ts +198 -0
  181. package/dist/src/lib/server/hydration.d.ts.map +1 -0
  182. package/dist/src/lib/server/hydration.js +345 -0
  183. package/dist/src/lib/server/hydration.mjs +148 -0
  184. package/dist/src/lib/server/index.cjs +406 -0
  185. package/dist/src/lib/server/index.d.ts +115 -0
  186. package/dist/src/lib/server/index.d.ts.map +1 -0
  187. package/dist/src/lib/server/index.js +164 -0
  188. package/dist/src/lib/server/index.mjs +384 -0
  189. package/dist/src/lib/server/reactive.cjs +197 -0
  190. package/dist/src/lib/server/reactive.d.ts +239 -0
  191. package/dist/src/lib/server/reactive.d.ts.map +1 -0
  192. package/dist/src/lib/server/reactive.js +413 -0
  193. package/dist/src/lib/server/reactive.mjs +176 -0
  194. package/dist/src/lib/storage/cache.cjs +51 -0
  195. package/dist/src/lib/storage/cache.d.ts +18 -0
  196. package/dist/src/lib/storage/cache.d.ts.map +1 -0
  197. package/dist/src/lib/storage/cache.js +42 -0
  198. package/dist/src/lib/storage/cache.mjs +30 -0
  199. package/dist/src/lib/storage/index.cjs +246 -0
  200. package/dist/src/lib/storage/index.d.ts +83 -0
  201. package/dist/src/lib/storage/index.d.ts.map +1 -0
  202. package/dist/src/lib/storage/index.js +179 -0
  203. package/dist/src/lib/storage/index.mjs +231 -0
  204. package/dist/src/lib/storage/persisted.cjs +91 -0
  205. package/dist/src/lib/storage/persisted.d.ts +53 -0
  206. package/dist/src/lib/storage/persisted.d.ts.map +1 -0
  207. package/dist/src/lib/storage/persisted.js +75 -0
  208. package/dist/src/lib/storage/persisted.mjs +70 -0
  209. package/dist/src/lib/theme/color-scheme.cjs +281 -0
  210. package/dist/src/lib/theme/color-scheme.d.ts +61 -0
  211. package/dist/src/lib/theme/color-scheme.d.ts.map +1 -0
  212. package/dist/src/lib/theme/color-scheme.js +120 -0
  213. package/dist/src/lib/theme/color-scheme.mjs +265 -0
  214. package/dist/src/lib/theme/index.cjs +267 -0
  215. package/dist/src/lib/theme/index.d.ts +78 -0
  216. package/dist/src/lib/theme/index.d.ts.map +1 -0
  217. package/dist/src/lib/theme/index.js +135 -0
  218. package/dist/src/lib/theme/index.mjs +251 -0
  219. package/dist/src/lib/theme/provider.cjs +346 -0
  220. package/dist/src/lib/theme/provider.d.ts +34 -0
  221. package/dist/src/lib/theme/provider.d.ts.map +1 -0
  222. package/dist/src/lib/theme/provider.js +60 -0
  223. package/dist/src/lib/theme/provider.mjs +332 -0
  224. package/dist/src/lib/utils/index.cjs +209 -0
  225. package/dist/src/lib/utils/index.d.ts +286 -0
  226. package/dist/src/lib/utils/index.d.ts.map +1 -0
  227. package/dist/src/lib/utils/index.js +434 -0
  228. package/dist/src/lib/utils/index.mjs +188 -0
  229. package/dist/src/routes.cjs +37 -0
  230. package/dist/src/routes.d.ts +22 -0
  231. package/dist/src/routes.d.ts.map +1 -0
  232. package/dist/src/routes.js +20 -0
  233. package/dist/src/routes.mjs +17 -0
  234. package/dist/src/server.cjs +405 -0
  235. package/dist/src/server.d.ts +63 -0
  236. package/dist/src/server.d.ts.map +1 -0
  237. package/dist/src/server.js +62 -0
  238. package/dist/src/server.mjs +382 -0
  239. package/dist/src/utils.cjs +21 -0
  240. package/dist/src/utils.d.ts +10 -0
  241. package/dist/src/utils.d.ts.map +1 -0
  242. package/dist/src/utils.js +9 -0
  243. package/dist/src/utils.mjs +4 -0
  244. package/dist/src/version.generated.cjs +26 -0
  245. package/dist/src/version.generated.d.ts +3 -0
  246. package/dist/src/version.generated.d.ts.map +1 -0
  247. package/dist/src/version.generated.js +3 -0
  248. package/dist/src/version.generated.mjs +5 -0
  249. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  250. package/package.json +164 -0
  251. package/src/index.ts +19 -0
  252. package/types/fluixi.d.ts +5 -0
  253. package/types/vinxi.d.ts +50 -0
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @module @fluixi/core/plugins/route-scanner
3
+ *
4
+ * Scans a routes directory and builds a route tree following SolidStart conventions.
5
+ * Pure utility, no bundler dependency.
6
+ */
7
+ export interface ScannedRoute {
8
+ /** Relative file path from routes dir: 'users/[id].tsx' */
9
+ filePath: string;
10
+ /** URL segment for this route: ':id', 'about', '' (index) */
11
+ urlSegment: string;
12
+ /** Full URL path: '/users/:id' */
13
+ urlPath: string;
14
+ /** Whether this is a layout file (layout.tsx) */
15
+ isLayout: boolean;
16
+ /** Whether this is an index file (index.tsx) */
17
+ isIndex: boolean;
18
+ /** Whether this has dynamic params ([id]) */
19
+ isDynamic: boolean;
20
+ /** Whether this is a catch-all ([...rest]) */
21
+ isCatchAll: boolean;
22
+ /** Whether the parent directory is a route group ((name)) */
23
+ isGroup: boolean;
24
+ /** Nested child routes */
25
+ children: ScannedRoute[];
26
+ parentUrlPath: string;
27
+ /** Whether this route file exports a `routeData` function */
28
+ hasRouteData: boolean;
29
+ }
30
+ export interface ScanOptions {
31
+ /** File extensions to include */
32
+ extensions?: string[];
33
+ }
34
+ /**
35
+ * Scan a routes directory and return a tree of ScannedRoute nodes.
36
+ */
37
+ export declare function scanRoutes(routesDir: string, options?: ScanOptions): ScannedRoute[];
38
+ //# 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;;;;;GAKG;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,215 @@
1
+ /**
2
+ * @module @fluixi/core/plugins/route-scanner
3
+ *
4
+ * Scans a routes directory and builds a route tree following SolidStart conventions.
5
+ * Pure utility, no bundler dependency.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ const DEFAULT_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js'];
10
+ // ============================================================================
11
+ // SCANNING
12
+ // ============================================================================
13
+ /**
14
+ * Scan a routes directory and return a tree of ScannedRoute nodes.
15
+ */
16
+ export function scanRoutes(routesDir, options = {}) {
17
+ const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
18
+ const absDir = path.resolve(routesDir);
19
+ if (!fs.existsSync(absDir)) {
20
+ return [];
21
+ }
22
+ return scanDirectory(absDir, absDir, '', extensions);
23
+ }
24
+ function scanDirectory(dir, rootDir, parentUrlPath, extensions) {
25
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
26
+ const routes = [];
27
+ const layoutRoute = null;
28
+ // Separate files and directories
29
+ const files = [];
30
+ const dirs = [];
31
+ for (const entry of entries) {
32
+ if (entry.isDirectory()) {
33
+ dirs.push(entry);
34
+ }
35
+ else if (entry.isFile() && hasValidExtension(entry.name, extensions)) {
36
+ files.push(entry);
37
+ }
38
+ }
39
+ // Find layout file first
40
+ let layout;
41
+ const nonLayoutFiles = [];
42
+ for (const file of files) {
43
+ const baseName = stripExtension(file.name);
44
+ if (baseName === 'layout') {
45
+ layout = buildFileRoute(file.name, dir, rootDir, parentUrlPath, true);
46
+ }
47
+ else {
48
+ nonLayoutFiles.push(file);
49
+ }
50
+ }
51
+ // Build routes for non-layout files
52
+ const fileRoutes = [];
53
+ for (const file of nonLayoutFiles) {
54
+ fileRoutes.push(buildFileRoute(file.name, dir, rootDir, parentUrlPath, false));
55
+ }
56
+ // Build routes for subdirectories
57
+ const dirRoutes = [];
58
+ for (const d of dirs) {
59
+ const dirName = d.name;
60
+ const isGroup = isRouteGroup(dirName);
61
+ const segment = isGroup ? '' : dirNameToSegment(dirName);
62
+ const childUrlPath = segment
63
+ ? joinUrlPath(parentUrlPath, segment)
64
+ : parentUrlPath;
65
+ const children = scanDirectory(path.join(dir, dirName), rootDir, childUrlPath, extensions);
66
+ if (isGroup) {
67
+ // Route groups: children are flattened to parent level
68
+ dirRoutes.push(...children);
69
+ }
70
+ else {
71
+ // Regular directory: becomes a nested route
72
+ // If there's a DIRECT layout in the children (urlPath matches this dir's path),
73
+ // it becomes the parent route. We must not pick up layouts from deeper descendants
74
+ // (e.g. campaigns/[id]/workspace/layout.tsx must not be the layout for campaigns/).
75
+ const childLayout = children.find((c) => c.isLayout && c.urlPath === childUrlPath);
76
+ const childNonLayout = children.filter((c) => !c.isLayout || c.urlPath !== childUrlPath);
77
+ if (childLayout) {
78
+ // Preserve children from recursive scan, add any non-layout siblings
79
+ childLayout.children = [...childLayout.children, ...childNonLayout];
80
+ dirRoutes.push(childLayout);
81
+ }
82
+ else if (childNonLayout.length > 0) {
83
+ // No layout, just add children with their full paths
84
+ dirRoutes.push(...childNonLayout);
85
+ }
86
+ }
87
+ }
88
+ // Combine: if there's a layout at this level, nest everything under it
89
+ if (layout) {
90
+ layout.children = [...fileRoutes, ...dirRoutes];
91
+ routes.push(layout);
92
+ }
93
+ else {
94
+ routes.push(...fileRoutes, ...dirRoutes);
95
+ }
96
+ // Sort: static routes first, then dynamic, then catch-all
97
+ return sortRoutes(routes);
98
+ }
99
+ // ============================================================================
100
+ // ROUTE BUILDING
101
+ // ============================================================================
102
+ function buildFileRoute(fileName, dir, rootDir, parentUrlPath, isLayout) {
103
+ const baseName = stripExtension(fileName);
104
+ const filePath = path.relative(rootDir, path.join(dir, fileName));
105
+ const isIndex = baseName === 'index';
106
+ const isCatchAll = baseName.startsWith('[...');
107
+ const isDynamic = !isCatchAll && baseName.startsWith('[') && baseName.endsWith(']');
108
+ let urlSegment;
109
+ if (isLayout) {
110
+ urlSegment = '';
111
+ }
112
+ else if (isIndex) {
113
+ urlSegment = '/';
114
+ }
115
+ else if (isCatchAll) {
116
+ // [...rest] -> *rest
117
+ const paramName = baseName.slice(4, -1); // remove '[...' and ']'
118
+ urlSegment = `*${paramName}`;
119
+ }
120
+ else if (isDynamic) {
121
+ // [id] -> :id
122
+ const paramName = baseName.slice(1, -1); // remove '[' and ']'
123
+ urlSegment = `:${paramName}`;
124
+ }
125
+ else {
126
+ urlSegment = baseName;
127
+ }
128
+ const urlPath = isLayout
129
+ ? parentUrlPath || '/'
130
+ : isIndex
131
+ ? parentUrlPath || '/'
132
+ : joinUrlPath(parentUrlPath, urlSegment);
133
+ // Detect if the file exports a `routeData` function (static analysis at scan time)
134
+ const absoluteFilePath = path.join(dir, fileName);
135
+ let hasRouteData = false;
136
+ try {
137
+ const content = fs.readFileSync(absoluteFilePath, 'utf-8');
138
+ hasRouteData = /export\s+(const|function|async\s+function)\s+routeData\b/.test(content);
139
+ }
140
+ catch {
141
+ // If file can't be read, assume no routeData
142
+ }
143
+ return {
144
+ filePath: filePath.replace(/\\/g, '/'), // normalize to forward slashes
145
+ urlSegment,
146
+ urlPath,
147
+ isLayout,
148
+ isIndex,
149
+ isDynamic,
150
+ isCatchAll,
151
+ isGroup: false,
152
+ children: [],
153
+ parentUrlPath,
154
+ hasRouteData,
155
+ rootDir,
156
+ dir
157
+ };
158
+ }
159
+ // ============================================================================
160
+ // UTILITIES
161
+ // ============================================================================
162
+ function hasValidExtension(fileName, extensions) {
163
+ return extensions.some((ext) => fileName.endsWith(ext));
164
+ }
165
+ function stripExtension(fileName) {
166
+ const lastDot = fileName.lastIndexOf('.');
167
+ return lastDot > 0 ? fileName.slice(0, lastDot) : fileName;
168
+ }
169
+ function isRouteGroup(dirName) {
170
+ return dirName.startsWith('(') && dirName.endsWith(')');
171
+ }
172
+ /** Convert a directory name to its URL segment, matching the same rules as file names. */
173
+ function dirNameToSegment(dirName) {
174
+ if (dirName.startsWith('[...') && dirName.endsWith(']')) {
175
+ return '*' + dirName.slice(4, -1); // [...rest] -> *rest
176
+ }
177
+ if (dirName.startsWith('[') && dirName.endsWith(']')) {
178
+ return ':' + dirName.slice(1, -1); // [id] -> :id
179
+ }
180
+ return dirName;
181
+ }
182
+ function joinUrlPath(parent, segment) {
183
+ const base = parent.endsWith('/') ? parent : parent + '/';
184
+ return base + segment;
185
+ }
186
+ /**
187
+ * Sort routes by specificity: static > dynamic > catch-all.
188
+ * Index routes come before non-index at the same level.
189
+ */
190
+ function sortRoutes(routes) {
191
+ return routes.sort((a, b) => {
192
+ // Layouts first (they wrap children)
193
+ if (a.isLayout && !b.isLayout)
194
+ return -1;
195
+ if (!a.isLayout && b.isLayout)
196
+ return 1;
197
+ // Index routes before others
198
+ if (a.isIndex && !b.isIndex)
199
+ return -1;
200
+ if (!a.isIndex && b.isIndex)
201
+ return 1;
202
+ // Static before dynamic
203
+ if (!a.isDynamic && !a.isCatchAll && (b.isDynamic || b.isCatchAll))
204
+ return -1;
205
+ if ((a.isDynamic || a.isCatchAll) && !b.isDynamic && !b.isCatchAll)
206
+ return 1;
207
+ // Dynamic before catch-all
208
+ if (a.isDynamic && b.isCatchAll)
209
+ return -1;
210
+ if (a.isCatchAll && b.isDynamic)
211
+ return 1;
212
+ // Alphabetical fallback
213
+ return a.urlSegment.localeCompare(b.urlSegment);
214
+ });
215
+ }
@@ -0,0 +1,158 @@
1
+ // src/lib/plugins/route-scanner.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ var DEFAULT_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js"];
5
+ function scanRoutes(routesDir, options = {}) {
6
+ const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
7
+ const absDir = path.resolve(routesDir);
8
+ if (!fs.existsSync(absDir)) {
9
+ return [];
10
+ }
11
+ return scanDirectory(absDir, absDir, "", extensions);
12
+ }
13
+ function scanDirectory(dir, rootDir, parentUrlPath, extensions) {
14
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
15
+ const routes = [];
16
+ const layoutRoute = null;
17
+ const files = [];
18
+ const dirs = [];
19
+ for (const entry of entries) {
20
+ if (entry.isDirectory()) {
21
+ dirs.push(entry);
22
+ } else if (entry.isFile() && hasValidExtension(entry.name, extensions)) {
23
+ files.push(entry);
24
+ }
25
+ }
26
+ let layout;
27
+ const nonLayoutFiles = [];
28
+ for (const file of files) {
29
+ const baseName = stripExtension(file.name);
30
+ if (baseName === "layout") {
31
+ layout = buildFileRoute(file.name, dir, rootDir, parentUrlPath, true);
32
+ } else {
33
+ nonLayoutFiles.push(file);
34
+ }
35
+ }
36
+ const fileRoutes = [];
37
+ for (const file of nonLayoutFiles) {
38
+ fileRoutes.push(
39
+ buildFileRoute(file.name, dir, rootDir, parentUrlPath, false)
40
+ );
41
+ }
42
+ const dirRoutes = [];
43
+ for (const d of dirs) {
44
+ const dirName = d.name;
45
+ const isGroup = isRouteGroup(dirName);
46
+ const segment = isGroup ? "" : dirNameToSegment(dirName);
47
+ const childUrlPath = segment ? joinUrlPath(parentUrlPath, segment) : parentUrlPath;
48
+ const children = scanDirectory(
49
+ path.join(dir, dirName),
50
+ rootDir,
51
+ childUrlPath,
52
+ extensions
53
+ );
54
+ if (isGroup) {
55
+ dirRoutes.push(...children);
56
+ } else {
57
+ const childLayout = children.find((c) => c.isLayout && c.urlPath === childUrlPath);
58
+ const childNonLayout = children.filter((c) => !c.isLayout || c.urlPath !== childUrlPath);
59
+ if (childLayout) {
60
+ childLayout.children = [...childLayout.children, ...childNonLayout];
61
+ dirRoutes.push(childLayout);
62
+ } else if (childNonLayout.length > 0) {
63
+ dirRoutes.push(...childNonLayout);
64
+ }
65
+ }
66
+ }
67
+ if (layout) {
68
+ layout.children = [...fileRoutes, ...dirRoutes];
69
+ routes.push(layout);
70
+ } else {
71
+ routes.push(...fileRoutes, ...dirRoutes);
72
+ }
73
+ return sortRoutes(routes);
74
+ }
75
+ function buildFileRoute(fileName, dir, rootDir, parentUrlPath, isLayout) {
76
+ const baseName = stripExtension(fileName);
77
+ const filePath = path.relative(rootDir, path.join(dir, fileName));
78
+ const isIndex = baseName === "index";
79
+ const isCatchAll = baseName.startsWith("[...");
80
+ const isDynamic = !isCatchAll && baseName.startsWith("[") && baseName.endsWith("]");
81
+ let urlSegment;
82
+ if (isLayout) {
83
+ urlSegment = "";
84
+ } else if (isIndex) {
85
+ urlSegment = "/";
86
+ } else if (isCatchAll) {
87
+ const paramName = baseName.slice(4, -1);
88
+ urlSegment = `*${paramName}`;
89
+ } else if (isDynamic) {
90
+ const paramName = baseName.slice(1, -1);
91
+ urlSegment = `:${paramName}`;
92
+ } else {
93
+ urlSegment = baseName;
94
+ }
95
+ const urlPath = isLayout ? parentUrlPath || "/" : isIndex ? parentUrlPath || "/" : joinUrlPath(parentUrlPath, urlSegment);
96
+ const absoluteFilePath = path.join(dir, fileName);
97
+ let hasRouteData = false;
98
+ try {
99
+ const content = fs.readFileSync(absoluteFilePath, "utf-8");
100
+ hasRouteData = /export\s+(const|function|async\s+function)\s+routeData\b/.test(content);
101
+ } catch {
102
+ }
103
+ return {
104
+ filePath: filePath.replace(/\\/g, "/"),
105
+ // normalize to forward slashes
106
+ urlSegment,
107
+ urlPath,
108
+ isLayout,
109
+ isIndex,
110
+ isDynamic,
111
+ isCatchAll,
112
+ isGroup: false,
113
+ children: [],
114
+ parentUrlPath,
115
+ hasRouteData,
116
+ rootDir,
117
+ dir
118
+ };
119
+ }
120
+ function hasValidExtension(fileName, extensions) {
121
+ return extensions.some((ext) => fileName.endsWith(ext));
122
+ }
123
+ function stripExtension(fileName) {
124
+ const lastDot = fileName.lastIndexOf(".");
125
+ return lastDot > 0 ? fileName.slice(0, lastDot) : fileName;
126
+ }
127
+ function isRouteGroup(dirName) {
128
+ return dirName.startsWith("(") && dirName.endsWith(")");
129
+ }
130
+ function dirNameToSegment(dirName) {
131
+ if (dirName.startsWith("[...") && dirName.endsWith("]")) {
132
+ return "*" + dirName.slice(4, -1);
133
+ }
134
+ if (dirName.startsWith("[") && dirName.endsWith("]")) {
135
+ return ":" + dirName.slice(1, -1);
136
+ }
137
+ return dirName;
138
+ }
139
+ function joinUrlPath(parent, segment) {
140
+ const base = parent.endsWith("/") ? parent : parent + "/";
141
+ return base + segment;
142
+ }
143
+ function sortRoutes(routes) {
144
+ return routes.sort((a, b) => {
145
+ if (a.isLayout && !b.isLayout) return -1;
146
+ if (!a.isLayout && b.isLayout) return 1;
147
+ if (a.isIndex && !b.isIndex) return -1;
148
+ if (!a.isIndex && b.isIndex) return 1;
149
+ if (!a.isDynamic && !a.isCatchAll && (b.isDynamic || b.isCatchAll)) return -1;
150
+ if ((a.isDynamic || a.isCatchAll) && !b.isDynamic && !b.isCatchAll) return 1;
151
+ if (a.isDynamic && b.isCatchAll) return -1;
152
+ if (a.isCatchAll && b.isDynamic) return 1;
153
+ return a.urlSegment.localeCompare(b.urlSegment);
154
+ });
155
+ }
156
+ export {
157
+ scanRoutes
158
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/plugins/vite.ts
21
+ var vite_exports = {};
22
+ __export(vite_exports, {
23
+ createVitePlugin: () => import_vite_plugin.createVitePlugin,
24
+ fluixi: () => import_vite_plugin.fluixi
25
+ });
26
+ module.exports = __toCommonJS(vite_exports);
27
+ var import_vite_plugin = 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,6 @@
1
+ // src/lib/plugins/vite.ts
2
+ import { fluixi, createVitePlugin } from "@fluixi/vite-plugin";
3
+ export {
4
+ createVitePlugin,
5
+ fluixi
6
+ };
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/render/await.ts
21
+ var await_exports = {};
22
+ __export(await_exports, {
23
+ Await: () => Await
24
+ });
25
+ module.exports = __toCommonJS(await_exports);
26
+ var import_signal = require("@fluixi/reactive/signal");
27
+ function Await(props) {
28
+ const fetcher = () => {
29
+ const v = props.value;
30
+ return typeof v === "function" ? v() : v;
31
+ };
32
+ const [data] = (0, import_signal.createResource)(fetcher);
33
+ return () => {
34
+ if (data.loading) return props.fallback;
35
+ const child = props.children;
36
+ return typeof child === "function" ? child(data()) : child;
37
+ };
38
+ }
@@ -0,0 +1,26 @@
1
+ export interface AwaitProps<T> {
2
+ value: Promise<T> | (() => Promise<T>);
3
+ fallback?: unknown;
4
+ /** Render prop called with the resolved value (or plain children). */
5
+ children?: ((value: T) => unknown) | unknown;
6
+ }
7
+ /**
8
+ * Render the result of a promise, with a fallback while it is pending.
9
+ *
10
+ * `value` may be a promise or a function returning one. Pass a function when the promise
11
+ * should be created by the component rather than by whoever wrote the tag, which is what
12
+ * keeps a re-render from firing the request again.
13
+ *
14
+ * `children` is either a render prop called with the resolved value, or plain children
15
+ * that ignore it.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * html`
20
+ * <${Await} value=${() => fetchUser(id)} fallback=${html`<p>loading...</p>`}>
21
+ * ${(user) => html`<h1>${user.name}</h1>`}
22
+ * </${Await}>`;
23
+ * ```
24
+ */
25
+ export declare function Await<T>(props: AwaitProps<T>): () => unknown;
26
+ //# sourceMappingURL=await.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"await.d.ts","sourceRoot":"","sources":["../../../../src/lib/render/await.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,OAAO,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAW5D"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * `<Await value=${promise}>`: resolve a promise and render its value.
3
+ *
4
+ * A thin, Suspense-free helper for the common "await one promise" case:
5
+ *
6
+ * <Await value=${fetchUser(id)} fallback=${html`<p>loading...</p>`}>
7
+ * ${(user) => html`<span>${user.name}</span>`}
8
+ * </Await>
9
+ *
10
+ * `value` is a promise (or a function returning one). While pending it renders
11
+ * `fallback`; once resolved it calls the render-prop child with the value. The
12
+ * resource read is guarded by `.loading`, so it never throws/suspends.
13
+ */
14
+ import { createResource } from '@fluixi/reactive/signal';
15
+ /**
16
+ * Render the result of a promise, with a fallback while it is pending.
17
+ *
18
+ * `value` may be a promise or a function returning one. Pass a function when the promise
19
+ * should be created by the component rather than by whoever wrote the tag, which is what
20
+ * keeps a re-render from firing the request again.
21
+ *
22
+ * `children` is either a render prop called with the resolved value, or plain children
23
+ * that ignore it.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * html`
28
+ * <${Await} value=${() => fetchUser(id)} fallback=${html`<p>loading...</p>`}>
29
+ * ${(user) => html`<h1>${user.name}</h1>`}
30
+ * </${Await}>`;
31
+ * ```
32
+ */
33
+ export function Await(props) {
34
+ const fetcher = () => {
35
+ const v = props.value;
36
+ return typeof v === 'function' ? v() : v;
37
+ };
38
+ const [data] = createResource(fetcher);
39
+ return () => {
40
+ if (data.loading)
41
+ return props.fallback;
42
+ const child = props.children;
43
+ return typeof child === 'function' ? child(data()) : child;
44
+ };
45
+ }
@@ -0,0 +1,17 @@
1
+ // src/lib/render/await.ts
2
+ import { createResource } from "@fluixi/reactive/signal";
3
+ function Await(props) {
4
+ const fetcher = () => {
5
+ const v = props.value;
6
+ return typeof v === "function" ? v() : v;
7
+ };
8
+ const [data] = createResource(fetcher);
9
+ return () => {
10
+ if (data.loading) return props.fallback;
11
+ const child = props.children;
12
+ return typeof child === "function" ? child(data()) : child;
13
+ };
14
+ }
15
+ export {
16
+ Await
17
+ };