@dxos/echo 0.8.4-main.ef1bc66f44 → 0.8.4-main.effb148878

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 (602) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +9 -9
  3. package/dist/lib/neutral/Annotation.mjs +7 -3
  4. package/dist/lib/neutral/Database.mjs +8 -4
  5. package/dist/lib/neutral/Entity.mjs +35 -18
  6. package/dist/lib/neutral/Err.mjs +3 -1
  7. package/dist/lib/neutral/Extension.mjs +18 -0
  8. package/dist/lib/neutral/Extension.mjs.map +7 -0
  9. package/dist/lib/neutral/Feed.mjs +54 -0
  10. package/dist/lib/neutral/Feed.mjs.map +7 -0
  11. package/dist/lib/neutral/Filter.mjs +25 -12
  12. package/dist/lib/neutral/Format.mjs +23 -3
  13. package/dist/lib/neutral/JsonSchema.mjs +9 -9
  14. package/dist/lib/neutral/Key.mjs +7 -3
  15. package/dist/lib/neutral/Migration.mjs +18 -0
  16. package/dist/lib/neutral/Migration.mjs.map +7 -0
  17. package/dist/lib/neutral/Obj.mjs +41 -23
  18. package/dist/lib/neutral/Order.mjs +1 -1
  19. package/dist/lib/neutral/Query.mjs +21 -9
  20. package/dist/lib/neutral/QueryResult.mjs +1 -1
  21. package/dist/lib/neutral/Ref.mjs +13 -9
  22. package/dist/lib/neutral/Relation.mjs +34 -23
  23. package/dist/lib/neutral/SchemaRegistry.mjs +1 -1
  24. package/dist/lib/neutral/Tag.mjs +14 -10
  25. package/dist/lib/neutral/Type.mjs +52 -36
  26. package/dist/lib/neutral/{chunk-K5K3Z62A.mjs → chunk-4SYHDOQA.mjs} +14 -6
  27. package/dist/lib/neutral/chunk-4SYHDOQA.mjs.map +7 -0
  28. package/dist/lib/neutral/{chunk-XAJMXQ4H.mjs → chunk-4U7OD55H.mjs} +6 -2
  29. package/dist/lib/neutral/chunk-4U7OD55H.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-52NG2XEE.mjs +34 -0
  31. package/dist/lib/neutral/chunk-52NG2XEE.mjs.map +7 -0
  32. package/dist/lib/neutral/{chunk-KB7RIVLK.mjs → chunk-A5HDDVKS.mjs} +33 -6
  33. package/dist/lib/neutral/chunk-A5HDDVKS.mjs.map +7 -0
  34. package/dist/lib/neutral/{chunk-DLPC7DHQ.mjs → chunk-EZ4XJFHJ.mjs} +9 -11
  35. package/dist/lib/neutral/chunk-EZ4XJFHJ.mjs.map +7 -0
  36. package/dist/lib/neutral/{chunk-ZAHWXGK4.mjs → chunk-F625JEZB.mjs} +97 -19
  37. package/dist/lib/neutral/chunk-F625JEZB.mjs.map +7 -0
  38. package/dist/lib/neutral/chunk-FFCN66OF.mjs +420 -0
  39. package/dist/lib/neutral/chunk-FFCN66OF.mjs.map +7 -0
  40. package/dist/lib/neutral/{chunk-RPB6V4BE.mjs → chunk-GOHDOJE3.mjs} +16 -3
  41. package/dist/lib/neutral/chunk-GOHDOJE3.mjs.map +7 -0
  42. package/dist/lib/neutral/chunk-GWFFC34K.mjs +50 -0
  43. package/dist/lib/neutral/chunk-GWFFC34K.mjs.map +7 -0
  44. package/dist/lib/neutral/chunk-J7QWJQQV.mjs +318 -0
  45. package/dist/lib/neutral/chunk-J7QWJQQV.mjs.map +7 -0
  46. package/dist/lib/neutral/{chunk-QARLJVDB.mjs → chunk-JTHNDGAR.mjs} +8 -4
  47. package/dist/lib/neutral/chunk-JTHNDGAR.mjs.map +7 -0
  48. package/dist/lib/neutral/chunk-K5RH2PBH.mjs +361 -0
  49. package/dist/lib/neutral/chunk-K5RH2PBH.mjs.map +7 -0
  50. package/dist/lib/neutral/{chunk-RIMHNJ3E.mjs → chunk-KHRAQDYX.mjs} +138 -91
  51. package/dist/lib/neutral/chunk-KHRAQDYX.mjs.map +7 -0
  52. package/dist/lib/neutral/chunk-L65CW5EI.mjs +156 -0
  53. package/dist/lib/neutral/chunk-L65CW5EI.mjs.map +7 -0
  54. package/dist/lib/neutral/chunk-LNZIPZX6.mjs +2186 -0
  55. package/dist/lib/neutral/chunk-LNZIPZX6.mjs.map +7 -0
  56. package/dist/lib/neutral/chunk-MPXUNTME.mjs +41 -0
  57. package/dist/lib/neutral/chunk-MPXUNTME.mjs.map +7 -0
  58. package/dist/lib/neutral/{chunk-7WE7SBA2.mjs → chunk-O2EOH7XQ.mjs} +152 -134
  59. package/dist/lib/neutral/chunk-O2EOH7XQ.mjs.map +7 -0
  60. package/dist/lib/neutral/{chunk-MTEHHY62.mjs → chunk-Q7ID37KF.mjs} +121 -94
  61. package/dist/lib/neutral/chunk-Q7ID37KF.mjs.map +7 -0
  62. package/dist/lib/neutral/chunk-QLYEQ5VA.mjs +205 -0
  63. package/dist/lib/neutral/chunk-QLYEQ5VA.mjs.map +7 -0
  64. package/dist/lib/neutral/chunk-SSDGRJ3A.mjs +747 -0
  65. package/dist/lib/neutral/chunk-SSDGRJ3A.mjs.map +7 -0
  66. package/dist/lib/neutral/{chunk-ROKO4RKJ.mjs → chunk-TTCSATUD.mjs} +2 -2
  67. package/dist/lib/neutral/chunk-TTCSATUD.mjs.map +7 -0
  68. package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-UEFRFUYC.mjs} +8 -4
  69. package/dist/lib/neutral/chunk-UEFRFUYC.mjs.map +7 -0
  70. package/dist/lib/neutral/chunk-UN7K472Q.mjs +132 -0
  71. package/dist/lib/neutral/chunk-UN7K472Q.mjs.map +7 -0
  72. package/dist/lib/neutral/chunk-UQAMAXDU.mjs +243 -0
  73. package/dist/lib/neutral/chunk-UQAMAXDU.mjs.map +7 -0
  74. package/dist/lib/neutral/{chunk-4L6DOFXP.mjs → chunk-V5NE2X7Y.mjs} +1 -1
  75. package/dist/lib/neutral/chunk-V5NE2X7Y.mjs.map +7 -0
  76. package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-V72DY6LU.mjs} +1 -1
  77. package/dist/lib/neutral/chunk-ZII2BGPM.mjs +269 -0
  78. package/dist/lib/neutral/chunk-ZII2BGPM.mjs.map +7 -0
  79. package/dist/lib/neutral/{chunk-N2QNHMT5.mjs → chunk-ZM7VFIS2.mjs} +22 -2
  80. package/dist/lib/neutral/chunk-ZM7VFIS2.mjs.map +7 -0
  81. package/dist/lib/neutral/index.mjs +56 -29
  82. package/dist/lib/neutral/internal/index.mjs +128 -77
  83. package/dist/lib/neutral/meta.json +1 -1
  84. package/dist/lib/neutral/testing/index.mjs +226 -174
  85. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  86. package/dist/types/src/Annotation.d.ts +3 -3
  87. package/dist/types/src/Annotation.d.ts.map +1 -1
  88. package/dist/types/src/Collection.d.ts +15 -0
  89. package/dist/types/src/Collection.d.ts.map +1 -0
  90. package/dist/types/src/Database.d.ts +27 -42
  91. package/dist/types/src/Database.d.ts.map +1 -1
  92. package/dist/types/src/Dataset.d.ts +29 -0
  93. package/dist/types/src/Dataset.d.ts.map +1 -0
  94. package/dist/types/src/Entity.d.ts +123 -29
  95. package/dist/types/src/Entity.d.ts.map +1 -1
  96. package/dist/types/src/Err.d.ts +56 -13
  97. package/dist/types/src/Err.d.ts.map +1 -1
  98. package/dist/types/src/Extension.d.ts +80 -0
  99. package/dist/types/src/Extension.d.ts.map +1 -0
  100. package/dist/types/src/Extension.test.d.ts +2 -0
  101. package/dist/types/src/Extension.test.d.ts.map +1 -0
  102. package/dist/types/src/Feed.d.ts +229 -0
  103. package/dist/types/src/Feed.d.ts.map +1 -0
  104. package/dist/types/src/Filter.d.ts +74 -11
  105. package/dist/types/src/Filter.d.ts.map +1 -1
  106. package/dist/types/src/Filter.test.d.ts +2 -0
  107. package/dist/types/src/Filter.test.d.ts.map +1 -0
  108. package/dist/types/src/Format.d.ts +3 -3
  109. package/dist/types/src/Format.d.ts.map +1 -1
  110. package/dist/types/src/Hypergraph.d.ts +15 -10
  111. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  112. package/dist/types/src/Json.d.ts +33 -0
  113. package/dist/types/src/Json.d.ts.map +1 -0
  114. package/dist/types/src/Json.test.d.ts +2 -0
  115. package/dist/types/src/Json.test.d.ts.map +1 -0
  116. package/dist/types/src/JsonSchema.d.ts +11 -4
  117. package/dist/types/src/JsonSchema.d.ts.map +1 -1
  118. package/dist/types/src/Key.d.ts +1 -1
  119. package/dist/types/src/Key.d.ts.map +1 -1
  120. package/dist/types/src/Migration.d.ts +72 -0
  121. package/dist/types/src/Migration.d.ts.map +1 -0
  122. package/dist/types/src/Obj.d.ts +201 -77
  123. package/dist/types/src/Obj.d.ts.map +1 -1
  124. package/dist/types/src/Order.d.ts.map +1 -1
  125. package/dist/types/src/Query.d.ts +117 -17
  126. package/dist/types/src/Query.d.ts.map +1 -1
  127. package/dist/types/src/Ref.d.ts +66 -10
  128. package/dist/types/src/Ref.d.ts.map +1 -1
  129. package/dist/types/src/Relation.d.ts +127 -54
  130. package/dist/types/src/Relation.d.ts.map +1 -1
  131. package/dist/types/src/SchemaRegistry.d.ts +12 -13
  132. package/dist/types/src/SchemaRegistry.d.ts.map +1 -1
  133. package/dist/types/src/Tag.d.ts +4 -3
  134. package/dist/types/src/Tag.d.ts.map +1 -1
  135. package/dist/types/src/Type.d.ts +337 -218
  136. package/dist/types/src/Type.d.ts.map +1 -1
  137. package/dist/types/src/View.d.ts +65 -0
  138. package/dist/types/src/View.d.ts.map +1 -0
  139. package/dist/types/src/exemplars.test.d.ts +2 -0
  140. package/dist/types/src/exemplars.test.d.ts.map +1 -0
  141. package/dist/types/src/index.d.ts +8 -1
  142. package/dist/types/src/index.d.ts.map +1 -1
  143. package/dist/types/src/internal/{annotations → Annotation}/annotations.d.ts +98 -24
  144. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -0
  145. package/dist/types/src/internal/Annotation/annotations.test.d.ts.map +1 -0
  146. package/dist/types/src/internal/Annotation/index.d.ts +4 -0
  147. package/dist/types/src/internal/Annotation/index.d.ts.map +1 -0
  148. package/dist/types/src/internal/{api → Annotation}/sorting.d.ts +1 -1
  149. package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -0
  150. package/dist/types/src/internal/{annotations → Annotation}/util.d.ts +15 -6
  151. package/dist/types/src/internal/Annotation/util.d.ts.map +1 -0
  152. package/dist/types/src/internal/Entity/api.d.ts +13 -0
  153. package/dist/types/src/internal/Entity/api.d.ts.map +1 -0
  154. package/dist/types/src/internal/Entity/entity.d.ts +67 -0
  155. package/dist/types/src/internal/Entity/entity.d.ts.map +1 -0
  156. package/dist/types/src/internal/Entity/index.d.ts +10 -0
  157. package/dist/types/src/internal/Entity/index.d.ts.map +1 -0
  158. package/dist/types/src/internal/Entity/model.d.ts +57 -0
  159. package/dist/types/src/internal/Entity/model.d.ts.map +1 -0
  160. package/dist/types/src/internal/{entities → Entity}/object.d.ts +3 -3
  161. package/dist/types/src/internal/Entity/object.d.ts.map +1 -0
  162. package/dist/types/src/internal/Entity/relation.d.ts +51 -0
  163. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -0
  164. package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
  165. package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
  166. package/dist/types/src/internal/Entity/type-uri.d.ts +25 -0
  167. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
  168. package/dist/types/src/internal/Entity/util.d.ts.map +1 -0
  169. package/dist/types/src/internal/{api → Entity}/version.d.ts +1 -1
  170. package/dist/types/src/internal/Entity/version.d.ts.map +1 -0
  171. package/dist/types/src/internal/Format/date.d.ts.map +1 -0
  172. package/dist/types/src/internal/Format/date.test.d.ts.map +1 -0
  173. package/dist/types/src/internal/{formats → Format}/format.d.ts +2 -1
  174. package/dist/types/src/internal/Format/format.d.ts.map +1 -0
  175. package/dist/types/src/internal/Format/format.test.d.ts.map +1 -0
  176. package/dist/types/src/internal/{formats → Format}/index.d.ts +2 -2
  177. package/dist/types/src/internal/Format/index.d.ts.map +1 -0
  178. package/dist/types/src/internal/Format/number.d.ts.map +1 -0
  179. package/dist/types/src/internal/Format/object.d.ts.map +1 -0
  180. package/dist/types/src/internal/Format/select.d.ts.map +1 -0
  181. package/dist/types/src/internal/Format/string.d.ts.map +1 -0
  182. package/dist/types/src/internal/{formats → Format}/types.d.ts +1 -1
  183. package/dist/types/src/internal/Format/types.d.ts.map +1 -0
  184. package/dist/types/src/internal/{json-schema → JsonSchema}/annotations.d.ts +1 -1
  185. package/dist/types/src/internal/JsonSchema/annotations.d.ts.map +1 -0
  186. package/dist/types/src/internal/JsonSchema/effect-schema.test.d.ts.map +1 -0
  187. package/dist/types/src/internal/JsonSchema/index.d.ts.map +1 -0
  188. package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -0
  189. package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema-type.d.ts +37 -37
  190. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -0
  191. package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema.d.ts +3 -2
  192. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -0
  193. package/dist/types/src/internal/JsonSchema/json-schema.test.d.ts.map +1 -0
  194. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -0
  195. package/dist/types/src/internal/Obj/common.d.ts.map +1 -0
  196. package/dist/types/src/internal/{object → Obj}/create-object.d.ts +10 -12
  197. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -0
  198. package/dist/types/src/internal/Obj/create-object.test.d.ts.map +1 -0
  199. package/dist/types/src/internal/{object → Obj}/deleted.d.ts +1 -1
  200. package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -0
  201. package/dist/types/src/internal/{object → Obj}/index.d.ts +0 -1
  202. package/dist/types/src/internal/Obj/index.d.ts.map +1 -0
  203. package/dist/types/src/internal/Obj/inspect.d.ts.map +1 -0
  204. package/dist/types/src/internal/{object → Obj}/json-serializer.d.ts +16 -8
  205. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -0
  206. package/dist/types/src/internal/Obj/json-serializer.test.d.ts.map +1 -0
  207. package/dist/types/src/internal/Obj/schema-validator.d.ts +2 -0
  208. package/dist/types/src/internal/Obj/schema-validator.d.ts.map +1 -0
  209. package/dist/types/src/internal/Obj/schema-validator.test.d.ts.map +1 -0
  210. package/dist/types/src/internal/{object → Obj}/set-value.d.ts +2 -2
  211. package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -0
  212. package/dist/types/src/internal/Obj/set-value.test.d.ts.map +1 -0
  213. package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -0
  214. package/dist/types/src/internal/{object → Obj}/typed-object.d.ts +5 -5
  215. package/dist/types/src/internal/Obj/typed-object.d.ts.map +1 -0
  216. package/dist/types/src/internal/Obj/typed-object.test.d.ts.map +1 -0
  217. package/dist/types/src/internal/Query.d.ts +10 -0
  218. package/dist/types/src/internal/Query.d.ts.map +1 -0
  219. package/dist/types/src/internal/Ref/index.d.ts.map +1 -0
  220. package/dist/types/src/internal/{ref → Ref}/ref-array.d.ts +1 -1
  221. package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -0
  222. package/dist/types/src/internal/{ref → Ref}/ref.d.ts +42 -19
  223. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -0
  224. package/dist/types/src/internal/Ref/ref.test.d.ts.map +1 -0
  225. package/dist/types/src/internal/{schema → Type}/compose.d.ts +1 -1
  226. package/dist/types/src/internal/Type/compose.d.ts.map +1 -0
  227. package/dist/types/src/internal/Type/compose.test.d.ts.map +1 -0
  228. package/dist/types/src/internal/Type/index.d.ts +3 -0
  229. package/dist/types/src/internal/Type/index.d.ts.map +1 -0
  230. package/dist/types/src/internal/{schema → Type}/manipulation.d.ts +0 -1
  231. package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -0
  232. package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
  233. package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
  234. package/dist/types/src/internal/{api → common/api}/index.d.ts +0 -4
  235. package/dist/types/src/internal/common/api/index.d.ts.map +1 -0
  236. package/dist/types/src/internal/{api → common/api}/meta.d.ts +3 -3
  237. package/dist/types/src/internal/common/api/meta.d.ts.map +1 -0
  238. package/dist/types/src/internal/common/index.d.ts +4 -0
  239. package/dist/types/src/internal/common/index.d.ts.map +1 -0
  240. package/dist/types/src/internal/{proxy → common/proxy}/change-context.d.ts +1 -1
  241. package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -0
  242. package/dist/types/src/internal/common/proxy/change.test.d.ts.map +1 -0
  243. package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -0
  244. package/dist/types/src/internal/{proxy → common/proxy}/errors.d.ts +1 -1
  245. package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -0
  246. package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -0
  247. package/dist/types/src/internal/common/proxy/handler.test.d.ts.map +1 -0
  248. package/dist/types/src/internal/common/proxy/index.d.ts.map +1 -0
  249. package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -0
  250. package/dist/types/src/internal/common/proxy/make-object.d.ts +19 -0
  251. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -0
  252. package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -0
  253. package/dist/types/src/internal/common/proxy/proxy-types.d.ts.map +1 -0
  254. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -0
  255. package/dist/types/src/internal/{proxy → common/proxy}/reactive-array.d.ts +1 -1
  256. package/dist/types/src/internal/common/proxy/reactive-array.d.ts.map +1 -0
  257. package/dist/types/src/internal/{proxy → common/proxy}/reactive.d.ts +2 -2
  258. package/dist/types/src/internal/{proxy → common/proxy}/reactive.d.ts.map +1 -1
  259. package/dist/types/src/internal/common/proxy/reactive.test.d.ts +2 -0
  260. package/dist/types/src/internal/common/proxy/reactive.test.d.ts.map +1 -0
  261. package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -0
  262. package/dist/types/src/internal/common/proxy/schema.test.d.ts.map +1 -0
  263. package/dist/types/src/internal/common/proxy/symbols.d.ts.map +1 -0
  264. package/dist/types/src/internal/{proxy → common/proxy}/typed-handler.d.ts +18 -2
  265. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -0
  266. package/dist/types/src/internal/common/proxy/typed-handler.test.d.ts.map +1 -0
  267. package/dist/types/src/internal/common/proxy/typed-object.test.d.ts.map +1 -0
  268. package/dist/types/src/internal/{types → common/types}/base.d.ts +1 -0
  269. package/dist/types/src/internal/common/types/base.d.ts.map +1 -0
  270. package/dist/types/src/internal/common/types/entity.d.ts +94 -0
  271. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -0
  272. package/dist/types/src/internal/{types → common/types}/index.d.ts +1 -0
  273. package/dist/types/src/internal/common/types/index.d.ts.map +1 -0
  274. package/dist/types/src/internal/{types → common/types}/meta.d.ts +12 -1
  275. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -0
  276. package/dist/types/src/internal/common/types/model-symbols.d.ts +58 -0
  277. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -0
  278. package/dist/types/src/internal/{types → common/types}/typename.d.ts +7 -0
  279. package/dist/types/src/internal/common/types/typename.d.ts.map +1 -0
  280. package/dist/types/src/internal/{types → common/types}/version.d.ts +2 -2
  281. package/dist/types/src/internal/common/types/version.d.ts.map +1 -0
  282. package/dist/types/src/internal/index.d.ts +9 -10
  283. package/dist/types/src/internal/index.d.ts.map +1 -1
  284. package/dist/types/src/testing/test-data.d.ts +8 -8
  285. package/dist/types/src/testing/test-data.d.ts.map +1 -1
  286. package/dist/types/src/testing/test-schema.d.ts +77 -82
  287. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  288. package/dist/types/src/testing/util.d.ts +5 -3
  289. package/dist/types/src/testing/util.d.ts.map +1 -1
  290. package/dist/types/tsconfig.tsbuildinfo +1 -1
  291. package/package.json +30 -15
  292. package/src/Annotation.ts +7 -3
  293. package/src/Collection.ts +36 -0
  294. package/src/Database.ts +80 -77
  295. package/src/Dataset.ts +34 -0
  296. package/src/Entity.test.ts +116 -6
  297. package/src/Entity.ts +181 -66
  298. package/src/Err.ts +25 -3
  299. package/src/Extension.test.ts +235 -0
  300. package/src/Extension.ts +122 -0
  301. package/src/Feed.ts +356 -0
  302. package/src/Filter.test.ts +90 -0
  303. package/src/Filter.ts +152 -21
  304. package/src/Format.ts +3 -3
  305. package/src/Hypergraph.ts +16 -11
  306. package/src/Json.test.ts +175 -0
  307. package/src/Json.ts +103 -0
  308. package/src/JsonSchema.ts +14 -4
  309. package/src/Key.ts +1 -1
  310. package/src/Migration.ts +114 -0
  311. package/src/Obj.test.ts +158 -20
  312. package/src/Obj.ts +451 -183
  313. package/src/Order.ts +3 -1
  314. package/src/Query.test.ts +446 -89
  315. package/src/Query.ts +300 -35
  316. package/src/Ref.ts +83 -12
  317. package/src/Relation.test.ts +16 -10
  318. package/src/Relation.ts +236 -165
  319. package/src/SchemaRegistry.ts +13 -17
  320. package/src/Tag.ts +9 -9
  321. package/src/Type.test.ts +169 -24
  322. package/src/Type.ts +561 -354
  323. package/src/View.ts +101 -0
  324. package/src/exemplars.test.ts +21 -0
  325. package/src/index.ts +9 -2
  326. package/src/internal/Annotation/annotations.test.ts +165 -0
  327. package/src/internal/{annotations → Annotation}/annotations.ts +181 -101
  328. package/src/internal/{annotations → Annotation}/index.ts +1 -0
  329. package/src/internal/{api → Annotation}/sorting.ts +2 -4
  330. package/src/internal/{annotations → Annotation}/util.ts +17 -9
  331. package/src/internal/{api/entity.ts → Entity/api.ts} +9 -8
  332. package/src/internal/Entity/entity.ts +246 -0
  333. package/src/internal/{entities → Entity}/index.ts +4 -0
  334. package/src/internal/{entities → Entity}/model.ts +42 -60
  335. package/src/internal/{entities → Entity}/object.ts +13 -6
  336. package/src/internal/Entity/relation.ts +179 -0
  337. package/src/internal/Entity/type-kind.ts +67 -0
  338. package/src/internal/Entity/type-uri.ts +87 -0
  339. package/src/internal/Entity/util.ts +34 -0
  340. package/src/internal/{api → Entity}/version.ts +2 -2
  341. package/src/internal/{formats → Format}/date.test.ts +1 -2
  342. package/src/internal/{formats → Format}/date.ts +0 -4
  343. package/src/internal/{formats → Format}/format.test.ts +1 -2
  344. package/src/internal/{formats → Format}/index.ts +2 -3
  345. package/src/internal/{formats → Format}/types.ts +2 -2
  346. package/src/internal/{json-schema → JsonSchema}/annotations.ts +3 -3
  347. package/src/internal/{json-schema → JsonSchema}/json-schema-type.ts +4 -4
  348. package/src/internal/{json-schema → JsonSchema}/json-schema.test.ts +64 -151
  349. package/src/internal/{json-schema → JsonSchema}/json-schema.ts +47 -28
  350. package/src/internal/{object → Obj}/clone.ts +10 -6
  351. package/src/internal/{object → Obj}/common.ts +2 -2
  352. package/src/internal/{object → Obj}/create-object.test.ts +13 -14
  353. package/src/internal/Obj/create-object.ts +135 -0
  354. package/src/internal/{object → Obj}/deleted.ts +2 -2
  355. package/src/internal/{object → Obj}/index.ts +0 -1
  356. package/src/internal/{object → Obj}/inspect.ts +3 -3
  357. package/src/internal/Obj/json-serializer.test.ts +185 -0
  358. package/src/internal/{object → Obj}/json-serializer.ts +108 -45
  359. package/src/internal/{object → Obj}/schema-validator.ts +1 -1
  360. package/src/internal/{object → Obj}/set-value.test.ts +31 -54
  361. package/src/internal/{object → Obj}/set-value.ts +3 -3
  362. package/src/internal/{object → Obj}/snapshot.ts +41 -23
  363. package/src/internal/Obj/typed-object.test.ts +32 -0
  364. package/src/internal/{object → Obj}/typed-object.ts +5 -5
  365. package/src/internal/Query.ts +156 -0
  366. package/src/internal/{ref → Ref}/ref-array.ts +1 -2
  367. package/src/internal/{ref → Ref}/ref.test.ts +16 -26
  368. package/src/internal/{ref → Ref}/ref.ts +117 -57
  369. package/src/internal/{schema → Type}/compose.test.ts +6 -5
  370. package/src/internal/{schema → Type}/compose.ts +1 -1
  371. package/src/internal/Type/index.ts +6 -0
  372. package/src/internal/{schema → Type}/manipulation.ts +0 -25
  373. package/src/internal/Type/type-schema.ts +60 -0
  374. package/src/internal/{README.md → common/README.md} +2 -2
  375. package/src/internal/{api → common/api}/index.ts +0 -4
  376. package/src/internal/{api → common/api}/meta.ts +3 -3
  377. package/src/internal/common/index.ts +7 -0
  378. package/src/internal/{proxy → common/proxy}/change-context.ts +1 -1
  379. package/src/internal/{proxy → common/proxy}/change.test.ts +97 -97
  380. package/src/internal/{proxy → common/proxy}/errors.ts +2 -2
  381. package/src/internal/{proxy → common/proxy}/handler.test.ts +2 -4
  382. package/src/internal/{proxy → common/proxy}/json-serializer.ts +20 -14
  383. package/src/internal/{proxy → common/proxy}/make-object.ts +37 -15
  384. package/src/internal/{proxy → common/proxy}/ownership.ts +0 -1
  385. package/src/internal/{proxy → common/proxy}/reactive-array.ts +1 -1
  386. package/src/internal/common/proxy/reactive.test.ts +54 -0
  387. package/src/internal/{proxy → common/proxy}/reactive.ts +12 -4
  388. package/src/internal/common/proxy/schema.test.ts +107 -0
  389. package/src/internal/{proxy → common/proxy}/typed-handler.test.ts +15 -15
  390. package/src/internal/{proxy → common/proxy}/typed-handler.ts +75 -18
  391. package/src/internal/{proxy → common/proxy}/typed-object.test.ts +17 -30
  392. package/src/internal/{types → common/types}/base.ts +1 -1
  393. package/src/internal/common/types/entity.ts +133 -0
  394. package/src/internal/{types → common/types}/index.ts +1 -0
  395. package/src/internal/{types → common/types}/meta.ts +15 -1
  396. package/src/internal/common/types/model-symbols.ts +74 -0
  397. package/src/internal/common/types/typename.ts +91 -0
  398. package/src/internal/{types → common/types}/version.ts +2 -3
  399. package/src/internal/index.ts +9 -31
  400. package/src/testing/api.test.ts +15 -12
  401. package/src/testing/test-data.ts +158 -99
  402. package/src/testing/test-schema.ts +33 -67
  403. package/src/testing/util.ts +14 -11
  404. package/dist/lib/neutral/chunk-2AF5GMG6.mjs +0 -171
  405. package/dist/lib/neutral/chunk-2AF5GMG6.mjs.map +0 -7
  406. package/dist/lib/neutral/chunk-4L6DOFXP.mjs.map +0 -7
  407. package/dist/lib/neutral/chunk-7WE7SBA2.mjs.map +0 -7
  408. package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
  409. package/dist/lib/neutral/chunk-DLPC7DHQ.mjs.map +0 -7
  410. package/dist/lib/neutral/chunk-EBUAT5ID.mjs +0 -229
  411. package/dist/lib/neutral/chunk-EBUAT5ID.mjs.map +0 -7
  412. package/dist/lib/neutral/chunk-K5K3Z62A.mjs.map +0 -7
  413. package/dist/lib/neutral/chunk-KB7RIVLK.mjs.map +0 -7
  414. package/dist/lib/neutral/chunk-LKFNEFHF.mjs +0 -130
  415. package/dist/lib/neutral/chunk-LKFNEFHF.mjs.map +0 -7
  416. package/dist/lib/neutral/chunk-MTEHHY62.mjs.map +0 -7
  417. package/dist/lib/neutral/chunk-N2QNHMT5.mjs.map +0 -7
  418. package/dist/lib/neutral/chunk-QARLJVDB.mjs.map +0 -7
  419. package/dist/lib/neutral/chunk-RIMHNJ3E.mjs.map +0 -7
  420. package/dist/lib/neutral/chunk-ROKO4RKJ.mjs.map +0 -7
  421. package/dist/lib/neutral/chunk-RPB6V4BE.mjs.map +0 -7
  422. package/dist/lib/neutral/chunk-TLGNKUUG.mjs +0 -3905
  423. package/dist/lib/neutral/chunk-TLGNKUUG.mjs.map +0 -7
  424. package/dist/lib/neutral/chunk-TQT6WTIJ.mjs +0 -142
  425. package/dist/lib/neutral/chunk-TQT6WTIJ.mjs.map +0 -7
  426. package/dist/lib/neutral/chunk-VUQGRDRI.mjs +0 -97
  427. package/dist/lib/neutral/chunk-VUQGRDRI.mjs.map +0 -7
  428. package/dist/lib/neutral/chunk-X2MPMYYN.mjs +0 -13
  429. package/dist/lib/neutral/chunk-X2MPMYYN.mjs.map +0 -7
  430. package/dist/lib/neutral/chunk-XAJMXQ4H.mjs.map +0 -7
  431. package/dist/lib/neutral/chunk-ZAHWXGK4.mjs.map +0 -7
  432. package/dist/types/src/internal/annotations/annotations.d.ts.map +0 -1
  433. package/dist/types/src/internal/annotations/annotations.test.d.ts.map +0 -1
  434. package/dist/types/src/internal/annotations/index.d.ts +0 -3
  435. package/dist/types/src/internal/annotations/index.d.ts.map +0 -1
  436. package/dist/types/src/internal/annotations/util.d.ts.map +0 -1
  437. package/dist/types/src/internal/api/annotations.d.ts +0 -23
  438. package/dist/types/src/internal/api/annotations.d.ts.map +0 -1
  439. package/dist/types/src/internal/api/entity.d.ts +0 -13
  440. package/dist/types/src/internal/api/entity.d.ts.map +0 -1
  441. package/dist/types/src/internal/api/index.d.ts.map +0 -1
  442. package/dist/types/src/internal/api/meta.d.ts.map +0 -1
  443. package/dist/types/src/internal/api/sorting.d.ts.map +0 -1
  444. package/dist/types/src/internal/api/version.d.ts.map +0 -1
  445. package/dist/types/src/internal/entities/entity.d.ts +0 -20
  446. package/dist/types/src/internal/entities/entity.d.ts.map +0 -1
  447. package/dist/types/src/internal/entities/index.d.ts +0 -6
  448. package/dist/types/src/internal/entities/index.d.ts.map +0 -1
  449. package/dist/types/src/internal/entities/model.d.ts +0 -79
  450. package/dist/types/src/internal/entities/model.d.ts.map +0 -1
  451. package/dist/types/src/internal/entities/object.d.ts.map +0 -1
  452. package/dist/types/src/internal/entities/relation.d.ts +0 -62
  453. package/dist/types/src/internal/entities/relation.d.ts.map +0 -1
  454. package/dist/types/src/internal/entities/util.d.ts.map +0 -1
  455. package/dist/types/src/internal/formats/date.d.ts.map +0 -1
  456. package/dist/types/src/internal/formats/date.test.d.ts.map +0 -1
  457. package/dist/types/src/internal/formats/format.d.ts.map +0 -1
  458. package/dist/types/src/internal/formats/format.test.d.ts.map +0 -1
  459. package/dist/types/src/internal/formats/index.d.ts.map +0 -1
  460. package/dist/types/src/internal/formats/number.d.ts.map +0 -1
  461. package/dist/types/src/internal/formats/object.d.ts.map +0 -1
  462. package/dist/types/src/internal/formats/select.d.ts.map +0 -1
  463. package/dist/types/src/internal/formats/string.d.ts.map +0 -1
  464. package/dist/types/src/internal/formats/types.d.ts.map +0 -1
  465. package/dist/types/src/internal/json-schema/annotations.d.ts.map +0 -1
  466. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +0 -1
  467. package/dist/types/src/internal/json-schema/index.d.ts.map +0 -1
  468. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +0 -1
  469. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +0 -1
  470. package/dist/types/src/internal/json-schema/json-schema.d.ts.map +0 -1
  471. package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +0 -1
  472. package/dist/types/src/internal/object/clone.d.ts.map +0 -1
  473. package/dist/types/src/internal/object/common.d.ts.map +0 -1
  474. package/dist/types/src/internal/object/create-object.d.ts.map +0 -1
  475. package/dist/types/src/internal/object/create-object.test.d.ts.map +0 -1
  476. package/dist/types/src/internal/object/deleted.d.ts.map +0 -1
  477. package/dist/types/src/internal/object/ids.d.ts +0 -6
  478. package/dist/types/src/internal/object/ids.d.ts.map +0 -1
  479. package/dist/types/src/internal/object/index.d.ts.map +0 -1
  480. package/dist/types/src/internal/object/inspect.d.ts.map +0 -1
  481. package/dist/types/src/internal/object/json-serializer.d.ts.map +0 -1
  482. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +0 -1
  483. package/dist/types/src/internal/object/schema-validator.d.ts +0 -2
  484. package/dist/types/src/internal/object/schema-validator.d.ts.map +0 -1
  485. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +0 -1
  486. package/dist/types/src/internal/object/set-value.d.ts.map +0 -1
  487. package/dist/types/src/internal/object/set-value.test.d.ts.map +0 -1
  488. package/dist/types/src/internal/object/snapshot.d.ts.map +0 -1
  489. package/dist/types/src/internal/object/typed-object.d.ts.map +0 -1
  490. package/dist/types/src/internal/object/typed-object.test.d.ts.map +0 -1
  491. package/dist/types/src/internal/proxy/change-context.d.ts.map +0 -1
  492. package/dist/types/src/internal/proxy/change.test.d.ts.map +0 -1
  493. package/dist/types/src/internal/proxy/define-hidden-property.d.ts.map +0 -1
  494. package/dist/types/src/internal/proxy/errors.d.ts.map +0 -1
  495. package/dist/types/src/internal/proxy/event-batch.d.ts.map +0 -1
  496. package/dist/types/src/internal/proxy/handler.test.d.ts.map +0 -1
  497. package/dist/types/src/internal/proxy/index.d.ts.map +0 -1
  498. package/dist/types/src/internal/proxy/json-serializer.d.ts.map +0 -1
  499. package/dist/types/src/internal/proxy/make-object.d.ts +0 -14
  500. package/dist/types/src/internal/proxy/make-object.d.ts.map +0 -1
  501. package/dist/types/src/internal/proxy/ownership.d.ts.map +0 -1
  502. package/dist/types/src/internal/proxy/proxy-types.d.ts.map +0 -1
  503. package/dist/types/src/internal/proxy/proxy-utils.d.ts.map +0 -1
  504. package/dist/types/src/internal/proxy/reactive-array.d.ts.map +0 -1
  505. package/dist/types/src/internal/proxy/schema-validator.d.ts.map +0 -1
  506. package/dist/types/src/internal/proxy/schema.test.d.ts.map +0 -1
  507. package/dist/types/src/internal/proxy/symbols.d.ts.map +0 -1
  508. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +0 -1
  509. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +0 -1
  510. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +0 -1
  511. package/dist/types/src/internal/ref/index.d.ts.map +0 -1
  512. package/dist/types/src/internal/ref/ref-array.d.ts.map +0 -1
  513. package/dist/types/src/internal/ref/ref.d.ts.map +0 -1
  514. package/dist/types/src/internal/ref/ref.test.d.ts.map +0 -1
  515. package/dist/types/src/internal/schema/compose.d.ts.map +0 -1
  516. package/dist/types/src/internal/schema/compose.test.d.ts.map +0 -1
  517. package/dist/types/src/internal/schema/echo-schema.d.ts +0 -181
  518. package/dist/types/src/internal/schema/echo-schema.d.ts.map +0 -1
  519. package/dist/types/src/internal/schema/index.d.ts +0 -4
  520. package/dist/types/src/internal/schema/index.d.ts.map +0 -1
  521. package/dist/types/src/internal/schema/manipulation.d.ts.map +0 -1
  522. package/dist/types/src/internal/schema/persistent-schema.d.ts +0 -20
  523. package/dist/types/src/internal/schema/persistent-schema.d.ts.map +0 -1
  524. package/dist/types/src/internal/types/base.d.ts.map +0 -1
  525. package/dist/types/src/internal/types/entity.d.ts +0 -37
  526. package/dist/types/src/internal/types/entity.d.ts.map +0 -1
  527. package/dist/types/src/internal/types/index.d.ts.map +0 -1
  528. package/dist/types/src/internal/types/meta.d.ts.map +0 -1
  529. package/dist/types/src/internal/types/typename.d.ts.map +0 -1
  530. package/dist/types/src/internal/types/version.d.ts.map +0 -1
  531. package/src/internal/annotations/annotations.test.ts +0 -96
  532. package/src/internal/api/annotations.ts +0 -60
  533. package/src/internal/entities/entity.ts +0 -126
  534. package/src/internal/entities/relation.ts +0 -171
  535. package/src/internal/entities/util.ts +0 -33
  536. package/src/internal/object/create-object.ts +0 -95
  537. package/src/internal/object/ids.ts +0 -12
  538. package/src/internal/object/json-serializer.test.ts +0 -98
  539. package/src/internal/object/typed-object.test.ts +0 -34
  540. package/src/internal/proxy/schema.test.ts +0 -145
  541. package/src/internal/schema/echo-schema.ts +0 -424
  542. package/src/internal/schema/index.ts +0 -7
  543. package/src/internal/schema/persistent-schema.ts +0 -28
  544. package/src/internal/types/entity.ts +0 -54
  545. package/src/internal/types/typename.ts +0 -55
  546. /package/dist/lib/neutral/{chunk-OMUPQMLR.mjs.map → chunk-V72DY6LU.mjs.map} +0 -0
  547. /package/dist/types/src/internal/{annotations → Annotation}/annotations.test.d.ts +0 -0
  548. /package/dist/types/src/internal/{entities → Entity}/util.d.ts +0 -0
  549. /package/dist/types/src/internal/{formats → Format}/date.d.ts +0 -0
  550. /package/dist/types/src/internal/{formats → Format}/date.test.d.ts +0 -0
  551. /package/dist/types/src/internal/{formats → Format}/format.test.d.ts +0 -0
  552. /package/dist/types/src/internal/{formats → Format}/number.d.ts +0 -0
  553. /package/dist/types/src/internal/{formats → Format}/object.d.ts +0 -0
  554. /package/dist/types/src/internal/{formats → Format}/select.d.ts +0 -0
  555. /package/dist/types/src/internal/{formats → Format}/string.d.ts +0 -0
  556. /package/dist/types/src/internal/{json-schema → JsonSchema}/effect-schema.test.d.ts +0 -0
  557. /package/dist/types/src/internal/{json-schema → JsonSchema}/index.d.ts +0 -0
  558. /package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema-normalize.d.ts +0 -0
  559. /package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema.test.d.ts +0 -0
  560. /package/dist/types/src/internal/{object → Obj}/clone.d.ts +0 -0
  561. /package/dist/types/src/internal/{object → Obj}/common.d.ts +0 -0
  562. /package/dist/types/src/internal/{object → Obj}/create-object.test.d.ts +0 -0
  563. /package/dist/types/src/internal/{object → Obj}/inspect.d.ts +0 -0
  564. /package/dist/types/src/internal/{object → Obj}/json-serializer.test.d.ts +0 -0
  565. /package/dist/types/src/internal/{object → Obj}/schema-validator.test.d.ts +0 -0
  566. /package/dist/types/src/internal/{object → Obj}/set-value.test.d.ts +0 -0
  567. /package/dist/types/src/internal/{object → Obj}/snapshot.d.ts +0 -0
  568. /package/dist/types/src/internal/{object → Obj}/typed-object.test.d.ts +0 -0
  569. /package/dist/types/src/internal/{ref → Ref}/index.d.ts +0 -0
  570. /package/dist/types/src/internal/{ref → Ref}/ref.test.d.ts +0 -0
  571. /package/dist/types/src/internal/{schema → Type}/compose.test.d.ts +0 -0
  572. /package/dist/types/src/internal/{proxy → common/proxy}/change.test.d.ts +0 -0
  573. /package/dist/types/src/internal/{proxy → common/proxy}/define-hidden-property.d.ts +0 -0
  574. /package/dist/types/src/internal/{proxy → common/proxy}/event-batch.d.ts +0 -0
  575. /package/dist/types/src/internal/{proxy → common/proxy}/handler.test.d.ts +0 -0
  576. /package/dist/types/src/internal/{proxy → common/proxy}/index.d.ts +0 -0
  577. /package/dist/types/src/internal/{proxy → common/proxy}/json-serializer.d.ts +0 -0
  578. /package/dist/types/src/internal/{proxy → common/proxy}/ownership.d.ts +0 -0
  579. /package/dist/types/src/internal/{proxy → common/proxy}/proxy-types.d.ts +0 -0
  580. /package/dist/types/src/internal/{proxy → common/proxy}/proxy-utils.d.ts +0 -0
  581. /package/dist/types/src/internal/{proxy → common/proxy}/schema-validator.d.ts +0 -0
  582. /package/dist/types/src/internal/{proxy → common/proxy}/schema.test.d.ts +0 -0
  583. /package/dist/types/src/internal/{proxy → common/proxy}/symbols.d.ts +0 -0
  584. /package/dist/types/src/internal/{proxy → common/proxy}/typed-handler.test.d.ts +0 -0
  585. /package/dist/types/src/internal/{proxy → common/proxy}/typed-object.test.d.ts +0 -0
  586. /package/src/internal/{formats → Format}/format.ts +0 -0
  587. /package/src/internal/{formats → Format}/number.ts +0 -0
  588. /package/src/internal/{formats → Format}/object.ts +0 -0
  589. /package/src/internal/{formats → Format}/select.ts +0 -0
  590. /package/src/internal/{formats → Format}/string.ts +0 -0
  591. /package/src/internal/{json-schema → JsonSchema}/effect-schema.test.ts +0 -0
  592. /package/src/internal/{json-schema → JsonSchema}/index.ts +0 -0
  593. /package/src/internal/{json-schema → JsonSchema}/json-schema-normalize.ts +0 -0
  594. /package/src/internal/{object → Obj}/schema-validator.test.ts +0 -0
  595. /package/src/internal/{ref → Ref}/index.ts +0 -0
  596. /package/src/internal/{proxy → common/proxy}/define-hidden-property.ts +0 -0
  597. /package/src/internal/{proxy → common/proxy}/event-batch.ts +0 -0
  598. /package/src/internal/{proxy → common/proxy}/index.ts +0 -0
  599. /package/src/internal/{proxy → common/proxy}/proxy-types.ts +0 -0
  600. /package/src/internal/{proxy → common/proxy}/proxy-utils.ts +0 -0
  601. /package/src/internal/{proxy → common/proxy}/schema-validator.ts +0 -0
  602. /package/src/internal/{proxy → common/proxy}/symbols.ts +0 -0
package/src/Filter.ts CHANGED
@@ -2,20 +2,26 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ // @import-as-namespace
6
+
5
7
  import * as Match from 'effect/Match';
6
8
  import * as Schema from 'effect/Schema';
9
+ import * as SchemaAST from 'effect/SchemaAST';
7
10
  import type * as Types from 'effect/Types';
8
11
 
9
12
  import { type ForeignKey, type QueryAST } from '@dxos/echo-protocol';
10
13
  import { assertArgument } from '@dxos/invariant';
11
- import { DXN, ObjectId } from '@dxos/keys';
14
+ import { DXN, EchoURI, ObjectId, type URI } from '@dxos/keys';
12
15
 
13
- import { getTypeDXNFromSpecifier } from './internal';
16
+ import * as internal from './internal';
17
+ import type * as Obj from './Obj';
14
18
  import * as Ref from './Ref';
19
+ // eslint-disable-next-line @dxos/rules/import-as-namespace
20
+ import type * as Type$ from './Type';
15
21
 
16
22
  export interface Filter<T> {
17
23
  // TODO(dmaretskyi): See new effect-schema approach to variance.
18
- '~Filter': { value: Types.Contravariant<T> };
24
+ '~Filter': { value: Types.Covariant<T> };
19
25
 
20
26
  ast: QueryAST.Filter;
21
27
  }
@@ -30,7 +36,7 @@ export type Any = Filter<any>;
30
36
  export type Type<F extends Any> = F extends Filter<infer T> ? T : never;
31
37
 
32
38
  class FilterClass implements Any {
33
- private static variance: Any['~Filter'] = {} as Any['~Filter'];
39
+ private static 'variance': Any['~Filter'] = {} as Any['~Filter'];
34
40
 
35
41
  constructor(public readonly ast: QueryAST.Filter) {}
36
42
 
@@ -96,15 +102,46 @@ export const id = (...ids: ObjectId[]): Any => {
96
102
 
97
103
  /**
98
104
  * Filter by type.
105
+ *
106
+ * Accepts a `Type.Type` entity (the value produced by `Type.makeObject` /
107
+ * `Type.makeRelation`), a `Schema.Union` of such entities (for filtering across a
108
+ * union of ECHO types), or a non-qualified typename string.
99
109
  */
100
- export const type = <S extends Schema.Schema.All>(
101
- schema: S | string,
102
- props?: Props<Schema.Schema.Type<S>>,
103
- ): Filter<Schema.Schema.Type<S>> => {
104
- const dxn = getTypeDXNFromSpecifier(schema);
110
+ export const type: {
111
+ <T extends Type$.AnyEntity>(type: T, props?: Props<Type$.InstanceType<T>>): Filter<Type$.InstanceType<T>>;
112
+ // Schema-side overload restricted to the well-known unknown schemas and to
113
+ // `Schema.Union(...)` of `Type.Type` entities (for filtering across a union
114
+ // of ECHO types). Other raw schemas are rejected.
115
+ <S extends internal.UnknownTypeSchema<any, any>>(
116
+ schema: S,
117
+ props?: Props<Schema.Schema.Type<S>>,
118
+ ): Filter<Schema.Schema.Type<S>>;
119
+ <S extends Schema.Union<readonly Schema.Schema.AnyNoContext[]>>(
120
+ union: S,
121
+ props?: Props<Schema.Schema.Type<S>>,
122
+ ): Filter<Schema.Schema.Type<S>>;
123
+ (schema: string, props?: Props<unknown>): Filter<any>;
124
+ // Passthrough overload for callers that hold a `Type.AnyEntity | string` union
125
+ // (e.g. Query.type / Query.sourceOf / Query.targetOf impls). Listed last so the
126
+ // typed overloads above still win for monomorphic inputs.
127
+ (input: Type$.AnyEntity | string, props?: Props<unknown>): Filter<unknown>;
128
+ } = (input: Type$.AnyEntity | Schema.Schema.AnyNoContext | string, props?: Props<unknown>): any => {
129
+ if (Schema.isSchema(input) && SchemaAST.isUnion(input.ast)) {
130
+ const typenames = input.ast.types.map((t) => internal.getTypeURIFromSpecifier(Schema.make(t)));
131
+ return new FilterClass({
132
+ type: 'or',
133
+ filters: typenames.map((typename) => ({
134
+ type: 'object',
135
+ typename,
136
+ props: {},
137
+ })),
138
+ });
139
+ }
140
+
141
+ const uri = internal.getTypeURIFromSpecifier(input);
105
142
  return new FilterClass({
106
143
  type: 'object',
107
- typename: dxn.toString(),
144
+ typename: uri,
108
145
  ...propsFilterToAst(props ?? {}),
109
146
  });
110
147
  };
@@ -116,18 +153,19 @@ export const typename = (typename: string): Any => {
116
153
  assertArgument(!typename.startsWith('dxn:'), 'typename', 'Typename must no be qualified');
117
154
  return new FilterClass({
118
155
  type: 'object',
119
- typename: DXN.fromTypename(typename).toString(),
156
+ typename: DXN.make(typename),
120
157
  props: {},
121
158
  });
122
159
  };
123
160
 
124
161
  /**
125
- * Filter by fully qualified type DXN.
162
+ * Filter by fully qualified type URI — either a typename DXN (for static schemas) or
163
+ * a schema-as-object EchoURI (for stored dynamic schemas). See `getSchemaURI`.
126
164
  */
127
- export const typeDXN = (dxn: DXN): Any => {
165
+ export const typeURI = (uri: URI.URI): Any => {
128
166
  return new FilterClass({
129
167
  type: 'object',
130
- typename: dxn.toString(),
168
+ typename: uri,
131
169
  props: {},
132
170
  });
133
171
  };
@@ -142,6 +180,37 @@ export const tag = (tag: string): Any => {
142
180
  });
143
181
  };
144
182
 
183
+ /**
184
+ * Options for {@link key} filter.
185
+ */
186
+ export type KeyFilterOptions = {
187
+ /**
188
+ * Optional semver range expression (e.g. `^1.2.3`, `~2.0.0`, `>=1.0.0 <2.0.0`).
189
+ * Matches the object's meta `version` field against the range.
190
+ * If omitted, matches any version (including objects with no version).
191
+ */
192
+ version?: string;
193
+ };
194
+
195
+ /**
196
+ * Filter by registry key stored in object meta.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * Filter.key('org.example.type.foo');
201
+ * Filter.key('org.example.type.foo', { version: '^1.2.3' });
202
+ * ```
203
+ */
204
+ export const key = (key: string, options?: KeyFilterOptions): Any => {
205
+ return new FilterClass({
206
+ type: 'object',
207
+ typename: null,
208
+ props: {},
209
+ metaKey: key,
210
+ metaVersion: options?.version,
211
+ });
212
+ };
213
+
145
214
  /**
146
215
  * Filter by properties.
147
216
  */
@@ -176,14 +245,14 @@ export const text = (
176
245
  /**
177
246
  * Filter by foreign keys.
178
247
  */
179
- export const foreignKeys = <S extends Schema.Schema.All>(
180
- schema: S | string,
248
+ export const foreignKeys = <S extends Type$.AnyEntity | string>(
249
+ schema: S,
181
250
  keys: ForeignKey[],
182
- ): Filter<Schema.Schema.Type<S>> => {
183
- const dxn = getTypeDXNFromSpecifier(schema);
251
+ ): Filter<S extends Type$.AnyEntity ? Type$.InstanceType<S> : unknown> => {
252
+ const uri = internal.getTypeURIFromSpecifier(schema);
184
253
  return new FilterClass({
185
254
  type: 'object',
186
- typename: dxn.toString(),
255
+ typename: uri,
187
256
  props: {},
188
257
  foreignKeys: keys,
189
258
  });
@@ -263,7 +332,7 @@ export const lte = <T>(value: T): Filter<T | undefined> => {
263
332
  * Predicate for property to be in the provided array.
264
333
  * @param values - Values to check against.
265
334
  */
266
- const in$ = <T>(...values: T[]): Filter<T | undefined> => {
335
+ const in$ = <T>(...values: T[]): Filter<T> => {
267
336
  return new FilterClass({
268
337
  type: 'in',
269
338
  values,
@@ -287,7 +356,7 @@ export const contains = <T>(value: T): Filter<readonly T[] | undefined> => {
287
356
  * @param from - Start of the range (inclusive).
288
357
  * @param to - End of the range (exclusive).
289
358
  */
290
- export const between = <T>(from: T, to: T): Filter<unknown> => {
359
+ export const between = <T>(from: T, to: T): Filter<T> => {
291
360
  return new FilterClass({
292
361
  type: 'range',
293
362
  from,
@@ -295,6 +364,63 @@ export const between = <T>(from: T, to: T): Filter<unknown> => {
295
364
  });
296
365
  };
297
366
 
367
+ type TimeRange = { after?: Date | number; before?: Date | number };
368
+
369
+ const _toUnixMs = (date: Date | number): number => (typeof date === 'number' ? date : date.getTime());
370
+
371
+ const _timeRangeFilter = (field: 'updatedAt' | 'createdAt', range: TimeRange): Any => {
372
+ const filters: Any[] = [];
373
+ if (range.after != null) {
374
+ filters.push(new FilterClass({ type: 'timestamp', field, operator: 'gte', value: _toUnixMs(range.after) }));
375
+ }
376
+ if (range.before != null) {
377
+ filters.push(new FilterClass({ type: 'timestamp', field, operator: 'lte', value: _toUnixMs(range.before) }));
378
+ }
379
+ if (filters.length === 0) {
380
+ return everything();
381
+ }
382
+ return filters.length === 1 ? filters[0] : and(...filters);
383
+ };
384
+
385
+ /**
386
+ * Filter objects by updatedAt timestamp.
387
+ */
388
+ export const updated = (range: TimeRange): Any => _timeRangeFilter('updatedAt', range);
389
+
390
+ /**
391
+ * Filter objects by createdAt timestamp.
392
+ */
393
+ export const created = (range: TimeRange): Any => _timeRangeFilter('createdAt', range);
394
+
395
+ export type ChildOfOptions = {
396
+ /** Whether to match transitively (grandchildren, etc.). Defaults to true. */
397
+ transitive?: boolean;
398
+ };
399
+
400
+ /**
401
+ * Filter objects that are children of the specified parent(s).
402
+ * Accepts ECHO objects, Refs, or arrays of either.
403
+ * Refs are resolved to DXNs without loading; objects use {@link Obj.getURI}.
404
+ * With transitive=true (default), also matches grandchildren and beyond.
405
+ */
406
+ export const childOf = (
407
+ parents: Obj.Unknown | Ref.Unknown | readonly (Obj.Unknown | Ref.Unknown)[],
408
+ options?: ChildOfOptions,
409
+ ): Any => {
410
+ const items = Array.isArray(parents) ? parents : [parents];
411
+ const dxns = items.map((item) => {
412
+ if (Ref.isRef(item)) {
413
+ return EchoURI.parse(item.uri);
414
+ }
415
+ return internal.getUri(item);
416
+ });
417
+ return new FilterClass({
418
+ type: 'child-of',
419
+ parents: dxns,
420
+ transitive: options?.transitive ?? true,
421
+ });
422
+ };
423
+
298
424
  /**
299
425
  * Negate the filter.
300
426
  */
@@ -374,3 +500,8 @@ const processPredicate = (predicate: any): QueryAST.Filter => {
374
500
  Match.orElse((value) => eq(value).ast),
375
501
  );
376
502
  };
503
+
504
+ /**
505
+ * Returns a human-readable string representation of a Filter AST.
506
+ */
507
+ export const pretty = (filter: Any): string => internal.prettyFilter(filter.ast);
package/src/Format.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type TypeFormat as Format } from './internal';
5
+ import type * as internal from './internal';
6
6
 
7
- export * from './internal/formats';
7
+ export * from './internal/Format';
8
8
 
9
- export type { Format };
9
+ export type Format = internal.TypeFormat;
package/src/Hypergraph.ts CHANGED
@@ -2,11 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type DXN } from '@dxos/keys';
5
+ import { type URI } from '@dxos/keys';
6
6
 
7
7
  import type * as Database from './Database';
8
8
  import type * as Entity from './Entity';
9
- import { type AnyProperties } from './internal';
9
+ import type * as internal from './internal';
10
10
  import type * as Key from './Key';
11
11
  import type * as Ref from './Ref';
12
12
  import type * as SchemaRegistry from './SchemaRegistry';
@@ -22,10 +22,10 @@ export interface RefResolutionContext {
22
22
  space?: Key.SpaceId;
23
23
 
24
24
  /**
25
- * Queue that the resolution is happening from.
26
- * This queue will be searched first, and then the space it belongs to.
25
+ * Feed that the resolution is happening from.
26
+ * This feed will be searched first, and then the space it belongs to.
27
27
  */
28
- queue?: DXN;
28
+ feed?: URI.URI;
29
29
  }
30
30
 
31
31
  export interface RefResolverOptions {
@@ -39,13 +39,12 @@ export interface RefResolverOptions {
39
39
  * Middleware to change the resolved object before returning it.
40
40
  * @deprecated On track to be removed.
41
41
  */
42
- middleware?: (obj: AnyProperties) => AnyProperties;
42
+ middleware?: (obj: internal.AnyProperties) => internal.AnyProperties;
43
43
  }
44
44
 
45
45
  /**
46
- *
46
+ * Manages cross-space database interactions.
47
47
  */
48
- // TODO(burdon): Comment required.
49
48
  export interface Hypergraph extends Database.Queryable {
50
49
  get schemaRegistry(): SchemaRegistry.SchemaRegistry;
51
50
 
@@ -58,11 +57,11 @@ export interface Hypergraph extends Database.Queryable {
58
57
  * Creates a reference to an existing object in the database.
59
58
  *
60
59
  * NOTE: The reference may be dangling if the object is not present in the database.
61
- * NOTE: Difference from `Ref.fromDXN`
62
- * `Ref.fromDXN(dxn)` returns an unhydrated reference. The `.load` and `.target` APIs will not work.
60
+ * NOTE: Difference from `Ref.fromURI`
61
+ * `Ref.fromURI(dxn)` returns an unhydrated reference. The `.load` and `.target` APIs will not work.
63
62
  * `db.makeRef(dxn)` is preferable in cases with access to the database.
64
63
  */
65
- makeRef<T extends Entity.Unknown = Entity.Unknown>(dxn: DXN): Ref.Ref<T>;
64
+ makeRef<T extends Entity.Unknown = Entity.Unknown>(uri: URI.URI): Ref.Ref<T>;
66
65
 
67
66
  /**
68
67
  * @param hostDb Host database for reference resolution.
@@ -71,4 +70,10 @@ export interface Hypergraph extends Database.Queryable {
71
70
  */
72
71
  // TODO(dmaretskyi): Restructure API: Remove middleware.
73
72
  createRefResolver(options: RefResolverOptions): Ref.Resolver;
73
+
74
+ /**
75
+ * Get a database by space ID.
76
+ * @returns The database for the given space ID, or undefined if not found.
77
+ */
78
+ getDatabase(spaceId: Key.SpaceId): Database.Database | undefined;
74
79
  }
@@ -0,0 +1,175 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { DXN, EchoURI, ObjectId } from '@dxos/keys';
8
+ import { safeStringify } from '@dxos/util';
9
+
10
+ import * as Database from './Database';
11
+ import * as Json from './Json';
12
+
13
+ /** Mint a random ECHO object id usable as both a stub-db key and a DXN payload. */
14
+ const newId = (): string => ObjectId.random();
15
+
16
+ /** Build a fake encoded ref for a local-space object id. */
17
+ const encodeRef = (id: string): { '/': string } => ({ '/': EchoURI.make({ objectId: id }) });
18
+
19
+ /** Minimal stub: `createRefReplacer` only touches `db.getObjectById`. */
20
+ const makeStubDb = (objects: Record<string, unknown>): Database.Database => {
21
+ return {
22
+ getObjectById: (id: string) => objects[id],
23
+ } as unknown as Database.Database;
24
+ };
25
+
26
+ /**
27
+ * Run a value through the replacer's public contract — `JSON.stringify(value, replacer)` —
28
+ * then re-parse the result so tests can assert on plain JS shapes. This mirrors the way
29
+ * the JSON highlighter invokes the replacer in production.
30
+ */
31
+ const stringifyWith = (replacer: Json.JsonReplacer, value: unknown): unknown =>
32
+ JSON.parse(JSON.stringify(value, replacer));
33
+
34
+ describe('createRefReplacer', () => {
35
+ test('passes plain values through unchanged', () => {
36
+ const replacer = Json.createRefReplacer({ db: makeStubDb({}) });
37
+ const subject = { a: 1, b: 'two', c: [3, { d: 4 }] };
38
+ expect(stringifyWith(replacer, subject)).toEqual(subject);
39
+ });
40
+
41
+ test('inlines refs at default depth (1)', () => {
42
+ const id = newId();
43
+ const target = { name: 'inlined' };
44
+ const replacer = Json.createRefReplacer({ db: makeStubDb({ [id]: target }) });
45
+ const subject = { ref: encodeRef(id) };
46
+ expect(stringifyWith(replacer, subject)).toEqual({ ref: target });
47
+ });
48
+
49
+ test('does not follow refs when depth is 0', () => {
50
+ const id = newId();
51
+ const target = { name: 'inlined' };
52
+ const ref = encodeRef(id);
53
+ const replacer = Json.createRefReplacer({ db: makeStubDb({ [id]: target }), depth: 0 });
54
+ expect(stringifyWith(replacer, { ref })).toEqual({ ref });
55
+ });
56
+
57
+ test('inlines refs across multiple levels up to depth', () => {
58
+ const innerId = newId();
59
+ const middleId = newId();
60
+ const inner = { name: 'inner' };
61
+ const middle = { ref: encodeRef(innerId) };
62
+ const outer = { ref: encodeRef(middleId) };
63
+ const db = makeStubDb({ [innerId]: inner, [middleId]: middle });
64
+
65
+ expect(stringifyWith(Json.createRefReplacer({ db, depth: 1 }), outer)).toEqual({
66
+ ref: { ref: encodeRef(innerId) },
67
+ });
68
+
69
+ expect(stringifyWith(Json.createRefReplacer({ db, depth: 2 }), outer)).toEqual({
70
+ ref: { ref: inner },
71
+ });
72
+ });
73
+
74
+ test('leaves refs encoded when the target is missing in the db', () => {
75
+ const ref = encodeRef(newId());
76
+ const replacer = Json.createRefReplacer({ db: makeStubDb({}) });
77
+ expect(stringifyWith(replacer, { ref })).toEqual({ ref });
78
+ });
79
+
80
+ test('leaves non-DXN single-key { "/": string } objects untouched', () => {
81
+ // Same `{ '/': string }` shape is used by other IPLD-style refs (e.g. CIDs); those should
82
+ // not crash the replacer and should pass through verbatim.
83
+ const cidLike = { '/': 'bafybeibwzifw7izxykxz' };
84
+ const replacer = Json.createRefReplacer({ db: makeStubDb({}) });
85
+ expect(stringifyWith(replacer, { ref: cidLike })).toEqual({ ref: cidLike });
86
+ });
87
+
88
+ test('leaves malformed dxn strings untouched', () => {
89
+ const malformed = { '/': 'dxn:not-a-real-dxn' };
90
+ const replacer = Json.createRefReplacer({ db: makeStubDb({}) });
91
+ expect(stringifyWith(replacer, { ref: malformed })).toEqual({ ref: malformed });
92
+ });
93
+
94
+ test('leaves non-echo dxns untouched (e.g. type DXN)', () => {
95
+ // Type DXNs share the `dxn:` prefix but `asEchoDXN()` returns undefined.
96
+ const typeRef = { '/': DXN.make('com.example.Thing') };
97
+ const replacer = Json.createRefReplacer({ db: makeStubDb({}) });
98
+ expect(stringifyWith(replacer, { ref: typeRef })).toEqual({ ref: typeRef });
99
+ });
100
+
101
+ test('inlines refs inside arrays', () => {
102
+ const idA = newId();
103
+ const idB = newId();
104
+ const a = { name: 'a' };
105
+ const b = { name: 'b' };
106
+ const replacer = Json.createRefReplacer({ db: makeStubDb({ [idA]: a, [idB]: b }) });
107
+ expect(stringifyWith(replacer, { items: [encodeRef(idA), encodeRef(idB), { plain: true }] })).toEqual({
108
+ items: [a, b, { plain: true }],
109
+ });
110
+ });
111
+
112
+ test('walks nested objects recursively', () => {
113
+ const innerId = newId();
114
+ const inner = { name: 'inner' };
115
+ const replacer = Json.createRefReplacer({ db: makeStubDb({ [innerId]: inner }) });
116
+ const subject = { outer: { mid: { ref: encodeRef(innerId) } } };
117
+ expect(stringifyWith(replacer, subject)).toEqual({ outer: { mid: { ref: inner } } });
118
+ });
119
+
120
+ test('a single replacer invocation does not recurse on its own', () => {
121
+ // The replacer is per-call; JSON.stringify drives the tree walk. Calling the replacer
122
+ // directly on a cyclic input must therefore return without touching the cycle.
123
+ const replacer = Json.createRefReplacer({ db: makeStubDb({}) });
124
+ const node: any = { name: 'self' };
125
+ node.self = node;
126
+
127
+ expect(() => replacer('', node)).not.toThrow();
128
+ expect(replacer('', node)).toBe(node);
129
+ });
130
+
131
+ test('invokes `toJSON` on resolved targets so refs in the target are re-walked', () => {
132
+ // Simulates the ECHO-object branch: `db.getObjectById` returns a live proxy, the replacer
133
+ // calls `.toJSON()` to get the encoded form, then continues walking that form. A ref nested
134
+ // inside the target should be inlined when there's depth budget remaining.
135
+ const outerId = newId();
136
+ const innerId = newId();
137
+ const inner = { name: 'inner' };
138
+ const target = {
139
+ toJSON: () => ({ nestedRef: encodeRef(innerId) }),
140
+ };
141
+ const replacer = Json.createRefReplacer({ db: makeStubDb({ [outerId]: target, [innerId]: inner }), depth: 2 });
142
+ expect(stringifyWith(replacer, { ref: encodeRef(outerId) })).toEqual({
143
+ ref: { nestedRef: inner },
144
+ });
145
+ });
146
+
147
+ test('depth budget counts ref hops, not tree depth — a ref deep in a plain tree still resolves', () => {
148
+ // A ref nested under arbitrarily many plain objects is one ref hop from the root, so
149
+ // `depth: 1` resolves it. `depth: 0` leaves it encoded.
150
+ const innerId = newId();
151
+ const inner = { name: 'inner' };
152
+ const subject = { a: { b: { c: { d: { ref: encodeRef(innerId) } } } } };
153
+
154
+ const inlining = Json.createRefReplacer({ db: makeStubDb({ [innerId]: inner }), depth: 1 });
155
+ expect(stringifyWith(inlining, subject)).toEqual({ a: { b: { c: { d: { ref: inner } } } } });
156
+
157
+ const passthrough = Json.createRefReplacer({ db: makeStubDb({ [innerId]: inner }), depth: 0 });
158
+ expect(stringifyWith(passthrough, subject)).toEqual(subject);
159
+ });
160
+
161
+ test('inlines refs when invoked through safeStringify (production path)', () => {
162
+ // `JsonHighlighter` runs the replacer through `@dxos/util/safeStringify`, whose inner
163
+ // wrapper short-circuits the root call without forwarding it to the user's filter. The
164
+ // replacer must therefore work on a per-call basis — not as a one-shot root tree walk.
165
+ // This regression-tests that integration: the `content` ref must inline.
166
+ const targetId = newId();
167
+ const target = { toJSON: () => ({ name: 'README content' }) };
168
+ const document = { id: '01ABC', name: 'README', content: encodeRef(targetId) };
169
+
170
+ const replacer = Json.createRefReplacer({ db: makeStubDb({ [targetId]: target }) });
171
+ const out = JSON.parse(safeStringify(document, replacer, 0)!);
172
+
173
+ expect(out).toEqual({ id: '01ABC', name: 'README', content: { name: 'README content' } });
174
+ });
175
+ });
package/src/Json.ts ADDED
@@ -0,0 +1,103 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { EchoURI } from '@dxos/keys';
6
+
7
+ import * as Database from './Database';
8
+ import * as Obj from './Obj';
9
+
10
+ /**
11
+ * `JSON.stringify` replacer signature.
12
+ *
13
+ * Defined here (rather than re-imported from a UI package) so other ECHO-aware utilities can
14
+ * share a stable signature without creating a dependency edge into the UI tree.
15
+ */
16
+ export type JsonReplacer = (key: string, value: any) => any;
17
+
18
+ export type CreateRefReplacerOptions = {
19
+ db: Database.Database;
20
+ /** How many ref hops to follow. `0` leaves all refs as-is. Default: `1`. */
21
+ depth?: number;
22
+ };
23
+
24
+ const isEncodedRef = (value: unknown): value is { '/': string } =>
25
+ typeof value === 'object' &&
26
+ value !== null &&
27
+ Object.keys(value as object).length === 1 &&
28
+ typeof (value as { '/': unknown })['/'] === 'string';
29
+
30
+ const toJson = (obj: Obj.Any): unknown => (typeof (obj as any).toJSON === 'function' ? (obj as any).toJSON() : obj);
31
+
32
+ /**
33
+ * Returns a {@link JsonReplacer} that inlines ECHO ref objects (`{ "/": "dxn:echo:..." }`) up to
34
+ * `depth` ref hops. Beyond that depth refs are left in their encoded form.
35
+ *
36
+ * Implemented as a per-call `JSON.stringify` replacer (not a one-shot tree walk at root) so it
37
+ * composes with wrappers like `safeStringify` that intercept the root call. JSON.stringify
38
+ * already drives the recursion; we only need to (a) detect a ref at the current callback,
39
+ * (b) resolve and return the target if hop budget remains, and (c) tag the returned object
40
+ * with its hop count so children know how far in they are.
41
+ *
42
+ * The hop count is tracked per-object via a `WeakMap`: a ref-resolved target's children inherit
43
+ * `parentHops + 1`; a regular intermediate object's children inherit `parentHops`. This makes the
44
+ * budget count *ref hops*, not tree depth — a ref deep in a tree still resolves once when
45
+ * `depth >= 1`.
46
+ *
47
+ * Note: ECHO objects' `toJSON` runs before the replacer is invoked, so by the time we see a
48
+ * value refs are already encoded as `{ "/": "dxn:..." }`.
49
+ */
50
+ export const createRefReplacer = ({ db, depth = 1 }: CreateRefReplacerOptions): JsonReplacer => {
51
+ // Per-object hop count. Set when we return an object (via ref resolution or pass-through) so
52
+ // the child callbacks (which carry that object as `this`) can read it.
53
+ const hops = new WeakMap<object, number>();
54
+
55
+ return function (this: any, key: string, value: any) {
56
+ // Hop count for this call: hops at the parent, or 0 for the root.
57
+ const parentHops = this && typeof this === 'object' ? (hops.get(this) ?? 0) : 0;
58
+ if (isEncodedRef(value)) {
59
+ if (parentHops >= depth) {
60
+ return value;
61
+ }
62
+
63
+ // The `{ '/': string }` shape is shared with non-DXN IPLD-style refs (e.g. CIDs);
64
+ // an unparseable string would otherwise crash the whole `JSON.stringify`.
65
+ // Treat any parse miss as "leave as-is" rather than propagating.
66
+ const dxnString = value['/'];
67
+ if (!dxnString.startsWith('dxn:') && !dxnString.startsWith('echo:')) {
68
+ return value;
69
+ }
70
+
71
+ let echoUri: string | undefined;
72
+ try {
73
+ const parsed = EchoURI.tryParse(dxnString);
74
+ echoUri = parsed ? EchoURI.getObjectId(parsed) : undefined;
75
+ } catch {
76
+ return value;
77
+ }
78
+
79
+ if (!echoUri) {
80
+ return value;
81
+ }
82
+ const target = db.getObjectById(echoUri);
83
+ if (!target) {
84
+ return value;
85
+ }
86
+
87
+ const encoded = toJson(target);
88
+ if (encoded != null && typeof encoded === 'object') {
89
+ // Children of the resolved target are one hop deeper.
90
+ hops.set(encoded as object, parentHops + 1);
91
+ }
92
+ return encoded;
93
+ }
94
+
95
+ // Pass-through object: children inherit the parent's hop count (this branch doesn't burn
96
+ // budget).
97
+ if (value != null && typeof value === 'object') {
98
+ hops.set(value, parentHops);
99
+ }
100
+
101
+ return value;
102
+ };
103
+ };
package/src/JsonSchema.ts CHANGED
@@ -2,15 +2,25 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ // @import-as-namespace
6
+
5
7
  import type * as Schema from 'effect/Schema';
6
8
 
7
- import { JsonSchemaType } from './internal';
9
+ import * as jsonSchemaInternal from './internal/JsonSchema';
10
+
11
+ /**
12
+ * Decode JSON Schema to Effect Schema.
13
+ */
14
+ export const toEffectSchema = jsonSchemaInternal.toEffectSchema;
8
15
 
9
- export { toEffectSchema, toJsonSchema } from './internal';
16
+ /**
17
+ * Encode Effect Schema to JSON Schema.
18
+ */
19
+ export const toJsonSchema = jsonSchemaInternal.toJsonSchema;
10
20
 
11
21
  /**
12
22
  * Serializable JsonSchema type definition.
13
23
  */
14
- export type JsonSchema = JsonSchemaType;
24
+ export type JsonSchema = jsonSchemaInternal.JsonSchemaType;
15
25
 
16
- export const JsonSchema: Schema.Schema<JsonSchemaType> = JsonSchemaType;
26
+ export const JsonSchema: Schema.Schema<jsonSchemaInternal.JsonSchemaType> = jsonSchemaInternal.JsonSchemaType;
package/src/Key.ts CHANGED
@@ -5,4 +5,4 @@
5
5
  // TODO(wittjosiah): Should this be a subset of Type?
6
6
 
7
7
  export { ForeignKey } from '@dxos/echo-protocol';
8
- export { SpaceId, ObjectId } from '@dxos/keys';
8
+ export { EchoURI, ObjectId, SpaceId, URI } from '@dxos/keys';