@flexireact/core 1.0.0
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/LICENSE +21 -0
- package/README.md +549 -0
- package/cli/index.js +992 -0
- package/cli/index.ts +1129 -0
- package/core/api.js +143 -0
- package/core/build/index.js +357 -0
- package/core/cli/logger.js +347 -0
- package/core/client/hydration.js +137 -0
- package/core/client/index.js +8 -0
- package/core/client/islands.js +138 -0
- package/core/client/navigation.js +204 -0
- package/core/client/runtime.js +36 -0
- package/core/config.js +113 -0
- package/core/context.js +83 -0
- package/core/dev.js +47 -0
- package/core/index.js +76 -0
- package/core/islands/index.js +281 -0
- package/core/loader.js +111 -0
- package/core/logger.js +242 -0
- package/core/middleware/index.js +393 -0
- package/core/plugins/index.js +370 -0
- package/core/render/index.js +765 -0
- package/core/render.js +134 -0
- package/core/router/index.js +296 -0
- package/core/router.js +141 -0
- package/core/rsc/index.js +198 -0
- package/core/server/index.js +653 -0
- package/core/server.js +197 -0
- package/core/ssg/index.js +321 -0
- package/core/utils.js +176 -0
- package/package.json +73 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexiReact Client Navigation
|
|
3
|
+
* Client-side navigation with prefetching
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
// Navigation state
|
|
9
|
+
const navigationState = {
|
|
10
|
+
listeners: new Set(),
|
|
11
|
+
prefetched: new Set()
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Navigates to a new URL
|
|
16
|
+
*/
|
|
17
|
+
export function navigate(url, options = {}) {
|
|
18
|
+
const { replace = false, scroll = true } = options;
|
|
19
|
+
|
|
20
|
+
if (replace) {
|
|
21
|
+
window.history.replaceState({}, '', url);
|
|
22
|
+
} else {
|
|
23
|
+
window.history.pushState({}, '', url);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Dispatch navigation event
|
|
27
|
+
window.dispatchEvent(new CustomEvent('flexi:navigate', {
|
|
28
|
+
detail: { url, replace, scroll }
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
// Scroll to top if needed
|
|
32
|
+
if (scroll) {
|
|
33
|
+
window.scrollTo(0, 0);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Notify listeners
|
|
37
|
+
navigationState.listeners.forEach(listener => listener(url));
|
|
38
|
+
|
|
39
|
+
// Fetch and render new page
|
|
40
|
+
return fetchAndRender(url);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Prefetches a URL for faster navigation
|
|
45
|
+
*/
|
|
46
|
+
export function prefetch(url) {
|
|
47
|
+
if (navigationState.prefetched.has(url)) {
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
navigationState.prefetched.add(url);
|
|
52
|
+
|
|
53
|
+
// Create a link element for prefetching
|
|
54
|
+
const link = document.createElement('link');
|
|
55
|
+
link.rel = 'prefetch';
|
|
56
|
+
link.href = url;
|
|
57
|
+
document.head.appendChild(link);
|
|
58
|
+
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Fetches and renders a new page
|
|
64
|
+
*/
|
|
65
|
+
async function fetchAndRender(url) {
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
headers: {
|
|
69
|
+
'X-Flexi-Navigation': 'true'
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new Error(`Navigation failed: ${response.status}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const html = await response.text();
|
|
78
|
+
|
|
79
|
+
// Parse the HTML
|
|
80
|
+
const parser = new DOMParser();
|
|
81
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
82
|
+
|
|
83
|
+
// Update the page content
|
|
84
|
+
const newRoot = doc.getElementById('root');
|
|
85
|
+
const currentRoot = document.getElementById('root');
|
|
86
|
+
|
|
87
|
+
if (newRoot && currentRoot) {
|
|
88
|
+
currentRoot.innerHTML = newRoot.innerHTML;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Update the title
|
|
92
|
+
document.title = doc.title;
|
|
93
|
+
|
|
94
|
+
// Update meta tags
|
|
95
|
+
updateMetaTags(doc);
|
|
96
|
+
|
|
97
|
+
// Re-hydrate islands
|
|
98
|
+
window.dispatchEvent(new CustomEvent('flexi:pageload'));
|
|
99
|
+
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('Navigation error:', error);
|
|
102
|
+
// Fallback to full page navigation
|
|
103
|
+
window.location.href = url;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Updates meta tags from new document
|
|
109
|
+
*/
|
|
110
|
+
function updateMetaTags(doc) {
|
|
111
|
+
// Remove old meta tags
|
|
112
|
+
document.querySelectorAll('meta[data-flexi]').forEach(el => el.remove());
|
|
113
|
+
|
|
114
|
+
// Add new meta tags
|
|
115
|
+
doc.querySelectorAll('meta').forEach(meta => {
|
|
116
|
+
if (meta.name || meta.property) {
|
|
117
|
+
const newMeta = meta.cloneNode(true);
|
|
118
|
+
newMeta.setAttribute('data-flexi', 'true');
|
|
119
|
+
document.head.appendChild(newMeta);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Link component for client-side navigation
|
|
126
|
+
*/
|
|
127
|
+
export function Link({ href, children, prefetch: shouldPrefetch = true, replace = false, className, ...props }) {
|
|
128
|
+
const handleClick = (e) => {
|
|
129
|
+
// Allow normal navigation for external links or modified clicks
|
|
130
|
+
if (
|
|
131
|
+
e.ctrlKey ||
|
|
132
|
+
e.metaKey ||
|
|
133
|
+
e.shiftKey ||
|
|
134
|
+
e.button !== 0 ||
|
|
135
|
+
href.startsWith('http') ||
|
|
136
|
+
href.startsWith('//')
|
|
137
|
+
) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
e.preventDefault();
|
|
142
|
+
navigate(href, { replace });
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const handleMouseEnter = () => {
|
|
146
|
+
if (shouldPrefetch) {
|
|
147
|
+
prefetch(href);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
return React.createElement('a', {
|
|
152
|
+
href,
|
|
153
|
+
onClick: handleClick,
|
|
154
|
+
onMouseEnter: handleMouseEnter,
|
|
155
|
+
className,
|
|
156
|
+
...props
|
|
157
|
+
}, children);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Hook to listen for navigation events
|
|
162
|
+
*/
|
|
163
|
+
export function useNavigation() {
|
|
164
|
+
const [pathname, setPathname] = React.useState(
|
|
165
|
+
typeof window !== 'undefined' ? window.location.pathname : '/'
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
React.useEffect(() => {
|
|
169
|
+
const handleNavigation = (url) => {
|
|
170
|
+
setPathname(new URL(url, window.location.origin).pathname);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
navigationState.listeners.add(handleNavigation);
|
|
174
|
+
|
|
175
|
+
const handlePopState = () => {
|
|
176
|
+
setPathname(window.location.pathname);
|
|
177
|
+
navigationState.listeners.forEach(listener => listener(window.location.pathname));
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
window.addEventListener('popstate', handlePopState);
|
|
181
|
+
|
|
182
|
+
return () => {
|
|
183
|
+
navigationState.listeners.delete(handleNavigation);
|
|
184
|
+
window.removeEventListener('popstate', handlePopState);
|
|
185
|
+
};
|
|
186
|
+
}, []);
|
|
187
|
+
|
|
188
|
+
return { pathname, navigate, prefetch };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Setup popstate listener
|
|
192
|
+
if (typeof window !== 'undefined') {
|
|
193
|
+
window.addEventListener('popstate', () => {
|
|
194
|
+
const url = window.location.pathname + window.location.search;
|
|
195
|
+
navigationState.listeners.forEach(listener => listener(url));
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export default {
|
|
200
|
+
navigate,
|
|
201
|
+
prefetch,
|
|
202
|
+
Link,
|
|
203
|
+
useNavigation
|
|
204
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexiReact Client Runtime
|
|
3
|
+
* Main entry point for client-side JavaScript
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { hydrateAllIslands, setupProgressiveHydration } from './hydration.js';
|
|
7
|
+
import { navigate, prefetch } from './navigation.js';
|
|
8
|
+
|
|
9
|
+
// Expose to global scope
|
|
10
|
+
window.FlexiReact = {
|
|
11
|
+
navigate,
|
|
12
|
+
prefetch,
|
|
13
|
+
hydrateAllIslands,
|
|
14
|
+
setupProgressiveHydration
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Auto-setup on page load
|
|
18
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
19
|
+
// Setup progressive hydration for islands
|
|
20
|
+
if (window.__FLEXI_DATA__?.islands) {
|
|
21
|
+
setupProgressiveHydration(window.__FLEXI_DATA__.islands);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Dispatch ready event
|
|
25
|
+
window.dispatchEvent(new CustomEvent('flexi:ready'));
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Handle page transitions
|
|
29
|
+
window.addEventListener('flexi:pageload', () => {
|
|
30
|
+
// Re-setup hydration after navigation
|
|
31
|
+
if (window.__FLEXI_DATA__?.islands) {
|
|
32
|
+
setupProgressiveHydration(window.__FLEXI_DATA__.islands);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log('⚡ FlexiReact v2 client runtime loaded');
|
package/core/config.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexiReact Configuration System
|
|
3
|
+
* Handles loading and merging of configuration from flexireact.config.js
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { pathToFileURL } from 'url';
|
|
9
|
+
|
|
10
|
+
// Default configuration
|
|
11
|
+
export const defaultConfig = {
|
|
12
|
+
// Directories
|
|
13
|
+
pagesDir: 'pages',
|
|
14
|
+
layoutsDir: 'layouts',
|
|
15
|
+
publicDir: 'public',
|
|
16
|
+
outDir: '.flexi',
|
|
17
|
+
|
|
18
|
+
// Build options
|
|
19
|
+
build: {
|
|
20
|
+
target: 'es2022',
|
|
21
|
+
minify: true,
|
|
22
|
+
sourcemap: true,
|
|
23
|
+
splitting: true
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Server options
|
|
27
|
+
server: {
|
|
28
|
+
port: 3000,
|
|
29
|
+
host: 'localhost'
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
// SSG options
|
|
33
|
+
ssg: {
|
|
34
|
+
enabled: false,
|
|
35
|
+
paths: []
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// Islands (partial hydration)
|
|
39
|
+
islands: {
|
|
40
|
+
enabled: true
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// RSC options
|
|
44
|
+
rsc: {
|
|
45
|
+
enabled: true
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// Plugins
|
|
49
|
+
plugins: [],
|
|
50
|
+
|
|
51
|
+
// Styles (CSS files to include)
|
|
52
|
+
styles: [],
|
|
53
|
+
|
|
54
|
+
// Scripts (JS files to include)
|
|
55
|
+
scripts: [],
|
|
56
|
+
|
|
57
|
+
// Favicon path
|
|
58
|
+
favicon: null
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Loads configuration from the project root
|
|
63
|
+
* @param {string} projectRoot - Path to project root
|
|
64
|
+
* @returns {Object} Merged configuration
|
|
65
|
+
*/
|
|
66
|
+
export async function loadConfig(projectRoot) {
|
|
67
|
+
const configPath = path.join(projectRoot, 'flexireact.config.js');
|
|
68
|
+
|
|
69
|
+
let userConfig = {};
|
|
70
|
+
|
|
71
|
+
if (fs.existsSync(configPath)) {
|
|
72
|
+
try {
|
|
73
|
+
const configUrl = pathToFileURL(configPath).href;
|
|
74
|
+
const module = await import(`${configUrl}?t=${Date.now()}`);
|
|
75
|
+
userConfig = module.default || module;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.warn('Warning: Failed to load flexireact.config.js:', error.message);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Deep merge configs
|
|
82
|
+
return deepMerge(defaultConfig, userConfig);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Deep merge two objects
|
|
87
|
+
*/
|
|
88
|
+
function deepMerge(target, source) {
|
|
89
|
+
const result = { ...target };
|
|
90
|
+
|
|
91
|
+
for (const key in source) {
|
|
92
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
93
|
+
result[key] = deepMerge(target[key] || {}, source[key]);
|
|
94
|
+
} else {
|
|
95
|
+
result[key] = source[key];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Resolves all paths in config relative to project root
|
|
104
|
+
*/
|
|
105
|
+
export function resolvePaths(config, projectRoot) {
|
|
106
|
+
return {
|
|
107
|
+
...config,
|
|
108
|
+
pagesDir: path.resolve(projectRoot, config.pagesDir),
|
|
109
|
+
layoutsDir: path.resolve(projectRoot, config.layoutsDir),
|
|
110
|
+
publicDir: path.resolve(projectRoot, config.publicDir),
|
|
111
|
+
outDir: path.resolve(projectRoot, config.outDir)
|
|
112
|
+
};
|
|
113
|
+
}
|
package/core/context.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexiReact Context System
|
|
3
|
+
* Provides request context and shared state for SSR/RSC
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
// Server-side request context
|
|
9
|
+
export const RequestContext = React.createContext(null);
|
|
10
|
+
|
|
11
|
+
// Route context for nested routes
|
|
12
|
+
export const RouteContext = React.createContext(null);
|
|
13
|
+
|
|
14
|
+
// Layout context
|
|
15
|
+
export const LayoutContext = React.createContext(null);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a request context value
|
|
19
|
+
*/
|
|
20
|
+
export function createRequestContext(req, res, params = {}, query = {}) {
|
|
21
|
+
return {
|
|
22
|
+
req,
|
|
23
|
+
res,
|
|
24
|
+
params,
|
|
25
|
+
query,
|
|
26
|
+
url: req.url,
|
|
27
|
+
method: req.method,
|
|
28
|
+
headers: req.headers,
|
|
29
|
+
cookies: parseCookies(req.headers.cookie || '')
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parse cookies from header string
|
|
35
|
+
*/
|
|
36
|
+
function parseCookies(cookieHeader) {
|
|
37
|
+
const cookies = {};
|
|
38
|
+
if (!cookieHeader) return cookies;
|
|
39
|
+
|
|
40
|
+
cookieHeader.split(';').forEach(cookie => {
|
|
41
|
+
const [name, ...rest] = cookie.split('=');
|
|
42
|
+
if (name) {
|
|
43
|
+
cookies[name.trim()] = rest.join('=').trim();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return cookies;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Hook to access request context (server-side only)
|
|
52
|
+
*/
|
|
53
|
+
export function useRequest() {
|
|
54
|
+
const context = React.useContext(RequestContext);
|
|
55
|
+
if (!context) {
|
|
56
|
+
throw new Error('useRequest must be used within a RequestContext provider');
|
|
57
|
+
}
|
|
58
|
+
return context;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Hook to access route params
|
|
63
|
+
*/
|
|
64
|
+
export function useParams() {
|
|
65
|
+
const context = React.useContext(RouteContext);
|
|
66
|
+
return context?.params || {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Hook to access query parameters
|
|
71
|
+
*/
|
|
72
|
+
export function useQuery() {
|
|
73
|
+
const context = React.useContext(RouteContext);
|
|
74
|
+
return context?.query || {};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Hook to access current pathname
|
|
79
|
+
*/
|
|
80
|
+
export function usePathname() {
|
|
81
|
+
const context = React.useContext(RouteContext);
|
|
82
|
+
return context?.pathname || '/';
|
|
83
|
+
}
|
package/core/dev.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FlexiReact Dev Server Launcher
|
|
5
|
+
* This script starts the server with the JSX loader enabled
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
const serverPath = path.join(__dirname, 'server.js');
|
|
16
|
+
const loaderPath = path.join(__dirname, 'loader.js');
|
|
17
|
+
|
|
18
|
+
// Convert to file:// URLs for Windows compatibility
|
|
19
|
+
const loaderUrl = pathToFileURL(loaderPath).href;
|
|
20
|
+
|
|
21
|
+
// Start Node.js with the custom loader
|
|
22
|
+
const child = spawn(
|
|
23
|
+
process.execPath,
|
|
24
|
+
[
|
|
25
|
+
'--import',
|
|
26
|
+
`data:text/javascript,import { register } from 'node:module'; register('${loaderUrl.replace(/\\/g, '/')}', import.meta.url);`,
|
|
27
|
+
serverPath
|
|
28
|
+
],
|
|
29
|
+
{
|
|
30
|
+
stdio: 'inherit',
|
|
31
|
+
cwd: process.cwd(),
|
|
32
|
+
env: process.env
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
child.on('error', (error) => {
|
|
37
|
+
console.error('Failed to start server:', error);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
child.on('exit', (code) => {
|
|
42
|
+
process.exit(code || 0);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Forward signals to child process
|
|
46
|
+
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
47
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
package/core/index.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexiReact v2 - Main Entry Point
|
|
3
|
+
* A modern React framework with RSC, SSG, Islands, and more
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Core exports
|
|
7
|
+
export { loadConfig, defaultConfig, resolvePaths } from './config.js';
|
|
8
|
+
export { createRequestContext, useRequest, useParams, useQuery, usePathname } from './context.js';
|
|
9
|
+
export * from './utils.js';
|
|
10
|
+
|
|
11
|
+
// Router
|
|
12
|
+
export { buildRouteTree, matchRoute, findRouteLayouts, RouteType } from './router/index.js';
|
|
13
|
+
|
|
14
|
+
// Render
|
|
15
|
+
export { renderPage, renderError, renderLoading } from './render/index.js';
|
|
16
|
+
|
|
17
|
+
// Server
|
|
18
|
+
export { createServer } from './server/index.js';
|
|
19
|
+
|
|
20
|
+
// Build
|
|
21
|
+
export { build, buildDev, BuildMode } from './build/index.js';
|
|
22
|
+
|
|
23
|
+
// SSG
|
|
24
|
+
export { generateStaticSite, SSGResult, ISRManager } from './ssg/index.js';
|
|
25
|
+
|
|
26
|
+
// RSC
|
|
27
|
+
export {
|
|
28
|
+
processServerComponent,
|
|
29
|
+
createClientReference,
|
|
30
|
+
serializeRSCPayload,
|
|
31
|
+
createServerAction,
|
|
32
|
+
handleServerAction,
|
|
33
|
+
ServerBoundary,
|
|
34
|
+
ClientBoundary,
|
|
35
|
+
RSC_CONTENT_TYPE
|
|
36
|
+
} from './rsc/index.js';
|
|
37
|
+
|
|
38
|
+
// Islands
|
|
39
|
+
export {
|
|
40
|
+
Island,
|
|
41
|
+
createIsland,
|
|
42
|
+
createLazyIsland,
|
|
43
|
+
getRegisteredIslands,
|
|
44
|
+
generateHydrationScript,
|
|
45
|
+
generateAdvancedHydrationScript,
|
|
46
|
+
LoadStrategy
|
|
47
|
+
} from './islands/index.js';
|
|
48
|
+
|
|
49
|
+
// Middleware
|
|
50
|
+
export {
|
|
51
|
+
MiddlewareRequest,
|
|
52
|
+
MiddlewareResponse,
|
|
53
|
+
loadMiddleware,
|
|
54
|
+
runMiddleware,
|
|
55
|
+
composeMiddleware,
|
|
56
|
+
middlewares
|
|
57
|
+
} from './middleware/index.js';
|
|
58
|
+
|
|
59
|
+
// Plugins
|
|
60
|
+
export {
|
|
61
|
+
PluginManager,
|
|
62
|
+
PluginHooks,
|
|
63
|
+
pluginManager,
|
|
64
|
+
loadPlugins,
|
|
65
|
+
definePlugin,
|
|
66
|
+
builtinPlugins
|
|
67
|
+
} from './plugins/index.js';
|
|
68
|
+
|
|
69
|
+
// Version
|
|
70
|
+
export const VERSION = '2.0.0';
|
|
71
|
+
|
|
72
|
+
// Default export
|
|
73
|
+
export default {
|
|
74
|
+
VERSION,
|
|
75
|
+
createServer
|
|
76
|
+
};
|