@knowlearning/agents 0.9.69 → 0.9.70

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.
@@ -11,11 +11,23 @@ function isLocal() { return localStorage.getItem('api') === 'local' }
11
11
  export default options => {
12
12
  const { host, protocol } = window.location
13
13
 
14
+ const Connection = function () {
15
+ const ws = new WebSocket(`${protocol === 'https:' ? 'wss' : 'ws'}://${isLocal() ? DEVELOPMENT_HOST : REMOTE_HOST}`)
16
+
17
+ this.send = message => ws.send(message)
18
+ this.close = () => ws.close()
19
+
20
+ ws.onopen = () => this.onopen && this.onopen()
21
+ ws.onmessage = ({ data }) => this.onmessage && this.onmessage(data)
22
+ ws.onerror = error => this.onerror && this.onerror(error)
23
+ ws.onclose = error => this.onclose && this.onclose(error)
24
+
25
+ return this
26
+ }
27
+
14
28
  const agent = GenericAgent({
15
- host: isLocal() ? DEVELOPMENT_HOST : REMOTE_HOST,
16
- protocol: protocol === 'https:' ? 'wss' : 'ws',
17
29
  token: options.getToken || getToken,
18
- WebSocket,
30
+ Connection,
19
31
  uuid,
20
32
  fetch,
21
33
  applyPatch,
@@ -13,7 +13,7 @@ const POSTGRES_QUERY_TYPE = 'application/json;type=postgres-query'
13
13
  const TAG_TYPE = 'application/json;type=tag'
14
14
  const DOMAIN_CLAIM_TYPE = 'application/json;type=domain-claim'
15
15
 
16
- export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fetch, applyPatch, login, logout, reboot }) {
16
+ export default function Agent({ Connection, token, uuid, fetch, applyPatch, login, logout, reboot }) {
17
17
  const states = {}
18
18
  const watchers = {}
19
19
  const keyToSubscriptionId = {}
@@ -29,7 +29,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
29
29
  reconnect,
30
30
  synced,
31
31
  environment
32
- ] = messageQueue({ token, protocol, host, WebSocket, watchers, states, applyPatch, log, login, interact })
32
+ ] = messageQueue({ token, Connection, watchers, states, applyPatch, log, login, interact, reboot })
33
33
 
34
34
  // initialize session
35
35
  environment()
@@ -14,8 +14,8 @@ function sanitizeJSONPatchPathSegment(s) {
14
14
  else return s
15
15
  }
16
16
 
17
- export default function messageQueue({ token, protocol, host, WebSocket, watchers, states, applyPatch, log, login }) {
18
- let ws
17
+ export default function messageQueue({ token, Connection, watchers, states, applyPatch, log, login, reboot }) {
18
+ let connection
19
19
  let user
20
20
  let authed = false
21
21
  let session
@@ -66,13 +66,19 @@ export default function messageQueue({ token, protocol, host, WebSocket, watcher
66
66
  await new Promise(r=>r())
67
67
  lastSynchronousScopePatched = null
68
68
 
69
- while (authed && ws.readyState === WebSocket.OPEN && lastSentSI+1 < messageQueue.length) {
69
+ while (authed && lastSentSI+1 < messageQueue.length) {
70
70
  lastSynchronousScopePatched = null
71
- lastSentSI += 1
72
- ws.send(JSON.stringify(messageQueue[lastSentSI]))
73
-
74
- // async so we don't try and push more to a closed connection
75
- await new Promise(r=>r())
71
+ try {
72
+ connection.send(JSON.stringify(messageQueue[lastSentSI + 1]))
73
+ lastSentSI += 1
74
+ // async so we don't try and push more to a closed connection
75
+ await new Promise(r=>r())
76
+ }
77
+ catch (error) {
78
+ console.warn('ERROR SENDING OVER CONNECTION', error)
79
+ restartConnection()
80
+ break
81
+ }
76
82
  }
77
83
  }
78
84
 
@@ -100,25 +106,25 @@ export default function messageQueue({ token, protocol, host, WebSocket, watcher
100
106
  authed = false
101
107
  if (!disconnected) {
102
108
  await new Promise(r => setTimeout(r, Math.min(1000, failedConnections * 100)))
103
- ws.onmessage = () => {} // needs to be a no-op since a closing ws can still get messages
109
+ connection.onmessage = () => {} // needs to be a no-op since a closing connection can still get messages
104
110
  restarting = true
105
111
  failedConnections += 1
106
- initWS() // TODO: don't do this if we are purposefully unloading...
112
+ initConnection() // TODO: don't do this if we are purposefully unloading...
107
113
  restarting = false
108
114
  }
109
115
  }
110
116
 
111
- function initWS() {
112
- ws = new WebSocket(`${protocol}://${host}`)
117
+ function initConnection() {
118
+ connection = new Connection()
113
119
 
114
- ws.onopen = async () => {
120
+ connection.onopen = async () => {
115
121
  if (!sessionMetrics.connected) sessionMetrics.connected = Date.now()
116
- log('AUTHORIZING NEWLY OPENED WS FOR SESSION:', session)
122
+ log('AUTHORIZING NEWLY OPENED CONNECTION FOR SESSION:', session)
117
123
  failedConnections = 0
118
- ws.send(JSON.stringify({ token: await token(), session }))
124
+ connection.send(JSON.stringify({ token: await token(), session }))
119
125
  }
120
126
 
121
- ws.onmessage = async ({ data }) => {
127
+ connection.onmessage = async data => {
122
128
  checkHeartbeat()
123
129
  if (data.length === 0) return // heartbeat
124
130
 
@@ -161,7 +167,7 @@ export default function messageQueue({ token, protocol, host, WebSocket, watcher
161
167
  .forEach(([res, rej]) => message.error ? rej(message) : res(message))
162
168
 
163
169
  delete responses[message.si]
164
- ws.send(JSON.stringify({ack: message.si})) // acknowledgement that we have received the response for this message
170
+ connection.send(JSON.stringify({ack: message.si})) // acknowledgement that we have received the response for this message
165
171
  resolveSyncPromises()
166
172
  }
167
173
  else {
@@ -200,16 +206,16 @@ export default function messageQueue({ token, protocol, host, WebSocket, watcher
200
206
  }
201
207
  }
202
208
  catch (error) {
203
- console.error('ERROR HANDLING WS MESSAGE', error)
209
+ console.error('ERROR HANDLING CONNECTION MESSAGE', error)
204
210
  }
205
211
  }
206
212
 
207
- ws.onerror = async error => {
208
- log('WS CONNECTION ERROR', error.message)
213
+ connection.onerror = async error => {
214
+ log('CONNECTION ERROR', error.message)
209
215
  }
210
216
 
211
- ws.onclose = async error => {
212
- log('WS CLOSURE', error.message)
217
+ connection.onclose = async error => {
218
+ log('CONNECTION CLOSURE', error.message)
213
219
  restartConnection()
214
220
  }
215
221
 
@@ -227,7 +233,7 @@ export default function messageQueue({ token, protocol, host, WebSocket, watcher
227
233
  function disconnect() {
228
234
  log('DISCONNECTED AGENT!!!!!!!!!!!!!!!')
229
235
  disconnected = true
230
- ws.close()
236
+ connection.close()
231
237
  }
232
238
 
233
239
  function reconnect() {
@@ -236,7 +242,7 @@ export default function messageQueue({ token, protocol, host, WebSocket, watcher
236
242
  restartConnection()
237
243
  }
238
244
 
239
- initWS()
245
+ initConnection()
240
246
 
241
247
  return [queueMessage, lastMessageResponse, disconnect, reconnect, synced, environment]
242
248
  }
package/deno.js CHANGED
@@ -4,10 +4,23 @@ import Agent from './agents/generic/index.js'
4
4
  const SERVE_HOST = Deno.env.get("SERVE_HOST")
5
5
  const SERVICE_ACCOUNT_TOKEN = Deno.env.get("SERVICE_ACCOUNT_TOKEN")
6
6
 
7
+ const postMessage = message => self.postMessage(message)
8
+
9
+ function Connection() {
10
+ this.send = postMessage
11
+
12
+ (async function () {
13
+ await new Promise(r => setTimeout(r))
14
+ this.onopen && this.onopen()
15
+ })()
16
+
17
+ // TODO: consider what onclose and onerror mean in this case
18
+ return this
19
+ }
20
+
7
21
  export default new Agent({
8
- host: SERVE_HOST,
22
+ Connection,
9
23
  token: () => Deno.readTextFile(SERVICE_ACCOUNT_TOKEN),
10
- WebSocket,
11
24
  uuid: () => crypto.randomUUID(),
12
25
  fetch,
13
26
  applyPatch: fastJSONPatch.applyPatch,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowlearning/agents",
3
- "version": "0.9.69",
3
+ "version": "0.9.70",
4
4
  "description": "API for embedding applications in KnowLearning systems.",
5
5
  "main": "node.js",
6
6
  "browser": "browser.js",