@agentshouse/mdruntime 0.1.0-c5fe3b2cddda7 → 0.1.0-c6197367d5fad

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.
Files changed (332) hide show
  1. package/README.md +21 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +156 -89
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +3 -11
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +20 -60
  16. package/dist/authored.d.ts +88 -0
  17. package/dist/authored.d.ts.map +1 -0
  18. package/dist/authored.js +345 -0
  19. package/dist/bootstrap.d.ts +9 -5
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +204 -85
  22. package/dist/cell.d.ts +6 -0
  23. package/dist/cell.d.ts.map +1 -0
  24. package/dist/cell.js +9 -0
  25. package/dist/chain.d.ts +2 -1
  26. package/dist/chain.d.ts.map +1 -1
  27. package/dist/change-set.d.ts +4 -0
  28. package/dist/change-set.d.ts.map +1 -1
  29. package/dist/change-set.js +6 -0
  30. package/dist/change.d.ts +5 -0
  31. package/dist/change.d.ts.map +1 -1
  32. package/dist/change.js +7 -2
  33. package/dist/chat-types.d.ts +3 -0
  34. package/dist/chat-types.d.ts.map +1 -0
  35. package/dist/chat-types.js +11 -0
  36. package/dist/client.d.ts +33 -23
  37. package/dist/client.d.ts.map +1 -1
  38. package/dist/client.js +43 -56
  39. package/dist/collection.d.ts +26 -4
  40. package/dist/collection.d.ts.map +1 -1
  41. package/dist/collection.js +19 -2
  42. package/dist/column.d.ts +5 -0
  43. package/dist/column.d.ts.map +1 -0
  44. package/dist/column.js +9 -0
  45. package/dist/compile.d.ts +8 -6
  46. package/dist/compile.d.ts.map +1 -1
  47. package/dist/compile.js +286 -336
  48. package/dist/connection.d.ts +5 -142
  49. package/dist/connection.d.ts.map +1 -1
  50. package/dist/connection.js +111 -4993
  51. package/dist/context.d.ts +2 -0
  52. package/dist/context.d.ts.map +1 -0
  53. package/dist/context.js +7 -0
  54. package/dist/conversation-live.d.ts +150 -0
  55. package/dist/conversation-live.d.ts.map +1 -0
  56. package/dist/conversation-live.js +259 -0
  57. package/dist/conversation-row.d.ts +40 -0
  58. package/dist/conversation-row.d.ts.map +1 -0
  59. package/dist/conversation-row.js +66 -0
  60. package/dist/conversation.d.ts +72 -51
  61. package/dist/conversation.d.ts.map +1 -1
  62. package/dist/conversation.js +1001 -926
  63. package/dist/declaration.d.ts +10 -0
  64. package/dist/declaration.d.ts.map +1 -0
  65. package/dist/declaration.js +24 -0
  66. package/dist/discovery.d.ts +11 -0
  67. package/dist/discovery.d.ts.map +1 -0
  68. package/dist/discovery.js +157 -0
  69. package/dist/download.d.ts +6 -0
  70. package/dist/download.d.ts.map +1 -0
  71. package/dist/download.js +42 -0
  72. package/dist/durability.d.ts +20 -0
  73. package/dist/durability.d.ts.map +1 -1
  74. package/dist/durability.js +7 -0
  75. package/dist/entry.d.ts +2 -2
  76. package/dist/entry.d.ts.map +1 -1
  77. package/dist/entry.js +18 -8
  78. package/dist/expectation.d.ts +26 -13
  79. package/dist/expectation.d.ts.map +1 -1
  80. package/dist/expectation.js +72 -19
  81. package/dist/failure.d.ts +3 -0
  82. package/dist/failure.d.ts.map +1 -1
  83. package/dist/failure.js +6 -0
  84. package/dist/figures.d.ts +49 -0
  85. package/dist/figures.d.ts.map +1 -0
  86. package/dist/figures.js +199 -0
  87. package/dist/file.d.ts +1 -1
  88. package/dist/file.d.ts.map +1 -1
  89. package/dist/file.js +3 -2
  90. package/dist/holdings.d.ts +29 -0
  91. package/dist/holdings.d.ts.map +1 -0
  92. package/dist/holdings.js +95 -0
  93. package/dist/host.d.ts +21 -7
  94. package/dist/host.d.ts.map +1 -1
  95. package/dist/host.js +83 -41
  96. package/dist/identity.d.ts +0 -1
  97. package/dist/identity.d.ts.map +1 -1
  98. package/dist/identity.js +0 -3
  99. package/dist/index.d.ts +37 -14
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +17 -5
  102. package/dist/install.d.ts +60 -0
  103. package/dist/install.d.ts.map +1 -0
  104. package/dist/install.js +537 -0
  105. package/dist/lifecycle.d.ts +7 -0
  106. package/dist/lifecycle.d.ts.map +1 -0
  107. package/dist/lifecycle.js +282 -0
  108. package/dist/listing.d.ts +52 -0
  109. package/dist/listing.d.ts.map +1 -0
  110. package/dist/listing.js +152 -0
  111. package/dist/live.d.ts +9 -6
  112. package/dist/live.d.ts.map +1 -1
  113. package/dist/live.js +118 -36
  114. package/dist/loaded.d.ts +5 -0
  115. package/dist/loaded.d.ts.map +1 -0
  116. package/dist/loaded.js +40 -0
  117. package/dist/locks.d.ts +7 -0
  118. package/dist/locks.d.ts.map +1 -0
  119. package/dist/locks.js +32 -0
  120. package/dist/lost.d.ts +5 -0
  121. package/dist/lost.d.ts.map +1 -0
  122. package/dist/lost.js +49 -0
  123. package/dist/media.d.ts +19 -2
  124. package/dist/media.d.ts.map +1 -1
  125. package/dist/media.js +105 -27
  126. package/dist/memory.d.ts +18 -6
  127. package/dist/memory.d.ts.map +1 -1
  128. package/dist/memory.js +214 -91
  129. package/dist/messages.d.ts +35 -5
  130. package/dist/messages.d.ts.map +1 -1
  131. package/dist/messages.js +109 -39
  132. package/dist/model.d.ts +2 -10
  133. package/dist/model.d.ts.map +1 -1
  134. package/dist/model.js +0 -14
  135. package/dist/models.d.ts +10 -0
  136. package/dist/models.d.ts.map +1 -0
  137. package/dist/models.js +153 -0
  138. package/dist/observation.d.ts +28 -13
  139. package/dist/observation.d.ts.map +1 -1
  140. package/dist/observation.js +185 -81
  141. package/dist/opened.d.ts +1 -1
  142. package/dist/opened.d.ts.map +1 -1
  143. package/dist/opened.js +5 -5
  144. package/dist/opening.d.ts +4 -0
  145. package/dist/opening.d.ts.map +1 -0
  146. package/dist/opening.js +53 -0
  147. package/dist/outcome.d.ts +17 -2
  148. package/dist/outcome.d.ts.map +1 -1
  149. package/dist/outcome.js +35 -2
  150. package/dist/overlay.d.ts +7 -2
  151. package/dist/overlay.d.ts.map +1 -1
  152. package/dist/overlay.js +48 -24
  153. package/dist/page-metadata.d.ts +8 -0
  154. package/dist/page-metadata.d.ts.map +1 -0
  155. package/dist/page-metadata.js +19 -0
  156. package/dist/parts.d.ts +4 -0
  157. package/dist/parts.d.ts.map +1 -0
  158. package/dist/parts.js +13 -0
  159. package/dist/paths.d.ts +1 -0
  160. package/dist/paths.d.ts.map +1 -1
  161. package/dist/paths.js +22 -0
  162. package/dist/preparation.d.ts +41 -0
  163. package/dist/preparation.d.ts.map +1 -0
  164. package/dist/preparation.js +314 -0
  165. package/dist/presence.d.ts +58 -0
  166. package/dist/presence.d.ts.map +1 -0
  167. package/dist/presence.js +231 -0
  168. package/dist/queries.d.ts +16 -0
  169. package/dist/queries.d.ts.map +1 -0
  170. package/dist/queries.js +308 -0
  171. package/dist/query.d.ts +14 -210
  172. package/dist/query.d.ts.map +1 -1
  173. package/dist/query.js +3 -505
  174. package/dist/questions.d.ts +30 -0
  175. package/dist/questions.d.ts.map +1 -0
  176. package/dist/questions.js +116 -0
  177. package/dist/queue.d.ts +40 -0
  178. package/dist/queue.d.ts.map +1 -0
  179. package/dist/queue.js +480 -0
  180. package/dist/reach.d.ts +16 -15
  181. package/dist/reach.d.ts.map +1 -1
  182. package/dist/reach.js +257 -148
  183. package/dist/react.d.ts +19 -3
  184. package/dist/react.d.ts.map +1 -1
  185. package/dist/react.js +33 -1
  186. package/dist/read.d.ts +7 -0
  187. package/dist/read.d.ts.map +1 -0
  188. package/dist/read.js +17 -0
  189. package/dist/readiness.d.ts +9 -6
  190. package/dist/readiness.d.ts.map +1 -1
  191. package/dist/readiness.js +3 -5
  192. package/dist/reads.d.ts +39 -0
  193. package/dist/reads.d.ts.map +1 -0
  194. package/dist/reads.js +178 -0
  195. package/dist/recovery.d.ts +3 -1
  196. package/dist/recovery.d.ts.map +1 -1
  197. package/dist/recovery.js +38 -8
  198. package/dist/refresh.d.ts +2 -1
  199. package/dist/refresh.d.ts.map +1 -1
  200. package/dist/refresh.js +31 -3
  201. package/dist/refusal.d.ts +5 -0
  202. package/dist/refusal.d.ts.map +1 -0
  203. package/dist/refusal.js +55 -0
  204. package/dist/replica.d.ts +11 -16
  205. package/dist/replica.d.ts.map +1 -1
  206. package/dist/replica.js +66 -32
  207. package/dist/retried.d.ts +30 -0
  208. package/dist/retried.d.ts.map +1 -0
  209. package/dist/retried.js +72 -0
  210. package/dist/room-draft.d.ts +34 -10
  211. package/dist/room-draft.d.ts.map +1 -1
  212. package/dist/room-draft.js +331 -111
  213. package/dist/room-drafts.d.ts +24 -0
  214. package/dist/room-drafts.d.ts.map +1 -0
  215. package/dist/room-drafts.js +220 -0
  216. package/dist/room-list.d.ts +10 -0
  217. package/dist/room-list.d.ts.map +1 -0
  218. package/dist/room-list.js +45 -0
  219. package/dist/rows.d.ts +16 -22
  220. package/dist/rows.d.ts.map +1 -1
  221. package/dist/rows.js +49 -186
  222. package/dist/runtime.d.ts +34 -0
  223. package/dist/runtime.d.ts.map +1 -0
  224. package/dist/runtime.js +1 -0
  225. package/dist/save.d.ts +42 -86
  226. package/dist/save.d.ts.map +1 -1
  227. package/dist/save.js +332 -228
  228. package/dist/saves.d.ts +34 -0
  229. package/dist/saves.d.ts.map +1 -0
  230. package/dist/saves.js +437 -0
  231. package/dist/search.d.ts +12 -63
  232. package/dist/search.d.ts.map +1 -1
  233. package/dist/search.js +9 -52
  234. package/dist/seed.d.ts +11 -2
  235. package/dist/seed.d.ts.map +1 -1
  236. package/dist/seed.js +71 -1
  237. package/dist/shared.d.ts +1 -6
  238. package/dist/shared.d.ts.map +1 -1
  239. package/dist/shared.js +13 -95
  240. package/dist/shown.d.ts +35 -0
  241. package/dist/shown.d.ts.map +1 -0
  242. package/dist/shown.js +313 -0
  243. package/dist/socket/admission.d.ts +7 -0
  244. package/dist/socket/admission.d.ts.map +1 -0
  245. package/dist/socket/admission.js +39 -0
  246. package/dist/socket/answers.d.ts +6 -0
  247. package/dist/socket/answers.d.ts.map +1 -0
  248. package/dist/socket/answers.js +20 -0
  249. package/dist/socket/lanes.d.ts +28 -0
  250. package/dist/socket/lanes.d.ts.map +1 -0
  251. package/dist/socket/lanes.js +103 -0
  252. package/dist/socket/reads.d.ts +10 -0
  253. package/dist/socket/reads.d.ts.map +1 -0
  254. package/dist/socket/reads.js +31 -0
  255. package/dist/socket/session.d.ts +38 -0
  256. package/dist/socket/session.d.ts.map +1 -0
  257. package/dist/socket/session.js +23 -0
  258. package/dist/socket.d.ts +67 -0
  259. package/dist/socket.d.ts.map +1 -0
  260. package/dist/socket.js +164 -0
  261. package/dist/source.d.ts +59 -0
  262. package/dist/source.d.ts.map +1 -0
  263. package/dist/source.js +93 -0
  264. package/dist/status.d.ts +0 -2
  265. package/dist/status.d.ts.map +1 -1
  266. package/dist/status.js +0 -6
  267. package/dist/store/installs.d.ts +30 -0
  268. package/dist/store/installs.d.ts.map +1 -0
  269. package/dist/store/installs.js +40 -0
  270. package/dist/store/readiness.d.ts +11 -0
  271. package/dist/store/readiness.d.ts.map +1 -0
  272. package/dist/store/readiness.js +68 -0
  273. package/dist/store/records.d.ts +224 -0
  274. package/dist/store/records.d.ts.map +1 -0
  275. package/dist/store/records.js +466 -0
  276. package/dist/store/room-held.d.ts +8 -0
  277. package/dist/store/room-held.d.ts.map +1 -0
  278. package/dist/store/room-held.js +17 -0
  279. package/dist/store/rooms-shown.d.ts +8 -0
  280. package/dist/store/rooms-shown.d.ts.map +1 -0
  281. package/dist/store/rooms-shown.js +13 -0
  282. package/dist/store/space.d.ts +11 -0
  283. package/dist/store/space.d.ts.map +1 -0
  284. package/dist/store/space.js +41 -0
  285. package/dist/store/watchers.d.ts +17 -0
  286. package/dist/store/watchers.d.ts.map +1 -0
  287. package/dist/store/watchers.js +56 -0
  288. package/dist/store/writes.d.ts +24 -0
  289. package/dist/store/writes.d.ts.map +1 -0
  290. package/dist/store/writes.js +125 -0
  291. package/dist/store.d.ts +115 -143
  292. package/dist/store.d.ts.map +1 -1
  293. package/dist/store.js +171 -364
  294. package/dist/stored.d.ts +72 -35
  295. package/dist/stored.d.ts.map +1 -1
  296. package/dist/stored.js +337 -197
  297. package/dist/surface.d.ts +92 -0
  298. package/dist/surface.d.ts.map +1 -0
  299. package/dist/surface.js +251 -0
  300. package/dist/sync.d.ts +19 -0
  301. package/dist/sync.d.ts.map +1 -0
  302. package/dist/sync.js +538 -0
  303. package/dist/tables.d.ts +118 -67
  304. package/dist/tables.d.ts.map +1 -1
  305. package/dist/tables.js +199 -278
  306. package/dist/tallies.d.ts +18 -0
  307. package/dist/tallies.d.ts.map +1 -0
  308. package/dist/tallies.js +128 -0
  309. package/dist/validation.d.ts.map +1 -1
  310. package/dist/validation.js +9 -12
  311. package/dist/windows.d.ts +1 -12
  312. package/dist/windows.d.ts.map +1 -1
  313. package/dist/windows.js +2 -75
  314. package/dist/wire.d.ts +72 -9
  315. package/dist/wire.d.ts.map +1 -1
  316. package/dist/wire.js +26 -5
  317. package/package.json +3 -2
  318. package/dist/attempt.d.ts +0 -16
  319. package/dist/attempt.d.ts.map +0 -1
  320. package/dist/attempt.js +0 -70
  321. package/dist/fence.d.ts +0 -6
  322. package/dist/fence.d.ts.map +0 -1
  323. package/dist/fence.js +0 -10
  324. package/dist/fulltext.d.ts +0 -27
  325. package/dist/fulltext.d.ts.map +0 -1
  326. package/dist/fulltext.js +0 -370
  327. package/dist/log.d.ts +0 -5
  328. package/dist/log.d.ts.map +0 -1
  329. package/dist/log.js +0 -14
  330. package/dist/words.d.ts +0 -19
  331. package/dist/words.d.ts.map +0 -1
  332. package/dist/words.js +0 -156
package/dist/tables.js CHANGED
@@ -1,11 +1,20 @@
1
+ import { sql } from '@agentshouse/mdmodel';
1
2
  import { answerQuery } from './compile.js';
2
- import { searched, SEARCH_TABLES } from './fulltext.js';
3
- import { droppedMessages, forgottenMessages, heldConversations, keptMessages, messageCount, messageWindow, MESSAGE_TABLES, turnArrived, } from './messages.js';
4
- import { abandon, release, commit, counts, ended, entries, erase, fenceRooms, files, folders, opened, rederive, referrers, refreshing, REPLICA_TABLES, stage, typed, typedWithin, unrefresh, } from './stored.js';
3
+ import { amended, authoredLocators, authoredPart, call, callRecords, chatDraft, chatDraftConversations, chatDraftRecord, chatDraftRecords, chatDraftsDropped, claim, fact, fenced, fencedWork, fences, FILE_PART_BYTES, authoredEmptied, heldOrder, kept, moving, pendingBatch, pendingState, queuedLocators, queueOf, queues, remember, roomDraft, roomDraftRecords, spooled, unfenced, unsent, unsentStatus, } from './authored.js';
4
+ import { count, text, texts } from './column.js';
5
+ import { conversationFacts, conversationRows, forgottenConversations, heldConversations, keptFact, keptMessages, messageCount, messageWindow, MESSAGE_TABLES, turnArrived, } from './messages.js';
6
+ import { keptRead, READ_TABLES, readsOfOtherBuildsForgotten, storedRead, } from './reads.js';
7
+ import { conversationTallies, roomTallies, } from './tallies.js';
8
+ import { abandon, release, commit, covering, demoted, ended, entries, erase, facts, fenceRooms, folders, heldLocators, heldRoom, heldRooms, offlineMode, opened, overlaid, presentation, rederive, referrers, refreshing, REPLICA_TABLES, resume, stage, typed, stagedLocators, tablesOf, typedWithin, unrefresh, } from './stored.js';
9
+ export { authoredEmptied, authoredTable, FILE_PART_BYTES, formatted, heldTables, } from './authored.js';
5
10
  const STATEMENTS_HELD = 256;
6
11
  export function sqliteConnection(engine, database) {
7
12
  const decoder = new TextDecoder();
8
13
  const held = new Map();
14
+ database.createFunction(sql.HOLDS_PHRASE, sql.holdsPhrase, {
15
+ arity: 2,
16
+ deterministic: true,
17
+ });
9
18
  function prepared(sql) {
10
19
  if (sql.includes(';'))
11
20
  return null;
@@ -65,59 +74,58 @@ export function sqliteConnection(engine, database) {
65
74
  },
66
75
  };
67
76
  }
68
- export const FILE_PART_BYTES = 1_048_576;
69
77
  const PROBE_BYTES = 4 * FILE_PART_BYTES;
70
- const TABLES = [
71
- ['authored_facts', 'name TEXT PRIMARY KEY, value TEXT NOT NULL'],
72
- ['authored_queues', 'locator TEXT PRIMARY KEY, ids TEXT NOT NULL'],
73
- [
74
- 'authored_pending',
75
- 'locator TEXT NOT NULL, id TEXT NOT NULL, batch TEXT NOT NULL, state TEXT NOT NULL, files TEXT NOT NULL, PRIMARY KEY (locator, id)',
76
- ],
77
- [
78
- 'authored_room_drafts',
79
- 'locator TEXT NOT NULL, path TEXT NOT NULL, record TEXT NOT NULL, files TEXT NOT NULL, PRIMARY KEY (locator, path)',
80
- ],
81
- ['authored_chat_drafts', 'conversation TEXT PRIMARY KEY, record TEXT NOT NULL'],
82
- ['authored_calls', 'operation TEXT PRIMARY KEY, record TEXT NOT NULL, files TEXT NOT NULL'],
83
- ['authored_fences', 'locator TEXT PRIMARY KEY'],
84
- ];
85
78
  export const RUNTIME_TABLES = [
86
- ...TABLES.map(([name, columns]) => `CREATE TABLE ${name} (${columns}) WITHOUT ROWID`),
87
- 'CREATE TABLE file_parts (key TEXT NOT NULL, part INTEGER NOT NULL, bytes BLOB NOT NULL, PRIMARY KEY (key, part))',
88
79
  'CREATE TABLE opened_files (key TEXT PRIMARY KEY, locator TEXT NOT NULL, path TEXT NOT NULL, revision TEXT NOT NULL, media_type TEXT NOT NULL, sha256 TEXT, byte_length INTEGER) WITHOUT ROWID',
89
80
  'CREATE INDEX opened_files_name ON opened_files (locator, path, revision)',
81
+ 'CREATE TABLE opened_parts (key TEXT NOT NULL, part INTEGER NOT NULL, bytes BLOB NOT NULL, PRIMARY KEY (key, part))',
90
82
  ...REPLICA_TABLES,
91
83
  ...MESSAGE_TABLES,
92
- ...SEARCH_TABLES,
84
+ ...READ_TABLES,
93
85
  ];
94
- const OWNERS = ['authored_pending', 'authored_room_drafts', 'authored_calls'];
95
- const AUTHORED_KEYS = OWNERS.map((table) => `SELECT value FROM ${table}, json_each(${table}.files)`).join(' UNION ');
96
- const UNOWNED_PARTS = `DELETE FROM file_parts WHERE key NOT IN (${AUTHORED_KEYS} UNION SELECT key FROM opened_files)`;
86
+ const UNOPENED_PARTS = 'DELETE FROM opened_parts WHERE key NOT IN (SELECT key FROM opened_files)';
97
87
  const READS = new Set([
98
- 'authored.queues',
88
+ 'authored.status',
89
+ 'authored.moving',
90
+ 'authored.pending',
91
+ 'authored.batch',
92
+ 'authored.order',
93
+ 'authored.queued',
99
94
  'authored.roomDrafts',
95
+ 'authored.chatDraft.read',
100
96
  'authored.chatDrafts',
101
97
  'authored.calls',
102
98
  'authored.fences',
99
+ 'authored.unsent',
103
100
  'authored.fact',
104
101
  'authored.file',
105
102
  'replica.open',
103
+ 'replica.rooms',
104
+ 'replica.room',
105
+ 'replica.covering',
106
+ 'replica.offline',
107
+ 'replica.held',
108
+ 'replica.facts',
109
+ 'replica.presentation',
106
110
  'replica.query',
111
+ 'replica.tallies',
107
112
  'replica.entries',
108
113
  'replica.typed',
109
114
  'replica.referrers',
110
- 'replica.files',
111
115
  'replica.folders',
112
116
  'replica.typedWithin',
113
- 'replica.counts',
114
- 'replica.search',
115
117
  'opened.find',
118
+ 'opened.held',
116
119
  'file.part',
117
120
  'conversation.held',
118
121
  'conversation.window',
119
122
  'conversation.count',
120
123
  'conversation.turn',
124
+ 'conversation.rows',
125
+ 'conversation.tallies',
126
+ 'conversation.facts',
127
+ 'conversation.stored',
128
+ 'read.stored',
121
129
  ]);
122
130
  const KINDS = new Set([
123
131
  ...READS,
@@ -129,14 +137,17 @@ const KINDS = new Set([
129
137
  'authored.claim',
130
138
  'authored.end',
131
139
  'replica.stage',
140
+ 'replica.resume',
132
141
  'replica.refresh',
133
142
  'replica.unrefresh',
134
143
  'replica.commit',
135
144
  'replica.fence',
136
145
  'replica.erase',
137
146
  'replica.abandon',
147
+ 'replica.unfence',
138
148
  'replica.release',
139
149
  'replica.rederive',
150
+ 'replica.demote',
140
151
  'replica.fact',
141
152
  'replica.present',
142
153
  'opened.begin',
@@ -145,8 +156,11 @@ const KINDS = new Set([
145
156
  'opened.drop',
146
157
  'opened.clean',
147
158
  'conversation.keep',
159
+ 'conversation.fact',
148
160
  'conversation.drop',
149
161
  'space.probe',
162
+ 'read.keep',
163
+ 'read.builds',
150
164
  ]);
151
165
  export function isRuntime(request) {
152
166
  return KINDS.has(request.kind);
@@ -154,236 +168,75 @@ export function isRuntime(request) {
154
168
  export function readsRuntime(request) {
155
169
  return READS.has(request.kind);
156
170
  }
157
- function text(value) {
158
- return typeof value === 'string' ? value : String(value);
159
- }
160
- function texts(rows, column) {
161
- return rows.map((row) => text(row[column]));
162
- }
163
- function owned(files) {
164
- return JSON.stringify([...new Set(files)]);
165
- }
166
- function fact(connection, name) {
167
- const [held] = connection.rows('SELECT value FROM authored_facts WHERE name = ?', [name]);
168
- return held === undefined ? null : text(held.value);
169
- }
170
- function remember(connection, name, value) {
171
- connection.run('INSERT OR REPLACE INTO authored_facts (name, value) VALUES (?, ?)', [
172
- name,
173
- value,
174
- ]);
175
- return null;
176
- }
177
- function fenced(connection, locator) {
178
- return connection.rows('SELECT 1 FROM authored_fences WHERE locator = ?', [locator]).length > 0;
179
- }
180
- function stored(connection, key) {
181
- return connection.rows('SELECT 1 FROM file_parts WHERE key = ? LIMIT 1', [key]).length > 0;
182
- }
183
- function storedPart(connection, key, part, bytes) {
184
- connection.run('INSERT INTO file_parts (key, part, bytes) VALUES (?, ?, ?)', [key, part, bytes]);
185
- }
186
- async function storedFiles(connection, files) {
187
- for (const { key, blob } of files) {
188
- if (stored(connection, key))
189
- continue;
190
- for (let at = 0, part = 0; at < blob.size; at += FILE_PART_BYTES, part += 1) {
191
- const bytes = new Uint8Array(await blob.slice(at, at + FILE_PART_BYTES).arrayBuffer());
192
- storedPart(connection, key, part, bytes);
193
- }
194
- }
195
- }
196
- function filePart(connection, key, part) {
197
- const [held] = connection.rows('SELECT bytes FROM file_parts WHERE key = ? AND part = ?', [
198
- key,
199
- part,
200
- ]);
201
- return held?.bytes instanceof Uint8Array ? held.bytes : null;
202
- }
203
- function* fileParts(connection, key) {
204
- for (let part = 0;; part += 1) {
205
- const bytes = filePart(connection, key, part);
206
- if (bytes === null)
207
- return;
208
- yield bytes;
209
- }
210
- }
211
- async function spooled(connection, spool, { key, type }) {
212
- for (const held of [...spool.held()]) {
213
- if (held !== key && !stored(connection, held))
214
- await spool.drop(held);
215
- }
216
- return spool.spool(key, type, fileParts(connection, key));
217
- }
218
- function unowned(connection) {
219
- connection.run(UNOWNED_PARTS);
220
- }
221
- function queued(connection) {
171
+ function heldWork(connection, locator) {
172
+ const room = heldRoom(connection, locator);
222
173
  return {
223
- queues: connection.rows('SELECT locator, ids FROM authored_queues').map((row) => ({
224
- locator: text(row.locator),
225
- ids: JSON.parse(text(row.ids)),
226
- })),
227
- pending: connection
228
- .rows('SELECT locator, id, batch, state FROM authored_pending')
229
- .map((row) => ({
230
- locator: text(row.locator),
231
- id: text(row.id),
232
- batch: text(row.batch),
233
- state: text(row.state),
234
- })),
174
+ room: room === null ? null : { ...room, overlaid: overlaid(connection, room.key) },
175
+ queue: queueOf(connection, locator),
235
176
  };
236
177
  }
237
- function heldOrder(connection, locator) {
238
- const [held] = connection.rows('SELECT ids FROM authored_queues WHERE locator = ?', [locator]);
239
- return held === undefined ? [] : JSON.parse(text(held.ids));
240
- }
241
- function keptRows(connection, { locator, order, added, founded, roomDrafts, consumedRoomDrafts }) {
242
- for (const path of consumedRoomDrafts ?? []) {
243
- connection.run('DELETE FROM authored_room_drafts WHERE locator = ? AND path = ?', [
244
- locator,
245
- path,
246
- ]);
247
- }
248
- for (const { path, record, files } of roomDrafts ?? []) {
249
- connection.run('INSERT OR REPLACE INTO authored_room_drafts (locator, path, record, files) VALUES (?, ?, ?, ?)', [locator, path, record, owned(files)]);
250
- }
251
- if (order === undefined)
252
- return;
253
- const before = new Set(heldOrder(connection, locator));
254
- const after = new Set(order);
255
- if (after.size === 0)
256
- connection.run('DELETE FROM authored_queues WHERE locator = ?', [locator]);
257
- else {
258
- connection.run('INSERT OR REPLACE INTO authored_queues (locator, ids) VALUES (?, ?)', [
259
- locator,
260
- JSON.stringify([...after]),
261
- ]);
262
- }
263
- for (const id of before) {
264
- if (!after.has(id)) {
265
- connection.run('DELETE FROM authored_pending WHERE locator = ? AND id = ?', [locator, id]);
266
- }
267
- }
268
- for (const { id, batch, state, files } of added ?? []) {
269
- if (before.has(id) || !after.has(id))
270
- continue;
271
- connection.run('INSERT OR REPLACE INTO authored_pending (locator, id, batch, state, files) VALUES (?, ?, ?, ?, ?)', [locator, id, batch, state, owned(files)]);
272
- }
273
- for (const { id, batch, files } of founded ?? []) {
274
- const [held] = connection.rows('SELECT files FROM authored_pending WHERE locator = ? AND id = ?', [locator, id]);
275
- if (held === undefined || !before.has(id))
276
- continue;
277
- connection.run('UPDATE authored_pending SET batch = ?, files = ? WHERE locator = ? AND id = ?', [batch, owned([...JSON.parse(text(held.files)), ...files]), locator, id]);
278
- }
279
- }
280
- async function kept(connection, { writes, files, whole, discards }) {
281
- const refused = writes.find(({ locator }) => fenced(connection, locator));
282
- if (refused !== undefined && whole)
283
- return refused.locator;
284
- await storedFiles(connection, files);
285
- for (const write of writes) {
286
- if (!fenced(connection, write.locator))
287
- keptRows(connection, write);
288
- }
289
- for (const locator of discards ?? [])
290
- roomWork(connection, locator);
291
- unowned(connection);
292
- return refused?.locator ?? null;
178
+ function status(connection) {
179
+ return {
180
+ ...unsentStatus(connection),
181
+ lastCompleted: facts(connection, ['lastCompleted']).lastCompleted ?? null,
182
+ };
293
183
  }
294
- function amended(connection, { locator, id, amendment }) {
295
- if (fenced(connection, locator))
296
- return null;
297
- const [held] = connection.rows('SELECT state FROM authored_pending WHERE locator = ? AND id = ?', [locator, id]);
298
- if (held === undefined)
299
- return null;
300
- connection.run('UPDATE authored_pending SET state = ? WHERE locator = ? AND id = ?', [
301
- JSON.stringify({
302
- ...JSON.parse(text(held.state)),
303
- ...JSON.parse(amendment),
304
- }),
305
- locator,
306
- id,
307
- ]);
308
- return null;
184
+ function pendingOf(connection, locator, id) {
185
+ return {
186
+ state: pendingState(connection, locator, id),
187
+ room: connection.rows('SELECT 1 FROM replica_rooms WHERE locator = ?', [locator]).length > 0,
188
+ };
309
189
  }
310
- async function roomDraft(connection, { locator, path, kept: draft, files }) {
311
- if (fenced(connection, locator))
312
- return locator;
313
- await storedFiles(connection, files);
314
- if (draft === null) {
315
- connection.run('DELETE FROM authored_room_drafts WHERE locator = ? AND path = ?', [
316
- locator,
317
- path,
190
+ function storedConversations(connection, conversations) {
191
+ const named = conversations === null ? '' : ' WHERE conversation IN (SELECT value FROM json_each(?))';
192
+ const bound = conversations === null ? [] : [JSON.stringify(conversations)];
193
+ return [
194
+ ...new Set([
195
+ ...tablesOf(MESSAGE_TABLES).flatMap((table) => texts(connection.rows(`SELECT DISTINCT conversation FROM ${table}${named}`, bound), 'conversation')),
196
+ ...chatDraftConversations(connection, conversations),
197
+ ]),
198
+ ];
199
+ }
200
+ function droppedConversations(connection, conversations) {
201
+ const held = storedConversations(connection, conversations);
202
+ for (const table of tablesOf(MESSAGE_TABLES)) {
203
+ connection.run(`DELETE FROM ${table} WHERE conversation IN (SELECT value FROM json_each(?))`, [
204
+ JSON.stringify(conversations),
318
205
  ]);
319
206
  }
320
- else {
321
- connection.run('INSERT OR REPLACE INTO authored_room_drafts (locator, path, record, files) VALUES (?, ?, ?, ?)', [locator, path, draft.record, owned(draft.files)]);
322
- }
323
- unowned(connection);
324
- return null;
207
+ chatDraftsDropped(connection, conversations);
208
+ return held;
325
209
  }
326
- function chatDraft(connection, { kept: drafts, dropped }) {
327
- for (const conversation of dropped) {
328
- connection.run('DELETE FROM authored_chat_drafts WHERE conversation = ?', [conversation]);
329
- }
330
- for (const { conversation, record } of drafts) {
331
- connection.run('INSERT OR REPLACE INTO authored_chat_drafts (conversation, record) VALUES (?, ?)', [conversation, record]);
332
- }
333
- return null;
334
- }
335
- async function call(connection, { operation, kept: held, files }) {
336
- await storedFiles(connection, files);
337
- if (held === null)
338
- connection.run('DELETE FROM authored_calls WHERE operation = ?', [operation]);
339
- else {
340
- connection.run('INSERT OR REPLACE INTO authored_calls (operation, record, files) VALUES (?, ?, ?)', [operation, held.record, owned(held.files)]);
341
- }
342
- unowned(connection);
343
- return null;
344
- }
345
- function roomWork(connection, locator) {
346
- connection.run('DELETE FROM authored_queues WHERE locator = ?', [locator]);
347
- connection.run('DELETE FROM authored_pending WHERE locator = ?', [locator]);
210
+ function unopened(connection) {
211
+ connection.run(UNOPENED_PARTS);
348
212
  }
349
213
  function fence(connection, locators) {
214
+ fencedWork(connection, locators);
350
215
  for (const locator of locators) {
351
- connection.run('INSERT OR REPLACE INTO authored_fences (locator) VALUES (?)', [locator]);
352
- roomWork(connection, locator);
353
- connection.run('DELETE FROM authored_room_drafts WHERE locator = ?', [locator]);
354
216
  connection.run('DELETE FROM opened_files WHERE locator = ?', [locator]);
355
217
  }
356
- unowned(connection);
218
+ unopened(connection);
357
219
  return fenceRooms(connection, locators);
358
220
  }
359
221
  function erased(connection, { locator, limit }) {
360
- const done = erase(connection, locator, limit);
361
- if (locator !== null && !done.remaining) {
362
- connection.run('DELETE FROM authored_fences WHERE locator = ?', [locator]);
363
- }
364
- return done;
222
+ return erase(connection, locator, limit);
365
223
  }
366
- function claim(connection, holder) {
367
- const held = fact(connection, 'holder');
368
- if (held !== null)
369
- return held === holder;
370
- remember(connection, 'holder', holder);
371
- return true;
224
+ function unfencedRooms(connection, locators) {
225
+ const erased = locators.filter((locator) => connection.rows('SELECT 1 FROM replica_erasing WHERE locator = ? LIMIT 1', [locator])
226
+ .length === 0);
227
+ unfenced(connection, erased);
228
+ return erased;
372
229
  }
373
230
  function end(connection, holder) {
374
231
  ended(connection);
375
- forgottenMessages(connection);
232
+ forgottenConversations(connection);
376
233
  if (holder !== null && claim(connection, holder))
377
234
  return true;
378
- for (const [table] of TABLES)
379
- connection.run(`DELETE FROM ${table}`);
235
+ authoredEmptied(connection);
380
236
  connection.run('DELETE FROM opened_files');
381
- connection.run('DELETE FROM file_parts');
237
+ connection.run('DELETE FROM opened_parts');
382
238
  return false;
383
239
  }
384
- function count(value) {
385
- return typeof value === 'bigint' ? Number(value) : typeof value === 'number' ? value : 0;
386
- }
387
240
  function openedFile(connection, { locator, path, revision }) {
388
241
  const [held] = connection.rows('SELECT key, media_type, byte_length FROM opened_files WHERE locator = ? AND path = ? AND revision = ? AND byte_length IS NOT NULL', [locator, path, revision]);
389
242
  return held === undefined
@@ -398,7 +251,7 @@ function opening(connection, { key, locator, path, revision, mediaType }) {
398
251
  if (fenced(connection, locator))
399
252
  return false;
400
253
  connection.run('DELETE FROM opened_files WHERE locator = ? AND path = ? AND revision = ? AND byte_length IS NULL', [locator, path, revision]);
401
- unowned(connection);
254
+ unopened(connection);
402
255
  connection.run('INSERT INTO opened_files (key, locator, path, revision, media_type) VALUES (?, ?, ?, ?, ?)', [key, locator, path, revision, mediaType]);
403
256
  return true;
404
257
  }
@@ -411,22 +264,26 @@ function fetching(connection, key) {
411
264
  function openedPart(connection, { key, part, bytes }) {
412
265
  if (fetching(connection, key) === null)
413
266
  return false;
414
- storedPart(connection, key, part, bytes);
267
+ connection.run('INSERT INTO opened_parts (key, part, bytes) VALUES (?, ?, ?)', [
268
+ key,
269
+ part,
270
+ bytes,
271
+ ]);
415
272
  return true;
416
273
  }
417
274
  function dropped(connection, key) {
418
275
  connection.run('DELETE FROM opened_files WHERE key = ?', [key]);
419
- connection.run('DELETE FROM file_parts WHERE key = ?', [key]);
276
+ connection.run('DELETE FROM opened_parts WHERE key = ?', [key]);
420
277
  return null;
421
278
  }
422
279
  function keptOpened(connection, { key, sha256, byteLength, parts }) {
423
280
  const fetched = fetching(connection, key);
424
281
  if (fetched === null)
425
282
  return false;
426
- const [held] = connection.rows('SELECT count(*) AS parts, min(part) AS first, max(part) AS last, coalesce(sum(length(bytes)), 0) AS bytes FROM file_parts WHERE key = ?', [key]);
427
- const whole = count(held?.parts) === parts &&
428
- count(held?.bytes) === byteLength &&
429
- (parts === 0 || (count(held?.first) === 0 && count(held?.last) === parts - 1));
283
+ const [held] = connection.rows('SELECT count(*) AS parts, min(part) AS first, max(part) AS last, coalesce(sum(length(bytes)), 0) AS bytes FROM opened_parts WHERE key = ?', [key]);
284
+ const whole = count(held.parts) === parts &&
285
+ count(held.bytes) === byteLength &&
286
+ (parts === 0 || (count(held.first) === 0 && count(held.last) === parts - 1));
430
287
  if (!whole) {
431
288
  dropped(connection, key);
432
289
  return false;
@@ -437,19 +294,38 @@ function keptOpened(connection, { key, sha256, byteLength, parts }) {
437
294
  key,
438
295
  ]);
439
296
  connection.run('DELETE FROM opened_files WHERE locator = ? AND path = ? AND revision = ? AND key <> ?', [fetched.locator, fetched.path, fetched.revision, key]);
440
- unowned(connection);
297
+ unopened(connection);
441
298
  return true;
442
299
  }
300
+ function heldPart(connection, key, part) {
301
+ const [held] = connection.rows('SELECT bytes FROM opened_parts WHERE key = ? AND part = ?', [
302
+ key,
303
+ part,
304
+ ]);
305
+ return held?.bytes instanceof Uint8Array ? held.bytes : authoredPart(connection, key, part);
306
+ }
307
+ function cleanable(connection) {
308
+ const [held] = connection.rows('SELECT coalesce(sum(length(bytes)), 0) AS bytes FROM opened_parts');
309
+ return count(held.bytes);
310
+ }
443
311
  function cleaned(connection) {
444
312
  connection.run('DELETE FROM opened_files');
445
- const [freed] = connection.rows(`SELECT coalesce(sum(length(bytes)), 0) AS bytes FROM file_parts WHERE key NOT IN (${AUTHORED_KEYS})`);
446
- unowned(connection);
447
- return count(freed?.bytes);
313
+ const freed = cleanable(connection);
314
+ unopened(connection);
315
+ return freed;
316
+ }
317
+ function openedHeld(connection) {
318
+ return {
319
+ rooms: connection
320
+ .rows('SELECT locator, count(*) AS files, sum(byte_length) AS bytes FROM opened_files WHERE byte_length IS NOT NULL GROUP BY locator ORDER BY locator')
321
+ .map((row) => ({ room: text(row.locator), count: count(row.files), size: count(row.bytes) })),
322
+ cleanable: cleanable(connection),
323
+ };
448
324
  }
449
325
  async function committed(connection, { authored, rooms }) {
450
326
  const refused = authored === undefined ? null : await kept(connection, authored);
451
327
  if (refused !== null && authored?.whole === true) {
452
- return { fenced: refused, counts: {}, changed: {}, indexed: {} };
328
+ return { fenced: refused, changed: {}, indexed: {} };
453
329
  }
454
330
  return {
455
331
  fenced: refused,
@@ -458,28 +334,42 @@ async function committed(connection, { authored, rooms }) {
458
334
  }
459
335
  export function answerRuntime(connection, request, spool) {
460
336
  switch (request.kind) {
461
- case 'authored.queues':
462
- return queued(connection);
337
+ case 'authored.status':
338
+ return status(connection);
339
+ case 'authored.moving':
340
+ return moving(connection);
341
+ case 'authored.pending':
342
+ return pendingOf(connection, request.locator, request.id);
343
+ case 'authored.batch':
344
+ return pendingBatch(connection, request.locator, request.id);
345
+ case 'authored.order':
346
+ return heldOrder(connection, request.locator);
347
+ case 'authored.queued':
348
+ return queuedLocators(connection);
463
349
  case 'authored.roomDrafts':
464
- return texts(connection.rows('SELECT record FROM authored_room_drafts'), 'record');
350
+ return roomDraftRecords(connection, request.locator, request.paths);
351
+ case 'authored.chatDraft.read':
352
+ return chatDraftRecord(connection, request.conversation);
465
353
  case 'authored.chatDrafts':
466
- return texts(connection.rows('SELECT record FROM authored_chat_drafts'), 'record');
354
+ return chatDraftRecords(connection);
467
355
  case 'authored.calls':
468
- return texts(connection.rows('SELECT record FROM authored_calls'), 'record');
356
+ return callRecords(connection);
469
357
  case 'authored.fences':
470
- return texts(connection.rows('SELECT locator FROM authored_fences'), 'locator');
358
+ return fences(connection);
359
+ case 'authored.unsent':
360
+ return unsent(connection);
471
361
  case 'authored.fact':
472
362
  return fact(connection, request.name);
473
363
  case 'authored.file':
474
- return spooled(connection, spool, request);
364
+ return spooled(connection, spool, request.key, request.type);
475
365
  case 'authored.amend':
476
- return amended(connection, request);
366
+ return amended(connection, request.locator, request.id, request.amendment);
477
367
  case 'authored.roomDraft':
478
- return roomDraft(connection, request);
368
+ return roomDraft(connection, request.locator, request.path, request.kept, request.files);
479
369
  case 'authored.chatDraft':
480
- return chatDraft(connection, request);
370
+ return chatDraft(connection, request.kept, request.dropped);
481
371
  case 'authored.call':
482
- return call(connection, request);
372
+ return call(connection, request.operation, request.kept, request.files);
483
373
  case 'authored.remember':
484
374
  return remember(connection, request.name, request.value);
485
375
  case 'authored.claim':
@@ -488,28 +378,43 @@ export function answerRuntime(connection, request, spool) {
488
378
  return end(connection, request.holder);
489
379
  case 'replica.open':
490
380
  return opened(connection);
381
+ case 'replica.rooms':
382
+ return heldRooms(connection, request.locators);
383
+ case 'replica.room':
384
+ return heldWork(connection, request.locator);
385
+ case 'replica.covering':
386
+ return { ...covering(connection, request.since), queues: queues(connection) };
387
+ case 'replica.offline':
388
+ return offlineMode(connection, request.locator);
389
+ case 'replica.held':
390
+ return {
391
+ held: [...new Set([...heldLocators(connection), ...authoredLocators(connection)])],
392
+ staged: stagedLocators(connection),
393
+ };
394
+ case 'replica.demote':
395
+ return demoted(connection);
396
+ case 'replica.facts':
397
+ return facts(connection, request.names);
398
+ case 'replica.presentation':
399
+ return presentation(connection, request.app);
491
400
  case 'replica.query':
492
401
  return answerQuery(connection, request.plan, request.rooms, request.budget);
402
+ case 'replica.tallies':
403
+ return roomTallies(connection, request.totals, request.rooms, request.since);
493
404
  case 'replica.entries':
494
405
  return entries(connection, request.key, request.view, request.paths);
495
406
  case 'replica.typed':
496
407
  return typed(connection, request.key, request.view, request.paths);
497
408
  case 'replica.referrers':
498
- return referrers(connection, request.key, request.view, request.targets, request.kinds);
499
- case 'replica.files':
500
- return files(connection, request.key, request.view, request.after, request.limit);
409
+ return referrers(connection, request.key, request.view, request.targets);
501
410
  case 'replica.folders':
502
- return folders(connection, request.key, request.view, request.paths);
411
+ return folders(connection, request.key, request.paths);
503
412
  case 'replica.typedWithin':
504
413
  return typedWithin(connection, request.key, request.view, request.roots, request.within);
505
- case 'replica.counts':
506
- return counts(connection, request.rooms);
507
- case 'replica.search': {
508
- const { kind: _kind, ...ask } = request;
509
- return searched(connection, ask);
510
- }
511
414
  case 'replica.stage':
512
415
  return fenced(connection, request.locator) ? null : stage(connection, request);
416
+ case 'replica.resume':
417
+ return fenced(connection, request.locator) ? null : resume(connection, request);
513
418
  case 'replica.refresh':
514
419
  return refreshing(connection, request);
515
420
  case 'replica.unrefresh':
@@ -522,6 +427,8 @@ export function answerRuntime(connection, request, spool) {
522
427
  return erased(connection, request);
523
428
  case 'replica.abandon':
524
429
  return abandon(connection, request.locator);
430
+ case 'replica.unfence':
431
+ return unfencedRooms(connection, request.locators);
525
432
  case 'replica.release':
526
433
  return release(connection, request.key);
527
434
  case 'replica.rederive':
@@ -550,29 +457,43 @@ export function answerRuntime(connection, request, spool) {
550
457
  return dropped(connection, request.key);
551
458
  case 'opened.clean':
552
459
  return cleaned(connection);
460
+ case 'opened.held':
461
+ return openedHeld(connection);
553
462
  case 'file.part':
554
- return filePart(connection, request.key, request.part);
463
+ return heldPart(connection, request.key, request.part);
555
464
  case 'conversation.held':
556
- return heldConversations(connection);
465
+ return heldConversations(connection, request.conversations);
557
466
  case 'conversation.keep': {
558
467
  const { kind: _kind, ...write } = request;
559
468
  return keptMessages(connection, write);
560
469
  }
561
470
  case 'conversation.window':
562
- return messageWindow(connection, request.conversation, request.limit, request.before);
471
+ return messageWindow(connection, request.conversation, request.limit, request.before, request.phrase);
563
472
  case 'conversation.count':
564
- return messageCount(connection, request.conversation);
473
+ return messageCount(connection, request.conversation, request.phrase);
565
474
  case 'conversation.turn':
566
475
  return turnArrived(connection, request.conversation, request.turn);
476
+ case 'conversation.rows':
477
+ return conversationRows(connection, request.conversations);
478
+ case 'conversation.tallies':
479
+ return conversationTallies(connection, request.conversations, request.since);
480
+ case 'conversation.facts':
481
+ return conversationFacts(connection);
482
+ case 'conversation.fact': {
483
+ const { kind: _kind, ...fact } = request;
484
+ return keptFact(connection, fact);
485
+ }
486
+ case 'conversation.stored':
487
+ return storedConversations(connection, null);
567
488
  case 'conversation.drop':
568
- chatDraft(connection, {
569
- kind: 'authored.chatDraft',
570
- kept: [],
571
- dropped: request.conversations,
572
- });
573
- droppedMessages(connection, request.conversations);
574
- return null;
489
+ return droppedConversations(connection, request.conversations);
575
490
  case 'space.probe':
576
491
  return spool.probe(PROBE_BYTES).then(() => null);
492
+ case 'read.stored':
493
+ return storedRead(connection, request);
494
+ case 'read.keep':
495
+ return keptRead(connection, request, request.answer);
496
+ case 'read.builds':
497
+ return readsOfOtherBuildsForgotten(connection, request.build);
577
498
  }
578
499
  }