UNPKG

fake-service-worker

Version:

Fake service worker implementation for testing developer edge applications

209 lines 5.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EdgeReadableStream = void 0; class EdgeReadableStream { _internals; constructor(underlyingSource, strategy) { this._internals = new StreamInternals(underlyingSource, strategy || {}); } get locked() { return this._internals.locked; } cancel(reason) { return this._internals.cancel(reason); } getReader({ mode } = {}) { if (mode) { throw new TypeError('ReadableStream modes other than default are not supported'); } this._internals.acquireLock(); return new EdgeReadableStreamDefaultReader(this._internals); } pipeThrough(_transform, _options) { throw new Error('pipeThrough not yet implemented'); } pipeTo(_dest, _options) { throw new Error('pipeTo not yet implemented'); } tee() { return this._internals.tee(); } } exports.EdgeReadableStream = EdgeReadableStream; class StreamInternals { _source; _chunks; _controller; _on_done_resolvers = new Set(); _closed = false; _done = false; _error = null; _locked = false; _start_promise = null; _highWaterMark; constructor(source, { highWaterMark, size } = {}) { this._source = source; if (source?.type) { throw new Error('UnderlyingSource.type is not yet supported'); } this._highWaterMark = highWaterMark || 10; if (size) { throw new Error('TODO call size'); } this._chunks = []; this._controller = new EdgeReadableStreamDefaultController(this); if (this._source?.start) { this._start_promise = this._source.start(this._controller); } } cancel(_reason) { this._chunks.length = 0; this._closed = true; if (this._source?.cancel) { this._source?.cancel(this._controller); } return new Promise(resolve => { this.addResolver(resolve); }); } get locked() { return this._locked; } acquireLock() { if (this._locked) { throw new Error('ReadableStream already locked'); } this._locked = true; } releaseLock() { this._locked = false; } close() { this._closed = true; } enqueue(chunk) { this._chunks.push(chunk); } error(e) { this._error = e || true; } addResolver(resolver) { this._on_done_resolvers.add(resolver); } done() { for (const resolve of this._on_done_resolvers) { resolve(); } this._done = true; return { done: true, value: undefined }; } async read() { if (this._done) { return { done: true, value: undefined }; } if (this._start_promise) { await this._start_promise; this._start_promise = null; } if (!this._closed && this._chunks.length < this._highWaterMark && this._source?.pull) { if (this._error) { throw this._error; } else { await Promise.resolve(this._source.pull(this._controller)); } } const value = this._chunks.shift(); if (value == undefined) { return this.done(); } else { return { done: false, value }; } } tee() { this.acquireLock(); const chunks1 = [...this._chunks]; const chunks2 = [...this._chunks]; const start = async () => { const p = this._start_promise; if (p) { this._start_promise = null; await p; } }; const pull = async (controller, which) => { const { value } = await this.read(); if (value) { chunks1.push(value); chunks2.push(value); } const chunks = which == 1 ? chunks1 : chunks2; const next = chunks.shift(); if (next == undefined) { controller.close(); } else { controller.enqueue(next); } }; const cancel = async (controller) => { this.cancel(); const c = this._source?.cancel; if (c) { delete this._source?.cancel; await c(controller); } }; const source1 = { start: () => start(), pull: controller => pull(controller, 1), cancel: controller => cancel(controller), }; const source2 = { start: () => start(), pull: controller => pull(controller, 2), cancel: controller => cancel(controller), }; return [new EdgeReadableStream(source1), new EdgeReadableStream(source2)]; } } class EdgeReadableStreamDefaultController { desiredSize = null; _internals; constructor(internals) { this._internals = internals; } close() { this._internals.close(); } enqueue(chunk) { this._internals.enqueue(chunk); } error(e) { this._internals.error(e); } } class EdgeReadableStreamDefaultReader { _internals; _closed_promise; constructor(internals) { this._internals = internals; this._closed_promise = new Promise(resolve => { internals.addResolver(() => resolve(undefined)); }); } get closed() { return this._closed_promise; } async read() { return this._internals.read(); } cancel(reason) { return this._internals.cancel(reason); } releaseLock() { this._internals.releaseLock(); } } //# sourceMappingURL=ReadableStream.js.map