git ssb

1+

Matt McKegg / mutant



Tree: 784a83eb521d4e284478ac2ee4160e2e85a617bc

Files: 784a83eb521d4e284478ac2ee4160e2e85a617bc / struct.js

1646 bytesRaw
1var Value = require('./value')
2
3module.exports = Struct
4
5var blackList = {
6 'length': 'Clashes with `Function.prototype.length`.\n',
7 'name': 'Clashes with `Function.prototype.name`\n',
8 'destroy': '`destroy` is a reserved key of struct\n'
9}
10
11function Struct (properties) {
12 var object = Object.create({})
13 var observable = Value(object)
14 var broadcast = observable.set
15 var keys = Object.keys(properties)
16 var suspendBroadcast = false
17
18 var releases = keys.forEach(function (key) {
19 if (blackList.hasOwnProperty(key)) {
20 throw new Error("Cannot create a struct with a key named '" + key + "'.\n" + blackList[key])
21 }
22
23 var obs = typeof properties[key] === 'function'
24 ? properties[key]
25 : Value(properties[key])
26
27 object[key] = obs()
28 observable[key] = obs
29
30 return obs(function (val) {
31 object[key] = val
32 if (!suspendBroadcast) {
33 broadcast(object)
34 }
35 })
36 })
37
38 observable.destroy = function () {
39 while (releases.length) {
40 releases.pop()()
41 }
42 }
43
44 observable.set = function (values) {
45 var lastValue = suspendBroadcast
46 suspendBroadcast = true
47 values = values || {}
48
49 // update inner observables
50 keys.forEach(function (key) {
51 if (observable[key]() !== values[key]) {
52 observable[key].set(values[key])
53 }
54 })
55
56 // store additional keys (but don't create observables)
57 Object.keys(values).forEach(function (key) {
58 if (!(key in properties)) {
59 object[key] = values[key]
60 }
61 })
62
63 suspendBroadcast = lastValue
64 if (!suspendBroadcast) {
65 broadcast(object)
66 }
67 }
68
69 return observable
70}
71

Built with git-ssb-web