id of this signal in the Context in which it exists.
runtime-id of this signal.
it equals to the id on the first, so that the dependencies of this signal can be notified of being observed.
but once all dependencies have been notified after the first run, this runtime-id should become 0
(UNTRACKED_ID),
so that the dependiencies do not have to re-register this signal as an observer.
Optional
namegive a name to this signal for debugging purposes
get the value of this signal, and handle any observing signal's id (observer_id).
typically, when observer_id
is non-zero, this signal should handle it by registering it as an
observer through the use of the context's Context.addEdge method.
Optional
observer_id: numberconst MySignalClass_Factory = (ctx: Context) => {
const addEdge = ctx.addEdge
return class MySignal<T> implements Signal<T> {
declare value: T
// ...
get(observer_id?: TO_ID | UNTRACKED_ID): T {
// register this.id to observer (if non-zero) in the dependency graph as a directed edge
if (observer_id) { addEdge(this.id, observer_id) }
return this.value
}
// ...
}
}
Optional
setset the value of this signal.
the meaning of setting a signal's value greatly varies from signal to signal, which is why it is so abstracted.
however, the returning value must always be a boolean
describing whether or not this signal's value has changed compared to its previous value.
what makes use of the returned value again greatly varies from signal to signal.
but it is typically used by the run method to decide whether or not this signal should propagate.
another purpose of the set method is typically to initiate the ignition of an update cycle in a context, bu using Context.runId.
this is how StateSignals and EffectSignals begin an update cycle when their values have changed from the prior value.
Rest
...args: any[]const MySignalClass_Factory = (ctx: Context) => {
const runId = ctx.runId
return class MySignal<T> implements Signal<T> {
declare value: T
// ...
set(new_value: T): boolean {
const value_has_changed = new_value !== this.value
if (value_has_changed) {
runId(this.id)
return true
}
return false
}
// ...
}
}
Optional
prerunspecify actions that need to be taken before an update cycle has even begun propagating.
TODO: CURRENTLY NOT IMPLEMENTED.
ISSUE: what should the order in which prepruns run be? we do know the FULL set of signal ids that will be visited.
but we do not know the subset of ids that WILL BE affected and ran, not until run time of the signal propagation.
should ids that might be affected also have their preruns ran? and in what order? because we cannot know the order until propagation runtime.
run the actions taken by a signal when it is informed that its dependency signals have been modified/changed.
the return value should be of the numertic enum kind SignalUpdateStatus, which specifies that this signal has been either been:
1
: updated, and therefore this signal's observers should be notified (i.e. ran via their run
method) 0
: unchanged, and therefore this signal's observers should be notified if this is their only active dependency-1
: aborted, and therefore this signal's observer should also abort their run
method's execution if they were queuedthis method may also accept an optional forced
parameter, which tells the signal that it is
being forced to run, even though none of its dependency signals have been executed or changed.
this information is useful when coding for signals that can be fired independently, such as StateSignal or EffectSignal.
Optional
forced: booleanwas this signal forced to run independently?
the update status of this signal, specifying whether or not it has changed, or if it has been aborted
Optional
postrunspecify actions that need to be taken after an update cycle has fully propagated till the end.
the order in which postrun
s will be executed will be in the reverse order in which they were first encountered (i.e: last in, last out).
meaning that if all three signals A
, B
, and C
, had postrun
methods on them, and the order of execution was:
A -> B -> C
, then all postrun
s will run in the order: [C.postrun, B.postrun, A.postrun]
(similar to a stack popping).
a utility method defined in SimpleSignal, which allows one to bind a certain method (by name) to this instance of a signal,
and therefore make that method freeable/seperable from this signal.
this method is used by all signal classes's static SignalClass.create method, which is supposed to construct a signal in
a fashion similar to SolidJS, and return an array containing important control functions of the created signal.
most, if not all, of these control function are generally plain old signal methods that have been bounded to the created signal instance.
Generated using TypeDoc
the abstraction that defines what a signal is.