Skip to content

Universal state management. Observable, serializable, transactional, and type safe JS objects.

License

Notifications You must be signed in to change notification settings

gaperton/Type-R

Repository files navigation

master build

Getting started

Type-R is the modern JS data framework to manage complex domain and UI application state. Features:

  • It's mapped to JSON by default. The mapping can handle sophisticated scenarios with nested JSON and relations by id, and can be easily customized for every particular attribute or class.
  • All changes are observable, happens in the scope of transactions, and there's the fine-grained change events system.
  • Validation is performed on the first access to the validation error and never happens twice for unchanged data.
  • Everything is typed at run-time and is protected from improper updates. The shape of generated JSON and data classes is guaranteed to match the definitions.
  • It still looks like regular JS classes and is freaking fast. Type-R data structures are about 10 times faster than Backbone models and collections.

overview

Data layer is defined as a superposition of three kinds of building blocks:

  • Record classes with typed attributes.
  • Ordered collections of records.
  • Stores are records with a set of collections in its attributes used to resolve id-references in JSON.
  • IOEndpoints is an entity encapsulating I/O transport which represent the persistent collection of records.

Type-R is completely unopinionated on the client-server transport protocol and the view layer technology. It's your perfect M and VM in modern MVVM or MVC architecture.

import { define, Record } from 'type-r'

// Define email attribute type with encapsulated validation check.
const Email = String.has.check( x => x! || x.indexOf( '@' ) >= 0, 'Invalid email' );

@define class User extends Record {
    static attributes = {
        name  : String.isRequired, // should not be empty for the record to be valid.
        email : Email.isRequired
    }
}

@define class Message extends Record {
    static attributes = {
        created : Date //  = new Date()
        author  : User, // aggregated User record.
        to      : User.Collection, // aggregating collection of users
        subject : '',
        body    : ''
    }
}

const msg = new Message();
assert( !msg.isValid() ); // Is not valid because msg.author has empty attributes

// Listen for the changes in aggregation tree...
msg.on( 'change', () => console.log( 'change!!!' ) );

msg.transaction( () => { // Prepare to make the sequence of changes on msg
    msg.author.name = 'John Dee'; // No 'change' event yet as we're in the transaction. 
    msg.author.email = '[email protected]'; 

    assert( msg.isValid() ); // Now msg is valid as all of its attributes are valid.
}); // Got single 'change!!!' message in the console.

Installation and requirements

Is packed as UMD and ES6 module. No peer dependencies are required.

npm install type-r --save-dev

IE10+, Edge, Safari, Chrome, and Firefox are supported IE9 and Opera may work but has not been tested. IE8 won't work.

About

Universal state management. Observable, serializable, transactional, and type safe JS objects.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published