statebus 7.0.2 → 7.0.5

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.
@@ -37,7 +37,7 @@ function set_options (bus, options) {
37
37
  }
38
38
  }
39
39
 
40
- function import_server (bus, options)
40
+ function import_server (bus, make_statebus, options)
41
41
  { var extra_methods = {
42
42
 
43
43
  serve: function serve (options) {
@@ -76,23 +76,6 @@ function import_server (bus, options)
76
76
  try { bus.http.use(require('compression')())
77
77
  console.log('Enabled http compression!') } catch (e) {}
78
78
 
79
-
80
- // Initialize new clients with an id. We put the client id on
81
- // req.client, and also in a cookie for the browser to see.
82
- if (bus.options.client)
83
- bus.express.use(function (req, res, next) {
84
- req.client = require('cookie').parse(req.headers.cookie || '').client
85
- if (!req.client) {
86
- req.client = (Math.random().toString(36).substring(2)
87
- + Math.random().toString(36).substring(2)
88
- + Math.random().toString(36).substring(2))
89
-
90
- res.setHeader('Set-Cookie', 'client=' + req.client
91
- + '; Expires=21 Oct 2025 00:0:00 GMT;')
92
- }
93
- next()
94
- })
95
-
96
79
  // Initialize file sync
97
80
  ; (bus.options.sync_files || []).forEach( x => {
98
81
  if (require('fs').existsSync(x.fs_path || x.state_path))
@@ -122,17 +105,17 @@ function import_server (bus, options)
122
105
  // Now handle backup handlers
123
106
  if (count === 0) {
124
107
 
125
- // A set to master without a to_set defined should be
108
+ // A set to master without a setter defined should be
126
109
  // automatically reflected to all clients.
127
- if (method === 'to_set') {
110
+ if (method === 'setter') {
128
111
  bus.set.fire(arg, t)
129
112
  bus.route(arg.key, 'on_set_sync', arg, t)
130
113
  count++
131
114
  }
132
115
 
133
- // A get to master without a to_get defined should go to
116
+ // A get to master without a getter defined should go to
134
117
  // the database, if we have one.
135
- if (method === 'to_get') {
118
+ if (method === 'getter') {
136
119
  bus.db_get(key)
137
120
  // This basically renders the count useless-- you probably
138
121
  // don't want to wrap this route() with another route().
@@ -165,30 +148,40 @@ function import_server (bus, options)
165
148
  || req.method === 'OPTIONS')
166
149
  free_the_cors(req, res)
167
150
 
151
+ // Initialize new clients with an id. We put the client id on
152
+ // req.client, and also in a cookie for the browser to see.
153
+ req.peer = //req.headers.peer ||
154
+ require('cookie').parse(req.headers.cookie || '').peer
155
+ if (!req.peer) {
156
+ req.peer = (Math.random().toString(36).substring(2)
157
+ + Math.random().toString(36).substring(2)
158
+ + Math.random().toString(36).substring(2))
159
+
160
+ res.setHeader('Set-Cookie', 'peer=' + req.peer
161
+ + '; Expires=21 Oct 2055 00:0:00 GMT;')
162
+ }
163
+
164
+ // Handle the GET or PUT request!
168
165
  if (req.method === 'GET') {
166
+ var key = req.path.substr(1)
169
167
 
170
168
  // Make a temporary client bus
171
169
  var cbus = bus.bus_for_http_client(req, res)
172
- var cb
173
- function end_it_all () {
174
- cbus.forget(key, cb)
175
- cbus.delete_bus()
176
- res.end()
177
- }
178
170
 
179
171
  braidify(req, res)
180
172
  if (req.subscribe)
181
- res.startSubscription({ onClose: end_it_all })
173
+ res.startSubscription({ onClose: end_subscription })
182
174
  else
183
175
  res.statusCode = 200
184
176
 
185
- // Do the get
186
- // cbus.honk = 'statelog'
187
- var key = req.path.substr(1)
188
- cbus.get(key, cb = (o) => {
189
- var body = to_http_body(o)
177
+ // We only return JSON
178
+ res.setHeader('Content-Type', 'application/json')
190
179
 
191
- // If we're braiding, send via subscription
180
+ // console.log('http_in: doing cbus.get(', key, ')')
181
+
182
+ var send_to_client = (o, t) => {
183
+ // console.trace('http_in: Sending update of', key)
184
+ var body = to_http_body(o)
192
185
 
193
186
  // Note: if body === undefined, we need to send the
194
187
  // equivalent of a 404. This is missing in braid spec:
@@ -197,14 +190,35 @@ function import_server (bus, options)
197
190
 
198
191
  // And shut down the connection if there's no subscription
199
192
  if (!req.subscribe)
200
- end_it_all()
201
- })
193
+ end_subscription()
194
+ }
195
+
196
+ function end_subscription () {
197
+ cbus.forget(key, send_to_client)
198
+ res.end()
199
+ cbus.http_unsubscribe(req)
200
+
201
+ let peer = req.headers.peer
202
+ if (cbus.http_callbacks)
203
+ delete cbus.http_callbacks[JSON.stringify({peer, key})]
204
+ }
205
+
206
+ // If we have a peer id, then register this callback at that peer,
207
+ // so it can avoid getting its own PUT versions echoed back to
208
+ // itself.
209
+ if (req.headers.peer) {
210
+ if (!cbus.http_callbacks)
211
+ cbus.http_callbacks = {}
212
+ let peer = req.headers.peer
213
+ cbus.http_callbacks[JSON.stringify({peer, key})]
214
+ = send_to_client
215
+ }
216
+
217
+ // And issue the get!
218
+ cbus.get(key, send_to_client)
202
219
  }
203
220
 
204
221
  else if (req.method === 'PUT') {
205
- // Make a temporary client bus
206
- var cbus = bus.bus_for_http_client(req, res)
207
-
208
222
  // Maybe the new state is expressed in patches
209
223
  if (req.headers.patches) {
210
224
  console.error("We don't actually handle PUT patches yet")
@@ -231,9 +245,31 @@ function import_server (bus, options)
231
245
  res.end()
232
246
  return
233
247
  }
234
- cbus.set(obj)
248
+
249
+ // Make a temporary client bus
250
+ var cbus = bus.bus_for_http_client(req, res)
251
+ var t = {
252
+ version: req.version || cbus.new_version(),
253
+ parents: req.parents
254
+ }
255
+
256
+ // If the peer declares itself, let's remember it so that
257
+ // we don't send it echoes
258
+ if (req.headers.peer) {
259
+ let peer = req.headers.peer,
260
+ key = obj.key
261
+ var cb = cbus.http_callbacks[
262
+ JSON.stringify({peer, key})
263
+ ]
264
+ if (cb) cb.has_seen(cbus, key, t.version)
265
+ }
266
+
267
+ // Now send the version to the bus!
268
+ cbus.set(obj, t)
269
+
235
270
  res.statusCode = 200
236
271
  res.end()
272
+ cbus.http_unsubscribe(req)
237
273
  })
238
274
  }
239
275
  }
@@ -243,16 +279,39 @@ function import_server (bus, options)
243
279
 
244
280
  bus_for_http_client: function (req, res) {
245
281
  var bus = this
246
- if (!bus.bus_for_http_client.counter)
282
+ if (!bus.bus_for_http_client.counter) {
247
283
  bus.bus_for_http_client.counter = 0
248
- var cbus = require('./statebus')()
284
+ bus.bus_for_http_client.busses = {}
285
+ }
286
+
287
+ // If this client has a peer ID, and we've got a bus for that peer,
288
+ // then re-use it!
289
+ if (req.peer && bus.bus_for_http_client.busses[req.peer]) {
290
+ var cbus = bus.bus_for_http_client.busses[req.peer]
291
+ cbus.client_ip = req.connection.remoteAddress
292
+ cbus.num_subscriptions++
293
+ return cbus
294
+ }
295
+
296
+ // Otherwise, create a new bus
297
+ var cbus = make_statebus()
249
298
  cbus.label = 'client_http' + bus.bus_for_http_client.counter++
250
299
  cbus.master = bus
300
+ cbus.num_subscriptions = 1
301
+ cbus.http_unsubscribe = (req) => {
302
+ cbus.num_subscriptions--
303
+ if (cbus.num_subscriptions === 0) {
304
+ // log('Last subscription! Killing client bus!')
305
+ cbus.delete_bus()
306
+ delete bus.bus_for_http_client.busses[req.peer]
307
+ }
308
+ }
309
+ bus.bus_for_http_client.busses[req.peer] = cbus
251
310
 
252
- // Log in as the client
311
+ // And log into it as the client
253
312
  cbus.serves_auth({remoteAddress: req.connection.remoteAddress}, bus)
254
313
  bus.options.client(cbus)
255
- cbus.set({key: 'current_user', client: req.client})
314
+ cbus.set({key: 'current_user', val: {client: req.peer}})
256
315
  return cbus
257
316
  },
258
317
 
@@ -355,7 +414,7 @@ function import_server (bus, options)
355
414
  // var client_busses = {} // XXX work in progress
356
415
  var log = master.log
357
416
  if (client_bus_func) {
358
- master.set({key: 'connections'}) // Clean out old sessions
417
+ master.set({key: 'connections', val: {}}) // Clean out old sessions
359
418
  var connections = master.get('connections')
360
419
  }
361
420
  var s = require('sockjs').createServer({
@@ -373,11 +432,11 @@ function import_server (bus, options)
373
432
  // - When disconnecting, decrement the number, and if it gets
374
433
  // to zero, delete the client bus.
375
434
 
376
- connections[conn.id] = {client: conn.id, // client is deprecated
377
- id: conn.id}
435
+ connections.val[conn.id] = {client: conn.id, // client is deprecated
436
+ id: conn.id}
378
437
  master.set(connections)
379
438
 
380
- var client = require('./statebus')()
439
+ var client = make_statebus()
381
440
  client.label = 'client' + client_num++
382
441
  master.label = master.label || 'master'
383
442
  client.master = master
@@ -486,7 +545,7 @@ function import_server (bus, options)
486
545
  for (var key in our_gets_in)
487
546
  client.forget(key, sockjs_pubber)
488
547
  if (client_bus_func) {
489
- delete connections[conn.id]; master.set(connections)
548
+ delete connections.val[conn.id]; master.set(connections)
490
549
  master.delete('connection/' + conn.id)
491
550
  client.delete_bus()
492
551
  }
@@ -496,7 +555,7 @@ function import_server (bus, options)
496
555
  if (client_bus_func && !master.options.__secure) {
497
556
 
498
557
  // A connection
499
- client('connection/*').to_get = function (key, star) {
558
+ client('connection/*').getter = function (key, star) {
500
559
  var result = bus.clone(master.get(key))
501
560
  if (master.options.connections.include_users && result.user)
502
561
  result.user = client.get(result.user.key)
@@ -504,7 +563,7 @@ function import_server (bus, options)
504
563
  result.client = star // Deprecated. Delete this line in v7.
505
564
  return result
506
565
  }
507
- client('connection/*').to_set = function (o, star, t) {
566
+ client('connection/*').setter = function (o, star, t) {
508
567
  // Check permissions before editing
509
568
  if (star !== conn.id && !master.options.connections.edit_others) {
510
569
  t.abort()
@@ -516,7 +575,7 @@ function import_server (bus, options)
516
575
  }
517
576
 
518
577
  // Your connection
519
- client('connection').to_get = function () {
578
+ client('connection').getter = function () {
520
579
  // subscribe to changes in authentication
521
580
  client.get('current_user')
522
581
 
@@ -524,22 +583,22 @@ function import_server (bus, options)
524
583
  delete result.key
525
584
  return result
526
585
  }
527
- client('connection').to_set = function (o) {
586
+ client('connection').setter = function (o) {
528
587
  o = client.clone(o)
529
588
  o.key = 'connection/' + conn.id
530
589
  client.set(o)
531
590
  }
532
591
 
533
592
  // All connections
534
- client('connections').to_set = function noop (t) {t.abort()}
535
- client('connections').to_get = function () {
593
+ client('connections').setter = function noop (t) {t.abort()}
594
+ client('connections').getter = function () {
536
595
  var result = []
537
- var conns = master.get('connections')
596
+ var conns = master.get('connections').val
538
597
  for (var connid in conns)
539
598
  if (connid !== 'key')
540
599
  result.push(client.get('connection/' + connid))
541
600
 
542
- return {all: result}
601
+ return {val: result}
543
602
  }
544
603
  }
545
604
  })
@@ -555,13 +614,6 @@ function import_server (bus, options)
555
614
  WebSocket = require('websocket').w3cwebsocket
556
615
  return new WebSocket(url + '/' + bus.options.websocket_path + '/websocket')
557
616
  },
558
- client_creds: function client_creds (server_url) {
559
- // Right now the server just creates a different random id each time
560
- // it connects.
561
- return {clientid: (Math.random().toString(36).substring(2)
562
- + Math.random().toString(36).substring(2)
563
- + Math.random().toString(36).substring(2))}
564
- },
565
617
 
566
618
  file_store: (function () {
567
619
  // Make a database
@@ -643,7 +695,7 @@ function import_server (bus, options)
643
695
  }
644
696
  on_set.priority = true
645
697
  bus(prefix).on_set = on_set
646
- bus(prefix).to_delete = function (key) {
698
+ bus(prefix).deleter = function (key) {
647
699
  delete db[key]
648
700
  if (active) save_later()
649
701
  }
@@ -709,7 +761,7 @@ function import_server (bus, options)
709
761
  return decodeURIComponent(k.replace('%2E', '.'))
710
762
  }
711
763
 
712
- bus(prefix).to_get = function (key, t) {
764
+ bus(prefix).getter = function (key, t) {
713
765
  firebase_ref.child(encode_firebase_key(key)).on('value', function (x) {
714
766
  t.done(x.val() || {})
715
767
  }, function (err) { t.abort() })
@@ -719,19 +771,19 @@ function import_server (bus, options)
719
771
  firebase_ref.child(encode_firebase_key(o.key)).set(o)
720
772
  }
721
773
 
722
- // bus(prefix).to_set = function (o, t) {
774
+ // bus(prefix).setter = function (o, t) {
723
775
  // firebase_ref.child(encode_firebase_key(o.key)).set(o, (err) => {
724
776
  // err ? t.abort() : t.done()
725
777
  // })
726
778
  // }
727
779
 
728
- bus(prefix).to_delete = function (key, t) {
780
+ bus(prefix).deleter = function (key, t) {
729
781
  firebase_ref.child(encode_firebase_key(key)).set(null, (err) => {
730
782
  err ? t.abort() : t.done()
731
783
  })
732
784
  }
733
785
 
734
- bus(prefix).to_forget = function (key, t) {
786
+ bus(prefix).forgetter = function (key, t) {
735
787
  firebase_ref.child(encode_firebase_key(key)).off()
736
788
  }
737
789
  },
@@ -823,7 +875,7 @@ function import_server (bus, options)
823
875
  : o))
824
876
 
825
877
  // Publish this to the bus
826
- bus.set.fire(obj, {to_get: true})
878
+ bus.set.fire(obj, {getter: true})
827
879
  })
828
880
  }
829
881
 
@@ -852,13 +904,13 @@ function import_server (bus, options)
852
904
  if (opts.set_sync) {
853
905
  var old_route = bus.route
854
906
  bus.route = function (key, method, arg, t) {
855
- if (method === 'to_set') on_set(arg)
907
+ if (method === 'setter') on_set(arg)
856
908
  return old_route(key, method, arg, t)
857
909
  }
858
910
  } else
859
911
  bus(prefix).on_set_sync = on_set
860
912
 
861
- bus(prefix).to_delete = function (key) {
913
+ bus(prefix).deleter = function (key) {
862
914
  if (opts.use_transactions && !open_transaction){
863
915
  console.time('save db')
864
916
  db.prepare('BEGIN TRANSACTION').run()
@@ -956,7 +1008,7 @@ function import_server (bus, options)
956
1008
  }
957
1009
  pg_set.priority = true
958
1010
  bus(opts.prefix).on_set = pg_set
959
- bus(opts.prefix).to_delete = function (key) {
1011
+ bus(opts.prefix).deleter = function (key) {
960
1012
  db.query('delete from store where key = $1', [key])
961
1013
  }
962
1014
 
@@ -1016,7 +1068,7 @@ function import_server (bus, options)
1016
1068
  bus.usage_log_nots = nots
1017
1069
 
1018
1070
  // Aggregate all accesses by day, to get daily active users
1019
- bus('usage').to_get = () => {
1071
+ bus('usage').getter = () => {
1020
1072
  bus.get('time/' + refresh_interval)
1021
1073
  var days = []
1022
1074
  var last_day
@@ -1055,7 +1107,7 @@ function import_server (bus, options)
1055
1107
  return {_: days}
1056
1108
  }
1057
1109
 
1058
- bus('recent_hits/*').to_get = (rest) => {
1110
+ bus('recent_hits/*').getter = (rest) => {
1059
1111
  bus.get('time/' + refresh_interval)
1060
1112
  var result = []
1061
1113
  for (var row of db.prepare('select * from usage where '
@@ -1071,7 +1123,7 @@ function import_server (bus, options)
1071
1123
  return {_: result}
1072
1124
  }
1073
1125
 
1074
- bus('recent_referers/*').to_get = (rest) => {
1126
+ bus('recent_referers/*').getter = (rest) => {
1075
1127
  bus.get('time/' + refresh_interval)
1076
1128
  var result = []
1077
1129
  for (var row of db.prepare('select * from usage where '
@@ -1120,7 +1172,7 @@ function import_server (bus, options)
1120
1172
  return times
1121
1173
  }
1122
1174
 
1123
- bus('socket_load_times').to_get = () => {
1175
+ bus('socket_load_times').getter = () => {
1124
1176
  return {_: sock_open_times()}
1125
1177
  }
1126
1178
  },
@@ -1132,21 +1184,21 @@ function import_server (bus, options)
1132
1184
  },
1133
1185
 
1134
1186
  time () {
1135
- if (bus('time*').to_get.length > 0)
1187
+ if (bus('time*').getter.length > 0)
1136
1188
  // Then it's already installed
1137
1189
  return
1138
1190
 
1139
1191
  // Time ticker
1140
1192
  var timeouts = {}
1141
1193
  bus('time*', {
1142
- to_get: (key, rest, t) => {
1194
+ getter: (key, rest, t) => {
1143
1195
  if (key === 'time') rest = '/1000'
1144
1196
  timeout = parseInt(rest.substr(1))
1145
1197
  function f () { bus.set.fire({key: key, val: Date.now()}) }
1146
1198
  timeouts[key] = setInterval(f, timeout)
1147
1199
  f()
1148
1200
  },
1149
- to_forget: (key, rest) => {
1201
+ forgetter: (key, rest) => {
1150
1202
  if (key === 'time') key = 'time/1000'
1151
1203
  clearTimeout(timeouts[key])
1152
1204
  }
@@ -1217,8 +1269,8 @@ function import_server (bus, options)
1217
1269
  // - Is there security hole if users have a ? or a / in their name?
1218
1270
  // - Make the master.posts/ state not require /
1219
1271
  // - Make standard url tools for optional slashes, and ? query params
1220
- // - Should a e.g. client to_set abort if it calls set that aborts?
1221
- // - e.g. if master('posts*').to_set aborts
1272
+ // - Should a e.g. client setter abort if it calls set that aborts?
1273
+ // - e.g. if master('posts*').setter aborts
1222
1274
 
1223
1275
  // Helpers
1224
1276
  function get_posts (args) {
@@ -1273,15 +1325,15 @@ function import_server (bus, options)
1273
1325
  // }
1274
1326
 
1275
1327
  // Define state on master
1276
- if (master('posts_for/*').to_get.length === 0) {
1328
+ if (master('posts_for/*').getter.length === 0) {
1277
1329
  // Get posts for each user
1278
- master('posts_for/*').to_get = (json) => {
1330
+ master('posts_for/*').getter = (json) => {
1279
1331
  watch_for_dirt('posts-for/' + json.for)
1280
1332
  return {_: get_posts(json)}
1281
1333
  }
1282
1334
  // Saving any post will dirty the list for all users mentioned in
1283
1335
  // the post
1284
- master('post/*').to_set = (old, New, t) => {
1336
+ master('post/*').setter = (old, New, t) => {
1285
1337
  // To do: diff the cc, to, and from lists, and only dirty
1286
1338
  // posts_for people who have been changed
1287
1339
 
@@ -1307,40 +1359,40 @@ function import_server (bus, options)
1307
1359
  }
1308
1360
 
1309
1361
  function user_addy (u) {
1362
+ console.error('fix this! not ported to v7 links')
1310
1363
  return u.name + '@' + opts.domain
1311
1364
  }
1312
1365
  function current_addy () {
1313
1366
  var c = client.get('current_user')
1314
- return c.logged_in ? user_addy(c.user) : 'public'
1367
+ console.error('fix this! not ported to v7 links')
1368
+ return c.val.logged_in ? user_addy(c.val.user) : 'public'
1315
1369
  }
1316
1370
  function is_author (post) {
1317
1371
  var from = post._.from
1318
- var c = client.get('current_user')
1319
1372
  return from.includes(current_addy())
1320
1373
  }
1321
1374
  function can_see (post) {
1322
- var c = client.get('current_user')
1375
+ console.error('fix this! not ported to v7')
1323
1376
  var allowed = post._.to.concat(post._.cc).concat(post._.from)
1324
1377
  return allowed.includes(current_addy()) || allowed.includes('public')
1325
1378
  }
1326
- var drtbus = master//require('./statebus')()
1379
+ var drtbus = master//make_statebus()
1327
1380
  function dirty (key) { drtbus.set({key: 'dirty-'+key, n: Math.random()}) }
1328
1381
  function watch_for_dirt (key) { drtbus.get('dirty-'+key) }
1329
1382
 
1330
- client('current_email').to_get = () => {
1383
+ client('current_email').getter = () => {
1331
1384
  return {_: current_addy()}
1332
1385
  }
1333
1386
 
1334
1387
  // Define state on client
1335
- client('posts*').to_get = (k, rest) => {
1388
+ client('posts*').getter = (k, rest) => {
1336
1389
  var args = bus.parse(rest.substr(1))
1337
- var c = client.get('current_user')
1338
1390
  args.for = current_addy()
1339
1391
  var e = master.get('posts_for/' + JSON.stringify(args))
1340
1392
  return {_: master.clone(e._).map(x=>client.get(x.key))}
1341
1393
  }
1342
1394
 
1343
- client('post/*').to_get = (k) => {
1395
+ client('post/*').getter = (k) => {
1344
1396
  var e = master.clone(master.get(k))
1345
1397
  if (!e._) return {}
1346
1398
  if (!can_see(e))
@@ -1352,7 +1404,7 @@ function import_server (bus, options)
1352
1404
  return e
1353
1405
  }
1354
1406
 
1355
- client('post/*').to_set = (o, t) => {
1407
+ client('post/*').setter = (o, t) => {
1356
1408
  if (!(client.validate(o, {key: 'string',
1357
1409
  _: {to: 'array',
1358
1410
  cc: 'array',
@@ -1387,7 +1439,7 @@ function import_server (bus, options)
1387
1439
  t.done()
1388
1440
  }
1389
1441
 
1390
- client('post/*').to_delete = (key, o, t) => {
1442
+ client('post/*').deleter = (key, o, t) => {
1391
1443
  // Validate
1392
1444
  if (!is_author(o)) {
1393
1445
  console.error('User', current_addy(),
@@ -1411,14 +1463,14 @@ function import_server (bus, options)
1411
1463
  t.done()
1412
1464
  }
1413
1465
 
1414
- client('friends').to_get = t => {
1415
- return {_: (master.get('users').all||[])
1466
+ client('friends').getter = t => {
1467
+ return {_: (master.get('users').val||[])
1416
1468
  .map(u=>client.get('email/' + user_addy(u)))
1417
1469
  .concat([client.get('email/public')])
1418
1470
  }
1419
1471
  }
1420
1472
 
1421
- client('email/*').to_get = (rest) => {
1473
+ client('email/*').getter = (rest) => {
1422
1474
  var m = rest.match(email_regex)
1423
1475
  var result = {address: rest}
1424
1476
  if (rest === 'public') {
@@ -1441,7 +1493,7 @@ function import_server (bus, options)
1441
1493
 
1442
1494
  sqlite_query_server: function sqlite_query_server (db) {
1443
1495
  var get = bus.get
1444
- bus('table_columns/*').to_get =
1496
+ bus('table_columns/*').getter =
1445
1497
  function get_table_columns (key, rest) {
1446
1498
  if (typeof key !== 'string')
1447
1499
  console.log(handlers.hash)
@@ -1464,7 +1516,7 @@ function import_server (bus, options)
1464
1516
  }
1465
1517
 
1466
1518
 
1467
- bus('table_foreign_keys/*').to_get =
1519
+ bus('table_foreign_keys/*').getter =
1468
1520
  function table_foreign_keys (key, rest) {
1469
1521
  var table_name = rest
1470
1522
  var foreign_keys = get('sql/PRAGMA foreign_key_list(' + table_name + ')').rows
@@ -1476,7 +1528,7 @@ function import_server (bus, options)
1476
1528
  return result
1477
1529
  }
1478
1530
 
1479
- bus('sql/*').to_get =
1531
+ bus('sql/*').getter =
1480
1532
  function sql (key, rest) {
1481
1533
  get('time/60000')
1482
1534
  var query = rest
@@ -1553,7 +1605,7 @@ function import_server (bus, options)
1553
1605
  // ************************
1554
1606
 
1555
1607
  // Getting the whole table, or a single row
1556
- bus(table_name + '*').to_get = function (key, rest) {
1608
+ bus(table_name + '*').getter = function (key, rest) {
1557
1609
  if (rest === '')
1558
1610
  // Return the whole table
1559
1611
  return render_table()
@@ -1573,7 +1625,7 @@ function import_server (bus, options)
1573
1625
  }
1574
1626
 
1575
1627
  // Saving a row
1576
- bus(table_name + '/*').to_set = function (obj, rest) {
1628
+ bus(table_name + '/*').setter = function (obj, rest) {
1577
1629
  var columns = table_columns.columns
1578
1630
  var key = remapped_keys.keys[obj.key] || obj.key
1579
1631
 
@@ -1599,7 +1651,7 @@ function import_server (bus, options)
1599
1651
  }
1600
1652
 
1601
1653
  // Inserting a new row
1602
- bus('new/' + table_name + '/*').to_set = function (obj) {
1654
+ bus('new/' + table_name + '/*').setter = function (obj) {
1603
1655
  var columns = table_columns.columns
1604
1656
  var stmt = ('insert into ' + table_name + ' (' + columns.join(',')
1605
1657
  + ') values (' + new Array(columns.length).join('?,') + '?)')
@@ -1618,7 +1670,7 @@ function import_server (bus, options)
1618
1670
  }
1619
1671
 
1620
1672
  // Deleting a row
1621
- bus(table_name + '/*').to_delete = function (key, rest) {
1673
+ bus(table_name + '/*').deleter = function (key, rest) {
1622
1674
  if (remapped_keys.keys[key]) {
1623
1675
  var old_key = key
1624
1676
  var new_key = remapped_keys.keys[key]
@@ -1640,72 +1692,84 @@ function import_server (bus, options)
1640
1692
 
1641
1693
  serves_auth: function serves_auth (conn, master) {
1642
1694
  var client = this // to keep me straight while programming
1643
-
1644
- function logout (key) {
1695
+ function logout (user_key) {
1645
1696
  var clients = master.get('logged_in_clients')
1646
- for (var k in clients)
1647
- if (k !== 'key')
1648
- if (Object.keys(clients[k]).length === 0) {
1649
- client.log('Found a deleted user. Removing.', k, clients[k])
1650
- delete clients[k]
1651
- master.set(clients)
1652
- } else if (clients[k].key === key) {
1653
- client.log('Logging out!', k, clients[k])
1654
- delete clients[k]
1655
- master.set(clients)
1656
- }
1697
+ clients.val = clients.val || {}
1698
+
1699
+ for (var k in clients.val) {
1700
+ // We used to encounter stray deleted accounts that hadn't
1701
+ // gotten properly garbage collected, and I added some code
1702
+ // here to remove them.
1703
+ //
1704
+ // However, it was a bit kludgy, and I'm rewriting the code
1705
+ // now, and not sure if this problem still occurs. Will watch
1706
+ // and see. Meanwhile, I'm commenting the code out.
1707
+ //
1708
+ // if (Object.keys(clients.val[k]).length === 0) {
1709
+ // client.log('Found a deleted user. Removing.', k, clients.val[k])
1710
+ // delete clients.val[k]
1711
+ // master.set(clients)
1712
+ // }
1713
+ if (clients.val[k].link === user_key) {
1714
+ client.log('Logging out!', k, clients.val[k])
1715
+ delete clients.val[k]
1716
+ master.set(clients)
1717
+ }
1718
+ }
1657
1719
  }
1658
1720
 
1659
1721
  // Initialize master
1660
1722
  if (!master.auth_initialized) {
1661
- master('users/passwords').to_get = function (k) {
1662
- master.log('users/passwords.to_get: Computing!')
1663
- var result = {key: 'users/passwords'}
1723
+
1724
+ // A hash for fast lookup of a user's password
1725
+ master('users/passwords').getter = function (k) {
1726
+ // We compute it from the 'users' state
1727
+ master.log('users/passwords.getter: Computing!')
1728
+ var result = {key: 'users/passwords', val: {}}
1664
1729
  var users = master.get('users')
1665
- users.all = users.all || []
1666
- for (var i=0; i<users.all.length; i++) {
1667
- var u = master.get(users.all[i])
1668
- if (!(u.login || u.name)) {
1669
- console.error('upass: this user has bogus name/login', u.key, u.name, u.login)
1730
+ users.val = users.val || []
1731
+ for (var i=0; i<users.val.length; i++) {
1732
+ var u = master.get(users.val[i].link)
1733
+ if (!(u.val.login || u.val.name)) {
1734
+ console.error('upass: this user has bogus name/login', u.key, u.val.name, u.val.login)
1670
1735
  continue
1671
1736
  }
1672
- var login = (u.login || u.name).toLowerCase()
1737
+ var login = (u.val.login || u.val.name).toLowerCase()
1673
1738
  console.assert(login, 'Missing login for user', u)
1674
- if (result.hasOwnProperty(login)) {
1739
+ if (result.val.hasOwnProperty(login)) {
1675
1740
  console.error("upass: this user's name is bogus, dude.", u.key)
1676
1741
  continue
1677
1742
  }
1678
- result[login] = {user: u.key, pass: u.pass}
1743
+ result.val[login] = {user: u.key, pass: u.val.pass}
1679
1744
  }
1680
1745
  return result
1681
1746
  }
1682
1747
  master.auth_initialized = true
1683
1748
  master.get('users/passwords')
1684
1749
 
1685
- master('user/*').to_delete = (key, t) => {
1750
+ master('user/*').deleter = (key, t) => {
1686
1751
  master.log('Deleteinggg!!!', key)
1687
1752
  // Remove from users.all
1688
1753
  var users = master.get('users')
1689
- users.all = users.all.filter(u => u.key && u.key !== key)
1754
+ users.val = users.val.filter(u => u.link && u.link !== key)
1690
1755
  master.set(users)
1691
1756
 
1692
1757
  // Log out
1693
1758
  master.log('Logging out', key)
1694
1759
  logout(key)
1695
1760
 
1696
- // Remove connection
1697
- master.log('Removing connections for', key)
1698
- var conns = master.get('connections')
1699
- for (var k in conns) {
1700
- console.log('Trying key', k)
1701
- if (k !== 'key')
1702
- if (conns[k].user && !conns[k].user.key) {
1703
- console.log('Cleaning keyless user', conss[k].user)
1704
- delete conns[k].user
1705
- master.set(conns)
1706
- continue
1707
- }
1708
- }
1761
+ // // Remove connection
1762
+ // master.log('Removing connections for', key)
1763
+ // var conns = master.get('connections')
1764
+ // for (var k in conns.val) {
1765
+ // console.log('Trying key', k)
1766
+ // if (conns.val[k].user && !conns.val[k].user.key) {
1767
+ // console.log('Cleaning keyless user', conss.val[k].user)
1768
+ // delete conns.val[k].user
1769
+ // master.set(conns)
1770
+ // continue
1771
+ // }
1772
+ // }
1709
1773
 
1710
1774
  master.log('Dirtying users/passwords for', key)
1711
1775
  master.dirty('users/passwords')
@@ -1717,9 +1781,9 @@ function import_server (bus, options)
1717
1781
 
1718
1782
  // Authentication functions
1719
1783
  function authenticate (login, pass) {
1720
- var userpass = master.get('users/passwords')[login.toLowerCase()]
1784
+ var userpass = master.get('users/passwords').val[login.toLowerCase()]
1721
1785
  master.log('authenticate: we see', {
1722
- passwords: master.get('users/passwords'),
1786
+ passwords: master.get('users/passwords').val,
1723
1787
  hash_to_match: userpass && userpass.pass,
1724
1788
  password_guess: pass
1725
1789
  })
@@ -1730,7 +1794,7 @@ function import_server (bus, options)
1730
1794
 
1731
1795
  // console.log('comparing passwords', pass, userpass.pass)
1732
1796
  if (require('bcrypt-nodejs').compareSync(pass, userpass.pass))
1733
- return master.get(userpass.user)
1797
+ return userpass.user
1734
1798
  }
1735
1799
  function create_account (params) {
1736
1800
  if (typeof (params.login || params.name) !== 'string')
@@ -1743,7 +1807,7 @@ function import_server (bus, options)
1743
1807
  throw 'invalid name, login, pass, or email'
1744
1808
 
1745
1809
  var passes = master.get('users/passwords')
1746
- if (passes.hasOwnProperty(login))
1810
+ if (passes.val.hasOwnProperty(login))
1747
1811
  throw 'there is already a user with that login or name'
1748
1812
 
1749
1813
  // Hash password
@@ -1763,60 +1827,81 @@ function import_server (bus, options)
1763
1827
  key = 'user/' + Math.random().toString(36).substring(7,13)
1764
1828
 
1765
1829
  // Make account object
1766
- var new_account = {key: key,
1767
- name: params.name,
1768
- login: params.login,
1769
- pass: params.pass,
1770
- email: params.email }
1771
- for (var k in new_account) if (!new_account[k]) delete new_account[k]
1830
+ var new_account = {
1831
+ key: key, val: {
1832
+ name: params.name,
1833
+ login: params.login,
1834
+ pass: params.pass,
1835
+ email: params.email
1836
+ }
1837
+ }
1838
+ for (var k in new_account.val) // Clean out falsy fields
1839
+ if (!new_account.val[k])
1840
+ delete new_account.val[k]
1772
1841
  master.set(new_account)
1773
1842
 
1774
1843
  var users = master.get('users')
1775
- users.all = users.all || []
1776
- users.all.push(new_account)
1777
- passes[login] = {user: new_account.key, pass: new_account.pass}
1844
+ users.val = users.val || []
1845
+ users.val.push({link: new_account.key})
1846
+ passes.val[login] = {user: new_account.key, pass: new_account.val.pass}
1778
1847
  master.set(users)
1779
1848
  master.set(passes)
1780
1849
  }
1781
1850
 
1782
1851
  // Current User
1783
- client('current_user').to_get = function (k) {
1784
- client.log('* getting: current_user')
1785
- if (!conn.client) return
1786
- var u = master.get('logged_in_clients')[conn.client]
1787
- u = u && user_obj(u.key, true)
1788
- return {user: u || null, logged_in: !!u}
1852
+ client('current_user').getter = function (k) {
1853
+ if (!conn.client)
1854
+ return {val: {error: 'no client'}}
1855
+
1856
+ var u = (master.get('logged_in_clients').val || {})[conn.client]
1857
+ var result = {val: {user: u || null, logged_in: !!u}}
1858
+ return result
1789
1859
  }
1790
1860
 
1791
- client('current_user').to_set = function (o, t) {
1861
+ client('current_user').setter = function (o, t) {
1862
+ var val = o.val
1863
+ if (typeof val !== 'object') {
1864
+ console.error('current_user: set to something not an object:', val)
1865
+ t.abort()
1866
+ return
1867
+ }
1792
1868
  function error (msg) {
1869
+ console.error(msg)
1793
1870
  client.set.abort(o)
1794
1871
  var c = client.get('current_user')
1795
- c.error = msg
1872
+ c.val.error = msg
1796
1873
  client.set.fire(c)
1797
1874
  }
1798
1875
 
1799
1876
  client.log('* saving: current_user!')
1800
- if (o.client && !conn.client) {
1877
+ if (val.client && !conn.client) {
1801
1878
  // Set the client
1802
- conn.client = o.client
1803
- client.client_id = o.client
1879
+ //
1880
+ // Note: Should this code be moved upstream, when creating a
1881
+ // client bus?
1882
+ conn.client = val.client
1883
+ client.client_id = val.client
1804
1884
  client.client_ip = conn.remoteAddress
1805
1885
 
1806
- if (conn.id) {
1807
- var connections = master.get('connections')
1808
- connections[conn.id].user = master.get('logged_in_clients')[conn.client]
1809
- master.set(connections)
1810
- }
1886
+ // if (conn.id) {
1887
+ // var connections = master.get('connections')
1888
+ // var logged_in_user =
1889
+ // (master.get('logged_in_clients').val || {})[conn.client]
1890
+
1891
+ // if (logged_in_user) {
1892
+ // connections.val[conn.id].user = {link: user.link}
1893
+ // master.set(connections)
1894
+ // }
1895
+ // }
1811
1896
  }
1812
1897
  else {
1813
- if (o.create_account) {
1898
+ if (val.create_account) {
1814
1899
  client.log('current_user: creating account')
1815
1900
  try {
1816
- create_account(o.create_account)
1901
+ create_account(val.create_account)
1817
1902
  client.log('Success creating account!')
1818
1903
  var cu = client.get('current_user')
1819
- cu.create_account = null
1904
+ cu.val.create_account = null
1820
1905
  client.set.fire(cu)
1821
1906
  } catch (e) {
1822
1907
  error('Cannot create that account because ' + e)
@@ -1824,29 +1909,29 @@ function import_server (bus, options)
1824
1909
  }
1825
1910
  }
1826
1911
 
1827
- if (o.login_as && conn.id) {
1912
+ if (val.login_as) {
1828
1913
  // Then client is trying to log in
1829
- client.log('current_user: trying to log in')
1830
- var creds = o.login_as
1914
+ var creds = val.login_as
1831
1915
  var login = creds.login || creds.name
1832
1916
  if (login && creds.pass) {
1833
1917
  // With a username and password
1834
- var u = authenticate(login, creds.pass)
1918
+ var user_key = authenticate(login, creds.pass)
1835
1919
 
1836
- client.log('auth said:', u)
1837
- if (u) {
1920
+ client.log('auth said:', user_key)
1921
+ if (user_key) {
1838
1922
  // Success!
1839
1923
  // Associate this user with this session
1840
1924
  // user.log('Logging the user in!', u)
1841
1925
 
1842
1926
  var clients = master.get('logged_in_clients')
1843
- var connections = master.get('connections')
1927
+ // var connections = master.get('connections')
1844
1928
 
1845
- clients[conn.client] = u
1846
- connections[conn.id].user = u
1929
+ clients.val = clients.val || {}
1930
+ clients.val[conn.client] = {link: user_key}
1931
+ // connections.val[conn.id].user = {link: user_key}
1847
1932
 
1848
1933
  master.set(clients)
1849
- master.set(connections)
1934
+ // master.set(connections)
1850
1935
 
1851
1936
  client.log('current_user: success logging in!')
1852
1937
  }
@@ -1861,38 +1946,41 @@ function import_server (bus, options)
1861
1946
  }
1862
1947
  }
1863
1948
 
1864
- else if (o.logout && conn.id) {
1949
+ else if (val.logout) {
1865
1950
  client.log('current_user: logging out')
1866
1951
  var clients = master.get('logged_in_clients')
1867
- var connections = master.get('connections')
1952
+ // var connections = master.get('connections')
1868
1953
 
1869
- delete clients[conn.client]
1870
- connections[conn.id].user = null
1954
+ clients.val = clients.val || {}
1955
+ delete clients.val[conn.client]
1956
+ // connections.val[conn.id].user = null
1871
1957
 
1872
1958
  master.set(clients)
1873
- master.set(connections)
1959
+ // master.set(connections)
1874
1960
  }
1875
1961
  }
1876
1962
 
1877
1963
  t.reget()
1878
1964
  }
1879
- client('current_user').to_delete = function () {}
1965
+ client('current_user').deleter = function () {}
1880
1966
 
1881
1967
  // Users have closet space at /user/<name>/*
1882
1968
  var closet_space_key = /^(user\/[^\/]+)\/.*/
1883
1969
  var private_closet_space_key = /^user\/[^\/]+\/private.*/
1884
1970
 
1885
1971
  // User
1886
- client('user/*').to_set = function (o, t) {
1972
+ client('user/*').setter = function (o, t) {
1887
1973
  var c = client.get('current_user')
1888
1974
  var user_key = o.key.match(/^user\/([^\/]+)/)
1889
1975
  user_key = user_key && ('user/' + user_key[1])
1890
1976
 
1891
- // Only the current user can touch themself.
1892
- if (!c.logged_in || c.user.key !== user_key) {
1893
- client.log('Only the current user can touch themself.',
1894
- {logged_in: c.logged_in, as: c.user && c.user.key,
1895
- touching: user_key})
1977
+ // Only the current user can touch himself.
1978
+ if (!c.val.logged_in || c.val.user.link !== user_key) {
1979
+ client.log('Only the current user can touch himself.', {
1980
+ logged_in: c.val.logged_in,
1981
+ as: c.val.user && c.val.user.link,
1982
+ touching: user_key
1983
+ })
1896
1984
  client.set.abort(o)
1897
1985
  return
1898
1986
  }
@@ -1908,9 +1996,14 @@ function import_server (bus, options)
1908
1996
  console.assert(o.key.match(/^user\/[^\/]+$/))
1909
1997
 
1910
1998
  // Validate types
1911
- if (!client.validate(o, {key: 'string', '?login': 'string', '?name': 'string',
1912
- '?pass': 'string', '?email': 'string', /*'?pic': 'string',*/
1913
- '*':'*'})) {
1999
+ if (!client.validate(o, {key: 'string',
2000
+ val: {
2001
+ '?login': 'string',
2002
+ '?name': 'string',
2003
+ '?pass': 'string',
2004
+ '?email': 'string',
2005
+ /*'?pic': 'string',*/
2006
+ '*':'*'}})) {
1914
2007
  client.log('This user change fails validation.')
1915
2008
  client.set.abort(o)
1916
2009
  return
@@ -1921,7 +2014,7 @@ function import_server (bus, options)
1921
2014
  // • That resulting login must be unique across all users
1922
2015
 
1923
2016
  // There must be at least a login or a name
1924
- var login = o.login || o.name
2017
+ var login = o.val.login || o.val.name
1925
2018
  if (!login) {
1926
2019
  client.log('User must have a login or a name')
1927
2020
  client.set.abort(o)
@@ -1932,26 +2025,26 @@ function import_server (bus, options)
1932
2025
  var userpass = master.get('users/passwords')
1933
2026
 
1934
2027
  // Validate that the login/name is not changed to something clobberish
1935
- var old_login = u.login || u.name
2028
+ var old_login = u.val.login || u.val.name
1936
2029
  if (old_login.toLowerCase() !== login.toLowerCase()
1937
2030
  && userpass.hasOwnProperty(login)) {
1938
2031
  client.log('The login', login, 'is already taken. Aborting.')
1939
2032
  client.set.abort(o) // Abort
1940
2033
 
1941
2034
  o = client.get(o.key) // Add error message
1942
- o.error = 'The login "' + login + '" is already taken'
2035
+ o.val.error = 'The login "' + login + '" is already taken'
1943
2036
  client.set.fire(o)
1944
2037
 
1945
2038
  return // And exit
1946
2039
  }
1947
2040
 
1948
2041
  // Now we can update login and name
1949
- u.login = o.login
1950
- u.name = o.name
2042
+ u.val.login = o.val.login
2043
+ u.val.name = o.val.name
1951
2044
 
1952
2045
  // Hash password
1953
- o.pass = o.pass && require('bcrypt-nodejs').hashSync(o.pass)
1954
- u.pass = o.pass || u.pass
2046
+ o.val.pass = o.val.pass && require('bcrypt-nodejs').hashSync(o.val.pass)
2047
+ u.val.pass = o.val.pass || u.val.pass
1955
2048
 
1956
2049
  // // Users can have pictures (remove this soon)
1957
2050
  // // Bug: if user changes name, this picture's url doesn't change.
@@ -1970,24 +2063,24 @@ function import_server (bus, options)
1970
2063
 
1971
2064
  // For anything else, go ahead and add it to the user object
1972
2065
  var protected = {key:1, name:1, /*pic:1,*/ pass:1}
1973
- for (var k in o)
2066
+ for (var k in o.val)
1974
2067
  if (!protected.hasOwnProperty(k))
1975
- u[k] = o[k]
1976
- for (var k in u)
1977
- if (!protected.hasOwnProperty(k) && !o.hasOwnProperty(k))
1978
- delete u[k]
2068
+ u.val[k] = o.val[k]
2069
+ for (var k in u.val)
2070
+ if (!protected.hasOwnProperty(k) && !o.val.hasOwnProperty(k))
2071
+ delete u.val[k]
1979
2072
 
1980
2073
  master.set(u)
1981
2074
  }
1982
- client('user/*').to_get = function user_getter (k) {
2075
+ client('user/*').getter = function user_getter (k) {
1983
2076
  var c = client.get('current_user')
1984
- client.log('* getting:', k, 'as', c.user)
2077
+ client.log('* getting:', k, 'as', c.val.user)
1985
2078
 
1986
2079
  // Users have closet space at /user/<name>/*
1987
2080
  if (k.match(closet_space_key)) {
1988
2081
  var obj_user = k.match(closet_space_key)[1]
1989
2082
  if (k.match(private_closet_space_key)
1990
- && (!c.user || obj_user !== c.user.key)) {
2083
+ && (!c.val.user || obj_user !== c.val.user.link)) {
1991
2084
  client.log('hiding private closet data')
1992
2085
  return {}
1993
2086
  }
@@ -1996,26 +2089,27 @@ function import_server (bus, options)
1996
2089
  }
1997
2090
 
1998
2091
  // Otherwise return the actual user
1999
- return user_obj(k, c.logged_in && c.user.key === k)
2092
+ return user_obj(k, c.val.logged_in && c.val.user.link === k)
2000
2093
  }
2001
- client('user/*').to_delete = function () {}
2094
+ client('user/*').deleter = function () {}
2002
2095
  function user_obj (k, logged_in) {
2003
2096
  var o = master.clone(master.get(k))
2004
2097
  if (k.match(/^user\/([^\/]+)\/private\/(.*)$/))
2005
2098
  return logged_in ? o : {key: k}
2006
-
2007
- delete o.pass
2008
- if (!logged_in) {delete o.email; delete o.login}
2099
+
2100
+ o.val = o.val || {}
2101
+ delete o.val.pass
2102
+ if (!logged_in) {delete o.val.email; delete o.val.login}
2009
2103
  return o
2010
2104
  }
2011
2105
 
2012
2106
  // Blacklist sensitive stuff on master, in case we have a shadow set up
2013
2107
  var blacklist = 'users users/passwords logged_in_clients'.split(' ')
2014
2108
  for (var i=0; i<blacklist.length; i++) {
2015
- client(blacklist[i]).to_get = function () {}
2016
- client(blacklist[i]).to_set = function () {}
2017
- client(blacklist[i]).to_delete = function () {}
2018
- client(blacklist[i]).to_forget = function () {}
2109
+ client(blacklist[i]).getter = function () {}
2110
+ client(blacklist[i]).setter = function () {}
2111
+ client(blacklist[i]).deleter = function () {}
2112
+ client(blacklist[i]).forgetter = function () {}
2019
2113
  }
2020
2114
  },
2021
2115
 
@@ -2024,14 +2118,14 @@ function import_server (bus, options)
2024
2118
  var was_logged_in = undefined
2025
2119
 
2026
2120
  function client_prefix (current_user) {
2027
- return 'client/' + (current_user.logged_in
2028
- ? current_user.user.key.substr('user/'.length)
2121
+ return 'client/' + (current_user.val.logged_in
2122
+ ? current_user.val.user.link.substr('user/'.length)
2029
2123
  : client.client_id) + '/'
2030
2124
  }
2031
2125
 
2032
- function copy_client_to_user(client, user) {
2126
+ function copy_client_to_user(client, user_key) {
2033
2127
  var old_prefix = 'client/' + client.client_id
2034
- var new_prefix = 'client/' + user.key.substr('user/'.length)
2128
+ var new_prefix = 'client/' + user_key.substr('user/'.length)
2035
2129
 
2036
2130
  var keys = client.master.get('persisted_keys/' + client.client_id)
2037
2131
  if (!keys.val) return
@@ -2077,13 +2171,13 @@ function import_server (bus, options)
2077
2171
  client(_=>{
2078
2172
  var c = client.get('current_user')
2079
2173
  if (client.loading()) return
2080
- if (was_logged_in == false && c.logged_in)
2174
+ if (was_logged_in == false && c.val.logged_in)
2081
2175
  // User just logged in! Let's copy his stuff over
2082
- copy_client_to_user(client, c.user)
2083
- was_logged_in = c.logged_in
2176
+ copy_client_to_user(client, c.val.user.link)
2177
+ was_logged_in = c.val.logged_in
2084
2178
  })
2085
2179
 
2086
- client(prefix_to_sync).to_get = function (key) {
2180
+ client(prefix_to_sync).getter = function (key) {
2087
2181
  var c = client.get('current_user')
2088
2182
  if (client.loading()) return
2089
2183
  var prefix = client_prefix(c)
@@ -2100,7 +2194,7 @@ function import_server (bus, options)
2100
2194
  return obj
2101
2195
  }
2102
2196
 
2103
- client(prefix_to_sync).to_set = function (obj) {
2197
+ client(prefix_to_sync).setter = function (obj) {
2104
2198
  if (validate && !validate(obj)) {
2105
2199
  console.warn('Validation failed on', obj)
2106
2200
  client.set.abort(obj)
@@ -2128,7 +2222,7 @@ function import_server (bus, options)
2128
2222
  p_keys && client.master.set(p_keys)
2129
2223
  }
2130
2224
 
2131
- client(prefix_to_sync).to_delete = function (k) {
2225
+ client(prefix_to_sync).deleter = function (k) {
2132
2226
  k = client_prefix(client.get('current_user')) + k
2133
2227
  client.master.delete(k)
2134
2228
 
@@ -2138,7 +2232,7 @@ function import_server (bus, options)
2138
2232
  }
2139
2233
 
2140
2234
  function client_persisted_keys () {
2141
- if (client.get('current_user').logged_in) return
2235
+ if (client.get('current_user').val.logged_in) return
2142
2236
  var result = client.master.get('persisted_keys/' + client.client_id)
2143
2237
  if (result && !result.val) result.val = {}
2144
2238
  return result
@@ -2154,19 +2248,19 @@ function import_server (bus, options)
2154
2248
  // to the global cache
2155
2249
  if (count === 0) {
2156
2250
  count++
2157
- if (method === 'to_get')
2251
+ if (method === 'getter')
2158
2252
  bus.run_handler(function get_from_master (k) {
2159
2253
  // console.log('DEFAULT GETting', k)
2160
2254
  var r = master_bus.get(k)
2161
2255
  // console.log('DEFAULT GETted', r)
2162
2256
  bus.set.fire(r, {version: master_bus.versions[r.key]})
2163
2257
  }, method, arg)
2164
- else if (method === 'to_set')
2258
+ else if (method === 'setter')
2165
2259
  bus.run_handler(function set_to_master (o, t) {
2166
2260
  // console.log('DEFAULT ROUTE', t)
2167
2261
  master_bus.set(bus.clone(o), t)
2168
2262
  }, method, arg, {t: t})
2169
- else if (method == 'to_delete')
2263
+ else if (method == 'deleter')
2170
2264
  bus.run_handler(function delete_from_master (k, t) {
2171
2265
  master_bus.delete(k)
2172
2266
  return 'done'
@@ -2220,7 +2314,7 @@ function import_server (bus, options)
2220
2314
  // file or recursive directory structure at fs_path
2221
2315
  sync_files: function sync_files (state_path, file_path) {
2222
2316
  // To do:
2223
- // - Hook up a to_delete handler
2317
+ // - Hook up a deleter handler
2224
2318
  // - recursively remove directories if all files gone
2225
2319
 
2226
2320
  console.assert(state_path.substr(-1) !== '*'
@@ -2231,7 +2325,7 @@ function import_server (bus, options)
2231
2325
  var buffer = {}
2232
2326
  var full_file_path = require('path').join(__dirname, file_path)
2233
2327
 
2234
- bus(state_path + '*').to_get = (rest) => {
2328
+ bus(state_path + '*').getter = (rest) => {
2235
2329
  // We DO want to handle:
2236
2330
  // - "foo"
2237
2331
  // - "foo/*"
@@ -2257,7 +2351,7 @@ function import_server (bus, options)
2257
2351
  return {_:f}
2258
2352
  }
2259
2353
 
2260
- bus(state_path + '/*').to_set = (o, rest, t) => {
2354
+ bus(state_path + '/*').setter = (o, rest, t) => {
2261
2355
  if (rest.length>0 && rest[0] !== '/') return
2262
2356
  var f = Buffer.from(o._, 'base64')
2263
2357
  require('fs').writeFile(file_path + rest, f,
@@ -2271,10 +2365,10 @@ function import_server (bus, options)
2271
2365
  // Installs a GET handler at route that gets state from a getter function
2272
2366
  // Note: Makes too many textbusses. Should re-use one.
2273
2367
  http_serve: function http_serve (route, getter) {
2274
- var textbus = require('./statebus')()
2368
+ var textbus = make_statebus()
2275
2369
  textbus.label = 'textbus'
2276
2370
  var watched = new Set()
2277
- textbus('*').to_get = (filename, old) => {
2371
+ textbus('*').getter = (filename, old) => {
2278
2372
  return {etag: Math.random() + '',
2279
2373
  _: getter(filename)}
2280
2374
  }
@@ -2350,7 +2444,7 @@ function import_server (bus, options)
2350
2444
  },
2351
2445
 
2352
2446
  serve_wiki: () => {
2353
- bus('edit/*').to_get = () => ({_: require('./extras/wiki.coffee').code})
2447
+ bus('edit/*').getter = () => ({_: require('./extras/wiki.coffee').code})
2354
2448
  },
2355
2449
 
2356
2450
  unix_socket_repl: function (filename) {
@@ -2497,7 +2591,7 @@ module.exports.import_module = function (statebus) {
2497
2591
 
2498
2592
  statebus.serve = function serve (options) {
2499
2593
  var bus = statebus()
2500
- require('./servers').run_server(bus, options)
2594
+ require('./server-library').run_server(bus, options)
2501
2595
  return bus
2502
2596
  }
2503
2597