@agentshouse/mdruntime-adapter 0.1.0-ccd2ccb1f7214 → 0.1.0-cd23c45caa798
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 +28 -23
- package/dist/actions.d.ts +11 -5
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +77 -97
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +144 -87
- package/dist/discovery.d.ts +3 -2
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +24 -6
- package/dist/gather.d.ts +1 -1
- package/dist/gather.d.ts.map +1 -1
- package/dist/gather.js +4 -14
- package/dist/handed.d.ts +6 -6
- package/dist/handed.d.ts.map +1 -1
- package/dist/handed.js +36 -29
- package/dist/part.d.ts +13 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +80 -0
- package/dist/read.d.ts +33 -23
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +159 -120
- package/dist/referrer.d.ts.map +1 -1
- package/dist/referrer.js +0 -2
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +58 -74
- package/dist/stream.d.ts +2 -3
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +23 -34
- package/dist/transport.d.ts +2 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/write.d.ts +12 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +79 -38
- package/package.json +2 -2
package/dist/handed.js
CHANGED
|
@@ -1,38 +1,45 @@
|
|
|
1
|
+
import { entriesIn, patching } from '@agentshouse/mdruntime';
|
|
1
2
|
import { roomVersion } from './version.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
3
|
+
function* revised(files) {
|
|
4
|
+
for (const { path, revision } of files)
|
|
5
|
+
if (revision !== undefined)
|
|
6
|
+
yield [path, revision];
|
|
7
7
|
}
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
revisions.delete(path);
|
|
11
|
-
else
|
|
12
|
-
revisions.set(path, revision);
|
|
8
|
+
export function* scopeHanded(scope) {
|
|
9
|
+
return { roomVersion: roomVersion(scope), revisions: yield* patching({}, revised(scope.files)) };
|
|
13
10
|
}
|
|
14
11
|
export function heldHanded(held) {
|
|
15
|
-
return { roomVersion: held.roomVersion, revisions:
|
|
16
|
-
}
|
|
17
|
-
export function acceptedHanded(held, accepted, roomVersion) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
revisions.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
export function enumeratedHanded(view, earlier) {
|
|
26
|
-
const revisions = new Map(earlier?.revisions);
|
|
12
|
+
return { roomVersion: held.roomVersion, revisions: held.revisions };
|
|
13
|
+
}
|
|
14
|
+
export function* acceptedHanded(held, accepted, roomVersion) {
|
|
15
|
+
return {
|
|
16
|
+
roomVersion,
|
|
17
|
+
revisions: yield* patching(held.revisions, entriesIn(accepted.revisions), accepted.removals),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function* kept(view) {
|
|
27
21
|
for (const change of view.changes) {
|
|
28
|
-
|
|
22
|
+
if (!('removed' in change) && change.revision !== undefined) {
|
|
23
|
+
yield [change.path, change.revision];
|
|
24
|
+
}
|
|
29
25
|
}
|
|
30
|
-
return { roomVersion: roomVersion(view), revisions };
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
function* dropped(view) {
|
|
28
|
+
for (const change of view.changes) {
|
|
29
|
+
if ('removed' in change || change.revision === undefined)
|
|
30
|
+
yield change.path;
|
|
36
31
|
}
|
|
37
|
-
|
|
32
|
+
}
|
|
33
|
+
export function* enumeratedHanded(view, earlier) {
|
|
34
|
+
return {
|
|
35
|
+
roomVersion: roomVersion(view),
|
|
36
|
+
revisions: yield* patching(earlier?.revisions ?? {}, kept(view), dropped(view)),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function* streamedHanded(held, advanced) {
|
|
40
|
+
const { page } = advanced;
|
|
41
|
+
return {
|
|
42
|
+
roomVersion: page.roomVersion,
|
|
43
|
+
revisions: yield* patching(held.revisions, entriesIn(page.revisions), page.removals),
|
|
44
|
+
};
|
|
38
45
|
}
|
package/dist/part.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ScopedRefusal } from '@agentshouse/mdruntime';
|
|
2
|
+
export declare const PART_ATTEMPTS = 3;
|
|
3
|
+
export declare const PART_UNVERIFIED = "part_unverified";
|
|
4
|
+
export type HousePart = {
|
|
5
|
+
part: string;
|
|
6
|
+
bytes: number;
|
|
7
|
+
sha256: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function parsePart(value: unknown): HousePart | null;
|
|
10
|
+
export declare function checkedPayload(body: unknown, listed: HousePart): Promise<Uint8Array<ArrayBuffer> | null>;
|
|
11
|
+
export declare function gunzipped(payload: Uint8Array<ArrayBuffer>): Promise<string | null>;
|
|
12
|
+
export declare function unverifiedPart(locator: string): ScopedRefusal;
|
|
13
|
+
//# sourceMappingURL=part.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"part.d.ts","sourceRoot":"","sources":["../src/part.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAU5D,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAO1D;AAoBD,wBAAsB,cAAc,CAClC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAiBzC;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAS7D"}
|
package/dist/part.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const PART_MAGIC = 0x48505431;
|
|
2
|
+
const PART_HEAD_BYTES = 8;
|
|
3
|
+
const PART_DIGEST_BYTES = 32;
|
|
4
|
+
const PART_SHA256 = /^[0-9a-f]{64}$/u;
|
|
5
|
+
export const PART_ATTEMPTS = 3;
|
|
6
|
+
export const PART_UNVERIFIED = 'part_unverified';
|
|
7
|
+
export function parsePart(value) {
|
|
8
|
+
if (typeof value !== 'object' || value === null)
|
|
9
|
+
return null;
|
|
10
|
+
const { part, bytes, sha256 } = value;
|
|
11
|
+
if (typeof part !== 'string' || part.length === 0)
|
|
12
|
+
return null;
|
|
13
|
+
if (typeof bytes !== 'number' || !Number.isSafeInteger(bytes) || bytes <= 0)
|
|
14
|
+
return null;
|
|
15
|
+
if (typeof sha256 !== 'string' || !PART_SHA256.test(sha256))
|
|
16
|
+
return null;
|
|
17
|
+
return { part, bytes, sha256 };
|
|
18
|
+
}
|
|
19
|
+
function decoded(text) {
|
|
20
|
+
let binary;
|
|
21
|
+
try {
|
|
22
|
+
binary = atob(text);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const bytes = new Uint8Array(binary.length);
|
|
28
|
+
for (let at = 0; at < binary.length; at += 1)
|
|
29
|
+
bytes[at] = binary.charCodeAt(at);
|
|
30
|
+
return bytes;
|
|
31
|
+
}
|
|
32
|
+
function hex(bytes) {
|
|
33
|
+
let text = '';
|
|
34
|
+
for (const byte of bytes)
|
|
35
|
+
text += byte.toString(16).padStart(2, '0');
|
|
36
|
+
return text;
|
|
37
|
+
}
|
|
38
|
+
export async function checkedPayload(body, listed) {
|
|
39
|
+
if (typeof body !== 'object' || body === null)
|
|
40
|
+
return null;
|
|
41
|
+
const { part } = body;
|
|
42
|
+
if (typeof part !== 'string')
|
|
43
|
+
return null;
|
|
44
|
+
const frame = decoded(part);
|
|
45
|
+
if (frame === null || frame.length !== listed.bytes)
|
|
46
|
+
return null;
|
|
47
|
+
if (frame.length < PART_HEAD_BYTES + PART_DIGEST_BYTES)
|
|
48
|
+
return null;
|
|
49
|
+
const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
|
|
50
|
+
if (view.getUint32(0) !== PART_MAGIC)
|
|
51
|
+
return null;
|
|
52
|
+
const length = view.getUint32(4);
|
|
53
|
+
if (PART_HEAD_BYTES + length + PART_DIGEST_BYTES !== frame.length)
|
|
54
|
+
return null;
|
|
55
|
+
const payload = frame.subarray(PART_HEAD_BYTES, PART_HEAD_BYTES + length);
|
|
56
|
+
const digest = hex(new Uint8Array(await crypto.subtle.digest('SHA-256', payload)));
|
|
57
|
+
if (digest !== listed.sha256 || hex(frame.subarray(PART_HEAD_BYTES + length)) !== digest) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return payload;
|
|
61
|
+
}
|
|
62
|
+
export async function gunzipped(payload) {
|
|
63
|
+
try {
|
|
64
|
+
const stream = new Blob([payload]).stream().pipeThrough(new DecompressionStream('gzip'));
|
|
65
|
+
return await new Response(stream).text();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function unverifiedPart(locator) {
|
|
72
|
+
return {
|
|
73
|
+
kind: 'scoped-refusal',
|
|
74
|
+
locator,
|
|
75
|
+
scope: 'undisclosed',
|
|
76
|
+
code: PART_UNVERIFIED,
|
|
77
|
+
fields: {},
|
|
78
|
+
retryable: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
package/dist/read.d.ts
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AdapterFailure, type BinaryFile, type BootstrapPage, type RefreshResult, type TransportUncertainty } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { TrackedAuthority } from './discovery.js';
|
|
3
|
+
import { type HousePart } from './part.js';
|
|
3
4
|
import type { HouseMode } from './transport.js';
|
|
4
5
|
import { type LogPosition } from './version.js';
|
|
5
6
|
export type HeadChange = BootstrapPage['changes'][string];
|
|
6
|
-
export
|
|
7
|
-
|
|
7
|
+
export type Answered = {
|
|
8
|
+
readonly documents: Map<string, string>;
|
|
9
|
+
readonly revisions: Map<string, string>;
|
|
10
|
+
readonly fileIds: Map<string, string>;
|
|
11
|
+
readonly changes: Map<string, HeadChange>;
|
|
12
|
+
readonly binaryFiles: Map<string, BinaryFile>;
|
|
13
|
+
readonly removals: Set<string>;
|
|
8
14
|
};
|
|
15
|
+
export declare function answering(): Answered;
|
|
16
|
+
export declare function revised(answer: Answered, path: string, revision: string): void;
|
|
17
|
+
export declare function forgotten(answer: Answered, path: string): void;
|
|
18
|
+
export declare function answered(answer: Answered): Generator<number, {
|
|
19
|
+
documents: Readonly<Record<string, string>>;
|
|
20
|
+
revisions: Readonly<Record<string, string>>;
|
|
21
|
+
fileIds?: Readonly<Record<string, string>>;
|
|
22
|
+
changes: Readonly<Record<string, HeadChange>>;
|
|
23
|
+
binaryFiles: Readonly<Record<string, BinaryFile>>;
|
|
24
|
+
removals: readonly string[];
|
|
25
|
+
}, void>;
|
|
9
26
|
export type HouseManifestFile = {
|
|
10
27
|
path: string;
|
|
11
28
|
revision: string | undefined;
|
|
@@ -23,18 +40,13 @@ export type HouseScope = LogPosition & {
|
|
|
23
40
|
files: readonly HouseManifestFile[];
|
|
24
41
|
contents: readonly HouseContent[];
|
|
25
42
|
};
|
|
26
|
-
export type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
export type HouseCursor = {
|
|
31
|
-
room: string;
|
|
32
|
-
path: string | null;
|
|
33
|
-
cut?: HouseCut;
|
|
43
|
+
export type HouseRoomParts = LogPosition & {
|
|
44
|
+
anchor: string;
|
|
45
|
+
parts: readonly HousePart[];
|
|
34
46
|
};
|
|
35
|
-
export type
|
|
36
|
-
|
|
37
|
-
next?:
|
|
47
|
+
export type HouseParted = {
|
|
48
|
+
rooms: readonly HouseRoomParts[];
|
|
49
|
+
next?: string;
|
|
38
50
|
};
|
|
39
51
|
export type HouseGrant = {
|
|
40
52
|
method: 'GET';
|
|
@@ -77,7 +89,6 @@ export type HouseEnumeration = {
|
|
|
77
89
|
authorities: readonly HouseView[];
|
|
78
90
|
};
|
|
79
91
|
export declare function authorityRoot(handle: string): string;
|
|
80
|
-
export declare function contentPrefixes(tracked: TrackedAuthority): readonly string[];
|
|
81
92
|
export declare function schemaPath(handle: string, schema: string): string;
|
|
82
93
|
export declare function parseGrant(body: unknown): HouseGrant | null;
|
|
83
94
|
export declare function headChange(held: {
|
|
@@ -85,15 +96,14 @@ export declare function headChange(held: {
|
|
|
85
96
|
readonly created_at?: unknown;
|
|
86
97
|
}): HeadChange | undefined | null;
|
|
87
98
|
export declare function binaryFileOf(held: Readonly<Record<string, unknown>>): BinaryFile | undefined | null;
|
|
88
|
-
export declare function
|
|
89
|
-
export declare function
|
|
90
|
-
export declare function
|
|
91
|
-
export declare function
|
|
99
|
+
export declare function parseParted(body: unknown): HouseParted | null;
|
|
100
|
+
export declare function parseSiteParted(body: unknown): HouseRoomParts | null;
|
|
101
|
+
export declare function emptyScope(room: HouseRoomParts): HouseScope;
|
|
102
|
+
export declare function housePart(room: HouseRoomParts, body: unknown, listed: HousePart, mode: HouseMode): Promise<HouseScope | TransportUncertainty | null>;
|
|
92
103
|
export declare function parseEnumeration(body: unknown, mode: HouseMode): HouseEnumeration | null;
|
|
93
104
|
export declare function wholeView(first: HouseView, more: (page: HousePage) => Promise<HouseView | PageFailure>): Promise<HouseView | PageFailure>;
|
|
94
|
-
export declare function advancedScope(scope: HouseScope, view: HouseView): HouseScope
|
|
95
|
-
export declare function
|
|
96
|
-
export declare function bootstrapOf(scope: HouseScope): BootstrapPage;
|
|
105
|
+
export declare function advancedScope(scope: HouseScope, view: HouseView): Generator<number, HouseScope, void>;
|
|
106
|
+
export declare function bootstrapping(scope: HouseScope): Generator<number, BootstrapPage, void>;
|
|
97
107
|
export type HouseSchema = {
|
|
98
108
|
schema: string | null;
|
|
99
109
|
version: string | null;
|
|
@@ -101,6 +111,6 @@ export type HouseSchema = {
|
|
|
101
111
|
};
|
|
102
112
|
export declare function schemaOf(scope: HouseScope, schema: string): HouseSchema | null;
|
|
103
113
|
export declare function viewOf(enumeration: HouseEnumeration, tracked: TrackedAuthority): HouseView | undefined;
|
|
104
|
-
export declare function refreshFrom(view: HouseView, fromRoomVersion: string): RefreshResult
|
|
114
|
+
export declare function refreshFrom(view: HouseView, fromRoomVersion: string): Promise<RefreshResult>;
|
|
105
115
|
export {};
|
|
106
116
|
//# 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,KAAK,
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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"}
|
package/dist/read.js
CHANGED
|
@@ -1,21 +1,52 @@
|
|
|
1
|
+
import { patching, ROW_WEIGHT, stepped, } from '@agentshouse/mdruntime';
|
|
2
|
+
import { checkedPayload, gunzipped, parsePart } from './part.js';
|
|
1
3
|
import { DECIMAL, readPosition, roomVersion } from './version.js';
|
|
2
4
|
const REVISION_FILE = /^fr_([0-9a-z]+)\.[0-9a-z]+\.[0-9a-z]$/u;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
function fileOf(revision) {
|
|
6
|
+
return REVISION_FILE.exec(revision)?.[1];
|
|
7
|
+
}
|
|
8
|
+
export function answering() {
|
|
9
|
+
return {
|
|
10
|
+
documents: new Map(),
|
|
11
|
+
revisions: new Map(),
|
|
12
|
+
fileIds: new Map(),
|
|
13
|
+
changes: new Map(),
|
|
14
|
+
binaryFiles: new Map(),
|
|
15
|
+
removals: new Set(),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function revised(answer, path, revision) {
|
|
19
|
+
answer.revisions.set(path, revision);
|
|
20
|
+
const file = fileOf(revision);
|
|
21
|
+
if (file !== undefined)
|
|
22
|
+
answer.fileIds.set(path, file);
|
|
23
|
+
}
|
|
24
|
+
export function forgotten(answer, path) {
|
|
25
|
+
answer.documents.delete(path);
|
|
26
|
+
answer.revisions.delete(path);
|
|
27
|
+
answer.fileIds.delete(path);
|
|
28
|
+
answer.changes.delete(path);
|
|
29
|
+
answer.binaryFiles.delete(path);
|
|
30
|
+
answer.removals.delete(path);
|
|
31
|
+
}
|
|
32
|
+
export function* answered(answer) {
|
|
33
|
+
const removals = [];
|
|
34
|
+
for (const path of answer.removals) {
|
|
35
|
+
removals.push(path);
|
|
36
|
+
yield ROW_WEIGHT;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
documents: yield* patching({}, answer.documents),
|
|
40
|
+
revisions: yield* patching({}, answer.revisions),
|
|
41
|
+
...(answer.fileIds.size === 0 ? {} : { fileIds: yield* patching({}, answer.fileIds) }),
|
|
42
|
+
changes: yield* patching({}, answer.changes),
|
|
43
|
+
binaryFiles: yield* patching({}, answer.binaryFiles),
|
|
44
|
+
removals,
|
|
45
|
+
};
|
|
9
46
|
}
|
|
10
47
|
export function authorityRoot(handle) {
|
|
11
48
|
return `/rooms/${handle}`;
|
|
12
49
|
}
|
|
13
|
-
export function contentPrefixes(tracked) {
|
|
14
|
-
return [
|
|
15
|
-
authorityRoot(tracked.handle),
|
|
16
|
-
...tracked.schemas.map((schema) => schemaPath(tracked.handle, schema)),
|
|
17
|
-
];
|
|
18
|
-
}
|
|
19
50
|
export function schemaPath(handle, schema) {
|
|
20
51
|
return `${authorityRoot(handle)}/${schema}`;
|
|
21
52
|
}
|
|
@@ -105,13 +136,13 @@ function parseFile(value, mode) {
|
|
|
105
136
|
...binaried(binary),
|
|
106
137
|
};
|
|
107
138
|
}
|
|
108
|
-
function
|
|
139
|
+
function parseRoomParts(value) {
|
|
109
140
|
if (typeof value !== 'object' || value === null)
|
|
110
141
|
return null;
|
|
111
142
|
const held = value;
|
|
112
143
|
if (typeof held.manifest !== 'object' || held.manifest === null)
|
|
113
144
|
return null;
|
|
114
|
-
if (!Array.isArray(held.
|
|
145
|
+
if (!Array.isArray(held.parts))
|
|
115
146
|
return null;
|
|
116
147
|
const manifest = held.manifest;
|
|
117
148
|
if (manifest.scope !== 'room')
|
|
@@ -121,78 +152,89 @@ function parseScope(value, mode) {
|
|
|
121
152
|
return null;
|
|
122
153
|
if (typeof manifest.room_handle !== 'string' || manifest.room_handle.length === 0)
|
|
123
154
|
return null;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const file = parseFile(entry, mode);
|
|
129
|
-
if (file === null)
|
|
130
|
-
return null;
|
|
131
|
-
files.push(file);
|
|
132
|
-
}
|
|
133
|
-
const contents = [];
|
|
134
|
-
for (const entry of held.contents) {
|
|
135
|
-
if (typeof entry !== 'object' || entry === null)
|
|
155
|
+
const parts = [];
|
|
156
|
+
for (const entry of held.parts) {
|
|
157
|
+
const part = parsePart(entry);
|
|
158
|
+
if (part === null)
|
|
136
159
|
return null;
|
|
137
|
-
|
|
138
|
-
if (typeof content.path !== 'string' || typeof content.content !== 'string')
|
|
139
|
-
return null;
|
|
140
|
-
contents.push({ path: content.path, content: content.content });
|
|
160
|
+
parts.push(part);
|
|
141
161
|
}
|
|
142
|
-
return { anchor: manifest.anchor, ...at,
|
|
143
|
-
}
|
|
144
|
-
function parseCut(value) {
|
|
145
|
-
if (value === undefined)
|
|
146
|
-
return undefined;
|
|
147
|
-
if (typeof value !== 'object' || value === null)
|
|
148
|
-
return null;
|
|
149
|
-
const { position, log_epoch: logEpoch } = value;
|
|
150
|
-
if (typeof position !== 'string' || typeof logEpoch !== 'string')
|
|
151
|
-
return null;
|
|
152
|
-
return { position, log_epoch: logEpoch };
|
|
162
|
+
return { anchor: manifest.anchor, ...at, parts };
|
|
153
163
|
}
|
|
154
|
-
function
|
|
155
|
-
if (typeof value !== 'object' || value === null)
|
|
156
|
-
return null;
|
|
157
|
-
const { room, path, cut } = value;
|
|
158
|
-
if (typeof room !== 'string' || (path !== null && typeof path !== 'string'))
|
|
159
|
-
return null;
|
|
160
|
-
const parsed = parseCut(cut);
|
|
161
|
-
if (parsed === null)
|
|
162
|
-
return null;
|
|
163
|
-
return { room, path, ...(parsed === undefined ? {} : { cut: parsed }) };
|
|
164
|
-
}
|
|
165
|
-
export function parseEnvelope(body) {
|
|
164
|
+
export function parseParted(body) {
|
|
166
165
|
if (typeof body !== 'object' || body === null)
|
|
167
166
|
return null;
|
|
168
167
|
if (!('scopes' in body) || !Array.isArray(body.scopes))
|
|
169
168
|
return null;
|
|
170
|
-
const
|
|
169
|
+
const rooms = [];
|
|
171
170
|
for (const entry of body.scopes) {
|
|
172
|
-
const
|
|
173
|
-
if (
|
|
171
|
+
const room = parseRoomParts(entry);
|
|
172
|
+
if (room === null)
|
|
174
173
|
return null;
|
|
175
|
-
|
|
174
|
+
rooms.push(room);
|
|
176
175
|
}
|
|
177
176
|
if (!('next' in body) || body.next === undefined)
|
|
178
|
-
return {
|
|
179
|
-
const next =
|
|
180
|
-
|
|
177
|
+
return { rooms };
|
|
178
|
+
const next = body.next;
|
|
179
|
+
if (typeof next !== 'object' || next === null || typeof next.room !== 'string')
|
|
180
|
+
return null;
|
|
181
|
+
return { rooms, next: next.room };
|
|
181
182
|
}
|
|
182
|
-
export function
|
|
183
|
-
return
|
|
183
|
+
export function parseSiteParted(body) {
|
|
184
|
+
return parseRoomParts(body);
|
|
184
185
|
}
|
|
185
|
-
export function
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
export function emptyScope(room) {
|
|
187
|
+
return {
|
|
188
|
+
anchor: room.anchor,
|
|
189
|
+
position: room.position,
|
|
190
|
+
logEpoch: room.logEpoch,
|
|
191
|
+
files: [],
|
|
192
|
+
contents: [],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function* partLines(text, mode) {
|
|
196
|
+
const files = [];
|
|
197
|
+
const contents = [];
|
|
198
|
+
let start = 0;
|
|
199
|
+
while (start < text.length) {
|
|
200
|
+
const end = text.indexOf('\n', start);
|
|
201
|
+
if (end === -1)
|
|
202
|
+
return null;
|
|
203
|
+
let entry;
|
|
204
|
+
try {
|
|
205
|
+
entry = JSON.parse(text.slice(start, end));
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
start = end + 1;
|
|
211
|
+
if (folderLine(entry))
|
|
212
|
+
continue;
|
|
213
|
+
const file = parseFile(entry, mode);
|
|
214
|
+
if (file === null)
|
|
215
|
+
return null;
|
|
216
|
+
files.push(file);
|
|
217
|
+
const { content } = entry;
|
|
218
|
+
if (typeof content === 'string')
|
|
219
|
+
contents.push({ path: file.path, content });
|
|
220
|
+
else if (content !== undefined)
|
|
221
|
+
return null;
|
|
222
|
+
yield ROW_WEIGHT;
|
|
223
|
+
}
|
|
224
|
+
return { files, contents };
|
|
225
|
+
}
|
|
226
|
+
function folderLine(entry) {
|
|
227
|
+
if (typeof entry !== 'object' || entry === null || !('folder' in entry))
|
|
228
|
+
return false;
|
|
229
|
+
return typeof entry.folder === 'string' && Object.keys(entry).length === 1;
|
|
189
230
|
}
|
|
190
|
-
export function
|
|
191
|
-
|
|
231
|
+
export async function housePart(room, body, listed, mode) {
|
|
232
|
+
const payload = await checkedPayload(body, listed);
|
|
233
|
+
if (payload === null)
|
|
192
234
|
return null;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
235
|
+
const text = await gunzipped(payload);
|
|
236
|
+
const read = text === null ? null : await stepped(partLines(text, mode));
|
|
237
|
+
return read === null ? { kind: 'transport-uncertainty' } : { ...emptyScope(room), ...read };
|
|
196
238
|
}
|
|
197
239
|
function parseChange(value, mode) {
|
|
198
240
|
if (typeof value !== 'object' || value === null)
|
|
@@ -310,12 +352,21 @@ export async function wholeView(first, more) {
|
|
|
310
352
|
changes: [...changes.values()],
|
|
311
353
|
};
|
|
312
354
|
}
|
|
313
|
-
export function advancedScope(scope, view) {
|
|
314
|
-
const files = new Map(
|
|
315
|
-
const
|
|
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
|
+
}
|
|
316
366
|
for (const change of view.changes) {
|
|
317
367
|
files.delete(change.path);
|
|
318
368
|
contents.delete(change.path);
|
|
369
|
+
yield ROW_WEIGHT;
|
|
319
370
|
if ('removed' in change)
|
|
320
371
|
continue;
|
|
321
372
|
files.set(change.path, {
|
|
@@ -328,43 +379,40 @@ export function advancedScope(scope, view) {
|
|
|
328
379
|
if ('content' in change)
|
|
329
380
|
contents.set(change.path, change.content);
|
|
330
381
|
}
|
|
382
|
+
const listed = [];
|
|
383
|
+
for (const [path, content] of contents) {
|
|
384
|
+
listed.push({ path, content });
|
|
385
|
+
yield ROW_WEIGHT;
|
|
386
|
+
}
|
|
331
387
|
return {
|
|
332
388
|
...scope,
|
|
333
389
|
position: view.position,
|
|
334
390
|
logEpoch: view.logEpoch,
|
|
335
391
|
files: [...files.values()],
|
|
336
|
-
contents:
|
|
392
|
+
contents: listed,
|
|
337
393
|
};
|
|
338
394
|
}
|
|
339
|
-
export function
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const
|
|
346
|
-
const changes = {};
|
|
347
|
-
const binaryFiles = {};
|
|
395
|
+
export function* bootstrapping(scope) {
|
|
396
|
+
const contents = new Map();
|
|
397
|
+
for (const entry of scope.contents) {
|
|
398
|
+
contents.set(entry.path, entry.content);
|
|
399
|
+
yield ROW_WEIGHT;
|
|
400
|
+
}
|
|
401
|
+
const answer = answering();
|
|
348
402
|
for (const file of scope.files) {
|
|
349
|
-
|
|
350
|
-
revisions[file.path] = file.revision;
|
|
403
|
+
yield ROW_WEIGHT;
|
|
351
404
|
if (file.head !== undefined)
|
|
352
|
-
changes
|
|
405
|
+
answer.changes.set(file.path, file.head);
|
|
353
406
|
const content = contents.get(file.path);
|
|
354
407
|
if (file.binary !== undefined)
|
|
355
|
-
binaryFiles
|
|
408
|
+
answer.binaryFiles.set(file.path, file.binary);
|
|
356
409
|
else if (content !== undefined)
|
|
357
|
-
documents
|
|
410
|
+
answer.documents.set(file.path, content);
|
|
411
|
+
if (file.revision !== undefined)
|
|
412
|
+
revised(answer, file.path, file.revision);
|
|
358
413
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
roomVersion: roomVersion(scope),
|
|
362
|
-
documents,
|
|
363
|
-
revisions,
|
|
364
|
-
...identities(revisions),
|
|
365
|
-
changes,
|
|
366
|
-
binaryFiles,
|
|
367
|
-
};
|
|
414
|
+
const { removals: _removals, ...page } = yield* answered(answer);
|
|
415
|
+
return { kind: 'bootstrap', roomVersion: roomVersion(scope), ...page };
|
|
368
416
|
}
|
|
369
417
|
export function schemaOf(scope, schema) {
|
|
370
418
|
const file = scope.files.find((entry) => entry.path === schema);
|
|
@@ -378,36 +426,27 @@ export function schemaOf(scope, schema) {
|
|
|
378
426
|
export function viewOf(enumeration, tracked) {
|
|
379
427
|
return enumeration.authorities.find((entry) => entry.authority === tracked.authority);
|
|
380
428
|
}
|
|
381
|
-
|
|
429
|
+
function* refreshing(view, fromRoomVersion) {
|
|
382
430
|
if (roomVersion(view) === fromRoomVersion)
|
|
383
431
|
return { kind: 'still-current' };
|
|
384
|
-
const
|
|
385
|
-
const revisions = {};
|
|
386
|
-
const changes = {};
|
|
387
|
-
const binaryFiles = {};
|
|
388
|
-
const removals = [];
|
|
432
|
+
const answer = answering();
|
|
389
433
|
for (const change of view.changes) {
|
|
434
|
+
yield ROW_WEIGHT;
|
|
390
435
|
if ('removed' in change) {
|
|
391
|
-
removals.
|
|
436
|
+
answer.removals.add(change.path);
|
|
392
437
|
continue;
|
|
393
438
|
}
|
|
394
439
|
if ('content' in change)
|
|
395
|
-
documents
|
|
440
|
+
answer.documents.set(change.path, change.content);
|
|
396
441
|
else
|
|
397
|
-
binaryFiles
|
|
398
|
-
if (change.revision !== undefined)
|
|
399
|
-
revisions[change.path] = change.revision;
|
|
442
|
+
answer.binaryFiles.set(change.path, change.binary);
|
|
400
443
|
if (change.head !== undefined)
|
|
401
|
-
changes
|
|
444
|
+
answer.changes.set(change.path, change.head);
|
|
445
|
+
if (change.revision !== undefined)
|
|
446
|
+
revised(answer, change.path, change.revision);
|
|
402
447
|
}
|
|
403
|
-
return {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
revisions,
|
|
408
|
-
...identities(revisions),
|
|
409
|
-
changes,
|
|
410
|
-
binaryFiles,
|
|
411
|
-
removals: removals.sort(),
|
|
412
|
-
};
|
|
448
|
+
return { kind: 'net-advancement', roomVersion: roomVersion(view), ...(yield* answered(answer)) };
|
|
449
|
+
}
|
|
450
|
+
export async function refreshFrom(view, fromRoomVersion) {
|
|
451
|
+
return stepped(refreshing(view, fromRoomVersion));
|
|
413
452
|
}
|