@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/Query.ts CHANGED
@@ -19,6 +19,8 @@ import * as Obj from './Obj';
19
19
  import type * as Order from './Order';
20
20
  import type * as Ref from './Ref';
21
21
  import type * as Relation from './Relation';
22
+ // eslint-disable-next-line @dxos/rules/import-as-namespace
23
+ import type * as Type$ from './Type';
22
24
  import type * as View from './View';
23
25
 
24
26
  // TODO(dmaretskyi): Split up into interfaces for objects and relations so they can have separate verbs.
@@ -69,11 +71,11 @@ export interface Query<T> {
69
71
  */
70
72
  // TODO(dmaretskyi): any way to enforce `Ref.Target<Schema.Schema.Type<S>[key]> == T`?
71
73
  // TODO(dmaretskyi): Ability to go through arrays of references.
72
- 'referencedBy'<S extends Schema.Schema.All>(
74
+ 'referencedBy'<S extends Type$.AnyEntity>(
73
75
  target: S | string,
74
- key: RefPropKey<Schema.Schema.Type<S>>,
75
- ): Query<Schema.Schema.Type<S>>;
76
- 'referencedBy'<S extends Schema.Schema.All>(target: S | string): Query<Schema.Schema.Type<S>>;
76
+ key: RefPropKey<Type$.InstanceType<S>>,
77
+ ): Query<Type$.InstanceType<S>>;
78
+ 'referencedBy'<S extends Type$.AnyEntity>(target: S | string): Query<Type$.InstanceType<S>>;
77
79
  'referencedBy'(): Query<any>;
78
80
 
79
81
  /**
@@ -82,21 +84,21 @@ export interface Query<T> {
82
84
  * @param relation - Schema of the relation.
83
85
  * @param predicates - Predicates to filter the relation objects.
84
86
  */
85
- 'sourceOf'<S extends Schema.Schema.All>(
86
- relation?: S | string,
87
- predicates?: Filter.Props<Schema.Schema.Type<S>>,
88
- ): Query<Schema.Schema.Type<S>>;
87
+ 'sourceOf'<R extends Type$.AnyRelation>(
88
+ relation?: R | string,
89
+ predicates?: Filter.Props<Type$.InstanceType<R>>,
90
+ ): Query<Type$.InstanceType<R>>;
89
91
 
90
92
  /**
91
93
  * Find relations where this object is the target.
92
94
  * @returns Query for the relation objects.
93
- * @param relation - Schema of the relation.
95
+ * @param relation - Type entity of the relation.
94
96
  * @param predicates - Predicates to filter the relation objects.
95
97
  */
96
- 'targetOf'<S extends Schema.Schema.All>(
97
- relation?: S | string,
98
- predicates?: Filter.Props<Schema.Schema.Type<S>>,
99
- ): Query<Schema.Schema.Type<S>>;
98
+ 'targetOf'<R extends Type$.AnyRelation>(
99
+ relation?: R | string,
100
+ predicates?: Filter.Props<Type$.InstanceType<R>>,
101
+ ): Query<Type$.InstanceType<R>>;
100
102
 
101
103
  /**
102
104
  * For a query for relations, get the source objects.
@@ -199,14 +201,30 @@ export interface Query<T> {
199
201
  'from'(query: Any): Query<T>;
200
202
 
201
203
  /**
202
- * Query from a raw scope specification.
204
+ * Query from one or more raw scopes.
205
+ *
206
+ * Use the {@link Scope} constructors rather than raw tagged objects:
207
+ *
208
+ * ```ts
209
+ * Query.select(Filter.type(Type.Type)).from(Scope.space(), Scope.registry());
210
+ * ```
211
+ */
212
+ 'from'(...scopes: QueryAST.Scope[]): Query<T>;
213
+
214
+ /**
215
+ * Query from a raw scope or array of scopes.
203
216
  */
204
- 'from'(scope: QueryAST.Scope): Query<T>;
217
+ 'from'(scope: QueryAST.Scope | QueryAST.Scope[]): Query<T>;
205
218
 
206
219
  /**
207
220
  * Add options to a query.
208
221
  */
209
222
  'options'(options: QueryAST.QueryOptions): Query<T>;
223
+
224
+ /**
225
+ * Attach a diagnostic label for logs and tooling (execution semantics unchanged).
226
+ */
227
+ 'debugLabel'(label: string): Query<T>;
210
228
  }
211
229
 
212
230
  export type Any = Query<any>;
@@ -244,17 +262,17 @@ class QueryClass implements Any {
244
262
  });
245
263
  }
246
264
 
247
- referencedBy(target?: Schema.Schema.All | string, key?: string): Any {
248
- const dxn = target !== undefined ? internal.getTypeDXNFromSpecifier(target) : null;
265
+ referencedBy(target?: Type$.AnyEntity | string, key?: string): Any {
266
+ const uri = target !== undefined ? internal.getTypeURIFromSpecifier(target) : null;
249
267
  return new QueryClass({
250
268
  type: 'incoming-references',
251
269
  anchor: this.ast,
252
270
  property: key ?? null,
253
- typename: dxn?.toString() ?? null,
271
+ typename: uri ?? null,
254
272
  });
255
273
  }
256
274
 
257
- sourceOf(relation?: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Any {
275
+ sourceOf(relation?: Type$.AnyRelation | string, predicates?: Filter.Props<unknown> | undefined): Any {
258
276
  return new QueryClass({
259
277
  type: 'relation',
260
278
  anchor: this.ast,
@@ -263,7 +281,7 @@ class QueryClass implements Any {
263
281
  });
264
282
  }
265
283
 
266
- targetOf(relation?: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Any {
284
+ targetOf(relation?: Type$.AnyRelation | string, predicates?: Filter.Props<unknown> | undefined): Any {
267
285
  return new QueryClass({
268
286
  type: 'relation',
269
287
  anchor: this.ast,
@@ -321,18 +339,54 @@ class QueryClass implements Any {
321
339
  }
322
340
 
323
341
  from(
324
- arg:
325
- | Database.Database
326
- | Database.Database[]
327
- | Feed.Feed
328
- | Feed.Feed[]
329
- | Collection.Collection
330
- | View.View
331
- | Any
332
- | QueryAST.Scope
333
- | 'all-accessible-spaces',
334
- options?: { includeFeeds?: boolean },
342
+ ...args:
343
+ | [
344
+ (
345
+ | Database.Database
346
+ | Database.Database[]
347
+ | Feed.Feed
348
+ | Feed.Feed[]
349
+ | Collection.Collection
350
+ | View.View
351
+ | Any
352
+ | QueryAST.Scope
353
+ | QueryAST.Scope[]
354
+ | 'all-accessible-spaces'
355
+ ),
356
+ { includeFeeds?: boolean }?,
357
+ ]
358
+ | QueryAST.Scope[]
335
359
  ): Any {
360
+ // Variadic raw scopes: `.from(Scope.space(), Scope.registry())`.
361
+ if (args.length > 1 && args.every(_isRawScope)) {
362
+ return new QueryClass({
363
+ type: 'from',
364
+ query: this.ast,
365
+ from: { _tag: 'scope', scopes: args as QueryAST.Scope[] },
366
+ });
367
+ }
368
+
369
+ const [arg, options] = args as [
370
+ (
371
+ | Database.Database
372
+ | Database.Database[]
373
+ | Feed.Feed
374
+ | Feed.Feed[]
375
+ | Collection.Collection
376
+ | View.View
377
+ | Any
378
+ | QueryAST.Scope
379
+ | QueryAST.Scope[]
380
+ | 'all-accessible-spaces'
381
+ ),
382
+ { includeFeeds?: boolean }?,
383
+ ];
384
+ if (arg == null) {
385
+ throw new TypeError(
386
+ 'Query.from() requires a valid data source argument (database, feed, query, scope, or "all-accessible-spaces").',
387
+ );
388
+ }
389
+
336
390
  if (is(arg)) {
337
391
  return new QueryClass({
338
392
  type: 'from',
@@ -345,20 +399,23 @@ class QueryClass implements Any {
345
399
  return new QueryClass({
346
400
  type: 'from',
347
401
  query: this.ast,
348
- from: {
349
- _tag: 'scope',
350
- scope: {
351
- ...(options?.includeFeeds ? { allQueuesFromSpaces: true } : {}),
352
- },
353
- },
402
+ from: { _tag: 'scope', scopes: [] },
354
403
  });
355
404
  }
356
405
 
357
- if (_isScope(arg)) {
406
+ // Raw scope(s): tagged union objects with _tag 'space' | 'feed' | 'registry'.
407
+ if (Array.isArray(arg) && arg.every(_isRawScope)) {
358
408
  return new QueryClass({
359
409
  type: 'from',
360
410
  query: this.ast,
361
- from: { _tag: 'scope', scope: arg },
411
+ from: { _tag: 'scope', scopes: arg as QueryAST.Scope[] },
412
+ });
413
+ }
414
+ if (_isRawScope(arg)) {
415
+ return new QueryClass({
416
+ type: 'from',
417
+ query: this.ast,
418
+ from: { _tag: 'scope', scopes: [arg] },
362
419
  });
363
420
  }
364
421
 
@@ -371,10 +428,11 @@ class QueryClass implements Any {
371
428
  query: this.ast,
372
429
  from: {
373
430
  _tag: 'scope',
374
- scope: {
375
- spaceIds: databases.map((db) => db.spaceId),
376
- ...(options?.includeFeeds ? { allQueuesFromSpaces: true } : {}),
377
- },
431
+ scopes: databases.map((db) => ({
432
+ _tag: 'space' as const,
433
+ spaceId: db.spaceId,
434
+ ...(options?.includeFeeds ? { includeAllFeeds: true } : {}),
435
+ })),
378
436
  },
379
437
  });
380
438
  }
@@ -389,22 +447,30 @@ class QueryClass implements Any {
389
447
  if (typename === 'org.dxos.type.collection') {
390
448
  throw new Error('Query.from(collection) is not yet supported.');
391
449
  }
450
+ // Validate that the items are Feed.Feed instances.
451
+ for (const item of items) {
452
+ if (!Obj.instanceOf(Feed.Feed, item)) {
453
+ throw new TypeError(
454
+ `Query.from() expects Feed objects (org.dxos.type.feed), but received an object with typename '${typename ?? 'unknown'}'.`,
455
+ );
456
+ }
457
+ }
392
458
  }
393
459
 
394
- const feeds = items as Feed.Feed[];
395
- const queueDxns = feeds.flatMap((feed) => {
396
- const dxn = Feed.getQueueDxn(feed);
397
- return dxn ? [dxn.toString()] : [];
460
+ const feedItems = items as Feed.Feed[];
461
+ const feedScopes = feedItems.map((feed) => {
462
+ const uri = Feed.getQueueUri(feed);
463
+ if (!uri) {
464
+ throw new TypeError(
465
+ `Query.from() expects persisted Feed objects with a queue URI; got feed without a space (id=${Obj.getURI(feed)}).`,
466
+ );
467
+ }
468
+ return { _tag: 'feed' as const, feedUri: String(uri) };
398
469
  });
399
470
  return new QueryClass({
400
471
  type: 'from',
401
472
  query: this.ast,
402
- from: {
403
- _tag: 'scope',
404
- scope: {
405
- queues: queueDxns,
406
- },
407
- },
473
+ from: { _tag: 'scope', scopes: feedScopes },
408
474
  });
409
475
  }
410
476
 
@@ -415,6 +481,21 @@ class QueryClass implements Any {
415
481
  options,
416
482
  });
417
483
  }
484
+
485
+ debugLabel(label: string): Any {
486
+ if (this.ast.type === 'options') {
487
+ return new QueryClass({
488
+ type: 'options',
489
+ query: this.ast.query,
490
+ options: { ...this.ast.options, debugLabel: label },
491
+ });
492
+ }
493
+ return new QueryClass({
494
+ type: 'options',
495
+ query: this.ast,
496
+ options: { debugLabel: label },
497
+ });
498
+ }
418
499
  }
419
500
 
420
501
  export const is = (value: unknown): value is Any => {
@@ -446,10 +527,22 @@ export const select = <F extends Filter.Any>(filter: F): Query<Filter.Type<F>> =
446
527
  *
447
528
  * Shorthand for: `Query.select(Filter.type(schema, predicates))`.
448
529
  */
449
- export const type = (schema: Schema.Schema.All | string, predicates?: Filter.Props<unknown>): Any => {
530
+ export const type: {
531
+ <T extends Type$.AnyEntity>(type: T, predicates?: Filter.Props<Type$.InstanceType<T>>): Query<Type$.InstanceType<T>>;
532
+ // Brand-narrowed schema overload — only well-known unknown schemas pass.
533
+ <S extends internal.UnknownTypeSchema<any, any>>(
534
+ schema: S,
535
+ predicates?: Filter.Props<Schema.Schema.Type<S>>,
536
+ ): Query<Schema.Schema.Type<S>>;
537
+ <S extends Schema.Union<readonly Schema.Schema.AnyNoContext[]>>(
538
+ union: S,
539
+ predicates?: Filter.Props<Schema.Schema.Type<S>>,
540
+ ): Query<Schema.Schema.Type<S>>;
541
+ (schema: string, predicates?: Filter.Props<unknown>): Query<any>;
542
+ } = (type: Type$.AnyEntity | string, predicates?: Filter.Props<unknown>): Any => {
450
543
  return new QueryClass({
451
544
  type: 'select',
452
- filter: Filter.type(schema, predicates).ast,
545
+ filter: Filter.type(type, predicates).ast,
453
546
  });
454
547
  };
455
548
 
@@ -493,30 +586,45 @@ export const without = <T>(source: Query<T>, exclude: Query<T>): Query<T> => {
493
586
  * @returns Query scoped to the given source.
494
587
  */
495
588
  export const from = (
496
- source:
497
- | Database.Database
498
- | Database.Database[]
499
- | Feed.Feed
500
- | Feed.Feed[]
501
- | Any
502
- | QueryAST.Scope
503
- | 'all-accessible-spaces',
504
- options?: { includeFeeds?: boolean },
589
+ ...args:
590
+ | [
591
+ (
592
+ | Database.Database
593
+ | Database.Database[]
594
+ | Feed.Feed
595
+ | Feed.Feed[]
596
+ | Any
597
+ | QueryAST.Scope
598
+ | QueryAST.Scope[]
599
+ | 'all-accessible-spaces'
600
+ ),
601
+ { includeFeeds?: boolean }?,
602
+ ]
603
+ | QueryAST.Scope[]
505
604
  ): Any => {
506
605
  const baseQuery: QueryAST.Query = {
507
606
  type: 'select',
508
607
  filter: Filter.everything().ast,
509
608
  };
510
609
  const wrapper = new QueryClass(baseQuery);
511
- return wrapper.from(source as any, options);
610
+ return (wrapper.from as (...args: unknown[]) => Any)(...args);
512
611
  };
513
612
 
514
- const SCOPE_KEYS = new Set(['spaceIds', 'queues', 'allQueuesFromSpaces']);
515
-
516
- /** Detect a raw Scope object (plain object with only Scope-valid keys). */
517
- const _isScope = (value: unknown): value is QueryAST.Scope => {
518
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
519
- return false;
520
- }
521
- return Object.keys(value).every((key) => SCOPE_KEYS.has(key));
613
+ const SCOPE_TAGS = new Set<string>(['space', 'feed', 'registry']);
614
+
615
+ /** Detect a raw Scope tagged-union object. */
616
+ const _isRawScope = (value: unknown): value is QueryAST.Scope => {
617
+ return (
618
+ typeof value === 'object' &&
619
+ value !== null &&
620
+ !Array.isArray(value) &&
621
+ '_tag' in value &&
622
+ typeof value._tag === 'string' &&
623
+ SCOPE_TAGS.has(value._tag)
624
+ );
522
625
  };
626
+
627
+ /**
628
+ * Returns a human-readable string representation of a Query AST.
629
+ */
630
+ export const pretty = (query: Any): string => internal.prettyQuery(query.ast);
@@ -2,6 +2,9 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Option from 'effect/Option';
7
+
5
8
  import { type CleanupFn } from '@dxos/async';
6
9
 
7
10
  import type * as Entity from './Entity';
@@ -104,3 +107,11 @@ export interface QueryResult<T> {
104
107
  */
105
108
  subscribe(callback?: (query: QueryResult<T>) => void, opts?: SubscriptionOptions): CleanupFn;
106
109
  }
110
+
111
+ /**
112
+ * Effect that returns a QueryResult when evaluated, but also has shorthand methods for running the query or getting the first result.
113
+ */
114
+ export interface QueryResultEffect<T, E, R> extends Effect.Effect<QueryResult<T>, E, R> {
115
+ run: Effect.Effect<T[], E, R>;
116
+ first: Effect.Effect<Option.Option<T>, E, R>;
117
+ }
package/src/Ref.ts CHANGED
@@ -8,10 +8,15 @@ import * as Option from 'effect/Option';
8
8
  import type * as Schema from 'effect/Schema';
9
9
  import * as SchemaAST from 'effect/SchemaAST';
10
10
 
11
+ import { type URI } from '@dxos/keys';
12
+
11
13
  import type * as Entity from './Entity';
14
+ import type * as internal from './internal';
12
15
  import * as refInternal from './internal/Ref';
13
16
  import type * as JsonSchema from './JsonSchema';
14
17
  import type * as Obj from './Obj';
18
+ // eslint-disable-next-line @dxos/rules/import-as-namespace
19
+ import type * as TypeNs from './Type';
15
20
 
16
21
  /**
17
22
  * Instance type for a reference.
@@ -42,10 +47,21 @@ export type Unknown = refInternal.Ref<Obj.Unknown>;
42
47
  * ```ts
43
48
  * const Task = Schema.Struct({
44
49
  * assignee: Ref.Ref(Person), // Creates a Ref schema
45
- * }).pipe(Type.object({ typename: 'Task', version: '0.1.0' }));
50
+ * }).pipe(Type.makeObject(DXN.make('com.example.type.task', '0.1.0')));
46
51
  * ```
47
52
  */
48
- export const Ref: <S extends Schema.Schema.Any>(schema: S) => RefSchema<Schema.Schema.Type<S>> = refInternal.Ref;
53
+ export const Ref: {
54
+ <S extends TypeNs.AnyObj | TypeNs.AnyRelation>(type: S): RefSchema<TypeNs.InstanceType<S> & Obj.Unknown>;
55
+
56
+ // `Type.Type` entities (the meta-schema kind) can be referenced too — e.g. a
57
+ // trigger that points to a stored function/workflow definition.
58
+ <T extends TypeNs.Type<any>>(type: T): RefSchema<TypeNs.InstanceType<T>>;
59
+
60
+ // Schema-side overload for the well-known "any object" / "any relation" schemas.
61
+ // Other raw `Schema.Schema` values are intentionally rejected — callers should
62
+ // pass a `Type.Type` entity instead.
63
+ <S extends internal.UnknownTypeSchema<any, any>>(schema: S): RefSchema<Schema.Schema.Type<S> & Obj.Unknown>;
64
+ } = refInternal.Ref as any;
49
65
 
50
66
  export const Array = refInternal.RefArray;
51
67
 
@@ -82,8 +98,10 @@ export const isRef: (value: unknown) => value is Unknown = refInternal.Ref.isRef
82
98
 
83
99
  export const make = refInternal.Ref.make;
84
100
 
85
- // TODO(dmaretskyi): Consider just allowing `make` to accept DXN.
86
- export const fromDXN = refInternal.Ref.fromDXN;
101
+ // TODO(dmaretskyi): Consider just allowing `make` to accept URI.
102
+ export const fromURI = (uri: URI.URI): refInternal.Ref<any> => refInternal.Ref.fromURI(uri);
103
+
104
+ export const hasEntityId = refInternal.Ref.hasEntityId;
87
105
 
88
106
  // TODO(wittjosiah): Factor out?
89
107
  export const isRefType = (ast: SchemaAST.AST): boolean => {
@@ -0,0 +1,155 @@
1
+ // Copyright 2026 DXOS.org
2
+
3
+ // @import-as-namespace
4
+
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import { type ReadOnlyEvent } from '@dxos/async';
9
+
10
+ import type * as Database from './Database';
11
+ import * as Entity from './Entity';
12
+ import type * as Filter from './Filter';
13
+ import type * as Query from './Query';
14
+
15
+ /**
16
+ * Identifier denoting an ECHO Registry.
17
+ */
18
+ export const TypeId = Symbol.for('@dxos/echo/Registry');
19
+ export type TypeId = typeof TypeId;
20
+
21
+ /**
22
+ * Composable, in-memory registry of keyed ECHO entities.
23
+ *
24
+ * Entities are stored by id and queried via the standard ECHO Query API.
25
+ * A registry may delegate to an optional upstream registry: results from the local
26
+ * registry take precedence and upstream results fill in anything not found locally.
27
+ *
28
+ * Intended use cases include caches of schemas, operations, blueprints, routines, plugins,
29
+ * etc., sourced from 3rd-party plugins, local code, or local space objects.
30
+ *
31
+ * Types (schema-definition entities produced by `Type.makeObject` / `Type.makeRelation`) are
32
+ * stored the same way as any other entity — via `add()`. Use `list().filter(Type.isType)` to
33
+ * retrieve them.
34
+ *
35
+ * Scope: a Registry is independent of any ECHO space or Hypergraph — it is a process-local,
36
+ * in-memory cache. Wire one per space (e.g. as a Layer scoped to the space's Effect runtime)
37
+ * or share a single instance across spaces depending on the use case.
38
+ *
39
+ * The concrete implementation (and the `makeRegistry` / `registryLayer` factories) lives in
40
+ * `@dxos/echo-db`; this module declares only the interface so that the `@dxos/echo` API surface
41
+ * stays free of query-matching dependencies.
42
+ */
43
+ export interface Registry {
44
+ readonly [TypeId]: TypeId;
45
+
46
+ /**
47
+ * Stable per-instance identifier. Used to key process-local resources (e.g. memoized
48
+ * reactive atoms) to a specific registry instance, analogous to {@link Database.spaceId}.
49
+ */
50
+ readonly id: string;
51
+
52
+ /**
53
+ * Fires whenever local registry contents change (add, remove, or clear).
54
+ */
55
+ readonly changed: ReadOnlyEvent<void>;
56
+
57
+ /**
58
+ * All locally-stored entities.
59
+ * Does not include upstream entities — use {@link list} for that.
60
+ */
61
+ readonly local: readonly Entity.Unknown[];
62
+
63
+ /**
64
+ * Add or replace one or more entities in the local registry.
65
+ * Existing entries with the same id are replaced.
66
+ * Also indexes type entities by DXN for fast lookup.
67
+ */
68
+ add(entities: readonly Entity.Unknown[]): void;
69
+
70
+ /**
71
+ * Remove an entity by id from the local registry.
72
+ * @returns true if an entity was removed, false if it was not found.
73
+ */
74
+ remove(id: string): boolean;
75
+
76
+ /**
77
+ * Remove all locally-stored entities.
78
+ * Does not affect the upstream registry.
79
+ */
80
+ clear(): void;
81
+
82
+ /**
83
+ * Get an entity by id.
84
+ * Searches the local registry first, then falls back to the upstream registry.
85
+ */
86
+ get(id: string): Entity.Unknown | undefined;
87
+
88
+ /**
89
+ * Get an entity by one of its addressing URIs — a type entity by its typename DXN (or, when
90
+ * persisted, its identifier EID), a keyed entity by its `dxn:<key>[:<version>]`. Accepts legacy
91
+ * DXN forms (normalized internally). Searches the local registry first, then falls back to the
92
+ * upstream registry. Narrow the result with `Type.isType` when a type entity is required.
93
+ */
94
+ getByURI(uri: string): Entity.Unknown | undefined;
95
+
96
+ /**
97
+ * List all entities.
98
+ * Local entities take precedence over upstream entities with the same id.
99
+ */
100
+ list(): Entity.Unknown[];
101
+
102
+ /**
103
+ * Run an ECHO query against the registry's entities (implements {@link Database.Queryable}).
104
+ *
105
+ * Matching happens in-memory over {@link list}. Scope (`from`) clauses are unwrapped and
106
+ * ignored — a direct registry query always targets the registry's own entities. The primary
107
+ * way to query registry contents is still through the database (`db.query(...).from(Scope.registry())`),
108
+ * which fans the database and registry together; this method is for querying a registry directly.
109
+ *
110
+ * Only locally-evaluable AST nodes are supported: `select`, `filter`, `limit`, `from`, `options`,
111
+ * and boolean combinators. Server-side concerns (order, traversal, text/timestamp filters) throw.
112
+ */
113
+ query: Database.QueryFn;
114
+ }
115
+
116
+ /**
117
+ * Type guard for {@link Registry}.
118
+ */
119
+ export const isRegistry = (obj: unknown): obj is Registry =>
120
+ obj != null && typeof obj === 'object' && TypeId in obj && (obj as { [TypeId]?: unknown })[TypeId] === TypeId;
121
+
122
+ /**
123
+ * Options for the registry factory (`makeRegistry` in `@dxos/echo-db`).
124
+ */
125
+ export type Options = {
126
+ /**
127
+ * Optional upstream registry. Queries fall back to upstream when an entity
128
+ * is not present in the local registry.
129
+ */
130
+ upstream?: Registry;
131
+
132
+ /**
133
+ * Initial set of entities to seed the local registry with.
134
+ */
135
+ initial?: readonly Entity.Unknown[];
136
+ };
137
+
138
+ /**
139
+ * Effect Context tag for {@link Registry}.
140
+ * Use this to inject a registry into Effect-based code.
141
+ */
142
+ export class Service extends Context.Tag('@dxos/echo/Registry/Service')<Service, Registry>() {}
143
+
144
+ /**
145
+ * Executes a query against the registry and returns the results.
146
+ * Analogous to {@link Database.runQuery} for the in-process registry.
147
+ */
148
+ export const runQuery: {
149
+ <Q extends Query.Any>(query: Q): Effect.Effect<Query.Type<Q>[], never, Service>;
150
+ <F extends Filter.Any>(filter: F): Effect.Effect<Filter.Type<F>[], never, Service>;
151
+ } = (queryOrFilter: Query.Any | Filter.Any) =>
152
+ Effect.gen(function* () {
153
+ const registry = yield* Service;
154
+ return (yield* Effect.promise(() => registry.query(queryOrFilter as any).run())) as any;
155
+ });
@@ -44,13 +44,13 @@ describe('Relation', () => {
44
44
  });
45
45
  const snapshot = Relation.getSnapshot(rel);
46
46
 
47
- // getSourceDXN - works with both.
48
- expect(Relation.getSourceDXN(rel)).toBeDefined();
49
- expect(Relation.getSourceDXN(snapshot)).toBeDefined();
47
+ // getSourceURI - works with both.
48
+ expect(Relation.getSourceURI(rel)).toBeDefined();
49
+ expect(Relation.getSourceURI(snapshot)).toBeDefined();
50
50
 
51
- // getTargetDXN - works with both.
52
- expect(Relation.getTargetDXN(rel)).toBeDefined();
53
- expect(Relation.getTargetDXN(snapshot)).toBeDefined();
51
+ // getTargetURI - works with both.
52
+ expect(Relation.getTargetURI(rel)).toBeDefined();
53
+ expect(Relation.getTargetURI(snapshot)).toBeDefined();
54
54
 
55
55
  // getSource - works with both.
56
56
  expect(Relation.getSource(rel)).toBeDefined();
@@ -61,12 +61,12 @@ describe('Relation', () => {
61
61
  expect(Relation.getTarget(snapshot)).toBeDefined();
62
62
 
63
63
  // getDXN - works with both.
64
- expect(Relation.getDXN(rel)).toBeDefined();
65
- expect(Relation.getDXN(snapshot)).toBeDefined();
64
+ expect(Relation.getURI(rel)).toBeDefined();
65
+ expect(Relation.getURI(snapshot)).toBeDefined();
66
66
 
67
67
  // getTypename - works with both.
68
- expect(Relation.getTypename(rel)).toBe('com.example.type.has-manager');
69
- expect(Relation.getTypename(snapshot)).toBe('com.example.type.has-manager');
68
+ expect(Relation.getTypename(rel)).toBe('com.example.type.hasManager');
69
+ expect(Relation.getTypename(snapshot)).toBe('com.example.type.hasManager');
70
70
 
71
71
  // getMeta - works with both.
72
72
  expect(Relation.getMeta(rel)).toBeDefined();