@dxos/echo-db 2.33.5-dev.97a81dd0 → 2.33.5-dev.a55bfd40

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 (362) hide show
  1. package/dist/src/api/index.d.ts +0 -5
  2. package/dist/src/api/index.d.ts.map +1 -1
  3. package/dist/src/api/index.js +5 -6
  4. package/dist/src/api/index.js.map +1 -1
  5. package/dist/src/api/schema.test.js +1 -1
  6. package/dist/src/api/schema.test.js.map +1 -1
  7. package/dist/src/echo.d.ts +1 -0
  8. package/dist/src/echo.d.ts.map +1 -1
  9. package/dist/src/echo.js +10 -21
  10. package/dist/src/echo.js.map +1 -1
  11. package/dist/src/echo.test.js +12 -4
  12. package/dist/src/echo.test.js.map +1 -1
  13. package/dist/src/halo/contact-manager.d.ts +2 -1
  14. package/dist/src/halo/contact-manager.d.ts.map +1 -1
  15. package/dist/src/halo/contact-manager.js +1 -1
  16. package/dist/src/halo/contact-manager.js.map +1 -1
  17. package/dist/src/halo/halo-factory.d.ts +4 -4
  18. package/dist/src/halo/halo-factory.d.ts.map +1 -1
  19. package/dist/src/halo/halo-factory.js +7 -6
  20. package/dist/src/halo/halo-factory.js.map +1 -1
  21. package/dist/src/halo/halo-party.d.ts +7 -6
  22. package/dist/src/halo/halo-party.d.ts.map +1 -1
  23. package/dist/src/halo/halo-party.js +13 -9
  24. package/dist/src/halo/halo-party.js.map +1 -1
  25. package/dist/src/halo/halo.d.ts +2 -2
  26. package/dist/src/halo/halo.d.ts.map +1 -1
  27. package/dist/src/halo/halo.test.js +4 -3
  28. package/dist/src/halo/halo.test.js.map +1 -1
  29. package/dist/src/halo/index.js +5 -1
  30. package/dist/src/halo/index.js.map +1 -1
  31. package/dist/src/halo/party-opener.d.ts.map +1 -1
  32. package/dist/src/halo/party-opener.js +3 -1
  33. package/dist/src/halo/party-opener.js.map +1 -1
  34. package/dist/src/halo/preferences.d.ts +1 -1
  35. package/dist/src/halo/preferences.d.ts.map +1 -1
  36. package/dist/src/halo/preferences.js +1 -1
  37. package/dist/src/halo/preferences.js.map +1 -1
  38. package/dist/src/index.d.ts +2 -2
  39. package/dist/src/index.d.ts.map +1 -1
  40. package/dist/src/index.js +7 -3
  41. package/dist/src/index.js.map +1 -1
  42. package/dist/src/invitations/greeting-initiator.d.ts +2 -2
  43. package/dist/src/invitations/greeting-initiator.d.ts.map +1 -1
  44. package/dist/src/invitations/greeting-initiator.js +2 -1
  45. package/dist/src/invitations/greeting-initiator.js.map +1 -1
  46. package/dist/src/invitations/greeting-responder.d.ts +6 -4
  47. package/dist/src/invitations/greeting-responder.d.ts.map +1 -1
  48. package/dist/src/invitations/greeting-responder.js +3 -2
  49. package/dist/src/invitations/greeting-responder.js.map +1 -1
  50. package/dist/src/invitations/halo-recovery-initiator.js +1 -1
  51. package/dist/src/invitations/halo-recovery-initiator.js.map +1 -1
  52. package/dist/src/invitations/index.js +5 -1
  53. package/dist/src/invitations/index.js.map +1 -1
  54. package/dist/src/invitations/invitation-descriptor.js +6 -2
  55. package/dist/src/invitations/invitation-descriptor.js.map +1 -1
  56. package/dist/src/invitations/invitation-factory.d.ts +5 -2
  57. package/dist/src/invitations/invitation-factory.d.ts.map +1 -1
  58. package/dist/src/invitations/invitation-factory.js +4 -3
  59. package/dist/src/invitations/invitation-factory.js.map +1 -1
  60. package/dist/src/invitations/offline-invitation-claimer.js +1 -1
  61. package/dist/src/invitations/offline-invitation-claimer.js.map +1 -1
  62. package/dist/src/{database → packlets/database}/data-mirror.d.ts +0 -0
  63. package/dist/src/packlets/database/data-mirror.d.ts.map +1 -0
  64. package/dist/src/{database → packlets/database}/data-mirror.js +0 -0
  65. package/dist/src/packlets/database/data-mirror.js.map +1 -0
  66. package/dist/src/{database → packlets/database}/data-mirror.test.d.ts +0 -0
  67. package/dist/src/packlets/database/data-mirror.test.d.ts.map +1 -0
  68. package/dist/src/{database → packlets/database}/data-mirror.test.js +2 -2
  69. package/dist/src/packlets/database/data-mirror.test.js.map +1 -0
  70. package/dist/src/{database → packlets/database}/data-service-host.d.ts +0 -0
  71. package/dist/src/packlets/database/data-service-host.d.ts.map +1 -0
  72. package/dist/src/{database → packlets/database}/data-service-host.js +4 -3
  73. package/dist/src/packlets/database/data-service-host.js.map +1 -0
  74. package/dist/src/{database → packlets/database}/data-service-router.d.ts +0 -0
  75. package/dist/src/packlets/database/data-service-router.d.ts.map +1 -0
  76. package/dist/src/{database → packlets/database}/data-service-router.js +0 -0
  77. package/dist/src/packlets/database/data-service-router.js.map +1 -0
  78. package/dist/src/{database → packlets/database}/database-backend.d.ts +4 -5
  79. package/dist/src/packlets/database/database-backend.d.ts.map +1 -0
  80. package/dist/src/{database → packlets/database}/database-backend.js +5 -6
  81. package/dist/src/packlets/database/database-backend.js.map +1 -0
  82. package/dist/src/{api → packlets/database}/database.d.ts +2 -1
  83. package/dist/src/packlets/database/database.d.ts.map +1 -0
  84. package/dist/src/{api → packlets/database}/database.js +2 -2
  85. package/dist/src/packlets/database/database.js.map +1 -0
  86. package/dist/src/{api → packlets/database}/database.test.d.ts +0 -0
  87. package/dist/src/packlets/database/database.test.d.ts.map +1 -0
  88. package/dist/src/{api → packlets/database}/database.test.js +3 -3
  89. package/dist/src/packlets/database/database.test.js.map +1 -0
  90. package/dist/src/{api → packlets/database}/entity.d.ts +1 -1
  91. package/dist/src/packlets/database/entity.d.ts.map +1 -0
  92. package/dist/src/{api → packlets/database}/entity.js +0 -0
  93. package/dist/src/packlets/database/entity.js.map +1 -0
  94. package/dist/src/{database → packlets/database}/index.d.ts +5 -0
  95. package/dist/src/packlets/database/index.d.ts.map +1 -0
  96. package/dist/src/{database → packlets/database}/index.js +10 -1
  97. package/dist/src/packlets/database/index.js.map +1 -0
  98. package/dist/src/{database → packlets/database}/item-demuxer.d.ts +4 -3
  99. package/dist/src/packlets/database/item-demuxer.d.ts.map +1 -0
  100. package/dist/src/{database → packlets/database}/item-demuxer.js +2 -3
  101. package/dist/src/packlets/database/item-demuxer.js.map +1 -0
  102. package/dist/src/{database → packlets/database}/item-demuxer.test.d.ts +0 -0
  103. package/dist/src/packlets/database/item-demuxer.test.d.ts.map +1 -0
  104. package/dist/src/{database → packlets/database}/item-demuxer.test.js +15 -11
  105. package/dist/src/packlets/database/item-demuxer.test.js.map +1 -0
  106. package/dist/src/{database → packlets/database}/item-manager.d.ts +3 -1
  107. package/dist/src/packlets/database/item-manager.d.ts.map +1 -0
  108. package/dist/src/{database → packlets/database}/item-manager.js +11 -10
  109. package/dist/src/packlets/database/item-manager.js.map +1 -0
  110. package/dist/src/{database → packlets/database}/item-manager.test.d.ts +0 -0
  111. package/dist/src/packlets/database/item-manager.test.d.ts.map +1 -0
  112. package/dist/src/{database → packlets/database}/item-manager.test.js +0 -0
  113. package/dist/src/packlets/database/item-manager.test.js.map +1 -0
  114. package/dist/src/{api → packlets/database}/item.d.ts +1 -1
  115. package/dist/src/packlets/database/item.d.ts.map +1 -0
  116. package/dist/src/{api → packlets/database}/item.js +0 -0
  117. package/dist/src/packlets/database/item.js.map +1 -0
  118. package/dist/src/{api → packlets/database}/link.d.ts +1 -1
  119. package/dist/src/packlets/database/link.d.ts.map +1 -0
  120. package/dist/src/{api → packlets/database}/link.js +0 -0
  121. package/dist/src/packlets/database/link.js.map +1 -0
  122. package/dist/src/{api → packlets/database}/selection/index.d.ts +0 -0
  123. package/dist/src/packlets/database/selection/index.d.ts.map +1 -0
  124. package/dist/src/{api → packlets/database}/selection/index.js +5 -1
  125. package/dist/src/packlets/database/selection/index.js.map +1 -0
  126. package/dist/src/{api → packlets/database}/selection/queries.d.ts +0 -0
  127. package/dist/src/packlets/database/selection/queries.d.ts.map +1 -0
  128. package/dist/src/{api → packlets/database}/selection/queries.js +0 -0
  129. package/dist/src/packlets/database/selection/queries.js.map +1 -0
  130. package/dist/src/{api → packlets/database}/selection/result.d.ts +0 -0
  131. package/dist/src/packlets/database/selection/result.d.ts.map +1 -0
  132. package/dist/src/{api → packlets/database}/selection/result.js +0 -0
  133. package/dist/src/packlets/database/selection/result.js.map +1 -0
  134. package/dist/src/{api → packlets/database}/selection/selection.d.ts +0 -0
  135. package/dist/src/packlets/database/selection/selection.d.ts.map +1 -0
  136. package/dist/src/{api → packlets/database}/selection/selection.js +0 -0
  137. package/dist/src/packlets/database/selection/selection.js.map +1 -0
  138. package/dist/src/{api → packlets/database}/selection/selection.test.d.ts +0 -0
  139. package/dist/src/packlets/database/selection/selection.test.d.ts.map +1 -0
  140. package/dist/src/{api → packlets/database}/selection/selection.test.js +0 -0
  141. package/dist/src/packlets/database/selection/selection.test.js.map +1 -0
  142. package/dist/src/{api → packlets/database}/selection/util.d.ts +0 -0
  143. package/dist/src/packlets/database/selection/util.d.ts.map +1 -0
  144. package/dist/src/{api → packlets/database}/selection/util.js +0 -0
  145. package/dist/src/packlets/database/selection/util.js.map +1 -0
  146. package/dist/src/{database → packlets/database}/testing.d.ts +1 -1
  147. package/dist/src/packlets/database/testing.d.ts.map +1 -0
  148. package/dist/src/{database → packlets/database}/testing.js +5 -6
  149. package/dist/src/packlets/database/testing.js.map +1 -0
  150. package/dist/src/{database → packlets/database}/timeframe-clock.d.ts +1 -0
  151. package/dist/src/packlets/database/timeframe-clock.d.ts.map +1 -0
  152. package/dist/src/{database → packlets/database}/timeframe-clock.js +3 -0
  153. package/dist/src/packlets/database/timeframe-clock.js.map +1 -0
  154. package/dist/src/{errors.d.ts → packlets/errors/index.d.ts} +1 -1
  155. package/dist/src/packlets/errors/index.d.ts.map +1 -0
  156. package/dist/src/{errors.js → packlets/errors/index.js} +1 -1
  157. package/dist/src/packlets/errors/index.js.map +1 -0
  158. package/dist/src/parties/data-party.d.ts +11 -9
  159. package/dist/src/parties/data-party.d.ts.map +1 -1
  160. package/dist/src/parties/data-party.js +31 -10
  161. package/dist/src/parties/data-party.js.map +1 -1
  162. package/dist/src/parties/data-party.test.js +37 -17
  163. package/dist/src/parties/data-party.test.js.map +1 -1
  164. package/dist/src/parties/index.js +5 -1
  165. package/dist/src/parties/index.js.map +1 -1
  166. package/dist/src/parties/party-factory.d.ts +5 -4
  167. package/dist/src/parties/party-factory.d.ts.map +1 -1
  168. package/dist/src/parties/party-factory.js +25 -21
  169. package/dist/src/parties/party-factory.js.map +1 -1
  170. package/dist/src/parties/party-manager.d.ts +3 -4
  171. package/dist/src/parties/party-manager.d.ts.map +1 -1
  172. package/dist/src/parties/party-manager.js +8 -7
  173. package/dist/src/parties/party-manager.js.map +1 -1
  174. package/dist/src/parties/party-manager.test.js +16 -15
  175. package/dist/src/parties/party-manager.test.js.map +1 -1
  176. package/dist/src/pipeline/{pipeline.d.ts → feed-muxer.d.ts} +8 -11
  177. package/dist/src/pipeline/feed-muxer.d.ts.map +1 -0
  178. package/dist/src/pipeline/{pipeline.js → feed-muxer.js} +34 -41
  179. package/dist/src/pipeline/feed-muxer.js.map +1 -0
  180. package/dist/src/pipeline/feed-muxer.test.d.ts +2 -0
  181. package/dist/src/pipeline/feed-muxer.test.d.ts.map +1 -0
  182. package/dist/src/pipeline/{pipeline.test.js → feed-muxer.test.js} +20 -18
  183. package/dist/src/pipeline/feed-muxer.test.js.map +1 -0
  184. package/dist/src/pipeline/index.d.ts +2 -2
  185. package/dist/src/pipeline/index.d.ts.map +1 -1
  186. package/dist/src/pipeline/index.js +7 -3
  187. package/dist/src/pipeline/index.js.map +1 -1
  188. package/dist/src/pipeline/message-selector.d.ts +1 -1
  189. package/dist/src/pipeline/message-selector.d.ts.map +1 -1
  190. package/dist/src/pipeline/message-selector.js +6 -5
  191. package/dist/src/pipeline/message-selector.js.map +1 -1
  192. package/dist/src/pipeline/metadata-store.d.ts +5 -4
  193. package/dist/src/pipeline/metadata-store.d.ts.map +1 -1
  194. package/dist/src/pipeline/metadata-store.js +11 -5
  195. package/dist/src/pipeline/metadata-store.js.map +1 -1
  196. package/dist/src/pipeline/metadata-store.test.js +8 -4
  197. package/dist/src/pipeline/metadata-store.test.js.map +1 -1
  198. package/dist/src/pipeline/party-feed-provider.d.ts +2 -3
  199. package/dist/src/pipeline/party-feed-provider.d.ts.map +1 -1
  200. package/dist/src/pipeline/party-feed-provider.js +2 -17
  201. package/dist/src/pipeline/party-feed-provider.js.map +1 -1
  202. package/dist/src/pipeline/{party-core.d.ts → party-pipeline.d.ts} +26 -12
  203. package/dist/src/pipeline/party-pipeline.d.ts.map +1 -0
  204. package/dist/src/pipeline/{party-core.js → party-pipeline.js} +32 -36
  205. package/dist/src/pipeline/party-pipeline.js.map +1 -0
  206. package/dist/src/pipeline/party-pipeline.test.d.ts +2 -0
  207. package/dist/src/pipeline/party-pipeline.test.d.ts.map +1 -0
  208. package/dist/src/pipeline/{party-core.test.js → party-pipeline.test.js} +62 -45
  209. package/dist/src/pipeline/party-pipeline.test.js.map +1 -0
  210. package/dist/src/pipeline/party-processor.d.ts +3 -9
  211. package/dist/src/pipeline/party-processor.d.ts.map +1 -1
  212. package/dist/src/pipeline/party-processor.js +0 -8
  213. package/dist/src/pipeline/party-processor.js.map +1 -1
  214. package/dist/src/protocol/authenticator.d.ts +3 -3
  215. package/dist/src/protocol/authenticator.d.ts.map +1 -1
  216. package/dist/src/protocol/authenticator.js +2 -2
  217. package/dist/src/protocol/authenticator.js.map +1 -1
  218. package/dist/src/protocol/authenticator.test.js +1 -4
  219. package/dist/src/protocol/authenticator.test.js.map +1 -1
  220. package/dist/src/protocol/index.js +5 -1
  221. package/dist/src/protocol/index.js.map +1 -1
  222. package/dist/src/snapshots/index.js +5 -1
  223. package/dist/src/snapshots/index.js.map +1 -1
  224. package/dist/src/snapshots/snapshot-generator.d.ts +3 -3
  225. package/dist/src/snapshots/snapshot-generator.d.ts.map +1 -1
  226. package/dist/src/snapshots/snapshot-generator.js.map +1 -1
  227. package/dist/src/snapshots/snapshot-store.d.ts +3 -3
  228. package/dist/src/snapshots/snapshot-store.d.ts.map +1 -1
  229. package/dist/src/snapshots/snapshot-store.js +5 -5
  230. package/dist/src/snapshots/snapshot-store.js.map +1 -1
  231. package/dist/src/snapshots/snapshot-store.test.js +1 -1
  232. package/dist/src/snapshots/snapshot-store.test.js.map +1 -1
  233. package/dist/src/snapshots/snapshot.test.js +1 -1
  234. package/dist/src/snapshots/snapshot.test.js.map +1 -1
  235. package/dist/src/testing/index.js +5 -1
  236. package/dist/src/testing/index.js.map +1 -1
  237. package/dist/src/testing/testing-factories.d.ts +1 -1
  238. package/dist/src/testing/testing-factories.d.ts.map +1 -1
  239. package/dist/tsconfig.tsbuildinfo +1 -1
  240. package/package.json +19 -19
  241. package/src/api/index.ts +0 -5
  242. package/src/api/schema.test.ts +1 -2
  243. package/src/echo.test.ts +16 -5
  244. package/src/echo.ts +11 -20
  245. package/src/halo/contact-manager.ts +3 -2
  246. package/src/halo/halo-factory.ts +10 -10
  247. package/src/halo/halo-party.ts +22 -15
  248. package/src/halo/halo.test.ts +4 -3
  249. package/src/halo/halo.ts +2 -2
  250. package/src/halo/party-opener.ts +3 -1
  251. package/src/halo/preferences.ts +3 -2
  252. package/src/index.ts +3 -2
  253. package/src/invitations/greeting-initiator.ts +5 -4
  254. package/src/invitations/greeting-responder.ts +7 -5
  255. package/src/invitations/halo-recovery-initiator.ts +1 -1
  256. package/src/invitations/invitation-descriptor.ts +1 -1
  257. package/src/invitations/invitation-factory.ts +8 -5
  258. package/src/invitations/offline-invitation-claimer.ts +1 -1
  259. package/src/{database → packlets/database}/data-mirror.test.ts +3 -3
  260. package/src/{database → packlets/database}/data-mirror.ts +1 -1
  261. package/src/{database → packlets/database}/data-service-host.ts +2 -1
  262. package/src/{database → packlets/database}/data-service-router.ts +0 -0
  263. package/src/{database → packlets/database}/database-backend.ts +7 -6
  264. package/src/{api → packlets/database}/database.test.ts +2 -1
  265. package/src/{api → packlets/database}/database.ts +3 -1
  266. package/src/{api → packlets/database}/entity.ts +1 -1
  267. package/src/{database → packlets/database}/index.ts +5 -0
  268. package/src/{database → packlets/database}/item-demuxer.test.ts +21 -19
  269. package/src/{database → packlets/database}/item-demuxer.ts +8 -5
  270. package/src/{database → packlets/database}/item-manager.test.ts +0 -0
  271. package/src/{database → packlets/database}/item-manager.ts +3 -1
  272. package/src/{api → packlets/database}/item.ts +2 -2
  273. package/src/{api → packlets/database}/link.ts +1 -1
  274. package/src/{api → packlets/database}/selection/index.ts +0 -0
  275. package/src/{api → packlets/database}/selection/queries.ts +0 -0
  276. package/src/{api → packlets/database}/selection/result.ts +0 -0
  277. package/src/{api → packlets/database}/selection/selection.test.ts +0 -0
  278. package/src/{api → packlets/database}/selection/selection.ts +0 -0
  279. package/src/{api → packlets/database}/selection/util.ts +0 -0
  280. package/src/{database → packlets/database}/testing.ts +4 -7
  281. package/src/{database → packlets/database}/timeframe-clock.ts +4 -0
  282. package/src/{errors.ts → packlets/errors/index.ts} +0 -0
  283. package/src/parties/data-party.test.ts +53 -20
  284. package/src/parties/data-party.ts +40 -16
  285. package/src/parties/party-factory.ts +29 -27
  286. package/src/parties/party-manager.test.ts +24 -15
  287. package/src/parties/party-manager.ts +9 -6
  288. package/src/pipeline/{pipeline.test.ts → feed-muxer.test.ts} +23 -19
  289. package/src/pipeline/{pipeline.ts → feed-muxer.ts} +39 -51
  290. package/src/pipeline/index.ts +2 -2
  291. package/src/pipeline/message-selector.ts +7 -6
  292. package/src/pipeline/metadata-store.test.ts +8 -4
  293. package/src/pipeline/metadata-store.ts +12 -6
  294. package/src/pipeline/party-feed-provider.ts +3 -16
  295. package/src/pipeline/{party-core.test.ts → party-pipeline.test.ts} +64 -42
  296. package/src/pipeline/{party-core.ts → party-pipeline.ts} +59 -36
  297. package/src/pipeline/party-processor.ts +2 -18
  298. package/src/protocol/authenticator.test.ts +1 -4
  299. package/src/protocol/authenticator.ts +8 -4
  300. package/src/snapshots/snapshot-generator.ts +3 -3
  301. package/src/snapshots/snapshot-store.test.ts +1 -1
  302. package/src/snapshots/snapshot-store.ts +5 -6
  303. package/src/snapshots/snapshot.test.ts +1 -1
  304. package/src/testing/testing-factories.ts +1 -1
  305. package/dist/src/api/database.d.ts.map +0 -1
  306. package/dist/src/api/database.js.map +0 -1
  307. package/dist/src/api/database.test.d.ts.map +0 -1
  308. package/dist/src/api/database.test.js.map +0 -1
  309. package/dist/src/api/entity.d.ts.map +0 -1
  310. package/dist/src/api/entity.js.map +0 -1
  311. package/dist/src/api/item.d.ts.map +0 -1
  312. package/dist/src/api/item.js.map +0 -1
  313. package/dist/src/api/link.d.ts.map +0 -1
  314. package/dist/src/api/link.js.map +0 -1
  315. package/dist/src/api/selection/index.d.ts.map +0 -1
  316. package/dist/src/api/selection/index.js.map +0 -1
  317. package/dist/src/api/selection/queries.d.ts.map +0 -1
  318. package/dist/src/api/selection/queries.js.map +0 -1
  319. package/dist/src/api/selection/result.d.ts.map +0 -1
  320. package/dist/src/api/selection/result.js.map +0 -1
  321. package/dist/src/api/selection/selection.d.ts.map +0 -1
  322. package/dist/src/api/selection/selection.js.map +0 -1
  323. package/dist/src/api/selection/selection.test.d.ts.map +0 -1
  324. package/dist/src/api/selection/selection.test.js.map +0 -1
  325. package/dist/src/api/selection/util.d.ts.map +0 -1
  326. package/dist/src/api/selection/util.js.map +0 -1
  327. package/dist/src/database/data-mirror.d.ts.map +0 -1
  328. package/dist/src/database/data-mirror.js.map +0 -1
  329. package/dist/src/database/data-mirror.test.d.ts.map +0 -1
  330. package/dist/src/database/data-mirror.test.js.map +0 -1
  331. package/dist/src/database/data-service-host.d.ts.map +0 -1
  332. package/dist/src/database/data-service-host.js.map +0 -1
  333. package/dist/src/database/data-service-router.d.ts.map +0 -1
  334. package/dist/src/database/data-service-router.js.map +0 -1
  335. package/dist/src/database/database-backend.d.ts.map +0 -1
  336. package/dist/src/database/database-backend.js.map +0 -1
  337. package/dist/src/database/index.d.ts.map +0 -1
  338. package/dist/src/database/index.js.map +0 -1
  339. package/dist/src/database/item-demuxer.d.ts.map +0 -1
  340. package/dist/src/database/item-demuxer.js.map +0 -1
  341. package/dist/src/database/item-demuxer.test.d.ts.map +0 -1
  342. package/dist/src/database/item-demuxer.test.js.map +0 -1
  343. package/dist/src/database/item-manager.d.ts.map +0 -1
  344. package/dist/src/database/item-manager.js.map +0 -1
  345. package/dist/src/database/item-manager.test.d.ts.map +0 -1
  346. package/dist/src/database/item-manager.test.js.map +0 -1
  347. package/dist/src/database/testing.d.ts.map +0 -1
  348. package/dist/src/database/testing.js.map +0 -1
  349. package/dist/src/database/timeframe-clock.d.ts.map +0 -1
  350. package/dist/src/database/timeframe-clock.js.map +0 -1
  351. package/dist/src/errors.d.ts.map +0 -1
  352. package/dist/src/errors.js.map +0 -1
  353. package/dist/src/pipeline/party-core.d.ts.map +0 -1
  354. package/dist/src/pipeline/party-core.js.map +0 -1
  355. package/dist/src/pipeline/party-core.test.d.ts +0 -2
  356. package/dist/src/pipeline/party-core.test.d.ts.map +0 -1
  357. package/dist/src/pipeline/party-core.test.js.map +0 -1
  358. package/dist/src/pipeline/pipeline.d.ts.map +0 -1
  359. package/dist/src/pipeline/pipeline.js.map +0 -1
  360. package/dist/src/pipeline/pipeline.test.d.ts +0 -2
  361. package/dist/src/pipeline/pipeline.test.d.ts.map +0 -1
  362. package/dist/src/pipeline/pipeline.test.js.map +0 -1
@@ -11,7 +11,8 @@ import { MetadataStore } from './metadata-store';
11
11
 
12
12
  describe('MetadataStore in-memory', () => {
13
13
  it('Creates party and adds feeds to it', async () => {
14
- const store = new MetadataStore(createStorage('metadata', StorageType.RAM));
14
+ const storage = createStorage('', StorageType.RAM);
15
+ const store = new MetadataStore(storage.directory('metadata'));
15
16
  await store.load();
16
17
  expect(store.parties?.length).toBe(0);
17
18
 
@@ -33,7 +34,8 @@ describe('MetadataStore in-memory', () => {
33
34
  });
34
35
 
35
36
  it('Creates party when adding feed', async () => {
36
- const store = new MetadataStore(createStorage('metadata', StorageType.RAM));
37
+ const storage = createStorage('', StorageType.RAM);
38
+ const store = new MetadataStore(storage.directory('metadata'));
37
39
  await store.load();
38
40
 
39
41
  const partyKey = PublicKey.random();
@@ -45,7 +47,8 @@ describe('MetadataStore in-memory', () => {
45
47
  });
46
48
 
47
49
  it('Doesn\'t add same feed twice', async () => {
48
- const store = new MetadataStore(createStorage('metadata', StorageType.RAM));
50
+ const storage = createStorage('', StorageType.RAM);
51
+ const store = new MetadataStore(storage.directory('metadata'));
49
52
  await store.load();
50
53
 
51
54
  const partyKey = PublicKey.random();
@@ -60,7 +63,8 @@ describe('MetadataStore in-memory', () => {
60
63
 
61
64
  // TODO(yivlad): Doesn't work for now.
62
65
  it.skip('Resets storage', async () => {
63
- const store = new MetadataStore(createStorage('snapshots', StorageType.RAM));
66
+ const storage = createStorage('snapshots', StorageType.RAM);
67
+ const store = new MetadataStore(storage.directory(''));
64
68
 
65
69
  const partyKey = PublicKey.random();
66
70
  const feedKey = PublicKey.random();
@@ -7,8 +7,8 @@ import debug from 'debug';
7
7
 
8
8
  import { PublicKey } from '@dxos/crypto';
9
9
  import { failUndefined } from '@dxos/debug';
10
- import { EchoMetadata, PartyMetadata, schema } from '@dxos/echo-protocol';
11
- import { Storage } from '@dxos/random-access-multi-storage';
10
+ import { EchoMetadata, PartyMetadata, schema, Timeframe } from '@dxos/echo-protocol';
11
+ import { Directory } from '@dxos/random-access-multi-storage';
12
12
 
13
13
  /**
14
14
  * Version for the schema of the stored data as defined in dxos.echo.metadata.EchoMetadata.
@@ -28,7 +28,7 @@ export class MetadataStore {
28
28
  };
29
29
 
30
30
  constructor (
31
- private readonly _storage: Storage
31
+ private readonly _directory: Directory
32
32
  ) {}
33
33
 
34
34
  get version (): number {
@@ -47,7 +47,7 @@ export class MetadataStore {
47
47
  * Loads metadata from persistent storage.
48
48
  */
49
49
  async load (): Promise<void> {
50
- const file = this._storage.createOrOpen('EchoMetadata');
50
+ const file = this._directory.createOrOpen('EchoMetadata');
51
51
  try {
52
52
  const { size } = await file.stat();
53
53
  if (size === 0) {
@@ -75,7 +75,7 @@ export class MetadataStore {
75
75
  updated: new Date()
76
76
  };
77
77
 
78
- const file = this._storage.createOrOpen('EchoMetadata');
78
+ const file = this._directory.createOrOpen('EchoMetadata');
79
79
 
80
80
  try {
81
81
  const encoded = Buffer.from(schema.getCodecForType('dxos.echo.metadata.EchoMetadata').encode(data));
@@ -90,7 +90,7 @@ export class MetadataStore {
90
90
  */
91
91
  async clear (): Promise<void> {
92
92
  log('Clearing all echo metadata...');
93
- await this._storage.destroy();
93
+ await this._directory.delete();
94
94
  }
95
95
 
96
96
  /**
@@ -158,4 +158,10 @@ export class MetadataStore {
158
158
  }
159
159
  return !!party.feedKeys?.find(fk => feedKey.equals(fk));
160
160
  }
161
+
162
+ async setTimeframe (partyKey: PublicKey, timeframe: Timeframe) {
163
+ const party = this.getParty(partyKey) ?? failUndefined();
164
+ party.latestTimeframe = timeframe;
165
+ await this._save();
166
+ }
161
167
  }
@@ -8,7 +8,7 @@ import debug from 'debug';
8
8
  import { Event, synchronized } from '@dxos/async';
9
9
  import { Keyring, KeyType } from '@dxos/credentials';
10
10
  import { PublicKey } from '@dxos/crypto';
11
- import { FeedStoreIterator, MessageSelector, Timeframe } from '@dxos/echo-protocol';
11
+ import { FeedSelector, FeedStoreIterator, MessageSelector, Timeframe } from '@dxos/echo-protocol';
12
12
  import { FeedDescriptor, FeedStore } from '@dxos/feed-store';
13
13
  import { ComplexMap } from '@dxos/util';
14
14
 
@@ -33,19 +33,6 @@ export class PartyFeedProvider {
33
33
  return Array.from(this._feeds.values());
34
34
  }
35
35
 
36
- @synchronized
37
- async openKnownFeeds () {
38
- for (const feedKey of this._metadataStore.getParty(this._partyKey)?.feedKeys ?? []) {
39
- if (!this._feeds.has(feedKey)) {
40
- const fullKey = this._keyring.getFullKey(feedKey);
41
- const feed = fullKey?.secretKey
42
- ? await this._feedStore.openReadWriteFeed(fullKey.publicKey, fullKey.secretKey)
43
- : await this._feedStore.openReadOnlyFeed(feedKey);
44
- this._trackFeed(feed);
45
- }
46
- }
47
- }
48
-
49
36
  @synchronized
50
37
  async createOrOpenWritableFeed () {
51
38
  const partyMetadata = this._metadataStore.getParty(this._partyKey);
@@ -103,8 +90,8 @@ export class PartyFeedProvider {
103
90
  return feed;
104
91
  }
105
92
 
106
- async createIterator (messageSelector: MessageSelector, initialTimeframe?: Timeframe) {
107
- const iterator = new FeedStoreIterator(() => true, messageSelector, initialTimeframe ?? new Timeframe());
93
+ async createIterator (messageSelector: MessageSelector, feedSelector: FeedSelector, initialTimeframe?: Timeframe) {
94
+ const iterator = new FeedStoreIterator(feedSelector, messageSelector, initialTimeframe ?? new Timeframe());
108
95
  for (const feed of this._feeds.values()) {
109
96
  iterator.addFeedDescriptor(feed);
110
97
  }
@@ -8,7 +8,8 @@ import { it as test } from 'mocha';
8
8
  import { promiseTimeout } from '@dxos/async';
9
9
  import { createFeedAdmitMessage, createPartyGenesisMessage, Keyring, KeyType } from '@dxos/credentials';
10
10
  import { createId, PublicKey } from '@dxos/crypto';
11
- import { codec, Timeframe } from '@dxos/echo-protocol';
11
+ import { checkType } from '@dxos/debug';
12
+ import { codec, FeedMessage, Timeframe } from '@dxos/echo-protocol';
12
13
  import { FeedStore } from '@dxos/feed-store';
13
14
  import { createTestProtocolPair } from '@dxos/mesh-protocol';
14
15
  import { ModelFactory } from '@dxos/model-factory';
@@ -16,29 +17,29 @@ import { ObjectModel } from '@dxos/object-model';
16
17
  import { createStorage, StorageType } from '@dxos/random-access-multi-storage';
17
18
  import { afterTest } from '@dxos/testutils';
18
19
 
19
- import { MetadataStore, PartyFeedProvider } from '../pipeline';
20
+ import { MetadataStore, PartyFeedProvider } from '.';
20
21
  import { createReplicatorPlugin } from '../protocol/replicator-plugin';
21
22
  import { SnapshotStore } from '../snapshots';
22
- import { PartyCore } from './party-core';
23
+ import { PartyPipeline } from './party-pipeline';
23
24
 
24
- describe('PartyCore', () => {
25
+ describe('PartyPipeline', () => {
25
26
  const setup = async () => {
26
27
  const storage = createStorage('', StorageType.RAM);
27
- const feedStore = new FeedStore(storage, { valueEncoding: codec });
28
+ const feedStore = new FeedStore(storage.directory('feed'), { valueEncoding: codec });
28
29
  afterTest(async () => feedStore.close());
29
30
 
30
31
  const keyring = new Keyring();
31
32
 
32
- const metadataStore = new MetadataStore(createStorage('metadata', StorageType.RAM));
33
+ const metadataStore = new MetadataStore(storage.directory('metadata'));
33
34
 
34
35
  const modelFactory = new ModelFactory().registerModel(ObjectModel);
35
- const snapshotStore = new SnapshotStore(createStorage('snapshots', StorageType.RAM));
36
+ const snapshotStore = new SnapshotStore(storage.directory('snapshots'));
36
37
 
37
38
  const partyKey = await keyring.createKeyRecord({ type: KeyType.PARTY });
38
39
 
39
40
  const partyFeedProvider = new PartyFeedProvider(metadataStore, keyring, feedStore, partyKey.publicKey);
40
41
 
41
- const party = new PartyCore(
42
+ const party = new PartyPipeline(
42
43
  partyKey.publicKey,
43
44
  partyFeedProvider,
44
45
  modelFactory,
@@ -47,11 +48,11 @@ describe('PartyCore', () => {
47
48
  );
48
49
 
49
50
  const feed = await partyFeedProvider.createOrOpenWritableFeed();
50
- await party.open();
51
+ await party.open({ feedHints: [feed.key] });
51
52
  afterTest(async () => party.close());
52
53
 
53
54
  // PartyGenesis (self-signed by Party).
54
- await party.writeCredentialsMessage(createPartyGenesisMessage(
55
+ await party.credentialsWriter.write(createPartyGenesisMessage(
55
56
  keyring,
56
57
  partyKey,
57
58
  feed.key,
@@ -59,7 +60,7 @@ describe('PartyCore', () => {
59
60
  );
60
61
 
61
62
  // FeedAdmit (signed by the Device KeyChain).
62
- await party.writeCredentialsMessage(createFeedAdmitMessage(
63
+ await party.credentialsWriter.write(createFeedAdmitMessage(
63
64
  keyring,
64
65
  partyKey.publicKey,
65
66
  feed.key,
@@ -87,7 +88,7 @@ describe('PartyCore', () => {
87
88
  });
88
89
 
89
90
  test('create item with parent and then reload', async () => {
90
- const { party } = await setup();
91
+ const { party, feedKey } = await setup();
91
92
 
92
93
  {
93
94
  const parent = await party.database.createItem({ model: ObjectModel, type: 'parent' });
@@ -102,7 +103,7 @@ describe('PartyCore', () => {
102
103
  }
103
104
 
104
105
  await party.close();
105
- await party.open();
106
+ await party.open({ feedHints: [feedKey] });
106
107
 
107
108
  {
108
109
  await party.database.select().exec().update.waitFor(result => result.entities.length === 2);
@@ -120,7 +121,7 @@ describe('PartyCore', () => {
120
121
  const feedKey = await keyring.createKeyRecord({ type: KeyType.FEED });
121
122
 
122
123
  const eventFired = feedStore.feedOpenedEvent.waitForCount(1);
123
- await party.writeCredentialsMessage(createFeedAdmitMessage(
124
+ await party.credentialsWriter.write(createFeedAdmitMessage(
124
125
  keyring,
125
126
  party.key,
126
127
  feedKey.publicKey,
@@ -132,15 +133,15 @@ describe('PartyCore', () => {
132
133
 
133
134
  test('opens feed from hints', async () => {
134
135
  const storage = createStorage('', StorageType.RAM);
135
- const feedStore = new FeedStore(storage, { valueEncoding: codec });
136
+ const feedStore = new FeedStore(storage.directory('feed'), { valueEncoding: codec });
136
137
  afterTest(async () => feedStore.close());
137
138
 
138
139
  const keyring = new Keyring();
139
140
 
140
- const metadataStore = new MetadataStore(createStorage('metadata', StorageType.RAM));
141
+ const metadataStore = new MetadataStore(storage.directory('metadata'));
141
142
 
142
143
  const modelFactory = new ModelFactory().registerModel(ObjectModel);
143
- const snapshotStore = new SnapshotStore(createStorage('snapshots', StorageType.RAM));
144
+ const snapshotStore = new SnapshotStore(storage.directory('snapshots'));
144
145
 
145
146
  const partyKey = await keyring.createKeyRecord({ type: KeyType.PARTY });
146
147
 
@@ -148,7 +149,7 @@ describe('PartyCore', () => {
148
149
 
149
150
  const otherFeedKey = PublicKey.random();
150
151
 
151
- const party = new PartyCore(
152
+ const party = new PartyPipeline(
152
153
  partyKey.publicKey,
153
154
  partyFeedProvider,
154
155
  modelFactory,
@@ -160,7 +161,7 @@ describe('PartyCore', () => {
160
161
 
161
162
  const feedOpened = feedStore.feedOpenedEvent.waitForCount(1);
162
163
 
163
- await party.open([{ type: KeyType.FEED, publicKey: otherFeedKey }]);
164
+ await party.open({ feedHints: [otherFeedKey] });
164
165
  afterTest(async () => party.close());
165
166
 
166
167
  await feedOpened;
@@ -175,16 +176,16 @@ describe('PartyCore', () => {
175
176
  const feed = await partyFeedProvider.createOrOpenWritableFeed();
176
177
 
177
178
  const itemId = createId();
178
- await feed.feed.append({
179
+ await feed.feed.append(checkType<FeedMessage>({
180
+ timeframe: new Timeframe(),
179
181
  echo: {
180
182
  itemId,
181
183
  genesis: {
182
184
  itemType: 'dxos:example',
183
185
  modelType: ObjectModel.meta.type
184
- },
185
- timeframe: new Timeframe()
186
+ }
186
187
  }
187
- });
188
+ }));
188
189
 
189
190
  await promiseTimeout(party.database.waitForItem({ id: itemId }), 1000, new Error('timeout'));
190
191
  });
@@ -197,7 +198,7 @@ describe('PartyCore', () => {
197
198
  const fullKey = keyring.getFullKey(feedKey.publicKey);
198
199
  const feed2 = await feedStore.openReadWriteFeed(fullKey!.publicKey, fullKey!.secretKey!);
199
200
 
200
- await party.writeCredentialsMessage(createFeedAdmitMessage(
201
+ await party.credentialsWriter.write(createFeedAdmitMessage(
201
202
  keyring,
202
203
  party.key,
203
204
  feed2.key,
@@ -205,16 +206,16 @@ describe('PartyCore', () => {
205
206
  ));
206
207
 
207
208
  const itemId = createId();
208
- await feed2.append({
209
+ await feed2.append(checkType<FeedMessage>({
210
+ timeframe: new Timeframe(),
209
211
  echo: {
210
212
  itemId,
211
213
  genesis: {
212
214
  itemType: 'dxos:example',
213
215
  modelType: ObjectModel.meta.type
214
- },
215
- timeframe: new Timeframe()
216
+ }
216
217
  }
217
- });
218
+ }));
218
219
 
219
220
  await promiseTimeout(party.database.waitForItem({ id: itemId }), 1000, new Error('timeout'));
220
221
  });
@@ -226,7 +227,7 @@ describe('PartyCore', () => {
226
227
  const feedKey = await keyring.createKeyRecord({ type: KeyType.FEED });
227
228
  const fullKey = keyring.getFullKey(feedKey.publicKey);
228
229
 
229
- await party.writeCredentialsMessage(createFeedAdmitMessage(
230
+ await party.credentialsWriter.write(createFeedAdmitMessage(
230
231
  keyring,
231
232
  party.key,
232
233
  feedKey.publicKey,
@@ -235,35 +236,57 @@ describe('PartyCore', () => {
235
236
 
236
237
  const feed2 = await feedStore.openReadWriteFeed(fullKey!.publicKey, fullKey!.secretKey!);
237
238
  const itemId = createId();
238
- await feed2.append({
239
+ await feed2.append(checkType<FeedMessage>({
240
+ timeframe: new Timeframe(),
239
241
  echo: {
240
242
  itemId,
241
243
  genesis: {
242
244
  itemType: 'dxos:example',
243
245
  modelType: ObjectModel.meta.type
244
- },
245
- timeframe: new Timeframe()
246
+ }
246
247
  }
247
- });
248
+ }));
248
249
 
249
250
  await promiseTimeout(party.database.waitForItem({ id: itemId }), 1000, new Error('timeout'));
250
251
  });
251
252
 
253
+ test('wait to reach specific timeframe', async () => {
254
+ const { party, feedKey } = await setup();
255
+
256
+ {
257
+ const parent = await party.database.createItem({ model: ObjectModel, type: 'parent' });
258
+ const child = await party.database.createItem({
259
+ model: ObjectModel,
260
+ parent: parent.id,
261
+ type: 'child'
262
+ });
263
+
264
+ expect(child.parent).toEqual(parent);
265
+ expect(parent.children).toContain(child);
266
+ }
267
+
268
+ const timeframe = party.timeframe;
269
+ expect(timeframe.isEmpty()).toBeFalsy();
270
+
271
+ await party.close();
272
+ await party.open({ feedHints: [feedKey], targetTimeframe: timeframe });
273
+ });
274
+
252
275
  test('two instances replicating', async () => {
253
276
  const peer1 = await setup();
254
277
 
255
278
  const storage = createStorage('', StorageType.RAM);
256
- const feedStore = new FeedStore(storage, { valueEncoding: codec });
279
+ const feedStore = new FeedStore(storage.directory('feed'), { valueEncoding: codec });
257
280
  afterTest(async () => feedStore.close());
258
281
 
259
- const metadataStore = new MetadataStore(createStorage('metadata', StorageType.RAM));
282
+ const metadataStore = new MetadataStore(storage.directory('metadata'));
260
283
 
261
284
  const modelFactory = new ModelFactory().registerModel(ObjectModel);
262
- const snapshotStore = new SnapshotStore(createStorage('snapshots', StorageType.RAM));
285
+ const snapshotStore = new SnapshotStore(storage.directory('snapshots'));
263
286
 
264
287
  const partyFeedProvider = new PartyFeedProvider(metadataStore, peer1.keyring, feedStore, peer1.party.key);
265
288
 
266
- const party2 = new PartyCore(
289
+ const party2 = new PartyPipeline(
267
290
  peer1.party.key,
268
291
  partyFeedProvider,
269
292
  modelFactory,
@@ -273,17 +296,16 @@ describe('PartyCore', () => {
273
296
 
274
297
  const feed2 = await partyFeedProvider.createOrOpenWritableFeed();
275
298
 
276
- await peer1.party.writeCredentialsMessage(createFeedAdmitMessage(
299
+ await peer1.party.credentialsWriter.write(createFeedAdmitMessage(
277
300
  peer1.keyring,
278
301
  peer1.party.key,
279
302
  feed2.key,
280
303
  [peer1.partyKey]
281
304
  ));
282
305
 
283
- await party2.open([{
284
- publicKey: peer1.feedKey,
285
- type: KeyType.FEED
286
- }]);
306
+ await party2.open({
307
+ feedHints: [peer1.feedKey]
308
+ });
287
309
  afterTest(async () => party2.close());
288
310
 
289
311
  createTestProtocolPair(
@@ -5,21 +5,20 @@
5
5
  import assert from 'assert';
6
6
 
7
7
  import { synchronized } from '@dxos/async';
8
- import { KeyHint, KeyType, Message as HaloMessage } from '@dxos/credentials';
8
+ import { KeyType, Message as HaloMessage } from '@dxos/credentials';
9
9
  import { PublicKey } from '@dxos/crypto';
10
10
  import { timed } from '@dxos/debug';
11
- import { createFeedWriter, DatabaseSnapshot, PartyKey, PartySnapshot, Timeframe, WriteReceipt } from '@dxos/echo-protocol';
11
+ import { createFeedWriter, DatabaseSnapshot, FeedSelector, FeedWriter, PartyKey, PartySnapshot, Timeframe } from '@dxos/echo-protocol';
12
12
  import { ModelFactory } from '@dxos/model-factory';
13
13
  import { SubscriptionGroup } from '@dxos/util';
14
14
 
15
- import { Database } from '../api';
16
- import { FeedDatabaseBackend, TimeframeClock } from '../database';
17
- import { createMessageSelector, PartyProcessor, PartyFeedProvider, Pipeline } from '../pipeline';
15
+ import { createMessageSelector, PartyProcessor, PartyFeedProvider, FeedMuxer } from '.';
16
+ import { Database, FeedDatabaseBackend, TimeframeClock } from '../packlets/database';
18
17
  import { createAutomaticSnapshots, SnapshotStore } from '../snapshots';
19
18
 
20
19
  const DEFAULT_SNAPSHOT_INTERVAL = 100; // Every 100 messages.
21
20
 
22
- export interface PartyOptions {
21
+ export interface PipelineOptions {
23
22
  readLogger?: (msg: any) => void;
24
23
  writeLogger?: (msg: any) => void;
25
24
  readOnly?: boolean;
@@ -29,6 +28,22 @@ export interface PartyOptions {
29
28
  snapshotInterval?: number;
30
29
  }
31
30
 
31
+ export interface OpenOptions {
32
+ /**
33
+ * Keys of initial feeds needed to bootstrap the party.
34
+ */
35
+ feedHints?: PublicKey[]
36
+ /**
37
+ * Timeframe to start processing feed messages from.
38
+ */
39
+ initialTimeframe?: Timeframe
40
+ /**
41
+ * Timeframe which must be reached until further processing.
42
+ * PartyCore.open will block until this timeframe is reached.
43
+ */
44
+ targetTimeframe?: Timeframe
45
+ }
46
+
32
47
  /**
33
48
  * Encapsulates core components needed by a party:
34
49
  * - ECHO database with item-manager & item-demuxer.
@@ -37,7 +52,7 @@ export interface PartyOptions {
37
52
  *
38
53
  * The core class also handles the combined ECHO and HALO state snapshots.
39
54
  */
40
- export class PartyCore {
55
+ export class PartyPipeline {
41
56
  /**
42
57
  * Snapshot to be restored from when party.open() is called.
43
58
  */
@@ -46,7 +61,7 @@ export class PartyCore {
46
61
  private readonly _subscriptions = new SubscriptionGroup();
47
62
 
48
63
  private _database?: Database;
49
- private _pipeline?: Pipeline;
64
+ private _pipeline?: FeedMuxer;
50
65
  private _partyProcessor?: PartyProcessor;
51
66
  private _timeframeClock?: TimeframeClock;
52
67
 
@@ -56,8 +71,7 @@ export class PartyCore {
56
71
  private readonly _modelFactory: ModelFactory,
57
72
  private readonly _snapshotStore: SnapshotStore,
58
73
  private readonly _memberKey: PublicKey,
59
- private readonly _initialTimeframe?: Timeframe,
60
- private readonly _options: PartyOptions = {}
74
+ private readonly _options: PipelineOptions = {}
61
75
  ) { }
62
76
 
63
77
  get key (): PartyKey {
@@ -99,20 +113,29 @@ export class PartyCore {
99
113
  return feed;
100
114
  }
101
115
 
116
+ get credentialsWriter (): FeedWriter<HaloMessage> {
117
+ assert(this._pipeline?.outboundHaloStream, 'Party not open');
118
+ return this._pipeline?.outboundHaloStream;
119
+ }
120
+
102
121
  /**
103
122
  * Opens the pipeline and connects the streams.
104
123
  */
105
124
  @synchronized
106
125
  @timed(1_000)
107
- async open (keyHints: KeyHint[] = []) {
126
+ async open (options: OpenOptions = {}) {
127
+ const {
128
+ feedHints = [],
129
+ initialTimeframe,
130
+ targetTimeframe
131
+ } = options;
132
+
108
133
  if (this.isOpen) {
109
134
  return this;
110
135
  }
111
136
 
112
- this._timeframeClock = new TimeframeClock(this._initialTimeframe);
137
+ this._timeframeClock = new TimeframeClock(initialTimeframe);
113
138
 
114
- // Open all feeds known from metadata and open or create a writable feed to the party.
115
- await this._feedProvider.openKnownFeeds();
116
139
  const writableFeed = await this._feedProvider.createOrOpenWritableFeed();
117
140
 
118
141
  if (!this._partyProcessor) {
@@ -124,12 +147,8 @@ export class PartyCore {
124
147
  void this._feedProvider.createOrOpenReadOnlyFeed(feed);
125
148
  }));
126
149
 
127
- // Hint at our own writable feed.
128
- // TODO(dmaretskyi): Does not seem like it should be required, but without it replication between devices (B -> A) breaks.
129
- await this._partyProcessor.takeHints([{ type: KeyType.FEED, publicKey: writableFeed.key }]);
130
-
131
- if (keyHints.length > 0) {
132
- await this._partyProcessor.takeHints(keyHints);
150
+ if (feedHints.length > 0) {
151
+ await this._partyProcessor.takeHints(feedHints.map(publicKey => ({ publicKey, type: KeyType.FEED })));
133
152
  }
134
153
 
135
154
  //
@@ -138,31 +157,34 @@ export class PartyCore {
138
157
 
139
158
  const iterator = await this._feedProvider.createIterator(
140
159
  createMessageSelector(this._partyProcessor, this._timeframeClock),
141
- this._initialTimeframe
160
+ createFeedSelector(this._partyProcessor, feedHints),
161
+ initialTimeframe
142
162
  );
143
163
 
144
- this._pipeline = new Pipeline(
145
- this._partyProcessor, iterator, this._timeframeClock, createFeedWriter(writableFeed.feed), this._options);
146
-
147
- // TODO(burdon): Support read-only parties.
148
- const [readStream, writeStream] = await this._pipeline.open();
164
+ this._pipeline = new FeedMuxer(
165
+ this._partyProcessor,
149
166
 
150
- // Must happen after open.
151
- if (this._pipeline.outboundHaloStream) {
152
- this._partyProcessor.setOutboundStream(this._pipeline.outboundHaloStream);
153
- }
167
+ iterator,
168
+ this._timeframeClock,
169
+ createFeedWriter(writableFeed.feed),
170
+ this._options
171
+ );
154
172
 
155
173
  //
156
174
  // Database
157
175
  //
158
176
 
177
+ const databaseBackend = new FeedDatabaseBackend(this._pipeline.outboundEchoStream, this._databaseSnapshot, { snapshots: true });
159
178
  this._database = new Database(
160
179
  this._modelFactory,
161
- new FeedDatabaseBackend(readStream, writeStream, this._databaseSnapshot, { snapshots: true }),
180
+ databaseBackend,
162
181
  this._memberKey
163
182
  );
164
183
 
184
+ // Open pipeline and connect it to the database.
165
185
  await this._database.initialize();
186
+ this._pipeline.setEchoProcessor(databaseBackend.echoProcessor);
187
+ await this._pipeline.open();
166
188
 
167
189
  // TODO(burdon): Propagate errors.
168
190
  this._subscriptions.push(this._pipeline.errors.on(err => console.error(err)));
@@ -176,6 +198,10 @@ export class PartyCore {
176
198
  );
177
199
  }
178
200
 
201
+ if (targetTimeframe) {
202
+ await this._timeframeClock.waitUntilReached(targetTimeframe);
203
+ }
204
+
179
205
  return this;
180
206
  }
181
207
 
@@ -202,11 +228,6 @@ export class PartyCore {
202
228
  return this;
203
229
  }
204
230
 
205
- writeCredentialsMessage (message: HaloMessage): Promise<WriteReceipt> {
206
- assert(this._partyProcessor, 'Party not open');
207
- return this._partyProcessor?.writeHaloMessage(message);
208
- }
209
-
210
231
  /**
211
232
  * Create a snapshot of the current state.
212
233
  */
@@ -234,3 +255,5 @@ export class PartyCore {
234
255
  this._databaseSnapshot = snapshot.database;
235
256
  }
236
257
  }
258
+
259
+ const createFeedSelector = (partyProcessor: PartyProcessor, hints: PublicKey[]): FeedSelector => feed => hints.some(hint => hint.equals(feed.key)) || partyProcessor.isFeedAdmitted(feed.key);
@@ -16,15 +16,11 @@ import {
16
16
  SignedMessage
17
17
  } from '@dxos/credentials';
18
18
  import { PublicKey } from '@dxos/crypto';
19
- import { FeedKey, FeedWriter, IHaloStream, PartyKey, HaloStateSnapshot, WriteReceipt } from '@dxos/echo-protocol';
19
+ import { FeedKey, IHaloStream, PartyKey, HaloStateSnapshot } from '@dxos/echo-protocol';
20
20
  import { jsonReplacer } from '@dxos/util';
21
21
 
22
22
  const log = debug('dxos:echo-db:party-processor');
23
23
 
24
- export interface CredentialWriter {
25
- writeHaloMessage (message: HaloMessage): Promise<WriteReceipt>
26
- }
27
-
28
24
  export interface CredentialProcessor {
29
25
  processMessage (message: IHaloStream): Promise<void>
30
26
  }
@@ -47,11 +43,9 @@ export interface PartyStateProvider {
47
43
  /**
48
44
  * TODO(burdon): Wrapper/Bridge between HALO APIs.
49
45
  */
50
- export class PartyProcessor implements CredentialWriter, CredentialProcessor, PartyStateProvider {
46
+ export class PartyProcessor implements CredentialProcessor, PartyStateProvider {
51
47
  private readonly _state: PartyState;
52
48
 
53
- private _outboundHaloStream: FeedWriter<HaloMessage> | undefined;
54
-
55
49
  readonly feedAdded = new Event<FeedKey>()
56
50
 
57
51
  public readonly keyOrInfoAdded = new Event<PublicKey>();
@@ -148,16 +142,6 @@ export class PartyProcessor implements CredentialWriter, CredentialProcessor, Pa
148
142
  await this._state.processMessages([data]);
149
143
  }
150
144
 
151
- setOutboundStream (stream: FeedWriter<HaloMessage>) {
152
- this._outboundHaloStream = stream;
153
- }
154
-
155
- async writeHaloMessage (message: HaloMessage): Promise<WriteReceipt> {
156
- assert(this._outboundHaloStream, 'Party is closed or read-only');
157
- // TODO(marik-d): Wait for the message to be processed?
158
- return this._outboundHaloStream.write(message);
159
- }
160
-
161
145
  makeSnapshot (): HaloStateSnapshot {
162
146
  return {
163
147
  messages: this._haloMessages
@@ -6,7 +6,6 @@ import expect from 'expect';
6
6
  import { it as test } from 'mocha';
7
7
 
8
8
  import { createAuthMessage, createKeyAdmitMessage, createPartyGenesisMessage, Keyring, KeyType } from '@dxos/credentials';
9
- import { MockFeedWriter } from '@dxos/echo-protocol';
10
9
 
11
10
  import { PartyProcessor } from '../pipeline';
12
11
  import { createAuthenticator } from './authenticator';
@@ -23,8 +22,6 @@ describe('authenticator', () => {
23
22
  const signer = CredentialsSigner.createDirectDeviceSigner(keyring);
24
23
 
25
24
  const partyProcessor = new PartyProcessor(partyKey.publicKey);
26
- const feed = new MockFeedWriter();
27
- partyProcessor.setOutboundStream(feed);
28
25
  await partyProcessor.processMessage({
29
26
  data: createPartyGenesisMessage(
30
27
  keyring,
@@ -53,7 +50,7 @@ describe('authenticator', () => {
53
50
  meta: {} as any
54
51
  });
55
52
 
56
- const authenticator = createAuthenticator(partyProcessor, signer);
53
+ const authenticator = createAuthenticator(partyProcessor, signer, null as any);
57
54
  const credential = createAuthMessage(
58
55
  keyring,
59
56
  partyKey.publicKey,