From fddddad8e6adf5b41e6107205b04f51bfbbb4dee Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Tue, 1 Oct 2024 22:55:03 +0930 Subject: [PATCH] worker: expose `markAsUncloneable` api External modules need a way to decorate their objects so that node can recognize it as a host object for serialization process. Exposing a way for turning off instead of turning on is much safer. --- doc/api/worker_threads.md | 32 +++++++++ lib/internal/worker/io.js | 16 +++++ lib/worker_threads.js | 2 + ...test-worker-message-mark-as-uncloneable.js | 70 +++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 test/parallel/test-worker-message-mark-as-uncloneable.js diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index b718a90f621178..42ec32e5a8451d 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -194,6 +194,38 @@ isMarkedAsUntransferable(pooledBuffer); // Returns true. There is no equivalent to this API in browsers. +## `worker.markAsUncloneable(object)` + + + +* `object` {any} Any arbitrary JavaScript value. + +Mark an object as not cloneable. If `object` is used as [`message`](#event-message) in +a [`port.postMessage()`][] call, an error is thrown. This is a no-op if `object` is a +primitive value. + +Note, this does not take effect on `ArrayBuffer`, or any `Buffer` like objects. + +This operation cannot be undone. + +```js +const { markAsUncloneable } = require('node:worker_threads'); + +const anyObject = { foo: 'bar' }; +markAsUncloneable(anyObject); +const { port1 } = new MessageChannel(); +try { + // This will throw an error, because anyObject is not cloneable. + port1.postMessage(anyObject) +} catch (error) { + // error.name === 'DataCloneError' +} +``` + +There is no equivalent to this API in browsers. + ## `worker.moveMessagePortToContext(port, contextifiedSandbox)`