@knowlearning/agents 0.9.15 → 0.9.17
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.
|
@@ -209,7 +209,7 @@ export default function EmbeddedAgent() {
|
|
|
209
209
|
function disconnect() { return send({ type: 'disconnect' }) }
|
|
210
210
|
function reconnect() { return send({ type: 'reconnect' }) }
|
|
211
211
|
function synced() { return send({ type: 'synced' }) }
|
|
212
|
-
function close() { return send({ type: 'close' }) }
|
|
212
|
+
function close(info) { return send({ type: 'close', info }) }
|
|
213
213
|
|
|
214
214
|
return {
|
|
215
215
|
embedded: true,
|
|
@@ -54,8 +54,7 @@ function embed(environment, iframe) {
|
|
|
54
54
|
sendDown({})
|
|
55
55
|
}
|
|
56
56
|
else if (type === 'close') {
|
|
57
|
-
|
|
58
|
-
if (listeners.close) listeners.close()
|
|
57
|
+
if (listeners.close) listeners.close(message.info)
|
|
59
58
|
}
|
|
60
59
|
else if (type === 'environment') {
|
|
61
60
|
const env = await Agent.environment()
|
package/agents/generic.js
CHANGED
|
@@ -56,6 +56,8 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
56
56
|
const environmentPromise = new Promise(r => resolveEnvironment = r)
|
|
57
57
|
let lastSentSI = -1
|
|
58
58
|
let lastHeartbeat
|
|
59
|
+
let lastSynchronousScopePatched = null
|
|
60
|
+
let lastSynchronousScopePatchPromise = null
|
|
59
61
|
const syncedPromiseResolutions = []
|
|
60
62
|
|
|
61
63
|
const patches = state('patches')
|
|
@@ -77,12 +79,20 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
77
79
|
if (watcherIndex > -1) watchers[key].splice(watcherIndex, 1)
|
|
78
80
|
else console.warn('TRIED TO REMOVE WATCHER THAT DOES NOT EXIST')
|
|
79
81
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
|
|
83
|
+
// TODO: clear acknowledged messages
|
|
84
|
+
async function flushMessageQueue() {
|
|
85
|
+
// this makes flushing async, giving time for queue message to combine synchronous updates
|
|
86
|
+
await new Promise(resolve => resolve())
|
|
87
|
+
lastSynchronousScopePatched = null
|
|
88
|
+
|
|
83
89
|
while (authed && ws.readyState === WebSocket.OPEN && lastSentSI+1 < messageQueue.length) {
|
|
90
|
+
lastSynchronousScopePatched = null
|
|
84
91
|
lastSentSI += 1
|
|
85
92
|
ws.send(JSON.stringify(messageQueue[lastSentSI]))
|
|
93
|
+
|
|
94
|
+
// async so we don't try and push more to a closed connection
|
|
95
|
+
await new Promise(resolve => resolve())
|
|
86
96
|
}
|
|
87
97
|
}
|
|
88
98
|
|
|
@@ -90,13 +100,21 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
90
100
|
return new Promise((resolve, reject) => responses[si].push([resolve, reject]))
|
|
91
101
|
}
|
|
92
102
|
|
|
93
|
-
function queueMessage(
|
|
103
|
+
function queueMessage({ scope, patch }) {
|
|
94
104
|
isSynced = false
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
if (lastSynchronousScopePatched === scope) {
|
|
106
|
+
const i = messageQueue.length - 1
|
|
107
|
+
messageQueue[i].patch = [...messageQueue[i].patch, ...patch]
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
si += 1
|
|
111
|
+
lastSynchronousScopePatchPromise = new Promise((resolve, reject) => responses[si] = [[resolve, reject]])
|
|
112
|
+
messageQueue.push({ scope, patch, si, ts: Date.now()})
|
|
113
|
+
lastSynchronousScopePatched = scope
|
|
114
|
+
flushMessageQueue()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return lastSynchronousScopePatchPromise
|
|
100
118
|
}
|
|
101
119
|
|
|
102
120
|
function checkHeartbeat() {
|
|
@@ -114,11 +132,11 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
114
132
|
async function restartConnection() {
|
|
115
133
|
if (restarting) return
|
|
116
134
|
|
|
117
|
-
restarting = true
|
|
118
135
|
authed = false
|
|
119
|
-
ws.onmessage = () => {} // needs to be a no-op since a closing ws can still get messages
|
|
120
136
|
if (!disconnected) {
|
|
121
137
|
await new Promise(r => setTimeout(r, Math.min(1000, failedConnections * 100)))
|
|
138
|
+
ws.onmessage = () => {} // needs to be a no-op since a closing ws can still get messages
|
|
139
|
+
restarting = true
|
|
122
140
|
failedConnections += 1
|
|
123
141
|
initWS() // TODO: don't do this if we are purposefully unloading...
|
|
124
142
|
restarting = false
|
|
@@ -231,8 +249,12 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
231
249
|
|
|
232
250
|
function create({ id=uuid(), active_type, active, name }) {
|
|
233
251
|
// TODO: collapse into 1 patch and 1 interact call
|
|
234
|
-
|
|
235
|
-
|
|
252
|
+
// (requires updating side effects)
|
|
253
|
+
const patch = [
|
|
254
|
+
{ op: 'add', path: ['active_type'], value: active_type },
|
|
255
|
+
{ op: 'add', path: ['active'], value: active }
|
|
256
|
+
]
|
|
257
|
+
interact(id, patch, false)
|
|
236
258
|
return id
|
|
237
259
|
}
|
|
238
260
|
|
|
@@ -300,7 +322,45 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
300
322
|
})
|
|
301
323
|
}
|
|
302
324
|
|
|
325
|
+
function watchResolution(path, callback) {
|
|
326
|
+
const id = path[0]
|
|
327
|
+
const references = path.slice(1)
|
|
328
|
+
let unwatchDeeper = () => {}
|
|
329
|
+
|
|
330
|
+
const unwatch = watch(id, ({ state }) => {
|
|
331
|
+
if (references.length === 0) {
|
|
332
|
+
callback(value)
|
|
333
|
+
return
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// TODO: check if value we care about actually changed
|
|
337
|
+
// and ignore this update if it has not.
|
|
338
|
+
unwatchDeeper()
|
|
339
|
+
|
|
340
|
+
let value = state
|
|
341
|
+
for (let index = 0; index < references.length; index += 1) {
|
|
342
|
+
value = value[references[index]]
|
|
343
|
+
if (
|
|
344
|
+
value === null ||
|
|
345
|
+
value === undefined ||
|
|
346
|
+
index === references.length - 1
|
|
347
|
+
) callback(value)
|
|
348
|
+
else if (isUUID(value)) {
|
|
349
|
+
unwatchDeeper = watchResolution([value, ...references.slice(index + 1)], callback)
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
return () => {
|
|
356
|
+
unwatch()
|
|
357
|
+
unwatchDeeper()
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
303
361
|
function watch(scope=DEFAULT_SCOPE_NAME, fn) {
|
|
362
|
+
if (Array.isArray(scope)) return watchResolution(scope, fn)
|
|
363
|
+
|
|
304
364
|
let initialSent = false
|
|
305
365
|
const queue = []
|
|
306
366
|
function cb(update) {
|
package/package.json
CHANGED
|
@@ -28,29 +28,7 @@ export default function (module, scope) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
else if (component.setup) {
|
|
31
|
-
|
|
32
|
-
const isReactiveRef = r => r && r.__v_isRef
|
|
33
|
-
component.setup = function setupProxy(a, b) { // need to specifically add this here, otherwise second argument not passed in arguments array (probably because of webpack optimization...)
|
|
34
|
-
let refs = origSetupFn.call(this, a, b)
|
|
35
|
-
|
|
36
|
-
Object
|
|
37
|
-
.entries(state)
|
|
38
|
-
.filter(([k]) => isReactiveRef(refs[k]))
|
|
39
|
-
.forEach(([k, v]) => refs[k].value = v)
|
|
40
|
-
|
|
41
|
-
Object
|
|
42
|
-
.entries(refs)
|
|
43
|
-
.filter(([_,r]) => isReactiveRef(r) && isScopeSerializable(r.value))
|
|
44
|
-
.forEach(([key, ref]) => {
|
|
45
|
-
watchEffect(() => {
|
|
46
|
-
if (state[key] !== ref.value) {
|
|
47
|
-
state[key] = ref.value
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
return refs
|
|
53
|
-
}
|
|
31
|
+
throw new Error('vuePersistantCompoent is for components using the Options API. To use the composition API see https://docs.knowlearning.systems/frameworks/vue/')
|
|
54
32
|
}
|
|
55
33
|
}
|
|
56
34
|
|