@knowlearning/agents 0.9.178 → 0.9.180

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.
@@ -3,7 +3,7 @@ import EmbeddedAgent from '../embedded.js'
3
3
  export default () => {
4
4
  // default to window opener if present
5
5
  const parent = window.opener ? window.opener : window.parent
6
- const agent = EmbeddedAgent(parent)
6
+ const agent = EmbeddedAgent(message => parent.postMessage(message, '*'))
7
7
 
8
8
  return agent
9
9
  }
@@ -48,6 +48,7 @@ function embed(environment, iframe) {
48
48
  const watchers = {}
49
49
  const postMessageQueue = []
50
50
  const listeners = {}
51
+ const responses = {}
51
52
  let frameLoaded = false
52
53
  let embeddedAgentInitialized = false
53
54
 
@@ -70,7 +71,10 @@ function embed(environment, iframe) {
70
71
  const handleMessage = async message => {
71
72
  const { requestId, type } = message
72
73
 
73
- const sendDown = (response, error) => postMessage({ requestId, response, error })
74
+ const sendDown = (response, error) => {
75
+ if (responses[requestId]) responses[requestId](response, error)
76
+ postMessage({ requestId, response, error })
77
+ }
74
78
 
75
79
  if (type === 'error') {
76
80
  console.error(message)
@@ -103,7 +107,7 @@ function embed(environment, iframe) {
103
107
  const namespacedScope = getNamespacedScope(environment.namespace, scope)
104
108
  let before, after
105
109
  if (listeners.mutate) before = copy(await Agent.state(namespacedScope))
106
- await Agent.interact(namespacedScope, patch, true, [environment.id, ...context])
110
+ const response = await Agent.interact(namespacedScope, patch, true, [environment.id, ...context])
107
111
  if (listeners.mutate) {
108
112
  const patchCopy = copy(patch)
109
113
  patchCopy.forEach(op => op.path.shift()) // remove "active" path prefix
@@ -115,7 +119,7 @@ function embed(environment, iframe) {
115
119
  patch: patchCopy
116
120
  })
117
121
  }
118
- sendDown({}) // TODO: might want to send down the interaction index
122
+ sendDown(response)
119
123
  }
120
124
  else if (type === 'metadata') {
121
125
  const { scope, user, domain } = message
@@ -146,7 +150,7 @@ function embed(environment, iframe) {
146
150
  Agent
147
151
  .query(query, params, domain, [environment.id, ...context])
148
152
  .then(sendDown)
149
- .catch(error => sendDown(null, error.error))
153
+ .catch(error => sendDown(null, error))
150
154
  }
151
155
  else if (type === 'upload') {
152
156
  const { info } = message
@@ -163,8 +167,19 @@ function embed(environment, iframe) {
163
167
  else if (type === 'disconnect') sendDown(await Agent.disconnect())
164
168
  else if (type === 'reconnect') sendDown(await Agent.reconnect())
165
169
  else if (type === 'synced') sendDown(await Agent.synced())
170
+ else if (type === 'guarantee') {
171
+ const { script, namespaces=[], context=[] } = message
172
+ sendDown(await Agent.guarantee(script, [environment.namespace || '', ...namespaces], [environment.id, ...context]))
173
+ }
174
+ else if (type === 'response') {
175
+ const { id, requestId } = message
176
+ responses[id] = (response, error) => {
177
+ delete responses[id]
178
+ sendDown(response, error)
179
+ }
180
+ }
166
181
  else {
167
- console.log('Unknown message type passed up...', message)
182
+ console.warn('Unknown message type passed up...', message)
168
183
  sendDown({})
169
184
  }
170
185
  }
@@ -2,7 +2,7 @@ import { validate as isUUID, v1 as uuid } from 'uuid'
2
2
  import PatchProxy from '@knowlearning/patch-proxy'
3
3
  import watchImplementation from './watch.js'
4
4
 
5
- export default function EmbeddedAgent(parent) {
5
+ export default function EmbeddedAgent(postMessage) {
6
6
  let messageIndex = 0
7
7
  let resolveSession
8
8
  const session = new Promise(r => resolveSession = r)
@@ -12,18 +12,19 @@ export default function EmbeddedAgent(parent) {
12
12
 
13
13
  const [ watch, removeWatcher ] = watchImplementation({ metadata, state, watchers, synced, sentUpdates, environment })
14
14
 
15
+ let lastRequestId
16
+
15
17
  async function send(message) {
16
- const requestId = message.requestId || uuid()
18
+ const requestId = lastRequestId = message.requestId || uuid()
17
19
 
18
20
  messageIndex += 1
19
21
  try {
20
- parent
21
- .postMessage({
22
- ...message,
23
- session: await session,
24
- requestId,
25
- index: messageIndex
26
- }, '*')
22
+ postMessage({
23
+ ...message,
24
+ session: await session,
25
+ requestId,
26
+ index: messageIndex
27
+ })
27
28
  return new Promise((resolve, reject) => {
28
29
  responses[requestId] = { resolve, reject }
29
30
  })
@@ -203,6 +204,8 @@ export default function EmbeddedAgent(parent) {
203
204
  function reconnect() { return send({ type: 'reconnect' }) }
204
205
  function synced() { return send({ type: 'synced' }) }
205
206
  function close(info) { return send({ type: 'close', info }) }
207
+ function guarantee(script, namespaces, context) { return send({ type: 'guarantee', script, namespaces, context }) }
208
+ function response(id=lastRequestId) { return send({ type: 'response', id }) }
206
209
 
207
210
  return {
208
211
  embedded: true,
@@ -223,6 +226,7 @@ export default function EmbeddedAgent(parent) {
223
226
  reconnect,
224
227
  synced,
225
228
  close,
229
+ response,
226
230
  query
227
231
  }
228
232
  }
@@ -28,9 +28,10 @@ export default function Agent({ Connection, domain, token, sid, uuid, fetch, app
28
28
  ] = messageQueue({ token, sid, domain, Connection, watchers, states, applyPatch, log, login, interact, reboot, trigger, handleDomainMessage, variables })
29
29
 
30
30
  // initialize session
31
+ const initialSessionData = { queries: {}, subscriptions: {}, guarantees: {} }
31
32
  environment()
32
33
  .then(({ session }) => {
33
- interact('sessions', [{ op: 'add', path: ['active', session], value: { queries: {}, subscriptions: {} } }], false)
34
+ interact('sessions', [{ op: 'add', path: ['active', session], value: initialSessionData }], false)
34
35
  })
35
36
 
36
37
  const internalReferences = {
@@ -157,23 +158,10 @@ export default function Agent({ Connection, domain, token, sid, uuid, fetch, app
157
158
  ], false)
158
159
  try {
159
160
  const response = await lastMessageResponse()
160
- const { rows } = response
161
-
162
- interact('sessions', [
163
- {
164
- op: 'add',
165
- path: ['active', session, 'queries', id, 'agent_latency'],
166
- value: Date.now() - requested
167
- },
168
- {
169
- op: 'remove',
170
- path: ['active', session, 'queries', id]
171
- }
172
- ], false)
173
- return rows
161
+ return response.rows
174
162
  }
175
163
  catch (error) {
176
- throw error
164
+ throw error.error
177
165
  }
178
166
  }
179
167
 
@@ -188,6 +176,37 @@ export default function Agent({ Connection, domain, token, sid, uuid, fetch, app
188
176
  reactions[event].forEach(f => f(data))
189
177
  }
190
178
 
179
+ async function guarantee(script, namespaces=[], context=[]) {
180
+ const { session } = await environment()
181
+ const id = uuid()
182
+
183
+ interact('sessions', [
184
+ {
185
+ op: 'add',
186
+ path: ['active', session, 'guarantees', id],
187
+ value: { script, namespaces, context }
188
+ }
189
+ ], false)
190
+
191
+ return {
192
+ execute() {
193
+ // TODO: use simplified worker wrapper to execute script in restricted environment
194
+ },
195
+ cancel() {
196
+ interact('sessions', [
197
+ {
198
+ op: 'remove',
199
+ path: ['active', session, 'guarantees', id]
200
+ }
201
+ ], false)
202
+ }
203
+ }
204
+ }
205
+
206
+ function response() {
207
+ return lastMessageResponse()
208
+ }
209
+
191
210
  return {
192
211
  uuid,
193
212
  environment,
@@ -208,6 +227,8 @@ export default function Agent({ Connection, domain, token, sid, uuid, fetch, app
208
227
  disconnect,
209
228
  reconnect,
210
229
  debug,
230
+ guarantee,
231
+ response,
211
232
  on
212
233
  }
213
234
  }
@@ -227,7 +227,11 @@ export default function messageQueue({ token, sid, domain, Connection, watchers,
227
227
  return syncPromise
228
228
  }
229
229
 
230
- function lastMessageResponse() { return new Promise((res, rej) => responses[si].push([res, rej])) }
230
+ function lastMessageResponse() {
231
+ if (!responses[si]) throw new Error('A response must be requested before all outstanding responses have already returned')
232
+
233
+ return new Promise((res, rej) => responses[si].push([res, rej]))
234
+ }
231
235
 
232
236
  function disconnect() {
233
237
  log('DISCONNECTED AGENT!!!!!!!!!!!!!!!')
package/browser.d.ts CHANGED
@@ -39,6 +39,7 @@ export interface Agent {
39
39
  environment(userId?: string): Promise<AgentEnvironment>;
40
40
  close(): void;
41
41
  reset(ns: string): Promise<void>;
42
+ // TODO: add query function
42
43
  synced(): Promise<void>;
43
44
  }
44
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowlearning/agents",
3
- "version": "0.9.178",
3
+ "version": "0.9.180",
4
4
  "description": "API for embedding applications in KnowLearning systems.",
5
5
  "main": "node.js",
6
6
  "browser": "browser.js",