Home Reference Source
import Bond from './packages/oo7/src/bond.js'
public class | source

Bond

Indirect Subclass:

ReactivePromise, TransformBond

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

all(list: array, resolveDepth: number): *

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.

public static

instanceOf(b: *): *

Duck-typed alternative to instanceof Bond, when multiple instantiations of Bond may be available.

public static

mapAll(list: array, f: function, resolveDepth: number, outResolveDepth: number): *

Create a new Bond which represents a functional transformation of many objects' representative values.

public static

promise(list: array): Promise

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
private
private
private

_notifies: {}

private

_parse: *

private
private
private
private
private

_thens: *[]

private
private
private

_uuid: *

private

_value: *

Method Summary

Public Methods
public

changed(v: *)

Makes the object ready and sets its current value.

public

default(defaultValue: Symbol): *

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

latched(defaultValue: Symbol): *

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

map(transform: function, outResolveDepth: number, cache: *, latched: *, mayBeNull: *): *

Make a new Bond which is the functional transformation of this object.

public

mapEach(transform: function): *

Create a new Bond which represents this object's array value with its elements transformed by a function.

public

Maps the represented value to a string.

public

notReady(): *

Convenience function for the logical negation of Bond#ready.

public

notify(f: Bond~notifyCallback): Symbol

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

reduce(accum: function, init: *): Bond

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.

public

reset()

Resets the state of this Bond into being not ready.

public

sub(name: string | number, outResolveDepth: number): *

Create a new Bond which represents this object's value when subscripted.

public

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

tie(f: Bond~tieCallback): Symbol

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

untie(id: Symbol)

Unregister a function previously registered with Bond#tie.

public

use(): *

Register a single dependency for this object.

public

xform(transform: function, outResolveDepth: number, cache: *, latched: *, mayBeNull: *): *

Just like map, except that it defaults to no latching and mayBeNull.

Protected Methods
protected

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.

Params:

NameTypeAttributeDescription
list array

An array of Bond objects, plain values or structures (arrays/objects) which contain either of these.

resolveDepth number

The depth in a structure (array or object) that a Bond may be in any of list's items for it to be resolved.

Return:

*

Bond - The object representing the value of the array of each object's representative value in list.

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:

NameTypeAttributeDescription
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:

NameTypeAttributeDescription
list array

An array of Bond objects or plain values.

f function

A function which accepts as many parameters are there values in list and transforms it into a Bond, Promise or other value.

resolveDepth number

The depth in a structure (array or object) that a Bond may be in any of list's items for it to be resolved.

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:

NameTypeAttributeDescription
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 list.

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

private static _fromSymbol(name: *): * source

Params:

NameTypeAttributeDescription
name *

Return:

*

private static _knowSymbol(name: *): * source

Params:

NameTypeAttributeDescription
name *

Return:

*

Public Constructors

public constructor(mayBeNull: boolean) source

Constructs a new Bond object whose value is not ready.

Params:

NameTypeAttributeDescription
mayBeNull boolean

true if this instance's value may ever validly be null. If false, then setting this object's value to null is equivalent to reseting back to being not ready.

Private Members

private _defaultTo: * source

private _mayBeNull: * source

private _notReadyBond: * source

private _notifies: {} source

private _parse: * source

private _ready: boolean source

private _readyBond: * source

private _stringify: * source

private _subscribers: {} source

private _thens: *[] source

private _triggering: * source

private _users: number 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:

NameTypeAttributeDescription
v *

The new value that this object should represent. If undefined then the function does nothing.

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:

NameTypeAttributeDescription
defaultValue Symbol

The value that the new bond should take when this bond is not ready.

Return:

*

Bond - Object representing the value returned by this Bond except that it evaluates to the given default value when this bond is not ready. The returned object itself is always 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:

NameTypeAttributeDescription
x *

The value that this object represents if it would otherwise be not ready.

Return:

*

Bond - This (mutated) object.

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:

NameTypeAttributeDescription
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.

Return:

boolean

true if there is presently a value that this object represents.

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:

NameTypeAttributeDescription
defaultValue Symbol

The value that the new bond should take when this bond is not ready.

Return:

*

Bond - Object representing the value returned by this Bond except that it evaluates to the given default value when this bond is not ready and sticks to the first value that made it ready.

public log(): * source

Logs the current value to the console.

Return:

*

Bond The current object.

public map(transform: function, outResolveDepth: number, cache: *, latched: *, mayBeNull: *): * source

Make a new Bond which is the functional transformation of this object.

Params:

NameTypeAttributeDescription
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 null such that if it ever becomes null, it is treated as being unready?

Return:

*

Bond - An object representing this object's value with the function transform applied to it.

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:

NameTypeAttributeDescription
transform function

The transformation to apply to each element.

Return:

*

The new Bond object representing the element-wise Transformation.

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 mapToString(): * source

Maps the represented value to a string.

Return:

*

Bond A new {link Bond} which represents the toString function on whatever value this Bond represents.

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:

NameTypeAttributeDescription
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:

NameTypeAttributeDescription
accum function

The reduce's accumulator function.

init *

The initialisation value for the reduce algorithm.

Return:

Bond

A Bond representing init when the input array is empty, otherwise the reduction of that array.

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.

Params:

NameTypeAttributeDescription
name string | number

The field or index by which to subscript this object's represented value. May itself be a Bond, in which case, the resolved value is used.

outResolveDepth number

The depth in any returned structure that a Bond may be for it to be resolved.

Return:

*

Bond - The object representing the value which is the value represented by this object subscripted by the value represented by name.

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:

NameTypeAttributeDescription
depth number

The maximum number of levels of subscripting that the returned Proxy will support.

Return:

Proxy

Proxy object that acts as a subscriptable variation for convenience.

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:

NameTypeAttributeDescription
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:

NameTypeAttributeDescription
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 toString(): * source

Return:

*

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:

NameTypeAttributeDescription
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:

NameTypeAttributeDescription
id Symbol

The identifier returned from the corresponding Bond#notify call.

public untie(id: Symbol) source

Unregister a function previously registered with Bond#tie.

Calling this function already implies calling Bond#drop - there is no need to call both.

Params:

NameTypeAttributeDescription
id Symbol

The identifier returned from the corresponding Bond#tie call.

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:

NameTypeAttributeDescription
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 null such that if it ever becomes null, it is treated as being unready?

Return:

*

Bond - An object representing this object's value with the function transform applied to it.

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.

protected isDone(): boolean source

Returns whether the object is currently in a terminal state.

WARNING: The output of this function should not change outside of a value change. If it ever changes without the value changing, trigger should be called to force an update.

Return:

boolean

true when the value should be interpreted as being in a final state.

See: