Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angulartodoexample #60

Open
wants to merge 80 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
2697a7f
Type-R docs build passes
Jul 21, 2019
40c9b2b
@type-r/models compiles
Jul 21, 2019
e3dfa13
ext-types compiles
Jul 21, 2019
66c3509
globals build passes.
Jul 21, 2019
50dce52
endpoints build passes
Jul 21, 2019
ac3a596
backbone tests pass
Jul 21, 2019
71da62f
Some intermediate fixes
Jul 22, 2019
a4fb363
fixed typo
Jul 22, 2019
933d7d8
Fixed wrong globals
Jul 22, 2019
f3cd112
Fixed tsconfig in tests
Jul 22, 2019
6a7b2ae
All seems to work
Jul 22, 2019
43376d8
Lifted up devDependencies
Jul 22, 2019
0600c8a
Factored out @type-r/mixture package
Jul 22, 2019
e0544af
Added draft for the react bindings
Jul 22, 2019
5d987ee
Added react folder
Jul 22, 2019
3ce08c7
New docs
Jul 22, 2019
31ecc27
mixture docs updated
Jul 22, 2019
ee5c956
front page fixes
Jul 22, 2019
8687547
Updated readme.
Jul 22, 2019
6977929
v4.0.2
Jul 22, 2019
8eabbe5
Added React bindings package
Jul 22, 2019
8fab438
Latest changes
Jul 23, 2019
878ee50
Added example
Jul 23, 2019
7581be0
minor change
Jul 23, 2019
4289588
Links mixin
Jul 23, 2019
83a397a
New links implementation
Jul 23, 2019
77cca98
Moved links to type-r
Jul 23, 2019
d2e1012
Added valueRef tests
Jul 24, 2019
19b35cc
Babel boilerplate works
Jul 24, 2019
0c63d5c
Cosmetic change
Jul 24, 2019
5a61408
checklist example
Jul 24, 2019
2cb8ac2
Pure render optimization
Jul 24, 2019
2641396
checklist fresh build
Jul 24, 2019
14c9045
updated docs
Jul 24, 2019
c5b5885
cosmetics
Jul 24, 2019
22b6330
Updated README
Jul 25, 2019
0082982
Merge branch 'develop' of https://github.com/VoliJS/Type-R into develop
Jul 25, 2019
7f154e5
minor change
Jul 25, 2019
aa52ac3
docs update
Jul 25, 2019
6532971
Update index.jsx
Jul 25, 2019
c1bb95c
updated descriptions
Jul 25, 2019
ad67e5c
Updated docs
Jul 25, 2019
ba5d1a0
updated version of @linked/react
Jul 25, 2019
d0442cc
Merge branch 'develop' of https://github.com/VoliJS/Type-R into develop
Jul 25, 2019
fa19f2b
Merge branch 'develop' of https://github.com/VoliJS/Type-R into develop
Jul 26, 2019
93046b3
Refactored the rest of examples
Jul 26, 2019
fb5c83a
Refactoring, added $includes
Jul 26, 2019
a3086f8
Merge branch 'develop' of https://github.com/VoliJS/Type-R into develop
Jul 26, 2019
c4ec112
Finished refactoring, all examples compiles
Jul 26, 2019
5dd1ad9
readme
Jul 26, 2019
e8df32a
Record -> Model
Jul 26, 2019
a8a7cc0
updated @linked/react
Jul 27, 2019
9617fd9
v4.0.1
Jul 27, 2019
e78f853
userslist example works
Jul 27, 2019
ef1b4bc
assignFrom can take linked values
Jul 27, 2019
f4f6b23
TodoMVC works
Jul 27, 2019
8f1ad2c
Added "loading" to todomvc
Jul 27, 2019
4c38463
New docs structure
Jul 27, 2019
6db7f22
Release notes
Jul 27, 2019
a9c9764
New docs structure
Jul 28, 2019
1f51a13
Remove old docs
Jul 28, 2019
55b30d8
Docs changes
Jul 28, 2019
e1bef6c
Cosmetics
Jul 28, 2019
b6dd3c6
Fixed image links in docs
Jul 28, 2019
3d260ed
Minor change in docs
Jul 28, 2019
7bc6d41
Refactoring the docs
Jul 28, 2019
601b117
Documentation chnages
Jul 28, 2019
8ebf0a7
docs changes
Jul 28, 2019
fa91ea5
Cleanup
Jul 29, 2019
5a589a8
Fix $ TS typings
Jul 29, 2019
007c4e7
nullable attribute types
Aug 8, 2019
d041148
v4.0.2
Aug 8, 2019
a69693c
Docs changes
Aug 9, 2019
1d62128
Merge branch 'develop' of https://github.com/VoliJS/Type-R into develop
Aug 9, 2019
f94b7af
Merge branch 'develop' of https://github.com/VoliJS/Type-R into develop
Aug 13, 2019
2451264
Prevent mock data to appear in production build
Aug 13, 2019
3bbc218
angular example
kkilictepe Aug 27, 2019
7d5259a
readme
kkilictepe Aug 27, 2019
fe0b704
readme update.
kkilictepe Aug 27, 2019
a23a3da
removed log
kkilictepe Aug 27, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ crashlytics.properties
crashlytics-build.properties

# Created by .ignore support plugin (hsz.mobi)
yarn-error.log
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ language: node_js
node_js:
- "node"
install:
- npm install
- npm install -g yarn
- yarn
97 changes: 60 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,95 @@
![master build](https://api.travis-ci.org/Volicon/Type-R.svg?branch=master)
![overview](docs/images/overview.png)

# Getting started
# Type-R Overview

Type-R is the modern JS data framework to manage complex domain and UI application state. Features:
Type-R is a serializable type system for JS and TS. Data structures you describe with Type-R models are automatically and with zero effort:

- _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.
- mapped to JSON and, optionally, REST API;
- protected from improper updates at run-time;
- deeply observable.

![overview](docs/images/overview.png)
## Features

Data layer is defined as a superposition of three kinds of building blocks:
Mapping of complex JS types to JSON (such as Date, classes, objects trees with cross-references) is automatic with Type-R which eliminates a possibility of programmer's error and improves productivity. Less code to write means less things to unit test, less bugs to fix, and less code to read and understand when making changes.

- *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 models safeguard both frontend and backend from errors in JSON. Programmer's mistake on a frontend can't affect the JSON sent to the server. Wrong JSON received from the server will be validated, sanitized, and can't cause catastrophic failures on the frontend. Type-R guarantee that the data structures will retain the declared shape and it immediately reports improper assignments to the console.

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.
There are virtually no point in unit-testing Type-R models as they are mostly declarative definitions. They are able to check the structural integrity themselves, and Type-R can be instructed to throw exceptions instead of console logging. It makes the unit tests of the data layer unnecessary, and greately reduces an effort when writing an integration test.

```javascript
import { define, Record } from 'type-r'
## React integration

Data structures defined with Type-R are deeply observable by default. They can be used to manage the state of React applications right out of box utilizing "unidirectional data flow" with no additional tooling. Type-R data structures support two-way data binding and attribute-level validation rules, making the a complex forms UI a trivial task. Normally, you don't change your UI code to add validation, just add the validation check to model's attributes.

## Example

// Define email attribute type with encapsulated validation check.
const Email = String.has.check( x => x! || x.indexOf( '@' ) >= 0, 'Invalid email' );
The main Type-R building block is the `Model` class with attributes types declaration which behaves as a regular JS class. Models and collections of models can be nested indefinitely to define data structures of arbitrary complexity.

```javascript
import { define, Record, Collection } from '@type-r/models'
import { restfulIO } from '@type-r/endpoints'

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

@define class Message extends Record {
static endpoint = restfulIO( '/api/messages', {
// REST I/O is simulated when the mock data is present, that's how you start.
mockData : [ { id : 0, createdAt : "1999-07-25T03:33:29.687Z", author : {}, to : [] }]
} );

static attributes = {
created : Date // = new Date()
createdAt : Date,
author : User, // aggregated User record.
to : User.Collection, // aggregating collection of users
to : Collection.of( User ), // aggregated collection of users
subject : '',
body : ''
}
}

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

// Listen for the changes in aggregation tree...
msg.on( 'change', () => console.log( 'change!!!' ) );
await messages.fetch({ params : { page : 0 }});

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 = 'dee@void.com';
const msg = messages.first();
msg.author.name = 'Alan Poe';
msg.subject = 'Nevermore';

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

## [Documentation](https://volijs.github.io/Type-R/)
## [API reference and docs](https://volijs.github.io/Type-R/)

## Installation and requirements

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

`npm install type-r --save-dev`

<aside class="success">IE10+, Edge, Safari, Chrome, and Firefox are supported</aside>

<aside class="warning">IE9 and Opera may work but has not been tested. IE8 won't work.</aside>

Install Type-R models and built-in set of I/O endpoints (restfulIO, localStorageIO, and memoryIO):

`npm install @type-r/models @type-r/endpoints`

Install React bindings:

`npm install @type-r/react`

Install extended data types (Email, URL, IP, Integer, Microsoft date, UNIX Timestamp date):

`npm install @type-r/ext-types`

## Repository structure

- `models` - Type-R framework core.
- `endpoints` - Type-R endpoints enabling models and collections I/O API.
- `react` - Type-R React bindings.
- `ext-types` - Extended data types.

- `globals` - `@type-r/globals` providing backward API compatibility for Type-R v2 apps.

- `mixture` - Events, Mixins, and log router. Used by `@type-r/models`.
- `tests` - private package containing all the unit tests.
- `examples/*` - example `@type-r/react` apps.
85 changes: 68 additions & 17 deletions docs/chapters/releasenotes.md → ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,57 @@
# Release Notes

## 3.0.0
## v4.0

### Overview

The major goals of this release is to bring the support for writing React applications with React hooks and TypeScript.

### npm package names changes

Renamed npm packages:

- `type-r` -> `@type-r/models`
- `type-r/ext-types` -> `@type-r/ext-types`
- `type-r/globals` -> `@type-r/globals`

Combined into one package:

- `type-r/endpoints/*` -> `@type-r/endpoints`

### `@type-r/models` (former `type-r`)

The main `type-r` package.

- More accurate TypeScript typings.
- `Linked` class representing an abstract reference to the value; the foundation of two-way data-binding.
- `model.$.attrName` returns linked attribute used for two-way data binding in React.
- `AttributesMixin` - TypeScript interface to inject attribute types into the Model. Attribute decorators are deprecated and will be removed in v5.

### `@type-r/react` (new)

New hooks-based React binding based on `@linked/react`:

- Local component state management with Type-R:
- `useModel( ModelClass )`
- `useCollection.of( ModelClass )`
- `useCollection.ofRefsTo( ModelClass )`
- `useCollection.subsetOf( collection )`
- `pureRenderProps` - declarative pure render wrapper working with `Date`, `Linked`, type-r models and collections.
- `useChanges( modelOrCollection )` - update React component when global model or collection changes.
- `useLinked( value )` - create linked component state.
- `useIO( async () => { ... } )` - perform an I/O with async functions.

### `@type-r/endpoints` (former `type-r/endpoints/*`)

- `modelFetchIO` - read-only endpoint to fetch models.
- `restfulIO` and `modelFetchIO` supports json data mocking. When `mockData` option is present, the HTTP is bypassed and I/O is simulated through the `memoryIO` endpoint. It makes it possible to develop frontend without a test server.
- `restfulIO` and `modelFetchIO` support for templated URLs.

### `@type-r/mixture` (new)

Type-R mixins, events, logging router, and helper functions factored out to the separate package.

## v3.0

### Breaking changes

Expand All @@ -10,8 +61,8 @@ Changed semantic which needs to be refactored:
-|-|-
Typeless attribute | `value(x)` | `type(null).value(x)`
Infer type from the value | `x` (except functions) | `value(x)`, or `x` (except functions)
record.parse() override | `record._parse(json)` | no such a method, remove it
record attributes iteration | `record.forEachAttr(obj, iteratee)` | `record.forEach(iteratee)`
model.parse() override | `model._parse(json)` | no such a method, remove it
model attributes iteration | `model.forEachAttr(obj, iteratee)` | `model.forEach(iteratee)`
Shared object | `User.shared` | `shared( User )`
one-to-many relationship | `RecordClass.from( ref )` | `memberOf( ref )`
many-to-many relationship | `CollectionClass.from( ref )` | `subsetOf( ref, CollectionClass? )`
Expand All @@ -37,7 +88,7 @@ Attribute "Required" check | `Ctor.isRequired` | `type(Ctor).required`

- `Infer<typeof Metatype>` infers TypeScript type from the Type-R attribute metatype.
- `InferAttrs<typeof attributes>` infers TypeScript type for the Type-R attributes definitions.
- `attributes({ attrDefs })` returns the properly typed TypeScript Record class.
- `attributes({ attrDefs })` returns the properly typed TypeScript Model class.

TypeScript attributes definitions:

Expand All @@ -57,26 +108,26 @@ Specify type and default value | `@attr(T.value(default)) name : T` | `@type(T).
- `Type.from( json, options? )` method to restore object from JSON with a strict type check and validation.

```typescript
@define class User extends Record {
@define class User extends Model {
// There's an HTTP REST enpoint for users.
static endpoint = restfulIO( '/api/users' );

@auto name : string

// Collection of Role records represented as an array of role.id in JSON.
// Collection of Role models represented as an array of role.id in JSON.
// When the "roles" attribute will be accessed for the first time,
// User will look-up for a 'roles' attribute of the nearest store to resolve ids to actual Users.
@subsetOf( '~roles' ).as roles : Collection<Role>
}

@define class Role extends Record {
@define class Role extends Model {
static endpoint = restfulIO( '/api/roles' );
@auto name : string
}

// Store is the regular Record, nothing special.
// Store is the regular Model, nothing special.
@define class UsersDirectory extends Store {
// When this record is fetched, fetch all the attributes instead.
// When this model is fetched, fetch all the attributes instead.
static endpoint = attributesIO();

// '~roles' references from all aggregated collections
Expand All @@ -93,28 +144,28 @@ for( let user of directory.users ){
}
```

## 2.1.0
## v2.1

This release adds long-awaited HTTP REST endpoint.

- IO endpoints moved outside of the man sources tree. Creation of the custom endpoints is easier than ever.
- Added HTTP REST endpoint `restfulIO` with relative urls support (https://volicon.github.io/Type-R/#endpoint-restfulio-url-options-).
- Added proxyIO endpoint for creating endpoints from records on the server side (https://volicon.github.io/Type-R/#endpoint-proxyio-recordctor-).
- Added proxyIO endpoint for creating endpoints from models on the server side (https://volicon.github.io/Type-R/#endpoint-proxyio-recordctor-).

## 2.0.0
## v2.0

This release brings new features which fixes problems with component's inheritance in React bindings and implements long-awaited generic IO implementation based on ES6 promises.

There shouldn't be breaking changes _unless_ you're using custom logger or React bindings (formerly known as React-MVx, with a name changed to React-R in new release).

### Generic IO support

New [IOEndpoint]() concept is introduced, making it easy to create IO abstractions. To enable `Record` and `Collection` IO API, you need to assign IO endpoint in the class definition.
New [IOEndpoint]() concept is introduced, making it easy to create IO abstractions. To enable `Model` and `Collection` IO API, you need to assign IO endpoint in the class definition.

Endpoint is the class defining CRUD and list operations on JSON data, as well as the methods to subscribe for the data changes. There are two endpoints included with 2.0 release, `memoryIO` which is suitable for mock testing and `localStorageIO` which could be used in demos and prototypes. They can be used as a references as starting points to define your own IO endpoints.

```javascript
@define class User extends Record {
@define class User extends Model {
static endpoint = memoryIO();
static attributes = {
name : String,
Expand All @@ -123,7 +174,7 @@ Endpoint is the class defining CRUD and list operations on JSON data, as well as
}
```

There are three Record IO methods (`save()`, `fetch()`, and `destroy()`) and two collection IO method (`fetch()` and `liveUpdates()`) ). All IO methods returns ES6 promises, so you either must have the runtime supporting ES6 or use the ES6 promise polyfill. The promises are modified to be _abortable_ (all of them have `abort()` method).
There are three Model IO methods (`save()`, `fetch()`, and `destroy()`) and two collection IO method (`fetch()` and `liveUpdates()`) ). All IO methods returns ES6 promises, so you either must have the runtime supporting ES6 or use the ES6 promise polyfill. The promises are modified to be _abortable_ (all of them have `abort()` method).

```javascript
const user = new User({ name : 'John' });
Expand Down Expand Up @@ -215,7 +266,7 @@ In this example, all of the methods defined in the mixin, base class, and subcla

### Other changes

- Update pipeline was rewritten to improve record's initialization speed (collection's fetch speed is improved by 30%).
- Fixed bug causing dynamic type checks to be disabled in records constructors.
- Update pipeline was rewritten to improve model's initialization speed (collection's fetch speed is improved by 30%).
- Fixed bug causing dynamic type checks to be disabled in models constructors.
- New implementation of the `Collection.subsetOf` which both fixes some edge case bugs and is more efficient.
- New logger handling NODE_ENV variable setting.
2 changes: 0 additions & 2 deletions dist/index.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/index.js.map

This file was deleted.

13 changes: 8 additions & 5 deletions docs/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under
*/
console.info( 'Building Type-R docs...' );

var marked = require('marked')
var fs = require('fs')
Expand Down Expand Up @@ -48,7 +49,7 @@ Handlebars.registerHelper('html', function (content) {
return new Handlebars.SafeString(content)
})

fs.readFile('./docs/index.md', 'utf8', function (err, content) {
fs.readFile('./index.md', 'utf8', function (err, content) {
if (err) console.log(err)

content = content.split(/---/g)
Expand Down Expand Up @@ -92,13 +93,13 @@ fs.readFile('./docs/index.md', 'utf8', function (err, content) {
// create partials
for (var i = 0; i < data.includes.length; i++) {
var includeFileName = data.includes[i]
var includeFilePath = path.resolve(__dirname, './chapters', includeFileName + '.md')
var includeFilePath = path.resolve(__dirname, '..', includeFileName + '.md')
var includeContent = fs.readFileSync(includeFilePath, {encoding: 'utf8'})
var markedInclude = marked(includeContent)
Handlebars.registerPartial(includeFileName, markedInclude)
}
}
fs.readFile('./docs/lib/layouts/layout.html', 'utf8', function (err, source) {
fs.readFile('./lib/layouts/layout.html', 'utf8', function (err, source) {
if (err) console.log(err)

if (data.includes) {
Expand All @@ -113,8 +114,10 @@ fs.readFile('./docs/index.md', 'utf8', function (err, content) {
var template = Handlebars.compile(source)
data['content'] = marked(content.slice(2).join(''))

fs.writeFile('./docs/index.html', template(data), function (err) {
if (err) console.log(err)
fs.writeFile('../index.html', template(data), function (err) {
if (err){
console.log(err);
}
})
})
})
Loading