@agentshouse/mdruntime 0.1.0-c2e8a6f99866d → 0.1.0-c2ef9303a058d
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 +11 -9
- package/dist/adapter.d.ts +95 -67
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +5 -11
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +36 -47
- 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 +17 -9
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +143 -94
- package/dist/chain.d.ts +2 -1
- package/dist/chain.d.ts.map +1 -1
- package/dist/change-set.d.ts +1 -7
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +1 -4
- package/dist/client.d.ts +15 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +56 -8
- package/dist/collection.d.ts +7 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +24 -19
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +117 -243
- package/dist/connection.d.ts +14 -12
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1466 -1431
- 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.d.ts +18 -15
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +273 -185
- package/dist/durability.d.ts +6 -4
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +3 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +17 -8
- package/dist/file.d.ts +2 -11
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +6 -4
- package/dist/host.d.ts +3 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +55 -38
- 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 +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/job.d.ts +14 -0
- package/dist/job.d.ts.map +1 -0
- package/dist/job.js +28 -0
- package/dist/live.d.ts +2 -1
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +9 -5
- 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 +12 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +209 -101
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +89 -0
- package/dist/model.d.ts +8 -8
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -13
- package/dist/observation.d.ts +3 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +8 -3
- package/dist/outcome.d.ts +13 -6
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +16 -5
- package/dist/overlay.js +1 -1
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +4 -0
- package/dist/query.d.ts +10 -206
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -494
- package/dist/reach.d.ts +14 -9
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +84 -72
- package/dist/react.d.ts +3 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/readiness.d.ts +14 -17
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +2 -8
- package/dist/recovery.d.ts +1 -0
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +26 -0
- package/dist/refresh.d.ts +10 -4
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +88 -30
- package/dist/replica.d.ts +11 -8
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +30 -15
- package/dist/room-draft.d.ts +22 -5
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +131 -51
- package/dist/rows.d.ts +18 -16
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +45 -153
- package/dist/save.d.ts +2 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +13 -7
- package/dist/search.d.ts +12 -95
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +10 -349
- package/dist/shared.d.ts +0 -1
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +0 -10
- package/dist/status.d.ts +4 -3
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -1
- package/dist/store.d.ts +25 -62
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +43 -282
- package/dist/stored.d.ts +12 -26
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +189 -226
- package/dist/tables.d.ts +55 -48
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +107 -57
- package/dist/transfer.d.ts +0 -5
- package/dist/transfer.d.ts.map +1 -1
- package/dist/validation.d.ts +3 -4
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +39 -97
- package/dist/windows.d.ts +1 -12
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +2 -75
- package/dist/wire.d.ts +14 -9
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +5 -3
- package/package.json +14 -18
- package/AGENTS.md +0 -312
- 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/house.d.ts +0 -25
- package/dist/chat/house.d.ts.map +0 -1
- package/dist/chat/house.js +0 -38
- package/dist/chat/input.d.ts +0 -11
- package/dist/chat/input.d.ts.map +0 -1
- package/dist/chat/input.js +0 -92
- 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 -28
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -103
- 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 -7
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -244
- package/dist/chat/messages.d.ts +0 -30
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -198
- package/dist/chat/name.d.ts +0 -7
- package/dist/chat/name.d.ts.map +0 -1
- package/dist/chat/name.js +0 -37
- package/dist/chat/opened.d.ts +0 -12
- package/dist/chat/opened.d.ts.map +0 -1
- package/dist/chat/opened.js +0 -19
- package/dist/chat/overlay.d.ts +0 -32
- package/dist/chat/overlay.d.ts.map +0 -1
- package/dist/chat/overlay.js +0 -103
- package/dist/chat/parts.d.ts +0 -58
- package/dist/chat/parts.d.ts.map +0 -1
- package/dist/chat/parts.js +0 -120
- 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 -70
- package/dist/chat/provider.d.ts.map +0 -1
- package/dist/chat/provider.js +0 -635
- 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 +0 -31
- package/dist/chat/questions.d.ts.map +0 -1
- package/dist/chat/questions.js +0 -111
- package/dist/chat/read.d.ts +0 -5
- package/dist/chat/read.d.ts.map +0 -1
- package/dist/chat/read.js +0 -13
- package/dist/chat/ready.d.ts +0 -37
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -93
- package/dist/chat/room-file.d.ts +0 -8
- package/dist/chat/room-file.d.ts.map +0 -1
- package/dist/chat/room-file.js +0 -72
- 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 -306
- package/dist/chat.d.ts +0 -15
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/reads.d.ts +0 -11
- package/dist/reads.d.ts.map +0 -1
- package/dist/reads.js +0 -98
package/dist/stored.js
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { sql } from '@agentshouse/mdmodel';
|
|
2
|
+
import { composedOf } from './collection.js';
|
|
3
|
+
import { described, derived, heldOf } from './rows.js';
|
|
3
4
|
export const REPLICA_TABLES = [
|
|
4
|
-
'CREATE TABLE replica_keys (key INTEGER PRIMARY KEY AUTOINCREMENT, locator TEXT NOT NULL, transfer TEXT NOT NULL,
|
|
5
|
+
'CREATE TABLE replica_keys (key INTEGER PRIMARY KEY AUTOINCREMENT, locator TEXT NOT NULL, transfer TEXT NOT NULL, fingerprint TEXT NOT NULL, rederiving INTEGER)',
|
|
5
6
|
'CREATE TABLE replica_rooms (locator TEXT PRIMARY KEY, key INTEGER NOT NULL, record TEXT NOT NULL) WITHOUT ROWID',
|
|
6
|
-
'CREATE TABLE
|
|
7
|
-
'CREATE TABLE replica_entries (id INTEGER PRIMARY KEY, key INTEGER NOT NULL, layer INTEGER NOT NULL, path TEXT NOT NULL, visible INTEGER NOT NULL, present INTEGER NOT NULL, queried INTEGER NOT NULL, binary TEXT, revision TEXT, file_id TEXT, change TEXT, written TEXT, type TEXT, declared TEXT, folder TEXT NOT NULL, fields TEXT, content TEXT)',
|
|
7
|
+
'CREATE TABLE replica_models (identity TEXT NOT NULL, version TEXT NOT NULL, schema TEXT NOT NULL, PRIMARY KEY (identity, version)) WITHOUT ROWID',
|
|
8
|
+
'CREATE TABLE replica_entries (id INTEGER PRIMARY KEY, key INTEGER NOT NULL, layer INTEGER NOT NULL, path TEXT NOT NULL, visible INTEGER NOT NULL, present INTEGER NOT NULL, queried INTEGER NOT NULL, binary TEXT, revision TEXT, file_id TEXT, change TEXT, written TEXT, type TEXT, declared TEXT, folder TEXT NOT NULL, fields TEXT, links TEXT, content TEXT)',
|
|
8
9
|
'CREATE UNIQUE INDEX replica_entries_path ON replica_entries (key, layer, path)',
|
|
9
|
-
'CREATE INDEX replica_entries_visible ON replica_entries (key, visible, path)',
|
|
10
|
+
'CREATE INDEX replica_entries_visible ON replica_entries (key, visible, present, path, binary)',
|
|
10
11
|
'CREATE INDEX replica_entries_folder ON replica_entries (key, folder, path)',
|
|
11
|
-
'CREATE
|
|
12
|
-
'CREATE INDEX
|
|
13
|
-
|
|
14
|
-
'CREATE
|
|
12
|
+
'CREATE INDEX replica_entries_type ON replica_entries (key, type, visible, present, queried, folder)',
|
|
13
|
+
'CREATE INDEX replica_entries_key ON replica_entries (key)',
|
|
14
|
+
sql.VALUE_TABLE,
|
|
15
|
+
'CREATE TABLE replica_links (doc INTEGER NOT NULL, key INTEGER NOT NULL, kind TEXT NOT NULL, keys TEXT NOT NULL, places TEXT NOT NULL, target TEXT NOT NULL, field TEXT NOT NULL, PRIMARY KEY (doc, kind, keys, places, target)) WITHOUT ROWID',
|
|
16
|
+
'CREATE INDEX replica_links_target ON replica_links (key, target, kind, keys)',
|
|
15
17
|
'CREATE TABLE replica_folders (key INTEGER NOT NULL, layer INTEGER NOT NULL, path TEXT NOT NULL, present INTEGER NOT NULL, PRIMARY KEY (key, layer, path)) WITHOUT ROWID',
|
|
16
18
|
'CREATE TABLE replica_erasing (key INTEGER PRIMARY KEY, locator TEXT NOT NULL)',
|
|
17
|
-
'CREATE TABLE replica_received (key TEXT PRIMARY KEY, head TEXT NOT NULL) WITHOUT ROWID',
|
|
18
|
-
'CREATE TABLE replica_received_parts (key TEXT NOT NULL, part INTEGER NOT NULL, value TEXT NOT NULL, PRIMARY KEY (key, part)) WITHOUT ROWID',
|
|
19
19
|
'CREATE TABLE replica_facts (name TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',
|
|
20
20
|
'CREATE TABLE replica_presentation (app TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',
|
|
21
21
|
];
|
|
22
22
|
const CONFIRMED = 0;
|
|
23
23
|
const OVERLAY = 1;
|
|
24
24
|
const REFRESHED = 2;
|
|
25
|
-
const
|
|
25
|
+
const DERIVED_ROWS = 64;
|
|
26
|
+
const ENTRY_WEIGHT = 256;
|
|
27
|
+
const ABSENT = {
|
|
28
|
+
type: null,
|
|
29
|
+
declared: null,
|
|
30
|
+
queried: false,
|
|
31
|
+
folder: '',
|
|
32
|
+
fields: null,
|
|
33
|
+
links: null,
|
|
34
|
+
};
|
|
26
35
|
function text(value) {
|
|
27
36
|
return typeof value === 'string' ? value : null;
|
|
28
37
|
}
|
|
@@ -38,55 +47,23 @@ function flag(value) {
|
|
|
38
47
|
function paths(list) {
|
|
39
48
|
return JSON.stringify(list);
|
|
40
49
|
}
|
|
41
|
-
function compositionOf(connection, key) {
|
|
42
|
-
let held = compositions.get(connection);
|
|
43
|
-
if (held === undefined) {
|
|
44
|
-
held = new Map();
|
|
45
|
-
compositions.set(connection, held);
|
|
46
|
-
}
|
|
47
|
-
const [row] = connection.rows('SELECT composition FROM replica_keys WHERE key = ?', [key]);
|
|
48
|
-
const textual = text(row?.composition) ?? 'null';
|
|
49
|
-
const known = held.get(textual);
|
|
50
|
-
if (known !== undefined)
|
|
51
|
-
return known;
|
|
52
|
-
const parsed = JSON.parse(textual) ?? {
|
|
53
|
-
model: { status: 'unavailable', reason: 'not-acquired' },
|
|
54
|
-
selection: null,
|
|
55
|
-
};
|
|
56
|
-
held.clear();
|
|
57
|
-
held.set(textual, parsed);
|
|
58
|
-
return parsed;
|
|
59
|
-
}
|
|
60
|
-
export function fingerprint(composition) {
|
|
61
|
-
const shape = (model) => model.status === 'unavailable' ? null : model.types;
|
|
62
|
-
return JSON.stringify({
|
|
63
|
-
model: shape(composition.model),
|
|
64
|
-
selection: composition.selection === null
|
|
65
|
-
? null
|
|
66
|
-
: { roots: composition.selection.roots, model: shape(composition.selection.model) },
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
50
|
function dropDerived(connection, doc) {
|
|
70
51
|
connection.run('DELETE FROM replica_values WHERE doc = ?', [doc]);
|
|
71
52
|
connection.run('DELETE FROM replica_links WHERE doc = ?', [doc]);
|
|
72
53
|
}
|
|
73
|
-
function writeDerived(connection, doc, key,
|
|
74
|
-
|
|
75
|
-
|
|
54
|
+
function writeDerived(connection, doc, key, path, held, composition) {
|
|
55
|
+
const made = derived(path, held, composition);
|
|
56
|
+
if (made.values.length > 0) {
|
|
57
|
+
const inserted = sql.insertedValues(doc, made.values);
|
|
58
|
+
connection.run(inserted.sql, inserted.bind);
|
|
59
|
+
}
|
|
60
|
+
if (made.links.length > 0) {
|
|
61
|
+
connection.run('INSERT OR IGNORE INTO replica_links (doc, key, kind, keys, places, target, field) SELECT ?, ?, value ->> 0, value ->> 1, value ->> 2, value ->> 3, value ->> 4 FROM json_each(?)', [
|
|
76
62
|
doc,
|
|
77
63
|
key,
|
|
78
|
-
|
|
79
|
-
value.held,
|
|
80
|
-
value.item,
|
|
81
|
-
value.kind,
|
|
82
|
-
value.value,
|
|
83
|
-
value.size,
|
|
84
|
-
flag(value.single),
|
|
64
|
+
JSON.stringify(made.links.map((link) => [link.kind, link.keys, link.places, link.target, link.field])),
|
|
85
65
|
]);
|
|
86
66
|
}
|
|
87
|
-
for (const link of made.links) {
|
|
88
|
-
connection.run('INSERT OR IGNORE INTO replica_links (doc, key, kind, form, target, field) VALUES (?, ?, ?, ?, ?, ?)', [doc, key, link.kind, link.form, link.target, link.field]);
|
|
89
|
-
}
|
|
90
67
|
}
|
|
91
68
|
function entryId(connection, key, layer, path) {
|
|
92
69
|
const [row] = connection.rows('SELECT id FROM replica_entries WHERE key = ? AND layer = ? AND path = ?', [key, layer, path]);
|
|
@@ -99,20 +76,8 @@ function removeEntry(connection, key, layer, path) {
|
|
|
99
76
|
dropDerived(connection, id);
|
|
100
77
|
connection.run('DELETE FROM replica_entries WHERE id = ?', [id]);
|
|
101
78
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
const made = present
|
|
105
|
-
? derived(entry.path, entry.binary === null ? entry.content : null, composition)
|
|
106
|
-
: {
|
|
107
|
-
type: null,
|
|
108
|
-
declared: null,
|
|
109
|
-
queried: false,
|
|
110
|
-
folder: '',
|
|
111
|
-
fields: null,
|
|
112
|
-
values: [],
|
|
113
|
-
links: [],
|
|
114
|
-
};
|
|
115
|
-
connection.run('INSERT INTO replica_entries (key, layer, path, visible, present, queried, content, binary, revision, file_id, change, written, type, declared, folder, fields) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
79
|
+
function insertEntry(connection, key, layer, entry, present, made) {
|
|
80
|
+
connection.run('INSERT INTO replica_entries (key, layer, path, visible, present, queried, content, binary, revision, file_id, change, written, type, declared, folder, fields, links) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
116
81
|
key,
|
|
117
82
|
layer,
|
|
118
83
|
entry.path,
|
|
@@ -129,69 +94,67 @@ function putEntry(connection, key, layer, entry, present, composition) {
|
|
|
129
94
|
made.declared,
|
|
130
95
|
made.folder,
|
|
131
96
|
made.fields,
|
|
97
|
+
made.links,
|
|
132
98
|
]);
|
|
99
|
+
}
|
|
100
|
+
function textOf(entry) {
|
|
101
|
+
return entry.binary === null ? entry.content : null;
|
|
102
|
+
}
|
|
103
|
+
function putEntry(connection, key, layer, entry, present, composition) {
|
|
104
|
+
removeEntry(connection, key, layer, entry.path);
|
|
105
|
+
const content = textOf(entry);
|
|
106
|
+
insertEntry(connection, key, layer, entry, present, present ? described(entry.path, content, entry.facts) : ABSENT);
|
|
133
107
|
if (!present)
|
|
134
108
|
return;
|
|
135
109
|
const id = entryId(connection, key, layer, entry.path);
|
|
136
|
-
writeDerived(connection, id, key,
|
|
110
|
+
writeDerived(connection, id, key, entry.path, heldOf(entry.path, content, entry.facts), composition);
|
|
111
|
+
}
|
|
112
|
+
function placeEntry(connection, key, entry) {
|
|
113
|
+
removeEntry(connection, key, CONFIRMED, entry.path);
|
|
114
|
+
insertEntry(connection, key, CONFIRMED, entry, true, described(entry.path, textOf(entry), entry.facts));
|
|
137
115
|
}
|
|
138
116
|
function revealed(connection, key, touched) {
|
|
139
117
|
if (touched.length === 0)
|
|
140
118
|
return;
|
|
141
119
|
connection.run(`UPDATE replica_entries SET visible = CASE WHEN layer = ${OVERLAY} THEN present ELSE NOT EXISTS (SELECT 1 FROM replica_entries o WHERE o.key = replica_entries.key AND o.layer = ${OVERLAY} AND o.path = replica_entries.path) END WHERE key = ? AND layer IN (${CONFIRMED}, ${OVERLAY}) AND path IN (SELECT value FROM json_each(?))`, [key, paths(touched)]);
|
|
142
120
|
}
|
|
143
|
-
function newKey(connection, locator, transfer,
|
|
144
|
-
|
|
121
|
+
function newKey(connection, locator, transfer, fingerprint, built) {
|
|
122
|
+
const owed = built ? null : 0;
|
|
123
|
+
connection.run('INSERT INTO replica_keys (locator, transfer, fingerprint, rederiving) VALUES (?, ?, ?, ?)', [locator, transfer, fingerprint, owed]);
|
|
145
124
|
const [row] = connection.rows('SELECT last_insert_rowid() AS key');
|
|
146
125
|
return number(row.key);
|
|
147
126
|
}
|
|
148
|
-
function recomposed(connection, key,
|
|
149
|
-
const [row] = connection.rows('SELECT
|
|
150
|
-
|
|
151
|
-
if (before !== null && fingerprint(before) === fingerprint(composition)) {
|
|
152
|
-
connection.run('UPDATE replica_keys SET composition = ? WHERE key = ?', [
|
|
153
|
-
JSON.stringify(composition),
|
|
154
|
-
key,
|
|
155
|
-
]);
|
|
127
|
+
function recomposed(connection, key, fingerprint) {
|
|
128
|
+
const [row] = connection.rows('SELECT fingerprint FROM replica_keys WHERE key = ?', [key]);
|
|
129
|
+
if (row === undefined || text(row.fingerprint) === fingerprint)
|
|
156
130
|
return;
|
|
157
|
-
|
|
158
|
-
connection.run(
|
|
159
|
-
JSON.stringify(composition),
|
|
160
|
-
key,
|
|
161
|
-
]);
|
|
131
|
+
const held = connection.rows('SELECT 1 FROM replica_entries WHERE key = ? LIMIT 1', [key]);
|
|
132
|
+
connection.run(`UPDATE replica_keys SET fingerprint = ?${held.length === 0 ? '' : ', rederiving = 0'} WHERE key = ?`, [fingerprint, key]);
|
|
162
133
|
}
|
|
163
134
|
export function entered(connection, locator, composition, rows) {
|
|
164
|
-
const key = newKey(connection, locator, '', composition);
|
|
135
|
+
const key = newKey(connection, locator, '', composedOf(composition).fingerprint, true);
|
|
165
136
|
for (const entry of rows)
|
|
166
137
|
putEntry(connection, key, CONFIRMED, entry, true, composition);
|
|
167
138
|
return key;
|
|
168
139
|
}
|
|
169
140
|
export function stage(connection, request) {
|
|
170
|
-
const [held] = connection.rows('SELECT key FROM replica_transfers WHERE locator = ?', [
|
|
171
|
-
request.locator,
|
|
172
|
-
]);
|
|
173
141
|
const key = request.key ??
|
|
174
|
-
(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
connection.run('INSERT OR REPLACE INTO replica_transfers (locator, key, record) VALUES (?, ?, ?)', [request.locator, key, request.record]);
|
|
180
|
-
}
|
|
181
|
-
const composition = compositionOf(connection, key);
|
|
182
|
-
for (const entry of request.entries) {
|
|
183
|
-
putEntry(connection, key, CONFIRMED, entry, true, composition);
|
|
184
|
-
}
|
|
142
|
+
newKey(connection, request.locator, request.transfer, request.fingerprint, false);
|
|
143
|
+
recomposed(connection, key, request.fingerprint);
|
|
144
|
+
connection.run('UPDATE replica_keys SET rederiving = coalesce(rederiving, last) FROM (SELECT coalesce(max(id), 0) AS last FROM replica_entries) WHERE key = ?', [key]);
|
|
145
|
+
for (const entry of request.entries)
|
|
146
|
+
placeEntry(connection, key, entry);
|
|
185
147
|
for (const path of request.folders) {
|
|
186
148
|
connection.run('INSERT OR REPLACE INTO replica_folders (key, layer, path, present) VALUES (?, ?, ?, 1)', [key, CONFIRMED, path]);
|
|
187
149
|
}
|
|
188
150
|
return key;
|
|
189
151
|
}
|
|
190
152
|
export function refreshing(connection, request) {
|
|
191
|
-
const held = connection.rows('SELECT 1 FROM
|
|
153
|
+
const held = connection.rows('SELECT 1 FROM replica_keys k WHERE k.key = ? AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)', [request.key]);
|
|
192
154
|
if (held.length === 0)
|
|
193
155
|
return null;
|
|
194
|
-
|
|
156
|
+
recomposed(connection, request.key, request.composed.fingerprint);
|
|
157
|
+
const composition = request.composed.composition;
|
|
195
158
|
for (const entry of request.entries) {
|
|
196
159
|
putEntry(connection, request.key, REFRESHED, entry, true, composition);
|
|
197
160
|
}
|
|
@@ -204,6 +167,7 @@ export function refreshing(connection, request) {
|
|
|
204
167
|
fileId: null,
|
|
205
168
|
change: null,
|
|
206
169
|
written: null,
|
|
170
|
+
facts: null,
|
|
207
171
|
}, false, composition);
|
|
208
172
|
}
|
|
209
173
|
for (const [list, present] of [
|
|
@@ -253,12 +217,11 @@ function applyRefresh(connection, key) {
|
|
|
253
217
|
connection.run('DELETE FROM replica_folders WHERE key = ? AND layer = ?', [key, REFRESHED]);
|
|
254
218
|
return touched;
|
|
255
219
|
}
|
|
220
|
+
function beneathRoots(path) {
|
|
221
|
+
return `EXISTS (SELECT 1 FROM json_each(?) r WHERE ${path} = r.value OR (${path} >= r.value || '/' AND ${path} < r.value || '0'))`;
|
|
222
|
+
}
|
|
256
223
|
function counted(connection, key, roots) {
|
|
257
|
-
const
|
|
258
|
-
const bind = [key];
|
|
259
|
-
for (const root of roots)
|
|
260
|
-
bind.push(root, `${root}/`, `${root}0`);
|
|
261
|
-
const [row] = connection.rows(`SELECT count(*) AS held FROM replica_entries WHERE key = ? AND visible = 1 AND present = 1 AND (binary IS NOT NULL OR substr(path, -3) = '.md')${roots.length === 0 ? '' : ` AND NOT (${outside})`}`, bind);
|
|
224
|
+
const [row] = connection.rows(`SELECT count(*) AS held FROM replica_entries WHERE key = ? AND visible = 1 AND present = 1 AND (binary IS NOT NULL OR substr(path, -3) = '.md') AND NOT ${beneathRoots('replica_entries.path')}`, [key, JSON.stringify(roots)]);
|
|
262
225
|
return number(row.held);
|
|
263
226
|
}
|
|
264
227
|
export function counts(connection, rooms) {
|
|
@@ -272,14 +235,12 @@ function erasing(connection, key, locator) {
|
|
|
272
235
|
}
|
|
273
236
|
function commitRoom(connection, room) {
|
|
274
237
|
const touched = new Set();
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
connection.run('DELETE FROM replica_transfers WHERE locator = ?', [room.locator]);
|
|
238
|
+
recomposed(connection, room.key, room.composed.fingerprint);
|
|
239
|
+
const composition = room.composed.composition;
|
|
240
|
+
if (room.published !== undefined &&
|
|
241
|
+
room.published.from !== null &&
|
|
242
|
+
room.published.from !== room.key) {
|
|
243
|
+
erasing(connection, room.published.from, room.locator);
|
|
283
244
|
}
|
|
284
245
|
if (room.refreshed === true) {
|
|
285
246
|
for (const path of applyRefresh(connection, room.key))
|
|
@@ -304,27 +265,43 @@ function commitRoom(connection, room) {
|
|
|
304
265
|
const changed = [...touched];
|
|
305
266
|
revealed(connection, room.key, changed);
|
|
306
267
|
if (room.record !== undefined) {
|
|
307
|
-
connection.run(
|
|
308
|
-
|
|
309
|
-
room.key,
|
|
310
|
-
room.record,
|
|
311
|
-
]);
|
|
268
|
+
connection.run(KEEP_MODEL, [room.record, room.record, room.record, room.record]);
|
|
269
|
+
connection.run(`INSERT OR REPLACE INTO replica_rooms (locator, key, record) VALUES (?, ?, ${MODEL_LEFT})`, [room.locator, room.key, room.record, room.record, room.record]);
|
|
312
270
|
}
|
|
313
271
|
return room.published === undefined ? changed : null;
|
|
314
272
|
}
|
|
273
|
+
const SCHEMA = '$.model.snapshot.schema';
|
|
274
|
+
const KEEP_MODEL = `INSERT OR IGNORE INTO replica_models (identity, version, schema)
|
|
275
|
+
SELECT json_extract(?, '$.model.snapshot.identity'), json_extract(?, '$.model.snapshot.version'),
|
|
276
|
+
json_extract(?, '${SCHEMA}')
|
|
277
|
+
WHERE json_type(?, '${SCHEMA}') = 'text'`;
|
|
278
|
+
const MODEL_LEFT = `CASE WHEN json_type(?, '${SCHEMA}') = 'text' THEN json_set(?, '${SCHEMA}', json('null')) ELSE ? END`;
|
|
279
|
+
const UNHELD_MODELS = `DELETE FROM replica_models WHERE NOT EXISTS (
|
|
280
|
+
SELECT 1 FROM replica_rooms r
|
|
281
|
+
WHERE json_extract(r.record, '$.model.snapshot.identity') = replica_models.identity
|
|
282
|
+
AND json_extract(r.record, '$.model.snapshot.version') = replica_models.version
|
|
283
|
+
)`;
|
|
284
|
+
const HELD_RECORDS = `SELECT r.locator, r.key, CASE WHEN m.schema IS NULL THEN r.record
|
|
285
|
+
ELSE json_set(r.record, '${SCHEMA}', m.schema) END AS record
|
|
286
|
+
FROM replica_rooms r
|
|
287
|
+
LEFT JOIN replica_models m
|
|
288
|
+
ON m.identity = json_extract(r.record, '$.model.snapshot.identity')
|
|
289
|
+
AND m.version = json_extract(r.record, '$.model.snapshot.version')`;
|
|
315
290
|
export function commit(connection, rooms) {
|
|
316
291
|
const counted = {};
|
|
317
292
|
const changed = {};
|
|
318
|
-
const
|
|
293
|
+
const indexed = {};
|
|
319
294
|
for (const room of rooms) {
|
|
320
295
|
changed[room.locator] = commitRoom(connection, room);
|
|
321
296
|
counted[room.locator] = counts(connection, [
|
|
322
297
|
{ key: room.key, roots: room.roots ?? rootsOf(connection, room.locator) },
|
|
323
298
|
])[0];
|
|
324
299
|
const [held] = connection.rows('SELECT rederiving FROM replica_keys WHERE key = ?', [room.key]);
|
|
325
|
-
|
|
300
|
+
indexed[room.locator] = held !== undefined && held.rederiving === null;
|
|
326
301
|
}
|
|
327
|
-
|
|
302
|
+
if (rooms.some((room) => room.record !== undefined))
|
|
303
|
+
connection.run(UNHELD_MODELS);
|
|
304
|
+
return { counts: counted, changed, indexed };
|
|
328
305
|
}
|
|
329
306
|
function rootsOf(connection, locator) {
|
|
330
307
|
const [row] = connection.rows('SELECT record FROM replica_rooms WHERE locator = ?', [locator]);
|
|
@@ -333,27 +310,25 @@ function rootsOf(connection, locator) {
|
|
|
333
310
|
}
|
|
334
311
|
export function fenceRooms(connection, locators) {
|
|
335
312
|
for (const locator of locators) {
|
|
336
|
-
for (const row of connection.rows('SELECT key FROM replica_keys WHERE locator = ? UNION SELECT key FROM replica_rooms WHERE locator = ?
|
|
313
|
+
for (const row of connection.rows('SELECT key FROM replica_keys WHERE locator = ? UNION SELECT key FROM replica_rooms WHERE locator = ?', [locator, locator])) {
|
|
337
314
|
erasing(connection, number(row.key), locator);
|
|
338
315
|
}
|
|
339
316
|
connection.run('DELETE FROM replica_rooms WHERE locator = ?', [locator]);
|
|
340
|
-
connection.run('DELETE FROM replica_transfers WHERE locator = ?', [locator]);
|
|
341
317
|
}
|
|
318
|
+
connection.run(UNHELD_MODELS);
|
|
342
319
|
return null;
|
|
343
320
|
}
|
|
344
|
-
export function abandon(connection, locator
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
return number(held.key);
|
|
321
|
+
export function abandon(connection, locator) {
|
|
322
|
+
for (const row of connection.rows(`SELECT k.key FROM replica_keys k WHERE k.locator = ?
|
|
323
|
+
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
324
|
+
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`, [locator])) {
|
|
325
|
+
erasing(connection, number(row.key), locator);
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
352
328
|
}
|
|
353
329
|
export function release(connection, key) {
|
|
354
330
|
const [held] = connection.rows(`SELECT k.locator FROM replica_keys k WHERE k.key = ?
|
|
355
|
-
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
356
|
-
AND NOT EXISTS (SELECT 1 FROM replica_transfers t WHERE t.key = k.key)`, [key]);
|
|
331
|
+
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)`, [key]);
|
|
357
332
|
if (held !== undefined)
|
|
358
333
|
erasing(connection, key, text(held.locator));
|
|
359
334
|
return null;
|
|
@@ -377,28 +352,46 @@ export function erase(connection, locator, limit) {
|
|
|
377
352
|
const [more] = connection.rows(`SELECT 1 FROM replica_erasing${locator === null ? '' : ' WHERE locator = ?'} LIMIT 1`, locator === null ? [] : [locator]);
|
|
378
353
|
return { remaining: more !== undefined };
|
|
379
354
|
}
|
|
380
|
-
|
|
355
|
+
function cursor(value) {
|
|
356
|
+
return value === null || value === undefined ? null : number(value);
|
|
357
|
+
}
|
|
358
|
+
export function rederive(connection, key, composed, bytes, ms, floor) {
|
|
359
|
+
const started = performance.now();
|
|
360
|
+
recomposed(connection, key, composed.fingerprint);
|
|
381
361
|
const [held] = connection.rows('SELECT rederiving FROM replica_keys WHERE key = ?', [key]);
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const composition =
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
362
|
+
const deriving = cursor(held?.rederiving);
|
|
363
|
+
if (deriving === null)
|
|
364
|
+
return { done: true, text: 0 };
|
|
365
|
+
const composition = composed.composition;
|
|
366
|
+
let last = deriving;
|
|
367
|
+
let spent = 0;
|
|
368
|
+
let built = 0;
|
|
369
|
+
let read = false;
|
|
370
|
+
reading: for (;;) {
|
|
371
|
+
const rows = connection.rows('SELECT id, path, type, fields, links, octet_length(content) AS size FROM replica_entries WHERE key = ? AND present = 1 AND id > ? ORDER BY id LIMIT ?', [key, last, DERIVED_ROWS]);
|
|
372
|
+
for (const row of rows) {
|
|
373
|
+
const id = number(row.id);
|
|
374
|
+
const path = text(row.path);
|
|
375
|
+
const size = row.size === null ? 0 : number(row.size);
|
|
376
|
+
dropDerived(connection, id);
|
|
377
|
+
writeDerived(connection, id, key, path, {
|
|
378
|
+
type: text(row.type),
|
|
379
|
+
fields: json(row.fields),
|
|
380
|
+
links: json(row.links) ?? [],
|
|
381
|
+
}, composition);
|
|
382
|
+
built += size;
|
|
383
|
+
last = id;
|
|
384
|
+
spent += ENTRY_WEIGHT + size;
|
|
385
|
+
if (spent >= bytes || (spent >= floor && performance.now() - started >= ms))
|
|
386
|
+
break reading;
|
|
387
|
+
}
|
|
388
|
+
if (rows.length < DERIVED_ROWS) {
|
|
389
|
+
read = true;
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
394
392
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
connection.run('UPDATE replica_keys SET rederiving = ? WHERE key = ?', [
|
|
398
|
-
done ? null : number(last.id),
|
|
399
|
-
key,
|
|
400
|
-
]);
|
|
401
|
-
return { done };
|
|
393
|
+
connection.run('UPDATE replica_keys SET rederiving = ? WHERE key = ?', [read ? null : last, key]);
|
|
394
|
+
return { done: read, text: built };
|
|
402
395
|
}
|
|
403
396
|
function heldEntry(row) {
|
|
404
397
|
return {
|
|
@@ -410,15 +403,45 @@ function heldEntry(row) {
|
|
|
410
403
|
change: json(row.change),
|
|
411
404
|
written: text(row.written),
|
|
412
405
|
type: text(row.type),
|
|
406
|
+
facts: factsHeld(row),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function factsHeld(row) {
|
|
410
|
+
const type = text(row.declared);
|
|
411
|
+
if (type === null)
|
|
412
|
+
return null;
|
|
413
|
+
return {
|
|
414
|
+
type,
|
|
415
|
+
fields: json(row.fields) ?? {},
|
|
416
|
+
links: json(row.links) ?? [],
|
|
413
417
|
};
|
|
414
418
|
}
|
|
415
|
-
const ENTRY_COLUMNS = 'e.path, e.content, e.binary, e.revision, e.file_id, e.change, e.written, e.type';
|
|
419
|
+
const ENTRY_COLUMNS = 'e.path, e.content, e.binary, e.revision, e.file_id, e.change, e.written, e.type, e.declared, e.fields, e.links';
|
|
420
|
+
function unrefreshed(alias) {
|
|
421
|
+
return `NOT EXISTS (SELECT 1 FROM replica_entries r WHERE r.key = ${alias}.key AND r.layer = ${REFRESHED} AND r.path = ${alias}.path)`;
|
|
422
|
+
}
|
|
416
423
|
function viewed(view, alias) {
|
|
417
424
|
if (view === 'visible')
|
|
418
425
|
return `${alias}.visible = 1 AND ${alias}.present = 1`;
|
|
419
426
|
if (view === 'confirmed')
|
|
420
427
|
return `${alias}.layer = ${CONFIRMED}`;
|
|
421
|
-
return `${alias}.present = 1 AND (${alias}.layer = ${REFRESHED} OR (${alias}.layer = ${CONFIRMED} AND
|
|
428
|
+
return `${alias}.present = 1 AND (${alias}.layer = ${REFRESHED} OR (${alias}.layer = ${CONFIRMED} AND ${unrefreshed(alias)}))`;
|
|
429
|
+
}
|
|
430
|
+
function layers(view) {
|
|
431
|
+
if (view !== 'refreshed')
|
|
432
|
+
return [viewed(view, 'e')];
|
|
433
|
+
return [
|
|
434
|
+
`e.layer = ${REFRESHED} AND e.present = 1`,
|
|
435
|
+
`e.layer = ${CONFIRMED} AND e.present = 1 AND ${unrefreshed('e')}`,
|
|
436
|
+
];
|
|
437
|
+
}
|
|
438
|
+
function pathOrdered(connection, columns, key, view, condition, after, limit) {
|
|
439
|
+
const beyond = after === null ? '' : ' AND e.path > ?';
|
|
440
|
+
const parts = layers(view).map((layer) => `SELECT ${columns} FROM replica_entries e WHERE e.key = ? AND ${layer}${condition}${beyond}`);
|
|
441
|
+
return connection.rows(`${parts.join(' UNION ALL ')} ORDER BY path LIMIT ?`, [
|
|
442
|
+
...parts.flatMap(() => (after === null ? [key] : [key, after])),
|
|
443
|
+
limit,
|
|
444
|
+
]);
|
|
422
445
|
}
|
|
423
446
|
export function entries(connection, key, view, list) {
|
|
424
447
|
if (list.length === 0)
|
|
@@ -438,75 +461,21 @@ export function typed(connection, key, view, list) {
|
|
|
438
461
|
binary: number(row.binary) === 1,
|
|
439
462
|
}));
|
|
440
463
|
}
|
|
441
|
-
export function referrers(connection, key, view, targets
|
|
464
|
+
export function referrers(connection, key, view, targets) {
|
|
442
465
|
if (targets.length === 0)
|
|
443
466
|
return [];
|
|
444
467
|
return connection
|
|
445
|
-
.rows(`SELECT DISTINCT e.path, l.target
|
|
446
|
-
.map((row) => ({
|
|
447
|
-
path: text(row.path),
|
|
448
|
-
target: text(row.target),
|
|
449
|
-
kind: text(row.kind),
|
|
450
|
-
}));
|
|
451
|
-
}
|
|
452
|
-
export function walk(connection, key, view, after, bytes) {
|
|
453
|
-
const found = [];
|
|
454
|
-
let spent = 0;
|
|
455
|
-
let from = after;
|
|
456
|
-
for (;;) {
|
|
457
|
-
const rows = connection.rows(`SELECT ${ENTRY_COLUMNS} FROM replica_entries e WHERE e.key = ? AND ${viewed(view, 'e')}${from === null ? '' : ' AND e.path > ?'} ORDER BY e.path LIMIT 64`, from === null ? [key] : [key, from]);
|
|
458
|
-
for (const row of rows) {
|
|
459
|
-
const entry = heldEntry(row);
|
|
460
|
-
found.push(entry);
|
|
461
|
-
spent += 256 + (entry.content?.length ?? 0) * 2;
|
|
462
|
-
if (spent >= bytes)
|
|
463
|
-
return { entries: found, next: entry.path };
|
|
464
|
-
}
|
|
465
|
-
if (rows.length < 64)
|
|
466
|
-
return { entries: found, next: null };
|
|
467
|
-
from = found.at(-1).path;
|
|
468
|
-
}
|
|
468
|
+
.rows(`SELECT DISTINCT e.path, l.target FROM replica_links l JOIN replica_entries e ON e.id = l.doc WHERE l.key = ? AND l.target IN (SELECT value FROM json_each(?)) AND ${viewed(view, 'e')}`, [key, paths(targets)])
|
|
469
|
+
.map((row) => ({ path: text(row.path), target: text(row.target) }));
|
|
469
470
|
}
|
|
470
471
|
export function files(connection, key, view, after, limit) {
|
|
471
|
-
return connection
|
|
472
|
-
|
|
473
|
-
|
|
472
|
+
return pathOrdered(connection, 'e.path, e.revision', key, view, ' AND e.content IS NOT NULL AND e.revision IS NOT NULL', after, limit).map((row) => ({ path: text(row.path), revision: text(row.revision) }));
|
|
473
|
+
}
|
|
474
|
+
export function folders(connection, key, view, list) {
|
|
475
|
+
return list.filter((path) => connection.rows(`SELECT 1 FROM replica_folders f WHERE f.key = ? AND f.layer = ${CONFIRMED} AND f.present = 1 AND f.path = ? UNION ALL SELECT 1 FROM replica_entries e WHERE e.key = ? AND ${viewed(view, 'e')} AND e.path >= ? AND e.path < ? LIMIT 1`, [key, path, key, `${path}/`, `${path}0`]).length > 0);
|
|
474
476
|
}
|
|
475
477
|
export function typedWithin(connection, key, view, roots, within) {
|
|
476
|
-
|
|
477
|
-
const bind = [key];
|
|
478
|
-
for (const root of roots)
|
|
479
|
-
bind.push(root, `${root}/`, `${root}0`);
|
|
480
|
-
const placed = roots.length === 0 ? (within ? ' AND 0' : '') : ` AND ${within ? '' : 'NOT '}(${inside})`;
|
|
481
|
-
return (connection.rows(`SELECT 1 FROM replica_entries e WHERE e.key = ? AND ${viewed(view, 'e')} AND e.declared IS NOT NULL AND e.declared <> 'any'${placed} LIMIT 1`, bind).length > 0);
|
|
482
|
-
}
|
|
483
|
-
export function searched(connection, key, locator, after, limit, only) {
|
|
484
|
-
const bind = [key];
|
|
485
|
-
if (only !== null)
|
|
486
|
-
bind.push(paths(only));
|
|
487
|
-
if (after !== null)
|
|
488
|
-
bind.push(after);
|
|
489
|
-
bind.push(limit);
|
|
490
|
-
const rows = connection.rows(`SELECT e.path, e.type, e.fields, e.content FROM replica_entries e WHERE e.key = ? AND e.visible = 1 AND e.present = 1 AND e.queried = 1 AND e.type IS NOT NULL${only === null ? '' : ' AND e.path IN (SELECT value FROM json_each(?))'}${after === null ? '' : ' AND e.path > ?'} ORDER BY e.path LIMIT ?`, bind);
|
|
491
|
-
const documents = [];
|
|
492
|
-
for (const row of rows) {
|
|
493
|
-
const path = text(row.path);
|
|
494
|
-
const read = parse(text(row.content) ?? '', path);
|
|
495
|
-
if (!read.ok || !markdownPath(path))
|
|
496
|
-
continue;
|
|
497
|
-
documents.push({
|
|
498
|
-
room: locator,
|
|
499
|
-
path,
|
|
500
|
-
type: text(row.type),
|
|
501
|
-
fields: json(row.fields) ?? {},
|
|
502
|
-
preamble: read.document.preamble,
|
|
503
|
-
sections: read.document.sections,
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
return {
|
|
507
|
-
documents,
|
|
508
|
-
next: rows.length < limit ? null : text(rows.at(-1).path),
|
|
509
|
-
};
|
|
478
|
+
return (connection.rows(`SELECT 1 FROM replica_entries e WHERE e.key = ? AND ${viewed(view, 'e')} AND e.declared IS NOT NULL AND e.declared <> 'any' AND ${within ? '' : 'NOT '}${beneathRoots('e.path')} LIMIT 1`, [key, JSON.stringify(roots)]).length > 0);
|
|
510
479
|
}
|
|
511
480
|
export function opened(connection) {
|
|
512
481
|
const facts = {};
|
|
@@ -514,12 +483,7 @@ export function opened(connection) {
|
|
|
514
483
|
facts[text(row.name)] = text(row.value);
|
|
515
484
|
}
|
|
516
485
|
return {
|
|
517
|
-
rooms: connection.rows(
|
|
518
|
-
locator: text(row.locator),
|
|
519
|
-
key: number(row.key),
|
|
520
|
-
record: text(row.record),
|
|
521
|
-
})),
|
|
522
|
-
transfers: connection.rows('SELECT locator, key, record FROM replica_transfers').map((row) => ({
|
|
486
|
+
rooms: connection.rows(HELD_RECORDS).map((row) => ({
|
|
523
487
|
locator: text(row.locator),
|
|
524
488
|
key: number(row.key),
|
|
525
489
|
record: text(row.record),
|
|
@@ -530,7 +494,7 @@ export function opened(connection) {
|
|
|
530
494
|
key: number(row.key),
|
|
531
495
|
locator: text(row.locator),
|
|
532
496
|
transfer: text(row.transfer),
|
|
533
|
-
rederiving:
|
|
497
|
+
rederiving: cursor(row.rederiving),
|
|
534
498
|
})),
|
|
535
499
|
facts,
|
|
536
500
|
presentation: connection.rows('SELECT app, value FROM replica_presentation').map((row) => ({
|
|
@@ -543,7 +507,6 @@ export function opened(connection) {
|
|
|
543
507
|
orphans: connection
|
|
544
508
|
.rows(`SELECT k.key FROM replica_keys k
|
|
545
509
|
WHERE NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
546
|
-
AND NOT EXISTS (SELECT 1 FROM replica_transfers t WHERE t.key = k.key)
|
|
547
510
|
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`)
|
|
548
511
|
.map((row) => number(row.key)),
|
|
549
512
|
erasing: connection.rows('SELECT key, locator FROM replica_erasing').map((row) => ({
|