@agentshouse/mdruntime-adapter 0.1.0-cd23c45caa798 → 0.1.0-cd36fe2bc9d48
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.md +72 -59
- package/dist/actions.d.ts +1 -16
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +20 -49
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +120 -130
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/part.d.ts +3 -1
- package/dist/part.d.ts.map +1 -1
- package/dist/part.js +10 -5
- package/dist/read.d.ts +22 -7
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +106 -62
- package/dist/room-types.d.ts +6 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +66 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +39 -52
- package/dist/stream.d.ts +1 -0
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +16 -1
- package/dist/transport.d.ts +10 -10
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +1 -1
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +52 -0
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +13 -17
- package/package.json +2 -2
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -45
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -33
package/dist/read.js
CHANGED
|
@@ -13,6 +13,8 @@ export function answering() {
|
|
|
13
13
|
changes: new Map(),
|
|
14
14
|
binaryFiles: new Map(),
|
|
15
15
|
removals: new Set(),
|
|
16
|
+
folders: new Set(),
|
|
17
|
+
folderRemovals: new Set(),
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
export function revised(answer, path, revision) {
|
|
@@ -29,12 +31,26 @@ export function forgotten(answer, path) {
|
|
|
29
31
|
answer.binaryFiles.delete(path);
|
|
30
32
|
answer.removals.delete(path);
|
|
31
33
|
}
|
|
32
|
-
export function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
export function folded(answer, path, removed) {
|
|
35
|
+
if (removed) {
|
|
36
|
+
answer.folders.delete(path);
|
|
37
|
+
answer.folderRemovals.add(path);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
answer.folderRemovals.delete(path);
|
|
41
|
+
answer.folders.add(path);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function* pathsOf(paths) {
|
|
45
|
+
const list = [];
|
|
46
|
+
for (const path of paths) {
|
|
47
|
+
list.push(path);
|
|
36
48
|
yield ROW_WEIGHT;
|
|
37
49
|
}
|
|
50
|
+
return list;
|
|
51
|
+
}
|
|
52
|
+
export function* answered(answer) {
|
|
53
|
+
const removals = yield* pathsOf(answer.removals);
|
|
38
54
|
return {
|
|
39
55
|
documents: yield* patching({}, answer.documents),
|
|
40
56
|
revisions: yield* patching({}, answer.revisions),
|
|
@@ -42,6 +58,10 @@ export function* answered(answer) {
|
|
|
42
58
|
changes: yield* patching({}, answer.changes),
|
|
43
59
|
binaryFiles: yield* patching({}, answer.binaryFiles),
|
|
44
60
|
removals,
|
|
61
|
+
...(answer.folders.size === 0 ? {} : { folders: yield* pathsOf(answer.folders) }),
|
|
62
|
+
...(answer.folderRemovals.size === 0
|
|
63
|
+
? {}
|
|
64
|
+
: { folderRemovals: yield* pathsOf(answer.folderRemovals) }),
|
|
45
65
|
};
|
|
46
66
|
}
|
|
47
67
|
export function authorityRoot(handle) {
|
|
@@ -59,22 +79,37 @@ export function parseGrant(body) {
|
|
|
59
79
|
const transfer = body.transfer;
|
|
60
80
|
if (typeof transfer.url !== 'string')
|
|
61
81
|
return null;
|
|
62
|
-
if (transfer.method === 'GET')
|
|
63
|
-
return { method: 'GET', url: transfer.url };
|
|
64
82
|
if (transfer.method !== 'POST' || typeof transfer.operation !== 'string')
|
|
65
83
|
return null;
|
|
66
|
-
return {
|
|
84
|
+
return { operation: transfer.operation, url: transfer.url };
|
|
85
|
+
}
|
|
86
|
+
export function parseFileAddress(body) {
|
|
87
|
+
if (typeof body !== 'object' || body === null)
|
|
88
|
+
return null;
|
|
89
|
+
const { download, name, sha256, media_type: mediaType } = body;
|
|
90
|
+
if (typeof download !== 'string' ||
|
|
91
|
+
typeof name !== 'string' ||
|
|
92
|
+
typeof sha256 !== 'string' ||
|
|
93
|
+
typeof mediaType !== 'string') {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return { url: download, name, sha256, mediaType };
|
|
67
97
|
}
|
|
68
98
|
function changeAuthor(value) {
|
|
69
99
|
if (typeof value !== 'object' || value === null)
|
|
70
100
|
return null;
|
|
71
|
-
const { user, site, name } = value;
|
|
101
|
+
const { user, site, inbox, name } = value;
|
|
72
102
|
if (typeof name !== 'string')
|
|
73
103
|
return null;
|
|
74
|
-
|
|
104
|
+
const named = [user, site, inbox].filter((id) => id !== undefined);
|
|
105
|
+
if (named.length !== 1)
|
|
106
|
+
return null;
|
|
107
|
+
if (typeof user === 'string')
|
|
75
108
|
return { kind: 'user', id: user, name };
|
|
76
|
-
if (typeof site === 'string'
|
|
109
|
+
if (typeof site === 'string')
|
|
77
110
|
return { kind: 'site', id: site, name };
|
|
111
|
+
if (typeof inbox === 'string')
|
|
112
|
+
return { kind: 'inbox', id: inbox, name };
|
|
78
113
|
return null;
|
|
79
114
|
}
|
|
80
115
|
export function headChange(held) {
|
|
@@ -91,15 +126,12 @@ function headed(head) {
|
|
|
91
126
|
return head === undefined ? {} : { head };
|
|
92
127
|
}
|
|
93
128
|
export function binaryFileOf(held) {
|
|
94
|
-
if (held.
|
|
129
|
+
if (held.media_type === undefined)
|
|
95
130
|
return undefined;
|
|
96
|
-
const {
|
|
97
|
-
if (typeof
|
|
98
|
-
typeof bytes !== 'number' ||
|
|
99
|
-
typeof mediaType !== 'string' ||
|
|
100
|
-
typeof sha256 !== 'string')
|
|
131
|
+
const { bytes, media_type: mediaType, sha256 } = held;
|
|
132
|
+
if (typeof bytes !== 'number' || typeof mediaType !== 'string' || typeof sha256 !== 'string')
|
|
101
133
|
return null;
|
|
102
|
-
return {
|
|
134
|
+
return { byteLength: bytes, mediaType, sha256 };
|
|
103
135
|
}
|
|
104
136
|
function binaried(binary) {
|
|
105
137
|
return binary === undefined ? {} : { binary };
|
|
@@ -183,6 +215,24 @@ export function parseParted(body) {
|
|
|
183
215
|
export function parseSiteParted(body) {
|
|
184
216
|
return parseRoomParts(body);
|
|
185
217
|
}
|
|
218
|
+
export function partInventory(room) {
|
|
219
|
+
return {
|
|
220
|
+
parts: room.parts.length,
|
|
221
|
+
bytes: room.parts.reduce((sum, part) => sum + part.bytes, 0),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
export function manifested(room, inventory, pageToken) {
|
|
225
|
+
return {
|
|
226
|
+
kind: 'bootstrap',
|
|
227
|
+
roomVersion: roomVersion(room),
|
|
228
|
+
documents: {},
|
|
229
|
+
revisions: {},
|
|
230
|
+
changes: {},
|
|
231
|
+
binaryFiles: {},
|
|
232
|
+
inventory,
|
|
233
|
+
pageToken,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
186
236
|
export function emptyScope(room) {
|
|
187
237
|
return {
|
|
188
238
|
anchor: room.anchor,
|
|
@@ -195,6 +245,7 @@ export function emptyScope(room) {
|
|
|
195
245
|
function* partLines(text, mode) {
|
|
196
246
|
const files = [];
|
|
197
247
|
const contents = [];
|
|
248
|
+
const folders = [];
|
|
198
249
|
let start = 0;
|
|
199
250
|
while (start < text.length) {
|
|
200
251
|
const end = text.indexOf('\n', start);
|
|
@@ -208,8 +259,11 @@ function* partLines(text, mode) {
|
|
|
208
259
|
return null;
|
|
209
260
|
}
|
|
210
261
|
start = end + 1;
|
|
211
|
-
if (folderLine(entry))
|
|
262
|
+
if (folderLine(entry)) {
|
|
263
|
+
folders.push(entry.folder);
|
|
264
|
+
yield ROW_WEIGHT;
|
|
212
265
|
continue;
|
|
266
|
+
}
|
|
213
267
|
const file = parseFile(entry, mode);
|
|
214
268
|
if (file === null)
|
|
215
269
|
return null;
|
|
@@ -221,21 +275,32 @@ function* partLines(text, mode) {
|
|
|
221
275
|
return null;
|
|
222
276
|
yield ROW_WEIGHT;
|
|
223
277
|
}
|
|
224
|
-
return { files, contents };
|
|
278
|
+
return { files, contents, folders };
|
|
225
279
|
}
|
|
226
280
|
function folderLine(entry) {
|
|
227
281
|
if (typeof entry !== 'object' || entry === null || !('folder' in entry))
|
|
228
282
|
return false;
|
|
229
283
|
return typeof entry.folder === 'string' && Object.keys(entry).length === 1;
|
|
230
284
|
}
|
|
231
|
-
export async function housePart(room,
|
|
232
|
-
const payload = await checkedPayload(
|
|
285
|
+
export async function housePart(room, frame, listed, mode) {
|
|
286
|
+
const payload = await checkedPayload(frame, listed);
|
|
233
287
|
if (payload === null)
|
|
234
288
|
return null;
|
|
235
289
|
const text = await gunzipped(payload);
|
|
236
290
|
const read = text === null ? null : await stepped(partLines(text, mode));
|
|
237
291
|
return read === null ? { kind: 'transport-uncertainty' } : { ...emptyScope(room), ...read };
|
|
238
292
|
}
|
|
293
|
+
function folderChange(value) {
|
|
294
|
+
if (typeof value !== 'object' || value === null)
|
|
295
|
+
return null;
|
|
296
|
+
const { path, folder, removed, ...rest } = value;
|
|
297
|
+
return typeof path === 'string' &&
|
|
298
|
+
folder === true &&
|
|
299
|
+
(removed === undefined || removed === true) &&
|
|
300
|
+
Object.keys(rest).length === 0
|
|
301
|
+
? { path, removed: removed === true }
|
|
302
|
+
: null;
|
|
303
|
+
}
|
|
239
304
|
function parseChange(value, mode) {
|
|
240
305
|
if (typeof value !== 'object' || value === null)
|
|
241
306
|
return null;
|
|
@@ -292,7 +357,13 @@ export function parseEnumeration(body, mode) {
|
|
|
292
357
|
if (!Array.isArray(held.changes))
|
|
293
358
|
return null;
|
|
294
359
|
const changes = [];
|
|
360
|
+
const folders = [];
|
|
295
361
|
for (const change of held.changes) {
|
|
362
|
+
const folder = folderChange(change);
|
|
363
|
+
if (folder !== null) {
|
|
364
|
+
folders.push(folder);
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
296
367
|
const mapped = parseChange(change, mode);
|
|
297
368
|
if (mapped === null)
|
|
298
369
|
return null;
|
|
@@ -305,6 +376,7 @@ export function parseEnumeration(body, mode) {
|
|
|
305
376
|
authority: held.authority,
|
|
306
377
|
...at,
|
|
307
378
|
changes,
|
|
379
|
+
...(folders.length === 0 ? {} : { folders }),
|
|
308
380
|
...(next === undefined ? {} : { next }),
|
|
309
381
|
});
|
|
310
382
|
}
|
|
@@ -328,6 +400,7 @@ function advances(asked, next) {
|
|
|
328
400
|
}
|
|
329
401
|
export async function wholeView(first, more) {
|
|
330
402
|
const changes = new Map(first.changes.map((change) => [change.path, change]));
|
|
403
|
+
const folders = new Map((first.folders ?? []).map((folder) => [folder.path, folder]));
|
|
331
404
|
let view = first;
|
|
332
405
|
while (view.next !== undefined) {
|
|
333
406
|
const asked = view.next;
|
|
@@ -343,6 +416,10 @@ export async function wholeView(first, more) {
|
|
|
343
416
|
changes.delete(change.path);
|
|
344
417
|
changes.set(change.path, change);
|
|
345
418
|
}
|
|
419
|
+
for (const folder of page.folders ?? []) {
|
|
420
|
+
folders.delete(folder.path);
|
|
421
|
+
folders.set(folder.path, folder);
|
|
422
|
+
}
|
|
346
423
|
view = page;
|
|
347
424
|
}
|
|
348
425
|
return {
|
|
@@ -350,46 +427,7 @@ export async function wholeView(first, more) {
|
|
|
350
427
|
position: view.position,
|
|
351
428
|
logEpoch: first.logEpoch,
|
|
352
429
|
changes: [...changes.values()],
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
export function* advancedScope(scope, view) {
|
|
356
|
-
const files = new Map();
|
|
357
|
-
for (const file of scope.files) {
|
|
358
|
-
files.set(file.path, file);
|
|
359
|
-
yield ROW_WEIGHT;
|
|
360
|
-
}
|
|
361
|
-
const contents = new Map();
|
|
362
|
-
for (const entry of scope.contents) {
|
|
363
|
-
contents.set(entry.path, entry.content);
|
|
364
|
-
yield ROW_WEIGHT;
|
|
365
|
-
}
|
|
366
|
-
for (const change of view.changes) {
|
|
367
|
-
files.delete(change.path);
|
|
368
|
-
contents.delete(change.path);
|
|
369
|
-
yield ROW_WEIGHT;
|
|
370
|
-
if ('removed' in change)
|
|
371
|
-
continue;
|
|
372
|
-
files.set(change.path, {
|
|
373
|
-
path: change.path,
|
|
374
|
-
revision: change.revision,
|
|
375
|
-
version: change.version,
|
|
376
|
-
...headed(change.head),
|
|
377
|
-
...('binary' in change ? { binary: change.binary } : {}),
|
|
378
|
-
});
|
|
379
|
-
if ('content' in change)
|
|
380
|
-
contents.set(change.path, change.content);
|
|
381
|
-
}
|
|
382
|
-
const listed = [];
|
|
383
|
-
for (const [path, content] of contents) {
|
|
384
|
-
listed.push({ path, content });
|
|
385
|
-
yield ROW_WEIGHT;
|
|
386
|
-
}
|
|
387
|
-
return {
|
|
388
|
-
...scope,
|
|
389
|
-
position: view.position,
|
|
390
|
-
logEpoch: view.logEpoch,
|
|
391
|
-
files: [...files.values()],
|
|
392
|
-
contents: listed,
|
|
430
|
+
...(folders.size === 0 ? {} : { folders: [...folders.values()] }),
|
|
393
431
|
};
|
|
394
432
|
}
|
|
395
433
|
export function* bootstrapping(scope) {
|
|
@@ -411,7 +449,9 @@ export function* bootstrapping(scope) {
|
|
|
411
449
|
if (file.revision !== undefined)
|
|
412
450
|
revised(answer, file.path, file.revision);
|
|
413
451
|
}
|
|
414
|
-
const
|
|
452
|
+
for (const folder of scope.folders ?? [])
|
|
453
|
+
folded(answer, folder, false);
|
|
454
|
+
const { removals: _removals, folderRemovals: _folderRemovals, ...page } = yield* answered(answer);
|
|
415
455
|
return { kind: 'bootstrap', roomVersion: roomVersion(scope), ...page };
|
|
416
456
|
}
|
|
417
457
|
export function schemaOf(scope, schema) {
|
|
@@ -445,6 +485,10 @@ function* refreshing(view, fromRoomVersion) {
|
|
|
445
485
|
if (change.revision !== undefined)
|
|
446
486
|
revised(answer, change.path, change.revision);
|
|
447
487
|
}
|
|
488
|
+
for (const folder of view.folders ?? []) {
|
|
489
|
+
yield ROW_WEIGHT;
|
|
490
|
+
folded(answer, folder.path, folder.removed);
|
|
491
|
+
}
|
|
448
492
|
return { kind: 'net-advancement', roomVersion: roomVersion(view), ...(yield* answered(answer)) };
|
|
449
493
|
}
|
|
450
494
|
export async function refreshFrom(view, fromRoomVersion) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const INBOX_CHANNEL_KINDS: readonly ['telegram-bot', 'whatsapp', 'messenger', 'instagram'];
|
|
2
|
+
export type InboxChannelKind = (typeof INBOX_CHANNEL_KINDS)[number];
|
|
3
|
+
export declare const INBOX_CHAT_TYPE = "inbox-chat";
|
|
4
|
+
export declare const INBOX_MESSAGE_TYPE = "inbox-message";
|
|
5
|
+
export declare const HOUSE_ROOM_TYPES: string;
|
|
6
|
+
//# sourceMappingURL=room-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"room-types.d.ts","sourceRoot":"","sources":["../src/room-types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,YAAI,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,CAAU,CAAC;AAEnG,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAalD,eAAO,MAAM,gBAAgB,QAsDjB,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const INBOX_CHANNEL_KINDS = ['telegram-bot', 'whatsapp', 'messenger', 'instagram'];
|
|
2
|
+
export const INBOX_CHAT_TYPE = 'inbox-chat';
|
|
3
|
+
export const INBOX_MESSAGE_TYPE = 'inbox-message';
|
|
4
|
+
const IDENTITY = "{ type: string, pattern: '^\\S+$' }";
|
|
5
|
+
const AGENT = [' agent: { type: string, format: uuid }', ' name: { type: string }'];
|
|
6
|
+
const ASSIGNEE = [
|
|
7
|
+
' type: object',
|
|
8
|
+
' properties:',
|
|
9
|
+
' user: { type: string, format: uuid }',
|
|
10
|
+
...AGENT,
|
|
11
|
+
];
|
|
12
|
+
export const HOUSE_ROOM_TYPES = [
|
|
13
|
+
`${INBOX_CHAT_TYPE}:`,
|
|
14
|
+
' properties:',
|
|
15
|
+
' inbox: { type: string, format: uuid }',
|
|
16
|
+
` channel: { enum: [${INBOX_CHANNEL_KINDS.join(', ')}] }`,
|
|
17
|
+
` chat: ${IDENTITY}`,
|
|
18
|
+
' customer:',
|
|
19
|
+
' type: object',
|
|
20
|
+
' properties:',
|
|
21
|
+
' name: { type: string }',
|
|
22
|
+
` username: ${IDENTITY}`,
|
|
23
|
+
` phone: ${IDENTITY}`,
|
|
24
|
+
' assignee:',
|
|
25
|
+
...ASSIGNEE,
|
|
26
|
+
' return_to:',
|
|
27
|
+
' type: object',
|
|
28
|
+
' properties:',
|
|
29
|
+
...AGENT,
|
|
30
|
+
' conversation: { type: string, format: uuid }',
|
|
31
|
+
' required: [inbox, channel, chat, customer]',
|
|
32
|
+
`${INBOX_MESSAGE_TYPE}:`,
|
|
33
|
+
' properties:',
|
|
34
|
+
' direction: { enum: [in, out] }',
|
|
35
|
+
' sender:',
|
|
36
|
+
' type: object',
|
|
37
|
+
' properties:',
|
|
38
|
+
' name: { type: string }',
|
|
39
|
+
` username: ${IDENTITY}`,
|
|
40
|
+
' sent_at: { type: string, format: date-time }',
|
|
41
|
+
` channel_message: ${IDENTITY}`,
|
|
42
|
+
' state: { enum: [sending, sent, failed] }',
|
|
43
|
+
' reason: { type: string }',
|
|
44
|
+
' reactions:',
|
|
45
|
+
' type: array',
|
|
46
|
+
' items:',
|
|
47
|
+
' type: object',
|
|
48
|
+
' properties:',
|
|
49
|
+
' reaction: { type: string, minLength: 1 }',
|
|
50
|
+
' sender:',
|
|
51
|
+
' type: object',
|
|
52
|
+
' properties:',
|
|
53
|
+
` id: ${IDENTITY}`,
|
|
54
|
+
' name: { type: string }',
|
|
55
|
+
` username: ${IDENTITY}`,
|
|
56
|
+
' count: { type: integer, minimum: 1 }',
|
|
57
|
+
' required: [reaction]',
|
|
58
|
+
` post: ${IDENTITY}`,
|
|
59
|
+
' assignee:',
|
|
60
|
+
...ASSIGNEE,
|
|
61
|
+
' sent_outside: { const: true }',
|
|
62
|
+
' required: [direction]',
|
|
63
|
+
' if: { properties: { direction: { const: in } } }',
|
|
64
|
+
' then: { required: [sent_at] }',
|
|
65
|
+
'',
|
|
66
|
+
].join('\n');
|
package/dist/site.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,
|
|
1
|
+
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAWR,MAAM,wBAAwB,CAAC;AA+BhC,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAoCxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAoP1F"}
|
package/dist/site.js
CHANGED
|
@@ -2,12 +2,12 @@ import { stepped } from '@agentshouse/mdruntime';
|
|
|
2
2
|
import { actionOutcome, SITE_SUBMIT } from './actions.js';
|
|
3
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
4
4
|
import { partModels, streamedModels, viewModels } from './model.js';
|
|
5
|
-
import {
|
|
6
|
-
import { PART_ATTEMPTS, unverifiedPart } from './part.js';
|
|
5
|
+
import { bootstrapping, emptyScope, housePart, manifested, parseEnumeration, parseSiteParted, partInventory, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
6
|
+
import { PART_ATTEMPTS, partArrival, partFrame, unverifiedPart } from './part.js';
|
|
7
7
|
import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
|
|
8
|
+
import { HOUSE_ROOM_TYPES } from './room-types.js';
|
|
8
9
|
import { houseNotifications } from './stream.js';
|
|
9
|
-
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT,
|
|
10
|
-
import { houseReferrer } from './referrer.js';
|
|
10
|
+
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILES, } from './transport.js';
|
|
11
11
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
12
12
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
13
13
|
function unfound() {
|
|
@@ -24,28 +24,15 @@ function siteRoom(tracked) {
|
|
|
24
24
|
providerOwnedPaths: [],
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
function settled(refused) {
|
|
28
|
-
return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
|
|
29
|
-
}
|
|
30
27
|
export function createSiteAdapter(transport, snapshot = false) {
|
|
31
28
|
const notifications = houseNotifications(transport, 'site');
|
|
32
29
|
const tracked = new Map();
|
|
33
30
|
const expired = new Map();
|
|
34
|
-
function published(referrer) {
|
|
35
|
-
const named = houseReferrer(referrer, tracked);
|
|
36
|
-
return named === null || !tracked.has(named.locator) ? null : named;
|
|
37
|
-
}
|
|
38
31
|
function fileRoute(request) {
|
|
39
|
-
const
|
|
40
|
-
if (
|
|
41
|
-
return { kind: '
|
|
42
|
-
}
|
|
43
|
-
if (request.fileRef === undefined)
|
|
44
|
-
return unfound();
|
|
45
|
-
const { room_ref, path, record } = named.referrer;
|
|
46
|
-
return `${SITE_FILES}${room_ref}/${encodeURIComponent(request.fileRef)}/${path === undefined
|
|
47
|
-
? `${SITE_FILE_RECORD}/${encodeURIComponent(record)}`
|
|
48
|
-
: encodeURIComponent(path)}`;
|
|
32
|
+
const entry = tracked.get(request.locator);
|
|
33
|
+
if (entry === undefined)
|
|
34
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
35
|
+
return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
|
|
49
36
|
}
|
|
50
37
|
async function enumerated(entry, from, page) {
|
|
51
38
|
const answer = await transport.door(SITE_DOOR_ENUMERATE, {
|
|
@@ -79,34 +66,29 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
79
66
|
const room = parseSiteParted(answer.body);
|
|
80
67
|
return room === null || room.anchor !== entry.authority ? UNCERTAIN : room;
|
|
81
68
|
}
|
|
82
|
-
async function fetchedPart(entry, room, listed) {
|
|
69
|
+
async function fetchedPart(entry, room, listed, received, arriving) {
|
|
70
|
+
if (received !== undefined) {
|
|
71
|
+
const kept = new Uint8Array(received);
|
|
72
|
+
const held = await housePart(room, kept, listed, 'site');
|
|
73
|
+
if (held !== null)
|
|
74
|
+
return 'kind' in held ? held : { scope: held, frame: kept };
|
|
75
|
+
}
|
|
83
76
|
for (let attempt = 0; attempt < PART_ATTEMPTS; attempt += 1) {
|
|
84
|
-
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}?part=${encodeURIComponent(listed.part)}
|
|
77
|
+
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}?part=${encodeURIComponent(listed.part)}`, partArrival(listed, arriving));
|
|
85
78
|
const failure = classifyRead(answer.status, answer.body, entry.locator);
|
|
86
79
|
if (failure?.kind === 'beyond-horizon')
|
|
87
80
|
expired.set(entry.locator, room.position);
|
|
88
81
|
if (failure !== null)
|
|
89
82
|
return failure;
|
|
90
|
-
const
|
|
83
|
+
const frame = partFrame(answer.body);
|
|
84
|
+
if (frame === null)
|
|
85
|
+
continue;
|
|
86
|
+
const scope = await housePart(room, frame, listed, 'site');
|
|
91
87
|
if (scope !== null)
|
|
92
|
-
return scope;
|
|
88
|
+
return 'kind' in scope ? scope : { scope, frame };
|
|
93
89
|
}
|
|
94
90
|
return unverifiedPart(entry.locator);
|
|
95
91
|
}
|
|
96
|
-
async function caughtUp(entry, continued) {
|
|
97
|
-
const listed = continued.room.parts[continued.next];
|
|
98
|
-
const scope = listed === undefined
|
|
99
|
-
? emptyScope(continued.room)
|
|
100
|
-
: await fetchedPart(entry, continued.room, listed);
|
|
101
|
-
if ('kind' in scope)
|
|
102
|
-
return scope;
|
|
103
|
-
if (continued.room.parts.length > 1 || roomVersion(scope) === roomVersion(entry))
|
|
104
|
-
return scope;
|
|
105
|
-
const view = await enumeration(entry, scope);
|
|
106
|
-
if ('kind' in view)
|
|
107
|
-
return settled(view);
|
|
108
|
-
return stepped(advancedScope(scope, view));
|
|
109
|
-
}
|
|
110
92
|
async function refreshed(entry, fromRoomVersion) {
|
|
111
93
|
const from = logPosition(fromRoomVersion);
|
|
112
94
|
if (from === null)
|
|
@@ -129,6 +111,7 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
129
111
|
return {
|
|
130
112
|
localSaves: true,
|
|
131
113
|
exhaustiveDiscovery: true,
|
|
114
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
132
115
|
async authorize() {
|
|
133
116
|
return {};
|
|
134
117
|
},
|
|
@@ -152,17 +135,25 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
152
135
|
if (entry === undefined)
|
|
153
136
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
154
137
|
let continued;
|
|
138
|
+
let inventory;
|
|
155
139
|
if (request.pageToken === undefined) {
|
|
156
140
|
const room = await partedRoom(entry);
|
|
157
141
|
if ('kind' in room)
|
|
158
142
|
return room;
|
|
159
143
|
continued = { room, next: 0, seen: [] };
|
|
144
|
+
inventory = partInventory(room);
|
|
145
|
+
if (inventory.parts > 0)
|
|
146
|
+
return manifested(room, inventory, JSON.stringify(continued));
|
|
160
147
|
}
|
|
161
148
|
else
|
|
162
149
|
continued = JSON.parse(request.pageToken);
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
150
|
+
const listed = continued.room.parts[continued.next];
|
|
151
|
+
const sent = listed === undefined
|
|
152
|
+
? { scope: emptyScope(continued.room), frame: null }
|
|
153
|
+
: await fetchedPart(entry, continued.room, listed, request.received, request.arriving);
|
|
154
|
+
if ('kind' in sent)
|
|
155
|
+
return sent;
|
|
156
|
+
const { scope } = sent;
|
|
166
157
|
notifications.reach(entry.authority, scope);
|
|
167
158
|
const next = continued.next + 1;
|
|
168
159
|
const more = next < continued.room.parts.length;
|
|
@@ -171,10 +162,13 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
171
162
|
...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
|
|
172
163
|
];
|
|
173
164
|
const models = await partModels(scope, entry, new Set(seen), !more);
|
|
165
|
+
const { folders: _folders, ...page } = await stepped(bootstrapping(scope));
|
|
174
166
|
return {
|
|
175
|
-
...
|
|
167
|
+
...page,
|
|
176
168
|
...(models === undefined ? {} : { models }),
|
|
177
169
|
...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
|
|
170
|
+
...(inventory === undefined ? {} : { inventory }),
|
|
171
|
+
...(sent.frame === null ? {} : { received: sent.frame }),
|
|
178
172
|
};
|
|
179
173
|
},
|
|
180
174
|
async refresh(_authorization, request) {
|
|
@@ -203,8 +197,8 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
203
197
|
const read = await transport.download(route);
|
|
204
198
|
if (read.status === 404)
|
|
205
199
|
return unfound();
|
|
206
|
-
return read.status === 200 && read.
|
|
207
|
-
? { kind: 'binary',
|
|
200
|
+
return read.status === 200 && read.body !== null
|
|
201
|
+
? { kind: 'binary', body: read.body, mediaType: read.mediaType }
|
|
208
202
|
: UNCERTAIN;
|
|
209
203
|
},
|
|
210
204
|
async link(_authorization, request) {
|
|
@@ -217,13 +211,6 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
217
211
|
name: request.path.slice(request.path.lastIndexOf('/') + 1),
|
|
218
212
|
};
|
|
219
213
|
},
|
|
220
|
-
referrerScope(referrer) {
|
|
221
|
-
const named = published(referrer);
|
|
222
|
-
if (named === null)
|
|
223
|
-
return null;
|
|
224
|
-
const { path } = named.referrer;
|
|
225
|
-
return { locator: named.locator, ...(path === undefined ? {} : { path }) };
|
|
226
|
-
},
|
|
227
214
|
reached(locator, version, target) {
|
|
228
215
|
return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
|
|
229
216
|
},
|
package/dist/stream.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type HouseNotifications = {
|
|
|
15
15
|
reopen(): void;
|
|
16
16
|
track(authorities: readonly TrackedAuthority[]): void;
|
|
17
17
|
reach(authority: string, at: LogPosition): void;
|
|
18
|
+
edited(tracked: TrackedAuthority, from: LogPosition): readonly string[];
|
|
18
19
|
advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
|
|
19
20
|
conversations: ConversationStream;
|
|
20
21
|
serviceMode: ServiceModeSignal;
|
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAUvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AA0C7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IACxF,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAClD,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAAC;IACxE,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAmFF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA8jB5F"}
|
package/dist/stream.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ROW_WEIGHT, } from '@agentshouse/mdruntime';
|
|
2
2
|
import { acceptedMessage } from './actions.js';
|
|
3
3
|
import { sha256Hex } from './digest.js';
|
|
4
|
-
import { answered, answering, binaryFileOf, forgotten, headChange, revised } from './read.js';
|
|
4
|
+
import { answered, answering, binaryFileOf, folded, forgotten, headChange, revised, } from './read.js';
|
|
5
5
|
import { roomVersion } from './version.js';
|
|
6
6
|
const HELD_FRAMES_MAX = 256;
|
|
7
7
|
function turnOperation(frame) {
|
|
@@ -556,6 +556,17 @@ export function houseNotifications(transport, mode) {
|
|
|
556
556
|
held,
|
|
557
557
|
});
|
|
558
558
|
},
|
|
559
|
+
edited(tracked, from) {
|
|
560
|
+
const line = lines.get(tracked.authority);
|
|
561
|
+
const start = position(from.position);
|
|
562
|
+
if (line === undefined || start === null || line.logEpoch !== from.logEpoch)
|
|
563
|
+
return [];
|
|
564
|
+
return [
|
|
565
|
+
...new Set(line.frames
|
|
566
|
+
.filter((frame) => frame.position > start)
|
|
567
|
+
.flatMap((frame) => frame.entries.flatMap((entry) => entry.kind === 'edited' && entry.revision !== undefined ? [entry.path] : []))),
|
|
568
|
+
];
|
|
569
|
+
},
|
|
559
570
|
*advance(tracked, from, holds) {
|
|
560
571
|
const line = lines.get(tracked.authority);
|
|
561
572
|
const start = position(from.position);
|
|
@@ -570,6 +581,10 @@ export function houseNotifications(transport, mode) {
|
|
|
570
581
|
for (const frame of pending) {
|
|
571
582
|
for (const entry of frame.entries) {
|
|
572
583
|
yield ROW_WEIGHT + (entry.text?.length ?? 0);
|
|
584
|
+
if (entry.kind === 'folder') {
|
|
585
|
+
folded(answer, entry.path, entry.removed === true);
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
573
588
|
if (entry.kind === 'edited' &&
|
|
574
589
|
entry.revision !== undefined &&
|
|
575
590
|
holds?.(entry.path, entry.revision) === true) {
|
package/dist/transport.d.ts
CHANGED
|
@@ -15,27 +15,26 @@ export type HouseDoorAnswer = {
|
|
|
15
15
|
body: unknown;
|
|
16
16
|
};
|
|
17
17
|
export declare const DOOR_FILES_GET = "/door/files/get";
|
|
18
|
+
export declare const DOOR_FILES_FINISH = "/door/files/finish";
|
|
18
19
|
export declare const SITE_FILES = "/_house/files/";
|
|
19
|
-
export
|
|
20
|
-
export type HouseByteAct = 'authored_batch_upload' | 'file_upload' | 'binary_stage';
|
|
21
|
-
export type HouseByteBody = string | ArrayBuffer | Uint8Array | Blob;
|
|
20
|
+
export type HouseByteAct = 'authored_batch_upload';
|
|
22
21
|
export type HouseBytesAnswer = {
|
|
23
22
|
status: number;
|
|
24
|
-
|
|
23
|
+
body: ReadableStream<Uint8Array> | null;
|
|
24
|
+
mediaType: string;
|
|
25
25
|
};
|
|
26
26
|
export type HouseByteTransfer = {
|
|
27
27
|
act: HouseByteAct;
|
|
28
28
|
url: string;
|
|
29
|
-
body:
|
|
30
|
-
operation?: string;
|
|
29
|
+
body: string;
|
|
31
30
|
};
|
|
32
31
|
export type HouseStreamEntry = {
|
|
33
32
|
path: string;
|
|
34
|
-
kind: 'edited' | 'removed' | 'piece';
|
|
33
|
+
kind: 'edited' | 'removed' | 'piece' | 'folder';
|
|
34
|
+
removed?: true;
|
|
35
35
|
revision?: string;
|
|
36
36
|
sha256?: string;
|
|
37
37
|
text?: string;
|
|
38
|
-
file?: string;
|
|
39
38
|
bytes?: number;
|
|
40
39
|
media_type?: string;
|
|
41
40
|
author?: {
|
|
@@ -165,16 +164,17 @@ export type HouseStream = {
|
|
|
165
164
|
closed(notify: (closing: HouseClosing) => void): () => void;
|
|
166
165
|
};
|
|
167
166
|
export type HouseDoor = {
|
|
168
|
-
door(route: string, body: unknown): Promise<HouseDoorAnswer>;
|
|
167
|
+
door(route: string, body: unknown, arriving?: (bytes: number) => void): Promise<HouseDoorAnswer>;
|
|
169
168
|
stream: HouseStream;
|
|
170
169
|
};
|
|
171
170
|
export type HouseTransport = HouseDoor & {
|
|
172
171
|
transfer(request: HouseByteTransfer): Promise<HouseDoorAnswer>;
|
|
172
|
+
put(url: string, body: Blob): Promise<number>;
|
|
173
173
|
download(url: string): Promise<HouseBytesAnswer>;
|
|
174
174
|
};
|
|
175
175
|
export type HouseSiteTransport = HouseDoor & {
|
|
176
176
|
online(): boolean;
|
|
177
|
-
read(route: string): Promise<HouseDoorAnswer>;
|
|
177
|
+
read(route: string, arriving?: (bytes: number) => void): Promise<HouseDoorAnswer>;
|
|
178
178
|
download(route: string): Promise<HouseBytesAnswer>;
|
|
179
179
|
};
|
|
180
180
|
export {};
|