@agentshouse/mdruntime 0.1.0-c4ca57eefb98a → 0.1.0-c4ef58fbdca7b

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 (284) 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 +389 -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 +85 -67
  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 +21 -56
  13. package/dist/bootstrap.d.ts +11 -10
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +218 -82
  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/chain.js +3 -7
  22. package/dist/change.d.ts +1 -0
  23. package/dist/change.d.ts.map +1 -1
  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 +3 -1
  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 +263 -319
  36. package/dist/connection.d.ts +5 -143
  37. package/dist/connection.d.ts.map +1 -1
  38. package/dist/connection.js +102 -5311
  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 -45
  49. package/dist/conversation.d.ts.map +1 -1
  50. package/dist/conversation.js +860 -869
  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 +2 -2
  57. package/dist/entry.d.ts.map +1 -1
  58. package/dist/entry.js +17 -7
  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 +25 -8
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +7 -1
  74. package/dist/install.d.ts +56 -0
  75. package/dist/install.d.ts.map +1 -0
  76. package/dist/install.js +556 -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 +175 -0
  86. package/dist/live.d.ts +5 -4
  87. package/dist/live.d.ts.map +1 -1
  88. package/dist/live.js +63 -22
  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 +1 -1
  98. package/dist/media.d.ts.map +1 -1
  99. package/dist/media.js +19 -9
  100. package/dist/memory.d.ts +11 -4
  101. package/dist/memory.d.ts.map +1 -1
  102. package/dist/memory.js +171 -82
  103. package/dist/messages.d.ts +27 -3
  104. package/dist/messages.d.ts.map +1 -1
  105. package/dist/messages.js +97 -19
  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 +193 -0
  112. package/dist/observation.d.ts +2 -2
  113. package/dist/observation.d.ts.map +1 -1
  114. package/dist/observation.js +7 -2
  115. package/dist/opening.d.ts +4 -0
  116. package/dist/opening.d.ts.map +1 -0
  117. package/dist/opening.js +57 -0
  118. package/dist/outcome.d.ts +4 -4
  119. package/dist/outcome.d.ts.map +1 -1
  120. package/dist/outcome.js +3 -0
  121. package/dist/overlay.d.ts +1 -0
  122. package/dist/overlay.d.ts.map +1 -1
  123. package/dist/overlay.js +11 -0
  124. package/dist/parts.d.ts +59 -0
  125. package/dist/parts.d.ts.map +1 -0
  126. package/dist/parts.js +118 -0
  127. package/dist/preparation.d.ts +20 -0
  128. package/dist/preparation.d.ts.map +1 -0
  129. package/dist/preparation.js +226 -0
  130. package/dist/queries.d.ts +16 -0
  131. package/dist/queries.d.ts.map +1 -0
  132. package/dist/queries.js +272 -0
  133. package/dist/query.d.ts +14 -209
  134. package/dist/query.d.ts.map +1 -1
  135. package/dist/query.js +3 -505
  136. package/dist/questions.d.ts +34 -0
  137. package/dist/questions.d.ts.map +1 -0
  138. package/dist/questions.js +122 -0
  139. package/dist/reach.d.ts +15 -13
  140. package/dist/reach.d.ts.map +1 -1
  141. package/dist/reach.js +183 -137
  142. package/dist/react.d.ts +10 -2
  143. package/dist/react.d.ts.map +1 -1
  144. package/dist/read.d.ts +7 -0
  145. package/dist/read.d.ts.map +1 -0
  146. package/dist/read.js +17 -0
  147. package/dist/readiness.d.ts +2 -16
  148. package/dist/readiness.d.ts.map +1 -1
  149. package/dist/readiness.js +4 -10
  150. package/dist/reads.d.ts +36 -10
  151. package/dist/reads.d.ts.map +1 -1
  152. package/dist/reads.js +158 -78
  153. package/dist/recovery.d.ts +1 -0
  154. package/dist/recovery.d.ts.map +1 -1
  155. package/dist/recovery.js +35 -1
  156. package/dist/refresh.d.ts +7 -5
  157. package/dist/refresh.d.ts.map +1 -1
  158. package/dist/refresh.js +33 -5
  159. package/dist/refusal.d.ts +5 -0
  160. package/dist/refusal.d.ts.map +1 -0
  161. package/dist/refusal.js +56 -0
  162. package/dist/replica.d.ts +8 -9
  163. package/dist/replica.d.ts.map +1 -1
  164. package/dist/replica.js +52 -20
  165. package/dist/room-draft.d.ts +4 -3
  166. package/dist/room-draft.d.ts.map +1 -1
  167. package/dist/room-draft.js +65 -52
  168. package/dist/room-drafts.d.ts +24 -0
  169. package/dist/room-drafts.d.ts.map +1 -0
  170. package/dist/room-drafts.js +216 -0
  171. package/dist/rows.d.ts +14 -21
  172. package/dist/rows.d.ts.map +1 -1
  173. package/dist/rows.js +48 -184
  174. package/dist/runtime.d.ts +43 -0
  175. package/dist/runtime.d.ts.map +1 -0
  176. package/dist/runtime.js +1 -0
  177. package/dist/save.d.ts +3 -1
  178. package/dist/save.d.ts.map +1 -1
  179. package/dist/save.js +16 -11
  180. package/dist/saves.d.ts +70 -0
  181. package/dist/saves.d.ts.map +1 -0
  182. package/dist/saves.js +1006 -0
  183. package/dist/search.d.ts +12 -63
  184. package/dist/search.d.ts.map +1 -1
  185. package/dist/search.js +9 -52
  186. package/dist/seed.d.ts +11 -2
  187. package/dist/seed.d.ts.map +1 -1
  188. package/dist/seed.js +71 -0
  189. package/dist/shared.d.ts +1 -2
  190. package/dist/shared.d.ts.map +1 -1
  191. package/dist/shared.js +9 -15
  192. package/dist/shown.d.ts +31 -0
  193. package/dist/shown.d.ts.map +1 -0
  194. package/dist/shown.js +295 -0
  195. package/dist/socket/admission.d.ts +7 -0
  196. package/dist/socket/admission.d.ts.map +1 -0
  197. package/dist/socket/admission.js +39 -0
  198. package/dist/socket/answers.d.ts +6 -0
  199. package/dist/socket/answers.d.ts.map +1 -0
  200. package/dist/socket/answers.js +20 -0
  201. package/dist/socket/lanes.d.ts +20 -0
  202. package/dist/socket/lanes.d.ts.map +1 -0
  203. package/dist/socket/lanes.js +77 -0
  204. package/dist/socket/reads.d.ts +10 -0
  205. package/dist/socket/reads.d.ts.map +1 -0
  206. package/dist/socket/reads.js +31 -0
  207. package/dist/socket/rooms.d.ts +43 -0
  208. package/dist/socket/rooms.d.ts.map +1 -0
  209. package/dist/socket/rooms.js +90 -0
  210. package/dist/socket/session.d.ts +39 -0
  211. package/dist/socket/session.d.ts.map +1 -0
  212. package/dist/socket/session.js +23 -0
  213. package/dist/socket.d.ts +70 -0
  214. package/dist/socket.d.ts.map +1 -0
  215. package/dist/socket.js +175 -0
  216. package/dist/source.d.ts +61 -0
  217. package/dist/source.d.ts.map +1 -0
  218. package/dist/source.js +81 -0
  219. package/dist/status.d.ts +0 -6
  220. package/dist/status.d.ts.map +1 -1
  221. package/dist/status.js +0 -6
  222. package/dist/store/fences.d.ts +16 -0
  223. package/dist/store/fences.d.ts.map +1 -0
  224. package/dist/store/fences.js +26 -0
  225. package/dist/store/installs.d.ts +30 -0
  226. package/dist/store/installs.d.ts.map +1 -0
  227. package/dist/store/installs.js +34 -0
  228. package/dist/store/readiness.d.ts +10 -0
  229. package/dist/store/readiness.d.ts.map +1 -0
  230. package/dist/store/readiness.js +52 -0
  231. package/dist/store/records.d.ts +212 -0
  232. package/dist/store/records.d.ts.map +1 -0
  233. package/dist/store/records.js +431 -0
  234. package/dist/store/room-held.d.ts +8 -0
  235. package/dist/store/room-held.d.ts.map +1 -0
  236. package/dist/store/room-held.js +17 -0
  237. package/dist/store/space.d.ts +11 -0
  238. package/dist/store/space.d.ts.map +1 -0
  239. package/dist/store/space.js +43 -0
  240. package/dist/store/watchers.d.ts +17 -0
  241. package/dist/store/watchers.d.ts.map +1 -0
  242. package/dist/store/watchers.js +57 -0
  243. package/dist/store/writes.d.ts +24 -0
  244. package/dist/store/writes.d.ts.map +1 -0
  245. package/dist/store/writes.js +125 -0
  246. package/dist/store.d.ts +107 -157
  247. package/dist/store.d.ts.map +1 -1
  248. package/dist/store.js +143 -395
  249. package/dist/stored.d.ts +58 -37
  250. package/dist/stored.d.ts.map +1 -1
  251. package/dist/stored.js +283 -203
  252. package/dist/surface.d.ts +88 -0
  253. package/dist/surface.d.ts.map +1 -0
  254. package/dist/surface.js +223 -0
  255. package/dist/sync.d.ts +20 -0
  256. package/dist/sync.d.ts.map +1 -0
  257. package/dist/sync.js +532 -0
  258. package/dist/tables.d.ts +120 -55
  259. package/dist/tables.d.ts.map +1 -1
  260. package/dist/tables.js +212 -93
  261. package/dist/tallies.d.ts +18 -0
  262. package/dist/tallies.d.ts.map +1 -0
  263. package/dist/tallies.js +129 -0
  264. package/dist/transfer.d.ts +0 -5
  265. package/dist/transfer.d.ts.map +1 -1
  266. package/dist/validation.d.ts +3 -4
  267. package/dist/validation.d.ts.map +1 -1
  268. package/dist/validation.js +42 -100
  269. package/dist/windows.d.ts +1 -12
  270. package/dist/windows.d.ts.map +1 -1
  271. package/dist/windows.js +2 -75
  272. package/dist/wire.d.ts +17 -5
  273. package/dist/wire.d.ts.map +1 -1
  274. package/dist/wire.js +7 -1
  275. package/package.json +2 -2
  276. package/dist/fence.d.ts +0 -6
  277. package/dist/fence.d.ts.map +0 -1
  278. package/dist/fence.js +0 -10
  279. package/dist/fulltext.d.ts +0 -27
  280. package/dist/fulltext.d.ts.map +0 -1
  281. package/dist/fulltext.js +0 -370
  282. package/dist/words.d.ts +0 -19
  283. package/dist/words.d.ts.map +0 -1
  284. package/dist/words.js +0 -156
@@ -0,0 +1,10 @@
1
+ import type { Discovery, DiscoveredRoom, Member } from './adapter.js';
2
+ import type { Runtime } from './runtime.js';
3
+ import type { Live } from './socket.js';
4
+ import type { CycleProgress } from './status.js';
5
+ import type { RuntimeStore } from './store.js';
6
+ export declare function malformed(listed: readonly DiscoveredRoom[]): string | null;
7
+ export declare function applyDiscovery(runtime: Runtime, found: readonly DiscoveredRoom[], started: number, left?: readonly string[]): Promise<readonly DiscoveredRoom[]>;
8
+ export declare function signIn(runtime: Runtime, local: RuntimeStore, signedIn: Member | null): Promise<void>;
9
+ export declare function discoverRooms(runtime: Runtime, local: RuntimeStore, progress: CycleProgress, live: Live, found: Discovery | null): Promise<readonly DiscoveredRoom[] | null>;
10
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,cAAc,EACd,MAAM,EAEP,MAAM,cAAc,CAAC;AAQtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkB/C,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,GAAG,IAAI,CAsB1E;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GACvB,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAoEpC;AAUD,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,iBAI1F;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,SAAS,GAAG,IAAI,GACtB,OAAO,CAAC,SAAS,cAAc,EAAE,GAAG,IAAI,CAAC,CA+D3C"}
@@ -0,0 +1,175 @@
1
+ import { validRoot } from './collection.js';
2
+ import { admitted, list, listHeld } from './listing.js';
3
+ import { confirmLocks, lockedRooms, relocked } from './locks.js';
4
+ import { loseRooms } from './lost.js';
5
+ import { cachedModels } from './models.js';
6
+ import { beneath } from './paths.js';
7
+ import { refuse } from './refusal.js';
8
+ import { emitMember, emitRefusal, emitRooms, moveTo, transferring } from './shown.js';
9
+ function within(root, path) {
10
+ return root === '' || beneath(root, path);
11
+ }
12
+ function declaredSelection(room) {
13
+ const selection = room.typedSelection;
14
+ if (selection === undefined)
15
+ return true;
16
+ if (!Array.isArray(selection.roots) || selection.roots.length === 0)
17
+ return false;
18
+ return selection.roots.every((root, index) => validRoot(root) &&
19
+ root !== '' &&
20
+ selection.roots.every((other, at) => at === index || !within(other, root)));
21
+ }
22
+ export function malformed(listed) {
23
+ for (const room of listed) {
24
+ if (room.operations === undefined ||
25
+ !['write', 'erase'].every((operation) => Array.isArray(room.operations[operation]) &&
26
+ room.operations[operation].every((scope) => typeof scope === 'string')) ||
27
+ room.replica === undefined ||
28
+ typeof room.replica.selection !== 'string' ||
29
+ room.replica.selection.length === 0 ||
30
+ !['admitted', 'unavailable'].includes(room.replica.admission) ||
31
+ !['locked', 'open'].includes(room.replica.offline)) {
32
+ return `invalid model or replica declaration ${room.locator}`;
33
+ }
34
+ if (!declaredSelection(room))
35
+ return `invalid typed selection declaration ${room.locator}`;
36
+ }
37
+ return null;
38
+ }
39
+ export async function applyDiscovery(runtime, found, started, left) {
40
+ const { store, socket } = runtime;
41
+ const { rooms } = socket;
42
+ const lockedBefore = await lockedRooms(runtime);
43
+ const local = await store.open();
44
+ const stillFenced = new Set(await local.fences());
45
+ const relisting = found
46
+ .map(({ locator }) => locator)
47
+ .filter((locator) => {
48
+ const fence = store.fences.of(locator);
49
+ return stillFenced.has(locator) && (fence === undefined || fence.at < started);
50
+ });
51
+ const relisted = relisting.length === 0
52
+ ? new Set()
53
+ : await store.durably((held) => held.unfence(relisting));
54
+ for (const { locator } of found) {
55
+ const fence = store.fences.of(locator);
56
+ if (fence === undefined || fence.at >= started)
57
+ continue;
58
+ if (relisted.has(locator) || (!stillFenced.has(locator) && !fence.written)) {
59
+ store.fences.lift(locator);
60
+ }
61
+ }
62
+ const kept = await local.held();
63
+ await loseRooms(runtime, found
64
+ .filter((room) => room.replica.admission !== 'admitted' &&
65
+ (kept.held.has(room.locator) || store.installs.of(room.locator).transfer !== null))
66
+ .map((room) => room.locator));
67
+ const listed = found.filter(({ locator }) => !store.fences.has(locator) && (!stillFenced.has(locator) || relisted.has(locator)));
68
+ const listedLocatorsNow = new Set(listed.map((room) => room.locator));
69
+ for (const locator of listedLocatorsNow)
70
+ rooms.stand(locator, { refusal: null });
71
+ if (left === undefined)
72
+ rooms.undiscoverAll();
73
+ for (const room of listed)
74
+ rooms.discover(room);
75
+ const named = new Set(found.map((room) => room.locator));
76
+ await loseRooms(runtime, left ??
77
+ [
78
+ ...new Set([
79
+ ...rooms.declarations().keys(),
80
+ ...kept.held,
81
+ ...store.installs.transferring(),
82
+ ]),
83
+ ].filter((locator) => !named.has(locator)));
84
+ const held = await store.rooms(listed.map((room) => room.locator));
85
+ for (const room of listed) {
86
+ const record = held.get(room.locator)?.record;
87
+ if (record !== undefined && record.replica.selection !== room.replica.selection) {
88
+ listHeld(runtime, room.locator);
89
+ continue;
90
+ }
91
+ list(runtime, room, admitted(runtime, room));
92
+ }
93
+ confirmLocks(runtime, listed);
94
+ socket.session.set({ roomsListed: true });
95
+ emitRooms(runtime);
96
+ await relocked(runtime, lockedBefore);
97
+ return listed;
98
+ }
99
+ async function asked({ socket }, authorized) {
100
+ try {
101
+ return (await socket.discover(authorized)) ?? { kind: 'transport-uncertainty' };
102
+ }
103
+ catch {
104
+ return { kind: 'transport-uncertainty' };
105
+ }
106
+ }
107
+ export async function signIn(runtime, local, signedIn) {
108
+ if (JSON.stringify(signedIn) === JSON.stringify((await local.facts()).member))
109
+ return;
110
+ await local.fact('member', signedIn);
111
+ emitMember(runtime, signedIn);
112
+ }
113
+ export async function discoverRooms(runtime, local, progress, live, found) {
114
+ const { socket, journal } = runtime;
115
+ const { session } = socket;
116
+ const { closed, authorization } = session.now();
117
+ if (closed || authorization === undefined) {
118
+ socket.notifyReady();
119
+ return null;
120
+ }
121
+ moveTo(runtime, transferring(runtime));
122
+ const started = session.now().discoveries + 1;
123
+ session.set({ discoveries: started });
124
+ const result = found ?? (await asked(runtime, authorization));
125
+ if (result.kind === 'discovery')
126
+ session.set({ roomsNamed: true });
127
+ if (!live()) {
128
+ progress.complete = false;
129
+ socket.notifyReady();
130
+ return null;
131
+ }
132
+ journal.record(`connection discover ${result.kind}`);
133
+ if (result.kind === 'transport-uncertainty') {
134
+ await cachedModels(runtime, local);
135
+ progress.reachable = false;
136
+ progress.complete = false;
137
+ socket.notifyReady();
138
+ return null;
139
+ }
140
+ if (result.kind === 'contract-unavailable') {
141
+ journal.record(`connection contract unavailable ${result.code}`);
142
+ await refuse(runtime, 'missing-required-guarantee', {
143
+ code: result.code,
144
+ fields: result.fields,
145
+ retryable: result.retryable,
146
+ });
147
+ socket.notifyReady();
148
+ return null;
149
+ }
150
+ if (result.kind === 'revoked-authorization') {
151
+ await refuse(runtime, 'revoked-authorization');
152
+ socket.notifyReady();
153
+ return null;
154
+ }
155
+ const invalid = malformed(result.rooms);
156
+ if (invalid !== null) {
157
+ journal.record(invalid);
158
+ await refuse(runtime, 'missing-required-guarantee');
159
+ socket.notifyReady();
160
+ return null;
161
+ }
162
+ if (session.now().refusal !== null) {
163
+ session.set({ refusal: null });
164
+ emitRefusal(runtime);
165
+ }
166
+ const held = await local.facts();
167
+ if (JSON.stringify(result.providerLimits) !== JSON.stringify(held.providerLimits) ||
168
+ JSON.stringify(result.capabilities) !== JSON.stringify(held.capabilities)) {
169
+ await local.fact('providerLimits', result.providerLimits);
170
+ await local.fact('capabilities', result.capabilities);
171
+ }
172
+ socket.notifyReady();
173
+ await signIn(runtime, local, result.member ?? null);
174
+ return applyDiscovery(runtime, result.rooms, started);
175
+ }
@@ -1,11 +1,25 @@
1
1
  import type { Persistence } from './readiness.js';
2
+ export type UnsentKind = 'pending-change' | 'call' | 'room-draft' | 'chat-draft';
3
+ export type UnsentWork = {
4
+ readonly kind: UnsentKind;
5
+ readonly count: number;
6
+ };
7
+ export type AppCode = {
8
+ readonly running: number;
9
+ readonly older: number;
10
+ };
11
+ export type HeldCode = {
12
+ readonly house: number | null;
13
+ readonly apps: readonly string[];
14
+ };
2
15
  export type RuntimeShell = {
3
16
  persistence: Persistence;
4
17
  generation: string | null;
5
- onScreen: boolean;
6
18
  keepGeneration(value: string): void | Promise<void>;
7
19
  dropGeneration(): void | Promise<void>;
8
20
  cleanUp?(): Promise<number>;
21
+ measure?(measured: (app: string, code: AppCode | null) => void): Promise<HeldCode>;
22
+ reset(): Promise<void>;
9
23
  };
10
24
  export declare function refusedForSpace(error: unknown): boolean;
11
25
  export declare function detectStorageLoss(stored: string | null, reported: string | null): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrF"}
1
+ {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC;AAEjF,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3F,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGrF"}
package/dist/entry.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { VerifiedModel } from '@agentshouse/mdmodel';
1
+ import { type VerifiedModel } from '@agentshouse/mdmodel';
2
2
  import { type QueryRows } from './query.js';
3
3
  import type { Connection } from './tables.js';
4
- export { QueryError } from './query.js';
4
+ export { QueryError } from '@agentshouse/mdmodel';
5
5
  export type EntryRoom = {
6
6
  locator: string;
7
7
  schema: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AA0D7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAE3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAMpE;AAkCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAmDZ"}
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAGnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AA0D7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAE3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAMpE;AAyCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACzF,CAAC;AAEF,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,UAAU,CAoDZ"}
package/dist/entry.js CHANGED
@@ -1,9 +1,10 @@
1
+ import { invalid, plain, QueryError, } from '@agentshouse/mdmodel';
1
2
  import { attachedModel } from './attached-model.js';
2
3
  import { answerQuery } from './compile.js';
3
- import { NO_MODEL } from './model.js';
4
- import { invalid, planOf, plain, QueryError, } from './query.js';
4
+ import { planWithin } from './query.js';
5
+ import { writtenFacts } from './rows.js';
5
6
  import { entered, REPLICA_TABLES } from './stored.js';
6
- export { QueryError } from './query.js';
7
+ export { QueryError } from '@agentshouse/mdmodel';
7
8
  const PARAMETER = '$param';
8
9
  const KIND = 'as';
9
10
  const INTEGER = /^-?(?:0|[1-9][0-9]*)$/u;
@@ -83,6 +84,7 @@ const SAMPLED = {
83
84
  $all: 'entry',
84
85
  $size: 0,
85
86
  $exists: true,
87
+ $prefix: 'entry',
86
88
  $gt: 0,
87
89
  $gte: 0,
88
90
  $lt: 0,
@@ -98,9 +100,15 @@ function sampled(template, key) {
98
100
  }
99
101
  return template;
100
102
  }
103
+ function entryPlan(query, facts) {
104
+ const plan = planWithin(query, facts);
105
+ if (plan.fileIds !== null)
106
+ invalid('fileIds', 'an entry Room holds no file IDs');
107
+ return plan;
108
+ }
101
109
  export function entryRefusal(template) {
102
110
  try {
103
- planOf(sampled(template, ''), { listed: false, rooms: [] });
111
+ entryPlan(sampled(template, ''), { listed: false, rooms: [] });
104
112
  return null;
105
113
  }
106
114
  catch (error) {
@@ -117,21 +125,23 @@ export function entryScope(rooms, roomTypes, connection) {
117
125
  const model = attachedModel({
118
126
  kind: 'model',
119
127
  snapshot: { identity: room.locator, version: '', schema: room.schema, revision: null },
120
- }, NO_MODEL, roomTypes).state;
128
+ }, roomTypes);
121
129
  held.push({
122
130
  locator: room.locator,
123
131
  available: model.status !== 'unavailable',
124
132
  types: model.status === 'unavailable' ? [] : Object.values(model.types),
125
133
  });
126
- const composition = { model, selection: null };
134
+ const composition = { model, selection: null, typedPaths: [] };
127
135
  const key = entered(connection, room.locator, composition, Object.keys(room.documents)
128
136
  .sort()
129
137
  .map((path) => ({
130
138
  path,
131
139
  content: room.documents[path],
140
+ facts: writtenFacts(path, room.documents[path], composition),
132
141
  binary: null,
133
142
  revision: room.revisions?.[path] ?? null,
134
143
  fileId: null,
144
+ created: null,
135
145
  change: null,
136
146
  written: null,
137
147
  })));
@@ -142,7 +152,7 @@ export function entryScope(rooms, roomTypes, connection) {
142
152
  async results(queries) {
143
153
  const results = {};
144
154
  for (const [name, query] of Object.entries(queries)) {
145
- const plan = planOf(query, planned);
155
+ const plan = entryPlan(query, planned);
146
156
  results[name] = answerQuery(connection, plan, keys.filter(({ locator }) => plan.rooms === null || plan.rooms.includes(locator)));
147
157
  }
148
158
  return results;
@@ -0,0 +1,49 @@
1
+ import type { ChangeSet } from './change-set.js';
2
+ import type { GroupTotal, PendingResult } from './query.js';
3
+ import type { Deliver, Fail } from './reach.js';
4
+ import type { ConversationTally, RoomTally } from './tallies.js';
5
+ import type { QueryRoom } from './tables.js';
6
+ export declare const HOUSE_DIRECTORY = "house";
7
+ export declare const ROOM_TOTALS: {
8
+ readonly outside: readonly ["house"];
9
+ readonly groupBy: readonly ["room"];
10
+ readonly select: {
11
+ readonly size: true;
12
+ };
13
+ };
14
+ export declare const FIGURES_DAY_MS = 86400000;
15
+ export type DayFigures = {
16
+ readonly created: number;
17
+ readonly changed: number;
18
+ readonly chats: number;
19
+ readonly messages: number;
20
+ };
21
+ export type RoomFigures = {
22
+ readonly room: string;
23
+ readonly day: DayFigures;
24
+ readonly total: {
25
+ readonly documents: GroupTotal;
26
+ readonly files: GroupTotal;
27
+ };
28
+ };
29
+ export type Figures = {
30
+ readonly rooms: readonly RoomFigures[];
31
+ readonly agentMessages: number;
32
+ };
33
+ export type FiguresResult = Figures | PendingResult;
34
+ export type FiguresCover = PendingResult | {
35
+ readonly rooms: readonly QueryRoom[];
36
+ };
37
+ export type FiguresSources = {
38
+ cover(): Promise<FiguresCover>;
39
+ rooms(rooms: readonly QueryRoom[], since: string): Promise<readonly RoomTally[]>;
40
+ conversations(conversations: readonly string[] | null, since: string): Promise<readonly ConversationTally[]>;
41
+ };
42
+ export type FiguresRead = {
43
+ watch(deliver: Deliver, fail: Fail): () => void;
44
+ touched(set: ChangeSet): void;
45
+ recover(): void;
46
+ close(): void;
47
+ };
48
+ export declare function createFigures(sources: FiguresSources): FiguresRead;
49
+ //# sourceMappingURL=figures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figures.d.ts","sourceRoot":"","sources":["../src/figures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC,eAAO,MAAM,WAAW;;;;iBAGZ,IAAI;;CACe,CAAC;AAGhC,eAAO,MAAM,cAAc,WAAa,CAAC;AAQzC,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;CAChF,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IACjF,aAAa,CACX,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,EACvC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC9B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAgDF,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAsIlE"}
@@ -0,0 +1,197 @@
1
+ import { instantKey } from '@agentshouse/mdmodel';
2
+ export const HOUSE_DIRECTORY = 'house';
3
+ export const ROOM_TOTALS = {
4
+ outside: [HOUSE_DIRECTORY],
5
+ groupBy: ['room'],
6
+ select: { size: true },
7
+ };
8
+ // Today's Last 24 hours is the day that ends as the read answers.
9
+ export const FIGURES_DAY_MS = 86_400_000;
10
+ // An install or a catch-up commits many times a second, so the figures answer again once changes rest this long, never per commit.
11
+ const SETTLED_MS = 1_000;
12
+ // Changes that never rest, such as an Agent writing all afternoon, still reach the figures this long after the first of them.
13
+ const LONGEST_UNSETTLED_MS = 5_000;
14
+ function dayOf(tally, since) {
15
+ const after = (at) => at !== null && at >= since;
16
+ return {
17
+ created: tally.documentTimes.filter(([created]) => after(created)).length,
18
+ changed: tally.documentTimes.filter(([created, changed]) => !after(created) && after(changed))
19
+ .length,
20
+ chats: tally.chatTimes.filter(after).length,
21
+ messages: tally.messageTimes.filter(after).length,
22
+ };
23
+ }
24
+ function figuresOf(rooms, held, since) {
25
+ return {
26
+ rooms: rooms.map(({ locator }) => {
27
+ const tally = held.rooms.get(locator);
28
+ return {
29
+ room: locator,
30
+ day: dayOf(tally, since),
31
+ total: { documents: tally.documents, files: tally.files },
32
+ };
33
+ }),
34
+ agentMessages: [...held.said.values()].reduce((sum, said) => sum + said.filter((at) => at >= since).length, 0),
35
+ };
36
+ }
37
+ function unheld() {
38
+ return {
39
+ rooms: new Map(),
40
+ said: new Map(),
41
+ staleRooms: new Set(),
42
+ staleConversations: new Set(),
43
+ everyConversation: true,
44
+ };
45
+ }
46
+ export function createFigures(sources) {
47
+ const listeners = new Map();
48
+ const answered = new Set();
49
+ let held = unheld();
50
+ let shown = null;
51
+ let running = false;
52
+ let again = false;
53
+ let quiet = null;
54
+ let longest = null;
55
+ let closed = false;
56
+ function unscheduled() {
57
+ if (quiet !== null)
58
+ clearTimeout(quiet);
59
+ if (longest !== null)
60
+ clearTimeout(longest);
61
+ quiet = null;
62
+ longest = null;
63
+ }
64
+ function deliver(answer) {
65
+ const text = JSON.stringify(answer);
66
+ const changed = text !== shown;
67
+ shown = text;
68
+ for (const listener of listeners.keys()) {
69
+ if (changed || !answered.has(listener))
70
+ listener(structuredClone(answer));
71
+ answered.add(listener);
72
+ }
73
+ }
74
+ async function tallied(rooms, since) {
75
+ for (const locator of held.rooms.keys()) {
76
+ if (!rooms.some((room) => room.locator === locator))
77
+ held.rooms.delete(locator);
78
+ }
79
+ const asked = rooms.filter(({ locator, key }) => held.staleRooms.has(locator) || held.rooms.get(locator)?.key !== key);
80
+ for (const { locator } of asked)
81
+ held.staleRooms.delete(locator);
82
+ const every = held.everyConversation;
83
+ const conversations = every ? null : [...held.staleConversations];
84
+ held.everyConversation = false;
85
+ held.staleConversations.clear();
86
+ const kept = held;
87
+ const [roomTallies, said] = await Promise.all([
88
+ asked.length === 0 ? [] : sources.rooms(asked, since),
89
+ conversations?.length === 0 ? [] : sources.conversations(conversations, since),
90
+ ]);
91
+ if (kept !== held)
92
+ return false;
93
+ for (const tally of roomTallies) {
94
+ const room = asked.find(({ key }) => key === tally.key);
95
+ if (room !== undefined)
96
+ held.rooms.set(room.locator, tally);
97
+ }
98
+ if (every)
99
+ held.said.clear();
100
+ for (const { conversation, said: times } of said) {
101
+ if (times.length === 0)
102
+ held.said.delete(conversation);
103
+ else
104
+ held.said.set(conversation, times);
105
+ }
106
+ return true;
107
+ }
108
+ async function answer() {
109
+ const window = new Date(Date.now() - FIGURES_DAY_MS).toISOString();
110
+ const cover = await sources.cover();
111
+ if ('pending' in cover)
112
+ return cover;
113
+ if (!(await tallied(cover.rooms, window)))
114
+ return null;
115
+ return figuresOf(cover.rooms, held, instantKey(window));
116
+ }
117
+ async function run() {
118
+ if (running) {
119
+ again = true;
120
+ return;
121
+ }
122
+ running = true;
123
+ try {
124
+ do {
125
+ again = false;
126
+ const result = await answer();
127
+ if (closed || listeners.size === 0)
128
+ return;
129
+ if (result === null)
130
+ again = true;
131
+ else
132
+ deliver(result);
133
+ } while (again && !closed && listeners.size > 0);
134
+ }
135
+ catch (error) {
136
+ for (const [listener, failed] of listeners) {
137
+ if (!answered.has(listener))
138
+ failed(error);
139
+ }
140
+ }
141
+ finally {
142
+ running = false;
143
+ }
144
+ }
145
+ function stop(listener) {
146
+ return () => {
147
+ listeners.delete(listener);
148
+ answered.delete(listener);
149
+ if (listeners.size > 0)
150
+ return;
151
+ unscheduled();
152
+ held = unheld();
153
+ shown = null;
154
+ };
155
+ }
156
+ function settle() {
157
+ if (closed || listeners.size === 0)
158
+ return;
159
+ const now = () => {
160
+ unscheduled();
161
+ void run();
162
+ };
163
+ if (quiet !== null)
164
+ clearTimeout(quiet);
165
+ quiet = setTimeout(now, SETTLED_MS);
166
+ longest ??= setTimeout(now, LONGEST_UNSETTLED_MS);
167
+ }
168
+ return {
169
+ watch(listener, failed) {
170
+ listeners.set(listener, failed);
171
+ void run();
172
+ return stop(listener);
173
+ },
174
+ touched(set) {
175
+ if (listeners.size === 0)
176
+ return;
177
+ for (const { locator } of set.documents)
178
+ held.staleRooms.add(locator);
179
+ for (const locator of set.rooms)
180
+ held.staleRooms.add(locator);
181
+ for (const conversation of set.conversations)
182
+ held.staleConversations.add(conversation);
183
+ if (set.documents.length + set.rooms.length + set.conversations.length > 0)
184
+ settle();
185
+ },
186
+ recover() {
187
+ if (listeners.size > 0)
188
+ settle();
189
+ },
190
+ close() {
191
+ closed = true;
192
+ unscheduled();
193
+ listeners.clear();
194
+ answered.clear();
195
+ },
196
+ };
197
+ }
@@ -0,0 +1,29 @@
1
+ import type { AppCode } from './durability.js';
2
+ import type { GroupTotal, PendingResult } from './query.js';
3
+ import type { Deliver, Fail } from './reach.js';
4
+ import type { Runtime } from './runtime.js';
5
+ import type { OpenedRoom } from './tables.js';
6
+ export type RoomDocuments = {
7
+ readonly room: string;
8
+ readonly documents: GroupTotal;
9
+ };
10
+ export type HeldApp = ({
11
+ readonly app: string;
12
+ readonly state: 'measured';
13
+ } & AppCode) | {
14
+ readonly app: string;
15
+ readonly state: 'asking' | 'unknown';
16
+ };
17
+ export type Holdings = {
18
+ readonly rooms: readonly RoomDocuments[] | PendingResult;
19
+ readonly opened: GroupTotal & {
20
+ readonly rooms: readonly OpenedRoom[];
21
+ };
22
+ readonly apps: readonly HeldApp[];
23
+ readonly house: number | null;
24
+ readonly total: number | null;
25
+ readonly cleanUp: number | null;
26
+ };
27
+ export declare const CLEANED_TOPIC = "cleaned";
28
+ export declare function watchHoldings({ store, figures, shell }: Runtime, deliver: Deliver, fail: Fail): () => void;
29
+ //# sourceMappingURL=holdings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"holdings.d.ts","sourceRoot":"","sources":["../src/holdings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,OAAO,GACf,CAAC;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG,OAAO,CAAC,GAChE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,CAAC;IACzD,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAA;KAAE,CAAC;IACxE,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAIF,eAAO,MAAM,aAAa,YAAY,CAAC;AA6CvC,wBAAgB,aAAa,CAC3B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,GACT,MAAM,IAAI,CA4DZ"}