@agentshouse/mdruntime 0.1.0-cd507e16e5fc0 → 0.1.0-cd574a610e9c8

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 (269) hide show
  1. package/README.md +21 -19
  2. package/dist/acceptance.d.ts +0 -3
  3. package/dist/acceptance.d.ts.map +1 -1
  4. package/dist/acceptance.js +75 -165
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +8 -2
  9. package/dist/actions.d.ts.map +1 -1
  10. package/dist/actions.js +118 -67
  11. package/dist/adapter.d.ts +90 -58
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +0 -1
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +0 -5
  16. package/dist/authored.d.ts +88 -0
  17. package/dist/authored.d.ts.map +1 -0
  18. package/dist/authored.js +345 -0
  19. package/dist/bootstrap.d.ts +1 -1
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +6 -19
  22. package/dist/change-set.d.ts +4 -0
  23. package/dist/change-set.d.ts.map +1 -1
  24. package/dist/change-set.js +6 -0
  25. package/dist/change.d.ts +4 -0
  26. package/dist/change.d.ts.map +1 -1
  27. package/dist/change.js +7 -2
  28. package/dist/chat-types.d.ts +0 -2
  29. package/dist/chat-types.d.ts.map +1 -1
  30. package/dist/chat-types.js +0 -2
  31. package/dist/client.d.ts +13 -20
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +36 -20
  34. package/dist/collection.d.ts +25 -4
  35. package/dist/collection.d.ts.map +1 -1
  36. package/dist/collection.js +19 -2
  37. package/dist/column.d.ts +5 -0
  38. package/dist/column.d.ts.map +1 -0
  39. package/dist/column.js +9 -0
  40. package/dist/compile.d.ts +2 -0
  41. package/dist/compile.d.ts.map +1 -1
  42. package/dist/compile.js +31 -25
  43. package/dist/connection.d.ts.map +1 -1
  44. package/dist/connection.js +31 -24
  45. package/dist/context.d.ts.map +1 -1
  46. package/dist/context.js +1 -1
  47. package/dist/conversation-live.d.ts +26 -12
  48. package/dist/conversation-live.d.ts.map +1 -1
  49. package/dist/conversation-live.js +23 -12
  50. package/dist/conversation-row.d.ts +8 -1
  51. package/dist/conversation-row.d.ts.map +1 -1
  52. package/dist/conversation-row.js +20 -7
  53. package/dist/conversation.d.ts +37 -12
  54. package/dist/conversation.d.ts.map +1 -1
  55. package/dist/conversation.js +320 -234
  56. package/dist/declaration.d.ts +10 -0
  57. package/dist/declaration.d.ts.map +1 -0
  58. package/dist/declaration.js +24 -0
  59. package/dist/discovery.d.ts.map +1 -1
  60. package/dist/discovery.js +19 -44
  61. package/dist/durability.d.ts +4 -0
  62. package/dist/durability.d.ts.map +1 -1
  63. package/dist/durability.js +4 -0
  64. package/dist/entry.js +1 -1
  65. package/dist/expectation.d.ts +26 -13
  66. package/dist/expectation.d.ts.map +1 -1
  67. package/dist/expectation.js +72 -19
  68. package/dist/failure.d.ts +3 -0
  69. package/dist/failure.d.ts.map +1 -1
  70. package/dist/failure.js +6 -0
  71. package/dist/figures.d.ts.map +1 -1
  72. package/dist/figures.js +4 -2
  73. package/dist/file.d.ts +1 -1
  74. package/dist/file.d.ts.map +1 -1
  75. package/dist/file.js +3 -2
  76. package/dist/host.d.ts +18 -2
  77. package/dist/host.d.ts.map +1 -1
  78. package/dist/host.js +59 -15
  79. package/dist/index.d.ts +16 -11
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +12 -7
  82. package/dist/install.d.ts +10 -6
  83. package/dist/install.d.ts.map +1 -1
  84. package/dist/install.js +92 -111
  85. package/dist/lifecycle.d.ts +1 -1
  86. package/dist/lifecycle.d.ts.map +1 -1
  87. package/dist/lifecycle.js +54 -40
  88. package/dist/listing.d.ts +11 -12
  89. package/dist/listing.d.ts.map +1 -1
  90. package/dist/listing.js +48 -72
  91. package/dist/live.d.ts +5 -3
  92. package/dist/live.d.ts.map +1 -1
  93. package/dist/live.js +74 -33
  94. package/dist/loaded.d.ts +5 -0
  95. package/dist/loaded.d.ts.map +1 -0
  96. package/dist/loaded.js +40 -0
  97. package/dist/locks.d.ts +2 -4
  98. package/dist/locks.d.ts.map +1 -1
  99. package/dist/locks.js +10 -39
  100. package/dist/lost.d.ts.map +1 -1
  101. package/dist/lost.js +11 -23
  102. package/dist/media.d.ts +6 -1
  103. package/dist/media.d.ts.map +1 -1
  104. package/dist/media.js +68 -17
  105. package/dist/memory.d.ts +8 -3
  106. package/dist/memory.d.ts.map +1 -1
  107. package/dist/memory.js +92 -33
  108. package/dist/messages.d.ts +12 -6
  109. package/dist/messages.d.ts.map +1 -1
  110. package/dist/messages.js +30 -38
  111. package/dist/model.d.ts +0 -1
  112. package/dist/model.d.ts.map +1 -1
  113. package/dist/model.js +0 -5
  114. package/dist/models.d.ts +4 -8
  115. package/dist/models.d.ts.map +1 -1
  116. package/dist/models.js +97 -139
  117. package/dist/observation.d.ts +27 -12
  118. package/dist/observation.d.ts.map +1 -1
  119. package/dist/observation.js +184 -85
  120. package/dist/opened.d.ts +1 -1
  121. package/dist/opened.d.ts.map +1 -1
  122. package/dist/opened.js +5 -5
  123. package/dist/opening.d.ts.map +1 -1
  124. package/dist/opening.js +5 -9
  125. package/dist/outcome.d.ts +13 -1
  126. package/dist/outcome.d.ts.map +1 -1
  127. package/dist/outcome.js +32 -2
  128. package/dist/overlay.d.ts +6 -2
  129. package/dist/overlay.d.ts.map +1 -1
  130. package/dist/overlay.js +37 -24
  131. package/dist/page-metadata.d.ts +8 -0
  132. package/dist/page-metadata.d.ts.map +1 -0
  133. package/dist/page-metadata.js +19 -0
  134. package/dist/parts.d.ts +3 -58
  135. package/dist/parts.d.ts.map +1 -1
  136. package/dist/parts.js +10 -115
  137. package/dist/preparation.d.ts +27 -6
  138. package/dist/preparation.d.ts.map +1 -1
  139. package/dist/preparation.js +156 -68
  140. package/dist/presence.d.ts +58 -0
  141. package/dist/presence.d.ts.map +1 -0
  142. package/dist/presence.js +231 -0
  143. package/dist/queries.d.ts +2 -2
  144. package/dist/queries.d.ts.map +1 -1
  145. package/dist/queries.js +67 -31
  146. package/dist/query.d.ts +0 -1
  147. package/dist/query.d.ts.map +1 -1
  148. package/dist/questions.d.ts +1 -5
  149. package/dist/questions.d.ts.map +1 -1
  150. package/dist/questions.js +1 -7
  151. package/dist/queue.d.ts +40 -0
  152. package/dist/queue.d.ts.map +1 -0
  153. package/dist/queue.js +480 -0
  154. package/dist/reach.d.ts +2 -3
  155. package/dist/reach.d.ts.map +1 -1
  156. package/dist/reach.js +88 -26
  157. package/dist/react.d.ts +8 -1
  158. package/dist/react.d.ts.map +1 -1
  159. package/dist/react.js +33 -1
  160. package/dist/readiness.d.ts +9 -3
  161. package/dist/readiness.d.ts.map +1 -1
  162. package/dist/readiness.js +3 -5
  163. package/dist/reads.d.ts +4 -2
  164. package/dist/reads.d.ts.map +1 -1
  165. package/dist/reads.js +11 -4
  166. package/dist/recovery.d.ts +3 -1
  167. package/dist/recovery.d.ts.map +1 -1
  168. package/dist/recovery.js +29 -7
  169. package/dist/refresh.js +2 -2
  170. package/dist/refusal.d.ts.map +1 -1
  171. package/dist/refusal.js +5 -6
  172. package/dist/replica.d.ts +5 -11
  173. package/dist/replica.d.ts.map +1 -1
  174. package/dist/replica.js +15 -17
  175. package/dist/retried.d.ts +30 -0
  176. package/dist/retried.d.ts.map +1 -0
  177. package/dist/retried.js +72 -0
  178. package/dist/room-draft.d.ts +31 -8
  179. package/dist/room-draft.d.ts.map +1 -1
  180. package/dist/room-draft.js +273 -66
  181. package/dist/room-drafts.d.ts.map +1 -1
  182. package/dist/room-drafts.js +22 -18
  183. package/dist/room-list.d.ts +10 -0
  184. package/dist/room-list.d.ts.map +1 -0
  185. package/dist/room-list.js +45 -0
  186. package/dist/rows.d.ts +2 -1
  187. package/dist/rows.d.ts.map +1 -1
  188. package/dist/rows.js +9 -10
  189. package/dist/runtime.d.ts +9 -18
  190. package/dist/runtime.d.ts.map +1 -1
  191. package/dist/save.d.ts +42 -90
  192. package/dist/save.d.ts.map +1 -1
  193. package/dist/save.js +327 -229
  194. package/dist/saves.d.ts +4 -40
  195. package/dist/saves.d.ts.map +1 -1
  196. package/dist/saves.js +143 -714
  197. package/dist/seed.d.ts.map +1 -1
  198. package/dist/seed.js +4 -5
  199. package/dist/shared.d.ts +0 -5
  200. package/dist/shared.d.ts.map +1 -1
  201. package/dist/shared.js +4 -90
  202. package/dist/shown.d.ts +7 -5
  203. package/dist/shown.d.ts.map +1 -1
  204. package/dist/shown.js +77 -63
  205. package/dist/socket/lanes.d.ts +12 -4
  206. package/dist/socket/lanes.d.ts.map +1 -1
  207. package/dist/socket/lanes.js +34 -8
  208. package/dist/socket/session.d.ts +0 -1
  209. package/dist/socket/session.d.ts.map +1 -1
  210. package/dist/socket.d.ts +3 -6
  211. package/dist/socket.d.ts.map +1 -1
  212. package/dist/socket.js +5 -16
  213. package/dist/source.d.ts +5 -7
  214. package/dist/source.d.ts.map +1 -1
  215. package/dist/source.js +18 -6
  216. package/dist/store/installs.d.ts +2 -2
  217. package/dist/store/installs.d.ts.map +1 -1
  218. package/dist/store/installs.js +10 -4
  219. package/dist/store/readiness.d.ts +5 -4
  220. package/dist/store/readiness.d.ts.map +1 -1
  221. package/dist/store/readiness.js +28 -12
  222. package/dist/store/records.d.ts +18 -7
  223. package/dist/store/records.d.ts.map +1 -1
  224. package/dist/store/records.js +58 -24
  225. package/dist/store/rooms-shown.d.ts +8 -0
  226. package/dist/store/rooms-shown.d.ts.map +1 -0
  227. package/dist/store/rooms-shown.js +13 -0
  228. package/dist/store/space.d.ts +1 -1
  229. package/dist/store/space.d.ts.map +1 -1
  230. package/dist/store/space.js +0 -2
  231. package/dist/store/watchers.js +1 -2
  232. package/dist/store.d.ts +23 -14
  233. package/dist/store.d.ts.map +1 -1
  234. package/dist/store.js +46 -17
  235. package/dist/stored.d.ts +25 -14
  236. package/dist/stored.d.ts.map +1 -1
  237. package/dist/stored.js +83 -32
  238. package/dist/surface.d.ts +5 -3
  239. package/dist/surface.d.ts.map +1 -1
  240. package/dist/surface.js +25 -23
  241. package/dist/sync.d.ts +1 -1
  242. package/dist/sync.d.ts.map +1 -1
  243. package/dist/sync.js +96 -92
  244. package/dist/tables.d.ts +16 -57
  245. package/dist/tables.d.ts.map +1 -1
  246. package/dist/tables.js +91 -332
  247. package/dist/tallies.d.ts.map +1 -1
  248. package/dist/tallies.js +6 -7
  249. package/dist/validation.d.ts.map +1 -1
  250. package/dist/validation.js +4 -10
  251. package/dist/wire.d.ts +53 -7
  252. package/dist/wire.d.ts.map +1 -1
  253. package/dist/wire.js +17 -4
  254. package/package.json +3 -2
  255. package/dist/attempt.d.ts +0 -16
  256. package/dist/attempt.d.ts.map +0 -1
  257. package/dist/attempt.js +0 -70
  258. package/dist/job.d.ts +0 -33
  259. package/dist/job.d.ts.map +0 -1
  260. package/dist/job.js +0 -54
  261. package/dist/log.d.ts +0 -6
  262. package/dist/log.d.ts.map +0 -1
  263. package/dist/log.js +0 -14
  264. package/dist/socket/rooms.d.ts +0 -44
  265. package/dist/socket/rooms.d.ts.map +0 -1
  266. package/dist/socket/rooms.js +0 -90
  267. package/dist/store/fences.d.ts +0 -16
  268. package/dist/store/fences.d.ts.map +0 -1
  269. package/dist/store/fences.js +0 -26
package/dist/messages.js CHANGED
@@ -1,16 +1,17 @@
1
1
  import { sql } from '@agentshouse/mdmodel';
2
+ import { text } from './column.js';
2
3
  import { EXCERPT } from './read.js';
4
+ import { tablesOf } from './stored.js';
3
5
  const SAID_BY_HOUSE = `json_extract(message, '$.role') = 'house'`;
4
6
  const ANSWERS_THE_TURN = `json_extract(message, '$.role') = 'assistant'`;
5
- const MARKS_A_JOB = `instr(message, '"marker":"job"') > 0`;
6
7
  export const MESSAGE_TABLES = [
7
8
  'CREATE TABLE conversation_reads (conversation TEXT PRIMARY KEY, read TEXT, partial INTEGER NOT NULL) WITHOUT ROWID',
8
- 'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
9
+ 'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, change TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
9
10
  'CREATE UNIQUE INDEX conversation_messages_identity ON conversation_messages (conversation, identity)',
10
11
  'CREATE INDEX conversation_messages_position ON conversation_messages (conversation, position, identity)',
11
12
  'CREATE INDEX conversation_messages_turn ON conversation_messages (conversation, turn)',
12
13
  `CREATE INDEX conversation_messages_house ON conversation_messages (conversation, position, identity) WHERE ${SAID_BY_HOUSE}`,
13
- `CREATE INDEX conversation_messages_jobs ON conversation_messages (conversation, position, identity) WHERE ${MARKS_A_JOB}`,
14
+ 'CREATE TABLE conversation_facts (conversation TEXT NOT NULL, name TEXT NOT NULL, value TEXT NOT NULL, PRIMARY KEY (conversation, name)) WITHOUT ROWID',
14
15
  ];
15
16
  const NEWEST_FIRST = 'ORDER BY position DESC, identity DESC LIMIT 1';
16
17
  const OLDEST_FIRST = 'ORDER BY position, identity LIMIT 1';
@@ -27,7 +28,9 @@ export const ROWS = `WITH chosen AS (
27
28
  substr(said.text, 1, ${EXCERPT}) AS said_text,
28
29
  json_extract(said.message, '$.role') AS said_role,
29
30
  json_extract(said.message, '$.accepted_at') AS said_at,
31
+ answer.turn AS answered,
30
32
  substr(json_extract(answer.message, '$.failure'), 1, ${EXCERPT}) AS failure,
33
+ (SELECT value FROM conversation_facts WHERE conversation = chosen.conversation AND name = 'openedTurn') AS opened_turn,
31
34
  json_extract(opened.message, '$.source') AS opened_source,
32
35
  json_extract(opened.message, '$.sender') AS opened_sender,
33
36
  asking.identity AS asking_identity,
@@ -40,16 +43,6 @@ export const ROWS = `WITH chosen AS (
40
43
  LEFT JOIN conversation_messages answer ON answer.id = chosen.answer
41
44
  LEFT JOIN conversation_messages opened ON opened.id = chosen.opened
42
45
  LEFT JOIN conversation_messages asking ON asking.id = chosen.asking`;
43
- export const JOB_MARKERS = `SELECT json_extract(part.value, '$.text') AS said,
44
- json_extract(message, '$.accepted_at') AS at
45
- FROM conversation_messages, json_each(message, '$.parts') AS part
46
- WHERE conversation = ? AND ${MARKS_A_JOB}
47
- AND json_extract(part.value, '$.type') = 'marker'
48
- AND json_extract(part.value, '$.marker') = 'job'
49
- ORDER BY position, identity, part.key`;
50
- function text(value) {
51
- return typeof value === 'string' ? value : String(value);
52
- }
53
46
  export function heldConversations(connection, conversations) {
54
47
  const named = conversations === null ? '' : ' AND conversation IN (SELECT value FROM json_each(?))';
55
48
  const bound = conversations === null ? [] : [JSON.stringify(conversations)];
@@ -72,19 +65,15 @@ export function heldConversations(connection, conversations) {
72
65
  }
73
66
  export function keptMessages(connection, { conversation, messages, read }) {
74
67
  for (const message of messages) {
75
- const [held] = connection.rows('SELECT id FROM conversation_messages WHERE conversation = ? AND identity = ?', [conversation, message.identity]);
76
- const record = [
68
+ connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, change, message, text) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (conversation, identity) DO UPDATE SET turn = excluded.turn, position = excluded.position, change = excluded.change, message = excluded.message, text = excluded.text', [
69
+ conversation,
70
+ message.identity,
77
71
  message.turn,
78
72
  message.position,
73
+ message.change,
79
74
  JSON.stringify(message.message ?? null),
80
75
  message.text,
81
- ];
82
- if (held === undefined) {
83
- connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, message, text) VALUES (?, ?, ?, ?, ?, ?)', [conversation, message.identity, ...record]);
84
- }
85
- else {
86
- connection.run('UPDATE conversation_messages SET turn = ?, position = ?, message = ?, text = ? WHERE id = ?', [...record, held.id]);
87
- }
76
+ ]);
88
77
  }
89
78
  if (read !== undefined) {
90
79
  connection.run('INSERT OR REPLACE INTO conversation_reads (conversation, read, partial) VALUES (?, ?, ?)', [conversation, read.at, read.partial ? 1 : 0]);
@@ -96,6 +85,7 @@ function accepted(row) {
96
85
  identity: text(row.identity),
97
86
  turn: text(row.turn),
98
87
  position: text(row.position),
88
+ change: text(row.change),
99
89
  text: text(row.text),
100
90
  message: JSON.parse(text(row.message)),
101
91
  };
@@ -107,7 +97,7 @@ function holding(phrase) {
107
97
  }
108
98
  export function messageWindow(connection, conversation, limit, before, phrase) {
109
99
  const held = holding(phrase);
110
- const rows = connection.rows(`SELECT identity, turn, position, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
100
+ const rows = connection.rows(`SELECT identity, turn, position, change, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
111
101
  ? [conversation, ...held.bind, limit + 1]
112
102
  : [conversation, ...held.bind, before[0], before[0], before[1], limit + 1]);
113
103
  return { messages: rows.slice(0, limit).map(accepted).reverse(), more: rows.length > limit };
@@ -118,11 +108,11 @@ export function messageCount(connection, conversation, phrase) {
118
108
  return Number(counted?.held ?? 0);
119
109
  }
120
110
  function textOrNull(value) {
121
- return value === null || value === undefined ? null : text(value);
111
+ return value === null ? null : text(value);
122
112
  }
123
113
  function heldSource(source, sender) {
124
114
  return {
125
- source: source === null || source === undefined ? null : JSON.parse(text(source)),
115
+ source: source === null ? null : JSON.parse(text(source)),
126
116
  sender: textOrNull(sender),
127
117
  };
128
118
  }
@@ -136,6 +126,8 @@ export function conversationRows(connection, conversations) {
136
126
  role: textOrNull(row.said_role),
137
127
  at: textOrNull(row.said_at),
138
128
  },
129
+ answered: textOrNull(row.answered),
130
+ openedTurn: textOrNull(row.opened_turn),
139
131
  failure: textOrNull(row.failure),
140
132
  opened: row.opened_source === null ? null : heldSource(row.opened_source, row.opened_sender),
141
133
  asking: row.asking_identity === null
@@ -148,21 +140,21 @@ export function conversationRows(connection, conversations) {
148
140
  },
149
141
  }));
150
142
  }
151
- export function jobMarkers(connection, conversation) {
152
- return connection
153
- .rows(JOB_MARKERS, [conversation])
154
- .map((row) => ({ said: text(row.said), at: text(row.at) }));
155
- }
156
143
  export function turnArrived(connection, conversation, turn) {
157
144
  return (connection.rows('SELECT 1 FROM conversation_messages WHERE conversation = ? AND turn = ? LIMIT 1', [conversation, turn]).length > 0);
158
145
  }
159
- export function droppedMessages(connection, conversations) {
160
- for (const conversation of conversations) {
161
- connection.run('DELETE FROM conversation_messages WHERE conversation = ?', [conversation]);
162
- connection.run('DELETE FROM conversation_reads WHERE conversation = ?', [conversation]);
163
- }
146
+ export function conversationFacts(connection) {
147
+ return connection.rows('SELECT conversation, name, value FROM conversation_facts').map((row) => ({
148
+ conversation: text(row.conversation),
149
+ name: text(row.name),
150
+ value: text(row.value),
151
+ }));
152
+ }
153
+ export function keptFact(connection, { conversation, name, value }) {
154
+ connection.run('INSERT OR REPLACE INTO conversation_facts (conversation, name, value) VALUES (?, ?, ?)', [conversation, name, value]);
155
+ return null;
164
156
  }
165
- export function forgottenMessages(connection) {
166
- connection.run('DELETE FROM conversation_messages');
167
- connection.run('DELETE FROM conversation_reads');
157
+ export function forgottenConversations(connection) {
158
+ for (const table of tablesOf(MESSAGE_TABLES))
159
+ connection.run(`DELETE FROM ${table}`);
168
160
  }
package/dist/model.d.ts CHANGED
@@ -50,7 +50,6 @@ export type ValidationReceipt = {
50
50
  source: Open<'current' | 'cached'>;
51
51
  };
52
52
  export declare const NO_MODEL: ModelState;
53
- export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
54
53
  export declare function modelTypes(state: ModelState): TypesResult;
55
54
  export declare function storedModel(state: ModelState): StoredModel;
56
55
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC5E;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAGhG;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAI1D"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC5E;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAI1D"}
package/dist/model.js CHANGED
@@ -1,9 +1,4 @@
1
1
  export const NO_MODEL = { status: 'unavailable', reason: 'not-acquired' };
2
- export function definitionOf(state, type) {
3
- if (state.status === 'unavailable' || type === undefined)
4
- return undefined;
5
- return Object.hasOwn(state.types, type) ? state.types[type] : undefined;
6
- }
7
2
  export function modelTypes(state) {
8
3
  return state.status === 'unavailable'
9
4
  ? { ...state, types: null }
package/dist/models.d.ts CHANGED
@@ -1,14 +1,10 @@
1
- import type { ScopedRefusal } from './adapter.js';
1
+ import type { RoomDeclaration, ScopedRefusal } from './adapter.js';
2
2
  import { type ModelState } from './model.js';
3
- import { type ReplicaRecord } from './replica.js';
4
3
  import type { Runtime } from './runtime.js';
5
- import type { RoomDeclaration } from './socket.js';
6
4
  import type { RuntimeStore } from './store.js';
7
- export declare function declaredAsHeld(held: ReplicaRecord | undefined, room: RoomDeclaration): boolean;
8
5
  export declare function revoked(model: ModelState | undefined): boolean;
9
- export declare function keepNaming(runtime: Runtime, local: RuntimeStore, room: RoomDeclaration): Promise<void>;
10
- export declare function retainModel(runtime: Runtime, local: RuntimeStore, room: RoomDeclaration, given: ModelState | null): Promise<void>;
11
- export declare function scoped(runtime: Runtime, result: ScopedRefusal, room: RoomDeclaration, local: RuntimeStore): Promise<void>;
12
- export declare function settleModels(runtime: Runtime, held: readonly RoomDeclaration[], status: 'current' | 'cached', local: RuntimeStore): Promise<void>;
6
+ export declare function retainModel(runtime: Runtime, locator: string, declaration: RoomDeclaration, given: ModelState | null, refused?: true): Promise<void>;
7
+ export declare function scoped(runtime: Runtime, result: ScopedRefusal, locator: string, declaration: RoomDeclaration): Promise<void>;
8
+ export declare function settleModels(runtime: Runtime, held: ReadonlyMap<string, RoomDeclaration>, status: 'current' | 'cached', local: RuntimeStore): Promise<void>;
13
9
  export declare function cachedModels(runtime: Runtime, local: RuntimeStore): Promise<void>;
14
10
  //# sourceMappingURL=models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAKlD,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAS9F;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAE9D;AAMD,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,iBAqB5F;AAMD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,UAAU,GAAG,IAAI,iBAuDzB;AAED,wBAAsB,MAAM,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,YAAY,iBA0BpB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,eAAe,EAAE,EAChC,MAAM,EAAE,SAAS,GAAG,QAAQ,EAC5B,KAAK,EAAE,YAAY,iBAsDpB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvF"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAOnE,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAc,YAAY,EAAS,MAAM,YAAY,CAAC;AAMlE,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAE9D;AA0DD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,eAAe,EAC5B,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE,IAAI,iBA2Bf;AAED,wBAAsB,MAAM,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,eAAe,iBAkB7B;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAC1C,MAAM,EAAE,SAAS,GAAG,QAAQ,EAC5B,KAAK,EAAE,YAAY,iBAkDpB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBvF"}
package/dist/models.js CHANGED
@@ -1,195 +1,153 @@
1
+ import { equalValue } from '@agentshouse/mdmodel';
1
2
  import { changeSet } from './change-set.js';
2
3
  import { composedOf } from './collection.js';
3
- import { admitted, declarationOf, list, listedLocators } from './listing.js';
4
+ import { declared, sameDeclaration } from './declaration.js';
5
+ import { uncaught } from './failure.js';
6
+ import { declarationOf, listedLocators } from './listing.js';
4
7
  import { loseRooms } from './lost.js';
5
8
  import { NO_MODEL } from './model.js';
9
+ import { settle } from './queue.js';
6
10
  import { storedRecord } from './replica.js';
7
- import { overlayDiff, preparedAfter, replayed, sliceAt } from './saves.js';
8
11
  import { emitRooms } from './shown.js';
9
- export function declaredAsHeld(held, room) {
10
- return (held === undefined ||
11
- (JSON.stringify(held.operations) === JSON.stringify(room.operations) &&
12
- JSON.stringify(held.replica) === JSON.stringify(room.replica) &&
13
- JSON.stringify(held.providerOwnedPaths) === JSON.stringify(room.providerOwnedPaths) &&
14
- JSON.stringify(held.authoredPaths) === JSON.stringify(room.authoredPaths) &&
15
- JSON.stringify(held.typedSelection) === JSON.stringify(room.typedSelection ?? null)));
12
+ function declaredAsHeld(held, declaration) {
13
+ return held === undefined || sameDeclaration(held.declaration, declaration);
16
14
  }
17
15
  export function revoked(model) {
18
16
  return model?.status === 'unavailable' && model.reason === 'revoked';
19
17
  }
20
- function unheldModelOf({ socket }, locator) {
21
- return socket.rooms.standing(locator).unheldModel ?? NO_MODEL;
18
+ function unheldModelOf({ presence }, locator) {
19
+ return presence.unheldModel(locator) ?? NO_MODEL;
22
20
  }
23
- export async function keepNaming(runtime, local, room) {
21
+ async function modelNow(runtime, locator) {
22
+ return (await runtime.store.record(locator))?.model ?? unheldModelOf(runtime, locator);
23
+ }
24
+ function restands(held, model, declaration) {
25
+ return (JSON.stringify(held.model) !== JSON.stringify(model) ||
26
+ !equalValue(held.declaration.typedSelection, declaration.typedSelection));
27
+ }
28
+ function recordAlone(store, record) {
29
+ return {
30
+ locator: record.locator,
31
+ key: record.key,
32
+ record: storedRecord(record),
33
+ composed: composedOf(store.composed(record)),
34
+ };
35
+ }
36
+ function unheld(runtime, locator, model) {
37
+ runtime.presence.modelled(locator, model);
38
+ emitRooms(runtime, [locator]);
39
+ }
40
+ function recorded(runtime, locator, declaration, model) {
24
41
  const { store, socket } = runtime;
25
- const held = await store.record(room.locator);
26
- if (held === undefined || (held.name === room.name && held.handle === room.handle))
27
- return;
28
- await store.exclusive(async () => {
42
+ return store.exclusive(async () => {
29
43
  if (!socket.continuing())
30
44
  return;
31
- const current = await store.record(room.locator);
32
- if (current === undefined)
45
+ const current = await store.record(locator);
46
+ if (current === undefined) {
47
+ unheld(runtime, locator, model);
33
48
  return;
34
- const record = { ...current, name: room.name, handle: room.handle };
35
- await local.commit({
36
- rooms: [
37
- {
38
- locator: room.locator,
39
- key: record.key,
40
- record: storedRecord(record),
41
- composed: composedOf(store.composed(record)),
42
- },
43
- ],
44
- });
45
- emitRooms(runtime);
49
+ }
50
+ const answer = await (await store.open()).commit({ rooms: [recordAlone(store, { ...current, declaration, model })] });
51
+ void store.changed(changeSet(locator, {
52
+ documents: answer.changed[locator] ?? [],
53
+ room: true,
54
+ unindexed: answer.indexed[locator] === false,
55
+ }));
46
56
  });
47
57
  }
48
- async function modelNow(runtime, locator) {
49
- return (await runtime.store.record(locator))?.model ?? unheldModelOf(runtime, locator);
50
- }
51
- export async function retainModel(runtime, local, room, given) {
58
+ export async function retainModel(runtime, locator, declaration, given, refused) {
52
59
  const { store, socket } = runtime;
53
- const held = await store.record(room.locator);
54
- const previous = held?.model ?? unheldModelOf(runtime, room.locator);
60
+ const held = await store.record(locator);
61
+ const previous = held?.model ?? unheldModelOf(runtime, locator);
55
62
  const next = given ?? previous;
56
- if (JSON.stringify(previous) === JSON.stringify(next) && declaredAsHeld(held, room))
63
+ if (JSON.stringify(previous) === JSON.stringify(next) && declaredAsHeld(held, declaration))
64
+ return;
65
+ if (held !== undefined && !restands(held, next, declaration)) {
66
+ await recorded(runtime, locator, declaration, next);
57
67
  return;
58
- await store.exclusive(async () => {
68
+ }
69
+ await settle(runtime, [locator], async (works) => {
59
70
  if (!socket.continuing())
60
- return;
61
- const work = await store.work(room.locator);
62
- const current = work.replica;
63
- let changed = null;
64
- if (current !== undefined) {
65
- const record = {
66
- ...current.record,
67
- name: room.name,
68
- handle: room.handle,
69
- operations: room.operations,
70
- replica: room.replica,
71
- providerOwnedPaths: room.providerOwnedPaths,
72
- authoredPaths: room.authoredPaths,
73
- typedSelection: room.typedSelection ?? null,
74
- model: next,
75
- };
76
- const confirmedLayer = await sliceAt(store, record, 'confirmed', current.queue, current.overlaid);
77
- const replayedLayer = await replayed(store, record, confirmedLayer, current.queue);
78
- const diff = await overlayDiff(record, current, replayedLayer.visible, replayedLayer.touched);
79
- const answer = await local.commit({
80
- rooms: [
81
- {
82
- locator: room.locator,
83
- key: record.key,
84
- record: storedRecord(record),
85
- roots: record.typedSelection?.roots ?? [],
86
- composed: composedOf(store.composed(record)),
87
- overlay: diff.overlay,
88
- },
89
- ],
90
- });
91
- preparedAfter(runtime, room.locator, answer);
92
- changed = changeSet(room.locator, {
93
- documents: answer.changed[room.locator] ?? [],
94
- room: true,
95
- });
71
+ return [];
72
+ const current = works.get(locator)?.replica;
73
+ if (current === undefined) {
74
+ unheld(runtime, locator, next);
75
+ return [];
96
76
  }
97
- else
98
- socket.rooms.stand(room.locator, { unheldModel: next });
99
- list(runtime, room, admitted(runtime, room));
100
- if (changed === null)
101
- emitRooms(runtime);
102
- else
103
- store.changed(changed);
77
+ return [
78
+ {
79
+ locator,
80
+ record: { ...current.record, declaration, model: next },
81
+ ...(refused === undefined ? {} : { refused }),
82
+ },
83
+ ];
104
84
  });
105
85
  }
106
- export async function scoped(runtime, result, room, local) {
107
- const { socket, journal } = runtime;
86
+ export async function scoped(runtime, result, locator, declaration) {
87
+ const { socket, presence } = runtime;
108
88
  if (result.scope === 'content' && !result.retryable) {
109
- journal.record(`scoped refusal ${room.locator} ${result.scope} ${result.code}`);
110
- await loseRooms(runtime, [room.locator]);
89
+ await loseRooms(runtime, [locator]);
111
90
  return;
112
91
  }
113
- socket.rooms.stand(room.locator, {
114
- refusal: { code: result.code, fields: result.fields, retryable: result.retryable },
115
- });
116
- let scopedAway = room;
92
+ presence.refused(locator, result);
117
93
  if (result.scope === 'model')
118
- await retainModel(runtime, local, room, {
119
- status: 'unavailable',
120
- reason: 'not-readable',
121
- });
122
- else if (result.scope !== 'operation') {
123
- socket.rooms.stand(room.locator, { unreadable: true });
124
- scopedAway = { ...room, replica: { ...room.replica, admission: 'unavailable' } };
125
- await retainModel(runtime, local, scopedAway, null);
126
- }
94
+ await retainModel(runtime, locator, declaration, { status: 'unavailable', reason: 'not-readable' }, true);
127
95
  if (!socket.continuing())
128
96
  return;
129
- list(runtime, scopedAway, admitted(runtime, scopedAway));
130
- emitRooms(runtime);
131
- journal.record(`scoped refusal ${room.locator} ${result.scope} ${result.code}`);
97
+ emitRooms(runtime, [locator]);
132
98
  }
133
99
  export async function settleModels(runtime, held, status, local) {
134
- const { store, socket, journal } = runtime;
100
+ const { store, socket, presence } = runtime;
135
101
  const owed = (model) => model.status !== 'unavailable' && model.status !== status;
136
102
  const declaredAnew = await store.exclusive(async () => {
137
103
  if (!socket.continuing())
138
104
  return [];
139
- const stored = await store.rooms(held.map(({ locator }) => locator));
140
- const unchanged = held.filter((room) => {
141
- const record = stored.get(room.locator)?.record;
142
- return (owed(record?.model ?? unheldModelOf(runtime, room.locator)) && declaredAsHeld(record, room));
105
+ const stored = await store.rooms([...held.keys()]);
106
+ const unchanged = [...held].filter(([locator, declaration]) => {
107
+ const record = stored.get(locator)?.record;
108
+ return (owed(record?.model ?? unheldModelOf(runtime, locator)) &&
109
+ declaredAsHeld(record, declaration));
143
110
  });
144
- const records = unchanged.flatMap((room) => {
145
- const record = stored.get(room.locator)?.record;
111
+ const records = unchanged.flatMap(([locator]) => {
112
+ const record = stored.get(locator)?.record;
146
113
  return record === undefined
147
114
  ? []
148
115
  : [{ ...record, model: { ...record.model, status } }];
149
116
  });
150
117
  if (records.length > 0) {
151
118
  try {
152
- await local.commit({
153
- rooms: records.map((record) => ({
154
- locator: record.locator,
155
- key: record.key,
156
- record: storedRecord(record),
157
- composed: composedOf(store.composed(record)),
158
- })),
159
- });
119
+ await local.commit({ rooms: records.map((record) => recordAlone(store, record)) });
160
120
  }
161
- catch {
162
- journal.record(`model ${status} persistence failed`);
121
+ catch (error) {
122
+ uncaught(error);
163
123
  }
164
124
  }
165
- for (const room of unchanged) {
166
- const { unheldModel } = socket.rooms.standing(room.locator);
167
- if (!stored.has(room.locator) && unheldModel !== null) {
168
- socket.rooms.stand(room.locator, {
169
- unheldModel: { ...unheldModel, status },
170
- });
125
+ for (const [locator] of unchanged) {
126
+ const unheldModel = presence.unheldModel(locator);
127
+ if (!stored.has(locator) && unheldModel !== null) {
128
+ presence.modelled(locator, { ...unheldModel, status });
171
129
  }
172
- list(runtime, room, admitted(runtime, room));
173
130
  }
174
131
  if (unchanged.length > 0)
175
- emitRooms(runtime);
176
- return held.filter((room) => {
177
- const record = stored.get(room.locator)?.record;
178
- return (!unchanged.includes(room) && owed(record?.model ?? unheldModelOf(runtime, room.locator)));
179
- });
132
+ emitRooms(runtime, unchanged.map(([locator]) => locator));
133
+ const kept = new Set(unchanged.map(([locator]) => locator));
134
+ return [...held].filter(([locator]) => !kept.has(locator) &&
135
+ owed(stored.get(locator)?.record.model ?? unheldModelOf(runtime, locator)));
180
136
  });
181
- for (const room of declaredAnew) {
182
- const model = await modelNow(runtime, room.locator);
137
+ for (const [locator, declaration] of declaredAnew) {
138
+ const model = await modelNow(runtime, locator);
183
139
  if (owed(model))
184
- await retainModel(runtime, local, room, { ...model, status });
140
+ await retainModel(runtime, locator, declaration, { ...model, status });
185
141
  }
186
142
  }
187
143
  export async function cachedModels(runtime, local) {
188
- const { store, socket } = runtime;
144
+ const { store, presence } = runtime;
189
145
  const held = await store.rooms();
190
- await settleModels(runtime, listedLocators(runtime, held).flatMap((locator) => {
191
- const room = socket.rooms.discovered(locator) ??
192
- declarationOf(runtime, locator, held.get(locator))?.room;
193
- return room === undefined ? [] : [room];
194
- }), 'cached', local);
146
+ await settleModels(runtime, new Map(listedLocators(runtime, held).flatMap((locator) => {
147
+ const discovered = presence.room(locator);
148
+ const declaration = discovered === undefined
149
+ ? declarationOf(runtime, locator, held.get(locator))?.room
150
+ : declared(discovered);
151
+ return declaration === undefined ? [] : [[locator, declaration]];
152
+ })), 'cached', local);
195
153
  }
@@ -1,4 +1,5 @@
1
- import type { QueryCoverage, QueryDocument, QueryGroup, QueryResult } from './query.js';
1
+ import type { PendingRoom, QueryCoverage, QueryDocument, QueryGroup, QueryResult } from './query.js';
2
+ import type { ReadinessShown, RoomCoverage } from './readiness.js';
2
3
  export type Observation<T> = {
3
4
  current(): T;
4
5
  subscribe(listener: (value: T) => void): () => void;
@@ -9,15 +10,24 @@ export type KeyedResult = {
9
10
  result: QueryResult;
10
11
  keys: readonly RowKey[];
11
12
  };
12
- export type QueryChange = {
13
- changed: readonly (readonly [RowKey, QueryDocument | QueryGroup])[];
14
- removed: readonly RowKey[];
15
- order: readonly RowKey[] | null;
13
+ export type KeyedChange<K, T> = {
14
+ readonly changed: readonly (readonly [K, T])[];
15
+ readonly removed: readonly K[];
16
+ readonly order: readonly K[] | null;
17
+ };
18
+ export type QueryChange = KeyedChange<RowKey, QueryDocument | QueryGroup> & {
16
19
  coverage?: QueryCoverage;
17
20
  next?: string | null;
18
21
  total?: number;
19
22
  };
20
- export type QueryMessage = KeyedResult | QueryChange;
23
+ export type ReadinessChange = {
24
+ readonly shown: ReadinessShown;
25
+ readonly rooms: KeyedChange<string, RoomCoverage>;
26
+ };
27
+ export type PendingChange = {
28
+ readonly pending: KeyedChange<string, PendingRoom>;
29
+ };
30
+ export type QueryMessage = KeyedResult | QueryChange | PendingChange;
21
31
  export type Observed = {
22
32
  observation: Observation<unknown>;
23
33
  receive(message: unknown): void;
@@ -25,15 +35,20 @@ export type Observed = {
25
35
  };
26
36
  export declare function rowsOf(result: QueryResult): readonly (QueryDocument | QueryGroup)[];
27
37
  export declare function whole(message: QueryMessage): message is KeyedResult;
28
- export declare function applied(keyed: KeyedResult, message: QueryMessage): KeyedResult;
29
- export declare function observed(first: unknown, stop: () => void, keyed: boolean): Observed;
30
- export declare function opened(watch: (deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void, keyed: boolean): Promise<Observation<unknown>>;
38
+ export declare function pendingChange(message: QueryMessage): message is PendingChange;
39
+ export declare function unchanged(change: KeyedChange<unknown, unknown>): boolean;
40
+ export declare function keyedChange<K, H, T>(held: ReadonlyMap<K, H>, keys: readonly K[], rows: readonly T[], same: (was: H, now: T) => boolean): KeyedChange<K, T>;
41
+ export declare function keyedAt<K, H, T>(held: ReadonlyMap<K, H>, at: ReadonlyMap<K, T | null>, same: (was: H, now: T) => boolean): KeyedChange<K, T> | null;
42
+ export declare function keyedInto<K, T>(held: Map<K, T>, change: KeyedChange<K, T>): void;
43
+ export declare function samePending(was: PendingRoom, now: PendingRoom): boolean;
44
+ export declare function replaces(topic: string, message: unknown): boolean;
45
+ export declare function observed(first: unknown, stop: () => void, topic: string): Observed;
46
+ export declare function opened(watch: (deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void, topic: string): Promise<Observation<unknown>>;
31
47
  export declare function observing<Topic extends string>(watch: (topic: Topic, input: readonly unknown[], deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void): (topic: Topic, ...input: unknown[]) => Promise<Observation<unknown>>;
32
48
  export type Digest = {
33
- readonly pending: string;
49
+ readonly pending: Map<string, PendingRoom>;
34
50
  } | {
35
- readonly keys: readonly RowKey[];
36
- readonly rows: ReadonlyMap<RowKey, number>;
51
+ readonly rows: Map<RowKey, number>;
37
52
  readonly coverage: string;
38
53
  readonly next: string | undefined;
39
54
  readonly total: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}