@cmj/juice 0.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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -0
  3. package/dist/cli/commands.d.ts +29 -0
  4. package/dist/cli/commands.d.ts.map +1 -0
  5. package/dist/cli/commands.js +102 -0
  6. package/dist/cli/commands.js.map +1 -0
  7. package/dist/cli/create.d.ts +35 -0
  8. package/dist/cli/create.d.ts.map +1 -0
  9. package/dist/cli/create.js +108 -0
  10. package/dist/cli/create.js.map +1 -0
  11. package/dist/cli/index.d.ts +3 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +97 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/templates.d.ts +14 -0
  16. package/dist/cli/templates.d.ts.map +1 -0
  17. package/dist/cli/templates.js +154 -0
  18. package/dist/cli/templates.js.map +1 -0
  19. package/dist/compiler/errors.d.ts +91 -0
  20. package/dist/compiler/errors.d.ts.map +1 -0
  21. package/dist/compiler/errors.js +110 -0
  22. package/dist/compiler/errors.js.map +1 -0
  23. package/dist/compiler/manifest.d.ts +39 -0
  24. package/dist/compiler/manifest.d.ts.map +1 -0
  25. package/dist/compiler/manifest.js +78 -0
  26. package/dist/compiler/manifest.js.map +1 -0
  27. package/dist/compiler/parse.d.ts +126 -0
  28. package/dist/compiler/parse.d.ts.map +1 -0
  29. package/dist/compiler/parse.js +246 -0
  30. package/dist/compiler/parse.js.map +1 -0
  31. package/dist/compiler/plugin.d.ts +43 -0
  32. package/dist/compiler/plugin.d.ts.map +1 -0
  33. package/dist/compiler/plugin.js +281 -0
  34. package/dist/compiler/plugin.js.map +1 -0
  35. package/dist/compiler/proxy.d.ts +42 -0
  36. package/dist/compiler/proxy.d.ts.map +1 -0
  37. package/dist/compiler/proxy.js +80 -0
  38. package/dist/compiler/proxy.js.map +1 -0
  39. package/dist/compiler/registry.d.ts +58 -0
  40. package/dist/compiler/registry.d.ts.map +1 -0
  41. package/dist/compiler/registry.js +79 -0
  42. package/dist/compiler/registry.js.map +1 -0
  43. package/dist/compiler/server-action-registry.d.ts +57 -0
  44. package/dist/compiler/server-action-registry.d.ts.map +1 -0
  45. package/dist/compiler/server-action-registry.js +76 -0
  46. package/dist/compiler/server-action-registry.js.map +1 -0
  47. package/dist/compiler/server-actions.d.ts +49 -0
  48. package/dist/compiler/server-actions.d.ts.map +1 -0
  49. package/dist/compiler/server-actions.js +89 -0
  50. package/dist/compiler/server-actions.js.map +1 -0
  51. package/dist/compiler/types.d.ts +188 -0
  52. package/dist/compiler/types.d.ts.map +1 -0
  53. package/dist/compiler/types.js +9 -0
  54. package/dist/compiler/types.js.map +1 -0
  55. package/dist/runtime/actions.d.ts +37 -0
  56. package/dist/runtime/actions.d.ts.map +1 -0
  57. package/dist/runtime/actions.js +167 -0
  58. package/dist/runtime/actions.js.map +1 -0
  59. package/dist/runtime/dev.d.ts +43 -0
  60. package/dist/runtime/dev.d.ts.map +1 -0
  61. package/dist/runtime/dev.js +260 -0
  62. package/dist/runtime/dev.js.map +1 -0
  63. package/dist/runtime/errors.d.ts +98 -0
  64. package/dist/runtime/errors.d.ts.map +1 -0
  65. package/dist/runtime/errors.js +124 -0
  66. package/dist/runtime/errors.js.map +1 -0
  67. package/dist/runtime/index.d.ts +3 -0
  68. package/dist/runtime/index.d.ts.map +1 -0
  69. package/dist/runtime/index.js +5 -0
  70. package/dist/runtime/index.js.map +1 -0
  71. package/dist/runtime/matcher.d.ts +44 -0
  72. package/dist/runtime/matcher.d.ts.map +1 -0
  73. package/dist/runtime/matcher.js +83 -0
  74. package/dist/runtime/matcher.js.map +1 -0
  75. package/dist/runtime/render.d.ts +25 -0
  76. package/dist/runtime/render.d.ts.map +1 -0
  77. package/dist/runtime/render.js +141 -0
  78. package/dist/runtime/render.js.map +1 -0
  79. package/dist/runtime/resolve.d.ts +24 -0
  80. package/dist/runtime/resolve.d.ts.map +1 -0
  81. package/dist/runtime/resolve.js +41 -0
  82. package/dist/runtime/resolve.js.map +1 -0
  83. package/dist/runtime/router.d.ts +74 -0
  84. package/dist/runtime/router.d.ts.map +1 -0
  85. package/dist/runtime/router.js +367 -0
  86. package/dist/runtime/router.js.map +1 -0
  87. package/dist/runtime/types.d.ts +245 -0
  88. package/dist/runtime/types.d.ts.map +1 -0
  89. package/dist/runtime/types.js +5 -0
  90. package/dist/runtime/types.js.map +1 -0
  91. package/package.json +92 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * AST-based detection of `'use client'` and `'use server'` directives
3
+ * and export extraction.
4
+ *
5
+ * Uses Vite's built-in acorn parser via the Rollup plugin context — zero
6
+ * additional dependencies.
7
+ *
8
+ * @module parse
9
+ * @internal
10
+ */
11
+ // ---------------------------------------------------------------------------
12
+ // Fast-path substring check
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Quick check for the `'use client'` substring before doing a full AST parse.
16
+ * Returns `false` if the directive cannot possibly be present.
17
+ *
18
+ * @internal
19
+ */
20
+ export function _mayContainClientDirective(source) {
21
+ return source.includes('use client');
22
+ }
23
+ /**
24
+ * Quick check for the `'use server'` substring before doing a full AST parse.
25
+ * Returns `false` if the directive cannot possibly be present.
26
+ *
27
+ * @internal
28
+ */
29
+ export function _mayContainServerDirective(source) {
30
+ return source.includes('use server');
31
+ }
32
+ /**
33
+ * Quick check for either `'use client'` or `'use server'` substrings.
34
+ * Returns `false` if neither directive can possibly be present.
35
+ *
36
+ * @internal
37
+ */
38
+ export function _mayContainDirective(source) {
39
+ return _mayContainClientDirective(source) || _mayContainServerDirective(source);
40
+ }
41
+ /**
42
+ * Analyze a parsed AST `Program` node for a `'use client'` directive and
43
+ * extract all exports if found.
44
+ *
45
+ * The directive MUST be the first statement in the module body (after optional
46
+ * comments). If `'use client'` appears anywhere other than position 0, this
47
+ * function returns `{ hasDirective: false }` — no false positives.
48
+ *
49
+ * @param ast - The acorn `Program` AST node (from `this.parse()` in Rollup context).
50
+ * @returns A {@link DirectiveResult} indicating whether the directive was found
51
+ * and, if so, all exports extracted from the module.
52
+ *
53
+ * @internal
54
+ */
55
+ export function _analyzeAST(ast) {
56
+ const program = ast;
57
+ if (!program.body || program.body.length === 0) {
58
+ return { hasDirective: false };
59
+ }
60
+ // The directive must be the very first statement
61
+ const firstNode = program.body[0];
62
+ if (!firstNode || !_isDirective(firstNode, 'use client')) {
63
+ return { hasDirective: false };
64
+ }
65
+ // Directive confirmed — extract all exports
66
+ const exports = _extractExports(program.body);
67
+ return { hasDirective: true, exports };
68
+ }
69
+ /**
70
+ * Analyze a parsed AST `Program` node for a `'use server'` directive and
71
+ * extract all exports if found.
72
+ *
73
+ * The directive MUST be the first statement in the module body (after optional
74
+ * comments). If `'use server'` appears anywhere other than position 0, this
75
+ * function returns `{ hasDirective: false }` — no false positives.
76
+ *
77
+ * @param ast - The acorn `Program` AST node (from `this.parse()` in Rollup context).
78
+ * @returns A {@link ServerDirectiveResult} indicating whether the directive was found
79
+ * and, if so, all exports extracted from the module.
80
+ *
81
+ * @internal
82
+ */
83
+ export function _analyzeServerAST(ast) {
84
+ const program = ast;
85
+ if (!program.body || program.body.length === 0) {
86
+ return { hasDirective: false };
87
+ }
88
+ // The directive must be the very first statement
89
+ const firstNode = program.body[0];
90
+ if (!firstNode || !_isDirective(firstNode, 'use server')) {
91
+ return { hasDirective: false };
92
+ }
93
+ // Directive confirmed — extract all exports
94
+ const exports = _extractExports(program.body);
95
+ return { hasDirective: true, exports };
96
+ }
97
+ /**
98
+ * Detect the directive (if any), extract exports, and perform validation
99
+ * checks in a single AST pass for the hardened pipeline.
100
+ *
101
+ * Advantages over calling `_analyzeAST` + `_analyzeServerAST` separately:
102
+ * - Single AST walk (not two)
103
+ * - Catches mutual exclusion (`'use client'` + `'use server'` simultaneously)
104
+ * - Detects barrel re-exports (`export *`) for a clear error
105
+ *
106
+ * @param ast - The acorn `Program` AST node.
107
+ * @returns A {@link UnifiedDirectiveResult} with all extracted information.
108
+ *
109
+ * @internal
110
+ */
111
+ export function _detectDirective(ast) {
112
+ const program = ast;
113
+ const empty = {
114
+ directive: null,
115
+ exports: [],
116
+ barrelReExports: [],
117
+ hasMutualExclusion: false,
118
+ };
119
+ if (!program.body || program.body.length === 0) {
120
+ return empty;
121
+ }
122
+ const firstNode = program.body[0];
123
+ if (!firstNode) {
124
+ return empty;
125
+ }
126
+ // Determine which directive (if any) is at position 0
127
+ const isClient = _isDirective(firstNode, 'use client');
128
+ const isServer = _isDirective(firstNode, 'use server');
129
+ if (!isClient && !isServer) {
130
+ return empty;
131
+ }
132
+ // Check for mutual exclusion: scan remaining body for the other directive
133
+ let hasMutualExclusion = false;
134
+ const otherDirective = isClient ? 'use server' : 'use client';
135
+ for (let i = 1; i < program.body.length; i++) {
136
+ const node = program.body[i];
137
+ if (node && _isDirective(node, otherDirective)) {
138
+ hasMutualExclusion = true;
139
+ break;
140
+ }
141
+ }
142
+ // Extract exports and barrel re-exports
143
+ const exports = _extractExports(program.body);
144
+ const barrelReExports = _extractBarrelReExports(program.body);
145
+ return {
146
+ directive: isClient ? 'use client' : 'use server',
147
+ exports,
148
+ barrelReExports,
149
+ hasMutualExclusion,
150
+ };
151
+ }
152
+ // ---------------------------------------------------------------------------
153
+ // Internal helpers
154
+ // ---------------------------------------------------------------------------
155
+ /**
156
+ * Check if an AST node is a directive expression statement with the given value.
157
+ *
158
+ * Handles both the `directive` shorthand (acorn option) and the raw
159
+ * `ExpressionStatement > Literal` pattern.
160
+ *
161
+ * @internal
162
+ */
163
+ function _isDirective(node, directive) {
164
+ if (node.type !== 'ExpressionStatement') {
165
+ return false;
166
+ }
167
+ const stmt = node;
168
+ // Acorn's `directive` property (when `allowReserved` is set)
169
+ if (stmt.directive === directive) {
170
+ return true;
171
+ }
172
+ // Fallback: raw literal check
173
+ const expr = stmt.expression;
174
+ if (expr.type === 'Literal' && expr.value === directive) {
175
+ return true;
176
+ }
177
+ return false;
178
+ }
179
+ /**
180
+ * Walk the program body and extract all named and default exports.
181
+ *
182
+ * @internal
183
+ */
184
+ function _extractExports(body) {
185
+ const records = [];
186
+ for (const node of body) {
187
+ switch (node.type) {
188
+ case 'ExportDefaultDeclaration': {
189
+ const decl = node;
190
+ const localName = decl.declaration.id?.name ?? 'default';
191
+ records.push({ exportedName: 'default', localName });
192
+ break;
193
+ }
194
+ case 'ExportNamedDeclaration': {
195
+ const named = node;
196
+ // `export function Foo() {}` / `export const Foo = ...`
197
+ if (named.declaration) {
198
+ const decl = named.declaration;
199
+ if (decl.id) {
200
+ records.push({ exportedName: decl.id.name, localName: decl.id.name });
201
+ }
202
+ else if (decl.declarations) {
203
+ for (const varDecl of decl.declarations) {
204
+ records.push({ exportedName: varDecl.id.name, localName: varDecl.id.name });
205
+ }
206
+ }
207
+ }
208
+ // `export { Foo, Bar as Baz }`
209
+ for (const spec of named.specifiers) {
210
+ records.push({
211
+ exportedName: spec.exported.name,
212
+ localName: spec.local.name,
213
+ });
214
+ }
215
+ break;
216
+ }
217
+ // ExportAllDeclaration (`export * from '...'`) is handled separately
218
+ // by _extractBarrelReExports — we intentionally skip it here.
219
+ default:
220
+ break;
221
+ }
222
+ }
223
+ return records;
224
+ }
225
+ /**
226
+ * Extract all `export * from '...'` (barrel re-export) sources from the AST.
227
+ *
228
+ * These are forbidden in `'use client'` and `'use server'` modules because
229
+ * each export must be individually addressable in the Flight protocol.
230
+ *
231
+ * @internal
232
+ */
233
+ function _extractBarrelReExports(body) {
234
+ const sources = [];
235
+ for (const node of body) {
236
+ if (node.type === 'ExportAllDeclaration') {
237
+ const exportAll = node;
238
+ const source = exportAll.source?.value;
239
+ if (typeof source === 'string') {
240
+ sources.push(source);
241
+ }
242
+ }
243
+ }
244
+ return sources;
245
+ }
246
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/compiler/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Juice Vite Plugin — `juice/plugin`
3
+ *
4
+ * Hooks into Vite's transform lifecycle to:
5
+ * 1. Detect `'use client'` directives via AST analysis.
6
+ * 2. Extract client components into separate Rollup chunks.
7
+ * 3. Replace server-side imports with React Flight proxy references.
8
+ * 4. Detect `'use server'` directives and register server actions.
9
+ * 5. Replace client-side imports of server actions with RPC proxies.
10
+ * 6. Emit a strict, readable `flight-manifest.json` mapping everything.
11
+ *
12
+ * @module plugin
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * // vite.config.ts
17
+ * import { defineConfig } from 'vite';
18
+ * import juice from '@cmj/juice/plugin';
19
+ *
20
+ * export default defineConfig({
21
+ * plugins: [juice()],
22
+ * });
23
+ * ```
24
+ */
25
+ import type { JuicePluginOptions } from './types.js';
26
+ /**
27
+ * Create the Juice Vite plugin.
28
+ *
29
+ * @param options - Optional plugin configuration.
30
+ * @returns A Vite {@link Plugin} object.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * import { defineConfig } from 'vite';
35
+ * import juice from '@cmj/juice/plugin';
36
+ *
37
+ * export default defineConfig({
38
+ * plugins: [juice()],
39
+ * });
40
+ * ```
41
+ */
42
+ export default function juice(options?: JuicePluginOptions): any;
43
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/compiler/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAwBrD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,GAAG,CAsQ/D"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Juice Vite Plugin — `juice/plugin`
3
+ *
4
+ * Hooks into Vite's transform lifecycle to:
5
+ * 1. Detect `'use client'` directives via AST analysis.
6
+ * 2. Extract client components into separate Rollup chunks.
7
+ * 3. Replace server-side imports with React Flight proxy references.
8
+ * 4. Detect `'use server'` directives and register server actions.
9
+ * 5. Replace client-side imports of server actions with RPC proxies.
10
+ * 6. Emit a strict, readable `flight-manifest.json` mapping everything.
11
+ *
12
+ * @module plugin
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * // vite.config.ts
17
+ * import { defineConfig } from 'vite';
18
+ * import juice from '@cmj/juice/plugin';
19
+ *
20
+ * export default defineConfig({
21
+ * plugins: [juice()],
22
+ * });
23
+ * ```
24
+ */
25
+ import { relative } from 'node:path';
26
+ import { JuiceExportError, JuiceMutualExclusionError, JuiceBarrelExportError, } from './errors.js';
27
+ import { _mayContainDirective, _detectDirective, } from './parse.js';
28
+ import { _generateProxyModule } from './proxy.js';
29
+ import { _generateServerActionProxy } from './server-actions.js';
30
+ import { _buildManifest, _serializeManifest } from './manifest.js';
31
+ import { ClientModuleRegistry } from './registry.js';
32
+ import { ServerActionRegistry } from './server-action-registry.js';
33
+ /**
34
+ * Virtual module prefix used to serve proxy modules for `'use client'`
35
+ * components during the server build.
36
+ *
37
+ * @internal
38
+ */
39
+ const VIRTUAL_PREFIX = '\0juice-client-proxy:';
40
+ /**
41
+ * Create the Juice Vite plugin.
42
+ *
43
+ * @param options - Optional plugin configuration.
44
+ * @returns A Vite {@link Plugin} object.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * import { defineConfig } from 'vite';
49
+ * import juice from '@cmj/juice/plugin';
50
+ *
51
+ * export default defineConfig({
52
+ * plugins: [juice()],
53
+ * });
54
+ * ```
55
+ */
56
+ export default function juice(options) {
57
+ // ── Options validation ─────────────────────────────────────────
58
+ if (options !== undefined && options !== null) {
59
+ if (typeof options !== 'object' || Array.isArray(options)) {
60
+ throw new TypeError(`juice() options must be a plain object. Received: ${typeof options}`);
61
+ }
62
+ if (options.manifestFileName !== undefined &&
63
+ typeof options.manifestFileName !== 'string') {
64
+ throw new TypeError(`juice() option 'manifestFileName' must be a string. ` +
65
+ `Received: ${typeof options.manifestFileName} (${JSON.stringify(options.manifestFileName)})`);
66
+ }
67
+ // Warn on unknown keys (non-breaking, but highly suspicious)
68
+ const knownKeys = new Set(['manifestFileName', 'routes']);
69
+ for (const key of Object.keys(options)) {
70
+ if (!knownKeys.has(key)) {
71
+ console.warn(`[juice] Unknown option "${key}" passed to juice(). ` +
72
+ `Known options: ${[...knownKeys].join(', ')}`);
73
+ }
74
+ }
75
+ // Validate routes shape if provided
76
+ if (options.routes !== undefined) {
77
+ if (typeof options.routes !== 'object' || options.routes === null || Array.isArray(options.routes)) {
78
+ throw new TypeError(`juice() option 'routes' must be a plain object mapping URL patterns to route entries. ` +
79
+ `Received: ${typeof options.routes}`);
80
+ }
81
+ for (const [pattern, entry] of Object.entries(options.routes)) {
82
+ if (!entry || typeof entry !== 'object' || typeof entry.moduleId !== 'string') {
83
+ throw new TypeError(`juice() route "${pattern}" must have a 'moduleId' string property. ` +
84
+ `Received: ${JSON.stringify(entry)}`);
85
+ }
86
+ }
87
+ }
88
+ }
89
+ const manifestFileName = options?.manifestFileName ?? 'flight-manifest.json';
90
+ const routes = options?.routes;
91
+ const clientRegistry = new ClientModuleRegistry();
92
+ const serverRegistry = new ServerActionRegistry();
93
+ let config;
94
+ let isSSR = false;
95
+ return {
96
+ name: 'juice:client-components',
97
+ enforce: 'pre',
98
+ // ------------------------------------------------------------------
99
+ // Config phase — capture resolved config
100
+ // ------------------------------------------------------------------
101
+ configResolved(resolvedConfig) {
102
+ config = resolvedConfig;
103
+ // Detect SSR mode from Vite's build config
104
+ isSSR = !!resolvedConfig.build.ssr;
105
+ },
106
+ // ------------------------------------------------------------------
107
+ // Transform phase — detect directives via unified analysis
108
+ // ------------------------------------------------------------------
109
+ transform(source, id) {
110
+ // Only process TS/JS/JSX/TSX files
111
+ if (!/\.[jt]sx?$/.test(id)) {
112
+ return null;
113
+ }
114
+ // Ignore node_modules — use path-segment-bounded check to avoid
115
+ // false positives (e.g., "/path/node_modules_extra/src/app.tsx")
116
+ if (/[\/\\]node_modules[\/\\]/.test(id)) {
117
+ return null;
118
+ }
119
+ // Fast-path bail-out: skip full AST parse if no directive is present
120
+ if (!_mayContainDirective(source)) {
121
+ return null;
122
+ }
123
+ // Parse the AST using Rollup's built-in acorn
124
+ const moduleSpecifier = relative(config.root, id);
125
+ let ast;
126
+ try {
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
+ ast = this.parse(source);
129
+ }
130
+ catch (parseError) {
131
+ const msg = parseError instanceof Error ? parseError.message : String(parseError);
132
+ throw new Error(`[juice] Syntax error in ${moduleSpecifier}: ${msg}\n` +
133
+ `This file was flagged for directive analysis because it contains ` +
134
+ `'use client' or 'use server' as a substring. If this file is not ` +
135
+ `a directive module, the issue is a syntax error in your source code.`);
136
+ }
137
+ // Unified analysis: single-pass detection + validation
138
+ const result = _detectDirective(ast);
139
+ // No directive found — pass through
140
+ if (result.directive === null) {
141
+ return null;
142
+ }
143
+ // ── Guard: mutual exclusion ──────────────────────────────────
144
+ if (result.hasMutualExclusion) {
145
+ throw new JuiceMutualExclusionError(moduleSpecifier);
146
+ }
147
+ // ── Guard: barrel re-exports ─────────────────────────────────
148
+ if (result.barrelReExports.length > 0) {
149
+ throw new JuiceBarrelExportError(moduleSpecifier, result.directive, result.barrelReExports[0]);
150
+ }
151
+ // ── Guard: empty exports ─────────────────────────────────────
152
+ if (result.exports.length === 0) {
153
+ throw new JuiceExportError(moduleSpecifier, result.directive);
154
+ }
155
+ // ── 'use client' path ────────────────────────────────────────
156
+ if (result.directive === 'use client') {
157
+ clientRegistry.register({
158
+ moduleSpecifier,
159
+ absolutePath: id,
160
+ exports: result.exports,
161
+ });
162
+ // Server build: replace with Flight proxy
163
+ if (isSSR) {
164
+ return {
165
+ code: _generateProxyModule(moduleSpecifier, result.exports),
166
+ map: null,
167
+ };
168
+ }
169
+ // Client build: pass through (Rollup will chunk it)
170
+ return null;
171
+ }
172
+ // ── 'use server' path ────────────────────────────────────────
173
+ if (result.directive === 'use server') {
174
+ serverRegistry.register({
175
+ moduleSpecifier,
176
+ absolutePath: id,
177
+ exports: result.exports,
178
+ });
179
+ // Client build: replace with RPC proxy
180
+ if (!isSSR) {
181
+ return {
182
+ code: _generateServerActionProxy(moduleSpecifier, result.exports),
183
+ map: null,
184
+ };
185
+ }
186
+ // Server build: pass through (real functions)
187
+ return null;
188
+ }
189
+ return null;
190
+ },
191
+ // ------------------------------------------------------------------
192
+ // resolveId — intercept virtual proxy module IDs
193
+ // ------------------------------------------------------------------
194
+ resolveId(source, importer) {
195
+ if (!importer) {
196
+ return null;
197
+ }
198
+ if (source.startsWith(VIRTUAL_PREFIX)) {
199
+ return source;
200
+ }
201
+ return null;
202
+ },
203
+ // ------------------------------------------------------------------
204
+ // buildStart — emit client modules as chunks (client build only)
205
+ // ------------------------------------------------------------------
206
+ buildStart() {
207
+ if (isSSR || clientRegistry.size === 0) {
208
+ return;
209
+ }
210
+ for (const [, info] of clientRegistry.entries()) {
211
+ this.emitFile({
212
+ type: 'chunk',
213
+ id: info.absolutePath,
214
+ name: _chunkName(info.moduleSpecifier),
215
+ });
216
+ }
217
+ },
218
+ // ------------------------------------------------------------------
219
+ // generateBundle — emit flight-manifest.json (client build only)
220
+ // ------------------------------------------------------------------
221
+ generateBundle(outputOptions, bundle) {
222
+ if (isSSR) {
223
+ return;
224
+ }
225
+ if (clientRegistry.size === 0 && serverRegistry.size === 0 && !routes) {
226
+ return;
227
+ }
228
+ // Build chunk map: moduleSpecifier → chunk file names
229
+ const chunkMap = new Map();
230
+ for (const [fileName, chunk] of Object.entries(bundle)) {
231
+ if (chunk.type !== 'chunk')
232
+ continue;
233
+ for (const [specifier, info] of clientRegistry.entries()) {
234
+ if (chunk.facadeModuleId === info.absolutePath ||
235
+ chunk.moduleIds?.includes(info.absolutePath)) {
236
+ const existing = chunkMap.get(specifier) ?? [];
237
+ existing.push(fileName);
238
+ chunkMap.set(specifier, existing);
239
+ }
240
+ }
241
+ }
242
+ // Build _meta for zero-config runtime DX
243
+ const isDev = config.command === 'serve';
244
+ const meta = {
245
+ root: `file://${config.root}/`,
246
+ mode: isDev ? 'development' : 'production',
247
+ assetPrefix: config.base || '/',
248
+ ...(isDev ? { hmrUrl: '/@vite/client' } : {}),
249
+ };
250
+ const manifest = _buildManifest(clientRegistry, chunkMap, serverRegistry, routes, meta);
251
+ const json = _serializeManifest(manifest);
252
+ this.emitFile({
253
+ type: 'asset',
254
+ fileName: manifestFileName,
255
+ source: json,
256
+ });
257
+ },
258
+ };
259
+ }
260
+ // ---------------------------------------------------------------------------
261
+ // Internal helpers
262
+ // ---------------------------------------------------------------------------
263
+ /**
264
+ * Derive a human-readable chunk name from a module specifier.
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * _chunkName('components/Counter.tsx'); // → 'Counter'
269
+ * _chunkName('src/ui/SearchBar.tsx'); // → 'SearchBar'
270
+ * ```
271
+ *
272
+ * @internal
273
+ */
274
+ function _chunkName(specifier) {
275
+ const parts = specifier.replace(/\.[jt]sx?$/, '').split('/');
276
+ // Use up to the last 2 path segments for uniqueness
277
+ // e.g., 'components/Counter' instead of just 'Counter'
278
+ const meaningful = parts.slice(-2).join('_');
279
+ return meaningful || 'chunk';
280
+ }
281
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/compiler/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Generates React Flight proxy modules that replace `'use client'` source
3
+ * modules in the server build.
4
+ *
5
+ * The proxy module exports `registerClientReference` calls for each export
6
+ * found in the original client component. This allows the React Flight
7
+ * serializer to emit a reference to the client chunk instead of attempting
8
+ * to render the component on the server.
9
+ *
10
+ * @module proxy
11
+ * @internal
12
+ */
13
+ import type { ExportRecord } from './types.js';
14
+ /**
15
+ * Generate the server-side proxy source code for a `'use client'` module.
16
+ *
17
+ * The emitted code replaces the original module in the server bundle.
18
+ * Each export becomes a `registerClientReference()` call that the React
19
+ * Flight serializer understands.
20
+ *
21
+ * @param moduleSpecifier - Root-relative module path used as the stable ID
22
+ * in the Flight wire format (e.g., `'components/Counter.tsx'`).
23
+ * @param exports - All exports extracted from the original module AST.
24
+ * @returns A complete ES module source string ready to feed into Vite's
25
+ * `load` hook.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const source = _generateProxyModule('components/Counter.tsx', [
30
+ * { exportedName: 'default', localName: 'Counter' },
31
+ * { exportedName: 'Badge', localName: 'Badge' },
32
+ * ]);
33
+ * // Returns:
34
+ * // import { registerClientReference } from 'react-server-dom-webpack/server';
35
+ * // export default registerClientReference({}, 'components/Counter.tsx', 'default');
36
+ * // export const Badge = registerClientReference({}, 'components/Counter.tsx', 'Badge');
37
+ * ```
38
+ *
39
+ * @internal
40
+ */
41
+ export declare function _generateProxyModule(moduleSpecifier: string, exports: readonly ExportRecord[]): string;
42
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/compiler/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,MAAM,CA6BR"}