@dxos/echo 0.8.4-main.40e3dcdf1b → 0.8.4-main.43cb759274

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 (428) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +7 -7
  3. package/dist/lib/neutral/Annotation.mjs +29 -6
  4. package/dist/lib/neutral/Database.mjs +8 -9
  5. package/dist/lib/neutral/Entity.mjs +29 -18
  6. package/dist/lib/neutral/Err.mjs +3 -3
  7. package/dist/lib/neutral/Feed.mjs +27 -19
  8. package/dist/lib/neutral/Filter.mjs +25 -15
  9. package/dist/lib/neutral/Format.mjs +23 -3
  10. package/dist/lib/neutral/JsonSchema.mjs +7 -8
  11. package/dist/lib/neutral/Key.mjs +9 -5
  12. package/dist/lib/neutral/Migration.mjs +18 -0
  13. package/dist/lib/neutral/Obj.mjs +25 -19
  14. package/dist/lib/neutral/Order.mjs +1 -1
  15. package/dist/lib/neutral/Query.mjs +19 -16
  16. package/dist/lib/neutral/QueryResult.mjs +1 -1
  17. package/dist/lib/neutral/Ref.mjs +10 -9
  18. package/dist/lib/neutral/Registry.mjs +14 -0
  19. package/dist/lib/neutral/Registry.mjs.map +7 -0
  20. package/dist/lib/neutral/Relation.mjs +26 -24
  21. package/dist/lib/neutral/Scope.mjs +12 -0
  22. package/dist/lib/neutral/Scope.mjs.map +7 -0
  23. package/dist/lib/neutral/Tag.mjs +17 -13
  24. package/dist/lib/neutral/Type.mjs +52 -26
  25. package/dist/lib/neutral/chunk-3DKP2EIN.mjs +31 -0
  26. package/dist/lib/neutral/chunk-3DKP2EIN.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-4BB4MFCN.mjs +154 -0
  28. package/dist/lib/neutral/chunk-4BB4MFCN.mjs.map +7 -0
  29. package/dist/lib/neutral/{chunk-CIRHIEMW.mjs → chunk-4SFPZJVA.mjs} +92 -112
  30. package/dist/lib/neutral/chunk-4SFPZJVA.mjs.map +7 -0
  31. package/dist/lib/neutral/{chunk-YWXWXIE5.mjs → chunk-4Z6GET2X.mjs} +3 -3
  32. package/dist/lib/neutral/chunk-4Z6GET2X.mjs.map +7 -0
  33. package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7LOUAPYZ.mjs} +9 -5
  34. package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +7 -0
  35. package/dist/lib/neutral/{chunk-43Y5DOS6.mjs → chunk-7OAFN3OX.mjs} +75 -112
  36. package/dist/lib/neutral/chunk-7OAFN3OX.mjs.map +7 -0
  37. package/dist/lib/neutral/{chunk-BOZZPUXE.mjs → chunk-7PRCIDHH.mjs} +41 -81
  38. package/dist/lib/neutral/chunk-7PRCIDHH.mjs.map +7 -0
  39. package/dist/lib/neutral/{chunk-UBEZSGXY.mjs → chunk-BBFJWWAV.mjs} +6 -6
  40. package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +7 -0
  41. package/dist/lib/neutral/chunk-BDQGMDIX.mjs +132 -0
  42. package/dist/lib/neutral/chunk-BDQGMDIX.mjs.map +7 -0
  43. package/dist/lib/neutral/chunk-CGTI5MXO.mjs +36 -0
  44. package/dist/lib/neutral/chunk-CGTI5MXO.mjs.map +7 -0
  45. package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-DKLUHO4T.mjs} +1 -1
  46. package/dist/lib/neutral/chunk-DKLUHO4T.mjs.map +7 -0
  47. package/dist/lib/neutral/chunk-DMN2CKPX.mjs +93 -0
  48. package/dist/lib/neutral/chunk-DMN2CKPX.mjs.map +7 -0
  49. package/dist/lib/neutral/{chunk-UTBRYVQC.mjs → chunk-G6CFWUYH.mjs} +2 -2
  50. package/dist/lib/neutral/chunk-H26LSXVJ.mjs +653 -0
  51. package/dist/lib/neutral/chunk-H26LSXVJ.mjs.map +7 -0
  52. package/dist/lib/neutral/{chunk-FXEG7EOK.mjs → chunk-J3MNM65T.mjs} +9 -6
  53. package/dist/lib/neutral/chunk-J3MNM65T.mjs.map +7 -0
  54. package/dist/lib/neutral/chunk-JE7AOSWF.mjs +247 -0
  55. package/dist/lib/neutral/chunk-JE7AOSWF.mjs.map +7 -0
  56. package/dist/lib/neutral/chunk-LAF3LSWI.mjs +379 -0
  57. package/dist/lib/neutral/chunk-LAF3LSWI.mjs.map +7 -0
  58. package/dist/lib/neutral/chunk-LMNRFOVB.mjs +108 -0
  59. package/dist/lib/neutral/chunk-LMNRFOVB.mjs.map +7 -0
  60. package/dist/lib/neutral/{chunk-WYOKA6AE.mjs → chunk-O6BH7EPN.mjs} +31 -4
  61. package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +7 -0
  62. package/dist/lib/neutral/{chunk-KTAWP7GI.mjs → chunk-OIYW7R2G.mjs} +99 -46
  63. package/dist/lib/neutral/chunk-OIYW7R2G.mjs.map +7 -0
  64. package/dist/lib/neutral/{chunk-TQQZLKB7.mjs → chunk-OYUG4FHF.mjs} +648 -1228
  65. package/dist/lib/neutral/chunk-OYUG4FHF.mjs.map +7 -0
  66. package/dist/lib/neutral/{chunk-NQRLRYJM.mjs → chunk-Q5FKCVBC.mjs} +173 -60
  67. package/dist/lib/neutral/chunk-Q5FKCVBC.mjs.map +7 -0
  68. package/dist/lib/neutral/chunk-Q62IHV2N.mjs +41 -0
  69. package/dist/lib/neutral/chunk-Q62IHV2N.mjs.map +7 -0
  70. package/dist/lib/neutral/{chunk-UFDK26FO.mjs → chunk-QVJDDG44.mjs} +69 -34
  71. package/dist/lib/neutral/chunk-QVJDDG44.mjs.map +7 -0
  72. package/dist/lib/neutral/{chunk-B5OXLWZL.mjs → chunk-TFEWTY5A.mjs} +155 -129
  73. package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +7 -0
  74. package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-TTCSATUD.mjs} +1 -1
  75. package/dist/lib/neutral/{chunk-FZO7LQO7.mjs → chunk-VKWOFXT2.mjs} +22 -2
  76. package/dist/lib/neutral/{chunk-FZO7LQO7.mjs.map → chunk-VKWOFXT2.mjs.map} +1 -1
  77. package/dist/lib/neutral/{chunk-NXMFBIT5.mjs → chunk-ZACMEAYV.mjs} +89 -23
  78. package/dist/lib/neutral/chunk-ZACMEAYV.mjs.map +7 -0
  79. package/dist/lib/neutral/index.mjs +58 -38
  80. package/dist/lib/neutral/internal/index.mjs +131 -64
  81. package/dist/lib/neutral/meta.json +1 -1
  82. package/dist/lib/neutral/testing/index.mjs +222 -177
  83. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  84. package/dist/types/src/Annotation.d.ts +108 -4
  85. package/dist/types/src/Annotation.d.ts.map +1 -1
  86. package/dist/types/src/Annotation.test.d.ts +2 -0
  87. package/dist/types/src/Annotation.test.d.ts.map +1 -0
  88. package/dist/types/src/Collection.d.ts +2 -3
  89. package/dist/types/src/Collection.d.ts.map +1 -1
  90. package/dist/types/src/Database.d.ts +56 -24
  91. package/dist/types/src/Database.d.ts.map +1 -1
  92. package/dist/types/src/Dataset.d.ts +17 -6
  93. package/dist/types/src/Dataset.d.ts.map +1 -1
  94. package/dist/types/src/Entity.d.ts +102 -26
  95. package/dist/types/src/Entity.d.ts.map +1 -1
  96. package/dist/types/src/Err.d.ts +27 -27
  97. package/dist/types/src/Err.d.ts.map +1 -1
  98. package/dist/types/src/Feed.d.ts +89 -25
  99. package/dist/types/src/Feed.d.ts.map +1 -1
  100. package/dist/types/src/Filter.d.ts +74 -11
  101. package/dist/types/src/Filter.d.ts.map +1 -1
  102. package/dist/types/src/Filter.test.d.ts +2 -0
  103. package/dist/types/src/Filter.test.d.ts.map +1 -0
  104. package/dist/types/src/Hypergraph.d.ts +14 -9
  105. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  106. package/dist/types/src/Json.d.ts +33 -0
  107. package/dist/types/src/Json.d.ts.map +1 -0
  108. package/dist/types/src/Json.test.d.ts +2 -0
  109. package/dist/types/src/Json.test.d.ts.map +1 -0
  110. package/dist/types/src/JsonSchema.d.ts +2 -2
  111. package/dist/types/src/JsonSchema.d.ts.map +1 -1
  112. package/dist/types/src/Key.d.ts +1 -1
  113. package/dist/types/src/Key.d.ts.map +1 -1
  114. package/dist/types/src/Migration.d.ts +72 -0
  115. package/dist/types/src/Migration.d.ts.map +1 -0
  116. package/dist/types/src/Obj.d.ts +108 -65
  117. package/dist/types/src/Obj.d.ts.map +1 -1
  118. package/dist/types/src/Order.d.ts.map +1 -1
  119. package/dist/types/src/Query.d.ts +35 -10
  120. package/dist/types/src/Query.d.ts.map +1 -1
  121. package/dist/types/src/QueryResult.d.ts +9 -0
  122. package/dist/types/src/QueryResult.d.ts.map +1 -1
  123. package/dist/types/src/Ref.d.ts +15 -7
  124. package/dist/types/src/Ref.d.ts.map +1 -1
  125. package/dist/types/src/Registry.d.ts +131 -0
  126. package/dist/types/src/Registry.d.ts.map +1 -0
  127. package/dist/types/src/Relation.d.ts +72 -44
  128. package/dist/types/src/Relation.d.ts.map +1 -1
  129. package/dist/types/src/Scope.d.ts +34 -0
  130. package/dist/types/src/Scope.d.ts.map +1 -0
  131. package/dist/types/src/StateMap.d.ts +32 -0
  132. package/dist/types/src/StateMap.d.ts.map +1 -0
  133. package/dist/types/src/StateMap.test.d.ts +2 -0
  134. package/dist/types/src/StateMap.test.d.ts.map +1 -0
  135. package/dist/types/src/Tag.d.ts +21 -5
  136. package/dist/types/src/Tag.d.ts.map +1 -1
  137. package/dist/types/src/TagIndex.d.ts +36 -0
  138. package/dist/types/src/TagIndex.d.ts.map +1 -0
  139. package/dist/types/src/TagIndex.test.d.ts +2 -0
  140. package/dist/types/src/TagIndex.test.d.ts.map +1 -0
  141. package/dist/types/src/Tagging.d.ts +31 -0
  142. package/dist/types/src/Tagging.d.ts.map +1 -0
  143. package/dist/types/src/Type.d.ts +357 -96
  144. package/dist/types/src/Type.d.ts.map +1 -1
  145. package/dist/types/src/View.d.ts +2 -5
  146. package/dist/types/src/View.d.ts.map +1 -1
  147. package/dist/types/src/exemplars.test.d.ts +2 -0
  148. package/dist/types/src/exemplars.test.d.ts.map +1 -0
  149. package/dist/types/src/index.d.ts +8 -2
  150. package/dist/types/src/index.d.ts.map +1 -1
  151. package/dist/types/src/internal/Annotation/annotations.d.ts +79 -37
  152. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
  153. package/dist/types/src/internal/Annotation/dictionary.d.ts +24 -0
  154. package/dist/types/src/internal/Annotation/dictionary.d.ts.map +1 -0
  155. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +14 -0
  156. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -0
  157. package/dist/types/src/internal/Annotation/index.d.ts +4 -2
  158. package/dist/types/src/internal/Annotation/index.d.ts.map +1 -1
  159. package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -1
  160. package/dist/types/src/internal/Annotation/util.d.ts +14 -5
  161. package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
  162. package/dist/types/src/internal/Entity/api.d.ts +3 -3
  163. package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
  164. package/dist/types/src/internal/Entity/entity.d.ts +72 -8
  165. package/dist/types/src/internal/Entity/entity.d.ts.map +1 -1
  166. package/dist/types/src/internal/Entity/guard.d.ts +10 -0
  167. package/dist/types/src/internal/Entity/guard.d.ts.map +1 -0
  168. package/dist/types/src/internal/Entity/index.d.ts +2 -0
  169. package/dist/types/src/internal/Entity/index.d.ts.map +1 -1
  170. package/dist/types/src/internal/Entity/model.d.ts +20 -17
  171. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  172. package/dist/types/src/internal/Entity/object.d.ts +3 -3
  173. package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
  174. package/dist/types/src/internal/Entity/relation.d.ts +30 -7
  175. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
  176. package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
  177. package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
  178. package/dist/types/src/internal/Entity/type-uri.d.ts +25 -0
  179. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
  180. package/dist/types/src/internal/Entity/version.d.ts.map +1 -1
  181. package/dist/types/src/internal/Format/date.d.ts.map +1 -1
  182. package/dist/types/src/internal/Format/format.d.ts +3 -2
  183. package/dist/types/src/internal/Format/format.d.ts.map +1 -1
  184. package/dist/types/src/internal/Format/index.d.ts +2 -2
  185. package/dist/types/src/internal/Format/index.d.ts.map +1 -1
  186. package/dist/types/src/internal/Format/number.d.ts.map +1 -1
  187. package/dist/types/src/internal/Format/object.d.ts +3 -1
  188. package/dist/types/src/internal/Format/object.d.ts.map +1 -1
  189. package/dist/types/src/internal/Format/types.d.ts.map +1 -1
  190. package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -1
  191. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts +28 -28
  192. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
  193. package/dist/types/src/internal/JsonSchema/json-schema.d.ts +3 -2
  194. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
  195. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
  196. package/dist/types/src/internal/Obj/common.d.ts.map +1 -1
  197. package/dist/types/src/internal/Obj/create-object.d.ts +11 -12
  198. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
  199. package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -1
  200. package/dist/types/src/internal/Obj/index.d.ts +0 -1
  201. package/dist/types/src/internal/Obj/index.d.ts.map +1 -1
  202. package/dist/types/src/internal/Obj/json-serializer.d.ts +11 -10
  203. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
  204. package/dist/types/src/internal/Obj/set-value.d.ts +1 -1
  205. package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -1
  206. package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -1
  207. package/dist/types/src/internal/Obj/typed-object.d.ts +1 -1
  208. package/dist/types/src/internal/Query.d.ts +10 -0
  209. package/dist/types/src/internal/Query.d.ts.map +1 -0
  210. package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
  211. package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -1
  212. package/dist/types/src/internal/Ref/ref.d.ts +42 -19
  213. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
  214. package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
  215. package/dist/types/src/internal/Type/index.d.ts +1 -2
  216. package/dist/types/src/internal/Type/index.d.ts.map +1 -1
  217. package/dist/types/src/internal/Type/manipulation.d.ts +0 -1
  218. package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
  219. package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
  220. package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
  221. package/dist/types/src/internal/common/api/meta.d.ts +14 -11
  222. package/dist/types/src/internal/common/api/meta.d.ts.map +1 -1
  223. package/dist/types/src/internal/common/proxy/change-context.d.ts +1 -1
  224. package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -1
  225. package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -1
  226. package/dist/types/src/internal/common/proxy/errors.d.ts +1 -1
  227. package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -1
  228. package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -1
  229. package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -1
  230. package/dist/types/src/internal/common/proxy/make-object.d.ts +11 -5
  231. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
  232. package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -1
  233. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
  234. package/dist/types/src/internal/common/proxy/reactive-array.d.ts +1 -1
  235. package/dist/types/src/internal/common/proxy/reactive.d.ts +1 -1
  236. package/dist/types/src/internal/common/proxy/reactive.d.ts.map +1 -1
  237. package/dist/types/src/internal/common/proxy/reactive.test.d.ts +2 -0
  238. package/dist/types/src/internal/common/proxy/reactive.test.d.ts.map +1 -0
  239. package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
  240. package/dist/types/src/internal/common/proxy/typed-handler.d.ts +18 -2
  241. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
  242. package/dist/types/src/internal/common/types/base.d.ts +4 -4
  243. package/dist/types/src/internal/common/types/base.d.ts.map +1 -1
  244. package/dist/types/src/internal/common/types/entity.d.ts +63 -6
  245. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
  246. package/dist/types/src/internal/common/types/index.d.ts +1 -1
  247. package/dist/types/src/internal/common/types/index.d.ts.map +1 -1
  248. package/dist/types/src/internal/common/types/meta.d.ts +23 -7
  249. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
  250. package/dist/types/src/internal/common/types/model-symbols.d.ts +8 -4
  251. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -1
  252. package/dist/types/src/internal/common/types/typename.d.ts +7 -0
  253. package/dist/types/src/internal/common/types/typename.d.ts.map +1 -1
  254. package/dist/types/src/internal/common/types/version.d.ts +1 -1
  255. package/dist/types/src/internal/common/types/well-known-types.d.ts +11 -0
  256. package/dist/types/src/internal/common/types/well-known-types.d.ts.map +1 -0
  257. package/dist/types/src/internal/index.d.ts +2 -0
  258. package/dist/types/src/internal/index.d.ts.map +1 -1
  259. package/dist/types/src/testing/test-data.d.ts +8 -8
  260. package/dist/types/src/testing/test-data.d.ts.map +1 -1
  261. package/dist/types/src/testing/test-schema.d.ts +83 -89
  262. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  263. package/dist/types/src/testing/util.d.ts +5 -3
  264. package/dist/types/src/testing/util.d.ts.map +1 -1
  265. package/dist/types/tsconfig.tsbuildinfo +1 -1
  266. package/package.json +27 -19
  267. package/src/Annotation.test.ts +439 -0
  268. package/src/Annotation.ts +152 -4
  269. package/src/Collection.ts +6 -5
  270. package/src/Database.ts +117 -57
  271. package/src/Dataset.ts +10 -2
  272. package/src/Entity.test.ts +116 -6
  273. package/src/Entity.ts +130 -31
  274. package/src/Err.ts +4 -4
  275. package/src/Feed.ts +138 -43
  276. package/src/Filter.test.ts +90 -0
  277. package/src/Filter.ts +143 -27
  278. package/src/Hypergraph.ts +14 -9
  279. package/src/Json.test.ts +175 -0
  280. package/src/Json.ts +103 -0
  281. package/src/Key.ts +1 -1
  282. package/src/Migration.ts +114 -0
  283. package/src/Obj.test.ts +122 -19
  284. package/src/Obj.ts +279 -97
  285. package/src/Query.test.ts +317 -131
  286. package/src/Query.ts +181 -73
  287. package/src/QueryResult.ts +11 -0
  288. package/src/Ref.ts +22 -4
  289. package/src/Registry.ts +155 -0
  290. package/src/Relation.test.ts +10 -10
  291. package/src/Relation.ts +112 -71
  292. package/src/Scope.ts +50 -0
  293. package/src/StateMap.test.ts +56 -0
  294. package/src/StateMap.ts +99 -0
  295. package/src/Tag.md +88 -0
  296. package/src/Tag.ts +49 -6
  297. package/src/TagIndex.test.ts +57 -0
  298. package/src/TagIndex.ts +110 -0
  299. package/src/Tagging.ts +83 -0
  300. package/src/Type.test.ts +223 -18
  301. package/src/Type.ts +602 -132
  302. package/src/View.ts +11 -15
  303. package/src/exemplars.test.ts +21 -0
  304. package/src/index.ts +9 -3
  305. package/src/internal/Annotation/annotations.test.ts +82 -13
  306. package/src/internal/Annotation/annotations.ts +153 -115
  307. package/src/internal/Annotation/dictionary.ts +47 -0
  308. package/src/internal/Annotation/entity-dictionary.ts +40 -0
  309. package/src/internal/Annotation/index.ts +4 -2
  310. package/src/internal/Annotation/sorting.ts +0 -1
  311. package/src/internal/Annotation/util.ts +17 -8
  312. package/src/internal/Entity/api.ts +7 -8
  313. package/src/internal/Entity/entity.ts +196 -47
  314. package/src/internal/Entity/guard.ts +26 -0
  315. package/src/internal/Entity/index.ts +2 -0
  316. package/src/internal/Entity/model.ts +37 -28
  317. package/src/internal/Entity/object.ts +21 -6
  318. package/src/internal/Entity/relation.ts +68 -34
  319. package/src/internal/Entity/type-kind.ts +75 -0
  320. package/src/internal/Entity/type-uri.ts +87 -0
  321. package/src/internal/Entity/util.ts +10 -9
  322. package/src/internal/Entity/version.ts +0 -1
  323. package/src/internal/Format/date.test.ts +0 -1
  324. package/src/internal/Format/date.ts +0 -4
  325. package/src/internal/Format/format.test.ts +21 -1
  326. package/src/internal/Format/index.ts +2 -3
  327. package/src/internal/Format/object.ts +21 -4
  328. package/src/internal/Format/types.ts +1 -1
  329. package/src/internal/JsonSchema/annotations.ts +1 -1
  330. package/src/internal/JsonSchema/json-schema-type.ts +1 -1
  331. package/src/internal/JsonSchema/json-schema.test.ts +55 -142
  332. package/src/internal/JsonSchema/json-schema.ts +44 -31
  333. package/src/internal/Obj/clone.ts +9 -4
  334. package/src/internal/Obj/create-object.test.ts +13 -13
  335. package/src/internal/Obj/create-object.ts +68 -24
  336. package/src/internal/Obj/deleted.ts +1 -1
  337. package/src/internal/Obj/index.ts +0 -1
  338. package/src/internal/Obj/inspect.ts +4 -3
  339. package/src/internal/Obj/json-serializer.test.ts +102 -24
  340. package/src/internal/Obj/json-serializer.ts +105 -43
  341. package/src/internal/Obj/set-value.test.ts +31 -54
  342. package/src/internal/Obj/set-value.ts +1 -1
  343. package/src/internal/Obj/snapshot.ts +11 -4
  344. package/src/internal/Obj/typed-object.test.ts +9 -11
  345. package/src/internal/Obj/typed-object.ts +1 -1
  346. package/src/internal/Query.ts +159 -0
  347. package/src/internal/Ref/ref-array.ts +3 -4
  348. package/src/internal/Ref/ref.test.ts +17 -27
  349. package/src/internal/Ref/ref.ts +124 -59
  350. package/src/internal/Type/compose.test.ts +3 -2
  351. package/src/internal/Type/index.ts +1 -2
  352. package/src/internal/Type/manipulation.ts +0 -25
  353. package/src/internal/Type/type-schema.ts +60 -0
  354. package/src/internal/common/README.md +2 -2
  355. package/src/internal/common/api/meta.ts +19 -17
  356. package/src/internal/common/proxy/change-context.ts +1 -1
  357. package/src/internal/common/proxy/change.test.ts +118 -110
  358. package/src/internal/common/proxy/errors.ts +2 -2
  359. package/src/internal/common/proxy/handler.test.ts +1 -3
  360. package/src/internal/common/proxy/json-serializer.ts +26 -16
  361. package/src/internal/common/proxy/make-object.ts +43 -21
  362. package/src/internal/common/proxy/ownership.ts +2 -3
  363. package/src/internal/common/proxy/reactive-array.ts +1 -1
  364. package/src/internal/common/proxy/reactive.test.ts +54 -0
  365. package/src/internal/common/proxy/reactive.ts +11 -3
  366. package/src/internal/common/proxy/schema.test.ts +48 -86
  367. package/src/internal/common/proxy/typed-handler.test.ts +12 -12
  368. package/src/internal/common/proxy/typed-handler.ts +79 -19
  369. package/src/internal/common/proxy/typed-object.test.ts +16 -29
  370. package/src/internal/common/types/base.ts +4 -4
  371. package/src/internal/common/types/entity.ts +81 -2
  372. package/src/internal/common/types/index.ts +6 -1
  373. package/src/internal/common/types/meta.ts +49 -15
  374. package/src/internal/common/types/model-symbols.ts +16 -4
  375. package/src/internal/common/types/typename.ts +39 -3
  376. package/src/internal/common/types/well-known-types.ts +15 -0
  377. package/src/internal/index.ts +6 -0
  378. package/src/testing/api.test.ts +15 -10
  379. package/src/testing/test-data.ts +159 -100
  380. package/src/testing/test-schema.ts +22 -58
  381. package/src/testing/util.ts +14 -11
  382. package/dist/lib/neutral/SchemaRegistry.mjs +0 -2
  383. package/dist/lib/neutral/chunk-43Y5DOS6.mjs.map +0 -7
  384. package/dist/lib/neutral/chunk-724GQYEN.mjs +0 -56
  385. package/dist/lib/neutral/chunk-724GQYEN.mjs.map +0 -7
  386. package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
  387. package/dist/lib/neutral/chunk-B5OXLWZL.mjs.map +0 -7
  388. package/dist/lib/neutral/chunk-BNCCGLJN.mjs +0 -7
  389. package/dist/lib/neutral/chunk-BNCCGLJN.mjs.map +0 -7
  390. package/dist/lib/neutral/chunk-BOZZPUXE.mjs.map +0 -7
  391. package/dist/lib/neutral/chunk-CIRHIEMW.mjs.map +0 -7
  392. package/dist/lib/neutral/chunk-DYDJBZEG.mjs +0 -102
  393. package/dist/lib/neutral/chunk-DYDJBZEG.mjs.map +0 -7
  394. package/dist/lib/neutral/chunk-FXEG7EOK.mjs.map +0 -7
  395. package/dist/lib/neutral/chunk-KTAWP7GI.mjs.map +0 -7
  396. package/dist/lib/neutral/chunk-NEGC54NE.mjs +0 -130
  397. package/dist/lib/neutral/chunk-NEGC54NE.mjs.map +0 -7
  398. package/dist/lib/neutral/chunk-NQRLRYJM.mjs.map +0 -7
  399. package/dist/lib/neutral/chunk-NXMFBIT5.mjs.map +0 -7
  400. package/dist/lib/neutral/chunk-OENWMTE6.mjs +0 -45
  401. package/dist/lib/neutral/chunk-OENWMTE6.mjs.map +0 -7
  402. package/dist/lib/neutral/chunk-OMUPQMLR.mjs.map +0 -7
  403. package/dist/lib/neutral/chunk-RMLF7JOZ.mjs +0 -97
  404. package/dist/lib/neutral/chunk-RMLF7JOZ.mjs.map +0 -7
  405. package/dist/lib/neutral/chunk-SEMVAGBM.mjs +0 -355
  406. package/dist/lib/neutral/chunk-SEMVAGBM.mjs.map +0 -7
  407. package/dist/lib/neutral/chunk-TQQZLKB7.mjs.map +0 -7
  408. package/dist/lib/neutral/chunk-UBEZSGXY.mjs.map +0 -7
  409. package/dist/lib/neutral/chunk-UFDK26FO.mjs.map +0 -7
  410. package/dist/lib/neutral/chunk-VA2F47ZC.mjs +0 -152
  411. package/dist/lib/neutral/chunk-VA2F47ZC.mjs.map +0 -7
  412. package/dist/lib/neutral/chunk-WYOKA6AE.mjs.map +0 -7
  413. package/dist/lib/neutral/chunk-YWXWXIE5.mjs.map +0 -7
  414. package/dist/types/src/SchemaRegistry.d.ts +0 -84
  415. package/dist/types/src/SchemaRegistry.d.ts.map +0 -1
  416. package/dist/types/src/internal/Obj/ids.d.ts +0 -6
  417. package/dist/types/src/internal/Obj/ids.d.ts.map +0 -1
  418. package/dist/types/src/internal/Type/echo-schema.d.ts +0 -181
  419. package/dist/types/src/internal/Type/echo-schema.d.ts.map +0 -1
  420. package/dist/types/src/internal/Type/persistent-schema.d.ts +0 -20
  421. package/dist/types/src/internal/Type/persistent-schema.d.ts.map +0 -1
  422. package/src/SchemaRegistry.ts +0 -106
  423. package/src/internal/Obj/ids.ts +0 -12
  424. package/src/internal/Type/echo-schema.ts +0 -424
  425. package/src/internal/Type/persistent-schema.ts +0 -33
  426. /package/dist/lib/neutral/{SchemaRegistry.mjs.map → Migration.mjs.map} +0 -0
  427. /package/dist/lib/neutral/{chunk-UTBRYVQC.mjs.map → chunk-G6CFWUYH.mjs.map} +0 -0
  428. /package/dist/lib/neutral/{chunk-UI6MWK5W.mjs.map → chunk-TTCSATUD.mjs.map} +0 -0
package/src/Entity.ts CHANGED
@@ -4,12 +4,16 @@
4
4
 
5
5
  // @import-as-namespace
6
6
 
7
+ import * as Schema from 'effect/Schema';
8
+
7
9
  import type { ForeignKey } from '@dxos/echo-protocol';
8
- import type { DXN, ObjectId } from '@dxos/keys';
10
+ import type { EntityId, URI } from '@dxos/keys';
9
11
 
10
- import * as entityInternal from './internal/Entity';
11
12
  import * as internal from './internal';
13
+ import type * as Ref from './Ref';
12
14
  import type * as Relation from './Relation';
15
+ import type * as Tag from './Tag';
16
+ import * as Type from './Type';
13
17
 
14
18
  // Re-export KindId and SnapshotKindId from internal.
15
19
  export const KindId = internal.KindId;
@@ -31,7 +35,7 @@ export const KindSchema = internal.EntityKindSchema;
31
35
  */
32
36
  export interface OfKind<K extends Kind> {
33
37
  readonly [KindId]: K;
34
- readonly id: ObjectId;
38
+ readonly id: EntityId;
35
39
  }
36
40
 
37
41
  /**
@@ -39,7 +43,7 @@ export interface OfKind<K extends Kind> {
39
43
  */
40
44
  export interface SnapshotOfKind<K extends Kind> {
41
45
  readonly [SnapshotKindId]: K;
42
- readonly id: ObjectId;
46
+ readonly id: EntityId;
43
47
  }
44
48
 
45
49
  /**
@@ -52,6 +56,27 @@ export type Entity<Props> = OfKind<Kind> & Props;
52
56
  */
53
57
  export interface Unknown extends OfKind<Kind> {}
54
58
 
59
+ /**
60
+ * Effect Schema for any ECHO entity (object or relation).
61
+ *
62
+ * Kind-agnostic counterpart to `Obj.Unknown` / `Relation.Unknown` — validates
63
+ * the structural shape (id + properties) without constraining `[KindId]`. Used
64
+ * in operation input schemas that accept any entity flavour (e.g.
65
+ * `Schema.Array(Entity.Unknown)`).
66
+ *
67
+ * The cast bridges the runtime structural schema to the branded `Unknown` type:
68
+ * `[KindId]` is a symbol brand that can't be expressed in a runtime `Struct`,
69
+ * so the entity guarantee is carried at the type level only (same approach as
70
+ * `Obj.Unknown` / `Relation.Unknown`). Unlike those, this is kind-agnostic so it
71
+ * isn't an `UnknownTypeSchema<_, K>` (there's no single `K`) and carries no
72
+ * `TypeAnnotation`.
73
+ */
74
+ export const Unknown: Schema.Schema<Unknown> = Schema.Struct({
75
+ id: Schema.String,
76
+ }).pipe(
77
+ Schema.extend(Schema.Record({ key: Schema.String, value: Schema.Unknown })),
78
+ ) as unknown as Schema.Schema<Unknown>;
79
+
55
80
  /**
56
81
  * Snapshot of an Obj or Relation.
57
82
  * Branded with SnapshotKindId instead of KindId.
@@ -80,12 +105,30 @@ export type Properties<T> = Omit<T, 'id' | KindId | Relation.Source | Relation.T
80
105
  * Check if a value is an ECHO entity (object or relation).
81
106
  * Returns `false` for snapshots.
82
107
  */
83
- export const isEntity = (value: unknown): value is Unknown => {
84
- if (typeof value !== 'object' || value === null) {
85
- return false;
108
+ export const isEntity: (value: unknown) => value is Unknown = internal.isEntity;
109
+
110
+ /**
111
+ * Test if a value is an instance of a given object or relation type.
112
+ *
113
+ * Kind-agnostic counterpart to `Obj.instanceOf` / `Relation.instanceOf` —
114
+ * use this when the caller's input type is `Type.AnyObj | Type.AnyRelation`.
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * // Caller doesn't know whether `type` is object- or relation-kind.
119
+ * const matches = <T extends Type.AnyObj | Type.AnyRelation>(type: T, value: unknown) =>
120
+ * Entity.instanceOf(type, value);
121
+ * ```
122
+ */
123
+ export const instanceOf: {
124
+ <S extends Type.AnyEntity>(schema: S): (value: unknown) => value is Type.InstanceType<S>;
125
+ <S extends Type.AnyEntity>(schema: S, value: unknown): value is Type.InstanceType<S>;
126
+ } = ((...args: [schema: Type.AnyEntity, value?: unknown]) => {
127
+ if (args.length === 1) {
128
+ return (entity: unknown) => internal.isInstanceOf(args[0], entity);
86
129
  }
87
- return (value as any)[KindId] !== undefined;
88
- };
130
+ return internal.isInstanceOf(args[0], args[1]);
131
+ }) as any;
89
132
 
90
133
  /**
91
134
  * Check if a value is an ECHO entity snapshot.
@@ -123,19 +166,58 @@ export type Meta = typeof Meta;
123
166
  export type JSON = internal.ObjectJSON;
124
167
 
125
168
  /**
126
- * Get the DXN of an entity (object or relation).
169
+ * Whether the entity is a type-kind entity (a `Type.Type` produced by
170
+ * `Type.makeObject` / `Type.makeRelation`, or a persisted schema). Type entities
171
+ * carry their identity (typename/version) on themselves rather than referencing a
172
+ * separate type, so the accessors below route them through the `Type.*` module.
173
+ */
174
+ const isTypeEntity = (entity: unknown): boolean => internal.getEntityKindBrand(entity) === internal.EntityKind.Type;
175
+
176
+ /**
177
+ * Any value the read accessors operate on: a reactive entity or a snapshot.
178
+ * Type entities (`Type.AnyEntity`) are also accepted — they're first-class
179
+ * entities, and `Unknown`'s kind-agnostic brand already subsumes them.
127
180
  */
128
- export const getDXN = (entity: Unknown | Snapshot): DXN => internal.getDXN(entity);
181
+ export type AnyInput = Unknown | Snapshot;
129
182
 
130
183
  /**
131
- * Get the DXN of an entity's type.
184
+ * Get the canonical URI of an entity (object, relation, or type). Returns `URI.URI` —
185
+ * an `EID` for object/relation instances and persisted types, or a typename
186
+ * `DXN` for static type entities; narrow with `EID.parse(uri)` or
187
+ * `DXN.tryMake(uri)` at the point of use.
132
188
  */
133
- export const getTypeDXN = internal.getTypeDXN;
189
+ export const getURI = (entity: AnyInput): URI.URI =>
190
+ isTypeEntity(entity) ? Type.getURI(entity as Type.AnyEntity) : internal.getUri(entity as Unknown);
134
191
 
135
192
  /**
136
- * Get the typename of an entity's type.
193
+ * Get the DXN of an entity's type. For object/relation instances this is the URI
194
+ * of the type they were created from; for a type entity it is the URI of the
195
+ * meta-type ({@link Type.Type}, `dxn:org.dxos.type.schema:0.1.0`).
137
196
  */
138
- export const getTypename = (entity: Unknown | Snapshot): string | undefined => internal.getTypename(entity);
197
+ export const getTypeURI = (entity: AnyInput): URI.URI | undefined =>
198
+ isTypeEntity(entity) ? Type.getURI(Type.Type) : internal.getTypeURI(entity as Unknown);
199
+
200
+ /**
201
+ * Get the type entity (`Type.AnyEntity`) the instance was created from.
202
+ *
203
+ * Returns `undefined` when the entity's type isn't registered in this runtime
204
+ * (e.g. a freshly deserialized snapshot whose type entity hasn't been wired
205
+ * up yet, or an entity loaded from storage before its schema is known). To
206
+ * get the Effect Schema from the returned entity, use `Type.getSchema(...)`.
207
+ *
208
+ * For a type entity, returns the meta-type {@link Type.Type} (a type entity's
209
+ * type is "Type").
210
+ */
211
+ export const getType = (entity: AnyInput): Type.AnyEntity | undefined =>
212
+ isTypeEntity(entity) ? Type.Type : (internal.getType(entity) as Type.AnyEntity | undefined);
213
+
214
+ /**
215
+ * Get the typename of an entity's type. For object/relation instances this is the
216
+ * typename of the type they were created from; for a type entity it is the type's
217
+ * own typename (e.g. `com.example.type.person`).
218
+ */
219
+ export const getTypename = (entity: AnyInput): string | undefined =>
220
+ isTypeEntity(entity) ? Type.getTypename(entity as Type.AnyEntity) : internal.getTypename(entity as Unknown);
139
221
 
140
222
  /**
141
223
  * Get the database an entity belongs to.
@@ -148,9 +230,9 @@ export const getDatabase = (entity: Unknown | Snapshot): any | undefined => inte
148
230
  * Returns read-only meta when passed a regular entity or snapshot.
149
231
  */
150
232
  // TODO(wittjosiah): When passed a Snapshot, should return a snapshot of meta, not the live meta proxy.
151
- export function getMeta(entity: Mutable<Unknown>): internal.ObjectMeta;
233
+ export function getMeta(entity: Mutable<Unknown>): internal.EntityMeta;
152
234
  export function getMeta(entity: Unknown | Snapshot): internal.ReadonlyMeta;
153
- export function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): internal.ObjectMeta | internal.ReadonlyMeta {
235
+ export function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): internal.EntityMeta | internal.ReadonlyMeta {
154
236
  return internal.getMetaChecked(entity);
155
237
  }
156
238
 
@@ -166,14 +248,31 @@ export const isDeleted = (entity: Unknown | Snapshot): boolean => internal.isDel
166
248
 
167
249
  /**
168
250
  * Get the label of an entity.
251
+ *
252
+ * @param options.fallback `'typename'` returns the entity's typename when no
253
+ * label is set (e.g. `org.dxos.type.table`).
254
+ */
255
+ export const getLabel = (entity: Unknown | Snapshot, options?: internal.GetLabelOptions): string | undefined =>
256
+ internal.getLabel(entity, options);
257
+
258
+ /**
259
+ * Set the label of an entity.
260
+ * Must be called within an `Entity.update` / `Obj.update` / `Relation.update` callback.
169
261
  */
170
- export const getLabel = (entity: Unknown | Snapshot): string | undefined => internal.getLabel(entity);
262
+ export const setLabel = (entity: Mutable<Unknown>, label: string): void => internal.setLabel(entity, label);
171
263
 
172
264
  /**
173
265
  * Get the description of an entity.
174
266
  */
175
267
  export const getDescription = (entity: Unknown | Snapshot): string | undefined => internal.getDescription(entity);
176
268
 
269
+ /**
270
+ * Get the icon annotation for an entity (object or relation), resolved via its type-level
271
+ * `IconAnnotation`. Returns the full `{ icon, hue }` annotation so callers can use both
272
+ * the phosphor icon name and the suggested colour.
273
+ */
274
+ export const getIcon = (entity: Unknown | Snapshot): internal.IconAnnotation | undefined => internal.getIcon(entity);
275
+
177
276
  /**
178
277
  * Convert an entity to its JSON representation.
179
278
  */
@@ -192,7 +291,7 @@ export const subscribe = (entity: Unknown, callback: () => void): (() => void) =
192
291
  //
193
292
 
194
293
  /**
195
- * Used to provide a mutable view of an entity within `Entity.change`.
294
+ * Used to provide a mutable view of an entity within `Entity.update`.
196
295
  */
197
296
  export type Mutable<T> = internal.Mutable<T>;
198
297
 
@@ -200,7 +299,7 @@ export type Mutable<T> = internal.Mutable<T>;
200
299
  * Perform mutations on an entity (object or relation) within a change context.
201
300
  *
202
301
  * Entities are read-only by default. Mutations are batched and notifications fire
203
- * when the callback completes. Direct mutations outside of `Entity.change` will throw
302
+ * when the callback completes. Direct mutations outside of `Entity.update` will throw
204
303
  * at runtime.
205
304
  *
206
305
  * @param entity - The echo entity (object or relation) to mutate.
@@ -208,30 +307,30 @@ export type Mutable<T> = internal.Mutable<T>;
208
307
  *
209
308
  * @example
210
309
  * ```typescript
211
- * // Mutate within Entity.change
212
- * Entity.change(entity, (e) => {
213
- * e.name = 'Updated';
214
- * e.count = 42;
310
+ * // Mutate within Entity.update
311
+ * Entity.update(entity, (obj) => {
312
+ * obj.name = 'Updated';
313
+ * obj.count = 42;
215
314
  * });
216
315
  *
217
316
  * // Direct mutation throws
218
- * entity.name = 'Bob'; // Error: Cannot modify outside Entity.change()
317
+ * entity.name = 'Bob'; // Error: Cannot modify outside Entity.update()
219
318
  * ```
220
319
  *
221
- * Note: For type-specific operations, prefer `Obj.change` or `Relation.change`.
320
+ * Note: For type-specific operations, prefer `Obj.update` or `Relation.update`.
222
321
  */
223
- export const change = <T extends Unknown>(entity: T, callback: internal.ChangeCallback<T>): void => {
322
+ export const update = <T extends Unknown>(entity: T, callback: internal.ChangeCallback<T>): void => {
224
323
  internal.change(entity, callback);
225
324
  };
226
325
 
227
326
  /**
228
327
  * Add a tag to an entity.
229
- * Must be called within an `Entity.change`, `Obj.change`, or `Relation.change` callback.
328
+ * Must be called within an `Entity.update`, `Obj.update`, or `Relation.update` callback.
230
329
  */
231
- export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.addTag(entity, tag);
330
+ export const addTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.addTag(entity, tag);
232
331
 
233
332
  /**
234
333
  * Remove a tag from an entity.
235
- * Must be called within an `Entity.change`, `Obj.change`, or `Relation.change` callback.
334
+ * Must be called within an `Entity.update`, `Obj.update`, or `Relation.update` callback.
236
335
  */
237
- export const removeTag = (entity: Mutable<Unknown>, tag: string): void => internal.removeTag(entity, tag);
336
+ export const removeTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.removeTag(entity, tag);
package/src/Err.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  // @import-as-namespace
6
6
 
7
7
  import { BaseError, type BaseErrorOptions } from '@dxos/errors';
8
- import { type DXN } from '@dxos/keys';
8
+ import { type URI } from '@dxos/keys';
9
9
 
10
10
  export class SchemaNotFoundError extends BaseError.extend('SchemaNotFoundError', 'Schema not found') {
11
11
  constructor(schema: string, options?: BaseErrorOptions) {
@@ -13,9 +13,9 @@ export class SchemaNotFoundError extends BaseError.extend('SchemaNotFoundError',
13
13
  }
14
14
  }
15
15
 
16
- export class ObjectNotFoundError extends BaseError.extend('ObjectNotFoundError', 'Object not found') {
17
- constructor(dxn: DXN, options?: BaseErrorOptions) {
18
- super({ context: { dxn }, ...options });
16
+ export class EntityNotFoundError extends BaseError.extend('EntityNotFoundError', 'Entity not found') {
17
+ constructor(uri: URI.URI, options?: BaseErrorOptions) {
18
+ super({ context: { uri }, ...options });
19
19
  }
20
20
  }
21
21
 
package/src/Feed.ts CHANGED
@@ -10,8 +10,9 @@ import * as Layer from 'effect/Layer';
10
10
  import type * as Option from 'effect/Option';
11
11
  import * as Schema from 'effect/Schema';
12
12
 
13
- import { DXN } from '@dxos/keys';
13
+ import { DXN, EID } from '@dxos/keys';
14
14
 
15
+ import * as Annotation from './Annotation';
15
16
  import type * as Entity from './Entity';
16
17
  import type * as Filter from './Filter';
17
18
  import * as internal from './internal';
@@ -33,29 +34,29 @@ export const Feed = Schema.Struct({
33
34
  name: Schema.String.pipe(Schema.optional),
34
35
  /** Identifier for the feed's kind (e.g., plugin id). */
35
36
  kind: Schema.String.pipe(internal.FormInputAnnotation.set(false), Schema.optional),
37
+
38
+ /**
39
+ * Feed namespace.
40
+ * Controls how feed data is stored and replicated.
41
+ * - `data`: Data feed (default).
42
+ * - `trace`: Trace feed.
43
+ */
44
+ namespace: Schema.optional(Schema.Literal('data', 'trace')),
36
45
  }).pipe(
37
- Type.object({
38
- typename: 'org.dxos.type.feed',
39
- version: '0.1.0',
40
- }),
41
- internal.SystemTypeAnnotation.set(true),
46
+ internal.HiddenAnnotation.set(true),
47
+ Annotation.IconAnnotation.set({ icon: 'ph--rows--regular', hue: 'yellow' }),
48
+ Type.makeObject(DXN.make('org.dxos.type.feed', '0.1.0')),
42
49
  );
43
50
 
44
51
  /**
45
52
  * TypeScript instance type for a Feed object.
46
53
  */
47
- export interface Feed extends Schema.Schema.Type<typeof Feed> {}
54
+ export type Feed = Type.InstanceType<typeof Feed>;
48
55
 
49
56
  //
50
57
  // Types
51
58
  //
52
59
 
53
- /**
54
- * Meta key source for storing the backing DXN bound to a feed object.
55
- */
56
- // TODO(dmaretskyi): Enforce that Feed ObjectId = feed storage ID. And remove this key.
57
- export const DXN_KEY = 'org.dxos.key.feed';
58
-
59
60
  /**
60
61
  * Opaque cursor for iterating over feed items.
61
62
  */
@@ -73,6 +74,29 @@ export interface RetentionOptions {
73
74
  cursor?: string;
74
75
  }
75
76
 
77
+ /**
78
+ * Sync options for a feed.
79
+ */
80
+ export interface SyncOptions {
81
+ /** Push local changes to the server. Defaults to true. */
82
+ shouldPush?: boolean;
83
+ /** Pull remote changes from the server. Defaults to true. */
84
+ shouldPull?: boolean;
85
+ }
86
+
87
+ /**
88
+ * Queue replication backlog for a feed namespace.
89
+ * `0` / `0` means caught up on pull and push.
90
+ */
91
+ export interface SyncState {
92
+ /** Blocks still to pull from remote. */
93
+ blocksToPull: number;
94
+ /** Unpositioned blocks still to push to remote. */
95
+ blocksToPush: number;
96
+ /** Total blocks stored locally for the feed namespace. */
97
+ totalBlocks: number;
98
+ }
99
+
76
100
  //
77
101
  // Factory
78
102
  //
@@ -89,15 +113,11 @@ export interface RetentionOptions {
89
113
  export const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);
90
114
 
91
115
  /**
92
- * Reads the queue DXN from feed metadata.
116
+ * Returns the feed object's EID when the feed is stored in a space.
93
117
  *
94
- * @deprecated
118
+ * Used internally by the feed service layer.
95
119
  */
96
- // TODO(wittjosiah): Align backing feed dxn's with object DXN.
97
- export const getQueueDxn = (feed: Feed): DXN | undefined => {
98
- const keys = Obj.getKeys(feed, DXN_KEY);
99
- return keys.length === 0 ? undefined : DXN.parse(keys[0].id);
100
- };
120
+ export const getQueueUri = (feed: Feed): EID.EID | undefined => EID.tryParse(Obj.getURI(feed));
101
121
 
102
122
  //
103
123
  // Service
@@ -108,8 +128,8 @@ export const getQueueDxn = (feed: Feed): DXN | undefined => {
108
128
  * Provides the bridge to the underlying storage implementation.
109
129
  * Must be provided by the application layer (e.g., echo-db).
110
130
  */
111
- export class Service extends Context.Tag('@dxos/echo/Feed/Service')<
112
- Service,
131
+ export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
132
+ FeedService,
113
133
  {
114
134
  /**
115
135
  * Appends items to a feed.
@@ -119,7 +139,6 @@ export class Service extends Context.Tag('@dxos/echo/Feed/Service')<
119
139
  /**
120
140
  * Removes items from a feed by ID.
121
141
  */
122
- // TODO(dmaretskyi): Change type to ObjectId.
123
142
  remove(feed: Feed, ids: string[]): Promise<void>;
124
143
 
125
144
  /**
@@ -129,24 +148,65 @@ export class Service extends Context.Tag('@dxos/echo/Feed/Service')<
129
148
  <Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;
130
149
  <F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;
131
150
  };
151
+
152
+ /**
153
+ * Syncs the feed with the server.
154
+ */
155
+ sync(feed: Feed, options?: SyncOptions): Promise<void>;
156
+
157
+ /**
158
+ * Returns queue replication backlog for the feed's namespace.
159
+ */
160
+ getSyncState(feed: Feed): Promise<SyncState>;
132
161
  }
133
162
  >() {}
134
163
 
164
+ /**
165
+ * @deprecated Use `FeedService` instead.
166
+ */
167
+ export type Service = FeedService;
168
+
169
+ /**
170
+ * @deprecated Use `FeedService` instead.
171
+ */
172
+ export const Service = FeedService;
173
+
174
+ /**
175
+ * Effect context service that holds the current feed for a scoped operation.
176
+ *
177
+ * @deprecated Prefer threading a `Feed.Feed` explicitly through function signatures
178
+ * over hiding it behind a context service.
179
+ */
180
+ export class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<
181
+ ContextFeedService,
182
+ {
183
+ readonly feed: Feed;
184
+ }
185
+ >() {
186
+ static layer = (feed: Feed): Layer.Layer<ContextFeedService> => Layer.succeed(ContextFeedService, { feed });
187
+ }
188
+
135
189
  /**
136
190
  * Layer that provides a Feed service that throws when accessed.
137
191
  * Useful as a default layer when no feed service is available.
138
192
  */
139
- export const notAvailable: Layer.Layer<Service> = Layer.succeed(Service, {
193
+ export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService, {
140
194
  append: () => {
141
- throw new Error('Feed.Service not available');
195
+ throw new Error('Feed.FeedService not available');
142
196
  },
143
197
  remove: () => {
144
- throw new Error('Feed.Service not available');
198
+ throw new Error('Feed.FeedService not available');
145
199
  },
146
200
  query: () => {
147
- throw new Error('Feed.Service not available');
201
+ throw new Error('Feed.FeedService not available');
202
+ },
203
+ sync: () => {
204
+ throw new Error('Feed.FeedService not available');
205
+ },
206
+ getSyncState: () => {
207
+ throw new Error('Feed.FeedService not available');
148
208
  },
149
- } as Context.Tag.Service<Service>);
209
+ } as Context.Tag.Service<FeedService>);
150
210
 
151
211
  //
152
212
  // Operations
@@ -160,9 +220,9 @@ export const notAvailable: Layer.Layer<Service> = Layer.succeed(Service, {
160
220
  * yield* Feed.append(feed, [Obj.make(Notification, { title: 'Hello' })]);
161
221
  * ```
162
222
  */
163
- export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, Service> =>
223
+ export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, FeedService> =>
164
224
  Effect.gen(function* () {
165
- const service = yield* Service;
225
+ const service = yield* FeedService;
166
226
  yield* Effect.promise(() => service.append(feed, items));
167
227
  });
168
228
 
@@ -175,9 +235,9 @@ export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void,
175
235
  * ```
176
236
  */
177
237
  // TODO(dmaretskyi): Should we allow snapshots here? - what does it mean to remove a snapshot?
178
- export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, Service> =>
238
+ export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, FeedService> =>
179
239
  Effect.gen(function* () {
180
- const service = yield* Service;
240
+ const service = yield* FeedService;
181
241
  const ids = items.map((item) => item.id);
182
242
  yield* Effect.promise(() => service.remove(feed, ids));
183
243
  });
@@ -196,10 +256,16 @@ export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Ef
196
256
  // const object = yield* feed.pipe(Feed.query(Filter.type(Person))).first;
197
257
  // ... unify for Database and schema queries.
198
258
  export const query: {
199
- <Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<QueryResult.QueryResult<Query.Type<Q>>, never, Service>;
200
- <F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<QueryResult.QueryResult<Filter.Type<F>>, never, Service>;
259
+ <Q extends Query.Any>(
260
+ feed: Feed,
261
+ query: Q,
262
+ ): Effect.Effect<QueryResult.QueryResult<Query.Type<Q>>, never, FeedService>;
263
+ <F extends Filter.Any>(
264
+ feed: Feed,
265
+ filter: F,
266
+ ): Effect.Effect<QueryResult.QueryResult<Filter.Type<F>>, never, FeedService>;
201
267
  } = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
202
- Service.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));
268
+ FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));
203
269
 
204
270
  /**
205
271
  * Executes a feed query once and returns the results.
@@ -210,11 +276,40 @@ export const query: {
210
276
  * ```
211
277
  */
212
278
  export const runQuery: {
213
- <Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never, Service>;
214
- <F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never, Service>;
279
+ <Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never, FeedService>;
280
+ <F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never, FeedService>;
215
281
  } = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
216
282
  query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
217
283
 
284
+ /**
285
+ * Syncs the feed with the server.
286
+ *
287
+ * @example
288
+ * ```ts
289
+ * yield* Feed.sync(feed);
290
+ * yield* Feed.sync(feed, { shouldPush: false });
291
+ * ```
292
+ */
293
+ export const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, FeedService> =>
294
+ Effect.gen(function* () {
295
+ const service = yield* FeedService;
296
+ yield* Effect.promise(() => service.sync(feed, options));
297
+ });
298
+
299
+ /**
300
+ * Returns queue replication backlog for the feed's namespace.
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * const { blocksToPull, blocksToPush } = yield* Feed.getSyncState(feed);
305
+ * ```
306
+ */
307
+ export const getSyncState = (feed: Feed): Effect.Effect<SyncState, never, FeedService> =>
308
+ Effect.gen(function* () {
309
+ const service = yield* FeedService;
310
+ return yield* Effect.promise(() => service.getSyncState(feed));
311
+ });
312
+
218
313
  /**
219
314
  * Creates a cursor for iterating over feed items.
220
315
  * Currently stubbed — cursor operations are not yet implemented.
@@ -226,32 +321,32 @@ export const runQuery: {
226
321
  * ```
227
322
  */
228
323
  // TODO(wittjosiah): Implement cursor operations. Use Effect streams?
229
- export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, Service> =>
324
+ export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, FeedService> =>
230
325
  Effect.succeed({ _tag: 'Cursor' } as Cursor<T>);
231
326
 
232
327
  /**
233
328
  * Returns the next item from a feed cursor.
234
329
  * Currently stubbed — cursor operations are not yet implemented.
235
330
  */
236
- export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, Service> =>
331
+ export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, FeedService> =>
237
332
  Effect.die('Feed.next is not yet implemented');
238
333
 
239
334
  /**
240
335
  * Returns the next item from a feed cursor as an Option.
241
336
  * Currently stubbed — cursor operations are not yet implemented.
242
337
  */
243
- export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, Service> =>
338
+ export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, FeedService> =>
244
339
  Effect.die('Feed.nextOption is not yet implemented');
245
340
 
246
341
  /**
247
342
  * Sets the local retention policy for a feed.
248
- * Currently stubbed — queues do not yet support retention.
343
+ * Currently stubbed — feeds do not yet support retention.
249
344
  *
250
345
  * @example
251
346
  * ```ts
252
347
  * yield* Feed.setRetention(feed, { count: 1000 });
253
348
  * ```
254
349
  */
255
- // TODO(feed): Implement when queue retention is supported.
256
- export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, Service> =>
350
+ // TODO(dmaretskyi): Implement when feed retention is supported.
351
+ export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>
257
352
  Effect.void;