Skip to content

Conversation

@octogonz
Copy link
Collaborator

Summary

More progress updating Lockfile Explorer.

Details

-.pnpmcfile.cjs is now evaluated in an isolated thread; the earlier approach of simply calling require() on it would cause memory leaks and incorrect caching

  • The file dump tabs now use a syntax highlighter

How it was tested

  • Tested manually

Impacted documentation

None.

@iclanton @nickpape @william2958 @dmichon-msft

});
}

public async disposeAsync(): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use [Symbol.asyncDispose] so that this object can be used with await using

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion. Fixed.

I had to upgrade Prettier to support this syntax

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that await using is not supported by Node 18 or Jest. I will revert those changes.

@iclanton @dmichon-msft

pnpmfileModuleError = error;
}

parentPort?.on('message', async (message: IRequestMessage) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parentPort not existing should be an immediate fatal error.

let pnpmfileModuleError: Error | undefined = undefined;

try {
if (fs.existsSync(resolvedPath)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant. You're already catching the error, and you should skip the worker altogether if you know the file doesn't exist to save on all the messaging overhead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

}

try {
if (!pnpmfileModule || !pnpmfileModule.hooks || typeof pnpmfileModule.hooks.readPackage !== 'function') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest instead sending a message on initialization to the host telling it which hooks are present, then don't bother sending messages when the readPackage hook isn't defined.

Combine with an initializeAsync method on PnpmfileRunner that you wait for before calling the individual APIs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea, but in the interest of time I need to keep the implementation simple for now.

}

parentPort?.on('message', async (message: IRequestMessage) => {
const { id, packageJson } = message;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it generally useful to have false be one of the valid message values, and have that be a signal to gracefully shut down the worker. See, e.g. the ModuleMinifierWorker.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good suggestion but I would need to add some safeguards to guarantee the child really does terminate. I'll do it in a future PR.

Comment on lines +54 to 57
const packageJSONFile: IPackageJson | undefined = await readPackageJsonAsync(packageName);
setPackageJSON(packageJSONFile);
const parsedJSON = await readPackageSpecAsync(packageName);
const parsedJSON: IPackageJson | undefined = await readPackageSpecAsync(packageName);
setParsedPackageJSON(parsedJSON);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parallelize these with Promise.all?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably premature optimization at this point.

Comment on lines +11 to +61
export type PrismLanguage =
| 'plain'
| 'plaintext'
| 'text'
| 'txt'
| 'markup'
| 'html'
| 'mathml'
| 'svg'
| 'xml'
| 'ssml'
| 'atom'
| 'rss'
| 'regex'
| 'clike'
| 'javascript'
| 'js'
| 'actionscript'
| 'coffeescript'
| 'coffee'
| 'javadoclike'
| 'css'
| 'yaml'
| 'yml'
| 'markdown'
| 'md'
| 'graphql'
| 'sql'
| 'typescript'
| 'ts'
| 'jsdoc'
| 'flow'
| 'n4js'
| 'n4jsd'
| 'jsx'
| 'tsx'
| 'swift'
| 'kotlin'
| 'kt'
| 'kts'
| 'c'
| 'objectivec'
| 'objc'
| 'reason'
| 'rust'
| 'go'
| 'cpp'
| 'python'
| 'py'
| 'json'
| 'webmanifest';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export type PrismLanguage =
| 'plain'
| 'plaintext'
| 'text'
| 'txt'
| 'markup'
| 'html'
| 'mathml'
| 'svg'
| 'xml'
| 'ssml'
| 'atom'
| 'rss'
| 'regex'
| 'clike'
| 'javascript'
| 'js'
| 'actionscript'
| 'coffeescript'
| 'coffee'
| 'javadoclike'
| 'css'
| 'yaml'
| 'yml'
| 'markdown'
| 'md'
| 'graphql'
| 'sql'
| 'typescript'
| 'ts'
| 'jsdoc'
| 'flow'
| 'n4js'
| 'n4jsd'
| 'jsx'
| 'tsx'
| 'swift'
| 'kotlin'
| 'kt'
| 'kts'
| 'c'
| 'objectivec'
| 'objc'
| 'reason'
| 'rust'
| 'go'
| 'cpp'
| 'python'
| 'py'
| 'json'
| 'webmanifest';
export type PrismLanguage = Omit<import('prism-react-renderer').Prism.languages, "extend" | "insertBefore" | "DFS">

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These strings are not expressed in the Prism .d.ts file. They are apparently only available at runtime.

// "The following entrypoint(s) combined asset size exceeds the recommended limit."
// maxEntrypointSize: 500000,
// maxAssetSize: 500000
maxEntrypointSize: Infinity,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're setting these to infinity, why not just turn off performance?

Copy link
Collaborator Author

@octogonz octogonz Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iclanton Is there a better way to do that? I tried undefined but in the merge it doesn't undo the rig's setting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's performance: false

Comment on lines 225 to 229
const pnpmfilePath: string = path.join(
appState.lfxWorkspace.workspaceRootFullPath,
appState.lfxWorkspace.pnpmLockfileFolder,
'.pnpmfile.cjs'
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const pnpmfilePath: string = path.join(
appState.lfxWorkspace.workspaceRootFullPath,
appState.lfxWorkspace.pnpmLockfileFolder,
'.pnpmfile.cjs'
);
const { lfxWorkspace: { workspaceRootFullPath, pnpmLockfileFolder } } = appState;
const pnpmfilePath: string = `${workspaceRootFullPath}/${pnpmLockfileFolder}/.pnpmfile.cjs`;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would incorrectly create double-slashes when pnpmLockfileFolder is the empty string

// debugger;

const { pnpmfilePath } = workerData;
const resolvedPath: string = path.resolve(pnpmfilePath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ever not absolute?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is absolute, but only because in the current implementation, an absolute path is used by the caller of the class constructor in the other thread. It is a very brittle assumption.

@octogonz octogonz merged commit c472ad5 into microsoft:main Sep 21, 2025
5 checks passed
@github-project-automation github-project-automation bot moved this from Needs triage to Closed in Bug Triage Sep 21, 2025
@octogonz octogonz deleted the octogonz/lfx-fixes4 branch September 21, 2025 23:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Closed

Development

Successfully merging this pull request may close these issues.

3 participants