statebus 7.1.2 → 7.2.3
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/extras/tests.js +162 -2
- package/package.json +1 -1
- package/statebus.js +204 -57
package/extras/tests.js
CHANGED
|
@@ -81,12 +81,13 @@ test(function validation (done) {
|
|
|
81
81
|
[{a: false}, {a: 'boolean'}, true],
|
|
82
82
|
[{a: 1, b: 2}, {a: 1}, false],
|
|
83
83
|
[{a: 1, b: 2}, {a: 1, '*':'*'}, true],
|
|
84
|
-
[{a: 2, b: 2}, {a: 1, '*':'*'}, false]
|
|
84
|
+
[{a: 2, b: 2}, {a: 1, '*':'*'}, false],
|
|
85
|
+
[{a: {link: "foo"}}, {a: 'link'}, true]
|
|
85
86
|
]
|
|
86
87
|
|
|
87
88
|
for (var i=0; i<v_tests.length; i++)
|
|
88
89
|
assert(bus.validate(v_tests[i][0], v_tests[i][1]) === v_tests[i][2],
|
|
89
|
-
'Validation test failed'
|
|
90
|
+
'Validation test failed: ' + i + ' ' + JSON.stringify(v_tests[i]))
|
|
90
91
|
|
|
91
92
|
done()
|
|
92
93
|
})
|
|
@@ -319,9 +320,82 @@ test(function proxy_link (done) {
|
|
|
319
320
|
done()
|
|
320
321
|
})
|
|
321
322
|
|
|
323
|
+
function verify_no_proxies (bus) {
|
|
324
|
+
bus.deep_map(bus.cache, o => {
|
|
325
|
+
if ((typeof o === 'object' || typeof o === 'function')
|
|
326
|
+
&& o[bus.symbols.is_proxy]) {
|
|
327
|
+
console.trace('NOOOO proxy is here', obj)
|
|
328
|
+
throw 'We got a bad one!!!'
|
|
329
|
+
}
|
|
330
|
+
return o
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
|
|
322
334
|
// Disable the version of proxy_links_through where the user does not have to
|
|
323
335
|
// explicitly traverse links with ._()
|
|
324
336
|
if (true)
|
|
337
|
+
test(function proxy_links_through3 (done) {
|
|
338
|
+
var bus = require('../statebus')()
|
|
339
|
+
|
|
340
|
+
// First try to dereference through three links
|
|
341
|
+
|
|
342
|
+
bus.state.a = [bus.link('b')]
|
|
343
|
+
bus.state.b = bus.link('c')
|
|
344
|
+
bus.state.c = 'see'
|
|
345
|
+
|
|
346
|
+
verify_no_proxies(bus)
|
|
347
|
+
|
|
348
|
+
log('state.c is', bus.state.c)
|
|
349
|
+
log('state.b is', bus.state.b, 'from cache', bus.cache.b)
|
|
350
|
+
log('state.a is', bus.state.a)
|
|
351
|
+
log('state.a[0] is', bus.state.a[0])
|
|
352
|
+
log('state.a[0]() is', bus.state.a[0]())
|
|
353
|
+
log('state.a[0]()() is', bus.state.a[0]()())
|
|
354
|
+
assert(bus.state.a[0]()() === 'see')
|
|
355
|
+
|
|
356
|
+
verify_no_proxies(bus)
|
|
357
|
+
|
|
358
|
+
// Add a little more wrapping and try some more
|
|
359
|
+
|
|
360
|
+
bus.state.nested = [99, {a: bus.link('a')}]
|
|
361
|
+
log('nested is', bus.state.nested, bus.state.nested[bus.symbols.is_proxy])
|
|
362
|
+
log('raw nested is', bus.state[bus.symbols.raw].nested)
|
|
363
|
+
log('raw cache is', bus.cache.nested)
|
|
364
|
+
|
|
365
|
+
log('nested[1].a()[0]()() is', bus.state.nested[1].a()[0]()())
|
|
366
|
+
assert(bus.state.nested[1].a()[0]()() === 'see')
|
|
367
|
+
|
|
368
|
+
verify_no_proxies(bus)
|
|
369
|
+
|
|
370
|
+
// Now try to go raw at the top-level
|
|
371
|
+
|
|
372
|
+
log('Raw is', bus.state[bus.symbols.raw].nested)
|
|
373
|
+
log('Raw is', bus.raw(bus.state).nested)
|
|
374
|
+
assert(bus.deep_equals(
|
|
375
|
+
bus.state[bus.symbols.raw].nested,
|
|
376
|
+
bus.raw(bus.state).nested
|
|
377
|
+
))
|
|
378
|
+
|
|
379
|
+
verify_no_proxies(bus)
|
|
380
|
+
|
|
381
|
+
log('Gonna deep_quals between:',
|
|
382
|
+
bus.raw(bus.state).nested.val,
|
|
383
|
+
[ 99, { a: { link: 'a' } } ])
|
|
384
|
+
|
|
385
|
+
assert(bus.deep_equals(
|
|
386
|
+
bus.raw(bus.state).nested.val,
|
|
387
|
+
[ 99, { a: { link: 'a' } } ]
|
|
388
|
+
))
|
|
389
|
+
|
|
390
|
+
// Now try to go raw within
|
|
391
|
+
|
|
392
|
+
log('Raw inner is', bus.raw(bus.state.nested[1]))
|
|
393
|
+
|
|
394
|
+
log('Bad raw call is', bus.raw(bus.state.nested[0]))
|
|
395
|
+
|
|
396
|
+
done()
|
|
397
|
+
})
|
|
398
|
+
else if (false)
|
|
325
399
|
test(function proxy_links_through2 (done) {
|
|
326
400
|
var bus = require('../statebus')()
|
|
327
401
|
|
|
@@ -446,6 +520,90 @@ test(function copy_link (done) {
|
|
|
446
520
|
})
|
|
447
521
|
|
|
448
522
|
|
|
523
|
+
|
|
524
|
+
// This was useful test code for figuring out how to set custom formatters on
|
|
525
|
+
// proxies. It's not needed anymore.
|
|
526
|
+
//
|
|
527
|
+
// test(function proxy_printing_in_node (done) {
|
|
528
|
+
// var bus = require('../statebus')(), state = bus.state
|
|
529
|
+
//
|
|
530
|
+
// state.a = [bus.link('b')]
|
|
531
|
+
// state.b = 3
|
|
532
|
+
// state.c = {a: 3, link: 99}
|
|
533
|
+
//
|
|
534
|
+
// log('a in cache is', bus.cache.a,
|
|
535
|
+
// {'typeof': typeof bus.cache.a === 'object',
|
|
536
|
+
// symbolsin: bus.symbols.link in bus.cache.a})
|
|
537
|
+
//
|
|
538
|
+
// log('state:', state)
|
|
539
|
+
// log('state.a:', state.a)
|
|
540
|
+
// log('state.b:', state.b)
|
|
541
|
+
// log('state.c:', state.c)
|
|
542
|
+
//
|
|
543
|
+
// var util = require('util')
|
|
544
|
+
//
|
|
545
|
+
// assert(util.inspect(state.a) === "Proxy [ { link: 'b' } ]")
|
|
546
|
+
// assert(util.inspect(state.b) === "3")
|
|
547
|
+
// assert(util.inspect(state.c) === "Proxy { a: 3, link: 99 }")
|
|
548
|
+
//
|
|
549
|
+
// log('passed!')
|
|
550
|
+
//
|
|
551
|
+
// // This version is abstracted and tested:
|
|
552
|
+
// var util = require('util')
|
|
553
|
+
// function make_proxy(target) {
|
|
554
|
+
// // Don't proxy null or non-objects
|
|
555
|
+
// if (!target || typeof target !== 'object') return target
|
|
556
|
+
//
|
|
557
|
+
// // Create proxies for all nested objects
|
|
558
|
+
// var clean = Array.isArray(target) ? [] : {}
|
|
559
|
+
// for (let prop of Object.getOwnPropertyNames(target)) {
|
|
560
|
+
// clean[prop] = make_proxy(target[prop])
|
|
561
|
+
// }
|
|
562
|
+
//
|
|
563
|
+
// // Create the proxy
|
|
564
|
+
// var proxy = new Proxy(clean, {
|
|
565
|
+
// get(target, prop) {
|
|
566
|
+
// return target[prop]
|
|
567
|
+
// }
|
|
568
|
+
// })
|
|
569
|
+
//
|
|
570
|
+
// // Add custom inspector
|
|
571
|
+
// proxy[util.inspect.custom] = function(depth, opts) {
|
|
572
|
+
// var formatted = Array.isArray(target) ? [] : {}
|
|
573
|
+
// for (let prop of Object.getOwnPropertyNames(target)) {
|
|
574
|
+
// formatted[prop] = target[prop]
|
|
575
|
+
// }
|
|
576
|
+
// return `Proxy ${util.inspect(formatted, { ...opts, customInspect: true })}`
|
|
577
|
+
// }
|
|
578
|
+
//
|
|
579
|
+
// return proxy
|
|
580
|
+
// }
|
|
581
|
+
//
|
|
582
|
+
// // Test various scenarios
|
|
583
|
+
// var data = {
|
|
584
|
+
// name: 'parent',
|
|
585
|
+
// child: {
|
|
586
|
+
// name: 'kid',
|
|
587
|
+
// toy: {
|
|
588
|
+
// name: 'teddy'
|
|
589
|
+
// }
|
|
590
|
+
// },
|
|
591
|
+
// numbers: [1, 2, {x: 3}], // Test with array containing object
|
|
592
|
+
// nullVal: null, // Test with null
|
|
593
|
+
// primitive: 42 // Test with primitive
|
|
594
|
+
// }
|
|
595
|
+
//
|
|
596
|
+
// var proxied = make_proxy(data)
|
|
597
|
+
// console.log('Full object:', proxied)
|
|
598
|
+
// console.log('Child:', proxied.child)
|
|
599
|
+
// console.log('Toy:', proxied.child.toy)
|
|
600
|
+
// console.log('Numbers:', proxied.numbers)
|
|
601
|
+
// console.log('Null value:', proxied.nullVal)
|
|
602
|
+
// console.log('Primitive:', proxied.primitive)
|
|
603
|
+
//
|
|
604
|
+
// done()
|
|
605
|
+
// })
|
|
606
|
+
|
|
449
607
|
test(function translate_fields (done) {
|
|
450
608
|
// Translate Statebus -> Proxy format
|
|
451
609
|
var tests1 = [
|
|
@@ -907,6 +1065,8 @@ test(function proxies (done) {
|
|
|
907
1065
|
var bus = require('../statebus').serve({file_store: false})
|
|
908
1066
|
var state = bus.state
|
|
909
1067
|
|
|
1068
|
+
log('Top-level proxy looks like:', bus.state)
|
|
1069
|
+
|
|
910
1070
|
assert(state.array === undefined)
|
|
911
1071
|
assert(state.bar === undefined)
|
|
912
1072
|
|
package/package.json
CHANGED
package/statebus.js
CHANGED
|
@@ -1456,20 +1456,26 @@
|
|
|
1456
1456
|
link: Symbol('link')
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
|
+
if (nodejs)
|
|
1460
|
+
var util = require('util')
|
|
1461
|
+
|
|
1459
1462
|
// The top-level Proxy object holds HTTP resources
|
|
1460
1463
|
var top_level_proxy = new Proxy(cache, {
|
|
1461
1464
|
get: function get(o, k) {
|
|
1462
1465
|
if (k === symbols.is_proxy)
|
|
1463
1466
|
return true
|
|
1464
1467
|
if (k === symbols.raw)
|
|
1465
|
-
return
|
|
1466
|
-
if (k === 'inspect' || k === 'valueOf' || typeof k === 'symbol')
|
|
1467
|
-
|
|
1468
|
+
return bus.cache
|
|
1469
|
+
// if (k === 'inspect' || k === 'valueOf' || typeof k === 'symbol')
|
|
1470
|
+
// return undefined
|
|
1468
1471
|
bogus_check(k)
|
|
1469
1472
|
var base = bus.get(k)
|
|
1470
1473
|
return json_proxy(base, '', base.val)
|
|
1471
1474
|
},
|
|
1472
1475
|
set: function set(o, key, val) {
|
|
1476
|
+
if (typeof key === 'symbol')
|
|
1477
|
+
return true
|
|
1478
|
+
|
|
1473
1479
|
bus.set({
|
|
1474
1480
|
key: key,
|
|
1475
1481
|
val: escape_json_to_bus(val)
|
|
@@ -1495,42 +1501,59 @@
|
|
|
1495
1501
|
|
|
1496
1502
|
return o
|
|
1497
1503
|
|
|
1498
|
-
//
|
|
1504
|
+
// Then o must be an object, array, or link
|
|
1505
|
+
|
|
1506
|
+
// First, handle links.
|
|
1499
1507
|
if (typeof o === 'object' && 'link' in o) {
|
|
1500
1508
|
// var new_base = bus.get(o.link)
|
|
1501
1509
|
// return json_proxy(new_base, '', new_base.val)
|
|
1502
1510
|
return link(o.link)
|
|
1511
|
+
|
|
1512
|
+
// Todo: to allow modifying links, or adding new fields to them,
|
|
1513
|
+
// we'll need to treat them more like a json_proxy, that passes
|
|
1514
|
+
// the base into the proxy creator, allowing edits, etc.
|
|
1503
1515
|
}
|
|
1504
1516
|
|
|
1517
|
+
// Now it must be an array or object. Shallow clone it, so we can set
|
|
1518
|
+
// a custom formatter on it
|
|
1519
|
+
var target = o
|
|
1520
|
+
if (Array.isArray(target)) target = [...o]
|
|
1521
|
+
else target = {...o}
|
|
1505
1522
|
|
|
1506
|
-
//
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1523
|
+
// Now set the custom formatter
|
|
1524
|
+
if (nodejs)
|
|
1525
|
+
target[util.inspect.custom] = function print_as_proxy (depth, opts) {
|
|
1526
|
+
var formatted = Array.isArray(target) ? [] : {}
|
|
1527
|
+
for (let prop of Object.getOwnPropertyNames(target))
|
|
1528
|
+
formatted[prop] = target[prop]
|
|
1529
|
+
formatted = unescape_bus_to_json(formatted)
|
|
1512
1530
|
|
|
1531
|
+
return `Proxy ${util.inspect(formatted, { ...opts, customInspect: true })}`
|
|
1532
|
+
}
|
|
1513
1533
|
|
|
1514
|
-
|
|
1534
|
+
var proxy = new Proxy(target, {
|
|
1515
1535
|
get: function (o, k) {
|
|
1516
1536
|
if (k === 'inspect' || k === 'valueOf')
|
|
1517
1537
|
return undefined
|
|
1518
|
-
// if (custom_inspect && k === custom_inspect)
|
|
1519
|
-
// return custom_inspect
|
|
1520
1538
|
if (k === symbols.is_proxy)
|
|
1521
1539
|
return true
|
|
1522
1540
|
if (k === symbols.raw)
|
|
1523
1541
|
return o
|
|
1524
|
-
if (typeof k === 'symbol')
|
|
1525
|
-
return undefined
|
|
1526
1542
|
|
|
1527
1543
|
// Compute the new path
|
|
1528
1544
|
var new_path = path + '[' + JSON.stringify(k) + ']'
|
|
1529
1545
|
return json_proxy(base, new_path, o[escape_field_json_to_bus(k)])
|
|
1530
1546
|
},
|
|
1531
|
-
set: function (
|
|
1547
|
+
set: function (target, k, v) {
|
|
1532
1548
|
var value = escape_json_to_bus(v)
|
|
1533
|
-
|
|
1549
|
+
var escaped_key = escape_field_json_to_bus(k)
|
|
1550
|
+
|
|
1551
|
+
// Now mutate both the shallow-copied target and the original
|
|
1552
|
+
// object because we have two because es6 proxies are stupidly
|
|
1553
|
+
// designed and we had to make a copy to make custom inspect
|
|
1554
|
+
// symbol work
|
|
1555
|
+
o[escaped_key] = value
|
|
1556
|
+
target[escaped_key] = value
|
|
1534
1557
|
var new_path = path + '[' + JSON.stringify(k) + ']'
|
|
1535
1558
|
bus.set.sync(
|
|
1536
1559
|
base,
|
|
@@ -1541,20 +1564,20 @@
|
|
|
1541
1564
|
)
|
|
1542
1565
|
return true
|
|
1543
1566
|
},
|
|
1544
|
-
has: function (o, k) {
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
},
|
|
1555
|
-
deleteProperty: function del (o, k) {
|
|
1567
|
+
// has: function (o, k) {
|
|
1568
|
+
// return o.hasOwnProperty(escape_field_json_to_bus(k))
|
|
1569
|
+
// },
|
|
1570
|
+
// ownKeys: function () {
|
|
1571
|
+
// return Object.keys(target).map(unescape_field_bus_to_json)
|
|
1572
|
+
// },
|
|
1573
|
+
// getOwnPropertyDescriptor: function (target, key) {
|
|
1574
|
+
// return { enumerable: true, configurable: true, value: this.get(target, key) }
|
|
1575
|
+
// },
|
|
1576
|
+
deleteProperty: function del (target, k) {
|
|
1556
1577
|
var new_path = path + '[' + JSON.stringify(k) + ']'
|
|
1557
|
-
|
|
1578
|
+
var escaped_key = escape_field_json_to_bus(k)
|
|
1579
|
+
delete o[escaped_key]
|
|
1580
|
+
delete target[escaped_key]
|
|
1558
1581
|
bus.set(
|
|
1559
1582
|
base,
|
|
1560
1583
|
// Forward the patches too
|
|
@@ -1563,17 +1586,32 @@
|
|
|
1563
1586
|
content: undefined}]}
|
|
1564
1587
|
)
|
|
1565
1588
|
return true // Report success to Proxy
|
|
1566
|
-
}
|
|
1567
|
-
// For function proxies:
|
|
1568
|
-
//
|
|
1569
|
-
// apply: function apply (o, This, args) {
|
|
1570
|
-
// return translate_fields(o, unescape_field_from_bus)
|
|
1571
|
-
// }
|
|
1589
|
+
},
|
|
1572
1590
|
})
|
|
1591
|
+
|
|
1592
|
+
return proxy
|
|
1573
1593
|
}
|
|
1574
1594
|
|
|
1575
1595
|
bus.state = top_level_proxy
|
|
1576
1596
|
|
|
1597
|
+
// This doesn't work because custom inspectors only work when the
|
|
1598
|
+
// util.inspect.custom symbol is defined on the "target" of the
|
|
1599
|
+
// proxy... which right now is `cache` for the top_level_proxy. I could
|
|
1600
|
+
// shallow-copy cache into a new target variable, and add this symbol to
|
|
1601
|
+
// it, and keep them in sync, but that sounds annoying. I'm just going to
|
|
1602
|
+
// ignore the custom proxy formatter on the top-level-proxy for now.
|
|
1603
|
+
|
|
1604
|
+
// if (nodejs) {
|
|
1605
|
+
// var util = require('util')
|
|
1606
|
+
// top_level_proxy[util.inspect.custom] = function(depth, opts) {
|
|
1607
|
+
// var formatted = {}
|
|
1608
|
+
// for (let prop of Object.getOwnPropertyNames(cache)) {
|
|
1609
|
+
// formatted[prop] = cache[prop].val
|
|
1610
|
+
// }
|
|
1611
|
+
// return `STATE ${util.inspect(formatted, { ...opts, customInspect: true })}`
|
|
1612
|
+
// }
|
|
1613
|
+
// }
|
|
1614
|
+
|
|
1577
1615
|
// This is temporary code to wrap the cache as a flat key/valuel store
|
|
1578
1616
|
// that returns raw objects, dereferencing .val. We can remove it once we
|
|
1579
1617
|
// remove the internal .val stuff from statebus.
|
|
@@ -1589,26 +1627,29 @@
|
|
|
1589
1627
|
})
|
|
1590
1628
|
}
|
|
1591
1629
|
|
|
1592
|
-
// How proxy links work right now:
|
|
1593
|
-
// - The user creates a link with bus.link(key)
|
|
1594
|
-
// - which produces a {[symbols.link]: key}
|
|
1595
|
-
// - which when set() into a proxy, is replaced with a {link: key}, to store internally
|
|
1596
|
-
// - Then, when get()ing that internal {link: key} through Proxy:
|
|
1597
|
-
// - We auto-dereference the key, with another get()
|
|
1598
|
-
// - So the user actually sees the value of the resource on the other side of the link
|
|
1599
|
-
function link (url) {
|
|
1600
|
-
return {
|
|
1601
|
-
link: url,
|
|
1602
|
-
[symbols.link]: true,
|
|
1603
|
-
_: (args, o) => (o = get(url), json_proxy(o, '', o.val))
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
1630
|
|
|
1607
|
-
//
|
|
1608
|
-
|
|
1631
|
+
// Old link code:
|
|
1632
|
+
|
|
1633
|
+
// // How proxy links work right now:
|
|
1634
|
+
// // - The user creates a link with bus.link(key)
|
|
1635
|
+
// // - which produces a {[symbols.link]: key}
|
|
1636
|
+
// // - which when set() into a proxy, is replaced with a {link: key}, to store internally
|
|
1637
|
+
// // - Then, when get()ing that internal {link: key} through Proxy:
|
|
1638
|
+
// // - We auto-dereference the key, with another get()
|
|
1639
|
+
// // - So the user actually sees the value of the resource on the other side of the link
|
|
1640
|
+
// function link (url) {
|
|
1641
|
+
// return {
|
|
1642
|
+
// link: url,
|
|
1643
|
+
// [symbols.link]: true,
|
|
1644
|
+
// _: (args, o) => (o = get(url), json_proxy(o, '', o.val))
|
|
1645
|
+
// }
|
|
1646
|
+
// }
|
|
1647
|
+
|
|
1648
|
+
// The proxy object for links. Disabled for now.
|
|
1649
|
+
// This type of link has to be function called, as link(), to dereference.
|
|
1609
1650
|
// function proxy_link (url) {
|
|
1610
1651
|
// function follow_link () {}
|
|
1611
|
-
//
|
|
1652
|
+
// var proxy = new Proxy(follow_link, {
|
|
1612
1653
|
// get: function (o, k) {
|
|
1613
1654
|
// console.log('get', k)
|
|
1614
1655
|
// if (k === 'inspect' || k === 'valueOf')
|
|
@@ -1686,7 +1727,109 @@
|
|
|
1686
1727
|
// return top_level_proxy[url]
|
|
1687
1728
|
// }
|
|
1688
1729
|
// })
|
|
1730
|
+
|
|
1731
|
+
// proxy[util.inspect.custom] = function(depth, opts) {
|
|
1732
|
+
// var formatted = Array.isArray(o) ? [] : {}
|
|
1733
|
+
// for (let prop of Object.getOwnPropertyNames(o)) {
|
|
1734
|
+
// formatted[prop] = o[prop]
|
|
1735
|
+
// }
|
|
1736
|
+
// return `*${util.inspect({link: url})}`
|
|
1737
|
+
// }
|
|
1738
|
+
|
|
1739
|
+
// return proxy
|
|
1740
|
+
|
|
1741
|
+
// }
|
|
1742
|
+
|
|
1743
|
+
// function proxy_link2 (url) {
|
|
1744
|
+
// var target = {link: url}
|
|
1745
|
+
|
|
1746
|
+
// Object.setPrototypeOf(obj, Function.prototype);
|
|
1747
|
+
// Object.defineProperty(obj, 'toString', {
|
|
1748
|
+
// value: function() { return `{link: "${this.link}"}`; },
|
|
1749
|
+
// writable: true,
|
|
1750
|
+
// configurable: true
|
|
1751
|
+
// })
|
|
1752
|
+
|
|
1753
|
+
// return new Proxy(target, {
|
|
1754
|
+
// apply(target, this_arg, args) {
|
|
1755
|
+
// return top_level_proxy[url]
|
|
1756
|
+
// }
|
|
1757
|
+
// })
|
|
1689
1758
|
// }
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
// New link code
|
|
1762
|
+
function link (url) {
|
|
1763
|
+
var target = () => {}
|
|
1764
|
+
|
|
1765
|
+
// Use non-enumerable properties for function stuff
|
|
1766
|
+
Object.defineProperties(target, {
|
|
1767
|
+
// 'length': { value: 0, enumerable: false },
|
|
1768
|
+
'name': { value: '', enumerable: false },
|
|
1769
|
+
'prototype': { value: {}, enumerable: false },
|
|
1770
|
+
|
|
1771
|
+
// Make link enumerable
|
|
1772
|
+
'link': { value: url, enumerable: true, writable: true, configurable: true },
|
|
1773
|
+
'toString': {
|
|
1774
|
+
value: function() { return `{link: "${this.link}"}` },
|
|
1775
|
+
enumerable: false
|
|
1776
|
+
},
|
|
1777
|
+
|
|
1778
|
+
// Add toJSON method
|
|
1779
|
+
'toJSON': {
|
|
1780
|
+
value: function() { return { link: this.link } },
|
|
1781
|
+
enumerable: false
|
|
1782
|
+
}
|
|
1783
|
+
})
|
|
1784
|
+
|
|
1785
|
+
var proxy = new Proxy(target, {
|
|
1786
|
+
get: function (o, k) {
|
|
1787
|
+
// console.log('link getting',k)
|
|
1788
|
+
// if (k === 'inspect' || k === 'valueOf')
|
|
1789
|
+
// return undefined
|
|
1790
|
+
|
|
1791
|
+
// if (custom_inspect && k === custom_inspect)
|
|
1792
|
+
// return custom_inspect
|
|
1793
|
+
if (k === symbols.is_proxy)
|
|
1794
|
+
return true
|
|
1795
|
+
if (k === symbols.link)
|
|
1796
|
+
return true
|
|
1797
|
+
if (k === symbols.raw)
|
|
1798
|
+
return {link: url}
|
|
1799
|
+
// if (typeof k === 'symbol')
|
|
1800
|
+
// return undefined
|
|
1801
|
+
|
|
1802
|
+
// if (k === 'link')
|
|
1803
|
+
// return url
|
|
1804
|
+
|
|
1805
|
+
return target[k]
|
|
1806
|
+
|
|
1807
|
+
// return undefined
|
|
1808
|
+
|
|
1809
|
+
},
|
|
1810
|
+
apply(target, this_arg, args) {
|
|
1811
|
+
return top_level_proxy[url]
|
|
1812
|
+
},
|
|
1813
|
+
has: function (o, k) {
|
|
1814
|
+
if (k === symbols.link)
|
|
1815
|
+
return true
|
|
1816
|
+
return Reflect.has(o, k)
|
|
1817
|
+
},
|
|
1818
|
+
})
|
|
1819
|
+
|
|
1820
|
+
if (nodejs)
|
|
1821
|
+
proxy[util.inspect.custom] = function(depth, opts) {
|
|
1822
|
+
var formatted = Array.isArray(target) ? [] : {}
|
|
1823
|
+
for (let prop of Object.getOwnPropertyNames(target)) {
|
|
1824
|
+
formatted[prop] = target[prop]
|
|
1825
|
+
}
|
|
1826
|
+
formatted = {link: url}
|
|
1827
|
+
return `Proxy ${util.inspect(formatted, { ...opts, customInspect: true })}`
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
return proxy
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1690
1833
|
function raw (proxy) {
|
|
1691
1834
|
if (!(typeof proxy === 'object' && proxy[symbols.is_proxy]))
|
|
1692
1835
|
return proxy
|
|
@@ -2099,13 +2242,14 @@
|
|
|
2099
2242
|
var unescape_field_bus_to_json = (field) =>
|
|
2100
2243
|
unescape_field_from_nelson(unescape_field_from_bus(field))
|
|
2101
2244
|
|
|
2102
|
-
var escape_json_to_bus
|
|
2245
|
+
var escape_json_to_bus = (obj) => {
|
|
2103
2246
|
obj = translate_fields(obj, escape_field_json_to_bus)
|
|
2104
|
-
return deep_map(obj, o => (typeof o === 'object'
|
|
2247
|
+
return deep_map(obj, o => ((typeof o === 'object' || typeof o === 'function')
|
|
2248
|
+
&& symbols.link in o
|
|
2105
2249
|
? {link: o.link}
|
|
2106
2250
|
: o))
|
|
2107
2251
|
}
|
|
2108
|
-
var unescape_bus_to_json
|
|
2252
|
+
var unescape_bus_to_json = (obj) =>
|
|
2109
2253
|
translate_fields(obj, field => unescape_field_bus_to_json(field))
|
|
2110
2254
|
|
|
2111
2255
|
|
|
@@ -2443,6 +2587,8 @@
|
|
|
2443
2587
|
|
|
2444
2588
|
if (typeof obj === 'object') {
|
|
2445
2589
|
if (schema === 'object') return true
|
|
2590
|
+
if (schema === 'link')
|
|
2591
|
+
return validate(obj, {link: 'string'})
|
|
2446
2592
|
|
|
2447
2593
|
if (typeof schema === 'object') {
|
|
2448
2594
|
for (var k in obj) {
|
|
@@ -2599,8 +2745,9 @@
|
|
|
2599
2745
|
if (nodejs)
|
|
2600
2746
|
// Use require.call() instead of require() to fool jsdelivr.net into ignoring the require
|
|
2601
2747
|
require.call(null, './server-library').import_server(bus, make_bus, options)
|
|
2602
|
-
|
|
2748
|
+
|
|
2603
2749
|
bus.render_when_loading = true
|
|
2750
|
+
|
|
2604
2751
|
return bus
|
|
2605
2752
|
}
|
|
2606
2753
|
|