mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-28 06:53:42 +08:00
LlEmitter's field list and constructor are where most concurrent edits to emitter.ts collide. A feature now defines its state in its own file with defineModuleState (emitter-state.ts) and reads it through the returned key, so it no longer edits the class. The loop optimizations' twelve fields and their per-function setup move to loop-state.ts; the emitted IR is unchanged. scripts/split holds the transforms used for the emitter and lowering splits, and rehome-split.mjs, which carries an open branch across a split.
25 lines
849 B
Plaintext
25 lines
849 B
Plaintext
/* Per-feature emitter state. A feature defines its state in its own file
|
|
* with defineModuleState and reads it through the returned key, so adding
|
|
* or extending a feature does not edit LlEmitter's field list or
|
|
* constructor. */
|
|
import type { LlEmitter } from "./emitter.js";
|
|
|
|
/** A feature's state on an emitter, read with `key.of(emitter)`. */
|
|
export interface EmitterStateKey<T> {
|
|
of(emitter: LlEmitter): T;
|
|
}
|
|
|
|
let moduleSlots = 0;
|
|
|
|
/** State that lives for the whole module, created on first read. */
|
|
export function defineModuleState<T>(create: (emitter: LlEmitter) => T): EmitterStateKey<T> {
|
|
const slot = moduleSlots++;
|
|
return {
|
|
of(emitter) {
|
|
const states = emitter.moduleStates;
|
|
if (slot >= states.length || states[slot] === undefined) states[slot] = create(emitter);
|
|
return states[slot] as T;
|
|
},
|
|
};
|
|
}
|