@agentshouse/mdruntime 0.1.0-c56daf494ecb4 → 0.1.0-c59a5a6bd2f31

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 (290) hide show
  1. package/README.md +19 -16
  2. package/dist/acceptance.d.ts +26 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +384 -0
  5. package/dist/adapter.d.ts +152 -57
  6. package/dist/adapter.d.ts.map +1 -1
  7. package/dist/attached-model.d.ts +7 -10
  8. package/dist/attached-model.d.ts.map +1 -1
  9. package/dist/attached-model.js +40 -41
  10. package/dist/binary.d.ts +0 -5
  11. package/dist/binary.d.ts.map +1 -1
  12. package/dist/binary.js +1 -1
  13. package/dist/bootstrap.d.ts +31 -11
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +323 -93
  16. package/dist/chain.d.ts +12 -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 -63
  22. package/dist/change.d.ts +32 -1
  23. package/dist/change.d.ts.map +1 -1
  24. package/dist/change.js +10 -1
  25. package/dist/chat-types.d.ts +3 -0
  26. package/dist/chat-types.d.ts.map +1 -0
  27. package/dist/chat-types.js +2 -0
  28. package/dist/client.d.ts +38 -16
  29. package/dist/client.d.ts.map +1 -1
  30. package/dist/client.js +101 -12
  31. package/dist/collection.d.ts +11 -7
  32. package/dist/collection.d.ts.map +1 -1
  33. package/dist/collection.js +38 -79
  34. package/dist/compile.d.ts +16 -0
  35. package/dist/compile.d.ts.map +1 -0
  36. package/dist/compile.js +717 -0
  37. package/dist/connection.d.ts +44 -39
  38. package/dist/connection.d.ts.map +1 -1
  39. package/dist/connection.js +2307 -1712
  40. package/dist/context.d.ts +2 -0
  41. package/dist/context.d.ts.map +1 -0
  42. package/dist/{chat/context.js → context.js} +1 -4
  43. package/dist/conversation-row.d.ts +33 -0
  44. package/dist/conversation-row.d.ts.map +1 -0
  45. package/dist/conversation-row.js +47 -0
  46. package/dist/conversation.d.ts +50 -20
  47. package/dist/conversation.d.ts.map +1 -1
  48. package/dist/conversation.js +897 -303
  49. package/dist/digest.d.ts +7 -0
  50. package/dist/digest.d.ts.map +1 -0
  51. package/dist/digest.js +113 -0
  52. package/dist/durability.d.ts +10 -1
  53. package/dist/durability.d.ts.map +1 -1
  54. package/dist/durability.js +5 -0
  55. package/dist/entry.d.ts +7 -4
  56. package/dist/entry.d.ts.map +1 -1
  57. package/dist/entry.js +33 -28
  58. package/dist/figures.d.ts +48 -0
  59. package/dist/figures.d.ts.map +1 -0
  60. package/dist/figures.js +197 -0
  61. package/dist/file.d.ts +2 -19
  62. package/dist/file.d.ts.map +1 -1
  63. package/dist/file.js +7 -122
  64. package/dist/host.d.ts +11 -2
  65. package/dist/host.d.ts.map +1 -1
  66. package/dist/host.js +127 -17
  67. package/dist/index.d.ts +27 -11
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +10 -0
  70. package/dist/install.d.ts +86 -0
  71. package/dist/install.d.ts.map +1 -0
  72. package/dist/install.js +537 -0
  73. package/dist/job.d.ts +33 -0
  74. package/dist/job.d.ts.map +1 -0
  75. package/dist/job.js +54 -0
  76. package/dist/live.d.ts +23 -0
  77. package/dist/live.d.ts.map +1 -0
  78. package/dist/live.js +165 -0
  79. package/dist/log.d.ts +1 -0
  80. package/dist/log.d.ts.map +1 -1
  81. package/dist/media.d.ts +8 -0
  82. package/dist/media.d.ts.map +1 -0
  83. package/dist/media.js +218 -0
  84. package/dist/memory.d.ts +19 -5
  85. package/dist/memory.d.ts.map +1 -1
  86. package/dist/memory.js +253 -94
  87. package/dist/messages.d.ts +52 -0
  88. package/dist/messages.d.ts.map +1 -0
  89. package/dist/messages.js +168 -0
  90. package/dist/model.d.ts +11 -11
  91. package/dist/model.d.ts.map +1 -1
  92. package/dist/model.js +7 -10
  93. package/dist/name.d.ts +4 -0
  94. package/dist/name.d.ts.map +1 -0
  95. package/dist/name.js +122 -0
  96. package/dist/observation.d.ts +22 -4
  97. package/dist/observation.d.ts.map +1 -1
  98. package/dist/observation.js +120 -14
  99. package/dist/opened.d.ts +22 -0
  100. package/dist/opened.d.ts.map +1 -0
  101. package/dist/opened.js +107 -0
  102. package/dist/outcome.d.ts +50 -7
  103. package/dist/outcome.d.ts.map +1 -1
  104. package/dist/outcome.js +43 -0
  105. package/dist/overlay.d.ts +4 -4
  106. package/dist/overlay.d.ts.map +1 -1
  107. package/dist/overlay.js +111 -182
  108. package/dist/{chat/parts.d.ts → parts.d.ts} +11 -9
  109. package/dist/parts.d.ts.map +1 -0
  110. package/dist/{chat/parts.js → parts.js} +45 -46
  111. package/dist/paths.d.ts +1 -0
  112. package/dist/paths.d.ts.map +1 -1
  113. package/dist/paths.js +4 -0
  114. package/dist/query.d.ts +50 -183
  115. package/dist/query.d.ts.map +1 -1
  116. package/dist/query.js +3 -464
  117. package/dist/{chat/questions.d.ts → questions.d.ts} +3 -2
  118. package/dist/questions.d.ts.map +1 -0
  119. package/dist/{chat/questions.js → questions.js} +8 -1
  120. package/dist/reach.d.ts +19 -7
  121. package/dist/reach.d.ts.map +1 -1
  122. package/dist/reach.js +289 -89
  123. package/dist/react.d.ts +11 -6
  124. package/dist/react.d.ts.map +1 -1
  125. package/dist/react.js +7 -17
  126. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  127. package/dist/read.d.ts.map +1 -0
  128. package/dist/{chat/read.js → read.js} +4 -0
  129. package/dist/readiness.d.ts +50 -0
  130. package/dist/readiness.d.ts.map +1 -0
  131. package/dist/readiness.js +27 -0
  132. package/dist/reads.d.ts +35 -0
  133. package/dist/reads.d.ts.map +1 -0
  134. package/dist/reads.js +128 -0
  135. package/dist/recovery.d.ts +26 -0
  136. package/dist/recovery.d.ts.map +1 -0
  137. package/dist/recovery.js +232 -0
  138. package/dist/refresh.d.ts +17 -14
  139. package/dist/refresh.d.ts.map +1 -1
  140. package/dist/refresh.js +143 -51
  141. package/dist/replica.d.ts +55 -33
  142. package/dist/replica.d.ts.map +1 -1
  143. package/dist/replica.js +332 -154
  144. package/dist/room-draft.d.ts +37 -6
  145. package/dist/room-draft.d.ts.map +1 -1
  146. package/dist/room-draft.js +161 -74
  147. package/dist/room-drafts.d.ts +29 -0
  148. package/dist/room-drafts.d.ts.map +1 -0
  149. package/dist/room-drafts.js +216 -0
  150. package/dist/rows.d.ts +30 -37
  151. package/dist/rows.d.ts.map +1 -1
  152. package/dist/rows.js +59 -126
  153. package/dist/save.d.ts +53 -9
  154. package/dist/save.d.ts.map +1 -1
  155. package/dist/save.js +542 -172
  156. package/dist/saves.d.ts +96 -0
  157. package/dist/saves.d.ts.map +1 -0
  158. package/dist/saves.js +999 -0
  159. package/dist/search.d.ts +15 -55
  160. package/dist/search.d.ts.map +1 -1
  161. package/dist/search.js +10 -121
  162. package/dist/seed.d.ts +30 -0
  163. package/dist/seed.d.ts.map +1 -0
  164. package/dist/seed.js +141 -0
  165. package/dist/shared.d.ts +15 -0
  166. package/dist/shared.d.ts.map +1 -0
  167. package/dist/shared.js +421 -0
  168. package/dist/socket/admission.d.ts +7 -0
  169. package/dist/socket/admission.d.ts.map +1 -0
  170. package/dist/socket/admission.js +39 -0
  171. package/dist/socket/answers.d.ts +6 -0
  172. package/dist/socket/answers.d.ts.map +1 -0
  173. package/dist/socket/answers.js +20 -0
  174. package/dist/socket/reads.d.ts +10 -0
  175. package/dist/socket/reads.d.ts.map +1 -0
  176. package/dist/socket/reads.js +31 -0
  177. package/dist/socket.d.ts +43 -0
  178. package/dist/socket.d.ts.map +1 -0
  179. package/dist/socket.js +96 -0
  180. package/dist/source.d.ts +61 -0
  181. package/dist/source.d.ts.map +1 -0
  182. package/dist/source.js +81 -0
  183. package/dist/status.d.ts +5 -2
  184. package/dist/status.d.ts.map +1 -1
  185. package/dist/status.js +3 -7
  186. package/dist/store/fences.d.ts +16 -0
  187. package/dist/store/fences.d.ts.map +1 -0
  188. package/dist/store/fences.js +26 -0
  189. package/dist/store/installs.d.ts +30 -0
  190. package/dist/store/installs.d.ts.map +1 -0
  191. package/dist/store/installs.js +34 -0
  192. package/dist/store/records.d.ts +212 -0
  193. package/dist/store/records.d.ts.map +1 -0
  194. package/dist/store/records.js +408 -0
  195. package/dist/store/room-held.d.ts +8 -0
  196. package/dist/store/room-held.d.ts.map +1 -0
  197. package/dist/store/room-held.js +17 -0
  198. package/dist/store/watchers.d.ts +15 -0
  199. package/dist/store/watchers.d.ts.map +1 -0
  200. package/dist/store/watchers.js +36 -0
  201. package/dist/store/writes.d.ts +24 -0
  202. package/dist/store/writes.d.ts.map +1 -0
  203. package/dist/store/writes.js +125 -0
  204. package/dist/store.d.ts +77 -120
  205. package/dist/store.d.ts.map +1 -1
  206. package/dist/store.js +112 -529
  207. package/dist/stored.d.ts +156 -0
  208. package/dist/stored.d.ts.map +1 -0
  209. package/dist/stored.js +637 -0
  210. package/dist/tables.d.ts +407 -0
  211. package/dist/tables.d.ts.map +1 -0
  212. package/dist/tables.js +724 -0
  213. package/dist/tallies.d.ts +18 -0
  214. package/dist/tallies.d.ts.map +1 -0
  215. package/dist/tallies.js +129 -0
  216. package/dist/transfer.d.ts +0 -5
  217. package/dist/transfer.d.ts.map +1 -1
  218. package/dist/turn.d.ts +9 -0
  219. package/dist/turn.d.ts.map +1 -0
  220. package/dist/turn.js +75 -0
  221. package/dist/validation.d.ts +29 -0
  222. package/dist/validation.d.ts.map +1 -0
  223. package/dist/validation.js +104 -0
  224. package/dist/windows.d.ts +11 -0
  225. package/dist/windows.d.ts.map +1 -0
  226. package/dist/windows.js +16 -0
  227. package/dist/wire.d.ts +179 -32
  228. package/dist/wire.d.ts.map +1 -1
  229. package/dist/wire.js +61 -31
  230. package/package.json +18 -19
  231. package/AGENTS.md +0 -302
  232. package/dist/chat/acts.d.ts +0 -34
  233. package/dist/chat/acts.d.ts.map +0 -1
  234. package/dist/chat/acts.js +0 -36
  235. package/dist/chat/context.d.ts +0 -3
  236. package/dist/chat/context.d.ts.map +0 -1
  237. package/dist/chat/input.d.ts +0 -9
  238. package/dist/chat/input.d.ts.map +0 -1
  239. package/dist/chat/input.js +0 -99
  240. package/dist/chat/kit.d.ts +0 -60
  241. package/dist/chat/kit.d.ts.map +0 -1
  242. package/dist/chat/kit.js +0 -123
  243. package/dist/chat/lasting.d.ts +0 -6
  244. package/dist/chat/lasting.d.ts.map +0 -1
  245. package/dist/chat/lasting.js +0 -19
  246. package/dist/chat/list.d.ts +0 -26
  247. package/dist/chat/list.d.ts.map +0 -1
  248. package/dist/chat/list.js +0 -62
  249. package/dist/chat/markdown.d.ts +0 -20
  250. package/dist/chat/markdown.d.ts.map +0 -1
  251. package/dist/chat/markdown.js +0 -188
  252. package/dist/chat/message.d.ts +0 -6
  253. package/dist/chat/message.d.ts.map +0 -1
  254. package/dist/chat/message.js +0 -192
  255. package/dist/chat/messages.d.ts +0 -21
  256. package/dist/chat/messages.d.ts.map +0 -1
  257. package/dist/chat/messages.js +0 -151
  258. package/dist/chat/name.d.ts +0 -6
  259. package/dist/chat/name.d.ts.map +0 -1
  260. package/dist/chat/name.js +0 -37
  261. package/dist/chat/opened.d.ts +0 -11
  262. package/dist/chat/opened.d.ts.map +0 -1
  263. package/dist/chat/opened.js +0 -17
  264. package/dist/chat/overlay.d.ts +0 -31
  265. package/dist/chat/overlay.d.ts.map +0 -1
  266. package/dist/chat/overlay.js +0 -97
  267. package/dist/chat/parts.d.ts.map +0 -1
  268. package/dist/chat/process.d.ts +0 -20
  269. package/dist/chat/process.d.ts.map +0 -1
  270. package/dist/chat/process.js +0 -32
  271. package/dist/chat/provider.d.ts +0 -63
  272. package/dist/chat/provider.d.ts.map +0 -1
  273. package/dist/chat/provider.js +0 -645
  274. package/dist/chat/question.d.ts +0 -9
  275. package/dist/chat/question.d.ts.map +0 -1
  276. package/dist/chat/question.js +0 -80
  277. package/dist/chat/questions.d.ts.map +0 -1
  278. package/dist/chat/read.d.ts.map +0 -1
  279. package/dist/chat/ready.d.ts +0 -33
  280. package/dist/chat/ready.d.ts.map +0 -1
  281. package/dist/chat/ready.js +0 -91
  282. package/dist/chat/style.d.ts +0 -4
  283. package/dist/chat/style.d.ts.map +0 -1
  284. package/dist/chat/style.js +0 -302
  285. package/dist/chat.d.ts +0 -14
  286. package/dist/chat.d.ts.map +0 -1
  287. package/dist/chat.js +0 -8
  288. package/dist/read-side.d.ts +0 -18
  289. package/dist/read-side.d.ts.map +0 -1
  290. package/dist/read-side.js +0 -440
package/dist/opened.js ADDED
@@ -0,0 +1,107 @@
1
+ import { digest } from './digest.js';
2
+ import { binaryLocalId } from './identity.js';
3
+ import { FILE_PART_BYTES } from './tables.js';
4
+ const UNCERTAIN = { kind: 'transport-uncertainty' };
5
+ function kept({ key, byteLength, mediaType }) {
6
+ return { kind: 'binary', file: key, byteLength, mediaType };
7
+ }
8
+ function taken(chunks, size) {
9
+ const part = new Uint8Array(size);
10
+ let at = 0;
11
+ while (at < size) {
12
+ const chunk = chunks[0];
13
+ const wanted = Math.min(chunk.length, size - at);
14
+ part.set(chunk.subarray(0, wanted), at);
15
+ at += wanted;
16
+ if (wanted === chunk.length)
17
+ chunks.shift();
18
+ else
19
+ chunks[0] = chunk.subarray(wanted);
20
+ }
21
+ return part;
22
+ }
23
+ export function openedFiles(database, fenced) {
24
+ const fetching = new Map();
25
+ async function find(name) {
26
+ const held = await database.ask({ kind: 'opened.find', ...name });
27
+ return held === null ? null : kept(held);
28
+ }
29
+ async function written(name, { body, mediaType, sha256 }) {
30
+ const key = binaryLocalId();
31
+ const reader = body.getReader();
32
+ const hashed = digest();
33
+ const chunks = [];
34
+ let held = 0;
35
+ let size = 0;
36
+ let part = 0;
37
+ const write = async (bytes) => {
38
+ if (!(await database.ask({ kind: 'opened.part', key, part, bytes }))) {
39
+ throw new Error('the device no longer keeps this download');
40
+ }
41
+ part += 1;
42
+ };
43
+ try {
44
+ if (fenced(name.locator) ||
45
+ !(await database.ask({ kind: 'opened.begin', key, ...name, mediaType }))) {
46
+ throw new Error('the device no longer reads this Room');
47
+ }
48
+ for (;;) {
49
+ const read = await reader.read();
50
+ if (read.done)
51
+ break;
52
+ hashed.update(read.value);
53
+ size += read.value.length;
54
+ chunks.push(read.value);
55
+ held += read.value.length;
56
+ for (; held >= FILE_PART_BYTES; held -= FILE_PART_BYTES) {
57
+ await write(taken(chunks, FILE_PART_BYTES));
58
+ }
59
+ }
60
+ if (held > 0)
61
+ await write(taken(chunks, held));
62
+ const received = hashed.hex();
63
+ if (sha256 !== undefined && sha256 !== received) {
64
+ throw new Error('the bytes are not the file the device asked for');
65
+ }
66
+ const whole = await database.ask({
67
+ kind: 'opened.keep',
68
+ key,
69
+ sha256: received,
70
+ byteLength: size,
71
+ parts: part,
72
+ });
73
+ return whole ? { kind: 'binary', file: key, byteLength: size, mediaType } : null;
74
+ }
75
+ catch {
76
+ await reader.cancel().catch(() => { });
77
+ await database.ask({ kind: 'opened.drop', key }).catch(() => null);
78
+ return null;
79
+ }
80
+ }
81
+ async function fetched(name, read) {
82
+ const held = await find(name);
83
+ if (held !== null)
84
+ return held;
85
+ const result = await read();
86
+ if (result.kind !== 'binary')
87
+ return result;
88
+ return (await written(name, result)) ?? UNCERTAIN;
89
+ }
90
+ return {
91
+ find,
92
+ fetch(name, read) {
93
+ const identity = `${name.locator}\u0000${name.path}\u0000${name.revision}`;
94
+ const held = fetching.get(identity);
95
+ if (held !== undefined)
96
+ return held;
97
+ const work = fetched(name, read);
98
+ fetching.set(identity, work);
99
+ const done = () => {
100
+ if (fetching.get(identity) === work)
101
+ fetching.delete(identity);
102
+ };
103
+ work.then(done, done);
104
+ return work;
105
+ },
106
+ };
107
+ }
package/dist/outcome.d.ts CHANGED
@@ -1,10 +1,13 @@
1
- import type { ActionResult, AdapterFailure, BinaryResult, HistoryResult, ProviderRefusal, RoomVersionAt, ScopedRefusal } from './adapter.js';
1
+ import type { ActionResult, AdapterFailure, AttachResult, BinaryLinkResult, HistoryResult, HistoryRevision, ProviderRefusal, RoomVersionAt, ScopedRefusal } from './adapter.js';
2
2
  import type { ChangeBatch } from './change.js';
3
+ import type { KeptBinary, KeptResult } from './opened.js';
3
4
  type Refused<Kind extends string> = ProviderRefusal & {
4
5
  kind: Kind;
5
6
  };
6
7
  export type Failure = Refused<'transport-uncertainty'> | Refused<'revoked-authorization'> | (Refused<'room-not-readable'> & {
7
8
  locator: string;
9
+ }) | (Refused<'room-locked'> & {
10
+ locator: string;
8
11
  }) | ScopedRefusal;
9
12
  export type CallResult = {
10
13
  kind: 'action';
@@ -14,12 +17,55 @@ export type CallResult = {
14
17
  export type HistoryAnswer = Exclude<HistoryResult, {
15
18
  kind: Failure['kind'];
16
19
  }> | Failure;
20
+ type BinaryRefusal = Refused<'rejected'> | Refused<'absent'> | Failure;
17
21
  export type BinaryAnswer = {
18
22
  kind: 'binary';
19
- blob: Blob;
23
+ stream: ReadableStream<Uint8Array>;
24
+ byteLength: number;
25
+ mediaType: string;
26
+ } | BinaryRefusal;
27
+ export type HeldBinaryAnswer = KeptBinary | BinaryRefusal;
28
+ export type BinaryLinkAnswer = {
29
+ kind: 'link';
30
+ url: string;
31
+ name: string;
32
+ mediaType: string;
20
33
  } | Refused<'rejected'> | Refused<'absent'> | Failure;
21
- export declare function absentBinary(path: string): BinaryAnswer;
22
- export declare function binaryAnswer(result: BinaryResult): BinaryAnswer;
34
+ export type HeldShownAnswer = KeptBinary | BinaryLinkAnswer;
35
+ export type ShownAnswer = BinaryAnswer | BinaryLinkAnswer;
36
+ export type AttachAnswer = {
37
+ kind: 'attached';
38
+ path: string;
39
+ } | Offline | Refused<'rejected'> | Failure;
40
+ export type DownloadAnswer = {
41
+ kind: 'started';
42
+ } | Refused<'rejected'> | Refused<'absent'> | Refused<'blocked'> | Failure;
43
+ export type Resolution = {
44
+ readonly kind: 'document';
45
+ readonly room: string;
46
+ readonly path: string;
47
+ } | {
48
+ readonly kind: 'deleted';
49
+ readonly room: string;
50
+ readonly path: string;
51
+ readonly revision: HistoryRevision;
52
+ } | Refused<'unreadable'> | Refused<'absent'> | Failure;
53
+ export declare const UNREADABLE: Refused<'unreadable'>;
54
+ export declare const LOCKED_UNREADABLE: Refused<'unreadable'>;
55
+ export declare const ABSENT_TARGET: Refused<'absent'>;
56
+ export declare function absentBinary(path: string): Refused<'absent'>;
57
+ export declare function binaryAnswer(result: KeptResult): HeldBinaryAnswer;
58
+ export declare function binaryLinkAnswer(result: BinaryLinkResult, held?: string): BinaryLinkAnswer;
59
+ export declare function attachAnswer(result: AttachResult): AttachAnswer;
60
+ export declare const ROOM_LOCKED = "room-locked";
61
+ export declare function lockedRoom(locator: string): Refused<'room-locked'> & {
62
+ locator: string;
63
+ };
64
+ export type Offline = {
65
+ readonly kind: 'offline';
66
+ };
67
+ export declare const OFFLINE: Offline;
68
+ export declare function answeredResult(value: unknown): boolean;
23
69
  export declare const UNCERTAIN: Failure;
24
70
  export declare function undeclared(name: string): CallResult;
25
71
  export declare function failure(result: AdapterFailure): Failure;
@@ -35,9 +81,6 @@ export type QueueEntry = {
35
81
  readonly batch: ChangeBatch;
36
82
  } & (Submission | {
37
83
  readonly state: 'local';
38
- } | {
39
- readonly state: 'accepted';
40
- readonly roomVersion: string;
41
84
  });
42
85
  export {};
43
86
  //# sourceMappingURL=outcome.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../src/outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EACf,aAAa,EACb,aAAa,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK,OAAO,CAAC,IAAI,SAAS,MAAM,IAAI,eAAe,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,OAAO,GACf,OAAO,CAAC,uBAAuB,CAAC,GAChC,OAAO,CAAC,uBAAuB,CAAC,GAChC,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,aAAa,CAAC;AAElB,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAA;CAAE,GACvD,OAAO,CAAC,UAAU,CAAC,GACnB,OAAO,CAAC,YAAY,CAAC,GACrB,OAAO,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,GAAG,OAAO,CAAC;AAExF,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC9B,OAAO,CAAC,UAAU,CAAC,GACnB,OAAO,CAAC,QAAQ,CAAC,GACjB,OAAO,CAAC;AAEZ,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAEvD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D;AAED,eAAO,MAAM,SAAS,EAAE,OAKvB,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEnD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAiBvD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAE7D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAIlE;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAAA;CAAE,GAC3C;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GAAG,CACvD,UAAU,GACV;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAC/D,CAAC"}
1
+ {"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../src/outcome.ts"],"names":[],"mappings":"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"}
package/dist/outcome.js CHANGED
@@ -1,9 +1,52 @@
1
+ export const UNREADABLE = {
2
+ kind: 'unreadable',
3
+ code: 'room-not-readable',
4
+ fields: {},
5
+ retryable: false,
6
+ };
7
+ export const LOCKED_UNREADABLE = {
8
+ kind: 'unreadable',
9
+ code: 'room-locked',
10
+ fields: {},
11
+ retryable: true,
12
+ };
13
+ export const ABSENT_TARGET = {
14
+ kind: 'absent',
15
+ code: 'reference-absent',
16
+ fields: {},
17
+ retryable: false,
18
+ };
1
19
  export function absentBinary(path) {
2
20
  return { kind: 'absent', code: 'binary-file-absent', fields: { path }, retryable: false };
3
21
  }
4
22
  export function binaryAnswer(result) {
5
23
  return result.kind === 'binary' || result.kind === 'rejected' ? result : failure(result);
6
24
  }
25
+ const OCTET_STREAM = 'application/octet-stream';
26
+ export function binaryLinkAnswer(result, held) {
27
+ if (result.kind === 'link') {
28
+ return {
29
+ kind: 'link',
30
+ url: result.url,
31
+ name: result.name,
32
+ mediaType: result.mediaType ?? held ?? OCTET_STREAM,
33
+ };
34
+ }
35
+ return result.kind === 'rejected' ? result : failure(result);
36
+ }
37
+ export function attachAnswer(result) {
38
+ if (result.kind === 'attached')
39
+ return { kind: 'attached', path: result.path };
40
+ return result.kind === 'rejected' ? result : failure(result);
41
+ }
42
+ export const ROOM_LOCKED = 'room-locked';
43
+ export function lockedRoom(locator) {
44
+ return { kind: ROOM_LOCKED, locator, code: ROOM_LOCKED, fields: {}, retryable: true };
45
+ }
46
+ export const OFFLINE = { kind: 'offline' };
47
+ export function answeredResult(value) {
48
+ return typeof value === 'object' && value !== null && !('pending' in value);
49
+ }
7
50
  export const UNCERTAIN = {
8
51
  kind: 'transport-uncertainty',
9
52
  code: 'transport-uncertainty',
package/dist/overlay.d.ts CHANGED
@@ -2,6 +2,8 @@ import type { BinaryFile, HeadChange } from './adapter.js';
2
2
  import type { ChangeBatch } from './change.js';
3
3
  export type Heads = {
4
4
  revisions: Readonly<Record<string, string>>;
5
+ fileIds: Readonly<Record<string, string>>;
6
+ created: Readonly<Record<string, string>>;
5
7
  changes: Readonly<Record<string, HeadChange>>;
6
8
  };
7
9
  export type HeldBinary = ({
@@ -17,10 +19,8 @@ export type Layer = Heads & {
17
19
  documents: Readonly<Record<string, string>>;
18
20
  binaries: Readonly<Record<string, HeldBinary>>;
19
21
  };
20
- export declare function acceptedBinaries(files: Readonly<Record<string, BinaryFile>>): Record<string, HeldBinary>;
22
+ export declare function acceptedBinaries(files: Readonly<Record<string, BinaryFile>>): Generator<readonly [string, HeldBinary]>;
21
23
  export declare function sameBinary(left: HeldBinary | undefined, right: HeldBinary | undefined): boolean;
22
24
  export declare function sameChange(left: HeadChange | undefined, right: HeadChange | undefined): boolean;
23
- export declare function overlay(base: Layer, queue: readonly ChangeBatch[], unapplied?: () => void): Layer;
24
- export declare function sameLayerText(left: Layer, right: Layer): boolean;
25
- export declare function overlayChanged(base: Layer, queue: readonly ChangeBatch[], previousBase: Layer, previousQueue: readonly ChangeBatch[], previousVisible: Layer): Layer;
25
+ export declare function overlaying(base: Layer, queue: readonly ChangeBatch[], unapplied?: () => void): Generator<number, Layer, void>;
26
26
  //# sourceMappingURL=overlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAU,WAAW,EAAgB,MAAM,aAAa,CAAC;AAErE,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG,UAAU,CAAC,GAC7C;IACE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG;IAC1B,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAC1C,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAI5B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAW/F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAQ/F;AAoKD,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,KAAK,CAmBjG;AAQD,wBAAgB,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAOhE;AAiCD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,SAAS,WAAW,EAAE,EACrC,eAAe,EAAE,KAAK,GACrB,KAAK,CAyFP"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAU,WAAW,EAAgB,MAAM,aAAa,CAAC;AAIrE,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG,UAAU,CAAC,GAC7C;IACE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG;IAC1B,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,wBAAiB,gBAAgB,CAC/B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAC1C,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAE1C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAW/F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAQ/F;AA6MD,wBAAiB,UAAU,CACzB,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAsChC"}
package/dist/overlay.js CHANGED
@@ -1,6 +1,9 @@
1
- import { apply, parse, serialize } from '@agentshouse/mdmodel';
2
- export function acceptedBinaries(files) {
3
- return Object.fromEntries(Object.entries(files).map(([path, file]) => [path, { state: 'accepted', ...file }]));
1
+ import { apply, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
2
+ import { drafted, entriesIn, settling } from './shared.js';
3
+ import { ROW_WEIGHT } from './turn.js';
4
+ export function* acceptedBinaries(files) {
5
+ for (const [path, file] of entriesIn(files))
6
+ yield [path, { state: 'accepted', ...file }];
4
7
  }
5
8
  export function sameBinary(left, right) {
6
9
  if (left === undefined || right === undefined)
@@ -10,7 +13,7 @@ export function sameBinary(left, right) {
10
13
  left.mediaType === right.mediaType &&
11
14
  left.sha256 === right.sha256 &&
12
15
  (left.state === 'accepted'
13
- ? right.state === 'accepted' && left.fileRef === right.fileRef
16
+ ? right.state === 'accepted'
14
17
  : right.state === 'pending' && left.localId === right.localId));
15
18
  }
16
19
  export function sameChange(left, right) {
@@ -22,10 +25,13 @@ export function sameChange(left, right) {
22
25
  left.author?.name === right.author?.name);
23
26
  }
24
27
  const EMPTY_FRONTMATTER = '---\n---\n';
28
+ function isPart(change) {
29
+ return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
30
+ }
25
31
  function at(path, name) {
26
32
  return `${path} ${name}`;
27
33
  }
28
- function priorsOf(preconditions) {
34
+ function* priorsOf(preconditions) {
29
35
  const fields = new Map();
30
36
  const sections = new Map();
31
37
  const preambles = new Map();
@@ -39,6 +45,7 @@ function priorsOf(preconditions) {
39
45
  if (precondition.kind === 'preamble') {
40
46
  preambles.set(precondition.path, precondition.value);
41
47
  }
48
+ yield ROW_WEIGHT;
42
49
  }
43
50
  return {
44
51
  field: (path, name) => fields.get(at(path, name)),
@@ -54,51 +61,50 @@ function compose(fields, sections) {
54
61
  const opened = parse(skeleton);
55
62
  if (!opened.ok)
56
63
  return skeleton;
57
- let document = opened.document;
58
- for (const [name, value] of Object.entries(fields)) {
59
- const next = apply(document, { kind: 'field', name, value, prior: undefined });
60
- if (next.outcome === 'applied')
61
- document = next.document;
62
- }
63
- return serialize(document);
64
+ const next = apply(opened.document, Object.entries(fields).flatMap(([name, value]) => frontmatterValue(value) ? [{ kind: 'field', name, value, prior: undefined }] : []));
65
+ return serialize(next.outcome === 'applied' ? next.document : opened.document);
64
66
  }
65
- function edited(document, change, priors) {
66
- if (change.kind === 'field') {
67
- return apply(document, {
67
+ function edited(change, priors) {
68
+ if (change.kind === 'field')
69
+ return {
68
70
  kind: 'field',
69
71
  name: change.name,
70
72
  value: change.value,
71
73
  prior: priors.field(change.path, change.name),
72
- });
73
- }
74
- if (change.kind === 'preamble') {
75
- return apply(document, {
76
- kind: 'preamble',
77
- value: change.value,
78
- prior: priors.preamble(change.path),
79
- });
80
- }
81
- if (change.kind !== 'section')
82
- return null;
83
- return apply(document, {
74
+ };
75
+ if (change.kind === 'preamble')
76
+ return { kind: 'preamble', value: change.value, prior: priors.preamble(change.path) };
77
+ return {
84
78
  kind: 'section',
85
79
  name: change.name,
86
80
  value: change.value,
87
81
  prior: priors.section(change.path, change.name),
88
- });
82
+ };
89
83
  }
90
- function edit(staged, change, priors) {
91
- const text = staged.documents[change.path];
84
+ function edit(staged, changes, priors) {
85
+ const path = changes[0].path;
86
+ delete staged.revisions[path];
87
+ const text = staged.documents[path];
92
88
  if (text === undefined)
93
- return false;
94
- const parsed = parse(text, change.path);
89
+ return changes.length;
90
+ const parsed = parse(text, path);
95
91
  if (!parsed.ok)
96
- return false;
97
- const next = edited(parsed.document, change, priors);
98
- if (next?.outcome !== 'applied')
99
- return false;
100
- staged.documents[change.path] = serialize(next.document);
101
- return true;
92
+ return changes.length;
93
+ const wanted = changes.map((change) => edited(change, priors));
94
+ const first = apply(parsed.document, wanted);
95
+ if (first.outcome === 'refuse')
96
+ return changes.length;
97
+ if (first.outcome === 'applied') {
98
+ staged.documents[path] = serialize(first.document);
99
+ return 0;
100
+ }
101
+ const stale = new Set(first.stale);
102
+ const kept = wanted.filter((_, at) => !stale.has(at));
103
+ const rest = apply(parsed.document, kept);
104
+ if (rest.outcome !== 'applied')
105
+ return changes.length;
106
+ staged.documents[path] = serialize(rest.document);
107
+ return first.stale.length;
102
108
  }
103
109
  function relocate(staged, from, to) {
104
110
  const text = staged.documents[from];
@@ -118,32 +124,44 @@ function relocate(staged, from, to) {
118
124
  }
119
125
  function moveHead(heads, from, to) {
120
126
  const revision = heads.revisions[from];
127
+ const fileId = heads.fileIds[from];
128
+ const created = heads.created[from];
121
129
  const change = heads.changes[from];
122
130
  delete heads.revisions[from];
131
+ delete heads.fileIds[from];
132
+ delete heads.created[from];
123
133
  delete heads.changes[from];
134
+ delete heads.fileIds[to];
135
+ delete heads.created[to];
124
136
  delete heads.changes[to];
125
137
  if (revision !== undefined)
126
138
  heads.revisions[to] = revision;
139
+ if (fileId !== undefined)
140
+ heads.fileIds[to] = fileId;
141
+ if (created !== undefined)
142
+ heads.created[to] = created;
127
143
  if (change !== undefined)
128
144
  heads.changes[to] = change;
129
145
  }
130
146
  function erase(staged, path) {
131
147
  delete staged.documents[path];
132
148
  delete staged.revisions[path];
149
+ delete staged.fileIds[path];
150
+ delete staged.created[path];
133
151
  delete staged.changes[path];
134
152
  delete staged.binaries[path];
135
153
  }
136
- function stage(staged, change, priors) {
137
- if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {
138
- return edit(staged, change, priors);
139
- }
154
+ function stage(staged, change) {
140
155
  if (change.kind === 'create') {
141
156
  staged.documents[change.path] =
142
157
  'content' in change ? change.content : compose(change.fields, change.sections);
158
+ delete staged.fileIds[change.path];
159
+ delete staged.created[change.path];
143
160
  delete staged.changes[change.path];
144
161
  return true;
145
162
  }
146
163
  if (change.kind === 'replace') {
164
+ delete staged.revisions[change.path];
147
165
  if (staged.documents[change.path] === undefined)
148
166
  return false;
149
167
  staged.documents[change.path] = change.content;
@@ -166,156 +184,67 @@ function stage(staged, change, priors) {
166
184
  if (change.kind === 'move') {
167
185
  return relocate(staged, change.path, change.to);
168
186
  }
187
+ if (change.kind === 'arrival') {
188
+ erase(staged, change.path);
189
+ if ('content' in change)
190
+ staged.documents[change.path] = change.content;
191
+ else
192
+ staged.binaries[change.path] = { state: 'accepted', ...change.binary };
193
+ arrive(staged, change);
194
+ return true;
195
+ }
169
196
  erase(staged, change.path);
170
197
  return true;
171
198
  }
172
- export function overlay(base, queue, unapplied) {
199
+ function arrive(heads, change) {
200
+ if (change.revision !== undefined)
201
+ heads.revisions[change.path] = change.revision;
202
+ if (change.fileId !== undefined)
203
+ heads.fileIds[change.path] = change.fileId;
204
+ if (change.created !== undefined)
205
+ heads.created[change.path] = change.created;
206
+ if (change.change !== undefined)
207
+ heads.changes[change.path] = change.change;
208
+ }
209
+ export function* overlaying(base, queue, unapplied) {
173
210
  const staged = {
174
- documents: { ...base.documents },
175
- binaries: { ...base.binaries },
176
- revisions: { ...base.revisions },
177
- changes: { ...base.changes },
178
- };
179
- for (const batch of queue) {
180
- const priors = priorsOf(batch.preconditions);
181
- for (const change of batch.changes) {
182
- if (!stage(staged, change, priors))
183
- unapplied?.();
184
- }
185
- }
186
- return {
187
- documents: staged.documents,
188
- binaries: staged.binaries,
189
- revisions: staged.revisions,
190
- changes: staged.changes,
211
+ documents: drafted(base.documents),
212
+ binaries: drafted(base.binaries),
213
+ revisions: drafted(base.revisions),
214
+ fileIds: drafted(base.fileIds),
215
+ created: drafted(base.created),
216
+ changes: drafted(base.changes),
191
217
  };
192
- }
193
- function pathsOf(batch) {
194
- return batch.changes.flatMap((change) => change.kind === 'move' ? [change.path, change.to] : [change.path]);
195
- }
196
- export function sameLayerText(left, right) {
197
- const paths = Object.keys(left.documents);
198
- return (paths.length === Object.keys(right.documents).length &&
199
- paths.every((path) => left.documents[path] === right.documents[path]) &&
200
- sameBinaries(left.binaries, right.binaries));
201
- }
202
- function sameBinaries(left, right) {
203
- const paths = Object.keys(left);
204
- return (paths.length === Object.keys(right).length &&
205
- paths.every((path) => sameBinary(left[path], right[path])));
206
- }
207
- function replayHeads(base, queue) {
208
- const heads = { revisions: { ...base.revisions }, changes: { ...base.changes } };
209
218
  for (const batch of queue) {
210
- for (const change of batch.changes) {
211
- if (change.kind === 'remove') {
212
- delete heads.revisions[change.path];
213
- delete heads.changes[change.path];
214
- }
215
- else if (change.kind === 'create') {
216
- delete heads.changes[change.path];
217
- }
218
- else if (change.kind === 'binary') {
219
- delete heads.revisions[change.path];
220
- delete heads.changes[change.path];
221
- }
222
- else if (change.kind === 'move') {
223
- moveHead(heads, change.path, change.to);
224
- }
225
- }
226
- }
227
- return heads;
228
- }
229
- export function overlayChanged(base, queue, previousBase, previousQueue, previousVisible) {
230
- const before = previousQueue.map((batch) => JSON.stringify(batch));
231
- const after = queue.map((batch) => JSON.stringify(batch));
232
- if (before.length === after.length &&
233
- before.every((id, index) => id === after[index]) &&
234
- sameLayerText(base, previousBase)) {
235
- return {
236
- documents: previousVisible.documents,
237
- binaries: previousVisible.binaries,
238
- ...replayHeads(base, queue),
239
- };
240
- }
241
- const affected = new Set();
242
- const paths = new Set([
243
- ...Object.keys(base.documents),
244
- ...Object.keys(previousBase.documents),
245
- ...Object.keys(base.revisions),
246
- ...Object.keys(previousBase.revisions),
247
- ...Object.keys(base.changes),
248
- ...Object.keys(previousBase.changes),
249
- ...Object.keys(base.binaries),
250
- ...Object.keys(previousBase.binaries),
251
- ]);
252
- for (const path of paths) {
253
- if (base.documents[path] !== previousBase.documents[path] ||
254
- base.revisions[path] !== previousBase.revisions[path] ||
255
- !sameChange(base.changes[path], previousBase.changes[path]) ||
256
- !sameBinary(base.binaries[path], previousBase.binaries[path]))
257
- affected.add(path);
258
- }
259
- const oldIds = new Set(before);
260
- const newIds = new Set(after);
261
- for (const batch of previousQueue) {
262
- if (!newIds.has(JSON.stringify(batch)))
263
- for (const path of pathsOf(batch))
264
- affected.add(path);
265
- }
266
- for (const batch of queue) {
267
- if (!oldIds.has(JSON.stringify(batch)))
268
- for (const path of pathsOf(batch))
269
- affected.add(path);
270
- }
271
- let expanded = true;
272
- while (expanded) {
273
- expanded = false;
274
- for (const batch of queue) {
275
- const touched = pathsOf(batch);
276
- if (!touched.some((path) => affected.has(path)))
219
+ const priors = yield* priorsOf(batch.preconditions);
220
+ for (let index = 0; index < batch.changes.length; index += 1) {
221
+ const change = batch.changes[index];
222
+ if (!isPart(change)) {
223
+ if (!stage(staged, change))
224
+ unapplied?.();
225
+ yield ROW_WEIGHT;
277
226
  continue;
278
- for (const path of touched) {
279
- if (affected.has(path))
280
- continue;
281
- affected.add(path);
282
- expanded = true;
283
227
  }
228
+ const run = [change];
229
+ while (index + 1 < batch.changes.length) {
230
+ const next = batch.changes[index + 1];
231
+ if (!isPart(next) || next.path !== change.path)
232
+ break;
233
+ run.push(next);
234
+ index += 1;
235
+ }
236
+ const text = staged.documents[change.path] ?? '';
237
+ for (let left = edit(staged, run, priors); left > 0; left -= 1)
238
+ unapplied?.();
239
+ yield ROW_WEIGHT + text.length;
284
240
  }
285
241
  }
286
- const documents = {};
287
- const revisions = {};
288
- const changes = {};
289
- const binaries = {};
290
- for (const path of affected) {
291
- if (base.documents[path] !== undefined)
292
- documents[path] = base.documents[path];
293
- if (base.revisions[path] !== undefined)
294
- revisions[path] = base.revisions[path];
295
- if (base.changes[path] !== undefined)
296
- changes[path] = base.changes[path];
297
- if (base.binaries[path] !== undefined)
298
- binaries[path] = base.binaries[path];
299
- }
300
- const staged = overlay({ documents, revisions, changes, binaries }, queue.filter((batch) => pathsOf(batch).some((path) => affected.has(path))));
301
- const mergedDocuments = { ...previousVisible.documents };
302
- const mergedRevisions = { ...previousVisible.revisions };
303
- const mergedChanges = { ...previousVisible.changes };
304
- const mergedBinaries = { ...previousVisible.binaries };
305
- for (const path of affected) {
306
- delete mergedDocuments[path];
307
- delete mergedRevisions[path];
308
- delete mergedChanges[path];
309
- delete mergedBinaries[path];
310
- }
311
- Object.assign(mergedDocuments, staged.documents);
312
- Object.assign(mergedRevisions, staged.revisions);
313
- Object.assign(mergedChanges, staged.changes);
314
- Object.assign(mergedBinaries, staged.binaries);
315
242
  return {
316
- documents: mergedDocuments,
317
- revisions: mergedRevisions,
318
- changes: mergedChanges,
319
- binaries: mergedBinaries,
243
+ documents: yield* settling(staged.documents),
244
+ binaries: yield* settling(staged.binaries),
245
+ revisions: yield* settling(staged.revisions),
246
+ fileIds: yield* settling(staged.fileIds),
247
+ created: yield* settling(staged.created),
248
+ changes: yield* settling(staged.changes),
320
249
  };
321
250
  }