@agentshouse/mdruntime 0.1.0-c1ffd2bc60355 → 0.1.0-c219104d36ac5
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 +10 -8
- package/dist/adapter.d.ts +25 -7
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +2 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +28 -4
- package/dist/bootstrap.d.ts +8 -8
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +90 -84
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +7 -3
- package/dist/client.d.ts +4 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +52 -5
- package/dist/collection.d.ts +5 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +23 -2
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +74 -24
- package/dist/connection.d.ts +5 -2
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +654 -359
- package/dist/conversation.d.ts +5 -5
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +126 -33
- package/dist/entry.d.ts +1 -0
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +1 -1
- package/dist/file.d.ts +2 -11
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +6 -4
- package/dist/fulltext.d.ts.map +1 -1
- package/dist/fulltext.js +8 -6
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +4 -2
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +2 -1
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +208 -0
- package/dist/memory.d.ts +2 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +47 -9
- package/dist/model.d.ts +6 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -1
- package/dist/observation.d.ts +1 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +1 -1
- package/dist/outcome.d.ts +13 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +16 -2
- 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 +6 -0
- package/dist/query.d.ts.map +1 -1
- package/dist/reach.d.ts +8 -1
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +51 -17
- package/dist/readiness.d.ts +1 -2
- package/dist/readiness.d.ts.map +1 -1
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +10 -19
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +1 -5
- package/dist/replica.d.ts +3 -4
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +4 -3
- package/dist/room-draft.d.ts +17 -2
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +40 -6
- package/dist/rows.d.ts +15 -6
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +102 -74
- package/dist/save.d.ts +2 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +11 -5
- package/dist/status.d.ts +5 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -1
- package/dist/store.d.ts +16 -19
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +23 -29
- package/dist/stored.d.ts +9 -19
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +197 -196
- package/dist/tables.d.ts +14 -16
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +6 -9
- package/dist/wire.d.ts +8 -4
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +2 -1
- package/dist/words.d.ts.map +1 -1
- package/dist/words.js +8 -2
- package/package.json +10 -17
- package/AGENTS.md +0 -317
- 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/context.js +0 -10
- 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 -20
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -229
- package/dist/chat/message.d.ts +0 -7
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -254
- package/dist/chat/messages.d.ts +0 -35
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -210
- 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 -307
- package/dist/chat.d.ts +0 -15
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
package/dist/stored.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
+
import { composedOf } from './collection.js';
|
|
1
2
|
import { indexDocument, unindexAll, unindexDocuments } from './fulltext.js';
|
|
2
|
-
import { derived } from './rows.js';
|
|
3
|
+
import { described, derived } 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, searching INTEGER)',
|
|
5
6
|
'CREATE TABLE replica_rooms (locator TEXT PRIMARY KEY, key INTEGER NOT NULL, record TEXT NOT NULL) WITHOUT ROWID',
|
|
6
|
-
'CREATE TABLE replica_transfers (locator TEXT PRIMARY KEY, key INTEGER NOT NULL, record TEXT NOT NULL) WITHOUT ROWID',
|
|
7
|
-
'CREATE TABLE replica_transfer_parts (locator TEXT NOT NULL, token TEXT NOT NULL, part BLOB NOT NULL)',
|
|
8
|
-
'CREATE INDEX replica_transfer_parts_locator ON replica_transfer_parts (locator)',
|
|
9
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)',
|
|
10
8
|
'CREATE UNIQUE INDEX replica_entries_path ON replica_entries (key, layer, path)',
|
|
11
|
-
'CREATE INDEX replica_entries_visible ON replica_entries (key, visible, path)',
|
|
9
|
+
'CREATE INDEX replica_entries_visible ON replica_entries (key, visible, present, path, binary)',
|
|
12
10
|
'CREATE INDEX replica_entries_folder ON replica_entries (key, folder, path)',
|
|
13
|
-
'CREATE
|
|
14
|
-
'CREATE
|
|
15
|
-
'CREATE TABLE replica_links (doc INTEGER NOT NULL, key INTEGER NOT NULL, kind TEXT NOT NULL,
|
|
16
|
-
'CREATE INDEX replica_links_target ON replica_links (key, target, kind,
|
|
11
|
+
'CREATE INDEX replica_entries_key ON replica_entries (key)',
|
|
12
|
+
'CREATE TABLE replica_values (doc INTEGER NOT NULL, keys TEXT NOT NULL, places TEXT NOT NULL, item INTEGER NOT NULL, kind TEXT NOT NULL, value, size INTEGER, PRIMARY KEY (doc, keys, places, item)) WITHOUT ROWID',
|
|
13
|
+
'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',
|
|
14
|
+
'CREATE INDEX replica_links_target ON replica_links (key, target, kind, keys)',
|
|
17
15
|
'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',
|
|
18
16
|
'CREATE TABLE replica_erasing (key INTEGER PRIMARY KEY, locator TEXT NOT NULL)',
|
|
19
17
|
'CREATE TABLE replica_received (key TEXT PRIMARY KEY, head TEXT NOT NULL) WITHOUT ROWID',
|
|
@@ -24,7 +22,17 @@ export const REPLICA_TABLES = [
|
|
|
24
22
|
const CONFIRMED = 0;
|
|
25
23
|
const OVERLAY = 1;
|
|
26
24
|
const REFRESHED = 2;
|
|
27
|
-
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
|
+
values: [],
|
|
34
|
+
links: [],
|
|
35
|
+
};
|
|
28
36
|
function text(value) {
|
|
29
37
|
return typeof value === 'string' ? value : null;
|
|
30
38
|
}
|
|
@@ -40,84 +48,54 @@ function flag(value) {
|
|
|
40
48
|
function paths(list) {
|
|
41
49
|
return JSON.stringify(list);
|
|
42
50
|
}
|
|
43
|
-
function compositionOf(connection, key) {
|
|
44
|
-
let held = compositions.get(connection);
|
|
45
|
-
if (held === undefined) {
|
|
46
|
-
held = new Map();
|
|
47
|
-
compositions.set(connection, held);
|
|
48
|
-
}
|
|
49
|
-
const [row] = connection.rows('SELECT composition FROM replica_keys WHERE key = ?', [key]);
|
|
50
|
-
const textual = text(row?.composition) ?? 'null';
|
|
51
|
-
const known = held.get(textual);
|
|
52
|
-
if (known !== undefined)
|
|
53
|
-
return known;
|
|
54
|
-
const parsed = JSON.parse(textual) ?? {
|
|
55
|
-
model: { status: 'unavailable', reason: 'not-acquired' },
|
|
56
|
-
selection: null,
|
|
57
|
-
};
|
|
58
|
-
held.clear();
|
|
59
|
-
held.set(textual, parsed);
|
|
60
|
-
return parsed;
|
|
61
|
-
}
|
|
62
|
-
export function fingerprint(composition) {
|
|
63
|
-
const shape = (model) => model.status === 'unavailable' ? null : model.types;
|
|
64
|
-
return JSON.stringify({
|
|
65
|
-
model: shape(composition.model),
|
|
66
|
-
selection: composition.selection === null
|
|
67
|
-
? null
|
|
68
|
-
: { roots: composition.selection.roots, model: shape(composition.selection.model) },
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
51
|
function dropDerived(connection, doc) {
|
|
72
52
|
connection.run('DELETE FROM replica_values WHERE doc = ?', [doc]);
|
|
73
53
|
connection.run('DELETE FROM replica_links WHERE doc = ?', [doc]);
|
|
74
54
|
}
|
|
55
|
+
function scalarText(value) {
|
|
56
|
+
if (value === Infinity)
|
|
57
|
+
return 'Infinity';
|
|
58
|
+
if (value === -Infinity)
|
|
59
|
+
return '-Infinity';
|
|
60
|
+
return JSON.stringify(value);
|
|
61
|
+
}
|
|
75
62
|
function writeDerived(connection, doc, key, made) {
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
if (made.values.length > 0) {
|
|
64
|
+
const rows = made.values.map((value) => `[${JSON.stringify(value.keys)},${JSON.stringify(value.places)},${value.item},${JSON.stringify(value.kind)},${scalarText(value.value)},${JSON.stringify(value.size)}]`);
|
|
65
|
+
connection.run('INSERT INTO replica_values (doc, keys, places, item, kind, value, size) SELECT ?, value ->> 0, value ->> 1, value ->> 2, value ->> 3, value ->> 4, value ->> 5 FROM json_each(?)', [doc, `[${rows.join(',')}]`]);
|
|
66
|
+
}
|
|
67
|
+
if (made.links.length > 0) {
|
|
68
|
+
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(?)', [
|
|
78
69
|
doc,
|
|
79
70
|
key,
|
|
80
|
-
|
|
81
|
-
value.held,
|
|
82
|
-
value.item,
|
|
83
|
-
value.kind,
|
|
84
|
-
value.value,
|
|
85
|
-
value.size,
|
|
86
|
-
flag(value.single),
|
|
71
|
+
JSON.stringify(made.links.map((link) => [link.kind, link.keys, link.places, link.target, link.field])),
|
|
87
72
|
]);
|
|
88
73
|
}
|
|
89
|
-
for (const link of made.links) {
|
|
90
|
-
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]);
|
|
91
|
-
}
|
|
92
74
|
}
|
|
93
75
|
function entryId(connection, key, layer, path) {
|
|
94
76
|
const [row] = connection.rows('SELECT id FROM replica_entries WHERE key = ? AND layer = ? AND path = ?', [key, layer, path]);
|
|
95
77
|
return row === undefined ? null : number(row.id);
|
|
96
78
|
}
|
|
97
|
-
function
|
|
79
|
+
function words() {
|
|
80
|
+
return { dropped: [], made: [] };
|
|
81
|
+
}
|
|
82
|
+
function wordsWritten(connection, owed) {
|
|
83
|
+
unindexDocuments(connection, owed.dropped);
|
|
84
|
+
for (const { id, path, content } of owed.made)
|
|
85
|
+
indexDocument(connection, id, path, content);
|
|
86
|
+
}
|
|
87
|
+
function removeEntry(connection, key, layer, path, owed) {
|
|
98
88
|
const id = entryId(connection, key, layer, path);
|
|
99
89
|
if (id === null)
|
|
100
90
|
return;
|
|
101
91
|
dropDerived(connection, id);
|
|
102
|
-
|
|
92
|
+
owed.dropped.push(id);
|
|
103
93
|
connection.run('DELETE FROM replica_entries WHERE id = ?', [id]);
|
|
104
94
|
}
|
|
105
95
|
function heldIds(connection, sql, bind) {
|
|
106
96
|
return connection.rows(sql, bind).map((row) => number(row.id));
|
|
107
97
|
}
|
|
108
|
-
function
|
|
109
|
-
removeEntry(connection, key, layer, entry.path);
|
|
110
|
-
const made = present
|
|
111
|
-
? derived(entry.path, entry.binary === null ? entry.content : null, composition)
|
|
112
|
-
: {
|
|
113
|
-
type: null,
|
|
114
|
-
declared: null,
|
|
115
|
-
queried: false,
|
|
116
|
-
folder: '',
|
|
117
|
-
fields: null,
|
|
118
|
-
values: [],
|
|
119
|
-
links: [],
|
|
120
|
-
};
|
|
98
|
+
function insertEntry(connection, key, layer, entry, present, made) {
|
|
121
99
|
connection.run('INSERT INTO replica_entries (key, layer, path, visible, present, queried, content, binary, revision, file_id, change, written, type, declared, folder, fields) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
122
100
|
key,
|
|
123
101
|
layer,
|
|
@@ -136,82 +114,76 @@ function putEntry(connection, key, layer, entry, present, composition, searched
|
|
|
136
114
|
made.folder,
|
|
137
115
|
made.fields,
|
|
138
116
|
]);
|
|
117
|
+
}
|
|
118
|
+
function textOf(entry) {
|
|
119
|
+
return entry.binary === null ? entry.content : null;
|
|
120
|
+
}
|
|
121
|
+
function putEntry(connection, key, layer, entry, present, composition, owed, searched = true) {
|
|
122
|
+
removeEntry(connection, key, layer, entry.path, owed);
|
|
123
|
+
const content = textOf(entry);
|
|
124
|
+
const made = present ? derived(entry.path, content, composition) : ABSENT;
|
|
125
|
+
insertEntry(connection, key, layer, entry, present, made);
|
|
139
126
|
if (!present)
|
|
140
127
|
return;
|
|
141
128
|
const id = entryId(connection, key, layer, entry.path);
|
|
142
129
|
writeDerived(connection, id, key, made);
|
|
143
|
-
if (searched &&
|
|
144
|
-
|
|
145
|
-
|
|
130
|
+
if (searched && content !== null && made.queried)
|
|
131
|
+
owed.made.push({ id, path: entry.path, content });
|
|
132
|
+
}
|
|
133
|
+
function placeEntry(connection, key, entry, owed) {
|
|
134
|
+
removeEntry(connection, key, CONFIRMED, entry.path, owed);
|
|
135
|
+
insertEntry(connection, key, CONFIRMED, entry, true, described(entry.path, textOf(entry)));
|
|
146
136
|
}
|
|
147
137
|
function revealed(connection, key, touched) {
|
|
148
138
|
if (touched.length === 0)
|
|
149
139
|
return;
|
|
150
140
|
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)]);
|
|
151
141
|
}
|
|
152
|
-
function newKey(connection, locator, transfer,
|
|
153
|
-
|
|
142
|
+
function newKey(connection, locator, transfer, fingerprint, built) {
|
|
143
|
+
const owed = built ? null : 0;
|
|
144
|
+
connection.run('INSERT INTO replica_keys (locator, transfer, fingerprint, rederiving, searching) VALUES (?, ?, ?, ?, ?)', [locator, transfer, fingerprint, owed, owed]);
|
|
154
145
|
const [row] = connection.rows('SELECT last_insert_rowid() AS key');
|
|
155
146
|
return number(row.key);
|
|
156
147
|
}
|
|
157
|
-
function recomposed(connection, key,
|
|
158
|
-
const [row] = connection.rows('SELECT
|
|
159
|
-
|
|
160
|
-
const held = connection.rows('SELECT 1 FROM replica_entries WHERE key = ? LIMIT 1', [key]);
|
|
161
|
-
if (held.length === 0 || (before !== null && fingerprint(before) === fingerprint(composition))) {
|
|
162
|
-
connection.run('UPDATE replica_keys SET composition = ? WHERE key = ?', [
|
|
163
|
-
JSON.stringify(composition),
|
|
164
|
-
key,
|
|
165
|
-
]);
|
|
148
|
+
function recomposed(connection, key, fingerprint) {
|
|
149
|
+
const [row] = connection.rows('SELECT fingerprint FROM replica_keys WHERE key = ?', [key]);
|
|
150
|
+
if (row === undefined || text(row.fingerprint) === fingerprint)
|
|
166
151
|
return;
|
|
167
|
-
|
|
168
|
-
connection.run(
|
|
169
|
-
JSON.stringify(composition),
|
|
170
|
-
key,
|
|
171
|
-
]);
|
|
152
|
+
const held = connection.rows('SELECT 1 FROM replica_entries WHERE key = ? LIMIT 1', [key]);
|
|
153
|
+
connection.run(`UPDATE replica_keys SET fingerprint = ?${held.length === 0 ? '' : ', rederiving = 0'} WHERE key = ?`, [fingerprint, key]);
|
|
172
154
|
}
|
|
173
155
|
export function entered(connection, locator, composition, rows) {
|
|
174
|
-
const key = newKey(connection, locator, '', composition);
|
|
175
|
-
|
|
176
|
-
|
|
156
|
+
const key = newKey(connection, locator, '', composedOf(composition).fingerprint, true);
|
|
157
|
+
const owed = words();
|
|
158
|
+
for (const entry of rows) {
|
|
159
|
+
putEntry(connection, key, CONFIRMED, entry, true, composition, owed, false);
|
|
160
|
+
}
|
|
161
|
+
wordsWritten(connection, owed);
|
|
177
162
|
return key;
|
|
178
163
|
}
|
|
179
|
-
function dropTransfer(connection, locator) {
|
|
180
|
-
connection.run('DELETE FROM replica_transfers WHERE locator = ?', [locator]);
|
|
181
|
-
connection.run('DELETE FROM replica_transfer_parts WHERE locator = ?', [locator]);
|
|
182
|
-
}
|
|
183
164
|
export function stage(connection, request) {
|
|
184
|
-
const [held] = connection.rows('SELECT key FROM replica_transfers WHERE locator = ?', [
|
|
185
|
-
request.locator,
|
|
186
|
-
]);
|
|
187
165
|
const key = request.key ??
|
|
188
|
-
(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
connection.run('DELETE FROM replica_transfer_parts WHERE locator = ? AND token = ?', [
|
|
195
|
-
request.locator,
|
|
196
|
-
request.written,
|
|
197
|
-
]);
|
|
198
|
-
}
|
|
199
|
-
const composition = compositionOf(connection, key);
|
|
200
|
-
for (const entry of request.entries) {
|
|
201
|
-
putEntry(connection, key, CONFIRMED, entry, true, composition);
|
|
202
|
-
}
|
|
166
|
+
newKey(connection, request.locator, request.transfer, request.fingerprint, false);
|
|
167
|
+
recomposed(connection, key, request.fingerprint);
|
|
168
|
+
connection.run('UPDATE replica_keys SET rederiving = coalesce(rederiving, last), searching = coalesce(searching, last) FROM (SELECT coalesce(max(id), 0) AS last FROM replica_entries) WHERE key = ?', [key]);
|
|
169
|
+
const owed = words();
|
|
170
|
+
for (const entry of request.entries)
|
|
171
|
+
placeEntry(connection, key, entry, owed);
|
|
203
172
|
for (const path of request.folders) {
|
|
204
173
|
connection.run('INSERT OR REPLACE INTO replica_folders (key, layer, path, present) VALUES (?, ?, ?, 1)', [key, CONFIRMED, path]);
|
|
205
174
|
}
|
|
175
|
+
wordsWritten(connection, owed);
|
|
206
176
|
return key;
|
|
207
177
|
}
|
|
208
178
|
export function refreshing(connection, request) {
|
|
209
|
-
const held = connection.rows('SELECT 1 FROM
|
|
179
|
+
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]);
|
|
210
180
|
if (held.length === 0)
|
|
211
181
|
return null;
|
|
212
|
-
|
|
182
|
+
recomposed(connection, request.key, request.composed.fingerprint);
|
|
183
|
+
const composition = request.composed.composition;
|
|
184
|
+
const owed = words();
|
|
213
185
|
for (const entry of request.entries) {
|
|
214
|
-
putEntry(connection, request.key, REFRESHED, entry, true, composition);
|
|
186
|
+
putEntry(connection, request.key, REFRESHED, entry, true, composition, owed);
|
|
215
187
|
}
|
|
216
188
|
for (const path of request.removals) {
|
|
217
189
|
putEntry(connection, request.key, REFRESHED, {
|
|
@@ -222,7 +194,7 @@ export function refreshing(connection, request) {
|
|
|
222
194
|
fileId: null,
|
|
223
195
|
change: null,
|
|
224
196
|
written: null,
|
|
225
|
-
}, false, composition);
|
|
197
|
+
}, false, composition, owed);
|
|
226
198
|
}
|
|
227
199
|
for (const [list, present] of [
|
|
228
200
|
[request.folders, 1],
|
|
@@ -232,6 +204,7 @@ export function refreshing(connection, request) {
|
|
|
232
204
|
connection.run('INSERT OR REPLACE INTO replica_folders (key, layer, path, present) VALUES (?, ?, ?, ?)', [request.key, REFRESHED, path, present]);
|
|
233
205
|
}
|
|
234
206
|
}
|
|
207
|
+
wordsWritten(connection, owed);
|
|
235
208
|
return null;
|
|
236
209
|
}
|
|
237
210
|
function dropLayer(connection, key, layer) {
|
|
@@ -273,12 +246,11 @@ function applyRefresh(connection, key) {
|
|
|
273
246
|
connection.run('DELETE FROM replica_folders WHERE key = ? AND layer = ?', [key, REFRESHED]);
|
|
274
247
|
return touched;
|
|
275
248
|
}
|
|
249
|
+
function beneathRoots(path) {
|
|
250
|
+
return `EXISTS (SELECT 1 FROM json_each(?) r WHERE ${path} = r.value OR (${path} >= r.value || '/' AND ${path} < r.value || '0'))`;
|
|
251
|
+
}
|
|
276
252
|
function counted(connection, key, roots) {
|
|
277
|
-
const
|
|
278
|
-
const bind = [key];
|
|
279
|
-
for (const root of roots)
|
|
280
|
-
bind.push(root, `${root}/`, `${root}0`);
|
|
281
|
-
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);
|
|
253
|
+
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)]);
|
|
282
254
|
return number(row.held);
|
|
283
255
|
}
|
|
284
256
|
export function counts(connection, rooms) {
|
|
@@ -292,33 +264,32 @@ function erasing(connection, key, locator) {
|
|
|
292
264
|
}
|
|
293
265
|
function commitRoom(connection, room) {
|
|
294
266
|
const touched = new Set();
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
dropTransfer(connection, room.locator);
|
|
267
|
+
recomposed(connection, room.key, room.composed.fingerprint);
|
|
268
|
+
const composition = room.composed.composition;
|
|
269
|
+
if (room.published !== undefined &&
|
|
270
|
+
room.published.from !== null &&
|
|
271
|
+
room.published.from !== room.key) {
|
|
272
|
+
erasing(connection, room.published.from, room.locator);
|
|
303
273
|
}
|
|
304
274
|
if (room.refreshed === true) {
|
|
305
275
|
for (const path of applyRefresh(connection, room.key))
|
|
306
276
|
touched.add(path);
|
|
307
277
|
}
|
|
278
|
+
const owed = words();
|
|
308
279
|
for (const entry of room.confirmed?.set ?? []) {
|
|
309
|
-
putEntry(connection, room.key, CONFIRMED, entry, true, composition);
|
|
280
|
+
putEntry(connection, room.key, CONFIRMED, entry, true, composition, owed);
|
|
310
281
|
touched.add(entry.path);
|
|
311
282
|
}
|
|
312
283
|
for (const path of room.confirmed?.removed ?? []) {
|
|
313
|
-
removeEntry(connection, room.key, CONFIRMED, path);
|
|
284
|
+
removeEntry(connection, room.key, CONFIRMED, path, owed);
|
|
314
285
|
touched.add(path);
|
|
315
286
|
}
|
|
316
287
|
for (const entry of room.overlay?.set ?? []) {
|
|
317
|
-
putEntry(connection, room.key, OVERLAY, entry, entry.present, composition);
|
|
288
|
+
putEntry(connection, room.key, OVERLAY, entry, entry.present, composition, owed);
|
|
318
289
|
touched.add(entry.path);
|
|
319
290
|
}
|
|
320
291
|
for (const path of room.overlay?.cleared ?? []) {
|
|
321
|
-
removeEntry(connection, room.key, OVERLAY, path);
|
|
292
|
+
removeEntry(connection, room.key, OVERLAY, path, owed);
|
|
322
293
|
touched.add(path);
|
|
323
294
|
}
|
|
324
295
|
const changed = [...touched];
|
|
@@ -330,6 +301,7 @@ function commitRoom(connection, room) {
|
|
|
330
301
|
room.record,
|
|
331
302
|
]);
|
|
332
303
|
}
|
|
304
|
+
wordsWritten(connection, owed);
|
|
333
305
|
return room.published === undefined ? changed : null;
|
|
334
306
|
}
|
|
335
307
|
export function commit(connection, rooms) {
|
|
@@ -341,8 +313,11 @@ export function commit(connection, rooms) {
|
|
|
341
313
|
counted[room.locator] = counts(connection, [
|
|
342
314
|
{ key: room.key, roots: room.roots ?? rootsOf(connection, room.locator) },
|
|
343
315
|
])[0];
|
|
344
|
-
const [held] = connection.rows('SELECT rederiving FROM replica_keys WHERE key = ?', [
|
|
345
|
-
|
|
316
|
+
const [held] = connection.rows('SELECT rederiving, searching FROM replica_keys WHERE key = ?', [
|
|
317
|
+
room.key,
|
|
318
|
+
]);
|
|
319
|
+
indexed[room.locator] =
|
|
320
|
+
held !== undefined && held.rederiving === null && held.searching === null;
|
|
346
321
|
}
|
|
347
322
|
return { counts: counted, changed, indexed };
|
|
348
323
|
}
|
|
@@ -353,27 +328,24 @@ function rootsOf(connection, locator) {
|
|
|
353
328
|
}
|
|
354
329
|
export function fenceRooms(connection, locators) {
|
|
355
330
|
for (const locator of locators) {
|
|
356
|
-
for (const row of connection.rows('SELECT key FROM replica_keys WHERE locator = ? UNION SELECT key FROM replica_rooms WHERE locator = ?
|
|
331
|
+
for (const row of connection.rows('SELECT key FROM replica_keys WHERE locator = ? UNION SELECT key FROM replica_rooms WHERE locator = ?', [locator, locator])) {
|
|
357
332
|
erasing(connection, number(row.key), locator);
|
|
358
333
|
}
|
|
359
334
|
connection.run('DELETE FROM replica_rooms WHERE locator = ?', [locator]);
|
|
360
|
-
dropTransfer(connection, locator);
|
|
361
335
|
}
|
|
362
336
|
return null;
|
|
363
337
|
}
|
|
364
|
-
export function abandon(connection, locator
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return number(held.key);
|
|
338
|
+
export function abandon(connection, locator) {
|
|
339
|
+
for (const row of connection.rows(`SELECT k.key FROM replica_keys k WHERE k.locator = ?
|
|
340
|
+
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
341
|
+
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`, [locator])) {
|
|
342
|
+
erasing(connection, number(row.key), locator);
|
|
343
|
+
}
|
|
344
|
+
return null;
|
|
372
345
|
}
|
|
373
346
|
export function release(connection, key) {
|
|
374
347
|
const [held] = connection.rows(`SELECT k.locator FROM replica_keys k WHERE k.key = ?
|
|
375
|
-
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
376
|
-
AND NOT EXISTS (SELECT 1 FROM replica_transfers t WHERE t.key = k.key)`, [key]);
|
|
348
|
+
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)`, [key]);
|
|
377
349
|
if (held !== undefined)
|
|
378
350
|
erasing(connection, key, text(held.locator));
|
|
379
351
|
return null;
|
|
@@ -398,28 +370,59 @@ export function erase(connection, locator, limit) {
|
|
|
398
370
|
const [more] = connection.rows(`SELECT 1 FROM replica_erasing${locator === null ? '' : ' WHERE locator = ?'} LIMIT 1`, locator === null ? [] : [locator]);
|
|
399
371
|
return { remaining: more !== undefined };
|
|
400
372
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
const
|
|
408
|
-
for (const row of rows) {
|
|
409
|
-
const id = number(row.id);
|
|
410
|
-
const path = text(row.path);
|
|
411
|
-
const made = derived(path, text(row.content), composition);
|
|
412
|
-
dropDerived(connection, id);
|
|
413
|
-
connection.run('UPDATE replica_entries SET type = ?, declared = ?, queried = ?, fields = ? WHERE id = ?', [made.type, made.declared, flag(made.queried), made.fields, id]);
|
|
414
|
-
writeDerived(connection, id, key, made);
|
|
415
|
-
}
|
|
416
|
-
const last = rows.at(-1);
|
|
417
|
-
const done = rows.length < limit || last === undefined;
|
|
418
|
-
connection.run('UPDATE replica_keys SET rederiving = ? WHERE key = ?', [
|
|
419
|
-
done ? null : number(last.id),
|
|
373
|
+
function cursor(value) {
|
|
374
|
+
return value === null || value === undefined ? null : number(value);
|
|
375
|
+
}
|
|
376
|
+
export function rederive(connection, key, composed, bytes, ms, floor) {
|
|
377
|
+
const started = performance.now();
|
|
378
|
+
recomposed(connection, key, composed.fingerprint);
|
|
379
|
+
const [held] = connection.rows('SELECT rederiving, searching FROM replica_keys WHERE key = ?', [
|
|
420
380
|
key,
|
|
421
381
|
]);
|
|
422
|
-
|
|
382
|
+
const deriving = cursor(held?.rederiving);
|
|
383
|
+
const searching = cursor(held?.searching);
|
|
384
|
+
if (deriving === null && searching === null)
|
|
385
|
+
return { done: true, text: 0 };
|
|
386
|
+
const composition = composed.composition;
|
|
387
|
+
let last = Math.min(deriving ?? Infinity, searching ?? Infinity);
|
|
388
|
+
let spent = 0;
|
|
389
|
+
let built = 0;
|
|
390
|
+
const owed = words();
|
|
391
|
+
const reached = (done) => {
|
|
392
|
+
wordsWritten(connection, owed);
|
|
393
|
+
const next = (from) => (from === null || done ? null : Math.max(from, last));
|
|
394
|
+
connection.run('UPDATE replica_keys SET rederiving = ?, searching = ? WHERE key = ?', [
|
|
395
|
+
next(deriving),
|
|
396
|
+
next(searching),
|
|
397
|
+
key,
|
|
398
|
+
]);
|
|
399
|
+
return { done, text: built };
|
|
400
|
+
};
|
|
401
|
+
for (;;) {
|
|
402
|
+
const rows = connection.rows('SELECT id, path, content FROM replica_entries WHERE key = ? AND present = 1 AND id > ? ORDER BY id LIMIT ?', [key, last, DERIVED_ROWS]);
|
|
403
|
+
for (const row of rows) {
|
|
404
|
+
const id = number(row.id);
|
|
405
|
+
const path = text(row.path);
|
|
406
|
+
const content = text(row.content);
|
|
407
|
+
const owedRows = deriving !== null && id > deriving;
|
|
408
|
+
const owedWords = searching !== null && id > searching && content !== null;
|
|
409
|
+
if (owedRows) {
|
|
410
|
+
const made = derived(path, content, composition);
|
|
411
|
+
dropDerived(connection, id);
|
|
412
|
+
writeDerived(connection, id, key, made);
|
|
413
|
+
}
|
|
414
|
+
if (owedWords && described(path, content).queried)
|
|
415
|
+
owed.made.push({ id, path, content });
|
|
416
|
+
last = id;
|
|
417
|
+
built += content?.length ?? 0;
|
|
418
|
+
spent += ENTRY_WEIGHT + (content?.length ?? 0);
|
|
419
|
+
if (spent >= bytes || (spent >= floor && performance.now() - started >= ms)) {
|
|
420
|
+
return reached(false);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (rows.length < DERIVED_ROWS)
|
|
424
|
+
return reached(true);
|
|
425
|
+
}
|
|
423
426
|
}
|
|
424
427
|
function heldEntry(row) {
|
|
425
428
|
return {
|
|
@@ -434,12 +437,31 @@ function heldEntry(row) {
|
|
|
434
437
|
};
|
|
435
438
|
}
|
|
436
439
|
const ENTRY_COLUMNS = 'e.path, e.content, e.binary, e.revision, e.file_id, e.change, e.written, e.type';
|
|
440
|
+
function unrefreshed(alias) {
|
|
441
|
+
return `NOT EXISTS (SELECT 1 FROM replica_entries r WHERE r.key = ${alias}.key AND r.layer = ${REFRESHED} AND r.path = ${alias}.path)`;
|
|
442
|
+
}
|
|
437
443
|
function viewed(view, alias) {
|
|
438
444
|
if (view === 'visible')
|
|
439
445
|
return `${alias}.visible = 1 AND ${alias}.present = 1`;
|
|
440
446
|
if (view === 'confirmed')
|
|
441
447
|
return `${alias}.layer = ${CONFIRMED}`;
|
|
442
|
-
return `${alias}.present = 1 AND (${alias}.layer = ${REFRESHED} OR (${alias}.layer = ${CONFIRMED} AND
|
|
448
|
+
return `${alias}.present = 1 AND (${alias}.layer = ${REFRESHED} OR (${alias}.layer = ${CONFIRMED} AND ${unrefreshed(alias)}))`;
|
|
449
|
+
}
|
|
450
|
+
function layers(view) {
|
|
451
|
+
if (view !== 'refreshed')
|
|
452
|
+
return [viewed(view, 'e')];
|
|
453
|
+
return [
|
|
454
|
+
`e.layer = ${REFRESHED} AND e.present = 1`,
|
|
455
|
+
`e.layer = ${CONFIRMED} AND e.present = 1 AND ${unrefreshed('e')}`,
|
|
456
|
+
];
|
|
457
|
+
}
|
|
458
|
+
function pathOrdered(connection, columns, key, view, condition, after, limit) {
|
|
459
|
+
const beyond = after === null ? '' : ' AND e.path > ?';
|
|
460
|
+
const parts = layers(view).map((layer) => `SELECT ${columns} FROM replica_entries e WHERE e.key = ? AND ${layer}${condition}${beyond}`);
|
|
461
|
+
return connection.rows(`${parts.join(' UNION ALL ')} ORDER BY path LIMIT ?`, [
|
|
462
|
+
...parts.flatMap(() => (after === null ? [key] : [key, after])),
|
|
463
|
+
limit,
|
|
464
|
+
]);
|
|
443
465
|
}
|
|
444
466
|
export function entries(connection, key, view, list) {
|
|
445
467
|
if (list.length === 0)
|
|
@@ -475,7 +497,7 @@ export function walk(connection, key, view, after, bytes) {
|
|
|
475
497
|
let spent = 0;
|
|
476
498
|
let from = after;
|
|
477
499
|
for (;;) {
|
|
478
|
-
const rows = connection
|
|
500
|
+
const rows = pathOrdered(connection, ENTRY_COLUMNS, key, view, '', from, 64);
|
|
479
501
|
for (const row of rows) {
|
|
480
502
|
const entry = heldEntry(row);
|
|
481
503
|
found.push(entry);
|
|
@@ -489,29 +511,13 @@ export function walk(connection, key, view, after, bytes) {
|
|
|
489
511
|
}
|
|
490
512
|
}
|
|
491
513
|
export function files(connection, key, view, after, limit) {
|
|
492
|
-
return connection
|
|
493
|
-
|
|
494
|
-
|
|
514
|
+
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) }));
|
|
515
|
+
}
|
|
516
|
+
export function folders(connection, key, view, list) {
|
|
517
|
+
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);
|
|
495
518
|
}
|
|
496
519
|
export function typedWithin(connection, key, view, roots, within) {
|
|
497
|
-
|
|
498
|
-
const bind = [key];
|
|
499
|
-
for (const root of roots)
|
|
500
|
-
bind.push(root, `${root}/`, `${root}0`);
|
|
501
|
-
const placed = roots.length === 0 ? (within ? ' AND 0' : '') : ` AND ${within ? '' : 'NOT '}(${inside})`;
|
|
502
|
-
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);
|
|
503
|
-
}
|
|
504
|
-
export function transferPart(connection, locator, token) {
|
|
505
|
-
const [held] = connection.rows('SELECT part FROM replica_transfer_parts WHERE locator = ? AND token = ?', [locator, token]);
|
|
506
|
-
return held?.part instanceof Uint8Array ? held.part : null;
|
|
507
|
-
}
|
|
508
|
-
export function keepPart(connection, request) {
|
|
509
|
-
connection.run('DELETE FROM replica_transfer_parts WHERE locator = ? AND token = ?', [
|
|
510
|
-
request.locator,
|
|
511
|
-
request.token,
|
|
512
|
-
]);
|
|
513
|
-
connection.run('INSERT INTO replica_transfer_parts (locator, token, part) SELECT ?, ?, ? WHERE EXISTS (SELECT 1 FROM replica_transfers WHERE locator = ?)', [request.locator, request.token, request.part, request.locator]);
|
|
514
|
-
return null;
|
|
520
|
+
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);
|
|
515
521
|
}
|
|
516
522
|
export function opened(connection) {
|
|
517
523
|
const facts = {};
|
|
@@ -524,18 +530,14 @@ export function opened(connection) {
|
|
|
524
530
|
key: number(row.key),
|
|
525
531
|
record: text(row.record),
|
|
526
532
|
})),
|
|
527
|
-
transfers: connection.rows('SELECT locator, key, record FROM replica_transfers').map((row) => ({
|
|
528
|
-
locator: text(row.locator),
|
|
529
|
-
key: number(row.key),
|
|
530
|
-
record: text(row.record),
|
|
531
|
-
})),
|
|
532
533
|
keys: connection
|
|
533
|
-
.rows('SELECT key, locator, transfer, rederiving FROM replica_keys')
|
|
534
|
+
.rows('SELECT key, locator, transfer, rederiving, searching FROM replica_keys')
|
|
534
535
|
.map((row) => ({
|
|
535
536
|
key: number(row.key),
|
|
536
537
|
locator: text(row.locator),
|
|
537
538
|
transfer: text(row.transfer),
|
|
538
|
-
rederiving:
|
|
539
|
+
rederiving: cursor(row.rederiving),
|
|
540
|
+
searching: cursor(row.searching),
|
|
539
541
|
})),
|
|
540
542
|
facts,
|
|
541
543
|
presentation: connection.rows('SELECT app, value FROM replica_presentation').map((row) => ({
|
|
@@ -548,7 +550,6 @@ export function opened(connection) {
|
|
|
548
550
|
orphans: connection
|
|
549
551
|
.rows(`SELECT k.key FROM replica_keys k
|
|
550
552
|
WHERE NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
551
|
-
AND NOT EXISTS (SELECT 1 FROM replica_transfers t WHERE t.key = k.key)
|
|
552
553
|
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`)
|
|
553
554
|
.map((row) => number(row.key)),
|
|
554
555
|
erasing: connection.rows('SELECT key, locator FROM replica_erasing').map((row) => ({
|