@knowlearning/agents 0.3.18 → 0.4.1

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.
@@ -95,28 +95,27 @@ export default function embed(environment, iframe) {
95
95
 
96
96
  // TODO: make sure content security policy headers for embedded domain always restrict iframe
97
97
  // src to only self for embedded domain
98
- Agent
99
- .environment()
100
- .then(async ({ embed }) => {
101
- iframe.onload = () => {
102
- frameLoaded = true
103
- processPostMessageQueue()
104
- }
105
- const { protocol, pathname } = window.location
106
- if (validateUUID(environment.content)) {
107
- // TODO: fix development port workararounds for embed
108
- if (protocol === 'http:') embed = embed.replace(':32002', ':32020')
109
- iframe.src = `${protocol}//${embed}${pathname}?s=${session}`
110
- }
111
- else {
112
- iframe.src = environment.content
113
- }
98
+ iframe.onload = () => {
99
+ frameLoaded = true
100
+ processPostMessageQueue()
101
+ }
114
102
 
115
- while(!embeddedAgentInitialized) {
116
- postMessage({ type: 'setup', session })
117
- await new Promise(r => setTimeout(r, 100))
118
- }
119
- })
103
+ setUpEmbeddedFrame()
104
+
105
+ async function setUpEmbeddedFrame() {
106
+ const { protocol } = window.location
107
+ const { id } = environment
108
+ if (validateUUID(id)) {
109
+ const { domain } = await Agent.metadata(id)
110
+ iframe.src = `${protocol}//${domain}/${id}`
111
+ }
112
+ else iframe.src = id // TODO: ensure is url
113
+
114
+ while(!embeddedAgentInitialized) {
115
+ postMessage({ type: 'setup', session })
116
+ await new Promise(r => setTimeout(r, 100))
117
+ }
118
+ }
120
119
 
121
120
  function remove () {
122
121
  if (iframe.parentNode) iframe.parentNode.removeChild(iframe)
package/agents/generic.js CHANGED
@@ -39,14 +39,11 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
39
39
  let lastSentSI = -1
40
40
  let lastHeartbeat
41
41
 
42
- const sessionData = new MutableProxy({}, patch => queueMessage({scope: 'sessions', patch}))
43
-
44
- sessionData[session] = {
45
- subscriptions: {},
46
- uploads: {},
47
- downloads: {},
48
- patches: {}
49
- }
42
+ // TODO: probably an use "mutate" function from below
43
+ const subscriptions = new MutableProxy({}, patch => queueMessage({scope: 'subscriptions', patch}))
44
+ const uploads = new MutableProxy({}, patch => queueMessage({scope: 'uploads', patch}))
45
+ const downloads = new MutableProxy({}, patch => queueMessage({scope: 'downloads', patch}))
46
+ const patches = new MutableProxy({}, patch => queueMessage({scope: 'patches', patch}))
50
47
 
51
48
  log('INITIALIZING AGENT CONNECTION')
52
49
  initWS()
@@ -91,23 +88,25 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
91
88
  )
92
89
  }
93
90
 
91
+ let restarting = false
94
92
  async function restartConnection() {
95
- if (authed) log(`CLOSED DOMAIN ${domain} USER ${user} SESSION ${session} CONNECTION TO SERVER ${server}`)
93
+ if (restarting) return
94
+
95
+ restarting = true
96
96
  authed = false
97
97
  ws.onmessage = () => {} // needs to be a no-op since a closing ws can still get messages
98
98
  if (!disconnected) {
99
99
  await new Promise(r => setTimeout(r, Math.min(1000, failedConnections * 100)))
100
100
  failedConnections += 1
101
101
  initWS() // TODO: don't do this if we are purposefully unloading...
102
+ restarting = false
102
103
  }
103
104
  }
104
105
 
105
106
  function initWS() {
106
107
  ws = new WebSocket(`${protocol}://${host}`)
107
108
 
108
- let opened = false
109
109
  ws.onopen = async () => {
110
- opened = true
111
110
  log('AUTHORIZING NEWLY OPENED WS FOR SESSION:', session)
112
111
  failedConnections = 0
113
112
  ws.send(JSON.stringify({ token: await token(), session }))
@@ -157,10 +156,10 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
157
156
  else {
158
157
  const key = `${message.domain}/${message.user}/${message.scope}`
159
158
  if (watchers[key]) {
160
- if (sessionData[session].subscriptions[key] + 1 !== message.ii) {
159
+ if (subscriptions[key] + 1 !== message.ii) {
161
160
  // TODO: this seems to be an error that happens with decent regularity (an answer with a given si was skipped/failed)
162
161
  // we should be wary of out-of-order ii being passed down (maybe need to wait for older ones???)
163
- console.warn('UNEXPECTED UPDATE INTERACTION INDEX!!!!!!!!!!! last index in session', sessionData[session].subscriptions[key], ' passed index ', message.ii)
162
+ console.warn('UNEXPECTED UPDATE INTERACTION INDEX!!!!!!!!!!! last index in session', subscriptions[key], ' passed index ', message.ii)
164
163
  }
165
164
  states[key] = await states[key] || {}
166
165
 
@@ -169,7 +168,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
169
168
 
170
169
  applyPatch(states[key], standardJSONPatch(message.patch.slice(lastResetPatchIndex + 1)))
171
170
  watchers[key].forEach(fn => fn({ ...message, state: states[key] }))
172
- sessionData[session].subscriptions[key] = message.ii
171
+ subscriptions[key] = message.ii
173
172
  }
174
173
  }
175
174
  }
@@ -180,12 +179,11 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
180
179
  }
181
180
 
182
181
  ws.onerror = async error => {
183
- log('WS CONNECTION ERROR', error.message, opened)
184
- if (!opened) restartConnection() // onclose won't trigger if never opened
182
+ log('WS CONNECTION ERROR', error.message)
185
183
  }
186
184
 
187
185
  ws.onclose = async error => {
188
- log('WS CLOSURE', error.message, opened)
186
+ log('WS CLOSURE', error.message)
189
187
  restartConnection()
190
188
  }
191
189
 
@@ -211,15 +209,15 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
211
209
  if (states[k] === undefined) {
212
210
  watchers[k] = []
213
211
  states[k] = new Promise(async resolve => {
214
- sessionData[session].subscriptions[k] = null
212
+ subscriptions[k] = null
215
213
  const { ii, state } = await lastMessageResponse()
216
- sessionData[session].subscriptions[k] = ii
214
+ subscriptions[k] = ii
217
215
  resolve(state)
218
216
  if (ii === -1) {
219
217
  // -1 indicates the result is a computed scope, so
220
218
  // ii does not apply (we clear out the subscription to not cache value)
221
219
  delete states[k]
222
- delete sessionData[session].subscriptions[k]
220
+ delete subscriptions[k]
223
221
  }
224
222
  })
225
223
  }
@@ -249,7 +247,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
249
247
  const k = await key
250
248
  removeWatcher(k, watchFn)
251
249
  if (watchers[k].length === 0) {
252
- delete sessionData[session].subscriptions[k]
250
+ delete subscriptions[k]
253
251
  delete watchers[k]
254
252
  }
255
253
  }
@@ -260,9 +258,9 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
260
258
  // TODO: if no data, set up streaming upload
261
259
  async function upload(name, type, data, id=uuid()) {
262
260
  // TODO: include data size info...
263
- sessionData[session].uploads[id] = { url: null, sent: 0, name, type }
261
+ uploads[id] = { url: null, sent: 0, name, type }
264
262
  const { url } = await lastMessageResponse()
265
- sessionData[session].uploads[id].url = url
263
+ uploads[id].url = url
266
264
 
267
265
  if (data === undefined) return url
268
266
  else {
@@ -276,9 +274,9 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
276
274
  }
277
275
 
278
276
  async function download(id, passthrough=false) {
279
- sessionData[session].downloads[id] = { url: null, size: null, sent: 0 }
277
+ downloads[id] = { url: null, size: null, sent: 0 }
280
278
  const { url } = await lastMessageResponse()
281
- sessionData[session].downloads[id].url = url
279
+ downloads[id].url = url
282
280
 
283
281
  if (passthrough) return url
284
282
  else {
@@ -291,7 +289,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
291
289
  }
292
290
 
293
291
  async function patch(root, scopes) {
294
- sessionData[session].patches[uuid()] = { root, scopes }
292
+ patches[uuid()] = { root, scopes }
295
293
  const { swaps } = await lastMessageResponse()
296
294
  return { swaps }
297
295
  }
@@ -333,6 +331,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
333
331
  }
334
332
 
335
333
  async function mutate(scope, initialize=true) {
334
+ // TODO: probably can remove redundant copy
336
335
  const initial = initialize ? copy(await state(scope) || {}) : {}
337
336
  return new MutableProxy(initial, patch => interact(scope, patch))
338
337
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowlearning/agents",
3
- "version": "0.3.18",
3
+ "version": "0.4.1",
4
4
  "description": "API for embedding applications in KnowLearning systems.",
5
5
  "main": "node.js",
6
6
  "browser": "browser.js",
package/vue/3/content.vue CHANGED
@@ -12,10 +12,6 @@ export default {
12
12
  id: {
13
13
  type: String,
14
14
  required: true
15
- },
16
- scope: {
17
- type: String,
18
- required: false
19
15
  }
20
16
  },
21
17
  unmounted() {
@@ -25,9 +21,9 @@ export default {
25
21
  setup(iframe) {
26
22
  if (!iframe || this.iframe === iframe) return
27
23
 
28
- const { id, scope } = this
24
+ const { id } = this
29
25
  this.iframe = iframe
30
- this.embedding = Agent.embed({ content: id, scope }, iframe)
26
+ this.embedding = Agent.embed({ id }, iframe)
31
27
 
32
28
  /*
33
29
  const { handle } = this.embedding