statebus 6.1.22 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{client.js → clients.js} +184 -130
- package/extras/tests.js +292 -412
- package/package.json +10 -3
- package/{server.js → servers.js} +285 -333
- package/statebus.js +297 -620
- package/extras/coffee.js +0 -12
- package/extras/dash.coffee +0 -302
- package/extras/diffsync.js +0 -1462
- package/extras/getCaretCoordinates.js +0 -141
- package/extras/react.js +0 -18147
- package/extras/sockjs.js +0 -27
package/{server.js → servers.js}
RENAMED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
var fs = require('fs'),
|
|
2
2
|
util = require('util')
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
try {
|
|
6
|
-
var braidify = require('braidify').http_server
|
|
7
|
-
console.log('Found braidify library. Braid-HTTP enabled!')
|
|
8
|
-
} catch (e) {
|
|
9
|
-
var braidify = undefined
|
|
10
|
-
}
|
|
4
|
+
var braidify = require('braidify').http_server
|
|
11
5
|
|
|
12
6
|
|
|
13
7
|
function default_options (bus) { return {
|
|
@@ -77,7 +71,6 @@ function import_server (bus, options)
|
|
|
77
71
|
bus.express = express()
|
|
78
72
|
bus.http = express.Router()
|
|
79
73
|
bus.install_express(bus.express)
|
|
80
|
-
bus.initialize_braid_http()
|
|
81
74
|
|
|
82
75
|
// use gzip compression if available
|
|
83
76
|
try { bus.http.use(require('compression')())
|
|
@@ -106,24 +99,11 @@ function import_server (bus, options)
|
|
|
106
99
|
bus.sync_files(x.state_path, x.fs_path)
|
|
107
100
|
})
|
|
108
101
|
|
|
109
|
-
// Free the CORS for Braid requests!
|
|
110
|
-
bus.express.use((req, res, next) => {
|
|
111
|
-
// If this requests knows about Braid then we presume the
|
|
112
|
-
// programmer knows that any client might make this cross-origin
|
|
113
|
-
// request.
|
|
114
|
-
if (req.version || req.parents || req.subscribe
|
|
115
|
-
|| req.headers.subscribe
|
|
116
|
-
|| req.method === 'OPTIONS')
|
|
117
|
-
free_the_cors(req, res, next)
|
|
118
|
-
else
|
|
119
|
-
next()
|
|
120
|
-
})
|
|
121
|
-
|
|
122
102
|
// User will put his routes in here
|
|
123
103
|
bus.express.use(bus.http)
|
|
124
104
|
|
|
125
105
|
// Connect bus to the HTTP server
|
|
126
|
-
bus.express.use(bus.
|
|
106
|
+
bus.express.use(bus.http_in)
|
|
127
107
|
|
|
128
108
|
// Serve Client Coffee
|
|
129
109
|
bus.serve_client_coffee()
|
|
@@ -142,18 +122,18 @@ function import_server (bus, options)
|
|
|
142
122
|
// Now handle backup handlers
|
|
143
123
|
if (count === 0) {
|
|
144
124
|
|
|
145
|
-
// A
|
|
125
|
+
// A set to master without a to_set defined should be
|
|
146
126
|
// automatically reflected to all clients.
|
|
147
|
-
if (method === '
|
|
148
|
-
bus.
|
|
127
|
+
if (method === 'to_set') {
|
|
128
|
+
bus.set.fire(arg, t)
|
|
149
129
|
bus.route(arg.key, 'on_set_sync', arg, t)
|
|
150
130
|
count++
|
|
151
131
|
}
|
|
152
132
|
|
|
153
|
-
// A
|
|
133
|
+
// A get to master without a to_get defined should go to
|
|
154
134
|
// the database, if we have one.
|
|
155
|
-
if (method === '
|
|
156
|
-
bus.
|
|
135
|
+
if (method === 'to_get') {
|
|
136
|
+
bus.db_get(key)
|
|
157
137
|
// This basically renders the count useless-- you probably
|
|
158
138
|
// don't want to wrap this route() with another route().
|
|
159
139
|
count++
|
|
@@ -173,28 +153,18 @@ function import_server (bus, options)
|
|
|
173
153
|
}
|
|
174
154
|
},
|
|
175
155
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (bus.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
} else
|
|
182
|
-
bus.to_http_body = (o) => {
|
|
183
|
-
var unwrap = (Object.keys(o).length === 2
|
|
184
|
-
&& '_' in o
|
|
185
|
-
&& typeof o._ === 'string')
|
|
186
|
-
// To do: translate pointers as keys
|
|
187
|
-
return unwrap ? o._ : JSON.stringify(o)
|
|
188
|
-
}
|
|
156
|
+
// Connect HTTP GET and PUT to our Get and Set
|
|
157
|
+
http_in: function (req, res, next) {
|
|
158
|
+
if (bus.honk)
|
|
159
|
+
console.log(req.method, req.url, req.headers.subscribe
|
|
160
|
+
? 'Subscribe: ' + req.headers.subscribe : '')
|
|
189
161
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
162
|
+
// If this requests knows about Braid then we presume the programmer
|
|
163
|
+
// knows that any client might make this cross-origin request.
|
|
164
|
+
if (req.headers.version || req.headers.parents || req.headers.subscribe
|
|
165
|
+
|| req.method === 'OPTIONS')
|
|
166
|
+
free_the_cors(req, res)
|
|
195
167
|
|
|
196
|
-
// Connect HTTP GET and PUT to our Fetch and Save
|
|
197
|
-
http_handlers: function (req, res, next) {
|
|
198
168
|
if (req.method === 'GET') {
|
|
199
169
|
|
|
200
170
|
// Make a temporary client bus
|
|
@@ -206,45 +176,32 @@ function import_server (bus, options)
|
|
|
206
176
|
res.end()
|
|
207
177
|
}
|
|
208
178
|
|
|
209
|
-
braidify
|
|
210
|
-
if (req.subscribe)
|
|
179
|
+
braidify(req, res)
|
|
180
|
+
if (req.subscribe)
|
|
211
181
|
res.startSubscription({ onClose: end_it_all })
|
|
212
|
-
|
|
213
|
-
} else
|
|
182
|
+
else
|
|
214
183
|
res.statusCode = 200
|
|
215
184
|
|
|
216
|
-
// Do the
|
|
217
|
-
cbus.honk = 'statelog'
|
|
185
|
+
// Do the get
|
|
186
|
+
// cbus.honk = 'statelog'
|
|
218
187
|
var key = req.path.substr(1)
|
|
219
|
-
cbus.
|
|
220
|
-
var body =
|
|
188
|
+
cbus.get(key, cb = (o) => {
|
|
189
|
+
var body = to_http_body(o)
|
|
221
190
|
|
|
222
191
|
// If we're braiding, send via subscription
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// Or just return the current version
|
|
230
|
-
else {
|
|
231
|
-
if (body !== undefined)
|
|
232
|
-
res.send(body)
|
|
233
|
-
else {
|
|
234
|
-
res.statusCode = 404
|
|
235
|
-
res.end()
|
|
236
|
-
}
|
|
237
|
-
}
|
|
192
|
+
|
|
193
|
+
// Note: if body === undefined, we need to send the
|
|
194
|
+
// equivalent of a 404. This is missing in braid spec:
|
|
195
|
+
// https://github.com/braid-org/braid-spec/issues/110
|
|
196
|
+
res.sendVersion({body: body || 'null'})
|
|
238
197
|
|
|
239
198
|
// And shut down the connection if there's no subscription
|
|
240
|
-
if (!
|
|
199
|
+
if (!req.subscribe)
|
|
241
200
|
end_it_all()
|
|
242
201
|
})
|
|
243
202
|
}
|
|
244
203
|
|
|
245
204
|
else if (req.method === 'PUT') {
|
|
246
|
-
console.log('Got a put with body', req.body)
|
|
247
|
-
|
|
248
205
|
// Make a temporary client bus
|
|
249
206
|
var cbus = bus.bus_for_http_client(req, res)
|
|
250
207
|
|
|
@@ -266,16 +223,15 @@ function import_server (bus, options)
|
|
|
266
223
|
req.on('data', chunk => {body += chunk.toString()})
|
|
267
224
|
req.on('end', () => {
|
|
268
225
|
try {
|
|
269
|
-
console.log('gonna parse', body)
|
|
270
226
|
var path = req.url.substr(1)
|
|
271
|
-
var obj =
|
|
227
|
+
var obj = from_http_body(path, body)
|
|
272
228
|
} catch (e) {
|
|
273
229
|
console.error('Error: PUT body was not valid json', e)
|
|
274
230
|
res.statusCode = 500
|
|
275
231
|
res.end()
|
|
276
232
|
return
|
|
277
233
|
}
|
|
278
|
-
cbus.
|
|
234
|
+
cbus.set(obj)
|
|
279
235
|
res.statusCode = 200
|
|
280
236
|
res.end()
|
|
281
237
|
})
|
|
@@ -296,7 +252,7 @@ function import_server (bus, options)
|
|
|
296
252
|
// Log in as the client
|
|
297
253
|
cbus.serves_auth({remoteAddress: req.connection.remoteAddress}, bus)
|
|
298
254
|
bus.options.client(cbus)
|
|
299
|
-
cbus.
|
|
255
|
+
cbus.set({key: 'current_user', client: req.client})
|
|
300
256
|
return cbus
|
|
301
257
|
},
|
|
302
258
|
|
|
@@ -346,7 +302,7 @@ function import_server (bus, options)
|
|
|
346
302
|
bus.port = next_port_attempt
|
|
347
303
|
return result
|
|
348
304
|
} catch (e) {
|
|
349
|
-
if (next_port_attempt <
|
|
305
|
+
if (next_port_attempt < 3007) next_port_attempt = 3007
|
|
350
306
|
else next_port_attempt++
|
|
351
307
|
}
|
|
352
308
|
}
|
|
@@ -399,8 +355,8 @@ function import_server (bus, options)
|
|
|
399
355
|
// var client_busses = {} // XXX work in progress
|
|
400
356
|
var log = master.log
|
|
401
357
|
if (client_bus_func) {
|
|
402
|
-
master.
|
|
403
|
-
var connections = master.
|
|
358
|
+
master.set({key: 'connections'}) // Clean out old sessions
|
|
359
|
+
var connections = master.get('connections')
|
|
404
360
|
}
|
|
405
361
|
var s = require('sockjs').createServer({
|
|
406
362
|
sockjs_url: 'https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js',
|
|
@@ -419,7 +375,7 @@ function import_server (bus, options)
|
|
|
419
375
|
|
|
420
376
|
connections[conn.id] = {client: conn.id, // client is deprecated
|
|
421
377
|
id: conn.id}
|
|
422
|
-
master.
|
|
378
|
+
master.set(connections)
|
|
423
379
|
|
|
424
380
|
var client = require('./statebus')()
|
|
425
381
|
client.label = 'client' + client_num++
|
|
@@ -429,15 +385,15 @@ function import_server (bus, options)
|
|
|
429
385
|
} else
|
|
430
386
|
var client = master
|
|
431
387
|
|
|
432
|
-
var
|
|
388
|
+
var our_gets_in = {} // Every key that this socket has got
|
|
433
389
|
log('sockjs_s: New connection from', conn.remoteAddress)
|
|
434
390
|
function sockjs_pubber (obj, t) {
|
|
435
391
|
// log('sockjs_pubber:', obj, t)
|
|
436
|
-
var msg = {
|
|
392
|
+
var msg = {set: obj}
|
|
437
393
|
if (t.version) msg.version = t.version
|
|
438
394
|
if (t.parents) msg.parents = t.parents
|
|
439
395
|
if (t.patch) msg.patch = t.patch
|
|
440
|
-
if (t.patch) msg.
|
|
396
|
+
if (t.patch) msg.set = msg.set.key
|
|
441
397
|
msg = JSON.stringify(msg)
|
|
442
398
|
|
|
443
399
|
if (master.simulate_network_delay) {
|
|
@@ -456,16 +412,16 @@ function import_server (bus, options)
|
|
|
456
412
|
var method = bus.message_method(message)
|
|
457
413
|
|
|
458
414
|
// Validate the message
|
|
459
|
-
if (!((method === '
|
|
460
|
-
&& master.validate(message, {
|
|
415
|
+
if (!((method === 'get'
|
|
416
|
+
&& master.validate(message, {get: 'string',
|
|
461
417
|
'?parent': 'string', '?version': 'string'}))
|
|
462
418
|
||
|
|
463
|
-
(method === '
|
|
464
|
-
&& master.validate(message, {
|
|
419
|
+
(method === 'set'
|
|
420
|
+
&& master.validate(message, {set: '*',
|
|
465
421
|
'?parents': 'array', '?version': 'string', '?patch': 'array'})
|
|
466
|
-
&& (typeof(message.
|
|
467
|
-
|| (typeof(message.
|
|
468
|
-
&& typeof(message.
|
|
422
|
+
&& (typeof(message.set) === 'string'
|
|
423
|
+
|| (typeof(message.set) === 'object'
|
|
424
|
+
&& typeof(message.set.key === 'string'))))
|
|
469
425
|
||
|
|
470
426
|
(method === 'forget'
|
|
471
427
|
&& master.validate(message, {forget: 'string'}))
|
|
@@ -482,55 +438,55 @@ function import_server (bus, options)
|
|
|
482
438
|
}
|
|
483
439
|
|
|
484
440
|
switch (method) {
|
|
485
|
-
case '
|
|
486
|
-
|
|
487
|
-
client.
|
|
441
|
+
case 'get':
|
|
442
|
+
our_gets_in[message.get] = true
|
|
443
|
+
client.get(message.get, sockjs_pubber)
|
|
488
444
|
break
|
|
489
445
|
case 'forget':
|
|
490
|
-
delete
|
|
446
|
+
delete our_gets_in[message.forget]
|
|
491
447
|
client.forget(message.forget, sockjs_pubber)
|
|
492
448
|
break
|
|
493
449
|
case 'delete':
|
|
494
450
|
client.delete(message['delete'])
|
|
495
451
|
break
|
|
496
|
-
case '
|
|
452
|
+
case 'set':
|
|
497
453
|
message.version = message.version || client.new_version()
|
|
498
454
|
if (message.patch) {
|
|
499
|
-
var o = bus.cache[message.
|
|
455
|
+
var o = bus.cache[message.set] || {key: message.set}
|
|
500
456
|
try {
|
|
501
|
-
message.
|
|
457
|
+
message.set = bus.apply_patch(o, message.patch[0])
|
|
502
458
|
} catch (e) {
|
|
503
459
|
console.error('Received bad sockjs message from '
|
|
504
460
|
+ conn.remoteAddress +': ', message, e)
|
|
505
461
|
return
|
|
506
462
|
}
|
|
507
463
|
}
|
|
508
|
-
client.
|
|
464
|
+
client.set(message.set,
|
|
509
465
|
{version: message.version,
|
|
510
466
|
parents: message.parents,
|
|
511
467
|
patch: message.patch})
|
|
512
|
-
if (
|
|
468
|
+
if (our_gets_in[message.set.key]) { // Store what we've seen if we
|
|
513
469
|
// might have to publish it later
|
|
514
|
-
client.log('Adding', message.
|
|
470
|
+
client.log('Adding', message.set.key+'#'+message.version,
|
|
515
471
|
'to pubber!')
|
|
516
|
-
sockjs_pubber.has_seen(client, message.
|
|
472
|
+
sockjs_pubber.has_seen(client, message.set.key, message.version)
|
|
517
473
|
}
|
|
518
474
|
break
|
|
519
475
|
}
|
|
520
476
|
|
|
521
|
-
// validate that our
|
|
522
|
-
for (var key in
|
|
523
|
-
if (!client.
|
|
477
|
+
// validate that our gets_in are all in the bus
|
|
478
|
+
for (var key in our_gets_in)
|
|
479
|
+
if (!client.gets_in.has(key, master.funk_key(sockjs_pubber)))
|
|
524
480
|
console.trace("***\n****\nFound errant key", key,
|
|
525
481
|
'when receiving a sockjs', method, 'of', message)
|
|
526
482
|
//log('sockjs_s: done with message')
|
|
527
483
|
})
|
|
528
484
|
conn.on('close', function() {
|
|
529
485
|
log('sockjs_s: disconnected from', conn.remoteAddress, conn.id, client.id)
|
|
530
|
-
for (var key in
|
|
486
|
+
for (var key in our_gets_in)
|
|
531
487
|
client.forget(key, sockjs_pubber)
|
|
532
488
|
if (client_bus_func) {
|
|
533
|
-
delete connections[conn.id]; master.
|
|
489
|
+
delete connections[conn.id]; master.set(connections)
|
|
534
490
|
master.delete('connection/' + conn.id)
|
|
535
491
|
client.delete_bus()
|
|
536
492
|
}
|
|
@@ -540,15 +496,15 @@ function import_server (bus, options)
|
|
|
540
496
|
if (client_bus_func && !master.options.__secure) {
|
|
541
497
|
|
|
542
498
|
// A connection
|
|
543
|
-
client('connection/*').
|
|
544
|
-
var result = bus.clone(master.
|
|
499
|
+
client('connection/*').to_get = function (key, star) {
|
|
500
|
+
var result = bus.clone(master.get(key))
|
|
545
501
|
if (master.options.connections.include_users && result.user)
|
|
546
|
-
result.user = client.
|
|
502
|
+
result.user = client.get(result.user.key)
|
|
547
503
|
result.id = star
|
|
548
504
|
result.client = star // Deprecated. Delete this line in v7.
|
|
549
505
|
return result
|
|
550
506
|
}
|
|
551
|
-
client('connection/*').
|
|
507
|
+
client('connection/*').to_set = function (o, star, t) {
|
|
552
508
|
// Check permissions before editing
|
|
553
509
|
if (star !== conn.id && !master.options.connections.edit_others) {
|
|
554
510
|
t.abort()
|
|
@@ -556,32 +512,32 @@ function import_server (bus, options)
|
|
|
556
512
|
}
|
|
557
513
|
o.id = star
|
|
558
514
|
o.client = star // Deprecated. Delete this line in v7.
|
|
559
|
-
master.
|
|
515
|
+
master.set(client.clone(o))
|
|
560
516
|
}
|
|
561
517
|
|
|
562
518
|
// Your connection
|
|
563
|
-
client('connection').
|
|
519
|
+
client('connection').to_get = function () {
|
|
564
520
|
// subscribe to changes in authentication
|
|
565
|
-
client.
|
|
521
|
+
client.get('current_user')
|
|
566
522
|
|
|
567
|
-
var result = client.clone(client.
|
|
523
|
+
var result = client.clone(client.get('connection/' + conn.id))
|
|
568
524
|
delete result.key
|
|
569
525
|
return result
|
|
570
526
|
}
|
|
571
|
-
client('connection').
|
|
527
|
+
client('connection').to_set = function (o) {
|
|
572
528
|
o = client.clone(o)
|
|
573
529
|
o.key = 'connection/' + conn.id
|
|
574
|
-
client.
|
|
530
|
+
client.set(o)
|
|
575
531
|
}
|
|
576
532
|
|
|
577
533
|
// All connections
|
|
578
|
-
client('connections').
|
|
579
|
-
client('connections').
|
|
534
|
+
client('connections').to_set = function noop (t) {t.abort()}
|
|
535
|
+
client('connections').to_get = function () {
|
|
580
536
|
var result = []
|
|
581
|
-
var conns = master.
|
|
537
|
+
var conns = master.get('connections')
|
|
582
538
|
for (var connid in conns)
|
|
583
539
|
if (connid !== 'key')
|
|
584
|
-
result.push(client.
|
|
540
|
+
result.push(client.get('connection/' + connid))
|
|
585
541
|
|
|
586
542
|
return {all: result}
|
|
587
543
|
}
|
|
@@ -607,14 +563,6 @@ function import_server (bus, options)
|
|
|
607
563
|
+ Math.random().toString(36).substring(2))}
|
|
608
564
|
},
|
|
609
565
|
|
|
610
|
-
// Deprecated
|
|
611
|
-
ws_client: function (prefix, url, account) {
|
|
612
|
-
console.error('ws_client() is deprecated; use net_mount() instead')
|
|
613
|
-
bus.net_mount(prefix, url, account) },
|
|
614
|
-
// Deprecated
|
|
615
|
-
universal_ws_client: function () {
|
|
616
|
-
console.error('calling universal_ws_client is deprecated and no longer necessary') },
|
|
617
|
-
|
|
618
566
|
file_store: (function () {
|
|
619
567
|
// Make a database
|
|
620
568
|
var fs = require('fs')
|
|
@@ -633,9 +581,9 @@ function import_server (bus, options)
|
|
|
633
581
|
(fs.writeFileSync(filename, '{}'), bus.log('Made a new db file'))
|
|
634
582
|
db = JSON.parse(fs.readFileSync(filename))
|
|
635
583
|
db_is_ok = true
|
|
636
|
-
// If we
|
|
584
|
+
// If we set before anything else is connected, we'll get this
|
|
637
585
|
// into the cache but not affect anything else
|
|
638
|
-
bus.
|
|
586
|
+
bus.set.fire(global.pointerify ? inline_pointers(db) : db)
|
|
639
587
|
bus.log('Read db')
|
|
640
588
|
} catch (e) {
|
|
641
589
|
console.error(e)
|
|
@@ -646,7 +594,7 @@ function import_server (bus, options)
|
|
|
646
594
|
function save_db() {
|
|
647
595
|
if (!db_is_ok) return
|
|
648
596
|
|
|
649
|
-
console.time('saved db')
|
|
597
|
+
// console.time('saved db')
|
|
650
598
|
|
|
651
599
|
fs.writeFile(filename+'.tmp', JSON.stringify(db, null, 1), function(err) {
|
|
652
600
|
if (err) {
|
|
@@ -658,7 +606,7 @@ function import_server (bus, options)
|
|
|
658
606
|
console.error('Crap !! DB IS DYING !!!!', err)
|
|
659
607
|
db_is_ok = false
|
|
660
608
|
} else {
|
|
661
|
-
console.timeEnd('saved db')
|
|
609
|
+
// console.timeEnd('saved db')
|
|
662
610
|
pending_save = null
|
|
663
611
|
}
|
|
664
612
|
})
|
|
@@ -689,12 +637,12 @@ function import_server (bus, options)
|
|
|
689
637
|
else return o
|
|
690
638
|
})
|
|
691
639
|
}
|
|
692
|
-
function
|
|
640
|
+
function on_set (obj) {
|
|
693
641
|
db[obj.key] = global.pointerify ? abstract_pointers(obj) : obj
|
|
694
642
|
if (active) save_later()
|
|
695
643
|
}
|
|
696
|
-
|
|
697
|
-
bus(prefix).
|
|
644
|
+
on_set.priority = true
|
|
645
|
+
bus(prefix).on_set = on_set
|
|
698
646
|
bus(prefix).to_delete = function (key) {
|
|
699
647
|
delete db[key]
|
|
700
648
|
if (active) save_later()
|
|
@@ -761,17 +709,17 @@ function import_server (bus, options)
|
|
|
761
709
|
return decodeURIComponent(k.replace('%2E', '.'))
|
|
762
710
|
}
|
|
763
711
|
|
|
764
|
-
bus(prefix).
|
|
712
|
+
bus(prefix).to_get = function (key, t) {
|
|
765
713
|
firebase_ref.child(encode_firebase_key(key)).on('value', function (x) {
|
|
766
714
|
t.done(x.val() || {})
|
|
767
715
|
}, function (err) { t.abort() })
|
|
768
716
|
}
|
|
769
717
|
|
|
770
|
-
bus(prefix).
|
|
718
|
+
bus(prefix).on_set = function (o) {
|
|
771
719
|
firebase_ref.child(encode_firebase_key(o.key)).set(o)
|
|
772
720
|
}
|
|
773
721
|
|
|
774
|
-
// bus(prefix).
|
|
722
|
+
// bus(prefix).to_set = function (o, t) {
|
|
775
723
|
// firebase_ref.child(encode_firebase_key(o.key)).set(o, (err) => {
|
|
776
724
|
// err ? t.abort() : t.done()
|
|
777
725
|
// })
|
|
@@ -788,7 +736,7 @@ function import_server (bus, options)
|
|
|
788
736
|
}
|
|
789
737
|
},
|
|
790
738
|
|
|
791
|
-
|
|
739
|
+
db_get: function db_get (key) {/* does nothing unless overridden */},
|
|
792
740
|
lazy_sqlite_store: function lazy_sqlite_store (opts) {
|
|
793
741
|
if (!opts) opts = {}
|
|
794
742
|
opts.lazy = true
|
|
@@ -840,7 +788,7 @@ function import_server (bus, options)
|
|
|
840
788
|
if (options.dont_fire)
|
|
841
789
|
bus.cache[key] = temp_db[key]
|
|
842
790
|
else
|
|
843
|
-
bus.
|
|
791
|
+
bus.set.fire(temp_db[key])
|
|
844
792
|
temp_db[key] = undefined
|
|
845
793
|
}
|
|
846
794
|
}
|
|
@@ -858,10 +806,10 @@ function import_server (bus, options)
|
|
|
858
806
|
return x ? JSON.parse(x.obj) : {}
|
|
859
807
|
}
|
|
860
808
|
if (opts.lazy) {
|
|
861
|
-
var
|
|
862
|
-
bus.
|
|
863
|
-
if (
|
|
864
|
-
|
|
809
|
+
var db_getted_keys = {}
|
|
810
|
+
bus.db_get = bus.reactive(function (key) {
|
|
811
|
+
if (db_getted_keys[key]) return
|
|
812
|
+
db_getted_keys[key] = true
|
|
865
813
|
|
|
866
814
|
// Get it from the database
|
|
867
815
|
var obj = sqlite_get(key)
|
|
@@ -875,12 +823,12 @@ function import_server (bus, options)
|
|
|
875
823
|
: o))
|
|
876
824
|
|
|
877
825
|
// Publish this to the bus
|
|
878
|
-
bus.
|
|
826
|
+
bus.set.fire(obj, {to_get: true})
|
|
879
827
|
})
|
|
880
828
|
}
|
|
881
829
|
|
|
882
|
-
// Add
|
|
883
|
-
function
|
|
830
|
+
// Add set handlers
|
|
831
|
+
function on_set (obj) {
|
|
884
832
|
if (opts.inline_pointers)
|
|
885
833
|
obj = abstract_pointers(obj)
|
|
886
834
|
|
|
@@ -901,14 +849,14 @@ function import_server (bus, options)
|
|
|
901
849
|
})
|
|
902
850
|
}
|
|
903
851
|
}
|
|
904
|
-
if (opts.
|
|
852
|
+
if (opts.set_sync) {
|
|
905
853
|
var old_route = bus.route
|
|
906
854
|
bus.route = function (key, method, arg, t) {
|
|
907
|
-
if (method === '
|
|
855
|
+
if (method === 'to_set') on_set(arg)
|
|
908
856
|
return old_route(key, method, arg, t)
|
|
909
857
|
}
|
|
910
858
|
} else
|
|
911
|
-
bus(prefix).on_set_sync =
|
|
859
|
+
bus(prefix).on_set_sync = on_set
|
|
912
860
|
|
|
913
861
|
bus(prefix).to_delete = function (key) {
|
|
914
862
|
if (opts.use_transactions && !open_transaction){
|
|
@@ -985,12 +933,12 @@ function import_server (bus, options)
|
|
|
985
933
|
try {
|
|
986
934
|
var db = new require('pg-native')()
|
|
987
935
|
bus.pg_db = db
|
|
988
|
-
bus.
|
|
936
|
+
bus.pg_set = pg_set
|
|
989
937
|
db.connectSync(opts.url)
|
|
990
938
|
db.querySync('create table if not exists store (key text primary key, value jsonb)')
|
|
991
939
|
|
|
992
940
|
var rows = db.querySync('select * from store')
|
|
993
|
-
rows.forEach(r => bus.
|
|
941
|
+
rows.forEach(r => bus.set(inline_pointers(r.value, bus)))
|
|
994
942
|
|
|
995
943
|
bus.log('Read ' + opts.url)
|
|
996
944
|
} catch (e) {
|
|
@@ -998,16 +946,16 @@ function import_server (bus, options)
|
|
|
998
946
|
console.error('Bad pg db')
|
|
999
947
|
}
|
|
1000
948
|
|
|
1001
|
-
// Add
|
|
1002
|
-
function
|
|
949
|
+
// Add set handlers
|
|
950
|
+
function pg_set (obj) {
|
|
1003
951
|
obj = abstract_pointers(obj)
|
|
1004
952
|
|
|
1005
953
|
db.querySync('insert into store (key, value) values ($1, $2) '
|
|
1006
954
|
+ 'on conflict (key) do update set value = $2',
|
|
1007
955
|
[obj.key, JSON.stringify(obj)])
|
|
1008
956
|
}
|
|
1009
|
-
|
|
1010
|
-
bus(opts.prefix).
|
|
957
|
+
pg_set.priority = true
|
|
958
|
+
bus(opts.prefix).on_set = pg_set
|
|
1011
959
|
bus(opts.prefix).to_delete = function (key) {
|
|
1012
960
|
db.query('delete from store where key = $1', [key])
|
|
1013
961
|
}
|
|
@@ -1068,8 +1016,8 @@ function import_server (bus, options)
|
|
|
1068
1016
|
bus.usage_log_nots = nots
|
|
1069
1017
|
|
|
1070
1018
|
// Aggregate all accesses by day, to get daily active users
|
|
1071
|
-
bus('usage').
|
|
1072
|
-
bus.
|
|
1019
|
+
bus('usage').to_get = () => {
|
|
1020
|
+
bus.get('time/' + refresh_interval)
|
|
1073
1021
|
var days = []
|
|
1074
1022
|
var last_day
|
|
1075
1023
|
for (var row of db.prepare('select * from usage where '
|
|
@@ -1107,8 +1055,8 @@ function import_server (bus, options)
|
|
|
1107
1055
|
return {_: days}
|
|
1108
1056
|
}
|
|
1109
1057
|
|
|
1110
|
-
bus('recent_hits/*').
|
|
1111
|
-
bus.
|
|
1058
|
+
bus('recent_hits/*').to_get = (rest) => {
|
|
1059
|
+
bus.get('time/' + refresh_interval)
|
|
1112
1060
|
var result = []
|
|
1113
1061
|
for (var row of db.prepare('select * from usage where '
|
|
1114
1062
|
+ nots + ' order by date desc limit ?').iterate(
|
|
@@ -1123,8 +1071,8 @@ function import_server (bus, options)
|
|
|
1123
1071
|
return {_: result}
|
|
1124
1072
|
}
|
|
1125
1073
|
|
|
1126
|
-
bus('recent_referers/*').
|
|
1127
|
-
bus.
|
|
1074
|
+
bus('recent_referers/*').to_get = (rest) => {
|
|
1075
|
+
bus.get('time/' + refresh_interval)
|
|
1128
1076
|
var result = []
|
|
1129
1077
|
for (var row of db.prepare('select * from usage where '
|
|
1130
1078
|
+ nots + ' order by date desc limit ?').iterate(
|
|
@@ -1172,7 +1120,7 @@ function import_server (bus, options)
|
|
|
1172
1120
|
return times
|
|
1173
1121
|
}
|
|
1174
1122
|
|
|
1175
|
-
bus('socket_load_times').
|
|
1123
|
+
bus('socket_load_times').to_get = () => {
|
|
1176
1124
|
return {_: sock_open_times()}
|
|
1177
1125
|
}
|
|
1178
1126
|
},
|
|
@@ -1183,26 +1131,26 @@ function import_server (bus, options)
|
|
|
1183
1131
|
JSON.stringify(details)])
|
|
1184
1132
|
},
|
|
1185
1133
|
|
|
1186
|
-
|
|
1187
|
-
if (bus('time*').
|
|
1134
|
+
time () {
|
|
1135
|
+
if (bus('time*').to_get.length > 0)
|
|
1188
1136
|
// Then it's already installed
|
|
1189
1137
|
return
|
|
1190
1138
|
|
|
1191
1139
|
// Time ticker
|
|
1192
1140
|
var timeouts = {}
|
|
1193
|
-
bus('time*'
|
|
1194
|
-
|
|
1141
|
+
bus('time*', {
|
|
1142
|
+
to_get: (key, rest, t) => {
|
|
1195
1143
|
if (key === 'time') rest = '/1000'
|
|
1196
1144
|
timeout = parseInt(rest.substr(1))
|
|
1197
|
-
function f () { bus.
|
|
1145
|
+
function f () { bus.set.fire({key: key, val: Date.now()}) }
|
|
1198
1146
|
timeouts[key] = setInterval(f, timeout)
|
|
1199
1147
|
f()
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
function (key, rest) {
|
|
1148
|
+
},
|
|
1149
|
+
to_forget: (key, rest) => {
|
|
1203
1150
|
if (key === 'time') key = 'time/1000'
|
|
1204
1151
|
clearTimeout(timeouts[key])
|
|
1205
1152
|
}
|
|
1153
|
+
})
|
|
1206
1154
|
},
|
|
1207
1155
|
|
|
1208
1156
|
smtp (opts) {
|
|
@@ -1252,7 +1200,7 @@ function import_server (bus, options)
|
|
|
1252
1200
|
}
|
|
1253
1201
|
}
|
|
1254
1202
|
|
|
1255
|
-
bus.
|
|
1203
|
+
bus.set(email)
|
|
1256
1204
|
})
|
|
1257
1205
|
}
|
|
1258
1206
|
},
|
|
@@ -1269,8 +1217,8 @@ function import_server (bus, options)
|
|
|
1269
1217
|
// - Is there security hole if users have a ? or a / in their name?
|
|
1270
1218
|
// - Make the master.posts/ state not require /
|
|
1271
1219
|
// - Make standard url tools for optional slashes, and ? query params
|
|
1272
|
-
// - Should a e.g. client
|
|
1273
|
-
// - e.g. if master('posts*').
|
|
1220
|
+
// - Should a e.g. client to_set abort if it calls set that aborts?
|
|
1221
|
+
// - e.g. if master('posts*').to_set aborts
|
|
1274
1222
|
|
|
1275
1223
|
// Helpers
|
|
1276
1224
|
function get_posts (args) {
|
|
@@ -1325,15 +1273,15 @@ function import_server (bus, options)
|
|
|
1325
1273
|
// }
|
|
1326
1274
|
|
|
1327
1275
|
// Define state on master
|
|
1328
|
-
if (master('posts_for/*').
|
|
1276
|
+
if (master('posts_for/*').to_get.length === 0) {
|
|
1329
1277
|
// Get posts for each user
|
|
1330
|
-
master('posts_for/*').
|
|
1278
|
+
master('posts_for/*').to_get = (json) => {
|
|
1331
1279
|
watch_for_dirt('posts-for/' + json.for)
|
|
1332
1280
|
return {_: get_posts(json)}
|
|
1333
1281
|
}
|
|
1334
1282
|
// Saving any post will dirty the list for all users mentioned in
|
|
1335
1283
|
// the post
|
|
1336
|
-
master('post/*').
|
|
1284
|
+
master('post/*').to_set = (old, New, t) => {
|
|
1337
1285
|
// To do: diff the cc, to, and from lists, and only dirty
|
|
1338
1286
|
// posts_for people who have been changed
|
|
1339
1287
|
|
|
@@ -1362,38 +1310,38 @@ function import_server (bus, options)
|
|
|
1362
1310
|
return u.name + '@' + opts.domain
|
|
1363
1311
|
}
|
|
1364
1312
|
function current_addy () {
|
|
1365
|
-
var c = client.
|
|
1313
|
+
var c = client.get('current_user')
|
|
1366
1314
|
return c.logged_in ? user_addy(c.user) : 'public'
|
|
1367
1315
|
}
|
|
1368
1316
|
function is_author (post) {
|
|
1369
1317
|
var from = post._.from
|
|
1370
|
-
var c = client.
|
|
1318
|
+
var c = client.get('current_user')
|
|
1371
1319
|
return from.includes(current_addy())
|
|
1372
1320
|
}
|
|
1373
1321
|
function can_see (post) {
|
|
1374
|
-
var c = client.
|
|
1322
|
+
var c = client.get('current_user')
|
|
1375
1323
|
var allowed = post._.to.concat(post._.cc).concat(post._.from)
|
|
1376
1324
|
return allowed.includes(current_addy()) || allowed.includes('public')
|
|
1377
1325
|
}
|
|
1378
1326
|
var drtbus = master//require('./statebus')()
|
|
1379
|
-
function dirty (key) { drtbus.
|
|
1380
|
-
function watch_for_dirt (key) { drtbus.
|
|
1327
|
+
function dirty (key) { drtbus.set({key: 'dirty-'+key, n: Math.random()}) }
|
|
1328
|
+
function watch_for_dirt (key) { drtbus.get('dirty-'+key) }
|
|
1381
1329
|
|
|
1382
|
-
client('current_email').
|
|
1330
|
+
client('current_email').to_get = () => {
|
|
1383
1331
|
return {_: current_addy()}
|
|
1384
1332
|
}
|
|
1385
1333
|
|
|
1386
1334
|
// Define state on client
|
|
1387
|
-
client('posts*').
|
|
1335
|
+
client('posts*').to_get = (k, rest) => {
|
|
1388
1336
|
var args = bus.parse(rest.substr(1))
|
|
1389
|
-
var c = client.
|
|
1337
|
+
var c = client.get('current_user')
|
|
1390
1338
|
args.for = current_addy()
|
|
1391
|
-
var e = master.
|
|
1392
|
-
return {_: master.clone(e._).map(x=>client.
|
|
1339
|
+
var e = master.get('posts_for/' + JSON.stringify(args))
|
|
1340
|
+
return {_: master.clone(e._).map(x=>client.get(x.key))}
|
|
1393
1341
|
}
|
|
1394
1342
|
|
|
1395
|
-
client('post/*').
|
|
1396
|
-
var e = master.clone(master.
|
|
1343
|
+
client('post/*').to_get = (k) => {
|
|
1344
|
+
var e = master.clone(master.get(k))
|
|
1397
1345
|
if (!e._) return {}
|
|
1398
1346
|
if (!can_see(e))
|
|
1399
1347
|
return {}
|
|
@@ -1404,7 +1352,7 @@ function import_server (bus, options)
|
|
|
1404
1352
|
return e
|
|
1405
1353
|
}
|
|
1406
1354
|
|
|
1407
|
-
client('post/*').
|
|
1355
|
+
client('post/*').to_set = (o, t) => {
|
|
1408
1356
|
if (!(client.validate(o, {key: 'string',
|
|
1409
1357
|
_: {to: 'array',
|
|
1410
1358
|
cc: 'array',
|
|
@@ -1422,7 +1370,7 @@ function import_server (bus, options)
|
|
|
1422
1370
|
return
|
|
1423
1371
|
}
|
|
1424
1372
|
|
|
1425
|
-
var c = client.
|
|
1373
|
+
var c = client.get('current_user')
|
|
1426
1374
|
|
|
1427
1375
|
// Make sure this user is an author
|
|
1428
1376
|
var from = o._.from
|
|
@@ -1435,7 +1383,7 @@ function import_server (bus, options)
|
|
|
1435
1383
|
o = client.clone(o)
|
|
1436
1384
|
delete o.children
|
|
1437
1385
|
|
|
1438
|
-
master.
|
|
1386
|
+
master.set(o)
|
|
1439
1387
|
t.done()
|
|
1440
1388
|
}
|
|
1441
1389
|
|
|
@@ -1463,21 +1411,21 @@ function import_server (bus, options)
|
|
|
1463
1411
|
t.done()
|
|
1464
1412
|
}
|
|
1465
1413
|
|
|
1466
|
-
client('friends').
|
|
1467
|
-
return {_: (master.
|
|
1468
|
-
.map(u=>client.
|
|
1469
|
-
.concat([client.
|
|
1414
|
+
client('friends').to_get = t => {
|
|
1415
|
+
return {_: (master.get('users').all||[])
|
|
1416
|
+
.map(u=>client.get('email/' + user_addy(u)))
|
|
1417
|
+
.concat([client.get('email/public')])
|
|
1470
1418
|
}
|
|
1471
1419
|
}
|
|
1472
1420
|
|
|
1473
|
-
client('email/*').
|
|
1421
|
+
client('email/*').to_get = (rest) => {
|
|
1474
1422
|
var m = rest.match(email_regex)
|
|
1475
1423
|
var result = {address: rest}
|
|
1476
1424
|
if (rest === 'public') {
|
|
1477
1425
|
result.name = 'public'
|
|
1478
1426
|
}
|
|
1479
1427
|
else if (m && m[5].toLowerCase() === opts.domain) {
|
|
1480
|
-
result.user = client.
|
|
1428
|
+
result.user = client.get('user/' + m[1])
|
|
1481
1429
|
result.name = result.user.name
|
|
1482
1430
|
result.pic = result.user.pic
|
|
1483
1431
|
result.upgraded = true
|
|
@@ -1492,14 +1440,14 @@ function import_server (bus, options)
|
|
|
1492
1440
|
},
|
|
1493
1441
|
|
|
1494
1442
|
sqlite_query_server: function sqlite_query_server (db) {
|
|
1495
|
-
var
|
|
1496
|
-
bus('table_columns/*').
|
|
1497
|
-
function
|
|
1443
|
+
var get = bus.get
|
|
1444
|
+
bus('table_columns/*').to_get =
|
|
1445
|
+
function get_table_columns (key, rest) {
|
|
1498
1446
|
if (typeof key !== 'string')
|
|
1499
1447
|
console.log(handlers.hash)
|
|
1500
1448
|
var table_name = rest
|
|
1501
|
-
var columns =
|
|
1502
|
-
var foreign_keys =
|
|
1449
|
+
var columns = get('sql/PRAGMA table_info(' + table_name + ')').rows.slice()
|
|
1450
|
+
var foreign_keys = get('table_foreign_keys/' + table_name)
|
|
1503
1451
|
var column_info = {}
|
|
1504
1452
|
for (var i=0;i< columns .length;i++) {
|
|
1505
1453
|
var col = columns[i].name
|
|
@@ -1516,10 +1464,10 @@ function import_server (bus, options)
|
|
|
1516
1464
|
}
|
|
1517
1465
|
|
|
1518
1466
|
|
|
1519
|
-
bus('table_foreign_keys/*').
|
|
1467
|
+
bus('table_foreign_keys/*').to_get =
|
|
1520
1468
|
function table_foreign_keys (key, rest) {
|
|
1521
1469
|
var table_name = rest
|
|
1522
|
-
var foreign_keys =
|
|
1470
|
+
var foreign_keys = get('sql/PRAGMA foreign_key_list(' + table_name + ')').rows
|
|
1523
1471
|
var result = {}
|
|
1524
1472
|
for (var i=0;i< foreign_keys .length;i++)
|
|
1525
1473
|
result[foreign_keys[i].from] = foreign_keys[i]
|
|
@@ -1528,26 +1476,26 @@ function import_server (bus, options)
|
|
|
1528
1476
|
return result
|
|
1529
1477
|
}
|
|
1530
1478
|
|
|
1531
|
-
bus('sql/*').
|
|
1479
|
+
bus('sql/*').to_get =
|
|
1532
1480
|
function sql (key, rest) {
|
|
1533
|
-
|
|
1481
|
+
get('time/60000')
|
|
1534
1482
|
var query = rest
|
|
1535
1483
|
try { query = JSON.parse(query) }
|
|
1536
1484
|
catch (e) { query = {stmt: query, args: []} }
|
|
1537
1485
|
|
|
1538
1486
|
db.all(query.stmt, query.args,
|
|
1539
1487
|
function (err, rows) {
|
|
1540
|
-
if (rows) bus.
|
|
1488
|
+
if (rows) bus.set.fire({key:key, rows: rows})
|
|
1541
1489
|
else console.error('Bad sqlite query', key, err)
|
|
1542
1490
|
}.bind(this))
|
|
1543
1491
|
}
|
|
1544
1492
|
},
|
|
1545
1493
|
|
|
1546
1494
|
sqlite_table_server: function sqlite_table_server(db, table_name) {
|
|
1547
|
-
var
|
|
1548
|
-
var table_columns =
|
|
1549
|
-
var foreign_keys =
|
|
1550
|
-
var remapped_keys =
|
|
1495
|
+
var set = bus.set, get = bus.get
|
|
1496
|
+
var table_columns = get('table_columns/'+table_name) // This will fail if used too soon
|
|
1497
|
+
var foreign_keys = get('table_foreign_keys/'+table_name)
|
|
1498
|
+
var remapped_keys = get('remapped_keys')
|
|
1551
1499
|
remapped_keys.keys = remapped_keys.keys || {}
|
|
1552
1500
|
remapped_keys.revs = remapped_keys.revs || {}
|
|
1553
1501
|
function row_json (row) {
|
|
@@ -1588,15 +1536,15 @@ function import_server (bus, options)
|
|
|
1588
1536
|
if (err) console.error('Problem with table!', table_name, err)
|
|
1589
1537
|
for (var i=0; i<rows.length; i++)
|
|
1590
1538
|
result[i] = row_json(rows[i])
|
|
1591
|
-
bus.
|
|
1539
|
+
bus.set.fire({key: table_name, rows: result})
|
|
1592
1540
|
})
|
|
1593
1541
|
}
|
|
1594
1542
|
function render_row(obj) {
|
|
1595
|
-
bus.
|
|
1543
|
+
bus.set.fire(row_json(obj))
|
|
1596
1544
|
if (remapped_keys.revs[obj.key]) {
|
|
1597
1545
|
var alias = bus.clone(obj)
|
|
1598
1546
|
alias.key = remapped_keys.revs[obj.key]
|
|
1599
|
-
bus.
|
|
1547
|
+
bus.set.fire(row_json(alias))
|
|
1600
1548
|
}
|
|
1601
1549
|
}
|
|
1602
1550
|
|
|
@@ -1604,8 +1552,8 @@ function import_server (bus, options)
|
|
|
1604
1552
|
// Handlers!
|
|
1605
1553
|
// ************************
|
|
1606
1554
|
|
|
1607
|
-
//
|
|
1608
|
-
bus(table_name + '*').
|
|
1555
|
+
// Getting the whole table, or a single row
|
|
1556
|
+
bus(table_name + '*').to_get = function (key, rest) {
|
|
1609
1557
|
if (rest === '')
|
|
1610
1558
|
// Return the whole table
|
|
1611
1559
|
return render_table()
|
|
@@ -1625,7 +1573,7 @@ function import_server (bus, options)
|
|
|
1625
1573
|
}
|
|
1626
1574
|
|
|
1627
1575
|
// Saving a row
|
|
1628
|
-
bus(table_name + '/*').
|
|
1576
|
+
bus(table_name + '/*').to_set = function (obj, rest) {
|
|
1629
1577
|
var columns = table_columns.columns
|
|
1630
1578
|
var key = remapped_keys.keys[obj.key] || obj.key
|
|
1631
1579
|
|
|
@@ -1651,7 +1599,7 @@ function import_server (bus, options)
|
|
|
1651
1599
|
}
|
|
1652
1600
|
|
|
1653
1601
|
// Inserting a new row
|
|
1654
|
-
bus('new/' + table_name + '/*').
|
|
1602
|
+
bus('new/' + table_name + '/*').to_set = function (obj) {
|
|
1655
1603
|
var columns = table_columns.columns
|
|
1656
1604
|
var stmt = ('insert into ' + table_name + ' (' + columns.join(',')
|
|
1657
1605
|
+ ') values (' + new Array(columns.length).join('?,') + '?)')
|
|
@@ -1664,7 +1612,7 @@ function import_server (bus, options)
|
|
|
1664
1612
|
console.log('insert complete, got id', this.lastID)
|
|
1665
1613
|
remapped_keys.keys[obj.key] = table_name + '/' + this.lastID
|
|
1666
1614
|
remapped_keys.revs[remapped_keys.keys[obj.key]] = obj.key
|
|
1667
|
-
|
|
1615
|
+
bus.set(remapped_keys)
|
|
1668
1616
|
render_table()
|
|
1669
1617
|
})
|
|
1670
1618
|
}
|
|
@@ -1694,29 +1642,29 @@ function import_server (bus, options)
|
|
|
1694
1642
|
var client = this // to keep me straight while programming
|
|
1695
1643
|
|
|
1696
1644
|
function logout (key) {
|
|
1697
|
-
var clients = master.
|
|
1645
|
+
var clients = master.get('logged_in_clients')
|
|
1698
1646
|
for (var k in clients)
|
|
1699
1647
|
if (k !== 'key')
|
|
1700
1648
|
if (Object.keys(clients[k]).length === 0) {
|
|
1701
1649
|
client.log('Found a deleted user. Removing.', k, clients[k])
|
|
1702
1650
|
delete clients[k]
|
|
1703
|
-
master.
|
|
1651
|
+
master.set(clients)
|
|
1704
1652
|
} else if (clients[k].key === key) {
|
|
1705
1653
|
client.log('Logging out!', k, clients[k])
|
|
1706
1654
|
delete clients[k]
|
|
1707
|
-
master.
|
|
1655
|
+
master.set(clients)
|
|
1708
1656
|
}
|
|
1709
1657
|
}
|
|
1710
1658
|
|
|
1711
1659
|
// Initialize master
|
|
1712
1660
|
if (!master.auth_initialized) {
|
|
1713
|
-
master('users/passwords').
|
|
1714
|
-
master.log('users/passwords.
|
|
1661
|
+
master('users/passwords').to_get = function (k) {
|
|
1662
|
+
master.log('users/passwords.to_get: Computing!')
|
|
1715
1663
|
var result = {key: 'users/passwords'}
|
|
1716
|
-
var users = master.
|
|
1664
|
+
var users = master.get('users')
|
|
1717
1665
|
users.all = users.all || []
|
|
1718
1666
|
for (var i=0; i<users.all.length; i++) {
|
|
1719
|
-
var u = master.
|
|
1667
|
+
var u = master.get(users.all[i])
|
|
1720
1668
|
if (!(u.login || u.name)) {
|
|
1721
1669
|
console.error('upass: this user has bogus name/login', u.key, u.name, u.login)
|
|
1722
1670
|
continue
|
|
@@ -1732,14 +1680,14 @@ function import_server (bus, options)
|
|
|
1732
1680
|
return result
|
|
1733
1681
|
}
|
|
1734
1682
|
master.auth_initialized = true
|
|
1735
|
-
master.
|
|
1683
|
+
master.get('users/passwords')
|
|
1736
1684
|
|
|
1737
1685
|
master('user/*').to_delete = (key, t) => {
|
|
1738
1686
|
master.log('Deleteinggg!!!', key)
|
|
1739
1687
|
// Remove from users.all
|
|
1740
|
-
var users = master.
|
|
1688
|
+
var users = master.get('users')
|
|
1741
1689
|
users.all = users.all.filter(u => u.key && u.key !== key)
|
|
1742
|
-
master.
|
|
1690
|
+
master.set(users)
|
|
1743
1691
|
|
|
1744
1692
|
// Log out
|
|
1745
1693
|
master.log('Logging out', key)
|
|
@@ -1747,14 +1695,14 @@ function import_server (bus, options)
|
|
|
1747
1695
|
|
|
1748
1696
|
// Remove connection
|
|
1749
1697
|
master.log('Removing connections for', key)
|
|
1750
|
-
var conns = master.
|
|
1698
|
+
var conns = master.get('connections')
|
|
1751
1699
|
for (var k in conns) {
|
|
1752
1700
|
console.log('Trying key', k)
|
|
1753
1701
|
if (k !== 'key')
|
|
1754
1702
|
if (conns[k].user && !conns[k].user.key) {
|
|
1755
1703
|
console.log('Cleaning keyless user', conss[k].user)
|
|
1756
1704
|
delete conns[k].user
|
|
1757
|
-
master.
|
|
1705
|
+
master.set(conns)
|
|
1758
1706
|
continue
|
|
1759
1707
|
}
|
|
1760
1708
|
}
|
|
@@ -1769,9 +1717,9 @@ function import_server (bus, options)
|
|
|
1769
1717
|
|
|
1770
1718
|
// Authentication functions
|
|
1771
1719
|
function authenticate (login, pass) {
|
|
1772
|
-
var userpass = master.
|
|
1720
|
+
var userpass = master.get('users/passwords')[login.toLowerCase()]
|
|
1773
1721
|
master.log('authenticate: we see', {
|
|
1774
|
-
passwords: master.
|
|
1722
|
+
passwords: master.get('users/passwords'),
|
|
1775
1723
|
hash_to_match: userpass && userpass.pass,
|
|
1776
1724
|
password_guess: pass
|
|
1777
1725
|
})
|
|
@@ -1782,7 +1730,7 @@ function import_server (bus, options)
|
|
|
1782
1730
|
|
|
1783
1731
|
// console.log('comparing passwords', pass, userpass.pass)
|
|
1784
1732
|
if (require('bcrypt-nodejs').compareSync(pass, userpass.pass))
|
|
1785
|
-
return master.
|
|
1733
|
+
return master.get(userpass.user)
|
|
1786
1734
|
}
|
|
1787
1735
|
function create_account (params) {
|
|
1788
1736
|
if (typeof (params.login || params.name) !== 'string')
|
|
@@ -1794,7 +1742,7 @@ function import_server (bus, options)
|
|
|
1794
1742
|
'?key': undefined, '*': '*'}))
|
|
1795
1743
|
throw 'invalid name, login, pass, or email'
|
|
1796
1744
|
|
|
1797
|
-
var passes = master.
|
|
1745
|
+
var passes = master.get('users/passwords')
|
|
1798
1746
|
if (passes.hasOwnProperty(login))
|
|
1799
1747
|
throw 'there is already a user with that login or name'
|
|
1800
1748
|
|
|
@@ -1804,7 +1752,7 @@ function import_server (bus, options)
|
|
|
1804
1752
|
// Choose account key
|
|
1805
1753
|
//
|
|
1806
1754
|
// NOTE: Checking if master.cache has the key probably sucks,
|
|
1807
|
-
// because if something
|
|
1755
|
+
// because if something gets that key (hoping it exists), it
|
|
1808
1756
|
// might create it, even though the account hasn't been created
|
|
1809
1757
|
// yet, and then this will rename it to some random ID.
|
|
1810
1758
|
//
|
|
@@ -1821,31 +1769,31 @@ function import_server (bus, options)
|
|
|
1821
1769
|
pass: params.pass,
|
|
1822
1770
|
email: params.email }
|
|
1823
1771
|
for (var k in new_account) if (!new_account[k]) delete new_account[k]
|
|
1824
|
-
master.
|
|
1772
|
+
master.set(new_account)
|
|
1825
1773
|
|
|
1826
|
-
var users = master.
|
|
1774
|
+
var users = master.get('users')
|
|
1827
1775
|
users.all = users.all || []
|
|
1828
1776
|
users.all.push(new_account)
|
|
1829
1777
|
passes[login] = {user: new_account.key, pass: new_account.pass}
|
|
1830
|
-
master.
|
|
1831
|
-
master.
|
|
1778
|
+
master.set(users)
|
|
1779
|
+
master.set(passes)
|
|
1832
1780
|
}
|
|
1833
1781
|
|
|
1834
1782
|
// Current User
|
|
1835
|
-
client('current_user').
|
|
1836
|
-
client.log('*
|
|
1783
|
+
client('current_user').to_get = function (k) {
|
|
1784
|
+
client.log('* getting: current_user')
|
|
1837
1785
|
if (!conn.client) return
|
|
1838
|
-
var u = master.
|
|
1786
|
+
var u = master.get('logged_in_clients')[conn.client]
|
|
1839
1787
|
u = u && user_obj(u.key, true)
|
|
1840
1788
|
return {user: u || null, logged_in: !!u}
|
|
1841
1789
|
}
|
|
1842
1790
|
|
|
1843
|
-
client('current_user').
|
|
1791
|
+
client('current_user').to_set = function (o, t) {
|
|
1844
1792
|
function error (msg) {
|
|
1845
|
-
client.
|
|
1846
|
-
var c = client.
|
|
1793
|
+
client.set.abort(o)
|
|
1794
|
+
var c = client.get('current_user')
|
|
1847
1795
|
c.error = msg
|
|
1848
|
-
client.
|
|
1796
|
+
client.set.fire(c)
|
|
1849
1797
|
}
|
|
1850
1798
|
|
|
1851
1799
|
client.log('* saving: current_user!')
|
|
@@ -1856,9 +1804,9 @@ function import_server (bus, options)
|
|
|
1856
1804
|
client.client_ip = conn.remoteAddress
|
|
1857
1805
|
|
|
1858
1806
|
if (conn.id) {
|
|
1859
|
-
var connections = master.
|
|
1860
|
-
connections[conn.id].user = master.
|
|
1861
|
-
master.
|
|
1807
|
+
var connections = master.get('connections')
|
|
1808
|
+
connections[conn.id].user = master.get('logged_in_clients')[conn.client]
|
|
1809
|
+
master.set(connections)
|
|
1862
1810
|
}
|
|
1863
1811
|
}
|
|
1864
1812
|
else {
|
|
@@ -1867,9 +1815,9 @@ function import_server (bus, options)
|
|
|
1867
1815
|
try {
|
|
1868
1816
|
create_account(o.create_account)
|
|
1869
1817
|
client.log('Success creating account!')
|
|
1870
|
-
var cu = client.
|
|
1818
|
+
var cu = client.get('current_user')
|
|
1871
1819
|
cu.create_account = null
|
|
1872
|
-
client.
|
|
1820
|
+
client.set.fire(cu)
|
|
1873
1821
|
} catch (e) {
|
|
1874
1822
|
error('Cannot create that account because ' + e)
|
|
1875
1823
|
return
|
|
@@ -1891,14 +1839,14 @@ function import_server (bus, options)
|
|
|
1891
1839
|
// Associate this user with this session
|
|
1892
1840
|
// user.log('Logging the user in!', u)
|
|
1893
1841
|
|
|
1894
|
-
var clients = master.
|
|
1895
|
-
var connections = master.
|
|
1842
|
+
var clients = master.get('logged_in_clients')
|
|
1843
|
+
var connections = master.get('connections')
|
|
1896
1844
|
|
|
1897
1845
|
clients[conn.client] = u
|
|
1898
1846
|
connections[conn.id].user = u
|
|
1899
1847
|
|
|
1900
|
-
master.
|
|
1901
|
-
master.
|
|
1848
|
+
master.set(clients)
|
|
1849
|
+
master.set(connections)
|
|
1902
1850
|
|
|
1903
1851
|
client.log('current_user: success logging in!')
|
|
1904
1852
|
}
|
|
@@ -1915,18 +1863,18 @@ function import_server (bus, options)
|
|
|
1915
1863
|
|
|
1916
1864
|
else if (o.logout && conn.id) {
|
|
1917
1865
|
client.log('current_user: logging out')
|
|
1918
|
-
var clients = master.
|
|
1919
|
-
var connections = master.
|
|
1866
|
+
var clients = master.get('logged_in_clients')
|
|
1867
|
+
var connections = master.get('connections')
|
|
1920
1868
|
|
|
1921
1869
|
delete clients[conn.client]
|
|
1922
1870
|
connections[conn.id].user = null
|
|
1923
1871
|
|
|
1924
|
-
master.
|
|
1925
|
-
master.
|
|
1872
|
+
master.set(clients)
|
|
1873
|
+
master.set(connections)
|
|
1926
1874
|
}
|
|
1927
1875
|
}
|
|
1928
1876
|
|
|
1929
|
-
t.
|
|
1877
|
+
t.reget()
|
|
1930
1878
|
}
|
|
1931
1879
|
client('current_user').to_delete = function () {}
|
|
1932
1880
|
|
|
@@ -1935,8 +1883,8 @@ function import_server (bus, options)
|
|
|
1935
1883
|
var private_closet_space_key = /^user\/[^\/]+\/private.*/
|
|
1936
1884
|
|
|
1937
1885
|
// User
|
|
1938
|
-
client('user/*').
|
|
1939
|
-
var c = client.
|
|
1886
|
+
client('user/*').to_set = function (o, t) {
|
|
1887
|
+
var c = client.get('current_user')
|
|
1940
1888
|
var user_key = o.key.match(/^user\/([^\/]+)/)
|
|
1941
1889
|
user_key = user_key && ('user/' + user_key[1])
|
|
1942
1890
|
|
|
@@ -1945,14 +1893,14 @@ function import_server (bus, options)
|
|
|
1945
1893
|
client.log('Only the current user can touch themself.',
|
|
1946
1894
|
{logged_in: c.logged_in, as: c.user && c.user.key,
|
|
1947
1895
|
touching: user_key})
|
|
1948
|
-
client.
|
|
1896
|
+
client.set.abort(o)
|
|
1949
1897
|
return
|
|
1950
1898
|
}
|
|
1951
1899
|
|
|
1952
1900
|
// Users have closet space at /user/<name>/*
|
|
1953
1901
|
if (o.key.match(closet_space_key)) {
|
|
1954
1902
|
client.log('saving closet data')
|
|
1955
|
-
master.
|
|
1903
|
+
master.set(o, t)
|
|
1956
1904
|
return
|
|
1957
1905
|
}
|
|
1958
1906
|
|
|
@@ -1964,7 +1912,7 @@ function import_server (bus, options)
|
|
|
1964
1912
|
'?pass': 'string', '?email': 'string', /*'?pic': 'string',*/
|
|
1965
1913
|
'*':'*'})) {
|
|
1966
1914
|
client.log('This user change fails validation.')
|
|
1967
|
-
client.
|
|
1915
|
+
client.set.abort(o)
|
|
1968
1916
|
return
|
|
1969
1917
|
}
|
|
1970
1918
|
|
|
@@ -1976,23 +1924,23 @@ function import_server (bus, options)
|
|
|
1976
1924
|
var login = o.login || o.name
|
|
1977
1925
|
if (!login) {
|
|
1978
1926
|
client.log('User must have a login or a name')
|
|
1979
|
-
client.
|
|
1927
|
+
client.set.abort(o)
|
|
1980
1928
|
return
|
|
1981
1929
|
}
|
|
1982
1930
|
|
|
1983
|
-
var u = master.
|
|
1984
|
-
var userpass = master.
|
|
1931
|
+
var u = master.get(o.key)
|
|
1932
|
+
var userpass = master.get('users/passwords')
|
|
1985
1933
|
|
|
1986
1934
|
// Validate that the login/name is not changed to something clobberish
|
|
1987
1935
|
var old_login = u.login || u.name
|
|
1988
1936
|
if (old_login.toLowerCase() !== login.toLowerCase()
|
|
1989
1937
|
&& userpass.hasOwnProperty(login)) {
|
|
1990
1938
|
client.log('The login', login, 'is already taken. Aborting.')
|
|
1991
|
-
client.
|
|
1939
|
+
client.set.abort(o) // Abort
|
|
1992
1940
|
|
|
1993
|
-
o = client.
|
|
1941
|
+
o = client.get(o.key) // Add error message
|
|
1994
1942
|
o.error = 'The login "' + login + '" is already taken'
|
|
1995
|
-
client.
|
|
1943
|
+
client.set.fire(o)
|
|
1996
1944
|
|
|
1997
1945
|
return // And exit
|
|
1998
1946
|
}
|
|
@@ -2029,11 +1977,11 @@ function import_server (bus, options)
|
|
|
2029
1977
|
if (!protected.hasOwnProperty(k) && !o.hasOwnProperty(k))
|
|
2030
1978
|
delete u[k]
|
|
2031
1979
|
|
|
2032
|
-
master.
|
|
1980
|
+
master.set(u)
|
|
2033
1981
|
}
|
|
2034
|
-
client('user/*').
|
|
2035
|
-
var c = client.
|
|
2036
|
-
client.log('*
|
|
1982
|
+
client('user/*').to_get = function user_getter (k) {
|
|
1983
|
+
var c = client.get('current_user')
|
|
1984
|
+
client.log('* getting:', k, 'as', c.user)
|
|
2037
1985
|
|
|
2038
1986
|
// Users have closet space at /user/<name>/*
|
|
2039
1987
|
if (k.match(closet_space_key)) {
|
|
@@ -2043,8 +1991,8 @@ function import_server (bus, options)
|
|
|
2043
1991
|
client.log('hiding private closet data')
|
|
2044
1992
|
return {}
|
|
2045
1993
|
}
|
|
2046
|
-
client.log('
|
|
2047
|
-
return client.clone(master.
|
|
1994
|
+
client.log('getting closet data')
|
|
1995
|
+
return client.clone(master.get(k))
|
|
2048
1996
|
}
|
|
2049
1997
|
|
|
2050
1998
|
// Otherwise return the actual user
|
|
@@ -2052,7 +2000,7 @@ function import_server (bus, options)
|
|
|
2052
2000
|
}
|
|
2053
2001
|
client('user/*').to_delete = function () {}
|
|
2054
2002
|
function user_obj (k, logged_in) {
|
|
2055
|
-
var o = master.clone(master.
|
|
2003
|
+
var o = master.clone(master.get(k))
|
|
2056
2004
|
if (k.match(/^user\/([^\/]+)\/private\/(.*)$/))
|
|
2057
2005
|
return logged_in ? o : {key: k}
|
|
2058
2006
|
|
|
@@ -2064,8 +2012,8 @@ function import_server (bus, options)
|
|
|
2064
2012
|
// Blacklist sensitive stuff on master, in case we have a shadow set up
|
|
2065
2013
|
var blacklist = 'users users/passwords logged_in_clients'.split(' ')
|
|
2066
2014
|
for (var i=0; i<blacklist.length; i++) {
|
|
2067
|
-
client(blacklist[i]).
|
|
2068
|
-
client(blacklist[i]).
|
|
2015
|
+
client(blacklist[i]).to_get = function () {}
|
|
2016
|
+
client(blacklist[i]).to_set = function () {}
|
|
2069
2017
|
client(blacklist[i]).to_delete = function () {}
|
|
2070
2018
|
client(blacklist[i]).to_forget = function () {}
|
|
2071
2019
|
}
|
|
@@ -2085,24 +2033,24 @@ function import_server (bus, options)
|
|
|
2085
2033
|
var old_prefix = 'client/' + client.client_id
|
|
2086
2034
|
var new_prefix = 'client/' + user.key.substr('user/'.length)
|
|
2087
2035
|
|
|
2088
|
-
var keys = client.master.
|
|
2036
|
+
var keys = client.master.get('persisted_keys/' + client.client_id)
|
|
2089
2037
|
if (!keys.val) return
|
|
2090
2038
|
for (var old_key in keys.val) {
|
|
2091
2039
|
var new_key = new_prefix + old_key.substr(old_prefix.length)
|
|
2092
|
-
var o = client.clone(client.master.
|
|
2040
|
+
var o = client.clone(client.master.get(old_key))
|
|
2093
2041
|
// Delete the old
|
|
2094
2042
|
client.master.del(old_key)
|
|
2095
2043
|
|
|
2096
|
-
var new_o = client.master.
|
|
2044
|
+
var new_o = client.master.get(new_key)
|
|
2097
2045
|
// If the new key doesn't clobber any existing data on the user...
|
|
2098
2046
|
if (Object.keys(new_o).length === 1) {
|
|
2099
|
-
//
|
|
2047
|
+
// Set the new
|
|
2100
2048
|
o.key = new_key
|
|
2101
|
-
client.master.
|
|
2049
|
+
client.master.set(o)
|
|
2102
2050
|
}
|
|
2103
2051
|
}
|
|
2104
2052
|
keys.val = {}
|
|
2105
|
-
client.master.
|
|
2053
|
+
client.master.set(keys)
|
|
2106
2054
|
|
|
2107
2055
|
// var cache = client.master.cache
|
|
2108
2056
|
|
|
@@ -2117,9 +2065,9 @@ function import_server (bus, options)
|
|
|
2117
2065
|
// client.master.del(old_key)
|
|
2118
2066
|
|
|
2119
2067
|
// if (!(cache.hasOwnProperty(new_key))) {
|
|
2120
|
-
// //
|
|
2068
|
+
// // Set the new
|
|
2121
2069
|
// o.key = new_key
|
|
2122
|
-
// client.master.
|
|
2070
|
+
// client.master.set(o)
|
|
2123
2071
|
// }
|
|
2124
2072
|
// }
|
|
2125
2073
|
// }
|
|
@@ -2127,7 +2075,7 @@ function import_server (bus, options)
|
|
|
2127
2075
|
|
|
2128
2076
|
// Copy client to user if we log in
|
|
2129
2077
|
client(_=>{
|
|
2130
|
-
var c = client.
|
|
2078
|
+
var c = client.get('current_user')
|
|
2131
2079
|
if (client.loading()) return
|
|
2132
2080
|
if (was_logged_in == false && c.logged_in)
|
|
2133
2081
|
// User just logged in! Let's copy his stuff over
|
|
@@ -2135,13 +2083,13 @@ function import_server (bus, options)
|
|
|
2135
2083
|
was_logged_in = c.logged_in
|
|
2136
2084
|
})
|
|
2137
2085
|
|
|
2138
|
-
client(prefix_to_sync).
|
|
2139
|
-
var c = client.
|
|
2086
|
+
client(prefix_to_sync).to_get = function (key) {
|
|
2087
|
+
var c = client.get('current_user')
|
|
2140
2088
|
if (client.loading()) return
|
|
2141
2089
|
var prefix = client_prefix(c)
|
|
2142
2090
|
|
|
2143
2091
|
// Get the state from master
|
|
2144
|
-
var obj = client.clone(client.master.
|
|
2092
|
+
var obj = client.clone(client.master.get(prefix + key))
|
|
2145
2093
|
|
|
2146
2094
|
// Translate it back to client
|
|
2147
2095
|
obj = client.deep_map(obj, function (o) {
|
|
@@ -2152,14 +2100,14 @@ function import_server (bus, options)
|
|
|
2152
2100
|
return obj
|
|
2153
2101
|
}
|
|
2154
2102
|
|
|
2155
|
-
client(prefix_to_sync).
|
|
2103
|
+
client(prefix_to_sync).to_set = function (obj) {
|
|
2156
2104
|
if (validate && !validate(obj)) {
|
|
2157
2105
|
console.warn('Validation failed on', obj)
|
|
2158
|
-
client.
|
|
2106
|
+
client.set.abort(obj)
|
|
2159
2107
|
return
|
|
2160
2108
|
}
|
|
2161
2109
|
|
|
2162
|
-
var c = client.
|
|
2110
|
+
var c = client.get('current_user')
|
|
2163
2111
|
if (client.loading()) return
|
|
2164
2112
|
var prefix = client_prefix(c)
|
|
2165
2113
|
|
|
@@ -2175,23 +2123,23 @@ function import_server (bus, options)
|
|
|
2175
2123
|
return o
|
|
2176
2124
|
})
|
|
2177
2125
|
|
|
2178
|
-
//
|
|
2179
|
-
client.master.
|
|
2180
|
-
p_keys && client.master.
|
|
2126
|
+
// Set to master
|
|
2127
|
+
client.master.set(obj)
|
|
2128
|
+
p_keys && client.master.set(p_keys)
|
|
2181
2129
|
}
|
|
2182
2130
|
|
|
2183
2131
|
client(prefix_to_sync).to_delete = function (k) {
|
|
2184
|
-
k = client_prefix(client.
|
|
2132
|
+
k = client_prefix(client.get('current_user')) + k
|
|
2185
2133
|
client.master.delete(k)
|
|
2186
2134
|
|
|
2187
2135
|
var p_keys = client_persisted_keys()
|
|
2188
2136
|
delete p_keys.val[k]
|
|
2189
|
-
client.master.
|
|
2137
|
+
client.master.set(p_keys)
|
|
2190
2138
|
}
|
|
2191
2139
|
|
|
2192
2140
|
function client_persisted_keys () {
|
|
2193
|
-
if (client.
|
|
2194
|
-
var result = client.master.
|
|
2141
|
+
if (client.get('current_user').logged_in) return
|
|
2142
|
+
var result = client.master.get('persisted_keys/' + client.client_id)
|
|
2195
2143
|
if (result && !result.val) result.val = {}
|
|
2196
2144
|
return result
|
|
2197
2145
|
}
|
|
@@ -2206,17 +2154,17 @@ function import_server (bus, options)
|
|
|
2206
2154
|
// to the global cache
|
|
2207
2155
|
if (count === 0) {
|
|
2208
2156
|
count++
|
|
2209
|
-
if (method === '
|
|
2157
|
+
if (method === 'to_get')
|
|
2210
2158
|
bus.run_handler(function get_from_master (k) {
|
|
2211
|
-
// console.log('DEFAULT
|
|
2212
|
-
var r = master_bus.
|
|
2213
|
-
// console.log('DEFAULT
|
|
2214
|
-
bus.
|
|
2159
|
+
// console.log('DEFAULT GETting', k)
|
|
2160
|
+
var r = master_bus.get(k)
|
|
2161
|
+
// console.log('DEFAULT GETted', r)
|
|
2162
|
+
bus.set.fire(r, {version: master_bus.versions[r.key]})
|
|
2215
2163
|
}, method, arg)
|
|
2216
|
-
else if (method === '
|
|
2217
|
-
bus.run_handler(function
|
|
2164
|
+
else if (method === 'to_set')
|
|
2165
|
+
bus.run_handler(function set_to_master (o, t) {
|
|
2218
2166
|
// console.log('DEFAULT ROUTE', t)
|
|
2219
|
-
master_bus.
|
|
2167
|
+
master_bus.set(bus.clone(o), t)
|
|
2220
2168
|
}, method, arg, {t: t})
|
|
2221
2169
|
else if (method == 'to_delete')
|
|
2222
2170
|
bus.run_handler(function delete_from_master (k, t) {
|
|
@@ -2283,7 +2231,7 @@ function import_server (bus, options)
|
|
|
2283
2231
|
var buffer = {}
|
|
2284
2232
|
var full_file_path = require('path').join(__dirname, file_path)
|
|
2285
2233
|
|
|
2286
|
-
bus(state_path + '*').
|
|
2234
|
+
bus(state_path + '*').to_get = (rest) => {
|
|
2287
2235
|
// We DO want to handle:
|
|
2288
2236
|
// - "foo"
|
|
2289
2237
|
// - "foo/*"
|
|
@@ -2309,7 +2257,7 @@ function import_server (bus, options)
|
|
|
2309
2257
|
return {_:f}
|
|
2310
2258
|
}
|
|
2311
2259
|
|
|
2312
|
-
bus(state_path + '/*').
|
|
2260
|
+
bus(state_path + '/*').to_set = (o, rest, t) => {
|
|
2313
2261
|
if (rest.length>0 && rest[0] !== '/') return
|
|
2314
2262
|
var f = Buffer.from(o._, 'base64')
|
|
2315
2263
|
require('fs').writeFile(file_path + rest, f,
|
|
@@ -2320,15 +2268,15 @@ function import_server (bus, options)
|
|
|
2320
2268
|
bus.http.use('/'+state_path, require('express').static(full_file_path))
|
|
2321
2269
|
},
|
|
2322
2270
|
|
|
2323
|
-
// Installs a GET handler at route that gets state from a
|
|
2271
|
+
// Installs a GET handler at route that gets state from a getter function
|
|
2324
2272
|
// Note: Makes too many textbusses. Should re-use one.
|
|
2325
|
-
http_serve: function http_serve (route,
|
|
2273
|
+
http_serve: function http_serve (route, getter) {
|
|
2326
2274
|
var textbus = require('./statebus')()
|
|
2327
2275
|
textbus.label = 'textbus'
|
|
2328
2276
|
var watched = new Set()
|
|
2329
|
-
textbus('*').
|
|
2277
|
+
textbus('*').to_get = (filename, old) => {
|
|
2330
2278
|
return {etag: Math.random() + '',
|
|
2331
|
-
_:
|
|
2279
|
+
_: getter(filename)}
|
|
2332
2280
|
}
|
|
2333
2281
|
bus.http.get(route, (req, res) => {
|
|
2334
2282
|
var path = req.path
|
|
@@ -2338,8 +2286,8 @@ function import_server (bus, options)
|
|
|
2338
2286
|
return
|
|
2339
2287
|
}
|
|
2340
2288
|
|
|
2341
|
-
textbus.
|
|
2342
|
-
textbus.
|
|
2289
|
+
textbus.get(req.path) // So that textbus never clears the cache
|
|
2290
|
+
textbus.get(req.path, function cb (o) {
|
|
2343
2291
|
res.setHeader('Cache-Control', 'public')
|
|
2344
2292
|
// res.setHeader('Cache-Control', 'public, max-age='
|
|
2345
2293
|
// + (60 * 60 * 24 * 30)) // 1 month
|
|
@@ -2394,16 +2342,15 @@ function import_server (bus, options)
|
|
|
2394
2342
|
var files =
|
|
2395
2343
|
['extras/coffee.js', 'extras/sockjs.js', 'extras/react.js',
|
|
2396
2344
|
'statebus.js', 'client.js'].map((f) => fs.readFileSync('node_modules/statebus/' + f))
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
))
|
|
2345
|
+
files.unshift(fs.readFileSync(
|
|
2346
|
+
'node_modules/braidify/braidify-client.js'
|
|
2347
|
+
))
|
|
2401
2348
|
res.send(files.join(';\n'))
|
|
2402
2349
|
})
|
|
2403
2350
|
},
|
|
2404
2351
|
|
|
2405
2352
|
serve_wiki: () => {
|
|
2406
|
-
bus('edit/*').
|
|
2353
|
+
bus('edit/*').to_get = () => ({_: require('./extras/wiki.coffee').code})
|
|
2407
2354
|
},
|
|
2408
2355
|
|
|
2409
2356
|
unix_socket_repl: function (filename) {
|
|
@@ -2470,13 +2417,15 @@ function import_server (bus, options)
|
|
|
2470
2417
|
}
|
|
2471
2418
|
}
|
|
2472
2419
|
// Add methods to bus object
|
|
2473
|
-
for (var m in extra_methods)
|
|
2420
|
+
for (var m in extra_methods) {
|
|
2474
2421
|
bus[m] = extra_methods[m]
|
|
2422
|
+
bus.libs[m] = extra_methods[m]
|
|
2423
|
+
}
|
|
2475
2424
|
|
|
2476
2425
|
bus.options = default_options(bus)
|
|
2477
2426
|
set_options(bus, options)
|
|
2478
2427
|
|
|
2479
|
-
// Automatically make state://
|
|
2428
|
+
// Automatically make state:// get over a websocket
|
|
2480
2429
|
bus.net_automount()
|
|
2481
2430
|
return bus
|
|
2482
2431
|
}
|
|
@@ -2484,8 +2433,6 @@ function import_server (bus, options)
|
|
|
2484
2433
|
|
|
2485
2434
|
// Disables CORS in HTTP servers
|
|
2486
2435
|
function free_the_cors (req, res, next) {
|
|
2487
|
-
console.log('free the cors!', req.method, req.url)
|
|
2488
|
-
|
|
2489
2436
|
var free_the_cors = {
|
|
2490
2437
|
"Access-Control-Allow-Origin": "*",
|
|
2491
2438
|
"Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT, UNSUBSCRIBE",
|
|
@@ -2496,7 +2443,7 @@ function free_the_cors (req, res, next) {
|
|
|
2496
2443
|
res.writeHead(200)
|
|
2497
2444
|
res.end()
|
|
2498
2445
|
} else
|
|
2499
|
-
next()
|
|
2446
|
+
next && next()
|
|
2500
2447
|
}
|
|
2501
2448
|
|
|
2502
2449
|
|
|
@@ -2537,6 +2484,11 @@ delay.init = _=> delay_so_far = 0
|
|
|
2537
2484
|
var delay_so_far = 0
|
|
2538
2485
|
|
|
2539
2486
|
|
|
2487
|
+
// Set up default linked json converters
|
|
2488
|
+
var to_http_body = (o) => JSON.stringify(o.val)
|
|
2489
|
+
var from_http_body = (key, body) => ({ key, val: JSON.parse(body) })
|
|
2490
|
+
|
|
2491
|
+
|
|
2540
2492
|
// Now export everything
|
|
2541
2493
|
module.exports.import_server = import_server
|
|
2542
2494
|
module.exports.run_server = function (bus, options) { bus.serve(options) }
|
|
@@ -2545,7 +2497,7 @@ module.exports.import_module = function (statebus) {
|
|
|
2545
2497
|
|
|
2546
2498
|
statebus.serve = function serve (options) {
|
|
2547
2499
|
var bus = statebus()
|
|
2548
|
-
require('./
|
|
2500
|
+
require('./servers').run_server(bus, options)
|
|
2549
2501
|
return bus
|
|
2550
2502
|
}
|
|
2551
2503
|
|