-
-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3b17ef6
commit 83dea6e
Showing
9 changed files
with
195 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,14 @@ | ||
import module from 'node:module'; | ||
import { MessageChannel } from 'node:worker_threads'; | ||
import { installSourceMapSupport } from '../source-map.js'; | ||
|
||
export const registerLoader = () => { | ||
const { port1, port2 } = new MessageChannel(); | ||
|
||
installSourceMapSupport(); | ||
if (process.send) { | ||
port1.addListener('message', (message) => { | ||
if (message.type === 'dependency') { | ||
process.send!(message); | ||
} | ||
}); | ||
} | ||
|
||
// Allows process to exit without waiting for port to close | ||
port1.unref(); | ||
|
||
module.register( | ||
'./index.mjs', | ||
{ | ||
parentURL: import.meta.url, | ||
data: { | ||
port: port2, | ||
}, | ||
transferList: [port2], | ||
data: true, | ||
}, | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import net from 'net'; | ||
import { getPipePath } from './get-pipe-path.js'; | ||
|
||
export type SendToParent = (data: Record<string, unknown>) => void; | ||
|
||
const connectToServer = () => new Promise<SendToParent | void>((resolve) => { | ||
const pipePath = getPipePath(process.ppid); | ||
const socket: net.Socket = net.createConnection( | ||
pipePath, | ||
() => { | ||
resolve((data) => { | ||
const messageBuffer = Buffer.from(JSON.stringify(data)); | ||
const lengthBuffer = Buffer.alloc(4); | ||
lengthBuffer.writeInt32BE(messageBuffer.length, 0); | ||
socket.write(Buffer.concat([lengthBuffer, messageBuffer])); | ||
}); | ||
}, | ||
); | ||
|
||
/** | ||
* Ignore error when: | ||
* - Called as a loader and there is no server | ||
* - Nested process when using --test and the ppid is incorrect | ||
*/ | ||
socket.on('error', () => { | ||
resolve(); | ||
}); | ||
|
||
// Prevent Node from waiting for this socket to close before exiting | ||
socket.unref(); | ||
}); | ||
|
||
export const connectingToServer = connectToServer(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import path from 'path'; | ||
import { tmpdir } from '../temporary-directory.js'; | ||
|
||
export const getPipePath = (processId: number) => { | ||
const pipePath = path.join(tmpdir, `${processId}.pipe`); | ||
return ( | ||
process.platform === 'win32' | ||
? `\\\\?\\pipe\\${pipePath}` | ||
: pipePath | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import net from 'net'; | ||
import fs from 'fs'; | ||
import { tmpdir } from '../temporary-directory.js'; | ||
import { getPipePath } from './get-pipe-path.js'; | ||
|
||
type OnMessage = (message: Buffer) => void; | ||
|
||
const bufferData = ( | ||
onMessage: OnMessage, | ||
) => { | ||
let buffer = Buffer.alloc(0); | ||
return (data: Buffer) => { | ||
buffer = Buffer.concat([buffer, data]); | ||
|
||
while (buffer.length > 4) { | ||
const messageLength = buffer.readInt32BE(0); | ||
if (buffer.length >= 4 + messageLength) { | ||
const message = buffer.slice(4, 4 + messageLength); | ||
onMessage(message); | ||
buffer = buffer.slice(4 + messageLength); | ||
} else { | ||
break; | ||
} | ||
} | ||
}; | ||
}; | ||
|
||
export const createIpcServer = async () => { | ||
const server = net.createServer((socket) => { | ||
socket.on('data', bufferData((message: Buffer) => { | ||
const data = JSON.parse(message.toString()); | ||
server.emit('data', data); | ||
})); | ||
}); | ||
|
||
const pipePath = getPipePath(process.pid); | ||
await fs.promises.mkdir(tmpdir, { recursive: true }); | ||
|
||
await new Promise<void>((resolve, reject) => { | ||
server.listen(pipePath, resolve); | ||
server.on('error', reject); | ||
}); | ||
|
||
// Prevent Node from waiting for this socket to close before exiting | ||
server.unref(); | ||
|
||
process.on('exit', () => { | ||
server.close(); | ||
|
||
/** | ||
* Only clean on Unix | ||
* | ||
* https://nodejs.org/api/net.html#ipc-support: | ||
* On Windows, the local domain is implemented using a named pipe. | ||
* The path must refer to an entry in \\?\pipe\ or \\.\pipe\. | ||
* Any characters are permitted, but the latter may do some processing | ||
* of pipe names, such as resolving .. sequences. Despite how it might | ||
* look, the pipe namespace is flat. Pipes will not persist. They are | ||
* removed when the last reference to them is closed. Unlike Unix domain | ||
* sockets, Windows will close and remove the pipe when the owning process exits. | ||
*/ | ||
if (process.platform !== 'win32') { | ||
try { | ||
fs.rmSync(pipePath); | ||
} catch {} | ||
} | ||
}); | ||
|
||
return server; | ||
}; |
Oops, something went wrong.