type Signal < T = unknown > = { /** Read value */ ( ) : T ; /** Write value; notifying wires */ ( value ) : void ; /** Read value & subscribe */ ( $ ) : T ; /** Wires subscribed to this signal */ wires : Set < Wire < X > > ; /** Transaction value; set and deleted on commit */ next ? : T ; /** If this is a computed-signal, this is its wire */ cw ? : Wire < T > ; /** To check "if x is a signal" */ $signal : 1 ; } ; type Wire < T = unknown > = { /** Run the wire */ ( ) : T ; /** Signals read-subscribed last run */ sigRS : Set < Signal < X > > ; /** Signals read-passed last run */ sigRP : Set < Signal < X > > ; /** Signals inherited from computed-signals, for consistent two-way linking */ sigIC : Set < Signal < X > > ; /** Post-run tasks */ tasks : Set < ( nextValue : T ) => void > ; /** Wire that created this wire (parent of this child) */ upper : Wire < X > | undefined ; /** Wires created during this run (children of this parent) */ lower : Set < Wire < X > > ; /** FSM state 3-bit bitmask: [RUNNING][SKIP_RUN_QUEUE][NEEDS_RUN] */ state : WireState ; /** Run count */ run : number ; /** If part of a computed signal, this is its signal */ cs ? : Signal < T > ; /** To check "if x is a wire" */ $wire : 1 ; } ; type SubToken = { /** Allow $(...signals) to return an array of read values */ < U extends Array < ( ) => unknown > > ( ... args ) : { [ P in keyof U ] : U [ P ] extends Signal < infer R > ? R : never ; } ; /** Wire to subscribe to */ wire : Wire < X > ; /** To check "if x is a subscription token" */ $$ : 1 ; } ; /** 3 bits: [RUNNING][SKIP_RUN_QUEUE][NEEDS_RUN] */ type WireState = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ; type X = any ; type P < T > = Partial < T > ; let wireId = 0 ; let signalId = 0 ; let activeWire ; let transactionSignals ; let transactionCommit = false ; declare const S_RUNNING = 0b100 ; declare const S_SKIP_RUN_QUEUE = 0b010 ; declare const S_NEEDS_RUN = 0b001 ; /**
 * Void subcription token. Used when a function demands a token but you don't
 * want to consent to any signal subscriptions. */ const v$ = ( ( ... signals ) => signals . map ( ( sig ) => sig ( v$ ) ) ) ; /**
 * Create a wire. Activate the wire by running it (function call). Any signals
 * that read-subscribed during the run will re-run the wire later when written
 * to. Wires can be run anytime manually. They're pausable and are resumed when
 * called; resuming will avoid a wire run if the wire is not stale. Wires are
 * named by their function's name and a counter. */ const createWire = < T > ( fn ) : Wire < T > => { const id = `wire|${ wireId ++ }{${ fn . name }}` ; let saved ; const wire = { [ id ] ( ) { if ( wire . state & S_RUNNING ) { throw new Error ( `Loop ${ wire . name }` ) ; } wireReset ( wire ) ; wire . state |= S_RUNNING ; wireAdopt ( wire , ( ) => saved = fn ( $ ) ) ; wire . tasks . forEach ( ( task ) => task ( saved ) ) ; wire . run ++ ; wire . state &= ~ ( S_RUNNING | S_NEEDS_RUN ) ; return saved ; } } [ id ] ; const $ = ( ( ... sig ) => sig . map ( ( _sig ) => _sig ( $ ) ) ) ; $ . $$ = 1 ; $ . wire = wire ; if ( activeWire ) activeWire . lower . add ( wire ) ; wire . upper = activeWire ; wire . tasks = new Set ( ) ; wire . $wire = 1 ; wire . run = 0 ; _initWire ( wire ) ; return wire ; } ; const _initWire = ( wire ) : void => { wire . state = S_NEEDS_RUN ; wire . lower = new Set ( ) ; wire . sigRS = new Set ( ) ; wire . sigRP = new Set ( ) ; wire . sigIC = new Set ( ) ; } ; const _runWires = ( wires ) : void => { const toRun = new Set ( wires ) ; let curr ; toRun . forEach ( ( wire ) => { if ( wire . cs || wire . state & S_SKIP_RUN_QUEUE ) { toRun . delete ( wire ) ; wire . state |= S_NEEDS_RUN ; } curr = wire ; while ( ( curr = curr . upper ) ) if ( toRun . has ( curr ) ) return toRun . delete ( wire ) ; } ) ; toRun . forEach ( ( wire ) => wire ( ) as void ) ; } ; /**
 * Removes two-way subscriptions between its signals and itself. This also turns
 * off the wire until it is manually re-run. */ const wireReset = ( wire ) : void => { wire . lower . forEach ( wireReset ) ; wire . sigRS . forEach ( ( signal ) => signal . wires . delete ( wire ) ) ; wire . sigIC . forEach ( ( signal ) => signal . wires . delete ( wire ) ) ; _initWire ( wire ) ; } ; /**
 * Pauses a wire so signal writes won't cause runs. Affects nested wires */ const wirePause = ( wire ) : void => { wire . lower . forEach ( wirePause ) ; wire . state |= S_SKIP_RUN_QUEUE ; } ; /**
 * Resumes a paused wire. Affects nested wires but skips wires belonging to
 * computed-signals. Returns true if any runs were missed during the pause */ const wireResume = ( wire ) : boolean => { wire . lower . forEach ( wireResume ) ; if ( ! wire . cs ) wire . state &= ~ S_SKIP_RUN_QUEUE ; return ! ! ( wire . state & S_NEEDS_RUN ) ; } ; const signalBase = < T > ( value , id = '' ) : Signal < T > => { type W = Wire < X > ; let saved ; let cwTask ; let read = `signal|${ signalId ++ }{${ id }}` ; const signal = { [ read as string ] ( ... args ) { if ( ( read = ! args . length ) ) { if ( activeWire ) { if ( activeWire . sigRS . has ( signal ) ) { throw new Error ( `${ activeWire . name } mixes sig($) & sig()` ) ; } activeWire . sigRP . add ( signal ) ; } } else if ( ( read = args [ 0 ] === v$ ) ) { } else if ( ( read = args [ 0 ] && ( args [ 0 ] as P < SubToken > ) . $$ && args [ 0 ] . wire ) ) { if ( ( read as W ) . sigRP . has ( signal ) ) { throw new Error ( `${ ( read as W ) . name } mixes sig($) & sig()` ) ; } ( read as W ) . sigRS . add ( signal ) ; signal . wires . add ( ( read as W ) ) ; if ( signal . cw ) { if ( signal . cw . state & S_NEEDS_RUN ) signal . cw ( ) ; signal . cw . sigRS . forEach ( ( _signal ) => { ( read as W ) . sigIC . add ( _signal ) ; _signal . wires . add ( ( read as W ) ) ; } ) ; } } else { if ( transactionSignals ) { transactionSignals . add ( signal ) ; signal . next = args [ 0 ] as unknown as T ; return ; } if ( signal . cw ) { signal . cw . tasks . delete ( cwTask as ( ) => void ) ; wireReset ( signal . cw ) ; delete signal . cw . cs ; delete signal . cw ; } saved = args [ 0 ] as unknown as T ; if ( saved && ( saved as P < Wire > ) . $wire ) { ( saved as W ) . cs = signal ; ( saved as W ) . state |= S_SKIP_RUN_QUEUE ; ( saved as W ) . tasks . add ( cwTask = ( value ) => saved = value ) ; signal . cw = saved as W ; } if ( ! transactionCommit ) _runWires ( signal . wires ) ; } if ( read ) { if ( signal . cw && signal . cw . state & S_NEEDS_RUN ) signal . cw ( ) ; return saved ; } } } [ read as string ] as Signal < T > ; signal . $signal = 1 ; signal . wires = new Set < Wire < X > > ( ) ; signal ( value ) ; return signal ; } ; /**
 * Creates signals for each object entry. Signals are read/write variables which
 * hold a list of subscribed wires. When a value is written those wires are
 * re-run. Writing a wire into a signal creates a lazy computed-signal. Signals
 * are named by the key of the object entry and a global counter. */ const createSignal = < T > ( obj ) : { [ K in keyof T ] : Signal < T [ K ] extends Wire < infer R > ? R : T [ K ] > ; } => { Object . keys ( obj ) . forEach ( ( k ) => { obj [ k ] = signalBase ( obj [ k as keyof T ] , k ) ; signalId -- ; } ) ; signalId ++ ; return obj ; } ; createSignal . anon = signalBase ; /**
 * Batch signal writes so only the last write per signal is applied. Values are
 * committed at the end of the function call. */ const transaction = < T > ( fn ) : T => { const prev = transactionSignals ; transactionSignals = new Set ( ) ; let error ; let ret ; try { ret = fn ( ) ; const signals = transactionSignals ; transactionSignals = prev ; const transactionWires = new Set < Wire < X > > ( ) ; transactionCommit = true ; signals . forEach ( ( signal ) => { signal ( signal . next ) ; delete signal . next ; signal . wires . forEach ( ( wire ) => transactionWires . add ( wire ) ) ; } ) ; transactionCommit = false ; _runWires ( transactionWires ) ; } catch ( err ) { error = err ; } transactionSignals = prev ; if ( error ) throw error ; return ret as T ; } ; /**
 * Run a function within the context of a wire. Wires created in this context
 * are adopted (see wire.lower). This affects signal read consistency checks for
 * read-pass (signal.sigRP) and read-subscribe (signal.sigRS). */ const wireAdopt = < T > ( wire , fn ) : void => { const prev = activeWire ; activeWire = wire ; let error ; try { fn ( ) ; } catch ( err ) { error = err ; } activeWire = prev ; if ( error ) throw error ; } ; export { createSignal as signal , createWire as wire , wireReset , wirePause , wireResume , wireAdopt , transaction , v$ } ; export type { Signal , Wire , WireState , SubToken } ;