@knowlearning/agents 0.9.83 → 0.9.85
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.
- package/agents/browser/root.js +1 -1
- package/agents/generic/index.js +15 -3
- package/agents/generic/message-queue.js +8 -5
- package/deno.js +34 -2
- package/package.json +1 -1
package/agents/browser/root.js
CHANGED
|
@@ -18,7 +18,7 @@ export default options => {
|
|
|
18
18
|
this.close = () => ws.close()
|
|
19
19
|
|
|
20
20
|
ws.onopen = () => this.onopen()
|
|
21
|
-
ws.onmessage = ({ data }) => this.onmessage(data)
|
|
21
|
+
ws.onmessage = ({ data }) => this.onmessage(data.length === 0 ? null : JSON.parse(data))
|
|
22
22
|
ws.onerror = error => this.onerror && this.onerror(error)
|
|
23
23
|
ws.onclose = error => this.onclose && this.onclose(error)
|
|
24
24
|
|
package/agents/generic/index.js
CHANGED
|
@@ -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({ Connection, token, uuid, fetch, applyPatch, login, logout, reboot }) {
|
|
16
|
+
export default function Agent({ Connection, token, uuid, fetch, applyPatch, login, logout, reboot, handleDomainInteraction }) {
|
|
17
17
|
const states = {}
|
|
18
18
|
const watchers = {}
|
|
19
19
|
const keyToSubscriptionId = {}
|
|
@@ -29,7 +29,7 @@ export default function Agent({ Connection, token, uuid, fetch, applyPatch, logi
|
|
|
29
29
|
reconnect,
|
|
30
30
|
synced,
|
|
31
31
|
environment
|
|
32
|
-
] = messageQueue({ token, Connection, watchers, states, applyPatch, log, login, interact, reboot })
|
|
32
|
+
] = messageQueue({ token, Connection, watchers, states, applyPatch, log, login, interact, reboot, trigger })
|
|
33
33
|
|
|
34
34
|
// initialize session
|
|
35
35
|
environment()
|
|
@@ -216,6 +216,17 @@ export default function Agent({ Connection, token, uuid, fetch, applyPatch, logi
|
|
|
216
216
|
})
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
const reactions = { child: [] }
|
|
220
|
+
|
|
221
|
+
function on(event, reaction) {
|
|
222
|
+
if (!reactions[event]) throw new Error('Agent can only listen to events of "child"')
|
|
223
|
+
reactions[event].push(reaction)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function trigger(event, data) {
|
|
227
|
+
reactions[event].forEach(f => f(data))
|
|
228
|
+
}
|
|
229
|
+
|
|
219
230
|
return {
|
|
220
231
|
uuid,
|
|
221
232
|
environment,
|
|
@@ -235,6 +246,7 @@ export default function Agent({ Connection, token, uuid, fetch, applyPatch, logi
|
|
|
235
246
|
disconnect,
|
|
236
247
|
reconnect,
|
|
237
248
|
tag,
|
|
238
|
-
debug
|
|
249
|
+
debug,
|
|
250
|
+
on
|
|
239
251
|
}
|
|
240
252
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { validate as isUUID } from 'uuid'
|
|
2
2
|
|
|
3
3
|
const HEARTBEAT_TIMEOUT = 10000
|
|
4
|
+
const DOMAIN_MESSAGES = { open: true, mutate: true, close: true }
|
|
4
5
|
|
|
5
6
|
// transform our custom path implementation to the standard JSONPatch path
|
|
6
7
|
function standardJSONPatch(patch) {
|
|
@@ -14,7 +15,7 @@ function sanitizeJSONPatchPathSegment(s) {
|
|
|
14
15
|
else return s
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export default function messageQueue({ token, Connection, watchers, states, applyPatch, log, login, reboot }) {
|
|
18
|
+
export default function messageQueue({ token, Connection, watchers, states, applyPatch, log, login, reboot, handleDomainMessage, trigger }) {
|
|
18
19
|
let connection
|
|
19
20
|
let user
|
|
20
21
|
let authed = false
|
|
@@ -124,13 +125,12 @@ export default function messageQueue({ token, Connection, watchers, states, appl
|
|
|
124
125
|
connection.send({ token: await token(), session })
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
connection.onmessage = async
|
|
128
|
+
connection.onmessage = async message => {
|
|
128
129
|
checkHeartbeat()
|
|
129
|
-
if (
|
|
130
|
+
if (!message) return // heartbeat
|
|
130
131
|
|
|
131
132
|
try {
|
|
132
133
|
log('handling message', disconnected, authed)
|
|
133
|
-
const message = JSON.parse(data)
|
|
134
134
|
log('message', JSON.stringify(message))
|
|
135
135
|
|
|
136
136
|
if (message.error) console.warn('ERROR RESPONSE', message)
|
|
@@ -160,7 +160,10 @@ export default function messageQueue({ token, Connection, watchers, states, appl
|
|
|
160
160
|
flushMessageQueue()
|
|
161
161
|
}
|
|
162
162
|
else {
|
|
163
|
-
if (message.
|
|
163
|
+
if (DOMAIN_MESSAGES[message.type]) {
|
|
164
|
+
handleDomainMessage && handleDomainMessage(message, trigger)
|
|
165
|
+
}
|
|
166
|
+
else if (message.si !== undefined) {
|
|
164
167
|
if (responses[message.si]) {
|
|
165
168
|
// TODO: remove "acknowledged" messages from queue and do accounting with si
|
|
166
169
|
responses[message.si]
|
package/deno.js
CHANGED
|
@@ -18,11 +18,43 @@ function Connection() {
|
|
|
18
18
|
return thisConnection
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
const children = {}
|
|
22
|
+
const listeners = {}
|
|
23
|
+
|
|
24
|
+
const agent new Agent({
|
|
22
25
|
Connection,
|
|
23
26
|
token: () => AGENT_TOKEN,
|
|
24
27
|
uuid: () => crypto.randomUUID(),
|
|
25
28
|
fetch,
|
|
26
29
|
applyPatch: fastJSONPatch.applyPatch,
|
|
27
|
-
reboot: () => Deno.exit(1)
|
|
30
|
+
reboot: () => Deno.exit(1),
|
|
31
|
+
handleDomainMessage: ({ type, session, data }, trigger) => {
|
|
32
|
+
// this functionality is only implemented for the deno
|
|
33
|
+
// agent for now, but this central management of children
|
|
34
|
+
// concept probably has a place in the generic agent
|
|
35
|
+
if (type === 'open') {
|
|
36
|
+
const child = {
|
|
37
|
+
on: (eventType, reaction) => {
|
|
38
|
+
if (!listeners[session]) throw new Error('Error attaching listener, child is closed')
|
|
39
|
+
if (!listeners[session][eventType]) throw new Error('Only "mutate" and "close" events can be listened to with Agent.on')
|
|
40
|
+
listeners[session][eventType].push(reaction)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
listeners[session] = { mutate: [], close: [] }
|
|
44
|
+
children[session] = child
|
|
45
|
+
trigger('child', child)
|
|
46
|
+
}
|
|
47
|
+
else if (type === 'mutate') {
|
|
48
|
+
listeners[session].mutate.forEach(f => f(data))
|
|
49
|
+
delete listeners[session]
|
|
50
|
+
delete children[session]
|
|
51
|
+
}
|
|
52
|
+
else if (type === 'close') {
|
|
53
|
+
listeners[session].close.forEach(f => f(data))
|
|
54
|
+
delete listeners[session]
|
|
55
|
+
delete children[session]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
28
58
|
})
|
|
59
|
+
|
|
60
|
+
export default agent
|