From 74d68427b2f6c396431ff0ba0edca3b98e290b53 Mon Sep 17 00:00:00 2001 From: neverland Date: Tue, 20 Oct 2026 21:04:05 +0800 Subject: [PATCH 1/2] perf(fmt): reuse formatter import promise --- packages/rstack/src/fmt/worker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/rstack/src/fmt/worker.ts b/packages/rstack/src/fmt/worker.ts index 74252679..56238f4a 100644 --- a/packages/rstack/src/fmt/worker.ts +++ b/packages/rstack/src/fmt/worker.ts @@ -12,6 +12,8 @@ interface FormatFileTask { cache?: FmtFileCache; } +let formatModule: Promise | undefined; + const hashContent = (content: string | Uint8Array): string => hash('sha256', content, 'base64url').slice(0, 16); @@ -65,7 +67,7 @@ const formatFile = async ({ } } - const { formatFmtSource } = await import('./format.ts'); + const { formatFmtSource } = await (formatModule ??= import('./format.ts')); const result = await formatFmtSource(file, () => (source ??= readSource())); if (result.status === 'unsupported') { return cache From 459fa4cd8f25d3cdf2b64354608d12ad2a1f8cfd Mon Sep 17 00:00:00 2001 From: neverland Date: Tue, 20 Oct 2026 21:35:29 +0800 Subject: [PATCH 2/2] refactor(fmt): use shared cached import helper --- packages/rstack/src/cachedImport.ts | 12 +++++++++ packages/rstack/src/fmt/worker.ts | 5 ++-- packages/rstack/tests/cachedImport.test.ts | 30 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 packages/rstack/src/cachedImport.ts create mode 100644 packages/rstack/tests/cachedImport.test.ts diff --git a/packages/rstack/src/cachedImport.ts b/packages/rstack/src/cachedImport.ts new file mode 100644 index 00000000..24cae1a6 --- /dev/null +++ b/packages/rstack/src/cachedImport.ts @@ -0,0 +1,12 @@ +/** Share the pending import while allowing a failed import to be retried. */ +export const cachedImport = ( + importer: () => Promise, +): (() => Promise) => { + let promise: Promise | undefined; + + return () => + (promise ??= importer().catch((error: unknown) => { + promise = undefined; + throw error; + })); +}; diff --git a/packages/rstack/src/fmt/worker.ts b/packages/rstack/src/fmt/worker.ts index 56238f4a..dfe27df7 100644 --- a/packages/rstack/src/fmt/worker.ts +++ b/packages/rstack/src/fmt/worker.ts @@ -2,6 +2,7 @@ import { hash } from 'node:crypto'; import { readFileSync, writeFileSync } from 'node:fs'; +import { cachedImport } from '../cachedImport.ts'; import type { FmtCacheEntry } from './cacheStore.ts'; import { hasDottedBasename } from './pathHelpers.ts'; import type { FmtFileCache, FmtFileRequest, FmtWorkerResult } from './types.ts'; @@ -12,7 +13,7 @@ interface FormatFileTask { cache?: FmtFileCache; } -let formatModule: Promise | undefined; +const getFormatModule = cachedImport(() => import('./format.ts')); const hashContent = (content: string | Uint8Array): string => hash('sha256', content, 'base64url').slice(0, 16); @@ -67,7 +68,7 @@ const formatFile = async ({ } } - const { formatFmtSource } = await (formatModule ??= import('./format.ts')); + const { formatFmtSource } = await getFormatModule(); const result = await formatFmtSource(file, () => (source ??= readSource())); if (result.status === 'unsupported') { return cache diff --git a/packages/rstack/tests/cachedImport.test.ts b/packages/rstack/tests/cachedImport.test.ts new file mode 100644 index 00000000..5f590f58 --- /dev/null +++ b/packages/rstack/tests/cachedImport.test.ts @@ -0,0 +1,30 @@ +import { expect, rs, test } from 'rstack/test'; +import { cachedImport } from '../src/cachedImport.ts'; + +test('loads lazily and shares pending and fulfilled imports', async () => { + const module = { value: 1 }; + const importer = rs.fn(() => Promise.resolve(module)); + const load = cachedImport(importer); + + expect(importer).not.toHaveBeenCalled(); + const pending = load(); + expect(load()).toBe(pending); + await expect(pending).resolves.toBe(module); + await expect(load()).resolves.toBe(module); + expect(importer).toHaveBeenCalledTimes(1); +}); + +test('allows retrying a failed import', async () => { + const error = new Error('Failed to load module'); + const module = { value: 1 }; + const importer = rs + .fn<() => Promise>() + .mockRejectedValueOnce(error) + .mockResolvedValue(module); + const load = cachedImport(importer); + + await expect(load()).rejects.toBe(error); + await expect(load()).resolves.toBe(module); + await expect(load()).resolves.toBe(module); + expect(importer).toHaveBeenCalledTimes(2); +});