Skip to content

Commit

Permalink
Move all Prettier logic to the worker
Browse files Browse the repository at this point in the history
This way the only data that needs to be cloned using the Structured
Clone Algorithm is the string contents. This means the Prettier
configuration may now use plugins.

Because `tsx` was unable to resolve `worker.ts` with a `.js` extension,
the code had to be changed to JavaScript. Because of a bug in
TypeScript, type definitions had to be written manually.

Closes #1
  • Loading branch information
remcohaszing committed Aug 1, 2023
1 parent c113447 commit 2f22eb8
Show file tree
Hide file tree
Showing 10 changed files with 899 additions and 1,272 deletions.
1 change: 1 addition & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ root: true
extends:
- remcohaszing
rules:
new-cap: off
import/no-extraneous-dependencies: off
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
coverage/
node_modules/
*.d.ts
*.js
*.log
*.tgz
13 changes: 13 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type Options } from 'prettier'
import { type FrozenProcessor } from 'unified'

/**
* A unified plugin to format output using Prettier.
*
* @param options
* Options to pass to Prettier.
*/
export default function unifiedPrettier<Processor extends FrozenProcessor<void, void, void, void>>(
this: Processor,
options?: Options | undefined
): undefined
64 changes: 64 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { resolve } from 'node:path'
import { MessageChannel, receiveMessageOnPort, Worker } from 'node:worker_threads'

/** @type {Worker} */
let worker

/**
* A unified plugin to format output using Prettier.
*
* @param {import('prettier').Options | undefined} [options]
* Options to pass to Prettier.
* @this {import('unified').FrozenProcessor}
*/
export default function unifiedPrettier(options) {
const { Compiler } = this

if (!Compiler) {
throw new Error('unified-prettier needs another compiler to be registered first')
}

this.Compiler = (tree, file) => {
/** @type {unknown} */
let content
if (Compiler.prototype?.compile) {
const compiler = new /** @type {any} */ (Compiler)(tree, file)
content = compiler.compile()
} else {
content = /** @type {import('unified').CompilerFunction} */ (Compiler)(tree, file)
}

const filepath = resolve(file.cwd, file.path)

const signal = new Int32Array(new SharedArrayBuffer(4))
const { port1: localPort, port2: workerPort } = new MessageChannel()

if (!worker) {
worker = new Worker(new URL('worker.js', import.meta.url))
worker.unref()
}

worker.postMessage(
/** @type {import('./worker.js').Payload} */ ({
content: String(content),
filepath,
options,
port: workerPort,
signal
}),
[workerPort]
)

Atomics.wait(signal, 0, 0)

const { message } = /** @type {{ message: import('./worker.js').Response }} */ (
receiveMessageOnPort(localPort)
)

if ('error' in message) {
throw message.error
}

return message.result
}
}
47 changes: 0 additions & 47 deletions index.ts

This file was deleted.

Loading

0 comments on commit 2f22eb8

Please sign in to comment.