diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js new file mode 100644 index 000000000..bd9fc6f5a --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js @@ -0,0 +1,13 @@ +let count = 0 + +function Counter() { + const name = 'value' + + return { + type: 'form', + action: (formData) => { + 'use server' + count += Number(formData.get(name)) + }, + } +} diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js.snap.encode.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js.snap.encode.js new file mode 100644 index 000000000..53f1bf2a9 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js.snap.encode.js @@ -0,0 +1,17 @@ +let count = 0 + +function Counter() { + const name = 'value' + + return { + type: 'form', + action: /* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, __enc([name])), + } +} + +;export function $$hoist_0_anonymous_server_function($$hoist_encoded, formData) { + const [name] = __dec($$hoist_encoded); +'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js.snap.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js.snap.js new file mode 100644 index 000000000..eb6ed0b04 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/arrow.js.snap.js @@ -0,0 +1,16 @@ +let count = 0 + +function Counter() { + const name = 'value' + + return { + type: 'form', + action: /* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, name), + } +} + +;export function $$hoist_0_anonymous_server_function(name, formData) { + 'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js new file mode 100644 index 000000000..c4a90b085 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js @@ -0,0 +1,12 @@ +let count = 0 + +function Counter() { + const name = 'value' + + async function changeCount(formData) { + 'use server' + count += Number(formData.get(name)) + } + + return 'something' +} diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js.snap.encode.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js.snap.encode.js new file mode 100644 index 000000000..6af41deea --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js.snap.encode.js @@ -0,0 +1,16 @@ +let count = 0 + +function Counter() { + const name = 'value' + + const changeCount = /* #__PURE__ */ $$register($$hoist_0_changeCount, "", "$$hoist_0_changeCount").bind(null, __enc([name])); + + return 'something' +} + +;export async function $$hoist_0_changeCount($$hoist_encoded, formData) { + const [name] = __dec($$hoist_encoded); +'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_changeCount, "name", { value: "changeCount" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js.snap.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js.snap.js new file mode 100644 index 000000000..5893ab328 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/closure.js.snap.js @@ -0,0 +1,15 @@ +let count = 0 + +function Counter() { + const name = 'value' + + const changeCount = /* #__PURE__ */ $$register($$hoist_0_changeCount, "", "$$hoist_0_changeCount").bind(null, name); + + return 'something' +} + +;export async function $$hoist_0_changeCount(name, formData) { + 'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_changeCount, "name", { value: "changeCount" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js new file mode 100644 index 000000000..be1e7031b --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js @@ -0,0 +1,10 @@ +// https://github.com/remix-run/react-router/blob/98367e49900701c460cb08eb16c2441da5007efc/playground/rsc-vite/src/routes/home/home.tsx +export {} from 'edge-case' +import { redirect } from 'react-router/rsc' + +export default () => { + const redirectOnServer = async () => { + 'use server' + throw redirect() + } +} diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js.snap.encode.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js.snap.encode.js new file mode 100644 index 000000000..73ddb2a51 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js.snap.encode.js @@ -0,0 +1,13 @@ +// https://github.com/remix-run/react-router/blob/98367e49900701c460cb08eb16c2441da5007efc/playground/rsc-vite/src/routes/home/home.tsx +export {} from 'edge-case' +import { redirect } from 'react-router/rsc' + +export default () => { + const redirectOnServer = /* #__PURE__ */ $$register($$hoist_0_redirectOnServer, "", "$$hoist_0_redirectOnServer") +} + +;export async function $$hoist_0_redirectOnServer() { + 'use server' + throw redirect() + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_redirectOnServer, "name", { value: "redirectOnServer" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js.snap.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js.snap.js new file mode 100644 index 000000000..73ddb2a51 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/export-before-import.js.snap.js @@ -0,0 +1,13 @@ +// https://github.com/remix-run/react-router/blob/98367e49900701c460cb08eb16c2441da5007efc/playground/rsc-vite/src/routes/home/home.tsx +export {} from 'edge-case' +import { redirect } from 'react-router/rsc' + +export default () => { + const redirectOnServer = /* #__PURE__ */ $$register($$hoist_0_redirectOnServer, "", "$$hoist_0_redirectOnServer") +} + +;export async function $$hoist_0_redirectOnServer() { + 'use server' + throw redirect() + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_redirectOnServer, "name", { value: "redirectOnServer" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js new file mode 100644 index 000000000..870b97879 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js @@ -0,0 +1,15 @@ +// Adapted from React's Next.js server action examples. +export default function Page() { + const x = 0 + const action = validator(async (y) => { + 'use server' + return x + y + }) +} + +function validator(action) { + return async function (arg) { + 'use server' + return action(arg) + } +} diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js.snap.encode.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js.snap.encode.js new file mode 100644 index 000000000..8b7e53f9f --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js.snap.encode.js @@ -0,0 +1,23 @@ +// Adapted from React's Next.js server action examples. +export default function Page() { + const x = 0 + const action = validator(/* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, __enc([x]))) +} + +function validator(action) { + return /* #__PURE__ */ $$register($$hoist_1_anonymous_server_function, "", "$$hoist_1_anonymous_server_function").bind(null, __enc([action])) +} + +;export async function $$hoist_0_anonymous_server_function($$hoist_encoded, y) { + const [x] = __dec($$hoist_encoded); +'use server' + return x + y + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); + +;export async function $$hoist_1_anonymous_server_function($$hoist_encoded, arg) { + const [action] = __dec($$hoist_encoded); +'use server' + return action(arg) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_1_anonymous_server_function, "name", { value: "anonymous_server_function" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js.snap.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js.snap.js new file mode 100644 index 000000000..e07758575 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/higher-order.js.snap.js @@ -0,0 +1,21 @@ +// Adapted from React's Next.js server action examples. +export default function Page() { + const x = 0 + const action = validator(/* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, x)) +} + +function validator(action) { + return /* #__PURE__ */ $$register($$hoist_1_anonymous_server_function, "", "$$hoist_1_anonymous_server_function").bind(null, action) +} + +;export async function $$hoist_0_anonymous_server_function(x, y) { + 'use server' + return x + y + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); + +;export async function $$hoist_1_anonymous_server_function(action, arg) { + 'use server' + return action(arg) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_1_anonymous_server_function, "name", { value: "anonymous_server_function" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js new file mode 100644 index 000000000..ce9c16521 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js @@ -0,0 +1,17 @@ +let count = 0 + +function Counter() { + const name = 'value' + + async function changeCount(formData) { + 'use server' + count += Number(formData.get(name)) + } + + async function changeCount2(formData) { + 'use server' + count += Number(formData.get(name)) + } + + return 'something' +} diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js.snap.encode.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js.snap.encode.js new file mode 100644 index 000000000..2b794a619 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js.snap.encode.js @@ -0,0 +1,25 @@ +let count = 0 + +function Counter() { + const name = 'value' + + const changeCount = /* #__PURE__ */ $$register($$hoist_0_changeCount, "", "$$hoist_0_changeCount").bind(null, __enc([name])); + + const changeCount2 = /* #__PURE__ */ $$register($$hoist_1_changeCount2, "", "$$hoist_1_changeCount2").bind(null, __enc([name])); + + return 'something' +} + +;export async function $$hoist_0_changeCount($$hoist_encoded, formData) { + const [name] = __dec($$hoist_encoded); +'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_changeCount, "name", { value: "changeCount" }); + +;export async function $$hoist_1_changeCount2($$hoist_encoded, formData) { + const [name] = __dec($$hoist_encoded); +'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_1_changeCount2, "name", { value: "changeCount2" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js.snap.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js.snap.js new file mode 100644 index 000000000..d1c2a9fa5 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/multiple.js.snap.js @@ -0,0 +1,23 @@ +let count = 0 + +function Counter() { + const name = 'value' + + const changeCount = /* #__PURE__ */ $$register($$hoist_0_changeCount, "", "$$hoist_0_changeCount").bind(null, name); + + const changeCount2 = /* #__PURE__ */ $$register($$hoist_1_changeCount2, "", "$$hoist_1_changeCount2").bind(null, name); + + return 'something' +} + +;export async function $$hoist_0_changeCount(name, formData) { + 'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_0_changeCount, "name", { value: "changeCount" }); + +;export async function $$hoist_1_changeCount2(name, formData) { + 'use server' + count += Number(formData.get(name)) + }; +/* #__PURE__ */ Object.defineProperty($$hoist_1_changeCount2, "name", { value: "changeCount2" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js new file mode 100644 index 000000000..fe86bc92d --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js @@ -0,0 +1,17 @@ +const x = 'x' + +async function f() { + 'use server' + return x +} + +async function g() {} + +export async function h(formData) { + 'use server' + return formData.get(x) +} + +export default function w() { + 'use server' +} diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js.snap.encode.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js.snap.encode.js new file mode 100644 index 000000000..2f151f924 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js.snap.encode.js @@ -0,0 +1,27 @@ +const x = 'x' + +const f = /* #__PURE__ */ $$register($$hoist_0_f, "", "$$hoist_0_f"); + +async function g() {} + +export const h = /* #__PURE__ */ $$register($$hoist_1_h, "", "$$hoist_1_h"); + +const w = /* #__PURE__ */ $$register($$hoist_2_w, "", "$$hoist_2_w"); +export default w; + +;export async function $$hoist_0_f() { + 'use server' + return x +}; +/* #__PURE__ */ Object.defineProperty($$hoist_0_f, "name", { value: "f" }); + +;export async function $$hoist_1_h(formData) { + 'use server' + return formData.get(x) +}; +/* #__PURE__ */ Object.defineProperty($$hoist_1_h, "name", { value: "h" }); + +;export function $$hoist_2_w() { + 'use server' +}; +/* #__PURE__ */ Object.defineProperty($$hoist_2_w, "name", { value: "w" }); diff --git a/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js.snap.js b/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js.snap.js new file mode 100644 index 000000000..2f151f924 --- /dev/null +++ b/packages/plugin-rsc/src/transforms/fixtures/hoist/top-level.js.snap.js @@ -0,0 +1,27 @@ +const x = 'x' + +const f = /* #__PURE__ */ $$register($$hoist_0_f, "", "$$hoist_0_f"); + +async function g() {} + +export const h = /* #__PURE__ */ $$register($$hoist_1_h, "", "$$hoist_1_h"); + +const w = /* #__PURE__ */ $$register($$hoist_2_w, "", "$$hoist_2_w"); +export default w; + +;export async function $$hoist_0_f() { + 'use server' + return x +}; +/* #__PURE__ */ Object.defineProperty($$hoist_0_f, "name", { value: "f" }); + +;export async function $$hoist_1_h(formData) { + 'use server' + return formData.get(x) +}; +/* #__PURE__ */ Object.defineProperty($$hoist_1_h, "name", { value: "h" }); + +;export function $$hoist_2_w() { + 'use server' +}; +/* #__PURE__ */ Object.defineProperty($$hoist_2_w, "name", { value: "w" }); diff --git a/packages/plugin-rsc/src/transforms/hoist.test.ts b/packages/plugin-rsc/src/transforms/hoist.test.ts index 3950f8419..97b1deac2 100644 --- a/packages/plugin-rsc/src/transforms/hoist.test.ts +++ b/packages/plugin-rsc/src/transforms/hoist.test.ts @@ -125,7 +125,22 @@ async function f() { return x; } ` - expect(await testTransform(input)).toMatchInlineSnapshot(`undefined`) + expect(await testTransform(input)).toBeUndefined() + }) + + it('returns generated names in order', async () => { + const input = ` +async function first() { + "use server"; +} +async function second() { + "use server"; +} +` + expect(await testTransformNames(input)).toEqual([ + '$$hoist_0_first', + '$$hoist_1_second', + ]) }) it('ignores strings outside a function directive prologue', async () => { @@ -165,322 +180,6 @@ async function action() { expect(findDirectives(ast, 'use server')).toHaveLength(1) }) - it('top level', async () => { - const input = ` -const x = "x"; - -async function f() { - "use server"; - return x; -} - -async function g() { -} - -export async function h(formData) { - "use server"; - return formData.get(x); -} - -export default function w() { - "use server"; -} -` - expect(await testTransform(input)).toMatchInlineSnapshot(` - " - const x = "x"; - - const f = /* #__PURE__ */ $$register($$hoist_0_f, "", "$$hoist_0_f"); - - async function g() { - } - - export const h = /* #__PURE__ */ $$register($$hoist_1_h, "", "$$hoist_1_h"); - - const w = /* #__PURE__ */ $$register($$hoist_2_w, "", "$$hoist_2_w"); - export default w; - - ;export async function $$hoist_0_f() { - "use server"; - return x; - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_f, "name", { value: "f" }); - - ;export async function $$hoist_1_h(formData) { - "use server"; - return formData.get(x); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_1_h, "name", { value: "h" }); - - ;export function $$hoist_2_w() { - "use server"; - }; - /* #__PURE__ */ Object.defineProperty($$hoist_2_w, "name", { value: "w" }); - " - `) - - // nothing to encode - expect(await testTransform(input, { encode: true })).toBe( - await testTransform(input), - ) - - expect(await testTransformNames(input)).toMatchInlineSnapshot(` - [ - "$$hoist_0_f", - "$$hoist_1_h", - "$$hoist_2_w", - ] - `) - }) - - it('closure', async () => { - const input = ` -let count = 0; - -function Counter() { - const name = "value"; - - async function changeCount(formData) { - "use server"; - count += Number(formData.get(name)); - } - - return "something"; -} -` - expect(await testTransform(input)).toMatchInlineSnapshot(` - " - let count = 0; - - function Counter() { - const name = "value"; - - const changeCount = /* #__PURE__ */ $$register($$hoist_0_changeCount, "", "$$hoist_0_changeCount").bind(null, name); - - return "something"; - } - - ;export async function $$hoist_0_changeCount(name, formData) { - "use server"; - count += Number(formData.get(name)); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_changeCount, "name", { value: "changeCount" }); - " - `) - }) - - it('many', async () => { - const input = ` -let count = 0; - -function Counter() { - const name = "value"; - - async function changeCount(formData) { - "use server"; - count += Number(formData.get(name)); - } - - async function changeCount2(formData) { - "use server"; - count += Number(formData.get(name)); - } - - return "something"; -} -` - expect(await testTransform(input)).toMatchInlineSnapshot(` - " - let count = 0; - - function Counter() { - const name = "value"; - - const changeCount = /* #__PURE__ */ $$register($$hoist_0_changeCount, "", "$$hoist_0_changeCount").bind(null, name); - - const changeCount2 = /* #__PURE__ */ $$register($$hoist_1_changeCount2, "", "$$hoist_1_changeCount2").bind(null, name); - - return "something"; - } - - ;export async function $$hoist_0_changeCount(name, formData) { - "use server"; - count += Number(formData.get(name)); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_changeCount, "name", { value: "changeCount" }); - - ;export async function $$hoist_1_changeCount2(name, formData) { - "use server"; - count += Number(formData.get(name)); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_1_changeCount2, "name", { value: "changeCount2" }); - " - `) - }) - - it('arrow', async () => { - const input = ` -let count = 0; - -function Counter() { - const name = "value"; - - return { - type: "form", - action: (formData) => { - "use server"; - count += Number(formData.get(name)); - } - } -} -` - expect(await testTransform(input)).toMatchInlineSnapshot(` - " - let count = 0; - - function Counter() { - const name = "value"; - - return { - type: "form", - action: /* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, name) - } - } - - ;export function $$hoist_0_anonymous_server_function(name, formData) { - "use server"; - count += Number(formData.get(name)); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); - " - `) - - expect(await testTransform(input, { encode: true })).toMatchInlineSnapshot(` - " - let count = 0; - - function Counter() { - const name = "value"; - - return { - type: "form", - action: /* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, __enc([name])) - } - } - - ;export function $$hoist_0_anonymous_server_function($$hoist_encoded, formData) { - const [name] = __dec($$hoist_encoded); - "use server"; - count += Number(formData.get(name)); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); - " - `) - }) - - it('higher order', async () => { - // packages/react-server/examples/next/app/actions/header/page.tsx - // packages/react-server/examples/next/app/actions/header/validator.ts - const input = ` -export default function Page() { - const x = 0; - const action = validator(async (y) => { - "use server"; - return x + y; - }) -} - -function validator(action) { - return async function (arg) { - "use server"; - return action(arg); - }; -} -` - expect(await testTransform(input)).toMatchInlineSnapshot(` - " - export default function Page() { - const x = 0; - const action = validator(/* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, x)) - } - - function validator(action) { - return /* #__PURE__ */ $$register($$hoist_1_anonymous_server_function, "", "$$hoist_1_anonymous_server_function").bind(null, action); - } - - ;export async function $$hoist_0_anonymous_server_function(x, y) { - "use server"; - return x + y; - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); - - ;export async function $$hoist_1_anonymous_server_function(action, arg) { - "use server"; - return action(arg); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_1_anonymous_server_function, "name", { value: "anonymous_server_function" }); - " - `) - - expect(await testTransform(input, { encode: true })).toMatchInlineSnapshot(` - " - export default function Page() { - const x = 0; - const action = validator(/* #__PURE__ */ $$register($$hoist_0_anonymous_server_function, "", "$$hoist_0_anonymous_server_function").bind(null, __enc([x]))) - } - - function validator(action) { - return /* #__PURE__ */ $$register($$hoist_1_anonymous_server_function, "", "$$hoist_1_anonymous_server_function").bind(null, __enc([action])); - } - - ;export async function $$hoist_0_anonymous_server_function($$hoist_encoded, y) { - const [x] = __dec($$hoist_encoded); - "use server"; - return x + y; - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_anonymous_server_function, "name", { value: "anonymous_server_function" }); - - ;export async function $$hoist_1_anonymous_server_function($$hoist_encoded, arg) { - const [action] = __dec($$hoist_encoded); - "use server"; - return action(arg); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_1_anonymous_server_function, "name", { value: "anonymous_server_function" }); - " - `) - }) - - // edge case found in https://github.com/remix-run/react-router/blob/98367e49900701c460cb08eb16c2441da5007efc/playground/rsc-vite/src/routes/home/home.tsx - it('export before import', async () => { - const input = ` -export {} from "edge-case"; -import { redirect } from "react-router/rsc"; - -export default () => { - const redirectOnServer = async () => { - "use server"; - throw redirect(); - }; -} -` - expect(await testTransform(input)).toMatchInlineSnapshot(` - " - export {} from "edge-case"; - import { redirect } from "react-router/rsc"; - - export default () => { - const redirectOnServer = /* #__PURE__ */ $$register($$hoist_0_redirectOnServer, "", "$$hoist_0_redirectOnServer"); - } - - ;export async function $$hoist_0_redirectOnServer() { - "use server"; - throw redirect(); - }; - /* #__PURE__ */ Object.defineProperty($$hoist_0_redirectOnServer, "name", { value: "redirectOnServer" }); - " - `) - }) - it('noExport', async () => { const input = ` export async function test() {