statebus 6.1.21 → 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.
Files changed (3) hide show
  1. package/client.js +77 -19
  2. package/package.json +1 -1
  3. package/server.js +16 -14
package/client.js CHANGED
@@ -62,7 +62,7 @@
62
62
  var preprefix = prefix.slice(0,-1)
63
63
  var has_prefix = new RegExp('^' + preprefix)
64
64
  var is_absolute = /^https?:\/\//
65
- var client_fetched_keys = new bus.Set()
65
+ var subscriptions = {}
66
66
  //if (url[url.length-1]=='/') url = url.substr(0,url.length-1)
67
67
  function add_prefix (key) {
68
68
  return is_absolute.test(key) ? key : preprefix + key }
@@ -91,27 +91,85 @@
91
91
  }
92
92
 
93
93
  bus(prefix).to_fetch = function (key, t) {
94
- try {
95
- braid_fetch(url + rem_prefix(key),
96
- {
97
- method: 'get',
98
- subscribe: true,
99
- headers: {accept: 'application/json'}
100
- }
101
- ).andThen( function (x) {
102
- t.return({
103
- key: key,
104
- val: add_prefixes(JSON.parse(x.body))
105
- })
106
- })
107
- } catch (e) {
108
- 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
+ }
109
168
  }
110
- client_fetched_keys.add(key)
111
169
  }
112
170
  bus(prefix).to_forget = function (key) {
113
- // send({forget: key}),
114
- client_fetched_keys.delete(key)
171
+ subscriptions[key].status = 'aborted'
172
+ subscriptions[key].aborter.abort()
115
173
  }
116
174
  }
117
175
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statebus",
3
- "version": "6.1.21",
3
+ "version": "6.1.22",
4
4
  "description": "Synchronize state.",
5
5
  "main": "statebus.js",
6
6
  "scripts": {
package/server.js CHANGED
@@ -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
  }
@@ -587,6 +588,7 @@ function import_server (bus, options)
587
588
  }
588
589
  })
589
590
 
591
+ // console.log('websocket listening on', '/' + bus.options.websocket_path)
590
592
  s.installHandlers(httpserver, {prefix:'/' + bus.options.websocket_path})
591
593
  },
592
594
 
@@ -595,7 +597,7 @@ function import_server (bus, options)
595
597
  url = url.replace(/^istate:\/\//, 'ws://')
596
598
  url = url.replace(/^statei:\/\//, 'ws://')
597
599
  WebSocket = require('websocket').w3cwebsocket
598
- return new WebSocket(url+'/'+bus.options.websocket_path+'/websocket')
600
+ return new WebSocket(url + '/' + bus.options.websocket_path + '/websocket')
599
601
  },
600
602
  client_creds: function client_creds (server_url) {
601
603
  // Right now the server just creates a different random id each time