@knowlearning/agents 0.3.17 → 0.3.18

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 (2) hide show
  1. package/agents/generic.js +27 -19
  2. package/package.json +1 -1
package/agents/generic.js CHANGED
@@ -36,6 +36,8 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
36
36
  let failedConnections = 0
37
37
  let mode = 'normal'
38
38
  const environmentPromise = new Promise(r => resolveEnvironment = r)
39
+ let lastSentSI = -1
40
+ let lastHeartbeat
39
41
 
40
42
  const sessionData = new MutableProxy({}, patch => queueMessage({scope: 'sessions', patch}))
41
43
 
@@ -46,6 +48,9 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
46
48
  patches: {}
47
49
  }
48
50
 
51
+ log('INITIALIZING AGENT CONNECTION')
52
+ initWS()
53
+
49
54
  function log() {
50
55
  if (mode === 'debug') console.log(...arguments)
51
56
  }
@@ -55,11 +60,6 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
55
60
  if (watcherIndex > -1) watchers[key].splice(watcherIndex, 1)
56
61
  else console.warn('TRIED TO REMOVE WATCHER THAT DOES NOT EXIST')
57
62
  }
58
-
59
- log('INITIALIZING AGENT CONNECTION')
60
- initWS()
61
-
62
- let lastSentSI = -1
63
63
  function flushMessageQueue() {
64
64
  // TODO: probably want to make this loop async so we don't try and push more to
65
65
  // a closed connection
@@ -80,23 +80,34 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
80
80
  flushMessageQueue()
81
81
  }
82
82
 
83
- let lastHeartbeat
84
83
  function checkHeartbeat() {
85
84
  clearTimeout(lastHeartbeat)
86
85
  lastHeartbeat = setTimeout(
87
86
  () => {
88
87
  log('CLOSING DUE TO HEARTBEAT TIMEOUT')
89
- ws.close()
88
+ restartConnection()
90
89
  },
91
90
  HEARTBEAT_TIMEOUT
92
91
  )
93
92
  }
94
93
 
94
+ async function restartConnection() {
95
+ if (authed) log(`CLOSED DOMAIN ${domain} USER ${user} SESSION ${session} CONNECTION TO SERVER ${server}`)
96
+ authed = false
97
+ ws.onmessage = () => {} // needs to be a no-op since a closing ws can still get messages
98
+ if (!disconnected) {
99
+ await new Promise(r => setTimeout(r, Math.min(1000, failedConnections * 100)))
100
+ failedConnections += 1
101
+ initWS() // TODO: don't do this if we are purposefully unloading...
102
+ }
103
+ }
104
+
95
105
  function initWS() {
96
106
  ws = new WebSocket(`${protocol}://${host}`)
97
107
 
108
+ let opened = false
98
109
  ws.onopen = async () => {
99
- checkHeartbeat()
110
+ opened = true
100
111
  log('AUTHORIZING NEWLY OPENED WS FOR SESSION:', session)
101
112
  failedConnections = 0
102
113
  ws.send(JSON.stringify({ token: await token(), session }))
@@ -169,19 +180,16 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
169
180
  }
170
181
 
171
182
  ws.onerror = async error => {
172
- log('WS CONNECTION ERROR', error.message)
183
+ log('WS CONNECTION ERROR', error.message, opened)
184
+ if (!opened) restartConnection() // onclose won't trigger if never opened
173
185
  }
174
186
 
175
- ws.onclose = async () => {
176
- if (authed) log(`CLOSED DOMAIN ${domain} USER ${user} SESSION ${session} CONNECTION TO SERVER ${server}`)
177
- authed = false
178
- ws.onmessage = () => {} // needs to be a no-op since a closing ws can still get messages
179
- if (!disconnected) {
180
- await new Promise(r => setTimeout(r, Math.min(1000, failedConnections * 100)))
181
- failedConnections += 1
182
- initWS() // TODO: don't do this if we are purposefully unloading...
183
- }
187
+ ws.onclose = async error => {
188
+ log('WS CLOSURE', error.message, opened)
189
+ restartConnection()
184
190
  }
191
+
192
+ checkHeartbeat()
185
193
  }
186
194
 
187
195
  function environment() { return environmentPromise }
@@ -223,7 +231,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
223
231
  // POSSIBLE: wait for most recent interaction update response for key k that we sent...
224
232
  await lastInteractionUpdateForWatchedScope[k]
225
233
  // TODO: probably something like await updateMessageReceivedForLastInteractionWeSentForKey[k]
226
- resolveState(states[k])
234
+ resolveState(structuredClone(await states[k]))
227
235
  })
228
236
 
229
237
  promise.watch = fn => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowlearning/agents",
3
- "version": "0.3.17",
3
+ "version": "0.3.18",
4
4
  "description": "API for embedding applications in KnowLearning systems.",
5
5
  "main": "node.js",
6
6
  "browser": "browser.js",