This repository has been archived by the owner on Feb 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 120
/
declare.js
56 lines (49 loc) · 2.36 KB
/
declare.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
var assert = require('./assert');
var isTypeName = require('./isTypeName');
var isType = require('./isType');
var isNil = require('./isNil');
var mixin = require('./mixin');
var getTypeName = require('./getTypeName');
var isUnion = require('./isUnion');
// All the .declare-d types should be clearly different from each other thus they should have
// different names when a name was not explicitly provided.
var nextDeclareUniqueId = 1;
module.exports = function declare(name) {
if (process.env.NODE_ENV !== 'production') {
assert(isTypeName(name), function () { return 'Invalid argument name ' + name + ' supplied to declare([name]) (expected a string)'; });
}
var type;
function Declare(value, path) {
if (process.env.NODE_ENV !== 'production') {
assert(!isNil(type), function () { return 'Type declared but not defined, don\'t forget to call .define on every declared type'; });
if (isUnion(type)) {
assert(type.dispatch === Declare.dispatch, function () { return 'Please define the custom ' + name + '.dispatch function before calling ' + name + '.define()'; });
}
}
return type(value, path);
}
Declare.define = function (spec) {
if (process.env.NODE_ENV !== 'production') {
assert(isType(spec), function () { return 'Invalid argument type ' + assert.stringify(spec) + ' supplied to define(type) (expected a type)'; });
assert(isNil(type), function () { return 'Declare.define(type) can only be invoked once'; });
assert(isNil(spec.meta.name) && Object.keys(spec.prototype).length === 0, function () { return 'Invalid argument type ' + assert.stringify(spec) + ' supplied to define(type) (expected a fresh, unnamed type)'; });
}
if (isUnion(spec) && Declare.hasOwnProperty('dispatch')) {
spec.dispatch = Declare.dispatch;
}
type = spec;
mixin(Declare, type, true); // true because it overwrites Declare.displayName
if (name) {
type.displayName = Declare.displayName = name;
Declare.meta.name = name;
}
Declare.meta.identity = type.meta.identity;
Declare.prototype = type.prototype;
return Declare;
};
Declare.displayName = name || ( getTypeName(Declare) + "$" + nextDeclareUniqueId++ );
// in general I can't say if this type will be an identity, for safety setting to false
Declare.meta = { identity: false };
Declare.prototype = null;
return Declare;
};