@agentshouse/mdruntime 0.1.0-ccbb89b0ca151 → 0.1.0-ccc0e3407f107
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 +1 -1
- package/dist/adapter.d.ts +74 -57
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +3 -10
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +29 -47
- package/dist/bootstrap.d.ts +11 -18
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +85 -108
- package/dist/chain.d.ts +2 -1
- package/dist/chain.d.ts.map +1 -1
- package/dist/client.d.ts +9 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -1
- package/dist/collection.d.ts +7 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +23 -17
- package/dist/compile.d.ts +1 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +91 -270
- package/dist/connection.d.ts +10 -9
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1009 -1063
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +7 -0
- package/dist/conversation.d.ts +16 -13
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +229 -155
- package/dist/durability.d.ts +6 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +3 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +17 -8
- package/dist/host.d.ts +3 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +22 -27
- package/dist/identity.d.ts +0 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -3
- package/dist/index.d.ts +11 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- 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 +10 -7
- package/dist/media.d.ts +1 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +27 -4
- package/dist/memory.d.ts +11 -5
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +167 -84
- package/dist/messages.d.ts +2 -2
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +15 -16
- package/dist/model.d.ts +8 -8
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +6 -12
- 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 +0 -3
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +3 -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 +4 -209
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -505
- package/dist/reach.d.ts +9 -8
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +37 -48
- package/dist/react.d.ts +3 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/readiness.d.ts +3 -17
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +4 -10
- 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 +7 -5
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +29 -5
- package/dist/replica.d.ts +10 -8
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +29 -14
- package/dist/room-draft.d.ts +21 -5
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +98 -51
- package/dist/rows.d.ts +14 -21
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +48 -184
- package/dist/save.d.ts +2 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +20 -12
- package/dist/search.d.ts +12 -63
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +9 -52
- 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 +21 -34
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +34 -77
- package/dist/stored.d.ts +11 -34
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +158 -241
- package/dist/tables.d.ts +23 -48
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +29 -66
- 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 +42 -100
- 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 +9 -4
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +3 -1
- package/package.json +2 -2
- package/dist/fulltext.d.ts +0 -27
- package/dist/fulltext.d.ts.map +0 -1
- package/dist/fulltext.js +0 -368
- package/dist/reads.d.ts +0 -11
- package/dist/reads.d.ts.map +0 -1
- package/dist/reads.js +0 -100
- package/dist/words.d.ts +0 -19
- package/dist/words.d.ts.map +0 -1
- package/dist/words.js +0 -150
package/dist/stored.js
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
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
|
|
8
|
-
'CREATE INDEX replica_transfer_parts_locator ON replica_transfer_parts (locator)',
|
|
9
|
-
'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)',
|
|
10
9
|
'CREATE UNIQUE INDEX replica_entries_path ON replica_entries (key, layer, path)',
|
|
11
|
-
'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)',
|
|
12
11
|
'CREATE INDEX replica_entries_folder ON replica_entries (key, folder, path)',
|
|
13
|
-
'CREATE
|
|
14
|
-
'CREATE INDEX
|
|
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
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
16
|
'CREATE INDEX replica_links_target ON replica_links (key, target, kind, keys)',
|
|
17
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',
|
|
18
18
|
'CREATE TABLE replica_erasing (key INTEGER PRIMARY KEY, locator TEXT NOT NULL)',
|
|
19
|
-
'CREATE TABLE replica_received (key TEXT PRIMARY KEY, head TEXT NOT NULL) WITHOUT ROWID',
|
|
20
|
-
'CREATE TABLE replica_received_parts (key TEXT NOT NULL, part INTEGER NOT NULL, value TEXT NOT NULL, PRIMARY KEY (key, part)) WITHOUT ROWID',
|
|
21
19
|
'CREATE TABLE replica_facts (name TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',
|
|
22
20
|
'CREATE TABLE replica_presentation (app TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',
|
|
23
21
|
];
|
|
@@ -32,10 +30,8 @@ const ABSENT = {
|
|
|
32
30
|
queried: false,
|
|
33
31
|
folder: '',
|
|
34
32
|
fields: null,
|
|
35
|
-
|
|
36
|
-
links: [],
|
|
33
|
+
links: null,
|
|
37
34
|
};
|
|
38
|
-
const compositions = new WeakMap();
|
|
39
35
|
function text(value) {
|
|
40
36
|
return typeof value === 'string' ? value : null;
|
|
41
37
|
}
|
|
@@ -51,44 +47,22 @@ function flag(value) {
|
|
|
51
47
|
function paths(list) {
|
|
52
48
|
return JSON.stringify(list);
|
|
53
49
|
}
|
|
54
|
-
function compositionOf(connection, key) {
|
|
55
|
-
let held = compositions.get(connection);
|
|
56
|
-
if (held === undefined) {
|
|
57
|
-
held = new Map();
|
|
58
|
-
compositions.set(connection, held);
|
|
59
|
-
}
|
|
60
|
-
const [row] = connection.rows('SELECT composition FROM replica_keys WHERE key = ?', [key]);
|
|
61
|
-
const textual = text(row?.composition) ?? 'null';
|
|
62
|
-
const known = held.get(textual);
|
|
63
|
-
if (known !== undefined)
|
|
64
|
-
return known;
|
|
65
|
-
const parsed = JSON.parse(textual) ?? {
|
|
66
|
-
model: { status: 'unavailable', reason: 'not-acquired' },
|
|
67
|
-
selection: null,
|
|
68
|
-
};
|
|
69
|
-
held.clear();
|
|
70
|
-
held.set(textual, parsed);
|
|
71
|
-
return parsed;
|
|
72
|
-
}
|
|
73
|
-
export function fingerprint(composition) {
|
|
74
|
-
const shape = (model) => model.status === 'unavailable' ? null : model.types;
|
|
75
|
-
return JSON.stringify({
|
|
76
|
-
model: shape(composition.model),
|
|
77
|
-
selection: composition.selection === null
|
|
78
|
-
? null
|
|
79
|
-
: { roots: composition.selection.roots, model: shape(composition.selection.model) },
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
50
|
function dropDerived(connection, doc) {
|
|
83
51
|
connection.run('DELETE FROM replica_values WHERE doc = ?', [doc]);
|
|
84
52
|
connection.run('DELETE FROM replica_links WHERE doc = ?', [doc]);
|
|
85
53
|
}
|
|
86
|
-
function writeDerived(connection, doc, key,
|
|
87
|
-
|
|
88
|
-
|
|
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);
|
|
89
59
|
}
|
|
90
|
-
|
|
91
|
-
connection.run('INSERT OR IGNORE INTO replica_links (doc, key, kind, keys, places, target, field)
|
|
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(?)', [
|
|
62
|
+
doc,
|
|
63
|
+
key,
|
|
64
|
+
JSON.stringify(made.links.map((link) => [link.kind, link.keys, link.places, link.target, link.field])),
|
|
65
|
+
]);
|
|
92
66
|
}
|
|
93
67
|
}
|
|
94
68
|
function entryId(connection, key, layer, path) {
|
|
@@ -100,14 +74,10 @@ function removeEntry(connection, key, layer, path) {
|
|
|
100
74
|
if (id === null)
|
|
101
75
|
return;
|
|
102
76
|
dropDerived(connection, id);
|
|
103
|
-
unindexDocuments(connection, [id]);
|
|
104
77
|
connection.run('DELETE FROM replica_entries WHERE id = ?', [id]);
|
|
105
78
|
}
|
|
106
|
-
function heldIds(connection, sql, bind) {
|
|
107
|
-
return connection.rows(sql, bind).map((row) => number(row.id));
|
|
108
|
-
}
|
|
109
79
|
function insertEntry(connection, key, layer, entry, present, made) {
|
|
110
|
-
connection.run('INSERT INTO replica_entries (key, layer, path, visible, present, queried, content, binary, revision, file_id, change, written, type, declared, folder, fields) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
111
81
|
key,
|
|
112
82
|
layer,
|
|
113
83
|
entry.path,
|
|
@@ -124,82 +94,54 @@ function insertEntry(connection, key, layer, entry, present, made) {
|
|
|
124
94
|
made.declared,
|
|
125
95
|
made.folder,
|
|
126
96
|
made.fields,
|
|
97
|
+
made.links,
|
|
127
98
|
]);
|
|
128
99
|
}
|
|
129
100
|
function textOf(entry) {
|
|
130
101
|
return entry.binary === null ? entry.content : null;
|
|
131
102
|
}
|
|
132
|
-
function putEntry(connection, key, layer, entry, present, composition
|
|
103
|
+
function putEntry(connection, key, layer, entry, present, composition) {
|
|
133
104
|
removeEntry(connection, key, layer, entry.path);
|
|
134
105
|
const content = textOf(entry);
|
|
135
|
-
|
|
136
|
-
insertEntry(connection, key, layer, entry, present, made);
|
|
106
|
+
insertEntry(connection, key, layer, entry, present, present ? described(entry.path, content, entry.facts) : ABSENT);
|
|
137
107
|
if (!present)
|
|
138
108
|
return;
|
|
139
109
|
const id = entryId(connection, key, layer, entry.path);
|
|
140
|
-
writeDerived(connection, id, key,
|
|
141
|
-
if (searched && content !== null && made.queried) {
|
|
142
|
-
indexDocument(connection, id, entry.path, content);
|
|
143
|
-
}
|
|
110
|
+
writeDerived(connection, id, key, entry.path, heldOf(entry.path, content, entry.facts), composition);
|
|
144
111
|
}
|
|
145
112
|
function placeEntry(connection, key, entry) {
|
|
146
113
|
removeEntry(connection, key, CONFIRMED, entry.path);
|
|
147
|
-
insertEntry(connection, key, CONFIRMED, entry, true, described(entry.path, textOf(entry)));
|
|
114
|
+
insertEntry(connection, key, CONFIRMED, entry, true, described(entry.path, textOf(entry), entry.facts));
|
|
148
115
|
}
|
|
149
116
|
function revealed(connection, key, touched) {
|
|
150
117
|
if (touched.length === 0)
|
|
151
118
|
return;
|
|
152
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)]);
|
|
153
120
|
}
|
|
154
|
-
function newKey(connection, locator, transfer,
|
|
121
|
+
function newKey(connection, locator, transfer, fingerprint, built) {
|
|
155
122
|
const owed = built ? null : 0;
|
|
156
|
-
connection.run('INSERT INTO replica_keys (locator, transfer,
|
|
123
|
+
connection.run('INSERT INTO replica_keys (locator, transfer, fingerprint, rederiving) VALUES (?, ?, ?, ?)', [locator, transfer, fingerprint, owed]);
|
|
157
124
|
const [row] = connection.rows('SELECT last_insert_rowid() AS key');
|
|
158
125
|
return number(row.key);
|
|
159
126
|
}
|
|
160
|
-
function recomposed(connection, key,
|
|
161
|
-
const [row] = connection.rows('SELECT
|
|
162
|
-
|
|
163
|
-
const held = connection.rows('SELECT 1 FROM replica_entries WHERE key = ? LIMIT 1', [key]);
|
|
164
|
-
if (held.length === 0 || (before !== null && fingerprint(before) === fingerprint(composition))) {
|
|
165
|
-
connection.run('UPDATE replica_keys SET composition = ? WHERE key = ?', [
|
|
166
|
-
JSON.stringify(composition),
|
|
167
|
-
key,
|
|
168
|
-
]);
|
|
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)
|
|
169
130
|
return;
|
|
170
|
-
|
|
171
|
-
connection.run(
|
|
172
|
-
JSON.stringify(composition),
|
|
173
|
-
key,
|
|
174
|
-
]);
|
|
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]);
|
|
175
133
|
}
|
|
176
134
|
export function entered(connection, locator, composition, rows) {
|
|
177
|
-
const key = newKey(connection, locator, '', composition, true);
|
|
135
|
+
const key = newKey(connection, locator, '', composedOf(composition).fingerprint, true);
|
|
178
136
|
for (const entry of rows)
|
|
179
|
-
putEntry(connection, key, CONFIRMED, entry, true, composition
|
|
137
|
+
putEntry(connection, key, CONFIRMED, entry, true, composition);
|
|
180
138
|
return key;
|
|
181
139
|
}
|
|
182
|
-
function dropTransfer(connection, locator) {
|
|
183
|
-
connection.run('DELETE FROM replica_transfers WHERE locator = ?', [locator]);
|
|
184
|
-
connection.run('DELETE FROM replica_transfer_parts WHERE locator = ?', [locator]);
|
|
185
|
-
}
|
|
186
140
|
export function stage(connection, request) {
|
|
187
|
-
const [held] = connection.rows('SELECT key FROM replica_transfers WHERE locator = ?', [
|
|
188
|
-
request.locator,
|
|
189
|
-
]);
|
|
190
141
|
const key = request.key ??
|
|
191
|
-
(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
recomposed(connection, key, request.composition);
|
|
195
|
-
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]);
|
|
196
|
-
connection.run('INSERT OR REPLACE INTO replica_transfers (locator, key, record) VALUES (?, ?, ?)', [request.locator, key, request.record]);
|
|
197
|
-
if (request.written !== undefined) {
|
|
198
|
-
connection.run('DELETE FROM replica_transfer_parts WHERE locator = ? AND token = ?', [
|
|
199
|
-
request.locator,
|
|
200
|
-
request.written,
|
|
201
|
-
]);
|
|
202
|
-
}
|
|
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]);
|
|
203
145
|
for (const entry of request.entries)
|
|
204
146
|
placeEntry(connection, key, entry);
|
|
205
147
|
for (const path of request.folders) {
|
|
@@ -208,10 +150,11 @@ export function stage(connection, request) {
|
|
|
208
150
|
return key;
|
|
209
151
|
}
|
|
210
152
|
export function refreshing(connection, request) {
|
|
211
|
-
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]);
|
|
212
154
|
if (held.length === 0)
|
|
213
155
|
return null;
|
|
214
|
-
|
|
156
|
+
recomposed(connection, request.key, request.composed.fingerprint);
|
|
157
|
+
const composition = request.composed.composition;
|
|
215
158
|
for (const entry of request.entries) {
|
|
216
159
|
putEntry(connection, request.key, REFRESHED, entry, true, composition);
|
|
217
160
|
}
|
|
@@ -224,6 +167,7 @@ export function refreshing(connection, request) {
|
|
|
224
167
|
fileId: null,
|
|
225
168
|
change: null,
|
|
226
169
|
written: null,
|
|
170
|
+
facts: null,
|
|
227
171
|
}, false, composition);
|
|
228
172
|
}
|
|
229
173
|
for (const [list, present] of [
|
|
@@ -237,7 +181,6 @@ export function refreshing(connection, request) {
|
|
|
237
181
|
return null;
|
|
238
182
|
}
|
|
239
183
|
function dropLayer(connection, key, layer) {
|
|
240
|
-
unindexDocuments(connection, heldIds(connection, 'SELECT id FROM replica_entries WHERE key = ? AND layer = ?', [key, layer]));
|
|
241
184
|
for (const table of ['replica_values', 'replica_links']) {
|
|
242
185
|
connection.run(`DELETE FROM ${table} WHERE doc IN (SELECT id FROM replica_entries WHERE key = ? AND layer = ?)`, [key, layer]);
|
|
243
186
|
}
|
|
@@ -256,7 +199,6 @@ function refreshedPaths(connection, key) {
|
|
|
256
199
|
function applyRefresh(connection, key) {
|
|
257
200
|
const touched = refreshedPaths(connection, key);
|
|
258
201
|
const replaced = `SELECT c.id FROM replica_entries c JOIN replica_entries r ON r.key = c.key AND r.layer = ${REFRESHED} AND r.path = c.path WHERE c.key = ? AND c.layer = ${CONFIRMED}`;
|
|
259
|
-
unindexDocuments(connection, heldIds(connection, replaced, [key]));
|
|
260
202
|
for (const table of ['replica_values', 'replica_links']) {
|
|
261
203
|
connection.run(`DELETE FROM ${table} WHERE doc IN (${replaced})`, [key]);
|
|
262
204
|
}
|
|
@@ -275,12 +217,11 @@ function applyRefresh(connection, key) {
|
|
|
275
217
|
connection.run('DELETE FROM replica_folders WHERE key = ? AND layer = ?', [key, REFRESHED]);
|
|
276
218
|
return touched;
|
|
277
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
|
+
}
|
|
278
223
|
function counted(connection, key, roots) {
|
|
279
|
-
const
|
|
280
|
-
const bind = [key];
|
|
281
|
-
for (const root of roots)
|
|
282
|
-
bind.push(root, `${root}/`, `${root}0`);
|
|
283
|
-
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)]);
|
|
284
225
|
return number(row.held);
|
|
285
226
|
}
|
|
286
227
|
export function counts(connection, rooms) {
|
|
@@ -294,14 +235,12 @@ function erasing(connection, key, locator) {
|
|
|
294
235
|
}
|
|
295
236
|
function commitRoom(connection, room) {
|
|
296
237
|
const touched = new Set();
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
dropTransfer(connection, 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);
|
|
305
244
|
}
|
|
306
245
|
if (room.refreshed === true) {
|
|
307
246
|
for (const path of applyRefresh(connection, room.key))
|
|
@@ -326,14 +265,28 @@ function commitRoom(connection, room) {
|
|
|
326
265
|
const changed = [...touched];
|
|
327
266
|
revealed(connection, room.key, changed);
|
|
328
267
|
if (room.record !== undefined) {
|
|
329
|
-
connection.run(
|
|
330
|
-
|
|
331
|
-
room.key,
|
|
332
|
-
room.record,
|
|
333
|
-
]);
|
|
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]);
|
|
334
270
|
}
|
|
335
271
|
return room.published === undefined ? changed : null;
|
|
336
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')`;
|
|
337
290
|
export function commit(connection, rooms) {
|
|
338
291
|
const counted = {};
|
|
339
292
|
const changed = {};
|
|
@@ -343,12 +296,11 @@ export function commit(connection, rooms) {
|
|
|
343
296
|
counted[room.locator] = counts(connection, [
|
|
344
297
|
{ key: room.key, roots: room.roots ?? rootsOf(connection, room.locator) },
|
|
345
298
|
])[0];
|
|
346
|
-
const [held] = connection.rows('SELECT rederiving
|
|
347
|
-
|
|
348
|
-
]);
|
|
349
|
-
indexed[room.locator] =
|
|
350
|
-
held !== undefined && held.rederiving === null && held.searching === null;
|
|
299
|
+
const [held] = connection.rows('SELECT rederiving FROM replica_keys WHERE key = ?', [room.key]);
|
|
300
|
+
indexed[room.locator] = held !== undefined && held.rederiving === null;
|
|
351
301
|
}
|
|
302
|
+
if (rooms.some((room) => room.record !== undefined))
|
|
303
|
+
connection.run(UNHELD_MODELS);
|
|
352
304
|
return { counts: counted, changed, indexed };
|
|
353
305
|
}
|
|
354
306
|
function rootsOf(connection, locator) {
|
|
@@ -358,27 +310,25 @@ function rootsOf(connection, locator) {
|
|
|
358
310
|
}
|
|
359
311
|
export function fenceRooms(connection, locators) {
|
|
360
312
|
for (const locator of locators) {
|
|
361
|
-
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])) {
|
|
362
314
|
erasing(connection, number(row.key), locator);
|
|
363
315
|
}
|
|
364
316
|
connection.run('DELETE FROM replica_rooms WHERE locator = ?', [locator]);
|
|
365
|
-
dropTransfer(connection, locator);
|
|
366
317
|
}
|
|
318
|
+
connection.run(UNHELD_MODELS);
|
|
367
319
|
return null;
|
|
368
320
|
}
|
|
369
|
-
export function abandon(connection, locator
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
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;
|
|
377
328
|
}
|
|
378
329
|
export function release(connection, key) {
|
|
379
330
|
const [held] = connection.rows(`SELECT k.locator FROM replica_keys k WHERE k.key = ?
|
|
380
|
-
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
381
|
-
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]);
|
|
382
332
|
if (held !== undefined)
|
|
383
333
|
erasing(connection, key, text(held.locator));
|
|
384
334
|
return null;
|
|
@@ -389,7 +339,6 @@ export function erase(connection, locator, limit) {
|
|
|
389
339
|
return { remaining: false };
|
|
390
340
|
const key = number(held.key);
|
|
391
341
|
const batch = 'SELECT id FROM replica_entries WHERE key = ? ORDER BY id LIMIT ?';
|
|
392
|
-
unindexDocuments(connection, heldIds(connection, batch, [key, limit]));
|
|
393
342
|
for (const table of ['replica_values', 'replica_links']) {
|
|
394
343
|
connection.run(`DELETE FROM ${table} WHERE doc IN (${batch})`, [key, limit]);
|
|
395
344
|
}
|
|
@@ -406,50 +355,43 @@ export function erase(connection, locator, limit) {
|
|
|
406
355
|
function cursor(value) {
|
|
407
356
|
return value === null || value === undefined ? null : number(value);
|
|
408
357
|
}
|
|
409
|
-
export function rederive(connection, key, bytes) {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
]);
|
|
358
|
+
export function rederive(connection, key, composed, bytes, ms, floor) {
|
|
359
|
+
const started = performance.now();
|
|
360
|
+
recomposed(connection, key, composed.fingerprint);
|
|
361
|
+
const [held] = connection.rows('SELECT rederiving FROM replica_keys WHERE key = ?', [key]);
|
|
413
362
|
const deriving = cursor(held?.rederiving);
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
let last = Math.min(deriving ?? Infinity, searching ?? Infinity);
|
|
363
|
+
if (deriving === null)
|
|
364
|
+
return { done: true, text: 0 };
|
|
365
|
+
const composition = composed.composition;
|
|
366
|
+
let last = deriving;
|
|
419
367
|
let spent = 0;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
next(searching),
|
|
425
|
-
key,
|
|
426
|
-
]);
|
|
427
|
-
return { done };
|
|
428
|
-
};
|
|
429
|
-
for (;;) {
|
|
430
|
-
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]);
|
|
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]);
|
|
431
372
|
for (const row of rows) {
|
|
432
373
|
const id = number(row.id);
|
|
433
374
|
const path = text(row.path);
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
if (owedWords && described(path, content).queried) {
|
|
443
|
-
indexDocument(connection, id, path, content);
|
|
444
|
-
}
|
|
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;
|
|
445
383
|
last = id;
|
|
446
|
-
spent += ENTRY_WEIGHT +
|
|
447
|
-
if (spent >= bytes)
|
|
448
|
-
|
|
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;
|
|
449
391
|
}
|
|
450
|
-
if (rows.length < DERIVED_ROWS)
|
|
451
|
-
return reached(true);
|
|
452
392
|
}
|
|
393
|
+
connection.run('UPDATE replica_keys SET rederiving = ? WHERE key = ?', [read ? null : last, key]);
|
|
394
|
+
return { done: read, text: built };
|
|
453
395
|
}
|
|
454
396
|
function heldEntry(row) {
|
|
455
397
|
return {
|
|
@@ -461,15 +403,45 @@ function heldEntry(row) {
|
|
|
461
403
|
change: json(row.change),
|
|
462
404
|
written: text(row.written),
|
|
463
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) ?? [],
|
|
464
417
|
};
|
|
465
418
|
}
|
|
466
|
-
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
|
+
}
|
|
467
423
|
function viewed(view, alias) {
|
|
468
424
|
if (view === 'visible')
|
|
469
425
|
return `${alias}.visible = 1 AND ${alias}.present = 1`;
|
|
470
426
|
if (view === 'confirmed')
|
|
471
427
|
return `${alias}.layer = ${CONFIRMED}`;
|
|
472
|
-
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
|
+
]);
|
|
473
445
|
}
|
|
474
446
|
export function entries(connection, key, view, list) {
|
|
475
447
|
if (list.length === 0)
|
|
@@ -489,61 +461,21 @@ export function typed(connection, key, view, list) {
|
|
|
489
461
|
binary: number(row.binary) === 1,
|
|
490
462
|
}));
|
|
491
463
|
}
|
|
492
|
-
export function referrers(connection, key, view, targets
|
|
464
|
+
export function referrers(connection, key, view, targets) {
|
|
493
465
|
if (targets.length === 0)
|
|
494
466
|
return [];
|
|
495
467
|
return connection
|
|
496
|
-
.rows(`SELECT DISTINCT e.path, l.target
|
|
497
|
-
.map((row) => ({
|
|
498
|
-
path: text(row.path),
|
|
499
|
-
target: text(row.target),
|
|
500
|
-
kind: text(row.kind),
|
|
501
|
-
}));
|
|
502
|
-
}
|
|
503
|
-
export function walk(connection, key, view, after, bytes) {
|
|
504
|
-
const found = [];
|
|
505
|
-
let spent = 0;
|
|
506
|
-
let from = after;
|
|
507
|
-
for (;;) {
|
|
508
|
-
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]);
|
|
509
|
-
for (const row of rows) {
|
|
510
|
-
const entry = heldEntry(row);
|
|
511
|
-
found.push(entry);
|
|
512
|
-
spent += 256 + (entry.content?.length ?? 0) * 2;
|
|
513
|
-
if (spent >= bytes)
|
|
514
|
-
return { entries: found, next: entry.path };
|
|
515
|
-
}
|
|
516
|
-
if (rows.length < 64)
|
|
517
|
-
return { entries: found, next: null };
|
|
518
|
-
from = found.at(-1).path;
|
|
519
|
-
}
|
|
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) }));
|
|
520
470
|
}
|
|
521
471
|
export function files(connection, key, view, after, limit) {
|
|
522
|
-
return connection
|
|
523
|
-
|
|
524
|
-
|
|
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);
|
|
525
476
|
}
|
|
526
477
|
export function typedWithin(connection, key, view, roots, within) {
|
|
527
|
-
|
|
528
|
-
const bind = [key];
|
|
529
|
-
for (const root of roots)
|
|
530
|
-
bind.push(root, `${root}/`, `${root}0`);
|
|
531
|
-
const placed = roots.length === 0 ? (within ? ' AND 0' : '') : ` AND ${within ? '' : 'NOT '}(${inside})`;
|
|
532
|
-
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);
|
|
533
|
-
}
|
|
534
|
-
export function transferPart(connection, locator, token) {
|
|
535
|
-
const [held] = connection.rows('SELECT part FROM replica_transfer_parts WHERE locator = ? AND token = ?', [locator, token]);
|
|
536
|
-
return held?.part instanceof Uint8Array ? held.part : null;
|
|
537
|
-
}
|
|
538
|
-
export function keepParts(connection, parts) {
|
|
539
|
-
for (const { locator, token, part } of parts) {
|
|
540
|
-
connection.run('DELETE FROM replica_transfer_parts WHERE locator = ? AND token = ?', [
|
|
541
|
-
locator,
|
|
542
|
-
token,
|
|
543
|
-
]);
|
|
544
|
-
connection.run('INSERT INTO replica_transfer_parts (locator, token, part) SELECT ?, ?, ? WHERE EXISTS (SELECT 1 FROM replica_transfers WHERE locator = ?)', [locator, token, part, locator]);
|
|
545
|
-
}
|
|
546
|
-
return null;
|
|
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);
|
|
547
479
|
}
|
|
548
480
|
export function opened(connection) {
|
|
549
481
|
const facts = {};
|
|
@@ -551,31 +483,18 @@ export function opened(connection) {
|
|
|
551
483
|
facts[text(row.name)] = text(row.value);
|
|
552
484
|
}
|
|
553
485
|
return {
|
|
554
|
-
rooms: connection.rows(
|
|
486
|
+
rooms: connection.rows(HELD_RECORDS).map((row) => ({
|
|
555
487
|
locator: text(row.locator),
|
|
556
488
|
key: number(row.key),
|
|
557
489
|
record: text(row.record),
|
|
558
490
|
})),
|
|
559
|
-
transfers: connection.rows('SELECT locator, key, record FROM replica_transfers').map((row) => ({
|
|
560
|
-
locator: text(row.locator),
|
|
561
|
-
key: number(row.key),
|
|
562
|
-
record: text(row.record),
|
|
563
|
-
})),
|
|
564
|
-
kept: connection
|
|
565
|
-
.rows('SELECT locator, token, length(part) AS bytes FROM replica_transfer_parts')
|
|
566
|
-
.map((row) => ({
|
|
567
|
-
locator: text(row.locator),
|
|
568
|
-
token: text(row.token),
|
|
569
|
-
bytes: number(row.bytes),
|
|
570
|
-
})),
|
|
571
491
|
keys: connection
|
|
572
|
-
.rows('SELECT key, locator, transfer, rederiving
|
|
492
|
+
.rows('SELECT key, locator, transfer, rederiving FROM replica_keys')
|
|
573
493
|
.map((row) => ({
|
|
574
494
|
key: number(row.key),
|
|
575
495
|
locator: text(row.locator),
|
|
576
496
|
transfer: text(row.transfer),
|
|
577
497
|
rederiving: cursor(row.rederiving),
|
|
578
|
-
searching: cursor(row.searching),
|
|
579
498
|
})),
|
|
580
499
|
facts,
|
|
581
500
|
presentation: connection.rows('SELECT app, value FROM replica_presentation').map((row) => ({
|
|
@@ -588,7 +507,6 @@ export function opened(connection) {
|
|
|
588
507
|
orphans: connection
|
|
589
508
|
.rows(`SELECT k.key FROM replica_keys k
|
|
590
509
|
WHERE NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
591
|
-
AND NOT EXISTS (SELECT 1 FROM replica_transfers t WHERE t.key = k.key)
|
|
592
510
|
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`)
|
|
593
511
|
.map((row) => number(row.key)),
|
|
594
512
|
erasing: connection.rows('SELECT key, locator FROM replica_erasing').map((row) => ({
|
|
@@ -603,5 +521,4 @@ export function ended(connection) {
|
|
|
603
521
|
if (table !== undefined)
|
|
604
522
|
connection.run(`DELETE FROM ${table}`);
|
|
605
523
|
}
|
|
606
|
-
unindexAll(connection);
|
|
607
524
|
}
|