Files: d5d72211c23248c2827327ac4e1b357f755b178b / index.js
3860 bytesRaw
1 | const cbor = require('borc') |
2 | const EventEmitter = require('events') |
3 | const Buffer = require('safe-buffer').Buffer |
4 | |
5 | const TAGS = { |
6 | id: 41, |
7 | link: 42, |
8 | func: 43, |
9 | mod: 44 |
10 | } |
11 | |
12 | /** |
13 | * a cbor decoder for the objects |
14 | * @type {Object} |
15 | */ |
16 | const decoder = new cbor.Decoder({ |
17 | tags: { |
18 | [TAGS.id]: val => new ID(val), |
19 | [TAGS.func]: val => new FunctionRef({ |
20 | identifier: val[0], |
21 | params: val[1], |
22 | actorID: val[2], |
23 | gas: val[3] |
24 | }), |
25 | [TAGS.mod]: val => new ModuleRef(...val), |
26 | [TAGS.link]: val => { |
27 | return { |
28 | '/': val |
29 | } |
30 | } |
31 | } |
32 | }) |
33 | |
34 | /** |
35 | * an ID |
36 | */ |
37 | class ID { |
38 | /* |
39 | * @param {Buffer} id - the id as an buffer |
40 | */ |
41 | constructor (id) { |
42 | this.id = id |
43 | } |
44 | |
45 | toString () { |
46 | return this.id.toString('hex') |
47 | } |
48 | |
49 | encodeCBOR (gen) { |
50 | return gen.write(new cbor.Tagged(TAGS.id, this.id)) |
51 | } |
52 | } |
53 | |
54 | /** |
55 | * A function reference |
56 | */ |
57 | class FunctionRef { |
58 | /** |
59 | * @param {Object} opts |
60 | * @param {*} opts.identifier - the function's identifier |
61 | * @param {ID} opts.actorID - the id of the actor |
62 | * @param {Array} opts.params - the params of the function |
63 | */ |
64 | constructor (opts) { |
65 | this.identifier = opts.identifier |
66 | this.actorID = opts.actorID |
67 | this.params = opts.params |
68 | this.gas = opts.gas || 0 |
69 | } |
70 | |
71 | encodeCBOR (gen) { |
72 | return gen.write(new cbor.Tagged(TAGS.func, [ |
73 | this.identifier, |
74 | this.params, |
75 | this.actorID, |
76 | this.gas |
77 | ])) |
78 | } |
79 | |
80 | /** |
81 | * Creates a copy of the funcRef |
82 | * @returns {FunctionRef} |
83 | */ |
84 | copy () { |
85 | return new FunctionRef({ |
86 | identifier: this.identifier, |
87 | actorID: this.actorID, |
88 | params: this.params, |
89 | gas: this.gas |
90 | }) |
91 | } |
92 | } |
93 | |
94 | /** |
95 | * A module reference |
96 | */ |
97 | class ModuleRef { |
98 | /** |
99 | * @param {Object} exports - a map of exported function to params for the funcion if any |
100 | * @param {ID} id - the id of the actor |
101 | */ |
102 | constructor (exports, id) { |
103 | this.exports = exports |
104 | this.id = id |
105 | } |
106 | |
107 | /** |
108 | * return a function refernce given the name of the function |
109 | * @param {string} name |
110 | * @returns {FunctionRef} |
111 | */ |
112 | getFuncRef (name) { |
113 | const params = this.exports[name] |
114 | |
115 | return new FunctionRef({ |
116 | identifier: [false, name], |
117 | params, |
118 | actorID: this.id |
119 | }) |
120 | } |
121 | |
122 | encodeCBOR (gen) { |
123 | return gen.write(new cbor.Tagged(TAGS.mod, [this.exports, this.id])) |
124 | } |
125 | } |
126 | |
127 | /** |
128 | * This implements Messages for Primea |
129 | */ |
130 | class Message extends EventEmitter { |
131 | /** |
132 | * @param {Object} opts |
133 | * @param {ArrayBuffer} opts.data - the payload of the message |
134 | * @param {Array<Object>} opts.caps - an array of capabilities to send in the message |
135 | */ |
136 | constructor (opts) { |
137 | super() |
138 | const defaults = this.constructor.defaults |
139 | this._opts = Object.assign(defaults, opts) |
140 | Object.keys(this._opts).forEach(key => { |
141 | Object.defineProperty(this, key, { |
142 | get: function () { |
143 | return this._opts[key] |
144 | }, |
145 | set: function (y) { |
146 | this._opts[key] = y |
147 | } |
148 | }) |
149 | }) |
150 | } |
151 | |
152 | static get defaults () { |
153 | return { |
154 | ticks: 0, |
155 | funcRef: null, |
156 | funcArguments: [], |
157 | funcParameters: [], |
158 | _fromId: new ID(Buffer.alloc(20)), |
159 | _fromTicks: 0 |
160 | } |
161 | } |
162 | } |
163 | |
164 | /** |
165 | * returns the type that the object is |
166 | * @param {*} obj |
167 | * @return {String} |
168 | */ |
169 | function getType (obj) { |
170 | if (obj) { |
171 | if (Buffer.isBuffer(obj)) { |
172 | return 'data' |
173 | } else if (Array.isArray(obj)) { |
174 | return 'elem' |
175 | } else if (obj['/']) { |
176 | return 'link' |
177 | } else if (obj.constructor === Message) { |
178 | return 'message' |
179 | } else if (obj.constructor === ID) { |
180 | return 'id' |
181 | } else if (obj.constructor === FunctionRef) { |
182 | return 'func' |
183 | } else if (obj.constructor === ModuleRef) { |
184 | return 'mod' |
185 | } |
186 | } |
187 | return 'invalid' |
188 | } |
189 | |
190 | module.exports = { |
191 | Message, |
192 | ID, |
193 | FunctionRef, |
194 | ModuleRef, |
195 | decoder, |
196 | getType |
197 | } |
198 |
Built with git-ssb-web