You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Type-R mechanic is based on class transformations at the moment of module load. These transformations are controlled by _definitions_ in static class members.
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
+
classX {
23
+
static urlRoot ='/api';
24
+
25
+
staticonDefine( 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
+
classX {
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
+
constM= {
53
+
attributes : {
54
+
b :1
55
+
}
56
+
};
57
+
58
+
@define
59
+
@mixins( M )
60
+
@definitions({
61
+
attributes :mixinRules.merge
62
+
})
63
+
classX {
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.
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
2
135
3
-
Type-R is based on mixins with configurable properties merge rules.
4
136
5
-
## Definition
6
137
7
138
### `decorator`@mixins( mixinA, mixinB, ... ) class X ...
8
139
@@ -12,49 +143,81 @@ Merge specified mixins to the class definition. Both plain JS object and class c
12
143
import { mixins, Events } from'type-r'
13
144
...
14
145
146
+
@define
15
147
@mixins( Events, plainObject, MyClass, ... )
16
148
classX {
17
149
...
18
150
}
19
151
```
20
152
21
-
### `decorator`@mixinRules({ propName : `rule`, ... }) class ...
153
+
### `static` Class.mixins
154
+
155
+
Class member holding the state of the class mixins.
22
156
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
+
<asideclass="warning">
158
+
This is an experimental API which may change in future.
159
+
</aside>
25
160
26
-
This allows for automatic chaining of the methods on inheritance.
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.
27
166
28
167
<asideclass="warning">
29
168
This is an experimental feature to support React-style mixins. Should be used with an extreme care.
30
169
</aside>
31
170
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 );...`
33
174
34
-
### `rule` propName : 'merge'
175
+
### `rule` mixinRules.classLast
176
+
Same as sequence, but functions are called in the reverse sequence.
35
177
36
-
Assume the property to be an object. Merge objects from mixins.
178
+
```javascript
179
+
@define
180
+
@mixinRules({
181
+
componentWillMount :mixinRules.classLast
182
+
})
183
+
classComponent {
184
+
componentWillMount(){
185
+
console.log( 1 );
186
+
}
187
+
}
37
188
38
-
### `rule` propName : { name1 : `rule`, ... }
189
+
constM= {
190
+
componentWillMount(){
191
+
console.log( 2 );
192
+
}
193
+
}
39
194
40
-
Assume the property to be an object. Recursively define merge rules for its properties.
195
+
@define
196
+
@mixins( M )
197
+
classXextendsComponent {
198
+
componentWillMount(){
199
+
console.log( 3 );
200
+
}
201
+
}
41
202
42
-
### `rule` propName : 'pipe'
203
+
constx=newX();
204
+
x.componentWillMount();
205
+
// Will print 1, 2, 3
43
206
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
+
```
45
208
46
-
### `rule`propName : 'sequence'
209
+
### `rule`mixinRules.pipe
47
210
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 ) ) )`.
49
212
50
-
### `rule` propName : 'reverse'
51
-
Same as sequence, but functions are called in the reverse sequence.
213
+
### `rule` mixinRules.defaults
52
214
53
-
### `rule` propName : 'mergeSequence'
54
215
Assume the property to be the function returning object. Merge objects returned by functions from mixins, executing them in sequence.
55
216
56
-
### `rule` propName : 'every'
217
+
### `rule` mixinRules.every
218
+
57
219
Assume property to be the function returning boolean. Return `true` if all functions from mixins return truthy values.
58
220
59
-
### `rule` propName : 'some'
221
+
### `rule` mixinRules.some
222
+
60
223
Same as `every`, but return true when at least one function from mixins returns true.
0 commit comments