Repository: dai-shi/waku
Pull request #1205 (2025-02-01 09:38:13)

fix: prefix for exported functions
To make it consistent:
- `unstable_` functions are subject to change
- `INTERNAL_` functions are not public API (and implies `unstable_`)

vercel[bot]: [vc]: #1HksAbLSUg41/xtZHH9+aZj8QaDL3Xj4y4Qee5ab/zw=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJ3YWt1IiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL2RhaXNoaXMtcHJvamVjdHMvd2FrdS83ZVpSSjVNUDJjUmVkaGFzMllESFE1UWJyZm5UIiwicHJldmlld1VybCI6Indha3UtZ2l0LWZpeC1leHBvcnRlZC1mdW5jdGlvbi1wcmVmaXgtZGFpc2hpcy1wcm9qZWN0cy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIn1dfQ==
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Updated (UTC) |
| :--- | :----- | :------ | :------ |
| **waku** | ✅ Ready ([Inspect](https://vercel.com/daishis-projects/waku/7eZRJ5MP2cRedhas2YDHQ5QbrfnT)) | [Visit Preview](https://waku-git-fix-exported-function-prefix-daishis-projects.vercel.app) | Feb 1, 2025 9:38am |


codesandbox-ci[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/dai-shi/waku/pr/1205/builds/584142) or the icon next to each commit SHA.

Patch:
diff --git a/examples/11_fs-router/src/entries.tsx b/examples/11_fs-router/src/entries.tsx
index c4d32be8..553f3991 100644
--- a/examples/11_fs-router/src/entries.tsx
+++ b/examples/11_fs-router/src/entries.tsx
@@ -1,4 +1,4 @@
-import { fsRouter } from 'waku/router/server';
+import { unstable_fsRouter as fsRouter } from 'waku/router/server';
 
 declare global {
   interface ImportMeta {
diff --git a/examples/12_nossr/src/entries.ts b/examples/12_nossr/src/entries.ts
index 0c951b95..94348e6a 100644
--- a/examples/12_nossr/src/entries.ts
+++ b/examples/12_nossr/src/entries.ts
@@ -1,7 +1,7 @@
 /// <reference types="vite/client" />
 
 import { unstable_defineEntries as defineEntries } from 'waku/minimal/server';
-import { fsRouter } from 'waku/router/server';
+import { unstable_fsRouter as fsRouter } from 'waku/router/server';
 
 const router = fsRouter(
   import.meta.url,
diff --git a/packages/waku/src/client.ts b/packages/waku/src/client.ts
index a11e360a..c7629740 100644
--- a/packages/waku/src/client.ts
+++ b/packages/waku/src/client.ts
@@ -1,4 +1,4 @@
 /**
  * Highly experimental, the name might change.
  */
-export const allowServer = <T>(x: T) => x;
+export const unstable_allowServer = <T>(x: T) => x;
diff --git a/packages/waku/src/config.ts b/packages/waku/src/config.ts
index bffd6b7f..2661f832 100644
--- a/packages/waku/src/config.ts
+++ b/packages/waku/src/config.ts
@@ -7,6 +7,7 @@ export interface Config {
   /**
    * The base path for serve HTTP.
    * Defaults to  "/".
+   * TODO https://github.com/dai-shi/waku/issues/698
    */
   basePath?: string;
   /**
diff --git a/packages/waku/src/lib/builder/build.ts b/packages/waku/src/lib/builder/build.ts
index 59a3ca57..cb5eadba 100644
--- a/packages/waku/src/lib/builder/build.ts
+++ b/packages/waku/src/lib/builder/build.ts
@@ -8,8 +8,8 @@ import type { ReactNode } from 'react';
 
 import type { Config } from '../../config.js';
 import {
-  setAllEnvInternal,
-  iterateSerializablePlatformDataInternal,
+  INTERNAL_setAllEnv,
+  INTERNAL_iterateSerializablePlatformData,
   unstable_getBuildOptions,
 } from '../../server.js';
 import type { EntriesPrd } from '../types.js';
@@ -747,7 +747,7 @@ export async function build(options: {
     filePathToFileURL(distEntriesFile)
   );
 
-  setAllEnvInternal(env);
+  INTERNAL_setAllEnv(env);
   const cssAssets = clientBuildOutput.output.flatMap(({ type, fileName }) =>
     type === 'asset' && fileName.endsWith('.css') ? [fileName] : [],
   );
@@ -770,7 +770,7 @@ export async function build(options: {
     await mkdir(joinPath(rootDir, config.distDir, DIST_PLATFORM_DATA), {
       recursive: true,
     });
-    for (const [key, data] of iterateSerializablePlatformDataInternal()) {
+    for (const [key, data] of INTERNAL_iterateSerializablePlatformData()) {
       keys.add(key);
       const destFile = joinPath(
         rootDir,
diff --git a/packages/waku/src/lib/middleware/handler.ts b/packages/waku/src/lib/middleware/handler.ts
index 319fa153..59fca4c2 100644
--- a/packages/waku/src/lib/middleware/handler.ts
+++ b/packages/waku/src/lib/middleware/handler.ts
@@ -3,8 +3,8 @@ import type { ReactNode } from 'react';
 import { resolveConfig, extractPureConfig } from '../config.js';
 import type { PureConfig } from '../config.js';
 import {
-  setAllEnvInternal,
-  setPlatformDataLoaderInternal,
+  INTERNAL_setAllEnv,
+  INTERNAL_setPlatformDataLoader,
 } from '../../server.js';
 import type { HandleRequest, HandlerRes } from '../types.js';
 import type { Middleware, HandlerContext } from './types.js';
@@ -71,7 +71,7 @@ const getInput = async (
 
 export const handler: Middleware = (options) => {
   const env = options.env || {};
-  setAllEnvInternal(env);
+  INTERNAL_setAllEnv(env);
   const entriesPromise =
     options.cmd === 'start'
       ? options.loadEntries()
@@ -80,7 +80,7 @@ export const handler: Middleware = (options) => {
     options.cmd === 'start'
       ? entriesPromise.then(async (entries) => {
           if (entries.loadPlatformData) {
-            setPlatformDataLoaderInternal(entries.loadPlatformData);
+            INTERNAL_setPlatformDataLoader(entries.loadPlatformData);
           }
           return resolveConfig(await entries.loadConfig());
         })
diff --git a/packages/waku/src/lib/plugins/vite-plugin-deploy-cloudflare.ts b/packages/waku/src/lib/plugins/vite-plugin-deploy-cloudflare.ts
index 47f26fb0..cbaf8667 100644
--- a/packages/waku/src/lib/plugins/vite-plugin-deploy-cloudflare.ts
+++ b/packages/waku/src/lib/plugins/vite-plugin-deploy-cloudflare.ts
@@ -14,7 +14,7 @@ import { randomBytes } from 'node:crypto';
 import type { Plugin } from 'vite';
 
 import {
-  iterateSerializablePlatformDataInternal,
+  INTERNAL_iterateSerializablePlatformData,
   unstable_getBuildOptions,
 } from '../../server.js';
 import { SRC_ENTRIES } from '../constants.js';
@@ -215,7 +215,7 @@ export function deployCloudflarePlugin(opts: {
       mkdirSync(path.join(workerDistDir, DIST_PLATFORM_DATA), {
         recursive: true,
       });
-      for (const [key, data] of iterateSerializablePlatformDataInternal()) {
+      for (const [key, data] of INTERNAL_iterateSerializablePlatformData()) {
         keys.add(key);
         const destFile = path.join(
           workerDistDir,
diff --git a/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts b/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts
index 542c52c7..f4ef8a80 100644
--- a/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts
+++ b/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts
@@ -13,7 +13,7 @@ const getManagedEntries = (
   srcDir: string,
   pagesDir: string,
 ) => `
-import { fsRouter } from 'waku/router/server';
+import { unstable_fsRouter as fsRouter } from 'waku/router/server';
 
 export default fsRouter(
   '${filePathToFileURL(filePath)}',
diff --git a/packages/waku/src/lib/plugins/vite-plugin-rsc-transform.ts b/packages/waku/src/lib/plugins/vite-plugin-rsc-transform.ts
index 82b81ffd..8ea228af 100644
--- a/packages/waku/src/lib/plugins/vite-plugin-rsc-transform.ts
+++ b/packages/waku/src/lib/plugins/vite-plugin-rsc-transform.ts
@@ -61,7 +61,7 @@ const transformClient = (
     const exportNames = collectExportNames(mod);
     let newCode = `
 import { createServerReference } from 'react-server-dom-webpack/client';
-import { callServerRsc } from 'waku/minimal/client';
+import { unstable_callServerRsc as callServerRsc } from 'waku/minimal/client';
 `;
     for (const name of exportNames) {
       newCode += `
@@ -189,14 +189,14 @@ const transformExportedClientThings = (
     });
   };
   // Pass 1: find allowServer identifier
-  let allowServer = 'allowServer';
+  let allowServer = 'unstable_allowServer';
   for (const item of mod.body) {
     if (item.type === 'ImportDeclaration') {
       if (item.source.value === 'waku/client') {
         for (const specifier of item.specifiers) {
           if (specifier.type === 'ImportSpecifier') {
-            if (specifier.local.value === allowServer && specifier.imported) {
-              allowServer = specifier.imported.value;
+            if (specifier.imported?.value === allowServer) {
+              allowServer = specifier.local.value;
               break;
             }
           }
diff --git a/packages/waku/src/lib/renderers/html.ts b/packages/waku/src/lib/renderers/html.ts
index d80482ee..3b259db1 100644
--- a/packages/waku/src/lib/renderers/html.ts
+++ b/packages/waku/src/lib/renderers/html.ts
@@ -180,7 +180,7 @@ export async function renderHtml(
   const {
     default: { createFromReadableStream },
   } = modules.rsdwClient as { default: typeof RSDWClientType };
-  const { ServerRootInternal: ServerRoot } =
+  const { INTERNAL_ServerRoot } =
     modules.wakuMinimalClient as typeof WakuMinimalClientType;
 
   const stream = await renderRsc(config, ctx, elements);
@@ -226,8 +226,8 @@ export async function renderHtml(
   try {
     const readable = await renderToReadableStream(
       createElement(
-        ServerRoot as FunctionComponent<
-          Omit<ComponentProps<typeof ServerRoot>, 'children'>
+        INTERNAL_ServerRoot as FunctionComponent<
+          Omit<ComponentProps<typeof INTERNAL_ServerRoot>, 'children'>
         >,
         { elementsPromise },
         htmlNode as any,
diff --git a/packages/waku/src/minimal/client.ts b/packages/waku/src/minimal/client.ts
index 1502d458..c8dea976 100644
--- a/packages/waku/src/minimal/client.ts
+++ b/packages/waku/src/minimal/client.ts
@@ -98,7 +98,7 @@ const defaultFetchCache: FetchCache = {};
  * callServer callback
  * This is not a public API.
  */
-export const callServerRsc = async (
+export const unstable_callServerRsc = async (
   funcId: string,
   args: unknown[],
   fetchCache = defaultFetchCache,
@@ -108,7 +108,7 @@ export const callServerRsc = async (
   const createData = (responsePromise: Promise<Response>) =>
     createFromFetch<Elements>(checkStatus(responsePromise), {
       callServer: (funcId: string, args: unknown[]) =>
-        callServerRsc(funcId, args, fetchCache),
+        unstable_callServerRsc(funcId, args, fetchCache),
     });
   const url = BASE_PATH + encodeRscPath(encodeFuncId(funcId));
   const responsePromise =
@@ -154,7 +154,7 @@ export const fetchRsc = (
   const createData = (responsePromise: Promise<Response>) =>
     createFromFetch<Elements>(checkStatus(responsePromise), {
       callServer: (funcId: string, args: unknown[]) =>
-        callServerRsc(funcId, args, fetchCache),
+        unstable_callServerRsc(funcId, args, fetchCache),
     });
   const prefetched = ((globalThis as any).__WAKU_PREFETCHED__ ||= {});
   const url = BASE_PATH + encodeRscPath(rscPath);
@@ -359,7 +359,7 @@ export const Children = () => use(ChildrenContext);
  * ServerRoot for SSR
  * This is not a public API.
  */
-export const ServerRootInternal = ({
+export const INTERNAL_ServerRoot = ({
   elementsPromise,
   children,
 }: {
diff --git a/packages/waku/src/router/client.ts b/packages/waku/src/router/client.ts
index 0564f044..09a27240 100644
--- a/packages/waku/src/router/client.ts
+++ b/packages/waku/src/router/client.ts
@@ -524,7 +524,7 @@ export function Router({
  * ServerRouter for SSR
  * This is not a public API.
  */
-export function ServerRouter({ route }: { route: RouteProps }) {
+export function INTERNAL_ServerRouter({ route }: { route: RouteProps }) {
   const routeElement = createElement(Slot, { id: getRouteSlotId(route.path) });
   const rootElement = createElement(
     Slot,
diff --git a/packages/waku/src/router/define-router.ts b/packages/waku/src/router/define-router.ts
index dea682fb..dbdebf01 100644
--- a/packages/waku/src/router/define-router.ts
+++ b/packages/waku/src/router/define-router.ts
@@ -17,7 +17,7 @@ import {
 } from './common.js';
 import { getPathMapping, path2regexp } from '../lib/utils/path.js';
 import type { PathSpec } from '../lib/utils/path.js';
-import { ServerRouter } from './client.js';
+import { INTERNAL_ServerRouter } from './client.js';
 import { getContext } from '../middleware/context.js';
 import { stringToStream } from '../lib/utils/stream.js';
 
@@ -318,7 +318,7 @@ export function unstable_defineRouter(fns: {
       if (!entries) {
         return null;
       }
-      const html = createElement(ServerRouter, {
+      const html = createElement(INTERNAL_ServerRouter, {
         route: { path: pathname, query, hash: '' },
       });
       const actionResult =
@@ -412,7 +412,7 @@ globalThis.__WAKU_ROUTER_PREFETCH__ = (path) => {
               (specs.is404 ? 'globalThis.__WAKU_ROUTER_404__ = true;' : '');
             const entries = entriesCache.get(pathname);
             if (specs.isStatic && entries) {
-              const html = createElement(ServerRouter, {
+              const html = createElement(INTERNAL_ServerRouter, {
                 route: { path: pathname, query: '', hash: '' },
               });
               return {
diff --git a/packages/waku/src/router/fs-router.ts b/packages/waku/src/router/fs-router.ts
index 339246a9..ef103102 100644
--- a/packages/waku/src/router/fs-router.ts
+++ b/packages/waku/src/router/fs-router.ts
@@ -10,7 +10,7 @@ import { EXTENSIONS } from '../lib/constants.js';
 
 const DO_NOT_BUNDLE = '';
 
-export function fsRouter(
+export function unstable_fsRouter(
   importMetaUrl: string,
   loadPage: (file: string) => Promise<any> | undefined,
   pages: string,
diff --git a/packages/waku/src/router/server.ts b/packages/waku/src/router/server.ts
index 6c220c01..0a25ae90 100644
--- a/packages/waku/src/router/server.ts
+++ b/packages/waku/src/router/server.ts
@@ -3,4 +3,4 @@ export {
   unstable_rerenderRoute,
 } from './define-router.js';
 export { createPages } from './create-pages.js';
-export { fsRouter } from './fs-router.js';
+export { unstable_fsRouter } from './fs-router.js';
diff --git a/packages/waku/src/server.ts b/packages/waku/src/server.ts
index a2642980..160b88df 100644
--- a/packages/waku/src/server.ts
+++ b/packages/waku/src/server.ts
@@ -6,7 +6,7 @@ import { getContext } from './middleware/context.js';
 /**
  * This is an internal function and not for public use.
  */
-export function setAllEnvInternal(newEnv: Readonly<Record<string, string>>) {
+export function INTERNAL_setAllEnv(newEnv: Readonly<Record<string, string>>) {
   (globalThis as any).__WAKU_SERVER_ENV__ = newEnv;
 }
 
@@ -17,7 +17,7 @@ export function getEnv(key: string): string | undefined {
 /**
  * This is an internal function and not for public use.
  */
-export function iterateSerializablePlatformDataInternal(): Iterable<
+export function INTERNAL_iterateSerializablePlatformData(): Iterable<
   [string, unknown]
 > {
   const platformData: Record<string, [unknown, boolean]> = ((
@@ -31,7 +31,7 @@ export function iterateSerializablePlatformDataInternal(): Iterable<
 /**
  * This is an internal function and not for public use.
  */
-export function setPlatformDataLoaderInternal(
+export function INTERNAL_setPlatformDataLoader(
   loader: (key: string) => Promise<unknown>,
 ): void {
   (globalThis as any).__WAKU_SERVER_PLATFORM_DATA_LOADER__ = loader;


Test patch:
diff --git a/packages/waku/tests/vite-plugin-rsc-transform-internals.test.ts b/packages/waku/tests/vite-plugin-rsc-transform-internals.test.ts
index 6efffa7d..0debb656 100644
--- a/packages/waku/tests/vite-plugin-rsc-transform-internals.test.ts
+++ b/packages/waku/tests/vite-plugin-rsc-transform-internals.test.ts
@@ -32,7 +32,7 @@ export default function App() {
 
 import { Component, createContext, useContext, memo } from 'react';
 import { atom } from 'jotai/vanilla';
-import { allowServer } from 'waku/client';
+import { unstable_allowServer as allowServer } from 'waku/client';
 
 const initialCount = 1;
 const TWO = 2;
@@ -440,7 +440,7 @@ export default async function log4(mesg) {
     expect(await transform(code, '/src/func.ts')).toMatchInlineSnapshot(`
       "
       import { createServerReference } from 'react-server-dom-webpack/client';
-      import { callServerRsc } from 'waku/minimal/client';
+      import { unstable_callServerRsc as callServerRsc } from 'waku/minimal/client';
 
       export const log1 = createServerReference('/src/func.ts#log1', callServerRsc);