11import { parseAstAsync } from 'vite'
22import { describe , expect , test } from 'vitest'
3+ import { transformDirectiveProxyExport } from './proxy-export'
34import { transformServerActionServer } from './server-action'
45import { debugSourceMap } from './test-utils'
56
7+ // Unified utility for directive proxy export transforms
8+ async function testDirectiveTransform ( input : string , directive : string ) {
9+ const ast = await parseAstAsync ( input )
10+ const result = transformDirectiveProxyExport ( ast , {
11+ directive,
12+ code : input ,
13+ runtime : ( name ) =>
14+ `$runtime(${ JSON . stringify ( '<id>#' + name ) } , ${ JSON . stringify ( name ) } )` ,
15+ keep : directive === 'use client' ,
16+ } )
17+
18+ if ( ! result || ! result . output . hasChanged ( ) ) {
19+ return
20+ }
21+
22+ if ( process . env [ 'DEBUG_SOURCEMAP' ] ) {
23+ await debugSourceMap ( result . output )
24+ }
25+
26+ return result . output . toString ( )
27+ }
28+
629describe ( 'internal transform function for server environment' , ( ) => {
730 async function testTransform ( input : string ) {
831 const ast = await parseAstAsync ( input )
@@ -31,10 +54,7 @@ export default function App() {
3154 expect ( await testTransform ( input ) ) . toBeUndefined ( )
3255 } )
3356
34- test . skip ( 'top-level use client' , ( ) => {
35- // This test is skipped since transformServerActionServer only handles server transforms
36- // The client transform would be handled by a different function
37- // @ts -expect-error - unused in skipped test for documentation
57+ test ( 'top-level use client' , async ( ) => {
3858 const input = `
3959'use client';
4060
@@ -44,7 +64,7 @@ import { unstable_allowServer as allowServer } from 'waku/client';
4464
4565const initialCount = 1;
4666const TWO = 2;
47- function double (x: number ) {
67+ function double (x) {
4868 return x * TWO;
4969}
5070export const countAtom = allowServer(atom(double(initialCount)));
@@ -54,16 +74,16 @@ export const Empty = () => null;
5474function Private() {
5575 return "Secret";
5676}
57- const SecretComponent = () => <p> Secret</p> ;
58- const SecretFunction = (n: number ) => 'Secret' + n;
77+ const SecretComponent = () => " Secret" ;
78+ const SecretFunction = (n) => 'Secret' + n;
5979
60- export function Greet({ name }: { name: string } ) {
61- return <> Hello { name}</> ;
80+ export function Greet({ name }) {
81+ return " Hello " + name;
6282}
6383
6484export class MyComponent extends Component {
6585 render() {
66- return <p> Class Component</p> ;
86+ return " Class Component" ;
6787 }
6888}
6989
@@ -76,41 +96,51 @@ const MyProvider = memo(MyContext);
7696export const NAME = 'World';
7797
7898export default function App() {
79- return (
80- <MyProvider value="Hello">
81- <div>Hello World</div>
82- </MyProvider>
83- );
99+ return "Hello World";
84100}
85101`
86- // Expected output (from Waku server transform):
87- // @ts -expect-error - unused in skipped test for documentation
88- const expectedOutput = `import { registerClientReference as __waku_registerClientReference } from 'react-server-dom-webpack/server.edge';
89- import { atom } from 'jotai/vanilla';
90- const initialCount = 1;
91- const TWO = 2;
92- function double(x) {
93- return x * TWO;
94- }
95- export const countAtom = __waku_registerClientReference(atom(double(initialCount)), "/src/App.tsx", "countAtom");
96- export const Empty = __waku_registerClientReference(()=>{
97- throw new Error('It is not possible to invoke a client function from the server: /src/App.tsx#Empty');
98- }, '/src/App.tsx', 'Empty');
99- export const Greet = __waku_registerClientReference(()=>{
100- throw new Error('It is not possible to invoke a client function from the server: /src/App.tsx#Greet');
101- }, '/src/App.tsx', 'Greet');
102- export const MyComponent = __waku_registerClientReference(()=>{
103- throw new Error('It is not possible to invoke a client function from the server: /src/App.tsx#MyComponent');
104- }, '/src/App.tsx', 'MyComponent');
105- export const useMyContext = __waku_registerClientReference(()=>{
106- throw new Error('It is not possible to invoke a client function from the server: /src/App.tsx#useMyContext');
107- }, '/src/App.tsx', 'useMyContext');
108- export const NAME = __waku_registerClientReference(()=>{
109- throw new Error('It is not possible to invoke a client function from the server: /src/App.tsx#NAME');
110- }, '/src/App.tsx', 'NAME');
111- export default __waku_registerClientReference(()=>{
112- throw new Error('It is not possible to invoke a client function from the server: /src/App.tsx#default');
113- }, '/src/App.tsx', 'default');`
102+ expect ( await testDirectiveTransform ( input , 'use client' ) )
103+ . toMatchInlineSnapshot ( `
104+ "
105+ 'use client';
106+
107+ import { Component, createContext, useContext, memo } from 'react';
108+ import { atom } from 'jotai/vanilla';
109+ import { unstable_allowServer as allowServer } from 'waku/client';
110+
111+ const initialCount = 1;
112+ const TWO = 2;
113+ function double (x) {
114+ return x * TWO;
115+ }
116+ export const countAtom = /* #__PURE__ */ $runtime("<id>#countAtom", "countAtom");
117+
118+ export const Empty = /* #__PURE__ */ $runtime("<id>#Empty", "Empty");
119+
120+ function Private() {
121+ return "Secret";
122+ }
123+ const SecretComponent = () => "Secret";
124+ const SecretFunction = (n) => 'Secret' + n;
125+
126+ export const Greet = /* #__PURE__ */ $runtime("<id>#Greet", "Greet");
127+
128+
129+ export const MyComponent = /* #__PURE__ */ $runtime("<id>#MyComponent", "MyComponent");
130+
131+
132+ const MyContext = createContext();
133+
134+ export const useMyContext = /* #__PURE__ */ $runtime("<id>#useMyContext", "useMyContext");
135+
136+ const MyProvider = memo(MyContext);
137+
138+ export const NAME = /* #__PURE__ */ $runtime("<id>#NAME", "NAME");
139+
140+ export default /* #__PURE__ */ $runtime("<id>#default", "default");
141+
142+ "
143+ ` )
114144 } )
115145
116146 test ( 'top-level use server' , async ( ) => {
@@ -435,18 +465,16 @@ export default defaultFn;
435465} )
436466
437467describe ( 'internal transform function for client environment' , ( ) => {
438- test . skip ( 'no transformation' , ( ) => {
439- // @ts -expect-error - unused in skipped test for documentation
468+ test ( 'no transformation' , async ( ) => {
440469 const input = `
441470export const log = (mesg) => {
442471 console.log(mesg);
443472};
444473`
445- // Expected: no transformation (undefined )
474+ expect ( await testDirectiveTransform ( input , 'use server' ) ) . toBeUndefined ( )
446475 } )
447476
448- test . skip ( 'top-level use server' , ( ) => {
449- // @ts -expect-error - unused in skipped test for documentation
477+ test ( 'top-level use server' , async ( ) => {
450478 const input = `
451479'use server';
452480
@@ -468,18 +496,29 @@ export default async function log4(mesg) {
468496 console.log(mesg);
469497}
470498`
471- // Expected output (from Waku client transform):
472- // @ts -expect-error - unused in skipped test for documentation
473- const expectedOutput = `import { createServerReference } from 'react-server-dom-webpack/client';
474- import { unstable_callServerRsc as callServerRsc } from 'waku/minimal/client';
475- export const log1 = createServerReference('/src/func.ts#log1', callServerRsc);
476- export const log2 = createServerReference('/src/func.ts#log2', callServerRsc);
477- export const log3 = createServerReference('/src/func.ts#log3', callServerRsc);
478- export default createServerReference('/src/func.ts#default', callServerRsc);`
499+ expect ( await testDirectiveTransform ( input , 'use server' ) )
500+ . toMatchInlineSnapshot ( `
501+ "
502+
503+
504+
505+
506+ export const log1 = /* #__PURE__ */ $runtime("<id>#log1", "log1");
507+
508+
509+ export const log2 = /* #__PURE__ */ $runtime("<id>#log2", "log2");
510+
511+
512+ export const log3 = /* #__PURE__ */ $runtime("<id>#log3", "log3");
513+
514+
515+ export default /* #__PURE__ */ $runtime("<id>#default", "default");
516+
517+ "
518+ ` )
479519 } )
480520
481- test . skip ( 'top-level use server for SSR' , ( ) => {
482- // @ts -expect-error - unused in skipped test for documentation
521+ test ( 'top-level use server for SSR' , async ( ) => {
483522 const input = `
484523'use server';
485524
@@ -491,10 +530,18 @@ export async function log(mesg) {
491530 console.log(mesg);
492531}
493532`
494- // Expected output (from Waku SSR transform):
495- // @ts -expect-error - unused in skipped test for documentation
496- const expectedOutput = `export const log = ()=>{
497- throw new Error('You cannot call server functions during SSR');
498- };`
533+ expect ( await testDirectiveTransform ( input , 'use server' ) )
534+ . toMatchInlineSnapshot ( `
535+ "
536+
537+
538+
539+
540+
541+
542+ export const log = /* #__PURE__ */ $runtime("<id>#log", "log");
543+
544+ "
545+ ` )
499546 } )
500547} )
0 commit comments