@agentshouse/mdruntime 0.1.0-alpha.8 → 0.1.0-c3903a68dcbbf
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 +210 -0
- package/README.md +44 -0
- package/dist/adapter.d.ts +223 -25
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +2 -3
- package/dist/attachment.d.ts +3 -0
- package/dist/attachment.d.ts.map +1 -0
- package/dist/attachment.js +8 -0
- package/dist/bootstrap.d.ts +6 -7
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +32 -28
- package/dist/change-set.d.ts +33 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/change-set.js +87 -0
- package/dist/change.d.ts +9 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +6 -5
- package/dist/client.d.ts +75 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +171 -0
- package/dist/collection.d.ts +24 -15
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +69 -77
- package/dist/connection.d.ts +79 -36
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1699 -953
- package/dist/conversation.d.ts +79 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/conversation.js +557 -0
- package/dist/durability.d.ts +8 -3
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +7 -61
- package/dist/file.d.ts +20 -0
- package/dist/file.d.ts.map +1 -0
- package/dist/file.js +126 -0
- package/dist/host.d.ts +14 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +198 -0
- package/dist/identity.d.ts +1 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +10 -9
- package/dist/index.d.ts +14 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/log.js +5 -6
- package/dist/memory.d.ts +17 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +269 -113
- package/dist/model.d.ts +10 -25
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +18 -21
- package/dist/observation.d.ts +25 -0
- package/dist/observation.d.ts.map +1 -0
- package/dist/observation.js +85 -0
- package/dist/outcome.d.ts +22 -18
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +1 -13
- package/dist/overlay.d.ts +9 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +187 -43
- package/dist/paths.d.ts +0 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +12 -19
- package/dist/query.d.ts +210 -9
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +420 -15
- package/dist/read-side.d.ts +14 -0
- package/dist/read-side.d.ts.map +1 -0
- package/dist/read-side.js +371 -0
- package/dist/refresh.d.ts +4 -5
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +45 -30
- package/dist/replica.d.ts +27 -6
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +237 -30
- package/dist/room-draft.d.ts +124 -0
- package/dist/room-draft.d.ts.map +1 -0
- package/dist/room-draft.js +327 -0
- package/dist/rows.d.ts +41 -0
- package/dist/rows.d.ts.map +1 -0
- package/dist/rows.js +100 -0
- package/dist/save.d.ts +10 -6
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +267 -333
- package/dist/search.d.ts +61 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +125 -0
- package/dist/status.d.ts +9 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +11 -14
- package/dist/store.d.ts +85 -18
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +380 -97
- package/dist/transfer.d.ts +5 -0
- package/dist/transfer.d.ts.map +1 -1
- package/dist/transfer.js +1 -5
- package/dist/wire.d.ts +64 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +124 -0
- package/package.json +15 -13
- package/dist/adapter.js.map +0 -1
- package/dist/bootstrap.js.map +0 -1
- package/dist/change.js.map +0 -1
- package/dist/collection.js.map +0 -1
- package/dist/connection.js.map +0 -1
- package/dist/durability.js.map +0 -1
- package/dist/identity.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/log.js.map +0 -1
- package/dist/memory.js.map +0 -1
- package/dist/model.js.map +0 -1
- package/dist/outcome.js.map +0 -1
- package/dist/overlay.js.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/query.js.map +0 -1
- package/dist/refresh.js.map +0 -1
- package/dist/replica.js.map +0 -1
- package/dist/save.js.map +0 -1
- package/dist/status.js.map +0 -1
- package/dist/store.js.map +0 -1
- package/dist/transfer.js.map +0 -1
package/dist/memory.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { ROOM_CONTRACT_VERSION } from './adapter.js';
|
|
1
|
+
import { ROOM_CONTRACT_VERSION, } from './adapter.js';
|
|
2
2
|
import { MD_MODEL } from './collection.js';
|
|
3
|
+
import { sameChange } from './overlay.js';
|
|
3
4
|
const FIXTURE_RETENTION = {
|
|
4
|
-
history: {
|
|
5
|
-
kind: 'duration',
|
|
6
|
-
seconds: 1
|
|
7
|
-
},
|
|
5
|
+
history: { kind: 'duration', seconds: 1 },
|
|
8
6
|
outcome: 1,
|
|
9
|
-
refreshHorizon: 1
|
|
7
|
+
refreshHorizon: 1,
|
|
10
8
|
};
|
|
11
9
|
function declaredRetention(value) {
|
|
12
10
|
const retention = value ?? FIXTURE_RETENTION;
|
|
13
|
-
if (retention.history.kind === 'no-declared-time-bound')
|
|
11
|
+
if (retention.history.kind === 'no-declared-time-bound')
|
|
12
|
+
return retention;
|
|
14
13
|
if (Number.isFinite(retention.history.seconds) && retention.history.seconds > 0) {
|
|
15
14
|
return retention;
|
|
16
15
|
}
|
|
@@ -18,36 +17,68 @@ function declaredRetention(value) {
|
|
|
18
17
|
}
|
|
19
18
|
function named(source, paths) {
|
|
20
19
|
const taken = {};
|
|
21
|
-
for (const path of paths){
|
|
20
|
+
for (const path of paths) {
|
|
22
21
|
const value = source[path];
|
|
23
|
-
if (value !== undefined)
|
|
22
|
+
if (value !== undefined)
|
|
23
|
+
taken[path] = value;
|
|
24
24
|
}
|
|
25
25
|
return taken;
|
|
26
26
|
}
|
|
27
27
|
async function resolveScript(answer, fallback, request) {
|
|
28
|
-
if (answer === undefined)
|
|
28
|
+
if (answer === undefined)
|
|
29
|
+
return fallback();
|
|
29
30
|
return typeof answer === 'function' ? answer(request) : answer;
|
|
30
31
|
}
|
|
31
32
|
export function createMemoryAdapter(options = {}) {
|
|
32
|
-
let rooms = options.rooms === undefined ? [] : [
|
|
33
|
-
...options.rooms
|
|
34
|
-
];
|
|
33
|
+
let rooms = options.rooms === undefined ? [] : [...options.rooms];
|
|
35
34
|
const mdModel = options.mdModel ?? MD_MODEL;
|
|
36
|
-
const supportedVersions = options.supportedVersions ?? [
|
|
37
|
-
ROOM_CONTRACT_VERSION
|
|
38
|
-
];
|
|
35
|
+
const supportedVersions = options.supportedVersions ?? [ROOM_CONTRACT_VERSION];
|
|
39
36
|
const capabilities = options.capabilities ?? [];
|
|
40
37
|
const providerLimits = options.providerLimits ?? [];
|
|
41
38
|
const retention = declaredRetention(options.retention);
|
|
42
|
-
const origins = options.origins ?? [
|
|
43
|
-
'https://origin.example'
|
|
44
|
-
];
|
|
45
39
|
const pageSize = options.pageSize;
|
|
46
40
|
const scripts = {};
|
|
47
41
|
const served = new Map();
|
|
48
42
|
const refreshPages = new Map();
|
|
43
|
+
const observers = new Set();
|
|
44
|
+
const listeners = new Set();
|
|
45
|
+
const modeObservers = new Set();
|
|
46
|
+
const scripted = new Map();
|
|
47
|
+
const unsealed = new Map();
|
|
48
|
+
const sealed = new Set();
|
|
49
|
+
const historyPageSize = options.historyPageSize;
|
|
50
|
+
let selected = [];
|
|
51
|
+
let replicated = [];
|
|
52
|
+
let issued = 0;
|
|
53
|
+
function scriptConversations(entries) {
|
|
54
|
+
scripted.clear();
|
|
55
|
+
for (const entry of entries)
|
|
56
|
+
scripted.set(entry.conversation, entry);
|
|
57
|
+
}
|
|
58
|
+
scriptConversations(options.conversations ?? []);
|
|
59
|
+
const ordinals = new Map();
|
|
60
|
+
function note(locator, answer) {
|
|
61
|
+
const roomVersion = answer.roomVersion;
|
|
62
|
+
const key = `${locator}\u0000${String(roomVersion)}`;
|
|
63
|
+
if (typeof roomVersion === 'string' && !ordinals.has(key))
|
|
64
|
+
ordinals.set(key, ordinals.size);
|
|
65
|
+
return answer;
|
|
66
|
+
}
|
|
67
|
+
function reached(locator, roomVersion, target) {
|
|
68
|
+
const scripted = scripts.reached;
|
|
69
|
+
if (typeof scripted === 'boolean')
|
|
70
|
+
return scripted;
|
|
71
|
+
if (scripted !== undefined)
|
|
72
|
+
return scripted(locator, roomVersion, target);
|
|
73
|
+
if (roomVersion === target)
|
|
74
|
+
return true;
|
|
75
|
+
const held = ordinals.get(`${locator}\u0000${roomVersion}`);
|
|
76
|
+
const wanted = ordinals.get(`${locator}\u0000${target}`);
|
|
77
|
+
return held !== undefined && wanted !== undefined && held >= wanted;
|
|
78
|
+
}
|
|
49
79
|
function retain(entries) {
|
|
50
|
-
for (const room of entries){
|
|
80
|
+
for (const room of entries) {
|
|
81
|
+
note(room.locator, room);
|
|
51
82
|
const versions = served.get(room.locator) ?? new Map();
|
|
52
83
|
versions.set(room.roomVersion, room);
|
|
53
84
|
served.set(room.locator, versions);
|
|
@@ -58,12 +89,13 @@ export function createMemoryAdapter(options = {}) {
|
|
|
58
89
|
return {
|
|
59
90
|
name: room.name,
|
|
60
91
|
locator: room.locator,
|
|
61
|
-
collectionRoot: room.collectionRoot,
|
|
62
92
|
roomVersion: room.roomVersion,
|
|
63
93
|
operations: room.operations,
|
|
64
94
|
replica: room.replica,
|
|
65
95
|
attachedModel: room.attachedModel,
|
|
66
|
-
|
|
96
|
+
...(room.typedSelection === undefined ? {} : { typedSelection: room.typedSelection }),
|
|
97
|
+
...(room.untypedFolders === undefined ? {} : { untypedFolders: room.untypedFolders }),
|
|
98
|
+
providerOwnedPaths: room.providerOwnedPaths,
|
|
67
99
|
};
|
|
68
100
|
}
|
|
69
101
|
function page(room, from) {
|
|
@@ -71,15 +103,16 @@ export function createMemoryAdapter(options = {}) {
|
|
|
71
103
|
const size = pageSize ?? paths.length;
|
|
72
104
|
const taken = paths.slice(from, from + size);
|
|
73
105
|
const next = from + taken.length;
|
|
106
|
+
const targets = from === 0 ? (room.binaryTargets ?? []) : [];
|
|
74
107
|
return {
|
|
75
108
|
kind: 'bootstrap',
|
|
76
109
|
roomVersion: room.roomVersion,
|
|
77
110
|
documents: named(room.documents ?? {}, taken),
|
|
78
111
|
revisions: named(room.revisions ?? {}, taken),
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
} : {}
|
|
112
|
+
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
113
|
+
binaryTargets: targets,
|
|
114
|
+
...(from === 0 && room.attachments !== undefined ? { attachments: room.attachments } : {}),
|
|
115
|
+
...(next < paths.length ? { pageToken: String(next) } : {}),
|
|
83
116
|
};
|
|
84
117
|
}
|
|
85
118
|
function advancement(room, from, at) {
|
|
@@ -87,36 +120,108 @@ export function createMemoryAdapter(options = {}) {
|
|
|
87
120
|
const previous = from.documents ?? {};
|
|
88
121
|
const currentTargets = new Set(room.binaryTargets ?? []);
|
|
89
122
|
const previousTargets = new Set(from.binaryTargets ?? []);
|
|
90
|
-
const
|
|
123
|
+
const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
|
|
124
|
+
!sameChange(room.changes?.[path], from.changes?.[path]);
|
|
125
|
+
const changed = Object.keys(current)
|
|
126
|
+
.filter((path) => current[path] !== previous[path] || headMoved(path))
|
|
127
|
+
.sort();
|
|
91
128
|
const size = pageSize ?? changed.length;
|
|
92
129
|
const taken = changed.slice(at, at + size);
|
|
93
130
|
const next = at + taken.length;
|
|
94
131
|
const opening = at === 0;
|
|
95
132
|
const pageToken = next < changed.length ? `refresh-${refreshPages.size}` : undefined;
|
|
96
|
-
if (pageToken !== undefined)
|
|
97
|
-
room,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
133
|
+
if (pageToken !== undefined)
|
|
134
|
+
refreshPages.set(pageToken, { room, from, at: next });
|
|
135
|
+
const targets = opening
|
|
136
|
+
? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
|
|
137
|
+
: [];
|
|
138
|
+
const attachments = room.attachments ?? [];
|
|
139
|
+
const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
|
|
101
140
|
return {
|
|
102
141
|
kind: 'net-advancement',
|
|
103
142
|
roomVersion: room.roomVersion,
|
|
104
143
|
documents: named(current, taken),
|
|
105
144
|
revisions: named(room.revisions ?? {}, taken),
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
...pageToken === undefined ? {} : {
|
|
116
|
-
pageToken
|
|
117
|
-
}
|
|
145
|
+
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
146
|
+
binaryTargets: targets,
|
|
147
|
+
removals: opening
|
|
148
|
+
? [
|
|
149
|
+
...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
|
|
150
|
+
...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
|
|
151
|
+
].sort()
|
|
152
|
+
: [],
|
|
153
|
+
...(declared ? { attachments } : {}),
|
|
154
|
+
...(pageToken === undefined ? {} : { pageToken }),
|
|
118
155
|
};
|
|
119
156
|
}
|
|
157
|
+
function pageOf(conversation, after) {
|
|
158
|
+
const messages = conversation.messages ?? [];
|
|
159
|
+
const first = typeof after === 'string' ? messages.findIndex((message) => message.position > after) : 0;
|
|
160
|
+
const from = first === -1 ? messages.length : first;
|
|
161
|
+
const page = messages.slice(from, from + (historyPageSize ?? messages.length));
|
|
162
|
+
const last = page.at(-1);
|
|
163
|
+
return {
|
|
164
|
+
conversation: conversation.conversation,
|
|
165
|
+
messages: page,
|
|
166
|
+
...(last !== undefined && from + page.length < messages.length
|
|
167
|
+
? { next: last.position }
|
|
168
|
+
: {}),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function historiesOf(input) {
|
|
172
|
+
const asked = input?.conversations;
|
|
173
|
+
if (!Array.isArray(asked))
|
|
174
|
+
return { kind: 'rejected', code: 'invalid_request', fields: {} };
|
|
175
|
+
const histories = [];
|
|
176
|
+
for (const entry of asked) {
|
|
177
|
+
const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
|
|
178
|
+
if (conversation === undefined)
|
|
179
|
+
continue;
|
|
180
|
+
const outcome = conversation.outcomes?.['conversation.history'];
|
|
181
|
+
if (outcome !== undefined)
|
|
182
|
+
return outcome;
|
|
183
|
+
histories.push(pageOf(conversation, entry.after));
|
|
184
|
+
}
|
|
185
|
+
const result = { histories };
|
|
186
|
+
return { kind: 'action', result };
|
|
187
|
+
}
|
|
188
|
+
function conversationAction(request) {
|
|
189
|
+
const name = request.name;
|
|
190
|
+
const input = (request.input ?? {});
|
|
191
|
+
if (name === 'conversation.history')
|
|
192
|
+
return historiesOf(request.input);
|
|
193
|
+
if (name === 'conversation.create') {
|
|
194
|
+
issued += 1;
|
|
195
|
+
const conversation = `conversation-${issued}`;
|
|
196
|
+
scripted.set(conversation, { conversation });
|
|
197
|
+
return { kind: 'action', result: { conversation } };
|
|
198
|
+
}
|
|
199
|
+
const named = typeof input.conversation === 'string' ? input.conversation : '';
|
|
200
|
+
const conversation = scripted.get(named);
|
|
201
|
+
if (conversation === undefined) {
|
|
202
|
+
return { kind: 'rejected', code: 'unknown-conversation', fields: { conversation: named } };
|
|
203
|
+
}
|
|
204
|
+
const outcome = conversation.outcomes?.[name];
|
|
205
|
+
if (outcome !== undefined)
|
|
206
|
+
return outcome;
|
|
207
|
+
if (name === 'conversation.send') {
|
|
208
|
+
issued += 1;
|
|
209
|
+
const turn = `turn-${issued}`;
|
|
210
|
+
unsealed.set(turn, named);
|
|
211
|
+
return { kind: 'action', result: { turn } };
|
|
212
|
+
}
|
|
213
|
+
if (name === 'conversation.cancel') {
|
|
214
|
+
const turn = typeof input.turn === 'string' ? input.turn : '';
|
|
215
|
+
if (sealed.has(turn) || !unsealed.has(turn)) {
|
|
216
|
+
return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
|
|
217
|
+
}
|
|
218
|
+
unsealed.delete(turn);
|
|
219
|
+
return { kind: 'action', result: { turn, cancelled: true } };
|
|
220
|
+
}
|
|
221
|
+
if (name === 'conversation.delete')
|
|
222
|
+
scripted.delete(named);
|
|
223
|
+
return { kind: 'action', result: { conversation: named } };
|
|
224
|
+
}
|
|
120
225
|
function discovery() {
|
|
121
226
|
return {
|
|
122
227
|
kind: 'discovery',
|
|
@@ -126,110 +231,161 @@ export function createMemoryAdapter(options = {}) {
|
|
|
126
231
|
capabilities,
|
|
127
232
|
providerLimits,
|
|
128
233
|
retention,
|
|
129
|
-
origins
|
|
130
234
|
};
|
|
131
235
|
}
|
|
132
236
|
return {
|
|
133
|
-
setRooms
|
|
134
|
-
rooms = [
|
|
135
|
-
...next
|
|
136
|
-
];
|
|
237
|
+
setRooms(next) {
|
|
238
|
+
rooms = [...next];
|
|
137
239
|
retain(rooms);
|
|
138
240
|
},
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
241
|
+
setConversations(next) {
|
|
242
|
+
scriptConversations(next);
|
|
243
|
+
},
|
|
244
|
+
notifyRoomVersion(notification) {
|
|
245
|
+
for (const observer of observers)
|
|
246
|
+
observer(notification);
|
|
142
247
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
248
|
+
notifyConversation(event) {
|
|
249
|
+
if (event.kind === 'accepted-message') {
|
|
250
|
+
sealed.add(event.message.turn);
|
|
251
|
+
unsealed.delete(event.message.turn);
|
|
252
|
+
}
|
|
253
|
+
for (const listener of listeners)
|
|
254
|
+
listener(event);
|
|
148
255
|
},
|
|
149
|
-
|
|
150
|
-
|
|
256
|
+
notifyServiceMode(mode) {
|
|
257
|
+
for (const observer of modeObservers)
|
|
258
|
+
observer(mode);
|
|
151
259
|
},
|
|
152
|
-
|
|
153
|
-
return
|
|
260
|
+
selectedRooms() {
|
|
261
|
+
return selected;
|
|
154
262
|
},
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
|
|
263
|
+
replicatedConversations() {
|
|
264
|
+
return replicated;
|
|
265
|
+
},
|
|
266
|
+
conversations: {
|
|
267
|
+
replicate(next) {
|
|
268
|
+
replicated = [...next];
|
|
269
|
+
},
|
|
270
|
+
observe(notify) {
|
|
271
|
+
listeners.add(notify);
|
|
272
|
+
return () => {
|
|
273
|
+
listeners.delete(notify);
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
serviceMode: {
|
|
278
|
+
observe(notify) {
|
|
279
|
+
modeObservers.add(notify);
|
|
280
|
+
return () => {
|
|
281
|
+
modeObservers.delete(notify);
|
|
282
|
+
};
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
roomVersions: {
|
|
286
|
+
select(locators) {
|
|
287
|
+
selected = [...locators];
|
|
288
|
+
},
|
|
289
|
+
observe(notify) {
|
|
290
|
+
observers.add(notify);
|
|
291
|
+
return () => {
|
|
292
|
+
observers.delete(notify);
|
|
293
|
+
};
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
script(operation, answer) {
|
|
297
|
+
if (answer === undefined)
|
|
298
|
+
delete scripts[operation];
|
|
299
|
+
else
|
|
300
|
+
scripts[operation] = answer;
|
|
301
|
+
},
|
|
302
|
+
async model(_authorization, request) {
|
|
303
|
+
return resolveScript(scripts.model, () => {
|
|
304
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
305
|
+
const answer = request.attached === 'collection' ? room?.model : room?.selectionModel;
|
|
306
|
+
return answer ?? { kind: 'model-unavailable', reason: 'not-readable' };
|
|
307
|
+
}, request);
|
|
308
|
+
},
|
|
309
|
+
async authorize() {
|
|
310
|
+
return resolveScript(scripts.authorize, () => ({}), undefined);
|
|
311
|
+
},
|
|
312
|
+
async discover(_authorization) {
|
|
313
|
+
return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
|
|
314
|
+
if (answer.kind === 'discovery')
|
|
315
|
+
for (const room of answer.rooms)
|
|
316
|
+
note(room.locator, room);
|
|
317
|
+
return answer;
|
|
318
|
+
});
|
|
319
|
+
},
|
|
320
|
+
reached,
|
|
321
|
+
async bootstrap(_authorization, request) {
|
|
322
|
+
return resolveScript(scripts.bootstrap, () => {
|
|
323
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
158
324
|
if (room === undefined) {
|
|
159
|
-
return {
|
|
160
|
-
kind: 'room-not-readable',
|
|
161
|
-
locator: request.locator
|
|
162
|
-
};
|
|
325
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
163
326
|
}
|
|
164
327
|
return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));
|
|
165
|
-
}, request);
|
|
328
|
+
}, request).then((answer) => note(request.locator, answer));
|
|
166
329
|
},
|
|
167
|
-
async refresh
|
|
168
|
-
return resolveScript(scripts.refresh, ()=>{
|
|
169
|
-
const room = rooms.find((entry)=>entry.locator === request.locator);
|
|
330
|
+
async refresh(_authorization, request) {
|
|
331
|
+
return resolveScript(scripts.refresh, () => {
|
|
332
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
170
333
|
if (room === undefined) {
|
|
171
|
-
return {
|
|
172
|
-
kind: 'room-not-readable',
|
|
173
|
-
locator: request.locator
|
|
174
|
-
};
|
|
334
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
175
335
|
}
|
|
176
336
|
if (request.pageToken !== undefined) {
|
|
177
337
|
const continuation = refreshPages.get(request.pageToken);
|
|
178
|
-
if (continuation === undefined ||
|
|
338
|
+
if (continuation === undefined ||
|
|
339
|
+
continuation.room.locator !== request.locator ||
|
|
340
|
+
continuation.from.roomVersion !== request.fromRoomVersion) {
|
|
179
341
|
throw new Error('Invalid Refresh Page Token');
|
|
180
342
|
}
|
|
181
343
|
return advancement(continuation.room, continuation.from, continuation.at);
|
|
182
344
|
}
|
|
345
|
+
if (request.minPosition !== undefined &&
|
|
346
|
+
!reached(room.locator, room.roomVersion, request.minPosition)) {
|
|
347
|
+
return { kind: 'retryable-refusal', code: 'replica_behind', fields: {} };
|
|
348
|
+
}
|
|
183
349
|
if (request.fromRoomVersion === room.roomVersion) {
|
|
184
|
-
return {
|
|
185
|
-
kind: 'still-current'
|
|
186
|
-
};
|
|
350
|
+
return { kind: 'still-current' };
|
|
187
351
|
}
|
|
188
352
|
const from = served.get(room.locator)?.get(request.fromRoomVersion);
|
|
189
|
-
if (from === undefined)
|
|
190
|
-
kind: 'beyond-horizon'
|
|
191
|
-
};
|
|
353
|
+
if (from === undefined)
|
|
354
|
+
return { kind: 'beyond-horizon' };
|
|
192
355
|
return advancement(room, from, 0);
|
|
193
|
-
}, request);
|
|
356
|
+
}, request).then((answer) => note(request.locator, answer));
|
|
194
357
|
},
|
|
195
|
-
async mutate
|
|
196
|
-
return resolveScript(scripts.mutate, ()=>{
|
|
197
|
-
const room = rooms.find((entry)=>entry.locator === request.locator);
|
|
358
|
+
async mutate(_authorization, request) {
|
|
359
|
+
return resolveScript(scripts.mutate, () => {
|
|
360
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
198
361
|
if (room === undefined) {
|
|
199
|
-
return {
|
|
200
|
-
kind: 'room-not-readable',
|
|
201
|
-
locator: request.locator
|
|
202
|
-
};
|
|
362
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
203
363
|
}
|
|
204
|
-
return {
|
|
205
|
-
|
|
206
|
-
text: '',
|
|
207
|
-
affected: {}
|
|
208
|
-
};
|
|
209
|
-
}, request);
|
|
364
|
+
return { kind: 'rejected', code: 'unscripted-mutation', fields: {}, affected: {} };
|
|
365
|
+
}, request).then((answer) => note(request.locator, answer));
|
|
210
366
|
},
|
|
211
|
-
async history
|
|
212
|
-
return resolveScript(scripts.history, ()=>{
|
|
213
|
-
const room = rooms.find((entry)=>entry.locator === request.locator);
|
|
367
|
+
async history(_authorization, request) {
|
|
368
|
+
return resolveScript(scripts.history, () => {
|
|
369
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
214
370
|
if (room === undefined) {
|
|
215
|
-
return {
|
|
216
|
-
kind: 'room-not-readable',
|
|
217
|
-
locator: request.locator
|
|
218
|
-
};
|
|
371
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
219
372
|
}
|
|
220
373
|
return {
|
|
221
374
|
kind: 'history',
|
|
222
|
-
revisions: []
|
|
375
|
+
revisions: [],
|
|
223
376
|
};
|
|
224
377
|
}, request);
|
|
225
378
|
},
|
|
226
|
-
async action
|
|
227
|
-
return resolveScript(scripts.action, ()=>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
379
|
+
async action(_authorization, request) {
|
|
380
|
+
return resolveScript(scripts.action, () => {
|
|
381
|
+
if (request.name.startsWith('conversation.'))
|
|
382
|
+
return conversationAction(request);
|
|
383
|
+
return { kind: 'rejected', code: 'unscripted-action', fields: {} };
|
|
384
|
+
}, request).then((answer) => {
|
|
385
|
+
if (answer.kind === 'action' && answer.at !== undefined)
|
|
386
|
+
note(answer.at.locator, answer.at);
|
|
387
|
+
return answer;
|
|
388
|
+
});
|
|
389
|
+
},
|
|
232
390
|
};
|
|
233
391
|
}
|
|
234
|
-
|
|
235
|
-
//# sourceMappingURL=memory.js.map
|
package/dist/model.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { MdType } from './collection.js';
|
|
1
|
+
import type { Definition, FieldSpec, SectionSpec, VerifiedModel } from '@agentshouse/mdmodel';
|
|
3
2
|
export type ModelIdentity = {
|
|
4
3
|
identity: string;
|
|
5
4
|
version: string;
|
|
6
5
|
};
|
|
7
6
|
export type ModelSnapshot = ModelIdentity & {
|
|
8
|
-
|
|
7
|
+
schema: string | null;
|
|
9
8
|
};
|
|
10
|
-
export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'version-changed' | 'invalid'
|
|
9
|
+
export type ModelUnavailableReason = 'not-readable' | 'revoked' | 'not-acquired' | 'version-changed' | 'invalid';
|
|
11
10
|
export type ModelResult = {
|
|
12
11
|
kind: 'model';
|
|
13
12
|
snapshot: ModelSnapshot;
|
|
@@ -19,6 +18,11 @@ export type ModelResult = {
|
|
|
19
18
|
} | {
|
|
20
19
|
kind: 'revoked-authorization';
|
|
21
20
|
};
|
|
21
|
+
export type MdType = {
|
|
22
|
+
name: string;
|
|
23
|
+
fields: Readonly<Record<string, FieldSpec>>;
|
|
24
|
+
sections: Readonly<Record<string, SectionSpec>>;
|
|
25
|
+
};
|
|
22
26
|
export type ModelState = {
|
|
23
27
|
status: 'unavailable';
|
|
24
28
|
reason: ModelUnavailableReason;
|
|
@@ -26,7 +30,7 @@ export type ModelState = {
|
|
|
26
30
|
status: 'current' | 'cached';
|
|
27
31
|
snapshot: ModelSnapshot;
|
|
28
32
|
verifiedWith: ModelIdentity;
|
|
29
|
-
types:
|
|
33
|
+
types: VerifiedModel['types'];
|
|
30
34
|
};
|
|
31
35
|
export type TypesResult = {
|
|
32
36
|
status: 'unavailable';
|
|
@@ -38,32 +42,13 @@ export type TypesResult = {
|
|
|
38
42
|
verifiedWith: ModelIdentity;
|
|
39
43
|
types: readonly MdType[];
|
|
40
44
|
};
|
|
41
|
-
export type ModelValidation = {
|
|
42
|
-
verdict: 'accept';
|
|
43
|
-
} | (Extract<Validation, {
|
|
44
|
-
verdict: 'refuse';
|
|
45
|
-
}> & {
|
|
46
|
-
source: 'content' | 'model';
|
|
47
|
-
});
|
|
48
|
-
export type AttachedModelBinding = {
|
|
49
|
-
verify(snapshot: ModelSnapshot): {
|
|
50
|
-
kind: 'verified';
|
|
51
|
-
types: readonly MdType[];
|
|
52
|
-
} | {
|
|
53
|
-
kind: 'invalid';
|
|
54
|
-
};
|
|
55
|
-
validate(input: {
|
|
56
|
-
model: ModelSnapshot;
|
|
57
|
-
documents: Readonly<Record<string, string>>;
|
|
58
|
-
binaryTargets: readonly string[];
|
|
59
|
-
}): ModelValidation;
|
|
60
|
-
};
|
|
61
45
|
export type ValidationReceipt = {
|
|
62
46
|
identity: string;
|
|
63
47
|
version: string;
|
|
64
48
|
source: 'current' | 'cached';
|
|
65
49
|
};
|
|
66
50
|
export declare const NO_MODEL: ModelState;
|
|
51
|
+
export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
|
|
67
52
|
export declare function modelTypes(state: ModelState): TypesResult;
|
|
68
53
|
export declare function cached(state: ModelState): ModelState;
|
|
69
54
|
export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9F,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AACtE,MAAM,MAAM,sBAAsB,GAC9B,cAAc,GACd,SAAS,GACT,cAAc,GACd,iBAAiB,GACjB,SAAS,CAAC;AACd,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,CAAC;AACtC,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;CACjD,CAAC;AACF,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC;AACpG,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAGhG;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAEpD;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAE5E"}
|
package/dist/model.js
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
export const NO_MODEL = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export const NO_MODEL = { status: 'unavailable', reason: 'not-acquired' };
|
|
2
|
+
export function definitionOf(state, type) {
|
|
3
|
+
if (state.status === 'unavailable' || type === undefined)
|
|
4
|
+
return undefined;
|
|
5
|
+
return Object.hasOwn(state.types, type) ? state.types[type] : undefined;
|
|
6
|
+
}
|
|
5
7
|
export function modelTypes(state) {
|
|
6
|
-
return state.status === 'unavailable'
|
|
7
|
-
...state
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
return state.status === 'unavailable'
|
|
9
|
+
? { ...state }
|
|
10
|
+
: {
|
|
11
|
+
status: state.status,
|
|
12
|
+
identity: state.snapshot.identity,
|
|
13
|
+
version: state.snapshot.version,
|
|
14
|
+
verifiedWith: { ...state.verifiedWith },
|
|
15
|
+
types: structuredClone(Object.values(state.types)
|
|
16
|
+
.sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0))
|
|
17
|
+
.map(({ name, fields, sections }) => ({ name, fields, sections }))),
|
|
18
|
+
};
|
|
17
19
|
}
|
|
18
20
|
export function cached(state) {
|
|
19
|
-
return state.status === 'unavailable' ? state : {
|
|
20
|
-
...state,
|
|
21
|
-
status: 'cached'
|
|
22
|
-
};
|
|
21
|
+
return state.status === 'unavailable' ? state : { ...state, status: 'cached' };
|
|
23
22
|
}
|
|
24
23
|
export function sameModel(left, right) {
|
|
25
24
|
return left.identity === right.identity && left.version === right.version;
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { QueryDocument, QueryGroup, QueryResult } from './query.js';
|
|
2
|
+
export type Observation<T> = {
|
|
3
|
+
current(): T;
|
|
4
|
+
subscribe(listener: (value: T) => void): () => void;
|
|
5
|
+
close(): void;
|
|
6
|
+
};
|
|
7
|
+
export type RowKey = string | number;
|
|
8
|
+
export type KeyedResult = {
|
|
9
|
+
result: QueryResult;
|
|
10
|
+
keys: readonly RowKey[];
|
|
11
|
+
};
|
|
12
|
+
export type QueryChange = {
|
|
13
|
+
changed: readonly (readonly [RowKey, QueryDocument | QueryGroup])[];
|
|
14
|
+
removed: readonly RowKey[];
|
|
15
|
+
order: readonly RowKey[] | null;
|
|
16
|
+
};
|
|
17
|
+
export type Observed = {
|
|
18
|
+
observation: Observation<unknown>;
|
|
19
|
+
receive(message: unknown): void;
|
|
20
|
+
end(): void;
|
|
21
|
+
};
|
|
22
|
+
export declare function rowsOf(result: QueryResult): readonly (QueryDocument | QueryGroup)[];
|
|
23
|
+
export declare function observed(first: unknown, stop: () => void, keyed: boolean): Observed;
|
|
24
|
+
export declare function opened(watch: (deliver: (message: unknown) => void) => () => void, keyed: boolean): Promise<Observation<unknown>>;
|
|
25
|
+
//# sourceMappingURL=observation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,IAAI,CAAC,CAAC;IACb,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACpD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC;IACpE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,GAAG,IAAI,IAAI,CAAC;CACb,CAAC;AAEF,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,aAAa,GAAG,UAAU,CAAC,EAAE,CAEnF;AA0BD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAkCnF;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,EAC1D,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAiB/B"}
|