0.0.4 • Published 2 years ago

link-oriented v0.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Link Oriented

A fantasy programming conception.

Installation

Using npm:

$ npm i --save link-oriented

Get Started

Use $var(value) function to create variables. value is an initial value of the variable. The value of a variable can be modified by using the method assigned.

Then use link method to link two variables. The variable that invokes the function is called head, while the other is tail. A link can be simply written in the form of head -> tail. You can also define a trigger function. Once the link is created, any assignment of the head will raise an invocation of the trigger function.

Note that attribute val is the value of a variable. In other words, we can use m.val to access the value of m.

const { $var } = require('link-oriented');

const basketNumber = $var(0), appleNumber = $var(0);
basketNumber.link(appleNumber, (n) => n * 5);  // basketNumber -> appleNumber
basketNumber.assign(4);
console.log(`number of apples: ${appleNumber}`);  // number of apples: 20
basketNumber.assign(7);
console.log(`number of apples: ${appleNumber}`);  // number of apples: 35

The following is a more complex but common-used example. currentVistor is a variable that stores the reference of current visitor. When currentVistor changed, it will be put into visit list.

class Visitor {
  constructor(name) {
    this.name = name;
  }

  toString() {
    return this.name;
  }
}

const currentVisitor = $var(), visitorList = $var([]);

// when visitor changed, add it into visitor list
currentVisitor.link(visitorList, (visitor, visitorList) => {
  visitorList.val.push(visitor.val);
});	// currentVisitor -> visitorList

// print the number of visitors when it changes
visitorList.link($var(), (visitorList) => {
  console.log(visitorList.val.length);
});	// visitorList -> [anonymous variable]

currentVisitor.assign(new Visitor('James'));
currentVisitor.assign(new Visitor('Lily'));
currentVisitor.assign(new Visitor('Michael'));  // console prints 1, 2, 3 in a row
console.log(visitorList.toString());  // James,Lily,Michael

Specification

The following example shows us two different ways to modify the value and the difference between them.

const week = $var(0), weekStr = $var();
console.log(week.val);  // get the value of the variable
week.val = 2; // modify the value of the variable (not to trigger)
week.assign(3);  // modify the value of the variable (trigger)

// establish a link as follows
// head.link(tail, triggerFunction);
const ln = week.link(weekStr, (week, weekStr) => {
  return ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][week.val];
});

// assign a value to variable week
week.assign(5);
console.log(weekStr);
// the weekStr is modified by trigger function, the result is "Sat"

week.val = 2;
console.log(weekStr);
// this approach will only modify the value of variable but not trigger, so the result is still "Sat"

We can also use link.on() and link.off() to turn the link on and off.

ln.off(); // turn off the link, the trigger is disabled
week.assign(2);
console.log(weekStr); // still "Sat"

ln.on();  // turn on the link, the trigger is enabled
week.assign(4);
console.log(weekStr); // "Fri"

If we want to remove a variable (never use it again), we need to use the release method to remove all triggers related to it.

week.release();

Helper functions

We provide some helpful functions in module Links.

two-way binding

declare function twoWayBinding<H, T>(
    head: Var<H>,
    tail: Var<T>,
    forwardFunction: TriggerFunction<T>,
    backwardFunction: TriggerFunction<H>
): void;

If we create two links to connect two variables, their relationship is called two-way binding. It can be written as head <-> tail. Note that when head is assigned, tail is changed but will not raise an invocation of link tail -> head. Likewise to the assignment to tail.

const { $var, two_way_binding } = require('link-oriented');

const tab = $var('    '), tabLength = $var(4);
two_way_binding(tab, tabLength, (tab) => {
  return tab.val.length;
}, (tabLength) => {
  return ' '.repeat(tabLength.val);
});

tab.assign('  ');
console.log(`tab length: ${tabLength}`); // tab length: 2

tabLength.assign(4);
console.log(`tab: '${tab}'`); // tab: '    '

trigger

declare function trigger<V>(_var: Var<V>, trigger: (_var: Var<V>) => any): void;

This function allows a specified callback function to be invoked when the specified variable is being assigned.

const name = $var('Bob');
Links.trigger(name, (name) => {
  console.log(`Name is changed to: ${name}`);
});
name.assign('James'); // console print: Name is changed to: James

log

declare function log(_var: Var<any>, caption: string = ''): void;

This function allows a variable to be printed on the console when being assigned.

const thumbsUp = $var(0);
Links.log(thumbsUp, 'thumbs up');
thumbsUp.assign(1); // console print: thumbs up: 1
thumbsUp.assign(2); // console print: thumbs up: 2

TypeScript

There is no difference when using TypeScript, import it as follows.

import { $var, Var, Link } from 'link-oriented';

Then use it freely~

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago

0.0.0

2 years ago