doc: esm examples /w imports for process, Buffer

PR-URL: https://github.com/nodejs/node/pull/39043
Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
This commit is contained in:
Guy Bedford 2021-06-15 10:09:29 -07:00 committed by Michaël Zasso
parent 412b1012d2
commit 81cebec5cc
No known key found for this signature in database
GPG Key ID: 770F7A9A5AE15600
13 changed files with 3650 additions and 396 deletions

View File

@ -98,6 +98,14 @@ module.exports = {
name: 'require',
message: 'Use import instead',
},
{
name: 'Buffer',
message: 'Import Buffer instead of using the global'
},
{
name: 'process',
message: 'Import process instead of using the global'
},
] },
},
],

View File

@ -240,6 +240,7 @@ for the verification to take place. The usual pattern would be to call it in a
```mjs
import assert from 'assert';
import process from 'process';
const tracker = new assert.CallTracker();

View File

@ -14,7 +14,11 @@ in other languages.
The `AsyncLocalStorage` and `AsyncResource` classes are part of the
`async_hooks` module:
```js
```mjs
import async_hooks from 'async_hooks';
```
```cjs
const async_hooks = require('async_hooks');
```
@ -40,7 +44,39 @@ The following example uses `AsyncLocalStorage` to build a simple logger
that assigns IDs to incoming HTTP requests and includes them in messages
logged within each request.
```js
```mjs
import http from 'http';
import { AsyncLocalStorage } from 'async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();
function logWithId(msg) {
const id = asyncLocalStorage.getStore();
console.log(`${id !== undefined ? id : '-'}:`, msg);
}
let idSeq = 0;
http.createServer((req, res) => {
asyncLocalStorage.run(idSeq++, () => {
logWithId('start');
// Imagine any chain of async operations here
setImmediate(() => {
logWithId('finish');
res.end();
});
});
}).listen(8080);
http.get('http://localhost:8080');
http.get('http://localhost:8080');
// Prints:
// 0: start
// 1: start
// 0: finish
// 1: finish
```
```cjs
const http = require('http');
const { AsyncLocalStorage } = require('async_hooks');
@ -299,7 +335,35 @@ The `init` hook will trigger when an `AsyncResource` is instantiated.
The following is an overview of the `AsyncResource` API.
```js
```mjs
import { AsyncResource, executionAsyncId } from 'async_hooks';
// AsyncResource() is meant to be extended. Instantiating a
// new AsyncResource() also triggers init. If triggerAsyncId is omitted then
// async_hook.executionAsyncId() is used.
const asyncResource = new AsyncResource(
type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false }
);
// Run a function in the execution context of the resource. This will
// * establish the context of the resource
// * trigger the AsyncHooks before callbacks
// * call the provided function `fn` with the supplied arguments
// * trigger the AsyncHooks after callbacks
// * restore the original execution context
asyncResource.runInAsyncScope(fn, thisArg, ...args);
// Call AsyncHooks destroy callbacks.
asyncResource.emitDestroy();
// Return the unique ID assigned to the AsyncResource instance.
asyncResource.asyncId();
// Return the trigger ID for the AsyncResource instance.
asyncResource.triggerAsyncId();
```
```cjs
const { AsyncResource, executionAsyncId } = require('async_hooks');
// AsyncResource() is meant to be extended. Instantiating a
@ -446,7 +510,14 @@ database connection pools, can follow a similar model.
Assuming that the task is adding two numbers, using a file named
`task_processor.js` with the following content:
```js
```mjs
import { parentPort } from 'worker_threads';
parentPort.on('message', (task) => {
parentPort.postMessage(task.a + task.b);
});
```
```cjs
const { parentPort } = require('worker_threads');
parentPort.on('message', (task) => {
parentPort.postMessage(task.a + task.b);
@ -455,7 +526,95 @@ parentPort.on('message', (task) => {
a Worker pool around it could use the following structure:
```js
```mjs
import { AsyncResource } from 'async_hooks';
import { EventEmitter } from 'events';
import path from 'path';
import { Worker } from 'worker_threads';
const kTaskInfo = Symbol('kTaskInfo');
const kWorkerFreedEvent = Symbol('kWorkerFreedEvent');
class WorkerPoolTaskInfo extends AsyncResource {
constructor(callback) {
super('WorkerPoolTaskInfo');
this.callback = callback;
}
done(err, result) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy(); // `TaskInfo`s are used only once.
}
}
export default class WorkerPool extends EventEmitter {
constructor(numThreads) {
super();
this.numThreads = numThreads;
this.workers = [];
this.freeWorkers = [];
this.tasks = [];
for (let i = 0; i < numThreads; i++)
this.addNewWorker();
// Any time the kWorkerFreedEvent is emitted, dispatch
// the next task pending in the queue, if any.
this.on(kWorkerFreedEvent, () => {
if (this.tasks.length > 0) {
const { task, callback } = this.tasks.shift();
this.runTask(task, callback);
}
});
}
addNewWorker() {
const worker = new Worker(new URL('task_processer.js', import.meta.url));
worker.on('message', (result) => {
// In case of success: Call the callback that was passed to `runTask`,
// remove the `TaskInfo` associated with the Worker, and mark it as free
// again.
worker[kTaskInfo].done(null, result);
worker[kTaskInfo] = null;
this.freeWorkers.push(worker);
this.emit(kWorkerFreedEvent);
});
worker.on('error', (err) => {
// In case of an uncaught exception: Call the callback that was passed to
// `runTask` with the error.
if (worker[kTaskInfo])
worker[kTaskInfo].done(err, null);
else
this.emit('error', err);
// Remove the worker from the list and start a new Worker to replace the
// current one.
this.workers.splice(this.workers.indexOf(worker), 1);
this.addNewWorker();
});
this.workers.push(worker);
this.freeWorkers.push(worker);
this.emit(kWorkerFreedEvent);
}
runTask(task, callback) {
if (this.freeWorkers.length === 0) {
// No free threads, wait until a worker thread becomes free.
this.tasks.push({ task, callback });
return;
}
const worker = this.freeWorkers.pop();
worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);
worker.postMessage(task);
}
close() {
for (const worker of this.workers) worker.terminate();
}
}
```
```cjs
const { AsyncResource } = require('async_hooks');
const { EventEmitter } = require('events');
const path = require('path');
@ -553,7 +712,23 @@ were scheduled.
This pool could be used as follows:
```js
```mjs
import WorkerPool from './worker_pool.js';
import os from 'os';
const pool = new WorkerPool(os.cpus().length);
let finished = 0;
for (let i = 0; i < 10; i++) {
pool.runTask({ a: 42, b: 100 }, (err, result) => {
console.log(i, err, result);
if (++finished === 10)
pool.close();
});
}
```
```cjs
const WorkerPool = require('./worker_pool.js');
const os = require('os');
@ -579,7 +754,22 @@ The following example shows how to use the `AsyncResource` class to properly
associate an event listener with the correct execution context. The same
approach can be applied to a [`Stream`][] or a similar event-driven class.
```js
```mjs
import { createServer } from 'http';
import { AsyncResource, executionAsyncId } from 'async_hooks';
const server = createServer((req, res) => {
req.on('close', AsyncResource.bind(() => {
// Execution context is bound to the current outer scope.
}));
req.on('close', () => {
// Execution context is bound to the scope that caused 'close' to emit.
});
res.end();
}).listen(3000);
```
```cjs
const { createServer } = require('http');
const { AsyncResource, executionAsyncId } = require('async_hooks');
@ -593,6 +783,7 @@ const server = createServer((req, res) => {
res.end();
}).listen(3000);
```
[`AsyncResource`]: #async_context_class_asyncresource
[`EventEmitter`]: events.md#events_class_eventemitter
[`Stream`]: stream.md#stream_stream

View File

@ -9,7 +9,11 @@
The `async_hooks` module provides an API to track asynchronous resources. It
can be accessed using:
```js
```mjs
import async_hooks from 'async_hooks';
```
```cjs
const async_hooks = require('async_hooks');
```
@ -29,7 +33,55 @@ interface, and each thread will use a new set of async IDs.
Following is a simple overview of the public API.
```js
```mjs
import async_hooks from 'async_hooks';
// Return the ID of the current execution context.
const eid = async_hooks.executionAsyncId();
// Return the ID of the handle responsible for triggering the callback of the
// current execution scope to call.
const tid = async_hooks.triggerAsyncId();
// Create a new AsyncHook instance. All of these callbacks are optional.
const asyncHook =
async_hooks.createHook({ init, before, after, destroy, promiseResolve });
// Allow callbacks of this AsyncHook instance to call. This is not an implicit
// action after running the constructor, and must be explicitly run to begin
// executing callbacks.
asyncHook.enable();
// Disable listening for new asynchronous events.
asyncHook.disable();
//
// The following are the callbacks that can be passed to createHook().
//
// init is called during object construction. The resource may not have
// completed construction when this callback runs, therefore all fields of the
// resource referenced by "asyncId" may not have been populated.
function init(asyncId, type, triggerAsyncId, resource) { }
// Before is called just before the resource's callback is called. It can be
// called 0-N times for handles (such as TCPWrap), and will be called exactly 1
// time for requests (such as FSReqCallback).
function before(asyncId) { }
// After is called just after the resource's callback has finished.
function after(asyncId) { }
// Destroy is called when the resource is destroyed.
function destroy(asyncId) { }
// promiseResolve is called only for promise resources, when the
// `resolve` function passed to the `Promise` constructor is invoked
// (either directly or through other means of resolving a promise).
function promiseResolve(asyncId) { }
```
```cjs
const async_hooks = require('async_hooks');
// Return the ID of the current execution context.
@ -102,7 +154,16 @@ be tracked, then only the `destroy` callback needs to be passed. The
specifics of all functions that can be passed to `callbacks` is in the
[Hook Callbacks][] section.
```js
```mjs
import { createHook } from 'async_hooks';
const asyncHook = createHook({
init(asyncId, type, triggerAsyncId, resource) { },
destroy(asyncId) { }
});
```
```cjs
const async_hooks = require('async_hooks');
const asyncHook = async_hooks.createHook({
@ -158,7 +219,17 @@ synchronous logging operation such as `fs.writeFileSync(file, msg, flag)`.
This will print to the file and will not invoke AsyncHooks recursively because
it is synchronous.
```js
```mjs
import { writeFileSync } from 'fs';
import { format } from 'util';
function debug(...args) {
// Use a function like this one when debugging inside an AsyncHooks callback
writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' });
}
```
```cjs
const fs = require('fs');
const util = require('util');
@ -189,7 +260,13 @@ provided, enabling is a no-op.
The `AsyncHook` instance is disabled by default. If the `AsyncHook` instance
should be enabled immediately after creation, the following pattern can be used.
```js
```mjs
import { createHook } from 'async_hooks';
const hook = createHook(callbacks).enable();
```
```cjs
const async_hooks = require('async_hooks');
const hook = async_hooks.createHook(callbacks).enable();
@ -229,7 +306,15 @@ This behavior can be observed by doing something like opening a resource then
closing it before the resource can be used. The following snippet demonstrates
this.
```js
```mjs
import { createServer } from 'net';
createServer().listen(function() { this.close(); });
// OR
clearTimeout(setTimeout(() => {}, 10));
```
```cjs
require('net').createServer().listen(function() { this.close(); });
// OR
clearTimeout(setTimeout(() => {}, 10));
@ -270,12 +355,31 @@ created, while `triggerAsyncId` shows *why* a resource was created.
The following is a simple demonstration of `triggerAsyncId`:
```js
const { fd } = process.stdout;
```mjs
import { createHook, executionASyncId } from 'async_hooks';
import { stdout } from 'process';
import net from 'net';
async_hooks.createHook({
createHook({
init(asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId();
const eid = executionAsyncId();
fs.writeSync(
stdout.fd,
`${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`);
}
}).enable();
net.createServer((conn) => {}).listen(8080);
```
```cjs
const { createHook, executionAsyncId } = require('async_hooks');
const { fd } = require('process').stdout;
const net = require('net');
createHook({
init(asyncId, type, triggerAsyncId) {
const eid = executionAsyncId();
fs.writeSync(
fd,
`${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`);
@ -506,7 +610,17 @@ Using `executionAsyncResource()` in the top-level execution context will
return an empty object as there is no handle or request object to use,
but having an object representing the top-level can be helpful.
```js
```mjs
import { open } from 'fs';
import { executionAsyncId, executionAsyncResource } from 'async_hooks';
console.log(executionAsyncId(), executionAsyncResource()); // 1 {}
open(new URL(import.meta.url), 'r', (err, fd) => {
console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap
});
```
```cjs
const { open } = require('fs');
const { executionAsyncId, executionAsyncResource } = require('async_hooks');
@ -519,7 +633,33 @@ open(__filename, 'r', (err, fd) => {
This can be used to implement continuation local storage without the
use of a tracking `Map` to store the metadata:
```js
```mjs
import { createServer } from 'http';
import {
executionAsyncId,
executionAsyncResource,
createHook
} from 'async_hooks';
const sym = Symbol('state'); // Private symbol to avoid pollution
createHook({
init(asyncId, type, triggerAsyncId, resource) {
const cr = executionAsyncResource();
if (cr) {
resource[sym] = cr[sym];
}
}
}).enable();
const server = createServer((req, res) => {
executionAsyncResource()[sym] = { state: req.url };
setTimeout(function() {
res.end(JSON.stringify(executionAsyncResource()[sym]));
}, 100);
}).listen(3000);
```
```cjs
const { createServer } = require('http');
const {
executionAsyncId,
@ -558,7 +698,16 @@ changes:
* Returns: {number} The `asyncId` of the current execution context. Useful to
track when something calls.
```js
```mjs
import { executionAsyncId } from 'async_hooks';
console.log(executionAsyncId()); // 1 - bootstrap
fs.open(path, 'r', (err, fd) => {
console.log(executionAsyncId()); // 6 - open()
});
```
```cjs
const async_hooks = require('async_hooks');
console.log(async_hooks.executionAsyncId()); // 1 - bootstrap
@ -616,10 +765,21 @@ expensive nature of the [promise introspection API][PromiseHooks] provided by
V8. This means that programs using promises or `async`/`await` will not get
correct execution and trigger ids for promise callback contexts by default.
```js
const ah = require('async_hooks');
```mjs
import { executionAsyncId, triggerAsyncId } from 'async_hooks';
Promise.resolve(1729).then(() => {
console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 1 tid 0
```
```cjs
const { executionAsyncId, triggerAsyncId } = require('async_hooks');
Promise.resolve(1729).then(() => {
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 1 tid 0
@ -633,11 +793,22 @@ the resource that caused (triggered) the `then()` callback to be executed.
Installing async hooks via `async_hooks.createHook` enables promise execution
tracking:
```js
const ah = require('async_hooks');
ah.createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
```mjs
import { createHook, executionAsyncId, triggerAsyncId } from 'async_hooks';
createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
Promise.resolve(1729).then(() => {
console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 7 tid 6
```
```cjs
const { createHook, exectionAsyncId, triggerAsyncId } = require('async_hooks');
createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
Promise.resolve(1729).then(() => {
console.log(`eid ${executionAsyncId()} tid ${triggerAsyncId()}`);
});
// produces:
// eid 7 tid 6

File diff suppressed because it is too large Load Diff

View File

@ -13,10 +13,42 @@ processes to handle the load.
The cluster module allows easy creation of child processes that all share
server ports.
```js
```mjs
import cluster from 'cluster';
import http from 'http';
import { cpus } from 'os';
import process from 'process';
const numCPUs = cpus().length;
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
```
```cjs
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
const process = require('process');
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
@ -157,7 +189,24 @@ added: v0.11.2
Similar to the `cluster.on('exit')` event, but specific to this worker.
```js
```mjs
import cluster from 'cluster';
const worker = cluster.fork();
worker.on('exit', (code, signal) => {
if (signal) {
console.log(`worker was killed by signal: ${signal}`);
} else if (code !== 0) {
console.log(`worker exited with error code: ${code}`);
} else {
console.log('worker success!');
}
});
```
```cjs
const cluster = require('cluster');
const worker = cluster.fork();
worker.on('exit', (code, signal) => {
if (signal) {
@ -179,7 +228,17 @@ added: v0.7.0
Similar to the `cluster.on('listening')` event, but specific to this worker.
```js
```mjs
import cluster from 'cluster';
cluster.fork().on('listening', (address) => {
// Worker is listening
});
```
```cjs
const cluster = require('cluster');
cluster.fork().on('listening', (address) => {
// Worker is listening
});
@ -204,9 +263,54 @@ See [`process` event: `'message'`][].
Here is an example using the message system. It keeps a count in the primary
process of the number of HTTP requests received by the workers:
```js
```mjs
import cluster from 'cluster';
import http from 'http';
import { cpus } from 'os';
import process from 'process';
if (cluster.isPrimary) {
// Keep track of http requests
let numReqs = 0;
setInterval(() => {
console.log(`numReqs = ${numReqs}`);
}, 1000);
// Count requests
function messageHandler(msg) {
if (msg.cmd && msg.cmd === 'notifyRequest') {
numReqs += 1;
}
}
// Start workers and listen for messages containing notifyRequest
const numCPUs = cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
for (const id in cluster.workers) {
cluster.workers[id].on('message', messageHandler);
}
} else {
// Worker processes have a http server.
http.Server((req, res) => {
res.writeHead(200);
res.end('hello world\n');
// Notify primary about the request
process.send({ cmd: 'notifyRequest' });
}).listen(8000);
}
```
```cjs
const cluster = require('cluster');
const http = require('http');
const process = require('process');
if (cluster.isPrimary) {
@ -387,10 +491,44 @@ added: v0.11.14
This function returns `true` if the worker's process has terminated (either
because of exiting or being signaled). Otherwise, it returns `false`.
```js
```mjs
import cluster from 'cluster';
import http from 'http';
import { cpus } from 'os';
import process from 'process';
const numCPUs = cpus().length;
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('fork', (worker) => {
console.log('worker is dead:', worker.isDead());
});
cluster.on('exit', (worker, code, signal) => {
console.log('worker is dead:', worker.isDead());
});
} else {
// Workers can share any TCP connection. In this case, it is an HTTP server.
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Current process\n ${process.pid}`);
process.kill(process.pid);
}).listen(8000);
}
```
```cjs
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
const process = require('process');
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
@ -817,8 +955,25 @@ the `env` passed to [`.fork()`][].
The defaults above apply to the first call only; the defaults for later
calls are the current values at the time of `cluster.setupPrimary()` is called.
```js
```mjs
import cluster from 'cluster';
cluster.setupPrimary({
exec: 'worker.js',
args: ['--use', 'https'],
silent: true
});
cluster.fork(); // https worker
cluster.setupPrimary({
exec: 'worker.js',
args: ['--use', 'http']
});
cluster.fork(); // http worker
```
```cjs
const cluster = require('cluster');
cluster.setupPrimary({
exec: 'worker.js',
args: ['--use', 'https'],
@ -843,7 +998,19 @@ added: v0.7.0
A reference to the current worker object. Not available in the primary process.
```js
```mjs
import cluster from 'cluster';
if (cluster.isPrimary) {
console.log('I am primary');
cluster.fork();
cluster.fork();
} else if (cluster.isWorker) {
console.log(`I am worker #${cluster.worker.id}`);
}
```
```cjs
const cluster = require('cluster');
if (cluster.isPrimary) {
@ -871,7 +1038,23 @@ _and_ exited. The order between these two events cannot be determined in
advance. However, it is guaranteed that the removal from the `cluster.workers`
list happens before last `'disconnect'` or `'exit'` event is emitted.
```js
```mjs
import cluster from 'cluster';
// Go through all workers
function eachWorker(callback) {
for (const id in cluster.workers) {
callback(cluster.workers[id]);
}
}
eachWorker((worker) => {
worker.send('big announcement to all workers');
});
```
```cjs
const cluster = require('cluster');
// Go through all workers
function eachWorker(callback) {
for (const id in cluster.workers) {

View File

@ -10,7 +10,7 @@ The `crypto` module provides cryptographic functionality that includes a set of
wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify functions.
```mjs
import { createHmac } from 'crypto';
const { createHmac } = await import('crypto');
const secret = 'abcdefg';
const hash = createHmac('sha256', secret)
@ -162,7 +162,9 @@ changes:
`false` otherwise.
```mjs
import { Buffer } from 'buffer';
const { Certificate } = await import('crypto');
const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// Prints: true or false
@ -170,6 +172,8 @@ console.log(Certificate.verifySpkac(Buffer.from(spkac)));
```cjs
const { Certificate } = require('crypto');
const { Buffer } = require('buffer');
const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// Prints: true or false
@ -268,7 +272,9 @@ added: v0.11.8
`false` otherwise.
```mjs
import { Buffer } from 'buffer';
const { Certificate } = await import('crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
@ -277,6 +283,8 @@ console.log(cert.verifySpkac(Buffer.from(spkac)));
```cjs
const { Certificate } = require('crypto');
const { Buffer } = require('buffer');
const cert = Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
@ -385,7 +393,7 @@ import {
const {
scrypt,
randomFill,
createCipheriv,
createCipheriv
} = await import('crypto');
const algorithm = 'aes-192-cbc';
@ -456,7 +464,7 @@ Example: Using the [`cipher.update()`][] and [`cipher.final()`][] methods:
const {
scrypt,
randomFill,
createCipheriv,
createCipheriv
} = await import('crypto');
const algorithm = 'aes-192-cbc';
@ -626,9 +634,10 @@ directly using the `new` keyword.
Example: Using `Decipher` objects as streams:
```mjs
import { Buffer } from 'buffer';
const {
scryptSync,
createDecipheriv,
createDecipheriv
} = await import('crypto');
const algorithm = 'aes-192-cbc';
@ -665,6 +674,7 @@ const {
scryptSync,
createDecipheriv,
} = require('crypto');
const { Buffer } = require('buffer');
const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
@ -702,10 +712,10 @@ import {
createReadStream,
createWriteStream,
} from 'fs';
import { Buffer } from 'buffer';
const {
scryptSync,
createDecipheriv,
createDecipheriv
} = await import('crypto');
const algorithm = 'aes-192-cbc';
@ -728,11 +738,11 @@ const {
createReadStream,
createWriteStream,
} = require('fs');
const {
scryptSync,
createDecipheriv,
} = require('crypto');
const { Buffer } = require('buffer');
const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
@ -752,9 +762,10 @@ input.pipe(decipher).pipe(output);
Example: Using the [`decipher.update()`][] and [`decipher.final()`][] methods:
```mjs
import { Buffer } from 'buffer';
const {
scryptSync,
createDecipheriv,
createDecipheriv
} = await import('crypto');
const algorithm = 'aes-192-cbc';
@ -780,6 +791,7 @@ const {
scryptSync,
createDecipheriv,
} = require('crypto');
const { Buffer } = require('buffer');
const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
@ -942,7 +954,7 @@ Instances of the `DiffieHellman` class can be created using the
import assert from 'assert';
const {
createDiffieHellman,
createDiffieHellman
} = await import('crypto');
// Generate Alice's keys...
@ -1159,7 +1171,7 @@ Instances of the `ECDH` class can be created using the
import assert from 'assert';
const {
createECDH,
createECDH
} = await import('crypto');
// Generate Alice's keys...
@ -1234,7 +1246,7 @@ Example (uncompressing a key):
```mjs
const {
createECDH,
ECDH,
ECDH
} = await import('crypto');
const ecdh = createECDH('secp256k1');
@ -1400,7 +1412,7 @@ Example (obtaining a shared secret):
```mjs
const {
createECDH,
createHash,
createHash
} = await import('crypto');
const alice = createECDH('secp256k1');
@ -1473,7 +1485,7 @@ Example: Using `Hash` objects as streams:
```mjs
const {
createHash,
createHash
} = await import('crypto');
const hash = createHash('sha256');
@ -1519,36 +1531,31 @@ Example: Using `Hash` and piped streams:
```mjs
import { createReadStream } from 'fs';
import { stdout } from 'process';
const { createHash } = await import('crypto');
const {
createHash,
} = await import('crypto');
const hash = createHash('sha256');
const input = createReadStream('test.js');
input.pipe(hash).setEncoding('hex').pipe(process.stdout);
input.pipe(hash).setEncoding('hex').pipe(stdout);
```
```cjs
const {
createReadStream,
} = require('fs');
const {
createHash,
} = require('crypto');
const { createReadStream } = require('fs');
const { createHash } = require('crypto');
const { stdout } = require('process');
const hash = createHash('sha256');
const input = createReadStream('test.js');
input.pipe(hash).setEncoding('hex').pipe(process.stdout);
input.pipe(hash).setEncoding('hex').pipe(stdout);
```
Example: Using the [`hash.update()`][] and [`hash.digest()`][] methods:
```mjs
const {
createHash,
createHash
} = await import('crypto');
const hash = createHash('sha256');
@ -1593,7 +1600,7 @@ its [`hash.digest()`][] method has been called.
```mjs
// Calculate a rolling hash.
const {
createHash,
createHash
} = await import('crypto');
const hash = createHash('sha256');
@ -1688,7 +1695,7 @@ Example: Using `Hmac` objects as streams:
```mjs
const {
createHmac,
createHmac
} = await import('crypto');
const hmac = createHmac('sha256', 'a secret');
@ -1734,37 +1741,37 @@ Example: Using `Hmac` and piped streams:
```mjs
import { createReadStream } from 'fs';
import { stdout } from 'process';
const {
createHmac,
createHmac
} = await import('crypto');
const hmac = createHmac('sha256', 'a secret');
const input = createReadStream('test.js');
input.pipe(hmac).pipe(process.stdout);
input.pipe(hmac).pipe(stdout);
```
```cjs
const {
createReadStream,
} = require('fs');
const {
createHmac,
} = require('crypto');
const { stdout } = require('process');
const hmac = createHmac('sha256', 'a secret');
const input = createReadStream('test.js');
input.pipe(hmac).pipe(process.stdout);
input.pipe(hmac).pipe(stdout);
```
Example: Using the [`hmac.update()`][] and [`hmac.digest()`][] methods:
```mjs
const {
createHmac,
createHmac
} = await import('crypto');
const hmac = createHmac('sha256', 'a secret');
@ -1863,12 +1870,8 @@ added: v15.0.0
Example: Converting a `CryptoKey` instance to a `KeyObject`:
```mjs
const {
webcrypto: {
subtle,
},
KeyObject,
} = await import('crypto');
const { webcrypto, KeyObject } = await import('crypto');
const { subtle } = webcrypto;
const key = await subtle.generateKey({
name: 'HMAC',
@ -2058,7 +2061,7 @@ Example: Using `Sign` and [`Verify`][] objects as streams:
const {
generateKeyPairSync,
createSign,
createVerify,
createVerify
} = await import('crypto');
const { privateKey, publicKey } = generateKeyPairSync('ec', {
@ -2106,7 +2109,7 @@ Example: Using the [`sign.update()`][] and [`verify.update()`][] methods:
const {
generateKeyPairSync,
createSign,
createVerify,
createVerify
} = await import('crypto');
const { privateKey, publicKey } = generateKeyPairSync('rsa', {
@ -3026,12 +3029,12 @@ Example: generating the sha256 sum of a file
import {
createReadStream
} from 'fs';
import { argv } from 'process';
const {
createHash,
createHash
} = await import('crypto');
const filename = process.argv[2];
const filename = argv[2];
const hash = createHash('sha256');
@ -3052,12 +3055,12 @@ input.on('readable', () => {
const {
createReadStream,
} = require('fs');
const {
createHash,
} = require('crypto');
const { argv } = require('process');
const filename = process.argv[2];
const filename = argv[2];
const hash = createHash('sha256');
@ -3112,12 +3115,12 @@ Example: generating the sha256 HMAC of a file
import {
createReadStream
} from 'fs';
import { argv } from 'process';
const {
createHmac,
createHmac
} = await import('crypto');
const filename = process.argv[2];
const filename = argv[2];
const hmac = createHmac('sha256', 'a secret');
@ -3138,12 +3141,12 @@ input.on('readable', () => {
const {
createReadStream,
} = require('fs');
const {
createHmac,
} = require('crypto');
const { argv } = require('process');
const filename = process.argv[2];
const filename = argv[2];
const hmac = createHmac('sha256', 'a secret');
@ -3336,7 +3339,7 @@ Asynchronously generates a new random secret key of the given `length`. The
```mjs
const {
generateKey,
generateKey
} = await import('crypto');
generateKey('hmac', { length: 64 }, (err, key) => {
@ -3408,7 +3411,7 @@ It is recommended to encode public keys as `'spki'` and private keys as
```mjs
const {
generateKeyPair,
generateKeyPair
} = await import('crypto');
generateKeyPair('rsa', {
@ -3505,7 +3508,7 @@ and to keep the passphrase confidential.
```mjs
const {
generateKeyPairSync,
generateKeyPairSync
} = await import('crypto');
const {
@ -3573,7 +3576,7 @@ Synchronously generates a new random secret key of the given `length`. The
```mjs
const {
generateKeySync,
generateKeySync
} = await import('crypto');
const key = generateKeySync('hmac', 64);
@ -3710,7 +3713,7 @@ added: v0.9.3
```mjs
const {
getCiphers,
getCiphers
} = await import('crypto');
console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
@ -3733,7 +3736,7 @@ added: v2.3.0
```mjs
const {
getCurves,
getCurves
} = await import('crypto');
console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]
@ -3770,7 +3773,7 @@ Example (obtaining a shared secret):
```mjs
const {
getDiffieHellman,
getDiffieHellman
} = await import('crypto');
const alice = getDiffieHellman('modp14');
const bob = getDiffieHellman('modp14');
@ -3822,7 +3825,7 @@ added: v0.9.3
```mjs
const {
getHashes,
getHashes
} = await import('crypto');
console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]
@ -3866,8 +3869,9 @@ be passed to the callback as an {ArrayBuffer}. An error will be thrown if any
of the input arguments specify invalid values or types.
```mjs
import { Buffer } from 'buffer';
const {
hkdf,
hkdf
} = await import('crypto');
hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => {
@ -3880,6 +3884,7 @@ hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => {
const {
hkdf,
} = require('crypto');
const { Buffer } = require('buffer');
hkdf('sha512', 'key', 'salt', 'info', 64, (err, derivedKey) => {
if (err) throw err;
@ -3915,8 +3920,9 @@ An error will be thrown if any of the input arguments specify invalid values or
types, or if the derived key cannot be generated.
```mjs
import { Buffer } from 'buffer';
const {
hkdfSync,
hkdfSync
} = await import('crypto');
const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64);
@ -3927,6 +3933,7 @@ console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653'
const {
hkdfSync,
} = require('crypto');
const { Buffer } = require('buffer');
const derivedKey = hkdfSync('sha512', 'key', 'salt', 'info', 64);
console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653'
@ -3992,7 +3999,7 @@ When passing strings for `password` or `salt`, please consider
```mjs
const {
pbkdf2,
pbkdf2
} = await import('crypto');
pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
@ -4017,7 +4024,7 @@ The `crypto.DEFAULT_ENCODING` property can be used to change the way the
deprecated and use should be avoided.
```mjs
const crypto = await import('crypto');
import crypto from 'crypto';
crypto.DEFAULT_ENCODING = 'hex';
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, derivedKey) => {
if (err) throw err;
@ -4089,7 +4096,7 @@ When passing strings for `password` or `salt`, please consider
```mjs
const {
pbkdf2Sync,
pbkdf2Sync
} = await import('crypto');
const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha512');
@ -4110,7 +4117,7 @@ The `crypto.DEFAULT_ENCODING` property may be used to change the way the
should be avoided.
```mjs
const crypto = await import('crypto');
import crypto from 'crypto';
crypto.DEFAULT_ENCODING = 'hex';
const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512');
console.log(key); // '3745e48...aa39b34'
@ -4327,7 +4334,7 @@ If an error occurs, `err` will be an `Error` object; otherwise it is `null`. The
```mjs
// Asynchronous
const {
randomBytes,
randomBytes
} = await import('crypto');
randomBytes(256, (err, buf) => {
@ -4355,7 +4362,7 @@ there is a problem generating the bytes.
```mjs
// Synchronous
const {
randomBytes,
randomBytes
} = await import('crypto');
const buf = randomBytes(256);
@ -4411,9 +4418,8 @@ changes:
Synchronous version of [`crypto.randomFill()`][].
```mjs
const {
randomFillSync,
} = await import('crypto');
import { Buffer } from 'buffer';
const { randomFillSync } = await import('crypto');
const buf = Buffer.alloc(10);
console.log(randomFillSync(buf).toString('hex'));
@ -4427,9 +4433,8 @@ console.log(buf.toString('hex'));
```
```cjs
const {
randomFillSync,
} = require('crypto');
const { randomFillSync } = require('crypto');
const { Buffer } = require('buffer');
const buf = Buffer.alloc(10);
console.log(randomFillSync(buf).toString('hex'));
@ -4446,9 +4451,8 @@ Any `ArrayBuffer`, `TypedArray` or `DataView` instance may be passed as
`buffer`.
```mjs
const {
randomFillSync,
} = await import('crypto');
import { Buffer } from 'buffer';
const { randomFillSync } = await import('crypto');
const a = new Uint32Array(10);
console.log(Buffer.from(randomFillSync(a).buffer,
@ -4463,9 +4467,8 @@ console.log(Buffer.from(randomFillSync(c)).toString('hex'));
```
```cjs
const {
randomFillSync,
} = require('crypto');
const { randomFillSync } = require('crypto');
const { Buffer } = require('buffer');
const a = new Uint32Array(10);
console.log(Buffer.from(randomFillSync(a).buffer,
@ -4504,9 +4507,8 @@ requires that a callback is passed in.
If the `callback` function is not provided, an error will be thrown.
```mjs
const {
randomFill,
} = await import('crypto');
import { Buffer } from 'buffer';
const { randomFill } = await import('crypto');
const buf = Buffer.alloc(10);
randomFill(buf, (err, buf) => {
@ -4527,9 +4529,8 @@ randomFill(buf, 5, 5, (err, buf) => {
```
```cjs
const {
randomFill,
} = require('crypto');
const { randomFill } = require('crypto');
const { Buffer } = require('buffer');
const buf = Buffer.alloc(10);
randomFill(buf, (err, buf) => {
@ -4559,9 +4560,8 @@ contains finite numbers only, they are not drawn from a uniform random
distribution and have no meaningful lower or upper bounds.
```mjs
const {
randomFill,
} = await import('crypto');
import { Buffer } from 'buffer';
const { randomFill } = await import('crypto');
const a = new Uint32Array(10);
randomFill(a, (err, buf) => {
@ -4585,9 +4585,8 @@ randomFill(c, (err, buf) => {
```
```cjs
const {
randomFill,
} = require('crypto');
const { randomFill } = require('crypto');
const { Buffer } = require('buffer');
const a = new Uint32Array(10);
randomFill(a, (err, buf) => {
@ -4642,7 +4641,7 @@ generated synchronously.
```mjs
// Asynchronous
const {
randomInt,
randomInt
} = await import('crypto');
randomInt(3, (err, n) => {
@ -4666,7 +4665,7 @@ randomInt(3, (err, n) => {
```mjs
// Synchronous
const {
randomInt,
randomInt
} = await import('crypto');
const n = randomInt(3);
@ -4686,7 +4685,7 @@ console.log(`Random number chosen from (0, 1, 2): ${n}`);
```mjs
// With `min` argument
const {
randomInt,
randomInt
} = await import('crypto');
const n = randomInt(1, 7);
@ -4774,7 +4773,7 @@ or types.
```mjs
const {
scrypt,
scrypt
} = await import('crypto');
// Using the factory defaults.
@ -4854,7 +4853,7 @@ or types.
```mjs
const {
scryptSync,
scryptSync
} = await import('crypto');
// Using the factory defaults.
@ -5210,10 +5209,11 @@ mode must adhere to certain restrictions when using the cipher API:
authentication tag.
```mjs
import { Buffer } from 'buffer';
const {
createCipheriv,
createDecipheriv,
randomBytes,
randomBytes
} = await import('crypto');
const key = 'keykeykeykeykeykeykeykey';
@ -5259,6 +5259,7 @@ const {
createDecipheriv,
randomBytes,
} = require('crypto');
const { Buffer } = require('buffer');
const key = 'keykeykeykeykeykeykeykey';
const nonce = randomBytes(12);

View File

@ -10,7 +10,30 @@
The `dgram` module provides an implementation of UDP datagram sockets.
```js
```mjs
import dgram from 'dgram';
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server error:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
const address = server.address();
console.log(`server listening ${address.address}:${address.port}`);
});
server.bind(41234);
// Prints: server listening 0.0.0.0:41234
```
```cjs
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
@ -123,9 +146,25 @@ When sharing a UDP socket across multiple `cluster` workers, the
`socket.addMembership()` function must be called only once or an
`EADDRINUSE` error will occur:
```js
```mjs
import cluster from 'cluster';
import dgram from 'dgram';
if (cluster.isPrimary) {
cluster.fork(); // Works ok.
cluster.fork(); // Fails with EADDRINUSE.
} else {
const s = dgram.createSocket('udp4');
s.bind(1234, () => {
s.addMembership('224.0.0.114');
});
}
```
```cjs
const cluster = require('cluster');
const dgram = require('dgram');
if (cluster.isPrimary) {
cluster.fork(); // Works ok.
cluster.fork(); // Fails with EADDRINUSE.
@ -205,7 +244,30 @@ attempting to bind with a closed socket), an [`Error`][] may be thrown.
Example of a UDP server listening on port 41234:
```js
```mjs
import dgram from 'dgram';
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server error:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
const address = server.address();
console.log(`server listening ${address.address}:${address.port}`);
});
server.bind(41234);
// Prints: server listening 0.0.0.0:41234
```
```cjs
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
@ -480,8 +542,21 @@ This method throws [`ERR_SOCKET_BAD_PORT`][] if called on an unbound socket.
Example of sending a UDP packet to a port on `localhost`;
```js
```mjs
import dgram from 'dgram';
import { Buffer } from 'buffer';
const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {
client.close();
});
```
```cjs
const dgram = require('dgram');
const { Buffer } = require('buffer');
const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {
@ -492,8 +567,22 @@ client.send(message, 41234, 'localhost', (err) => {
Example of sending a UDP packet composed of multiple buffers to a port on
`127.0.0.1`;
```js
```mjs
import dgram from 'dgram';
import { Buffer } from 'buffer';
const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
const client = dgram.createSocket('udp4');
client.send([buf1, buf2], 41234, (err) => {
client.close();
});
```
```cjs
const dgram = require('dgram');
const { Buffer } = require('buffer');
const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
const client = dgram.createSocket('udp4');
@ -510,8 +599,23 @@ however, sending multiple buffers is faster.
Example of sending a UDP packet using a socket connected to a port on
`localhost`:
```js
```mjs
import dgram from 'dgram';
import { Buffer } from 'buffer';
const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.connect(41234, 'localhost', (err) => {
client.send(message, (err) => {
client.close();
});
});
```
```cjs
const dgram = require('dgram');
const { Buffer } = require('buffer');
const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.connect(41234, 'localhost', (err) => {

View File

@ -11,7 +11,11 @@ to report arbitrary message data for diagnostics purposes.
It can be accessed using:
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
```
@ -33,7 +37,27 @@ other modules.
Following is a simple overview of the public API.
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
// Get a reusable channel object
const channel = diagnostics_channel.channel('my-channel');
// Subscribe to the channel
channel.subscribe((message, name) => {
// Received data
});
// Check if the channel has an active subscriber
if (channel.hasSubscribers) {
// Publish data to the channel
channel.publish({
some: 'data'
});
}
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
// Get a reusable channel object
@ -64,7 +88,15 @@ the message you want to send might be expensive to prepare.
This API is optional but helpful when trying to publish messages from very
performance-sensitive code.
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
if (diagnostics_channel.hasSubscribers('my-channel')) {
// There are subscribers, prepare and publish message
}
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
if (diagnostics_channel.hasSubscribers('my-channel')) {
@ -81,7 +113,13 @@ This is the primary entry-point for anyone wanting to interact with a named
channel. It produces a channel object which is optimized to reduce overhead at
publish time as much as possible.
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
const channel = diagnostics_channel.channel('my-channel');
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
const channel = diagnostics_channel.channel('my-channel');
@ -107,7 +145,17 @@ the message you want to send might be expensive to prepare.
This API is optional but helpful when trying to publish messages from very
performance-sensitive code.
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
const channel = diagnostics_channel.channel('my-channel');
if (channel.hasSubscribers) {
// There are subscribers, prepare and publish message
}
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
const channel = diagnostics_channel.channel('my-channel');
@ -124,7 +172,17 @@ if (channel.hasSubscribers) {
Publish a message to any subscribers to the channel. This will trigger
message handlers synchronously so they will execute within the same context.
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
const channel = diagnostics_channel.channel('my-channel');
channel.publish({
some: 'message'
});
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
const channel = diagnostics_channel.channel('my-channel');
@ -144,7 +202,17 @@ Register a message handler to subscribe to this channel. This message handler
will be run synchronously whenever a message is published to the channel. Any
errors thrown in the message handler will trigger an [`'uncaughtException'`][].
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
const channel = diagnostics_channel.channel('my-channel');
channel.subscribe((message, name) => {
// Received data
});
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
const channel = diagnostics_channel.channel('my-channel');
@ -161,7 +229,21 @@ channel.subscribe((message, name) => {
Remove a message handler previously registered to this channel with
[`channel.subscribe(onMessage)`][].
```js
```mjs
import diagnostics_channel from 'diagnostics_channel';
const channel = diagnostics_channel.channel('my-channel');
function onMessage(message, name) {
// Received data
}
channel.subscribe(onMessage);
channel.unsubscribe(onMessage);
```
```cjs
const diagnostics_channel = require('diagnostics_channel');
const channel = diagnostics_channel.channel('my-channel');

View File

@ -246,6 +246,7 @@ readFile('./foo.txt', (err, source) => {
```js
import fs, { readFileSync } from 'fs';
import { syncBuiltinESMExports } from 'module';
import { Buffer } from 'buffer';
fs.readFileSync = () => Buffer.from('Hello, ESM');
syncBuiltinESMExports();
@ -818,8 +819,9 @@ globalThis.someInjectedProperty = 42;
console.log('I just set some globals!');
const { createRequire } = getBuiltin('module');
const { cwd } = getBuiltin('process');
const require = createRequire(process.cwd() + '/<preload>');
const require = createRequire(cwd() + '/<preload>');
// [...]
`;
}
@ -920,8 +922,9 @@ purposes.
// coffeescript-loader.mjs
import { URL, pathToFileURL } from 'url';
import CoffeeScript from 'coffeescript';
import { cwd } from 'process';
const baseURL = pathToFileURL(`${process.cwd()}/`).href;
const baseURL = pathToFileURL(`${cwd()}/`).href;
// CoffeeScript files end in .coffee, .litcoffee or .coffee.md.
const extensionsRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/;

View File

@ -1313,6 +1313,7 @@ to be written.
```mjs
import { writeFile } from 'fs/promises';
import { Buffer } from 'buffer';
try {
const controller = new AbortController();
@ -3943,6 +3944,7 @@ If `data` is a normal object, it must have an own `toString` function property.
```mjs
import { writeFile } from 'fs';
import { Buffer } from 'buffer';
const data = new Uint8Array(Buffer.from('Hello Node.js'));
writeFile('message.txt', data, (err) => {
@ -3973,6 +3975,7 @@ to be written.
```mjs
import { writeFile } from 'fs';
import { Buffer } from 'buffer';
const controller = new AbortController();
const { signal } = controller;
@ -3994,6 +3997,7 @@ calling `fs.write()` like:
```mjs
import { write } from 'fs';
import { Buffer } from 'buffer';
write(fd, Buffer.from(data, options.encoding), callback);
```
@ -6499,6 +6503,7 @@ Example using an absolute path on POSIX:
```mjs
import { open } from 'fs/promises';
import { Buffer } from 'buffer';
let fd;
try {

File diff suppressed because it is too large Load Diff

View File

@ -13,10 +13,11 @@ underlying operating system via a collection of POSIX-like functions.
```mjs
import fs from 'fs';
import { WASI } from 'wasi';
import { argv, env } from 'process';
const wasi = new WASI({
args: process.argv,
env: process.env,
args: argv,
env,
preopens: {
'/sandbox': '/some/real/path/that/wasm/can/access'
}
@ -33,9 +34,11 @@ wasi.start(instance);
'use strict';
const fs = require('fs');
const { WASI } = require('wasi');
const { argv, env } = require('process');
const wasi = new WASI({
args: process.argv,
env: process.env,
args: argv,
env,
preopens: {
'/sandbox': '/some/real/path/that/wasm/can/access'
}