@agentshouse/mdruntime 0.1.0-caee7332d2235 → 0.1.0-caf080a9a9c60
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 +19 -16
- package/dist/acceptance.d.ts +3 -0
- package/dist/acceptance.d.ts.map +1 -0
- package/dist/acceptance.js +318 -0
- package/dist/act-lanes.d.ts +29 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +177 -0
- package/dist/actions.d.ts +25 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +261 -0
- package/dist/adapter.d.ts +162 -122
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +7 -10
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +40 -41
- package/dist/binary.d.ts +0 -5
- package/dist/binary.d.ts.map +1 -1
- package/dist/binary.js +1 -1
- package/dist/bootstrap.d.ts +30 -11
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +309 -113
- 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 +10 -16
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +17 -94
- package/dist/change.d.ts +32 -1
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +14 -3
- package/dist/chat-types.d.ts +5 -0
- package/dist/chat-types.d.ts.map +1 -0
- package/dist/chat-types.js +13 -0
- package/dist/client.d.ts +33 -19
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +112 -21
- package/dist/collection.d.ts +29 -22
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +47 -354
- package/dist/compile.d.ts +18 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +724 -0
- package/dist/connection.d.ts +7 -137
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +111 -3623
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/{chat/context.js → context.js} +1 -4
- package/dist/conversation-live.d.ts +138 -0
- package/dist/conversation-live.d.ts.map +1 -0
- package/dist/conversation-live.js +249 -0
- package/dist/conversation-row.d.ts +33 -0
- package/dist/conversation-row.d.ts.map +1 -0
- package/dist/conversation-row.js +53 -0
- package/dist/conversation.d.ts +66 -49
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +962 -799
- 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 +153 -0
- package/dist/durability.d.ts +19 -4
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +5 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +33 -29
- 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 +197 -0
- package/dist/file.d.ts +2 -19
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +7 -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 +20 -8
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +103 -45
- package/dist/identity.d.ts +0 -2
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -6
- package/dist/index.d.ts +39 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -4
- package/dist/install.d.ts +54 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +539 -0
- package/dist/lifecycle.d.ts +7 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +279 -0
- package/dist/listing.d.ts +48 -0
- package/dist/listing.d.ts.map +1 -0
- package/dist/listing.js +139 -0
- package/dist/live.d.ts +23 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +165 -0
- package/dist/locks.d.ts +7 -0
- package/dist/locks.d.ts.map +1 -0
- package/dist/locks.js +33 -0
- package/dist/log.d.ts +1 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/lost.d.ts +5 -0
- package/dist/lost.d.ts.map +1 -0
- package/dist/lost.js +50 -0
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +218 -0
- package/dist/memory.d.ts +17 -7
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +272 -118
- package/dist/messages.d.ts +49 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +150 -0
- package/dist/model.d.ts +8 -11
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +6 -23
- package/dist/models.d.ts +10 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +156 -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 +15 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +98 -14
- 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 +59 -0
- package/dist/outcome.d.ts +47 -9
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +56 -2
- package/dist/overlay.d.ts +7 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +69 -169
- 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 +3 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +10 -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 +20 -0
- package/dist/preparation.d.ts.map +1 -0
- package/dist/preparation.js +233 -0
- package/dist/presence.d.ts +52 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +220 -0
- package/dist/queries.d.ts +16 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +285 -0
- package/dist/query.d.ts +21 -207
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -493
- 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 +465 -0
- package/dist/reach.d.ts +20 -9
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +306 -111
- package/dist/react.d.ts +15 -2
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +33 -1
- 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 +13 -17
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +2 -8
- package/dist/reads.d.ts +38 -10
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +163 -83
- package/dist/recovery.d.ts +5 -2
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +65 -8
- package/dist/refresh.d.ts +18 -15
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +145 -79
- package/dist/refusal.d.ts +5 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +57 -0
- package/dist/replica.d.ts +50 -39
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +319 -208
- 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 +28 -11
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +194 -117
- package/dist/room-drafts.d.ts +24 -0
- package/dist/room-drafts.d.ts.map +1 -0
- package/dist/room-drafts.js +217 -0
- package/dist/rows.d.ts +31 -31
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +60 -125
- package/dist/runtime.d.ts +36 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/save.d.ts +43 -50
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +661 -228
- package/dist/saves.d.ts +32 -0
- package/dist/saves.d.ts.map +1 -0
- package/dist/saves.js +413 -0
- package/dist/search.d.ts +12 -95
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +10 -266
- package/dist/seed.d.ts +11 -2
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +71 -1
- package/dist/shared.d.ts +4 -9
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +61 -120
- package/dist/shown.d.ts +32 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +290 -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 +21 -0
- package/dist/socket/lanes.d.ts.map +1 -0
- package/dist/socket/lanes.js +80 -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 +68 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +171 -0
- package/dist/source.d.ts +54 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +82 -0
- package/dist/status.d.ts +4 -5
- 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 +34 -0
- package/dist/store/readiness.d.ts +10 -0
- package/dist/store/readiness.d.ts.map +1 -0
- package/dist/store/readiness.js +52 -0
- package/dist/store/records.d.ts +212 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +430 -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/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 +111 -166
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +158 -797
- package/dist/stored.d.ts +156 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +649 -0
- package/dist/surface.d.ts +88 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +223 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +540 -0
- package/dist/tables.d.ts +412 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +737 -0
- package/dist/tallies.d.ts +18 -0
- package/dist/tallies.d.ts.map +1 -0
- package/dist/tallies.js +129 -0
- package/dist/transfer.d.ts +0 -5
- package/dist/transfer.d.ts.map +1 -1
- package/dist/turn.d.ts +1 -1
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +31 -20
- package/dist/validation.d.ts +29 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +104 -0
- package/dist/windows.d.ts +1 -16
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +2 -79
- package/dist/wire.d.ts +72 -8
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +24 -5
- package/package.json +19 -19
- package/AGENTS.md +0 -299
- package/dist/attempt.d.ts +0 -16
- package/dist/attempt.d.ts.map +0 -1
- package/dist/attempt.js +0 -70
- package/dist/chat/acts.d.ts +0 -33
- 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/earlier.d.ts +0 -10
- package/dist/chat/earlier.d.ts.map +0 -1
- package/dist/chat/earlier.js +0 -54
- 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 -61
- 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 -27
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -99
- package/dist/chat/markdown.d.ts +0 -21
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -246
- 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 -22
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -171
- 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/pieces.d.ts +0 -62
- package/dist/chat/pieces.d.ts.map +0 -1
- package/dist/chat/pieces.js +0 -1110
- 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 -630
- package/dist/chat/question.d.ts +0 -9
- package/dist/chat/question.d.ts.map +0 -1
- package/dist/chat/question.js +0 -69
- 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 -34
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -91
- package/dist/chat/steady.d.ts +0 -3
- package/dist/chat/steady.d.ts.map +0 -1
- package/dist/chat/steady.js +0 -26
- 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/fence.d.ts +0 -6
- package/dist/fence.d.ts.map +0 -1
- package/dist/fence.js +0 -10
- package/dist/read-side.d.ts +0 -27
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -826
package/dist/search.js
CHANGED
|
@@ -1,270 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { indexGeneration } from './identity.js';
|
|
3
|
-
import { flag, invalid, known, limitOf, plain, } from './query.js';
|
|
4
|
-
import { beneath } from './paths.js';
|
|
5
|
-
import { inUnits, ROW_WEIGHT } from './turn.js';
|
|
6
|
-
import { decodedCursor } from './windows.js';
|
|
7
|
-
export function undeclaredSearch() {
|
|
8
|
-
return {
|
|
9
|
-
kind: 'undeclared',
|
|
10
|
-
code: 'search-undeclared',
|
|
11
|
-
fields: { name: 'local_search' },
|
|
12
|
-
retryable: false,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
const FIELDS = ['fields', 'sections', 'preamble', 'path', 'text'];
|
|
16
|
-
function documentId(room, path) {
|
|
17
|
-
return JSON.stringify(['document', room, path]);
|
|
18
|
-
}
|
|
19
|
-
function messageId(conversation, identity) {
|
|
20
|
-
return JSON.stringify(['message', conversation, identity]);
|
|
21
|
-
}
|
|
22
|
-
function scalars(value) {
|
|
23
|
-
if (value === null || value === undefined)
|
|
24
|
-
return [];
|
|
25
|
-
if (Array.isArray(value))
|
|
26
|
-
return value.flatMap(scalars);
|
|
27
|
-
if (typeof value === 'object')
|
|
28
|
-
return Object.values(value).flatMap(scalars);
|
|
29
|
-
return [String(value)];
|
|
30
|
-
}
|
|
31
|
-
function hitCursor(input) {
|
|
32
|
-
if (input === null)
|
|
33
|
-
return null;
|
|
34
|
-
if (!Array.isArray(input))
|
|
35
|
-
return undefined;
|
|
36
|
-
if (input.length === 0)
|
|
37
|
-
return [];
|
|
38
|
-
const [score, first, second] = input;
|
|
39
|
-
return input.length === 3 &&
|
|
40
|
-
typeof score === 'number' &&
|
|
41
|
-
typeof first === 'string' &&
|
|
42
|
-
typeof second === 'string'
|
|
43
|
-
? [score, first, second]
|
|
44
|
-
: undefined;
|
|
45
|
-
}
|
|
46
|
-
function searchAfter(input) {
|
|
47
|
-
if (input === undefined)
|
|
48
|
-
return null;
|
|
49
|
-
const decoded = typeof input === 'string' ? decodedCursor(input) : null;
|
|
50
|
-
const documents = decoded?.length === 2 ? hitCursor(decoded[0]) : undefined;
|
|
51
|
-
const messages = decoded?.length === 2 ? hitCursor(decoded[1]) : undefined;
|
|
52
|
-
if (documents === undefined || messages === undefined) {
|
|
53
|
-
invalid('after', 'expects the next an earlier search returned');
|
|
54
|
-
}
|
|
55
|
-
return [documents, messages];
|
|
56
|
-
}
|
|
1
|
+
import { invalid, known, plain } from '@agentshouse/mdmodel';
|
|
57
2
|
export function searchPlanOf(input) {
|
|
58
3
|
if (!plain(input))
|
|
59
4
|
invalid('search', 'expects a search object');
|
|
60
|
-
known(input, ['text', '
|
|
61
|
-
if (typeof input.text !== 'string')
|
|
62
|
-
invalid('text', 'expects
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
65
|
-
(!Array.isArray(
|
|
66
|
-
invalid('
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
text: input.text,
|
|
70
|
-
documents: input.documents,
|
|
71
|
-
collection: flag(input.collection, 'collection'),
|
|
72
|
-
conversations: conversations ?? null,
|
|
73
|
-
limit: limitOf(input.limit),
|
|
74
|
-
after: searchAfter(input.after),
|
|
75
|
-
total: flag(input.total, 'total'),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
function pair(left, right) {
|
|
79
|
-
if (left[0] !== right[0])
|
|
80
|
-
return left[0] < right[0] ? -1 : 1;
|
|
81
|
-
if (left[1] !== right[1])
|
|
82
|
-
return left[1] < right[1] ? -1 : 1;
|
|
83
|
-
return 0;
|
|
84
|
-
}
|
|
85
|
-
function hitWindow(found, cursor, limit, tie) {
|
|
86
|
-
if (cursor === null)
|
|
87
|
-
return { kept: [], cursor: null };
|
|
88
|
-
const start = cursor.length === 0
|
|
89
|
-
? 0
|
|
90
|
-
: found.findIndex((hit) => hit.score < cursor[0] ||
|
|
91
|
-
(hit.score === cursor[0] && pair(tie(hit), [cursor[1], cursor[2]]) > 0));
|
|
92
|
-
const following = start === -1 ? [] : found.slice(start);
|
|
93
|
-
if (limit === null || following.length <= limit)
|
|
94
|
-
return { kept: following, cursor: null };
|
|
95
|
-
const kept = following.slice(0, limit);
|
|
96
|
-
const last = kept[kept.length - 1];
|
|
97
|
-
return { kept, cursor: last === undefined ? cursor : [last.score, ...tie(last)] };
|
|
98
|
-
}
|
|
99
|
-
export function createSearchIndex(source) {
|
|
100
|
-
const generation = indexGeneration();
|
|
101
|
-
const index = new MiniSearch({ fields: FIELDS });
|
|
102
|
-
const documents = new Map();
|
|
103
|
-
const messages = new Map();
|
|
104
|
-
const rooms = new Set();
|
|
105
|
-
const filling = new Set();
|
|
106
|
-
const conversations = new Set();
|
|
107
|
-
const acquiring = new Set();
|
|
108
|
-
const changedDocuments = new Map();
|
|
109
|
-
let changes = 0;
|
|
110
|
-
function addDocument(document) {
|
|
111
|
-
const id = documentId(document.room, document.path);
|
|
112
|
-
discard(id, documents);
|
|
113
|
-
index.add({
|
|
114
|
-
id,
|
|
115
|
-
fields: scalars(document.fields).join('\n'),
|
|
116
|
-
sections: Object.entries(document.sections)
|
|
117
|
-
.map(([heading, text]) => `${heading}\n${text}`)
|
|
118
|
-
.join('\n'),
|
|
119
|
-
preamble: document.preamble,
|
|
120
|
-
path: document.path,
|
|
121
|
-
});
|
|
122
|
-
documents.set(id, { room: document.room, path: document.path, type: document.type });
|
|
123
|
-
}
|
|
124
|
-
function addMessage(message) {
|
|
125
|
-
const id = messageId(message.conversation, message.identity);
|
|
126
|
-
discard(id, messages);
|
|
127
|
-
index.add({ id, text: message.text });
|
|
128
|
-
messages.set(id, { conversation: message.conversation, identity: message.identity });
|
|
129
|
-
}
|
|
130
|
-
function discard(id, entries) {
|
|
131
|
-
if (entries.delete(id))
|
|
132
|
-
index.discard(id);
|
|
133
|
-
}
|
|
134
|
-
function* pending() {
|
|
135
|
-
for (;;) {
|
|
136
|
-
const next = changedDocuments.entries().next();
|
|
137
|
-
if (next.done === true)
|
|
138
|
-
return;
|
|
139
|
-
changedDocuments.delete(next.value[0]);
|
|
140
|
-
yield next.value;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
let catching = null;
|
|
144
|
-
function caughtUp() {
|
|
145
|
-
if (catching !== null)
|
|
146
|
-
return catching;
|
|
147
|
-
const running = inUnits(pending(), ([id, { room, path }]) => {
|
|
148
|
-
discard(id, documents);
|
|
149
|
-
const document = source.document(room, path);
|
|
150
|
-
if (document === null)
|
|
151
|
-
return ROW_WEIGHT;
|
|
152
|
-
addDocument(document);
|
|
153
|
-
return Object.values(document.sections).reduce((total, text) => total + text.length, ROW_WEIGHT + document.preamble.length);
|
|
154
|
-
});
|
|
155
|
-
if (!(running instanceof Promise))
|
|
156
|
-
return Promise.resolve();
|
|
157
|
-
catching = running.finally(() => {
|
|
158
|
-
catching = null;
|
|
159
|
-
});
|
|
160
|
-
return catching;
|
|
161
|
-
}
|
|
162
|
-
function ranked(text, entries, keep, tie) {
|
|
163
|
-
const found = index.search(text, {
|
|
164
|
-
filter: ({ id }) => {
|
|
165
|
-
const entry = entries.get(id);
|
|
166
|
-
return entry !== undefined && keep(entry, id);
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
found.sort((left, right) => right.score - left.score ||
|
|
170
|
-
pair(tie(entries.get(left.id)), tie(entries.get(right.id))));
|
|
171
|
-
return found.map(({ id, score, match }) => ({
|
|
172
|
-
...entries.get(id),
|
|
173
|
-
score,
|
|
174
|
-
match,
|
|
175
|
-
}));
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
generation: () => generation,
|
|
179
|
-
rooms: () => rooms,
|
|
180
|
-
conversations: () => conversations,
|
|
181
|
-
async indexRoom(room) {
|
|
182
|
-
if (rooms.has(room) || filling.has(room))
|
|
183
|
-
return;
|
|
184
|
-
filling.add(room);
|
|
185
|
-
try {
|
|
186
|
-
await inUnits(source.room(room), (path) => {
|
|
187
|
-
const document = filling.has(room) ? source.document(room, path) : null;
|
|
188
|
-
if (document === null)
|
|
189
|
-
return ROW_WEIGHT;
|
|
190
|
-
addDocument(document);
|
|
191
|
-
return Object.values(document.sections).reduce((total, text) => total + text.length, ROW_WEIGHT + document.preamble.length);
|
|
192
|
-
});
|
|
193
|
-
if (filling.has(room))
|
|
194
|
-
rooms.add(room);
|
|
195
|
-
}
|
|
196
|
-
finally {
|
|
197
|
-
filling.delete(room);
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
indexMessages(conversation, arriving, whole) {
|
|
201
|
-
for (const message of arriving)
|
|
202
|
-
addMessage(message);
|
|
203
|
-
if (!whole) {
|
|
204
|
-
acquiring.add(conversation);
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
acquiring.delete(conversation);
|
|
208
|
-
conversations.add(conversation);
|
|
209
|
-
},
|
|
210
|
-
forget(leaving) {
|
|
211
|
-
const gone = new Set(leaving);
|
|
212
|
-
for (const [id, entry] of documents)
|
|
213
|
-
if (gone.has(entry.room))
|
|
214
|
-
discard(id, documents);
|
|
215
|
-
for (const room of leaving) {
|
|
216
|
-
rooms.delete(room);
|
|
217
|
-
filling.delete(room);
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
changed(set) {
|
|
221
|
-
changes += 1;
|
|
222
|
-
for (const { locator, path } of set.documents) {
|
|
223
|
-
if (rooms.has(locator) || filling.has(locator)) {
|
|
224
|
-
changedDocuments.set(documentId(locator, path), { room: locator, path });
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
for (const { conversation, identity, text } of set.messages) {
|
|
228
|
-
if (!conversations.has(conversation) && !acquiring.has(conversation))
|
|
229
|
-
continue;
|
|
230
|
-
const id = messageId(conversation, identity);
|
|
231
|
-
if (text === null)
|
|
232
|
-
discard(id, messages);
|
|
233
|
-
else
|
|
234
|
-
addMessage({ conversation, identity, text });
|
|
235
|
-
}
|
|
236
|
-
},
|
|
237
|
-
changes: () => changes,
|
|
238
|
-
caughtUp,
|
|
239
|
-
search({ text, limit, after, total }, selected, named, within, selections) {
|
|
240
|
-
const chosen = selected === null
|
|
241
|
-
? null
|
|
242
|
-
: new Set(selected.map(({ room, path }) => documentId(room, path)));
|
|
243
|
-
const asked = new Set(named);
|
|
244
|
-
const documentTie = ({ room, path }) => [room, path];
|
|
245
|
-
const messageTie = ({ conversation, identity }) => [conversation, identity];
|
|
246
|
-
const foundDocuments = ranked(text, documents, ({ room, path }, id) => (chosen === null || chosen.has(id)) &&
|
|
247
|
-
(within === null || within.has(room)) &&
|
|
248
|
-
!(selections?.get(room) ?? []).some((root) => beneath(root, path)), documentTie);
|
|
249
|
-
const foundMessages = ranked(text, messages, ({ conversation }) => asked.has(conversation), messageTie);
|
|
250
|
-
const [documentsAfter, messagesAfter] = after ?? [[], []];
|
|
251
|
-
const documentWindow = hitWindow(foundDocuments, documentsAfter, limit, documentTie);
|
|
252
|
-
const messageWindow = hitWindow(foundMessages, messagesAfter, limit, messageTie);
|
|
253
|
-
const more = documentWindow.cursor !== null || messageWindow.cursor !== null;
|
|
254
|
-
return {
|
|
255
|
-
documents: documentWindow.kept.map(({ match, ...hit }) => ({
|
|
256
|
-
...hit,
|
|
257
|
-
matches: match,
|
|
258
|
-
})),
|
|
259
|
-
messages: messageWindow.kept.map(({ match, ...hit }) => ({
|
|
260
|
-
...hit,
|
|
261
|
-
matches: match,
|
|
262
|
-
})),
|
|
263
|
-
...(more ? { next: JSON.stringify([documentWindow.cursor, messageWindow.cursor]) } : {}),
|
|
264
|
-
...(total
|
|
265
|
-
? { total: { documents: foundDocuments.length, messages: foundMessages.length } }
|
|
266
|
-
: {}),
|
|
267
|
-
};
|
|
268
|
-
},
|
|
269
|
-
};
|
|
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 };
|
|
270
14
|
}
|
package/dist/seed.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type
|
|
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';
|
|
3
7
|
export type EntrySeed = {
|
|
4
8
|
readonly at: Readonly<Record<string, string>>;
|
|
5
9
|
readonly queries: readonly {
|
|
@@ -11,6 +15,11 @@ export type Seeded = {
|
|
|
11
15
|
readonly rows: QueryRows;
|
|
12
16
|
readonly at: Readonly<Record<string, string>>;
|
|
13
17
|
};
|
|
18
|
+
type SeededWatch = (coverOf: (cover: Cover, held: HeldCover) => Cover, deliver: (message: unknown) => void) => () => void;
|
|
14
19
|
export declare function entrySeedOf(value: unknown): EntrySeed | null;
|
|
15
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 {};
|
|
16
25
|
//# sourceMappingURL=seed.d.ts.map
|
package/dist/seed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"
|
|
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,EAAS,KAAK,WAAW,EAAqB,MAAM,kBAAkB,CAAC;AAC9E,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
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { queryKey } from '@agentshouse/mdmodel';
|
|
2
|
+
import { whole } from './observation.js';
|
|
1
3
|
import { documentKey } from './rows.js';
|
|
4
|
+
const seedTopic = (key) => `seed\u0000${key}`;
|
|
2
5
|
function plain(value) {
|
|
3
6
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
7
|
}
|
|
@@ -59,7 +62,6 @@ export function seededResult(seed) {
|
|
|
59
62
|
generation,
|
|
60
63
|
current: false,
|
|
61
64
|
})),
|
|
62
|
-
indexes: [],
|
|
63
65
|
overlay: [],
|
|
64
66
|
};
|
|
65
67
|
if ('groups' in seed.rows) {
|
|
@@ -73,3 +75,71 @@ export function seededResult(seed) {
|
|
|
73
75
|
keys: seed.rows.documents.map((document) => documentKey(document.room, document.path)),
|
|
74
76
|
};
|
|
75
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;
|
|
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
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
export type Paths<V> = Readonly<Record<string, V>>;
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
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
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 tally<V>(map: Paths<V>, weigh: Weigh<V>): number;
|
|
8
|
-
export declare function sizeOf<V>(map: Paths<V>): number;
|
|
9
|
-
export declare function differences<V>(left: Paths<V>, right: Paths<V>, same?: (left: V, right: V) => boolean): Generator<number, ReadonlySet<string>, void>;
|
|
10
|
-
export declare function differing<V>(left: Paths<V>, right: Paths<V>, same?: (left: V, right: V) => boolean): ReadonlySet<string>;
|
|
11
7
|
export declare function drafted<V>(base: Paths<V>): Record<string, V>;
|
|
12
8
|
export declare function settled<V>(draft: Record<string, V>): Paths<V>;
|
|
13
9
|
export declare function settling<V>(draft: Record<string, V>): Generator<number, Paths<V>, void>;
|
|
14
|
-
export {};
|
|
15
10
|
//# sourceMappingURL=shared.d.ts.map
|
package/dist/shared.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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
CHANGED
|
@@ -2,7 +2,6 @@ import { finished, ROW_WEIGHT } from './turn.js';
|
|
|
2
2
|
const BITS = 5;
|
|
3
3
|
const MASK = (1 << BITS) - 1;
|
|
4
4
|
const roots = new WeakMap();
|
|
5
|
-
const tallies = new WeakMap();
|
|
6
5
|
function hashOf(key) {
|
|
7
6
|
let hash = 0x811c9dc5;
|
|
8
7
|
for (let index = 0; index < key.length; index += 1) {
|
|
@@ -101,21 +100,15 @@ function lone(node) {
|
|
|
101
100
|
}
|
|
102
101
|
function taken(node, hash, key, shift) {
|
|
103
102
|
if (isLeaf(node))
|
|
104
|
-
return
|
|
103
|
+
return undefined;
|
|
105
104
|
if (isCollision(node)) {
|
|
106
105
|
const leaves = node.leaves.filter((leaf) => leaf.key !== key);
|
|
107
|
-
if (leaves.length === node.leaves.length)
|
|
108
|
-
return node;
|
|
109
106
|
return leaves.length === 1 ? leaves[0] : { hash: node.hash, leaves };
|
|
110
107
|
}
|
|
111
108
|
const bit = 1 << fragment(hash, shift);
|
|
112
|
-
if ((node.bitmap & bit) === 0)
|
|
113
|
-
return node;
|
|
114
109
|
const at = slot(node.bitmap, bit);
|
|
115
110
|
const child = node.children[at];
|
|
116
111
|
const next = taken(child, hash, key, shift + BITS);
|
|
117
|
-
if (next === child)
|
|
118
|
-
return node;
|
|
119
112
|
if (next === undefined) {
|
|
120
113
|
if (node.children.length === 1)
|
|
121
114
|
return undefined;
|
|
@@ -180,147 +173,95 @@ function facade(root) {
|
|
|
180
173
|
roots.set(map, root);
|
|
181
174
|
return map;
|
|
182
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
|
+
}
|
|
183
193
|
function* rooted(map) {
|
|
184
194
|
const held = roots.get(map);
|
|
185
195
|
if (held !== undefined)
|
|
186
196
|
return held;
|
|
187
197
|
let node;
|
|
188
|
-
|
|
189
|
-
for (const [key, value] of Object.entries(map)) {
|
|
198
|
+
for (const [key, value] of entriesIn(map)) {
|
|
190
199
|
node = put(node, { key, hash: hashOf(key), value }, 0);
|
|
191
|
-
size += 1;
|
|
192
200
|
yield ROW_WEIGHT;
|
|
193
201
|
}
|
|
194
|
-
return { node
|
|
202
|
+
return { node };
|
|
195
203
|
}
|
|
196
|
-
|
|
197
|
-
|
|
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;
|
|
198
220
|
}
|
|
199
|
-
export function
|
|
200
|
-
return
|
|
221
|
+
export function* sortedKeys(map) {
|
|
222
|
+
return yield* sorting(pathsOf(map));
|
|
201
223
|
}
|
|
202
|
-
export function
|
|
203
|
-
|
|
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] ?? [];
|
|
204
245
|
}
|
|
205
246
|
export function* patching(base, set, removed = []) {
|
|
206
247
|
const root = yield* rooted(base);
|
|
207
|
-
const weighed = [...(tallies.get(base) ?? [])];
|
|
208
248
|
let node = root.node;
|
|
209
|
-
let size = root.size;
|
|
210
|
-
const shift = (key, before, after) => {
|
|
211
|
-
for (const entry of weighed) {
|
|
212
|
-
entry[1] +=
|
|
213
|
-
(after === undefined ? 0 : entry[0](key, after)) -
|
|
214
|
-
(before === undefined ? 0 : entry[0](key, before.value));
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
249
|
for (const key of removed) {
|
|
218
250
|
if (node === undefined)
|
|
219
251
|
break;
|
|
220
|
-
const before = lookup({ node
|
|
252
|
+
const before = lookup({ node }, key);
|
|
221
253
|
if (before === undefined)
|
|
222
254
|
continue;
|
|
223
255
|
node = taken(node, before.hash, key, 0);
|
|
224
|
-
size -= 1;
|
|
225
|
-
shift(key, before, undefined);
|
|
226
256
|
yield ROW_WEIGHT;
|
|
227
257
|
}
|
|
228
258
|
for (const [key, value] of set) {
|
|
229
|
-
const before = lookup({ node, size }, key);
|
|
230
259
|
node = put(node, { key, hash: hashOf(key), value }, 0);
|
|
231
|
-
if (before === undefined)
|
|
232
|
-
size += 1;
|
|
233
|
-
shift(key, before, value);
|
|
234
260
|
yield ROW_WEIGHT;
|
|
235
261
|
}
|
|
236
262
|
if (node === root.node && roots.has(base))
|
|
237
263
|
return base;
|
|
238
|
-
|
|
239
|
-
if (weighed.length > 0)
|
|
240
|
-
tallies.set(map, new Map(weighed));
|
|
241
|
-
return map;
|
|
242
|
-
}
|
|
243
|
-
export function tally(map, weigh) {
|
|
244
|
-
const held = tallies.get(map);
|
|
245
|
-
const known = held?.get(weigh);
|
|
246
|
-
if (known !== undefined)
|
|
247
|
-
return known;
|
|
248
|
-
let total = 0;
|
|
249
|
-
for (const [key, value] of Object.entries(map))
|
|
250
|
-
total += weigh(key, value);
|
|
251
|
-
if (roots.has(map)) {
|
|
252
|
-
const kept = held ?? new Map();
|
|
253
|
-
kept.set(weigh, total);
|
|
254
|
-
tallies.set(map, kept);
|
|
255
|
-
}
|
|
256
|
-
return total;
|
|
257
|
-
}
|
|
258
|
-
export function sizeOf(map) {
|
|
259
|
-
return roots.get(map)?.size ?? Object.keys(map).length;
|
|
260
|
-
}
|
|
261
|
-
function* compared(left, right, same, into) {
|
|
262
|
-
const pending = [[left, right]];
|
|
263
|
-
for (let pair = pending.pop(); pair !== undefined; pair = pending.pop()) {
|
|
264
|
-
const [one, other] = pair;
|
|
265
|
-
if (one === other)
|
|
266
|
-
continue;
|
|
267
|
-
if (one !== undefined &&
|
|
268
|
-
other !== undefined &&
|
|
269
|
-
!isLeaf(one) &&
|
|
270
|
-
!isCollision(one) &&
|
|
271
|
-
!isLeaf(other) &&
|
|
272
|
-
!isCollision(other)) {
|
|
273
|
-
const children = [];
|
|
274
|
-
for (let remaining = one.bitmap | other.bitmap; remaining !== 0; remaining &= remaining - 1) {
|
|
275
|
-
const bit = remaining & -remaining;
|
|
276
|
-
children.push([
|
|
277
|
-
(one.bitmap & bit) === 0 ? undefined : one.children[slot(one.bitmap, bit)],
|
|
278
|
-
(other.bitmap & bit) === 0 ? undefined : other.children[slot(other.bitmap, bit)],
|
|
279
|
-
]);
|
|
280
|
-
}
|
|
281
|
-
pending.push(...children.reverse());
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
const before = new Map();
|
|
285
|
-
for (const leaf of leavesOf(one)) {
|
|
286
|
-
before.set(leaf.key, leaf.value);
|
|
287
|
-
yield ROW_WEIGHT;
|
|
288
|
-
}
|
|
289
|
-
for (const leaf of leavesOf(other)) {
|
|
290
|
-
const held = before.get(leaf.key);
|
|
291
|
-
before.delete(leaf.key);
|
|
292
|
-
if (held === undefined || !same(held, leaf.value))
|
|
293
|
-
into.add(leaf.key);
|
|
294
|
-
yield ROW_WEIGHT;
|
|
295
|
-
}
|
|
296
|
-
for (const key of before.keys())
|
|
297
|
-
into.add(key);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
export function* differences(left, right, same = Object.is) {
|
|
301
|
-
const into = new Set();
|
|
302
|
-
if (left === right)
|
|
303
|
-
return into;
|
|
304
|
-
const leftRoot = roots.get(left);
|
|
305
|
-
const rightRoot = roots.get(right);
|
|
306
|
-
if (leftRoot !== undefined && rightRoot !== undefined) {
|
|
307
|
-
yield* compared(leftRoot.node, rightRoot.node, same, into);
|
|
308
|
-
return into;
|
|
309
|
-
}
|
|
310
|
-
for (const key of Object.keys(left)) {
|
|
311
|
-
if (!Object.hasOwn(right, key) || !same(left[key], right[key]))
|
|
312
|
-
into.add(key);
|
|
313
|
-
yield ROW_WEIGHT;
|
|
314
|
-
}
|
|
315
|
-
for (const key of Object.keys(right)) {
|
|
316
|
-
if (!Object.hasOwn(left, key))
|
|
317
|
-
into.add(key);
|
|
318
|
-
yield ROW_WEIGHT;
|
|
319
|
-
}
|
|
320
|
-
return into;
|
|
321
|
-
}
|
|
322
|
-
export function differing(left, right, same = Object.is) {
|
|
323
|
-
return finished(differences(left, right, same));
|
|
264
|
+
return facade({ node });
|
|
324
265
|
}
|
|
325
266
|
const drafts = new WeakMap();
|
|
326
267
|
const GONE = Symbol('gone');
|