



























@@ -6,7 +6,7 @@ import {
66readPersistedInstalledPluginIndex,
77writePersistedInstalledPluginIndex,
88} from "./installed-plugin-index-store.js";
9-import type { InstalledPluginIndex } from "./installed-plugin-index.js";
9+import type { InstalledPluginIndex, InstalledPluginIndexRecord } from "./installed-plugin-index.js";
1010import {
1111loadPluginManifestRegistryForInstalledIndex,
1212resolveInstalledManifestRegistryIndexFingerprint,
@@ -151,6 +151,24 @@ function createIndexWithPackageJson(rootDir: string): InstalledPluginIndex {
151151};
152152}
153153154+function createIndexWithUnhashedPackageJson(rootDir: string): InstalledPluginIndex {
155+const index = createIndexWithFileSignatures(rootDir);
156+const packageJsonPath = writePackageManifest(rootDir, "Installed");
157+const record = index.plugins[0];
158+if (!record) {
159+throw new Error("expected index record");
160+}
161+record.packageJson = {
162+path: "package.json",
163+hash: "",
164+fileSignature: fileSignature(packageJsonPath),
165+};
166+return {
167+ ...index,
168+plugins: [record],
169+};
170+}
171+154172describe("loadPluginManifestRegistryForInstalledIndex", () => {
155173it("reuses frozen installed-index fingerprints when file signatures are persisted", () => {
156174const rootDir = makeTempDir();
@@ -180,6 +198,97 @@ describe("loadPluginManifestRegistryForInstalledIndex", () => {
180198expect(second).not.toBe(first);
181199});
182200201+it("reuses package realpaths across mutable installed-index fingerprint builds", () => {
202+const rootDir = makeTempDir();
203+writePlugin(rootDir, "installed", "installed-");
204+const index = createIndexWithUnhashedPackageJson(rootDir);
205+const packageJsonPath = path.join(fs.realpathSync(rootDir), "package.json");
206+const realpathSpy = vi.spyOn(fs, "realpathSync");
207+let rootPathCalls: unknown[][];
208+let packageJsonPathCalls: unknown[][];
209+try {
210+resolveInstalledManifestRegistryIndexFingerprint(index);
211+resolveInstalledManifestRegistryIndexFingerprint(index);
212+rootPathCalls = realpathSpy.mock.calls.filter(([filePath]) => filePath === rootDir);
213+packageJsonPathCalls = realpathSpy.mock.calls.filter(
214+([filePath]) => filePath === packageJsonPath,
215+);
216+} finally {
217+realpathSpy.mockRestore();
218+}
219+220+expect(rootPathCalls).toHaveLength(1);
221+expect(packageJsonPathCalls).toHaveLength(1);
222+});
223+224+it("clears package realpath memoization with plugin metadata lifecycle caches", () => {
225+const rootDir = makeTempDir();
226+writePlugin(rootDir, "installed", "installed-");
227+const index = createIndexWithUnhashedPackageJson(rootDir);
228+const packageJsonPath = path.join(fs.realpathSync(rootDir), "package.json");
229+const realpathSpy = vi.spyOn(fs, "realpathSync");
230+let rootPathCalls: unknown[][];
231+let packageJsonPathCalls: unknown[][];
232+try {
233+resolveInstalledManifestRegistryIndexFingerprint(index);
234+clearPluginMetadataLifecycleCaches();
235+resolveInstalledManifestRegistryIndexFingerprint(index);
236+rootPathCalls = realpathSpy.mock.calls.filter(([filePath]) => filePath === rootDir);
237+packageJsonPathCalls = realpathSpy.mock.calls.filter(
238+([filePath]) => filePath === packageJsonPath,
239+);
240+} finally {
241+realpathSpy.mockRestore();
242+}
243+244+expect(rootPathCalls).toHaveLength(2);
245+expect(packageJsonPathCalls).toHaveLength(2);
246+});
247+248+it("bounds package realpath memoization across many fingerprint roots", () => {
249+const firstRootDir = makeTempDir();
250+writePlugin(firstRootDir, "installed", "installed-");
251+const firstIndex = createIndexWithUnhashedPackageJson(firstRootDir);
252+resolveInstalledManifestRegistryIndexFingerprint(firstIndex);
253+254+const records: InstalledPluginIndexRecord[] = [];
255+for (let index = 0; index < 300; index += 1) {
256+const rootDir = makeTempDir();
257+const pluginId = `installed-${index}`;
258+writePlugin(rootDir, pluginId, `${pluginId}-`);
259+const record = createIndexWithUnhashedPackageJson(rootDir).plugins[0];
260+if (!record) {
261+throw new Error("expected index record");
262+}
263+records.push({
264+ ...record,
265+ pluginId,
266+manifestHash: `manifest-hash-${index}`,
267+});
268+}
269+resolveInstalledManifestRegistryIndexFingerprint({
270+ ...firstIndex,
271+plugins: records,
272+});
273+274+const packageJsonPath = path.join(fs.realpathSync(firstRootDir), "package.json");
275+const realpathSpy = vi.spyOn(fs, "realpathSync");
276+let rootPathCalls: unknown[][];
277+let packageJsonPathCalls: unknown[][];
278+try {
279+resolveInstalledManifestRegistryIndexFingerprint(firstIndex);
280+rootPathCalls = realpathSpy.mock.calls.filter(([filePath]) => filePath === firstRootDir);
281+packageJsonPathCalls = realpathSpy.mock.calls.filter(
282+([filePath]) => filePath === packageJsonPath,
283+);
284+} finally {
285+realpathSpy.mockRestore();
286+}
287+288+expect(rootPathCalls).toHaveLength(1);
289+expect(packageJsonPathCalls).toHaveLength(1);
290+});
291+183292it("does not cache shallow-frozen installed-index fingerprints with mutable nested records", () => {
184293const rootDir = makeTempDir();
185294writePlugin(rootDir, "installed", "installed-");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。