@agentshouse/mdruntime 0.1.0-cf04ede9fb796 → 0.1.0-cf0c43fc48aad

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 (220) hide show
  1. package/README.md +12 -12
  2. package/dist/acceptance.d.ts +0 -3
  3. package/dist/acceptance.d.ts.map +1 -1
  4. package/dist/acceptance.js +74 -164
  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 +27 -48
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/bootstrap.d.ts +1 -1
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +6 -19
  16. package/dist/change-set.d.ts +4 -0
  17. package/dist/change-set.d.ts.map +1 -1
  18. package/dist/change-set.js +6 -0
  19. package/dist/change.d.ts.map +1 -1
  20. package/dist/change.js +4 -2
  21. package/dist/client.d.ts +9 -18
  22. package/dist/client.d.ts.map +1 -1
  23. package/dist/client.js +32 -15
  24. package/dist/collection.d.ts +22 -4
  25. package/dist/collection.d.ts.map +1 -1
  26. package/dist/collection.js +12 -2
  27. package/dist/compile.d.ts +2 -0
  28. package/dist/compile.d.ts.map +1 -1
  29. package/dist/compile.js +31 -24
  30. package/dist/connection.d.ts.map +1 -1
  31. package/dist/connection.js +26 -21
  32. package/dist/conversation-live.d.ts +10 -6
  33. package/dist/conversation-live.d.ts.map +1 -1
  34. package/dist/conversation-live.js +8 -6
  35. package/dist/conversation.d.ts +28 -10
  36. package/dist/conversation.d.ts.map +1 -1
  37. package/dist/conversation.js +194 -141
  38. package/dist/declaration.d.ts +10 -0
  39. package/dist/declaration.d.ts.map +1 -0
  40. package/dist/declaration.js +24 -0
  41. package/dist/discovery.d.ts.map +1 -1
  42. package/dist/discovery.js +19 -44
  43. package/dist/durability.d.ts +3 -0
  44. package/dist/durability.d.ts.map +1 -1
  45. package/dist/entry.js +1 -1
  46. package/dist/expectation.d.ts +26 -13
  47. package/dist/expectation.d.ts.map +1 -1
  48. package/dist/expectation.js +72 -19
  49. package/dist/failure.d.ts +3 -0
  50. package/dist/failure.d.ts.map +1 -1
  51. package/dist/failure.js +6 -0
  52. package/dist/host.d.ts +17 -2
  53. package/dist/host.d.ts.map +1 -1
  54. package/dist/host.js +45 -11
  55. package/dist/index.d.ts +12 -8
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +10 -6
  58. package/dist/install.d.ts +2 -4
  59. package/dist/install.d.ts.map +1 -1
  60. package/dist/install.js +52 -78
  61. package/dist/lifecycle.d.ts +1 -1
  62. package/dist/lifecycle.d.ts.map +1 -1
  63. package/dist/lifecycle.js +40 -31
  64. package/dist/listing.d.ts +6 -11
  65. package/dist/listing.d.ts.map +1 -1
  66. package/dist/listing.js +25 -62
  67. package/dist/live.d.ts.map +1 -1
  68. package/dist/live.js +3 -3
  69. package/dist/locks.d.ts +2 -4
  70. package/dist/locks.d.ts.map +1 -1
  71. package/dist/locks.js +10 -39
  72. package/dist/lost.d.ts.map +1 -1
  73. package/dist/lost.js +10 -22
  74. package/dist/media.d.ts +1 -1
  75. package/dist/media.d.ts.map +1 -1
  76. package/dist/media.js +4 -4
  77. package/dist/memory.d.ts +4 -2
  78. package/dist/memory.d.ts.map +1 -1
  79. package/dist/memory.js +44 -23
  80. package/dist/messages.d.ts +9 -5
  81. package/dist/messages.d.ts.map +1 -1
  82. package/dist/messages.js +25 -35
  83. package/dist/model.d.ts +0 -1
  84. package/dist/model.d.ts.map +1 -1
  85. package/dist/model.js +0 -5
  86. package/dist/models.d.ts +4 -8
  87. package/dist/models.d.ts.map +1 -1
  88. package/dist/models.js +95 -137
  89. package/dist/observation.d.ts.map +1 -1
  90. package/dist/observation.js +12 -17
  91. package/dist/opened.d.ts +1 -1
  92. package/dist/opened.d.ts.map +1 -1
  93. package/dist/opened.js +5 -5
  94. package/dist/opening.d.ts.map +1 -1
  95. package/dist/opening.js +5 -9
  96. package/dist/outcome.d.ts +3 -0
  97. package/dist/outcome.d.ts.map +1 -1
  98. package/dist/outcome.js +15 -0
  99. package/dist/overlay.d.ts +5 -1
  100. package/dist/overlay.d.ts.map +1 -1
  101. package/dist/overlay.js +36 -21
  102. package/dist/page-metadata.d.ts +8 -0
  103. package/dist/page-metadata.d.ts.map +1 -0
  104. package/dist/page-metadata.js +19 -0
  105. package/dist/parts.d.ts +3 -59
  106. package/dist/parts.d.ts.map +1 -1
  107. package/dist/parts.js +10 -123
  108. package/dist/preparation.d.ts.map +1 -1
  109. package/dist/preparation.js +25 -24
  110. package/dist/presence.d.ts +52 -0
  111. package/dist/presence.d.ts.map +1 -0
  112. package/dist/presence.js +220 -0
  113. package/dist/queries.d.ts +1 -1
  114. package/dist/queries.d.ts.map +1 -1
  115. package/dist/queries.js +24 -14
  116. package/dist/query.d.ts +0 -1
  117. package/dist/query.d.ts.map +1 -1
  118. package/dist/questions.d.ts +0 -5
  119. package/dist/questions.d.ts.map +1 -1
  120. package/dist/questions.js +0 -7
  121. package/dist/queue.d.ts +40 -0
  122. package/dist/queue.d.ts.map +1 -0
  123. package/dist/queue.js +450 -0
  124. package/dist/reach.d.ts.map +1 -1
  125. package/dist/reach.js +67 -22
  126. package/dist/react.d.ts +5 -0
  127. package/dist/react.d.ts.map +1 -1
  128. package/dist/react.js +33 -1
  129. package/dist/reads.d.ts +3 -1
  130. package/dist/reads.d.ts.map +1 -1
  131. package/dist/reads.js +9 -2
  132. package/dist/recovery.d.ts +3 -1
  133. package/dist/recovery.d.ts.map +1 -1
  134. package/dist/recovery.js +29 -7
  135. package/dist/refresh.js +2 -2
  136. package/dist/refusal.d.ts.map +1 -1
  137. package/dist/refusal.js +5 -6
  138. package/dist/replica.d.ts +5 -11
  139. package/dist/replica.d.ts.map +1 -1
  140. package/dist/replica.js +13 -15
  141. package/dist/retried.d.ts +30 -0
  142. package/dist/retried.d.ts.map +1 -0
  143. package/dist/retried.js +72 -0
  144. package/dist/room-draft.d.ts +4 -6
  145. package/dist/room-draft.d.ts.map +1 -1
  146. package/dist/room-draft.js +46 -57
  147. package/dist/room-drafts.d.ts.map +1 -1
  148. package/dist/room-drafts.js +17 -16
  149. package/dist/rows.d.ts.map +1 -1
  150. package/dist/rows.js +3 -4
  151. package/dist/runtime.d.ts +9 -18
  152. package/dist/runtime.d.ts.map +1 -1
  153. package/dist/save.d.ts +42 -90
  154. package/dist/save.d.ts.map +1 -1
  155. package/dist/save.js +334 -167
  156. package/dist/saves.d.ts +2 -40
  157. package/dist/saves.d.ts.map +1 -1
  158. package/dist/saves.js +107 -705
  159. package/dist/seed.d.ts.map +1 -1
  160. package/dist/seed.js +2 -3
  161. package/dist/shared.d.ts +0 -5
  162. package/dist/shared.d.ts.map +1 -1
  163. package/dist/shared.js +4 -90
  164. package/dist/shown.d.ts +4 -3
  165. package/dist/shown.d.ts.map +1 -1
  166. package/dist/shown.js +26 -31
  167. package/dist/socket/lanes.d.ts +12 -4
  168. package/dist/socket/lanes.d.ts.map +1 -1
  169. package/dist/socket/lanes.js +34 -8
  170. package/dist/socket/session.d.ts +0 -1
  171. package/dist/socket/session.d.ts.map +1 -1
  172. package/dist/socket.d.ts +3 -6
  173. package/dist/socket.d.ts.map +1 -1
  174. package/dist/socket.js +5 -16
  175. package/dist/source.d.ts +0 -7
  176. package/dist/source.d.ts.map +1 -1
  177. package/dist/source.js +5 -4
  178. package/dist/store/records.d.ts +8 -6
  179. package/dist/store/records.d.ts.map +1 -1
  180. package/dist/store/records.js +13 -6
  181. package/dist/store/space.d.ts +1 -1
  182. package/dist/store/space.d.ts.map +1 -1
  183. package/dist/store/space.js +0 -2
  184. package/dist/store/watchers.js +1 -2
  185. package/dist/store.d.ts +11 -6
  186. package/dist/store.d.ts.map +1 -1
  187. package/dist/store.js +38 -13
  188. package/dist/stored.d.ts +2 -1
  189. package/dist/stored.d.ts.map +1 -1
  190. package/dist/stored.js +11 -11
  191. package/dist/surface.d.ts +1 -1
  192. package/dist/surface.d.ts.map +1 -1
  193. package/dist/surface.js +13 -16
  194. package/dist/sync.d.ts.map +1 -1
  195. package/dist/sync.js +88 -85
  196. package/dist/tables.d.ts +6 -8
  197. package/dist/tables.d.ts.map +1 -1
  198. package/dist/tables.js +41 -20
  199. package/dist/tallies.js +5 -5
  200. package/dist/validation.d.ts.map +1 -1
  201. package/dist/validation.js +2 -2
  202. package/dist/wire.d.ts +51 -7
  203. package/dist/wire.d.ts.map +1 -1
  204. package/dist/wire.js +15 -4
  205. package/package.json +3 -2
  206. package/dist/attempt.d.ts +0 -16
  207. package/dist/attempt.d.ts.map +0 -1
  208. package/dist/attempt.js +0 -70
  209. package/dist/job.d.ts +0 -33
  210. package/dist/job.d.ts.map +0 -1
  211. package/dist/job.js +0 -54
  212. package/dist/log.d.ts +0 -6
  213. package/dist/log.d.ts.map +0 -1
  214. package/dist/log.js +0 -14
  215. package/dist/socket/rooms.d.ts +0 -44
  216. package/dist/socket/rooms.d.ts.map +0 -1
  217. package/dist/socket/rooms.js +0 -90
  218. package/dist/store/fences.d.ts +0 -16
  219. package/dist/store/fences.d.ts.map +0 -1
  220. package/dist/store/fences.js +0 -26
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declaration.d.ts","sourceRoot":"","sources":["../src/declaration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/F,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EACT,WAAW,GACX,qBAAqB,GACrB,cAAc,GACd,GAAG,MAAM,eAAe,QAAQ,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,CAAC,MAAM,eAAe,CAAC,EAAE,KACtC,YAAY,GAAG,IAAI,CAAC;AAEzB,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EAAE,QAAQ,EACjB,WAAW,EAAE,YAAY,EACzB,GAAG,WAAW,EACf,EAAE,cAAc,GAAG,eAAe,CAElC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAEtF;AAED,wBAAgB,SAAS,CACvB,EACE,UAAU,EACV,kBAAkB,EAClB,aAAa,GACd,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,oBAAoB,GAAG,eAAe,CAAC,EAC/E,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,OAAO,GACb,SAAS,CAYX"}
@@ -0,0 +1,24 @@
1
+ import { equalValue } from '@agentshouse/mdmodel';
2
+ import { authoredAt, covered, normalize } from './paths.js';
3
+ export function declared({ locator: _locator, roomVersion: _roomVersion, ...declaration }) {
4
+ return declaration;
5
+ }
6
+ export function sameDeclaration(left, right) {
7
+ return equalValue(left, right);
8
+ }
9
+ export function writeRule({ operations, providerOwnedPaths, authoredPaths, }, pathRule, local) {
10
+ return (path, needs) => {
11
+ const normalized = normalize(path);
12
+ if (normalized === null || normalized === '')
13
+ return { code: 'room-root', path };
14
+ if (covered(providerOwnedPaths, normalized) || !authoredAt(authoredPaths, normalized)) {
15
+ return { code: 'provider-owned-path', path: normalized };
16
+ }
17
+ if (!pathRule(normalized))
18
+ return { code: 'invalid-path', path: normalized };
19
+ if (local)
20
+ return null;
21
+ const missing = needs.find((operation) => !covered(operations[operation], normalized));
22
+ return missing === undefined ? null : { code: `${missing}-grant`, path: normalized };
23
+ };
24
+ }
@@ -1 +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"}
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;AAOtB,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,CA0CpC;AAYD,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"}
package/dist/discovery.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { validRoot } from './collection.js';
2
- import { admitted, list, listHeld } from './listing.js';
3
- import { confirmLocks, lockedRooms, relocked } from './locks.js';
2
+ import { lockedRooms, relocked } from './locks.js';
4
3
  import { loseRooms } from './lost.js';
5
4
  import { cachedModels } from './models.js';
6
5
  import { beneath } from './paths.js';
@@ -11,7 +10,7 @@ function within(root, path) {
11
10
  }
12
11
  function declaredSelection(room) {
13
12
  const selection = room.typedSelection;
14
- if (selection === undefined)
13
+ if (selection === null)
15
14
  return true;
16
15
  if (!Array.isArray(selection.roots) || selection.roots.length === 0)
17
16
  return false;
@@ -37,60 +36,34 @@ export function malformed(listed) {
37
36
  return null;
38
37
  }
39
38
  export async function applyDiscovery(runtime, found, started, left) {
40
- const { store, socket } = runtime;
41
- const { rooms } = socket;
39
+ const { store, socket, presence } = runtime;
42
40
  const lockedBefore = await lockedRooms(runtime);
43
41
  const local = await store.open();
44
- const stillFenced = new Set(await local.fences());
42
+ const fenced = new Set(await local.fences());
45
43
  const relisting = found
46
44
  .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
45
+ .filter((locator) => fenced.has(locator) && presence.liftable(locator, started));
46
+ const unfenced = relisting.length === 0
52
47
  ? new Set()
53
48
  : 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
- }
49
+ const clear = found.filter(({ locator }) => !fenced.has(locator) || unfenced.has(locator));
50
+ for (const { locator } of clear)
51
+ presence.lift(locator, started, unfenced.has(locator));
62
52
  const kept = await local.held();
63
53
  await loseRooms(runtime, found
64
54
  .filter((room) => room.replica.admission !== 'admitted' &&
65
55
  (kept.held.has(room.locator) || store.installs.of(room.locator).transfer !== null))
66
56
  .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
57
  const named = new Set(found.map((room) => room.locator));
76
58
  await loseRooms(runtime, left ??
77
59
  [
78
60
  ...new Set([
79
- ...rooms.declarations().keys(),
61
+ ...presence.rooms().map(({ locator }) => locator),
80
62
  ...kept.held,
81
63
  ...store.installs.transferring(),
82
64
  ]),
83
65
  ].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);
66
+ const listed = presence.list(clear, { whole: left === undefined, live: socket.isOpen() });
94
67
  socket.session.set({ roomsListed: true });
95
68
  emitRooms(runtime);
96
69
  await relocked(runtime, lockedBefore);
@@ -100,10 +73,11 @@ async function asked({ socket }, authorized) {
100
73
  try {
101
74
  return (await socket.discover(authorized)) ?? { kind: 'transport-uncertainty' };
102
75
  }
103
- catch {
104
- return { kind: 'transport-uncertainty' };
76
+ catch (failure) {
77
+ return { kind: 'transport-uncertainty', failure };
105
78
  }
106
79
  }
80
+ const DISCOVERY = 'discovery';
107
81
  export async function signIn(runtime, local, signedIn) {
108
82
  if (JSON.stringify(signedIn) === JSON.stringify((await local.facts()).member))
109
83
  return;
@@ -111,7 +85,7 @@ export async function signIn(runtime, local, signedIn) {
111
85
  emitMember(runtime, signedIn);
112
86
  }
113
87
  export async function discoverRooms(runtime, local, progress, live, found) {
114
- const { socket, journal } = runtime;
88
+ const { socket } = runtime;
115
89
  const { session } = socket;
116
90
  const { closed, authorization } = session.now();
117
91
  if (closed || authorization === undefined) {
@@ -129,7 +103,10 @@ export async function discoverRooms(runtime, local, progress, live, found) {
129
103
  socket.notifyReady();
130
104
  return null;
131
105
  }
132
- journal.record(`connection discover ${result.kind}`);
106
+ if (result.kind === 'transport-uncertainty')
107
+ runtime.retries.uncertain('connection', DISCOVERY, result);
108
+ if (result.kind === 'discovery')
109
+ runtime.retries.succeeded('connection', DISCOVERY);
133
110
  if (result.kind === 'transport-uncertainty') {
134
111
  await cachedModels(runtime, local);
135
112
  progress.reachable = false;
@@ -138,7 +115,6 @@ export async function discoverRooms(runtime, local, progress, live, found) {
138
115
  return null;
139
116
  }
140
117
  if (result.kind === 'contract-unavailable') {
141
- journal.record(`connection contract unavailable ${result.code}`);
142
118
  await refuse(runtime, 'missing-required-guarantee', {
143
119
  code: result.code,
144
120
  fields: result.fields,
@@ -154,7 +130,6 @@ export async function discoverRooms(runtime, local, progress, live, found) {
154
130
  }
155
131
  const invalid = malformed(result.rooms);
156
132
  if (invalid !== null) {
157
- journal.record(invalid);
158
133
  await refuse(runtime, 'missing-required-guarantee');
159
134
  socket.notifyReady();
160
135
  return null;
@@ -1,4 +1,5 @@
1
1
  import type { Persistence } from './readiness.js';
2
+ import type { RetriedFailure, Step } from './retried.js';
2
3
  export type UnsentKind = 'pending-change' | 'call' | 'room-draft' | 'chat-draft';
3
4
  export type UnsentWork = {
4
5
  readonly kind: UnsentKind;
@@ -20,6 +21,8 @@ export type RuntimeShell = {
20
21
  cleanUp?(): Promise<number>;
21
22
  measure?(measured: (app: string, code: AppCode | null) => void): Promise<HeldCode>;
22
23
  reset(): Promise<void>;
24
+ retried?(failure: RetriedFailure): void;
25
+ succeeded?(step: Step): void;
23
26
  };
24
27
  export declare function refusedForSpace(error: unknown): boolean;
25
28
  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,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
+ {"version":3,"file":"durability.d.ts","sourceRoot":"","sources":["../src/durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAIzD,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;IACvB,OAAO,CAAC,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACxC,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAC9B,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.js CHANGED
@@ -145,7 +145,7 @@ export function entryScope(rooms, roomTypes, connection) {
145
145
  change: null,
146
146
  written: null,
147
147
  })));
148
- return { locator: room.locator, key };
148
+ return { locator: room.locator, key, composition };
149
149
  });
150
150
  const planned = { listed: true, rooms: held };
151
151
  return {
@@ -1,21 +1,34 @@
1
- export type ExpectedOf<E extends {
2
- readonly key: string;
3
- }> = E | readonly E[] | null;
4
- export type Expecting<E extends {
1
+ declare const heldType: unique symbol;
2
+ export type Descriptor<A, T> = {
3
+ place(asked: A): string;
4
+ readonly [heldType]?: T;
5
+ };
6
+ export type Expectation = {
5
7
  readonly key: string;
6
- }> = {
8
+ readonly descriptor: object;
9
+ readonly places: ReadonlySet<string>;
10
+ draw(held: unknown): unknown;
11
+ shown(held: unknown): boolean;
12
+ };
13
+ export type Expected = Expectation | readonly Expectation[] | null;
14
+ export type Expecting = {
7
15
  subscribe(listener: () => void): () => void;
8
16
  version(): number;
9
17
  begin(): number;
10
- expect(act: number, expected: ExpectedOf<E>, settled?: (one: E) => boolean): void;
18
+ expect(act: number, expected: Expected): void;
11
19
  drop(act: number): void;
12
- heard(shown: (one: E) => boolean): void;
13
- drawn(): readonly E[];
20
+ reads<A, T>(reader: string, descriptor: Descriptor<A, T>, places: readonly A[]): void;
21
+ heard<A, T>(reader: string, descriptor: Descriptor<A, T>, held: ReadonlyMap<A, T>): void;
22
+ left(reader: string): void;
23
+ draw<A, T>(descriptor: Descriptor<A, T>, place: A, held: T): T;
14
24
  };
15
- export declare function expectedList<E extends {
16
- readonly key: string;
17
- }>(expected: ExpectedOf<E>): readonly E[];
18
- export declare function expecting<E extends {
25
+ export declare function expectation<A, T>(descriptor: Descriptor<A, T>, made: {
19
26
  readonly key: string;
20
- }>(): Expecting<E>;
27
+ readonly at: readonly A[];
28
+ draw(held: T): T;
29
+ shown(held: T): boolean;
30
+ }): Expectation;
31
+ export declare function expectedList(expected: Expected): readonly Expectation[];
32
+ export declare function expecting(): Expecting;
33
+ export {};
21
34
  //# sourceMappingURL=expectation.d.ts.map
@@ -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,OAAO,CAAC,MAAM,QAAQ,EAAE,OAAO,MAAM,CAAC;AAEtC,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI;IAC7B,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC;AAEnE,MAAM,MAAM,SAAS,GAAG;IACtB,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,QAAQ,GAAG,IAAI,CAAC;IAC9C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;IACtF,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACzF,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;CAChE,CAAC;AAcF,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAC9B,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,IAAI,EAAE;IACJ,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;CACzB,GACA,WAAW,CAQb;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,WAAW,EAAE,CAGvE;AA+BD,wBAAgB,SAAS,IAAI,SAAS,CAqFrC"}
@@ -1,22 +1,40 @@
1
+ const NOWHERE = new Set();
2
+ const NOTHING = new Map();
3
+ export function expectation(descriptor, made) {
4
+ return {
5
+ key: made.key,
6
+ descriptor,
7
+ places: new Set(made.at.map((one) => descriptor.place(one))),
8
+ draw: (value) => made.draw(value),
9
+ shown: (value) => made.shown(value),
10
+ };
11
+ }
1
12
  export function expectedList(expected) {
2
13
  if (expected === null)
3
14
  return [];
4
15
  return 'key' in expected ? [expected] : expected;
5
16
  }
17
+ function asks(reader, one) {
18
+ return (reader.descriptor === one.descriptor && [...one.places].some((at) => reader.places.has(at)));
19
+ }
20
+ function shows(reader, one) {
21
+ return (reader.descriptor === one.descriptor &&
22
+ [...reader.held].some(([at, value]) => one.places.has(at) && one.shown(value)));
23
+ }
6
24
  function superseded(entries, at) {
7
- const key = entries[at]?.expectation.key;
8
- return entries.slice(at + 1).some((later) => later.expectation.key === key);
25
+ const key = entries[at]?.one.key;
26
+ return entries.slice(at + 1).some((later) => later.one.key === key);
9
27
  }
10
28
  function unended(entries, ends) {
11
29
  const ended = new Set();
12
30
  const kept = [];
13
- for (const one of [...entries].reverse()) {
14
- if (ended.has(one.expectation.key))
31
+ for (const entry of [...entries].reverse()) {
32
+ if (ended.has(entry.one.key))
15
33
  continue;
16
- if (ends(one.expectation))
17
- ended.add(one.expectation.key);
34
+ if (ends(entry))
35
+ ended.add(entry.one.key);
18
36
  else
19
- kept.unshift(one);
37
+ kept.unshift(entry);
20
38
  }
21
39
  return kept;
22
40
  }
@@ -24,6 +42,7 @@ export function expecting() {
24
42
  let entries = [];
25
43
  let version = 0;
26
44
  let acts = 0;
45
+ const readers = new Map();
27
46
  const listeners = new Set();
28
47
  const set = (next) => {
29
48
  if (next.length === entries.length && next.every((one, at) => one === entries[at]))
@@ -33,6 +52,18 @@ export function expecting() {
33
52
  for (const listener of listeners)
34
53
  listener();
35
54
  };
55
+ const settle = (next) => {
56
+ for (const entry of next)
57
+ for (const [id, reader] of readers)
58
+ if (asks(reader, entry.one) && shows(reader, entry.one))
59
+ entry.seen.add(id);
60
+ set(unended(next, (entry) => {
61
+ const asking = [...readers].filter(([, reader]) => asks(reader, entry.one));
62
+ const seen = asking.filter(([id]) => entry.seen.has(id));
63
+ return (seen.length > 0 &&
64
+ (seen.length === asking.length || seen.some(([, reader]) => !shows(reader, entry.one))));
65
+ }));
66
+ };
36
67
  return {
37
68
  subscribe(listener) {
38
69
  listeners.add(listener);
@@ -45,26 +76,48 @@ export function expecting() {
45
76
  acts += 1;
46
77
  return acts;
47
78
  },
48
- expect(act, expected, settled = () => false) {
79
+ expect(act, expected) {
49
80
  const fresh = expectedList(expected);
50
81
  if (fresh.length === 0)
51
82
  return;
52
83
  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 })),
84
+ settle([
85
+ ...entries.filter((entry) => entry.act !== act || !keys.has(entry.one.key)),
86
+ ...fresh.map((one) => ({ act, one, seen: new Set() })),
60
87
  ]);
61
88
  },
62
89
  drop(act) {
63
- set(entries.filter((one) => one.act !== act));
90
+ set(entries.filter((entry) => entry.act !== act));
91
+ },
92
+ reads(reader, descriptor, places) {
93
+ readers.set(reader, {
94
+ descriptor,
95
+ places: new Set(places.map((one) => descriptor.place(one))),
96
+ held: readers.get(reader)?.held ?? NOTHING,
97
+ });
98
+ settle(entries);
99
+ },
100
+ heard(reader, descriptor, held) {
101
+ readers.set(reader, {
102
+ descriptor,
103
+ places: readers.get(reader)?.places ?? NOWHERE,
104
+ held: new Map([...held].map(([place, value]) => [descriptor.place(place), value])),
105
+ });
106
+ settle(entries);
107
+ },
108
+ left(reader) {
109
+ readers.delete(reader);
110
+ for (const entry of entries)
111
+ entry.seen.delete(reader);
112
+ settle(entries);
64
113
  },
65
- heard(shown) {
66
- set(unended(entries, shown));
114
+ draw(descriptor, place, held) {
115
+ const at = descriptor.place(place);
116
+ return entries.reduce((now, entry, index) => entry.one.descriptor === descriptor &&
117
+ entry.one.places.has(at) &&
118
+ !superseded(entries, index)
119
+ ? entry.one.draw(now)
120
+ : now, held);
67
121
  },
68
- drawn: () => entries.flatMap((one, at) => (superseded(entries, at) ? [] : [one.expectation])),
69
122
  };
70
123
  }
package/dist/failure.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ProviderRefusal } from './adapter.js';
1
2
  export type RuntimeError = Error & {
2
3
  readonly code: string;
3
4
  readonly retryable: boolean;
@@ -8,6 +9,8 @@ export type Described = {
8
9
  retryable: boolean;
9
10
  };
10
11
  export declare function runtimeError(code: string, message?: string, retryable?: boolean): RuntimeError;
12
+ export declare function refusalError(refusal: ProviderRefusal): RuntimeError;
11
13
  export declare function failed(error: unknown): RuntimeError;
14
+ export declare function uncaught(error: unknown): void;
12
15
  export declare function described(error: unknown): Described;
13
16
  //# sourceMappingURL=failure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../src/failure.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1F,MAAM,MAAM,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAa,EACtB,SAAS,UAAQ,GAChB,YAAY,CAEd;AAYD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAGnD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAGnD"}
1
+ {"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../src/failure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1F,MAAM,MAAM,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAa,EACtB,SAAS,UAAQ,GAChB,YAAY,CAEd;AAYD,wBAAgB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,CAEnE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAGnD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE7C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAGnD"}
package/dist/failure.js CHANGED
@@ -8,11 +8,17 @@ function coded(error) {
8
8
  'retryable' in error &&
9
9
  typeof error.retryable === 'boolean');
10
10
  }
11
+ export function refusalError(refusal) {
12
+ return runtimeError(refusal.code, refusal.code, refusal.retryable);
13
+ }
11
14
  export function failed(error) {
12
15
  if (coded(error))
13
16
  return error;
14
17
  return runtimeError('runtime-failure', error instanceof Error ? error.message : String(error));
15
18
  }
19
+ export function uncaught(error) {
20
+ reportError(error);
21
+ }
16
22
  export function described(error) {
17
23
  const { message, code, retryable } = failed(error);
18
24
  return { message, code, retryable };
package/dist/host.d.ts CHANGED
@@ -2,10 +2,24 @@ import { type MdRuntimeOptions } from './connection.js';
2
2
  import type { PortReach } from './reach.js';
3
3
  import type { CodeAvailability, Persistence, Readiness } from './readiness.js';
4
4
  import type { EntrySeed } from './seed.js';
5
+ import { type CallResult } from './outcome.js';
5
6
  import { type RuntimePort } from './wire.js';
6
7
  export type MdRuntimeHostOptions = MdRuntimeOptions & {
7
8
  deploymentFacts?: unknown;
8
9
  };
10
+ export type Admitted = {
11
+ readonly admitted: unknown;
12
+ } | {
13
+ readonly refused: CallResult;
14
+ };
15
+ export type ActionAdmission = (name: string, input: unknown) => Promise<Admitted>;
16
+ export type AttachOptions = {
17
+ readonly app: string;
18
+ readonly release?: string;
19
+ readonly reach?: PortReach;
20
+ readonly admission?: ActionAdmission;
21
+ readonly code?: CodeAvailability;
22
+ };
9
23
  export type AttachedPort = {
10
24
  detach(): void;
11
25
  narrow(reach: PortReach): void;
@@ -13,7 +27,7 @@ export type AttachedPort = {
13
27
  answered(queries: readonly unknown[], done: () => void): void;
14
28
  };
15
29
  export type MdRuntimeHost = {
16
- attach(port: RuntimePort, app: string, release?: string, reach?: PortReach, code?: CodeAvailability): AttachedPort;
30
+ attach(port: RuntimePort, options: AttachOptions): AttachedPort;
17
31
  present(app: string, members: Readonly<Record<string, unknown>>): Promise<void>;
18
32
  seed(entry: EntrySeed): void;
19
33
  persisted(answer: Persistence): void;
@@ -25,5 +39,6 @@ export { entrySeedOf, type EntrySeed } from './seed.js';
25
39
  export type { PortReach, ReachedDocument } from './reach.js';
26
40
  export type { CodeAvailability, Persistence, Space } from './readiness.js';
27
41
  export { createRecovery, retryDelay, type Attempt, type Attempted, type AttemptOptions, type Recovery, type RecoveryOptions, } from './recovery.js';
28
- export type { RuntimePort } from './wire.js';
42
+ export { undeclared } from './outcome.js';
43
+ export { wireAnswer, wireRequest, type RuntimePort, type WireAnswer, type WireRequest, } from './wire.js';
29
44
  //# sourceMappingURL=host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAGL,KAAK,WAAW,EAOjB,MAAM,WAAW,CAAC;AAInB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CACJ,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE,gBAAgB,GACtB,YAAY,CAAC;IAChB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AAsIF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAuL3E;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,UAAU,EACV,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
package/dist/host.js CHANGED
@@ -3,7 +3,7 @@ import { composeRuntime } from './connection.js';
3
3
  import { untilAnswered } from './recovery.js';
4
4
  import { described } from './failure.js';
5
5
  import { answeredResult } from './outcome.js';
6
- import { AUTHORIZATION_ENDED, request, WIRE, } from './wire.js';
6
+ import { AUTHORIZATION_ENDED, WIRE, wireRequest, } from './wire.js';
7
7
  const NARROWED = new Set(['within', 'whole']);
8
8
  function answered(md, app, writtenBy, member, input) {
9
9
  switch (member) {
@@ -35,10 +35,10 @@ function answered(md, app, writtenBy, member, input) {
35
35
  return md.binaryFile.part(input[0], input[1]);
36
36
  case 'call':
37
37
  return md.call(input[0], input[1]);
38
+ case 'answered':
39
+ return md.answered(input[0]);
38
40
  case 'reached':
39
41
  return md.reached(input[0], input[1], input[2]);
40
- case 'log':
41
- return md.log();
42
42
  case 'cleanUp':
43
43
  return md.cleanUp();
44
44
  case 'unsent':
@@ -76,17 +76,39 @@ function answered(md, app, writtenBy, member, input) {
76
76
  case 'conversation.send':
77
77
  return md.conversation.send(input[0], input[1], input[2]);
78
78
  case 'conversation.answer':
79
- return md.conversation.answer(input[0], input[1]);
79
+ return md.conversation.answer(input[0], input[1], input[2]);
80
80
  case 'conversation.interrupt':
81
- return md.conversation.interrupt(input[0]);
81
+ return md.conversation.interrupt(input[0], input[1]);
82
82
  case 'conversation.kill':
83
- return md.conversation.kill(input[0]);
83
+ return md.conversation.kill(input[0], input[1]);
84
84
  case 'conversation.delete':
85
- return md.conversation.delete(input[0]);
85
+ return md.conversation.delete(input[0], input[1]);
86
+ case 'conversation.takeOut':
87
+ return md.conversation.takeOut(input[0], input[1], input[2]);
88
+ case 'conversation.decide':
89
+ return md.conversation.decide(input[0], input[1], input[2]);
90
+ case 'conversation.rename':
91
+ return md.conversation.rename(input[0], input[1], input[2]);
92
+ case 'conversation.option':
93
+ return md.conversation.option(input[0], input[1], input[2], input[3]);
94
+ case 'conversation.retry':
95
+ return md.conversation.retry(input[0], input[1], input[2]);
96
+ case 'conversation.pins':
97
+ return md.conversation.pins();
98
+ case 'conversation.pin':
99
+ return md.conversation.pin(input[0]);
100
+ case 'conversation.openedTurns':
101
+ return md.conversation.openedTurns();
102
+ case 'conversation.openTurn':
103
+ return md.conversation.openTurn(input[0], input[1]);
104
+ case 'conversation.dismissSuggestion':
105
+ return md.conversation.dismissSuggestion(input[0], input[1]);
86
106
  case 'chatDraft.write':
87
107
  return md.chatDraft.write(input[0], input[1], input[2]);
88
108
  case 'chatDraft.prepend':
89
109
  return md.chatDraft.prepend(input[0], input[1]);
110
+ case 'chatDraft.append':
111
+ return md.chatDraft.append(input[0], input[1]);
90
112
  case 'chatDraft.discard':
91
113
  return md.chatDraft.discard(input[0]);
92
114
  }
@@ -118,14 +140,15 @@ export function serveMdRuntime(options) {
118
140
  const attachments = new Map();
119
141
  let authorized = true;
120
142
  let opening = null;
121
- const opened = () => (opening ??= untilAnswered(() => md.loaded(), closing.signal));
143
+ const opened = () => (opening ??= untilAnswered(() => md.loaded(), closing.signal, () => true, options.recovery));
122
144
  const watchFacts = (deliver) => {
123
145
  deliver(structuredClone(deploymentFacts));
124
146
  return () => { };
125
147
  };
126
- function attach(port, app, release, reach, code = 'stored') {
148
+ function attach(port, options) {
127
149
  if (!authorized)
128
150
  throw new Error(AUTHORIZATION_ENDED);
151
+ const { app, release, reach, admission, code = 'stored' } = options;
129
152
  const writtenBy = release === undefined ? undefined : { app, release };
130
153
  const view = runtime.within(reach ?? null, { target: app, code });
131
154
  const observations = new Map();
@@ -190,6 +213,15 @@ export function serveMdRuntime(options) {
190
213
  send({ kind: 'failure', id, ...described(error) });
191
214
  }
192
215
  };
216
+ const admitted = admission === undefined
217
+ ? view.md
218
+ : {
219
+ ...view.md,
220
+ async call(name, input) {
221
+ const decided = await admission(name, input);
222
+ return 'refused' in decided ? decided.refused : view.md.call(name, decided.admitted);
223
+ },
224
+ };
193
225
  const serve = async (message) => {
194
226
  if (message.kind === 'hello')
195
227
  return;
@@ -215,13 +247,13 @@ export function serveMdRuntime(options) {
215
247
  return;
216
248
  }
217
249
  const { id, member, input } = message;
218
- const pending = attempted(() => answered(NARROWED.has(WIRE.members[member].reach) ? view.md : md, app, writtenBy, member, input));
250
+ const pending = attempted(() => answered(NARROWED.has(WIRE.members[member].reach) ? admitted : md, app, writtenBy, member, input));
219
251
  return reply(id, member === 'query' ? input[0] : undefined, pending);
220
252
  };
221
253
  port.addEventListener('message', (event) => {
222
254
  if (!serving)
223
255
  return;
224
- const message = request(event.data);
256
+ const message = wireRequest(event.data);
225
257
  if (message === null)
226
258
  return;
227
259
  void serve(message);
@@ -287,3 +319,5 @@ export function serveMdRuntime(options) {
287
319
  }
288
320
  export { entrySeedOf } from './seed.js';
289
321
  export { createRecovery, retryDelay, } from './recovery.js';
322
+ export { undeclared } from './outcome.js';
323
+ export { wireAnswer, wireRequest, } from './wire.js';