statebus 7.2.5 → 7.2.6
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/package.json +1 -1
- package/server-library.js +14 -11
- package/statebus.js +58 -35
package/package.json
CHANGED
package/server-library.js
CHANGED
|
@@ -2371,31 +2371,34 @@ function import_server (bus, make_statebus, options)
|
|
|
2371
2371
|
// Installs a GET handler at route that gets state from a getter function
|
|
2372
2372
|
// Note: Makes too many textbusses. Should re-use one.
|
|
2373
2373
|
http_serve: function http_serve (route, getter) {
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
textbus('*').getter = (filename, old) => {
|
|
2378
|
-
return {etag: Math.random() + '',
|
|
2379
|
-
_: getter(filename)}
|
|
2374
|
+
if (!this.filebus) {
|
|
2375
|
+
this.filebus = make_statebus()
|
|
2376
|
+
this.filebus.label = 'filebus'
|
|
2380
2377
|
}
|
|
2378
|
+
var filebus = this.filebus
|
|
2379
|
+
|
|
2380
|
+
filebus('*').getter = (filename, old) => ({
|
|
2381
|
+
etag: Math.random() + '',
|
|
2382
|
+
contents: getter(filename)
|
|
2383
|
+
})
|
|
2381
2384
|
bus.http.get(route, (req, res) => {
|
|
2382
2385
|
var path = req.path
|
|
2383
|
-
var etag =
|
|
2386
|
+
var etag = filebus.cache[path] && filebus.cache[path].etag
|
|
2384
2387
|
if (etag && req.get('If-None-Match') === etag) {
|
|
2385
2388
|
res.status(304).end()
|
|
2386
2389
|
return
|
|
2387
2390
|
}
|
|
2388
2391
|
|
|
2389
|
-
|
|
2390
|
-
|
|
2392
|
+
filebus.get(req.path) // So that filebus never clears the cache
|
|
2393
|
+
filebus.get(req.path, function cb (o) {
|
|
2391
2394
|
res.setHeader('Cache-Control', 'public')
|
|
2392
2395
|
// res.setHeader('Cache-Control', 'public, max-age='
|
|
2393
2396
|
// + (60 * 60 * 24 * 30)) // 1 month
|
|
2394
2397
|
res.setHeader('ETag', o.etag)
|
|
2395
2398
|
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
2396
2399
|
res.setHeader('Content-Type', 'application/javascript')
|
|
2397
|
-
res.send(o.
|
|
2398
|
-
|
|
2400
|
+
res.send(o.contents)
|
|
2401
|
+
filebus.forget(o.key, cb) // But we do want to forget the cb
|
|
2399
2402
|
})
|
|
2400
2403
|
})
|
|
2401
2404
|
},
|
package/statebus.js
CHANGED
|
@@ -963,45 +963,11 @@
|
|
|
963
963
|
// We're currently calling that (param1,param2:val2) part "function params", and presuming
|
|
964
964
|
// that it exists in the () part of the pattern like in /foo/bar*().
|
|
965
965
|
function func_args () {
|
|
966
|
-
// This code is copied from Raphael Walker's parser.coffee
|
|
967
|
-
function split_once (str, char) {
|
|
968
|
-
var i = str.indexOf(char)
|
|
969
|
-
return i === -1 ? [str, ""] : [str.slice(0, i), str.slice(i + 1)]
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
// Function Strings -- an alternative to query strings
|
|
973
|
-
//
|
|
974
|
-
function parse_function_string (str) {
|
|
975
|
-
// Coffeescript doesn't have object comprehensions :(
|
|
976
|
-
var ret = {}
|
|
977
|
-
|
|
978
|
-
// Now process the string:
|
|
979
|
-
str
|
|
980
|
-
// Pull out the parentheses
|
|
981
|
-
.slice(1, -1)
|
|
982
|
-
// Split by commas. TODO: Allow spaces after commas?
|
|
983
|
-
.split(",")
|
|
984
|
-
// Delete empty parts (this ensures that empty strings
|
|
985
|
-
// will properly result in empty func_string, and allows trailing
|
|
986
|
-
// commas)
|
|
987
|
-
.filter(part => part.length)
|
|
988
|
-
.forEach(part => {
|
|
989
|
-
// If the part has a comma, its a key:value, otherwise
|
|
990
|
-
// it's just a singleton
|
|
991
|
-
var [k, v] = split_once(part, ":")
|
|
992
|
-
|
|
993
|
-
if (v.length === 0) ret[k] = true
|
|
994
|
-
// If the value is itself a func_string params object, parse it recursively
|
|
995
|
-
else if (v.startsWith("(")) ret[k] = parse_function_string(v)
|
|
996
|
-
else ret[k] = v
|
|
997
|
-
})
|
|
998
|
-
return ret
|
|
999
|
-
}
|
|
1000
966
|
// console.log('Getting func_args from', func.statebus_binding.args)
|
|
1001
967
|
if (!(func.statebus_binding.args
|
|
1002
968
|
&& func.statebus_binding.args.func_args))
|
|
1003
969
|
return undefined
|
|
1004
|
-
return
|
|
970
|
+
return funcarg_parse(func.statebus_binding.args.func_args)
|
|
1005
971
|
}
|
|
1006
972
|
var f = reactive(function () {
|
|
1007
973
|
// Initialize transaction
|
|
@@ -1447,6 +1413,62 @@
|
|
|
1447
1413
|
bus.get_once(key, (o) => resolve(o)))
|
|
1448
1414
|
}
|
|
1449
1415
|
|
|
1416
|
+
// ******************
|
|
1417
|
+
// Function Args -- an alternative to Query Params
|
|
1418
|
+
|
|
1419
|
+
// Parse a funcarg string.
|
|
1420
|
+
|
|
1421
|
+
function funcarg_parse (str) {
|
|
1422
|
+
// Coffeescript doesn't have object comprehensions :(
|
|
1423
|
+
var ret = {}
|
|
1424
|
+
|
|
1425
|
+
function split_once (str, char) {
|
|
1426
|
+
var i = str.indexOf(char)
|
|
1427
|
+
return i === -1 ? [str, ""] : [str.slice(0, i), str.slice(i + 1)]
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
// Now process the string:
|
|
1431
|
+
str
|
|
1432
|
+
// Pull out the parentheses
|
|
1433
|
+
.slice(1, -1)
|
|
1434
|
+
// Split by commas. TODO: Allow spaces after commas?
|
|
1435
|
+
.split(",")
|
|
1436
|
+
// Delete empty parts (this ensures that empty strings
|
|
1437
|
+
// will properly result in empty func_string, and allows trailing
|
|
1438
|
+
// commas)
|
|
1439
|
+
.filter(part => part.length)
|
|
1440
|
+
.forEach(part => {
|
|
1441
|
+
// If the part has a comma, its a key:value, otherwise
|
|
1442
|
+
// it's just a singleton
|
|
1443
|
+
var [k, v] = split_once(part, ":")
|
|
1444
|
+
|
|
1445
|
+
if (v.length === 0) ret[k] = true
|
|
1446
|
+
// If the value is itself a func_string params object, parse it recursively
|
|
1447
|
+
else if (v.startsWith("(")) ret[k] = funcarg_parse(v)
|
|
1448
|
+
else ret[k] = v
|
|
1449
|
+
})
|
|
1450
|
+
return ret
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
// Generate a funcarg string
|
|
1454
|
+
function funcarg_stringify (obj) {
|
|
1455
|
+
var inner = Object.entries(obj)
|
|
1456
|
+
// Allowed values in KSON are: object, string, true
|
|
1457
|
+
// Arrays are in fact objects, and we don't need to treat them differently.
|
|
1458
|
+
// Their order won't change!
|
|
1459
|
+
.filter(([k, v]) => v)
|
|
1460
|
+
.sort()
|
|
1461
|
+
.map(([k, v]) => {
|
|
1462
|
+
if (typeof v === "boolean") return k
|
|
1463
|
+
if (typeof v === "string") return `${k}:${v}`
|
|
1464
|
+
if (typeof v === "object") return `${k}:${funcarg_string(v)}`
|
|
1465
|
+
return ""
|
|
1466
|
+
})
|
|
1467
|
+
.join(",")
|
|
1468
|
+
return inner.length ? `(${inner})` : ""
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
|
|
1450
1472
|
// ******************
|
|
1451
1473
|
// Proxy
|
|
1452
1474
|
|
|
@@ -2717,6 +2739,7 @@
|
|
|
2717
2739
|
'old_subspace new_subspace bindings run_handler bind unbind reactive uncallback',
|
|
2718
2740
|
'versions new_version',
|
|
2719
2741
|
'aget client_bus_for',
|
|
2742
|
+
'funcarg_parse funcarg_stringify',
|
|
2720
2743
|
'funk_key funk_name funks key_id key_name id',
|
|
2721
2744
|
'pending_gets gets_in gets_out loading_keys loading once',
|
|
2722
2745
|
'global_funk busses rerunnable_funks',
|