mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-24 06:14:01 +08:00
- The forwarding shape — emit(event, ...args) whose rest appears only as super.emit(event, ...args) — lowers per dispatching event as a real hierarchy method, vtable-participating - error events keep the throw-when-unhandled path through overrides; super.emit resolves to the nearest override ancestor, JS's chain - Receivers above every override route through interned instanceOf dispatch; other emitter members and stream-rooted classes keep their fences with reasons stated # Conflicts: # packages/compiler/test/ts7/baselines/order-parity.json
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
// The real-world shape: an emitter subclass as a job queue — constructor
|
|
// args + super(), own fields and methods, colon-spelled event names,
|
|
// multi-argument tuples, once('drain'), listeners registered from outside
|
|
// on a base-typed binding, and removeListener mid-flight.
|
|
import { EventEmitter } from "node:events";
|
|
|
|
interface Job {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
|
|
class JobQueue extends EventEmitter {
|
|
private jobs: Job[] = [];
|
|
done = 0;
|
|
readonly label: string;
|
|
constructor(label: string) {
|
|
super();
|
|
this.label = label;
|
|
}
|
|
add(name: string): number {
|
|
const job = { id: this.jobs.length + 1, name };
|
|
this.jobs.push(job);
|
|
this.emit("job:added", job.id, name);
|
|
return job.id;
|
|
}
|
|
run(): void {
|
|
for (const job of this.jobs) {
|
|
this.emit("job:done", job.id, job.name, ++this.done);
|
|
}
|
|
this.jobs = [];
|
|
this.emit("drain", this.done);
|
|
}
|
|
}
|
|
|
|
const q = new JobQueue("build");
|
|
q.on("job:added", (id: number, name: string) => console.log(`[${q.label}] queued #${id} ${name}`));
|
|
const progress = (id: number, name: string, total: number): void => {
|
|
console.log(`done #${id} ${name} (${total} total)`);
|
|
};
|
|
q.on("job:done", progress);
|
|
q.once("drain", (total: number) => console.log("drained after", total));
|
|
|
|
q.add("compile");
|
|
q.add("link");
|
|
q.run();
|
|
|
|
// Mid-flight removal: the second batch reports through a fresh listener
|
|
// only; drain's once-listener is already gone.
|
|
q.removeListener("job:done", progress);
|
|
q.on("job:done", (id: number) => console.log("quietly finished", id));
|
|
q.add("package");
|
|
q.run();
|
|
console.log(q.done, q.listenerCount("job:done"), q instanceof JobQueue, q instanceof EventEmitter);
|