diff --git a/config/packaged-runtime-node-modules.cjs b/config/packaged-runtime-node-modules.cjs index 30f0e999c3f..1eca37b7c05 100644 --- a/config/packaged-runtime-node-modules.cjs +++ b/config/packaged-runtime-node-modules.cjs @@ -439,24 +439,22 @@ function prunePackagedParcelWatcher(resourcesDir, electronPlatformName, electron } } -function prunePackagedRuntimeTypeDeclarations(resourcesDir) { - const nodeModulesDir = join(resourcesDir, 'node_modules') - if (!existsSync(nodeModulesDir)) { - return - } - pruneMatchingFiles(nodeModulesDir, (filename) => TYPE_DECLARATION_ARTIFACT_RE.test(filename)) +// Why type declarations: they are compile-time only; the packaged app never resolves them. +// Why source maps: they embed the original sources (megabytes for @linear/sdk alone) and +// nothing in the packaged app turns on Node's source-map support, so they are never read. +// Orca's own main-process maps live outside node_modules and ship as a separate release artifact. +function isPrunableTypeOrSourceMapArtifact(filename) { + return TYPE_DECLARATION_ARTIFACT_RE.test(filename) || JS_SOURCE_MAP_ARTIFACT_RE.test(filename) } -function prunePackagedRuntimeSourceMaps(resourcesDir) { - // Why: dependency source maps embed the original sources (megabytes for - // @linear/sdk alone), and nothing in the packaged app turns on Node's - // source-map support, so they are never read. Orca's own main-process maps - // live outside node_modules and ship as a separate release artifact. +// Why one walk: pruneMatchingFiles only ever deletes files, so passes over the same tree +// commute — a second recursive traversal costs seconds for no extra deletions. +function prunePackagedRuntimeTypeAndSourceMapArtifacts(resourcesDir) { const nodeModulesDir = join(resourcesDir, 'node_modules') if (!existsSync(nodeModulesDir)) { return } - pruneMatchingFiles(nodeModulesDir, (filename) => JS_SOURCE_MAP_ARTIFACT_RE.test(filename)) + pruneMatchingFiles(nodeModulesDir, isPrunableTypeOrSourceMapArtifact) } function prunePackagedSherpaOnnx(resourcesDir, electronPlatformName) { @@ -494,10 +492,10 @@ function prunePackagedRuntimeNodeModules(resourcesDir, electronPlatformName, ele const architecture = normalizeElectronArchitecture(electronArch) prunePackagedNodePty(resourcesDir, electronPlatformName, architecture) prunePackagedParcelWatcher(resourcesDir, electronPlatformName, architecture) - prunePackagedRuntimeTypeDeclarations(resourcesDir) - prunePackagedRuntimeSourceMaps(resourcesDir) - prunePackagedSherpaOnnx(resourcesDir, electronPlatformName) + // Why before the filename walk: zod/src is deleted wholesale, so walking it first is wasted work. prunePackagedZodSources(resourcesDir) + prunePackagedRuntimeTypeAndSourceMapArtifacts(resourcesDir) + prunePackagedSherpaOnnx(resourcesDir, electronPlatformName) } function pruneMatchingFiles(directory, shouldPrune) { @@ -520,9 +518,8 @@ module.exports = { prunePackagedNodePty, prunePackagedParcelWatcher, prunePackagedRuntimeNodeModules, - prunePackagedRuntimeSourceMaps, + prunePackagedRuntimeTypeAndSourceMapArtifacts, prunePackagedSherpaOnnx, - prunePackagedRuntimeTypeDeclarations, prunePackagedZodSources, verifyPackagedMainRuntimeDeps } diff --git a/config/scripts/electron-builder-config.test.mjs b/config/scripts/electron-builder-config.test.mjs index 152061b432d..347cae8fcfc 100644 --- a/config/scripts/electron-builder-config.test.mjs +++ b/config/scripts/electron-builder-config.test.mjs @@ -17,7 +17,7 @@ const { prunePackagedNodePty, prunePackagedParcelWatcher, prunePackagedSherpaOnnx, - prunePackagedRuntimeTypeDeclarations, + prunePackagedRuntimeTypeAndSourceMapArtifacts, prunePackagedZodSources, verifyPackagedMainRuntimeDeps } = require('../packaged-runtime-node-modules.cjs') @@ -534,9 +534,11 @@ describe('electron-builder config', () => { await writeFile(join(packageDir, 'dist', 'index.cjs'), 'module.exports = {}', 'utf8') await writeFile(join(packageDir, 'dist', 'index.d.ts'), 'export type Value = string', 'utf8') await writeFile(join(packageDir, 'dist', 'index.d.cts'), 'export type Value = string', 'utf8') + await writeFile(join(packageDir, 'dist', 'index.d.mts'), 'export type Value = string', 'utf8') + await writeFile(join(packageDir, 'dist', 'index.d.cts.map'), '{}', 'utf8') await writeFile(join(packageDir, 'dist', 'index.d.mts.map'), '{}', 'utf8') - prunePackagedRuntimeTypeDeclarations(resourcesDir) + prunePackagedRuntimeTypeAndSourceMapArtifacts(resourcesDir) await expect(readdir(join(packageDir, 'dist'))).resolves.toEqual(['index.cjs']) } finally { diff --git a/config/scripts/packaged-source-map-prune.test.mjs b/config/scripts/packaged-source-map-prune.test.mjs index 0650e03ca56..ac21d374ae6 100644 --- a/config/scripts/packaged-source-map-prune.test.mjs +++ b/config/scripts/packaged-source-map-prune.test.mjs @@ -6,7 +6,7 @@ import { describe, expect, it } from 'vitest' const require = createRequire(import.meta.url) const { - prunePackagedRuntimeSourceMaps, + prunePackagedRuntimeTypeAndSourceMapArtifacts, prunePackagedRuntimeNodeModules } = require('../packaged-runtime-node-modules.cjs') @@ -54,14 +54,14 @@ async function createPackagedNodeModulesFixture(resourcesDir) { return { packageDir, distDir, webhooksDir, updaterDir, jsYamlDir, nodePtyDir } } -describe('packaged runtime source-map pruning', () => { +describe('packaged runtime type-declaration and source-map pruning', () => { it('removes @linear/sdk source maps while preserving runtime files and non-JS maps', async () => { const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-prune-')) try { const { packageDir, distDir, webhooksDir } = await createPackagedNodeModulesFixture(resourcesDir) - prunePackagedRuntimeSourceMaps(resourcesDir) + prunePackagedRuntimeTypeAndSourceMapArtifacts(resourcesDir) await expect(readdir(distDir).then((entries) => entries.sort())).resolves.toEqual([ 'index.cjs', @@ -91,7 +91,7 @@ describe('packaged runtime source-map pruning', () => { try { const { jsYamlDir, nodePtyDir } = await createPackagedNodeModulesFixture(resourcesDir) - prunePackagedRuntimeSourceMaps(resourcesDir) + prunePackagedRuntimeTypeAndSourceMapArtifacts(resourcesDir) await expect(readdir(jsYamlDir)).resolves.toEqual(['js-yaml.min.js']) await expect(readdir(nodePtyDir)).resolves.toEqual(['index.js']) @@ -100,25 +100,20 @@ describe('packaged runtime source-map pruning', () => { } }) - it('leaves declaration-map cleanup to the type-declaration prune', async () => { + it('removes type declarations and declaration maps in the same walk', async () => { const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-prune-dts-')) try { const { updaterDir } = await createPackagedNodeModulesFixture(resourcesDir) - prunePackagedRuntimeSourceMaps(resourcesDir) + prunePackagedRuntimeTypeAndSourceMapArtifacts(resourcesDir) - // Why: the two predicates are disjoint -- `.d.ts.map` never ends in `.js.map`. - await expect(readdir(updaterDir).then((entries) => entries.sort())).resolves.toEqual([ - 'main.d.ts', - 'main.d.ts.map', - 'main.js' - ]) + await expect(readdir(updaterDir)).resolves.toEqual(['main.js']) } finally { await rm(resourcesDir, { recursive: true, force: true }) } }) - it('runs the source-map prune through aggregate runtime cleanup', async () => { + it('runs the artifact prune through aggregate runtime cleanup', async () => { const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-aggregate-prune-')) try { const { distDir, updaterDir, packageDir } =