Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// #region Disposable
/**
* A well-known symbol used to define an explicit resource disposal method on an object.
*/
export const dispose = Symbol.for("@esfx/disposable:Disposable.dispose");
// #endregion Disposable
/**
* Determines whether a value is Disposable.
* @deprecated Use `Disposable.hasInstance` instead.
*/
export function isDisposable(value: unknown): value is Disposable {
return Disposable.hasInstance(value);
}
const disposablePrototype: object = defineTag({ }, "Disposable");
/**
* Creates a `Disposable` wrapper around a callback used to dispose of a resource.
*/
export function create(dispose: () => void): Disposable {
return Object.setPrototypeOf({
[Disposable.dispose]() {
dispose();
}
}, disposablePrototype);
}
/**
* Creates a `Disposable` wrapper around a set of other disposables.
* @param disposables An `Iterable` of `Disposable` objects.
*/
export interface Cancelable {
/**
* Gets the [[CancelSignal]] for this [[Cancelable]].
*/
[Cancelable.cancelSignal](): CancelSignal;
}
export namespace Cancelable {
// #region Cancelable
/**
* A well-known symbol used to define a method to retrieve the `CancelSignal` for an object.
*/
export const cancelSignal = Symbol.for("@esfx/cancelable:Cancelable.cancelSignal");
// #endregion Cancelable
const cancelSignalPrototype: Cancelable = defineTag({
[Cancelable.cancelSignal](this: CancelableCancelSignal) {
return this;
}
}, "CancelSignal");
const emptySubscription: CancelSubscription = createCancelSubscription(() => { });
Object.freeze(emptySubscription);
/**
* A `Cancelable` that is already signaled.
*/
export const canceled: CancelableCancelSignal = Object.setPrototypeOf({
get signaled() {
return true;
},
subscribe(onSignaled: () => void) {
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { Disposable } from "@esfx/disposable";
import { isFunction, isMissing, isObject } from "@esfx/internal-guards";
import { defineTag } from "@esfx/internal-tag";
import { deprecateProperty } from "@esfx/internal-deprecate";
const disposablePrototype = Object.getPrototypeOf(Disposable.create(() => {}));
const cancelSubscriptionPrototype: Disposable = defineTag(Object.setPrototypeOf({
[Disposable.dispose](this: CancelSubscription) {
this.unsubscribe();
},
}, disposablePrototype), "CancelSubscription");
function createCancelSubscription(unsubscribe: () => void): CancelSubscription {
return Object.setPrototypeOf({
unsubscribe() {
unsubscribe();
},
}, cancelSubscriptionPrototype);
}
/**
* An object that can be canceled from an external source.
*/
},
[AsyncLockable.unlock](this: LockHandle) {
this.unlock();
},
[Disposable.dispose](this: LockHandle) {
if (this.ownsLock) {
this.unlock();
}
}
};
defineTag(lockHandlePrototype, "LockHandle");
Object.setPrototypeOf(lockHandlePrototype, disposablePrototype);
const readerPrototype: object = {};
defineTag(readerPrototype, "AsyncReaderWriterLockReader");
Object.setPrototypeOf(readerPrototype, lockHandlePrototype);
const writerPrototype: object = {};
defineTag(writerPrototype, "AsyncReaderWriterLockWriter");
Object.setPrototypeOf(writerPrototype, lockHandlePrototype);
const upgradeableReaderPrototype: object = {};
defineTag(upgradeableReaderPrototype, "AsyncReaderWriterLockUpgradeableReader");
Object.setPrototypeOf(upgradeableReaderPrototype, readerPrototype);
const upgradedWriterPrototype: object = {};
defineTag(upgradedWriterPrototype, "AsyncReaderWriterLockUpgradedWriter");
Object.setPrototypeOf(upgradedWriterPrototype, writerPrototype);
/**
* Coordinates readers and writers for a resource.
return signal.signaled;
}
function canBeSignaled(signal: CancelSignal) {
return signal !== Cancelable.none && (!(signal instanceof CancelToken) || signal.canBeSignaled);
}
const disposablePrototype: object = Object.getPrototypeOf(Disposable.create(() => { }));
const cancelSourcePrototype: object = {
[Cancelable.cancelSignal](this: CancelSource) { return this.token; },
[CancelableSource.cancel](this: CancelSource) { this.cancel(); },
};
Object.setPrototypeOf(cancelSourcePrototype, disposablePrototype);
defineTag(cancelSourcePrototype, "CancelSource");
function createCancelSource(links: CancelLinks | undefined): CancelSource {
let state: "unsignaled" | "signaled" | "closed" = "unsignaled";
let token: CancelToken | undefined;
let subscriptions: LinkedList<() => void> | undefined;
const source: CancelSource = Object.setPrototypeOf({
get token() {
return token || (token = createCancelToken({
getState() {
return state === "unsignaled" && links ? links.getLinkedState() : state;
},
subscribe(onSignaled) {
if (state === "closed") {
return Cancelable.none.subscribe(onSignaled);
}
if (state === "signaled") {
Object.setPrototypeOf(lockHandlePrototype, disposablePrototype);
const readerPrototype: object = {};
defineTag(readerPrototype, "AsyncReaderWriterLockReader");
Object.setPrototypeOf(readerPrototype, lockHandlePrototype);
const writerPrototype: object = {};
defineTag(writerPrototype, "AsyncReaderWriterLockWriter");
Object.setPrototypeOf(writerPrototype, lockHandlePrototype);
const upgradeableReaderPrototype: object = {};
defineTag(upgradeableReaderPrototype, "AsyncReaderWriterLockUpgradeableReader");
Object.setPrototypeOf(upgradeableReaderPrototype, readerPrototype);
const upgradedWriterPrototype: object = {};
defineTag(upgradedWriterPrototype, "AsyncReaderWriterLockUpgradedWriter");
Object.setPrototypeOf(upgradedWriterPrototype, writerPrototype);
/**
* Coordinates readers and writers for a resource.
*/
@Tag()
export class AsyncReaderWriterLock {
private _readerQueue = new WaitQueue();
private _writerQueue = new WaitQueue();
private _readers = new Set();
private _writer: LockHandle | undefined;
private _upgradeable: LockHandle | undefined;
/**
* Creates a `AsyncReaderWriterLockReader` that can be used to take and release "read" locks on a resource.
*/
const mutexLockHandlePrototype: object = {
[AsyncLockable.lock](this: LockHandle, cancelable?: Cancelable) {
return this.lock(cancelable);
},
[AsyncLockable.unlock](this: LockHandle) {
return this.unlock();
},
[Disposable.dispose](this: LockHandle) {
if (this.ownsLock) {
this.unlock();
}
}
};
defineTag(mutexLockHandlePrototype, "MutexLockHandle");
Object.setPrototypeOf(mutexLockHandlePrototype, disposablePrototype);
function createLockHandle(mutex: AsyncMutex): LockHandle {
const handle: LockHandle = Object.setPrototypeOf({
get mutex() {
return mutex;
},
get ownsLock() {
return mutex["_handle"] === handle;
},
async lock(cancelable?: Cancelable) {
await mutex["_lock"](handle, cancelable);
return this;
},
unlock() {
mutex["_unlock"](handle);
export namespace AsyncDisposable {
/**
* A well-known symbol used to define an async explicit resource disposal method on an object.
*/
export const asyncDispose = Symbol.for("@esfx/disposable:AsyncDisposable.asyncDispose");
/**
* Determines whether a value is [[AsyncDisposable]].
* @deprecated Use `AsyncDisposable.hasInstance` instead.
*/
export function isAsyncDisposable(value: unknown): value is AsyncDisposable {
return AsyncDisposable.hasInstance(value);
}
const asyncDisposablePrototype: object = defineTag({ }, "AsyncDisposable");
/**
* Creates an `AsyncDisposable` wrapper around a callback used to dispose resources.
*/
export function create(dispose: () => void | PromiseLike): AsyncDisposable {
return Object.setPrototypeOf({
async [AsyncDisposable.asyncDispose]() {
await dispose();
}
}, asyncDisposablePrototype);
}
function asyncFromSyncDisposable(disposable: Disposable) {
return create(() => disposable[Disposable.dispose]());
}
}
};
defineTag(lockHandlePrototype, "LockHandle");
Object.setPrototypeOf(lockHandlePrototype, disposablePrototype);
const readerPrototype: object = {};
defineTag(readerPrototype, "AsyncReaderWriterLockReader");
Object.setPrototypeOf(readerPrototype, lockHandlePrototype);
const writerPrototype: object = {};
defineTag(writerPrototype, "AsyncReaderWriterLockWriter");
Object.setPrototypeOf(writerPrototype, lockHandlePrototype);
const upgradeableReaderPrototype: object = {};
defineTag(upgradeableReaderPrototype, "AsyncReaderWriterLockUpgradeableReader");
Object.setPrototypeOf(upgradeableReaderPrototype, readerPrototype);
const upgradedWriterPrototype: object = {};
defineTag(upgradedWriterPrototype, "AsyncReaderWriterLockUpgradedWriter");
Object.setPrototypeOf(upgradedWriterPrototype, writerPrototype);
/**
* Coordinates readers and writers for a resource.
*/
@Tag()
export class AsyncReaderWriterLock {
private _readerQueue = new WaitQueue();
private _writerQueue = new WaitQueue();
private _readers = new Set();
private _writer: LockHandle | undefined;
private _upgradeable: LockHandle | undefined;
[Disposable.dispose](this: LockHandle) {
if (this.ownsLock) {
this.unlock();
}
}
};
defineTag(lockHandlePrototype, "LockHandle");
Object.setPrototypeOf(lockHandlePrototype, disposablePrototype);
const readerPrototype: object = {};
defineTag(readerPrototype, "AsyncReaderWriterLockReader");
Object.setPrototypeOf(readerPrototype, lockHandlePrototype);
const writerPrototype: object = {};
defineTag(writerPrototype, "AsyncReaderWriterLockWriter");
Object.setPrototypeOf(writerPrototype, lockHandlePrototype);
const upgradeableReaderPrototype: object = {};
defineTag(upgradeableReaderPrototype, "AsyncReaderWriterLockUpgradeableReader");
Object.setPrototypeOf(upgradeableReaderPrototype, readerPrototype);
const upgradedWriterPrototype: object = {};
defineTag(upgradedWriterPrototype, "AsyncReaderWriterLockUpgradedWriter");
Object.setPrototypeOf(upgradedWriterPrototype, writerPrototype);
/**
* Coordinates readers and writers for a resource.
*/
@Tag()
export class AsyncReaderWriterLock {
private _readerQueue = new WaitQueue();