@agentshouse/mdruntime 0.1.0-c1ffd2bc60355 → 0.1.0-c20970f71a6a9
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 +89 -53
- 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 +10 -13
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +100 -89
- package/dist/client.d.ts +8 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +52 -6
- package/dist/collection.d.ts +5 -3
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +24 -19
- package/dist/compile.d.ts +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +113 -45
- package/dist/connection.d.ts +8 -7
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1311 -1067
- package/dist/conversation.d.ts +15 -14
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +222 -140
- package/dist/durability.d.ts +0 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +1 -0
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +2 -1
- 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 -6
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +12 -19
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- 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 +10 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +178 -90
- 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 +6 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +7 -10
- 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 -5
- 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/phrase.d.ts +3 -0
- package/dist/phrase.d.ts.map +1 -0
- package/dist/phrase.js +8 -0
- package/dist/query.d.ts +10 -0
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +20 -1
- package/dist/reach.d.ts +10 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +53 -29
- package/dist/react.d.ts +1 -0
- 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 +47 -11
- package/dist/replica.d.ts +3 -5
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +7 -7
- package/dist/room-draft.d.ts +18 -3
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +94 -47
- package/dist/rows.d.ts +17 -7
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +120 -87
- package/dist/save.d.ts +2 -0
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +11 -5
- 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 +30 -37
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +61 -66
- package/dist/stored.d.ts +41 -24
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +196 -214
- package/dist/tables.d.ts +48 -49
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +23 -62
- 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 +35 -96
- package/dist/wire.d.ts +9 -8
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +3 -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/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,30 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { derived } from './rows.js';
|
|
1
|
+
import { composedOf } from './collection.js';
|
|
2
|
+
import { described, derived } from './rows.js';
|
|
3
3
|
export const REPLICA_TABLES = [
|
|
4
|
-
'CREATE TABLE replica_keys (key INTEGER PRIMARY KEY AUTOINCREMENT, locator TEXT NOT NULL, transfer TEXT NOT NULL,
|
|
4
|
+
'CREATE TABLE replica_keys (key INTEGER PRIMARY KEY AUTOINCREMENT, locator TEXT NOT NULL, transfer TEXT NOT NULL, fingerprint TEXT NOT NULL, rederiving INTEGER)',
|
|
5
5
|
'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_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
|
-
'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)',
|
|
6
|
+
'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, outline TEXT)',
|
|
10
7
|
'CREATE UNIQUE INDEX replica_entries_path ON replica_entries (key, layer, path)',
|
|
11
|
-
'CREATE INDEX replica_entries_visible ON replica_entries (key, visible, path)',
|
|
8
|
+
'CREATE INDEX replica_entries_visible ON replica_entries (key, visible, present, path, binary)',
|
|
12
9
|
'CREATE INDEX replica_entries_folder ON replica_entries (key, folder, path)',
|
|
13
|
-
'CREATE
|
|
14
|
-
'CREATE INDEX
|
|
15
|
-
'CREATE TABLE
|
|
16
|
-
'CREATE
|
|
10
|
+
'CREATE INDEX replica_entries_type ON replica_entries (key, type, visible, present, queried, folder)',
|
|
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
|
-
'CREATE TABLE
|
|
20
|
-
'CREATE TABLE replica_received_parts (key TEXT NOT NULL, part INTEGER NOT NULL, value TEXT NOT NULL, PRIMARY KEY (key, part)) WITHOUT ROWID',
|
|
17
|
+
'CREATE TABLE replica_opened (locator TEXT NOT NULL, path TEXT NOT NULL, PRIMARY KEY (locator, path)) WITHOUT ROWID',
|
|
21
18
|
'CREATE TABLE replica_facts (name TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',
|
|
22
19
|
'CREATE TABLE replica_presentation (app TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',
|
|
23
20
|
];
|
|
24
21
|
const CONFIRMED = 0;
|
|
25
22
|
const OVERLAY = 1;
|
|
26
23
|
const REFRESHED = 2;
|
|
27
|
-
const
|
|
24
|
+
const DERIVED_ROWS = 64;
|
|
25
|
+
const ENTRY_WEIGHT = 256;
|
|
26
|
+
const ABSENT = {
|
|
27
|
+
type: null,
|
|
28
|
+
declared: null,
|
|
29
|
+
queried: false,
|
|
30
|
+
folder: '',
|
|
31
|
+
fields: null,
|
|
32
|
+
values: [],
|
|
33
|
+
links: [],
|
|
34
|
+
};
|
|
28
35
|
function text(value) {
|
|
29
36
|
return typeof value === 'string' ? value : null;
|
|
30
37
|
}
|
|
@@ -40,55 +47,29 @@ function flag(value) {
|
|
|
40
47
|
function paths(list) {
|
|
41
48
|
return JSON.stringify(list);
|
|
42
49
|
}
|
|
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
50
|
function dropDerived(connection, doc) {
|
|
72
51
|
connection.run('DELETE FROM replica_values WHERE doc = ?', [doc]);
|
|
73
52
|
connection.run('DELETE FROM replica_links WHERE doc = ?', [doc]);
|
|
74
53
|
}
|
|
54
|
+
function scalarText(value) {
|
|
55
|
+
if (value === Infinity)
|
|
56
|
+
return 'Infinity';
|
|
57
|
+
if (value === -Infinity)
|
|
58
|
+
return '-Infinity';
|
|
59
|
+
return JSON.stringify(value);
|
|
60
|
+
}
|
|
75
61
|
function writeDerived(connection, doc, key, made) {
|
|
76
|
-
|
|
77
|
-
|
|
62
|
+
if (made.values.length > 0) {
|
|
63
|
+
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)}]`);
|
|
64
|
+
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(',')}]`]);
|
|
65
|
+
}
|
|
66
|
+
if (made.links.length > 0) {
|
|
67
|
+
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
68
|
doc,
|
|
79
69
|
key,
|
|
80
|
-
|
|
81
|
-
value.held,
|
|
82
|
-
value.item,
|
|
83
|
-
value.kind,
|
|
84
|
-
value.value,
|
|
85
|
-
value.size,
|
|
86
|
-
flag(value.single),
|
|
70
|
+
JSON.stringify(made.links.map((link) => [link.kind, link.keys, link.places, link.target, link.field])),
|
|
87
71
|
]);
|
|
88
72
|
}
|
|
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
73
|
}
|
|
93
74
|
function entryId(connection, key, layer, path) {
|
|
94
75
|
const [row] = connection.rows('SELECT id FROM replica_entries WHERE key = ? AND layer = ? AND path = ?', [key, layer, path]);
|
|
@@ -99,26 +80,10 @@ function removeEntry(connection, key, layer, path) {
|
|
|
99
80
|
if (id === null)
|
|
100
81
|
return;
|
|
101
82
|
dropDerived(connection, id);
|
|
102
|
-
unindexDocuments(connection, [id]);
|
|
103
83
|
connection.run('DELETE FROM replica_entries WHERE id = ?', [id]);
|
|
104
84
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
function putEntry(connection, key, layer, entry, present, composition, searched = true) {
|
|
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
|
-
};
|
|
121
|
-
connection.run('INSERT INTO replica_entries (key, layer, path, visible, present, queried, content, binary, revision, file_id, change, written, type, declared, folder, fields) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
85
|
+
function insertEntry(connection, key, layer, entry, present, made) {
|
|
86
|
+
connection.run('INSERT INTO replica_entries (key, layer, path, visible, present, queried, content, outline, binary, revision, file_id, change, written, type, declared, folder, fields) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
|
122
87
|
key,
|
|
123
88
|
layer,
|
|
124
89
|
entry.path,
|
|
@@ -126,6 +91,7 @@ function putEntry(connection, key, layer, entry, present, composition, searched
|
|
|
126
91
|
flag(present),
|
|
127
92
|
flag(made.queried),
|
|
128
93
|
entry.binary === null ? entry.content : null,
|
|
94
|
+
entry.binary === null && entry.outline !== null ? JSON.stringify(entry.outline) : null,
|
|
129
95
|
entry.binary === null ? null : JSON.stringify(entry.binary),
|
|
130
96
|
entry.revision,
|
|
131
97
|
entry.fileId,
|
|
@@ -136,80 +102,66 @@ function putEntry(connection, key, layer, entry, present, composition, searched
|
|
|
136
102
|
made.folder,
|
|
137
103
|
made.fields,
|
|
138
104
|
]);
|
|
105
|
+
}
|
|
106
|
+
function textOf(entry) {
|
|
107
|
+
return entry.binary === null ? entry.content : null;
|
|
108
|
+
}
|
|
109
|
+
function putEntry(connection, key, layer, entry, present, composition) {
|
|
110
|
+
removeEntry(connection, key, layer, entry.path);
|
|
111
|
+
const content = textOf(entry);
|
|
112
|
+
const made = present ? derived(entry.path, content, entry.outline, composition) : ABSENT;
|
|
113
|
+
insertEntry(connection, key, layer, entry, present, made);
|
|
139
114
|
if (!present)
|
|
140
115
|
return;
|
|
141
116
|
const id = entryId(connection, key, layer, entry.path);
|
|
142
117
|
writeDerived(connection, id, key, made);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
118
|
+
}
|
|
119
|
+
function placeEntry(connection, key, entry) {
|
|
120
|
+
removeEntry(connection, key, CONFIRMED, entry.path);
|
|
121
|
+
insertEntry(connection, key, CONFIRMED, entry, true, described(entry.path, textOf(entry), entry.outline));
|
|
146
122
|
}
|
|
147
123
|
function revealed(connection, key, touched) {
|
|
148
124
|
if (touched.length === 0)
|
|
149
125
|
return;
|
|
150
126
|
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
127
|
}
|
|
152
|
-
function newKey(connection, locator, transfer,
|
|
153
|
-
|
|
128
|
+
function newKey(connection, locator, transfer, fingerprint, built) {
|
|
129
|
+
const owed = built ? null : 0;
|
|
130
|
+
connection.run('INSERT INTO replica_keys (locator, transfer, fingerprint, rederiving) VALUES (?, ?, ?, ?)', [locator, transfer, fingerprint, owed]);
|
|
154
131
|
const [row] = connection.rows('SELECT last_insert_rowid() AS key');
|
|
155
132
|
return number(row.key);
|
|
156
133
|
}
|
|
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
|
-
]);
|
|
134
|
+
function recomposed(connection, key, fingerprint) {
|
|
135
|
+
const [row] = connection.rows('SELECT fingerprint FROM replica_keys WHERE key = ?', [key]);
|
|
136
|
+
if (row === undefined || text(row.fingerprint) === fingerprint)
|
|
166
137
|
return;
|
|
167
|
-
|
|
168
|
-
connection.run(
|
|
169
|
-
JSON.stringify(composition),
|
|
170
|
-
key,
|
|
171
|
-
]);
|
|
138
|
+
const held = connection.rows('SELECT 1 FROM replica_entries WHERE key = ? LIMIT 1', [key]);
|
|
139
|
+
connection.run(`UPDATE replica_keys SET fingerprint = ?${held.length === 0 ? '' : ', rederiving = 0'} WHERE key = ?`, [fingerprint, key]);
|
|
172
140
|
}
|
|
173
141
|
export function entered(connection, locator, composition, rows) {
|
|
174
|
-
const key = newKey(connection, locator, '', composition);
|
|
142
|
+
const key = newKey(connection, locator, '', composedOf(composition).fingerprint, true);
|
|
175
143
|
for (const entry of rows)
|
|
176
|
-
putEntry(connection, key, CONFIRMED, entry, true, composition
|
|
144
|
+
putEntry(connection, key, CONFIRMED, entry, true, composition);
|
|
177
145
|
return key;
|
|
178
146
|
}
|
|
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
147
|
export function stage(connection, request) {
|
|
184
|
-
const [held] = connection.rows('SELECT key FROM replica_transfers WHERE locator = ?', [
|
|
185
|
-
request.locator,
|
|
186
|
-
]);
|
|
187
148
|
const key = request.key ??
|
|
188
|
-
(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (request.written !== undefined) {
|
|
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
|
-
}
|
|
149
|
+
newKey(connection, request.locator, request.transfer, request.fingerprint, false);
|
|
150
|
+
recomposed(connection, key, request.fingerprint);
|
|
151
|
+
connection.run('UPDATE replica_keys SET rederiving = coalesce(rederiving, last) FROM (SELECT coalesce(max(id), 0) AS last FROM replica_entries) WHERE key = ?', [key]);
|
|
152
|
+
for (const entry of request.entries)
|
|
153
|
+
placeEntry(connection, key, entry);
|
|
203
154
|
for (const path of request.folders) {
|
|
204
155
|
connection.run('INSERT OR REPLACE INTO replica_folders (key, layer, path, present) VALUES (?, ?, ?, 1)', [key, CONFIRMED, path]);
|
|
205
156
|
}
|
|
206
157
|
return key;
|
|
207
158
|
}
|
|
208
159
|
export function refreshing(connection, request) {
|
|
209
|
-
const held = connection.rows('SELECT 1 FROM
|
|
160
|
+
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
161
|
if (held.length === 0)
|
|
211
162
|
return null;
|
|
212
|
-
|
|
163
|
+
recomposed(connection, request.key, request.composed.fingerprint);
|
|
164
|
+
const composition = request.composed.composition;
|
|
213
165
|
for (const entry of request.entries) {
|
|
214
166
|
putEntry(connection, request.key, REFRESHED, entry, true, composition);
|
|
215
167
|
}
|
|
@@ -217,6 +169,7 @@ export function refreshing(connection, request) {
|
|
|
217
169
|
putEntry(connection, request.key, REFRESHED, {
|
|
218
170
|
path,
|
|
219
171
|
content: null,
|
|
172
|
+
outline: null,
|
|
220
173
|
binary: null,
|
|
221
174
|
revision: null,
|
|
222
175
|
fileId: null,
|
|
@@ -235,7 +188,6 @@ export function refreshing(connection, request) {
|
|
|
235
188
|
return null;
|
|
236
189
|
}
|
|
237
190
|
function dropLayer(connection, key, layer) {
|
|
238
|
-
unindexDocuments(connection, heldIds(connection, 'SELECT id FROM replica_entries WHERE key = ? AND layer = ?', [key, layer]));
|
|
239
191
|
for (const table of ['replica_values', 'replica_links']) {
|
|
240
192
|
connection.run(`DELETE FROM ${table} WHERE doc IN (SELECT id FROM replica_entries WHERE key = ? AND layer = ?)`, [key, layer]);
|
|
241
193
|
}
|
|
@@ -254,7 +206,6 @@ function refreshedPaths(connection, key) {
|
|
|
254
206
|
function applyRefresh(connection, key) {
|
|
255
207
|
const touched = refreshedPaths(connection, key);
|
|
256
208
|
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}`;
|
|
257
|
-
unindexDocuments(connection, heldIds(connection, replaced, [key]));
|
|
258
209
|
for (const table of ['replica_values', 'replica_links']) {
|
|
259
210
|
connection.run(`DELETE FROM ${table} WHERE doc IN (${replaced})`, [key]);
|
|
260
211
|
}
|
|
@@ -273,12 +224,11 @@ function applyRefresh(connection, key) {
|
|
|
273
224
|
connection.run('DELETE FROM replica_folders WHERE key = ? AND layer = ?', [key, REFRESHED]);
|
|
274
225
|
return touched;
|
|
275
226
|
}
|
|
227
|
+
function beneathRoots(path) {
|
|
228
|
+
return `EXISTS (SELECT 1 FROM json_each(?) r WHERE ${path} = r.value OR (${path} >= r.value || '/' AND ${path} < r.value || '0'))`;
|
|
229
|
+
}
|
|
276
230
|
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);
|
|
231
|
+
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
232
|
return number(row.held);
|
|
283
233
|
}
|
|
284
234
|
export function counts(connection, rooms) {
|
|
@@ -292,14 +242,12 @@ function erasing(connection, key, locator) {
|
|
|
292
242
|
}
|
|
293
243
|
function commitRoom(connection, room) {
|
|
294
244
|
const touched = new Set();
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
dropTransfer(connection, room.locator);
|
|
245
|
+
recomposed(connection, room.key, room.composed.fingerprint);
|
|
246
|
+
const composition = room.composed.composition;
|
|
247
|
+
if (room.published !== undefined &&
|
|
248
|
+
room.published.from !== null &&
|
|
249
|
+
room.published.from !== room.key) {
|
|
250
|
+
erasing(connection, room.published.from, room.locator);
|
|
303
251
|
}
|
|
304
252
|
if (room.refreshed === true) {
|
|
305
253
|
for (const path of applyRefresh(connection, room.key))
|
|
@@ -353,27 +301,25 @@ function rootsOf(connection, locator) {
|
|
|
353
301
|
}
|
|
354
302
|
export function fenceRooms(connection, locators) {
|
|
355
303
|
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 = ?
|
|
304
|
+
for (const row of connection.rows('SELECT key FROM replica_keys WHERE locator = ? UNION SELECT key FROM replica_rooms WHERE locator = ?', [locator, locator])) {
|
|
357
305
|
erasing(connection, number(row.key), locator);
|
|
358
306
|
}
|
|
359
307
|
connection.run('DELETE FROM replica_rooms WHERE locator = ?', [locator]);
|
|
360
|
-
|
|
308
|
+
connection.run('DELETE FROM replica_opened WHERE locator = ?', [locator]);
|
|
361
309
|
}
|
|
362
310
|
return null;
|
|
363
311
|
}
|
|
364
|
-
export function abandon(connection, locator
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return number(held.key);
|
|
312
|
+
export function abandon(connection, locator) {
|
|
313
|
+
for (const row of connection.rows(`SELECT k.key FROM replica_keys k WHERE k.locator = ?
|
|
314
|
+
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)
|
|
315
|
+
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`, [locator])) {
|
|
316
|
+
erasing(connection, number(row.key), locator);
|
|
317
|
+
}
|
|
318
|
+
return null;
|
|
372
319
|
}
|
|
373
320
|
export function release(connection, key) {
|
|
374
321
|
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]);
|
|
322
|
+
AND NOT EXISTS (SELECT 1 FROM replica_rooms r WHERE r.key = k.key)`, [key]);
|
|
377
323
|
if (held !== undefined)
|
|
378
324
|
erasing(connection, key, text(held.locator));
|
|
379
325
|
return null;
|
|
@@ -384,7 +330,6 @@ export function erase(connection, locator, limit) {
|
|
|
384
330
|
return { remaining: false };
|
|
385
331
|
const key = number(held.key);
|
|
386
332
|
const batch = 'SELECT id FROM replica_entries WHERE key = ? ORDER BY id LIMIT ?';
|
|
387
|
-
unindexDocuments(connection, heldIds(connection, batch, [key, limit]));
|
|
388
333
|
for (const table of ['replica_values', 'replica_links']) {
|
|
389
334
|
connection.run(`DELETE FROM ${table} WHERE doc IN (${batch})`, [key, limit]);
|
|
390
335
|
}
|
|
@@ -398,33 +343,92 @@ export function erase(connection, locator, limit) {
|
|
|
398
343
|
const [more] = connection.rows(`SELECT 1 FROM replica_erasing${locator === null ? '' : ' WHERE locator = ?'} LIMIT 1`, locator === null ? [] : [locator]);
|
|
399
344
|
return { remaining: more !== undefined };
|
|
400
345
|
}
|
|
401
|
-
|
|
346
|
+
function cursor(value) {
|
|
347
|
+
return value === null || value === undefined ? null : number(value);
|
|
348
|
+
}
|
|
349
|
+
export function rederive(connection, key, composed, bytes, ms, floor) {
|
|
350
|
+
const started = performance.now();
|
|
351
|
+
recomposed(connection, key, composed.fingerprint);
|
|
402
352
|
const [held] = connection.rows('SELECT rederiving FROM replica_keys WHERE key = ?', [key]);
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const composition =
|
|
407
|
-
|
|
353
|
+
const deriving = cursor(held?.rederiving);
|
|
354
|
+
if (deriving === null)
|
|
355
|
+
return { done: true, text: 0 };
|
|
356
|
+
const composition = composed.composition;
|
|
357
|
+
let last = deriving;
|
|
358
|
+
let spent = 0;
|
|
359
|
+
let built = 0;
|
|
360
|
+
let read = false;
|
|
361
|
+
reading: for (;;) {
|
|
362
|
+
const rows = connection.rows('SELECT id, path, content, outline FROM replica_entries WHERE key = ? AND present = 1 AND id > ? ORDER BY id LIMIT ?', [key, last, DERIVED_ROWS]);
|
|
363
|
+
for (const row of rows) {
|
|
364
|
+
const id = number(row.id);
|
|
365
|
+
const path = text(row.path);
|
|
366
|
+
const content = text(row.content);
|
|
367
|
+
const made = derived(path, content, json(row.outline), composition);
|
|
368
|
+
dropDerived(connection, id);
|
|
369
|
+
writeDerived(connection, id, key, made);
|
|
370
|
+
built += content?.length ?? 0;
|
|
371
|
+
last = id;
|
|
372
|
+
spent += ENTRY_WEIGHT + (content?.length ?? 0);
|
|
373
|
+
if (spent >= bytes || (spent >= floor && performance.now() - started >= ms))
|
|
374
|
+
break reading;
|
|
375
|
+
}
|
|
376
|
+
if (rows.length < DERIVED_ROWS) {
|
|
377
|
+
read = true;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
connection.run('UPDATE replica_keys SET rederiving = ? WHERE key = ?', [read ? null : last, key]);
|
|
382
|
+
return { done: read, text: built };
|
|
383
|
+
}
|
|
384
|
+
function outlinedAgain(connection, row, key, content, composition) {
|
|
385
|
+
const id = number(row.id);
|
|
386
|
+
const path = text(row.path);
|
|
387
|
+
const made = derived(path, content, json(row.outline), composition);
|
|
388
|
+
connection.run('UPDATE replica_entries SET content = ?, type = ?, declared = ?, queried = ?, folder = ?, fields = ? WHERE id = ?', [content, made.type, made.declared, flag(made.queried), made.folder, made.fields, id]);
|
|
389
|
+
dropDerived(connection, id);
|
|
390
|
+
writeDerived(connection, id, key, made);
|
|
391
|
+
}
|
|
392
|
+
export function holdTexts(connection, request) {
|
|
393
|
+
const held = [];
|
|
394
|
+
for (const { path, revision, content } of request.texts) {
|
|
395
|
+
const [row] = connection.rows(`SELECT id, path, outline FROM replica_entries WHERE key = ? AND layer = ${CONFIRMED} AND path = ? AND revision = ? AND content IS NULL AND outline IS NOT NULL`, [request.key, path, revision]);
|
|
396
|
+
if (row === undefined)
|
|
397
|
+
continue;
|
|
398
|
+
outlinedAgain(connection, row, request.key, content, request.composed.composition);
|
|
399
|
+
connection.run('INSERT OR IGNORE INTO replica_opened (locator, path) VALUES (?, ?)', [
|
|
400
|
+
request.locator,
|
|
401
|
+
path,
|
|
402
|
+
]);
|
|
403
|
+
held.push(path);
|
|
404
|
+
}
|
|
405
|
+
return held;
|
|
406
|
+
}
|
|
407
|
+
export function unholdTexts(connection, request) {
|
|
408
|
+
connection.run('DELETE FROM replica_opened WHERE locator = ?', [request.locator]);
|
|
409
|
+
const rows = connection.rows(`SELECT id, path, outline, octet_length(content) AS bytes FROM replica_entries WHERE key = ? AND layer = ${CONFIRMED} AND visible = 1 AND content IS NOT NULL AND outline IS NOT NULL`, [request.key]);
|
|
408
410
|
for (const row of rows) {
|
|
409
|
-
|
|
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);
|
|
411
|
+
outlinedAgain(connection, row, request.key, null, request.composed.composition);
|
|
415
412
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
413
|
+
return {
|
|
414
|
+
paths: rows.map((row) => text(row.path)),
|
|
415
|
+
bytes: rows.reduce((total, row) => total + number(row.bytes), 0),
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
export function remembered(connection, request) {
|
|
419
|
+
connection.run(`INSERT OR IGNORE INTO replica_opened (locator, path) SELECT ?, path FROM replica_entries WHERE key = ? AND layer = ${CONFIRMED} AND content IS NOT NULL AND binary IS NULL AND path IN (SELECT value FROM json_each(?))`, [request.locator, request.key, paths(request.paths)]);
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
export function wanted(connection, request) {
|
|
423
|
+
return connection
|
|
424
|
+
.rows(`SELECT e.path, e.revision FROM replica_opened o JOIN replica_entries e ON e.key = ? AND e.layer = ${CONFIRMED} AND e.path = o.path WHERE o.locator = ? AND e.content IS NULL AND e.outline IS NOT NULL AND e.revision IS NOT NULL`, [request.key, request.locator])
|
|
425
|
+
.map((row) => ({ path: text(row.path), revision: text(row.revision) }));
|
|
423
426
|
}
|
|
424
427
|
function heldEntry(row) {
|
|
425
428
|
return {
|
|
426
429
|
path: text(row.path),
|
|
427
430
|
content: text(row.content),
|
|
431
|
+
outline: json(row.outline),
|
|
428
432
|
binary: json(row.binary),
|
|
429
433
|
revision: text(row.revision),
|
|
430
434
|
fileId: text(row.file_id),
|
|
@@ -433,13 +437,32 @@ function heldEntry(row) {
|
|
|
433
437
|
type: text(row.type),
|
|
434
438
|
};
|
|
435
439
|
}
|
|
436
|
-
const ENTRY_COLUMNS = 'e.path, e.content, e.binary, e.revision, e.file_id, e.change, e.written, e.type';
|
|
440
|
+
const ENTRY_COLUMNS = 'e.path, e.content, e.outline, e.binary, e.revision, e.file_id, e.change, e.written, e.type';
|
|
441
|
+
function unrefreshed(alias) {
|
|
442
|
+
return `NOT EXISTS (SELECT 1 FROM replica_entries r WHERE r.key = ${alias}.key AND r.layer = ${REFRESHED} AND r.path = ${alias}.path)`;
|
|
443
|
+
}
|
|
437
444
|
function viewed(view, alias) {
|
|
438
445
|
if (view === 'visible')
|
|
439
446
|
return `${alias}.visible = 1 AND ${alias}.present = 1`;
|
|
440
447
|
if (view === 'confirmed')
|
|
441
448
|
return `${alias}.layer = ${CONFIRMED}`;
|
|
442
|
-
return `${alias}.present = 1 AND (${alias}.layer = ${REFRESHED} OR (${alias}.layer = ${CONFIRMED} AND
|
|
449
|
+
return `${alias}.present = 1 AND (${alias}.layer = ${REFRESHED} OR (${alias}.layer = ${CONFIRMED} AND ${unrefreshed(alias)}))`;
|
|
450
|
+
}
|
|
451
|
+
function layers(view) {
|
|
452
|
+
if (view !== 'refreshed')
|
|
453
|
+
return [viewed(view, 'e')];
|
|
454
|
+
return [
|
|
455
|
+
`e.layer = ${REFRESHED} AND e.present = 1`,
|
|
456
|
+
`e.layer = ${CONFIRMED} AND e.present = 1 AND ${unrefreshed('e')}`,
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
function pathOrdered(connection, columns, key, view, condition, after, limit) {
|
|
460
|
+
const beyond = after === null ? '' : ' AND e.path > ?';
|
|
461
|
+
const parts = layers(view).map((layer) => `SELECT ${columns} FROM replica_entries e WHERE e.key = ? AND ${layer}${condition}${beyond}`);
|
|
462
|
+
return connection.rows(`${parts.join(' UNION ALL ')} ORDER BY path LIMIT ?`, [
|
|
463
|
+
...parts.flatMap(() => (after === null ? [key] : [key, after])),
|
|
464
|
+
limit,
|
|
465
|
+
]);
|
|
443
466
|
}
|
|
444
467
|
export function entries(connection, key, view, list) {
|
|
445
468
|
if (list.length === 0)
|
|
@@ -470,48 +493,14 @@ export function referrers(connection, key, view, targets, kinds) {
|
|
|
470
493
|
kind: text(row.kind),
|
|
471
494
|
}));
|
|
472
495
|
}
|
|
473
|
-
export function walk(connection, key, view, after, bytes) {
|
|
474
|
-
const found = [];
|
|
475
|
-
let spent = 0;
|
|
476
|
-
let from = after;
|
|
477
|
-
for (;;) {
|
|
478
|
-
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]);
|
|
479
|
-
for (const row of rows) {
|
|
480
|
-
const entry = heldEntry(row);
|
|
481
|
-
found.push(entry);
|
|
482
|
-
spent += 256 + (entry.content?.length ?? 0) * 2;
|
|
483
|
-
if (spent >= bytes)
|
|
484
|
-
return { entries: found, next: entry.path };
|
|
485
|
-
}
|
|
486
|
-
if (rows.length < 64)
|
|
487
|
-
return { entries: found, next: null };
|
|
488
|
-
from = found.at(-1).path;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
496
|
export function files(connection, key, view, after, limit) {
|
|
492
|
-
return connection
|
|
493
|
-
|
|
494
|
-
|
|
497
|
+
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) }));
|
|
498
|
+
}
|
|
499
|
+
export function folders(connection, key, view, list) {
|
|
500
|
+
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
501
|
}
|
|
496
502
|
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;
|
|
503
|
+
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
504
|
}
|
|
516
505
|
export function opened(connection) {
|
|
517
506
|
const facts = {};
|
|
@@ -524,18 +513,13 @@ export function opened(connection) {
|
|
|
524
513
|
key: number(row.key),
|
|
525
514
|
record: text(row.record),
|
|
526
515
|
})),
|
|
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
516
|
keys: connection
|
|
533
517
|
.rows('SELECT key, locator, transfer, rederiving FROM replica_keys')
|
|
534
518
|
.map((row) => ({
|
|
535
519
|
key: number(row.key),
|
|
536
520
|
locator: text(row.locator),
|
|
537
521
|
transfer: text(row.transfer),
|
|
538
|
-
rederiving:
|
|
522
|
+
rederiving: cursor(row.rederiving),
|
|
539
523
|
})),
|
|
540
524
|
facts,
|
|
541
525
|
presentation: connection.rows('SELECT app, value FROM replica_presentation').map((row) => ({
|
|
@@ -548,7 +532,6 @@ export function opened(connection) {
|
|
|
548
532
|
orphans: connection
|
|
549
533
|
.rows(`SELECT k.key FROM replica_keys k
|
|
550
534
|
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
535
|
AND NOT EXISTS (SELECT 1 FROM replica_erasing e WHERE e.key = k.key)`)
|
|
553
536
|
.map((row) => number(row.key)),
|
|
554
537
|
erasing: connection.rows('SELECT key, locator FROM replica_erasing').map((row) => ({
|
|
@@ -563,5 +546,4 @@ export function ended(connection) {
|
|
|
563
546
|
if (table !== undefined)
|
|
564
547
|
connection.run(`DELETE FROM ${table}`);
|
|
565
548
|
}
|
|
566
|
-
unindexAll(connection);
|
|
567
549
|
}
|