statebus 6.1.18 → 6.1.22

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 CHANGED
@@ -1,5 +1,6 @@
1
1
  (function () {
2
- var unique_sockjs_string = '_connect_to_statebus_'
2
+ var websocket_prefix = (clientjs_option('websocket_path')
3
+ || '_connect_to_statebus_')
3
4
 
4
5
  window.dom = window.dom || new Proxy({}, {
5
6
  get: function (o, k) { return o[k] },
@@ -36,9 +37,9 @@
36
37
  // link.href = url
37
38
  // url = link.href
38
39
  // }
39
- console.log('opening websocket to', url)
40
- return new WebSocket(url + '/' + unique_sockjs_string + '/websocket')
41
- // return new SockJS(url + '/' + unique_sockjs_string)
40
+
41
+ return new WebSocket(url + '/' + websocket_prefix + '/websocket')
42
+ // return new SockJS(url + '/' + websocket_prefix)
42
43
  }
43
44
  function client_creds (server_url) {
44
45
  var me = bus.fetch('ls/me')
@@ -61,7 +62,7 @@
61
62
  var preprefix = prefix.slice(0,-1)
62
63
  var has_prefix = new RegExp('^' + preprefix)
63
64
  var is_absolute = /^https?:\/\//
64
- var client_fetched_keys = new bus.Set()
65
+ var subscriptions = {}
65
66
  //if (url[url.length-1]=='/') url = url.substr(0,url.length-1)
66
67
  function add_prefix (key) {
67
68
  return is_absolute.test(key) ? key : preprefix + key }
@@ -90,27 +91,85 @@
90
91
  }
91
92
 
92
93
  bus(prefix).to_fetch = function (key, t) {
93
- try {
94
- braid_fetch(url + rem_prefix(key),
95
- {
96
- method: 'get',
97
- subscribe: true,
98
- headers: {accept: 'application/json'}
99
- }
100
- ).andThen( x => {
101
- t.return({
102
- key,
103
- val: add_prefixes(JSON.parse(x.body))
104
- })
105
- })
106
- } catch (e) {
107
- console.error('Braid-HTTP network error:', e)
94
+ // Subscription can be in states:
95
+ // - connecting
96
+ // - connected
97
+ // - reconnect
98
+ // - reconnecting
99
+ // - aborted
100
+
101
+ // If we have an outstanding fetch running, then let's tell it to
102
+ // re-activate!
103
+ if (subscriptions[key]) {
104
+ // We should only be here if an existing subscription was
105
+ // aborted, but hasn't cleared yet.
106
+ console.assert(subscriptions[key].status === 'aborted',
107
+ 'Refetching a subscription of status '
108
+ + subscriptions[key].status)
109
+
110
+ console.trace('foo')
111
+
112
+ // Let's tell it to reconnect when it tries to clear!
113
+ subscriptions[key].status = 'reconnect'
114
+ }
115
+
116
+ // Otherwise, create a new subscription
117
+ else
118
+ subscribe (key, t)
119
+
120
+ function subscribe (key, t) {
121
+ var aborter = new AbortController(),
122
+ reconnect_attempts = 0
123
+
124
+ // Start the subscription!
125
+ braid_fetch(
126
+ // URL
127
+ url + rem_prefix(key),
128
+
129
+ // Options
130
+ {
131
+ method: 'get',
132
+ subscribe: true,
133
+ headers: {accept: 'application/json'},
134
+ signal: aborter.signal
135
+ }
136
+ ).andThen( function (x) {
137
+ // New update received!
138
+ if (subscriptions[key].status === 'connecting') {
139
+ console.log('%c[*] opened ' + key,
140
+ 'color: blue')
141
+ reconnect_attempts = 0
142
+ subscriptions[key].status = 'connected'
143
+ }
144
+
145
+ // Return the update
146
+ t.return({
147
+ key: key,
148
+ val: add_prefixes(JSON.parse(x.body))
149
+ })
150
+ }).catch( function (e) {
151
+ if (subscriptions[key].status === 'aborted') {
152
+ // Then this fetch is over and done with!
153
+ delete subscriptions[key]
154
+ return
155
+ }
156
+
157
+ // Reconnect!
158
+ setTimeout(function () { subscribe(key, t) },
159
+ reconnect_attempts > 0 ? 5000 : 1500)
160
+ subscriptions[key].status = 'reconnecting'
161
+ })
162
+
163
+ // Remember this subscription
164
+ subscriptions[key] = {
165
+ aborter: aborter,
166
+ status: 'connecting'
167
+ }
108
168
  }
109
- client_fetched_keys.add(key)
110
169
  }
111
170
  bus(prefix).to_forget = function (key) {
112
- // send({forget: key}),
113
- client_fetched_keys.delete(key)
171
+ subscriptions[key].status = 'aborted'
172
+ subscriptions[key].aborter.abort()
114
173
  }
115
174
  }
116
175
 
@@ -452,11 +511,10 @@
452
511
  window.ignore_flashbacks = false
453
512
  if (statebus_server !== 'none') {
454
513
  if (clientjs_option('braid_mode')) {
455
- console.log('We socket-free!')
514
+ console.log('Using Braid-HTTP!')
456
515
  braid_http_mount ('/*', statebus_server)
457
516
  } else {
458
517
  bus.net_mount ('/*', statebus_server)
459
- console.log('We going websocket!')
460
518
  }
461
519
  }
462
520
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statebus",
3
- "version": "6.1.18",
3
+ "version": "6.1.22",
4
4
  "description": "Synchronize state.",
5
5
  "main": "statebus.js",
6
6
  "scripts": {
package/server.js CHANGED
@@ -1,6 +1,5 @@
1
1
  var fs = require('fs'),
2
2
  util = require('util')
3
- var unique_sockjs_string = '_connect_to_statebus_'
4
3
 
5
4
  // Import braidify if it's available
6
5
  try {
@@ -22,6 +21,7 @@ function default_options (bus) { return {
22
21
  certificate: 'certs/certificate',
23
22
  certificate_bundle: 'certs/certificate-bundle'},
24
23
  connections: {include_users: true, edit_others: true},
24
+ websocket_path: '_connect_to_statebus_',
25
25
  __secure: false
26
26
  }}
27
27
 
@@ -219,24 +219,25 @@ function import_server (bus, options)
219
219
  cbus.fetch(key, cb = (o) => {
220
220
  var body = bus.to_http_body(o)
221
221
 
222
- // // Return 404 if the value is undefined
223
- // if (!body) {
224
- // console.log('no body! time to 404')
225
- // res.statusCode = 404
226
- // res.end()
227
- // }
228
-
229
- // Or if we're braid, send via subscription
230
- // else
222
+ // If we're braiding, send via subscription
231
223
  if (braidify)
224
+ // Note: if body === undefined, we need to send the
225
+ // equivalent of a 404. This is missing in braid spec:
226
+ // https://github.com/braid-org/braid-spec/issues/110
232
227
  res.sendVersion({body: body || 'null'})
233
228
 
234
229
  // Or just return the current version
235
- else
236
- res.send(body)
230
+ else {
231
+ if (body !== undefined)
232
+ res.send(body)
233
+ else {
234
+ res.statusCode = 404
235
+ res.end()
236
+ }
237
+ }
237
238
 
238
- // And shut down the connection if nothing's left to do
239
- if (!braidify || !req.subscribe || !body)
239
+ // And shut down the connection if there's no subscription
240
+ if (!braidify || !req.subscribe)
240
241
  end_it_all()
241
242
  })
242
243
  }
@@ -386,7 +387,8 @@ function import_server (bus, options)
386
387
  this.http_server.on('request', // Install express
387
388
  function (request, response) {
388
389
  // But express should ignore all sockjs requests
389
- if (!request.url.startsWith('/'+unique_sockjs_string+'/'))
390
+ if (!request.url.startsWith(
391
+ '/' + bus.options.websocket_path + '/'))
390
392
  express_app(request, response)
391
393
  })
392
394
 
@@ -586,7 +588,8 @@ function import_server (bus, options)
586
588
  }
587
589
  })
588
590
 
589
- s.installHandlers(httpserver, {prefix:'/' + unique_sockjs_string})
591
+ // console.log('websocket listening on', '/' + bus.options.websocket_path)
592
+ s.installHandlers(httpserver, {prefix:'/' + bus.options.websocket_path})
590
593
  },
591
594
 
592
595
  make_websocket: function make_websocket (url) {
@@ -594,7 +597,7 @@ function import_server (bus, options)
594
597
  url = url.replace(/^istate:\/\//, 'ws://')
595
598
  url = url.replace(/^statei:\/\//, 'ws://')
596
599
  WebSocket = require('websocket').w3cwebsocket
597
- return new WebSocket(url+'/'+unique_sockjs_string+'/websocket')
600
+ return new WebSocket(url + '/' + bus.options.websocket_path + '/websocket')
598
601
  },
599
602
  client_creds: function client_creds (server_url) {
600
603
  // Right now the server just creates a different random id each time
package/statebus.js CHANGED
@@ -10,10 +10,12 @@
10
10
  // Fetch, Save, Forget, Delete
11
11
 
12
12
  function fetch (key, callback) {
13
+ if (typeof key !== 'string'
14
+ && !(typeof key === 'object' && typeof key.key === 'string'))
15
+ throw ('Error: fetch(key) called with key = '
16
+ + JSON.stringify(key))
13
17
  key = key.key || key // You can pass in an object instead of key
14
18
  // We should probably disable this in future
15
- if (typeof key !== 'string')
16
- throw ('Error: fetch(key) called with a non-string key: '+key)
17
19
  bogus_check(key)
18
20
 
19
21
  var called_from_reactive_funk = !callback