Skip to content

Commit 740534e

Browse files
author
Vlad Balin
committed
Merge changes
2 parents 7981627 + f16e767 commit 740534e

File tree

179 files changed

+29795
-2689
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+29795
-2689
lines changed

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/chapters/Mixins.md

Lines changed: 184 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,139 @@
1-
# Mixins
1+
# Class definitions and mixins
2+
3+
## Class Definitions
4+
5+
Type-R mechanic is based on class transformations at the moment of module load. These transformations are controlled by _definitions_ in static class members.
6+
7+
### `decorator` @definitions({ propName : `rule`, ... })
8+
9+
Treat specified static class members as _definitions_. When `@define` decorator is being called, definitions are extracted from static class members and mixins and passed as an argument to the `Class.onDefine( definition )`.
10+
11+
Class definitions are intended to use in the abstract base classes and they are inherited by subclasses. You don't need to add any new definitions to existing Type-R classes unless you want to extend the library, which you're welcome to do.
12+
13+
### `rule` mixinRules.value
14+
15+
Merge rule used to mark class definitions. The same rule is also applied to all mixin members if other rule is not specified.
16+
17+
```javascript
18+
@define
19+
@definitions({
20+
urlRoot : mixinRules.value
21+
})
22+
class X {
23+
static urlRoot = '/api';
24+
25+
static onDefine( definition ){
26+
this.prototype.urlRoot = definition.urlRoot;
27+
}
28+
}
29+
```
30+
31+
### `rule` mixinRules.protoValue
32+
33+
Same as `mixinRules.value`, but the value is being assigned to the class prototype.
34+
35+
```javascript
36+
@define
37+
@definitions({
38+
urlRoot : mixinRules.protoValue
39+
})
40+
class X {
41+
static urlRoot = '/api';
42+
}
43+
44+
assert( X.prototype.urlRoot === '/api' );
45+
```
46+
47+
### `rule` mixinRules.merge
48+
49+
Assume the property to be the key-value hash. Properties with the same name from mixins are merged.
50+
51+
```javascript
52+
const M = {
53+
attributes : {
54+
b : 1
55+
}
56+
};
57+
58+
@define
59+
@mixins( M )
60+
@definitions({
61+
attributes : mixinRules.merge
62+
})
63+
class X {
64+
static attributes = {
65+
a : 1
66+
};
67+
68+
onDefine( definitions ){
69+
const { attributes } = definitions;
70+
assert( attributes.a === attributes.b === 1 );
71+
}
72+
}
73+
```
74+
75+
### `decorator` @define
76+
77+
Extract class definitions, call class definition hooks, and apply mixin merge rules to inherited class members.
78+
79+
1. Call static `onExtend( BaseClass )` hook.
80+
2. Extract definitions from static class members and all the mixins applied, and pass them to `onDefine( definitions, BaseClass )` hook.
81+
4. Apply _merge rules_ for overriden class methods.
82+
83+
All Type-R class definitions must be precedeed with the `@define` (or `@predefine`) decorator.
84+
85+
```javascript
86+
@define
87+
@definitions({
88+
attributes : mixinRules.merge
89+
})
90+
class Record {
91+
static onDefine( definitions, BaseClass ){
92+
definitions.attributes && console.log( JSON.stringify( definitions.attributes ) );
93+
}
94+
}
95+
96+
// Will print "{ "a" : 1 }"
97+
@define class A extends Record {
98+
static attributes = {
99+
a : 1
100+
}
101+
}
102+
103+
// Will print "{ "b" : 1 }"
104+
@define class B extends Record {
105+
static attributes = {
106+
b : 1
107+
}
108+
}
109+
```
110+
111+
### `decorator` @define( mixin )
112+
113+
When called with an argument, `@define` decorator applies the given mixin as if it would be the first mixin applied.
114+
In other aspects, it behaves the same as the `@default` decorator without argument.
115+
116+
### `static` Class.onExtend( BaseClass )
117+
118+
Called from the `@predefine` or as the first action of the `@define`. Takes base class constructor as an argument.
119+
120+
### `static` Class.onDefine( definition, BaseClass )
121+
122+
Called from the `@define` or `Class.define()` method. Takes class definition (see the `@definitions` decorator) as the first argument.
123+
124+
### `decorator` @predefine
125+
126+
The sequence of `@predefine` with the following `Class.define()` call is equivalent to `@define` decorator. It should be used in the case if the class definition must reference itself, or multiple definitions contain circular dependency.
127+
128+
It calls static `onExtend( BaseClass )` function if it's defined. It assumes that the `Class.define( definitions )` method will be called later, and attaches `Class.define` method to the class if it was not defined.
129+
130+
### `static` Class.define( definitions? )
131+
132+
Finalized the class definition started with `@predefine` decorator. Has the same effect as the `@define` decorator excepts it assumes that `Class.onExtend()` static function was called already.
133+
134+
## Mixins
2135

3-
Type-R is based on mixins with configurable properties merge rules.
4136

5-
## Definition
6137

7138
### `decorator` @mixins( mixinA, mixinB, ... ) class X ...
8139

@@ -12,49 +143,81 @@ Merge specified mixins to the class definition. Both plain JS object and class c
12143
import { mixins, Events } from 'type-r'
13144
...
14145

146+
@define
15147
@mixins( Events, plainObject, MyClass, ... )
16148
class X {
17149
...
18150
}
19151
```
20152

21-
### `decorator` @mixinRules({ propName : `rule`, ... }) class ...
153+
### `static` Class.mixins
154+
155+
Class member holding the state of the class mixins.
22156

23-
Specified class properties will be merged according to the given rule when both merging properties from
24-
the mixin or the base class. Rules can be extended and overridden in any subclass.
157+
<aside class="warning">
158+
This is an experimental API which may change in future.
159+
</aside>
25160

26-
This allows for automatic chaining of the methods on inheritance.
161+
## Merge rules
162+
163+
### `decorator` @mixinRules({ propName : `rule`, ... })
164+
165+
The `rule` is the reducer function which is applied when there are several values for the particular class members are defined in different mixins or the class, or if the class member is overriden by the subclass.
27166

28167
<aside class="warning">
29168
This is an experimental feature to support React-style mixins. Should be used with an extreme care.
30169
</aside>
31170

32-
## Mixin rules
171+
### `rule` mixinRules.classFirst
172+
173+
Assume the property to be the function. Call functions from mixins in sequence: `f1.apply( this, arguments ); f2.apply( this, arguments );...`
33174

34-
### `rule` propName : 'merge'
175+
### `rule` mixinRules.classLast
176+
Same as sequence, but functions are called in the reverse sequence.
35177

36-
Assume the property to be an object. Merge objects from mixins.
178+
```javascript
179+
@define
180+
@mixinRules({
181+
componentWillMount : mixinRules.classLast
182+
})
183+
class Component {
184+
componentWillMount(){
185+
console.log( 1 );
186+
}
187+
}
37188

38-
### `rule` propName : { name1 : `rule`, ... }
189+
const M = {
190+
componentWillMount(){
191+
console.log( 2 );
192+
}
193+
}
39194

40-
Assume the property to be an object. Recursively define merge rules for its properties.
195+
@define
196+
@mixins( M )
197+
class X extends Component {
198+
componentWillMount(){
199+
console.log( 3 );
200+
}
201+
}
41202

42-
### `rule` propName : 'pipe'
203+
const x = new X();
204+
x.componentWillMount();
205+
// Will print 1, 2, 3
43206

44-
Assume the property to be the function with a signature `( x : T ) => T`. Join functions from mixins in a pipe: `f1( f2( f3( x ) ) )`.
207+
```
45208

46-
### `rule` propName : 'sequence'
209+
### `rule` mixinRules.pipe
47210

48-
Assume the property to be the function. Call functions from mixins in sequence: `f1.apply( this, arguments ); f2.apply( this, arguments );...`
211+
Assume the property to be the function with a signature `( x : T ) => T`. Join functions from mixins in a pipe: `f1( f2( f3( x ) ) )`.
49212

50-
### `rule` propName : 'reverse'
51-
Same as sequence, but functions are called in the reverse sequence.
213+
### `rule` mixinRules.defaults
52214

53-
### `rule` propName : 'mergeSequence'
54215
Assume the property to be the function returning object. Merge objects returned by functions from mixins, executing them in sequence.
55216

56-
### `rule` propName : 'every'
217+
### `rule` mixinRules.every
218+
57219
Assume property to be the function returning boolean. Return `true` if all functions from mixins return truthy values.
58220

59-
### `rule` propName : 'some'
221+
### `rule` mixinRules.some
222+
60223
Same as `every`, but return true when at least one function from mixins returns true.

endpoints/localStorage/index.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

endpoints/localStorage/index.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

endpoints/localStorage/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "localStorageIO",
3+
"main": "./index.js",
4+
"jsnext:main": "../../lib/endpoints/localStorage.js",
5+
"module": "../../lib/endpoints/localStorage.js",
6+
"types": "../../lib/endpoints/localStorage.d.ts",
7+
"scripts": {
8+
},
9+
"author": "Vlad Balin",
10+
"license": "MIT"
11+
}
12+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import resolve from 'rollup-plugin-node-resolve';
2+
import uglify from 'rollup-plugin-uglify';
3+
import sourcemaps from 'rollup-plugin-sourcemaps';
4+
5+
export default {
6+
input : 'lib/endpoints/localStorage.js',
7+
8+
output : {
9+
file : 'endpoints/localStorage/index.js',
10+
format : 'umd',
11+
name : 'localStorageIO'
12+
},
13+
plugins: [
14+
resolve(), //for support of `import X from "directory"` rather than verbose `import X from "directory/index"`
15+
sourcemaps(),
16+
uglify()
17+
],
18+
sourcemap: true,
19+
};

endpoints/memory/index.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)