forked from ashaffer/models
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
68 lines (53 loc) · 1.33 KB
/
index.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
57
58
59
60
61
62
63
64
65
66
67
68
var Emitter = require('component-emitter');
var isArray = require('isarray');
var clone = require('clone');
function BaseModel(value) {
this.value = value;
this.__isDocument = true;
}
Emitter(BaseModel);
BaseModel.use = function(fn, opts) {
fn = fn || function() {};
if('function' !== typeof fn)
fn = optsPlugin(fn);
if(this.mutable) {
fn.call(this, opts);
return this;
}
var model = createModel();
extend(model, this);
model.prototype = clone(this.prototype);
model.prototype.model = model;
model.mutable = true;
fn.call(model, opts);
model.mutable = false;
return model;
};
function createModel(root) {
function model(value) {
BaseModel.call(this, value);
// Allow event handlers to manipulate what ends up getting
// returned here, so plugins can implement things like
// discriminators
var evt = {doc: this};
this.model.emit('init', evt);
return evt.doc;
}
return model;
}
function optsPlugin(opts) {
return function() {
var model = this;
Object.keys(opts).forEach(function(key) {
model = model[key](opts[key]);
});
};
}
function extend(dest, src) {
Object.keys(src).forEach(function(key) {
// clone is a noop for functions.
// i.e. clone(console.log) === console.log
dest[key] = clone(src[key]);
});
}
module.exports = BaseModel;