statebus 6.1.13 → 6.1.17

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
@@ -62,7 +62,7 @@
62
62
  var has_prefix = new RegExp('^' + preprefix)
63
63
  var is_absolute = /^https?:\/\//
64
64
  var client_fetched_keys = new bus.Set()
65
- if (url[url.length-1]=='/') url = url.substr(0,url.length-1)
65
+ //if (url[url.length-1]=='/') url = url.substr(0,url.length-1)
66
66
  function add_prefix (key) {
67
67
  return is_absolute.test(key) ? key : preprefix + key }
68
68
  function rem_prefix (key) {
@@ -73,7 +73,6 @@
73
73
  return bus.translate_keys(bus.clone(obj), rem_prefix) }
74
74
 
75
75
  bus(prefix).to_save = function (obj, t) {
76
- console.log('saving', prefix, obj)
77
76
  bus.save.fire(obj)
78
77
 
79
78
  // var x = {save: obj}
@@ -82,9 +81,10 @@
82
81
  // if (t.patch) x.patch = t.patch
83
82
  // if (t.patch) x.save = rem_prefix(x.save.key)
84
83
 
85
- braid_fetch(url + obj.key,
84
+ braid_fetch(url + rem_prefix(obj.key),
86
85
  {
87
86
  method: 'put',
87
+ 'content-type': 'application/json',
88
88
  body: JSON.stringify(obj.val)
89
89
  })
90
90
  }
@@ -94,7 +94,8 @@
94
94
  braid_fetch(url + rem_prefix(key),
95
95
  {
96
96
  method: 'get',
97
- subscribe: true
97
+ subscribe: true,
98
+ headers: {accept: 'application/json'}
98
99
  }
99
100
  ).andThen( x => {
100
101
  t.return({
@@ -439,7 +440,7 @@
439
440
  make_client_statebus_maker()
440
441
  window.bus = window.statebus()
441
442
  bus.label = 'bus'
442
- if (clientjs_option('braid_mode_test'))
443
+ if (clientjs_option('braid_mode'))
443
444
  bus.state = bus.braid_proxy()
444
445
  else
445
446
  window.sb = bus.sb
@@ -450,9 +451,13 @@
450
451
  improve_react()
451
452
  window.ignore_flashbacks = false
452
453
  if (statebus_server !== 'none') {
453
- bus.net_mount ('/*', statebus_server)
454
- if (clientjs_option('braid_mode_test'))
455
- braid_http_mount ('http/*', statebus_server)
454
+ if (clientjs_option('braid_mode')) {
455
+ console.log('We socket-free!')
456
+ braid_http_mount ('/*', statebus_server)
457
+ } else {
458
+ bus.net_mount ('/*', statebus_server)
459
+ console.log('We going websocket!')
460
+ }
456
461
  }
457
462
 
458
463
  if (window.statebus_backdoor) {
@@ -462,7 +467,7 @@
462
467
  bus.net_automount()
463
468
 
464
469
  // This /new/* code is deprecated
465
- if (!clientjs_option('braid_mode_test')) {
470
+ if (!clientjs_option('braid_mode')) {
466
471
  bus('/new/*').to_save = function (o) {
467
472
  if (o.key.split('/').length > 3) return
468
473
 
package/extras/tests.js CHANGED
@@ -872,7 +872,7 @@ test(function proxies2 (done) {
872
872
  })
873
873
 
874
874
  test(function braid_proxies (done) {
875
- var bus = require('../statebus').serve({braid_mode_test: true,
875
+ var bus = require('../statebus').serve({braid_mode: true,
876
876
  file_store: false})
877
877
  var state = bus.state
878
878
 
@@ -896,8 +896,8 @@ test(function braid_proxies (done) {
896
896
  log('array:', state.array)
897
897
  log('bar:', state.bar)
898
898
  assert(state.bar.a[1] !== 2,
899
- "Array ref linked.\n\t"
900
- + JSON.stringify(bus.cache.bar) + '\n\t'
899
+ "Array ref linked.\n\tbar: "
900
+ + JSON.stringify(bus.cache.bar) + '\n\tarray: '
901
901
  + JSON.stringify(bus.cache.array))
902
902
 
903
903
  state.undefining = undefined
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statebus",
3
- "version": "6.1.13",
3
+ "version": "6.1.17",
4
4
  "description": "Synchronize state.",
5
5
  "main": "statebus.js",
6
6
  "scripts": {
package/server.js CHANGED
@@ -2,6 +2,15 @@ var fs = require('fs'),
2
2
  util = require('util')
3
3
  var unique_sockjs_string = '_connect_to_statebus_'
4
4
 
5
+ // Import braidify if it's available
6
+ try {
7
+ var braidify = require('braidify').http_server
8
+ console.log('Found braidify library. Braid-HTTP enabled!')
9
+ } catch (e) {
10
+ var braidify = undefined
11
+ }
12
+
13
+
5
14
  function default_options (bus) { return {
6
15
  port: 'auto',
7
16
  backdoor: null,
@@ -68,6 +77,7 @@ function import_server (bus, options)
68
77
  bus.express = express()
69
78
  bus.http = express.Router()
70
79
  bus.install_express(bus.express)
80
+ bus.initialize_braid_http()
71
81
 
72
82
  // use gzip compression if available
73
83
  try { bus.http.use(require('compression')())
@@ -96,19 +106,102 @@ function import_server (bus, options)
96
106
  bus.sync_files(x.state_path, x.fs_path)
97
107
  })
98
108
 
109
+ bus.express.use((req, res, next) => {
110
+ console.log('server.js:', req.method, req.url)
111
+ next()
112
+ })
113
+
114
+ // Free the CORS for Braid requests!
115
+ bus.express.use((req, res, next) => {
116
+ // If this requests knows about Braid then we presume the
117
+ // programmer knows that any client might make this cross-origin
118
+ // request.
119
+ if (req.version || req.parents || req.subscribe
120
+ || req.headers.subscribe
121
+ || req.method === 'OPTIONS')
122
+ free_the_cors(req, res, next)
123
+ else
124
+ next()
125
+ })
126
+
99
127
  // User will put his routes in here
100
- bus.express.use('/', bus.http)
128
+ bus.express.use(bus.http)
101
129
 
102
- // Use braidify if it's available
103
- try {
104
- var braidify = require('braidify').http_server
105
- console.log('Found braidify library. Braid-HTTP enabled!')
106
- } catch (e) {
107
- var braidify = undefined
130
+ // Connect bus to the HTTP server
131
+ bus.express.use(bus.http_handlers)
132
+
133
+ // Serve Client Coffee
134
+ bus.serve_client_coffee()
135
+
136
+ // Custom router
137
+ bus.route = function server_route (key, method, arg, t) {
138
+ var handlers = bus.bindings(key, method)
139
+ var count = handlers.length
140
+ if (count)
141
+ bus.log('route:', bus+'("'+key+'").'+method+'['+handlers.length+'](key:"'+(arg.key||arg)+'")')
142
+
143
+ // Call all handlers!
144
+ for (var i=0; i<handlers.length; i++)
145
+ bus.run_handler(handlers[i].func, method, arg, {t: t, binding: handlers[i].key})
146
+
147
+ // Now handle backup handlers
148
+ if (count === 0) {
149
+
150
+ // A save to master without a to_save defined should be
151
+ // automatically reflected to all clients.
152
+ if (method === 'to_save') {
153
+ bus.save.fire(arg, t)
154
+ bus.route(arg.key, 'on_set_sync', arg, t)
155
+ count++
156
+ }
157
+
158
+ // A fetch to master without a to_fetch defined should go to
159
+ // the database, if we have one.
160
+ if (method === 'to_fetch') {
161
+ bus.db_fetch(key)
162
+ // This basically renders the count useless-- you probably
163
+ // don't want to wrap this route() with another route().
164
+ count++
165
+ }
166
+ }
167
+ return handlers.length
168
+ }
169
+
170
+ // Back door to the control room
171
+ if (bus.options.backdoor) {
172
+ bus.make_http_server({
173
+ port: bus.options.backdoor,
174
+ name: 'backdoor_http_server',
175
+ use_ssl: use_ssl
176
+ })
177
+ bus.sockjs_server(this.backdoor_http_server)
108
178
  }
179
+ },
180
+
181
+ initialize_braid_http: function () {
182
+ // Set up default linked json converters
183
+ if (bus.options.braid_mode) {
184
+ bus.to_http_body = (o) => JSON.stringify(o.val)
185
+ bus.state = bus.braid_proxy()
186
+ } else
187
+ bus.to_http_body = (o) => {
188
+ var unwrap = (Object.keys(o).length === 2
189
+ && '_' in o
190
+ && typeof o._ === 'string')
191
+ // To do: translate pointers as keys
192
+ return unwrap ? o._ : JSON.stringify(o)
193
+ }
194
+
195
+ bus.from_http_body = (key, body) => ({
196
+ key,
197
+ val: JSON.parse(body)
198
+ })
199
+ },
200
+
201
+ // Connect HTTP GET and PUT to our Fetch and Save
202
+ http_handlers: function (req, res, next) {
203
+ if (req.method === 'GET') {
109
204
 
110
- // Mirror state over HTTP
111
- bus.express.get('*', function (req, res) {
112
205
  // Make a temporary client bus
113
206
  var cbus = bus.bus_for_http_client(req, res)
114
207
  var cb
@@ -131,28 +224,29 @@ function import_server (bus, options)
131
224
  cbus.fetch(key, cb = (o) => {
132
225
  var body = bus.to_http_body(o)
133
226
 
134
- // Return 404 if the value is undefined
135
- if (!body) {
136
- console.log('no body! time to 404')
137
- res.statusCode = 404
138
- res.end()
139
- }
227
+ // // Return 404 if the value is undefined
228
+ // if (!body) {
229
+ // console.log('no body! time to 404')
230
+ // res.statusCode = 404
231
+ // res.end()
232
+ // }
140
233
 
141
234
  // Or if we're braid, send via subscription
142
- else if (braidify)
143
- res.sendVersion({body})
235
+ // else
236
+ if (braidify)
237
+ res.sendVersion({body: body || 'null'})
144
238
 
145
239
  // Or just return the current version
146
240
  else
147
241
  res.send(body)
148
242
 
149
- // And shut down the connection if there's nothing left to do
243
+ // And shut down the connection if nothing's left to do
150
244
  if (!braidify || !req.subscribe || !body)
151
245
  end_it_all()
152
246
  })
153
- })
247
+ }
154
248
 
155
- bus.express.put('*', function (req, res) {
249
+ else if (req.method === 'PUT') {
156
250
  console.log('Got a put with body', req.body)
157
251
 
158
252
  // Make a temporary client bus
@@ -190,72 +284,9 @@ function import_server (bus, options)
190
284
  res.end()
191
285
  })
192
286
  }
193
- })
194
-
195
- // Set up default linked json converters
196
- if (bus.options.braid_mode_test) {
197
- bus.to_http_body = (o) => JSON.stringify(o.val)
198
- bus.state = bus.braid_proxy()
199
- } else
200
- bus.to_http_body = (o) => {
201
- var unwrap = (Object.keys(o).length === 2
202
- && '_' in o
203
- && typeof o._ === 'string')
204
- // To do: translate pointers as keys
205
- return unwrap ? o._ : JSON.stringify(o)
206
- }
207
-
208
- bus.from_http_body = (key, body) => ({
209
- key,
210
- val: JSON.parse(body)
211
- })
212
-
213
- // Serve Client Coffee
214
- bus.serve_client_coffee()
215
-
216
- // Custom router
217
- bus.route = function server_route (key, method, arg, t) {
218
- var handlers = bus.bindings(key, method)
219
- var count = handlers.length
220
- if (count)
221
- bus.log('route:', bus+'("'+key+'").'+method+'['+handlers.length+'](key:"'+(arg.key||arg)+'")')
222
-
223
- // Call all handlers!
224
- for (var i=0; i<handlers.length; i++)
225
- bus.run_handler(handlers[i].func, method, arg, {t: t, binding: handlers[i].key})
226
-
227
- // Now handle backup handlers
228
- if (count === 0) {
229
-
230
- // A save to master without a to_save defined should be
231
- // automatically reflected to all clients.
232
- if (method === 'to_save') {
233
- bus.save.fire(arg, t)
234
- bus.route(arg.key, 'on_set_sync', arg, t)
235
- count++
236
- }
237
-
238
- // A fetch to master without a to_fetch defined should go to
239
- // the database, if we have one.
240
- if (method === 'to_fetch') {
241
- bus.db_fetch(key)
242
- // This basically renders the count useless-- you probably
243
- // don't want to wrap this route() with another route().
244
- count++
245
- }
246
- }
247
- return handlers.length
248
- }
249
-
250
- // Back door to the control room
251
- if (bus.options.backdoor) {
252
- bus.make_http_server({
253
- port: bus.options.backdoor,
254
- name: 'backdoor_http_server',
255
- use_ssl: use_ssl
256
- })
257
- bus.sockjs_server(this.backdoor_http_server)
258
287
  }
288
+ else
289
+ next()
259
290
  },
260
291
 
261
292
  bus_for_http_client: function (req, res) {
@@ -2362,11 +2393,14 @@ function import_server (bus, options)
2362
2393
  serve_clientjs: function serve_clientjs (path) {
2363
2394
  path = path || 'client.js'
2364
2395
  bus.http.get('/' + path, (req, res) => {
2365
- res.send(
2396
+ var files =
2366
2397
  ['extras/coffee.js', 'extras/sockjs.js', 'extras/react.js',
2367
- 'statebus.js', 'client.js']
2368
- .map((f) => fs.readFileSync('node_modules/statebus/' + f))
2369
- .join(';\n'))
2398
+ 'statebus.js', 'client.js'].map((f) => fs.readFileSync('node_modules/statebus/' + f))
2399
+ if (bus.options.braid_mode)
2400
+ files.unshift(fs.readFileSync(
2401
+ 'node_modules/braidify/braidify-client.js'
2402
+ ))
2403
+ res.send(files.join(';\n'))
2370
2404
  })
2371
2405
  },
2372
2406
 
@@ -2450,6 +2484,24 @@ function import_server (bus, options)
2450
2484
  }
2451
2485
 
2452
2486
 
2487
+ // Disables CORS in HTTP servers
2488
+ function free_the_cors (req, res, next) {
2489
+ console.log('free the cors!', req.method, req.url)
2490
+
2491
+ var free_the_cors = {
2492
+ "Access-Control-Allow-Origin": "*",
2493
+ "Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT, UNSUBSCRIBE",
2494
+ "Access-Control-Allow-Headers": "subscribe, peer, version, parents, merge-type, content-type, patches, cache-control"
2495
+ }
2496
+ Object.entries(free_the_cors).forEach(x => res.setHeader(x[0], x[1]))
2497
+ if (req.method === 'OPTIONS') {
2498
+ res.writeHead(200)
2499
+ res.end()
2500
+ } else
2501
+ next()
2502
+ }
2503
+
2504
+
2453
2505
  // Handy functions for writing tests on nodejs
2454
2506
  var tests = []
2455
2507
  function test (f) {tests.push(f)}
package/statebus.js CHANGED
@@ -1546,9 +1546,14 @@
1546
1546
  if (!nodejs)
1547
1547
  window.devtoolsFormatters = [{
1548
1548
  header: function (x) {
1549
- return x[symbols.is_proxy] &&
1550
- ['span', {style: 'background-color: #feb; padding: 3px;'},
1551
- JSON.stringify(proxy_decode_json(x()))]
1549
+ if (x[symbols.is_proxy])
1550
+ return ['span', {style: 'background-color: #feb; padding: 3px;'},
1551
+ JSON.stringify(proxy_decode_json(x()))]
1552
+ else if (x[symbols.is_braid_proxy])
1553
+ return ['span', {style: 'background-color: #fffbe5; padding: 3px;'},
1554
+ JSON.stringify(x)]
1555
+ // For function proxies:
1556
+ // JSON.stringify(x(), null, 2)]
1552
1557
  },
1553
1558
  hasBody: function (x) {return false}
1554
1559
  }]
@@ -1557,10 +1562,12 @@
1557
1562
  // ******************
1558
1563
  // Braid Test Mode Proxy
1559
1564
 
1560
- var symbols = {is_proxy: Symbol('is_proxy'),
1565
+ var symbols = {is_braid_proxy: Symbol('is_braid_proxy'),
1566
+ is_proxy: Symbol('is_proxy'),
1561
1567
  is_link: Symbol('is_link'),
1562
1568
  get_json: Symbol('get_json'),
1563
- get_base: Symbol('get_base')}
1569
+ get_base: Symbol('get_base')
1570
+ }
1564
1571
  function braid_proxy () {
1565
1572
  function item_proxy (base, o) {
1566
1573
 
@@ -1580,10 +1587,22 @@
1580
1587
  return item_proxy(new_base, new_base.val)
1581
1588
  }
1582
1589
 
1590
+
1591
+ // For function proxies:
1592
+ //
1593
+ // // Javascript won't let us function call a proxy unless the
1594
+ // // "target" is a function. So we make a dummy target, and
1595
+ // // don't use it.
1596
+ // var dummy = function () {}
1597
+
1598
+
1583
1599
  return new Proxy(o, {
1584
1600
  get: function get(o, k) {
1585
- if (k === 'inspect'
1586
- || k === 'valueOf' || typeof k === 'symbol')
1601
+ if (k === 'inspect' || k === 'valueOf')
1602
+ return undefined
1603
+ if (k === symbols.is_braid_proxy)
1604
+ return true
1605
+ if (typeof k === 'symbol')
1587
1606
  return undefined
1588
1607
  return item_proxy(base, o[proxied_2_keyed(k)])
1589
1608
  },
@@ -1591,36 +1610,46 @@
1591
1610
  var value = translate_fields(v, proxied_2_keyed)
1592
1611
  o[proxied_2_keyed(k)] = value
1593
1612
  bus.save(base)
1594
- return value
1613
+ return true
1595
1614
  },
1596
1615
  has: function has(o, k) {
1597
1616
  return o.hasOwnProperty(proxied_2_keyed(k))
1598
1617
  },
1599
1618
  deleteProperty: function del (o, k) {
1600
1619
  delete o[proxied_2_keyed(k)]
1601
- },
1602
- apply: function apply (o, This, args) {
1603
- return o
1604
1620
  }
1621
+ // For function proxies:
1622
+ //
1623
+ // apply: function apply (o, This, args) {
1624
+ // return translate_fields(o, keyed_2_proxied)
1625
+ // }
1605
1626
  })}
1606
1627
 
1607
1628
 
1629
+ // For function proxies:
1630
+ // var dummy = function () {}
1631
+
1608
1632
  // The top-level Proxy object holds HTTP resources
1609
1633
  return new Proxy(cache, {
1610
1634
  get: function get(o, k) {
1611
1635
  if (k === 'inspect' || k === 'valueOf' || typeof k === 'symbol')
1612
1636
  return undefined
1613
- if (k in bogus_keys)
1614
- return o[k]
1637
+ bogus_check(k)
1615
1638
  var base = bus.fetch(k)
1616
1639
  return item_proxy(base, base.val)
1617
1640
  },
1618
1641
  set: function set(o, key, val) {
1619
- bus.save({key: key, val: val})
1642
+ bus.save({key: key,
1643
+ val: translate_fields(val, proxied_2_keyed)})
1644
+ return true
1620
1645
  },
1621
1646
  deleteProperty: function del (o, k) {
1622
1647
  bus.delete(proxied_2_keyed(k))
1623
- }
1648
+ },
1649
+ // For function proxies:
1650
+ // apply: function apply (o, This, args) {
1651
+ // return 'fluffy'
1652
+ // }
1624
1653
  })
1625
1654
  }
1626
1655
 
@@ -1630,8 +1659,8 @@
1630
1659
  return result
1631
1660
  }
1632
1661
 
1633
- if ((nodejs && bus.options && bus.options.braid_mode_test)
1634
- || (!nodejs && window.Proxy && clientjs_option('braid_mode_test')))
1662
+ if ((nodejs && bus.options && bus.options.braid_mode)
1663
+ || (!nodejs && window.Proxy && clientjs_option('braid_mode')))
1635
1664
  state = braid_proxy()
1636
1665
 
1637
1666
 
@@ -2371,7 +2400,7 @@
2371
2400
  'escape_keys unescape_keys translate_keys apply_patch',
2372
2401
  'keyed_2_proxied proxied_2_keyed translate_fields',
2373
2402
  'net_mount net_automount message_method',
2374
- 'parse Set One_To_Many clone extend deep_map deep_equals prune validate sorta_diff log deps'
2403
+ 'parse Set One_To_Many clone extend deep_map deep_equals prune validate sorta_diff log deps symbols'
2375
2404
  ].join(' ').split(' ')
2376
2405
  for (var i=0; i<api.length; i++)
2377
2406
  bus[api[i]] = eval(api[i])