@agentshouse/mdruntime 0.1.0-cec6690d5712e → 0.1.0-cedd665dffa4c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -19
- package/dist/acceptance.d.ts +3 -0
- package/dist/acceptance.d.ts.map +1 -0
- package/dist/acceptance.js +299 -0
- package/dist/act-lanes.d.ts +30 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +225 -0
- package/dist/actions.d.ts +26 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +302 -0
- package/dist/adapter.d.ts +207 -94
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +6 -10
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +35 -41
- package/dist/binary.d.ts +18 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +8 -0
- package/dist/bootstrap.d.ts +31 -11
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +311 -92
- package/dist/cell.d.ts +6 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +9 -0
- package/dist/chain.d.ts +12 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +64 -0
- package/dist/change-set.d.ts +13 -14
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +17 -62
- package/dist/change.d.ts +46 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +39 -0
- package/dist/chat-types.d.ts +3 -0
- package/dist/chat-types.d.ts.map +1 -0
- package/dist/chat-types.js +11 -0
- package/dist/client.d.ts +51 -27
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +133 -26
- package/dist/collection.d.ts +34 -9
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +55 -79
- package/dist/compile.d.ts +18 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +723 -0
- package/dist/connection.d.ts +8 -111
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +113 -2221
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/{chat/context.js → context.js} +2 -5
- package/dist/conversation-live.d.ts +150 -0
- package/dist/conversation-live.d.ts.map +1 -0
- package/dist/conversation-live.js +259 -0
- package/dist/conversation-row.d.ts +40 -0
- package/dist/conversation-row.d.ts.map +1 -0
- package/dist/conversation-row.js +66 -0
- package/dist/conversation.d.ts +84 -45
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +1118 -584
- package/dist/declaration.d.ts +10 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +24 -0
- package/dist/digest.d.ts +7 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +113 -0
- package/dist/discovery.d.ts +10 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +150 -0
- package/dist/durability.d.ts +23 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +9 -0
- package/dist/entry.d.ts +20 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +161 -0
- package/dist/expectation.d.ts +26 -13
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +72 -19
- package/dist/failure.d.ts +3 -0
- package/dist/failure.d.ts.map +1 -1
- package/dist/failure.js +6 -0
- package/dist/figures.d.ts +49 -0
- package/dist/figures.d.ts.map +1 -0
- package/dist/figures.js +199 -0
- package/dist/file.d.ts +2 -19
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +8 -122
- package/dist/holdings.d.ts +29 -0
- package/dist/holdings.d.ts.map +1 -0
- package/dist/holdings.js +95 -0
- package/dist/host.d.ts +29 -4
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +179 -25
- package/dist/identity.d.ts +1 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +3 -0
- package/dist/index.d.ts +42 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -2
- package/dist/install.d.ts +60 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +537 -0
- package/dist/lifecycle.d.ts +7 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +278 -0
- package/dist/listing.d.ts +52 -0
- package/dist/listing.d.ts.map +1 -0
- package/dist/listing.js +152 -0
- package/dist/live.d.ts +25 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +206 -0
- package/dist/loaded.d.ts +5 -0
- package/dist/loaded.d.ts.map +1 -0
- package/dist/loaded.js +40 -0
- package/dist/locks.d.ts +7 -0
- package/dist/locks.d.ts.map +1 -0
- package/dist/locks.js +32 -0
- package/dist/lost.d.ts +5 -0
- package/dist/lost.d.ts.map +1 -0
- package/dist/lost.js +49 -0
- package/dist/media.d.ts +13 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +269 -0
- package/dist/memory.d.ts +26 -8
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +307 -97
- package/dist/messages.d.ts +58 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +162 -0
- package/dist/model.d.ts +11 -12
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -15
- package/dist/models.d.ts +10 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +153 -0
- package/dist/name.d.ts +4 -0
- package/dist/name.d.ts.map +1 -0
- package/dist/name.js +122 -0
- package/dist/observation.d.ts +42 -9
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +238 -33
- package/dist/opened.d.ts +22 -0
- package/dist/opened.d.ts.map +1 -0
- package/dist/opened.js +107 -0
- package/dist/opening.d.ts +4 -0
- package/dist/opening.d.ts.map +1 -0
- package/dist/opening.js +53 -0
- package/dist/outcome.d.ts +63 -5
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +70 -0
- package/dist/overlay.d.ts +21 -6
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +163 -187
- package/dist/page-metadata.d.ts +8 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +19 -0
- package/dist/parts.d.ts +4 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +13 -0
- package/dist/paths.d.ts +2 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +26 -0
- package/dist/preparation.d.ts +41 -0
- package/dist/preparation.d.ts.map +1 -0
- package/dist/preparation.js +314 -0
- package/dist/presence.d.ts +58 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +231 -0
- package/dist/queries.d.ts +16 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +308 -0
- package/dist/query.d.ts +51 -183
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -464
- package/dist/{chat/questions.d.ts → questions.d.ts} +5 -7
- package/dist/questions.d.ts.map +1 -0
- package/dist/{chat/questions.js → questions.js} +11 -7
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +480 -0
- package/dist/reach.d.ts +20 -5
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +357 -80
- package/dist/react.d.ts +23 -7
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +40 -18
- package/dist/{chat/read.d.ts → read.d.ts} +2 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/{chat/read.js → read.js} +4 -0
- package/dist/readiness.d.ts +55 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +25 -0
- package/dist/reads.d.ts +39 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +178 -0
- package/dist/recovery.d.ts +28 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +254 -0
- package/dist/refresh.d.ts +17 -14
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +145 -58
- package/dist/refusal.d.ts +5 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +55 -0
- package/dist/replica.d.ts +53 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +349 -167
- package/dist/retried.d.ts +30 -0
- package/dist/retried.d.ts.map +1 -0
- package/dist/retried.js +72 -0
- package/dist/room-draft.d.ts +82 -11
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +490 -78
- package/dist/room-drafts.d.ts +24 -0
- package/dist/room-drafts.d.ts.map +1 -0
- package/dist/room-drafts.js +220 -0
- package/dist/rows.d.ts +31 -35
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +60 -126
- package/dist/runtime.d.ts +34 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/save.d.ts +45 -22
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +977 -215
- package/dist/saves.d.ts +32 -0
- package/dist/saves.d.ts.map +1 -0
- package/dist/saves.js +426 -0
- package/dist/search.d.ts +15 -55
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +10 -121
- package/dist/seed.d.ts +25 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +145 -0
- package/dist/shared.d.ts +10 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +339 -0
- package/dist/shown.d.ts +33 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +309 -0
- package/dist/socket/admission.d.ts +7 -0
- package/dist/socket/admission.d.ts.map +1 -0
- package/dist/socket/admission.js +39 -0
- package/dist/socket/answers.d.ts +6 -0
- package/dist/socket/answers.d.ts.map +1 -0
- package/dist/socket/answers.js +20 -0
- package/dist/socket/lanes.d.ts +28 -0
- package/dist/socket/lanes.d.ts.map +1 -0
- package/dist/socket/lanes.js +103 -0
- package/dist/socket/reads.d.ts +10 -0
- package/dist/socket/reads.d.ts.map +1 -0
- package/dist/socket/reads.js +31 -0
- package/dist/socket/session.d.ts +38 -0
- package/dist/socket/session.d.ts.map +1 -0
- package/dist/socket/session.js +23 -0
- package/dist/socket.d.ts +67 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +164 -0
- package/dist/source.d.ts +59 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +93 -0
- package/dist/status.d.ts +5 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -7
- package/dist/store/installs.d.ts +30 -0
- package/dist/store/installs.d.ts.map +1 -0
- package/dist/store/installs.js +40 -0
- package/dist/store/readiness.d.ts +11 -0
- package/dist/store/readiness.d.ts.map +1 -0
- package/dist/store/readiness.js +68 -0
- package/dist/store/records.d.ts +217 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +464 -0
- package/dist/store/room-held.d.ts +8 -0
- package/dist/store/room-held.d.ts.map +1 -0
- package/dist/store/room-held.js +17 -0
- package/dist/store/rooms-shown.d.ts +8 -0
- package/dist/store/rooms-shown.d.ts.map +1 -0
- package/dist/store/rooms-shown.js +13 -0
- package/dist/store/space.d.ts +11 -0
- package/dist/store/space.d.ts.map +1 -0
- package/dist/store/space.js +41 -0
- package/dist/store/watchers.d.ts +17 -0
- package/dist/store/watchers.d.ts.map +1 -0
- package/dist/store/watchers.js +56 -0
- package/dist/store/writes.d.ts +24 -0
- package/dist/store/writes.d.ts.map +1 -0
- package/dist/store/writes.js +125 -0
- package/dist/store.d.ts +114 -116
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +164 -494
- package/dist/stored.d.ts +167 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +703 -0
- package/dist/surface.d.ts +89 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +222 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +535 -0
- package/dist/tables.d.ts +419 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +758 -0
- package/dist/tallies.d.ts +18 -0
- package/dist/tallies.d.ts.map +1 -0
- package/dist/tallies.js +128 -0
- package/dist/transfer.d.ts +0 -5
- package/dist/transfer.d.ts.map +1 -1
- package/dist/turn.d.ts +9 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +75 -0
- package/dist/validation.d.ts +29 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +98 -0
- package/dist/windows.d.ts +11 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +16 -0
- package/dist/wire.d.ts +221 -34
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +74 -31
- package/package.json +28 -24
- package/AGENTS.md +0 -299
- package/dist/attachment.d.ts +0 -3
- package/dist/attachment.d.ts.map +0 -1
- package/dist/attachment.js +0 -8
- package/dist/attempt.d.ts +0 -16
- package/dist/attempt.d.ts.map +0 -1
- package/dist/attempt.js +0 -57
- package/dist/chat/acts.d.ts +0 -34
- package/dist/chat/acts.d.ts.map +0 -1
- package/dist/chat/acts.js +0 -36
- package/dist/chat/context.d.ts +0 -3
- package/dist/chat/context.d.ts.map +0 -1
- package/dist/chat/input.d.ts +0 -9
- package/dist/chat/input.d.ts.map +0 -1
- package/dist/chat/input.js +0 -99
- package/dist/chat/kit.d.ts +0 -60
- package/dist/chat/kit.d.ts.map +0 -1
- package/dist/chat/kit.js +0 -123
- package/dist/chat/lasting.d.ts +0 -6
- package/dist/chat/lasting.d.ts.map +0 -1
- package/dist/chat/lasting.js +0 -19
- package/dist/chat/list.d.ts +0 -20
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -59
- package/dist/chat/markdown.d.ts +0 -19
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -187
- package/dist/chat/message.d.ts +0 -6
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -192
- package/dist/chat/messages.d.ts +0 -21
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -151
- package/dist/chat/name.d.ts +0 -6
- package/dist/chat/name.d.ts.map +0 -1
- package/dist/chat/name.js +0 -37
- package/dist/chat/opened.d.ts +0 -11
- package/dist/chat/opened.d.ts.map +0 -1
- package/dist/chat/opened.js +0 -17
- package/dist/chat/overlay.d.ts +0 -31
- package/dist/chat/overlay.d.ts.map +0 -1
- package/dist/chat/overlay.js +0 -97
- package/dist/chat/parts.d.ts +0 -57
- package/dist/chat/parts.d.ts.map +0 -1
- package/dist/chat/parts.js +0 -119
- package/dist/chat/process.d.ts +0 -20
- package/dist/chat/process.d.ts.map +0 -1
- package/dist/chat/process.js +0 -32
- package/dist/chat/provider.d.ts +0 -63
- package/dist/chat/provider.d.ts.map +0 -1
- package/dist/chat/provider.js +0 -645
- package/dist/chat/question.d.ts +0 -9
- package/dist/chat/question.d.ts.map +0 -1
- package/dist/chat/question.js +0 -80
- package/dist/chat/questions.d.ts.map +0 -1
- package/dist/chat/read.d.ts.map +0 -1
- package/dist/chat/ready.d.ts +0 -33
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -91
- package/dist/chat/style.d.ts +0 -4
- package/dist/chat/style.d.ts.map +0 -1
- package/dist/chat/style.js +0 -302
- package/dist/chat.d.ts +0 -14
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/log.d.ts +0 -5
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/read-side.d.ts +0 -18
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -433
package/dist/search.js
CHANGED
|
@@ -1,125 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { invalid, known, limitOf, plain } from './query.js';
|
|
3
|
-
const FIELDS = ['fields', 'sections', 'preamble', 'path', 'text'];
|
|
4
|
-
function documentId(room, path) {
|
|
5
|
-
return JSON.stringify(['document', room, path]);
|
|
6
|
-
}
|
|
7
|
-
function messageId(conversation, identity) {
|
|
8
|
-
return JSON.stringify(['message', conversation, identity]);
|
|
9
|
-
}
|
|
10
|
-
function scalars(value) {
|
|
11
|
-
if (value === null || value === undefined)
|
|
12
|
-
return [];
|
|
13
|
-
if (Array.isArray(value))
|
|
14
|
-
return value.flatMap(scalars);
|
|
15
|
-
if (typeof value === 'object')
|
|
16
|
-
return Object.values(value).flatMap(scalars);
|
|
17
|
-
return [String(value)];
|
|
18
|
-
}
|
|
1
|
+
import { invalid, known, plain } from '@agentshouse/mdmodel';
|
|
19
2
|
export function searchPlanOf(input) {
|
|
20
3
|
if (!plain(input))
|
|
21
4
|
invalid('search', 'expects a search object');
|
|
22
|
-
known(input, ['text', '
|
|
23
|
-
if (typeof input.text !== 'string')
|
|
24
|
-
invalid('text', 'expects
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
(!Array.isArray(
|
|
28
|
-
invalid('
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
text: input.text,
|
|
32
|
-
documents: input.documents,
|
|
33
|
-
conversations: conversations ?? null,
|
|
34
|
-
limit: limitOf(input.limit),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
export function createSearchIndex(source) {
|
|
38
|
-
let index = null;
|
|
39
|
-
const documents = new Map();
|
|
40
|
-
const messages = new Map();
|
|
41
|
-
const changedDocuments = new Map();
|
|
42
|
-
const changedMessages = new Map();
|
|
43
|
-
function addDocument(built, document) {
|
|
44
|
-
const id = documentId(document.room, document.path);
|
|
45
|
-
documents.set(id, { room: document.room, path: document.path, type: document.type });
|
|
46
|
-
built.add({
|
|
47
|
-
id,
|
|
48
|
-
fields: scalars(document.fields).join('\n'),
|
|
49
|
-
sections: Object.entries(document.sections)
|
|
50
|
-
.map(([heading, text]) => `${heading}\n${text}`)
|
|
51
|
-
.join('\n'),
|
|
52
|
-
preamble: document.preamble,
|
|
53
|
-
path: document.path,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
function addMessage(built, message) {
|
|
57
|
-
const id = messageId(message.conversation, message.identity);
|
|
58
|
-
messages.set(id, { conversation: message.conversation, identity: message.identity });
|
|
59
|
-
built.add({ id, text: message.text });
|
|
60
|
-
}
|
|
61
|
-
function current() {
|
|
62
|
-
if (index === null) {
|
|
63
|
-
const built = new MiniSearch({ fields: FIELDS });
|
|
64
|
-
for (const document of source.documents())
|
|
65
|
-
addDocument(built, document);
|
|
66
|
-
for (const message of source.messages())
|
|
67
|
-
addMessage(built, message);
|
|
68
|
-
index = built;
|
|
69
|
-
return built;
|
|
70
|
-
}
|
|
71
|
-
const built = index;
|
|
72
|
-
for (const [id, { room, path }] of changedDocuments) {
|
|
73
|
-
if (documents.delete(id))
|
|
74
|
-
built.discard(id);
|
|
75
|
-
const document = source.document(room, path);
|
|
76
|
-
if (document !== null)
|
|
77
|
-
addDocument(built, document);
|
|
78
|
-
}
|
|
79
|
-
changedDocuments.clear();
|
|
80
|
-
for (const [id, { conversation, identity }] of changedMessages) {
|
|
81
|
-
if (messages.delete(id))
|
|
82
|
-
built.discard(id);
|
|
83
|
-
const message = source.message(conversation, identity);
|
|
84
|
-
if (message !== null)
|
|
85
|
-
addMessage(built, message);
|
|
86
|
-
}
|
|
87
|
-
changedMessages.clear();
|
|
88
|
-
return built;
|
|
89
|
-
}
|
|
90
|
-
function ranked(built, text, entries, keep, limit) {
|
|
91
|
-
const found = built.search(text, {
|
|
92
|
-
filter: ({ id }) => {
|
|
93
|
-
const entry = entries.get(id);
|
|
94
|
-
return entry !== undefined && keep(entry, id);
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
return (limit === null ? found : found.slice(0, limit)).map(({ id, score, match }) => ({
|
|
98
|
-
...entries.get(id),
|
|
99
|
-
score,
|
|
100
|
-
match,
|
|
101
|
-
}));
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
changed(set) {
|
|
105
|
-
if (index === null)
|
|
106
|
-
return;
|
|
107
|
-
for (const { locator, path } of set.documents) {
|
|
108
|
-
changedDocuments.set(documentId(locator, path), { room: locator, path });
|
|
109
|
-
}
|
|
110
|
-
for (const { conversation, identity } of set.messages) {
|
|
111
|
-
changedMessages.set(messageId(conversation, identity), { conversation, identity });
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
search({ text, conversations, limit }, selected) {
|
|
115
|
-
const built = current();
|
|
116
|
-
const chosen = selected === null
|
|
117
|
-
? null
|
|
118
|
-
: new Set(selected.map(({ room, path }) => documentId(room, path)));
|
|
119
|
-
return {
|
|
120
|
-
documents: ranked(built, text, documents, (_entry, id) => chosen === null || chosen.has(id), limit).map(({ match, ...hit }) => ({ ...hit, matches: match })),
|
|
121
|
-
messages: ranked(built, text, messages, ({ conversation }) => conversations === null || conversations.includes(conversation), limit).map(({ match, ...hit }) => ({ ...hit, matches: match })),
|
|
122
|
-
};
|
|
123
|
-
},
|
|
124
|
-
};
|
|
5
|
+
known(input, ['text', 'rooms'], '');
|
|
6
|
+
if (typeof input.text !== 'string' || input.text.trim() === '')
|
|
7
|
+
invalid('text', 'expects words');
|
|
8
|
+
const rooms = input.rooms;
|
|
9
|
+
if (rooms !== undefined &&
|
|
10
|
+
(!Array.isArray(rooms) || rooms.some((named) => typeof named !== 'string'))) {
|
|
11
|
+
invalid('rooms', 'expects a list of Rooms');
|
|
12
|
+
}
|
|
13
|
+
return { text: input.text, rooms: rooms ?? null };
|
|
125
14
|
}
|
package/dist/seed.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Cover } from './live.js';
|
|
2
|
+
import { type KeyedResult } from './observation.js';
|
|
3
|
+
import type { Plan, QueryRows } from './query.js';
|
|
4
|
+
import type { Deliver } from './reach.js';
|
|
5
|
+
import type { Runtime } from './runtime.js';
|
|
6
|
+
import type { HeldCover, Store } from './store.js';
|
|
7
|
+
export type EntrySeed = {
|
|
8
|
+
readonly at: Readonly<Record<string, string>>;
|
|
9
|
+
readonly queries: readonly {
|
|
10
|
+
readonly query: unknown;
|
|
11
|
+
readonly rows: QueryRows;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
export type Seeded = {
|
|
15
|
+
readonly rows: QueryRows;
|
|
16
|
+
readonly at: Readonly<Record<string, string>>;
|
|
17
|
+
};
|
|
18
|
+
type SeededWatch = (coverOf: (cover: Cover, held: HeldCover) => Cover, deliver: (message: unknown) => void) => () => void;
|
|
19
|
+
export declare function entrySeedOf(value: unknown): EntrySeed | null;
|
|
20
|
+
export declare function seededResult(seed: Seeded): KeyedResult;
|
|
21
|
+
export declare function seedApplies(runtime: Runtime, plan: Plan, held: HeldCover): Seeded | null;
|
|
22
|
+
export declare function keepEntrySeed(store: Store, entry: EntrySeed): void;
|
|
23
|
+
export declare function watchSeeded(runtime: Runtime, plan: Plan, deliver: Deliver, watch: SeededWatch): () => void;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAwB,KAAK,WAAW,EAAqB,MAAM,kBAAkB,CAAC;AAC7F,OAAO,KAAK,EAAE,IAAI,EAA4C,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;KAAE,EAAE,CAAC;CACpF,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAC;AAEjG,KAAK,WAAW,GAAG,CACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KAAK,KAAK,EACjD,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KAChC,MAAM,IAAI,CAAC;AA0ChB,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAe5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAmBtD;AA+BD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAOxF;AAYD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAMlE;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,WAAW,GACjB,MAAM,IAAI,CA4BZ"}
|
package/dist/seed.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { queryKey } from '@agentshouse/mdmodel';
|
|
2
|
+
import { pendingChange, whole } from './observation.js';
|
|
3
|
+
import { documentKey } from './rows.js';
|
|
4
|
+
const seedTopic = (key) => `seed\u0000${key}`;
|
|
5
|
+
function plain(value) {
|
|
6
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
function windowOf(value) {
|
|
9
|
+
const { next, total } = value;
|
|
10
|
+
if (next !== undefined && typeof next !== 'string')
|
|
11
|
+
return null;
|
|
12
|
+
if (total !== undefined && !Number.isSafeInteger(total))
|
|
13
|
+
return null;
|
|
14
|
+
return {
|
|
15
|
+
...(next === undefined ? {} : { next }),
|
|
16
|
+
...(total === undefined ? {} : { total: total }),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function rowsOf(value) {
|
|
20
|
+
if (!plain(value))
|
|
21
|
+
return null;
|
|
22
|
+
const window = windowOf(value);
|
|
23
|
+
if (window === null)
|
|
24
|
+
return null;
|
|
25
|
+
if (Array.isArray(value.groups)) {
|
|
26
|
+
const groups = value.groups;
|
|
27
|
+
return groups.every((group) => plain(group) && Array.isArray(group.key) && typeof group.count === 'number')
|
|
28
|
+
? { groups: groups, ...window }
|
|
29
|
+
: null;
|
|
30
|
+
}
|
|
31
|
+
if (!Array.isArray(value.documents))
|
|
32
|
+
return null;
|
|
33
|
+
const documents = value.documents;
|
|
34
|
+
return documents.every((document) => plain(document) && typeof document.room === 'string' && typeof document.path === 'string')
|
|
35
|
+
? { documents: documents, ...window }
|
|
36
|
+
: null;
|
|
37
|
+
}
|
|
38
|
+
export function entrySeedOf(value) {
|
|
39
|
+
if (!plain(value) || !plain(value.at) || !Array.isArray(value.queries))
|
|
40
|
+
return null;
|
|
41
|
+
const at = {};
|
|
42
|
+
for (const [room, version] of Object.entries(value.at)) {
|
|
43
|
+
if (typeof version !== 'string')
|
|
44
|
+
return null;
|
|
45
|
+
at[room] = version;
|
|
46
|
+
}
|
|
47
|
+
const queries = [];
|
|
48
|
+
for (const entry of value.queries) {
|
|
49
|
+
if (!plain(entry) || !plain(entry.query))
|
|
50
|
+
return null;
|
|
51
|
+
const rows = rowsOf(entry.rows);
|
|
52
|
+
if (rows === null)
|
|
53
|
+
return null;
|
|
54
|
+
queries.push({ query: entry.query, rows });
|
|
55
|
+
}
|
|
56
|
+
return { at, queries };
|
|
57
|
+
}
|
|
58
|
+
export function seededResult(seed) {
|
|
59
|
+
const coverage = {
|
|
60
|
+
rooms: Object.entries(seed.at).map(([room, generation]) => ({
|
|
61
|
+
room,
|
|
62
|
+
generation,
|
|
63
|
+
current: false,
|
|
64
|
+
})),
|
|
65
|
+
overlay: [],
|
|
66
|
+
};
|
|
67
|
+
if ('groups' in seed.rows) {
|
|
68
|
+
return {
|
|
69
|
+
result: { ...seed.rows, coverage },
|
|
70
|
+
keys: seed.rows.groups.map((_group, index) => index),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
result: { ...seed.rows, coverage },
|
|
75
|
+
keys: seed.rows.documents.map((document) => documentKey(document.room, document.path)),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function seedRoomHeld({ socket }, room, version, held) {
|
|
79
|
+
const stored = held.rooms.get(room);
|
|
80
|
+
return (stored !== undefined &&
|
|
81
|
+
stored.indexed &&
|
|
82
|
+
socket.reads.reached(room, stored.roomVersion, version));
|
|
83
|
+
}
|
|
84
|
+
function seedHeld(runtime, at, held) {
|
|
85
|
+
const { socket, presence } = runtime;
|
|
86
|
+
return Object.entries(at).every(([room, version]) => (socket.session.now().roomsListed &&
|
|
87
|
+
presence.room(room) === undefined &&
|
|
88
|
+
!held.rooms.has(room)) ||
|
|
89
|
+
seedRoomHeld(runtime, room, version, held));
|
|
90
|
+
}
|
|
91
|
+
export function seedApplies(runtime, plan, held) {
|
|
92
|
+
const { seeds } = runtime.store;
|
|
93
|
+
const seed = seeds.of(plan.key);
|
|
94
|
+
if (seed === undefined)
|
|
95
|
+
return null;
|
|
96
|
+
if (!seedHeld(runtime, seed.at, held))
|
|
97
|
+
return seed;
|
|
98
|
+
seeds.drop(plan.key);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
function seedBehind(runtime, plan, cover, held) {
|
|
102
|
+
const seed = seedApplies(runtime, plan, held);
|
|
103
|
+
if (seed === null || 'pending' in cover)
|
|
104
|
+
return cover;
|
|
105
|
+
return {
|
|
106
|
+
pending: Object.entries(seed.at)
|
|
107
|
+
.filter(([room, version]) => !seedRoomHeld(runtime, room, version, held))
|
|
108
|
+
.map(([room]) => ({ room, awaits: 'acquisition' })),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function keepEntrySeed(store, entry) {
|
|
112
|
+
for (const { query, rows } of entry.queries) {
|
|
113
|
+
const key = queryKey(query);
|
|
114
|
+
store.seeds.keep(key, { rows, at: entry.at });
|
|
115
|
+
for (const watcher of store.watching(seedTopic(key)))
|
|
116
|
+
watcher.answer(null);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function watchSeeded(runtime, plan, deliver, watch) {
|
|
120
|
+
const { store } = runtime;
|
|
121
|
+
let seeded = false;
|
|
122
|
+
let pending = true;
|
|
123
|
+
const shown = () => {
|
|
124
|
+
const seed = store.seeds.of(plan.key);
|
|
125
|
+
if (seed === undefined || seeded || !pending)
|
|
126
|
+
return;
|
|
127
|
+
seeded = true;
|
|
128
|
+
deliver(seededResult(seed));
|
|
129
|
+
};
|
|
130
|
+
const watcher = store.watch(seedTopic(plan.key), shown);
|
|
131
|
+
const stop = watch((cover, held) => seedBehind(runtime, plan, cover, held), (message) => {
|
|
132
|
+
const answered = message;
|
|
133
|
+
pending = whole(answered) ? 'pending' in answered.result : pendingChange(answered);
|
|
134
|
+
if (pending && store.seeds.of(plan.key) !== undefined) {
|
|
135
|
+
shown();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
seeded = false;
|
|
139
|
+
deliver(message);
|
|
140
|
+
});
|
|
141
|
+
return () => {
|
|
142
|
+
watcher.stop();
|
|
143
|
+
stop();
|
|
144
|
+
};
|
|
145
|
+
}
|
package/dist/shared.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Paths<V> = Readonly<Record<string, V>>;
|
|
2
|
+
export declare function guarding<V>(values: Paths<V>, handler: ProxyHandler<Paths<V>>): Paths<V>;
|
|
3
|
+
export declare function entriesIn<V>(map: Paths<V>): Generator<readonly [string, V]>;
|
|
4
|
+
export declare function sortedKeys(map: Paths<unknown>): Generator<number, readonly string[], void>;
|
|
5
|
+
export declare function sorting(keys: Iterable<string>): Generator<number, readonly string[], void>;
|
|
6
|
+
export declare function patching<V>(base: Paths<V>, set: Iterable<readonly [string, V]>, removed?: Iterable<string>): Generator<number, Paths<V>, void>;
|
|
7
|
+
export declare function drafted<V>(base: Paths<V>): Record<string, V>;
|
|
8
|
+
export declare function settled<V>(draft: Record<string, V>): Paths<V>;
|
|
9
|
+
export declare function settling<V>(draft: Record<string, V>): Generator<number, Paths<V>, void>;
|
|
10
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AA8LnD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAIvF;AAED,wBAAiB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAQ5E;AAqCD,wBAAiB,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,CAE3F;AAED,wBAAiB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,CAoB3F;AAED,wBAAiB,QAAQ,CAAC,CAAC,EACzB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EACnC,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAM,GAC7B,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAgBnC;AAMD,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAiD5D;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAE7D;AAED,wBAAiB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAUxF"}
|
package/dist/shared.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { finished, ROW_WEIGHT } from './turn.js';
|
|
2
|
+
const BITS = 5;
|
|
3
|
+
const MASK = (1 << BITS) - 1;
|
|
4
|
+
const roots = new WeakMap();
|
|
5
|
+
function hashOf(key) {
|
|
6
|
+
let hash = 0x811c9dc5;
|
|
7
|
+
for (let index = 0; index < key.length; index += 1) {
|
|
8
|
+
hash ^= key.charCodeAt(index);
|
|
9
|
+
hash = Math.imul(hash, 0x01000193);
|
|
10
|
+
}
|
|
11
|
+
return hash >>> 0;
|
|
12
|
+
}
|
|
13
|
+
function isLeaf(node) {
|
|
14
|
+
return 'key' in node;
|
|
15
|
+
}
|
|
16
|
+
function isCollision(node) {
|
|
17
|
+
return 'leaves' in node;
|
|
18
|
+
}
|
|
19
|
+
function fragment(hash, shift) {
|
|
20
|
+
return (hash >>> shift) & MASK;
|
|
21
|
+
}
|
|
22
|
+
function count(bits) {
|
|
23
|
+
let left = bits - ((bits >>> 1) & 0x55555555);
|
|
24
|
+
left = (left & 0x33333333) + ((left >>> 2) & 0x33333333);
|
|
25
|
+
return (((left + (left >>> 4)) & 0x0f0f0f0f) * 0x01010101) >>> 24;
|
|
26
|
+
}
|
|
27
|
+
function slot(bitmap, bit) {
|
|
28
|
+
return count(bitmap & (bit - 1));
|
|
29
|
+
}
|
|
30
|
+
function lookup(root, key) {
|
|
31
|
+
const hash = hashOf(key);
|
|
32
|
+
let node = root.node;
|
|
33
|
+
let shift = 0;
|
|
34
|
+
while (node !== undefined) {
|
|
35
|
+
if (isLeaf(node))
|
|
36
|
+
return node.key === key ? node : undefined;
|
|
37
|
+
if (isCollision(node))
|
|
38
|
+
return node.leaves.find((leaf) => leaf.key === key);
|
|
39
|
+
const bit = 1 << fragment(hash, shift);
|
|
40
|
+
if ((node.bitmap & bit) === 0)
|
|
41
|
+
return undefined;
|
|
42
|
+
node = node.children[slot(node.bitmap, bit)];
|
|
43
|
+
shift += BITS;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
function branchOf(node, shift) {
|
|
48
|
+
return { bitmap: 1 << fragment(node.hash, shift), children: [node] };
|
|
49
|
+
}
|
|
50
|
+
function joined(left, right, shift) {
|
|
51
|
+
if (left.hash === right.hash) {
|
|
52
|
+
const leaves = isCollision(left) ? left.leaves : [left];
|
|
53
|
+
return { hash: right.hash, leaves: [...leaves, right] };
|
|
54
|
+
}
|
|
55
|
+
return put(branchOf(left, shift), right, shift);
|
|
56
|
+
}
|
|
57
|
+
function put(node, leaf, shift) {
|
|
58
|
+
if (node === undefined)
|
|
59
|
+
return leaf;
|
|
60
|
+
if (isLeaf(node)) {
|
|
61
|
+
if (node.key !== leaf.key)
|
|
62
|
+
return joined(node, leaf, shift);
|
|
63
|
+
return node.value === leaf.value ? node : leaf;
|
|
64
|
+
}
|
|
65
|
+
if (isCollision(node)) {
|
|
66
|
+
if (node.hash !== leaf.hash)
|
|
67
|
+
return joined(node, leaf, shift);
|
|
68
|
+
const at = node.leaves.findIndex((held) => held.key === leaf.key);
|
|
69
|
+
if (at === -1)
|
|
70
|
+
return { hash: node.hash, leaves: [...node.leaves, leaf] };
|
|
71
|
+
if (node.leaves[at].value === leaf.value)
|
|
72
|
+
return node;
|
|
73
|
+
return {
|
|
74
|
+
hash: node.hash,
|
|
75
|
+
leaves: node.leaves.map((held, index) => (index === at ? leaf : held)),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const bit = 1 << fragment(leaf.hash, shift);
|
|
79
|
+
const at = slot(node.bitmap, bit);
|
|
80
|
+
if ((node.bitmap & bit) === 0) {
|
|
81
|
+
return {
|
|
82
|
+
bitmap: node.bitmap | bit,
|
|
83
|
+
children: [...node.children.slice(0, at), leaf, ...node.children.slice(at)],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const child = node.children[at];
|
|
87
|
+
const next = put(child, leaf, shift + BITS);
|
|
88
|
+
if (next === child)
|
|
89
|
+
return node;
|
|
90
|
+
return {
|
|
91
|
+
bitmap: node.bitmap,
|
|
92
|
+
children: node.children.map((held, index) => (index === at ? next : held)),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function lone(node) {
|
|
96
|
+
if (node.children.length !== 1)
|
|
97
|
+
return null;
|
|
98
|
+
const [only] = node.children;
|
|
99
|
+
return isLeaf(only) || isCollision(only) ? only : null;
|
|
100
|
+
}
|
|
101
|
+
function taken(node, hash, key, shift) {
|
|
102
|
+
if (isLeaf(node))
|
|
103
|
+
return undefined;
|
|
104
|
+
if (isCollision(node)) {
|
|
105
|
+
const leaves = node.leaves.filter((leaf) => leaf.key !== key);
|
|
106
|
+
return leaves.length === 1 ? leaves[0] : { hash: node.hash, leaves };
|
|
107
|
+
}
|
|
108
|
+
const bit = 1 << fragment(hash, shift);
|
|
109
|
+
const at = slot(node.bitmap, bit);
|
|
110
|
+
const child = node.children[at];
|
|
111
|
+
const next = taken(child, hash, key, shift + BITS);
|
|
112
|
+
if (next === undefined) {
|
|
113
|
+
if (node.children.length === 1)
|
|
114
|
+
return undefined;
|
|
115
|
+
const rest = {
|
|
116
|
+
bitmap: node.bitmap & ~bit,
|
|
117
|
+
children: node.children.filter((_, index) => index !== at),
|
|
118
|
+
};
|
|
119
|
+
return lone(rest) ?? rest;
|
|
120
|
+
}
|
|
121
|
+
const replaced = {
|
|
122
|
+
bitmap: node.bitmap,
|
|
123
|
+
children: node.children.map((held, index) => (index === at ? next : held)),
|
|
124
|
+
};
|
|
125
|
+
return lone(replaced) ?? replaced;
|
|
126
|
+
}
|
|
127
|
+
function* leavesOf(node) {
|
|
128
|
+
if (node === undefined)
|
|
129
|
+
return;
|
|
130
|
+
if (isLeaf(node)) {
|
|
131
|
+
yield node;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (isCollision(node)) {
|
|
135
|
+
yield* node.leaves;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
for (const child of node.children)
|
|
139
|
+
yield* leavesOf(child);
|
|
140
|
+
}
|
|
141
|
+
function facade(root) {
|
|
142
|
+
let keys;
|
|
143
|
+
const target = {};
|
|
144
|
+
const map = new Proxy(target, {
|
|
145
|
+
get(held, property, receiver) {
|
|
146
|
+
if (typeof property === 'string') {
|
|
147
|
+
const leaf = lookup(root, property);
|
|
148
|
+
if (leaf !== undefined)
|
|
149
|
+
return leaf.value;
|
|
150
|
+
}
|
|
151
|
+
return Reflect.get(held, property, receiver);
|
|
152
|
+
},
|
|
153
|
+
has(held, property) {
|
|
154
|
+
return ((typeof property === 'string' && lookup(root, property) !== undefined) ||
|
|
155
|
+
Reflect.has(held, property));
|
|
156
|
+
},
|
|
157
|
+
ownKeys() {
|
|
158
|
+
keys ??= [...leavesOf(root.node)].map((leaf) => leaf.key);
|
|
159
|
+
return keys;
|
|
160
|
+
},
|
|
161
|
+
getOwnPropertyDescriptor(_held, property) {
|
|
162
|
+
if (typeof property !== 'string')
|
|
163
|
+
return undefined;
|
|
164
|
+
const leaf = lookup(root, property);
|
|
165
|
+
if (leaf === undefined)
|
|
166
|
+
return undefined;
|
|
167
|
+
return { value: leaf.value, writable: false, enumerable: true, configurable: true };
|
|
168
|
+
},
|
|
169
|
+
set: () => false,
|
|
170
|
+
defineProperty: () => false,
|
|
171
|
+
deleteProperty: () => false,
|
|
172
|
+
});
|
|
173
|
+
roots.set(map, root);
|
|
174
|
+
return map;
|
|
175
|
+
}
|
|
176
|
+
const guarded = new WeakMap();
|
|
177
|
+
export function guarding(values, handler) {
|
|
178
|
+
const map = new Proxy(values, handler);
|
|
179
|
+
guarded.set(map, values);
|
|
180
|
+
return map;
|
|
181
|
+
}
|
|
182
|
+
export function* entriesIn(map) {
|
|
183
|
+
const root = roots.get(map);
|
|
184
|
+
if (root === undefined) {
|
|
185
|
+
const values = guarded.get(map) ?? map;
|
|
186
|
+
for (const key of Object.keys(values))
|
|
187
|
+
yield [key, values[key]];
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
for (const leaf of leavesOf(root.node))
|
|
191
|
+
yield [leaf.key, leaf.value];
|
|
192
|
+
}
|
|
193
|
+
function* rooted(map) {
|
|
194
|
+
const held = roots.get(map);
|
|
195
|
+
if (held !== undefined)
|
|
196
|
+
return held;
|
|
197
|
+
let node;
|
|
198
|
+
for (const [key, value] of entriesIn(map)) {
|
|
199
|
+
node = put(node, { key, hash: hashOf(key), value }, 0);
|
|
200
|
+
yield ROW_WEIGHT;
|
|
201
|
+
}
|
|
202
|
+
return { node };
|
|
203
|
+
}
|
|
204
|
+
const RUN = 1 << 10;
|
|
205
|
+
function* merged(left, right) {
|
|
206
|
+
const into = [];
|
|
207
|
+
let at = 0;
|
|
208
|
+
let from = 0;
|
|
209
|
+
while (at < left.length || from < right.length) {
|
|
210
|
+
into.push(from === right.length || (at < left.length && left[at] < right[from])
|
|
211
|
+
? left[at++]
|
|
212
|
+
: right[from++]);
|
|
213
|
+
yield ROW_WEIGHT;
|
|
214
|
+
}
|
|
215
|
+
return into;
|
|
216
|
+
}
|
|
217
|
+
function* pathsOf(map) {
|
|
218
|
+
for (const [key] of entriesIn(map))
|
|
219
|
+
yield key;
|
|
220
|
+
}
|
|
221
|
+
export function* sortedKeys(map) {
|
|
222
|
+
return yield* sorting(pathsOf(map));
|
|
223
|
+
}
|
|
224
|
+
export function* sorting(keys) {
|
|
225
|
+
let runs = [];
|
|
226
|
+
let run = [];
|
|
227
|
+
for (const key of keys) {
|
|
228
|
+
run.push(key);
|
|
229
|
+
yield ROW_WEIGHT;
|
|
230
|
+
if (run.length === RUN) {
|
|
231
|
+
runs.push(run.sort());
|
|
232
|
+
run = [];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (run.length > 0)
|
|
236
|
+
runs.push(run.sort());
|
|
237
|
+
while (runs.length > 1) {
|
|
238
|
+
const next = [];
|
|
239
|
+
for (let at = 0; at < runs.length; at += 2) {
|
|
240
|
+
next.push(at + 1 === runs.length ? runs[at] : yield* merged(runs[at], runs[at + 1]));
|
|
241
|
+
}
|
|
242
|
+
runs = next;
|
|
243
|
+
}
|
|
244
|
+
return runs[0] ?? [];
|
|
245
|
+
}
|
|
246
|
+
export function* patching(base, set, removed = []) {
|
|
247
|
+
const root = yield* rooted(base);
|
|
248
|
+
let node = root.node;
|
|
249
|
+
for (const key of removed) {
|
|
250
|
+
if (node === undefined)
|
|
251
|
+
break;
|
|
252
|
+
const before = lookup({ node }, key);
|
|
253
|
+
if (before === undefined)
|
|
254
|
+
continue;
|
|
255
|
+
node = taken(node, before.hash, key, 0);
|
|
256
|
+
yield ROW_WEIGHT;
|
|
257
|
+
}
|
|
258
|
+
for (const [key, value] of set) {
|
|
259
|
+
node = put(node, { key, hash: hashOf(key), value }, 0);
|
|
260
|
+
yield ROW_WEIGHT;
|
|
261
|
+
}
|
|
262
|
+
if (node === root.node && roots.has(base))
|
|
263
|
+
return base;
|
|
264
|
+
return facade({ node });
|
|
265
|
+
}
|
|
266
|
+
const drafts = new WeakMap();
|
|
267
|
+
const GONE = Symbol('gone');
|
|
268
|
+
export function drafted(base) {
|
|
269
|
+
const written = new Map();
|
|
270
|
+
const read = (key) => {
|
|
271
|
+
const held = written.get(key);
|
|
272
|
+
if (held === GONE)
|
|
273
|
+
return undefined;
|
|
274
|
+
return held ?? (Object.hasOwn(base, key) ? base[key] : undefined);
|
|
275
|
+
};
|
|
276
|
+
const draft = new Proxy({}, {
|
|
277
|
+
get(held, property, receiver) {
|
|
278
|
+
if (typeof property === 'string') {
|
|
279
|
+
const value = read(property);
|
|
280
|
+
if (value !== undefined)
|
|
281
|
+
return value;
|
|
282
|
+
}
|
|
283
|
+
return Reflect.get(held, property, receiver);
|
|
284
|
+
},
|
|
285
|
+
has(held, property) {
|
|
286
|
+
return ((typeof property === 'string' && read(property) !== undefined) ||
|
|
287
|
+
Reflect.has(held, property));
|
|
288
|
+
},
|
|
289
|
+
ownKeys() {
|
|
290
|
+
const keys = new Set(Object.keys(base));
|
|
291
|
+
for (const [key, value] of written) {
|
|
292
|
+
if (value === GONE)
|
|
293
|
+
keys.delete(key);
|
|
294
|
+
else
|
|
295
|
+
keys.add(key);
|
|
296
|
+
}
|
|
297
|
+
return [...keys];
|
|
298
|
+
},
|
|
299
|
+
getOwnPropertyDescriptor(_held, property) {
|
|
300
|
+
if (typeof property !== 'string')
|
|
301
|
+
return undefined;
|
|
302
|
+
const value = read(property);
|
|
303
|
+
if (value === undefined)
|
|
304
|
+
return undefined;
|
|
305
|
+
return { value, writable: true, enumerable: true, configurable: true };
|
|
306
|
+
},
|
|
307
|
+
set(_held, property, value) {
|
|
308
|
+
if (typeof property !== 'string')
|
|
309
|
+
return false;
|
|
310
|
+
written.set(property, value);
|
|
311
|
+
return true;
|
|
312
|
+
},
|
|
313
|
+
deleteProperty(_held, property) {
|
|
314
|
+
if (typeof property !== 'string')
|
|
315
|
+
return false;
|
|
316
|
+
written.set(property, GONE);
|
|
317
|
+
return true;
|
|
318
|
+
},
|
|
319
|
+
defineProperty: () => false,
|
|
320
|
+
});
|
|
321
|
+
drafts.set(draft, { base, written });
|
|
322
|
+
return draft;
|
|
323
|
+
}
|
|
324
|
+
export function settled(draft) {
|
|
325
|
+
return finished(settling(draft));
|
|
326
|
+
}
|
|
327
|
+
export function* settling(draft) {
|
|
328
|
+
const held = drafts.get(draft);
|
|
329
|
+
const set = [];
|
|
330
|
+
const removed = [];
|
|
331
|
+
for (const [key, value] of held.written) {
|
|
332
|
+
if (value === GONE)
|
|
333
|
+
removed.push(key);
|
|
334
|
+
else
|
|
335
|
+
set.push([key, value]);
|
|
336
|
+
yield ROW_WEIGHT;
|
|
337
|
+
}
|
|
338
|
+
return yield* patching(held.base, set, removed);
|
|
339
|
+
}
|