Bond
Direct Subclass:
Indirect Subclass:
An object which tracks a single, potentially variable, value. Bonds may be updated to new values with Bond#changed and reset to an indeterminate ("not ready") value with Bond#reset.
Bonds track their dependents - aspects of the program, including other Bonds, which reference their current value. Dependents may be added with Bond#use and removed with Bond#drop.
A Bond may be tied to a particular function to ensure it is called whenever the value changes. This implies a dependency, and can be registered with Bond#tie and dropped with Bond#untie. A function may also be called should the Bond be reverted to an undefined value; in this case Bond#notify and Bond#unnotify should be used.
Bonds can be made to execute a function once their value becomes ready
using Bond#then, which in some sense replicates the same function in the
context of a Promise
. The similar function Bond#done is also supplied which
executes a given function when the Bond reaches a value which is considered
"final", determined by Bond#isDone being implemented and true
. Precisely
what any given Bond considers final depends entirely on the subclass of
Bond; for the Bond class itself, isDone
always returns false
and thus
Bond#done is unusable. The value of the Bond, once ready, may
be logged to the console with the Bond#log function.
A Bond can provide a derivative Bond whose value reflects the "readiness" of the original, using Bond#ready and conversely Bond#notReady. This can also be queried normally with Bond#isReady.
One or a number of Bonds can be converted into a single {Promise} with the Bond#promise function.
Bonds
can be composed. Bond#map creates a new Bond whose value is a
transformation. Bond.all creates a new Bond which evaluates to the array
of values of each of a number of dependent Bonds. Bond.mapAll combines
both. Bond#reduce allows a Bond that evaluates to array to be
transformed into some other value recursively.
Bond#sub forms a derivative Bond as the subscript (square-bracket
indexing). Bond#subscriptable may be used to return a Proxy
object that
allows the Bond to be subscripted (square-bracket indexed) directly without
need of the Bond#sub function.
Bond is built to be subclassed. When subclassing, three functions are useful to implement. Bond#isDone may be implemented in order to make Bond#done be useful. Bond#initialise is called exactly once when there becomes at least one dependent; Bond#finalise is called when there are no longer any dependents.
WARNING: You should not attempt to use the toString
function with this
class. It cannot be meaningfully converted into a string, and to attempt it
will give an undefined result.
Static Method Summary
Static Public Methods | ||
public static |
Create a new Bond which represents the array of many objects' representative values. This object will be ready if and only if all objects in |
|
public static |
instanceOf(b: *): * Duck-typed alternative to |
|
public static |
Create a new Bond which represents a functional transformation of many objects' representative values. |
|
public static |
Create a Promise which represents one or more Bonds. |
Static Private Methods | ||
private static |
_fromSymbol(name: *): * |
|
private static |
_knowSymbol(name: *): * |
Constructor Summary
Public Constructor | ||
public |
constructor(mayBeNull: boolean) Constructs a new Bond object whose value is not ready. |
Member Summary
Private Members | ||
private |
_defaultTo: * |
|
private |
_mayBeNull: * |
|
private |
|
|
private |
_notifies: {} |
|
private |
_parse: * |
|
private |
|
|
private |
_readyBond: * |
|
private |
_stringify: * |
|
private |
_subscribers: {} |
|
private |
_thens: *[] |
|
private |
_triggering: * |
|
private |
|
|
private |
_uuid: * |
|
private |
_value: * |
Method Summary
Public Methods | ||
public |
changed(v: *) Makes the object ready and sets its current value. |
|
public |
Provide a Bond which represents the same as this object except that it takes a particular value when this would be unready. |
|
public |
defaultTo(x: *): * Alters this object so that it is always ready. |
|
public |
done(f: Bond~thenCallback): * Register a function to be called when this object becomes done. |
|
public |
drop() Unregister a single dependency for this object. |
|
public |
Determine if there is a definite value that this object represents at present. |
|
public |
Provide a derivative Bond which represents the same as this object except that before it is ready it evaluates to a given default value and after it becomes ready for the first time it stays fixed to that value indefinitely. |
|
public |
log(): * Logs the current value to the console. |
|
public |
Make a new Bond which is the functional transformation of this object. |
|
public |
Create a new Bond which represents this object's array value with its elements transformed by a function. |
|
public |
mapToString(): * Maps the represented value to a string. |
|
public |
notReady(): * Convenience function for the logical negation of Bond#ready. |
|
public |
Register a function to be called when the value or the readiness changes. |
|
public |
ready(): * Provide a Bond which represents whether this object itself represents a particular value. |
|
public |
Lazily transforms the contents of this object's value when it is an array. This operates on a Bond which should represent an array. It transforms this into a value based on a number of elements at the beginning of that array using a recursive reduce algorithm. The reduce algorithm works around an accumulator model. It begins with
the The Accumulation will continue until either there are no more elements in the array to be processed, or until the early exit flag is true, which ever happens first. |
|
public |
reset() Resets the state of this Bond into being not ready. |
|
public |
Create a new Bond which represents this object's value when subscripted. |
|
public |
subscriptable(depth: number): Proxy Provides a transparently subscriptable version of this object. |
|
public |
then(f: Bond~thenCallback): * Register a function to be called when this object becomes ready. |
|
public |
Register a function to be called when the value changes. |
|
public |
toString(): * |
|
public |
trigger(v: *) Makes the object ready and sets its current value. |
|
public |
Unregister a function previously registered with Bond#notify. |
|
public |
Unregister a function previously registered with Bond#tie. |
|
public |
use(): * Register a single dependency for this object. |
|
public |
Just like |
Protected Methods | ||
protected |
finalise() Uninitialise the object. |
|
protected |
Initialise the object. |
|
protected |
Returns whether the object is currently in a terminal state. |
Static Public Methods
public static all(list: array, resolveDepth: number): * source
Create a new Bond which represents the array of many objects' representative values.
This object will be ready if and only if all objects in list
are
themselves ready.
Return:
* | Bond - The object representing the value of the array of
each object's representative value in |
Example:
let b = new Bond;
let c = new Bond;
let t = Bond.all([b, c]);
t.tie(console.log);
b.changed(42);
c.changed(69); // logs [42, 69]
b.changed(3); // logs [3, 69]
let b = new Bond;
let c = new Bond;
let t = Bond.all(['a', {b, c}, 'd'], 2);
t.tie(console.log);
b.changed(42);
c.changed(69); // logs ['a', {b: 42, c: 69}, 'd']
b.changed(null); // logs ['a', {b: null, c: 69}, 'd']
public static instanceOf(b: *): * source
Duck-typed alternative to instanceof Bond
, when multiple instantiations
of Bond
may be available.
Params:
Name | Type | Attribute | Description |
b | * |
Return:
* |
public static mapAll(list: array, f: function, resolveDepth: number, outResolveDepth: number): * source
Create a new Bond which represents a functional transformation of many objects' representative values.
Params:
Name | Type | Attribute | Description |
list | array | An array of Bond objects or plain values. |
|
f | function | A function which accepts as many parameters are there
values in |
|
resolveDepth | number | The depth in a structure (array or object)
that a Bond may be in any of |
|
outResolveDepth | number | The depth in any returned structure that a Bond may be for it to be resolved. |
Return:
* |
Example:
let b = new Bond;
b.changed(23);
let c = new Bond;
c.changed(3);
let multiply = (x, y) => x * y;
// These two are exactly equivalent:
let bc = Bond.all([b, c]).map(([b, c]) => multiply(b, c));
let bc2 = Bond.mapAll([b, c], multiply);
public static promise(list: array): Promise source
Create a Promise which represents one or more Bonds.
Params:
Name | Type | Attribute | Description |
list | array | A list of values, {Promise}s or Bonds. |
Return:
Promise | A object which resolves to an array of values
corresponding to those passed in |
Example:
let b = new Bond;
let p = Bond.promise([b, 42])
p.then(console.log);
b.changed(69); // logs [69, 42]
b.changed(42); // nothing.
Static Private Methods
Public Constructors
public constructor(mayBeNull: boolean) source
Constructs a new Bond object whose value is not ready.
Params:
Name | Type | Attribute | Description |
mayBeNull | boolean |
|
Private Members
private _defaultTo: * source
private _mayBeNull: * source
private _notReadyBond: * source
private _notifies: {} source
private _parse: * source
private _readyBond: * source
private _stringify: * source
private _subscribers: {} source
private _thens: *[] source
private _triggering: * source
private _uuid: * source
private _value: * source
Public Methods
public changed(v: *) source
Makes the object ready and sets its current value.
Any functions that are registered for notification (see Bond#notify) or are tied (see Bond#tie) will be called if this Bond is not currently ready or is ready but has a different value.
This function is a no-op if the JSON representations of v
and of the
current value, if any, are equal.
Params:
Name | Type | Attribute | Description |
v | * | The new value that this object should represent. If |
public default(defaultValue: Symbol): * source
Provide a Bond which represents the same as this object except that it takes a particular value when this would be unready.
Params:
Name | Type | Attribute | Description |
defaultValue | Symbol | The value that the new bond should take when this bond is not ready. |
public defaultTo(x: *): * source
Alters this object so that it is always ready.
If this object is ever Bond#reset, then it will be changed to the value given.
Params:
Name | Type | Attribute | Description |
x | * | The value that this object represents if it would otherwise be not ready. |
Example:
let x = (new Bond).defaultTo(42);
x.log(); // 42
x.changed(69);
x.log(); // 69
x.reset();
x.log() // 42
public done(f: Bond~thenCallback): * source
Register a function to be called when this object becomes done.
For an object to be considered done
, it must be ready and the
function Bond#isDone should exist and return true
.
If the object is already done, then f
will be called immediately. If
not, f
will be deferred until the object assumes a value. f
will be
called at most once.
Params:
Name | Type | Attribute | Description |
f | Bond~thenCallback | The callback to be made once the object is ready. |
Return:
* |
Example:
let x = new Bond;
x.then(console.log);
x.changed(42); // 42 is written to the console.
public drop() source
Unregister a single dependency for this object.
Notes that a previously registered dependency has since expired. Must be called exactly once for each time Bond#use was called.
public isReady(): boolean source
Determine if there is a definite value that this object represents at present.
public latched(defaultValue: Symbol): * source
Provide a derivative Bond which represents the same as this object except that before it is ready it evaluates to a given default value and after it becomes ready for the first time it stays fixed to that value indefinitely.
Params:
Name | Type | Attribute | Description |
defaultValue | Symbol | The value that the new bond should take when this bond is not ready. |
public map(transform: function, outResolveDepth: number, cache: *, latched: *, mayBeNull: *): * source
Make a new Bond which is the functional transformation of this object.
Params:
Name | Type | Attribute | Description |
transform | function | The transformation to apply to the value represented by this Bond. |
|
outResolveDepth | number | The number of levels deep in any array object values of the result of the transformation that Bond values will be resolved. |
|
cache | * | Cache information. See constructor. |
|
latched | * | Should the value be latched so that once ready it stays ready? |
|
mayBeNull | * | Should the value be allowed to be |
Return:
* | Bond - An object representing this object's value with
the function |
Example:
let b = new Bond;
let t = b.map(_ => _ * 2);
t.tie(console.log);
b.changed(21); // logs 42
b.changed(34.5); // logs 69
let b = new Bond;
let t = b.map(_ => { let r = new Bond; r.changed(_ * 2); return r; });
t.tie(console.log);
b.changed(21); // logs 42
b.changed(34.5); // logs 69
let b = new Bond;
let t = b.map(_ => { let r = new Bond; r.changed(_ * 2); return [r]; }, 1);
t.tie(console.log);
b.changed(21); // logs [42]
b.changed(34.5); // logs [69]
public mapEach(transform: function): * source
Create a new Bond which represents this object's array value with its elements transformed by a function.
Params:
Name | Type | Attribute | Description |
transform | function | The transformation to apply to each element. |
Example:
let b = new Bond;
let t = b.mapEach(_ => _ * 2);
t.tie(console.log);
b.changed([1, 2, 3]); // logs [2, 4, 6]
b.changed([21]); // logs [42]
public notReady(): * source
Convenience function for the logical negation of Bond#ready.
Return:
* | Bond Object representing the logical opposite of the value returned by this Bond's Bond#isReady result. The returned object is itself always ready. |
Example:
// These two expressions are exactly equivalent:
bond.notReady();
bond.ready().map(_ => !_);
public notify(f: Bond~notifyCallback): Symbol source
Register a function to be called when the value or the readiness changes.
Calling this function already implies calling Bond#use - there is no need to call both.
Use this only when you need to be notified should the object be reset to a not ready state. In general you will want to use Bond#tie instead.
Params:
Name | Type | Attribute | Description |
f | Bond~notifyCallback | The function to be called. Takes no parameters. |
Return:
Symbol | An identifier for this registration. Must be provided to Bond#unnotify when the function no longer needs to be called. |
public ready(): * source
Provide a Bond which represents whether this object itself represents a particular value.
Return:
* | Bond - Object representing the value returned by this Bond's Bond#isReady result. The returned object is itself always ready. |
public reduce(accum: function, init: *): Bond source
Lazily transforms the contents of this object's value when it is an array.
This operates on a Bond which should represent an array. It transforms this into a value based on a number of elements at the beginning of that array using a recursive reduce algorithm.
The reduce algorithm works around an accumulator model. It begins with
the init
value, and incremenetally accumulates
elements from the array by changing its value to one returned from the
accum
function, when passed the current accumulator and the next value
from the array. The accum
function may return a Bond, in which case it
will be resolved (using Bond#then) and that value used.
The accum
function returns a value (or a Bond which resolves to a value)
of an array with exactly two elements; the first is the new value for the
accumulator. The second is a boolean early exit flag.
Accumulation will continue until either there are no more elements in the array to be processed, or until the early exit flag is true, which ever happens first.
Params:
Name | Type | Attribute | Description |
accum | function | The reduce's accumulator function. |
|
init | * | The initialisation value for the reduce algorithm. |
public reset() source
Resets the state of this Bond into being not ready.
Any functions that are registered for notification (see Bond#notify) will be called if this Bond is currently ready.
public sub(name: string | number, outResolveDepth: number): * source
Create a new Bond which represents this object's value when subscripted.
Return:
* | Bond - The object representing the value which is the
value represented by this object subscripted by the value represented by
|
Example:
let b = new Bond;
let t = b.sub('foo');
t.tie(console.log);
b.changed({foo: 42}); // logs 42
b.changed({foo: 69}); // logs 69
let b = new Bond;
let c = new Bond;
let t = b.sub(c);
t.tie(console.log);
b.changed([42, 4, 2]);
c.changed(0); // logs 42
c.changed(1); // logs 4
b.changed([68, 69, 70]); // logs 69
public subscriptable(depth: number): Proxy source
Provides a transparently subscriptable version of this object.
The object that is returned from this function is a convenience Proxy
which acts exactly equivalent
to the original Bond, except that any subscripting of fields that are
not members of the Bond object will create a new Bond that
itself evaluates to this Bond's value when subscripted with the same
field.
Params:
Name | Type | Attribute | Description |
depth | number | The maximum number of levels of subscripting that
the returned |
Example:
let x = (new Bond).subscriptable();
let y = x.foo;
y.log(); // nothing yet
x.changed({foo: 42, bar: 69}); // logs 42
public then(f: Bond~thenCallback): * source
Register a function to be called when this object becomes ready.
For an object to be considered ready, it must represent a definite
value. In this case, Bond#isReady will return true
.
If the object is already ready, then f
will be called immediately. If
not, f
will be deferred until the object assumes a value. f
will be
called at most once.
Params:
Name | Type | Attribute | Description |
f | Bond~thenCallback | The callback to be made once the object is ready. |
Return:
* |
Example:
let x = new Bond;
x.then(console.log);
x.changed(42); // 42 is written to the console.
public tie(f: Bond~tieCallback): Symbol source
Register a function to be called when the value changes.
Calling this function already implies calling Bond#use - there is no need to call both.
Unlike Bond#notify, this does not get called should the object become reset into being not ready.
Params:
Name | Type | Attribute | Description |
f | Bond~tieCallback | The function to be called. |
Return:
Symbol | An identifier for this registration. Must be provided to Bond#untie when the function no longer needs to be called. |
public trigger(v: *) source
Makes the object ready and sets its current value.
Any functions that are registered for notification (see Bond#notify) or are tied (see Bond#tie) will be called if this Bond is not currently ready or is ready but has a different value.
Unlike Bond#changed, this function doesn't check equivalence between the new value and the current value.
Params:
Name | Type | Attribute | Description |
v | * | The new value that this object should represent. By default, it will reissue the current value. It is an error to call it without an argument if it is not ready. |
public unnotify(id: Symbol) source
Unregister a function previously registered with Bond#notify.
Calling this function already implies calling Bond#drop - there is no need to call both.
Params:
Name | Type | Attribute | Description |
id | Symbol | The identifier returned from the corresponding Bond#notify call. |
public untie(id: Symbol) source
public use(): * source
Register a single dependency for this object.
Notes that the object's value is in use, and that it should be computed. Bond sub-classes are allowed to not work properly unless there is at least one dependency registered.
Return:
* |
See:
public xform(transform: function, outResolveDepth: number, cache: *, latched: *, mayBeNull: *): * source
Just like map
, except that it defaults to no latching and mayBeNull.
Params:
Name | Type | Attribute | Description |
transform | function | The transformation to apply to the value represented by this Bond. |
|
outResolveDepth | number | The number of levels deep in any array object values of the result of the transformation that Bond values will be resolved. |
|
cache | * | Cache information. See constructor. |
|
latched | * | Should the value be latched so that once ready it stays ready? |
|
mayBeNull | * | Should the value be allowed to be |
Return:
* | Bond - An object representing this object's value with
the function |
Protected Methods
protected finalise() source
Uninitialise the object.
Will be called at most once after an accompanying Bond#initialise and should close/finalise/drop any resources that are required for the sub-class to maintain its value.
protected initialise() source
Initialise the object.
Will be called at most once before an accompanying Bond#finalise and should initialise/open/create any resources that are required for the sub-class to maintain its value.