mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-29 07:04:09 +08:00
91 lines
5.1 KiB
JavaScript
91 lines
5.1 KiB
JavaScript
import { WritableStream, WritableStreamDefaultWriter } from "node:stream/web";
|
|
import { out, deferred, result, caught, sameError, launch } from "./helpers.js";
|
|
|
|
export function reportLifecycle() { launch(async () => {
|
|
{
|
|
const entered = deferred(), gate = deferred();
|
|
const stream = new WritableStream({ write() { entered.resolve(); return gate.promise; } });
|
|
const w = stream.getWriter();
|
|
const pending = w.write("first");
|
|
await entered.promise;
|
|
const ready = w.ready, closed = w.closed;
|
|
const readyResult = result(ready), closedResult = result(closed);
|
|
out("locked", caught(() => stream.getWriter()), await result(stream.close()), await result(stream.abort("locked")));
|
|
w.releaseLock(); w.releaseLock();
|
|
out("release", stream.locked, await readyResult, await closedResult, await result(w.ready), await result(w.closed), caught(() => w.desiredSize));
|
|
out("released-methods", await result(w.write()), await result(w.close()), await result(w.abort()));
|
|
const next = new WritableStreamDefaultWriter(stream);
|
|
out("reacquire", next.desiredSize, stream.locked);
|
|
gate.resolve(); out("old-write", await pending);
|
|
await next.close(); await next.closed;
|
|
const oldReady = next.ready, oldClosed = next.closed;
|
|
next.releaseLock();
|
|
out("closed-release", await result(oldReady), await result(oldClosed), await result(next.ready), await result(next.closed));
|
|
const last = stream.getWriter();
|
|
out("closed-writer", last.desiredSize, await result(last.ready), await result(last.closed), await result(last.close()), await result(last.abort()));
|
|
last.releaseLock();
|
|
out("closed-stream", await result(stream.close()), await result(stream.abort()));
|
|
}
|
|
{
|
|
const start = deferred(), aborted = deferred(), abortGate = deferred();
|
|
const reason = new Error("abort-before-start"); let controller, abortReason;
|
|
const calls = [];
|
|
const stream = new WritableStream({
|
|
start(c) { controller = c; return start.promise; },
|
|
write() { calls.push("write"); },
|
|
abort(e) { abortReason = e; calls.push("abort"); aborted.resolve(); return abortGate.promise; },
|
|
});
|
|
const w = stream.getWriter();
|
|
const a = sameError(w.write("a"), reason), b = sameError(w.write("b"), reason);
|
|
const abort = w.abort(reason), again = w.abort("second");
|
|
let closed = false; w.closed.catch(() => { closed = true; });
|
|
out("abort-start", controller.signal.aborted, controller.signal.reason === reason, abort === again, calls.length, w.desiredSize, await sameError(w.ready, reason));
|
|
start.resolve(); await aborted.promise;
|
|
out("abort-pending", await a, await b, abortReason === reason, closed, calls.join(","));
|
|
abortGate.resolve(); await abort;
|
|
out("abort-done", await sameError(w.closed, reason), await result(w.abort("later")), closed);
|
|
}
|
|
{
|
|
const entered = deferred(), gate = deferred(); let controller;
|
|
const log = [], reason = new Error("abort-inflight");
|
|
const stream = new WritableStream({
|
|
start(c) { controller = c; c.signal.addEventListener("abort", () => log.push("signal")); },
|
|
write(chunk) { log.push("write:" + chunk); entered.resolve(); return gate.promise; },
|
|
close() { log.push("close"); },
|
|
abort(e) { log.push("abort:" + (e === reason)); },
|
|
});
|
|
const w = stream.getWriter();
|
|
const a = result(w.write("a")), b = sameError(w.write("b"), reason);
|
|
const close = sameError(w.close(), reason);
|
|
await entered.promise;
|
|
const abort = w.abort(reason);
|
|
out("abort-inflight", log.join(","), w.desiredSize, controller.signal.reason === reason);
|
|
gate.resolve(); await abort;
|
|
out("abort-finish", await a, await b, await close, await sameError(w.closed, reason), log.join(","));
|
|
out("errored-close", await result(w.close()));
|
|
}
|
|
for (const fails of [false, true]) {
|
|
const entered = deferred(), gate = deferred(); let controller;
|
|
const abortReason = new Error("during-close"), closeError = new Error("close-failure"), log = [];
|
|
const stream = new WritableStream({ start(c) { controller = c; }, close() { log.push("close"); entered.resolve(); return gate.promise; }, abort() { log.push("abort"); } });
|
|
const w = stream.getWriter(), close = result(w.close());
|
|
await entered.promise;
|
|
const abort = result(w.abort(abortReason));
|
|
out("closing-abort", fails, controller.signal.aborted, await sameError(w.ready, abortReason));
|
|
if (fails) gate.reject(closeError); else gate.resolve();
|
|
out("closing-settled", await close, await abort, await result(w.closed), w.desiredSize, log.join(","));
|
|
}
|
|
{
|
|
let controller, aborted = false;
|
|
const stream = new WritableStream({ start(c) { controller = c; }, abort() { aborted = true; } });
|
|
const w = stream.getWriter(); await w.abort();
|
|
out("default-abort", controller.signal.aborted, controller.signal.reason.name, aborted, await sameError(w.closed, undefined), w.desiredSize);
|
|
}
|
|
{
|
|
const stream = new WritableStream();
|
|
const close = stream.close();
|
|
out("duplicate-stream-close", await result(stream.close())); await close;
|
|
out("direct-close", await result(stream.abort()), await result(stream.close()));
|
|
}
|
|
}); }
|