@knowlearning/agents 0.7.3 → 0.7.5

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.
@@ -75,7 +75,7 @@ export default function embed(environment, iframe) {
75
75
  sendDown(await Agent.upload(name, contentType, false, id))
76
76
  }
77
77
  else if (type === 'download') {
78
- sendDown(await Agent.download(message.id, true))
78
+ sendDown(await Agent.download(message.id).url())
79
79
  }
80
80
  else if (type === 'login') {
81
81
  const { provider, username, password } = message
@@ -133,9 +133,46 @@ export default function EmbeddedAgent() {
133
133
  }
134
134
  }
135
135
 
136
- async function download(id, passthrough=false) {
137
- const url = await send({ type: 'download', id })
138
- return passthrough ? url : fetch(url)
136
+ function download(id) {
137
+ const mode = 'fetch'
138
+ const promise = new Promise(async (resolve, reject) => {
139
+ const url = await send({ type: 'download', id })
140
+
141
+ await new Promise(r => setTimeout(r))
142
+ if (mode === 'url') resolve(url)
143
+ else if (mode === 'fetch') {
144
+ const response = await fetch(url)
145
+ const { ok, statusText } = response
146
+
147
+ if (ok) resolve(response)
148
+ else reject(statusText)
149
+ }
150
+ else if (mode === 'direct') {
151
+ // TODO: use browser progress UX instead of downloading all into memory first
152
+ const res = await download(id)
153
+ const { name } = await metadata(id)
154
+ const type = res.headers.get('Content-Type')
155
+ const blob = new Blob([ await res.blob() ], { type })
156
+ const url = window.URL.createObjectURL(blob)
157
+ const a = document.createElement('a')
158
+ a.style.display = 'none'
159
+ a.href = url
160
+ a.download = name
161
+ document.body.appendChild(a)
162
+ a.click()
163
+ window.URL.revokeObjectURL(url)
164
+ resolve()
165
+ }
166
+ })
167
+ promise.direct = () => {
168
+ mode = 'direct'
169
+ return promise
170
+ }
171
+ promise.url = () => {
172
+ mode = 'url'
173
+ return promise
174
+ }
175
+ return promise
139
176
  }
140
177
 
141
178
  function metadata(id) {
@@ -0,0 +1,54 @@
1
+ export default function download (id, { uuid, initialize, lastMessageResponse, fetch, metadata }) {
2
+ // TODO: initialize size info
3
+ const downloadId = uuid()
4
+ initialize(
5
+ downloadId,
6
+ 'application/json;type=download',
7
+ { id }
8
+ )
9
+
10
+ let mode = 'fetch'
11
+
12
+ const promise = new Promise(async (resolve, reject) => {
13
+ const { url } = await lastMessageResponse()
14
+ await new Promise(r => setTimeout(r))
15
+
16
+ if (mode === 'url') resolve(url)
17
+ else if (mode === 'fetch') {
18
+ const response = await fetch(url)
19
+ const { ok, statusText } = response
20
+
21
+ if (ok) resolve(response)
22
+ else reject(statusText)
23
+ }
24
+ else if (mode === 'direct') {
25
+ // TODO: throw meaningful error if not in browser context
26
+ // (following block assumes browser context)
27
+ // TODO: use browser progress UX instead of downloading all into memory first
28
+ const res = await download(id, { uuid, initialize, lastMessageResponse, fetch, metadata })
29
+ const { name } = await metadata(id)
30
+ const type = res.headers.get('Content-Type')
31
+ const blob = new Blob([ await res.blob() ], { type })
32
+ const url = window.URL.createObjectURL(blob)
33
+ const a = document.createElement('a')
34
+ a.style.display = 'none'
35
+ a.href = url
36
+ a.download = name
37
+ document.body.appendChild(a)
38
+ a.click()
39
+ window.URL.revokeObjectURL(url)
40
+ resolve()
41
+ }
42
+ })
43
+
44
+ promise.direct = () => {
45
+ mode = 'direct'
46
+ return promise
47
+ }
48
+ promise.url = () => {
49
+ mode = 'url'
50
+ return promise
51
+ }
52
+
53
+ return promise
54
+ }
package/agents/generic.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import MutableProxy from '../persistence/json.js'
2
+ import download from './download.js'
2
3
 
3
4
  const HEARTBEAT_TIMEOUT = 10000
4
5
 
@@ -181,7 +182,11 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
181
182
 
182
183
  if (states[message.scope].active === undefined) states[message.scope].active = {}
183
184
  applyPatch(states[message.scope], standardJSONPatch(message.patch.slice(lastResetPatchIndex + 1)))
184
- watchers[message.scope].forEach(fn => fn({ ...message, state: states[message.scope].active }))
185
+ watchers[message.scope]
186
+ .forEach(fn => {
187
+ const state = structuredClone(states[message.scope].active)
188
+ fn({ ...message, state })
189
+ })
185
190
  if (sub) sub.ii = message.ii
186
191
  }
187
192
  }
@@ -351,26 +356,6 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
351
356
  }
352
357
  }
353
358
 
354
- async function download(id, passthrough=false) {
355
- // TODO: initialize size info
356
- const downloadId = uuid()
357
- initialize(
358
- downloadId,
359
- 'application/json;type=download',
360
- { id }
361
- )
362
- const { url } = await lastMessageResponse()
363
-
364
- if (passthrough) return url
365
- else {
366
- const response = await fetch(url)
367
- const { ok, statusText } = response
368
-
369
- if (ok) return response
370
- else throw new Error(statusText)
371
- }
372
- }
373
-
374
359
  async function patch(root, scopes) {
375
360
  patches[uuid()] = { root, scopes }
376
361
  const { swaps } = await lastMessageResponse()
@@ -470,7 +455,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
470
455
  state,
471
456
  watch,
472
457
  upload,
473
- download,
458
+ download: id => download(id, { uuid, initialize, lastMessageResponse, fetch, download, metadata }),
474
459
  interact,
475
460
  patch,
476
461
  claim,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowlearning/agents",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "API for embedding applications in KnowLearning systems.",
5
5
  "main": "node.js",
6
6
  "browser": "browser.js",