|
6 | 6 | readPersistedInstalledPluginIndex, |
7 | 7 | writePersistedInstalledPluginIndex, |
8 | 8 | } 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"; |
10 | 10 | import { |
11 | 11 | loadPluginManifestRegistryForInstalledIndex, |
12 | 12 | resolveInstalledManifestRegistryIndexFingerprint, |
@@ -151,6 +151,24 @@ function createIndexWithPackageJson(rootDir: string): InstalledPluginIndex { |
151 | 151 | }; |
152 | 152 | } |
153 | 153 |
|
| 154 | +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 | + |
154 | 172 | describe("loadPluginManifestRegistryForInstalledIndex", () => { |
155 | 173 | it("reuses frozen installed-index fingerprints when file signatures are persisted", () => { |
156 | 174 | const rootDir = makeTempDir(); |
@@ -180,6 +198,97 @@ describe("loadPluginManifestRegistryForInstalledIndex", () => { |
180 | 198 | expect(second).not.toBe(first); |
181 | 199 | }); |
182 | 200 |
|
| 201 | + 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 | + |
183 | 292 | it("does not cache shallow-frozen installed-index fingerprints with mutable nested records", () => { |
184 | 293 | const rootDir = makeTempDir(); |
185 | 294 | writePlugin(rootDir, "installed", "installed-"); |
|
0 commit comments