Skip to content

Commit

Permalink
drop support for transferable AbortControllers/AbortSignals
Browse files Browse the repository at this point in the history
Seems it's a non-standard feature. Dropping because it would still have required users to do extra work like providing their own MessageChannel implementation to override the included one.

It's a feature that requires runtime integration, so I can only provide a basis and not a full implementation.

whatwg/dom#948
  • Loading branch information
shirakaba committed Mar 19, 2024
1 parent 542a103 commit d64beb7
Show file tree
Hide file tree
Showing 4 changed files with 2 additions and 210 deletions.
120 changes: 1 addition & 119 deletions src/abort-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,14 @@ const {
ERR_METHOD_NOT_IMPLEMENTED,
} = codes;

import {
kDeserialize,
kTransfer,
kTransferList,
markTransferMode,
} from './js-transferable.js';
import { MessageChannel as NoOpMessageChannel } from './message-channel.js';

function lazyMessageChannel() {
const MessageChannel = globalThis.MessageChannel ?? NoOpMessageChannel;
return new MessageChannel();
}

function lazyMarkTransferMode(obj, cloneable, transferable) {
markTransferMode(obj, cloneable, transferable);
}

const clearTimeoutRegistry = new SafeFinalizationRegistry(
globalThis.clearTimeout,
);
const gcPersistentSignals = new SafeSet();

const kAborted = Symbol('kAborted');
const kReason = Symbol('kReason');
const kCloneData = Symbol('kCloneData');
const kTimeout = Symbol('kTimeout');
const kMakeTransferable = Symbol('kMakeTransferable');
const kComposite = Symbol('kComposite');
const kSourceSignals = Symbol('kSourceSignals');
const kDependantSignals = Symbol('kDependantSignals');
Expand Down Expand Up @@ -259,73 +240,8 @@ export class AbortSignal extends EventTarget {
gcPersistentSignals.delete(this);
}
}

[kTransfer]() {
validateThisAbortSignal(this);
const aborted = this.aborted;
if (aborted) {
const reason = this.reason;
return {
data: { aborted, reason },
deserializeInfo: 'internal/abort_controller:ClonedAbortSignal',
};
}

const { port1, port2 } = this[kCloneData];
this[kCloneData] = undefined;

this.addEventListener(
'abort',
() => {
port1.postMessage(this.reason);
port1.close();
},
{ once: true },
);

return {
data: { port: port2 },
deserializeInfo: 'internal/abort_controller:ClonedAbortSignal',
};
}

[kTransferList]() {
if (!this.aborted) {
const { port1, port2 } = lazyMessageChannel();
port1.unref();
port2.unref();
this[kCloneData] = {
port1,
port2,
};
return [port2];
}
return [];
}

[kDeserialize]({ aborted, reason, port }) {
if (aborted) {
this[kAborted] = aborted;
this[kReason] = reason;
return;
}

port.onmessage = ({ data }) => {
abortSignal(this, data);
port.close();
port.onmessage = undefined;
};
// The receiving port, by itself, should never keep the event loop open.
// The unref() has to be called *after* setting the onmessage handler.
port.unref();
}
}

export function ClonedAbortSignal() {
return createAbortSignal({ transferable: true });
}
ClonedAbortSignal.prototype[kDeserialize] = () => {};

ObjectDefineProperties(AbortSignal.prototype, {
aborted: kEnumerableProperty,
});
Expand All @@ -344,26 +260,17 @@ defineEventHandler(AbortSignal.prototype, 'abort');
* @param {{
* aborted? : boolean,
* reason? : any,
* transferable? : boolean,
* composite? : boolean,
* }} [init]
* @returns {AbortSignal}
*/
function createAbortSignal(init = kEmptyObject) {
const {
aborted = false,
reason = undefined,
transferable = false,
composite = false,
} = init;
const { aborted = false, reason = undefined, composite = false } = init;
const signal = new EventTarget();
ObjectSetPrototypeOf(signal, AbortSignal.prototype);
signal[kAborted] = aborted;
signal[kReason] = reason;
signal[kComposite] = composite;
if (transferable) {
lazyMarkTransferMode(signal, false, true);
}
return signal;
}

Expand Down Expand Up @@ -409,31 +316,6 @@ export class AbortController {
options,
);
}

static [kMakeTransferable]() {
const controller = new AbortController();
controller.#signal = createAbortSignal({ transferable: true });
return controller;
}
}

/**
* Enables the AbortSignal to be transferable using structuredClone/postMessage.
* @param {AbortSignal} signal
* @returns {AbortSignal}
*/
export function transferableAbortSignal(signal) {
if (signal?.[kAborted] === undefined)
throw new ERR_INVALID_ARG_TYPE('signal', 'AbortSignal', signal);
lazyMarkTransferMode(signal, false, true);
return signal;
}

/**
* Creates an AbortController with a transferable AbortSignal
*/
export function transferableAbortController() {
return AbortController[kMakeTransferable]();
}

/**
Expand Down
10 changes: 1 addition & 9 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
export {
AbortController,
aborted,
AbortSignal,
ClonedAbortSignal,
transferableAbortController,
transferableAbortSignal,
} from './abort-controller.js';
export { AbortController, aborted, AbortSignal } from './abort-controller.js';
export { DOMException } from './dom-exception.js';
export {
CustomEvent,
Expand All @@ -15,5 +8,4 @@ export {
kWeakHandler,
} from './event-target.js';
export { setMaxListeners } from './events.js';
export { MessageChannel } from './message-channel.js';
export { polyfill } from './polyfill.js';
56 changes: 0 additions & 56 deletions src/js-transferable.js

This file was deleted.

26 changes: 0 additions & 26 deletions src/message-channel.js

This file was deleted.

0 comments on commit d64beb7

Please sign in to comment.