@agentshouse/mdruntime 0.1.0-cb1f56e16291b → 0.1.0-cb3bb3b233fa1

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 (327) hide show
  1. package/README.md +21 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  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 +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +113 -81
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +3 -11
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +20 -60
  16. package/dist/authored.d.ts +88 -0
  17. package/dist/authored.d.ts.map +1 -0
  18. package/dist/authored.js +345 -0
  19. package/dist/bootstrap.d.ts +9 -5
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +204 -85
  22. package/dist/cell.d.ts +6 -0
  23. package/dist/cell.d.ts.map +1 -0
  24. package/dist/cell.js +9 -0
  25. package/dist/chain.d.ts +2 -1
  26. package/dist/chain.d.ts.map +1 -1
  27. package/dist/change-set.d.ts +4 -0
  28. package/dist/change-set.d.ts.map +1 -1
  29. package/dist/change-set.js +6 -0
  30. package/dist/change.d.ts +5 -0
  31. package/dist/change.d.ts.map +1 -1
  32. package/dist/change.js +7 -2
  33. package/dist/chat-types.d.ts +3 -0
  34. package/dist/chat-types.d.ts.map +1 -0
  35. package/dist/chat-types.js +11 -0
  36. package/dist/client.d.ts +30 -22
  37. package/dist/client.d.ts.map +1 -1
  38. package/dist/client.js +39 -20
  39. package/dist/collection.d.ts +26 -4
  40. package/dist/collection.d.ts.map +1 -1
  41. package/dist/collection.js +19 -2
  42. package/dist/column.d.ts +5 -0
  43. package/dist/column.d.ts.map +1 -0
  44. package/dist/column.js +9 -0
  45. package/dist/compile.d.ts +9 -7
  46. package/dist/compile.d.ts.map +1 -1
  47. package/dist/compile.js +252 -318
  48. package/dist/connection.d.ts +5 -141
  49. package/dist/connection.d.ts.map +1 -1
  50. package/dist/connection.js +111 -5282
  51. package/dist/context.d.ts.map +1 -1
  52. package/dist/context.js +1 -1
  53. package/dist/conversation-live.d.ts +150 -0
  54. package/dist/conversation-live.d.ts.map +1 -0
  55. package/dist/conversation-live.js +259 -0
  56. package/dist/conversation-row.d.ts +40 -0
  57. package/dist/conversation-row.d.ts.map +1 -0
  58. package/dist/conversation-row.js +66 -0
  59. package/dist/conversation.d.ts +62 -43
  60. package/dist/conversation.d.ts.map +1 -1
  61. package/dist/conversation.js +987 -902
  62. package/dist/declaration.d.ts +10 -0
  63. package/dist/declaration.d.ts.map +1 -0
  64. package/dist/declaration.js +24 -0
  65. package/dist/discovery.d.ts +10 -0
  66. package/dist/discovery.d.ts.map +1 -0
  67. package/dist/discovery.js +150 -0
  68. package/dist/durability.d.ts +19 -0
  69. package/dist/durability.d.ts.map +1 -1
  70. package/dist/durability.js +4 -0
  71. package/dist/entry.d.ts +2 -2
  72. package/dist/entry.d.ts.map +1 -1
  73. package/dist/entry.js +18 -9
  74. package/dist/expectation.d.ts +26 -13
  75. package/dist/expectation.d.ts.map +1 -1
  76. package/dist/expectation.js +72 -19
  77. package/dist/failure.d.ts +3 -0
  78. package/dist/failure.d.ts.map +1 -1
  79. package/dist/failure.js +6 -0
  80. package/dist/figures.d.ts +49 -0
  81. package/dist/figures.d.ts.map +1 -0
  82. package/dist/figures.js +199 -0
  83. package/dist/file.d.ts +1 -1
  84. package/dist/file.d.ts.map +1 -1
  85. package/dist/file.js +3 -2
  86. package/dist/holdings.d.ts +29 -0
  87. package/dist/holdings.d.ts.map +1 -0
  88. package/dist/holdings.js +95 -0
  89. package/dist/host.d.ts +20 -4
  90. package/dist/host.d.ts.map +1 -1
  91. package/dist/host.js +72 -28
  92. package/dist/identity.d.ts +0 -1
  93. package/dist/identity.d.ts.map +1 -1
  94. package/dist/identity.js +0 -3
  95. package/dist/index.d.ts +32 -12
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +14 -5
  98. package/dist/install.d.ts +60 -0
  99. package/dist/install.d.ts.map +1 -0
  100. package/dist/install.js +537 -0
  101. package/dist/lifecycle.d.ts +7 -0
  102. package/dist/lifecycle.d.ts.map +1 -0
  103. package/dist/lifecycle.js +282 -0
  104. package/dist/listing.d.ts +52 -0
  105. package/dist/listing.d.ts.map +1 -0
  106. package/dist/listing.js +152 -0
  107. package/dist/live.d.ts +8 -6
  108. package/dist/live.d.ts.map +1 -1
  109. package/dist/live.js +110 -31
  110. package/dist/loaded.d.ts +5 -0
  111. package/dist/loaded.d.ts.map +1 -0
  112. package/dist/loaded.js +40 -0
  113. package/dist/locks.d.ts +7 -0
  114. package/dist/locks.d.ts.map +1 -0
  115. package/dist/locks.js +32 -0
  116. package/dist/lost.d.ts +5 -0
  117. package/dist/lost.d.ts.map +1 -0
  118. package/dist/lost.js +49 -0
  119. package/dist/media.d.ts +6 -1
  120. package/dist/media.d.ts.map +1 -1
  121. package/dist/media.js +68 -17
  122. package/dist/memory.d.ts +11 -3
  123. package/dist/memory.d.ts.map +1 -1
  124. package/dist/memory.js +132 -33
  125. package/dist/messages.d.ts +33 -3
  126. package/dist/messages.d.ts.map +1 -1
  127. package/dist/messages.js +98 -27
  128. package/dist/model.d.ts +2 -10
  129. package/dist/model.d.ts.map +1 -1
  130. package/dist/model.js +0 -14
  131. package/dist/models.d.ts +10 -0
  132. package/dist/models.d.ts.map +1 -0
  133. package/dist/models.js +153 -0
  134. package/dist/observation.d.ts +27 -12
  135. package/dist/observation.d.ts.map +1 -1
  136. package/dist/observation.js +184 -85
  137. package/dist/opened.d.ts +1 -1
  138. package/dist/opened.d.ts.map +1 -1
  139. package/dist/opened.js +5 -5
  140. package/dist/opening.d.ts +4 -0
  141. package/dist/opening.d.ts.map +1 -0
  142. package/dist/opening.js +53 -0
  143. package/dist/outcome.d.ts +17 -2
  144. package/dist/outcome.d.ts.map +1 -1
  145. package/dist/outcome.js +35 -2
  146. package/dist/overlay.d.ts +7 -2
  147. package/dist/overlay.d.ts.map +1 -1
  148. package/dist/overlay.js +48 -24
  149. package/dist/page-metadata.d.ts +8 -0
  150. package/dist/page-metadata.d.ts.map +1 -0
  151. package/dist/page-metadata.js +19 -0
  152. package/dist/parts.d.ts +4 -0
  153. package/dist/parts.d.ts.map +1 -0
  154. package/dist/parts.js +13 -0
  155. package/dist/paths.d.ts +1 -0
  156. package/dist/paths.d.ts.map +1 -1
  157. package/dist/paths.js +22 -0
  158. package/dist/preparation.d.ts +41 -0
  159. package/dist/preparation.d.ts.map +1 -0
  160. package/dist/preparation.js +314 -0
  161. package/dist/presence.d.ts +58 -0
  162. package/dist/presence.d.ts.map +1 -0
  163. package/dist/presence.js +231 -0
  164. package/dist/queries.d.ts +16 -0
  165. package/dist/queries.d.ts.map +1 -0
  166. package/dist/queries.js +308 -0
  167. package/dist/query.d.ts +13 -213
  168. package/dist/query.d.ts.map +1 -1
  169. package/dist/query.js +3 -524
  170. package/dist/questions.d.ts +30 -0
  171. package/dist/questions.d.ts.map +1 -0
  172. package/dist/questions.js +116 -0
  173. package/dist/queue.d.ts +40 -0
  174. package/dist/queue.d.ts.map +1 -0
  175. package/dist/queue.js +480 -0
  176. package/dist/reach.d.ts +10 -10
  177. package/dist/reach.d.ts.map +1 -1
  178. package/dist/reach.js +235 -120
  179. package/dist/react.d.ts +17 -3
  180. package/dist/react.d.ts.map +1 -1
  181. package/dist/react.js +33 -1
  182. package/dist/read.d.ts +7 -0
  183. package/dist/read.d.ts.map +1 -0
  184. package/dist/read.js +17 -0
  185. package/dist/readiness.d.ts +9 -4
  186. package/dist/readiness.d.ts.map +1 -1
  187. package/dist/readiness.js +3 -5
  188. package/dist/reads.d.ts +39 -0
  189. package/dist/reads.d.ts.map +1 -0
  190. package/dist/reads.js +178 -0
  191. package/dist/recovery.d.ts +3 -1
  192. package/dist/recovery.d.ts.map +1 -1
  193. package/dist/recovery.js +38 -8
  194. package/dist/refresh.d.ts +1 -1
  195. package/dist/refresh.d.ts.map +1 -1
  196. package/dist/refresh.js +10 -22
  197. package/dist/refusal.d.ts +5 -0
  198. package/dist/refusal.d.ts.map +1 -0
  199. package/dist/refusal.js +55 -0
  200. package/dist/replica.d.ts +11 -16
  201. package/dist/replica.d.ts.map +1 -1
  202. package/dist/replica.js +66 -35
  203. package/dist/retried.d.ts +30 -0
  204. package/dist/retried.d.ts.map +1 -0
  205. package/dist/retried.js +72 -0
  206. package/dist/room-draft.d.ts +32 -9
  207. package/dist/room-draft.d.ts.map +1 -1
  208. package/dist/room-draft.js +273 -66
  209. package/dist/room-drafts.d.ts +24 -0
  210. package/dist/room-drafts.d.ts.map +1 -0
  211. package/dist/room-drafts.js +220 -0
  212. package/dist/room-list.d.ts +10 -0
  213. package/dist/room-list.d.ts.map +1 -0
  214. package/dist/room-list.js +45 -0
  215. package/dist/rows.d.ts +16 -23
  216. package/dist/rows.d.ts.map +1 -1
  217. package/dist/rows.js +49 -191
  218. package/dist/runtime.d.ts +34 -0
  219. package/dist/runtime.d.ts.map +1 -0
  220. package/dist/runtime.js +1 -0
  221. package/dist/save.d.ts +42 -86
  222. package/dist/save.d.ts.map +1 -1
  223. package/dist/save.js +332 -228
  224. package/dist/saves.d.ts +34 -0
  225. package/dist/saves.d.ts.map +1 -0
  226. package/dist/saves.js +437 -0
  227. package/dist/search.d.ts.map +1 -1
  228. package/dist/search.js +1 -1
  229. package/dist/seed.d.ts +11 -2
  230. package/dist/seed.d.ts.map +1 -1
  231. package/dist/seed.js +71 -1
  232. package/dist/shared.d.ts +1 -6
  233. package/dist/shared.d.ts.map +1 -1
  234. package/dist/shared.js +13 -95
  235. package/dist/shown.d.ts +33 -0
  236. package/dist/shown.d.ts.map +1 -0
  237. package/dist/shown.js +309 -0
  238. package/dist/socket/admission.d.ts +7 -0
  239. package/dist/socket/admission.d.ts.map +1 -0
  240. package/dist/socket/admission.js +39 -0
  241. package/dist/socket/answers.d.ts +6 -0
  242. package/dist/socket/answers.d.ts.map +1 -0
  243. package/dist/socket/answers.js +20 -0
  244. package/dist/socket/lanes.d.ts +28 -0
  245. package/dist/socket/lanes.d.ts.map +1 -0
  246. package/dist/socket/lanes.js +103 -0
  247. package/dist/socket/reads.d.ts +10 -0
  248. package/dist/socket/reads.d.ts.map +1 -0
  249. package/dist/socket/reads.js +31 -0
  250. package/dist/socket/session.d.ts +38 -0
  251. package/dist/socket/session.d.ts.map +1 -0
  252. package/dist/socket/session.js +23 -0
  253. package/dist/socket.d.ts +67 -0
  254. package/dist/socket.d.ts.map +1 -0
  255. package/dist/socket.js +164 -0
  256. package/dist/source.d.ts +59 -0
  257. package/dist/source.d.ts.map +1 -0
  258. package/dist/source.js +93 -0
  259. package/dist/status.d.ts +0 -2
  260. package/dist/status.d.ts.map +1 -1
  261. package/dist/status.js +0 -6
  262. package/dist/store/installs.d.ts +30 -0
  263. package/dist/store/installs.d.ts.map +1 -0
  264. package/dist/store/installs.js +40 -0
  265. package/dist/store/readiness.d.ts +11 -0
  266. package/dist/store/readiness.d.ts.map +1 -0
  267. package/dist/store/readiness.js +68 -0
  268. package/dist/store/records.d.ts +223 -0
  269. package/dist/store/records.d.ts.map +1 -0
  270. package/dist/store/records.js +465 -0
  271. package/dist/store/room-held.d.ts +8 -0
  272. package/dist/store/room-held.d.ts.map +1 -0
  273. package/dist/store/room-held.js +17 -0
  274. package/dist/store/rooms-shown.d.ts +8 -0
  275. package/dist/store/rooms-shown.d.ts.map +1 -0
  276. package/dist/store/rooms-shown.js +13 -0
  277. package/dist/store/space.d.ts +11 -0
  278. package/dist/store/space.d.ts.map +1 -0
  279. package/dist/store/space.js +41 -0
  280. package/dist/store/watchers.d.ts +17 -0
  281. package/dist/store/watchers.d.ts.map +1 -0
  282. package/dist/store/watchers.js +56 -0
  283. package/dist/store/writes.d.ts +24 -0
  284. package/dist/store/writes.d.ts.map +1 -0
  285. package/dist/store/writes.js +125 -0
  286. package/dist/store.d.ts +115 -152
  287. package/dist/store.d.ts.map +1 -1
  288. package/dist/store.js +171 -395
  289. package/dist/stored.d.ts +72 -67
  290. package/dist/stored.d.ts.map +1 -1
  291. package/dist/stored.js +317 -166
  292. package/dist/surface.d.ts +90 -0
  293. package/dist/surface.d.ts.map +1 -0
  294. package/dist/surface.js +225 -0
  295. package/dist/sync.d.ts +19 -0
  296. package/dist/sync.d.ts.map +1 -0
  297. package/dist/sync.js +536 -0
  298. package/dist/tables.d.ts +112 -89
  299. package/dist/tables.d.ts.map +1 -1
  300. package/dist/tables.js +197 -283
  301. package/dist/tallies.d.ts +18 -0
  302. package/dist/tallies.d.ts.map +1 -0
  303. package/dist/tallies.js +128 -0
  304. package/dist/validation.d.ts.map +1 -1
  305. package/dist/validation.js +9 -12
  306. package/dist/windows.d.ts +1 -12
  307. package/dist/windows.d.ts.map +1 -1
  308. package/dist/windows.js +2 -75
  309. package/dist/wire.d.ts +68 -7
  310. package/dist/wire.d.ts.map +1 -1
  311. package/dist/wire.js +23 -4
  312. package/package.json +3 -2
  313. package/dist/attempt.d.ts +0 -16
  314. package/dist/attempt.d.ts.map +0 -1
  315. package/dist/attempt.js +0 -70
  316. package/dist/fence.d.ts +0 -6
  317. package/dist/fence.d.ts.map +0 -1
  318. package/dist/fence.js +0 -10
  319. package/dist/job.d.ts +0 -14
  320. package/dist/job.d.ts.map +0 -1
  321. package/dist/job.js +0 -28
  322. package/dist/log.d.ts +0 -5
  323. package/dist/log.d.ts.map +0 -1
  324. package/dist/log.js +0 -14
  325. package/dist/phrase.d.ts +0 -3
  326. package/dist/phrase.d.ts.map +0 -1
  327. package/dist/phrase.js +0 -8
@@ -1,13 +1,15 @@
1
- import { apply, equalValue, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
1
+ import { apply, create, documentValue, equalValue, parse, serialize, } from '@agentshouse/mdmodel';
2
+ import { definitionsAt, governing } from './collection.js';
2
3
  import { runtimeError } from './failure.js';
3
4
  import { sha256 } from './digest.js';
5
+ import { declaredType } from './outcome.js';
4
6
  import { binaryLocalId } from './identity.js';
5
7
  import { normalize } from './paths.js';
6
- export function returnedBy(kind) {
7
- return { kind, code: kind, fields: {}, retryable: false };
8
+ export function returnedBy() {
9
+ return { kind: 'withdrawn', code: 'withdrawn', fields: {}, retryable: false };
8
10
  }
9
11
  export function staleWrite(current) {
10
- return { outcome: 'stale', code: 'stale', retryable: false, current };
12
+ return { outcome: 'stale', current };
11
13
  }
12
14
  function malformed(at, needs) {
13
15
  throw runtimeError('room-draft-malformed', at === undefined ? 'room-draft-malformed' : `room-draft-malformed at ${at}: ${needs}`);
@@ -32,14 +34,14 @@ function entries(value, at, each) {
32
34
  read[name] = each(item, `${at}.${name}`);
33
35
  return read;
34
36
  }
35
- function frontmatter(item, at) {
36
- return frontmatterValue(item) ? item : malformed(at, 'a frontmatter value');
37
+ function documentValueAt(item, at) {
38
+ return documentValue(item) ? item : malformed(at, 'a document value');
37
39
  }
38
40
  function fieldValue(value, at) {
39
41
  if (value === null)
40
42
  return null;
41
- if (!plain(value) || !Object.hasOwn(value, 'value') || !frontmatterValue(value.value)) {
42
- malformed(at, '{ value } with a frontmatter value, or null where the document lacks it');
43
+ if (!plain(value) || !Object.hasOwn(value, 'value') || !documentValue(value.value)) {
44
+ malformed(at, '{ value } with a document value, or null where the document lacks it');
43
45
  }
44
46
  return { value: value.value };
45
47
  }
@@ -58,7 +60,7 @@ function creationOf(value, at) {
58
60
  malformed(`${at}.type`, 'a type name, or markdown in place of type, fields and sections');
59
61
  return {
60
62
  type: value.type,
61
- fields: entries(value.fields, `${at}.fields`, frontmatter),
63
+ fields: entries(value.fields, `${at}.fields`, documentValueAt),
62
64
  sections: entries(value.sections, `${at}.sections`, text),
63
65
  };
64
66
  }
@@ -72,7 +74,7 @@ const PART_NAMES = [
72
74
  'removal',
73
75
  'file',
74
76
  ];
75
- const NAMED_PARTS = `a part named ${PART_NAMES.slice(0, -1).join(', ')} or ${PART_NAMES.at(-1)}`;
77
+ const NAMED_PARTS = `a part named ${PART_NAMES.slice(0, -1).join(', ')} or ${PART_NAMES.slice(-1).join('')}`;
76
78
  export function readParts(value, path) {
77
79
  if (!plain(value))
78
80
  malformed(path, 'an object of parts');
@@ -82,8 +84,8 @@ export function readParts(value, path) {
82
84
  const parts = {};
83
85
  if (value.fields !== undefined) {
84
86
  parts.fields = entries(value.fields, `${path} fields`, (item, at) => {
85
- if (!plain(item) || !Object.hasOwn(item, 'value') || !frontmatterValue(item.value)) {
86
- malformed(at, '{ value, base } with a frontmatter value');
87
+ if (!plain(item) || !Object.hasOwn(item, 'value') || !documentValue(item.value)) {
88
+ malformed(at, '{ value, base } with a document value');
87
89
  }
88
90
  return item.base === undefined
89
91
  ? { value: item.value }
@@ -255,8 +257,10 @@ export function underneath(parts, path, visible) {
255
257
  const markdown = visible?.documents[path] ?? null;
256
258
  const document = visible?.collection.document(path);
257
259
  const report = {};
260
+ const unread = document?.type !== undefined &&
261
+ governing(visible.collection.composition, path).status === 'unavailable';
258
262
  const fields = {};
259
- for (const [name, part] of named(parts.fields)) {
263
+ for (const [name, part] of unread ? [] : named(parts.fields)) {
260
264
  const current = document !== undefined && Object.hasOwn(document.fields, name)
261
265
  ? { value: document.fields[name] }
262
266
  : null;
@@ -266,7 +270,7 @@ export function underneath(parts, path, visible) {
266
270
  if (Object.keys(fields).length > 0)
267
271
  report.fields = fields;
268
272
  const sections = {};
269
- for (const [name, part] of named(parts.sections)) {
273
+ for (const [name, part] of unread ? [] : named(parts.sections)) {
270
274
  const current = document !== undefined && Object.hasOwn(document.sections, name)
271
275
  ? document.sections[name]
272
276
  : null;
@@ -276,8 +280,9 @@ export function underneath(parts, path, visible) {
276
280
  if (Object.keys(sections).length > 0)
277
281
  report.sections = sections;
278
282
  const preamble = document?.preamble ?? null;
279
- if (parts.preamble !== undefined && preamble !== parts.preamble.base)
283
+ if (!unread && parts.preamble !== undefined && preamble !== parts.preamble.base) {
280
284
  report.preamble = preamble;
285
+ }
281
286
  if (parts.markdown !== undefined && markdown !== parts.markdown.base)
282
287
  report.markdown = markdown;
283
288
  if (parts.creation !== undefined && markdown !== null)
@@ -293,13 +298,12 @@ export function underneath(parts, path, visible) {
293
298
  }
294
299
  return report;
295
300
  }
296
- const UNTYPED_MEDIA_TYPE = 'application/octet-stream';
297
301
  export async function heldFile(blob, base) {
298
302
  return {
299
303
  localId: binaryLocalId(),
300
304
  ...(blob instanceof File ? { name: blob.name } : {}),
301
305
  byteLength: blob.size,
302
- mediaType: blob.type === '' ? UNTYPED_MEDIA_TYPE : blob.type,
306
+ mediaType: declaredType(blob),
303
307
  sha256: await sha256(blob),
304
308
  base,
305
309
  };
@@ -323,6 +327,224 @@ export function changedParts(path, parts, visible) {
323
327
  ...(report.file === undefined || made ? [] : [{ path, part: 'file' }]),
324
328
  ];
325
329
  }
330
+ function marksOf(fields, sections, rest) {
331
+ return {
332
+ ...(Object.keys(fields).length === 0 ? {} : { fields }),
333
+ ...(Object.keys(sections).length === 0 ? {} : { sections }),
334
+ ...(rest.preamble === undefined ? {} : { preamble: rest.preamble }),
335
+ ...(rest.markdown === undefined ? {} : { markdown: rest.markdown }),
336
+ ...(rest.file === undefined ? {} : { file: rest.file }),
337
+ };
338
+ }
339
+ export function marksOver(kept, under) {
340
+ return marksOf({ ...under.fields, ...kept.fields }, { ...under.sections, ...kept.sections }, {
341
+ preamble: kept.preamble ?? under.preamble,
342
+ markdown: kept.markdown ?? under.markdown,
343
+ file: kept.file ?? under.file,
344
+ });
345
+ }
346
+ export function heldMarks(marks, parts) {
347
+ const whole = parts.markdown !== undefined;
348
+ const heldIn = (record, part) => Object.fromEntries(named(record).filter(([name]) => whole || own(part, name) !== undefined));
349
+ return marksOf(heldIn(marks.fields, parts.fields), heldIn(marks.sections, parts.sections), {
350
+ preamble: whole || parts.preamble !== undefined ? marks.preamble : undefined,
351
+ markdown: whole ? marks.markdown : undefined,
352
+ file: parts.file === undefined ? undefined : marks.file,
353
+ });
354
+ }
355
+ function followedBy(first, then) {
356
+ const kept = first.replace(/(?:\r?\n)+$/u, '');
357
+ return kept.trim() === '' ? then : `${kept}\n\n${then.replace(/^(?:\r?\n)+/u, '')}`;
358
+ }
359
+ function bothSides(current, value) {
360
+ return lineEnded(current) === lineEnded(value) ? value : followedBy(current, value);
361
+ }
362
+ export function partsBetween(path, before, after) {
363
+ const changes = [];
364
+ for (const name of new Set([...Object.keys(before.fields), ...Object.keys(after.fields)])) {
365
+ const value = own(after.fields, name);
366
+ if (!equalValue(own(before.fields, name), value)) {
367
+ changes.push({ kind: 'field', path, name, value });
368
+ }
369
+ }
370
+ if (after.preamble !== before.preamble) {
371
+ changes.push({ kind: 'preamble', path, value: after.preamble });
372
+ }
373
+ for (const [name, value] of Object.entries(after.sections)) {
374
+ if (own(before.sections, name) !== value)
375
+ changes.push({ kind: 'section', path, name, value });
376
+ }
377
+ return changes;
378
+ }
379
+ export function applyParts(document, changes, definition) {
380
+ const parts = new Map();
381
+ for (const change of changes) {
382
+ if (change.kind === 'field')
383
+ parts.set(`field ${change.name}`, {
384
+ kind: 'field',
385
+ name: change.name,
386
+ value: change.value,
387
+ prior: own(document.fields, change.name),
388
+ });
389
+ if (change.kind === 'preamble')
390
+ parts.set('preamble', { kind: 'preamble', value: change.value, prior: document.preamble });
391
+ if (change.kind === 'section')
392
+ parts.set(`section ${change.name}`, {
393
+ kind: 'section',
394
+ name: change.name,
395
+ value: change.value,
396
+ prior: own(document.sections, change.name),
397
+ });
398
+ }
399
+ if (parts.size === 0)
400
+ return { outcome: 'applied', document };
401
+ return apply(document, [...parts.values()], definition);
402
+ }
403
+ function wholeJoined(part, current, path, composition, change) {
404
+ const definitions = definitionsAt(composition, path);
405
+ const read = (text) => {
406
+ const parsed = parse(text, path, definitions);
407
+ return parsed.ok ? parsed.document : undefined;
408
+ };
409
+ const base = read(part.base);
410
+ const mine = read(part.value);
411
+ const now = read(current);
412
+ if (base === undefined ||
413
+ mine === undefined ||
414
+ now === undefined ||
415
+ mine.type !== base.type ||
416
+ now.type !== base.type ||
417
+ Object.keys(base.sections).some((name) => !Object.hasOwn(mine.sections, name))) {
418
+ return null;
419
+ }
420
+ const definition = definitions(base.type);
421
+ const changes = partsBetween(path, base, mine);
422
+ const again = applyParts(base, changes, definition);
423
+ if (again.outcome !== 'applied' || serialize(again.document) !== part.value)
424
+ return null;
425
+ const fields = {};
426
+ const sections = {};
427
+ let preamble;
428
+ const over = [];
429
+ for (const one of changes) {
430
+ if (one.kind === 'field') {
431
+ const held = own(now.fields, one.name);
432
+ if (!equalValue(held, own(base.fields, one.name)) && !equalValue(held, one.value)) {
433
+ fields[one.name] = { current: held === undefined ? null : { value: held }, change };
434
+ }
435
+ over.push(one);
436
+ continue;
437
+ }
438
+ if (one.kind === 'preamble') {
439
+ const value = now.preamble === base.preamble ? one.value : bothSides(now.preamble, one.value);
440
+ if (value !== one.value)
441
+ preamble = { change };
442
+ over.push({ ...one, value });
443
+ continue;
444
+ }
445
+ const prior = own(base.sections, one.name);
446
+ const held = own(now.sections, one.name);
447
+ if (held === undefined && prior !== undefined)
448
+ return null;
449
+ const value = held === undefined || held === prior ? one.value : bothSides(held, one.value);
450
+ if (value !== one.value)
451
+ sections[one.name] = { change };
452
+ over.push({ ...one, value });
453
+ }
454
+ const joined = applyParts(now, over, definition);
455
+ if (joined.outcome !== 'applied')
456
+ return null;
457
+ return {
458
+ value: serialize(joined.document),
459
+ marks: marksOf(fields, sections, { preamble }),
460
+ };
461
+ }
462
+ export function joinedOver(parts, marks, path, visible) {
463
+ const report = underneath(parts, path, visible);
464
+ const change = visible.changes[path] ?? null;
465
+ const next = { ...parts };
466
+ const fields = {};
467
+ const sections = {};
468
+ const rest = {};
469
+ let rebased = false;
470
+ const text = (value, current, mark) => {
471
+ const joined = bothSides(current, value);
472
+ if (joined !== value)
473
+ mark();
474
+ return { value: joined, base: current };
475
+ };
476
+ const now = visible.collection.document(path);
477
+ if (now !== undefined) {
478
+ for (const [name, current] of named(report.fields)) {
479
+ const { value } = parts.fields[name];
480
+ next.fields = { ...next.fields, [name]: { value, base: current } };
481
+ if (!sameField(current, { value }))
482
+ fields[name] = { current, change };
483
+ rebased = true;
484
+ }
485
+ const removed = [];
486
+ for (const [name, current] of named(report.sections)) {
487
+ if (current === null) {
488
+ removed.push(name);
489
+ continue;
490
+ }
491
+ const joined = text(parts.sections[name].value, current, () => {
492
+ sections[name] = { change };
493
+ });
494
+ next.sections = { ...next.sections, [name]: joined };
495
+ rebased = true;
496
+ }
497
+ if (typeof report.preamble === 'string') {
498
+ next.preamble = text(parts.preamble.value, report.preamble, () => {
499
+ rest.preamble = { change };
500
+ });
501
+ rebased = true;
502
+ }
503
+ const whole = removed.length === 0
504
+ ? null
505
+ : applyParts(now, changesOf(path, next).changes, definitionsAt(visible.collection.composition, path)(now.type));
506
+ if (whole?.outcome === 'applied') {
507
+ delete next.fields;
508
+ delete next.sections;
509
+ delete next.preamble;
510
+ next.markdown = { value: serialize(whole.document), base: visible.documents[path] };
511
+ for (const name of removed)
512
+ sections[name] = { change };
513
+ rebased = true;
514
+ }
515
+ }
516
+ if (typeof report.markdown === 'string' && parts.markdown !== undefined) {
517
+ const current = report.markdown;
518
+ const whole = wholeJoined(parts.markdown, current, path, visible.collection.composition, change);
519
+ const value = whole?.value ?? bothSides(current, parts.markdown.value);
520
+ next.markdown = { value, base: current };
521
+ if (whole !== null) {
522
+ Object.assign(fields, whole.marks.fields);
523
+ Object.assign(sections, whole.marks.sections);
524
+ if (whole.marks.preamble !== undefined)
525
+ rest.preamble = whole.marks.preamble;
526
+ }
527
+ else if (value !== parts.markdown.value)
528
+ rest.markdown = { change };
529
+ rebased = true;
530
+ }
531
+ if (typeof report.move === 'string' && parts.move !== undefined) {
532
+ next.move = { ...parts.move, base: report.move };
533
+ rebased = true;
534
+ }
535
+ if (typeof report.removal === 'string' && parts.removal !== undefined) {
536
+ next.removal = { base: report.removal };
537
+ rebased = true;
538
+ }
539
+ if (typeof report.file === 'string' && parts.file !== undefined && parts.file.base !== null) {
540
+ next.file = { ...parts.file, base: report.file };
541
+ if (visible.binaries[path]?.sha256 !== parts.file.sha256) {
542
+ rest.file = { current: report.file, change };
543
+ }
544
+ rebased = true;
545
+ }
546
+ return rebased ? { parts: next, marks: marksOver(marksOf(fields, sections, rest), marks) } : null;
547
+ }
326
548
  function joined(existing, returned) {
327
549
  const merged = { ...existing };
328
550
  for (const [name, part] of named(returned))
@@ -333,30 +555,42 @@ function joined(existing, returned) {
333
555
  export function lineEnded(text) {
334
556
  return text === '' || text.endsWith('\n') ? text : `${text}\n`;
335
557
  }
336
- function frontmatterOf(fields) {
337
- const opened = parse('---\n---\n');
338
- if (!opened.ok)
339
- return malformed();
340
- const next = apply(opened.document, fields.map(([name, part]) => ({
341
- kind: 'field',
342
- name,
343
- value: part.value,
344
- prior: undefined,
345
- })));
346
- return next.outcome === 'applied' ? serialize(next.document) : malformed();
558
+ function written(start, changes, definition) {
559
+ const next = apply(start, changes, definition);
560
+ return next.outcome === 'applied' ? next.document : malformed();
561
+ }
562
+ function empty(definition) {
563
+ const parsed = parse('', '', definition);
564
+ return parsed.ok ? parsed.document : malformed();
347
565
  }
348
- export function partsAfter(markdown, parts) {
566
+ export function partsAfter(markdown, parts, definitions) {
349
567
  const fields = named(parts.fields);
568
+ const sections = named(parts.sections);
569
+ if (fields.length === 0 && sections.length === 0 && parts.preamble === undefined)
570
+ return markdown;
571
+ const whole = parse(markdown, '', definitions);
572
+ const type = whole.ok ? whole.document.type : undefined;
573
+ const definition = definitions?.(type);
574
+ if (type !== undefined && definition === undefined)
575
+ return null;
576
+ const valued = fields.length === 0
577
+ ? empty(definition)
578
+ : written(create(type, definition), fields.map(([name, part]) => ({
579
+ kind: 'field',
580
+ name,
581
+ value: part.value,
582
+ prior: undefined,
583
+ })), definition);
584
+ const head = parts.preamble === undefined
585
+ ? valued
586
+ : written(valued, [{ kind: 'preamble', value: lineEnded(parts.preamble.value), prior: valued.preamble }], definition);
350
587
  const pieces = [
351
- ...(fields.length === 0 ? [] : [frontmatterOf(fields)]),
352
- ...(parts.preamble === undefined ? [] : [parts.preamble.value]),
353
- ...named(parts.sections).map(([name, part]) => `## ${name}\n${part.value}`),
588
+ ...(fields.length === 0 && parts.preamble === undefined ? [] : [serialize(head)]),
589
+ ...sections.map(([name, part]) => serialize(written(empty(definition), [{ kind: 'section', name, value: lineEnded(part.value), prior: undefined }], definition))),
354
590
  ];
355
- if (pieces.length === 0)
356
- return markdown;
357
- return `${lineEnded(markdown)}\n${pieces.map(lineEnded).join('')}`;
591
+ return followedBy(markdown, pieces.join(''));
358
592
  }
359
- export function returnedInto(existing, returned) {
593
+ export function returnedInto(existing, returned, definitions) {
360
594
  if (existing === undefined)
361
595
  return returned;
362
596
  const next = { ...existing };
@@ -376,7 +610,9 @@ export function returnedInto(existing, returned) {
376
610
  delete next.fields;
377
611
  delete next.sections;
378
612
  delete next.preamble;
379
- const value = partsAfter(whole.value, existing.markdown === undefined ? existing : returned);
613
+ const value = partsAfter(whole.value, existing.markdown === undefined ? existing : returned, definitions);
614
+ if (value === null)
615
+ return null;
380
616
  next.markdown = { value, base: whole.base };
381
617
  }
382
618
  const creation = existing.creation ?? returned.creation;
@@ -474,35 +710,6 @@ export function changesOf(path, parts) {
474
710
  changes.push({ kind: 'remove', path });
475
711
  return { changes, bases };
476
712
  }
477
- function rebased(before, after) {
478
- return before === undefined ? after : { ...after, base: before.base };
479
- }
480
- function rebasedAll(before, after) {
481
- return {
482
- ...before,
483
- ...Object.fromEntries(Object.entries(after).map(([name, part]) => [name, rebased(before?.[name], part)])),
484
- };
485
- }
486
- export function joinedDraft(carried, saved) {
487
- const draft = saved.find((item) => item.path === carried.path);
488
- if (draft === undefined)
489
- return carried;
490
- const held = carried.parts;
491
- const next = draft.parts;
492
- return {
493
- path: carried.path,
494
- parts: {
495
- ...held,
496
- ...next,
497
- ...(next.fields === undefined ? {} : { fields: rebasedAll(held.fields, next.fields) }),
498
- ...(next.sections === undefined
499
- ? {}
500
- : { sections: rebasedAll(held.sections, next.sections) }),
501
- ...(next.preamble === undefined ? {} : { preamble: rebased(held.preamble, next.preamble) }),
502
- ...(next.markdown === undefined ? {} : { markdown: rebased(held.markdown, next.markdown) }),
503
- },
504
- };
505
- }
506
713
  export function withdrawnDrafts(drafts, changes) {
507
714
  return drafts.flatMap((draft) => {
508
715
  const file = draft.parts.file;
@@ -0,0 +1,24 @@
1
+ import { type ChangeSet } from './change-set.js';
2
+ import { type VisibleLayer } from './replica.js';
3
+ import { type RoomDraft, type RoomDraftWrite } from './room-draft.js';
4
+ import type { Runtime } from './runtime.js';
5
+ import type { Store } from './store.js';
6
+ export type RoomDraftSurface = {
7
+ list(): Promise<readonly RoomDraft[]>;
8
+ read(room: string, path: string): Promise<RoomDraft | null>;
9
+ write(room: string, path: string, revision: string | null, parts: unknown, next?: string): Promise<RoomDraftWrite>;
10
+ discard(room: string, path: string, revision: string): Promise<RoomDraftWrite>;
11
+ };
12
+ export type PresentationSurface = {
13
+ read(app: string): Promise<unknown>;
14
+ write(app: string, value: unknown): Promise<void>;
15
+ edit(app: string, members: Readonly<Record<string, unknown>>): Promise<void>;
16
+ };
17
+ export declare function visibleOf(store: Store, locator: string, paths: readonly string[]): Promise<VisibleLayer | undefined>;
18
+ export declare function publishRoomDrafts({ store, socket }: Runtime, waitingOnly: boolean, touched?: ChangeSet['documents'] | null): Promise<void>;
19
+ export declare function emitPresentation({ store, socket }: Runtime, app: string): Promise<void>;
20
+ export declare function roomDraftSurface(runtime: Runtime): RoomDraftSurface;
21
+ export declare function presentationSurface(runtime: Runtime): PresentationSurface;
22
+ export declare function watchRoomDrafts({ store, socket }: Runtime, deliver: (value: unknown) => void): () => void;
23
+ export declare function watchPresentation({ store, socket }: Runtime, app: string, deliver: (value: unknown) => void): () => void;
24
+ //# sourceMappingURL=room-drafts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-drafts.d.ts","sourceRoot":"","sources":["../src/room-drafts.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5D,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EASL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,KAAK,EAAE,OAAO,EACd,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAChF,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAMF,wBAAsB,SAAS,CAC7B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAMnC;AA2CD,wBAAgB,iBAAiB,CAC/B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAC1B,WAAW,EAAE,OAAO,EACpB,OAAO,GAAE,SAAS,CAAC,WAAW,CAAC,GAAG,IAAW,GAC5C,OAAO,CAAC,IAAI,CAAC,CAuBf;AAOD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvF;AAsDD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAkDnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,mBAAmB,CA8BzE;AAED,wBAAgB,eAAe,CAC7B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,MAAM,IAAI,CAiBZ;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,MAAM,IAAI,CASZ"}