@knowlearning/agents 0.9.179 → 0.9.181
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.
|
@@ -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) =>
|
|
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(
|
|
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
|
|
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.
|
|
182
|
+
console.warn('Unknown message type passed up...', message)
|
|
168
183
|
sendDown({})
|
|
169
184
|
}
|
|
170
185
|
}
|
package/agents/browser/root.js
CHANGED
|
@@ -2,19 +2,22 @@ import { v1 as uuid } from 'uuid'
|
|
|
2
2
|
import { applyPatch } from 'fast-json-patch'
|
|
3
3
|
import { getToken, login, logout } from './auth.js'
|
|
4
4
|
import GenericAgent from '../generic/index.js'
|
|
5
|
+
import { io } from 'socket.io-client'
|
|
5
6
|
|
|
6
7
|
const TEST_DOMAIN = 'tests.knowlearning.systems'
|
|
7
8
|
const LANGUAGES = [...navigator.languages]
|
|
8
9
|
|
|
9
10
|
const API_HOST = localStorage.getItem('API_HOST') || 'api.knowlearning.systems'
|
|
10
|
-
//
|
|
11
|
-
//const API_HOST = 'localhost:8765'
|
|
11
|
+
// const API_HOST = 'api-test.knowlearning.systems'
|
|
12
|
+
// const API_HOST = 'localhost:8765'
|
|
12
13
|
|
|
13
|
-
//
|
|
14
|
-
// deno is partly in the way on teh set side, and browser support is in the way for
|
|
15
|
-
// the client side.
|
|
14
|
+
// TODO: remove sid hack when partitioned cookies via WS handshakes are supported
|
|
16
15
|
async function ensureSidEstablished() {
|
|
17
|
-
const response = await fetch(`https://${API_HOST}/_sid-check`, {
|
|
16
|
+
const response = await fetch(`https://${API_HOST}/_sid-check`, {
|
|
17
|
+
method: 'GET',
|
|
18
|
+
credentials: 'include'
|
|
19
|
+
})
|
|
20
|
+
|
|
18
21
|
const hasLocalStorageSID = !!localStorage.getItem('sid')
|
|
19
22
|
if (response.status === 201) {
|
|
20
23
|
if (!hasLocalStorageSID) {
|
|
@@ -24,7 +27,6 @@ async function ensureSidEstablished() {
|
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
else if (response.status === 200) {
|
|
27
|
-
// if we reach here, assumably the server has seen an sid cookie
|
|
28
30
|
if (hasLocalStorageSID) {
|
|
29
31
|
localStorage.removeItem('sid')
|
|
30
32
|
location.reload()
|
|
@@ -37,20 +39,44 @@ async function ensureSidEstablished() {
|
|
|
37
39
|
|
|
38
40
|
export default options => {
|
|
39
41
|
ensureSidEstablished()
|
|
42
|
+
|
|
40
43
|
const Connection = function () {
|
|
44
|
+
const sid = localStorage.getItem('sid')
|
|
45
|
+
|
|
46
|
+
// socket.io client connection
|
|
47
|
+
const socket = io(`https://${API_HOST}`, {
|
|
48
|
+
withCredentials: true,
|
|
49
|
+
extraHeaders: sid ? { sid } : {}
|
|
50
|
+
})
|
|
41
51
|
|
|
42
|
-
|
|
52
|
+
this.send = message => {
|
|
53
|
+
try {
|
|
54
|
+
socket.emit('message', message)
|
|
55
|
+
} catch (err) {
|
|
56
|
+
console.warn('Error sending via socket.io', err)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
43
59
|
|
|
44
|
-
this.send = message => ws.send(JSON.stringify(message))
|
|
45
60
|
this.close = info => {
|
|
46
61
|
this.send({ type: 'close', info })
|
|
47
|
-
|
|
62
|
+
socket.disconnect()
|
|
48
63
|
}
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
socket.on('connect', () => {
|
|
66
|
+
if (this.onopen) this.onopen()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
socket.on('message', (data) => {
|
|
70
|
+
if (this.onmessage) this.onmessage(data)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
socket.on('error', (err) => {
|
|
74
|
+
if (this.onerror) this.onerror(err)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
socket.on('disconnect', (reason) => {
|
|
78
|
+
if (this.onclose) this.onclose(reason)
|
|
79
|
+
})
|
|
54
80
|
|
|
55
81
|
return this
|
|
56
82
|
}
|
package/agents/embedded.js
CHANGED
|
@@ -12,8 +12,10 @@ export default function EmbeddedAgent(postMessage) {
|
|
|
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 {
|
|
@@ -202,6 +204,8 @@ export default function EmbeddedAgent(postMessage) {
|
|
|
202
204
|
function reconnect() { return send({ type: 'reconnect' }) }
|
|
203
205
|
function synced() { return send({ type: 'synced' }) }
|
|
204
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 }) }
|
|
205
209
|
|
|
206
210
|
return {
|
|
207
211
|
embedded: true,
|
|
@@ -222,6 +226,7 @@ export default function EmbeddedAgent(postMessage) {
|
|
|
222
226
|
reconnect,
|
|
223
227
|
synced,
|
|
224
228
|
close,
|
|
229
|
+
response,
|
|
225
230
|
query
|
|
226
231
|
}
|
|
227
232
|
}
|
package/agents/generic/index.js
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
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() {
|
|
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/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knowlearning/agents",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.181",
|
|
4
4
|
"description": "API for embedding applications in KnowLearning systems.",
|
|
5
5
|
"main": "node.js",
|
|
6
6
|
"browser": "browser.js",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"types": "types.d.ts",
|
|
8
9
|
"directories": {
|
|
9
10
|
"example": "examples",
|
|
10
11
|
"test": "test"
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@knowlearning/patch-proxy": "^1.3.4",
|
|
27
28
|
"fast-json-patch": "^3.1.1",
|
|
29
|
+
"socket.io-client": "^4.8.1",
|
|
28
30
|
"uuid": "^8.3.2"
|
|
29
31
|
},
|
|
30
32
|
"devDependencies": {
|
|
@@ -19,12 +19,12 @@ export interface AgentEnvironment {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export interface AgentUploadInfo {
|
|
22
|
-
name?: string
|
|
23
|
-
type?: string
|
|
24
|
-
data?: string | ArrayBuffer
|
|
25
|
-
id?: string
|
|
26
|
-
browser?: boolean
|
|
27
|
-
accept?: string
|
|
22
|
+
name?: string;
|
|
23
|
+
type?: string;
|
|
24
|
+
data?: string | ArrayBuffer;
|
|
25
|
+
id?: string;
|
|
26
|
+
browser?: boolean;
|
|
27
|
+
accept?: string;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export interface Agent {
|
|
@@ -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
|
|