ti2c
v25.5.6
Published
A JavaScript toolkit for (t)yped, (i)mmutable, and (i)nterned objects with lazily (c)ached computations
Downloads
32
Readme
ti2c
is a{T}yping, {I}mmuting, {I}nterning and {C}aching library for Javascript ti2c is designed to facilitate robust coding and improve performance with caching avoiding deep copy or protective copying of data structures.
a minimal working example
Following code can be downloaded from https://gitlab.com/ti2c/ti2c/-/tree/examples.
src/Point.js
Defines point as a ti2c class having two attributes. Also a function to add to points is defined.
def.attributes =
{
x: { type: 'number' },
y: { type: 'number' },
};
def.proto.add =
function( p )
{
return Self.create( 'x', this.x + p.x, 'y', this.y + p.y );
};Currently ti2c follows a one class per file rule.
src/Root.js
Not lets use the "Point class". Since this file does not define a class to b einstanced it is declared to be "abstract".
Also the import syntax ti2c uses to import another ti2c class can be seen using {} in the import string.
def.abstract = true;
import { Self as Point } from '{Point}';
def.static.run =
function( )
{
const p1 = Point.create( 'x', 1, 'y', 2 );
const p2 = Point.create( 'x', 1, 'y', 2 );
const p3 = Point.create( 'x', 2, 'y', 4 );
console.log( 'equal?', p1 === p2 );
console.log( 'equal?', p1 === p3 );
console.log( 'equal?', p1.add( p2 ) === p3 );
};src/Start.js
Finally a ti2c application needs a starting driver running in the default node context.
global.CHECK = true;
await import( 'ti2c' );
const pkg =
await ti2c.register(
'name', 'example',
'meta', import.meta,
'source', 'src/',
'relPath', 'Start',
'codegen', 'codegen/'
);
const Root = await pkg.import( 'Root' );
Root.run( );Now we can run the example. Note that currently --experimental-vm-modules is needed as node parameter, since ti2c uses the esm vm module.
$ node --experimental-vm-modules src/Start.js
The output is:
equal? true
equal? false
equal? true
``
p1 added to p1 returns the object that is also p2.
## lazy evaluation
ti2c supports lazy evaluation and caching of the results.
Lets enhance previous Point function with two lazy evaluated attributes, first the length from Point 0/0 as "length" as well a distance to another point.
### src/Point.js
```js
def.attributes =
{
x: { type: 'number' },
y: { type: 'number' },
};
def.lazy.length =
function( )
{
console.log( 'calculating length...' );
const x = this.x;
const y = this.y;
return Math.sqrt( x * x + y * y );
};
def.lazyFunc.distanceTo =
function( p )
{
console.log( 'calculating distance...' );
const dx = this.x - p.x;
const dy = this.y - p.y;
return Math.sqrt( dx * dx + dy * dy );
};and now again a test program:
src/Root.js
def.abstract = true;
import { Self as Point } from '{Point}';
def.static.run =
function( )
{
const p1 = Point.create( 'x', 1, 'y', 2 );
const p2 = Point.create( 'x', 2, 'y', 4 );
console.log( 'p1 length is', p1.length );
console.log( 'p1 length is', p1.length );
console.log( 'p1-p2 distance is', p1.distanceTo( p2 ) );
console.log( 'p1-p2 distance is', p1.distanceTo( p2 ) );
};the output is
calculating length...
p1 length is 2.23606797749979
p1 length is 2.23606797749979
calculating distance...
p1-p2 distance is 2.23606797749979
p1-p2 distance is 2.23606797749979