@agentshouse/mdruntime-adapter 0.1.0-cd0511bd2d033 → 0.1.0-cd0b0339c1003
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/README.md +1 -1
- package/dist/actions.d.ts +2 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +10 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +68 -76
- package/dist/chunks.d.ts +38 -0
- package/dist/chunks.d.ts.map +1 -0
- package/dist/chunks.js +247 -0
- package/dist/discovery.d.ts +1 -2
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +4 -5
- package/dist/history.js +1 -1
- package/dist/house-model.d.ts +70 -107
- package/dist/house-model.d.ts.map +1 -1
- package/dist/house-model.js +59 -56
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/model.d.ts +5 -7
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +30 -18
- package/dist/read.d.ts +11 -9
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +36 -144
- package/dist/room-types.d.ts +0 -2
- package/dist/room-types.d.ts.map +1 -1
- package/dist/room-types.js +2 -7
- package/dist/search.js +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +31 -41
- package/dist/space-schema.d.ts +7 -0
- package/dist/space-schema.d.ts.map +1 -0
- package/dist/space-schema.js +18 -0
- package/dist/stream.d.ts +6 -4
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +86 -16
- package/dist/transport.d.ts +5 -8
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +12 -12
- package/package.json +2 -2
- package/dist/part.d.ts +0 -14
- package/dist/part.d.ts.map +0 -1
- package/dist/part.js +0 -90
- package/dist/room-stream.d.ts +0 -19
- package/dist/room-stream.d.ts.map +0 -1
- package/dist/room-stream.js +0 -57
package/dist/model.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { sha256Hex } from './digest.js';
|
|
2
2
|
import { modelScope, schemaOf, schemaPath, } from './read.js';
|
|
3
|
+
import { spaceIdentity } from './space-schema.js';
|
|
3
4
|
const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
|
|
4
5
|
const ABSENT_SCHEMA = { schema: null, version: null, revision: null };
|
|
5
6
|
async function heldModel(read, identity) {
|
|
@@ -8,7 +9,12 @@ async function heldModel(read, identity) {
|
|
|
8
9
|
const version = await sha256Hex(JSON.stringify(read.version));
|
|
9
10
|
return {
|
|
10
11
|
kind: 'model',
|
|
11
|
-
snapshot: {
|
|
12
|
+
snapshot: {
|
|
13
|
+
identity: read.space === undefined ? identity : spaceIdentity(read.space),
|
|
14
|
+
version,
|
|
15
|
+
schema: read.schema,
|
|
16
|
+
revision: read.revision,
|
|
17
|
+
},
|
|
12
18
|
};
|
|
13
19
|
}
|
|
14
20
|
async function modelsOf(tracked, read) {
|
|
@@ -17,32 +23,38 @@ async function modelsOf(tracked, read) {
|
|
|
17
23
|
return undefined;
|
|
18
24
|
return { collection: await heldModel(collection, schemaPath(tracked.handle, tracked.schema)) };
|
|
19
25
|
}
|
|
20
|
-
export function
|
|
21
|
-
return modelsOf(tracked, (schema) => {
|
|
22
|
-
if (scope.files.some((file) => file.path === schema))
|
|
23
|
-
return schemaOf(scope, schema);
|
|
24
|
-
return final && !seen.has(schema) ? ABSENT_SCHEMA : undefined;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
export async function manifestedModels(room, tracked) {
|
|
26
|
+
export async function manifestedModels(room, tracked, spaces) {
|
|
28
27
|
const scope = modelScope(room);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
const held = schemaOf(scope, tracked.schema);
|
|
29
|
+
if (held?.space !== undefined && held.schema !== null && held.revision !== null)
|
|
30
|
+
spaces.keep(held.space, held.revision, held.schema);
|
|
31
|
+
return modelsOf(tracked, (schema) => scope.files.some((file) => file.path === schema) ? schemaOf(scope, schema) : ABSENT_SCHEMA);
|
|
32
|
+
}
|
|
33
|
+
export function keptSpaceSchemas(entries, spaces) {
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
if (entry.space !== undefined && entry.text !== undefined && entry.revision !== undefined)
|
|
36
|
+
spaces.keep(entry.space, entry.revision, entry.text);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function streamedText(entry, spaces) {
|
|
40
|
+
if (entry.text !== undefined || entry.space === undefined || entry.revision === undefined)
|
|
41
|
+
return entry.text;
|
|
42
|
+
return spaces.held(entry.space, entry.revision);
|
|
33
43
|
}
|
|
34
|
-
export function streamedModels(schemas, tracked, mode) {
|
|
44
|
+
export function streamedModels(schemas, tracked, mode, spaces, whole) {
|
|
35
45
|
return modelsOf(tracked, (schema) => {
|
|
36
46
|
const entry = schemas.get(schema);
|
|
37
47
|
if (entry === undefined)
|
|
38
|
-
return undefined;
|
|
48
|
+
return whole ? ABSENT_SCHEMA : undefined;
|
|
49
|
+
const space = entry.space === undefined ? {} : { space: entry.space };
|
|
39
50
|
if (entry.kind === 'removed')
|
|
40
|
-
return ABSENT_SCHEMA;
|
|
41
|
-
|
|
51
|
+
return { ...ABSENT_SCHEMA, ...space };
|
|
52
|
+
const text = streamedText(entry, spaces);
|
|
53
|
+
if (text === undefined)
|
|
42
54
|
return null;
|
|
43
55
|
const version = mode === 'site' ? entry.sha256 : entry.revision;
|
|
44
56
|
return version === undefined
|
|
45
57
|
? null
|
|
46
|
-
: { schema:
|
|
58
|
+
: { schema: text, version, revision: mode === 'site' ? null : version, ...space };
|
|
47
59
|
});
|
|
48
60
|
}
|
package/dist/read.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BinaryFile, type BootstrapPage, type SavedFacts
|
|
1
|
+
import { type BinaryFile, type BootstrapPage, type SavedFacts } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { HouseMode } from './transport.js';
|
|
3
3
|
import { type LogPosition } from './version.js';
|
|
4
4
|
export type HeadChange = BootstrapPage['changes'][string];
|
|
@@ -7,6 +7,7 @@ export type Answered = {
|
|
|
7
7
|
readonly facts: Map<string, SavedFacts>;
|
|
8
8
|
readonly revisions: Map<string, string>;
|
|
9
9
|
readonly fileIds: Map<string, string>;
|
|
10
|
+
readonly created: Map<string, string>;
|
|
10
11
|
readonly changes: Map<string, HeadChange>;
|
|
11
12
|
readonly binaryFiles: Map<string, BinaryFile>;
|
|
12
13
|
readonly removals: Set<string>;
|
|
@@ -22,6 +23,7 @@ export declare function answered(answer: Answered): Generator<number, {
|
|
|
22
23
|
facts: Readonly<Record<string, SavedFacts>>;
|
|
23
24
|
revisions: Readonly<Record<string, string>>;
|
|
24
25
|
fileIds?: Readonly<Record<string, string>>;
|
|
26
|
+
created?: Readonly<Record<string, string>>;
|
|
25
27
|
changes: Readonly<Record<string, HeadChange>>;
|
|
26
28
|
binaryFiles: Readonly<Record<string, BinaryFile>>;
|
|
27
29
|
removals: readonly string[];
|
|
@@ -34,8 +36,10 @@ export type HouseManifestFile = {
|
|
|
34
36
|
version: string;
|
|
35
37
|
sha256?: string;
|
|
36
38
|
head?: HeadChange;
|
|
39
|
+
created?: string;
|
|
37
40
|
binary?: BinaryFile;
|
|
38
41
|
facts?: SavedFacts;
|
|
42
|
+
space?: string;
|
|
39
43
|
};
|
|
40
44
|
export type HouseContent = {
|
|
41
45
|
path: string;
|
|
@@ -71,27 +75,25 @@ export declare function parseGrant(body: unknown): HouseGrant | null;
|
|
|
71
75
|
export declare function parseFileAddress(body: unknown): HouseFileAddress | null;
|
|
72
76
|
export declare function headChange(held: {
|
|
73
77
|
readonly author?: unknown;
|
|
74
|
-
readonly
|
|
78
|
+
readonly changed_at?: unknown;
|
|
75
79
|
}): HeadChange | undefined | null;
|
|
80
|
+
export declare function createdOf(held: {
|
|
81
|
+
readonly created_at?: unknown;
|
|
82
|
+
}): string | undefined | null;
|
|
76
83
|
export declare function binaryFileOf(held: Readonly<Record<string, unknown>>): BinaryFile | undefined | null;
|
|
77
84
|
export declare function carriedFacts(held: Readonly<Record<string, unknown>>): {
|
|
78
85
|
facts?: undefined;
|
|
79
86
|
} | {
|
|
80
87
|
facts: SavedFacts;
|
|
81
88
|
};
|
|
82
|
-
export declare function
|
|
83
|
-
export declare function manifested(room: HouseRoomHead, pageToken: string, models: RoomModels | undefined): BootstrapPage;
|
|
89
|
+
export declare function parseFile(value: unknown, mode: HouseMode): HouseManifestFile | null;
|
|
84
90
|
export declare function modelScope(room: HouseRoomHead): HouseScope;
|
|
85
|
-
export declare function emptyScope(room: HouseRoomHead): HouseScope;
|
|
86
|
-
export declare function housePart(room: HouseRoomHead, payload: Uint8Array<ArrayBuffer>, mode: HouseMode): Promise<{
|
|
87
|
-
scope: HouseScope;
|
|
88
|
-
ended: boolean;
|
|
89
|
-
} | TransportUncertainty>;
|
|
90
91
|
export declare function bootstrapping(scope: HouseScope): Generator<number, BootstrapPage, void>;
|
|
91
92
|
export type HouseSchema = {
|
|
92
93
|
schema: string | null;
|
|
93
94
|
version: string | null;
|
|
94
95
|
revision: string | null;
|
|
96
|
+
space?: string;
|
|
95
97
|
};
|
|
96
98
|
export declare function schemaOf(scope: HouseScope, schema: string): HouseSchema | null;
|
|
97
99
|
//# sourceMappingURL=read.d.ts.map
|
package/dist/read.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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"}
|
package/dist/read.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { readPosition, roomVersion } from './version.js';
|
|
1
|
+
import { patching, ROW_WEIGHT, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { roomVersion } from './version.js';
|
|
4
3
|
const REVISION_FILE = /^fr_([0-9a-z]+)\.[0-9a-z]+\.[0-9a-z]$/u;
|
|
5
4
|
function fileOf(revision) {
|
|
6
5
|
return REVISION_FILE.exec(revision)?.[1];
|
|
@@ -11,6 +10,7 @@ export function answering() {
|
|
|
11
10
|
facts: new Map(),
|
|
12
11
|
revisions: new Map(),
|
|
13
12
|
fileIds: new Map(),
|
|
13
|
+
created: new Map(),
|
|
14
14
|
changes: new Map(),
|
|
15
15
|
binaryFiles: new Map(),
|
|
16
16
|
removals: new Set(),
|
|
@@ -29,6 +29,7 @@ export function forgotten(answer, path) {
|
|
|
29
29
|
answer.facts.delete(path);
|
|
30
30
|
answer.revisions.delete(path);
|
|
31
31
|
answer.fileIds.delete(path);
|
|
32
|
+
answer.created.delete(path);
|
|
32
33
|
answer.changes.delete(path);
|
|
33
34
|
answer.binaryFiles.delete(path);
|
|
34
35
|
answer.removals.delete(path);
|
|
@@ -58,6 +59,7 @@ export function* answered(answer) {
|
|
|
58
59
|
facts: yield* patching({}, answer.facts),
|
|
59
60
|
revisions: yield* patching({}, answer.revisions),
|
|
60
61
|
...(answer.fileIds.size === 0 ? {} : { fileIds: yield* patching({}, answer.fileIds) }),
|
|
62
|
+
...(answer.created.size === 0 ? {} : { created: yield* patching({}, answer.created) }),
|
|
61
63
|
changes: yield* patching({}, answer.changes),
|
|
62
64
|
binaryFiles: yield* patching({}, answer.binaryFiles),
|
|
63
65
|
removals,
|
|
@@ -121,11 +123,19 @@ export function headChange(held) {
|
|
|
121
123
|
const author = held.author === undefined ? null : changeAuthor(held.author);
|
|
122
124
|
if (held.author !== undefined && author === null)
|
|
123
125
|
return null;
|
|
124
|
-
if (held.
|
|
126
|
+
if (held.changed_at === undefined)
|
|
125
127
|
return undefined;
|
|
126
|
-
if (typeof held.
|
|
128
|
+
if (typeof held.changed_at !== 'string')
|
|
127
129
|
return null;
|
|
128
|
-
return { author, time: held.
|
|
130
|
+
return { author, time: held.changed_at };
|
|
131
|
+
}
|
|
132
|
+
export function createdOf(held) {
|
|
133
|
+
if (held.created_at === undefined)
|
|
134
|
+
return undefined;
|
|
135
|
+
return typeof held.created_at === 'string' ? held.created_at : null;
|
|
136
|
+
}
|
|
137
|
+
function createdHeld(created) {
|
|
138
|
+
return created === undefined ? {} : { created };
|
|
129
139
|
}
|
|
130
140
|
function headed(head) {
|
|
131
141
|
return head === undefined ? {} : { head };
|
|
@@ -144,15 +154,19 @@ function binaried(binary) {
|
|
|
144
154
|
export function carriedFacts(held) {
|
|
145
155
|
return held.facts === undefined ? {} : { facts: held.facts };
|
|
146
156
|
}
|
|
147
|
-
function
|
|
157
|
+
function carriedSpace(held) {
|
|
158
|
+
return typeof held.space === 'string' ? { space: held.space } : {};
|
|
159
|
+
}
|
|
160
|
+
export function parseFile(value, mode) {
|
|
148
161
|
if (typeof value !== 'object' || value === null)
|
|
149
162
|
return null;
|
|
150
163
|
const file = value;
|
|
151
164
|
if (typeof file.path !== 'string')
|
|
152
165
|
return null;
|
|
153
166
|
const head = headChange(file);
|
|
167
|
+
const created = createdOf(file);
|
|
154
168
|
const binary = binaryFileOf(file);
|
|
155
|
-
if (head === null || binary === null)
|
|
169
|
+
if (head === null || created === null || binary === null)
|
|
156
170
|
return null;
|
|
157
171
|
if (mode === 'site') {
|
|
158
172
|
if (typeof file.sha256 !== 'string')
|
|
@@ -174,152 +188,21 @@ function parseFile(value, mode) {
|
|
|
174
188
|
version: file.revision,
|
|
175
189
|
...(typeof file.sha256 === 'string' ? { sha256: file.sha256 } : {}),
|
|
176
190
|
...headed(head),
|
|
191
|
+
...createdHeld(created),
|
|
177
192
|
...binaried(binary),
|
|
178
193
|
...carriedFacts(file),
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
function parseModels(value, mode) {
|
|
182
|
-
if (!Array.isArray(value))
|
|
183
|
-
return null;
|
|
184
|
-
const files = [];
|
|
185
|
-
const contents = [];
|
|
186
|
-
for (const entry of value) {
|
|
187
|
-
const file = parseFile(entry, mode);
|
|
188
|
-
const { content } = entry;
|
|
189
|
-
if (file === null || typeof content !== 'string')
|
|
190
|
-
return null;
|
|
191
|
-
files.push(file);
|
|
192
|
-
contents.push({ path: file.path, content });
|
|
193
|
-
}
|
|
194
|
-
return { files, contents };
|
|
195
|
-
}
|
|
196
|
-
function parseRoomHead(value, mode) {
|
|
197
|
-
if (typeof value !== 'object' || value === null)
|
|
198
|
-
return null;
|
|
199
|
-
const held = value;
|
|
200
|
-
if (typeof held.manifest !== 'object' || held.manifest === null)
|
|
201
|
-
return null;
|
|
202
|
-
const models = parseModels(held.models, mode);
|
|
203
|
-
if (models === null)
|
|
204
|
-
return null;
|
|
205
|
-
const manifest = held.manifest;
|
|
206
|
-
if (manifest.scope !== 'room')
|
|
207
|
-
return null;
|
|
208
|
-
const at = readPosition(manifest);
|
|
209
|
-
if (typeof manifest.anchor !== 'string' || manifest.anchor.length === 0 || at === null)
|
|
210
|
-
return null;
|
|
211
|
-
if (typeof manifest.room_handle !== 'string' || manifest.room_handle.length === 0)
|
|
212
|
-
return null;
|
|
213
|
-
return { anchor: manifest.anchor, ...at, models };
|
|
214
|
-
}
|
|
215
|
-
export async function roomHead(payload, mode) {
|
|
216
|
-
let text = '';
|
|
217
|
-
try {
|
|
218
|
-
for await (const chunk of gunzipped(payload))
|
|
219
|
-
text += chunk;
|
|
220
|
-
return text.endsWith('\n') && text.indexOf('\n') === text.length - 1
|
|
221
|
-
? parseRoomHead(JSON.parse(text), mode)
|
|
222
|
-
: null;
|
|
223
|
-
}
|
|
224
|
-
catch {
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
export function manifested(room, pageToken, models) {
|
|
229
|
-
return {
|
|
230
|
-
kind: 'bootstrap',
|
|
231
|
-
roomVersion: roomVersion(room),
|
|
232
|
-
documents: {},
|
|
233
|
-
facts: {},
|
|
234
|
-
revisions: {},
|
|
235
|
-
changes: {},
|
|
236
|
-
binaryFiles: {},
|
|
237
|
-
pageToken,
|
|
238
|
-
...(models === undefined ? {} : { models }),
|
|
194
|
+
...carriedSpace(file),
|
|
239
195
|
};
|
|
240
196
|
}
|
|
241
197
|
export function modelScope(room) {
|
|
242
|
-
return { ...emptyScope(room), files: room.models.files, contents: room.models.contents };
|
|
243
|
-
}
|
|
244
|
-
export function emptyScope(room) {
|
|
245
198
|
return {
|
|
246
199
|
anchor: room.anchor,
|
|
247
200
|
position: room.position,
|
|
248
201
|
logEpoch: room.logEpoch,
|
|
249
|
-
files:
|
|
250
|
-
contents:
|
|
202
|
+
files: room.models.files,
|
|
203
|
+
contents: room.models.contents,
|
|
251
204
|
};
|
|
252
205
|
}
|
|
253
|
-
function partLine(line, mode, read) {
|
|
254
|
-
if (read.ended)
|
|
255
|
-
return false;
|
|
256
|
-
let entry;
|
|
257
|
-
try {
|
|
258
|
-
entry = JSON.parse(line);
|
|
259
|
-
}
|
|
260
|
-
catch {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
if (endLine(entry)) {
|
|
264
|
-
read.ended = true;
|
|
265
|
-
return true;
|
|
266
|
-
}
|
|
267
|
-
if (folderLine(entry)) {
|
|
268
|
-
read.folders.push(entry.folder);
|
|
269
|
-
return true;
|
|
270
|
-
}
|
|
271
|
-
const file = parseFile(entry, mode);
|
|
272
|
-
if (file === null)
|
|
273
|
-
return false;
|
|
274
|
-
read.files.push(file);
|
|
275
|
-
const { content } = entry;
|
|
276
|
-
if (typeof content === 'string')
|
|
277
|
-
read.contents.push({ path: file.path, content });
|
|
278
|
-
else if (content !== undefined)
|
|
279
|
-
return false;
|
|
280
|
-
return true;
|
|
281
|
-
}
|
|
282
|
-
async function partRead(chunks, mode) {
|
|
283
|
-
const read = { files: [], contents: [], folders: [], ended: false };
|
|
284
|
-
const pace = paced();
|
|
285
|
-
const unfinished = [];
|
|
286
|
-
for (let chunk = await chunks.read(); chunk.done !== true; chunk = await chunks.read()) {
|
|
287
|
-
const text = chunk.value;
|
|
288
|
-
let start = 0;
|
|
289
|
-
for (let end = text.indexOf('\n'); end !== -1; end = text.indexOf('\n', start)) {
|
|
290
|
-
const piece = text.slice(start, end);
|
|
291
|
-
const line = unfinished.length === 0 ? piece : unfinished.splice(0).join('') + piece;
|
|
292
|
-
if (!partLine(line, mode, read)) {
|
|
293
|
-
await chunks.cancel();
|
|
294
|
-
return null;
|
|
295
|
-
}
|
|
296
|
-
start = end + 1;
|
|
297
|
-
const due = pace(line.length + ROW_WEIGHT);
|
|
298
|
-
if (due instanceof Promise)
|
|
299
|
-
await due;
|
|
300
|
-
}
|
|
301
|
-
if (start < text.length)
|
|
302
|
-
unfinished.push(text.slice(start));
|
|
303
|
-
}
|
|
304
|
-
return unfinished.length === 0 ? read : null;
|
|
305
|
-
}
|
|
306
|
-
function endLine(entry) {
|
|
307
|
-
if (typeof entry !== 'object' || entry === null || !('end' in entry))
|
|
308
|
-
return false;
|
|
309
|
-
return entry.end === true && Object.keys(entry).length === 1;
|
|
310
|
-
}
|
|
311
|
-
function folderLine(entry) {
|
|
312
|
-
if (typeof entry !== 'object' || entry === null || !('folder' in entry))
|
|
313
|
-
return false;
|
|
314
|
-
return typeof entry.folder === 'string' && Object.keys(entry).length === 1;
|
|
315
|
-
}
|
|
316
|
-
export async function housePart(room, payload, mode) {
|
|
317
|
-
const read = await partRead(gunzipped(payload).getReader(), mode).catch(() => null);
|
|
318
|
-
if (read === null)
|
|
319
|
-
return { kind: 'transport-uncertainty' };
|
|
320
|
-
const { ended, ...scope } = read;
|
|
321
|
-
return { scope: { ...emptyScope(room), ...scope }, ended };
|
|
322
|
-
}
|
|
323
206
|
export function* bootstrapping(scope) {
|
|
324
207
|
const contents = new Map();
|
|
325
208
|
for (const entry of scope.contents) {
|
|
@@ -329,8 +212,12 @@ export function* bootstrapping(scope) {
|
|
|
329
212
|
const answer = answering();
|
|
330
213
|
for (const file of scope.files) {
|
|
331
214
|
yield ROW_WEIGHT;
|
|
215
|
+
if (file.space !== undefined)
|
|
216
|
+
continue;
|
|
332
217
|
if (file.head !== undefined)
|
|
333
218
|
answer.changes.set(file.path, file.head);
|
|
219
|
+
if (file.created !== undefined)
|
|
220
|
+
answer.created.set(file.path, file.created);
|
|
334
221
|
const content = contents.get(file.path);
|
|
335
222
|
if (file.binary !== undefined)
|
|
336
223
|
answer.binaryFiles.set(file.path, file.binary);
|
|
@@ -353,5 +240,10 @@ export function schemaOf(scope, schema) {
|
|
|
353
240
|
const content = scope.contents.find((entry) => entry.path === schema);
|
|
354
241
|
return content === undefined
|
|
355
242
|
? null
|
|
356
|
-
: {
|
|
243
|
+
: {
|
|
244
|
+
schema: content.content,
|
|
245
|
+
version: file.version,
|
|
246
|
+
revision: file.revision ?? null,
|
|
247
|
+
...(file.space === undefined ? {} : { space: file.space }),
|
|
248
|
+
};
|
|
357
249
|
}
|
package/dist/room-types.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export declare const INBOX_CHANNEL_KINDS: readonly ['telegram-bot', 'telegram-business', 'whatsapp', 'messenger', 'instagram', 'viber', 'tiktok'];
|
|
2
2
|
export type InboxChannelKind = (typeof INBOX_CHANNEL_KINDS)[number];
|
|
3
|
-
export declare const CHAT_TYPE = "chat";
|
|
4
|
-
export declare const CHAT_MESSAGE_TYPE = "chat-message";
|
|
5
3
|
export declare const HOUSE_NAMEABLE_ROOM_TYPES: string[];
|
|
6
4
|
export declare const HOUSE_ROOM_TYPES: string;
|
|
7
5
|
//# sourceMappingURL=room-types.d.ts.map
|
package/dist/room-types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-types.d.ts","sourceRoot":"","sources":["../src/room-types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"room-types.d.ts","sourceRoot":"","sources":["../src/room-types.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB,YAC9B,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,QAAQ,CACA,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,yBAAyB,UAAiC,CAAC;AAyBxE,eAAO,MAAM,gBAAgB,QAyFjB,CAAC"}
|
package/dist/room-types.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CHAT_MESSAGE_TYPE, CHAT_TYPE } from '@agentshouse/mdruntime';
|
|
1
2
|
import { APP_REFERENCE_PATTERN } from './app-reference.js';
|
|
2
3
|
import { HOUSE_MODEL_TYPES } from './house-model.js';
|
|
3
4
|
export const INBOX_CHANNEL_KINDS = [
|
|
@@ -9,8 +10,6 @@ export const INBOX_CHANNEL_KINDS = [
|
|
|
9
10
|
'viber',
|
|
10
11
|
'tiktok',
|
|
11
12
|
];
|
|
12
|
-
export const CHAT_TYPE = 'chat';
|
|
13
|
-
export const CHAT_MESSAGE_TYPE = 'chat-message';
|
|
14
13
|
export const HOUSE_NAMEABLE_ROOM_TYPES = [CHAT_TYPE, CHAT_MESSAGE_TYPE];
|
|
15
14
|
const WAYFINDING_MAP_TYPE = 'wayfinding-map';
|
|
16
15
|
const WAYFINDING_TICKET_TYPE = 'wayfinding-ticket';
|
|
@@ -52,14 +51,10 @@ export const HOUSE_ROOM_TYPES = [
|
|
|
52
51
|
' properties:',
|
|
53
52
|
' direction: { enum: [in, out] }',
|
|
54
53
|
' sender:',
|
|
55
|
-
|
|
56
|
-
' properties:',
|
|
57
|
-
' name: { type: string }',
|
|
54
|
+
...ASSIGNEE,
|
|
58
55
|
` username: ${IDENTITY}`,
|
|
59
56
|
' sent_at: { type: string, format: date-time }',
|
|
60
57
|
` channel_message: ${IDENTITY}`,
|
|
61
|
-
' state: { enum: [sending, sent, failed] }',
|
|
62
|
-
' reason: { type: string }',
|
|
63
58
|
' labelled: { const: true }',
|
|
64
59
|
' reactions:',
|
|
65
60
|
' type: array',
|
package/dist/search.js
CHANGED
|
@@ -27,7 +27,7 @@ export async function houseSearch(transport, tracked, request) {
|
|
|
27
27
|
: tracked.filter((entry) => request.rooms.includes(entry.locator));
|
|
28
28
|
if (named !== null && named.length === 0)
|
|
29
29
|
return { kind: 'found', documents: [] };
|
|
30
|
-
const answer = await transport.door(houseDoorRoute('search'), {
|
|
30
|
+
const answer = await transport.door(houseDoorRoute('rooms/search'), {
|
|
31
31
|
query: request.text,
|
|
32
32
|
...(named === null ? {} : { paths: named.map((entry) => `${ROOMS}${entry.handle}`) }),
|
|
33
33
|
});
|
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,EAQR,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAQR,MAAM,wBAAwB,CAAC;AAehC,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAuBxB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAiK1F"}
|
package/dist/site.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { stepped } from '@agentshouse/mdruntime';
|
|
2
1
|
import { actionOutcome } from './actions.js';
|
|
2
|
+
import { chunkedHead, chunkPart, siteChunkList } from './chunks.js';
|
|
3
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { classifyDoor, discoveryFailure } from './refusal.js';
|
|
4
|
+
import { spaceSchemas } from './space-schema.js';
|
|
5
|
+
import { discoveryFailure } from './refusal.js';
|
|
7
6
|
import { HOUSE_TYPED_PATHS } from './house-model.js';
|
|
8
7
|
import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
|
|
9
8
|
import { houseNotifications } from './stream.js';
|
|
10
|
-
import { houseSiteRoute, SITE_DOOR_SUBMIT, SITE_FILES,
|
|
11
|
-
import { followsVersion,
|
|
9
|
+
import { houseSiteRoute, SITE_DOOR_SUBMIT, SITE_FILES, SITES_SUBMISSIONS_CREATE, } from './transport.js';
|
|
10
|
+
import { followsVersion, reachedVersion, roomVersion } from './version.js';
|
|
12
11
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
13
12
|
function unfound() {
|
|
14
13
|
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
@@ -19,50 +18,47 @@ function siteRoom(tracked) {
|
|
|
19
18
|
locator: tracked.locator,
|
|
20
19
|
handle: tracked.handle,
|
|
21
20
|
roomVersion: roomVersion(tracked),
|
|
22
|
-
operations: { write: [],
|
|
21
|
+
operations: { write: [], erase: [] },
|
|
23
22
|
replica: { selection: tracked.locator, admission: 'admitted', offline: 'open' },
|
|
24
23
|
providerOwnedPaths: [],
|
|
25
24
|
};
|
|
26
25
|
}
|
|
27
26
|
export function createSiteAdapter(transport, snapshot = false) {
|
|
27
|
+
const spaces = spaceSchemas();
|
|
28
28
|
const notifications = houseNotifications(transport, 'site', {
|
|
29
29
|
opened: async () => {
|
|
30
30
|
const found = await discovered();
|
|
31
31
|
return found.kind === 'discovery' ? found : null;
|
|
32
32
|
},
|
|
33
33
|
changed: () => null,
|
|
34
|
-
});
|
|
34
|
+
}, spaces);
|
|
35
35
|
const tracked = new Map();
|
|
36
|
-
const
|
|
37
|
-
const rooms = roomStreams('site');
|
|
36
|
+
const chunked = new Map();
|
|
38
37
|
function fileRoute(request) {
|
|
39
38
|
const entry = tracked.get(request.locator);
|
|
40
39
|
if (entry === undefined)
|
|
41
40
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
42
41
|
return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
|
|
43
42
|
}
|
|
44
|
-
async function
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
return
|
|
49
|
-
const head = await
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
read.set(entry.locator, at.position);
|
|
43
|
+
async function listedRoom(entry) {
|
|
44
|
+
const past = chunked.get(entry.locator)?.position;
|
|
45
|
+
const listed = siteChunkList(await transport.read(`${houseSiteRoute('chunks')}/${entry.authority}${past === undefined ? '' : `?expired=${past}`}`), entry.locator);
|
|
46
|
+
if ('kind' in listed)
|
|
47
|
+
return listed;
|
|
48
|
+
const head = await chunkedHead(listed, entry, spaces);
|
|
49
|
+
if (head.kind === 'bootstrap')
|
|
50
|
+
chunked.set(entry.locator, listed);
|
|
53
51
|
return head;
|
|
54
52
|
}
|
|
55
|
-
async function
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
bytes: part.bytes,
|
|
65
|
-
};
|
|
53
|
+
async function chunkPage(entry, id, arriving) {
|
|
54
|
+
const room = chunked.get(entry.locator);
|
|
55
|
+
const address = room?.chunks.get(id);
|
|
56
|
+
if (room === undefined || address === undefined)
|
|
57
|
+
return UNCERTAIN;
|
|
58
|
+
const read = await transport.download(address.url);
|
|
59
|
+
if (read.status !== 200)
|
|
60
|
+
return UNCERTAIN;
|
|
61
|
+
return chunkPart(read.body, room, id, arriving);
|
|
66
62
|
}
|
|
67
63
|
async function discovered() {
|
|
68
64
|
const answer = await transport.read(houseSiteRoute('discover'));
|
|
@@ -92,8 +88,8 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
92
88
|
if (entry === undefined)
|
|
93
89
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
94
90
|
return request.pageToken === undefined
|
|
95
|
-
?
|
|
96
|
-
:
|
|
91
|
+
? listedRoom(entry)
|
|
92
|
+
: chunkPage(entry, request.pageToken, request.arriving);
|
|
97
93
|
},
|
|
98
94
|
...(snapshot
|
|
99
95
|
? {
|
|
@@ -147,7 +143,7 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
147
143
|
return followsVersion(version, next);
|
|
148
144
|
},
|
|
149
145
|
async action(_authorization, request) {
|
|
150
|
-
if (request.name !==
|
|
146
|
+
if (request.name !== SITES_SUBMISSIONS_CREATE) {
|
|
151
147
|
return {
|
|
152
148
|
kind: 'rejected',
|
|
153
149
|
code: 'action-unimplemented',
|
|
@@ -157,18 +153,12 @@ export function createSiteAdapter(transport, snapshot = false) {
|
|
|
157
153
|
}
|
|
158
154
|
if (!transport.online())
|
|
159
155
|
return UNCERTAIN;
|
|
160
|
-
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input),
|
|
156
|
+
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITES_SUBMISSIONS_CREATE, request.input);
|
|
161
157
|
},
|
|
162
158
|
roomStream: snapshot
|
|
163
159
|
? undefined
|
|
164
160
|
: {
|
|
165
|
-
hold
|
|
166
|
-
notifications.send(rooms.flatMap((room) => {
|
|
167
|
-
const entry = tracked.get(room.locator);
|
|
168
|
-
const at = logPosition(room.roomVersion);
|
|
169
|
-
return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
|
|
170
|
-
}));
|
|
171
|
-
},
|
|
161
|
+
hold: notifications.send,
|
|
172
162
|
observe: notifications.observe,
|
|
173
163
|
},
|
|
174
164
|
serviceMode: notifications.serviceMode,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SpaceSchemas = {
|
|
2
|
+
held(space: string, revision: string): string | undefined;
|
|
3
|
+
keep(space: string, revision: string, text: string): void;
|
|
4
|
+
};
|
|
5
|
+
export declare function spaceSchemas(): SpaceSchemas;
|
|
6
|
+
export declare function spaceIdentity(space: string): string;
|
|
7
|
+
//# sourceMappingURL=space-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-schema.d.ts","sourceRoot":"","sources":["../src/space-schema.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D,CAAC;AAEF,wBAAgB,YAAY,IAAI,YAAY,CAY3C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const HELD_TEXTS = 16;
|
|
2
|
+
export function spaceSchemas() {
|
|
3
|
+
const texts = new Map();
|
|
4
|
+
const key = (space, revision) => `${space} ${revision}`;
|
|
5
|
+
return {
|
|
6
|
+
held: (space, revision) => texts.get(key(space, revision)),
|
|
7
|
+
keep(space, revision, text) {
|
|
8
|
+
const named = key(space, revision);
|
|
9
|
+
texts.delete(named);
|
|
10
|
+
texts.set(named, text);
|
|
11
|
+
if (texts.size > HELD_TEXTS)
|
|
12
|
+
texts.delete(texts.keys().next().value);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function spaceIdentity(space) {
|
|
17
|
+
return `space:${space}`;
|
|
18
|
+
}
|