@agentshouse/mdruntime 0.1.0-c3c7796382e28 → 0.1.0-c3faae279d4d2

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 (288) hide show
  1. package/README.md +2 -2
  2. package/dist/acceptance.d.ts +6 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +385 -0
  5. package/dist/actions.d.ts +20 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +251 -0
  8. package/dist/adapter.d.ts +90 -70
  9. package/dist/adapter.d.ts.map +1 -1
  10. package/dist/attached-model.d.ts +3 -10
  11. package/dist/attached-model.d.ts.map +1 -1
  12. package/dist/attached-model.js +29 -47
  13. package/dist/bootstrap.d.ts +14 -17
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +259 -152
  16. package/dist/cell.d.ts +6 -0
  17. package/dist/cell.d.ts.map +1 -0
  18. package/dist/cell.js +9 -0
  19. package/dist/chain.d.ts +2 -1
  20. package/dist/chain.d.ts.map +1 -1
  21. package/dist/change.d.ts +1 -0
  22. package/dist/change.d.ts.map +1 -1
  23. package/dist/change.js +4 -2
  24. package/dist/chat-types.d.ts +5 -0
  25. package/dist/chat-types.d.ts.map +1 -0
  26. package/dist/chat-types.js +13 -0
  27. package/dist/client.d.ts +21 -6
  28. package/dist/client.d.ts.map +1 -1
  29. package/dist/client.js +4 -2
  30. package/dist/collection.d.ts +2 -4
  31. package/dist/collection.d.ts.map +1 -1
  32. package/dist/collection.js +1 -17
  33. package/dist/compile.d.ts +6 -6
  34. package/dist/compile.d.ts.map +1 -1
  35. package/dist/compile.js +272 -326
  36. package/dist/connection.d.ts +5 -143
  37. package/dist/connection.d.ts.map +1 -1
  38. package/dist/connection.js +102 -5122
  39. package/dist/context.d.ts +2 -0
  40. package/dist/context.d.ts.map +1 -0
  41. package/dist/context.js +7 -0
  42. package/dist/conversation-live.d.ts +136 -0
  43. package/dist/conversation-live.d.ts.map +1 -0
  44. package/dist/conversation-live.js +248 -0
  45. package/dist/conversation-row.d.ts +33 -0
  46. package/dist/conversation-row.d.ts.map +1 -0
  47. package/dist/conversation-row.js +53 -0
  48. package/dist/conversation.d.ts +41 -43
  49. package/dist/conversation.d.ts.map +1 -1
  50. package/dist/conversation.js +870 -779
  51. package/dist/discovery.d.ts +10 -0
  52. package/dist/discovery.d.ts.map +1 -0
  53. package/dist/discovery.js +175 -0
  54. package/dist/durability.d.ts +15 -1
  55. package/dist/durability.d.ts.map +1 -1
  56. package/dist/entry.d.ts +3 -2
  57. package/dist/entry.d.ts.map +1 -1
  58. package/dist/entry.js +18 -8
  59. package/dist/figures.d.ts +49 -0
  60. package/dist/figures.d.ts.map +1 -0
  61. package/dist/figures.js +197 -0
  62. package/dist/holdings.d.ts +29 -0
  63. package/dist/holdings.d.ts.map +1 -0
  64. package/dist/holdings.js +95 -0
  65. package/dist/host.d.ts +4 -7
  66. package/dist/host.d.ts.map +1 -1
  67. package/dist/host.js +29 -31
  68. package/dist/identity.d.ts +0 -1
  69. package/dist/identity.d.ts.map +1 -1
  70. package/dist/identity.js +0 -3
  71. package/dist/index.d.ts +26 -8
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +8 -1
  74. package/dist/install.d.ts +56 -0
  75. package/dist/install.d.ts.map +1 -0
  76. package/dist/install.js +554 -0
  77. package/dist/job.d.ts +33 -0
  78. package/dist/job.d.ts.map +1 -0
  79. package/dist/job.js +54 -0
  80. package/dist/lifecycle.d.ts +7 -0
  81. package/dist/lifecycle.d.ts.map +1 -0
  82. package/dist/lifecycle.js +268 -0
  83. package/dist/listing.d.ts +53 -0
  84. package/dist/listing.d.ts.map +1 -0
  85. package/dist/listing.js +176 -0
  86. package/dist/live.d.ts +5 -4
  87. package/dist/live.d.ts.map +1 -1
  88. package/dist/live.js +62 -23
  89. package/dist/locks.d.ts +9 -0
  90. package/dist/locks.d.ts.map +1 -0
  91. package/dist/locks.js +61 -0
  92. package/dist/log.d.ts +1 -0
  93. package/dist/log.d.ts.map +1 -1
  94. package/dist/lost.d.ts +5 -0
  95. package/dist/lost.d.ts.map +1 -0
  96. package/dist/lost.js +61 -0
  97. package/dist/media.d.ts +2 -2
  98. package/dist/media.d.ts.map +1 -1
  99. package/dist/media.js +22 -12
  100. package/dist/memory.d.ts +12 -5
  101. package/dist/memory.d.ts.map +1 -1
  102. package/dist/memory.js +175 -83
  103. package/dist/messages.d.ts +27 -3
  104. package/dist/messages.d.ts.map +1 -1
  105. package/dist/messages.js +103 -31
  106. package/dist/model.d.ts +2 -10
  107. package/dist/model.d.ts.map +1 -1
  108. package/dist/model.js +0 -18
  109. package/dist/models.d.ts +14 -0
  110. package/dist/models.d.ts.map +1 -0
  111. package/dist/models.js +195 -0
  112. package/dist/observation.d.ts +2 -2
  113. package/dist/observation.d.ts.map +1 -1
  114. package/dist/observation.js +14 -14
  115. package/dist/opened.js +3 -3
  116. package/dist/opening.d.ts +4 -0
  117. package/dist/opening.d.ts.map +1 -0
  118. package/dist/opening.js +57 -0
  119. package/dist/outcome.d.ts +4 -4
  120. package/dist/outcome.d.ts.map +1 -1
  121. package/dist/outcome.js +3 -0
  122. package/dist/overlay.d.ts +1 -0
  123. package/dist/overlay.d.ts.map +1 -1
  124. package/dist/overlay.js +11 -0
  125. package/dist/parts.d.ts +60 -0
  126. package/dist/parts.d.ts.map +1 -0
  127. package/dist/parts.js +126 -0
  128. package/dist/paths.d.ts +2 -0
  129. package/dist/paths.d.ts.map +1 -1
  130. package/dist/paths.js +26 -0
  131. package/dist/preparation.d.ts +20 -0
  132. package/dist/preparation.d.ts.map +1 -0
  133. package/dist/preparation.js +226 -0
  134. package/dist/queries.d.ts +16 -0
  135. package/dist/queries.d.ts.map +1 -0
  136. package/dist/queries.js +272 -0
  137. package/dist/query.d.ts +14 -210
  138. package/dist/query.d.ts.map +1 -1
  139. package/dist/query.js +3 -505
  140. package/dist/questions.d.ts +34 -0
  141. package/dist/questions.d.ts.map +1 -0
  142. package/dist/questions.js +122 -0
  143. package/dist/reach.d.ts +15 -12
  144. package/dist/reach.d.ts.map +1 -1
  145. package/dist/reach.js +185 -139
  146. package/dist/react.d.ts +10 -2
  147. package/dist/react.d.ts.map +1 -1
  148. package/dist/read.d.ts +7 -0
  149. package/dist/read.d.ts.map +1 -0
  150. package/dist/read.js +17 -0
  151. package/dist/readiness.d.ts +3 -18
  152. package/dist/readiness.d.ts.map +1 -1
  153. package/dist/readiness.js +4 -10
  154. package/dist/reads.d.ts +36 -10
  155. package/dist/reads.d.ts.map +1 -1
  156. package/dist/reads.js +157 -86
  157. package/dist/recovery.d.ts +1 -0
  158. package/dist/recovery.d.ts.map +1 -1
  159. package/dist/recovery.js +35 -1
  160. package/dist/refresh.d.ts +7 -5
  161. package/dist/refresh.d.ts.map +1 -1
  162. package/dist/refresh.js +33 -5
  163. package/dist/refusal.d.ts +5 -0
  164. package/dist/refusal.d.ts.map +1 -0
  165. package/dist/refusal.js +55 -0
  166. package/dist/replica.d.ts +10 -10
  167. package/dist/replica.d.ts.map +1 -1
  168. package/dist/replica.js +53 -21
  169. package/dist/room-draft.d.ts +21 -7
  170. package/dist/room-draft.d.ts.map +1 -1
  171. package/dist/room-draft.js +101 -54
  172. package/dist/room-drafts.d.ts +24 -0
  173. package/dist/room-drafts.d.ts.map +1 -0
  174. package/dist/room-drafts.js +217 -0
  175. package/dist/rows.d.ts +14 -21
  176. package/dist/rows.d.ts.map +1 -1
  177. package/dist/rows.js +48 -184
  178. package/dist/runtime.d.ts +43 -0
  179. package/dist/runtime.d.ts.map +1 -0
  180. package/dist/runtime.js +1 -0
  181. package/dist/save.d.ts +7 -1
  182. package/dist/save.d.ts.map +1 -1
  183. package/dist/save.js +31 -24
  184. package/dist/saves.d.ts +70 -0
  185. package/dist/saves.d.ts.map +1 -0
  186. package/dist/saves.js +1005 -0
  187. package/dist/search.d.ts +12 -63
  188. package/dist/search.d.ts.map +1 -1
  189. package/dist/search.js +9 -52
  190. package/dist/seed.d.ts +11 -2
  191. package/dist/seed.d.ts.map +1 -1
  192. package/dist/seed.js +71 -1
  193. package/dist/shared.d.ts +1 -7
  194. package/dist/shared.d.ts.map +1 -1
  195. package/dist/shared.js +13 -105
  196. package/dist/shown.d.ts +31 -0
  197. package/dist/shown.d.ts.map +1 -0
  198. package/dist/shown.js +292 -0
  199. package/dist/socket/admission.d.ts +7 -0
  200. package/dist/socket/admission.d.ts.map +1 -0
  201. package/dist/socket/admission.js +39 -0
  202. package/dist/socket/answers.d.ts +6 -0
  203. package/dist/socket/answers.d.ts.map +1 -0
  204. package/dist/socket/answers.js +20 -0
  205. package/dist/socket/lanes.d.ts +20 -0
  206. package/dist/socket/lanes.d.ts.map +1 -0
  207. package/dist/socket/lanes.js +77 -0
  208. package/dist/socket/reads.d.ts +10 -0
  209. package/dist/socket/reads.d.ts.map +1 -0
  210. package/dist/socket/reads.js +31 -0
  211. package/dist/socket/rooms.d.ts +44 -0
  212. package/dist/socket/rooms.d.ts.map +1 -0
  213. package/dist/socket/rooms.js +90 -0
  214. package/dist/socket/session.d.ts +38 -0
  215. package/dist/socket/session.d.ts.map +1 -0
  216. package/dist/socket/session.js +23 -0
  217. package/dist/socket.d.ts +70 -0
  218. package/dist/socket.d.ts.map +1 -0
  219. package/dist/socket.js +175 -0
  220. package/dist/source.d.ts +61 -0
  221. package/dist/source.d.ts.map +1 -0
  222. package/dist/source.js +82 -0
  223. package/dist/status.d.ts +4 -5
  224. package/dist/status.d.ts.map +1 -1
  225. package/dist/status.js +3 -7
  226. package/dist/store/fences.d.ts +16 -0
  227. package/dist/store/fences.d.ts.map +1 -0
  228. package/dist/store/fences.js +26 -0
  229. package/dist/store/installs.d.ts +30 -0
  230. package/dist/store/installs.d.ts.map +1 -0
  231. package/dist/store/installs.js +34 -0
  232. package/dist/store/readiness.d.ts +10 -0
  233. package/dist/store/readiness.d.ts.map +1 -0
  234. package/dist/store/readiness.js +52 -0
  235. package/dist/store/records.d.ts +212 -0
  236. package/dist/store/records.d.ts.map +1 -0
  237. package/dist/store/records.js +431 -0
  238. package/dist/store/room-held.d.ts +8 -0
  239. package/dist/store/room-held.d.ts.map +1 -0
  240. package/dist/store/room-held.js +17 -0
  241. package/dist/store/space.d.ts +11 -0
  242. package/dist/store/space.d.ts.map +1 -0
  243. package/dist/store/space.js +41 -0
  244. package/dist/store/watchers.d.ts +17 -0
  245. package/dist/store/watchers.d.ts.map +1 -0
  246. package/dist/store/watchers.js +56 -0
  247. package/dist/store/writes.d.ts +24 -0
  248. package/dist/store/writes.d.ts.map +1 -0
  249. package/dist/store/writes.js +125 -0
  250. package/dist/store.d.ts +115 -171
  251. package/dist/store.d.ts.map +1 -1
  252. package/dist/store.js +143 -416
  253. package/dist/stored.d.ts +61 -57
  254. package/dist/stored.d.ts.map +1 -1
  255. package/dist/stored.js +311 -233
  256. package/dist/surface.d.ts +88 -0
  257. package/dist/surface.d.ts.map +1 -0
  258. package/dist/surface.js +223 -0
  259. package/dist/sync.d.ts +19 -0
  260. package/dist/sync.d.ts.map +1 -0
  261. package/dist/sync.js +532 -0
  262. package/dist/tables.d.ts +126 -64
  263. package/dist/tables.d.ts.map +1 -1
  264. package/dist/tables.js +221 -105
  265. package/dist/tallies.d.ts +18 -0
  266. package/dist/tallies.d.ts.map +1 -0
  267. package/dist/tallies.js +129 -0
  268. package/dist/transfer.d.ts +0 -5
  269. package/dist/transfer.d.ts.map +1 -1
  270. package/dist/validation.d.ts +3 -4
  271. package/dist/validation.d.ts.map +1 -1
  272. package/dist/validation.js +42 -100
  273. package/dist/windows.d.ts +1 -12
  274. package/dist/windows.d.ts.map +1 -1
  275. package/dist/windows.js +2 -75
  276. package/dist/wire.d.ts +17 -5
  277. package/dist/wire.d.ts.map +1 -1
  278. package/dist/wire.js +7 -1
  279. package/package.json +2 -2
  280. package/dist/fence.d.ts +0 -6
  281. package/dist/fence.d.ts.map +0 -1
  282. package/dist/fence.js +0 -10
  283. package/dist/fulltext.d.ts +0 -27
  284. package/dist/fulltext.d.ts.map +0 -1
  285. package/dist/fulltext.js +0 -368
  286. package/dist/words.d.ts +0 -19
  287. package/dist/words.d.ts.map +0 -1
  288. package/dist/words.js +0 -150
package/dist/tables.js CHANGED
@@ -1,11 +1,17 @@
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, opened, rederive, referrers, refreshing, REPLICA_TABLES, keepParts, stage, transferPart, typed, typedWithin, unrefresh, walk, } from './stored.js';
3
+ import { conversationRows, droppedMessages, forgottenMessages, heldConversations, jobMarkers, keptMessages, messageCount, messageWindow, MESSAGE_TABLES, turnArrived, } from './messages.js';
4
+ import { keptRead, READ_TABLES, readsOfOtherBuildsForgotten, storedRead, } from './reads.js';
5
+ import { conversationTallies, roomTallies, } from './tallies.js';
6
+ 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, typedWithin, unrefresh, } from './stored.js';
5
7
  const STATEMENTS_HELD = 256;
6
8
  export function sqliteConnection(engine, database) {
7
9
  const decoder = new TextDecoder();
8
10
  const held = new Map();
11
+ database.createFunction(sql.HOLDS_PHRASE, sql.holdsPhrase, {
12
+ arity: 2,
13
+ deterministic: true,
14
+ });
9
15
  function prepared(sql) {
10
16
  if (sql.includes(';'))
11
17
  return null;
@@ -72,7 +78,7 @@ const TABLES = [
72
78
  ['authored_queues', 'locator TEXT PRIMARY KEY, ids TEXT NOT NULL'],
73
79
  [
74
80
  '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)',
81
+ 'locator TEXT NOT NULL, id TEXT NOT NULL, batch TEXT NOT NULL, state TEXT NOT NULL, files TEXT NOT NULL, paths TEXT NOT NULL, moving INTEGER NOT NULL, PRIMARY KEY (locator, id)',
76
82
  ],
77
83
  [
78
84
  'authored_room_drafts',
@@ -89,38 +95,53 @@ export const RUNTIME_TABLES = [
89
95
  'CREATE INDEX opened_files_name ON opened_files (locator, path, revision)',
90
96
  ...REPLICA_TABLES,
91
97
  ...MESSAGE_TABLES,
92
- ...SEARCH_TABLES,
98
+ ...READ_TABLES,
93
99
  ];
94
100
  const OWNERS = ['authored_pending', 'authored_room_drafts', 'authored_calls'];
95
101
  const AUTHORED_KEYS = OWNERS.map((table) => `SELECT value FROM ${table}, json_each(${table}.files)`).join(' UNION ');
96
102
  const UNOWNED_PARTS = `DELETE FROM file_parts WHERE key NOT IN (${AUTHORED_KEYS} UNION SELECT key FROM opened_files)`;
103
+ const CLEANABLE_BYTES = `SELECT coalesce(sum(length(bytes)), 0) AS bytes FROM file_parts WHERE key NOT IN (${AUTHORED_KEYS})`;
97
104
  const READS = new Set([
98
- 'authored.queues',
105
+ 'authored.status',
106
+ 'authored.moving',
107
+ 'authored.pending',
108
+ 'authored.batch',
109
+ 'authored.order',
110
+ 'authored.queued',
99
111
  'authored.roomDrafts',
112
+ 'authored.chatDraft.read',
100
113
  'authored.chatDrafts',
101
114
  'authored.calls',
102
115
  'authored.fences',
116
+ 'authored.unsent',
103
117
  'authored.fact',
104
118
  'authored.file',
105
119
  'replica.open',
120
+ 'replica.rooms',
121
+ 'replica.room',
122
+ 'replica.covering',
123
+ 'replica.offline',
124
+ 'replica.held',
125
+ 'replica.facts',
126
+ 'replica.presentation',
106
127
  'replica.query',
128
+ 'replica.tallies',
107
129
  'replica.entries',
108
130
  'replica.typed',
109
131
  'replica.referrers',
110
- 'replica.walk',
111
- 'replica.files',
132
+ 'replica.folders',
112
133
  'replica.typedWithin',
113
- 'replica.counts',
114
- 'replica.search',
115
- 'replica.received',
116
- 'replica.receivedParts',
117
- 'replica.transferPart',
118
134
  'opened.find',
135
+ 'opened.held',
119
136
  'file.part',
120
137
  'conversation.held',
121
138
  'conversation.window',
122
139
  'conversation.count',
123
140
  'conversation.turn',
141
+ 'conversation.rows',
142
+ 'conversation.jobs',
143
+ 'conversation.tallies',
144
+ 'read.stored',
124
145
  ]);
125
146
  const KINDS = new Set([
126
147
  ...READS,
@@ -132,19 +153,19 @@ const KINDS = new Set([
132
153
  'authored.claim',
133
154
  'authored.end',
134
155
  'replica.stage',
135
- 'replica.keepParts',
156
+ 'replica.resume',
136
157
  'replica.refresh',
137
158
  'replica.unrefresh',
138
159
  'replica.commit',
139
160
  'replica.fence',
140
161
  'replica.erase',
141
162
  'replica.abandon',
163
+ 'replica.unfence',
142
164
  'replica.release',
143
165
  'replica.rederive',
166
+ 'replica.demote',
144
167
  'replica.fact',
145
168
  'replica.present',
146
- 'replica.receive',
147
- 'replica.unreceive',
148
169
  'opened.begin',
149
170
  'opened.part',
150
171
  'opened.keep',
@@ -153,6 +174,8 @@ const KINDS = new Set([
153
174
  'conversation.keep',
154
175
  'conversation.drop',
155
176
  'space.probe',
177
+ 'read.keep',
178
+ 'read.builds',
156
179
  ]);
157
180
  export function isRuntime(request) {
158
181
  return KINDS.has(request.kind);
@@ -225,29 +248,71 @@ function unowned(connection) {
225
248
  connection.run(UNOWNED_PARTS);
226
249
  }
227
250
  function queued(connection) {
251
+ return connection.rows('SELECT locator, ids FROM authored_queues').map((row) => ({
252
+ locator: text(row.locator),
253
+ ids: JSON.parse(text(row.ids)),
254
+ }));
255
+ }
256
+ function heldWork(connection, locator) {
257
+ const room = heldRoom(connection, locator);
258
+ const pending = new Map(connection
259
+ .rows('SELECT id, batch, state FROM authored_pending WHERE locator = ?', [locator])
260
+ .map((row) => [
261
+ text(row.id),
262
+ { id: text(row.id), batch: text(row.batch), state: text(row.state) },
263
+ ]));
228
264
  return {
229
- queues: connection.rows('SELECT locator, ids FROM authored_queues').map((row) => ({
230
- locator: text(row.locator),
231
- ids: JSON.parse(text(row.ids)),
232
- })),
233
- pending: connection
234
- .rows('SELECT locator, id, batch, state FROM authored_pending')
235
- .map((row) => ({
236
- locator: text(row.locator),
237
- id: text(row.id),
238
- batch: text(row.batch),
239
- state: text(row.state),
240
- })),
265
+ room: room === null ? null : { ...room, overlaid: overlaid(connection, room.key) },
266
+ queue: heldOrder(connection, locator).map((id) => {
267
+ const held = pending.get(id);
268
+ if (held === undefined)
269
+ throw new Error(`Missing Pending Change ${locator}/${id}`);
270
+ return held;
271
+ }),
241
272
  };
242
273
  }
274
+ function status(connection) {
275
+ const [completed] = connection.rows("SELECT value FROM replica_facts WHERE name = 'lastCompleted'");
276
+ return {
277
+ queued: texts(connection.rows('SELECT locator FROM authored_queues'), 'locator'),
278
+ lastCompleted: completed === undefined ? null : text(completed.value),
279
+ changes: connection
280
+ .rows('SELECT p.locator, c.value AS path FROM authored_pending p, json_each(p.paths) c')
281
+ .map((row) => ({ locator: text(row.locator), path: text(row.path) })),
282
+ resets: connection
283
+ .rows(`SELECT locator, json_extract(state, '$.submission.reset') AS reset FROM authored_pending
284
+ WHERE json_extract(state, '$.submission.state') = 'reset'`)
285
+ .map((row) => ({ locator: text(row.locator), reset: text(row.reset) })),
286
+ returned: texts(connection.rows(`SELECT record FROM authored_room_drafts WHERE json_type(record, '$.returned') = 'object'`), 'record'),
287
+ };
288
+ }
289
+ function pendingOf(connection, locator, id) {
290
+ const [held] = connection.rows('SELECT state FROM authored_pending WHERE locator = ? AND id = ?', [locator, id]);
291
+ return {
292
+ state: held === undefined ? null : text(held.state),
293
+ room: connection.rows('SELECT 1 FROM replica_rooms WHERE locator = ?', [locator]).length > 0,
294
+ };
295
+ }
296
+ function roomDraftRecords(connection, locator, paths) {
297
+ if (locator === null) {
298
+ return texts(connection.rows('SELECT record FROM authored_room_drafts'), 'record');
299
+ }
300
+ if (paths === null) {
301
+ return texts(connection.rows('SELECT record FROM authored_room_drafts WHERE locator = ?', [locator]), 'record');
302
+ }
303
+ return texts(connection.rows('SELECT record FROM authored_room_drafts WHERE locator = ? AND path IN (SELECT value FROM json_each(?))', [locator, JSON.stringify(paths)]), 'record');
304
+ }
305
+ function chatDraftRecord(connection, conversation) {
306
+ const [held] = connection.rows('SELECT record FROM authored_chat_drafts WHERE conversation = ?', [
307
+ conversation,
308
+ ]);
309
+ return held === undefined ? null : text(held.record);
310
+ }
243
311
  function heldOrder(connection, locator) {
244
312
  const [held] = connection.rows('SELECT ids FROM authored_queues WHERE locator = ?', [locator]);
245
313
  return held === undefined ? [] : JSON.parse(text(held.ids));
246
314
  }
247
- function keptRows(connection, { locator, order, added, founded, roomDrafts, consumedRoomDrafts, amendments }) {
248
- for (const { id, amendment } of amendments ?? []) {
249
- amended(connection, { kind: 'authored.amend', locator, id, amendment });
250
- }
315
+ function keptRows(connection, { locator, order, added, founded, roomDrafts, consumedRoomDrafts }) {
251
316
  for (const path of consumedRoomDrafts ?? []) {
252
317
  connection.run('DELETE FROM authored_room_drafts WHERE locator = ? AND path = ?', [
253
318
  locator,
@@ -274,19 +339,26 @@ function keptRows(connection, { locator, order, added, founded, roomDrafts, cons
274
339
  connection.run('DELETE FROM authored_pending WHERE locator = ? AND id = ?', [locator, id]);
275
340
  }
276
341
  }
277
- for (const { id, batch, state, files } of added ?? []) {
278
- if (before.has(id) || !after.has(id))
342
+ for (const { id, batch, state, files, paths, moving } of added ?? []) {
343
+ if (before.has(id))
279
344
  continue;
280
- connection.run('INSERT OR REPLACE INTO authored_pending (locator, id, batch, state, files) VALUES (?, ?, ?, ?, ?)', [locator, id, batch, state, owned(files)]);
345
+ connection.run('INSERT OR REPLACE INTO authored_pending (locator, id, batch, state, files, paths, moving) VALUES (?, ?, ?, ?, ?, ?, ?)', [locator, id, batch, state, owned(files), JSON.stringify(paths), moving ? 1 : 0]);
281
346
  }
282
- for (const { id, batch, files } of founded ?? []) {
347
+ for (const { id, batch, files, paths, moving } of founded ?? []) {
283
348
  const [held] = connection.rows('SELECT files FROM authored_pending WHERE locator = ? AND id = ?', [locator, id]);
284
349
  if (held === undefined || !before.has(id))
285
350
  continue;
286
- connection.run('UPDATE authored_pending SET batch = ?, files = ? WHERE locator = ? AND id = ?', [batch, owned([...JSON.parse(text(held.files)), ...files]), locator, id]);
351
+ connection.run('UPDATE authored_pending SET batch = ?, files = ?, paths = ?, moving = ? WHERE locator = ? AND id = ?', [
352
+ batch,
353
+ owned([...JSON.parse(text(held.files)), ...files]),
354
+ JSON.stringify(paths),
355
+ moving ? 1 : 0,
356
+ locator,
357
+ id,
358
+ ]);
287
359
  }
288
360
  }
289
- async function kept(connection, { writes, files, whole, discards }) {
361
+ async function kept(connection, { writes, files, whole }) {
290
362
  const refused = writes.find(({ locator }) => fenced(connection, locator));
291
363
  if (refused !== undefined && whole)
292
364
  return refused.locator;
@@ -295,8 +367,6 @@ async function kept(connection, { writes, files, whole, discards }) {
295
367
  if (!fenced(connection, write.locator))
296
368
  keptRows(connection, write);
297
369
  }
298
- for (const locator of discards ?? [])
299
- roomWork(connection, locator);
300
370
  unowned(connection);
301
371
  return refused?.locator ?? null;
302
372
  }
@@ -366,11 +436,15 @@ function fence(connection, locators) {
366
436
  return fenceRooms(connection, locators);
367
437
  }
368
438
  function erased(connection, { locator, limit }) {
369
- const done = erase(connection, locator, limit);
370
- if (locator !== null && !done.remaining) {
439
+ return erase(connection, locator, limit);
440
+ }
441
+ function unfenced(connection, locators) {
442
+ const erased = locators.filter((locator) => connection.rows('SELECT 1 FROM replica_erasing WHERE locator = ? LIMIT 1', [locator])
443
+ .length === 0);
444
+ for (const locator of erased) {
371
445
  connection.run('DELETE FROM authored_fences WHERE locator = ?', [locator]);
372
446
  }
373
- return done;
447
+ return erased;
374
448
  }
375
449
  function claim(connection, holder) {
376
450
  const held = fact(connection, 'holder');
@@ -433,9 +507,9 @@ function keptOpened(connection, { key, sha256, byteLength, parts }) {
433
507
  if (fetched === null)
434
508
  return false;
435
509
  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]);
436
- const whole = count(held?.parts) === parts &&
437
- count(held?.bytes) === byteLength &&
438
- (parts === 0 || (count(held?.first) === 0 && count(held?.last) === parts - 1));
510
+ const whole = count(held.parts) === parts &&
511
+ count(held.bytes) === byteLength &&
512
+ (parts === 0 || (count(held.first) === 0 && count(held.last) === parts - 1));
439
513
  if (!whole) {
440
514
  dropped(connection, key);
441
515
  return false;
@@ -449,56 +523,82 @@ function keptOpened(connection, { key, sha256, byteLength, parts }) {
449
523
  unowned(connection);
450
524
  return true;
451
525
  }
526
+ const UNSENT = [
527
+ ['pending-change', 'authored_pending'],
528
+ ['call', 'authored_calls'],
529
+ ['room-draft', 'authored_room_drafts'],
530
+ ['chat-draft', 'authored_chat_drafts'],
531
+ ];
532
+ function unsent(connection) {
533
+ const [held] = connection.rows(`SELECT ${UNSENT.map(([kind, table]) => `(SELECT count(*) FROM ${table}) AS "${kind}"`).join(', ')}`);
534
+ return UNSENT.map(([kind]) => ({ kind, count: count(held[kind]) })).filter((work) => work.count > 0);
535
+ }
536
+ function cleanable(connection) {
537
+ const [held] = connection.rows(CLEANABLE_BYTES);
538
+ return count(held.bytes);
539
+ }
452
540
  function cleaned(connection) {
453
541
  connection.run('DELETE FROM opened_files');
454
- const [freed] = connection.rows(`SELECT coalesce(sum(length(bytes)), 0) AS bytes FROM file_parts WHERE key NOT IN (${AUTHORED_KEYS})`);
542
+ const freed = cleanable(connection);
455
543
  unowned(connection);
456
- return count(freed?.bytes);
544
+ return freed;
545
+ }
546
+ function openedHeld(connection) {
547
+ return {
548
+ rooms: connection
549
+ .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')
550
+ .map((row) => ({ room: text(row.locator), count: count(row.files), size: count(row.bytes) })),
551
+ cleanable: cleanable(connection),
552
+ };
457
553
  }
458
554
  async function committed(connection, { authored, rooms }) {
459
555
  const refused = authored === undefined ? null : await kept(connection, authored);
460
556
  if (refused !== null && authored?.whole === true) {
461
- return { fenced: refused, counts: {}, changed: {}, indexed: {} };
557
+ return { fenced: refused, changed: {}, indexed: {} };
462
558
  }
463
559
  return {
464
560
  fenced: refused,
465
561
  ...commit(connection, rooms.filter(({ locator }) => !fenced(connection, locator))),
466
562
  };
467
563
  }
468
- function receivedParts(connection, key, count) {
469
- return connection
470
- .rows('SELECT value FROM replica_received_parts WHERE key = ? AND part < ? ORDER BY part', [
471
- key,
472
- count,
473
- ])
474
- .map((row) => JSON.parse(text(row.value)));
475
- }
476
- function receive(connection, { key, head, part }) {
477
- connection.run('INSERT OR REPLACE INTO replica_received (key, head) VALUES (?, ?)', [key, head]);
478
- if (part !== undefined) {
479
- connection.run('INSERT OR REPLACE INTO replica_received_parts (key, part, value) VALUES (?, ?, ?)', [key, part.index, part.value]);
480
- }
481
- return null;
482
- }
483
- function unreceive(connection, keys) {
484
- for (const key of keys) {
485
- connection.run('DELETE FROM replica_received WHERE key = ?', [key]);
486
- connection.run('DELETE FROM replica_received_parts WHERE key = ?', [key]);
487
- }
488
- return null;
489
- }
490
564
  export function answerRuntime(connection, request, spool) {
491
565
  switch (request.kind) {
492
- case 'authored.queues':
493
- return queued(connection);
566
+ case 'authored.status':
567
+ return status(connection);
568
+ case 'authored.moving':
569
+ return {
570
+ queues: queued(connection),
571
+ pending: connection
572
+ .rows('SELECT locator, id, batch, state FROM authored_pending WHERE moving = 1 ORDER BY locator')
573
+ .map((row) => ({
574
+ locator: text(row.locator),
575
+ id: text(row.id),
576
+ batch: text(row.batch),
577
+ state: text(row.state),
578
+ })),
579
+ };
580
+ case 'authored.pending':
581
+ return pendingOf(connection, request.locator, request.id);
582
+ case 'authored.batch': {
583
+ const [held] = connection.rows('SELECT batch FROM authored_pending WHERE locator = ? AND id = ?', [request.locator, request.id]);
584
+ return held === undefined ? null : text(held.batch);
585
+ }
586
+ case 'authored.order':
587
+ return heldOrder(connection, request.locator);
588
+ case 'authored.queued':
589
+ return texts(connection.rows('SELECT locator FROM authored_queues'), 'locator');
494
590
  case 'authored.roomDrafts':
495
- return texts(connection.rows('SELECT record FROM authored_room_drafts'), 'record');
591
+ return roomDraftRecords(connection, request.locator, request.paths);
592
+ case 'authored.chatDraft.read':
593
+ return chatDraftRecord(connection, request.conversation);
496
594
  case 'authored.chatDrafts':
497
595
  return texts(connection.rows('SELECT record FROM authored_chat_drafts'), 'record');
498
596
  case 'authored.calls':
499
597
  return texts(connection.rows('SELECT record FROM authored_calls'), 'record');
500
598
  case 'authored.fences':
501
599
  return texts(connection.rows('SELECT locator FROM authored_fences'), 'locator');
600
+ case 'authored.unsent':
601
+ return unsent(connection);
502
602
  case 'authored.fact':
503
603
  return fact(connection, request.name);
504
604
  case 'authored.file':
@@ -519,39 +619,43 @@ export function answerRuntime(connection, request, spool) {
519
619
  return end(connection, request.holder);
520
620
  case 'replica.open':
521
621
  return opened(connection);
622
+ case 'replica.rooms':
623
+ return heldRooms(connection, request.locators);
624
+ case 'replica.room':
625
+ return heldWork(connection, request.locator);
626
+ case 'replica.covering':
627
+ return {
628
+ rooms: covering(connection),
629
+ queues: queued(connection),
630
+ };
631
+ case 'replica.offline':
632
+ return offlineMode(connection, request.locator);
633
+ case 'replica.held':
634
+ return { held: heldLocators(connection), staged: stagedLocators(connection) };
635
+ case 'replica.demote':
636
+ return demoted(connection);
637
+ case 'replica.facts':
638
+ return facts(connection);
639
+ case 'replica.presentation':
640
+ return presentation(connection, request.app);
522
641
  case 'replica.query':
523
642
  return answerQuery(connection, request.plan, request.rooms, request.budget);
643
+ case 'replica.tallies':
644
+ return roomTallies(connection, request.totals, request.rooms, request.since);
524
645
  case 'replica.entries':
525
646
  return entries(connection, request.key, request.view, request.paths);
526
647
  case 'replica.typed':
527
648
  return typed(connection, request.key, request.view, request.paths);
528
649
  case 'replica.referrers':
529
- return referrers(connection, request.key, request.view, request.targets, request.kinds);
530
- case 'replica.walk':
531
- return walk(connection, request.key, request.view, request.after, request.bytes);
532
- case 'replica.files':
533
- return files(connection, request.key, request.view, request.after, request.limit);
650
+ return referrers(connection, request.key, request.view, request.targets);
651
+ case 'replica.folders':
652
+ return folders(connection, request.key, request.paths);
534
653
  case 'replica.typedWithin':
535
654
  return typedWithin(connection, request.key, request.view, request.roots, request.within);
536
- case 'replica.counts':
537
- return counts(connection, request.rooms);
538
- case 'replica.search': {
539
- const { kind: _kind, ...ask } = request;
540
- return searched(connection, ask);
541
- }
542
- case 'replica.received':
543
- return connection.rows('SELECT key, head FROM replica_received').map((row) => ({
544
- key: text(row.key),
545
- head: JSON.parse(text(row.head)),
546
- }));
547
- case 'replica.receivedParts':
548
- return receivedParts(connection, request.key, request.count);
549
655
  case 'replica.stage':
550
656
  return fenced(connection, request.locator) ? null : stage(connection, request);
551
- case 'replica.transferPart':
552
- return transferPart(connection, request.locator, request.token);
553
- case 'replica.keepParts':
554
- return keepParts(connection, request.parts.filter(({ locator }) => !fenced(connection, locator)));
657
+ case 'replica.resume':
658
+ return fenced(connection, request.locator) ? null : resume(connection, request);
555
659
  case 'replica.refresh':
556
660
  return refreshing(connection, request);
557
661
  case 'replica.unrefresh':
@@ -563,11 +667,13 @@ export function answerRuntime(connection, request, spool) {
563
667
  case 'replica.erase':
564
668
  return erased(connection, request);
565
669
  case 'replica.abandon':
566
- return abandon(connection, request.locator, request.kept);
670
+ return abandon(connection, request.locator);
671
+ case 'replica.unfence':
672
+ return unfenced(connection, request.locators);
567
673
  case 'replica.release':
568
674
  return release(connection, request.key);
569
675
  case 'replica.rederive':
570
- return rederive(connection, request.key, request.composed, request.bytes);
676
+ return rederive(connection, request.key, request.composed, request.bytes, request.ms, request.floor);
571
677
  case 'replica.fact':
572
678
  connection.run('INSERT OR REPLACE INTO replica_facts (name, value) VALUES (?, ?)', [
573
679
  request.name,
@@ -580,10 +686,6 @@ export function answerRuntime(connection, request, spool) {
580
686
  request.value,
581
687
  ]);
582
688
  return null;
583
- case 'replica.receive':
584
- return receive(connection, request);
585
- case 'replica.unreceive':
586
- return unreceive(connection, request.keys);
587
689
  case 'opened.find':
588
690
  return openedFile(connection, request);
589
691
  case 'opened.begin':
@@ -596,20 +698,28 @@ export function answerRuntime(connection, request, spool) {
596
698
  return dropped(connection, request.key);
597
699
  case 'opened.clean':
598
700
  return cleaned(connection);
701
+ case 'opened.held':
702
+ return openedHeld(connection);
599
703
  case 'file.part':
600
704
  return filePart(connection, request.key, request.part);
601
705
  case 'conversation.held':
602
- return heldConversations(connection);
706
+ return heldConversations(connection, request.conversations);
603
707
  case 'conversation.keep': {
604
708
  const { kind: _kind, ...write } = request;
605
709
  return keptMessages(connection, write);
606
710
  }
607
711
  case 'conversation.window':
608
- return messageWindow(connection, request.conversation, request.limit, request.before);
712
+ return messageWindow(connection, request.conversation, request.limit, request.before, request.phrase);
609
713
  case 'conversation.count':
610
- return messageCount(connection, request.conversation);
714
+ return messageCount(connection, request.conversation, request.phrase);
611
715
  case 'conversation.turn':
612
716
  return turnArrived(connection, request.conversation, request.turn);
717
+ case 'conversation.rows':
718
+ return conversationRows(connection, request.conversations);
719
+ case 'conversation.jobs':
720
+ return jobMarkers(connection, request.conversation);
721
+ case 'conversation.tallies':
722
+ return conversationTallies(connection, request.conversations, request.since);
613
723
  case 'conversation.drop':
614
724
  chatDraft(connection, {
615
725
  kind: 'authored.chatDraft',
@@ -620,5 +730,11 @@ export function answerRuntime(connection, request, spool) {
620
730
  return null;
621
731
  case 'space.probe':
622
732
  return spool.probe(PROBE_BYTES).then(() => null);
733
+ case 'read.stored':
734
+ return storedRead(connection, request);
735
+ case 'read.keep':
736
+ return keptRead(connection, request, request.answer);
737
+ case 'read.builds':
738
+ return readsOfOtherBuildsForgotten(connection, request.build);
623
739
  }
624
740
  }
@@ -0,0 +1,18 @@
1
+ import { type QueryRoom } from './compile.js';
2
+ import type { GroupTotal, Plan } from './query.js';
3
+ import type { Connection } from './tables.js';
4
+ export type RoomTally = {
5
+ readonly key: number;
6
+ readonly documents: GroupTotal;
7
+ readonly files: GroupTotal;
8
+ readonly documentTimes: readonly (readonly [string | null, string | null])[];
9
+ readonly chatTimes: readonly string[];
10
+ readonly messageTimes: readonly string[];
11
+ };
12
+ export type ConversationTally = {
13
+ readonly conversation: string;
14
+ readonly said: readonly string[];
15
+ };
16
+ export declare function roomTallies(connection: Connection, totals: Plan, rooms: readonly QueryRoom[], since: string): RoomTally[];
17
+ export declare function conversationTallies(connection: Connection, conversations: readonly string[] | null, since: string): ConversationTally[];
18
+ //# sourceMappingURL=tallies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tallies.d.ts","sourceRoot":"","sources":["../src/tallies.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAI1D,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC;IAC7E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAmHpG,wBAAgB,WAAW,CACzB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,KAAK,EAAE,MAAM,GACZ,SAAS,EAAE,CAwBb;AA0BD,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,EACvC,KAAK,EAAE,MAAM,GACZ,iBAAiB,EAAE,CAerB"}