@agentshouse/mdruntime 0.1.0-alpha.2 → 0.1.0-alpha.3
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/dist/adapter.d.ts +12 -10
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/bootstrap.d.ts +5 -12
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +13 -20
- package/dist/bootstrap.js.map +1 -1
- package/dist/change.d.ts +64 -0
- package/dist/change.d.ts.map +1 -0
- package/dist/change.js +12 -0
- package/dist/change.js.map +1 -0
- package/dist/collection.d.ts +1 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +10 -6
- package/dist/collection.js.map +1 -1
- package/dist/connection.d.ts +19 -0
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +238 -32
- package/dist/connection.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +1 -0
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +67 -6
- package/dist/memory.js.map +1 -1
- package/dist/overlay.d.ts +8 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +139 -0
- package/dist/overlay.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +47 -0
- package/dist/paths.js.map +1 -0
- package/dist/refresh.d.ts +13 -0
- package/dist/refresh.d.ts.map +1 -0
- package/dist/refresh.js +63 -0
- package/dist/refresh.js.map +1 -0
- package/dist/replica.d.ts +19 -0
- package/dist/replica.d.ts.map +1 -0
- package/dist/replica.js +36 -0
- package/dist/replica.js.map +1 -0
- package/dist/save.d.ts +26 -0
- package/dist/save.d.ts.map +1 -0
- package/dist/save.js +496 -0
- package/dist/save.js.map +1 -0
- package/dist/status.d.ts +15 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +29 -0
- package/dist/status.js.map +1 -0
- package/dist/store.d.ts +21 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +77 -2
- package/dist/store.js.map +1 -1
- package/dist/transfer.d.ts +5 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transfer.js +5 -0
- package/dist/transfer.js.map +1 -0
- package/package.json +3 -3
package/dist/memory.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ROOM_CONTRACT_VERSION } from './adapter.js';
|
|
2
2
|
import { MD_MODEL } from './collection.js';
|
|
3
|
+
function named(source, paths) {
|
|
4
|
+
const taken = {};
|
|
5
|
+
for (const path of paths){
|
|
6
|
+
const value = source[path];
|
|
7
|
+
if (value !== undefined) taken[path] = value;
|
|
8
|
+
}
|
|
9
|
+
return taken;
|
|
10
|
+
}
|
|
3
11
|
async function resolveScript(answer, fallback, request) {
|
|
4
12
|
if (answer === undefined) return fallback();
|
|
5
13
|
return typeof answer === 'function' ? answer(request) : answer;
|
|
@@ -24,6 +32,16 @@ export function createMemoryAdapter(options = {}) {
|
|
|
24
32
|
];
|
|
25
33
|
const pageSize = options.pageSize;
|
|
26
34
|
const scripts = {};
|
|
35
|
+
const served = new Map();
|
|
36
|
+
const refreshPages = new Map();
|
|
37
|
+
function retain(entries) {
|
|
38
|
+
for (const room of entries){
|
|
39
|
+
const versions = served.get(room.locator) ?? new Map();
|
|
40
|
+
versions.set(room.roomVersion, room);
|
|
41
|
+
served.set(room.locator, versions);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
retain(rooms);
|
|
27
45
|
function declared(room) {
|
|
28
46
|
return {
|
|
29
47
|
name: room.name,
|
|
@@ -37,19 +55,53 @@ export function createMemoryAdapter(options = {}) {
|
|
|
37
55
|
const paths = Object.keys(room.documents ?? {}).sort();
|
|
38
56
|
const size = pageSize ?? paths.length;
|
|
39
57
|
const taken = paths.slice(from, from + size);
|
|
40
|
-
const documents = {};
|
|
41
|
-
for (const path of taken)documents[path] = (room.documents ?? {})[path];
|
|
42
58
|
const next = from + taken.length;
|
|
43
59
|
return {
|
|
44
60
|
kind: 'bootstrap',
|
|
45
61
|
roomVersion: room.roomVersion,
|
|
46
|
-
documents,
|
|
62
|
+
documents: named(room.documents ?? {}, taken),
|
|
63
|
+
revisions: named(room.revisions ?? {}, taken),
|
|
47
64
|
binaryTargets: from === 0 ? room.binaryTargets ?? [] : [],
|
|
48
65
|
...next < paths.length ? {
|
|
49
66
|
pageToken: String(next)
|
|
50
67
|
} : {}
|
|
51
68
|
};
|
|
52
69
|
}
|
|
70
|
+
function advancement(room, from, at) {
|
|
71
|
+
const current = room.documents ?? {};
|
|
72
|
+
const previous = from.documents ?? {};
|
|
73
|
+
const currentTargets = new Set(room.binaryTargets ?? []);
|
|
74
|
+
const previousTargets = new Set(from.binaryTargets ?? []);
|
|
75
|
+
const changed = Object.keys(current).filter((path)=>current[path] !== previous[path]).sort();
|
|
76
|
+
const size = pageSize ?? changed.length;
|
|
77
|
+
const taken = changed.slice(at, at + size);
|
|
78
|
+
const next = at + taken.length;
|
|
79
|
+
const opening = at === 0;
|
|
80
|
+
const pageToken = next < changed.length ? `refresh-${refreshPages.size}` : undefined;
|
|
81
|
+
if (pageToken !== undefined) refreshPages.set(pageToken, {
|
|
82
|
+
room,
|
|
83
|
+
from,
|
|
84
|
+
at: next
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
kind: 'net-advancement',
|
|
88
|
+
roomVersion: room.roomVersion,
|
|
89
|
+
documents: named(current, taken),
|
|
90
|
+
revisions: named(room.revisions ?? {}, taken),
|
|
91
|
+
binaryTargets: opening ? [
|
|
92
|
+
...currentTargets
|
|
93
|
+
].filter((target)=>!previousTargets.has(target)) : [],
|
|
94
|
+
removals: opening ? [
|
|
95
|
+
...Object.keys(previous).filter((path)=>!(path in current) && !currentTargets.has(path)),
|
|
96
|
+
...[
|
|
97
|
+
...previousTargets
|
|
98
|
+
].filter((target)=>!currentTargets.has(target) && !(target in current))
|
|
99
|
+
].sort() : [],
|
|
100
|
+
...pageToken === undefined ? {} : {
|
|
101
|
+
pageToken
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
53
105
|
function discovery() {
|
|
54
106
|
return {
|
|
55
107
|
kind: 'discovery',
|
|
@@ -67,6 +119,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
67
119
|
rooms = [
|
|
68
120
|
...next
|
|
69
121
|
];
|
|
122
|
+
retain(rooms);
|
|
70
123
|
},
|
|
71
124
|
script (operation, answer) {
|
|
72
125
|
if (answer === undefined) delete scripts[operation];
|
|
@@ -99,15 +152,23 @@ export function createMemoryAdapter(options = {}) {
|
|
|
99
152
|
locator: request.locator
|
|
100
153
|
};
|
|
101
154
|
}
|
|
155
|
+
if (request.pageToken !== undefined) {
|
|
156
|
+
const continuation = refreshPages.get(request.pageToken);
|
|
157
|
+
if (continuation === undefined || continuation.room.locator !== request.locator || continuation.from.roomVersion !== request.fromRoomVersion) {
|
|
158
|
+
throw new Error('Invalid Refresh Page Token');
|
|
159
|
+
}
|
|
160
|
+
return advancement(continuation.room, continuation.from, continuation.at);
|
|
161
|
+
}
|
|
102
162
|
if (request.fromRoomVersion === room.roomVersion) {
|
|
103
163
|
return {
|
|
104
164
|
kind: 'still-current'
|
|
105
165
|
};
|
|
106
166
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
167
|
+
const from = served.get(room.locator)?.get(request.fromRoomVersion);
|
|
168
|
+
if (from === undefined) return {
|
|
169
|
+
kind: 'beyond-horizon'
|
|
110
170
|
};
|
|
171
|
+
return advancement(room, from, 0);
|
|
111
172
|
}, request);
|
|
112
173
|
},
|
|
113
174
|
async mutate (_authorization, request) {
|
package/dist/memory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/workspace/packages/mdruntime/src/memory.ts"],"sourcesContent":["import {\n ROOM_CONTRACT_VERSION,\n type ActionRequest,\n type ActionResult,\n type Adapter,\n type Authorization,\n type BootstrapRequest,\n type BootstrapResult,\n type Capability,\n type DiscoverResult,\n type DiscoveredRoom,\n type HistoryRequest,\n type HistoryResult,\n type MdModelIdentity,\n type MutationRequest,\n type MutationResult,\n type ProviderLimit,\n type RefreshRequest,\n type RefreshResult,\n type Retention,\n} from './adapter.js';\nimport { MD_MODEL } from './collection.js';\n\nexport type MemoryRoom = DiscoveredRoom & {\n documents?: Readonly<Record<string, string>>;\n binaryTargets?: readonly string[];\n};\n\nexport type MemoryAdapterOptions = {\n rooms?: readonly MemoryRoom[];\n pageSize?: number;\n mdModel?: MdModelIdentity;\n supportedVersions?: readonly number[];\n capabilities?: readonly Capability[];\n providerLimits?: readonly ProviderLimit[];\n retention?: Retention;\n origins?: readonly string[];\n};\n\nexport type MemoryAdapter = Adapter & {\n setRooms(rooms: readonly MemoryRoom[]): void;\n script(operation: keyof Adapter, answer: unknown): void;\n};\n\ntype Script<T, R> = T | ((request: R) => T | Promise<T>);\n\nasync function resolveScript<T, R>(\n answer: Script<T, R> | undefined,\n fallback: () => T | Promise<T>,\n request: R,\n) {\n if (answer === undefined) return fallback();\n return typeof answer === 'function' ? (answer as (value: R) => T | Promise<T>)(request) : answer;\n}\n\nexport function createMemoryAdapter(options: MemoryAdapterOptions = {}): MemoryAdapter {\n let rooms = options.rooms === undefined ? [] : [...options.rooms];\n const mdModel = options.mdModel ?? MD_MODEL;\n const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];\n const capabilities = options.capabilities ?? [];\n const providerLimits = options.providerLimits ?? [];\n const retention = options.retention ?? { history: 1, outcome: 1, refreshHorizon: 1 };\n const origins = options.origins ?? ['https://origin.example'];\n const pageSize = options.pageSize;\n const scripts: Partial<Record<keyof Adapter, unknown>> = {};\n\n function declared(room: MemoryRoom): DiscoveredRoom {\n return {\n name: room.name,\n locator: room.locator,\n roomVersion: room.roomVersion,\n writeGrants: room.writeGrants,\n providerOwnedPaths: room.providerOwnedPaths,\n };\n }\n\n function page(room: MemoryRoom, from: number): BootstrapResult {\n const paths = Object.keys(room.documents ?? {}).sort();\n const size = pageSize ?? paths.length;\n const taken = paths.slice(from, from + size);\n const documents: Record<string, string> = {};\n for (const path of taken) documents[path] = (room.documents ?? {})[path];\n const next = from + taken.length;\n return {\n kind: 'bootstrap',\n roomVersion: room.roomVersion,\n documents,\n binaryTargets: from === 0 ? (room.binaryTargets ?? []) : [],\n ...(next < paths.length ? { pageToken: String(next) } : {}),\n };\n }\n\n function discovery(): DiscoverResult {\n return {\n kind: 'discovery',\n supportedVersions,\n mdModel,\n rooms: rooms.map(declared),\n capabilities,\n providerLimits,\n retention,\n origins,\n };\n }\n\n return {\n setRooms(next) {\n rooms = [...next];\n },\n script(operation, answer) {\n if (answer === undefined) delete scripts[operation];\n else scripts[operation] = answer;\n },\n async authorize() {\n return resolveScript<Authorization, void>(\n scripts.authorize as Script<Authorization, void> | undefined,\n () => ({}),\n undefined,\n );\n },\n async discover(_authorization: Authorization) {\n return resolveScript<DiscoverResult, void>(\n scripts.discover as Script<DiscoverResult, void> | undefined,\n discovery,\n undefined,\n );\n },\n async bootstrap(_authorization: Authorization, request: BootstrapRequest) {\n return resolveScript<BootstrapResult, BootstrapRequest>(\n scripts.bootstrap as Script<BootstrapResult, BootstrapRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));\n },\n request,\n );\n },\n async refresh(_authorization: Authorization, request: RefreshRequest) {\n return resolveScript<RefreshResult, RefreshRequest>(\n scripts.refresh as Script<RefreshResult, RefreshRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n if (request.fromRoomVersion === room.roomVersion) {\n return { kind: 'still-current' };\n }\n return { kind: 'net-advancement', roomVersion: room.roomVersion };\n },\n request,\n );\n },\n async mutate(_authorization: Authorization, request: MutationRequest) {\n return resolveScript<MutationResult, MutationRequest>(\n scripts.mutate as Script<MutationResult, MutationRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n return { kind: 'rejected', text: '' };\n },\n request,\n );\n },\n async history(_authorization: Authorization, request: HistoryRequest) {\n return resolveScript<HistoryResult, HistoryRequest>(\n scripts.history as Script<HistoryResult, HistoryRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n return {\n kind: 'history',\n revisions: [],\n };\n },\n request,\n );\n },\n async action(_authorization: Authorization, request: ActionRequest) {\n return resolveScript<ActionResult, ActionRequest>(\n scripts.action as Script<ActionResult, ActionRequest> | undefined,\n () => ({\n kind: 'rejected',\n text: '',\n }),\n request,\n );\n },\n };\n}\n"],"names":["ROOM_CONTRACT_VERSION","MD_MODEL","resolveScript","answer","fallback","request","undefined","createMemoryAdapter","options","rooms","mdModel","supportedVersions","capabilities","providerLimits","retention","history","outcome","refreshHorizon","origins","pageSize","scripts","declared","room","name","locator","roomVersion","writeGrants","providerOwnedPaths","page","from","paths","Object","keys","documents","sort","size","length","taken","slice","path","next","kind","binaryTargets","pageToken","String","discovery","map","setRooms","script","operation","authorize","discover","_authorization","bootstrap","find","entry","Number","refresh","fromRoomVersion","mutate","text","revisions","action"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/memory.ts"],"sourcesContent":["import {\n ROOM_CONTRACT_VERSION,\n type ActionRequest,\n type ActionResult,\n type Adapter,\n type Authorization,\n type BootstrapRequest,\n type BootstrapResult,\n type Capability,\n type DiscoverResult,\n type DiscoveredRoom,\n type HistoryRequest,\n type HistoryResult,\n type MdModelIdentity,\n type MutationRequest,\n type MutationResult,\n type ProviderLimit,\n type RefreshRequest,\n type RefreshResult,\n type Retention,\n} from './adapter.js';\nimport { MD_MODEL } from './collection.js';\n\nexport type MemoryRoom = DiscoveredRoom & {\n documents?: Readonly<Record<string, string>>;\n revisions?: Readonly<Record<string, string>>;\n binaryTargets?: readonly string[];\n};\n\nexport type MemoryAdapterOptions = {\n rooms?: readonly MemoryRoom[];\n pageSize?: number;\n mdModel?: MdModelIdentity;\n supportedVersions?: readonly number[];\n capabilities?: readonly Capability[];\n providerLimits?: readonly ProviderLimit[];\n retention?: Retention;\n origins?: readonly string[];\n};\n\nexport type MemoryAdapter = Adapter & {\n setRooms(rooms: readonly MemoryRoom[]): void;\n script(operation: keyof Adapter, answer: unknown): void;\n};\n\ntype Script<T, R> = T | ((request: R) => T | Promise<T>);\n\ntype RefreshContinuation = {\n room: MemoryRoom;\n from: MemoryRoom;\n at: number;\n};\n\nfunction named(\n source: Readonly<Record<string, string>>,\n paths: readonly string[],\n): Readonly<Record<string, string>> {\n const taken: Record<string, string> = {};\n for (const path of paths) {\n const value = source[path];\n if (value !== undefined) taken[path] = value;\n }\n return taken;\n}\n\nasync function resolveScript<T, R>(\n answer: Script<T, R> | undefined,\n fallback: () => T | Promise<T>,\n request: R,\n) {\n if (answer === undefined) return fallback();\n return typeof answer === 'function' ? (answer as (value: R) => T | Promise<T>)(request) : answer;\n}\n\nexport function createMemoryAdapter(options: MemoryAdapterOptions = {}): MemoryAdapter {\n let rooms = options.rooms === undefined ? [] : [...options.rooms];\n const mdModel = options.mdModel ?? MD_MODEL;\n const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];\n const capabilities = options.capabilities ?? [];\n const providerLimits = options.providerLimits ?? [];\n const retention = options.retention ?? { history: 1, outcome: 1, refreshHorizon: 1 };\n const origins = options.origins ?? ['https://origin.example'];\n const pageSize = options.pageSize;\n const scripts: Partial<Record<keyof Adapter, unknown>> = {};\n const served = new Map<string, Map<string, MemoryRoom>>();\n const refreshPages = new Map<string, RefreshContinuation>();\n\n function retain(entries: readonly MemoryRoom[]) {\n for (const room of entries) {\n const versions = served.get(room.locator) ?? new Map<string, MemoryRoom>();\n versions.set(room.roomVersion, room);\n served.set(room.locator, versions);\n }\n }\n\n retain(rooms);\n\n function declared(room: MemoryRoom): DiscoveredRoom {\n return {\n name: room.name,\n locator: room.locator,\n roomVersion: room.roomVersion,\n writeGrants: room.writeGrants,\n providerOwnedPaths: room.providerOwnedPaths,\n };\n }\n\n function page(room: MemoryRoom, from: number): BootstrapResult {\n const paths = Object.keys(room.documents ?? {}).sort();\n const size = pageSize ?? paths.length;\n const taken = paths.slice(from, from + size);\n const next = from + taken.length;\n return {\n kind: 'bootstrap',\n roomVersion: room.roomVersion,\n documents: named(room.documents ?? {}, taken),\n revisions: named(room.revisions ?? {}, taken),\n binaryTargets: from === 0 ? (room.binaryTargets ?? []) : [],\n ...(next < paths.length ? { pageToken: String(next) } : {}),\n };\n }\n\n function advancement(room: MemoryRoom, from: MemoryRoom, at: number): RefreshResult {\n const current = room.documents ?? {};\n const previous = from.documents ?? {};\n const currentTargets = new Set(room.binaryTargets ?? []);\n const previousTargets = new Set(from.binaryTargets ?? []);\n const changed = Object.keys(current)\n .filter((path) => current[path] !== previous[path])\n .sort();\n const size = pageSize ?? changed.length;\n const taken = changed.slice(at, at + size);\n const next = at + taken.length;\n const opening = at === 0;\n const pageToken = next < changed.length ? `refresh-${refreshPages.size}` : undefined;\n if (pageToken !== undefined) refreshPages.set(pageToken, { room, from, at: next });\n return {\n kind: 'net-advancement',\n roomVersion: room.roomVersion,\n documents: named(current, taken),\n revisions: named(room.revisions ?? {}, taken),\n binaryTargets: opening\n ? [...currentTargets].filter((target) => !previousTargets.has(target))\n : [],\n removals: opening\n ? [\n ...Object.keys(previous).filter(\n (path) => !(path in current) && !currentTargets.has(path),\n ),\n ...[...previousTargets].filter(\n (target) => !currentTargets.has(target) && !(target in current),\n ),\n ].sort()\n : [],\n ...(pageToken === undefined ? {} : { pageToken }),\n };\n }\n\n function discovery(): DiscoverResult {\n return {\n kind: 'discovery',\n supportedVersions,\n mdModel,\n rooms: rooms.map(declared),\n capabilities,\n providerLimits,\n retention,\n origins,\n };\n }\n\n return {\n setRooms(next) {\n rooms = [...next];\n retain(rooms);\n },\n script(operation, answer) {\n if (answer === undefined) delete scripts[operation];\n else scripts[operation] = answer;\n },\n async authorize() {\n return resolveScript<Authorization, void>(\n scripts.authorize as Script<Authorization, void> | undefined,\n () => ({}),\n undefined,\n );\n },\n async discover(_authorization: Authorization) {\n return resolveScript<DiscoverResult, void>(\n scripts.discover as Script<DiscoverResult, void> | undefined,\n discovery,\n undefined,\n );\n },\n async bootstrap(_authorization: Authorization, request: BootstrapRequest) {\n return resolveScript<BootstrapResult, BootstrapRequest>(\n scripts.bootstrap as Script<BootstrapResult, BootstrapRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));\n },\n request,\n );\n },\n async refresh(_authorization: Authorization, request: RefreshRequest) {\n return resolveScript<RefreshResult, RefreshRequest>(\n scripts.refresh as Script<RefreshResult, RefreshRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n if (request.pageToken !== undefined) {\n const continuation = refreshPages.get(request.pageToken);\n if (\n continuation === undefined ||\n continuation.room.locator !== request.locator ||\n continuation.from.roomVersion !== request.fromRoomVersion\n ) {\n throw new Error('Invalid Refresh Page Token');\n }\n return advancement(continuation.room, continuation.from, continuation.at);\n }\n if (request.fromRoomVersion === room.roomVersion) {\n return { kind: 'still-current' };\n }\n const from = served.get(room.locator)?.get(request.fromRoomVersion);\n if (from === undefined) return { kind: 'beyond-horizon' };\n return advancement(room, from, 0);\n },\n request,\n );\n },\n async mutate(_authorization: Authorization, request: MutationRequest) {\n return resolveScript<MutationResult, MutationRequest>(\n scripts.mutate as Script<MutationResult, MutationRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n return { kind: 'rejected', text: '' };\n },\n request,\n );\n },\n async history(_authorization: Authorization, request: HistoryRequest) {\n return resolveScript<HistoryResult, HistoryRequest>(\n scripts.history as Script<HistoryResult, HistoryRequest> | undefined,\n () => {\n const room = rooms.find((entry) => entry.locator === request.locator);\n if (room === undefined) {\n return { kind: 'room-not-readable', locator: request.locator };\n }\n return {\n kind: 'history',\n revisions: [],\n };\n },\n request,\n );\n },\n async action(_authorization: Authorization, request: ActionRequest) {\n return resolveScript<ActionResult, ActionRequest>(\n scripts.action as Script<ActionResult, ActionRequest> | undefined,\n () => ({\n kind: 'rejected',\n text: '',\n }),\n request,\n );\n },\n };\n}\n"],"names":["ROOM_CONTRACT_VERSION","MD_MODEL","named","source","paths","taken","path","value","undefined","resolveScript","answer","fallback","request","createMemoryAdapter","options","rooms","mdModel","supportedVersions","capabilities","providerLimits","retention","history","outcome","refreshHorizon","origins","pageSize","scripts","served","Map","refreshPages","retain","entries","room","versions","get","locator","set","roomVersion","declared","name","writeGrants","providerOwnedPaths","page","from","Object","keys","documents","sort","size","length","slice","next","kind","revisions","binaryTargets","pageToken","String","advancement","at","current","previous","currentTargets","Set","previousTargets","changed","filter","opening","target","has","removals","discovery","map","setRooms","script","operation","authorize","discover","_authorization","bootstrap","find","entry","Number","refresh","continuation","fromRoomVersion","Error","mutate","text","action"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ChangeBatch } from './change.js';
|
|
2
|
+
export type Layer = {
|
|
3
|
+
documents: Readonly<Record<string, string>>;
|
|
4
|
+
binaryTargets: readonly string[];
|
|
5
|
+
revisions: Readonly<Record<string, string>>;
|
|
6
|
+
};
|
|
7
|
+
export declare function overlay(base: Layer, queue: readonly ChangeBatch[]): Layer;
|
|
8
|
+
//# sourceMappingURL=overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,WAAW,EAAgB,MAAM,aAAa,CAAC;AAErE,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7C,CAAC;AAyIF,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,KAAK,CAezE"}
|
package/dist/overlay.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { apply, parse, serialize } from '@agentshouse/mdmodel';
|
|
2
|
+
const EMPTY_FRONTMATTER = '---\n---\n';
|
|
3
|
+
function at(path, name) {
|
|
4
|
+
return `${path} ${name}`;
|
|
5
|
+
}
|
|
6
|
+
function priorsOf(preconditions) {
|
|
7
|
+
const fields = new Map();
|
|
8
|
+
const sections = new Map();
|
|
9
|
+
const preambles = new Map();
|
|
10
|
+
for (const precondition of preconditions){
|
|
11
|
+
if (precondition.kind === 'field') {
|
|
12
|
+
fields.set(at(precondition.path, precondition.name), precondition.value);
|
|
13
|
+
}
|
|
14
|
+
if (precondition.kind === 'section') {
|
|
15
|
+
sections.set(at(precondition.path, precondition.name), precondition.value);
|
|
16
|
+
}
|
|
17
|
+
if (precondition.kind === 'preamble') {
|
|
18
|
+
preambles.set(precondition.path, precondition.value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
field: (path, name)=>fields.get(at(path, name)),
|
|
23
|
+
section: (path, name)=>sections.get(at(path, name)) ?? '',
|
|
24
|
+
preamble: (path)=>preambles.get(path) ?? ''
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function compose(fields, sections) {
|
|
28
|
+
const body = Object.entries(sections).map(([name, value])=>`\n## ${name}\n${value}`).join('');
|
|
29
|
+
const skeleton = `${EMPTY_FRONTMATTER}${body}`;
|
|
30
|
+
const opened = parse(skeleton);
|
|
31
|
+
if (!opened.ok) return skeleton;
|
|
32
|
+
let document = opened.document;
|
|
33
|
+
for (const [name, value] of Object.entries(fields)){
|
|
34
|
+
const next = apply(document, {
|
|
35
|
+
kind: 'field',
|
|
36
|
+
name,
|
|
37
|
+
value,
|
|
38
|
+
prior: undefined
|
|
39
|
+
});
|
|
40
|
+
if (next.outcome === 'applied') document = next.document;
|
|
41
|
+
}
|
|
42
|
+
return serialize(document);
|
|
43
|
+
}
|
|
44
|
+
function edited(document, change, priors) {
|
|
45
|
+
if (change.kind === 'field') {
|
|
46
|
+
return apply(document, {
|
|
47
|
+
kind: 'field',
|
|
48
|
+
name: change.name,
|
|
49
|
+
value: change.value,
|
|
50
|
+
prior: priors.field(change.path, change.name)
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (change.kind === 'preamble') {
|
|
54
|
+
return apply(document, {
|
|
55
|
+
kind: 'preamble',
|
|
56
|
+
value: change.value,
|
|
57
|
+
prior: priors.preamble(change.path)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (change.kind !== 'section') return null;
|
|
61
|
+
return apply(document, {
|
|
62
|
+
kind: 'section',
|
|
63
|
+
name: change.name,
|
|
64
|
+
value: change.value,
|
|
65
|
+
prior: priors.section(change.path, change.name)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function edit(staged, change, priors) {
|
|
69
|
+
const text = staged.documents[change.path];
|
|
70
|
+
if (text === undefined) return;
|
|
71
|
+
const parsed = parse(text, change.path);
|
|
72
|
+
if (!parsed.ok) return;
|
|
73
|
+
const next = edited(parsed.document, change, priors);
|
|
74
|
+
if (next?.outcome === 'applied') staged.documents[change.path] = serialize(next.document);
|
|
75
|
+
}
|
|
76
|
+
function relocate(staged, from, to) {
|
|
77
|
+
const text = staged.documents[from];
|
|
78
|
+
if (text !== undefined) {
|
|
79
|
+
delete staged.documents[from];
|
|
80
|
+
staged.documents[to] = text;
|
|
81
|
+
} else if (staged.binaryTargets.delete(from)) {
|
|
82
|
+
staged.binaryTargets.add(to);
|
|
83
|
+
} else {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const revision = staged.revisions[from];
|
|
87
|
+
if (revision === undefined) return;
|
|
88
|
+
delete staged.revisions[from];
|
|
89
|
+
staged.revisions[to] = revision;
|
|
90
|
+
}
|
|
91
|
+
function erase(staged, path) {
|
|
92
|
+
delete staged.documents[path];
|
|
93
|
+
delete staged.revisions[path];
|
|
94
|
+
staged.binaryTargets.delete(path);
|
|
95
|
+
}
|
|
96
|
+
function stage(staged, change, priors) {
|
|
97
|
+
if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {
|
|
98
|
+
edit(staged, change, priors);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (change.kind === 'create') {
|
|
102
|
+
staged.documents[change.path] = compose(change.fields, change.sections);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (change.kind === 'replace') {
|
|
106
|
+
if (staged.documents[change.path] === undefined) return;
|
|
107
|
+
staged.documents[change.path] = change.content;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (change.kind === 'move') {
|
|
111
|
+
relocate(staged, change.path, change.to);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
erase(staged, change.path);
|
|
115
|
+
}
|
|
116
|
+
export function overlay(base, queue) {
|
|
117
|
+
const staged = {
|
|
118
|
+
documents: {
|
|
119
|
+
...base.documents
|
|
120
|
+
},
|
|
121
|
+
binaryTargets: new Set(base.binaryTargets),
|
|
122
|
+
revisions: {
|
|
123
|
+
...base.revisions
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
for (const batch of queue){
|
|
127
|
+
const priors = priorsOf(batch.preconditions);
|
|
128
|
+
for (const change of batch.changes)stage(staged, change, priors);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
documents: staged.documents,
|
|
132
|
+
binaryTargets: [
|
|
133
|
+
...staged.binaryTargets
|
|
134
|
+
].sort(),
|
|
135
|
+
revisions: staged.revisions
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/overlay.ts"],"sourcesContent":["import { apply, parse, serialize, type Document } from '@agentshouse/mdmodel';\nimport type { Change, ChangeBatch, Precondition } from './change.js';\n\nexport type Layer = {\n documents: Readonly<Record<string, string>>;\n binaryTargets: readonly string[];\n revisions: Readonly<Record<string, string>>;\n};\n\ntype Staged = {\n documents: Record<string, string>;\n binaryTargets: Set<string>;\n revisions: Record<string, string>;\n};\n\ntype Priors = {\n field(path: string, name: string): unknown;\n section(path: string, name: string): string;\n preamble(path: string): string;\n};\n\nconst EMPTY_FRONTMATTER = '---\\n---\\n';\n\nfunction at(path: string, name: string) {\n return `${path} ${name}`;\n}\n\nfunction priorsOf(preconditions: readonly Precondition[]): Priors {\n const fields = new Map<string, unknown>();\n const sections = new Map<string, string>();\n const preambles = new Map<string, string>();\n for (const precondition of preconditions) {\n if (precondition.kind === 'field') {\n fields.set(at(precondition.path, precondition.name), precondition.value);\n }\n if (precondition.kind === 'section') {\n sections.set(at(precondition.path, precondition.name), precondition.value);\n }\n if (precondition.kind === 'preamble') {\n preambles.set(precondition.path, precondition.value);\n }\n }\n return {\n field: (path, name) => fields.get(at(path, name)),\n section: (path, name) => sections.get(at(path, name)) ?? '',\n preamble: (path) => preambles.get(path) ?? '',\n };\n}\n\nfunction compose(\n fields: Readonly<Record<string, unknown>>,\n sections: Readonly<Record<string, string>>,\n): string {\n const body = Object.entries(sections)\n .map(([name, value]) => `\\n## ${name}\\n${value}`)\n .join('');\n const skeleton = `${EMPTY_FRONTMATTER}${body}`;\n const opened = parse(skeleton);\n if (!opened.ok) return skeleton;\n let document: Document = opened.document;\n for (const [name, value] of Object.entries(fields)) {\n const next = apply(document, { kind: 'field', name, value, prior: undefined });\n if (next.outcome === 'applied') document = next.document;\n }\n return serialize(document);\n}\n\nfunction edited(document: Document, change: Change, priors: Priors) {\n if (change.kind === 'field') {\n return apply(document, {\n kind: 'field',\n name: change.name,\n value: change.value,\n prior: priors.field(change.path, change.name),\n });\n }\n if (change.kind === 'preamble') {\n return apply(document, {\n kind: 'preamble',\n value: change.value,\n prior: priors.preamble(change.path),\n });\n }\n if (change.kind !== 'section') return null;\n return apply(document, {\n kind: 'section',\n name: change.name,\n value: change.value,\n prior: priors.section(change.path, change.name),\n });\n}\n\nfunction edit(staged: Staged, change: Change, priors: Priors) {\n const text = staged.documents[change.path];\n if (text === undefined) return;\n const parsed = parse(text, change.path);\n if (!parsed.ok) return;\n const next = edited(parsed.document, change, priors);\n if (next?.outcome === 'applied') staged.documents[change.path] = serialize(next.document);\n}\n\nfunction relocate(staged: Staged, from: string, to: string) {\n const text = staged.documents[from];\n if (text !== undefined) {\n delete staged.documents[from];\n staged.documents[to] = text;\n } else if (staged.binaryTargets.delete(from)) {\n staged.binaryTargets.add(to);\n } else {\n return;\n }\n const revision = staged.revisions[from];\n if (revision === undefined) return;\n delete staged.revisions[from];\n staged.revisions[to] = revision;\n}\n\nfunction erase(staged: Staged, path: string) {\n delete staged.documents[path];\n delete staged.revisions[path];\n staged.binaryTargets.delete(path);\n}\n\nfunction stage(staged: Staged, change: Change, priors: Priors) {\n if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {\n edit(staged, change, priors);\n return;\n }\n if (change.kind === 'create') {\n staged.documents[change.path] = compose(change.fields, change.sections);\n return;\n }\n if (change.kind === 'replace') {\n if (staged.documents[change.path] === undefined) return;\n staged.documents[change.path] = change.content;\n return;\n }\n if (change.kind === 'move') {\n relocate(staged, change.path, change.to);\n return;\n }\n erase(staged, change.path);\n}\n\nexport function overlay(base: Layer, queue: readonly ChangeBatch[]): Layer {\n const staged: Staged = {\n documents: { ...base.documents },\n binaryTargets: new Set(base.binaryTargets),\n revisions: { ...base.revisions },\n };\n for (const batch of queue) {\n const priors = priorsOf(batch.preconditions);\n for (const change of batch.changes) stage(staged, change, priors);\n }\n return {\n documents: staged.documents,\n binaryTargets: [...staged.binaryTargets].sort(),\n revisions: staged.revisions,\n };\n}\n"],"names":["apply","parse","serialize","EMPTY_FRONTMATTER","at","path","name","priorsOf","preconditions","fields","Map","sections","preambles","precondition","kind","set","value","field","get","section","preamble","compose","body","Object","entries","map","join","skeleton","opened","ok","document","next","prior","undefined","outcome","edited","change","priors","edit","staged","text","documents","parsed","relocate","from","to","binaryTargets","delete","add","revision","revisions","erase","stage","content","overlay","base","queue","Set","batch","changes","sort"],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function normalize(path: string): string | null;
|
|
2
|
+
export declare function resolve(from: string, reference: string): string | null;
|
|
3
|
+
export declare function relative(from: string, target: string): string;
|
|
4
|
+
export declare function beneath(prefix: string, path: string): boolean;
|
|
5
|
+
export declare function covered(prefixes: readonly string[], path: string): boolean;
|
|
6
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1E"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function dirname(path) {
|
|
2
|
+
const index = path.lastIndexOf('/');
|
|
3
|
+
return index === -1 ? '' : path.slice(0, index);
|
|
4
|
+
}
|
|
5
|
+
export function normalize(path) {
|
|
6
|
+
const parts = [];
|
|
7
|
+
for (const part of path.split('/')){
|
|
8
|
+
if (part === '' || part === '.') continue;
|
|
9
|
+
if (part === '..') {
|
|
10
|
+
if (parts.length === 0) return null;
|
|
11
|
+
parts.pop();
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
parts.push(part);
|
|
15
|
+
}
|
|
16
|
+
return parts.join('/');
|
|
17
|
+
}
|
|
18
|
+
export function resolve(from, reference) {
|
|
19
|
+
const base = dirname(from);
|
|
20
|
+
return normalize(base === '' ? reference : `${base}/${reference}`);
|
|
21
|
+
}
|
|
22
|
+
export function relative(from, target) {
|
|
23
|
+
const base = dirname(from).split('/').filter((part)=>part !== '');
|
|
24
|
+
const parts = target.split('/');
|
|
25
|
+
let shared = 0;
|
|
26
|
+
while(shared < base.length && shared + 1 < parts.length && base[shared] === parts[shared]){
|
|
27
|
+
shared += 1;
|
|
28
|
+
}
|
|
29
|
+
const up = Array.from({
|
|
30
|
+
length: base.length - shared
|
|
31
|
+
}, ()=>'..');
|
|
32
|
+
return [
|
|
33
|
+
...up,
|
|
34
|
+
...parts.slice(shared)
|
|
35
|
+
].join('/');
|
|
36
|
+
}
|
|
37
|
+
export function beneath(prefix, path) {
|
|
38
|
+
return path === prefix || path.startsWith(`${prefix}/`);
|
|
39
|
+
}
|
|
40
|
+
export function covered(prefixes, path) {
|
|
41
|
+
return prefixes.some((prefix)=>{
|
|
42
|
+
const normalized = normalize(prefix);
|
|
43
|
+
return normalized !== null && (normalized === '' || beneath(normalized, path));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/paths.ts"],"sourcesContent":["function dirname(path: string): string {\n const index = path.lastIndexOf('/');\n return index === -1 ? '' : path.slice(0, index);\n}\n\nexport function normalize(path: string): string | null {\n const parts: string[] = [];\n for (const part of path.split('/')) {\n if (part === '' || part === '.') continue;\n if (part === '..') {\n if (parts.length === 0) return null;\n parts.pop();\n continue;\n }\n parts.push(part);\n }\n return parts.join('/');\n}\n\nexport function resolve(from: string, reference: string): string | null {\n const base = dirname(from);\n return normalize(base === '' ? reference : `${base}/${reference}`);\n}\n\nexport function relative(from: string, target: string): string {\n const base = dirname(from)\n .split('/')\n .filter((part) => part !== '');\n const parts = target.split('/');\n let shared = 0;\n while (shared < base.length && shared + 1 < parts.length && base[shared] === parts[shared]) {\n shared += 1;\n }\n const up = Array.from({ length: base.length - shared }, () => '..');\n return [...up, ...parts.slice(shared)].join('/');\n}\n\nexport function beneath(prefix: string, path: string): boolean {\n return path === prefix || path.startsWith(`${prefix}/`);\n}\n\nexport function covered(prefixes: readonly string[], path: string): boolean {\n return prefixes.some((prefix) => {\n const normalized = normalize(prefix);\n return normalized !== null && (normalized === '' || beneath(normalized, path));\n });\n}\n"],"names":["dirname","path","index","lastIndexOf","slice","normalize","parts","part","split","length","pop","push","join","resolve","from","reference","base","relative","target","filter","shared","up","Array","beneath","prefix","startsWith","covered","prefixes","some","normalized"],"mappings":"AAAA,SAASA,QAAQC,IAAY;IAC3B,MAAMC,QAAQD,KAAKE,WAAW,CAAC;IAC/B,OAAOD,UAAU,CAAC,IAAI,KAAKD,KAAKG,KAAK,CAAC,GAAGF;AAC3C;AAEA,OAAO,SAASG,UAAUJ,IAAY;IACpC,MAAMK,QAAkB,EAAE;IAC1B,KAAK,MAAMC,QAAQN,KAAKO,KAAK,CAAC,KAAM;QAClC,IAAID,SAAS,MAAMA,SAAS,KAAK;QACjC,IAAIA,SAAS,MAAM;YACjB,IAAID,MAAMG,MAAM,KAAK,GAAG,OAAO;YAC/BH,MAAMI,GAAG;YACT;QACF;QACAJ,MAAMK,IAAI,CAACJ;IACb;IACA,OAAOD,MAAMM,IAAI,CAAC;AACpB;AAEA,OAAO,SAASC,QAAQC,IAAY,EAAEC,SAAiB;IACrD,MAAMC,OAAOhB,QAAQc;IACrB,OAAOT,UAAUW,SAAS,KAAKD,YAAY,GAAGC,KAAK,CAAC,EAAED,WAAW;AACnE;AAEA,OAAO,SAASE,SAASH,IAAY,EAAEI,MAAc;IACnD,MAAMF,OAAOhB,QAAQc,MAClBN,KAAK,CAAC,KACNW,MAAM,CAAC,CAACZ,OAASA,SAAS;IAC7B,MAAMD,QAAQY,OAAOV,KAAK,CAAC;IAC3B,IAAIY,SAAS;IACb,MAAOA,SAASJ,KAAKP,MAAM,IAAIW,SAAS,IAAId,MAAMG,MAAM,IAAIO,IAAI,CAACI,OAAO,KAAKd,KAAK,CAACc,OAAO,CAAE;QAC1FA,UAAU;IACZ;IACA,MAAMC,KAAKC,MAAMR,IAAI,CAAC;QAAEL,QAAQO,KAAKP,MAAM,GAAGW;IAAO,GAAG,IAAM;IAC9D,OAAO;WAAIC;WAAOf,MAAMF,KAAK,CAACgB;KAAQ,CAACR,IAAI,CAAC;AAC9C;AAEA,OAAO,SAASW,QAAQC,MAAc,EAAEvB,IAAY;IAClD,OAAOA,SAASuB,UAAUvB,KAAKwB,UAAU,CAAC,GAAGD,OAAO,CAAC,CAAC;AACxD;AAEA,OAAO,SAASE,QAAQC,QAA2B,EAAE1B,IAAY;IAC/D,OAAO0B,SAASC,IAAI,CAAC,CAACJ;QACpB,MAAMK,aAAaxB,UAAUmB;QAC7B,OAAOK,eAAe,QAASA,CAAAA,eAAe,MAAMN,QAAQM,YAAY5B,KAAI;IAC9E;AACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Adapter, AdapterFailure, Authorization } from './adapter.js';
|
|
2
|
+
import { type ConfirmedLayer } from './replica.js';
|
|
3
|
+
import { type Unconfirmed } from './transfer.js';
|
|
4
|
+
export type RefreshOutcome = {
|
|
5
|
+
kind: 'still-current';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'advanced';
|
|
8
|
+
confirmed: ConfirmedLayer;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'beyond-horizon';
|
|
11
|
+
} | Unconfirmed | AdapterFailure;
|
|
12
|
+
export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer): Promise<RefreshOutcome>;
|
|
13
|
+
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AACxF,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,WAAW,GACX,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,cAAc,CAAC,CA0CzB"}
|
package/dist/refresh.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readConfirmed } from './replica.js';
|
|
2
|
+
import { unconfirmed } from './transfer.js';
|
|
3
|
+
export async function refreshRoom(adapter, authorization, confirmed) {
|
|
4
|
+
const locator = confirmed.record.locator;
|
|
5
|
+
const fromRoomVersion = confirmed.record.roomVersion;
|
|
6
|
+
const first = await adapter.refresh(authorization, {
|
|
7
|
+
locator,
|
|
8
|
+
fromRoomVersion
|
|
9
|
+
});
|
|
10
|
+
if (first.kind !== 'net-advancement') return first;
|
|
11
|
+
const roomVersion = first.roomVersion;
|
|
12
|
+
const documents = {
|
|
13
|
+
...confirmed.record.documents
|
|
14
|
+
};
|
|
15
|
+
const revisions = {
|
|
16
|
+
...confirmed.record.revisions
|
|
17
|
+
};
|
|
18
|
+
const binaryTargets = new Set(confirmed.record.binaryTargets);
|
|
19
|
+
const stage = (page)=>{
|
|
20
|
+
Object.assign(documents, page.documents);
|
|
21
|
+
Object.assign(revisions, page.revisions);
|
|
22
|
+
for (const path of Object.keys(page.documents))binaryTargets.delete(path);
|
|
23
|
+
for (const target of page.binaryTargets){
|
|
24
|
+
delete documents[target];
|
|
25
|
+
delete revisions[target];
|
|
26
|
+
binaryTargets.add(target);
|
|
27
|
+
}
|
|
28
|
+
for (const path of page.removals){
|
|
29
|
+
delete documents[path];
|
|
30
|
+
delete revisions[path];
|
|
31
|
+
binaryTargets.delete(path);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
stage(first);
|
|
35
|
+
let pageToken = first.pageToken;
|
|
36
|
+
while(pageToken !== undefined){
|
|
37
|
+
const page = await adapter.refresh(authorization, {
|
|
38
|
+
locator,
|
|
39
|
+
fromRoomVersion,
|
|
40
|
+
pageToken
|
|
41
|
+
});
|
|
42
|
+
if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;
|
|
43
|
+
if (page.kind !== 'net-advancement') return page;
|
|
44
|
+
if (page.roomVersion !== roomVersion) return unconfirmed;
|
|
45
|
+
stage(page);
|
|
46
|
+
pageToken = page.pageToken;
|
|
47
|
+
}
|
|
48
|
+
const advanced = readConfirmed({
|
|
49
|
+
...confirmed.record,
|
|
50
|
+
roomVersion,
|
|
51
|
+
documents,
|
|
52
|
+
binaryTargets: [
|
|
53
|
+
...binaryTargets
|
|
54
|
+
].sort(),
|
|
55
|
+
revisions
|
|
56
|
+
});
|
|
57
|
+
return advanced === null ? unconfirmed : {
|
|
58
|
+
kind: 'advanced',
|
|
59
|
+
confirmed: advanced
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/refresh.ts"],"sourcesContent":["import type { Adapter, AdapterFailure, Authorization, RefreshPage } from './adapter.js';\nimport { readConfirmed, type ConfirmedLayer } from './replica.js';\nimport { unconfirmed, type Unconfirmed } from './transfer.js';\n\nexport type RefreshOutcome =\n | { kind: 'still-current' }\n | { kind: 'advanced'; confirmed: ConfirmedLayer }\n | { kind: 'beyond-horizon' }\n | Unconfirmed\n | AdapterFailure;\n\nexport async function refreshRoom(\n adapter: Adapter,\n authorization: Authorization,\n confirmed: ConfirmedLayer,\n): Promise<RefreshOutcome> {\n const locator = confirmed.record.locator;\n const fromRoomVersion = confirmed.record.roomVersion;\n const first = await adapter.refresh(authorization, { locator, fromRoomVersion });\n if (first.kind !== 'net-advancement') return first;\n const roomVersion = first.roomVersion;\n const documents: Record<string, string> = { ...confirmed.record.documents };\n const revisions: Record<string, string> = { ...confirmed.record.revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n const stage = (page: RefreshPage) => {\n Object.assign(documents, page.documents);\n Object.assign(revisions, page.revisions);\n for (const path of Object.keys(page.documents)) binaryTargets.delete(path);\n for (const target of page.binaryTargets) {\n delete documents[target];\n delete revisions[target];\n binaryTargets.add(target);\n }\n for (const path of page.removals) {\n delete documents[path];\n delete revisions[path];\n binaryTargets.delete(path);\n }\n };\n stage(first);\n let pageToken = first.pageToken;\n while (pageToken !== undefined) {\n const page = await adapter.refresh(authorization, { locator, fromRoomVersion, pageToken });\n if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;\n if (page.kind !== 'net-advancement') return page;\n if (page.roomVersion !== roomVersion) return unconfirmed;\n stage(page);\n pageToken = page.pageToken;\n }\n const advanced = readConfirmed({\n ...confirmed.record,\n roomVersion,\n documents,\n binaryTargets: [...binaryTargets].sort(),\n revisions,\n });\n return advanced === null ? unconfirmed : { kind: 'advanced', confirmed: advanced };\n}\n"],"names":["readConfirmed","unconfirmed","refreshRoom","adapter","authorization","confirmed","locator","record","fromRoomVersion","roomVersion","first","refresh","kind","documents","revisions","binaryTargets","Set","stage","page","Object","assign","path","keys","delete","target","add","removals","pageToken","undefined","advanced","sort"],"mappings":"AACA,SAASA,aAAa,QAA6B,eAAe;AAClE,SAASC,WAAW,QAA0B,gBAAgB;AAS9D,OAAO,eAAeC,YACpBC,OAAgB,EAChBC,aAA4B,EAC5BC,SAAyB;IAEzB,MAAMC,UAAUD,UAAUE,MAAM,CAACD,OAAO;IACxC,MAAME,kBAAkBH,UAAUE,MAAM,CAACE,WAAW;IACpD,MAAMC,QAAQ,MAAMP,QAAQQ,OAAO,CAACP,eAAe;QAAEE;QAASE;IAAgB;IAC9E,IAAIE,MAAME,IAAI,KAAK,mBAAmB,OAAOF;IAC7C,MAAMD,cAAcC,MAAMD,WAAW;IACrC,MAAMI,YAAoC;QAAE,GAAGR,UAAUE,MAAM,CAACM,SAAS;IAAC;IAC1E,MAAMC,YAAoC;QAAE,GAAGT,UAAUE,MAAM,CAACO,SAAS;IAAC;IAC1E,MAAMC,gBAAgB,IAAIC,IAAIX,UAAUE,MAAM,CAACQ,aAAa;IAC5D,MAAME,QAAQ,CAACC;QACbC,OAAOC,MAAM,CAACP,WAAWK,KAAKL,SAAS;QACvCM,OAAOC,MAAM,CAACN,WAAWI,KAAKJ,SAAS;QACvC,KAAK,MAAMO,QAAQF,OAAOG,IAAI,CAACJ,KAAKL,SAAS,EAAGE,cAAcQ,MAAM,CAACF;QACrE,KAAK,MAAMG,UAAUN,KAAKH,aAAa,CAAE;YACvC,OAAOF,SAAS,CAACW,OAAO;YACxB,OAAOV,SAAS,CAACU,OAAO;YACxBT,cAAcU,GAAG,CAACD;QACpB;QACA,KAAK,MAAMH,QAAQH,KAAKQ,QAAQ,CAAE;YAChC,OAAOb,SAAS,CAACQ,KAAK;YACtB,OAAOP,SAAS,CAACO,KAAK;YACtBN,cAAcQ,MAAM,CAACF;QACvB;IACF;IACAJ,MAAMP;IACN,IAAIiB,YAAYjB,MAAMiB,SAAS;IAC/B,MAAOA,cAAcC,UAAW;QAC9B,MAAMV,OAAO,MAAMf,QAAQQ,OAAO,CAACP,eAAe;YAAEE;YAASE;YAAiBmB;QAAU;QACxF,IAAIT,KAAKN,IAAI,KAAK,mBAAmBM,KAAKN,IAAI,KAAK,kBAAkB,OAAOX;QAC5E,IAAIiB,KAAKN,IAAI,KAAK,mBAAmB,OAAOM;QAC5C,IAAIA,KAAKT,WAAW,KAAKA,aAAa,OAAOR;QAC7CgB,MAAMC;QACNS,YAAYT,KAAKS,SAAS;IAC5B;IACA,MAAME,WAAW7B,cAAc;QAC7B,GAAGK,UAAUE,MAAM;QACnBE;QACAI;QACAE,eAAe;eAAIA;SAAc,CAACe,IAAI;QACtChB;IACF;IACA,OAAOe,aAAa,OAAO5B,cAAc;QAAEW,MAAM;QAAYP,WAAWwB;IAAS;AACnF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ChangeBatch } from './change.js';
|
|
2
|
+
import { type Collection } from './collection.js';
|
|
3
|
+
import { type Layer } from './overlay.js';
|
|
4
|
+
import type { ReplicaRecord } from './store.js';
|
|
5
|
+
export type ConfirmedLayer = {
|
|
6
|
+
record: ReplicaRecord;
|
|
7
|
+
collection: Collection;
|
|
8
|
+
};
|
|
9
|
+
export type VisibleLayer = Layer & {
|
|
10
|
+
collection: Collection;
|
|
11
|
+
};
|
|
12
|
+
export type Replica = {
|
|
13
|
+
confirmed: ConfirmedLayer;
|
|
14
|
+
queue: readonly ChangeBatch[];
|
|
15
|
+
visible: VisibleLayer;
|
|
16
|
+
};
|
|
17
|
+
export declare function readConfirmed(record: ReplicaRecord): ConfirmedLayer | null;
|
|
18
|
+
export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[]): Replica;
|
|
19
|
+
//# sourceMappingURL=replica.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG,IAAI,CAG1E;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAoB3F"}
|
package/dist/replica.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { immutable } from './change.js';
|
|
2
|
+
import { parseCollection, readCollection } from './collection.js';
|
|
3
|
+
import { overlay } from './overlay.js';
|
|
4
|
+
export function readConfirmed(record) {
|
|
5
|
+
const collection = readCollection(record.documents, record.binaryTargets);
|
|
6
|
+
return collection === null ? null : {
|
|
7
|
+
record,
|
|
8
|
+
collection
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function replicaOf(confirmed, queue) {
|
|
12
|
+
const batches = Object.freeze(queue.map(immutable));
|
|
13
|
+
if (batches.length === 0) {
|
|
14
|
+
return {
|
|
15
|
+
confirmed,
|
|
16
|
+
queue: batches,
|
|
17
|
+
visible: {
|
|
18
|
+
documents: confirmed.record.documents,
|
|
19
|
+
binaryTargets: confirmed.record.binaryTargets,
|
|
20
|
+
revisions: confirmed.record.revisions,
|
|
21
|
+
collection: confirmed.collection
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const layer = overlay(confirmed.record, batches);
|
|
26
|
+
return {
|
|
27
|
+
confirmed,
|
|
28
|
+
queue: batches,
|
|
29
|
+
visible: {
|
|
30
|
+
...layer,
|
|
31
|
+
collection: parseCollection(layer.documents)
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=replica.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import { immutable, type ChangeBatch } from './change.js';\nimport { parseCollection, readCollection, type Collection } from './collection.js';\nimport { overlay, type Layer } from './overlay.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n};\n\nexport function readConfirmed(record: ReplicaRecord): ConfirmedLayer | null {\n const collection = readCollection(record.documents, record.binaryTargets);\n return collection === null ? null : { record, collection };\n}\n\nexport function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[]): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n };\n }\n const layer = overlay(confirmed.record, batches);\n return {\n confirmed,\n queue: batches,\n visible: { ...layer, collection: parseCollection(layer.documents) },\n };\n}\n"],"names":["immutable","parseCollection","readCollection","overlay","readConfirmed","record","collection","documents","binaryTargets","replicaOf","confirmed","queue","batches","Object","freeze","map","length","visible","revisions","layer"],"mappings":"AAAA,SAASA,SAAS,QAA0B,cAAc;AAC1D,SAASC,eAAe,EAAEC,cAAc,QAAyB,kBAAkB;AACnF,SAASC,OAAO,QAAoB,eAAe;AAkBnD,OAAO,SAASC,cAAcC,MAAqB;IACjD,MAAMC,aAAaJ,eAAeG,OAAOE,SAAS,EAAEF,OAAOG,aAAa;IACxE,OAAOF,eAAe,OAAO,OAAO;QAAED;QAAQC;IAAW;AAC3D;AAEA,OAAO,SAASG,UAAUC,SAAyB,EAAEC,KAA6B;IAChF,MAAMC,UAAUC,OAAOC,MAAM,CAACH,MAAMI,GAAG,CAACf;IACxC,IAAIY,QAAQI,MAAM,KAAK,GAAG;QACxB,OAAO;YACLN;YACAC,OAAOC;YACPK,SAAS;gBACPV,WAAWG,UAAUL,MAAM,CAACE,SAAS;gBACrCC,eAAeE,UAAUL,MAAM,CAACG,aAAa;gBAC7CU,WAAWR,UAAUL,MAAM,CAACa,SAAS;gBACrCZ,YAAYI,UAAUJ,UAAU;YAClC;QACF;IACF;IACA,MAAMa,QAAQhB,QAAQO,UAAUL,MAAM,EAAEO;IACxC,OAAO;QACLF;QACAC,OAAOC;QACPK,SAAS;YAAE,GAAGE,KAAK;YAAEb,YAAYL,gBAAgBkB,MAAMZ,SAAS;QAAE;IACpE;AACF"}
|
package/dist/save.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ProviderLimit } from './adapter.js';
|
|
2
|
+
import { type Change, type ChangeBatch } from './change.js';
|
|
3
|
+
import type { VisibleLayer } from './replica.js';
|
|
4
|
+
export type SaveRefusal = {
|
|
5
|
+
rule: string;
|
|
6
|
+
file?: string;
|
|
7
|
+
location?: string;
|
|
8
|
+
referrers?: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
export type SaveInput = {
|
|
11
|
+
baseRoomVersion: string;
|
|
12
|
+
writeGrants: readonly string[];
|
|
13
|
+
providerOwnedPaths: readonly string[];
|
|
14
|
+
providerLimits: readonly ProviderLimit[];
|
|
15
|
+
visible: VisibleLayer;
|
|
16
|
+
changes: readonly Change[];
|
|
17
|
+
};
|
|
18
|
+
export type BatchResult = {
|
|
19
|
+
kind: 'batch';
|
|
20
|
+
batch: ChangeBatch;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'refused';
|
|
23
|
+
refusal: SaveRefusal;
|
|
24
|
+
};
|
|
25
|
+
export declare function buildBatch(input: SaveInput): BatchResult;
|
|
26
|
+
//# sourceMappingURL=save.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAa,KAAK,MAAM,EAAE,KAAK,WAAW,EAAqB,MAAM,aAAa,CAAC;AAI1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AA0X9C,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CA2CxD"}
|