@agentshouse/mdruntime 0.1.0-alpha.8 → 0.1.0-c009335e08279
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 +208 -0
- package/README.md +44 -0
- package/dist/adapter.d.ts +215 -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 +31 -28
- package/dist/change-set.d.ts +33 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/change-set.js +83 -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 +69 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +165 -0
- package/dist/collection.d.ts +22 -15
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +60 -78
- package/dist/connection.d.ts +68 -40
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1597 -961
- 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 +13 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +175 -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 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- 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 +268 -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 +12 -24
- 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 +233 -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 +266 -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 +75 -18
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +358 -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 +118 -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,12 @@ 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
|
+
providerOwnedPaths: room.providerOwnedPaths,
|
|
67
98
|
};
|
|
68
99
|
}
|
|
69
100
|
function page(room, from) {
|
|
@@ -71,15 +102,16 @@ export function createMemoryAdapter(options = {}) {
|
|
|
71
102
|
const size = pageSize ?? paths.length;
|
|
72
103
|
const taken = paths.slice(from, from + size);
|
|
73
104
|
const next = from + taken.length;
|
|
105
|
+
const targets = from === 0 ? (room.binaryTargets ?? []) : [];
|
|
74
106
|
return {
|
|
75
107
|
kind: 'bootstrap',
|
|
76
108
|
roomVersion: room.roomVersion,
|
|
77
109
|
documents: named(room.documents ?? {}, taken),
|
|
78
110
|
revisions: named(room.revisions ?? {}, taken),
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
} : {}
|
|
111
|
+
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
112
|
+
binaryTargets: targets,
|
|
113
|
+
...(from === 0 && room.attachments !== undefined ? { attachments: room.attachments } : {}),
|
|
114
|
+
...(next < paths.length ? { pageToken: String(next) } : {}),
|
|
83
115
|
};
|
|
84
116
|
}
|
|
85
117
|
function advancement(room, from, at) {
|
|
@@ -87,36 +119,108 @@ export function createMemoryAdapter(options = {}) {
|
|
|
87
119
|
const previous = from.documents ?? {};
|
|
88
120
|
const currentTargets = new Set(room.binaryTargets ?? []);
|
|
89
121
|
const previousTargets = new Set(from.binaryTargets ?? []);
|
|
90
|
-
const
|
|
122
|
+
const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
|
|
123
|
+
!sameChange(room.changes?.[path], from.changes?.[path]);
|
|
124
|
+
const changed = Object.keys(current)
|
|
125
|
+
.filter((path) => current[path] !== previous[path] || headMoved(path))
|
|
126
|
+
.sort();
|
|
91
127
|
const size = pageSize ?? changed.length;
|
|
92
128
|
const taken = changed.slice(at, at + size);
|
|
93
129
|
const next = at + taken.length;
|
|
94
130
|
const opening = at === 0;
|
|
95
131
|
const pageToken = next < changed.length ? `refresh-${refreshPages.size}` : undefined;
|
|
96
|
-
if (pageToken !== undefined)
|
|
97
|
-
room,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
132
|
+
if (pageToken !== undefined)
|
|
133
|
+
refreshPages.set(pageToken, { room, from, at: next });
|
|
134
|
+
const targets = opening
|
|
135
|
+
? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
|
|
136
|
+
: [];
|
|
137
|
+
const attachments = room.attachments ?? [];
|
|
138
|
+
const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
|
|
101
139
|
return {
|
|
102
140
|
kind: 'net-advancement',
|
|
103
141
|
roomVersion: room.roomVersion,
|
|
104
142
|
documents: named(current, taken),
|
|
105
143
|
revisions: named(room.revisions ?? {}, taken),
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
...pageToken === undefined ? {} : {
|
|
116
|
-
pageToken
|
|
117
|
-
}
|
|
144
|
+
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
145
|
+
binaryTargets: targets,
|
|
146
|
+
removals: opening
|
|
147
|
+
? [
|
|
148
|
+
...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
|
|
149
|
+
...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
|
|
150
|
+
].sort()
|
|
151
|
+
: [],
|
|
152
|
+
...(declared ? { attachments } : {}),
|
|
153
|
+
...(pageToken === undefined ? {} : { pageToken }),
|
|
118
154
|
};
|
|
119
155
|
}
|
|
156
|
+
function pageOf(conversation, after) {
|
|
157
|
+
const messages = conversation.messages ?? [];
|
|
158
|
+
const first = typeof after === 'string' ? messages.findIndex((message) => message.position > after) : 0;
|
|
159
|
+
const from = first === -1 ? messages.length : first;
|
|
160
|
+
const page = messages.slice(from, from + (historyPageSize ?? messages.length));
|
|
161
|
+
const last = page.at(-1);
|
|
162
|
+
return {
|
|
163
|
+
conversation: conversation.conversation,
|
|
164
|
+
messages: page,
|
|
165
|
+
...(last !== undefined && from + page.length < messages.length
|
|
166
|
+
? { next: last.position }
|
|
167
|
+
: {}),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function historiesOf(input) {
|
|
171
|
+
const asked = input?.conversations;
|
|
172
|
+
if (!Array.isArray(asked))
|
|
173
|
+
return { kind: 'rejected', code: 'invalid_request', fields: {} };
|
|
174
|
+
const histories = [];
|
|
175
|
+
for (const entry of asked) {
|
|
176
|
+
const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
|
|
177
|
+
if (conversation === undefined)
|
|
178
|
+
continue;
|
|
179
|
+
const outcome = conversation.outcomes?.['conversation.history'];
|
|
180
|
+
if (outcome !== undefined)
|
|
181
|
+
return outcome;
|
|
182
|
+
histories.push(pageOf(conversation, entry.after));
|
|
183
|
+
}
|
|
184
|
+
const result = { histories };
|
|
185
|
+
return { kind: 'action', result };
|
|
186
|
+
}
|
|
187
|
+
function conversationAction(request) {
|
|
188
|
+
const name = request.name;
|
|
189
|
+
const input = (request.input ?? {});
|
|
190
|
+
if (name === 'conversation.history')
|
|
191
|
+
return historiesOf(request.input);
|
|
192
|
+
if (name === 'conversation.create') {
|
|
193
|
+
issued += 1;
|
|
194
|
+
const conversation = `conversation-${issued}`;
|
|
195
|
+
scripted.set(conversation, { conversation });
|
|
196
|
+
return { kind: 'action', result: { conversation } };
|
|
197
|
+
}
|
|
198
|
+
const named = typeof input.conversation === 'string' ? input.conversation : '';
|
|
199
|
+
const conversation = scripted.get(named);
|
|
200
|
+
if (conversation === undefined) {
|
|
201
|
+
return { kind: 'rejected', code: 'unknown-conversation', fields: { conversation: named } };
|
|
202
|
+
}
|
|
203
|
+
const outcome = conversation.outcomes?.[name];
|
|
204
|
+
if (outcome !== undefined)
|
|
205
|
+
return outcome;
|
|
206
|
+
if (name === 'conversation.send') {
|
|
207
|
+
issued += 1;
|
|
208
|
+
const turn = `turn-${issued}`;
|
|
209
|
+
unsealed.set(turn, named);
|
|
210
|
+
return { kind: 'action', result: { turn } };
|
|
211
|
+
}
|
|
212
|
+
if (name === 'conversation.cancel') {
|
|
213
|
+
const turn = typeof input.turn === 'string' ? input.turn : '';
|
|
214
|
+
if (sealed.has(turn) || !unsealed.has(turn)) {
|
|
215
|
+
return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
|
|
216
|
+
}
|
|
217
|
+
unsealed.delete(turn);
|
|
218
|
+
return { kind: 'action', result: { turn, cancelled: true } };
|
|
219
|
+
}
|
|
220
|
+
if (name === 'conversation.delete')
|
|
221
|
+
scripted.delete(named);
|
|
222
|
+
return { kind: 'action', result: { conversation: named } };
|
|
223
|
+
}
|
|
120
224
|
function discovery() {
|
|
121
225
|
return {
|
|
122
226
|
kind: 'discovery',
|
|
@@ -126,110 +230,161 @@ export function createMemoryAdapter(options = {}) {
|
|
|
126
230
|
capabilities,
|
|
127
231
|
providerLimits,
|
|
128
232
|
retention,
|
|
129
|
-
origins
|
|
130
233
|
};
|
|
131
234
|
}
|
|
132
235
|
return {
|
|
133
|
-
setRooms
|
|
134
|
-
rooms = [
|
|
135
|
-
...next
|
|
136
|
-
];
|
|
236
|
+
setRooms(next) {
|
|
237
|
+
rooms = [...next];
|
|
137
238
|
retain(rooms);
|
|
138
239
|
},
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
240
|
+
setConversations(next) {
|
|
241
|
+
scriptConversations(next);
|
|
242
|
+
},
|
|
243
|
+
notifyRoomVersion(notification) {
|
|
244
|
+
for (const observer of observers)
|
|
245
|
+
observer(notification);
|
|
142
246
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
247
|
+
notifyConversation(event) {
|
|
248
|
+
if (event.kind === 'accepted-message') {
|
|
249
|
+
sealed.add(event.message.turn);
|
|
250
|
+
unsealed.delete(event.message.turn);
|
|
251
|
+
}
|
|
252
|
+
for (const listener of listeners)
|
|
253
|
+
listener(event);
|
|
148
254
|
},
|
|
149
|
-
|
|
150
|
-
|
|
255
|
+
notifyServiceMode(mode) {
|
|
256
|
+
for (const observer of modeObservers)
|
|
257
|
+
observer(mode);
|
|
151
258
|
},
|
|
152
|
-
|
|
153
|
-
return
|
|
259
|
+
selectedRooms() {
|
|
260
|
+
return selected;
|
|
154
261
|
},
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
|
|
262
|
+
replicatedConversations() {
|
|
263
|
+
return replicated;
|
|
264
|
+
},
|
|
265
|
+
conversations: {
|
|
266
|
+
replicate(next) {
|
|
267
|
+
replicated = [...next];
|
|
268
|
+
},
|
|
269
|
+
observe(notify) {
|
|
270
|
+
listeners.add(notify);
|
|
271
|
+
return () => {
|
|
272
|
+
listeners.delete(notify);
|
|
273
|
+
};
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
serviceMode: {
|
|
277
|
+
observe(notify) {
|
|
278
|
+
modeObservers.add(notify);
|
|
279
|
+
return () => {
|
|
280
|
+
modeObservers.delete(notify);
|
|
281
|
+
};
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
roomVersions: {
|
|
285
|
+
select(locators) {
|
|
286
|
+
selected = [...locators];
|
|
287
|
+
},
|
|
288
|
+
observe(notify) {
|
|
289
|
+
observers.add(notify);
|
|
290
|
+
return () => {
|
|
291
|
+
observers.delete(notify);
|
|
292
|
+
};
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
script(operation, answer) {
|
|
296
|
+
if (answer === undefined)
|
|
297
|
+
delete scripts[operation];
|
|
298
|
+
else
|
|
299
|
+
scripts[operation] = answer;
|
|
300
|
+
},
|
|
301
|
+
async model(_authorization, request) {
|
|
302
|
+
return resolveScript(scripts.model, () => {
|
|
303
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
304
|
+
const answer = request.attached === 'collection' ? room?.model : room?.selectionModel;
|
|
305
|
+
return answer ?? { kind: 'model-unavailable', reason: 'not-readable' };
|
|
306
|
+
}, request);
|
|
307
|
+
},
|
|
308
|
+
async authorize() {
|
|
309
|
+
return resolveScript(scripts.authorize, () => ({}), undefined);
|
|
310
|
+
},
|
|
311
|
+
async discover(_authorization) {
|
|
312
|
+
return resolveScript(scripts.discover, discovery, undefined).then((answer) => {
|
|
313
|
+
if (answer.kind === 'discovery')
|
|
314
|
+
for (const room of answer.rooms)
|
|
315
|
+
note(room.locator, room);
|
|
316
|
+
return answer;
|
|
317
|
+
});
|
|
318
|
+
},
|
|
319
|
+
reached,
|
|
320
|
+
async bootstrap(_authorization, request) {
|
|
321
|
+
return resolveScript(scripts.bootstrap, () => {
|
|
322
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
158
323
|
if (room === undefined) {
|
|
159
|
-
return {
|
|
160
|
-
kind: 'room-not-readable',
|
|
161
|
-
locator: request.locator
|
|
162
|
-
};
|
|
324
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
163
325
|
}
|
|
164
326
|
return page(room, request.pageToken === undefined ? 0 : Number(request.pageToken));
|
|
165
|
-
}, request);
|
|
327
|
+
}, request).then((answer) => note(request.locator, answer));
|
|
166
328
|
},
|
|
167
|
-
async refresh
|
|
168
|
-
return resolveScript(scripts.refresh, ()=>{
|
|
169
|
-
const room = rooms.find((entry)=>entry.locator === request.locator);
|
|
329
|
+
async refresh(_authorization, request) {
|
|
330
|
+
return resolveScript(scripts.refresh, () => {
|
|
331
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
170
332
|
if (room === undefined) {
|
|
171
|
-
return {
|
|
172
|
-
kind: 'room-not-readable',
|
|
173
|
-
locator: request.locator
|
|
174
|
-
};
|
|
333
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
175
334
|
}
|
|
176
335
|
if (request.pageToken !== undefined) {
|
|
177
336
|
const continuation = refreshPages.get(request.pageToken);
|
|
178
|
-
if (continuation === undefined ||
|
|
337
|
+
if (continuation === undefined ||
|
|
338
|
+
continuation.room.locator !== request.locator ||
|
|
339
|
+
continuation.from.roomVersion !== request.fromRoomVersion) {
|
|
179
340
|
throw new Error('Invalid Refresh Page Token');
|
|
180
341
|
}
|
|
181
342
|
return advancement(continuation.room, continuation.from, continuation.at);
|
|
182
343
|
}
|
|
344
|
+
if (request.minPosition !== undefined &&
|
|
345
|
+
!reached(room.locator, room.roomVersion, request.minPosition)) {
|
|
346
|
+
return { kind: 'retryable-refusal', code: 'replica_behind', fields: {} };
|
|
347
|
+
}
|
|
183
348
|
if (request.fromRoomVersion === room.roomVersion) {
|
|
184
|
-
return {
|
|
185
|
-
kind: 'still-current'
|
|
186
|
-
};
|
|
349
|
+
return { kind: 'still-current' };
|
|
187
350
|
}
|
|
188
351
|
const from = served.get(room.locator)?.get(request.fromRoomVersion);
|
|
189
|
-
if (from === undefined)
|
|
190
|
-
kind: 'beyond-horizon'
|
|
191
|
-
};
|
|
352
|
+
if (from === undefined)
|
|
353
|
+
return { kind: 'beyond-horizon' };
|
|
192
354
|
return advancement(room, from, 0);
|
|
193
|
-
}, request);
|
|
355
|
+
}, request).then((answer) => note(request.locator, answer));
|
|
194
356
|
},
|
|
195
|
-
async mutate
|
|
196
|
-
return resolveScript(scripts.mutate, ()=>{
|
|
197
|
-
const room = rooms.find((entry)=>entry.locator === request.locator);
|
|
357
|
+
async mutate(_authorization, request) {
|
|
358
|
+
return resolveScript(scripts.mutate, () => {
|
|
359
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
198
360
|
if (room === undefined) {
|
|
199
|
-
return {
|
|
200
|
-
kind: 'room-not-readable',
|
|
201
|
-
locator: request.locator
|
|
202
|
-
};
|
|
361
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
203
362
|
}
|
|
204
|
-
return {
|
|
205
|
-
|
|
206
|
-
text: '',
|
|
207
|
-
affected: {}
|
|
208
|
-
};
|
|
209
|
-
}, request);
|
|
363
|
+
return { kind: 'rejected', code: 'unscripted-mutation', fields: {}, affected: {} };
|
|
364
|
+
}, request).then((answer) => note(request.locator, answer));
|
|
210
365
|
},
|
|
211
|
-
async history
|
|
212
|
-
return resolveScript(scripts.history, ()=>{
|
|
213
|
-
const room = rooms.find((entry)=>entry.locator === request.locator);
|
|
366
|
+
async history(_authorization, request) {
|
|
367
|
+
return resolveScript(scripts.history, () => {
|
|
368
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
214
369
|
if (room === undefined) {
|
|
215
|
-
return {
|
|
216
|
-
kind: 'room-not-readable',
|
|
217
|
-
locator: request.locator
|
|
218
|
-
};
|
|
370
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
219
371
|
}
|
|
220
372
|
return {
|
|
221
373
|
kind: 'history',
|
|
222
|
-
revisions: []
|
|
374
|
+
revisions: [],
|
|
223
375
|
};
|
|
224
376
|
}, request);
|
|
225
377
|
},
|
|
226
|
-
async action
|
|
227
|
-
return resolveScript(scripts.action, ()=>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
378
|
+
async action(_authorization, request) {
|
|
379
|
+
return resolveScript(scripts.action, () => {
|
|
380
|
+
if (request.name.startsWith('conversation.'))
|
|
381
|
+
return conversationAction(request);
|
|
382
|
+
return { kind: 'rejected', code: 'unscripted-action', fields: {} };
|
|
383
|
+
}, request).then((answer) => {
|
|
384
|
+
if (answer.kind === 'action' && answer.at !== undefined)
|
|
385
|
+
note(answer.at.locator, answer.at);
|
|
386
|
+
return answer;
|
|
387
|
+
});
|
|
388
|
+
},
|
|
232
389
|
};
|
|
233
390
|
}
|
|
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"}
|