diff --git a/packages/plugin-rsc/package.json b/packages/plugin-rsc/package.json index 99a2e84ad..baf3fc08e 100644 --- a/packages/plugin-rsc/package.json +++ b/packages/plugin-rsc/package.json @@ -25,6 +25,7 @@ "./package.json": "./package.json", "./types": "./types/index.d.ts", ".": "./dist/index.js", + "./utils": "./dist/utils.js", "./transforms": "./dist/transforms/index.js", "./*": "./dist/*.js" }, diff --git a/packages/plugin-rsc/src/utils.test.ts b/packages/plugin-rsc/src/utils.test.ts new file mode 100644 index 000000000..9cd7537e8 --- /dev/null +++ b/packages/plugin-rsc/src/utils.test.ts @@ -0,0 +1,61 @@ +import type { DevEnvironment } from 'vite' +import { describe, expect, it } from 'vitest' +import { hashString, normalizeViteImportAnalysisUrl } from './utils' + +function createEnvironment(options?: { + consumer?: 'client' | 'server' + timestamp?: number +}) { + return { + config: { + root: '/root', + consumer: options?.consumer ?? 'server', + }, + moduleGraph: { + getModuleById: () => + options?.timestamp + ? { lastHMRTimestamp: options.timestamp } + : undefined, + }, + } as unknown as DevEnvironment +} + +describe(hashString, () => { + it('returns a stable short sha256 hash', () => { + expect(hashString('test')).toBe('9f86d081884c') + expect(hashString('test')).toBe(hashString('test')) + expect(hashString('other')).not.toBe(hashString('test')) + }) +}) + +describe(normalizeViteImportAnalysisUrl, () => { + it('normalizes root files and virtual ids', () => { + const environment = createEnvironment() + expect( + normalizeViteImportAnalysisUrl(environment, '/root/src/action.ts'), + ).toBe('/src/action.ts') + expect(normalizeViteImportAnalysisUrl(environment, 'virtual:action')).toBe( + '/@id/virtual:action', + ) + }) + + it('injects HMR timestamps for client consumers or when requested', () => { + const id = '/root/src/action.ts' + expect( + normalizeViteImportAnalysisUrl( + createEnvironment({ consumer: 'client', timestamp: 123 }), + id, + ), + ).toBe('/src/action.ts?t=123') + expect( + normalizeViteImportAnalysisUrl( + createEnvironment({ timestamp: 456 }), + id, + { injectHMRTimestamp: true }, + ), + ).toBe('/src/action.ts?t=456') + expect( + normalizeViteImportAnalysisUrl(createEnvironment({ timestamp: 789 }), id), + ).toBe('/src/action.ts') + }) +}) diff --git a/packages/plugin-rsc/src/utils.ts b/packages/plugin-rsc/src/utils.ts new file mode 100644 index 000000000..efbc0e34e --- /dev/null +++ b/packages/plugin-rsc/src/utils.ts @@ -0,0 +1,2 @@ +export { hashString } from './plugins/utils' +export { normalizeViteImportAnalysisUrl } from './plugins/vite-utils' diff --git a/packages/plugin-rsc/tsdown.config.ts b/packages/plugin-rsc/tsdown.config.ts index d226dd01d..78efa1dcf 100644 --- a/packages/plugin-rsc/tsdown.config.ts +++ b/packages/plugin-rsc/tsdown.config.ts @@ -15,6 +15,7 @@ export default defineConfig({ 'src/react/browser.ts', 'src/react/ssr.ts', 'src/react/rsc.ts', + 'src/utils.ts', 'src/transforms/index.ts', 'src/plugins/cjs.ts', 'src/utils/rpc.ts',