@knowlearning/agents 0.9.28 → 0.9.30

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
- function removeWatcher(key, fn) {
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()
@@ -57,12 +54,15 @@ export default function EmbeddedAgent() {
57
54
  const u = !user || auth.user === user ? '' : user
58
55
  const key = isUUID(scope) ? scope : `${d}/${u}/${scope}`
59
56
  if (watchers[key]) {
60
- if (sentUpdates[key] + 1 === data.ii) {
57
+ if (sentUpdates[key] === undefined || sentUpdates[key] + 1 === data.ii) {
61
58
  sentUpdates[key] = data.ii
62
59
  watchers[key].forEach(fn => fn(data))
63
60
  }
64
- else if (data.ii !== sentUpdates[key]) {
65
- console.warn('Out of order or repeated update for', key, data.ii, sentUpdates[key])
61
+ else if (data.ii === sentUpdates[key]) {
62
+ console.warn('Repeated update for', key, data, sentUpdates[key])
63
+ }
64
+ else {
65
+ console.warn('Out of order update for', key, data, sentUpdates[key])
66
66
  }
67
67
  }
68
68
  }
@@ -96,28 +96,6 @@ export default function EmbeddedAgent() {
96
96
  await tag(tag_type, target)
97
97
  }
98
98
 
99
- function watch(scope, fn, user, domain) {
100
- tagIfNotYetTaggedInSession('subscribed', scope)
101
-
102
- const key = (
103
- environment()
104
- .then(async ({ auth, domain:rootDomain }) => {
105
- const d = !domain || domain === rootDomain ? '' : domain
106
- const u = !user || auth.user === user ? '' : user
107
- const key = isUUID(scope) ? scope : `${d}/${u}/${scope}`
108
-
109
- const state = await send({ type: 'state', scope, user, domain })
110
- const metadata = await send({ type: 'metadata', scope, user, domain })
111
- fn({ state, patch: null, ii: metadata.ii })
112
- sentUpdates[key] = metadata.ii
113
- if (!watchers[key]) watchers[key] = []
114
- watchers[key].push(fn)
115
- return key
116
- })
117
- )
118
- return async () => removeWatcher(await key, fn)
119
- }
120
-
121
99
  async function patch(root, scopes) {
122
100
  // TODO: consider watch function added to return to receive progress
123
101
  return send({ type: 'patch', root, scopes })
@@ -212,8 +190,8 @@ export default function EmbeddedAgent() {
212
190
  )
213
191
  }
214
192
 
215
- async function metadata(scope) {
216
- const md = await send({ type: 'metadata', scope })
193
+ async function metadata(scope, user, domain) {
194
+ const md = await send({ type: 'metadata', scope, user, domain })
217
195
  return new MutableProxy(md, patch => {
218
196
  const activePatch = structuredClone(patch)
219
197
  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
@@ -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 './watch.js'
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
- export default function({ metadata, state, watchers, synced }) {
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 () => removeWatcher(qualifiedScope, fn)
38
+ return () => {
39
+ removed = true
40
+ return removeWatcher(qualifiedScope, fn)
41
+ }
26
42
  }
27
43
 
28
44
  function watchResolution(path, callback, user, domain) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowlearning/agents",
3
- "version": "0.9.28",
3
+ "version": "0.9.30",
4
4
  "description": "API for embedding applications in KnowLearning systems.",
5
5
  "main": "node.js",
6
6
  "browser": "browser.js",