@flight-framework/core 0.4.0 → 0.6.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/dist/adapters/index.d.ts +123 -1
- package/dist/adapters/index.js +1 -1
- package/dist/chunk-56ZZNOJD.js +93 -0
- package/dist/chunk-56ZZNOJD.js.map +1 -0
- package/dist/{chunk-K5NYYNFS.js → chunk-77MJZCYD.js} +46 -3
- package/dist/chunk-77MJZCYD.js.map +1 -0
- package/dist/chunk-RFTE6JVG.js +88 -0
- package/dist/chunk-RFTE6JVG.js.map +1 -0
- package/dist/chunk-WF46NESN.js +67 -0
- package/dist/chunk-WF46NESN.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/env-9do2c6yn.d.ts +42 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/plugins/env-plugin.d.ts +65 -0
- package/dist/plugins/env-plugin.js +3 -0
- package/dist/plugins/env-plugin.js.map +1 -0
- package/dist/plugins/index.d.ts +155 -0
- package/dist/plugins/index.js +150 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/server-boundary-plugin.d.ts +67 -0
- package/dist/plugins/server-boundary-plugin.js +3 -0
- package/dist/plugins/server-boundary-plugin.js.map +1 -0
- package/dist/utils/index.d.ts +83 -28
- package/dist/utils/index.js +1 -1
- package/package.json +13 -3
- package/dist/chunk-K5NYYNFS.js.map +0 -1
- package/dist/chunk-PL37KFRJ.js +0 -3
- package/dist/chunk-PL37KFRJ.js.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @flight-framework/core - Environment Variables Plugin
|
|
5
|
+
*
|
|
6
|
+
* Vite plugin for environment variable protection.
|
|
7
|
+
* OPTIONAL - use if you want build-time protection.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - FLIGHT_PUBLIC_* and VITE_* accessible on client
|
|
11
|
+
* - Other vars replaced with undefined on client
|
|
12
|
+
* - Configurable behavior (warn, error, silent)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // vite.config.ts
|
|
17
|
+
* import { flightEnvPlugin } from '@flight-framework/core/plugins';
|
|
18
|
+
*
|
|
19
|
+
* export default {
|
|
20
|
+
* plugins: [flightEnvPlugin()],
|
|
21
|
+
* };
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
interface FlightEnvPluginOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Prefix for public environment variables.
|
|
28
|
+
* Variables with this prefix will be accessible on the client.
|
|
29
|
+
* @default 'FLIGHT_PUBLIC_'
|
|
30
|
+
*/
|
|
31
|
+
publicPrefix?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Additional prefixes to treat as public.
|
|
34
|
+
* @default ['VITE_']
|
|
35
|
+
*/
|
|
36
|
+
additionalPublicPrefixes?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* How to handle private vars accessed in client code.
|
|
39
|
+
* - 'warn': Log warning, replace with undefined
|
|
40
|
+
* - 'error': Throw build error
|
|
41
|
+
* - 'silent': Replace with undefined, no warning
|
|
42
|
+
* @default 'warn'
|
|
43
|
+
*/
|
|
44
|
+
privateVarBehavior?: 'warn' | 'error' | 'silent';
|
|
45
|
+
/**
|
|
46
|
+
* Specific variables to allow (bypass prefix check).
|
|
47
|
+
* @default ['NODE_ENV', 'MODE']
|
|
48
|
+
*/
|
|
49
|
+
allowList?: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Vite plugin to protect environment variables.
|
|
53
|
+
*
|
|
54
|
+
* This plugin is OPTIONAL. Use it if you want build-time
|
|
55
|
+
* protection for your environment variables.
|
|
56
|
+
*
|
|
57
|
+
* By default, it will:
|
|
58
|
+
* - Allow FLIGHT_PUBLIC_* and VITE_* on client
|
|
59
|
+
* - Allow NODE_ENV and MODE
|
|
60
|
+
* - Replace other process.env.* with undefined on client
|
|
61
|
+
* - Show warnings in development
|
|
62
|
+
*/
|
|
63
|
+
declare function flightEnvPlugin(options?: FlightEnvPluginOptions): Plugin;
|
|
64
|
+
|
|
65
|
+
export { type FlightEnvPluginOptions, flightEnvPlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"env-plugin.js"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { FlightEnvPluginOptions } from './env-plugin.js';
|
|
3
|
+
export { flightEnvPlugin } from './env-plugin.js';
|
|
4
|
+
import { ServerBoundaryPluginOptions } from './server-boundary-plugin.js';
|
|
5
|
+
export { serverBoundaryPlugin } from './server-boundary-plugin.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @flight-framework/core - Critical CSS Plugin
|
|
9
|
+
*
|
|
10
|
+
* Extract and inline critical CSS for improved Core Web Vitals.
|
|
11
|
+
* Uses Critters under the hood for CSS extraction.
|
|
12
|
+
*
|
|
13
|
+
* This is an OPTIONAL plugin. Install 'critters' only if you use it.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // vite.config.ts
|
|
18
|
+
* import { criticalCSS } from '@flight-framework/core/plugins';
|
|
19
|
+
*
|
|
20
|
+
* export default defineConfig({
|
|
21
|
+
* plugins: [
|
|
22
|
+
* criticalCSS({
|
|
23
|
+
* preload: 'swap',
|
|
24
|
+
* pruneSource: false,
|
|
25
|
+
* }),
|
|
26
|
+
* ],
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Preload strategy for non-critical CSS.
|
|
33
|
+
*
|
|
34
|
+
* - 'body': Move stylesheet links to end of body
|
|
35
|
+
* - 'media': Use media="print" and swap to "all" on load
|
|
36
|
+
* - 'swap': Use link rel="preload" and swap to stylesheet
|
|
37
|
+
* - 'swap-high': Like swap, with fetchpriority="high"
|
|
38
|
+
* - 'js': Load via JavaScript
|
|
39
|
+
* - 'js-lazy': Load via JavaScript when idle
|
|
40
|
+
* - false: Don't preload
|
|
41
|
+
*/
|
|
42
|
+
type PreloadStrategy = 'body' | 'media' | 'swap' | 'swap-high' | 'js' | 'js-lazy' | false;
|
|
43
|
+
/**
|
|
44
|
+
* Critical CSS plugin options.
|
|
45
|
+
*/
|
|
46
|
+
interface CriticalCSSOptions {
|
|
47
|
+
/**
|
|
48
|
+
* Enable critical CSS extraction.
|
|
49
|
+
* @default true in production
|
|
50
|
+
*/
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Strategy for loading non-critical CSS.
|
|
54
|
+
* @default 'swap'
|
|
55
|
+
*/
|
|
56
|
+
preload?: PreloadStrategy;
|
|
57
|
+
/**
|
|
58
|
+
* Remove inlined CSS rules from the source stylesheet.
|
|
59
|
+
* Reduces duplicate CSS but may cause issues with JS frameworks.
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
pruneSource?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Remove unused CSS selectors from critical CSS.
|
|
65
|
+
* @default true
|
|
66
|
+
*/
|
|
67
|
+
reduceInlineStyles?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Merge adjacent inline <style> tags.
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
mergeStylesheets?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Additional CSS selectors to always include as critical.
|
|
75
|
+
*/
|
|
76
|
+
additionalStylesheets?: string[];
|
|
77
|
+
/**
|
|
78
|
+
* CSS selectors to exclude from critical extraction.
|
|
79
|
+
*/
|
|
80
|
+
excludeSelectors?: string[];
|
|
81
|
+
/**
|
|
82
|
+
* Routes to include (glob patterns).
|
|
83
|
+
* @default ['**\/*.html']
|
|
84
|
+
*/
|
|
85
|
+
include?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Routes to exclude (glob patterns).
|
|
88
|
+
* @default ['/api/**']
|
|
89
|
+
*/
|
|
90
|
+
exclude?: string[];
|
|
91
|
+
/**
|
|
92
|
+
* Inline external fonts.
|
|
93
|
+
* @default false
|
|
94
|
+
*/
|
|
95
|
+
inlineFonts?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Preload external fonts.
|
|
98
|
+
* @default true
|
|
99
|
+
*/
|
|
100
|
+
preloadFonts?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Maximum size of inlined CSS (in bytes).
|
|
103
|
+
* Larger stylesheets will be loaded normally.
|
|
104
|
+
* @default 100000 (100KB)
|
|
105
|
+
*/
|
|
106
|
+
maxInlinedSize?: number;
|
|
107
|
+
/**
|
|
108
|
+
* Log extraction stats.
|
|
109
|
+
* @default true
|
|
110
|
+
*/
|
|
111
|
+
verbose?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Vite plugin for critical CSS extraction.
|
|
115
|
+
*
|
|
116
|
+
* This plugin extracts critical (above-the-fold) CSS and inlines it
|
|
117
|
+
* in the HTML, deferring non-critical CSS for better performance.
|
|
118
|
+
*
|
|
119
|
+
* Requires 'critters' as a peer dependency:
|
|
120
|
+
* ```bash
|
|
121
|
+
* npm install critters
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @param options - Plugin configuration
|
|
125
|
+
* @returns Vite plugin
|
|
126
|
+
*/
|
|
127
|
+
declare function criticalCSS(options?: CriticalCSSOptions): Plugin;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @flight-framework/core - Build Plugins
|
|
131
|
+
*
|
|
132
|
+
* Optional Vite plugins for advanced optimizations.
|
|
133
|
+
* These plugins are opt-in and require explicit configuration.
|
|
134
|
+
*
|
|
135
|
+
* Flight doesn't force you to use any of these - use them if you want.
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Recommended plugins for most apps.
|
|
140
|
+
* Provides sensible defaults with warnings for violations.
|
|
141
|
+
*/
|
|
142
|
+
declare function flightRecommendedPlugins(options?: {
|
|
143
|
+
env?: FlightEnvPluginOptions;
|
|
144
|
+
serverBoundary?: ServerBoundaryPluginOptions;
|
|
145
|
+
}): Plugin[];
|
|
146
|
+
/**
|
|
147
|
+
* Strict mode plugins - errors instead of warnings.
|
|
148
|
+
* Recommended for production builds.
|
|
149
|
+
*/
|
|
150
|
+
declare function flightStrictPlugins(options?: {
|
|
151
|
+
env?: FlightEnvPluginOptions;
|
|
152
|
+
serverBoundary?: ServerBoundaryPluginOptions;
|
|
153
|
+
}): Plugin[];
|
|
154
|
+
|
|
155
|
+
export { type CriticalCSSOptions, FlightEnvPluginOptions, type PreloadStrategy, ServerBoundaryPluginOptions, criticalCSS, flightRecommendedPlugins, flightStrictPlugins };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { serverBoundaryPlugin } from '../chunk-56ZZNOJD.js';
|
|
2
|
+
export { serverBoundaryPlugin } from '../chunk-56ZZNOJD.js';
|
|
3
|
+
import { flightEnvPlugin } from '../chunk-RFTE6JVG.js';
|
|
4
|
+
export { flightEnvPlugin } from '../chunk-RFTE6JVG.js';
|
|
5
|
+
|
|
6
|
+
// src/plugins/critical-css.ts
|
|
7
|
+
function criticalCSS(options = {}) {
|
|
8
|
+
const {
|
|
9
|
+
preload = "swap",
|
|
10
|
+
pruneSource = false,
|
|
11
|
+
reduceInlineStyles = true,
|
|
12
|
+
mergeStylesheets = true,
|
|
13
|
+
additionalStylesheets = [],
|
|
14
|
+
inlineFonts = false,
|
|
15
|
+
preloadFonts = true,
|
|
16
|
+
maxInlinedSize = 1e5,
|
|
17
|
+
include = ["**/*.html"],
|
|
18
|
+
exclude = ["/api/**"],
|
|
19
|
+
verbose = true
|
|
20
|
+
} = options;
|
|
21
|
+
let config;
|
|
22
|
+
let isProduction = false;
|
|
23
|
+
let enabled = options.enabled;
|
|
24
|
+
let critters = null;
|
|
25
|
+
return {
|
|
26
|
+
name: "flight-critical-css",
|
|
27
|
+
enforce: "post",
|
|
28
|
+
apply: "build",
|
|
29
|
+
configResolved(resolvedConfig) {
|
|
30
|
+
config = resolvedConfig;
|
|
31
|
+
isProduction = resolvedConfig.command === "build";
|
|
32
|
+
if (enabled === void 0) {
|
|
33
|
+
enabled = isProduction;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
async buildStart() {
|
|
37
|
+
if (!enabled) return;
|
|
38
|
+
try {
|
|
39
|
+
const CrittersModule = await import('critters');
|
|
40
|
+
const Critters = CrittersModule.default || CrittersModule;
|
|
41
|
+
const crittersOptions = {
|
|
42
|
+
preload,
|
|
43
|
+
pruneSource,
|
|
44
|
+
reduceInlineStyles,
|
|
45
|
+
mergeStylesheets,
|
|
46
|
+
inlineFonts,
|
|
47
|
+
preloadFonts,
|
|
48
|
+
additionalStylesheets,
|
|
49
|
+
external: true,
|
|
50
|
+
noscriptFallback: true,
|
|
51
|
+
path: config.build.outDir,
|
|
52
|
+
publicPath: config.base || "/",
|
|
53
|
+
logLevel: verbose ? "info" : "silent"
|
|
54
|
+
};
|
|
55
|
+
critters = new Critters(crittersOptions);
|
|
56
|
+
if (verbose) {
|
|
57
|
+
console.log("[flight-critical-css] Critical CSS extraction enabled");
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.warn(
|
|
61
|
+
"[flight-critical-css] Critters not installed. Install with: npm install critters"
|
|
62
|
+
);
|
|
63
|
+
critters = null;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
async transformIndexHtml(html, ctx) {
|
|
67
|
+
if (!enabled || !critters) {
|
|
68
|
+
return html;
|
|
69
|
+
}
|
|
70
|
+
const path = ctx.path || "";
|
|
71
|
+
for (const pattern of exclude) {
|
|
72
|
+
if (matchesPattern(path, pattern)) {
|
|
73
|
+
return html;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
let shouldProcess = false;
|
|
77
|
+
for (const pattern of include) {
|
|
78
|
+
if (matchesPattern(path, pattern)) {
|
|
79
|
+
shouldProcess = true;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!shouldProcess) {
|
|
84
|
+
return html;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const processedHtml = await critters.process(html);
|
|
88
|
+
const inlineStyleMatch = processedHtml.match(/<style[^>]*>([\s\S]*?)<\/style>/gi);
|
|
89
|
+
if (inlineStyleMatch) {
|
|
90
|
+
const totalInlineSize = inlineStyleMatch.reduce(
|
|
91
|
+
(sum, style) => sum + style.length,
|
|
92
|
+
0
|
|
93
|
+
);
|
|
94
|
+
if (totalInlineSize > maxInlinedSize) {
|
|
95
|
+
console.warn(
|
|
96
|
+
`[flight-critical-css] Inline CSS (${totalInlineSize} bytes) exceeds max (${maxInlinedSize} bytes) for ${path}`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (verbose) {
|
|
101
|
+
console.log(`[flight-critical-css] Processed: ${path}`);
|
|
102
|
+
}
|
|
103
|
+
return processedHtml;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(`[flight-critical-css] Error processing ${path}:`, error);
|
|
106
|
+
return html;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
async closeBundle() {
|
|
110
|
+
if (verbose && critters) {
|
|
111
|
+
console.log("[flight-critical-css] Critical CSS extraction complete");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function matchesPattern(path, pattern) {
|
|
117
|
+
const regexPattern = pattern.replace(/\*\*/g, "{{DOUBLE_STAR}}").replace(/\*/g, "[^/]*").replace(/\{\{DOUBLE_STAR\}\}/g, ".*").replace(/\?/g, ".");
|
|
118
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
119
|
+
return regex.test(path);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/plugins/index.ts
|
|
123
|
+
function flightRecommendedPlugins(options) {
|
|
124
|
+
return [
|
|
125
|
+
flightEnvPlugin({
|
|
126
|
+
privateVarBehavior: "warn",
|
|
127
|
+
...options?.env
|
|
128
|
+
}),
|
|
129
|
+
serverBoundaryPlugin({
|
|
130
|
+
violationBehavior: "warn",
|
|
131
|
+
...options?.serverBoundary
|
|
132
|
+
})
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
function flightStrictPlugins(options) {
|
|
136
|
+
return [
|
|
137
|
+
flightEnvPlugin({
|
|
138
|
+
privateVarBehavior: "error",
|
|
139
|
+
...options?.env
|
|
140
|
+
}),
|
|
141
|
+
serverBoundaryPlugin({
|
|
142
|
+
violationBehavior: "error",
|
|
143
|
+
...options?.serverBoundary
|
|
144
|
+
})
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { criticalCSS, flightRecommendedPlugins, flightStrictPlugins };
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
150
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/critical-css.ts","../../src/plugins/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * @flight-framework/core - Critical CSS Plugin\r\n *\r\n * Extract and inline critical CSS for improved Core Web Vitals.\r\n * Uses Critters under the hood for CSS extraction.\r\n *\r\n * This is an OPTIONAL plugin. Install 'critters' only if you use it.\r\n *\r\n * @example\r\n * ```typescript\r\n * // vite.config.ts\r\n * import { criticalCSS } from '@flight-framework/core/plugins';\r\n *\r\n * export default defineConfig({\r\n * plugins: [\r\n * criticalCSS({\r\n * preload: 'swap',\r\n * pruneSource: false,\r\n * }),\r\n * ],\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig } from 'vite';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Preload strategy for non-critical CSS.\r\n *\r\n * - 'body': Move stylesheet links to end of body\r\n * - 'media': Use media=\"print\" and swap to \"all\" on load\r\n * - 'swap': Use link rel=\"preload\" and swap to stylesheet\r\n * - 'swap-high': Like swap, with fetchpriority=\"high\"\r\n * - 'js': Load via JavaScript\r\n * - 'js-lazy': Load via JavaScript when idle\r\n * - false: Don't preload\r\n */\r\nexport type PreloadStrategy =\r\n | 'body'\r\n | 'media'\r\n | 'swap'\r\n | 'swap-high'\r\n | 'js'\r\n | 'js-lazy'\r\n | false;\r\n\r\n/**\r\n * Critical CSS plugin options.\r\n */\r\nexport interface CriticalCSSOptions {\r\n /**\r\n * Enable critical CSS extraction.\r\n * @default true in production\r\n */\r\n enabled?: boolean;\r\n\r\n /**\r\n * Strategy for loading non-critical CSS.\r\n * @default 'swap'\r\n */\r\n preload?: PreloadStrategy;\r\n\r\n /**\r\n * Remove inlined CSS rules from the source stylesheet.\r\n * Reduces duplicate CSS but may cause issues with JS frameworks.\r\n * @default false\r\n */\r\n pruneSource?: boolean;\r\n\r\n /**\r\n * Remove unused CSS selectors from critical CSS.\r\n * @default true\r\n */\r\n reduceInlineStyles?: boolean;\r\n\r\n /**\r\n * Merge adjacent inline <style> tags.\r\n * @default true\r\n */\r\n mergeStylesheets?: boolean;\r\n\r\n /**\r\n * Additional CSS selectors to always include as critical.\r\n */\r\n additionalStylesheets?: string[];\r\n\r\n /**\r\n * CSS selectors to exclude from critical extraction.\r\n */\r\n excludeSelectors?: string[];\r\n\r\n /**\r\n * Routes to include (glob patterns).\r\n * @default ['**\\/*.html']\r\n */\r\n include?: string[];\r\n\r\n /**\r\n * Routes to exclude (glob patterns).\r\n * @default ['/api/**']\r\n */\r\n exclude?: string[];\r\n\r\n /**\r\n * Inline external fonts.\r\n * @default false\r\n */\r\n inlineFonts?: boolean;\r\n\r\n /**\r\n * Preload external fonts.\r\n * @default true\r\n */\r\n preloadFonts?: boolean;\r\n\r\n /**\r\n * Maximum size of inlined CSS (in bytes).\r\n * Larger stylesheets will be loaded normally.\r\n * @default 100000 (100KB)\r\n */\r\n maxInlinedSize?: number;\r\n\r\n /**\r\n * Log extraction stats.\r\n * @default true\r\n */\r\n verbose?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// Critters Integration\r\n// ============================================================================\r\n\r\n/**\r\n * Critters options interface (subset of full Critters options).\r\n * Full options available at: https://github.com/GoogleChromeLabs/critters\r\n */\r\ninterface CrittersOptions {\r\n preload?: PreloadStrategy;\r\n pruneSource?: boolean;\r\n reduceInlineStyles?: boolean;\r\n mergeStylesheets?: boolean;\r\n external?: boolean;\r\n inlineFonts?: boolean;\r\n preloadFonts?: boolean;\r\n additionalStylesheets?: string[];\r\n noscriptFallback?: boolean;\r\n path?: string;\r\n publicPath?: string;\r\n logLevel?: 'info' | 'warn' | 'error' | 'trace' | 'debug' | 'silent';\r\n}\r\n\r\n// ============================================================================\r\n// Vite Plugin\r\n// ============================================================================\r\n\r\n/**\r\n * Vite plugin for critical CSS extraction.\r\n *\r\n * This plugin extracts critical (above-the-fold) CSS and inlines it\r\n * in the HTML, deferring non-critical CSS for better performance.\r\n *\r\n * Requires 'critters' as a peer dependency:\r\n * ```bash\r\n * npm install critters\r\n * ```\r\n *\r\n * @param options - Plugin configuration\r\n * @returns Vite plugin\r\n */\r\nexport function criticalCSS(options: CriticalCSSOptions = {}): Plugin {\r\n const {\r\n preload = 'swap',\r\n pruneSource = false,\r\n reduceInlineStyles = true,\r\n mergeStylesheets = true,\r\n additionalStylesheets = [],\r\n inlineFonts = false,\r\n preloadFonts = true,\r\n maxInlinedSize = 100000,\r\n include = ['**/*.html'],\r\n exclude = ['/api/**'],\r\n verbose = true,\r\n } = options;\r\n\r\n let config: ResolvedConfig;\r\n let isProduction = false;\r\n let enabled = options.enabled;\r\n let critters: {\r\n process: (html: string) => Promise<string>;\r\n } | null = null;\r\n\r\n return {\r\n name: 'flight-critical-css',\r\n enforce: 'post',\r\n apply: 'build',\r\n\r\n configResolved(resolvedConfig) {\r\n config = resolvedConfig;\r\n isProduction = resolvedConfig.command === 'build';\r\n\r\n // Enable by default only in production\r\n if (enabled === undefined) {\r\n enabled = isProduction;\r\n }\r\n },\r\n\r\n async buildStart() {\r\n if (!enabled) return;\r\n\r\n try {\r\n // Dynamic import of Critters (optional peer dependency)\r\n // @ts-expect-error - critters has broken type exports in its package.json\r\n const CrittersModule = await import('critters');\r\n const Critters = CrittersModule.default || CrittersModule;\r\n\r\n const crittersOptions: CrittersOptions = {\r\n preload,\r\n pruneSource,\r\n reduceInlineStyles,\r\n mergeStylesheets,\r\n inlineFonts,\r\n preloadFonts,\r\n additionalStylesheets,\r\n external: true,\r\n noscriptFallback: true,\r\n path: config.build.outDir,\r\n publicPath: config.base || '/',\r\n logLevel: verbose ? 'info' : 'silent',\r\n };\r\n\r\n critters = new Critters(crittersOptions);\r\n\r\n if (verbose) {\r\n console.log('[flight-critical-css] Critical CSS extraction enabled');\r\n }\r\n } catch (error) {\r\n console.warn(\r\n '[flight-critical-css] Critters not installed. Install with: npm install critters'\r\n );\r\n critters = null;\r\n }\r\n },\r\n\r\n async transformIndexHtml(html, ctx) {\r\n if (!enabled || !critters) {\r\n return html;\r\n }\r\n\r\n // Check if this route should be processed\r\n const path = ctx.path || '';\r\n\r\n // Check exclusions\r\n for (const pattern of exclude) {\r\n if (matchesPattern(path, pattern)) {\r\n return html;\r\n }\r\n }\r\n\r\n // Check inclusions\r\n let shouldProcess = false;\r\n for (const pattern of include) {\r\n if (matchesPattern(path, pattern)) {\r\n shouldProcess = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!shouldProcess) {\r\n return html;\r\n }\r\n\r\n try {\r\n const processedHtml = await critters.process(html);\r\n\r\n // Check if critical CSS is too large\r\n const inlineStyleMatch = processedHtml.match(/<style[^>]*>([\\s\\S]*?)<\\/style>/gi);\r\n if (inlineStyleMatch) {\r\n const totalInlineSize = inlineStyleMatch.reduce(\r\n (sum, style) => sum + style.length, 0\r\n );\r\n\r\n if (totalInlineSize > maxInlinedSize) {\r\n console.warn(\r\n `[flight-critical-css] Inline CSS (${totalInlineSize} bytes) exceeds max (${maxInlinedSize} bytes) for ${path}`\r\n );\r\n }\r\n }\r\n\r\n if (verbose) {\r\n console.log(`[flight-critical-css] Processed: ${path}`);\r\n }\r\n\r\n return processedHtml;\r\n } catch (error) {\r\n console.error(`[flight-critical-css] Error processing ${path}:`, error);\r\n return html;\r\n }\r\n },\r\n\r\n async closeBundle() {\r\n if (verbose && critters) {\r\n console.log('[flight-critical-css] Critical CSS extraction complete');\r\n }\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Simple glob pattern matching.\r\n */\r\nfunction matchesPattern(path: string, pattern: string): boolean {\r\n // Convert glob to regex\r\n const regexPattern = pattern\r\n .replace(/\\*\\*/g, '{{DOUBLE_STAR}}')\r\n .replace(/\\*/g, '[^/]*')\r\n .replace(/\\{\\{DOUBLE_STAR\\}\\}/g, '.*')\r\n .replace(/\\?/g, '.');\r\n\r\n const regex = new RegExp(`^${regexPattern}$`);\r\n return regex.test(path);\r\n}\r\n\r\n// ============================================================================\r\n// CSS Optimization Utilities\r\n// ============================================================================\r\n\r\n/**\r\n * Extract inline styles from HTML.\r\n * Utility for manual critical CSS handling.\r\n */\r\nexport function extractInlineStyles(html: string): {\r\n html: string;\r\n styles: string[];\r\n} {\r\n const styles: string[] = [];\r\n const cleanedHtml = html.replace(\r\n /<style[^>]*>([\\s\\S]*?)<\\/style>/gi,\r\n (match, content) => {\r\n styles.push(content);\r\n return '';\r\n }\r\n );\r\n\r\n return { html: cleanedHtml, styles };\r\n}\r\n\r\n/**\r\n * Merge multiple CSS strings into one.\r\n */\r\nexport function mergeCSS(styles: string[]): string {\r\n return styles\r\n .map(s => s.trim())\r\n .filter(Boolean)\r\n .join('\\n');\r\n}\r\n\r\n/**\r\n * Generate a preload link for a stylesheet.\r\n */\r\nexport function generatePreloadLink(\r\n href: string,\r\n strategy: PreloadStrategy\r\n): string {\r\n switch (strategy) {\r\n case 'swap':\r\n return `<link rel=\"preload\" href=\"${href}\" as=\"style\" onload=\"this.onload=null;this.rel='stylesheet'\">`;\r\n case 'swap-high':\r\n return `<link rel=\"preload\" href=\"${href}\" as=\"style\" fetchpriority=\"high\" onload=\"this.onload=null;this.rel='stylesheet'\">`;\r\n case 'media':\r\n return `<link rel=\"stylesheet\" href=\"${href}\" media=\"print\" onload=\"this.media='all'\">`;\r\n case 'js':\r\n return `<script>\r\n (function(){var l=document.createElement('link');l.rel='stylesheet';l.href='${href}';document.head.appendChild(l);})();\r\n </script>`;\r\n case 'js-lazy':\r\n return `<script>\r\n requestIdleCallback(function(){var l=document.createElement('link');l.rel='stylesheet';l.href='${href}';document.head.appendChild(l);});\r\n </script>`;\r\n default:\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Generate noscript fallback for preloaded stylesheet.\r\n */\r\nexport function generateNoscriptFallback(href: string): string {\r\n return `<noscript><link rel=\"stylesheet\" href=\"${href}\"></noscript>`;\r\n}\r\n\r\n// ============================================================================\r\n// Exports\r\n// ============================================================================\r\n\r\nexport default criticalCSS;\r\n","/**\r\n * @flight-framework/core - Build Plugins\r\n *\r\n * Optional Vite plugins for advanced optimizations.\r\n * These plugins are opt-in and require explicit configuration.\r\n * \r\n * Flight doesn't force you to use any of these - use them if you want.\r\n */\r\n\r\n// Critical CSS Plugin (existing)\r\nexport { criticalCSS } from './critical-css.js';\r\nexport type {\r\n CriticalCSSOptions,\r\n PreloadStrategy,\r\n} from './critical-css.js';\r\n\r\n// Environment Variables Plugin (NEW)\r\nexport {\r\n flightEnvPlugin,\r\n type FlightEnvPluginOptions,\r\n} from './env-plugin.js';\r\n\r\n// Server Boundary Plugin (NEW)\r\nexport {\r\n serverBoundaryPlugin,\r\n type ServerBoundaryPluginOptions,\r\n} from './server-boundary-plugin.js';\r\n\r\n// ============================================================================\r\n// Convenience Presets\r\n// ============================================================================\r\n\r\nimport type { Plugin } from 'vite';\r\nimport { flightEnvPlugin, type FlightEnvPluginOptions } from './env-plugin.js';\r\nimport { serverBoundaryPlugin, type ServerBoundaryPluginOptions } from './server-boundary-plugin.js';\r\n\r\n/**\r\n * Recommended plugins for most apps.\r\n * Provides sensible defaults with warnings for violations.\r\n */\r\nexport function flightRecommendedPlugins(options?: {\r\n env?: FlightEnvPluginOptions;\r\n serverBoundary?: ServerBoundaryPluginOptions;\r\n}): Plugin[] {\r\n return [\r\n flightEnvPlugin({\r\n privateVarBehavior: 'warn',\r\n ...options?.env,\r\n }),\r\n serverBoundaryPlugin({\r\n violationBehavior: 'warn',\r\n ...options?.serverBoundary,\r\n }),\r\n ];\r\n}\r\n\r\n/**\r\n * Strict mode plugins - errors instead of warnings.\r\n * Recommended for production builds.\r\n */\r\nexport function flightStrictPlugins(options?: {\r\n env?: FlightEnvPluginOptions;\r\n serverBoundary?: ServerBoundaryPluginOptions;\r\n}): Plugin[] {\r\n return [\r\n flightEnvPlugin({\r\n privateVarBehavior: 'error',\r\n ...options?.env,\r\n }),\r\n serverBoundaryPlugin({\r\n violationBehavior: 'error',\r\n ...options?.serverBoundary,\r\n }),\r\n ];\r\n}\r\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @flight-framework/core - Server Boundary Plugin
|
|
5
|
+
*
|
|
6
|
+
* Vite plugin to detect server-only code imported in client bundles.
|
|
7
|
+
* OPTIONAL - use if you want build-time protection.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Detects *.server.ts files imported in client code
|
|
11
|
+
* - Detects /server/ and /api/ directory imports
|
|
12
|
+
* - Configurable behavior (warn, error)
|
|
13
|
+
* - Clear error messages with solutions
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // vite.config.ts
|
|
18
|
+
* import { serverBoundaryPlugin } from '@flight-framework/core/plugins';
|
|
19
|
+
*
|
|
20
|
+
* export default {
|
|
21
|
+
* plugins: [serverBoundaryPlugin()],
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
interface ServerBoundaryPluginOptions {
|
|
27
|
+
/**
|
|
28
|
+
* File patterns that are server-only.
|
|
29
|
+
* @default ['.server.ts', '.server.tsx', '.server.js', '.server.jsx']
|
|
30
|
+
*/
|
|
31
|
+
serverFilePatterns?: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Directory patterns that are server-only.
|
|
34
|
+
* @default ['/server/', '/api/']
|
|
35
|
+
*/
|
|
36
|
+
serverDirPatterns?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* How to handle violations.
|
|
39
|
+
* - 'error': Build error (recommended for production)
|
|
40
|
+
* - 'warn': Warning only (for migration)
|
|
41
|
+
* @default 'error'
|
|
42
|
+
*/
|
|
43
|
+
violationBehavior?: 'error' | 'warn';
|
|
44
|
+
/**
|
|
45
|
+
* Custom error message template.
|
|
46
|
+
*/
|
|
47
|
+
customErrorMessage?: (module: string, importer: string) => string;
|
|
48
|
+
/**
|
|
49
|
+
* Files to exclude from checking (e.g., tests).
|
|
50
|
+
* @default ['**\/*.test.*', '**\/*.spec.*']
|
|
51
|
+
*/
|
|
52
|
+
exclude?: string[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Vite plugin to detect server-only imports in client code.
|
|
56
|
+
*
|
|
57
|
+
* This plugin is OPTIONAL. Use it if you want build-time
|
|
58
|
+
* detection of server code leaking to the client.
|
|
59
|
+
*
|
|
60
|
+
* By default, it will:
|
|
61
|
+
* - Block imports of *.server.ts files in client code
|
|
62
|
+
* - Block imports from /server/ and /api/ directories
|
|
63
|
+
* - Throw build errors with clear solutions
|
|
64
|
+
*/
|
|
65
|
+
declare function serverBoundaryPlugin(options?: ServerBoundaryPluginOptions): Plugin;
|
|
66
|
+
|
|
67
|
+
export { type ServerBoundaryPluginOptions, serverBoundaryPlugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"server-boundary-plugin.js"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,42 +1,97 @@
|
|
|
1
|
+
export { g as getEnvironment, d as isBrowser, a as isDevelopment, i as isProduction, c as isServer, b as isTest } from '../env-9do2c6yn.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
* @flight-framework/core -
|
|
4
|
+
* @flight-framework/core - Server/Client Boundaries
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Check if running in production environment.
|
|
6
|
+
* Runtime utilities for server/client code separation.
|
|
7
|
+
* These are OPTIONAL - use them if you want safety guards.
|
|
8
|
+
* Flight doesn't force you to use them.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 3. Default: false (not production)
|
|
14
|
-
*/
|
|
15
|
-
declare function isProduction(): boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Check if running in development environment.
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { assertServer, getEnv } from '@flight-framework/core';
|
|
18
13
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
14
|
+
* export async function fetchFromDatabase() {
|
|
15
|
+
* assertServer('fetchFromDatabase'); // Throws if called on client
|
|
16
|
+
* const dbUrl = getEnv('DATABASE_URL'); // Returns undefined on client
|
|
17
|
+
* // ... your code
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
23
20
|
*/
|
|
24
|
-
declare function isDevelopment(): boolean;
|
|
25
21
|
/**
|
|
26
|
-
*
|
|
22
|
+
* Assert that code is running on the server.
|
|
23
|
+
* Throws an error if called from the client (browser).
|
|
24
|
+
*
|
|
25
|
+
* Use this to protect server-only code from being accidentally
|
|
26
|
+
* called on the client.
|
|
27
|
+
*
|
|
28
|
+
* @param context - Optional context string for the error message
|
|
29
|
+
* @throws Error if called on client
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* export async function queryDatabase() {
|
|
34
|
+
* assertServer('queryDatabase');
|
|
35
|
+
* // Safe to use process.env, database connections, etc.
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
27
38
|
*/
|
|
28
|
-
declare function
|
|
39
|
+
declare function assertServer(context?: string): void;
|
|
29
40
|
/**
|
|
30
|
-
*
|
|
41
|
+
* Assert that code is running on the client.
|
|
42
|
+
* Throws an error if called from the server.
|
|
43
|
+
*
|
|
44
|
+
* Use this to protect client-only code (e.g., DOM manipulation,
|
|
45
|
+
* browser APIs) from being accidentally called during SSR.
|
|
46
|
+
*
|
|
47
|
+
* @param context - Optional context string for the error message
|
|
48
|
+
* @throws Error if called on server
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* export function scrollToTop() {
|
|
53
|
+
* assertClient('scrollToTop');
|
|
54
|
+
* window.scrollTo(0, 0);
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
31
57
|
*/
|
|
32
|
-
declare function
|
|
58
|
+
declare function assertClient(context?: string): void;
|
|
33
59
|
/**
|
|
34
|
-
*
|
|
60
|
+
* Get an environment variable safely.
|
|
61
|
+
*
|
|
62
|
+
* On the server: Returns the variable value.
|
|
63
|
+
* On the client: Returns undefined for non-public vars.
|
|
64
|
+
*
|
|
65
|
+
* Public variables (prefixed with FLIGHT_PUBLIC_) are always accessible.
|
|
66
|
+
*
|
|
67
|
+
* @param key - Environment variable name
|
|
68
|
+
* @returns The value or undefined
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* // On server: returns actual value
|
|
73
|
+
* // On client: returns undefined (safe!)
|
|
74
|
+
* const dbUrl = getEnv('DATABASE_URL');
|
|
75
|
+
*
|
|
76
|
+
* // Works on both server and client
|
|
77
|
+
* const apiUrl = getEnv('FLIGHT_PUBLIC_API_URL');
|
|
78
|
+
* ```
|
|
35
79
|
*/
|
|
36
|
-
declare function
|
|
80
|
+
declare function getEnv(key: string): string | undefined;
|
|
37
81
|
/**
|
|
38
|
-
* Get
|
|
82
|
+
* Get an environment variable, throwing if not found.
|
|
83
|
+
* Use this when a variable is required.
|
|
84
|
+
*
|
|
85
|
+
* @param key - Environment variable name
|
|
86
|
+
* @returns The value
|
|
87
|
+
* @throws Error if variable is not set or inaccessible
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* // Throws if DATABASE_URL is not set
|
|
92
|
+
* const dbUrl = requireEnv('DATABASE_URL');
|
|
93
|
+
* ```
|
|
39
94
|
*/
|
|
40
|
-
declare function
|
|
95
|
+
declare function requireEnv(key: string): string;
|
|
41
96
|
|
|
42
|
-
export {
|
|
97
|
+
export { assertClient, assertServer, getEnv, requireEnv };
|
package/dist/utils/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export { assertClient, assertServer, getEnv, requireEnv } from '../chunk-WF46NESN.js';
|
|
2
2
|
export { getEnvironment, isBrowser, isDevelopment, isProduction, isServer, isTest } from '../chunk-YHEVHRLH.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flight-framework/core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Core primitives for Flight Framework - routing, rendering, caching",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Core primitives for Flight Framework - routing, rendering, caching, server/client boundaries",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"flight",
|
|
7
7
|
"framework",
|
|
8
8
|
"core",
|
|
9
9
|
"ssr",
|
|
10
|
-
"routing"
|
|
10
|
+
"routing",
|
|
11
|
+
"server-components",
|
|
12
|
+
"boundaries"
|
|
11
13
|
],
|
|
12
14
|
"license": "MIT",
|
|
13
15
|
"author": "Flight Contributors",
|
|
@@ -182,6 +184,14 @@
|
|
|
182
184
|
"./plugins/critical-css": {
|
|
183
185
|
"types": "./dist/plugins/critical-css.d.ts",
|
|
184
186
|
"import": "./dist/plugins/critical-css.js"
|
|
187
|
+
},
|
|
188
|
+
"./plugins/env": {
|
|
189
|
+
"types": "./dist/plugins/env-plugin.d.ts",
|
|
190
|
+
"import": "./dist/plugins/env-plugin.js"
|
|
191
|
+
},
|
|
192
|
+
"./plugins/server-boundary": {
|
|
193
|
+
"types": "./dist/plugins/server-boundary-plugin.d.ts",
|
|
194
|
+
"import": "./dist/plugins/server-boundary-plugin.js"
|
|
185
195
|
}
|
|
186
196
|
},
|
|
187
197
|
"main": "./dist/index.js",
|