Class: Slot

Slot()

new Slot()

A Slot could be created in 2 methods:

  • new Slot(value)

    this will make a data slot

  • new Slot(valueFunc, followings)

    this will make a follower slot, where followings is an Array. if the element (say following) in observables is a:

    • Slot

      if following changed, follower will be re-evaludated by executing valueFunc, following.val() will be used as valueFunc's argument. its new value is the return value of valueFunc, and change will be propogated to follower's followers.

    • not Slot

      when follower is re-evaluated, following will be used as valueFunc's argument directly.

    and valueFunc will accept 2 parameters:

    • the current value of observables
    • mutation process context, it has two keys:

      • roots - the mutation process roots, namely, those changed by clients (api caller) directly

      • involved - the observed involed in this mutation process

      the context is very useful if the evaluation function needs to return value according to which of its followings mutated

    let's see two example:

    
    const $$following = Slot(1);
    const $$follower = Slot((following, n) => following + n, [$$following, 2]);
    console.log($$follower.val()); // output 3, since n is always 2
    
    $$following.inc();
    console.log($$follower.val()); // output 4, since n is always 2
    
    const $$a = Slot(1).tag('a');
    const $$b = Slot(([a]) => a + 1, [$$a]).tag('b');
    const $$c = Slot(2).tag('c');
    const $$d = Slot(function ([a, b], {roots, involved}) {
    console.log(roots.map(it => it.tag())); // output [a]
    console.log(involved.map(it => it.tag())); // output [b]
    return a + b;
    });
    
    // a is root of mutation proccess, and c is not changed in this mutation proccess
    $$a.inc();
    
Source:

Methods

change(proc) → {Slot}

add a change handler

!!!Warning, this is a very dangerous operation if you modify slots in change handler, consider the following scenario:

 let $$s1 = Slot(1);
 let $$s2 = $$s1.makeFollower(it => it * 2);
 let $$s3 = $$s1.makeFollower(it => it * 3);
 $$s2.change(function () {
   $$s1.val(3); // forever loop
 ));

 $$s1.val(2);

as a thumb of rule, don't set value for followings in change handler

Parameters:
Name Type Description
proc function

it will be invoked when slot is mutated in one mutation process the same order as it is added, it accepts the following parameters:

  • new value of Slot
  • the old value of Slot
  • the mutation context

for example, you could refresh the UI, when ever the final view changed

Source:
Returns:

this

Type
Slot

concat(arr) → {Slot}

concat the Slot's value with an array

Parameters:
Name Type Description
arr array
Source:
Returns:

this

Type
Slot

dec(cnt) → {Slot}

decrement the slot's value, the slot's value should be of type number

Parameters:
Name Type Description
cnt number

the value to be deremented, default is 1

Source:
Returns:

this

Type
Slot

divide(n) → {Slot}

divides the slot's value by n, the slot's value should be of type number

Parameters:
Name Type Description
n number

the divisor

Source:
Returns:

this

Type
Slot

filter(fn) → {Slot}

filter the Slot's value with a function

Parameters:
Name Type Description
fn function
Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3, 4]);
console.log($$s.filter(it => it % 2 == 0).val()); // 2, 4

follow(valueFunc, followings) → {Slot}

unfollow all the followings if any and follow the new followings using the new valueFunc, this method will mutate the following graph.

!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process

Parameters:
Name Type Description
valueFunc function
followings array

please see Slot's constructor

Source:
See:
Returns:

this

Type
Slot

fork(func)

make a follower slot of me. this following has only one followings it is me.

Parameters:
Name Type Description
func function

the evaluation function

Source:
Examples
const $$s1 = Slot(1);
const $$s2 = $$s1.fork(n => n + 1);

is equivalent to:
const $$s1 = Slot(1);
const $$s2 = Slot(([n]) => n + 1, [$$s1]);

inc(cnt) → {Slot}

increment the slot's value, the slot's value should be of type number

Parameters:
Name Type Description
cnt number

the value to be added, default is 1

Source:
Returns:

this

Type
Slot

isTopmost() → {boolean}

test if slot observes others

Source:
Returns:

true if it observes others, else false

Type
boolean

map(fn) → {Slot}

map the Slot's value with a function

Parameters:
Name Type Description
fn function
Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.map(it => it * 2).val()); // 2, 4, 6

mod(n) → {Slot}

get remainder the slot's value, the slot's value should be of type number

Parameters:
Name Type Description
n number

the divisor

Source:
Returns:

this

Type
Slot
Example
const $$s = $$(17).mod(7);
console.log($$s.val());  // output 3

multiply(n) → {Slot}

multiply the slot's value by n, the slot's value should be of type number

Parameters:
Name Type Description
n number

the multiplier

Source:
Returns:

this

Type
Slot

mutateWith(func, args) → {Slot}

apply the function to me

Parameters:
Name Type Description
func function

the mutation function

args array

the extra arguments provided to func, default is []

Source:
Returns:

this

Type
Slot
Examples
const $$s = Slot(1);
$$s.mutateWith(function (s, n) {
 return s + n;
}, [2]);
console.log($$s.val()); // output 3

is equivalent to
const $$s = Slot(1);
$$s.val(function (s, n) { return s + n; }($$s.val(), 2));

mutationTester(tester)

set a handler to Slot to test if slot is mutated, here is an example:

Parameters:
Name Type Description
tester function

a handler to test if slot is changed in one mutation process, if a slot finds all its dependents are unmutation, the mutation process stops from it. A propriate tester will improve the performance dramatically sometimes.

it access slot as this and slot's new value and old value as arguments, and return true if slot is changed in mutation process, else false.

Source:
Example
let $$s1 = Slot(true);
let $$s2 = Slot(false);

let $$s3 = Slot((s1, s2) => s1 && s2, [$$s1, $$s2])
.mutationTester((oldV, newV) => oldV != newV);

$$s4 = $$s3.makeFollower((s3) => !s3)
.change(function () {
   console.log('s4 changed!');
});

// $$s2 will be changed to true, but $$s3 is not changed,
// neither $$s4 will be changed
$$s2.toggle();

off() → {Slot}

make the Slot's value to be false

Source:
Returns:

this

Type
Slot

offChange()

remove the change handler

Source:
See:

omit() → {Slot}

omit the keys

Source:
Returns:

this

Type
Slot
Example
const $$s = $$({ name: 'Tom', color: 'Blue' });
$$s.omit(['color']);
console.log($$s.val(); // { name: 'Tom' }

on() → {Slot}

make the Slot's value to be true

Source:
Returns:

this

Type
Slot

override(targetSlot) → {Slot}

detach the target slot from its followings, and let its followers connect me(this), just as if slot has been eliminated after the detachment. this method is very useful if you want to change the dependent graph

!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process

Parameters:
Name Type Description
targetSlot Slot
Source:
Returns:

this

Type
Slot

patch(obj) → {Slot}

patch the object value

Parameters:
Name Type Description
obj object

object used to patch me

Source:
Returns:

this

Type
Slot
Example
const $$s = $$({ name: 'Tom', color: 'Blue' });
$$s.patch({ name: 'Jerry', species: 'Mouse' });
console.log($$s.val()); // { name: 'Jerry', species: 'Mouse', colur: 'Blue' }

pop() → {Slot}

push the Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.pop().val()); // 1, 2

push() → {Slot}

push the Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.push(4).val()); // 1, 2, 3, 4

removeFollowing(idx)

this is the shortcut of replaceFollowing(idx)

!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process

Parameters:
Name Type Description
idx number

the index of

Source:

replaceFollowing(idx, following) → {Slot}

replaceFollowing, why not just re-follow, since follow is a quite expensive operation, while replaceFollowing only affect the replaced one

!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process

Parameters:
Name Type Description
idx

the index of following

following

a slot or any object, if not provided, the "idx"th following will not be followed anymore.

Source:
Returns:

this

Type
Slot

reverse() → {Slot}

reverse the Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.pop().val()); // [3, 2, 1]

set() → {Slot}

set the property of Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$({ name: 'Tom', color: 'Red' });
$$s.set('color', 'Blue');
console.log($$s.val(); // { name: 'Tom', color: 'Red' }

setIn() → {Slot}

set the deep property of Slot's value

Source:
Returns:

this

Type
Slot
Examples
const $$s = $$({ name: 'Tom' });
$$s.setIn(['friend', 'name'], 'Jerry');
console.log($$s.val(); // { name: 'Tom', frien: { 'name': 'Red'} }
const s = slot({});
s.setIn(['a', 1], 'abc'); // { a: [, 'abc'] }

setV(newV)

set the slot's value, and starts a mutation process

Parameters:
Name Type Description
newV any

the new value of slot,

Source:

shift() → {Slot}

shift the Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3, 4]);
console.log($$s.shift().val()); // 2, 3, 4

shrink() → {Slot}

shrink to a data slot with value val

Source:
Returns:

this

Type
Slot

slice() → {Slot}

slice the Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$([1, 2, 3, 4]);
console.log($$s.slice(1, 2).val()); // [2]

tag(v) → {string|Slot}

Set/get tag of slot, useful when debugging.

Parameters:
Name Type Description
v string | undefined

if is string, set the tag of slot and return this, else return the tag

Source:
Returns:
Type
string | Slot
Example
// set tag will return this
const $$s = Slot('foo').tag('bar');
console.log($$s.tag()); // output bar

toggle() → {Slot}

toggle the Slot's value

Source:
Returns:

this

Type
Slot

touch(propogate, context, callChangeCbs) → {boolean}

touch a slot, that means, re-evaluate the slot's value forcely, and starts mutation process and call change callbacks if neccessary. usually, you don't need call this method, only when you need to mutate the following graph (like override, replaceFollowing, follow)

Parameters:
Name Type Description
propogate

if starts a mutation process, default is true

context

if null, the touched slot is served as roots, default is null

callChangeCbs

if call change callbacks, default is true

Source:
See:
Returns:
  • return true if this Slot is mutated, else false
Type
boolean

unshift() → {Slot}

shift the Slot's value

Source:
Returns:

this

Type
Slot
Example
const $$s = $$([2, 3, 4]);
console.log($$s.unshift(1).val()); // 1, 2, 3, 4

val() → {any|Slot}

get or set the value, if no argument is given, get the current value of Slot, otherwise, set the value of Slot, the mutation process starts, and returns this

Source:
Returns:
Type
any | Slot