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.
- package/{clients.js → client-library.js} +310 -281
- package/extras/tests.js +110 -106
- package/package.json +3 -4
- package/{servers.js → server-library.js} +341 -247
- package/statebus.js +132 -76
package/statebus.js
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
&& !(typeof key === 'object' && typeof key.key === 'string'))
|
|
15
15
|
throw ('Error: get(key) called with key = '
|
|
16
16
|
+ JSON.stringify(key))
|
|
17
|
-
key = key.key || key
|
|
18
|
-
|
|
17
|
+
key = key.key || key // You can pass in an object instead of key
|
|
18
|
+
// We should probably disable this in future
|
|
19
19
|
bogus_check(key)
|
|
20
20
|
|
|
21
21
|
var called_from_reactive_funk = !callback
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
// arrived nested within a bigger object, because we never explicity
|
|
52
52
|
// got those keys. But we don't need to get them now cause we
|
|
53
53
|
// already have them.
|
|
54
|
-
var
|
|
54
|
+
var getterters = 0
|
|
55
55
|
if (!gets_out[key])
|
|
56
|
-
|
|
56
|
+
getterters = bus.route(key, 'getter', key)
|
|
57
57
|
|
|
58
58
|
// Now there might be a new value pubbed onto this bus.
|
|
59
59
|
// Or there might be a pending get.
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
|
|
72
72
|
// Otherwise, we want to make sure that a pub gets called on the
|
|
73
73
|
// handler. If there's a pending get, then it'll get called later.
|
|
74
|
-
// If there was a
|
|
74
|
+
// If there was a getter, then it already got called. Otherwise,
|
|
75
75
|
// let's call it now.
|
|
76
|
-
else if (!pending_gets[key] &&
|
|
76
|
+
else if (!pending_gets[key] && getterters === 0) {
|
|
77
77
|
// TODO: my intuition suggests that we might prefer to delay this
|
|
78
78
|
// .on_set getting called in a setTimeout(f,0), to be consistent
|
|
79
79
|
// with other calls to .on_set.
|
|
@@ -130,8 +130,8 @@
|
|
|
130
130
|
var was_saving = currently_saving
|
|
131
131
|
currently_saving = obj.key
|
|
132
132
|
|
|
133
|
-
// Call the
|
|
134
|
-
var num_handlers = bus.route(obj.key, '
|
|
133
|
+
// Call the setter() handlers!
|
|
134
|
+
var num_handlers = bus.route(obj.key, 'setter', obj, t)
|
|
135
135
|
if (num_handlers === 0) {
|
|
136
136
|
// And fire if there weren't any!
|
|
137
137
|
set.fire(obj, t)
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
currently_saving = was_saving
|
|
144
144
|
}
|
|
145
145
|
// TODO: Here's an alternative. Instead of counting the handlers and
|
|
146
|
-
// seeing if there are zero, I could just make a
|
|
146
|
+
// seeing if there are zero, I could just make a setter handler that
|
|
147
147
|
// is shadowed by other handlers if I can get later handlers to shadow
|
|
148
148
|
// earlier ones.
|
|
149
149
|
}
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
if (obj.key && !changed(obj)) {
|
|
192
192
|
color = grey
|
|
193
193
|
icon = 'x'
|
|
194
|
-
if (t.
|
|
194
|
+
if (t.getter)
|
|
195
195
|
message = (t.m) || 'Got ' + bus + "('"+obj.key+"')"
|
|
196
196
|
if (t.version) message += ' [' + t.version + ']'
|
|
197
197
|
statelog(obj.key, color, icon, message)
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
color = red, icon = '•'
|
|
202
|
-
if (t.
|
|
202
|
+
if (t.getter || pending_gets[obj.key]) {
|
|
203
203
|
color = green
|
|
204
204
|
icon = '^'
|
|
205
205
|
message = add_diff_msg((t.m)||'Got '+bus+"('"+obj.key+"')",
|
|
@@ -409,10 +409,11 @@
|
|
|
409
409
|
clearTimeout(to_be_forgotten[key])
|
|
410
410
|
to_be_forgotten[key] = setTimeout(function () {
|
|
411
411
|
// Send a forget upstream
|
|
412
|
-
bus.route(key, '
|
|
412
|
+
bus.route(key, 'forgetter', key, t)
|
|
413
413
|
|
|
414
414
|
// Delete the cache entry...?
|
|
415
415
|
// delete cache[key]
|
|
416
|
+
// delete backup_cache[key]
|
|
416
417
|
delete gets_out[key]
|
|
417
418
|
delete to_be_forgotten[key]
|
|
418
419
|
}, 200)
|
|
@@ -428,8 +429,8 @@
|
|
|
428
429
|
}
|
|
429
430
|
|
|
430
431
|
statelog(key, yellow, 'v', 'Deleting ' + key)
|
|
431
|
-
// Call the
|
|
432
|
-
var handlers_called = bus.route(key, '
|
|
432
|
+
// Call the deleter handlers
|
|
433
|
+
var handlers_called = bus.route(key, 'deleter', key)
|
|
433
434
|
if (handlers_called === 0)
|
|
434
435
|
// And go ahead and delete if there aren't any!
|
|
435
436
|
delete cache[key]
|
|
@@ -444,11 +445,11 @@
|
|
|
444
445
|
// - Add transactions, so you can check permissions, abort a delete,
|
|
445
446
|
// etc.
|
|
446
447
|
// - NOTE: I did a crappy implementation of abort just now above!
|
|
447
|
-
// But it doesn't work if called after the
|
|
448
|
+
// But it doesn't work if called after the deleter handler returns.
|
|
448
449
|
// - Generalize the code across set and del with a "mutate"
|
|
449
450
|
// operation
|
|
450
451
|
//
|
|
451
|
-
// - Right now we fire the
|
|
452
|
+
// - Right now we fire the deleter handlers right here.
|
|
452
453
|
//
|
|
453
454
|
// - Do we want to batch them up and fire them later?
|
|
454
455
|
// e.g. we could make a mark_deleted(key) like mark_changed(key)
|
|
@@ -467,7 +468,7 @@
|
|
|
467
468
|
|
|
468
469
|
var version = (t && t.version) || 'dirty-' + new_version()
|
|
469
470
|
|
|
470
|
-
// Find any .
|
|
471
|
+
// Find any .getter, and mark as dirty so that it re-runs
|
|
471
472
|
var found = false
|
|
472
473
|
if (gets_out.hasOwnProperty(key))
|
|
473
474
|
for (var i=0; i<gets_out[key].length; i++) {
|
|
@@ -503,7 +504,6 @@
|
|
|
503
504
|
var funk = funks[k],
|
|
504
505
|
version = dirty_funks[k]
|
|
505
506
|
|
|
506
|
-
// console.log(funks[dirty_funks[i]].proxies_for)
|
|
507
507
|
var p = funk.proxies_for
|
|
508
508
|
if (p && p.priority) {
|
|
509
509
|
log('Clean-early:', funk_name(funk))
|
|
@@ -525,7 +525,7 @@
|
|
|
525
525
|
funk.react()
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
|
-
// log('We just cleaned up', dirty_funks.length, 'funks!')
|
|
528
|
+
// console.log('We just cleaned up', dirty_funks.length, 'funks!')
|
|
529
529
|
}
|
|
530
530
|
|
|
531
531
|
// Let's change this function to go through each key and grab the latest
|
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
var result = []
|
|
538
538
|
var keys = changed_keys.values()
|
|
539
539
|
|
|
540
|
-
//log(bus+'
|
|
540
|
+
// console.log(bus+' Finding rerunnable funcs for', keys, 'keys, and', Object.keys(dirty_getters).length, 'dirty_getters')
|
|
541
541
|
for (var i=0; i<keys.length; i++) { // Collect all keys
|
|
542
542
|
// if (to_be_forgotten[keys[i]])
|
|
543
543
|
// // Ignore changes to keys that have been forgotten, but not
|
|
@@ -549,7 +549,7 @@
|
|
|
549
549
|
if (f.react) {
|
|
550
550
|
// Skip if it's already up to date
|
|
551
551
|
var v = f.getted_keys[JSON.stringify([this.id, keys[i]])]
|
|
552
|
-
//log('re-run:', keys[i], f.statebus_id, f.getted_keys)
|
|
552
|
+
// console.log('re-run:', keys[i], f.statebus_id, f.getted_keys)
|
|
553
553
|
if (v && v.indexOf(versions[keys[i]]) !== -1) {
|
|
554
554
|
log('skipping', funk_name(f), 'already at version', versions[keys[i]], 'proof:', v)
|
|
555
555
|
continue
|
|
@@ -580,7 +580,7 @@
|
|
|
580
580
|
changed_keys.clear()
|
|
581
581
|
dirty_getters = {}
|
|
582
582
|
|
|
583
|
-
//log('found', result.length, 'funks to re run')
|
|
583
|
+
// console.log('found', result.length, 'funks to re run')
|
|
584
584
|
|
|
585
585
|
return result
|
|
586
586
|
}
|
|
@@ -588,13 +588,21 @@
|
|
|
588
588
|
// ****************
|
|
589
589
|
// Connections
|
|
590
590
|
function subspace (key, params) {
|
|
591
|
-
var methods = {
|
|
592
|
-
on_delete:null,
|
|
591
|
+
var methods = {getter:null, setter:null, on_set:null, on_set_sync:null,
|
|
592
|
+
on_delete:null, deleter:null, forgetter:null}
|
|
593
593
|
|
|
594
594
|
if (params) {
|
|
595
595
|
for (var method in params) {
|
|
596
|
-
console.assert(method in methods)
|
|
597
596
|
var func = params[method]
|
|
597
|
+
var param_names = {get:'getter', set:'setter',
|
|
598
|
+
delete: 'deleter', forget: 'forgetter',
|
|
599
|
+
on_set:'on_set', on_set_sync:'on_set_sync'}
|
|
600
|
+
|
|
601
|
+
// Map it from the API's name to our internal name
|
|
602
|
+
console.assert(param_names[method],
|
|
603
|
+
'Method "' + method + '" is invalid')
|
|
604
|
+
method = param_names[method]
|
|
605
|
+
|
|
598
606
|
autodetect_args(func)
|
|
599
607
|
func.defined = func.defined || []
|
|
600
608
|
func.defined.push({bus, method, key, as: 'handler'})
|
|
@@ -756,8 +764,8 @@
|
|
|
756
764
|
|
|
757
765
|
if (false && !funck.global_funk) {
|
|
758
766
|
// \u26A1
|
|
759
|
-
var event = {'
|
|
760
|
-
'
|
|
767
|
+
var event = {'setter':'set','on_set':'set.fire','getter':'get',
|
|
768
|
+
'deleter':'delete','forgetter':'forget'}[method],
|
|
761
769
|
triggering = funk ? 're-running' : 'initiating'
|
|
762
770
|
console.log(' > a', bus+'.'+event + "('" + (arg.key||arg) + "') is " + triggering
|
|
763
771
|
+'\n ' + funk_name(funck))
|
|
@@ -802,7 +810,8 @@
|
|
|
802
810
|
function key_arg () { return ((typeof arg.key) == 'string') ? arg.key : arg }
|
|
803
811
|
function rest_arg () { return (key_arg()).substr(binding.length-1) }
|
|
804
812
|
function val_arg () {
|
|
805
|
-
console.assert(method === '
|
|
813
|
+
console.assert(method === 'setter' || method === 'on_set' || method === 'on_set_sync',
|
|
814
|
+
'Bad method for val_arg()')
|
|
806
815
|
// Is there a time I am supposed to return bus.cache[arg]? It used to say:
|
|
807
816
|
// arg.key ? arg : bus.cache[arg]
|
|
808
817
|
|
|
@@ -821,9 +830,9 @@
|
|
|
821
830
|
t = clone(t || {})
|
|
822
831
|
|
|
823
832
|
// Add .abort() method
|
|
824
|
-
if (method === '
|
|
833
|
+
if (method === 'setter' || method === 'deleter')
|
|
825
834
|
t.abort = function () {
|
|
826
|
-
var key = method === '
|
|
835
|
+
var key = method === 'setter' ? arg.key : arg
|
|
827
836
|
if (f.loading()) return
|
|
828
837
|
bus.cache[key] = bus.cache[key] || {key: key}
|
|
829
838
|
bus.backup_cache[key] = bus.backup_cache[key] || {key: key}
|
|
@@ -831,34 +840,34 @@
|
|
|
831
840
|
}
|
|
832
841
|
|
|
833
842
|
// Add .done() method
|
|
834
|
-
if (method !== '
|
|
843
|
+
if (method !== 'forgetter')
|
|
835
844
|
t.done = function (o) {
|
|
836
|
-
var key = method === '
|
|
845
|
+
var key = method === 'setter' ? arg.key : arg
|
|
837
846
|
if (func.use_linked_json)
|
|
838
847
|
o = {key, val: o}
|
|
839
848
|
bus.log('We are DONE()ing', method, key, o||arg)
|
|
840
849
|
|
|
841
850
|
// We use a simple (and crappy?) heuristic to know if the
|
|
842
|
-
//
|
|
851
|
+
// setter handler has changed the state: whether the
|
|
843
852
|
// programmer passed (o) to the t.done(o) handler. If
|
|
844
853
|
// not, we assume it hasn't changed. If so, we assume it
|
|
845
854
|
// *has* changed, and thus we change the version of the
|
|
846
855
|
// state. I imagine it would be more accurate to diff
|
|
847
|
-
// from before the
|
|
856
|
+
// from before the setter handler began with when
|
|
848
857
|
// t.done(o) ran.
|
|
849
858
|
//
|
|
850
859
|
// Note: We will likely solve this in the future by
|
|
851
|
-
// preventing .
|
|
860
|
+
// preventing .setter() from changing the incoming state,
|
|
852
861
|
// except through an explicit .revise() function.
|
|
853
862
|
if (o) t.version = new_version()
|
|
854
863
|
|
|
855
|
-
if (method === '
|
|
864
|
+
if (method === 'deleter')
|
|
856
865
|
delete bus.cache[key]
|
|
857
|
-
else if (method === '
|
|
866
|
+
else if (method === 'setter') {
|
|
858
867
|
bus.set.fire(o || arg, t)
|
|
859
868
|
bus.route(key, 'on_set_sync', o || arg, t)
|
|
860
869
|
} else {
|
|
861
|
-
// Now method === '
|
|
870
|
+
// Now method === 'getter'
|
|
862
871
|
o.key = key
|
|
863
872
|
bus.set.fire(o, t)
|
|
864
873
|
// And now reset the version cause it could get called again
|
|
@@ -869,14 +878,20 @@
|
|
|
869
878
|
// Alias .return() to .done(), in case that feels better to you
|
|
870
879
|
t.return = t.done
|
|
871
880
|
|
|
881
|
+
// Prepush Scratch:
|
|
882
|
+
// var prepushed = {}
|
|
883
|
+
// t.prepush = function (key) {
|
|
884
|
+
// prepushed[key] = bus.get(key)
|
|
885
|
+
// }
|
|
886
|
+
|
|
872
887
|
// Alias t.reget() to bus.dirty()
|
|
873
|
-
if (method === '
|
|
888
|
+
if (method === 'setter')
|
|
874
889
|
t.reget = function () { bus.dirty(arg.key) }
|
|
875
890
|
|
|
876
891
|
// Now to call the handler, let's line up the function's special
|
|
877
892
|
// named arguemnts like key, o, t, rest, vars, etc.
|
|
878
893
|
var args = []
|
|
879
|
-
args[0] = (method in {
|
|
894
|
+
args[0] = (method in {setter:1, on_set:1, on_set_sync:1}) ? val_arg() : arg
|
|
880
895
|
args[1] = t
|
|
881
896
|
for (var k in (func.args||{})) {
|
|
882
897
|
switch (k) {
|
|
@@ -907,28 +922,29 @@
|
|
|
907
922
|
// arr[func.args[k]] = <compute_blah(k)>
|
|
908
923
|
|
|
909
924
|
// Trigger done() or abort() by return value
|
|
910
|
-
console.assert(!(result === '
|
|
925
|
+
console.assert(!(result === 'getter' &&
|
|
911
926
|
(result === 'done' || result === 'abort')),
|
|
912
|
-
'Returning "done" or "abort" is not allowed from
|
|
927
|
+
'Returning "done" or "abort" is not allowed from getter handlers')
|
|
928
|
+
|
|
913
929
|
if (result === 'done') t.done()
|
|
914
930
|
if (result === 'abort') t.abort()
|
|
915
931
|
|
|
916
932
|
// For get
|
|
917
933
|
if (func.use_linked_json) {
|
|
918
|
-
if (method === '
|
|
934
|
+
if (method === 'getter' && result !== undefined && !f.loading()) {
|
|
919
935
|
var obj = {key: arg, val: result}
|
|
920
936
|
var new_t = clone(t || {})
|
|
921
|
-
new_t.
|
|
937
|
+
new_t.getter = true
|
|
922
938
|
set.fire(obj, new_t)
|
|
923
939
|
return result
|
|
924
940
|
}
|
|
925
941
|
} else {
|
|
926
|
-
if (method === '
|
|
942
|
+
if (method === 'getter' && result instanceof Object
|
|
927
943
|
&& !f.loading() // Experimental.
|
|
928
944
|
) {
|
|
929
945
|
result.key = arg
|
|
930
946
|
var new_t = clone(t || {})
|
|
931
|
-
new_t.
|
|
947
|
+
new_t.getter = true
|
|
932
948
|
set.fire(result, new_t)
|
|
933
949
|
return result
|
|
934
950
|
}
|
|
@@ -937,29 +953,29 @@
|
|
|
937
953
|
// Set, forget and delete handlers stop re-running once they've
|
|
938
954
|
// completed without anything loading.
|
|
939
955
|
// ... with f.forget()
|
|
940
|
-
if (method !== '
|
|
956
|
+
if (method !== 'getter' && !f.loading())
|
|
941
957
|
f.forget()
|
|
942
958
|
})
|
|
943
959
|
f.proxies_for = func
|
|
944
960
|
f.arg = arg
|
|
945
961
|
f.transaction = t || {}
|
|
946
962
|
|
|
947
|
-
//
|
|
948
|
-
if (method === '
|
|
963
|
+
// getter handlers stop re-running when the key is forgotten
|
|
964
|
+
if (method === 'getter') {
|
|
949
965
|
var key = arg
|
|
950
966
|
function handler_done () {
|
|
951
967
|
f.forget()
|
|
952
|
-
unbind(key, '
|
|
968
|
+
unbind(key, 'forgetter', handler_done)
|
|
953
969
|
}
|
|
954
|
-
bind(key, '
|
|
970
|
+
bind(key, 'forgetter', handler_done)
|
|
955
971
|
|
|
956
972
|
// // Check if it's doubled-up
|
|
957
973
|
// if (gets_out[key])
|
|
958
|
-
// console.error('Two .
|
|
974
|
+
// console.error('Two .getter functions are running on the same key',
|
|
959
975
|
// key+'!', funk_name(funck), funk_name(gets_out[key]))
|
|
960
976
|
|
|
961
977
|
gets_out[key] = gets_out[key] || []
|
|
962
|
-
gets_out[key].push(f) // Record active
|
|
978
|
+
gets_out[key].push(f) // Record active getter handler
|
|
963
979
|
pending_gets[key] = f // Record that the get is pending
|
|
964
980
|
}
|
|
965
981
|
|
|
@@ -979,9 +995,9 @@
|
|
|
979
995
|
for (var i=0; i<handlers.length; i++)
|
|
980
996
|
bus.run_handler(handlers[i].func, method, arg, {t: t, binding: handlers[i].key})
|
|
981
997
|
|
|
982
|
-
// if (method === '
|
|
998
|
+
// if (method === 'getter')
|
|
983
999
|
// console.assert(handlers.length<2,
|
|
984
|
-
// 'Two
|
|
1000
|
+
// 'Two getter functions are registered for the same key '+key,
|
|
985
1001
|
// handlers)
|
|
986
1002
|
return handlers.length
|
|
987
1003
|
}
|
|
@@ -1187,7 +1203,7 @@
|
|
|
1187
1203
|
if (!name) throw 'Uncallback function needs a name'
|
|
1188
1204
|
var watching = {}
|
|
1189
1205
|
var prefix = 'uncallback/' + name
|
|
1190
|
-
bus(prefix + '/*').
|
|
1206
|
+
bus(prefix + '/*').getter = function (key, json) {
|
|
1191
1207
|
var args = json
|
|
1192
1208
|
function cb (err, result) {
|
|
1193
1209
|
if (err) {
|
|
@@ -1212,7 +1228,7 @@
|
|
|
1212
1228
|
}
|
|
1213
1229
|
}
|
|
1214
1230
|
if (options.stop_watching)
|
|
1215
|
-
bus(prefix + '/*').
|
|
1231
|
+
bus(prefix + '/*').forgetter = function (key, json) {
|
|
1216
1232
|
console.assert(watching[key],
|
|
1217
1233
|
'Forgetting a watcher for ' + JSON.stringify(key)
|
|
1218
1234
|
+ ' that is not enabled')
|
|
@@ -1234,6 +1250,10 @@
|
|
|
1234
1250
|
})
|
|
1235
1251
|
}
|
|
1236
1252
|
|
|
1253
|
+
function aget (key) {
|
|
1254
|
+
return new Promise((resolve, reject) =>
|
|
1255
|
+
bus.get_once(key, (o) => resolve(o)))
|
|
1256
|
+
}
|
|
1237
1257
|
|
|
1238
1258
|
// ******************
|
|
1239
1259
|
// Proxy
|
|
@@ -1258,8 +1278,8 @@
|
|
|
1258
1278
|
return o
|
|
1259
1279
|
|
|
1260
1280
|
// We recursively descend through {key: ...} links
|
|
1261
|
-
if (typeof o === 'object' && '
|
|
1262
|
-
var new_base = bus.get(o.
|
|
1281
|
+
if (typeof o === 'object' && 'link' in o) {
|
|
1282
|
+
var new_base = bus.get(o.link)
|
|
1263
1283
|
return item_proxy(new_base, new_base.val)
|
|
1264
1284
|
}
|
|
1265
1285
|
|
|
@@ -1409,11 +1429,15 @@
|
|
|
1409
1429
|
function rem_prefix (key) {
|
|
1410
1430
|
return has_prefix.test(key) ? key.substr(preprefix.length) : key }
|
|
1411
1431
|
function add_prefixes (obj) {
|
|
1412
|
-
|
|
1432
|
+
var keyed = bus.translate_keys(bus.clone(obj), add_prefix)
|
|
1433
|
+
return bus.translate_links(bus.clone(keyed), add_prefix)
|
|
1434
|
+
}
|
|
1413
1435
|
function rem_prefixes (obj) {
|
|
1414
|
-
|
|
1436
|
+
var keyed = bus.translate_keys(bus.clone(obj), rem_prefix)
|
|
1437
|
+
return bus.translate_links(bus.clone(keyed), rem_prefix)
|
|
1438
|
+
}
|
|
1415
1439
|
|
|
1416
|
-
bus(prefix).
|
|
1440
|
+
bus(prefix).setter = function (obj, t) {
|
|
1417
1441
|
bus.set.fire(obj)
|
|
1418
1442
|
var x = {set: obj}
|
|
1419
1443
|
if (t.version) x.version = t.version
|
|
@@ -1422,11 +1446,11 @@
|
|
|
1422
1446
|
if (t.patch) x.set = rem_prefix(x.set.key)
|
|
1423
1447
|
send(x)
|
|
1424
1448
|
}
|
|
1425
|
-
bus(prefix).
|
|
1449
|
+
bus(prefix).getter = function (key) { send({get: key}),
|
|
1426
1450
|
client_getted_keys.add(key) }
|
|
1427
|
-
bus(prefix).
|
|
1451
|
+
bus(prefix).forgetter = function (key) { send({forget: key}),
|
|
1428
1452
|
client_getted_keys.delete(key) }
|
|
1429
|
-
bus(prefix).
|
|
1453
|
+
bus(prefix).deleter = function (key) { send({'delete': key}) }
|
|
1430
1454
|
|
|
1431
1455
|
function connect () {
|
|
1432
1456
|
nlog('[ ] trying to open ' + url)
|
|
@@ -1446,9 +1470,9 @@
|
|
|
1446
1470
|
var i = []
|
|
1447
1471
|
function intro (o) {i.push(JSON.stringify({set: o}))}
|
|
1448
1472
|
if (creds.clientid)
|
|
1449
|
-
intro({key: 'current_user', client: creds.clientid})
|
|
1473
|
+
intro({key: 'current_user', val: {client: creds.clientid}})
|
|
1450
1474
|
if (creds.name && creds.pass)
|
|
1451
|
-
intro({key: 'current_user', login_as: {name: creds.name, pass: creds.pass}})
|
|
1475
|
+
intro({key: 'current_user', val: {login_as: {name: creds.name, pass: creds.pass}}})
|
|
1452
1476
|
// Todo: make this kinda thing work:
|
|
1453
1477
|
if (creds.private_key && creds.public_key) {
|
|
1454
1478
|
// Send public_key... start waiting for a
|
|
@@ -1540,6 +1564,14 @@
|
|
|
1540
1564
|
return {send: send, sock: sock, close: function () {done = true; sock.close()}}
|
|
1541
1565
|
}
|
|
1542
1566
|
|
|
1567
|
+
bus.client_creds = function client_creds (server_url) {
|
|
1568
|
+
// This default implementation just creates a different random id each time
|
|
1569
|
+
// we connect. Override this if you want a client ID that persists.
|
|
1570
|
+
return {clientid: (Math.random().toString(36).substring(2)
|
|
1571
|
+
+ Math.random().toString(36).substring(2)
|
|
1572
|
+
+ Math.random().toString(36).substring(2))}
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1543
1575
|
function net_automount () {
|
|
1544
1576
|
var bus = this
|
|
1545
1577
|
var old_route = bus.route
|
|
@@ -1586,6 +1618,30 @@
|
|
|
1586
1618
|
return k.replace(/(_$)/, '')
|
|
1587
1619
|
}
|
|
1588
1620
|
|
|
1621
|
+
// ************************************************
|
|
1622
|
+
// Translating the URLs under links of state
|
|
1623
|
+
function translate_links (obj, f) {
|
|
1624
|
+
// Recurse through each element in arrays
|
|
1625
|
+
if (Array.isArray(obj))
|
|
1626
|
+
for (var i=0; i < obj.length; i++)
|
|
1627
|
+
translate_links(obj[i], f)
|
|
1628
|
+
|
|
1629
|
+
// Recurse through each property on objects
|
|
1630
|
+
else if (typeof obj === 'object')
|
|
1631
|
+
for (var k in obj) {
|
|
1632
|
+
if (k === 'link')
|
|
1633
|
+
if (typeof obj[k] == 'string')
|
|
1634
|
+
obj[k] = f(obj[k])
|
|
1635
|
+
else if (Array.isArray(obj[k]))
|
|
1636
|
+
for (var i=0; i < obj[k].length; i++) {
|
|
1637
|
+
if (typeof obj[k][i] === 'string')
|
|
1638
|
+
obj[k][i] = f(obj[k][i])
|
|
1639
|
+
}
|
|
1640
|
+
translate_links(obj[k], f)
|
|
1641
|
+
}
|
|
1642
|
+
return obj
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1589
1645
|
|
|
1590
1646
|
// ************************************************
|
|
1591
1647
|
// Translating fields of objects
|
|
@@ -1863,13 +1919,13 @@
|
|
|
1863
1919
|
if (a_array !== b_array) return ' = ' + JSON.stringify(b)
|
|
1864
1920
|
if (a_array) {
|
|
1865
1921
|
if (a.length === b.length-1
|
|
1866
|
-
&&
|
|
1867
|
-
return '.push(' +JSON.stringify(b[b.length]) + ')'
|
|
1922
|
+
&& deep_equals(a[a.length-1], b[b.length-2])) {
|
|
1923
|
+
return '.push(' +JSON.stringify(b[b.length-1]) + ')'
|
|
1868
1924
|
}
|
|
1869
1925
|
for (var i=0; i < a.length; i++) {
|
|
1870
1926
|
var tmp = sorta_diff (a[i], b[i])
|
|
1871
1927
|
if (tmp)
|
|
1872
|
-
return '['+i+']
|
|
1928
|
+
return '['+i+']'+tmp
|
|
1873
1929
|
}
|
|
1874
1930
|
return null
|
|
1875
1931
|
}
|
|
@@ -1897,7 +1953,7 @@
|
|
|
1897
1953
|
|
|
1898
1954
|
// This prune() function is a temporary workaround for dealing with nested
|
|
1899
1955
|
// objects in set() handlers, until we change statebus' behavior. Right
|
|
1900
|
-
// now, it calls .
|
|
1956
|
+
// now, it calls .setter only on the top-level state. But if that state
|
|
1901
1957
|
// validates, it calls fire() on *every* level of state. This means that
|
|
1902
1958
|
// state changes can sneak inside. Prune() will take out any changes from
|
|
1903
1959
|
// the nested levels of state in a new object -- replacing them with the
|
|
@@ -2070,7 +2126,7 @@
|
|
|
2070
2126
|
if (!(key in bogus_keys))
|
|
2071
2127
|
return
|
|
2072
2128
|
|
|
2073
|
-
var msg = "Sorry, statebus.js currently prohibits use of the key \""+key+"\", and in fact all of these keys: " + Object.keys(bogus_keys).join(', ') + ". This is because Javascript is kinda lame, and even empty objects like \"{}\" have the \""+key+"\" field defined on them. Try typing this in your Javascript console: \"({}).constructor\" -- it returns a function instead of undefined!
|
|
2129
|
+
var msg = "Sorry, statebus.js currently prohibits use of the key \""+key+"\", and in fact all of these keys: " + Object.keys(bogus_keys).join(', ') + ". This is because Javascript is kinda lame, and even empty objects like \"{}\" have the \""+key+"\" field defined on them. Try typing this in your Javascript console: \"({}).constructor\" -- it returns a function instead of undefined! Mike needs to work around it by replacing every \"obj[key]\" with \"obj.hasOwnProperty(key) && obj[key]\" in the statebus code, or switching to a Map() object. Please contact him and let him know where this is impacting you, so he can bump the priority on it."
|
|
2074
2130
|
console.error(msg)
|
|
2075
2131
|
throw 'Invalid key'
|
|
2076
2132
|
}
|
|
@@ -2079,11 +2135,11 @@
|
|
|
2079
2135
|
var api = ['cache backup_cache get set forget del fire dirty get_once',
|
|
2080
2136
|
'subspace bindings run_handler bind unbind reactive uncallback',
|
|
2081
2137
|
'versions new_version',
|
|
2082
|
-
'link',
|
|
2138
|
+
'link aget',
|
|
2083
2139
|
'funk_key funk_name funks key_id key_name id',
|
|
2084
2140
|
'pending_gets gets_in gets_out loading_keys loading once',
|
|
2085
2141
|
'global_funk busses rerunnable_funks',
|
|
2086
|
-
'escape_keys unescape_keys translate_keys apply_patch',
|
|
2142
|
+
'escape_keys unescape_keys translate_keys translate_links apply_patch',
|
|
2087
2143
|
'keyed_2_proxied proxied_2_keyed translate_fields',
|
|
2088
2144
|
'ws_mount net_automount message_method',
|
|
2089
2145
|
'parse Set One_To_Many clone extend deep_map deep_equals prune validate sorta_diff log deps symbols'
|
|
@@ -2110,13 +2166,13 @@
|
|
|
2110
2166
|
bus.libs = {}
|
|
2111
2167
|
|
|
2112
2168
|
if (nodejs)
|
|
2113
|
-
require('./
|
|
2169
|
+
require('./server-library').import_server(bus, make_bus, options)
|
|
2114
2170
|
|
|
2115
2171
|
bus.render_when_loading = true
|
|
2116
2172
|
return bus
|
|
2117
2173
|
}
|
|
2118
2174
|
|
|
2119
|
-
if (nodejs) require('./
|
|
2175
|
+
if (nodejs) require('./server-library').import_module(make_bus)
|
|
2120
2176
|
|
|
2121
2177
|
return make_bus
|
|
2122
2178
|
}))
|