@knowlearning/agents 0.9.29 → 0.9.31
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.
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { validate as isUUID, v1 as uuid } from 'uuid'
|
|
2
|
+
import watchImplementation from '../watch.js'
|
|
2
3
|
import MutableProxy from '../../persistence/json.js'
|
|
3
4
|
|
|
4
5
|
export default function EmbeddedAgent() {
|
|
@@ -9,11 +10,7 @@ export default function EmbeddedAgent() {
|
|
|
9
10
|
const watchers = {}
|
|
10
11
|
const sentUpdates = {}
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
const watcherIndex = watchers[key].findIndex(x => x === fn)
|
|
14
|
-
if (watcherIndex > -1) watchers[key].splice(watcherIndex, 1)
|
|
15
|
-
else console.warn('TRIED TO REMOVE WATCHER THAT DOES NOT EXIST')
|
|
16
|
-
}
|
|
13
|
+
const [ watch, removeWatcher ] = watchImplementation({ metadata, state, watchers, synced, sentUpdates, environment })
|
|
17
14
|
|
|
18
15
|
async function send(message) {
|
|
19
16
|
const requestId = message.requestId || uuid()
|
|
@@ -56,13 +53,18 @@ export default function EmbeddedAgent() {
|
|
|
56
53
|
const d = !domain || domain === rootDomain ? '' : domain
|
|
57
54
|
const u = !user || auth.user === user ? '' : user
|
|
58
55
|
const key = isUUID(scope) ? scope : `${d}/${u}/${scope}`
|
|
56
|
+
|
|
57
|
+
const sendUpdate = () => {
|
|
58
|
+
sentUpdates[key] = data.ii
|
|
59
|
+
watchers[key].forEach(fn => fn(data))
|
|
60
|
+
}
|
|
61
|
+
|
|
59
62
|
if (watchers[key]) {
|
|
60
|
-
if (sentUpdates[key] + 1 === data.ii)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
console.warn('Out of order or repeated update for', key, data.ii, sentUpdates[key])
|
|
63
|
+
if (sentUpdates[key] === undefined || sentUpdates[key] + 1 === data.ii) sendUpdate()
|
|
64
|
+
else if (data.ii === sentUpdates[key]) console.warn('Repeated update for', key, data, sentUpdates[key])
|
|
65
|
+
else {
|
|
66
|
+
console.warn('Out of order update for', key, data, sentUpdates[key])
|
|
67
|
+
if (data.ii > sentUpdates[key]) sendUpdate()
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
}
|
|
@@ -96,37 +98,6 @@ export default function EmbeddedAgent() {
|
|
|
96
98
|
await tag(tag_type, target)
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
function watch(scope, fn, user, domain) {
|
|
100
|
-
let watchingPath = false
|
|
101
|
-
if (scope && scope.length === 1) {
|
|
102
|
-
watchingPath = true
|
|
103
|
-
scope = scope[0]
|
|
104
|
-
}
|
|
105
|
-
// TODO: actually allow watching at paths in embedded
|
|
106
|
-
|
|
107
|
-
tagIfNotYetTaggedInSession('subscribed', scope)
|
|
108
|
-
|
|
109
|
-
const wrappedFn = update => fn(watchingPath ? update.state : update)
|
|
110
|
-
|
|
111
|
-
const key = (
|
|
112
|
-
environment()
|
|
113
|
-
.then(async ({ auth, domain:rootDomain }) => {
|
|
114
|
-
const d = !domain || domain === rootDomain ? '' : domain
|
|
115
|
-
const u = !user || auth.user === user ? '' : user
|
|
116
|
-
const key = isUUID(scope) ? scope : `${d}/${u}/${scope}`
|
|
117
|
-
|
|
118
|
-
const state = await send({ type: 'state', scope, user, domain })
|
|
119
|
-
const metadata = await send({ type: 'metadata', scope, user, domain })
|
|
120
|
-
wrappedFn({ state, patch: null, ii: metadata.ii })
|
|
121
|
-
sentUpdates[key] = metadata.ii
|
|
122
|
-
if (!watchers[key]) watchers[key] = []
|
|
123
|
-
watchers[key].push(wrappedFn)
|
|
124
|
-
return key
|
|
125
|
-
})
|
|
126
|
-
)
|
|
127
|
-
return async () => removeWatcher(await key, wrappedFn)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
101
|
async function patch(root, scopes) {
|
|
131
102
|
// TODO: consider watch function added to return to receive progress
|
|
132
103
|
return send({ type: 'patch', root, scopes })
|
|
@@ -221,8 +192,8 @@ export default function EmbeddedAgent() {
|
|
|
221
192
|
)
|
|
222
193
|
}
|
|
223
194
|
|
|
224
|
-
async function metadata(scope) {
|
|
225
|
-
const md = await send({ type: 'metadata', scope })
|
|
195
|
+
async function metadata(scope, user, domain) {
|
|
196
|
+
const md = await send({ type: 'metadata', scope, user, domain })
|
|
226
197
|
return new MutableProxy(md, patch => {
|
|
227
198
|
const activePatch = structuredClone(patch)
|
|
228
199
|
activePatch.forEach(entry => {
|
|
@@ -72,8 +72,8 @@ function embed(environment, iframe) {
|
|
|
72
72
|
sendDown({}) // TODO: might want to send down the interaction index
|
|
73
73
|
}
|
|
74
74
|
else if (type === 'metadata') {
|
|
75
|
-
const { scope, user } = message
|
|
76
|
-
sendDown(await Agent.metadata(scope, user))
|
|
75
|
+
const { scope, user, domain } = message
|
|
76
|
+
sendDown(await Agent.metadata(scope, user, domain))
|
|
77
77
|
}
|
|
78
78
|
else if (type === 'tag') {
|
|
79
79
|
const { tag_type, target, context } = message
|
package/agents/generic/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { validate as isUUID } from 'uuid'
|
|
|
2
2
|
import MutableProxy from '../../persistence/json.js'
|
|
3
3
|
import messageQueue from './message-queue.js'
|
|
4
4
|
import stateImplementation from './state.js'
|
|
5
|
-
import watchImplementation from '
|
|
5
|
+
import watchImplementation from '../watch.js'
|
|
6
6
|
import downloadImplementation from '../download.js'
|
|
7
7
|
|
|
8
8
|
// TODO: consider using something better than name as mechanism
|
|
@@ -157,7 +157,7 @@ export default function Agent({ host, token, WebSocket, protocol='ws', uuid, fet
|
|
|
157
157
|
)
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
async function metadata(id=DEFAULT_SCOPE_NAME, user) {
|
|
160
|
+
async function metadata(id=DEFAULT_SCOPE_NAME, user, domain) {
|
|
161
161
|
const md = structuredClone(await state(id, user).metadata)
|
|
162
162
|
delete md.active
|
|
163
163
|
return new MutableProxy(md, patch => {
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import { validate as isUUID } from 'uuid'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const DEFAULT_SCOPE_NAME = '[]'
|
|
4
|
+
|
|
5
|
+
export default function({ metadata, environment, state, watchers, synced, sentUpdates }) {
|
|
4
6
|
|
|
5
7
|
function watch(scope=DEFAULT_SCOPE_NAME, fn, user, domain) {
|
|
6
8
|
if (Array.isArray(scope)) return watchResolution(scope, fn, user, domain)
|
|
7
9
|
|
|
8
10
|
const statePromise = state(scope, user, domain)
|
|
9
|
-
const qualifiedScope = isUUID(scope) ? scope : `${domain || ''}/${user || ''}/${scope}`
|
|
10
11
|
|
|
12
|
+
let qualifiedScope
|
|
13
|
+
let removed = false
|
|
11
14
|
metadata(scope, user, domain)
|
|
12
15
|
.then(async ({ ii }) => {
|
|
16
|
+
if (removed) return
|
|
17
|
+
|
|
18
|
+
const { auth: { user: u }, domain: d } = await environment()
|
|
19
|
+
qualifiedScope = isUUID(scope) ? scope : `${!domain || domain === d ? '' : domain}/${!user || user === u ? '' : user}/${scope}`
|
|
20
|
+
|
|
13
21
|
fn({
|
|
14
22
|
scope,
|
|
15
23
|
user,
|
|
@@ -18,11 +26,19 @@ export default function({ metadata, state, watchers, synced }) {
|
|
|
18
26
|
patch: null,
|
|
19
27
|
ii
|
|
20
28
|
})
|
|
29
|
+
|
|
30
|
+
if (sentUpdates) sentUpdates[qualifiedScope] = ii
|
|
31
|
+
|
|
32
|
+
if (removed) return
|
|
33
|
+
|
|
21
34
|
if (!watchers[qualifiedScope]) watchers[qualifiedScope] = []
|
|
22
35
|
watchers[qualifiedScope].push(fn)
|
|
23
36
|
})
|
|
24
37
|
|
|
25
|
-
return () =>
|
|
38
|
+
return () => {
|
|
39
|
+
removed = true
|
|
40
|
+
return removeWatcher(qualifiedScope, fn)
|
|
41
|
+
}
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
function watchResolution(path, callback, user, domain) {
|