statebus 6.1.21 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{client.js → clients.js} +258 -146
- package/extras/tests.js +292 -412
- package/package.json +9 -3
- package/{server.js → servers.js} +291 -337
- package/statebus.js +297 -620
- package/extras/coffee.js +0 -12
- package/extras/dash.coffee +0 -302
- package/extras/diffsync.js +0 -1462
- package/extras/getCaretCoordinates.js +0 -141
- package/extras/react.js +0 -18147
- package/extras/sockjs.js +0 -27
package/{client.js → clients.js}
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var websocket_prefix = (clientjs_option('websocket_path')
|
|
3
3
|
|| '_connect_to_statebus_')
|
|
4
4
|
|
|
5
|
+
// Todo: remove this global
|
|
5
6
|
window.dom = window.dom || new Proxy({}, {
|
|
6
7
|
get: function (o, k) { return o[k] },
|
|
7
8
|
set: function (o, k, v) {
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
// return new SockJS(url + '/' + websocket_prefix)
|
|
43
44
|
}
|
|
44
45
|
function client_creds (server_url) {
|
|
45
|
-
var me = bus.
|
|
46
|
+
var me = bus.get('ls/me')
|
|
46
47
|
bus.log('connect: me is', me)
|
|
47
48
|
if (!me.client) {
|
|
48
49
|
// Create a client id if we have none yet.
|
|
@@ -51,19 +52,20 @@
|
|
|
51
52
|
me.client = c || (Math.random().toString(36).substring(2)
|
|
52
53
|
+ Math.random().toString(36).substring(2)
|
|
53
54
|
+ Math.random().toString(36).substring(2))
|
|
54
|
-
bus.
|
|
55
|
+
bus.set(me)
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
set_cookie('client', me.client)
|
|
58
59
|
return {clientid: me.client}
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
function
|
|
62
|
+
function http_mount (prefix, url) {
|
|
62
63
|
var preprefix = prefix.slice(0,-1)
|
|
63
64
|
var has_prefix = new RegExp('^' + preprefix)
|
|
64
65
|
var is_absolute = /^https?:\/\//
|
|
65
|
-
var
|
|
66
|
-
|
|
66
|
+
var subscriptions = {}
|
|
67
|
+
var put_counter = 0
|
|
68
|
+
|
|
67
69
|
function add_prefix (key) {
|
|
68
70
|
return is_absolute.test(key) ? key : preprefix + key }
|
|
69
71
|
function rem_prefix (key) {
|
|
@@ -73,45 +75,146 @@
|
|
|
73
75
|
function rem_prefixes (obj) {
|
|
74
76
|
return bus.translate_keys(bus.clone(obj), rem_prefix) }
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
var puts = new Map()
|
|
79
|
+
function enqueue_put (url, body) {
|
|
80
|
+
var id = put_counter++
|
|
81
|
+
puts.set(id, {url: url, body: body, id: id})
|
|
82
|
+
send_put(id)
|
|
83
|
+
}
|
|
84
|
+
function send_put (id) {
|
|
85
|
+
try {
|
|
86
|
+
puts.get(id).status = 'sending'
|
|
87
|
+
braid_fetch(
|
|
88
|
+
puts.get(id).url,
|
|
89
|
+
{
|
|
90
|
+
method: 'put',
|
|
91
|
+
headers: {
|
|
92
|
+
'content-type': 'application/json',
|
|
93
|
+
'put-order': id,
|
|
94
|
+
},
|
|
95
|
+
body: puts.get(id).body
|
|
96
|
+
}
|
|
97
|
+
).then(function (res) {
|
|
98
|
+
if (res.status !== 200)
|
|
99
|
+
console.error('Server gave error on PUT:',
|
|
100
|
+
e, 'for', puts.get(id).body)
|
|
101
|
+
puts.delete(id)
|
|
102
|
+
}).catch(function (e) {
|
|
103
|
+
console.error('Error on PUT, waiting...', puts.get(id).url)
|
|
104
|
+
puts.get(id).status = 'waiting'
|
|
105
|
+
})
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.error('Error on PUT, waiting...', puts.get(id).url)
|
|
108
|
+
puts.get(id).status = 'waiting'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function retry_put (id) {
|
|
112
|
+
setTimeout(function () {send_put(id)}, 1000)
|
|
113
|
+
}
|
|
114
|
+
function send_all_puts () {
|
|
115
|
+
for (var id of puts.keys())
|
|
116
|
+
if (puts.get(id).status === 'waiting') {
|
|
117
|
+
console.log('Sending waiting put', id)
|
|
118
|
+
send_put(id)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
78
121
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// if (t.parents) x.parents = t.parents
|
|
82
|
-
// if (t.patch) x.patch = t.patch
|
|
83
|
-
// if (t.patch) x.save = rem_prefix(x.save.key)
|
|
122
|
+
bus(prefix).to_set = function (obj, t) {
|
|
123
|
+
bus.set.fire(obj)
|
|
84
124
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
125
|
+
var put = {
|
|
126
|
+
url: url + rem_prefix(obj.key),
|
|
127
|
+
body: JSON.stringify(obj.val)
|
|
128
|
+
}
|
|
129
|
+
if (t.version) put.version = t.version
|
|
130
|
+
if (t.parents) put.parents = t.parents
|
|
131
|
+
if (t.patch) put.patch = t.patch
|
|
132
|
+
var put_id = put_counter++
|
|
133
|
+
puts.set(put_id, put)
|
|
134
|
+
send_put(put_id)
|
|
91
135
|
}
|
|
92
136
|
|
|
93
|
-
bus(prefix).
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
137
|
+
bus(prefix).to_get = function (key, t) {
|
|
138
|
+
// Subscription can be in states:
|
|
139
|
+
// - connecting
|
|
140
|
+
// - connected
|
|
141
|
+
// - reconnect
|
|
142
|
+
// - reconnecting
|
|
143
|
+
// - aborted
|
|
144
|
+
|
|
145
|
+
// If we have an outstanding get running, then let's tell it to
|
|
146
|
+
// re-activate!
|
|
147
|
+
if (subscriptions[key]) {
|
|
148
|
+
// We should only be here if an existing subscription was
|
|
149
|
+
// aborted, but hasn't cleared yet.
|
|
150
|
+
console.assert(subscriptions[key].status === 'aborted',
|
|
151
|
+
'Regetting a subscription of status '
|
|
152
|
+
+ subscriptions[key].status)
|
|
153
|
+
|
|
154
|
+
console.trace('foo')
|
|
155
|
+
|
|
156
|
+
// Let's tell it to reconnect when it tries to clear!
|
|
157
|
+
subscriptions[key].status = 'reconnect'
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Otherwise, create a new subscription
|
|
161
|
+
else
|
|
162
|
+
subscribe (key, t)
|
|
163
|
+
|
|
164
|
+
function subscribe (key, t) {
|
|
165
|
+
var aborter = new AbortController(),
|
|
166
|
+
reconnect_attempts = 0
|
|
167
|
+
|
|
168
|
+
// Start the subscription!
|
|
169
|
+
braid_fetch(
|
|
170
|
+
// URL
|
|
171
|
+
url + rem_prefix(key),
|
|
172
|
+
|
|
173
|
+
// Options
|
|
174
|
+
{
|
|
175
|
+
method: 'get',
|
|
176
|
+
subscribe: true,
|
|
177
|
+
headers: {accept: 'application/json'},
|
|
178
|
+
signal: aborter.signal
|
|
179
|
+
}
|
|
180
|
+
).andThen( function (x) {
|
|
181
|
+
// New update received!
|
|
182
|
+
if (subscriptions[key].status === 'connecting') {
|
|
183
|
+
console.log('%c[*] opened ' + key,
|
|
184
|
+
'color: blue')
|
|
185
|
+
reconnect_attempts = 0
|
|
186
|
+
subscriptions[key].status = 'connected'
|
|
187
|
+
send_all_puts()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Return the update
|
|
191
|
+
t.return({
|
|
192
|
+
key: key,
|
|
193
|
+
val: add_prefixes(JSON.parse(x.body))
|
|
194
|
+
})
|
|
195
|
+
}).catch( function (e) {
|
|
196
|
+
if (subscriptions[key].status === 'aborted') {
|
|
197
|
+
// Then this get is over and done with!
|
|
198
|
+
delete subscriptions[key]
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Reconnect!
|
|
203
|
+
setTimeout(function () { subscribe(key, t) },
|
|
204
|
+
reconnect_attempts > 0 ? 5000 : 1500)
|
|
205
|
+
subscriptions[key].status = 'reconnecting'
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
// Remember this subscription
|
|
209
|
+
subscriptions[key] = {
|
|
210
|
+
aborter: aborter,
|
|
211
|
+
status: 'connecting'
|
|
212
|
+
}
|
|
109
213
|
}
|
|
110
|
-
client_fetched_keys.add(key)
|
|
111
214
|
}
|
|
112
215
|
bus(prefix).to_forget = function (key) {
|
|
113
|
-
|
|
114
|
-
|
|
216
|
+
subscriptions[key].status = 'aborted'
|
|
217
|
+
subscriptions[key].aborter.abort()
|
|
115
218
|
}
|
|
116
219
|
}
|
|
117
220
|
|
|
@@ -121,37 +224,30 @@
|
|
|
121
224
|
function localstorage_client (prefix) {
|
|
122
225
|
try { localStorage } catch (e) { return }
|
|
123
226
|
|
|
124
|
-
//
|
|
125
|
-
|
|
227
|
+
// Sets are queued up, to store values with a delay, in batch
|
|
228
|
+
var sets_are_pending = false
|
|
229
|
+
var pending_sets = {}
|
|
126
230
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
var saves_are_pending = false
|
|
133
|
-
var pending_saves = {}
|
|
134
|
-
|
|
135
|
-
function save_the_pending_saves() {
|
|
136
|
-
bus.log('localstore: saving', pending_saves)
|
|
137
|
-
for (var k in pending_saves)
|
|
138
|
-
localStorage.setItem(k, JSON.stringify(pending_saves[k]))
|
|
139
|
-
saves_are_pending = false
|
|
231
|
+
function set_the_pending_sets() {
|
|
232
|
+
bus.log('localstore: saving', pending_sets)
|
|
233
|
+
for (var k in pending_sets)
|
|
234
|
+
localStorage.setItem(k, JSON.stringify(pending_sets[k]))
|
|
235
|
+
sets_are_pending = false
|
|
140
236
|
}
|
|
141
237
|
|
|
142
|
-
bus(prefix).
|
|
238
|
+
bus(prefix).to_get = function (key) {
|
|
143
239
|
var result = localStorage.getItem(key)
|
|
144
240
|
return result ? JSON.parse(result) : {key: key}
|
|
145
241
|
}
|
|
146
|
-
bus(prefix).
|
|
242
|
+
bus(prefix).to_set = function (obj) {
|
|
147
243
|
// Do I need to make this recurse into the object?
|
|
148
|
-
bus.log('localStore:
|
|
149
|
-
|
|
150
|
-
if (!
|
|
151
|
-
setTimeout(
|
|
152
|
-
|
|
244
|
+
bus.log('localStore: on_set:', obj.key)
|
|
245
|
+
pending_sets[obj.key] = obj
|
|
246
|
+
if (!sets_are_pending) {
|
|
247
|
+
setTimeout(set_the_pending_sets, 50)
|
|
248
|
+
sets_are_pending = true
|
|
153
249
|
}
|
|
154
|
-
bus.
|
|
250
|
+
bus.set.fire(obj)
|
|
155
251
|
return obj
|
|
156
252
|
}
|
|
157
253
|
bus(prefix).to_delete = function (key) { localStorage.removeItem(key) }
|
|
@@ -160,6 +256,7 @@
|
|
|
160
256
|
// Hm... this update stuff doesn't seem to work on file:/// urls in chrome
|
|
161
257
|
function update (event) {
|
|
162
258
|
bus.log('Got a localstorage update', event)
|
|
259
|
+
bus.dirty(event.key)
|
|
163
260
|
//this.get(event.key.substr('statebus '.length))
|
|
164
261
|
}
|
|
165
262
|
if (window.addEventListener) window.addEventListener("storage", update, false)
|
|
@@ -184,39 +281,16 @@
|
|
|
184
281
|
data = (data && JSON.parse(data)) || {key : key}
|
|
185
282
|
// Then I would need to:
|
|
186
283
|
// - Change the key prefix
|
|
187
|
-
// -
|
|
284
|
+
// - Set this into the cache
|
|
188
285
|
|
|
189
|
-
bus(prefix).
|
|
286
|
+
bus(prefix).to_set = function (obj) {
|
|
190
287
|
window.history.replaceState(
|
|
191
288
|
'',
|
|
192
289
|
'',
|
|
193
290
|
document.location.origin
|
|
194
291
|
+ document.location.pathname
|
|
195
292
|
+ escape('?'+key+'='+JSON.stringify(obj)))
|
|
196
|
-
bus.
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function live_reload_from (prefix) {
|
|
201
|
-
if (!window.live_reload_initialized) {
|
|
202
|
-
var first_time = true
|
|
203
|
-
this(function () {
|
|
204
|
-
var re = new RegExp(".*/" + prefix + "/(.*)")
|
|
205
|
-
var file = window.location.href.match(re)[1]
|
|
206
|
-
var code = bus.fetch('/code/invisible.college/' + file).code
|
|
207
|
-
if (!code) return
|
|
208
|
-
if (first_time) {first_time = false; return}
|
|
209
|
-
var old_scroll_position = window.pageYOffset
|
|
210
|
-
document.body.innerHTML = code
|
|
211
|
-
var i = 0
|
|
212
|
-
var d = 100
|
|
213
|
-
var interval = setInterval(function () {
|
|
214
|
-
if (i > 500) clearInterval(interval)
|
|
215
|
-
i += d
|
|
216
|
-
window.scrollTo(0, old_scroll_position)
|
|
217
|
-
}, d)
|
|
218
|
-
})
|
|
219
|
-
window.live_reload_initialized = true
|
|
293
|
+
bus.set.fire(obj)
|
|
220
294
|
}
|
|
221
295
|
}
|
|
222
296
|
|
|
@@ -224,30 +298,40 @@
|
|
|
224
298
|
// ****************
|
|
225
299
|
// Wrapper for React Components
|
|
226
300
|
|
|
301
|
+
function react_version () {
|
|
302
|
+
if (!window.React) return undefined;
|
|
303
|
+
return Number(window.React.version.split('.')[0])
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Newer React requires createReactClass as a separate libary
|
|
307
|
+
if (window.React && !React.createClass && window.createReactClass)
|
|
308
|
+
React.createClass = createReactClass
|
|
309
|
+
|
|
227
310
|
// XXX Currently assumes there's a statebus named "bus" in global
|
|
228
311
|
// XXX scope.
|
|
229
312
|
|
|
230
313
|
var components = {} // Indexed by 'component/0', 'component/1', etc.
|
|
231
314
|
var components_count = 0
|
|
232
315
|
var dirty_components = {}
|
|
233
|
-
function
|
|
316
|
+
function create_react_class(component) {
|
|
234
317
|
function wrap(name, new_func) {
|
|
235
318
|
var old_func = component[name]
|
|
236
319
|
component[name] = function wrapper () { return new_func.bind(this)(old_func) }
|
|
237
320
|
}
|
|
238
321
|
|
|
239
322
|
// Register the component's basic info
|
|
240
|
-
wrap('
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
323
|
+
wrap((react_version() >= 16 ? 'UNSAFE_' : '') + 'componentWillMount',
|
|
324
|
+
function new_cwm (orig_func) {
|
|
325
|
+
// if (component.displayName === undefined)
|
|
326
|
+
// throw 'Component needs a displayName'
|
|
327
|
+
//this.name = component.displayName.toLowerCase().replace(' ', '_')
|
|
244
328
|
this.key = 'component/' + components_count++
|
|
245
329
|
components[this.key] = this
|
|
246
330
|
|
|
247
331
|
function add_shortcut (obj, shortcut_name, to_key) {
|
|
248
332
|
delete obj[shortcut_name]
|
|
249
333
|
Object.defineProperty(obj, shortcut_name, {
|
|
250
|
-
get: function () { return bus.
|
|
334
|
+
get: function () { return bus.get(to_key) },
|
|
251
335
|
configurable: true })
|
|
252
336
|
}
|
|
253
337
|
add_shortcut(this, 'local', this.key)
|
|
@@ -268,7 +352,7 @@
|
|
|
268
352
|
&& typeof this.props[k] === 'object'
|
|
269
353
|
&& this.props[k].key)
|
|
270
354
|
|
|
271
|
-
bus.
|
|
355
|
+
bus.get(this.props[k].key)
|
|
272
356
|
|
|
273
357
|
// Call the renderer!
|
|
274
358
|
return orig_render.apply(this, arguments)
|
|
@@ -339,17 +423,12 @@
|
|
|
339
423
|
props['data-key'] = props.key
|
|
340
424
|
props['data-widget'] = component.displayName
|
|
341
425
|
|
|
342
|
-
return
|
|
343
|
-
? React.createElement(react_class, props, children)
|
|
344
|
-
: react_class(props, children))
|
|
426
|
+
return React.createElement(react_class, props, children)
|
|
345
427
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
result.prototype = react_class.prototype
|
|
428
|
+
Object.defineProperty(result, 'name',
|
|
429
|
+
{value: component.displayName, writable: false})
|
|
349
430
|
return result
|
|
350
431
|
}
|
|
351
|
-
window.React_View = React_View
|
|
352
|
-
if (window.statebus) window.statebus.create_react_class = window.statebus.createReactClass = React_View
|
|
353
432
|
|
|
354
433
|
// *****************
|
|
355
434
|
// Re-rendering react components
|
|
@@ -384,7 +463,7 @@
|
|
|
384
463
|
|
|
385
464
|
function make_client_statebus_maker () {
|
|
386
465
|
var extra_stuff = ['localstorage_client make_websocket client_creds',
|
|
387
|
-
'url_store components
|
|
466
|
+
'url_store components'].join(' ').split(' ')
|
|
388
467
|
if (window.statebus) {
|
|
389
468
|
var orig_statebus = statebus
|
|
390
469
|
window.statebus = function make_client_bus () {
|
|
@@ -405,17 +484,17 @@
|
|
|
405
484
|
if (statebus_dir) statebus_dir = statebus_dir[1] + '/'
|
|
406
485
|
else statebus_dir = ''
|
|
407
486
|
|
|
408
|
-
var js_urls = {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
if (statebus_dir == 'https://stateb.us/')
|
|
415
|
-
|
|
487
|
+
// var js_urls = {
|
|
488
|
+
// react: statebus_dir + 'extras/react.js',
|
|
489
|
+
// sockjs: statebus_dir + 'extras/sockjs.js',
|
|
490
|
+
// coffee: statebus_dir + 'extras/coffee.js',
|
|
491
|
+
// statebus: statebus_dir + 'statebus.js'
|
|
492
|
+
// }
|
|
493
|
+
// if (statebus_dir == 'https://stateb.us/')
|
|
494
|
+
// js_urls.statebus = statebus_dir + 'statebus4.js'
|
|
416
495
|
|
|
417
|
-
for (var name in js_urls)
|
|
418
|
-
|
|
496
|
+
// for (var name in js_urls)
|
|
497
|
+
// document.write('<script src="' + js_urls[name] + '" charset="utf-8"></script>')
|
|
419
498
|
|
|
420
499
|
document.addEventListener('DOMContentLoaded', scripts_ready, false)
|
|
421
500
|
}
|
|
@@ -426,56 +505,52 @@
|
|
|
426
505
|
function clientjs_option (option_name) {
|
|
427
506
|
// This function must be copy/paste synchronized with statebus.js. Be
|
|
428
507
|
// sure to clone all edits there.
|
|
429
|
-
var script_elem = (
|
|
430
|
-
document.querySelector('script[src*="/client"][src$=".js"]') ||
|
|
431
|
-
document.querySelector('script[src^="client"][src$=".js"]'))
|
|
508
|
+
var script_elem = document.querySelector('script[src$="statebus/client.js"]')
|
|
432
509
|
return script_elem && script_elem.getAttribute(option_name)
|
|
433
510
|
}
|
|
434
511
|
var loaded_from_file_url = window.location.href.match(/^file:\/\//)
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
window.
|
|
512
|
+
|
|
513
|
+
// Todo: remove this global
|
|
514
|
+
window.statebus_server = clientjs_option('server')
|
|
438
515
|
var react_render
|
|
439
516
|
function scripts_ready () {
|
|
440
|
-
react_render =
|
|
441
|
-
make_client_statebus_maker()
|
|
517
|
+
react_render = ReactDOM.render
|
|
518
|
+
// make_client_statebus_maker()
|
|
442
519
|
window.bus = window.statebus()
|
|
443
520
|
bus.label = 'bus'
|
|
444
|
-
if (clientjs_option('braid_mode'))
|
|
445
|
-
bus.state = bus.braid_proxy()
|
|
446
|
-
else
|
|
447
|
-
window.sb = bus.sb
|
|
448
|
-
statebus.widget = React_View
|
|
449
|
-
statebus.create_react_class = React_View
|
|
450
|
-
statebus.createReactClass = React_View
|
|
451
|
-
|
|
452
|
-
improve_react()
|
|
453
|
-
window.ignore_flashbacks = false
|
|
454
|
-
if (statebus_server !== 'none') {
|
|
455
|
-
if (clientjs_option('braid_mode')) {
|
|
456
|
-
console.log('Using Braid-HTTP!')
|
|
457
|
-
braid_http_mount ('/*', statebus_server)
|
|
458
|
-
} else {
|
|
459
|
-
bus.net_mount ('/*', statebus_server)
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
521
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
522
|
+
statebus.create_react_class = create_react_class
|
|
523
|
+
statebus.createReactClass = create_react_class
|
|
524
|
+
|
|
525
|
+
// improve_react()
|
|
526
|
+
statebus.ignore_flashbacks = false
|
|
527
|
+
bus.libs = {}
|
|
528
|
+
bus.libs.http_out = http_mount
|
|
529
|
+
bus.libs.react_class = create_react_class
|
|
530
|
+
bus.libs.input = make_better_input_17()
|
|
531
|
+
bus.libs.localstorage = localstorage_client
|
|
532
|
+
|
|
533
|
+
// if (statebus_server !== 'none') {
|
|
534
|
+
// if (clientjs_option('braid_mode')) {
|
|
535
|
+
// console.log('Using Braid-HTTP!')
|
|
536
|
+
// http_mount ('/*', statebus_server)
|
|
537
|
+
// } else {
|
|
538
|
+
// bus.ws_mount ('/*', statebus_server)
|
|
539
|
+
// }
|
|
540
|
+
// }
|
|
541
|
+
|
|
467
542
|
bus.net_automount()
|
|
468
543
|
|
|
469
544
|
// This /new/* code is deprecated
|
|
470
545
|
if (!clientjs_option('braid_mode')) {
|
|
471
|
-
bus('/new/*').
|
|
546
|
+
bus('/new/*').to_set = function (o) {
|
|
472
547
|
if (o.key.split('/').length > 3) return
|
|
473
548
|
|
|
474
549
|
var old_key = o.key
|
|
475
550
|
o.key = old_key + '/' + Math.random().toString(36).substring(2,12)
|
|
476
551
|
statebus.cache[o.key] = o
|
|
477
552
|
delete statebus.cache[old_key]
|
|
478
|
-
bus.
|
|
553
|
+
bus.set(o)
|
|
479
554
|
}
|
|
480
555
|
}
|
|
481
556
|
|
|
@@ -485,6 +560,17 @@
|
|
|
485
560
|
statebus.load_client_code = load_client_code
|
|
486
561
|
statebus.load_widgets = load_widgets
|
|
487
562
|
|
|
563
|
+
if (clientjs_option('globals')) {
|
|
564
|
+
// Setup globals
|
|
565
|
+
var globals = ['get', 'set', 'state']
|
|
566
|
+
|
|
567
|
+
for (var i=0; i<globals.length; i++) {
|
|
568
|
+
console.log('globalizing', globals[i], 'as',
|
|
569
|
+
eval('bus.' + globals[i]))
|
|
570
|
+
window[globals[i]] = eval('bus.' + globals[i])
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
488
574
|
document.addEventListener('DOMContentLoaded', function () {
|
|
489
575
|
if (window.statebus_ready)
|
|
490
576
|
for (var i=0; i<statebus_ready.length; i++)
|
|
@@ -604,7 +690,7 @@
|
|
|
604
690
|
for (var i=0; i<arguments.length; i++) {
|
|
605
691
|
args.push(arguments[i])
|
|
606
692
|
if (arguments[i].state)
|
|
607
|
-
args[i].src = 'data:;base64,' +
|
|
693
|
+
args[i].src = 'data:;base64,' + bus.get(args[i].state)._
|
|
608
694
|
}
|
|
609
695
|
return og_img.apply(this, args)
|
|
610
696
|
}
|
|
@@ -636,12 +722,38 @@
|
|
|
636
722
|
}
|
|
637
723
|
|
|
638
724
|
|
|
725
|
+
// This one is for react v17+
|
|
726
|
+
function make_better_input_17 () {
|
|
727
|
+
return createReactClass({
|
|
728
|
+
getInitialState: function() {
|
|
729
|
+
return {value: this.props.value}
|
|
730
|
+
},
|
|
731
|
+
UNSAVE_componentWillReceiveProps: function(new_props) {
|
|
732
|
+
this.setState({value: new_props.value})
|
|
733
|
+
},
|
|
734
|
+
onChange: function(e) {
|
|
735
|
+
this.props.onChange && this.props.onChange(e)
|
|
736
|
+
if (this.props.value)
|
|
737
|
+
this.setState({value: e.target.value})
|
|
738
|
+
},
|
|
739
|
+
render: function() {
|
|
740
|
+
var new_props = {}
|
|
741
|
+
for (var k in this.props)
|
|
742
|
+
if (this.props.hasOwnProperty(k))
|
|
743
|
+
new_props[k] = this.props[k]
|
|
744
|
+
if (this.state.value) new_props.value = this.state.value
|
|
745
|
+
new_props.onChange = this.onChange
|
|
746
|
+
return React.createElement('input', new_props)
|
|
747
|
+
}
|
|
748
|
+
})
|
|
749
|
+
}
|
|
750
|
+
|
|
639
751
|
// Load the components
|
|
640
752
|
var users_widgets = {}
|
|
641
753
|
function make_component(name, func) {
|
|
642
754
|
// Define the component
|
|
643
755
|
|
|
644
|
-
window[name] = users_widgets[name] =
|
|
756
|
+
window[name] = users_widgets[name] = statebus.create_react_class({
|
|
645
757
|
displayName: name,
|
|
646
758
|
render: function () {
|
|
647
759
|
var args = []
|