statebus 7.0.3 → 7.0.6

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,33 +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
177
  // We only return JSON
186
178
  res.setHeader('Content-Type', 'application/json')
187
179
 
188
- // Do the get
189
- // cbus.honk = 'statelog'
190
- var key = req.path.substr(1)
191
- cbus.get(key, cb = (o) => {
192
- var body = to_http_body(o)
180
+ // console.log('http_in: doing cbus.get(', key, ')')
193
181
 
194
- // If we're braiding, send via subscription
182
+ var send_to_client = (o, t) => {
183
+ // console.trace('http_in: Sending update of', key)
184
+ var body = to_http_body(o)
195
185
 
196
186
  // Note: if body === undefined, we need to send the
197
187
  // equivalent of a 404. This is missing in braid spec:
@@ -200,14 +190,35 @@ function import_server (bus, options)
200
190
 
201
191
  // And shut down the connection if there's no subscription
202
192
  if (!req.subscribe)
203
- end_it_all()
204
- })
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)
205
219
  }
206
220
 
207
221
  else if (req.method === 'PUT') {
208
- // Make a temporary client bus
209
- var cbus = bus.bus_for_http_client(req, res)
210
-
211
222
  // Maybe the new state is expressed in patches
212
223
  if (req.headers.patches) {
213
224
  console.error("We don't actually handle PUT patches yet")
@@ -234,9 +245,31 @@ function import_server (bus, options)
234
245
  res.end()
235
246
  return
236
247
  }
237
- 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
+
238
270
  res.statusCode = 200
239
271
  res.end()
272
+ cbus.http_unsubscribe(req)
240
273
  })
241
274
  }
242
275
  }
@@ -246,16 +279,39 @@ function import_server (bus, options)
246
279
 
247
280
  bus_for_http_client: function (req, res) {
248
281
  var bus = this
249
- if (!bus.bus_for_http_client.counter)
282
+ if (!bus.bus_for_http_client.counter) {
250
283
  bus.bus_for_http_client.counter = 0
251
- 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()
252
298
  cbus.label = 'client_http' + bus.bus_for_http_client.counter++
253
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
254
310
 
255
- // Log in as the client
311
+ // And log into it as the client
256
312
  cbus.serves_auth({remoteAddress: req.connection.remoteAddress}, bus)
257
313
  bus.options.client(cbus)
258
- cbus.set({key: 'current_user', client: req.client})
314
+ cbus.set({key: 'current_user', val: {client: req.peer}})
259
315
  return cbus
260
316
  },
261
317
 
@@ -358,7 +414,7 @@ function import_server (bus, options)
358
414
  // var client_busses = {} // XXX work in progress
359
415
  var log = master.log
360
416
  if (client_bus_func) {
361
- master.set({key: 'connections'}) // Clean out old sessions
417
+ master.set({key: 'connections', val: {}}) // Clean out old sessions
362
418
  var connections = master.get('connections')
363
419
  }
364
420
  var s = require('sockjs').createServer({
@@ -376,11 +432,11 @@ function import_server (bus, options)
376
432
  // - When disconnecting, decrement the number, and if it gets
377
433
  // to zero, delete the client bus.
378
434
 
379
- connections[conn.id] = {client: conn.id, // client is deprecated
380
- id: conn.id}
435
+ connections.val[conn.id] = {client: conn.id, // client is deprecated
436
+ id: conn.id}
381
437
  master.set(connections)
382
438
 
383
- var client = require('./statebus')()
439
+ var client = make_statebus()
384
440
  client.label = 'client' + client_num++
385
441
  master.label = master.label || 'master'
386
442
  client.master = master
@@ -489,7 +545,7 @@ function import_server (bus, options)
489
545
  for (var key in our_gets_in)
490
546
  client.forget(key, sockjs_pubber)
491
547
  if (client_bus_func) {
492
- delete connections[conn.id]; master.set(connections)
548
+ delete connections.val[conn.id]; master.set(connections)
493
549
  master.delete('connection/' + conn.id)
494
550
  client.delete_bus()
495
551
  }
@@ -499,7 +555,7 @@ function import_server (bus, options)
499
555
  if (client_bus_func && !master.options.__secure) {
500
556
 
501
557
  // A connection
502
- client('connection/*').to_get = function (key, star) {
558
+ client('connection/*').getter = function (key, star) {
503
559
  var result = bus.clone(master.get(key))
504
560
  if (master.options.connections.include_users && result.user)
505
561
  result.user = client.get(result.user.key)
@@ -507,7 +563,7 @@ function import_server (bus, options)
507
563
  result.client = star // Deprecated. Delete this line in v7.
508
564
  return result
509
565
  }
510
- client('connection/*').to_set = function (o, star, t) {
566
+ client('connection/*').setter = function (o, star, t) {
511
567
  // Check permissions before editing
512
568
  if (star !== conn.id && !master.options.connections.edit_others) {
513
569
  t.abort()
@@ -519,7 +575,7 @@ function import_server (bus, options)
519
575
  }
520
576
 
521
577
  // Your connection
522
- client('connection').to_get = function () {
578
+ client('connection').getter = function () {
523
579
  // subscribe to changes in authentication
524
580
  client.get('current_user')
525
581
 
@@ -527,22 +583,22 @@ function import_server (bus, options)
527
583
  delete result.key
528
584
  return result
529
585
  }
530
- client('connection').to_set = function (o) {
586
+ client('connection').setter = function (o) {
531
587
  o = client.clone(o)
532
588
  o.key = 'connection/' + conn.id
533
589
  client.set(o)
534
590
  }
535
591
 
536
592
  // All connections
537
- client('connections').to_set = function noop (t) {t.abort()}
538
- client('connections').to_get = function () {
593
+ client('connections').setter = function noop (t) {t.abort()}
594
+ client('connections').getter = function () {
539
595
  var result = []
540
- var conns = master.get('connections')
596
+ var conns = master.get('connections').val
541
597
  for (var connid in conns)
542
598
  if (connid !== 'key')
543
599
  result.push(client.get('connection/' + connid))
544
600
 
545
- return {all: result}
601
+ return {val: result}
546
602
  }
547
603
  }
548
604
  })
@@ -558,13 +614,6 @@ function import_server (bus, options)
558
614
  WebSocket = require('websocket').w3cwebsocket
559
615
  return new WebSocket(url + '/' + bus.options.websocket_path + '/websocket')
560
616
  },
561
- client_creds: function client_creds (server_url) {
562
- // Right now the server just creates a different random id each time
563
- // it connects.
564
- return {clientid: (Math.random().toString(36).substring(2)
565
- + Math.random().toString(36).substring(2)
566
- + Math.random().toString(36).substring(2))}
567
- },
568
617
 
569
618
  file_store: (function () {
570
619
  // Make a database
@@ -646,7 +695,7 @@ function import_server (bus, options)
646
695
  }
647
696
  on_set.priority = true
648
697
  bus(prefix).on_set = on_set
649
- bus(prefix).to_delete = function (key) {
698
+ bus(prefix).deleter = function (key) {
650
699
  delete db[key]
651
700
  if (active) save_later()
652
701
  }
@@ -712,7 +761,7 @@ function import_server (bus, options)
712
761
  return decodeURIComponent(k.replace('%2E', '.'))
713
762
  }
714
763
 
715
- bus(prefix).to_get = function (key, t) {
764
+ bus(prefix).getter = function (key, t) {
716
765
  firebase_ref.child(encode_firebase_key(key)).on('value', function (x) {
717
766
  t.done(x.val() || {})
718
767
  }, function (err) { t.abort() })
@@ -722,19 +771,19 @@ function import_server (bus, options)
722
771
  firebase_ref.child(encode_firebase_key(o.key)).set(o)
723
772
  }
724
773
 
725
- // bus(prefix).to_set = function (o, t) {
774
+ // bus(prefix).setter = function (o, t) {
726
775
  // firebase_ref.child(encode_firebase_key(o.key)).set(o, (err) => {
727
776
  // err ? t.abort() : t.done()
728
777
  // })
729
778
  // }
730
779
 
731
- bus(prefix).to_delete = function (key, t) {
780
+ bus(prefix).deleter = function (key, t) {
732
781
  firebase_ref.child(encode_firebase_key(key)).set(null, (err) => {
733
782
  err ? t.abort() : t.done()
734
783
  })
735
784
  }
736
785
 
737
- bus(prefix).to_forget = function (key, t) {
786
+ bus(prefix).forgetter = function (key, t) {
738
787
  firebase_ref.child(encode_firebase_key(key)).off()
739
788
  }
740
789
  },
@@ -826,7 +875,7 @@ function import_server (bus, options)
826
875
  : o))
827
876
 
828
877
  // Publish this to the bus
829
- bus.set.fire(obj, {to_get: true})
878
+ bus.set.fire(obj, {getter: true})
830
879
  })
831
880
  }
832
881
 
@@ -855,13 +904,13 @@ function import_server (bus, options)
855
904
  if (opts.set_sync) {
856
905
  var old_route = bus.route
857
906
  bus.route = function (key, method, arg, t) {
858
- if (method === 'to_set') on_set(arg)
907
+ if (method === 'setter') on_set(arg)
859
908
  return old_route(key, method, arg, t)
860
909
  }
861
910
  } else
862
911
  bus(prefix).on_set_sync = on_set
863
912
 
864
- bus(prefix).to_delete = function (key) {
913
+ bus(prefix).deleter = function (key) {
865
914
  if (opts.use_transactions && !open_transaction){
866
915
  console.time('save db')
867
916
  db.prepare('BEGIN TRANSACTION').run()
@@ -959,7 +1008,7 @@ function import_server (bus, options)
959
1008
  }
960
1009
  pg_set.priority = true
961
1010
  bus(opts.prefix).on_set = pg_set
962
- bus(opts.prefix).to_delete = function (key) {
1011
+ bus(opts.prefix).deleter = function (key) {
963
1012
  db.query('delete from store where key = $1', [key])
964
1013
  }
965
1014
 
@@ -1019,7 +1068,7 @@ function import_server (bus, options)
1019
1068
  bus.usage_log_nots = nots
1020
1069
 
1021
1070
  // Aggregate all accesses by day, to get daily active users
1022
- bus('usage').to_get = () => {
1071
+ bus('usage').getter = () => {
1023
1072
  bus.get('time/' + refresh_interval)
1024
1073
  var days = []
1025
1074
  var last_day
@@ -1058,7 +1107,7 @@ function import_server (bus, options)
1058
1107
  return {_: days}
1059
1108
  }
1060
1109
 
1061
- bus('recent_hits/*').to_get = (rest) => {
1110
+ bus('recent_hits/*').getter = (rest) => {
1062
1111
  bus.get('time/' + refresh_interval)
1063
1112
  var result = []
1064
1113
  for (var row of db.prepare('select * from usage where '
@@ -1074,7 +1123,7 @@ function import_server (bus, options)
1074
1123
  return {_: result}
1075
1124
  }
1076
1125
 
1077
- bus('recent_referers/*').to_get = (rest) => {
1126
+ bus('recent_referers/*').getter = (rest) => {
1078
1127
  bus.get('time/' + refresh_interval)
1079
1128
  var result = []
1080
1129
  for (var row of db.prepare('select * from usage where '
@@ -1123,7 +1172,7 @@ function import_server (bus, options)
1123
1172
  return times
1124
1173
  }
1125
1174
 
1126
- bus('socket_load_times').to_get = () => {
1175
+ bus('socket_load_times').getter = () => {
1127
1176
  return {_: sock_open_times()}
1128
1177
  }
1129
1178
  },
@@ -1135,21 +1184,21 @@ function import_server (bus, options)
1135
1184
  },
1136
1185
 
1137
1186
  time () {
1138
- if (bus('time*').to_get.length > 0)
1187
+ if (bus('time*').getter.length > 0)
1139
1188
  // Then it's already installed
1140
1189
  return
1141
1190
 
1142
1191
  // Time ticker
1143
1192
  var timeouts = {}
1144
1193
  bus('time*', {
1145
- to_get: (key, rest, t) => {
1194
+ getter: (key, rest, t) => {
1146
1195
  if (key === 'time') rest = '/1000'
1147
1196
  timeout = parseInt(rest.substr(1))
1148
1197
  function f () { bus.set.fire({key: key, val: Date.now()}) }
1149
1198
  timeouts[key] = setInterval(f, timeout)
1150
1199
  f()
1151
1200
  },
1152
- to_forget: (key, rest) => {
1201
+ forgetter: (key, rest) => {
1153
1202
  if (key === 'time') key = 'time/1000'
1154
1203
  clearTimeout(timeouts[key])
1155
1204
  }
@@ -1220,8 +1269,8 @@ function import_server (bus, options)
1220
1269
  // - Is there security hole if users have a ? or a / in their name?
1221
1270
  // - Make the master.posts/ state not require /
1222
1271
  // - Make standard url tools for optional slashes, and ? query params
1223
- // - Should a e.g. client to_set abort if it calls set that aborts?
1224
- // - 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
1225
1274
 
1226
1275
  // Helpers
1227
1276
  function get_posts (args) {
@@ -1276,15 +1325,15 @@ function import_server (bus, options)
1276
1325
  // }
1277
1326
 
1278
1327
  // Define state on master
1279
- if (master('posts_for/*').to_get.length === 0) {
1328
+ if (master('posts_for/*').getter.length === 0) {
1280
1329
  // Get posts for each user
1281
- master('posts_for/*').to_get = (json) => {
1330
+ master('posts_for/*').getter = (json) => {
1282
1331
  watch_for_dirt('posts-for/' + json.for)
1283
1332
  return {_: get_posts(json)}
1284
1333
  }
1285
1334
  // Saving any post will dirty the list for all users mentioned in
1286
1335
  // the post
1287
- master('post/*').to_set = (old, New, t) => {
1336
+ master('post/*').setter = (old, New, t) => {
1288
1337
  // To do: diff the cc, to, and from lists, and only dirty
1289
1338
  // posts_for people who have been changed
1290
1339
 
@@ -1310,40 +1359,40 @@ function import_server (bus, options)
1310
1359
  }
1311
1360
 
1312
1361
  function user_addy (u) {
1362
+ console.error('fix this! not ported to v7 links')
1313
1363
  return u.name + '@' + opts.domain
1314
1364
  }
1315
1365
  function current_addy () {
1316
1366
  var c = client.get('current_user')
1317
- 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'
1318
1369
  }
1319
1370
  function is_author (post) {
1320
1371
  var from = post._.from
1321
- var c = client.get('current_user')
1322
1372
  return from.includes(current_addy())
1323
1373
  }
1324
1374
  function can_see (post) {
1325
- var c = client.get('current_user')
1375
+ console.error('fix this! not ported to v7')
1326
1376
  var allowed = post._.to.concat(post._.cc).concat(post._.from)
1327
1377
  return allowed.includes(current_addy()) || allowed.includes('public')
1328
1378
  }
1329
- var drtbus = master//require('./statebus')()
1379
+ var drtbus = master//make_statebus()
1330
1380
  function dirty (key) { drtbus.set({key: 'dirty-'+key, n: Math.random()}) }
1331
1381
  function watch_for_dirt (key) { drtbus.get('dirty-'+key) }
1332
1382
 
1333
- client('current_email').to_get = () => {
1383
+ client('current_email').getter = () => {
1334
1384
  return {_: current_addy()}
1335
1385
  }
1336
1386
 
1337
1387
  // Define state on client
1338
- client('posts*').to_get = (k, rest) => {
1388
+ client('posts*').getter = (k, rest) => {
1339
1389
  var args = bus.parse(rest.substr(1))
1340
- var c = client.get('current_user')
1341
1390
  args.for = current_addy()
1342
1391
  var e = master.get('posts_for/' + JSON.stringify(args))
1343
1392
  return {_: master.clone(e._).map(x=>client.get(x.key))}
1344
1393
  }
1345
1394
 
1346
- client('post/*').to_get = (k) => {
1395
+ client('post/*').getter = (k) => {
1347
1396
  var e = master.clone(master.get(k))
1348
1397
  if (!e._) return {}
1349
1398
  if (!can_see(e))
@@ -1355,7 +1404,7 @@ function import_server (bus, options)
1355
1404
  return e
1356
1405
  }
1357
1406
 
1358
- client('post/*').to_set = (o, t) => {
1407
+ client('post/*').setter = (o, t) => {
1359
1408
  if (!(client.validate(o, {key: 'string',
1360
1409
  _: {to: 'array',
1361
1410
  cc: 'array',
@@ -1390,7 +1439,7 @@ function import_server (bus, options)
1390
1439
  t.done()
1391
1440
  }
1392
1441
 
1393
- client('post/*').to_delete = (key, o, t) => {
1442
+ client('post/*').deleter = (key, o, t) => {
1394
1443
  // Validate
1395
1444
  if (!is_author(o)) {
1396
1445
  console.error('User', current_addy(),
@@ -1414,14 +1463,14 @@ function import_server (bus, options)
1414
1463
  t.done()
1415
1464
  }
1416
1465
 
1417
- client('friends').to_get = t => {
1418
- return {_: (master.get('users').all||[])
1466
+ client('friends').getter = t => {
1467
+ return {_: (master.get('users').val||[])
1419
1468
  .map(u=>client.get('email/' + user_addy(u)))
1420
1469
  .concat([client.get('email/public')])
1421
1470
  }
1422
1471
  }
1423
1472
 
1424
- client('email/*').to_get = (rest) => {
1473
+ client('email/*').getter = (rest) => {
1425
1474
  var m = rest.match(email_regex)
1426
1475
  var result = {address: rest}
1427
1476
  if (rest === 'public') {
@@ -1444,7 +1493,7 @@ function import_server (bus, options)
1444
1493
 
1445
1494
  sqlite_query_server: function sqlite_query_server (db) {
1446
1495
  var get = bus.get
1447
- bus('table_columns/*').to_get =
1496
+ bus('table_columns/*').getter =
1448
1497
  function get_table_columns (key, rest) {
1449
1498
  if (typeof key !== 'string')
1450
1499
  console.log(handlers.hash)
@@ -1467,7 +1516,7 @@ function import_server (bus, options)
1467
1516
  }
1468
1517
 
1469
1518
 
1470
- bus('table_foreign_keys/*').to_get =
1519
+ bus('table_foreign_keys/*').getter =
1471
1520
  function table_foreign_keys (key, rest) {
1472
1521
  var table_name = rest
1473
1522
  var foreign_keys = get('sql/PRAGMA foreign_key_list(' + table_name + ')').rows
@@ -1479,7 +1528,7 @@ function import_server (bus, options)
1479
1528
  return result
1480
1529
  }
1481
1530
 
1482
- bus('sql/*').to_get =
1531
+ bus('sql/*').getter =
1483
1532
  function sql (key, rest) {
1484
1533
  get('time/60000')
1485
1534
  var query = rest
@@ -1556,7 +1605,7 @@ function import_server (bus, options)
1556
1605
  // ************************
1557
1606
 
1558
1607
  // Getting the whole table, or a single row
1559
- bus(table_name + '*').to_get = function (key, rest) {
1608
+ bus(table_name + '*').getter = function (key, rest) {
1560
1609
  if (rest === '')
1561
1610
  // Return the whole table
1562
1611
  return render_table()
@@ -1576,7 +1625,7 @@ function import_server (bus, options)
1576
1625
  }
1577
1626
 
1578
1627
  // Saving a row
1579
- bus(table_name + '/*').to_set = function (obj, rest) {
1628
+ bus(table_name + '/*').setter = function (obj, rest) {
1580
1629
  var columns = table_columns.columns
1581
1630
  var key = remapped_keys.keys[obj.key] || obj.key
1582
1631
 
@@ -1602,7 +1651,7 @@ function import_server (bus, options)
1602
1651
  }
1603
1652
 
1604
1653
  // Inserting a new row
1605
- bus('new/' + table_name + '/*').to_set = function (obj) {
1654
+ bus('new/' + table_name + '/*').setter = function (obj) {
1606
1655
  var columns = table_columns.columns
1607
1656
  var stmt = ('insert into ' + table_name + ' (' + columns.join(',')
1608
1657
  + ') values (' + new Array(columns.length).join('?,') + '?)')
@@ -1621,7 +1670,7 @@ function import_server (bus, options)
1621
1670
  }
1622
1671
 
1623
1672
  // Deleting a row
1624
- bus(table_name + '/*').to_delete = function (key, rest) {
1673
+ bus(table_name + '/*').deleter = function (key, rest) {
1625
1674
  if (remapped_keys.keys[key]) {
1626
1675
  var old_key = key
1627
1676
  var new_key = remapped_keys.keys[key]
@@ -1643,72 +1692,84 @@ function import_server (bus, options)
1643
1692
 
1644
1693
  serves_auth: function serves_auth (conn, master) {
1645
1694
  var client = this // to keep me straight while programming
1646
-
1647
- function logout (key) {
1695
+ function logout (user_key) {
1648
1696
  var clients = master.get('logged_in_clients')
1649
- for (var k in clients)
1650
- if (k !== 'key')
1651
- if (Object.keys(clients[k]).length === 0) {
1652
- client.log('Found a deleted user. Removing.', k, clients[k])
1653
- delete clients[k]
1654
- master.set(clients)
1655
- } else if (clients[k].key === key) {
1656
- client.log('Logging out!', k, clients[k])
1657
- delete clients[k]
1658
- master.set(clients)
1659
- }
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
+ }
1660
1719
  }
1661
1720
 
1662
1721
  // Initialize master
1663
1722
  if (!master.auth_initialized) {
1664
- master('users/passwords').to_get = function (k) {
1665
- master.log('users/passwords.to_get: Computing!')
1666
- 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: {}}
1667
1729
  var users = master.get('users')
1668
- users.all = users.all || []
1669
- for (var i=0; i<users.all.length; i++) {
1670
- var u = master.get(users.all[i])
1671
- if (!(u.login || u.name)) {
1672
- 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)
1673
1735
  continue
1674
1736
  }
1675
- var login = (u.login || u.name).toLowerCase()
1737
+ var login = (u.val.login || u.val.name).toLowerCase()
1676
1738
  console.assert(login, 'Missing login for user', u)
1677
- if (result.hasOwnProperty(login)) {
1739
+ if (result.val.hasOwnProperty(login)) {
1678
1740
  console.error("upass: this user's name is bogus, dude.", u.key)
1679
1741
  continue
1680
1742
  }
1681
- result[login] = {user: u.key, pass: u.pass}
1743
+ result.val[login] = {user: u.key, pass: u.val.pass}
1682
1744
  }
1683
1745
  return result
1684
1746
  }
1685
1747
  master.auth_initialized = true
1686
1748
  master.get('users/passwords')
1687
1749
 
1688
- master('user/*').to_delete = (key, t) => {
1750
+ master('user/*').deleter = (key, t) => {
1689
1751
  master.log('Deleteinggg!!!', key)
1690
1752
  // Remove from users.all
1691
1753
  var users = master.get('users')
1692
- users.all = users.all.filter(u => u.key && u.key !== key)
1754
+ users.val = users.val.filter(u => u.link && u.link !== key)
1693
1755
  master.set(users)
1694
1756
 
1695
1757
  // Log out
1696
1758
  master.log('Logging out', key)
1697
1759
  logout(key)
1698
1760
 
1699
- // Remove connection
1700
- master.log('Removing connections for', key)
1701
- var conns = master.get('connections')
1702
- for (var k in conns) {
1703
- console.log('Trying key', k)
1704
- if (k !== 'key')
1705
- if (conns[k].user && !conns[k].user.key) {
1706
- console.log('Cleaning keyless user', conss[k].user)
1707
- delete conns[k].user
1708
- master.set(conns)
1709
- continue
1710
- }
1711
- }
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
+ // }
1712
1773
 
1713
1774
  master.log('Dirtying users/passwords for', key)
1714
1775
  master.dirty('users/passwords')
@@ -1720,9 +1781,9 @@ function import_server (bus, options)
1720
1781
 
1721
1782
  // Authentication functions
1722
1783
  function authenticate (login, pass) {
1723
- var userpass = master.get('users/passwords')[login.toLowerCase()]
1784
+ var userpass = master.get('users/passwords').val[login.toLowerCase()]
1724
1785
  master.log('authenticate: we see', {
1725
- passwords: master.get('users/passwords'),
1786
+ passwords: master.get('users/passwords').val,
1726
1787
  hash_to_match: userpass && userpass.pass,
1727
1788
  password_guess: pass
1728
1789
  })
@@ -1733,7 +1794,7 @@ function import_server (bus, options)
1733
1794
 
1734
1795
  // console.log('comparing passwords', pass, userpass.pass)
1735
1796
  if (require('bcrypt-nodejs').compareSync(pass, userpass.pass))
1736
- return master.get(userpass.user)
1797
+ return userpass.user
1737
1798
  }
1738
1799
  function create_account (params) {
1739
1800
  if (typeof (params.login || params.name) !== 'string')
@@ -1746,7 +1807,7 @@ function import_server (bus, options)
1746
1807
  throw 'invalid name, login, pass, or email'
1747
1808
 
1748
1809
  var passes = master.get('users/passwords')
1749
- if (passes.hasOwnProperty(login))
1810
+ if (passes.val.hasOwnProperty(login))
1750
1811
  throw 'there is already a user with that login or name'
1751
1812
 
1752
1813
  // Hash password
@@ -1766,60 +1827,81 @@ function import_server (bus, options)
1766
1827
  key = 'user/' + Math.random().toString(36).substring(7,13)
1767
1828
 
1768
1829
  // Make account object
1769
- var new_account = {key: key,
1770
- name: params.name,
1771
- login: params.login,
1772
- pass: params.pass,
1773
- email: params.email }
1774
- 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]
1775
1841
  master.set(new_account)
1776
1842
 
1777
1843
  var users = master.get('users')
1778
- users.all = users.all || []
1779
- users.all.push(new_account)
1780
- 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}
1781
1847
  master.set(users)
1782
1848
  master.set(passes)
1783
1849
  }
1784
1850
 
1785
1851
  // Current User
1786
- client('current_user').to_get = function (k) {
1787
- client.log('* getting: current_user')
1788
- if (!conn.client) return
1789
- var u = master.get('logged_in_clients')[conn.client]
1790
- u = u && user_obj(u.key, true)
1791
- 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
1792
1859
  }
1793
1860
 
1794
- 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
+ }
1795
1868
  function error (msg) {
1869
+ console.error(msg)
1796
1870
  client.set.abort(o)
1797
1871
  var c = client.get('current_user')
1798
- c.error = msg
1872
+ c.val.error = msg
1799
1873
  client.set.fire(c)
1800
1874
  }
1801
1875
 
1802
1876
  client.log('* saving: current_user!')
1803
- if (o.client && !conn.client) {
1877
+ if (val.client && !conn.client) {
1804
1878
  // Set the client
1805
- conn.client = o.client
1806
- 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
1807
1884
  client.client_ip = conn.remoteAddress
1808
1885
 
1809
- if (conn.id) {
1810
- var connections = master.get('connections')
1811
- connections[conn.id].user = master.get('logged_in_clients')[conn.client]
1812
- master.set(connections)
1813
- }
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
+ // }
1814
1896
  }
1815
1897
  else {
1816
- if (o.create_account) {
1898
+ if (val.create_account) {
1817
1899
  client.log('current_user: creating account')
1818
1900
  try {
1819
- create_account(o.create_account)
1901
+ create_account(val.create_account)
1820
1902
  client.log('Success creating account!')
1821
1903
  var cu = client.get('current_user')
1822
- cu.create_account = null
1904
+ cu.val.create_account = null
1823
1905
  client.set.fire(cu)
1824
1906
  } catch (e) {
1825
1907
  error('Cannot create that account because ' + e)
@@ -1827,29 +1909,29 @@ function import_server (bus, options)
1827
1909
  }
1828
1910
  }
1829
1911
 
1830
- if (o.login_as && conn.id) {
1912
+ if (val.login_as) {
1831
1913
  // Then client is trying to log in
1832
- client.log('current_user: trying to log in')
1833
- var creds = o.login_as
1914
+ var creds = val.login_as
1834
1915
  var login = creds.login || creds.name
1835
1916
  if (login && creds.pass) {
1836
1917
  // With a username and password
1837
- var u = authenticate(login, creds.pass)
1918
+ var user_key = authenticate(login, creds.pass)
1838
1919
 
1839
- client.log('auth said:', u)
1840
- if (u) {
1920
+ client.log('auth said:', user_key)
1921
+ if (user_key) {
1841
1922
  // Success!
1842
1923
  // Associate this user with this session
1843
1924
  // user.log('Logging the user in!', u)
1844
1925
 
1845
1926
  var clients = master.get('logged_in_clients')
1846
- var connections = master.get('connections')
1927
+ // var connections = master.get('connections')
1847
1928
 
1848
- clients[conn.client] = u
1849
- 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}
1850
1932
 
1851
1933
  master.set(clients)
1852
- master.set(connections)
1934
+ // master.set(connections)
1853
1935
 
1854
1936
  client.log('current_user: success logging in!')
1855
1937
  }
@@ -1864,38 +1946,41 @@ function import_server (bus, options)
1864
1946
  }
1865
1947
  }
1866
1948
 
1867
- else if (o.logout && conn.id) {
1949
+ else if (val.logout) {
1868
1950
  client.log('current_user: logging out')
1869
1951
  var clients = master.get('logged_in_clients')
1870
- var connections = master.get('connections')
1952
+ // var connections = master.get('connections')
1871
1953
 
1872
- delete clients[conn.client]
1873
- connections[conn.id].user = null
1954
+ clients.val = clients.val || {}
1955
+ delete clients.val[conn.client]
1956
+ // connections.val[conn.id].user = null
1874
1957
 
1875
1958
  master.set(clients)
1876
- master.set(connections)
1959
+ // master.set(connections)
1877
1960
  }
1878
1961
  }
1879
1962
 
1880
1963
  t.reget()
1881
1964
  }
1882
- client('current_user').to_delete = function () {}
1965
+ client('current_user').deleter = function () {}
1883
1966
 
1884
1967
  // Users have closet space at /user/<name>/*
1885
1968
  var closet_space_key = /^(user\/[^\/]+)\/.*/
1886
1969
  var private_closet_space_key = /^user\/[^\/]+\/private.*/
1887
1970
 
1888
1971
  // User
1889
- client('user/*').to_set = function (o, t) {
1972
+ client('user/*').setter = function (o, t) {
1890
1973
  var c = client.get('current_user')
1891
1974
  var user_key = o.key.match(/^user\/([^\/]+)/)
1892
1975
  user_key = user_key && ('user/' + user_key[1])
1893
1976
 
1894
- // Only the current user can touch themself.
1895
- if (!c.logged_in || c.user.key !== user_key) {
1896
- client.log('Only the current user can touch themself.',
1897
- {logged_in: c.logged_in, as: c.user && c.user.key,
1898
- 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
+ })
1899
1984
  client.set.abort(o)
1900
1985
  return
1901
1986
  }
@@ -1911,9 +1996,14 @@ function import_server (bus, options)
1911
1996
  console.assert(o.key.match(/^user\/[^\/]+$/))
1912
1997
 
1913
1998
  // Validate types
1914
- if (!client.validate(o, {key: 'string', '?login': 'string', '?name': 'string',
1915
- '?pass': 'string', '?email': 'string', /*'?pic': 'string',*/
1916
- '*':'*'})) {
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
+ '*':'*'}})) {
1917
2007
  client.log('This user change fails validation.')
1918
2008
  client.set.abort(o)
1919
2009
  return
@@ -1924,7 +2014,7 @@ function import_server (bus, options)
1924
2014
  // • That resulting login must be unique across all users
1925
2015
 
1926
2016
  // There must be at least a login or a name
1927
- var login = o.login || o.name
2017
+ var login = o.val.login || o.val.name
1928
2018
  if (!login) {
1929
2019
  client.log('User must have a login or a name')
1930
2020
  client.set.abort(o)
@@ -1935,26 +2025,26 @@ function import_server (bus, options)
1935
2025
  var userpass = master.get('users/passwords')
1936
2026
 
1937
2027
  // Validate that the login/name is not changed to something clobberish
1938
- var old_login = u.login || u.name
2028
+ var old_login = u.val.login || u.val.name
1939
2029
  if (old_login.toLowerCase() !== login.toLowerCase()
1940
2030
  && userpass.hasOwnProperty(login)) {
1941
2031
  client.log('The login', login, 'is already taken. Aborting.')
1942
2032
  client.set.abort(o) // Abort
1943
2033
 
1944
2034
  o = client.get(o.key) // Add error message
1945
- o.error = 'The login "' + login + '" is already taken'
2035
+ o.val.error = 'The login "' + login + '" is already taken'
1946
2036
  client.set.fire(o)
1947
2037
 
1948
2038
  return // And exit
1949
2039
  }
1950
2040
 
1951
2041
  // Now we can update login and name
1952
- u.login = o.login
1953
- u.name = o.name
2042
+ u.val.login = o.val.login
2043
+ u.val.name = o.val.name
1954
2044
 
1955
2045
  // Hash password
1956
- o.pass = o.pass && require('bcrypt-nodejs').hashSync(o.pass)
1957
- 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
1958
2048
 
1959
2049
  // // Users can have pictures (remove this soon)
1960
2050
  // // Bug: if user changes name, this picture's url doesn't change.
@@ -1973,24 +2063,24 @@ function import_server (bus, options)
1973
2063
 
1974
2064
  // For anything else, go ahead and add it to the user object
1975
2065
  var protected = {key:1, name:1, /*pic:1,*/ pass:1}
1976
- for (var k in o)
2066
+ for (var k in o.val)
1977
2067
  if (!protected.hasOwnProperty(k))
1978
- u[k] = o[k]
1979
- for (var k in u)
1980
- if (!protected.hasOwnProperty(k) && !o.hasOwnProperty(k))
1981
- 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]
1982
2072
 
1983
2073
  master.set(u)
1984
2074
  }
1985
- client('user/*').to_get = function user_getter (k) {
2075
+ client('user/*').getter = function user_getter (k) {
1986
2076
  var c = client.get('current_user')
1987
- client.log('* getting:', k, 'as', c.user)
2077
+ client.log('* getting:', k, 'as', c.val.user)
1988
2078
 
1989
2079
  // Users have closet space at /user/<name>/*
1990
2080
  if (k.match(closet_space_key)) {
1991
2081
  var obj_user = k.match(closet_space_key)[1]
1992
2082
  if (k.match(private_closet_space_key)
1993
- && (!c.user || obj_user !== c.user.key)) {
2083
+ && (!c.val.user || obj_user !== c.val.user.link)) {
1994
2084
  client.log('hiding private closet data')
1995
2085
  return {}
1996
2086
  }
@@ -1999,26 +2089,27 @@ function import_server (bus, options)
1999
2089
  }
2000
2090
 
2001
2091
  // Otherwise return the actual user
2002
- 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)
2003
2093
  }
2004
- client('user/*').to_delete = function () {}
2094
+ client('user/*').deleter = function () {}
2005
2095
  function user_obj (k, logged_in) {
2006
2096
  var o = master.clone(master.get(k))
2007
2097
  if (k.match(/^user\/([^\/]+)\/private\/(.*)$/))
2008
2098
  return logged_in ? o : {key: k}
2009
-
2010
- delete o.pass
2011
- 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}
2012
2103
  return o
2013
2104
  }
2014
2105
 
2015
2106
  // Blacklist sensitive stuff on master, in case we have a shadow set up
2016
2107
  var blacklist = 'users users/passwords logged_in_clients'.split(' ')
2017
2108
  for (var i=0; i<blacklist.length; i++) {
2018
- client(blacklist[i]).to_get = function () {}
2019
- client(blacklist[i]).to_set = function () {}
2020
- client(blacklist[i]).to_delete = function () {}
2021
- 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 () {}
2022
2113
  }
2023
2114
  },
2024
2115
 
@@ -2027,14 +2118,14 @@ function import_server (bus, options)
2027
2118
  var was_logged_in = undefined
2028
2119
 
2029
2120
  function client_prefix (current_user) {
2030
- return 'client/' + (current_user.logged_in
2031
- ? current_user.user.key.substr('user/'.length)
2121
+ return 'client/' + (current_user.val.logged_in
2122
+ ? current_user.val.user.link.substr('user/'.length)
2032
2123
  : client.client_id) + '/'
2033
2124
  }
2034
2125
 
2035
- function copy_client_to_user(client, user) {
2126
+ function copy_client_to_user(client, user_key) {
2036
2127
  var old_prefix = 'client/' + client.client_id
2037
- var new_prefix = 'client/' + user.key.substr('user/'.length)
2128
+ var new_prefix = 'client/' + user_key.substr('user/'.length)
2038
2129
 
2039
2130
  var keys = client.master.get('persisted_keys/' + client.client_id)
2040
2131
  if (!keys.val) return
@@ -2080,13 +2171,13 @@ function import_server (bus, options)
2080
2171
  client(_=>{
2081
2172
  var c = client.get('current_user')
2082
2173
  if (client.loading()) return
2083
- if (was_logged_in == false && c.logged_in)
2174
+ if (was_logged_in == false && c.val.logged_in)
2084
2175
  // User just logged in! Let's copy his stuff over
2085
- copy_client_to_user(client, c.user)
2086
- was_logged_in = c.logged_in
2176
+ copy_client_to_user(client, c.val.user.link)
2177
+ was_logged_in = c.val.logged_in
2087
2178
  })
2088
2179
 
2089
- client(prefix_to_sync).to_get = function (key) {
2180
+ client(prefix_to_sync).getter = function (key) {
2090
2181
  var c = client.get('current_user')
2091
2182
  if (client.loading()) return
2092
2183
  var prefix = client_prefix(c)
@@ -2103,7 +2194,7 @@ function import_server (bus, options)
2103
2194
  return obj
2104
2195
  }
2105
2196
 
2106
- client(prefix_to_sync).to_set = function (obj) {
2197
+ client(prefix_to_sync).setter = function (obj) {
2107
2198
  if (validate && !validate(obj)) {
2108
2199
  console.warn('Validation failed on', obj)
2109
2200
  client.set.abort(obj)
@@ -2131,7 +2222,7 @@ function import_server (bus, options)
2131
2222
  p_keys && client.master.set(p_keys)
2132
2223
  }
2133
2224
 
2134
- client(prefix_to_sync).to_delete = function (k) {
2225
+ client(prefix_to_sync).deleter = function (k) {
2135
2226
  k = client_prefix(client.get('current_user')) + k
2136
2227
  client.master.delete(k)
2137
2228
 
@@ -2141,7 +2232,7 @@ function import_server (bus, options)
2141
2232
  }
2142
2233
 
2143
2234
  function client_persisted_keys () {
2144
- if (client.get('current_user').logged_in) return
2235
+ if (client.get('current_user').val.logged_in) return
2145
2236
  var result = client.master.get('persisted_keys/' + client.client_id)
2146
2237
  if (result && !result.val) result.val = {}
2147
2238
  return result
@@ -2157,19 +2248,19 @@ function import_server (bus, options)
2157
2248
  // to the global cache
2158
2249
  if (count === 0) {
2159
2250
  count++
2160
- if (method === 'to_get')
2251
+ if (method === 'getter')
2161
2252
  bus.run_handler(function get_from_master (k) {
2162
2253
  // console.log('DEFAULT GETting', k)
2163
2254
  var r = master_bus.get(k)
2164
2255
  // console.log('DEFAULT GETted', r)
2165
2256
  bus.set.fire(r, {version: master_bus.versions[r.key]})
2166
2257
  }, method, arg)
2167
- else if (method === 'to_set')
2258
+ else if (method === 'setter')
2168
2259
  bus.run_handler(function set_to_master (o, t) {
2169
2260
  // console.log('DEFAULT ROUTE', t)
2170
2261
  master_bus.set(bus.clone(o), t)
2171
2262
  }, method, arg, {t: t})
2172
- else if (method == 'to_delete')
2263
+ else if (method == 'deleter')
2173
2264
  bus.run_handler(function delete_from_master (k, t) {
2174
2265
  master_bus.delete(k)
2175
2266
  return 'done'
@@ -2223,7 +2314,7 @@ function import_server (bus, options)
2223
2314
  // file or recursive directory structure at fs_path
2224
2315
  sync_files: function sync_files (state_path, file_path) {
2225
2316
  // To do:
2226
- // - Hook up a to_delete handler
2317
+ // - Hook up a deleter handler
2227
2318
  // - recursively remove directories if all files gone
2228
2319
 
2229
2320
  console.assert(state_path.substr(-1) !== '*'
@@ -2234,7 +2325,7 @@ function import_server (bus, options)
2234
2325
  var buffer = {}
2235
2326
  var full_file_path = require('path').join(__dirname, file_path)
2236
2327
 
2237
- bus(state_path + '*').to_get = (rest) => {
2328
+ bus(state_path + '*').getter = (rest) => {
2238
2329
  // We DO want to handle:
2239
2330
  // - "foo"
2240
2331
  // - "foo/*"
@@ -2260,7 +2351,7 @@ function import_server (bus, options)
2260
2351
  return {_:f}
2261
2352
  }
2262
2353
 
2263
- bus(state_path + '/*').to_set = (o, rest, t) => {
2354
+ bus(state_path + '/*').setter = (o, rest, t) => {
2264
2355
  if (rest.length>0 && rest[0] !== '/') return
2265
2356
  var f = Buffer.from(o._, 'base64')
2266
2357
  require('fs').writeFile(file_path + rest, f,
@@ -2274,10 +2365,10 @@ function import_server (bus, options)
2274
2365
  // Installs a GET handler at route that gets state from a getter function
2275
2366
  // Note: Makes too many textbusses. Should re-use one.
2276
2367
  http_serve: function http_serve (route, getter) {
2277
- var textbus = require('./statebus')()
2368
+ var textbus = make_statebus()
2278
2369
  textbus.label = 'textbus'
2279
2370
  var watched = new Set()
2280
- textbus('*').to_get = (filename, old) => {
2371
+ textbus('*').getter = (filename, old) => {
2281
2372
  return {etag: Math.random() + '',
2282
2373
  _: getter(filename)}
2283
2374
  }
@@ -2353,7 +2444,7 @@ function import_server (bus, options)
2353
2444
  },
2354
2445
 
2355
2446
  serve_wiki: () => {
2356
- bus('edit/*').to_get = () => ({_: require('./extras/wiki.coffee').code})
2447
+ bus('edit/*').getter = () => ({_: require('./extras/wiki.coffee').code})
2357
2448
  },
2358
2449
 
2359
2450
  unix_socket_repl: function (filename) {
@@ -2500,7 +2591,7 @@ module.exports.import_module = function (statebus) {
2500
2591
 
2501
2592
  statebus.serve = function serve (options) {
2502
2593
  var bus = statebus()
2503
- require('./servers').run_server(bus, options)
2594
+ require('./server-library').run_server(bus, options)
2504
2595
  return bus
2505
2596
  }
2506
2597