@float.js/core 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/index.d.ts +103 -0
- package/dist/ai/index.js +293 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/analytics/index.d.ts +193 -0
- package/dist/analytics/index.js +499 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/api/index.d.ts +172 -0
- package/dist/api/index.js +643 -0
- package/dist/api/index.js.map +1 -0
- package/dist/cli/index.js +2367 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/devtools/index.d.ts +82 -0
- package/dist/devtools/index.js +839 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/image/index.d.ts +114 -0
- package/dist/image/index.js +242 -0
- package/dist/image/index.js.map +1 -0
- package/dist/index.d.ts +400 -0
- package/dist/index.js +6511 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/index.d.ts +179 -0
- package/dist/middleware/index.js +362 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/realtime/index.d.ts +198 -0
- package/dist/realtime/index.js +555 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/router/index.d.ts +43 -0
- package/dist/router/index.js +143 -0
- package/dist/router/index.js.map +1 -0
- package/dist/server/index.d.ts +51 -0
- package/dist/server/index.js +2163 -0
- package/dist/server/index.js.map +1 -0
- package/dist/ssg/index.d.ts +178 -0
- package/dist/ssg/index.js +399 -0
- package/dist/ssg/index.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// src/router/index.ts
|
|
2
|
+
import fg from "fast-glob";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_OPTIONS = {
|
|
5
|
+
appDir: "app",
|
|
6
|
+
basePath: "",
|
|
7
|
+
extensions: [".tsx", ".ts", ".jsx", ".js"]
|
|
8
|
+
};
|
|
9
|
+
function filePathToUrlPath(filePath, appDir) {
|
|
10
|
+
let urlPath = filePath.replace(new RegExp(`^${appDir}/`), "").replace(/\/?(page|layout|route|error|loading|not-found)\.(tsx?|jsx?)$/, "");
|
|
11
|
+
const params = [];
|
|
12
|
+
let isCatchAll = false;
|
|
13
|
+
let isOptionalCatchAll = false;
|
|
14
|
+
urlPath = urlPath.replace(/\[([^\]]+)\]/g, (_, param) => {
|
|
15
|
+
if (param.startsWith("...") && filePath.includes("[[")) {
|
|
16
|
+
isOptionalCatchAll = true;
|
|
17
|
+
const paramName = param.replace("...", "");
|
|
18
|
+
params.push(paramName);
|
|
19
|
+
return `*${paramName}?`;
|
|
20
|
+
}
|
|
21
|
+
if (param.startsWith("...")) {
|
|
22
|
+
isCatchAll = true;
|
|
23
|
+
const paramName = param.replace("...", "");
|
|
24
|
+
params.push(paramName);
|
|
25
|
+
return `*${paramName}`;
|
|
26
|
+
}
|
|
27
|
+
params.push(param);
|
|
28
|
+
return `:${param}`;
|
|
29
|
+
});
|
|
30
|
+
urlPath = "/" + urlPath;
|
|
31
|
+
urlPath = urlPath.replace(/\/+/g, "/").replace(/\/$/, "") || "/";
|
|
32
|
+
return { urlPath, params, isCatchAll, isOptionalCatchAll };
|
|
33
|
+
}
|
|
34
|
+
function getRouteType(filePath) {
|
|
35
|
+
const fileName = filePath.split("/").pop() || filePath;
|
|
36
|
+
if (fileName.match(/^route\.(tsx?|jsx?)$/)) return "api";
|
|
37
|
+
if (fileName.match(/^layout\.(tsx?|jsx?)$/)) return "layout";
|
|
38
|
+
if (fileName.match(/^error\.(tsx?|jsx?)$/)) return "error";
|
|
39
|
+
if (fileName.match(/^loading\.(tsx?|jsx?)$/)) return "loading";
|
|
40
|
+
return "page";
|
|
41
|
+
}
|
|
42
|
+
function findLayouts(routePath, allLayouts) {
|
|
43
|
+
const layouts = [];
|
|
44
|
+
const segments = routePath.split("/").filter(Boolean);
|
|
45
|
+
let currentPath = "";
|
|
46
|
+
if (allLayouts.has("/")) {
|
|
47
|
+
layouts.push(allLayouts.get("/"));
|
|
48
|
+
}
|
|
49
|
+
for (const segment of segments) {
|
|
50
|
+
currentPath += "/" + segment;
|
|
51
|
+
if (allLayouts.has(currentPath)) {
|
|
52
|
+
layouts.push(allLayouts.get(currentPath));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return layouts;
|
|
56
|
+
}
|
|
57
|
+
async function scanRoutes(rootDir, options = {}) {
|
|
58
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
59
|
+
const appDir = path.join(rootDir, opts.appDir);
|
|
60
|
+
const extensions = opts.extensions.map((ext) => ext.replace(".", "")).join(",");
|
|
61
|
+
const pattern = `**/{page,layout,route,error,loading}.{${extensions}}`;
|
|
62
|
+
const files = await fg(pattern, {
|
|
63
|
+
cwd: appDir,
|
|
64
|
+
onlyFiles: true,
|
|
65
|
+
ignore: ["**/node_modules/**", "**/_*/**"]
|
|
66
|
+
});
|
|
67
|
+
const layoutMap = /* @__PURE__ */ new Map();
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
const type = getRouteType(file);
|
|
70
|
+
if (type === "layout") {
|
|
71
|
+
const { urlPath } = filePathToUrlPath(file, "");
|
|
72
|
+
const layoutPath = urlPath === "/" ? "/" : urlPath.replace(/\/layout$/, "") || "/";
|
|
73
|
+
layoutMap.set(layoutPath, path.join(appDir, file));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const routes = [];
|
|
77
|
+
for (const file of files) {
|
|
78
|
+
const type = getRouteType(file);
|
|
79
|
+
if (type === "layout" || type === "error" || type === "loading") {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const { urlPath, params, isCatchAll, isOptionalCatchAll } = filePathToUrlPath(file, "");
|
|
83
|
+
const route = {
|
|
84
|
+
path: opts.basePath + urlPath,
|
|
85
|
+
filePath: file,
|
|
86
|
+
absolutePath: path.join(appDir, file),
|
|
87
|
+
type,
|
|
88
|
+
params,
|
|
89
|
+
isCatchAll,
|
|
90
|
+
isOptionalCatchAll,
|
|
91
|
+
layouts: type === "page" ? findLayouts(urlPath, layoutMap) : []
|
|
92
|
+
};
|
|
93
|
+
routes.push(route);
|
|
94
|
+
}
|
|
95
|
+
routes.sort((a, b) => {
|
|
96
|
+
if (a.isCatchAll !== b.isCatchAll) return a.isCatchAll ? 1 : -1;
|
|
97
|
+
if (a.params.length !== b.params.length) return a.params.length - b.params.length;
|
|
98
|
+
return a.path.localeCompare(b.path);
|
|
99
|
+
});
|
|
100
|
+
return routes;
|
|
101
|
+
}
|
|
102
|
+
function matchRoute(url, routes) {
|
|
103
|
+
const urlParts = url.split("/").filter(Boolean);
|
|
104
|
+
for (const route of routes) {
|
|
105
|
+
if (route.type !== "page" && route.type !== "api") continue;
|
|
106
|
+
const routeParts = route.path.split("/").filter(Boolean);
|
|
107
|
+
const params = {};
|
|
108
|
+
let matched = true;
|
|
109
|
+
let urlIndex = 0;
|
|
110
|
+
for (let i = 0; i < routeParts.length; i++) {
|
|
111
|
+
const routePart = routeParts[i];
|
|
112
|
+
if (routePart.startsWith("*")) {
|
|
113
|
+
const paramName = routePart.replace(/^\*/, "").replace(/\?$/, "");
|
|
114
|
+
params[paramName] = urlParts.slice(urlIndex).join("/");
|
|
115
|
+
return { route, params };
|
|
116
|
+
}
|
|
117
|
+
if (routePart.startsWith(":")) {
|
|
118
|
+
const paramName = routePart.slice(1);
|
|
119
|
+
if (urlIndex >= urlParts.length) {
|
|
120
|
+
matched = false;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
params[paramName] = urlParts[urlIndex];
|
|
124
|
+
urlIndex++;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (urlParts[urlIndex] !== routePart) {
|
|
128
|
+
matched = false;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
urlIndex++;
|
|
132
|
+
}
|
|
133
|
+
if (matched && urlIndex === urlParts.length) {
|
|
134
|
+
return { route, params };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return { route: null, params: {} };
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
matchRoute,
|
|
141
|
+
scanRoutes
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/router/index.ts"],"sourcesContent":["/**\n * Float.js Router\n * File-based routing system\n */\n\nimport fg from 'fast-glob';\nimport path from 'node:path';\n\nexport interface Route {\n /** URL path pattern (e.g., /users/:id) */\n path: string;\n /** File path relative to app directory */\n filePath: string;\n /** Absolute file path */\n absolutePath: string;\n /** Route type */\n type: 'page' | 'layout' | 'api' | 'error' | 'loading';\n /** Dynamic segments */\n params: string[];\n /** Is catch-all route */\n isCatchAll: boolean;\n /** Is optional catch-all */\n isOptionalCatchAll: boolean;\n /** Nested layouts */\n layouts: string[];\n}\n\nexport interface RouterOptions {\n /** Root directory of the app (default: 'app') */\n appDir?: string;\n /** Base path for all routes */\n basePath?: string;\n /** File extensions to consider */\n extensions?: string[];\n}\n\nconst DEFAULT_OPTIONS: Required<RouterOptions> = {\n appDir: 'app',\n basePath: '',\n extensions: ['.tsx', '.ts', '.jsx', '.js'],\n};\n\n/**\n * Convert file path to URL path\n * \n * Examples:\n * - app/page.tsx -> /\n * - app/about/page.tsx -> /about\n * - app/users/[id]/page.tsx -> /users/:id\n * - app/docs/[...slug]/page.tsx -> /docs/*\n * - app/shop/[[...slug]]/page.tsx -> /shop/*?\n */\nfunction filePathToUrlPath(filePath: string, appDir: string): { \n urlPath: string; \n params: string[];\n isCatchAll: boolean;\n isOptionalCatchAll: boolean;\n} {\n // Remove app dir prefix and file name\n let urlPath = filePath\n .replace(new RegExp(`^${appDir}/`), '')\n .replace(/\\/?(page|layout|route|error|loading|not-found)\\.(tsx?|jsx?)$/, '');\n\n const params: string[] = [];\n let isCatchAll = false;\n let isOptionalCatchAll = false;\n\n // Convert [param] to :param\n urlPath = urlPath.replace(/\\[([^\\]]+)\\]/g, (_, param) => {\n // Optional catch-all [[...slug]]\n if (param.startsWith('...') && filePath.includes('[[')) {\n isOptionalCatchAll = true;\n const paramName = param.replace('...', '');\n params.push(paramName);\n return `*${paramName}?`;\n }\n // Catch-all [...slug]\n if (param.startsWith('...')) {\n isCatchAll = true;\n const paramName = param.replace('...', '');\n params.push(paramName);\n return `*${paramName}`;\n }\n // Regular dynamic param [id]\n params.push(param);\n return `:${param}`;\n });\n\n // Ensure leading slash\n urlPath = '/' + urlPath;\n \n // Clean up double slashes and trailing slash\n urlPath = urlPath.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/';\n\n return { urlPath, params, isCatchAll, isOptionalCatchAll };\n}\n\n/**\n * Determine route type from file name\n */\nfunction getRouteType(filePath: string): Route['type'] {\n // Check if file name (without path) matches special file types\n const fileName = filePath.split('/').pop() || filePath;\n \n if (fileName.match(/^route\\.(tsx?|jsx?)$/)) return 'api';\n if (fileName.match(/^layout\\.(tsx?|jsx?)$/)) return 'layout';\n if (fileName.match(/^error\\.(tsx?|jsx?)$/)) return 'error';\n if (fileName.match(/^loading\\.(tsx?|jsx?)$/)) return 'loading';\n return 'page';\n}\n\n/**\n * Find all layouts that apply to a route\n */\nfunction findLayouts(routePath: string, allLayouts: Map<string, string>): string[] {\n const layouts: string[] = [];\n const segments = routePath.split('/').filter(Boolean);\n \n // Check from root to deepest\n let currentPath = '';\n \n // Root layout\n if (allLayouts.has('/')) {\n layouts.push(allLayouts.get('/')!);\n }\n \n for (const segment of segments) {\n currentPath += '/' + segment;\n if (allLayouts.has(currentPath)) {\n layouts.push(allLayouts.get(currentPath)!);\n }\n }\n \n return layouts;\n}\n\n/**\n * Scan app directory and build routes\n */\nexport async function scanRoutes(\n rootDir: string,\n options: RouterOptions = {}\n): Promise<Route[]> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const appDir = path.join(rootDir, opts.appDir);\n const extensions = opts.extensions.map(ext => ext.replace('.', '')).join(',');\n\n // Find all route files\n const pattern = `**/{page,layout,route,error,loading}.{${extensions}}`;\n const files = await fg(pattern, {\n cwd: appDir,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/_*/**'],\n });\n\n // First pass: collect all layouts\n const layoutMap = new Map<string, string>();\n \n for (const file of files) {\n const type = getRouteType(file);\n if (type === 'layout') {\n const { urlPath } = filePathToUrlPath(file, '');\n const layoutPath = urlPath === '/' ? '/' : urlPath.replace(/\\/layout$/, '') || '/';\n layoutMap.set(layoutPath, path.join(appDir, file));\n }\n }\n\n // Second pass: build all routes (only pages and API routes)\n const routes: Route[] = [];\n\n for (const file of files) {\n const type = getRouteType(file);\n \n // Skip layouts, errors, loading - they are not matchable routes\n if (type === 'layout' || type === 'error' || type === 'loading') {\n continue;\n }\n const { urlPath, params, isCatchAll, isOptionalCatchAll } = filePathToUrlPath(file, '');\n \n const route: Route = {\n path: opts.basePath + urlPath,\n filePath: file,\n absolutePath: path.join(appDir, file),\n type,\n params,\n isCatchAll,\n isOptionalCatchAll,\n layouts: type === 'page' ? findLayouts(urlPath, layoutMap) : [],\n };\n\n routes.push(route);\n }\n\n // Sort routes: static first, then dynamic, catch-all last\n routes.sort((a, b) => {\n if (a.isCatchAll !== b.isCatchAll) return a.isCatchAll ? 1 : -1;\n if (a.params.length !== b.params.length) return a.params.length - b.params.length;\n return a.path.localeCompare(b.path);\n });\n\n return routes;\n}\n\n/**\n * Match a URL path to a route\n */\nexport function matchRoute(url: string, routes: Route[]): { \n route: Route | null; \n params: Record<string, string>;\n} {\n const urlParts = url.split('/').filter(Boolean);\n\n for (const route of routes) {\n if (route.type !== 'page' && route.type !== 'api') continue;\n\n const routeParts = route.path.split('/').filter(Boolean);\n const params: Record<string, string> = {};\n let matched = true;\n let urlIndex = 0;\n\n for (let i = 0; i < routeParts.length; i++) {\n const routePart = routeParts[i];\n\n // Catch-all\n if (routePart.startsWith('*')) {\n const paramName = routePart.replace(/^\\*/, '').replace(/\\?$/, '');\n params[paramName] = urlParts.slice(urlIndex).join('/');\n return { route, params };\n }\n\n // Dynamic segment\n if (routePart.startsWith(':')) {\n const paramName = routePart.slice(1);\n if (urlIndex >= urlParts.length) {\n matched = false;\n break;\n }\n params[paramName] = urlParts[urlIndex];\n urlIndex++;\n continue;\n }\n\n // Static segment\n if (urlParts[urlIndex] !== routePart) {\n matched = false;\n break;\n }\n urlIndex++;\n }\n\n // Check if we consumed all URL parts\n if (matched && urlIndex === urlParts.length) {\n return { route, params };\n }\n }\n\n return { route: null, params: {} };\n}\n\nexport type { Route as FloatRoute, RouterOptions as FloatRouterOptions };\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FloatRoute as Route } from '../router/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Float.js Development Server
|
|
5
|
+
* Fast development experience with HMR
|
|
6
|
+
*/
|
|
7
|
+
interface DevServerOptions {
|
|
8
|
+
port: number;
|
|
9
|
+
host: string;
|
|
10
|
+
open?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface DevServer {
|
|
13
|
+
start: () => Promise<void>;
|
|
14
|
+
stop: () => Promise<void>;
|
|
15
|
+
restart: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
declare function createDevServer(options: DevServerOptions): Promise<DevServer>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Float.js SSR Engine
|
|
21
|
+
* Server-Side Rendering with React 18 Streaming
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface RenderOptions {
|
|
25
|
+
hmrScript?: string;
|
|
26
|
+
isDev?: boolean;
|
|
27
|
+
streaming?: boolean;
|
|
28
|
+
}
|
|
29
|
+
interface PageProps {
|
|
30
|
+
params: Record<string, string>;
|
|
31
|
+
searchParams: Record<string, string>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Render a page to HTML string
|
|
35
|
+
*/
|
|
36
|
+
declare function renderPage(route: Route, params: Record<string, string>, options?: RenderOptions): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Render with streaming (React 18 Suspense)
|
|
39
|
+
*/
|
|
40
|
+
declare function renderPageStream(route: Route, params: Record<string, string>, _options?: RenderOptions): Promise<NodeJS.ReadableStream>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Float.js Production Server
|
|
44
|
+
*/
|
|
45
|
+
interface ProdServerOptions {
|
|
46
|
+
port: number;
|
|
47
|
+
host: string;
|
|
48
|
+
}
|
|
49
|
+
declare function startProductionServer(options: ProdServerOptions): Promise<void>;
|
|
50
|
+
|
|
51
|
+
export { type DevServer, type DevServerOptions, type PageProps, type ProdServerOptions, type RenderOptions, createDevServer, renderPage, renderPageStream, startProductionServer };
|