@flexireact/core 3.0.1 → 3.0.2
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/cli/index.js +1514 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/client/index.js +373 -0
- package/dist/core/client/index.js.map +1 -0
- package/dist/core/index.js +6415 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/server/index.js +3094 -0
- package/dist/core/server/index.js.map +1 -0
- package/package.json +80 -80
- package/bin/flexireact.js +0 -23
- package/cli/generators.ts +0 -616
- package/cli/index.ts +0 -1182
- package/core/actions/index.ts +0 -364
- package/core/api.ts +0 -143
- package/core/build/index.ts +0 -425
- package/core/cli/logger.ts +0 -353
- package/core/client/Link.tsx +0 -345
- package/core/client/hydration.ts +0 -147
- package/core/client/index.ts +0 -12
- package/core/client/islands.ts +0 -143
- package/core/client/navigation.ts +0 -212
- package/core/client/runtime.ts +0 -52
- package/core/config.ts +0 -116
- package/core/context.ts +0 -83
- package/core/dev.ts +0 -47
- package/core/devtools/index.ts +0 -644
- package/core/edge/cache.ts +0 -344
- package/core/edge/fetch-polyfill.ts +0 -247
- package/core/edge/handler.ts +0 -248
- package/core/edge/index.ts +0 -81
- package/core/edge/ppr.ts +0 -264
- package/core/edge/runtime.ts +0 -161
- package/core/font/index.ts +0 -306
- package/core/helpers.ts +0 -494
- package/core/image/index.ts +0 -413
- package/core/index.ts +0 -218
- package/core/islands/index.ts +0 -293
- package/core/loader.ts +0 -111
- package/core/logger.ts +0 -242
- package/core/metadata/index.ts +0 -622
- package/core/middleware/index.ts +0 -416
- package/core/plugins/index.ts +0 -373
- package/core/render/index.ts +0 -1243
- package/core/render.ts +0 -136
- package/core/router/index.ts +0 -551
- package/core/router.ts +0 -141
- package/core/rsc/index.ts +0 -199
- package/core/server/index.ts +0 -779
- package/core/server.ts +0 -203
- package/core/ssg/index.ts +0 -346
- package/core/start-dev.ts +0 -6
- package/core/start-prod.ts +0 -6
- package/core/tsconfig.json +0 -30
- package/core/types.ts +0 -239
- package/core/utils.ts +0 -176
package/core/router.ts
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Scans the pages directory and builds a route map
|
|
6
|
-
* @param {string} pagesDir - Path to the pages directory
|
|
7
|
-
* @returns {Object} Route map with paths and file locations
|
|
8
|
-
*/
|
|
9
|
-
export function buildRoutes(pagesDir) {
|
|
10
|
-
const routes = {
|
|
11
|
-
pages: [],
|
|
12
|
-
api: []
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
if (!fs.existsSync(pagesDir)) {
|
|
16
|
-
return routes;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
scanDirectory(pagesDir, pagesDir, routes);
|
|
20
|
-
return routes;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Recursively scans a directory for route files
|
|
25
|
-
*/
|
|
26
|
-
function scanDirectory(baseDir, currentDir, routes) {
|
|
27
|
-
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
28
|
-
|
|
29
|
-
for (const entry of entries) {
|
|
30
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
31
|
-
const relativePath = path.relative(baseDir, fullPath);
|
|
32
|
-
|
|
33
|
-
if (entry.isDirectory()) {
|
|
34
|
-
scanDirectory(baseDir, fullPath, routes);
|
|
35
|
-
} else if (entry.isFile()) {
|
|
36
|
-
const ext = path.extname(entry.name);
|
|
37
|
-
|
|
38
|
-
if (ext === '.jsx' || ext === '.js') {
|
|
39
|
-
const routePath = filePathToRoute(relativePath);
|
|
40
|
-
const isApi = relativePath.startsWith('api' + path.sep) || relativePath.startsWith('api/');
|
|
41
|
-
|
|
42
|
-
if (isApi && ext === '.js') {
|
|
43
|
-
routes.api.push({
|
|
44
|
-
path: routePath,
|
|
45
|
-
filePath: fullPath,
|
|
46
|
-
pattern: createRoutePattern(routePath)
|
|
47
|
-
});
|
|
48
|
-
} else if (!isApi && ext === '.jsx') {
|
|
49
|
-
routes.pages.push({
|
|
50
|
-
path: routePath,
|
|
51
|
-
filePath: fullPath,
|
|
52
|
-
pattern: createRoutePattern(routePath)
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Converts a file path to a route path
|
|
62
|
-
* pages/index.jsx -> /
|
|
63
|
-
* pages/about.jsx -> /about
|
|
64
|
-
* pages/blog/[id].jsx -> /blog/:id
|
|
65
|
-
* pages/api/hello.js -> /api/hello
|
|
66
|
-
*/
|
|
67
|
-
function filePathToRoute(filePath) {
|
|
68
|
-
// Normalize path separators
|
|
69
|
-
let route = filePath.replace(/\\/g, '/');
|
|
70
|
-
|
|
71
|
-
// Remove extension
|
|
72
|
-
route = route.replace(/\.(jsx|js)$/, '');
|
|
73
|
-
|
|
74
|
-
// Convert [param] to :param
|
|
75
|
-
route = route.replace(/\[([^\]]+)\]/g, ':$1');
|
|
76
|
-
|
|
77
|
-
// Handle index files
|
|
78
|
-
if (route.endsWith('/index')) {
|
|
79
|
-
route = route.slice(0, -6) || '/';
|
|
80
|
-
} else if (route === 'index') {
|
|
81
|
-
route = '/';
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Ensure leading slash
|
|
85
|
-
if (!route.startsWith('/')) {
|
|
86
|
-
route = '/' + route;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return route;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Creates a regex pattern for route matching
|
|
94
|
-
*/
|
|
95
|
-
function createRoutePattern(routePath) {
|
|
96
|
-
const pattern = routePath
|
|
97
|
-
.replace(/:[^/]+/g, '([^/]+)')
|
|
98
|
-
.replace(/\//g, '\\/');
|
|
99
|
-
|
|
100
|
-
return new RegExp(`^${pattern}$`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Matches a URL path against the route map
|
|
105
|
-
* @param {string} urlPath - The URL path to match
|
|
106
|
-
* @param {Array} routes - Array of route objects
|
|
107
|
-
* @returns {Object|null} Matched route with params or null
|
|
108
|
-
*/
|
|
109
|
-
export function matchRoute(urlPath, routes) {
|
|
110
|
-
// Normalize the URL path
|
|
111
|
-
const normalizedPath = urlPath === '' ? '/' : urlPath;
|
|
112
|
-
|
|
113
|
-
for (const route of routes) {
|
|
114
|
-
const match = normalizedPath.match(route.pattern);
|
|
115
|
-
|
|
116
|
-
if (match) {
|
|
117
|
-
// Extract params from the match
|
|
118
|
-
const params = {};
|
|
119
|
-
const paramNames = (route.path.match(/:[^/]+/g) || []).map(p => p.slice(1));
|
|
120
|
-
|
|
121
|
-
paramNames.forEach((name, index) => {
|
|
122
|
-
params[name] = match[index + 1];
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
...route,
|
|
127
|
-
params
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Invalidates the module cache for hot reload
|
|
137
|
-
*/
|
|
138
|
-
export function invalidateCache(filePath) {
|
|
139
|
-
// For ESM, we use query string cache busting
|
|
140
|
-
return `${filePath}?t=${Date.now()}`;
|
|
141
|
-
}
|
package/core/rsc/index.ts
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FlexiReact React Server Components (RSC) System
|
|
3
|
-
*
|
|
4
|
-
* RSC allows components to run exclusively on the server, reducing client bundle size
|
|
5
|
-
* and enabling direct database/filesystem access in components.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* - Add 'use server' at the top of a component file to make it a Server Component
|
|
9
|
-
* - Add 'use client' at the top to make it a Client Component (hydrated on client)
|
|
10
|
-
* - Server Components can import Client Components, but not vice versa
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import React from 'react';
|
|
14
|
-
import { renderToString } from 'react-dom/server';
|
|
15
|
-
import { isServerComponent, isClientComponent } from '../utils.js';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* RSC Payload format for streaming
|
|
19
|
-
*/
|
|
20
|
-
export const RSC_CONTENT_TYPE = 'text/x-component';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Processes a component tree for RSC
|
|
24
|
-
* Server components are rendered to HTML, client components are serialized
|
|
25
|
-
*/
|
|
26
|
-
export async function processServerComponent(Component, props, context) {
|
|
27
|
-
const componentInfo = {
|
|
28
|
-
isServer: true,
|
|
29
|
-
rendered: null,
|
|
30
|
-
clientComponents: [],
|
|
31
|
-
serverData: {}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
// If component has async data fetching
|
|
36
|
-
if (Component.getServerData) {
|
|
37
|
-
componentInfo.serverData = await Component.getServerData(context);
|
|
38
|
-
props = { ...props, ...componentInfo.serverData };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Render the server component
|
|
42
|
-
const element = React.createElement(Component, props);
|
|
43
|
-
componentInfo.rendered = renderToString(element);
|
|
44
|
-
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error('RSC Error:', error);
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return componentInfo;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Creates a client component reference for RSC payload
|
|
55
|
-
*/
|
|
56
|
-
export function createClientReference(componentPath, props) {
|
|
57
|
-
return {
|
|
58
|
-
$$typeof: Symbol.for('react.client.reference'),
|
|
59
|
-
$$id: componentPath,
|
|
60
|
-
$$props: props
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Serializes RSC payload for streaming
|
|
66
|
-
*/
|
|
67
|
-
export function serializeRSCPayload(componentTree) {
|
|
68
|
-
const payload = {
|
|
69
|
-
type: 'rsc',
|
|
70
|
-
tree: serializeNode(componentTree),
|
|
71
|
-
timestamp: Date.now()
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return JSON.stringify(payload);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Serializes a React node for RSC
|
|
79
|
-
*/
|
|
80
|
-
function serializeNode(node) {
|
|
81
|
-
if (node === null || node === undefined) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (typeof node === 'string' || typeof node === 'number' || typeof node === 'boolean') {
|
|
86
|
-
return node;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (Array.isArray(node)) {
|
|
90
|
-
return node.map(serializeNode);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (React.isValidElement(node)) {
|
|
94
|
-
const { type, props } = node;
|
|
95
|
-
|
|
96
|
-
// Handle client component references
|
|
97
|
-
const typeAny = type as any;
|
|
98
|
-
if (typeAny.$$typeof === Symbol.for('react.client.reference')) {
|
|
99
|
-
return {
|
|
100
|
-
$$type: 'client',
|
|
101
|
-
$$id: typeAny.$$id,
|
|
102
|
-
props: serializeProps(props)
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Handle regular elements
|
|
107
|
-
const typeName = typeof type === 'string' ? type : (typeAny.displayName || typeAny.name || 'Unknown');
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
$$type: 'element',
|
|
111
|
-
type: typeName,
|
|
112
|
-
props: serializeProps(props)
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return String(node);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Serializes props, handling special cases
|
|
121
|
-
*/
|
|
122
|
-
function serializeProps(props: Record<string, any>) {
|
|
123
|
-
const serialized: Record<string, any> = {};
|
|
124
|
-
|
|
125
|
-
for (const [key, value] of Object.entries(props)) {
|
|
126
|
-
if (key === 'children') {
|
|
127
|
-
serialized.children = serializeNode(value);
|
|
128
|
-
} else if (typeof value === 'function') {
|
|
129
|
-
// Functions can't be serialized - mark as client action
|
|
130
|
-
serialized[key] = { $$type: 'action', name: value.name };
|
|
131
|
-
} else if (value instanceof Date) {
|
|
132
|
-
serialized[key] = { $$type: 'date', value: value.toISOString() };
|
|
133
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
134
|
-
serialized[key] = JSON.parse(JSON.stringify(value));
|
|
135
|
-
} else {
|
|
136
|
-
serialized[key] = value;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return serialized;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Server Actions support
|
|
145
|
-
* Allows calling server functions from client components
|
|
146
|
-
*/
|
|
147
|
-
export function createServerAction(fn, actionId) {
|
|
148
|
-
// Mark function as server action
|
|
149
|
-
fn.$$typeof = Symbol.for('react.server.action');
|
|
150
|
-
fn.$$id = actionId;
|
|
151
|
-
|
|
152
|
-
return fn;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Handles server action invocation
|
|
157
|
-
*/
|
|
158
|
-
export async function handleServerAction(actionId, args, context) {
|
|
159
|
-
// Actions are registered during build
|
|
160
|
-
const action = globalThis.__FLEXI_ACTIONS__?.[actionId];
|
|
161
|
-
|
|
162
|
-
if (!action) {
|
|
163
|
-
throw new Error(`Server action not found: ${actionId}`);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return await action(...args, context);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* RSC Boundary component
|
|
171
|
-
* Marks the boundary between server and client rendering
|
|
172
|
-
*/
|
|
173
|
-
export function ServerBoundary({ children, fallback }) {
|
|
174
|
-
return children;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Client Boundary component
|
|
179
|
-
* Marks components that should be hydrated on the client
|
|
180
|
-
*/
|
|
181
|
-
export function ClientBoundary({ children, fallback }) {
|
|
182
|
-
// On server, render children normally
|
|
183
|
-
// On client, this will be hydrated
|
|
184
|
-
return React.createElement('div', {
|
|
185
|
-
'data-flexi-client': 'true',
|
|
186
|
-
children
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export default {
|
|
191
|
-
processServerComponent,
|
|
192
|
-
createClientReference,
|
|
193
|
-
serializeRSCPayload,
|
|
194
|
-
createServerAction,
|
|
195
|
-
handleServerAction,
|
|
196
|
-
ServerBoundary,
|
|
197
|
-
ClientBoundary,
|
|
198
|
-
RSC_CONTENT_TYPE
|
|
199
|
-
};
|