@agentshouse/mdruntime 0.1.0-cf6d5f0a5c9c8 → 0.1.0-cf6e25bcd52f6

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 (185) hide show
  1. package/README.md +21 -8
  2. package/dist/adapter.d.ts +139 -32
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +5 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +38 -4
  7. package/dist/attempt.d.ts +16 -0
  8. package/dist/attempt.d.ts.map +1 -0
  9. package/dist/attempt.js +70 -0
  10. package/dist/binary.d.ts +18 -0
  11. package/dist/binary.d.ts.map +1 -0
  12. package/dist/binary.js +8 -0
  13. package/dist/bootstrap.d.ts +32 -9
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +192 -67
  16. package/dist/chain.d.ts +11 -0
  17. package/dist/chain.d.ts.map +1 -0
  18. package/dist/chain.js +64 -0
  19. package/dist/change-set.d.ts +9 -14
  20. package/dist/change-set.d.ts.map +1 -1
  21. package/dist/change-set.js +11 -62
  22. package/dist/change.d.ts +45 -0
  23. package/dist/change.d.ts.map +1 -1
  24. package/dist/change.js +34 -0
  25. package/dist/client.d.ts +33 -14
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +123 -21
  28. package/dist/collection.d.ts +12 -6
  29. package/dist/collection.d.ts.map +1 -1
  30. package/dist/collection.js +51 -76
  31. package/dist/compile.d.ts +16 -0
  32. package/dist/compile.d.ts.map +1 -0
  33. package/dist/compile.js +765 -0
  34. package/dist/connection.d.ts +60 -20
  35. package/dist/connection.d.ts.map +1 -1
  36. package/dist/connection.js +3825 -793
  37. package/dist/conversation.d.ts +42 -12
  38. package/dist/conversation.d.ts.map +1 -1
  39. package/dist/conversation.js +642 -188
  40. package/dist/digest.d.ts +7 -0
  41. package/dist/digest.d.ts.map +1 -0
  42. package/dist/digest.js +113 -0
  43. package/dist/durability.d.ts +5 -1
  44. package/dist/durability.d.ts.map +1 -1
  45. package/dist/durability.js +5 -0
  46. package/dist/entry.d.ts +19 -0
  47. package/dist/entry.d.ts.map +1 -0
  48. package/dist/entry.js +151 -0
  49. package/dist/expectation.d.ts +21 -0
  50. package/dist/expectation.d.ts.map +1 -0
  51. package/dist/expectation.js +70 -0
  52. package/dist/failure.d.ts +13 -0
  53. package/dist/failure.d.ts.map +1 -0
  54. package/dist/failure.js +19 -0
  55. package/dist/fence.d.ts +6 -0
  56. package/dist/fence.d.ts.map +1 -0
  57. package/dist/fence.js +10 -0
  58. package/dist/file.d.ts +2 -19
  59. package/dist/file.d.ts.map +1 -1
  60. package/dist/file.js +7 -122
  61. package/dist/fulltext.d.ts +27 -0
  62. package/dist/fulltext.d.ts.map +1 -0
  63. package/dist/fulltext.js +368 -0
  64. package/dist/host.d.ts +15 -3
  65. package/dist/host.d.ts.map +1 -1
  66. package/dist/host.js +134 -22
  67. package/dist/identity.d.ts +3 -0
  68. package/dist/identity.d.ts.map +1 -1
  69. package/dist/identity.js +9 -0
  70. package/dist/index.d.ts +19 -9
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +8 -0
  73. package/dist/live.d.ts +22 -0
  74. package/dist/live.d.ts.map +1 -0
  75. package/dist/live.js +124 -0
  76. package/dist/media.d.ts +8 -0
  77. package/dist/media.d.ts.map +1 -0
  78. package/dist/media.js +208 -0
  79. package/dist/memory.d.ts +12 -5
  80. package/dist/memory.d.ts.map +1 -1
  81. package/dist/memory.js +128 -29
  82. package/dist/messages.d.ts +28 -0
  83. package/dist/messages.d.ts.map +1 -0
  84. package/dist/messages.js +90 -0
  85. package/dist/model.d.ts +13 -4
  86. package/dist/model.d.ts.map +1 -1
  87. package/dist/model.js +17 -2
  88. package/dist/name.d.ts +4 -0
  89. package/dist/name.d.ts.map +1 -0
  90. package/dist/name.js +122 -0
  91. package/dist/observation.d.ts +20 -2
  92. package/dist/observation.d.ts.map +1 -1
  93. package/dist/observation.js +113 -12
  94. package/dist/open.d.ts +2 -0
  95. package/dist/open.d.ts.map +1 -0
  96. package/dist/open.js +1 -0
  97. package/dist/opened.d.ts +22 -0
  98. package/dist/opened.d.ts.map +1 -0
  99. package/dist/opened.js +107 -0
  100. package/dist/outcome.d.ts +73 -3
  101. package/dist/outcome.d.ts.map +1 -1
  102. package/dist/outcome.js +81 -1
  103. package/dist/overlay.d.ts +15 -5
  104. package/dist/overlay.d.ts.map +1 -1
  105. package/dist/overlay.js +136 -180
  106. package/dist/paths.d.ts +1 -0
  107. package/dist/paths.d.ts.map +1 -1
  108. package/dist/paths.js +4 -0
  109. package/dist/query.d.ts +70 -4
  110. package/dist/query.d.ts.map +1 -1
  111. package/dist/query.js +51 -7
  112. package/dist/reach.d.ts +18 -4
  113. package/dist/reach.d.ts.map +1 -1
  114. package/dist/reach.js +246 -68
  115. package/dist/react.d.ts +12 -8
  116. package/dist/react.d.ts.map +1 -1
  117. package/dist/react.js +8 -17
  118. package/dist/readiness.d.ts +64 -0
  119. package/dist/readiness.d.ts.map +1 -0
  120. package/dist/readiness.js +33 -0
  121. package/dist/reads.d.ts +11 -0
  122. package/dist/reads.d.ts.map +1 -0
  123. package/dist/reads.js +100 -0
  124. package/dist/recovery.d.ts +25 -0
  125. package/dist/recovery.d.ts.map +1 -0
  126. package/dist/recovery.js +198 -0
  127. package/dist/refresh.d.ts +16 -15
  128. package/dist/refresh.d.ts.map +1 -1
  129. package/dist/refresh.js +113 -54
  130. package/dist/replica.d.ts +59 -33
  131. package/dist/replica.d.ts.map +1 -1
  132. package/dist/replica.js +320 -159
  133. package/dist/room-draft.d.ts +41 -9
  134. package/dist/room-draft.d.ts.map +1 -1
  135. package/dist/room-draft.js +185 -36
  136. package/dist/rows.d.ts +37 -35
  137. package/dist/rows.d.ts.map +1 -1
  138. package/dist/rows.js +173 -102
  139. package/dist/save.d.ts +73 -4
  140. package/dist/save.d.ts.map +1 -1
  141. package/dist/save.js +820 -151
  142. package/dist/search.d.ts +41 -29
  143. package/dist/search.d.ts.map +1 -1
  144. package/dist/search.js +37 -105
  145. package/dist/seed.d.ts +16 -0
  146. package/dist/seed.d.ts.map +1 -0
  147. package/dist/seed.js +75 -0
  148. package/dist/shared.d.ts +16 -0
  149. package/dist/shared.d.ts.map +1 -0
  150. package/dist/shared.js +431 -0
  151. package/dist/status.d.ts +11 -2
  152. package/dist/status.d.ts.map +1 -1
  153. package/dist/status.js +3 -9
  154. package/dist/store.d.ts +130 -80
  155. package/dist/store.d.ts.map +1 -1
  156. package/dist/store.js +376 -457
  157. package/dist/stored.d.ts +154 -0
  158. package/dist/stored.d.ts.map +1 -0
  159. package/dist/stored.js +578 -0
  160. package/dist/tables.d.ts +362 -0
  161. package/dist/tables.d.ts.map +1 -0
  162. package/dist/tables.js +627 -0
  163. package/dist/turn.d.ts +9 -0
  164. package/dist/turn.d.ts.map +1 -0
  165. package/dist/turn.js +75 -0
  166. package/dist/validation.d.ts +30 -0
  167. package/dist/validation.d.ts.map +1 -0
  168. package/dist/validation.js +162 -0
  169. package/dist/windows.d.ts +22 -0
  170. package/dist/windows.d.ts.map +1 -0
  171. package/dist/windows.js +89 -0
  172. package/dist/wire.d.ts +172 -33
  173. package/dist/wire.d.ts.map +1 -1
  174. package/dist/wire.js +68 -31
  175. package/dist/words.d.ts +19 -0
  176. package/dist/words.d.ts.map +1 -0
  177. package/dist/words.js +156 -0
  178. package/package.json +26 -15
  179. package/AGENTS.md +0 -253
  180. package/dist/attachment.d.ts +0 -3
  181. package/dist/attachment.d.ts.map +0 -1
  182. package/dist/attachment.js +0 -8
  183. package/dist/read-side.d.ts +0 -18
  184. package/dist/read-side.d.ts.map +0 -1
  185. package/dist/read-side.js +0 -433
package/dist/media.js ADDED
@@ -0,0 +1,208 @@
1
+ export const ROOM_MEDIA = 'room-media';
2
+ const ATTRIBUTES = ['room', 'path', 'revision', 'width', 'height', 'alt'];
3
+ const LOADING = new Set(['room', 'path', 'revision']);
4
+ const NEARING = '600px 0px';
5
+ const RELINKS = 2;
6
+ // The Room's stream brings a file seconds after the text that links it, minutes after on a first open, and a page's reach of its Rooms settles seconds after it opens, so a file not shown yet is asked for again every three seconds.
7
+ const UNSHOWN_MS = 3_000;
8
+ const SHAPE = '16 / 9';
9
+ const STYLE = `:host{display:block}
10
+ [part=box]{position:relative;overflow:hidden}
11
+ [part=box]>img,[part=box]>video,[part=box]>audio{display:block;width:100%;height:100%;object-fit:contain}
12
+ [part=box]>slot{display:flex;align-items:center;justify-content:center;width:100%;height:100%;text-align:center}`;
13
+ const shows = new WeakMap();
14
+ export function shownBy(show, client) {
15
+ shows.set(client, show);
16
+ return client;
17
+ }
18
+ function ratioOf(width, height) {
19
+ const across = Number(width);
20
+ const down = Number(height);
21
+ return Number.isFinite(across) && Number.isFinite(down) && across > 0 && down > 0
22
+ ? `${across} / ${down}`
23
+ : SHAPE;
24
+ }
25
+ function refusedForGood(shown) {
26
+ if (shown.kind === 'revoked-authorization')
27
+ return true;
28
+ return (shown.kind === 'rejected' || shown.kind === 'scoped-refusal') && !shown.retryable;
29
+ }
30
+ function drawnFor(mediaType) {
31
+ if (mediaType.startsWith('image/'))
32
+ return 'img';
33
+ if (mediaType.startsWith('video/'))
34
+ return 'video';
35
+ if (mediaType.startsWith('audio/'))
36
+ return 'audio';
37
+ return null;
38
+ }
39
+ export function defineRoomMedia(client, registry = customElements) {
40
+ if (registry.get(ROOM_MEDIA) !== undefined)
41
+ return;
42
+ const connected = Promise.resolve(client);
43
+ class RoomMedia extends HTMLElement {
44
+ static observedAttributes = ATTRIBUTES;
45
+ #root = this.attachShadow({ mode: 'open' });
46
+ #box = document.createElement('div');
47
+ #fallback = document.createElement('slot');
48
+ #watching = null;
49
+ #near = false;
50
+ #asked = 0;
51
+ #shown = null;
52
+ #drawn = null;
53
+ #loaded = false;
54
+ #relinked = 0;
55
+ constructor() {
56
+ super();
57
+ this.#box.setAttribute('part', 'box');
58
+ this.#root.append(Object.assign(document.createElement('style'), { textContent: STYLE }), this.#box);
59
+ this.#shape();
60
+ }
61
+ connectedCallback() {
62
+ this.#label();
63
+ this.#watching ??= new IntersectionObserver((seen) => {
64
+ if (!seen.some((entry) => entry.isIntersecting) || this.#near)
65
+ return;
66
+ this.#near = true;
67
+ void this.#load();
68
+ }, { rootMargin: NEARING });
69
+ this.#watching.observe(this);
70
+ }
71
+ disconnectedCallback() {
72
+ this.#watching?.disconnect();
73
+ this.#watching = null;
74
+ this.#near = false;
75
+ this.#asked += 1;
76
+ this.#show(null);
77
+ }
78
+ attributeChangedCallback(name, before, after) {
79
+ if (before === after)
80
+ return;
81
+ this.#shape();
82
+ if (this.isConnected)
83
+ this.#label();
84
+ if (!LOADING.has(name) || !this.#near)
85
+ return;
86
+ this.#relinked = 0;
87
+ void this.#load();
88
+ }
89
+ #shape() {
90
+ this.#box.style.aspectRatio = ratioOf(this.getAttribute('width'), this.getAttribute('height'));
91
+ }
92
+ #label() {
93
+ const alt = this.getAttribute('alt') ?? '';
94
+ const drawn = this.#drawn;
95
+ if (drawn instanceof HTMLMediaElement) {
96
+ this.removeAttribute('role');
97
+ this.removeAttribute('aria-label');
98
+ drawn.setAttribute('aria-label', alt);
99
+ return;
100
+ }
101
+ this.setAttribute('role', 'img');
102
+ this.setAttribute('aria-label', alt);
103
+ if (drawn !== null)
104
+ drawn.alt = '';
105
+ }
106
+ async #load() {
107
+ const asked = (this.#asked += 1);
108
+ this.#loaded = false;
109
+ const room = this.getAttribute('room');
110
+ const path = this.getAttribute('path');
111
+ const revision = this.getAttribute('revision') ?? undefined;
112
+ if (room === null || path === null) {
113
+ this.#unreadable();
114
+ return;
115
+ }
116
+ const show = shows.get(await connected);
117
+ const shown = show === undefined ? null : await show(room, path, revision);
118
+ if (asked !== this.#asked)
119
+ return;
120
+ if (shown?.kind === 'link') {
121
+ this.#draw({ url: shown.url, copy: false }, shown.mediaType);
122
+ return;
123
+ }
124
+ if (shown?.kind !== 'binary') {
125
+ this.#unreadable();
126
+ if (shown === null || refusedForGood(shown))
127
+ return;
128
+ setTimeout(() => {
129
+ if (asked === this.#asked && this.#near)
130
+ void this.#load();
131
+ }, UNSHOWN_MS);
132
+ return;
133
+ }
134
+ const copy = await new Response(shown.stream, {
135
+ headers: { 'content-type': shown.mediaType },
136
+ }).blob();
137
+ if (asked !== this.#asked)
138
+ return;
139
+ this.#draw({ url: URL.createObjectURL(copy), copy: true }, shown.mediaType);
140
+ }
141
+ #show(shown, content = null) {
142
+ if (this.#shown?.copy === true)
143
+ URL.revokeObjectURL(this.#shown.url);
144
+ this.#shown = shown;
145
+ if (content !== this.#drawn)
146
+ this.#drawn = null;
147
+ if (content === null)
148
+ this.#box.replaceChildren();
149
+ else if (content.parentNode !== this.#box)
150
+ this.#box.replaceChildren(content);
151
+ this.#label();
152
+ }
153
+ #unreadable() {
154
+ this.#show(null, this.#fallback);
155
+ }
156
+ #draw(shown, mediaType) {
157
+ const tag = drawnFor(mediaType);
158
+ if (tag === null) {
159
+ if (shown.copy)
160
+ URL.revokeObjectURL(shown.url);
161
+ this.#unreadable();
162
+ return;
163
+ }
164
+ const kept = this.#drawn?.localName === tag ? this.#drawn : null;
165
+ const drawn = kept ?? document.createElement(tag);
166
+ if (kept === null) {
167
+ if (drawn instanceof HTMLImageElement)
168
+ drawn.decoding = 'async';
169
+ if (drawn instanceof HTMLMediaElement) {
170
+ drawn.controls = true;
171
+ drawn.preload = 'metadata';
172
+ if (drawn instanceof HTMLVideoElement)
173
+ drawn.playsInline = true;
174
+ }
175
+ drawn.addEventListener(drawn instanceof HTMLImageElement ? 'load' : 'loadedmetadata', () => {
176
+ if (drawn !== this.#drawn)
177
+ return;
178
+ this.#loaded = true;
179
+ this.#relinked = 0;
180
+ });
181
+ drawn.addEventListener('error', () => this.#failed(drawn));
182
+ }
183
+ this.#drawn = drawn;
184
+ this.#show(shown, drawn);
185
+ drawn.src = shown.url;
186
+ }
187
+ #failed(drawn) {
188
+ if (drawn !== this.#drawn)
189
+ return;
190
+ if (this.#shown?.copy !== false || !this.#loaded || this.#relinked >= RELINKS) {
191
+ this.#unreadable();
192
+ return;
193
+ }
194
+ this.#relinked += 1;
195
+ if (drawn instanceof HTMLMediaElement) {
196
+ const at = drawn.currentTime;
197
+ const playing = !drawn.paused;
198
+ drawn.addEventListener('loadedmetadata', () => {
199
+ drawn.currentTime = at;
200
+ if (playing)
201
+ void drawn.play().catch(() => undefined);
202
+ }, { once: true });
203
+ }
204
+ void this.#load();
205
+ }
206
+ }
207
+ registry.define(ROOM_MEDIA, RoomMedia);
208
+ }
package/dist/memory.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import type { ModelResult } from './model.js';
2
- import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type HeadChange, type ListedConversation, type Member, type ProviderLimit, type Retention, type RoomAttachment, type ServiceMode } from './adapter.js';
2
+ import { type AcceptedMessage, type ActionResult, type Adapter, type BinaryFile, type Capability, type ConversationAction, type ConversationEvent, type DiscoveryScope, type DiscoveredRoom, type HeadChange, type ListedConversation, type Member, type ProviderLimit, type Retention, type ServiceMode } from './adapter.js';
3
3
  export type MemoryRoom = DiscoveredRoom & {
4
4
  model?: ModelResult;
5
- selectionModel?: ModelResult;
6
5
  documents?: Readonly<Record<string, string>>;
7
6
  revisions?: Readonly<Record<string, string>>;
7
+ fileIds?: Readonly<Record<string, string>>;
8
8
  changes?: Readonly<Record<string, HeadChange>>;
9
- binaryTargets?: readonly string[];
10
- attachments?: readonly RoomAttachment[];
9
+ binaryFiles?: Readonly<Record<string, BinaryFile>>;
10
+ folders?: readonly string[];
11
+ blobs?: Readonly<Record<string, Blob>>;
11
12
  };
12
13
  export type MemoryConversation = {
13
14
  conversation: string;
@@ -25,18 +26,24 @@ export type MemoryAdapterOptions = {
25
26
  retention?: Retention;
26
27
  member?: Member;
27
28
  unopened?: boolean;
29
+ exhaustiveDiscovery?: true;
30
+ roomTypes?: string;
28
31
  };
29
32
  export type MemoryAdapter = Adapter & {
30
33
  setRooms(rooms: readonly MemoryRoom[]): void;
31
34
  setConversations(conversations: readonly MemoryConversation[]): void;
32
35
  script(operation: keyof Adapter, answer: unknown): void;
33
36
  open(): void;
34
- close(revoked?: boolean): void;
37
+ close(closing?: {
38
+ revoked?: boolean;
39
+ lost?: boolean;
40
+ }): void;
35
41
  expire(locators: readonly string[]): void;
36
42
  notifyRoomVersion(notification: {
37
43
  locator: string;
38
44
  roomVersion: string;
39
45
  }): void;
46
+ notifyAuthorityChanged(scope?: DiscoveryScope): void;
40
47
  notifyConversation(event: ConversationEvent): void;
41
48
  notifyServiceMode(mode: ServiceMode): void;
42
49
  heldRooms(): readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAItB,KAAK,cAAc,EACnB,KAAK,UAAU,EAGf,KAAK,kBAAkB,EACvB,KAAK,MAAM,EAGX,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAkBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,SAAS,IAAI,SAAS,MAAM,EAAE,CAAC;IAC/B,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC;AA+CF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA2brF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
package/dist/memory.js CHANGED
@@ -1,7 +1,11 @@
1
1
  import { sameChange } from './overlay.js';
2
+ const ATTACHMENTS = 'attachments';
3
+ function lastName(path) {
4
+ return path.slice(path.lastIndexOf('/') + 1);
5
+ }
2
6
  const FIXTURE_RETENTION = {
3
7
  history: { kind: 'duration', seconds: 1 },
4
- outcome: 1,
8
+ outcome: 604_800,
5
9
  refreshHorizon: 1,
6
10
  };
7
11
  function declaredRetention(value) {
@@ -15,12 +19,7 @@ function declaredRetention(value) {
15
19
  }
16
20
  const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
17
21
  function modelsOf(room) {
18
- return {
19
- collection: room.model ?? MODEL_ABSENT,
20
- ...(room.typedSelection === undefined
21
- ? {}
22
- : { selection: room.selectionModel ?? MODEL_ABSENT }),
23
- };
22
+ return { collection: room.model ?? MODEL_ABSENT };
24
23
  }
25
24
  function changedModels(room, from) {
26
25
  const now = modelsOf(room);
@@ -55,7 +54,10 @@ export function createMemoryAdapter(options = {}) {
55
54
  const scripted = new Map();
56
55
  const unsealed = new Map();
57
56
  const sealed = new Set();
57
+ const sentTurns = new Map();
58
58
  const historyPageSize = options.historyPageSize;
59
+ const attached = new Map();
60
+ const linked = new WeakMap();
59
61
  let held = [];
60
62
  let expiring = [];
61
63
  let replicated = [];
@@ -86,6 +88,19 @@ export function createMemoryAdapter(options = {}) {
86
88
  const wanted = ordinals.get(`${locator}\u0000${target}`);
87
89
  return held !== undefined && wanted !== undefined && held >= wanted;
88
90
  }
91
+ function heldBlob(room, path) {
92
+ return attached.get(`${room.locator}\u0000${path}`) ?? room.blobs?.[path];
93
+ }
94
+ function freePath(room, name) {
95
+ const dot = name.lastIndexOf('.');
96
+ const stem = dot > 0 ? name.slice(0, dot) : name;
97
+ const extension = dot > 0 ? name.slice(dot) : '';
98
+ for (let count = 1;; count += 1) {
99
+ const path = `${ATTACHMENTS}/${count === 1 ? stem : `${stem}-${count}`}${extension}`;
100
+ if (heldBlob(room, path) === undefined && room.documents?.[path] === undefined)
101
+ return path;
102
+ }
103
+ }
89
104
  function retain(entries) {
90
105
  for (const room of entries) {
91
106
  note(room.locator, room);
@@ -114,25 +129,39 @@ export function createMemoryAdapter(options = {}) {
114
129
  const size = pageSize ?? paths.length;
115
130
  const taken = paths.slice(from, from + size);
116
131
  const next = from + taken.length;
117
- const targets = opening ? (room.binaryTargets ?? []) : [];
132
+ const targets = opening ? Object.keys(room.binaryFiles ?? {}) : [];
118
133
  return {
119
134
  kind: 'bootstrap',
120
135
  roomVersion: room.roomVersion,
121
136
  ...(opening ? { models: modelsOf(room) } : {}),
122
137
  documents: named(room.documents ?? {}, taken),
123
- revisions: named(room.revisions ?? {}, taken),
138
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
139
+ ...(room.fileIds === undefined
140
+ ? {}
141
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
124
142
  changes: named(room.changes ?? {}, [...taken, ...targets]),
125
- binaryTargets: targets,
126
- ...(opening && room.attachments !== undefined ? { attachments: room.attachments } : {}),
143
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
144
+ ...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
127
145
  ...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
128
146
  };
129
147
  }
148
+ function foldersMoved(room, from) {
149
+ const now = new Set(room.folders ?? []);
150
+ const before = new Set(from.folders ?? []);
151
+ const folders = [...now].filter((folder) => !before.has(folder)).sort();
152
+ const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
153
+ return {
154
+ ...(folders.length === 0 ? {} : { folders }),
155
+ ...(folderRemovals.length === 0 ? {} : { folderRemovals }),
156
+ };
157
+ }
130
158
  function advancement(room, from, at) {
131
159
  const current = room.documents ?? {};
132
160
  const previous = from.documents ?? {};
133
- const currentTargets = new Set(room.binaryTargets ?? []);
134
- const previousTargets = new Set(from.binaryTargets ?? []);
161
+ const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
162
+ const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
135
163
  const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
164
+ room.fileIds?.[path] !== from.fileIds?.[path] ||
136
165
  !sameChange(room.changes?.[path], from.changes?.[path]);
137
166
  const changed = Object.keys(current)
138
167
  .filter((path) => current[path] !== previous[path] || headMoved(path))
@@ -147,24 +176,25 @@ export function createMemoryAdapter(options = {}) {
147
176
  const targets = opening
148
177
  ? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
149
178
  : [];
150
- const attachments = room.attachments ?? [];
151
- const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
152
179
  const models = opening ? changedModels(room, from) : undefined;
153
180
  return {
154
181
  kind: 'net-advancement',
155
182
  roomVersion: room.roomVersion,
156
183
  ...(models === undefined ? {} : { models }),
157
184
  documents: named(current, taken),
158
- revisions: named(room.revisions ?? {}, taken),
185
+ revisions: named(room.revisions ?? {}, [...taken, ...targets]),
186
+ ...(room.fileIds === undefined
187
+ ? {}
188
+ : { fileIds: named(room.fileIds, [...taken, ...targets]) }),
159
189
  changes: named(room.changes ?? {}, [...taken, ...targets]),
160
- binaryTargets: targets,
190
+ binaryFiles: named(room.binaryFiles ?? {}, targets),
191
+ ...(opening ? foldersMoved(room, from) : {}),
161
192
  removals: opening
162
193
  ? [
163
194
  ...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
164
195
  ...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
165
196
  ].sort()
166
197
  : [],
167
- ...(declared ? { attachments } : {}),
168
198
  ...(pageToken === undefined ? {} : { pageToken }),
169
199
  };
170
200
  }
@@ -185,7 +215,7 @@ export function createMemoryAdapter(options = {}) {
185
215
  function historiesOf(input) {
186
216
  const asked = input?.conversations;
187
217
  if (!Array.isArray(asked))
188
- return { kind: 'rejected', code: 'invalid_request', fields: {} };
218
+ return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
189
219
  const histories = [];
190
220
  for (const entry of asked) {
191
221
  const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
@@ -213,21 +243,32 @@ export function createMemoryAdapter(options = {}) {
213
243
  const named = typeof input.conversation === 'string' ? input.conversation : '';
214
244
  const conversation = scripted.get(named);
215
245
  if (conversation === undefined) {
216
- return { kind: 'rejected', code: 'unknown-conversation', fields: { conversation: named } };
246
+ return {
247
+ kind: 'rejected',
248
+ code: 'unknown-conversation',
249
+ fields: { conversation: named },
250
+ retryable: false,
251
+ };
217
252
  }
218
253
  const outcome = conversation.outcomes?.[name];
219
254
  if (outcome !== undefined)
220
255
  return outcome;
221
256
  if (name === 'conversation.send') {
257
+ const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
258
+ const answered = operation === null ? undefined : sentTurns.get(operation);
259
+ if (answered !== undefined)
260
+ return { kind: 'action', result: { turn: answered } };
222
261
  issued += 1;
223
262
  const turn = `turn-${issued}`;
224
263
  unsealed.set(turn, named);
264
+ if (operation !== null)
265
+ sentTurns.set(operation, turn);
225
266
  return { kind: 'action', result: { turn } };
226
267
  }
227
268
  if (name === 'conversation.cancel') {
228
269
  const turn = typeof input.turn === 'string' ? input.turn : '';
229
270
  if (sealed.has(turn) || !unsealed.has(turn)) {
230
- return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
271
+ return { kind: 'rejected', code: 'turn-sealed', fields: { turn }, retryable: false };
231
272
  }
232
273
  unsealed.delete(turn);
233
274
  return { kind: 'action', result: { turn, cancelled: true } };
@@ -252,6 +293,8 @@ export function createMemoryAdapter(options = {}) {
252
293
  };
253
294
  }
254
295
  return {
296
+ ...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
297
+ ...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
255
298
  setRooms(next) {
256
299
  rooms = [...next];
257
300
  retain(rooms);
@@ -264,9 +307,9 @@ export function createMemoryAdapter(options = {}) {
264
307
  for (const observer of observers)
265
308
  observer({ kind: 'opened' });
266
309
  },
267
- close(revoked = false) {
310
+ close({ revoked = false, lost = !revoked } = {}) {
268
311
  for (const observer of observers)
269
- observer({ kind: 'closed', revoked });
312
+ observer({ kind: 'closed', revoked, lost });
270
313
  },
271
314
  expire(locators) {
272
315
  expiring = [...locators];
@@ -275,6 +318,13 @@ export function createMemoryAdapter(options = {}) {
275
318
  for (const observer of observers)
276
319
  observer({ kind: 'room-version', locator, roomVersion });
277
320
  },
321
+ notifyAuthorityChanged(scope) {
322
+ for (const observer of observers) {
323
+ observer(scope === undefined
324
+ ? { kind: 'authority-changed' }
325
+ : { kind: 'authority-changed', scope });
326
+ }
327
+ },
278
328
  notifyConversation(event) {
279
329
  if (event.kind === 'accepted-message') {
280
330
  sealed.add(event.message.turn);
@@ -335,17 +385,19 @@ export function createMemoryAdapter(options = {}) {
335
385
  },
336
386
  reopen() {
337
387
  queueMicrotask(() => {
338
- for (const observer of observers)
339
- observer({ kind: 'closed', revoked: false });
388
+ for (const observer of observers) {
389
+ observer({ kind: 'closed', revoked: false, lost: false });
390
+ }
340
391
  });
341
392
  },
393
+ published() { },
342
394
  observe(notify) {
343
395
  observers.add(notify);
344
396
  queueMicrotask(() => {
345
397
  if (!observers.has(notify))
346
398
  return;
347
399
  if (options.unopened === true) {
348
- notify({ kind: 'closed', revoked: false });
400
+ notify({ kind: 'closed', revoked: false, lost: true });
349
401
  return;
350
402
  }
351
403
  announceList();
@@ -421,8 +473,20 @@ export function createMemoryAdapter(options = {}) {
421
473
  if (room === undefined) {
422
474
  return { kind: 'room-not-readable', locator: request.locator };
423
475
  }
424
- return { kind: 'rejected', code: 'unscripted-mutation', fields: {}, affected: {} };
425
- }, request).then((answer) => note(request.locator, answer));
476
+ return {
477
+ kind: 'rejected',
478
+ code: 'unscripted-mutation',
479
+ fields: {},
480
+ retryable: false,
481
+ affected: {},
482
+ };
483
+ }, request).then((answer) => {
484
+ const destination = request.changeBatch.between?.destination.room;
485
+ if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
486
+ note(destination, answer.destination);
487
+ }
488
+ return note(request.locator, answer);
489
+ });
426
490
  },
427
491
  async history(_authorization, request) {
428
492
  return resolveScript(scripts.history, () => {
@@ -436,11 +500,46 @@ export function createMemoryAdapter(options = {}) {
436
500
  };
437
501
  }, request);
438
502
  },
503
+ async binary(_authorization, request) {
504
+ return resolveScript(scripts.binary, () => {
505
+ const room = rooms.find((entry) => entry.locator === request.locator);
506
+ if (room === undefined)
507
+ return { kind: 'room-not-readable', locator: request.locator };
508
+ const blob = heldBlob(room, request.path);
509
+ return blob === undefined
510
+ ? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
511
+ : { kind: 'binary', body: blob.stream(), mediaType: blob.type };
512
+ }, request);
513
+ },
514
+ async link(_authorization, request) {
515
+ return resolveScript(scripts.link, () => {
516
+ const room = rooms.find((entry) => entry.locator === request.locator);
517
+ if (room === undefined)
518
+ return { kind: 'room-not-readable', locator: request.locator };
519
+ const blob = heldBlob(room, request.path);
520
+ if (blob === undefined) {
521
+ return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
522
+ }
523
+ const url = linked.get(blob) ?? URL.createObjectURL(blob);
524
+ linked.set(blob, url);
525
+ return { kind: 'link', url, name: lastName(request.path), mediaType: blob.type };
526
+ }, request);
527
+ },
528
+ async attach(_authorization, request) {
529
+ return resolveScript(scripts.attach, () => {
530
+ const room = rooms.find((entry) => entry.locator === request.locator);
531
+ if (room === undefined)
532
+ return { kind: 'room-not-readable', locator: request.locator };
533
+ const path = freePath(room, request.name);
534
+ attached.set(`${room.locator}\u0000${path}`, request.blob);
535
+ return { kind: 'attached', path, revision: `attached-${attached.size}` };
536
+ }, request);
537
+ },
439
538
  async action(_authorization, request) {
440
539
  return resolveScript(scripts.action, () => {
441
540
  if (request.name.startsWith('conversation.'))
442
541
  return conversationAction(request);
443
- return { kind: 'rejected', code: 'unscripted-action', fields: {} };
542
+ return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
444
543
  }, request).then((answer) => {
445
544
  if (answer.kind === 'action' && answer.at !== undefined)
446
545
  note(answer.at.locator, answer.at);
@@ -0,0 +1,28 @@
1
+ import type { AcceptedMessage } from './adapter.js';
2
+ import type { Connection } from './tables.js';
3
+ export declare const MESSAGE_TABLES: readonly string[];
4
+ export type HeldConversation = {
5
+ readonly conversation: string;
6
+ readonly read: string | null | undefined;
7
+ readonly partial: boolean;
8
+ };
9
+ export type MessageWindow = {
10
+ readonly messages: AcceptedMessage[];
11
+ readonly more: boolean;
12
+ };
13
+ export type ConversationWrite = {
14
+ readonly conversation: string;
15
+ readonly messages: readonly AcceptedMessage[];
16
+ readonly read?: {
17
+ readonly at: string | null;
18
+ readonly partial: boolean;
19
+ };
20
+ };
21
+ export declare function heldConversations(connection: Connection): HeldConversation[];
22
+ export declare function keptMessages(connection: Connection, { conversation, messages, read }: ConversationWrite): null;
23
+ export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null): MessageWindow;
24
+ export declare function messageCount(connection: Connection, conversation: string): number;
25
+ export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
26
+ export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
27
+ export declare function forgottenMessages(connection: Connection): void;
28
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAM3C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3E,CAAC;AAMF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAmB5E;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,GAClD,IAAI,CAoCN;AAYD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GACvC,aAAa,CAUf;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAMjF;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/F;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAW9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAG9D"}