dmx-api 4.0.0 → 4.0.2
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/README.md +14 -2
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/model.js +5 -1
- package/src/rpc.js +1 -1
- package/src/websocket.js +31 -20
package/README.md
CHANGED
|
@@ -2,9 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## Version History
|
|
4
4
|
|
|
5
|
+
**4.0.2** -- Jan 31, 2026
|
|
6
|
+
|
|
7
|
+
* Fix:
|
|
8
|
+
- Log proper dmx-api version in browser console
|
|
9
|
+
|
|
10
|
+
**4.0.1** -- Jan 31, 2026
|
|
11
|
+
|
|
12
|
+
* Improvement:
|
|
13
|
+
- No alert box appears when WebSocket connection is dropped. Reopens when browser is "foregrounded".
|
|
14
|
+
* Fix:
|
|
15
|
+
- Topic positioning for `Topicmap` instances hold as reactive Vue 3 state.
|
|
16
|
+
|
|
5
17
|
**4.0** -- Oct 16, 2024
|
|
6
18
|
|
|
7
|
-
* BREAKING
|
|
19
|
+
* BREAKING CHANGE
|
|
8
20
|
- requires Vue 3 (instead Vue 2)
|
|
9
21
|
|
|
10
22
|
**3.1** -- Oct 16, 2024
|
|
@@ -331,4 +343,4 @@ library's `init()` function.
|
|
|
331
343
|
|
|
332
344
|
------------
|
|
333
345
|
Jörg Richter
|
|
334
|
-
|
|
346
|
+
Jan 31, 2026
|
package/package.json
CHANGED
package/src/index.js
CHANGED
package/src/model.js
CHANGED
|
@@ -901,7 +901,11 @@ class Topicmap extends Topic {
|
|
|
901
901
|
viewTopic.children = topic.children // ### TODO, see comment in newViewTopic() above
|
|
902
902
|
this.addTopic(viewTopic)
|
|
903
903
|
op.type = 'add'
|
|
904
|
-
op.viewTopic =
|
|
904
|
+
op.viewTopic = this.getTopic(topic.id)
|
|
905
|
+
// Note: we don't assign plain "viewTopic" to op.viewTopic but must re-access it by this.getTopic(). In case of a
|
|
906
|
+
// Vue 3 application both are not the same as addTopic() implicitly wraps viewTopic into a JS Proxy object
|
|
907
|
+
// (provided this Topicmap instance is reactive state). All subsequent modifications of viewTopic (in particular
|
|
908
|
+
// the initialization of its position) must be applied to the Proxy object then, not the original viewTopic.
|
|
905
909
|
} else {
|
|
906
910
|
if (!viewTopic.isVisible()) {
|
|
907
911
|
viewTopic.setVisibility(true)
|
package/src/rpc.js
CHANGED
package/src/websocket.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const HEARTBEAT_INTERVAL = 25 * 1000 // 25s
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A WebSocket connection to the DMX server.
|
|
@@ -13,6 +13,8 @@ const IDLE_INTERVAL = 60 * 1000 // 60s
|
|
|
13
13
|
export default class DMXWebSocket {
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
+
* @param config
|
|
17
|
+
* a promise for an object having a `dmx.websockets.url` property.
|
|
16
18
|
* @param messageHandler
|
|
17
19
|
* the function that processes incoming messages.
|
|
18
20
|
* One argument is passed: the message pushed by the server (a deserialzed JSON object).
|
|
@@ -20,8 +22,8 @@ export default class DMXWebSocket {
|
|
|
20
22
|
constructor (config, messageHandler) {
|
|
21
23
|
this.messageHandler = messageHandler
|
|
22
24
|
config.then(config => {
|
|
25
|
+
document.addEventListener('visibilitychange', this._handleVisibilityChange.bind(this))
|
|
23
26
|
this.url = config['dmx.websockets.url']
|
|
24
|
-
// DEV && console.log('[DMX] CONFIG: WebSocket server is reachable at', this.url)
|
|
25
27
|
this._connect()
|
|
26
28
|
})
|
|
27
29
|
}
|
|
@@ -35,11 +37,21 @@ export default class DMXWebSocket {
|
|
|
35
37
|
this.ws.send(JSON.stringify(message))
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
_handleVisibilityChange () {
|
|
41
|
+
DEV && console.log('[DMX] Document visibility:', document.visibilityState, new Date())
|
|
42
|
+
if (document.visibilityState === "hidden") {
|
|
43
|
+
// mobile browsers often kill background sockets anyway
|
|
44
|
+
this._close()
|
|
45
|
+
} else {
|
|
46
|
+
this._connect()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
38
50
|
_connect () {
|
|
39
|
-
DEV && console.log('[DMX]
|
|
51
|
+
DEV && console.log('[DMX] Connecting', this.url)
|
|
40
52
|
this.ws = new WebSocket(this.url)
|
|
41
53
|
this.ws.onopen = e => {
|
|
42
|
-
this.
|
|
54
|
+
this._startHeartbeat()
|
|
43
55
|
}
|
|
44
56
|
this.ws.onmessage = e => {
|
|
45
57
|
const message = JSON.parse(e.data)
|
|
@@ -47,33 +59,32 @@ export default class DMXWebSocket {
|
|
|
47
59
|
this.messageHandler(message)
|
|
48
60
|
}
|
|
49
61
|
this.ws.onclose = e => {
|
|
50
|
-
DEV && console.log('[DMX] WebSocket
|
|
51
|
-
this.
|
|
52
|
-
this._reload() // a closed ws connection is regarded an (backend/network) error which requires page reloading
|
|
62
|
+
DEV && console.log('[DMX] WebSocket closed', e.reason)
|
|
63
|
+
this._cleanup()
|
|
53
64
|
}
|
|
54
65
|
this.ws.onerror = e => {
|
|
55
66
|
DEV && console.warn('[DMX] WebSocket error')
|
|
56
67
|
}
|
|
57
68
|
}
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
this.
|
|
70
|
+
_startHeartbeat () {
|
|
71
|
+
this.heartbeatTimer = setInterval(this._ping.bind(this), HEARTBEAT_INTERVAL)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_stopHeartbeat () {
|
|
75
|
+
clearInterval(this.heartbeatTimer)
|
|
61
76
|
}
|
|
62
77
|
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
_ping () {
|
|
79
|
+
DEV && console.log('[DMX] WebSocket ping')
|
|
80
|
+
this.send({type: 'ping'})
|
|
65
81
|
}
|
|
66
82
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.send({type: 'idle'})
|
|
83
|
+
_close () {
|
|
84
|
+
this.ws.close()
|
|
70
85
|
}
|
|
71
86
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
alert('There is a problem with the server or network.\n\nPlease press OK to reload page.\n' +
|
|
75
|
-
'If it fails try manual page reload.')
|
|
76
|
-
location.reload()
|
|
77
|
-
}, 1000) // timeout to not interfere with interactive page reload (which also closes websocket connection)
|
|
87
|
+
_cleanup () {
|
|
88
|
+
this._stopHeartbeat()
|
|
78
89
|
}
|
|
79
90
|
}
|