@agentshouse/mdruntime 0.1.0-cf1e7fdb9c600 → 0.1.0-cf281e8224a5d

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 (264) hide show
  1. package/README.md +9 -9
  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 +24 -25
  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 +8 -4
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +207 -76
  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/change.d.ts +1 -0
  20. package/dist/change.d.ts.map +1 -1
  21. package/dist/change.js +4 -2
  22. package/dist/chat-types.d.ts +5 -0
  23. package/dist/chat-types.d.ts.map +1 -0
  24. package/dist/chat-types.js +13 -0
  25. package/dist/client.d.ts +18 -2
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +7 -2
  28. package/dist/compile.d.ts +5 -0
  29. package/dist/compile.d.ts.map +1 -1
  30. package/dist/compile.js +202 -80
  31. package/dist/connection.d.ts +5 -141
  32. package/dist/connection.d.ts.map +1 -1
  33. package/dist/connection.js +101 -5280
  34. package/dist/conversation-live.d.ts +136 -0
  35. package/dist/conversation-live.d.ts.map +1 -0
  36. package/dist/conversation-live.js +248 -0
  37. package/dist/conversation-row.d.ts +33 -0
  38. package/dist/conversation-row.d.ts.map +1 -0
  39. package/dist/conversation-row.js +53 -0
  40. package/dist/conversation.d.ts +29 -35
  41. package/dist/conversation.d.ts.map +1 -1
  42. package/dist/conversation.js +838 -840
  43. package/dist/discovery.d.ts +10 -0
  44. package/dist/discovery.d.ts.map +1 -0
  45. package/dist/discovery.js +175 -0
  46. package/dist/durability.d.ts +15 -0
  47. package/dist/durability.d.ts.map +1 -1
  48. package/dist/entry.d.ts.map +1 -1
  49. package/dist/entry.js +4 -3
  50. package/dist/expectation.d.ts +4 -2
  51. package/dist/expectation.d.ts.map +1 -1
  52. package/dist/expectation.js +33 -11
  53. package/dist/figures.d.ts +49 -0
  54. package/dist/figures.d.ts.map +1 -0
  55. package/dist/figures.js +197 -0
  56. package/dist/holdings.d.ts +29 -0
  57. package/dist/holdings.d.ts.map +1 -0
  58. package/dist/holdings.js +95 -0
  59. package/dist/host.d.ts +1 -0
  60. package/dist/host.d.ts.map +1 -1
  61. package/dist/host.js +11 -4
  62. package/dist/identity.d.ts +0 -1
  63. package/dist/identity.d.ts.map +1 -1
  64. package/dist/identity.js +0 -3
  65. package/dist/index.d.ts +20 -6
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +5 -1
  68. package/dist/install.d.ts +56 -0
  69. package/dist/install.d.ts.map +1 -0
  70. package/dist/install.js +554 -0
  71. package/dist/job.d.ts +20 -1
  72. package/dist/job.d.ts.map +1 -1
  73. package/dist/job.js +26 -0
  74. package/dist/lifecycle.d.ts +7 -0
  75. package/dist/lifecycle.d.ts.map +1 -0
  76. package/dist/lifecycle.js +268 -0
  77. package/dist/listing.d.ts +53 -0
  78. package/dist/listing.d.ts.map +1 -0
  79. package/dist/listing.js +176 -0
  80. package/dist/live.d.ts +4 -4
  81. package/dist/live.d.ts.map +1 -1
  82. package/dist/live.js +52 -16
  83. package/dist/locks.d.ts +9 -0
  84. package/dist/locks.d.ts.map +1 -0
  85. package/dist/locks.js +61 -0
  86. package/dist/log.d.ts +1 -0
  87. package/dist/log.d.ts.map +1 -1
  88. package/dist/lost.d.ts +5 -0
  89. package/dist/lost.d.ts.map +1 -0
  90. package/dist/lost.js +61 -0
  91. package/dist/media.d.ts +1 -1
  92. package/dist/media.d.ts.map +1 -1
  93. package/dist/media.js +3 -3
  94. package/dist/memory.d.ts +3 -1
  95. package/dist/memory.d.ts.map +1 -1
  96. package/dist/memory.js +45 -6
  97. package/dist/messages.d.ts +25 -1
  98. package/dist/messages.d.ts.map +1 -1
  99. package/dist/messages.js +89 -16
  100. package/dist/model.d.ts +1 -7
  101. package/dist/model.d.ts.map +1 -1
  102. package/dist/model.js +0 -6
  103. package/dist/models.d.ts +14 -0
  104. package/dist/models.d.ts.map +1 -0
  105. package/dist/models.js +195 -0
  106. package/dist/observation.d.ts.map +1 -1
  107. package/dist/observation.js +12 -17
  108. package/dist/opened.js +3 -3
  109. package/dist/opening.d.ts +4 -0
  110. package/dist/opening.d.ts.map +1 -0
  111. package/dist/opening.js +57 -0
  112. package/dist/outcome.d.ts +4 -1
  113. package/dist/outcome.d.ts.map +1 -1
  114. package/dist/outcome.js +3 -0
  115. package/dist/overlay.d.ts +1 -0
  116. package/dist/overlay.d.ts.map +1 -1
  117. package/dist/overlay.js +11 -0
  118. package/dist/parts.d.ts +60 -0
  119. package/dist/parts.d.ts.map +1 -0
  120. package/dist/parts.js +126 -0
  121. package/dist/paths.d.ts +1 -0
  122. package/dist/paths.d.ts.map +1 -1
  123. package/dist/paths.js +22 -0
  124. package/dist/preparation.d.ts +20 -0
  125. package/dist/preparation.d.ts.map +1 -0
  126. package/dist/preparation.js +226 -0
  127. package/dist/queries.d.ts +16 -0
  128. package/dist/queries.d.ts.map +1 -0
  129. package/dist/queries.js +272 -0
  130. package/dist/query.d.ts +10 -2
  131. package/dist/query.d.ts.map +1 -1
  132. package/dist/questions.d.ts +34 -0
  133. package/dist/questions.d.ts.map +1 -0
  134. package/dist/questions.js +122 -0
  135. package/dist/reach.d.ts +8 -6
  136. package/dist/reach.d.ts.map +1 -1
  137. package/dist/reach.js +159 -100
  138. package/dist/react.d.ts +11 -1
  139. package/dist/react.d.ts.map +1 -1
  140. package/dist/react.js +10 -1
  141. package/dist/read.d.ts +7 -0
  142. package/dist/read.d.ts.map +1 -0
  143. package/dist/read.js +17 -0
  144. package/dist/readiness.d.ts +0 -1
  145. package/dist/readiness.d.ts.map +1 -1
  146. package/dist/reads.d.ts +37 -0
  147. package/dist/reads.d.ts.map +1 -0
  148. package/dist/reads.js +171 -0
  149. package/dist/recovery.d.ts.map +1 -1
  150. package/dist/recovery.js +9 -1
  151. package/dist/refresh.d.ts +1 -1
  152. package/dist/refresh.d.ts.map +1 -1
  153. package/dist/refresh.js +8 -20
  154. package/dist/refusal.d.ts +5 -0
  155. package/dist/refusal.d.ts.map +1 -0
  156. package/dist/refusal.js +55 -0
  157. package/dist/replica.d.ts +7 -7
  158. package/dist/replica.d.ts.map +1 -1
  159. package/dist/replica.js +51 -19
  160. package/dist/room-draft.d.ts +2 -4
  161. package/dist/room-draft.d.ts.map +1 -1
  162. package/dist/room-draft.js +3 -3
  163. package/dist/room-drafts.d.ts +24 -0
  164. package/dist/room-drafts.d.ts.map +1 -0
  165. package/dist/room-drafts.js +217 -0
  166. package/dist/rows.d.ts +14 -5
  167. package/dist/rows.d.ts.map +1 -1
  168. package/dist/rows.js +50 -58
  169. package/dist/runtime.d.ts +43 -0
  170. package/dist/runtime.d.ts.map +1 -0
  171. package/dist/runtime.js +1 -0
  172. package/dist/save.d.ts +5 -1
  173. package/dist/save.d.ts.map +1 -1
  174. package/dist/save.js +21 -20
  175. package/dist/saves.d.ts +70 -0
  176. package/dist/saves.d.ts.map +1 -0
  177. package/dist/saves.js +1005 -0
  178. package/dist/seed.d.ts +11 -2
  179. package/dist/seed.d.ts.map +1 -1
  180. package/dist/seed.js +71 -1
  181. package/dist/shared.d.ts +1 -6
  182. package/dist/shared.d.ts.map +1 -1
  183. package/dist/shared.js +13 -95
  184. package/dist/shown.d.ts +31 -0
  185. package/dist/shown.d.ts.map +1 -0
  186. package/dist/shown.js +292 -0
  187. package/dist/socket/admission.d.ts +7 -0
  188. package/dist/socket/admission.d.ts.map +1 -0
  189. package/dist/socket/admission.js +39 -0
  190. package/dist/socket/answers.d.ts +6 -0
  191. package/dist/socket/answers.d.ts.map +1 -0
  192. package/dist/socket/answers.js +20 -0
  193. package/dist/socket/lanes.d.ts +20 -0
  194. package/dist/socket/lanes.d.ts.map +1 -0
  195. package/dist/socket/lanes.js +77 -0
  196. package/dist/socket/reads.d.ts +10 -0
  197. package/dist/socket/reads.d.ts.map +1 -0
  198. package/dist/socket/reads.js +31 -0
  199. package/dist/socket/rooms.d.ts +44 -0
  200. package/dist/socket/rooms.d.ts.map +1 -0
  201. package/dist/socket/rooms.js +90 -0
  202. package/dist/socket/session.d.ts +38 -0
  203. package/dist/socket/session.d.ts.map +1 -0
  204. package/dist/socket/session.js +23 -0
  205. package/dist/socket.d.ts +70 -0
  206. package/dist/socket.d.ts.map +1 -0
  207. package/dist/socket.js +175 -0
  208. package/dist/source.d.ts +61 -0
  209. package/dist/source.d.ts.map +1 -0
  210. package/dist/source.js +82 -0
  211. package/dist/status.d.ts +0 -2
  212. package/dist/status.d.ts.map +1 -1
  213. package/dist/status.js +0 -6
  214. package/dist/store/fences.d.ts +16 -0
  215. package/dist/store/fences.d.ts.map +1 -0
  216. package/dist/store/fences.js +26 -0
  217. package/dist/store/installs.d.ts +30 -0
  218. package/dist/store/installs.d.ts.map +1 -0
  219. package/dist/store/installs.js +34 -0
  220. package/dist/store/readiness.d.ts +10 -0
  221. package/dist/store/readiness.d.ts.map +1 -0
  222. package/dist/store/readiness.js +52 -0
  223. package/dist/store/records.d.ts +212 -0
  224. package/dist/store/records.d.ts.map +1 -0
  225. package/dist/store/records.js +431 -0
  226. package/dist/store/room-held.d.ts +8 -0
  227. package/dist/store/room-held.d.ts.map +1 -0
  228. package/dist/store/room-held.js +17 -0
  229. package/dist/store/space.d.ts +11 -0
  230. package/dist/store/space.d.ts.map +1 -0
  231. package/dist/store/space.js +41 -0
  232. package/dist/store/watchers.d.ts +17 -0
  233. package/dist/store/watchers.d.ts.map +1 -0
  234. package/dist/store/watchers.js +56 -0
  235. package/dist/store/writes.d.ts +24 -0
  236. package/dist/store/writes.d.ts.map +1 -0
  237. package/dist/store/writes.js +125 -0
  238. package/dist/store.d.ts +107 -153
  239. package/dist/store.d.ts.map +1 -1
  240. package/dist/store.js +143 -396
  241. package/dist/stored.d.ts +59 -65
  242. package/dist/stored.d.ts.map +1 -1
  243. package/dist/stored.js +255 -149
  244. package/dist/surface.d.ts +88 -0
  245. package/dist/surface.d.ts.map +1 -0
  246. package/dist/surface.js +223 -0
  247. package/dist/sync.d.ts +19 -0
  248. package/dist/sync.d.ts.map +1 -0
  249. package/dist/sync.js +532 -0
  250. package/dist/tables.d.ts +114 -51
  251. package/dist/tables.d.ts.map +1 -1
  252. package/dist/tables.js +209 -57
  253. package/dist/tallies.d.ts +18 -0
  254. package/dist/tallies.d.ts.map +1 -0
  255. package/dist/tallies.js +129 -0
  256. package/dist/validation.d.ts.map +1 -1
  257. package/dist/validation.js +4 -4
  258. package/dist/wire.d.ts +16 -1
  259. package/dist/wire.d.ts.map +1 -1
  260. package/dist/wire.js +6 -0
  261. package/package.json +2 -2
  262. package/dist/fence.d.ts +0 -6
  263. package/dist/fence.d.ts.map +0 -1
  264. package/dist/fence.js +0 -10
@@ -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,10 +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
18
  keepGeneration(value: string): void | Promise<void>;
6
19
  dropGeneration(): void | Promise<void>;
7
20
  cleanUp?(): Promise<number>;
21
+ measure?(measured: (app: string, code: AppCode | null) => void): Promise<HeldCode>;
22
+ reset(): Promise<void>;
8
23
  };
9
24
  export declare function refusedForSpace(error: unknown): boolean;
10
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,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"}
@@ -1 +1 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEnE,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"}
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,8 +1,8 @@
1
1
  import { invalid, plain, QueryError, } from '@agentshouse/mdmodel';
2
2
  import { attachedModel } from './attached-model.js';
3
3
  import { answerQuery } from './compile.js';
4
- import { NO_MODEL } from './model.js';
5
4
  import { planWithin } from './query.js';
5
+ import { writtenFacts } from './rows.js';
6
6
  import { entered, REPLICA_TABLES } from './stored.js';
7
7
  export { QueryError } from '@agentshouse/mdmodel';
8
8
  const PARAMETER = '$param';
@@ -125,7 +125,7 @@ export function entryScope(rooms, roomTypes, connection) {
125
125
  const model = attachedModel({
126
126
  kind: 'model',
127
127
  snapshot: { identity: room.locator, version: '', schema: room.schema, revision: null },
128
- }, NO_MODEL, roomTypes).state;
128
+ }, roomTypes);
129
129
  held.push({
130
130
  locator: room.locator,
131
131
  available: model.status !== 'unavailable',
@@ -137,10 +137,11 @@ export function entryScope(rooms, roomTypes, connection) {
137
137
  .map((path) => ({
138
138
  path,
139
139
  content: room.documents[path],
140
- outline: null,
140
+ facts: writtenFacts(path, room.documents[path], composition),
141
141
  binary: null,
142
142
  revision: room.revisions?.[path] ?? null,
143
143
  fileId: null,
144
+ created: null,
144
145
  change: null,
145
146
  written: null,
146
147
  })));
@@ -7,9 +7,11 @@ export type Expecting<E extends {
7
7
  subscribe(listener: () => void): () => void;
8
8
  version(): number;
9
9
  begin(): number;
10
- expect(act: number, expected: ExpectedOf<E>, settled?: (one: E) => boolean): void;
10
+ expect(act: number, expected: ExpectedOf<E>): void;
11
11
  drop(act: number): void;
12
- heard(shown: (one: E) => boolean): void;
12
+ reads(reader: string, asks: (one: E) => boolean): void;
13
+ heard(reader: string, shown: (one: E) => boolean): void;
14
+ left(reader: string): void;
13
15
  drawn(): readonly E[];
14
16
  };
15
17
  export declare function expectedList<E extends {
@@ -1 +1 @@
1
- {"version":3,"file":"expectation.d.ts","sourceRoot":"","sources":["../src/expectation.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;AAErF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,IAAI;IAC1D,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC;IAClF,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC;IACxC,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC;CACvB,CAAC;AAIF,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC7D,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,SAAS,CAAC,EAAE,CAGd;AAwBD,wBAAgB,SAAS,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,SAAS,CAAC,CAAC,CAAC,CA4C5E"}
1
+ {"version":3,"file":"expectation.d.ts","sourceRoot":"","sources":["../src/expectation.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;AAErF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,IAAI;IAC1D,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC;IACvD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,CAAC;IACxD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC;CACvB,CAAC;AAQF,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC7D,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,SAAS,CAAC,EAAE,CAGd;AAwBD,wBAAgB,SAAS,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,SAAS,CAAC,CAAC,CAAC,CAmE5E"}
@@ -1,3 +1,4 @@
1
+ const NONE = () => false;
1
2
  export function expectedList(expected) {
2
3
  if (expected === null)
3
4
  return [];
@@ -13,7 +14,7 @@ function unended(entries, ends) {
13
14
  for (const one of [...entries].reverse()) {
14
15
  if (ended.has(one.expectation.key))
15
16
  continue;
16
- if (ends(one.expectation))
17
+ if (ends(one))
17
18
  ended.add(one.expectation.key);
18
19
  else
19
20
  kept.unshift(one);
@@ -24,6 +25,7 @@ export function expecting() {
24
25
  let entries = [];
25
26
  let version = 0;
26
27
  let acts = 0;
28
+ const readers = new Map();
27
29
  const listeners = new Set();
28
30
  const set = (next) => {
29
31
  if (next.length === entries.length && next.every((one, at) => one === entries[at]))
@@ -33,6 +35,19 @@ export function expecting() {
33
35
  for (const listener of listeners)
34
36
  listener();
35
37
  };
38
+ const settle = (next) => {
39
+ for (const entry of next)
40
+ for (const [id, reader] of readers)
41
+ if (reader.asks(entry.expectation) && reader.shown(entry.expectation))
42
+ entry.seen.add(id);
43
+ set(unended(next, (entry) => {
44
+ const asking = [...readers].filter(([, reader]) => reader.asks(entry.expectation));
45
+ const seen = asking.filter(([id]) => entry.seen.has(id));
46
+ return (seen.length > 0 &&
47
+ (seen.length === asking.length ||
48
+ seen.some(([, reader]) => !reader.shown(entry.expectation))));
49
+ }));
50
+ };
36
51
  return {
37
52
  subscribe(listener) {
38
53
  listeners.add(listener);
@@ -45,25 +60,32 @@ export function expecting() {
45
60
  acts += 1;
46
61
  return acts;
47
62
  },
48
- expect(act, expected, settled = () => false) {
63
+ expect(act, expected) {
49
64
  const fresh = expectedList(expected);
50
65
  if (fresh.length === 0)
51
66
  return;
52
67
  const keys = new Set(fresh.map((one) => one.key));
53
- const kept = entries.filter((one) => one.act !== act || !keys.has(one.expectation.key));
54
- const over = new Set(kept.map((one) => one.expectation.key));
55
- set([
56
- ...kept,
57
- ...fresh
58
- .filter((one) => over.has(one.key) || !settled(one))
59
- .map((expectation) => ({ act, expectation })),
68
+ settle([
69
+ ...entries.filter((one) => one.act !== act || !keys.has(one.expectation.key)),
70
+ ...fresh.map((expectation) => ({ act, expectation, seen: new Set() })),
60
71
  ]);
61
72
  },
62
73
  drop(act) {
63
74
  set(entries.filter((one) => one.act !== act));
64
75
  },
65
- heard(shown) {
66
- set(unended(entries, shown));
76
+ reads(reader, asks) {
77
+ readers.set(reader, { asks, shown: readers.get(reader)?.shown ?? NONE });
78
+ settle(entries);
79
+ },
80
+ heard(reader, shown) {
81
+ readers.set(reader, { asks: readers.get(reader)?.asks ?? NONE, shown });
82
+ settle(entries);
83
+ },
84
+ left(reader) {
85
+ readers.delete(reader);
86
+ for (const entry of entries)
87
+ entry.seen.delete(reader);
88
+ settle(entries);
67
89
  },
68
90
  drawn: () => entries.flatMap((one, at) => (superseded(entries, at) ? [] : [one.expectation])),
69
91
  };
@@ -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"}