@dxos/echo 0.8.4-staging.ac66bdf99f → 0.9.0

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 (437) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +7 -7
  3. package/dist/lib/neutral/Annotation.mjs +37 -6
  4. package/dist/lib/neutral/Database.mjs +6 -17
  5. package/dist/lib/neutral/Entity.mjs +31 -20
  6. package/dist/lib/neutral/Err.mjs +3 -3
  7. package/dist/lib/neutral/Feed.mjs +23 -19
  8. package/dist/lib/neutral/Filter.mjs +13 -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 +11 -10
  13. package/dist/lib/neutral/Obj.mjs +29 -20
  14. package/dist/lib/neutral/Order.mjs +7 -3
  15. package/dist/lib/neutral/Query.mjs +17 -17
  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/Relation.mjs +28 -25
  20. package/dist/lib/neutral/Scope.mjs +12 -0
  21. package/dist/lib/neutral/Tag.mjs +17 -14
  22. package/dist/lib/neutral/Type.mjs +54 -26
  23. package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-35INCYOE.mjs} +1 -1
  24. package/dist/lib/neutral/chunk-35INCYOE.mjs.map +7 -0
  25. package/dist/lib/neutral/chunk-3PBP4V4O.mjs +101 -0
  26. package/dist/lib/neutral/chunk-3PBP4V4O.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-4ZUHOTCG.mjs +184 -0
  28. package/dist/lib/neutral/chunk-4ZUHOTCG.mjs.map +7 -0
  29. package/dist/lib/neutral/chunk-5SMDBFVB.mjs +108 -0
  30. package/dist/lib/neutral/chunk-5SMDBFVB.mjs.map +7 -0
  31. package/dist/lib/neutral/{chunk-OS35K56T.mjs → chunk-5SUJPHAE.mjs} +3 -3
  32. package/dist/lib/neutral/{chunk-OS35K56T.mjs.map → chunk-5SUJPHAE.mjs.map} +2 -2
  33. package/dist/lib/neutral/{chunk-GZQTCRJB.mjs → chunk-6M2Z6WBH.mjs} +22 -2
  34. package/dist/lib/neutral/chunk-6M2Z6WBH.mjs.map +7 -0
  35. package/dist/lib/neutral/{chunk-V36VO5SS.mjs → chunk-6YDI3J37.mjs} +32 -40
  36. package/dist/lib/neutral/chunk-6YDI3J37.mjs.map +7 -0
  37. package/dist/lib/neutral/{chunk-MOR5ERFM.mjs → chunk-7FPIAJIV.mjs} +701 -1256
  38. package/dist/lib/neutral/chunk-7FPIAJIV.mjs.map +7 -0
  39. package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7LOUAPYZ.mjs} +9 -5
  40. package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +7 -0
  41. package/dist/lib/neutral/{chunk-JUXPFOEI.mjs → chunk-7PI7C4EF.mjs} +48 -88
  42. package/dist/lib/neutral/chunk-7PI7C4EF.mjs.map +7 -0
  43. package/dist/lib/neutral/{chunk-UBEZSGXY.mjs → chunk-BBFJWWAV.mjs} +6 -6
  44. package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +7 -0
  45. package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-EVK6XBXO.mjs} +16 -2
  46. package/dist/lib/neutral/chunk-EVK6XBXO.mjs.map +7 -0
  47. package/dist/lib/neutral/{chunk-7RO7CPBZ.mjs → chunk-IGK6FN65.mjs} +2 -2
  48. package/dist/lib/neutral/{chunk-HBUZJNZO.mjs → chunk-LWXVKPPW.mjs} +94 -99
  49. package/dist/lib/neutral/chunk-LWXVKPPW.mjs.map +7 -0
  50. package/dist/lib/neutral/{chunk-BVOFLCVF.mjs → chunk-MZ7K3MLL.mjs} +9 -6
  51. package/dist/lib/neutral/chunk-MZ7K3MLL.mjs.map +7 -0
  52. package/dist/lib/neutral/{chunk-TBKX6JQO.mjs → chunk-O6BH7EPN.mjs} +30 -3
  53. package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +7 -0
  54. package/dist/lib/neutral/{chunk-EAMSSLZC.mjs → chunk-QQIYS74I.mjs} +83 -46
  55. package/dist/lib/neutral/chunk-QQIYS74I.mjs.map +7 -0
  56. package/dist/lib/neutral/chunk-R5W6DXR4.mjs +678 -0
  57. package/dist/lib/neutral/chunk-R5W6DXR4.mjs.map +7 -0
  58. package/dist/lib/neutral/{chunk-WAK4DMFV.mjs → chunk-RIVWNMSF.mjs} +12 -7
  59. package/dist/lib/neutral/chunk-RIVWNMSF.mjs.map +7 -0
  60. package/dist/lib/neutral/{chunk-T6W2LEZU.mjs → chunk-SBVFRTST.mjs} +73 -38
  61. package/dist/lib/neutral/chunk-SBVFRTST.mjs.map +7 -0
  62. package/dist/lib/neutral/chunk-T6E37YIP.mjs +251 -0
  63. package/dist/lib/neutral/chunk-T6E37YIP.mjs.map +7 -0
  64. package/dist/lib/neutral/{chunk-DQYLD2RB.mjs → chunk-TFEWTY5A.mjs} +155 -129
  65. package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +7 -0
  66. package/dist/lib/neutral/{chunk-B4BASU6W.mjs → chunk-TYGKCRMK.mjs} +85 -76
  67. package/dist/lib/neutral/chunk-TYGKCRMK.mjs.map +7 -0
  68. package/dist/lib/neutral/{chunk-4OIBYSXE.mjs → chunk-UUP46KUQ.mjs} +78 -32
  69. package/dist/lib/neutral/chunk-UUP46KUQ.mjs.map +7 -0
  70. package/dist/lib/neutral/chunk-WISOH2XH.mjs +36 -0
  71. package/dist/lib/neutral/chunk-WISOH2XH.mjs.map +7 -0
  72. package/dist/lib/neutral/{chunk-G3IQMKF7.mjs → chunk-WTQJHC75.mjs} +111 -112
  73. package/dist/lib/neutral/chunk-WTQJHC75.mjs.map +7 -0
  74. package/dist/lib/neutral/chunk-WU3GIANS.mjs +31 -0
  75. package/dist/lib/neutral/chunk-WU3GIANS.mjs.map +7 -0
  76. package/dist/lib/neutral/{chunk-TU3GW67D.mjs → chunk-ZGNNFYHS.mjs} +40 -40
  77. package/dist/lib/neutral/chunk-ZGNNFYHS.mjs.map +7 -0
  78. package/dist/lib/neutral/index.mjs +47 -41
  79. package/dist/lib/neutral/internal/index.mjs +137 -72
  80. package/dist/lib/neutral/meta.json +1 -1
  81. package/dist/lib/neutral/testing/index.mjs +261 -178
  82. package/dist/lib/neutral/testing/index.mjs.map +4 -4
  83. package/dist/types/src/Annotation.d.ts +108 -4
  84. package/dist/types/src/Annotation.d.ts.map +1 -1
  85. package/dist/types/src/Annotation.test.d.ts +2 -0
  86. package/dist/types/src/Annotation.test.d.ts.map +1 -0
  87. package/dist/types/src/Collection.d.ts +2 -3
  88. package/dist/types/src/Collection.d.ts.map +1 -1
  89. package/dist/types/src/Database.d.ts +56 -49
  90. package/dist/types/src/Database.d.ts.map +1 -1
  91. package/dist/types/src/Dataset.d.ts +16 -6
  92. package/dist/types/src/Dataset.d.ts.map +1 -1
  93. package/dist/types/src/Entity.d.ts +101 -28
  94. package/dist/types/src/Entity.d.ts.map +1 -1
  95. package/dist/types/src/Err.d.ts +27 -27
  96. package/dist/types/src/Err.d.ts.map +1 -1
  97. package/dist/types/src/Feed.d.ts +66 -19
  98. package/dist/types/src/Feed.d.ts.map +1 -1
  99. package/dist/types/src/Filter.d.ts +38 -12
  100. package/dist/types/src/Filter.d.ts.map +1 -1
  101. package/dist/types/src/Format.d.ts +0 -2
  102. package/dist/types/src/Format.d.ts.map +1 -1
  103. package/dist/types/src/Hypergraph.d.ts +14 -9
  104. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  105. package/dist/types/src/Json.d.ts +33 -0
  106. package/dist/types/src/Json.d.ts.map +1 -0
  107. package/dist/types/src/Json.test.d.ts +2 -0
  108. package/dist/types/src/Json.test.d.ts.map +1 -0
  109. package/dist/types/src/JsonSchema.d.ts +2 -2
  110. package/dist/types/src/JsonSchema.d.ts.map +1 -1
  111. package/dist/types/src/Key.d.ts +1 -1
  112. package/dist/types/src/Key.d.ts.map +1 -1
  113. package/dist/types/src/Migration.d.ts +26 -11
  114. package/dist/types/src/Migration.d.ts.map +1 -1
  115. package/dist/types/src/Obj.d.ts +104 -61
  116. package/dist/types/src/Obj.d.ts.map +1 -1
  117. package/dist/types/src/Order.d.ts +10 -0
  118. package/dist/types/src/Order.d.ts.map +1 -1
  119. package/dist/types/src/Query.d.ts +34 -12
  120. package/dist/types/src/Query.d.ts.map +1 -1
  121. package/dist/types/src/QueryResult.d.ts +21 -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 +73 -41
  128. package/dist/types/src/Relation.d.ts.map +1 -1
  129. package/dist/types/src/Scope.d.ts +35 -0
  130. package/dist/types/src/Scope.d.ts.map +1 -0
  131. package/dist/types/src/Tag.d.ts +21 -5
  132. package/dist/types/src/Tag.d.ts.map +1 -1
  133. package/dist/types/src/Type.d.ts +362 -95
  134. package/dist/types/src/Type.d.ts.map +1 -1
  135. package/dist/types/src/View.d.ts +9 -12
  136. package/dist/types/src/View.d.ts.map +1 -1
  137. package/dist/types/src/exemplars.test.d.ts +2 -0
  138. package/dist/types/src/exemplars.test.d.ts.map +1 -0
  139. package/dist/types/src/index.d.ts +4 -3
  140. package/dist/types/src/index.d.ts.map +1 -1
  141. package/dist/types/src/internal/Annotation/annotations.d.ts +79 -38
  142. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
  143. package/dist/types/src/internal/Annotation/dictionary.d.ts +24 -0
  144. package/dist/types/src/internal/Annotation/dictionary.d.ts.map +1 -0
  145. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +14 -0
  146. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -0
  147. package/dist/types/src/internal/Annotation/index.d.ts +4 -2
  148. package/dist/types/src/internal/Annotation/index.d.ts.map +1 -1
  149. package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -1
  150. package/dist/types/src/internal/Annotation/util.d.ts +14 -5
  151. package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
  152. package/dist/types/src/internal/Entity/api.d.ts +17 -3
  153. package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
  154. package/dist/types/src/internal/Entity/entity.d.ts +72 -8
  155. package/dist/types/src/internal/Entity/entity.d.ts.map +1 -1
  156. package/dist/types/src/internal/Entity/guard.d.ts +10 -0
  157. package/dist/types/src/internal/Entity/guard.d.ts.map +1 -0
  158. package/dist/types/src/internal/Entity/index.d.ts +2 -0
  159. package/dist/types/src/internal/Entity/index.d.ts.map +1 -1
  160. package/dist/types/src/internal/Entity/model.d.ts +21 -17
  161. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  162. package/dist/types/src/internal/Entity/object.d.ts +3 -3
  163. package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
  164. package/dist/types/src/internal/Entity/relation.d.ts +30 -7
  165. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
  166. package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
  167. package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
  168. package/dist/types/src/internal/Entity/type-uri.d.ts +24 -0
  169. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
  170. package/dist/types/src/internal/Entity/version.d.ts.map +1 -1
  171. package/dist/types/src/internal/Format/date.d.ts.map +1 -1
  172. package/dist/types/src/internal/Format/format.d.ts +3 -2
  173. package/dist/types/src/internal/Format/format.d.ts.map +1 -1
  174. package/dist/types/src/internal/Format/index.d.ts +2 -2
  175. package/dist/types/src/internal/Format/index.d.ts.map +1 -1
  176. package/dist/types/src/internal/Format/number.d.ts.map +1 -1
  177. package/dist/types/src/internal/Format/object.d.ts +3 -1
  178. package/dist/types/src/internal/Format/object.d.ts.map +1 -1
  179. package/dist/types/src/internal/Format/types.d.ts.map +1 -1
  180. package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -1
  181. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts +34 -34
  182. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
  183. package/dist/types/src/internal/JsonSchema/json-schema.d.ts +3 -2
  184. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
  185. package/dist/types/src/internal/Obj/atoms.d.ts +38 -0
  186. package/dist/types/src/internal/Obj/atoms.d.ts.map +1 -0
  187. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
  188. package/dist/types/src/internal/Obj/common.d.ts.map +1 -1
  189. package/dist/types/src/internal/Obj/create-object.d.ts +12 -12
  190. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
  191. package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -1
  192. package/dist/types/src/internal/Obj/index.d.ts +1 -1
  193. package/dist/types/src/internal/Obj/index.d.ts.map +1 -1
  194. package/dist/types/src/internal/Obj/json-serializer.d.ts +8 -8
  195. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
  196. package/dist/types/src/internal/Obj/set-value.d.ts +1 -1
  197. package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -1
  198. package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -1
  199. package/dist/types/src/internal/Obj/typed-object.d.ts +1 -1
  200. package/dist/types/src/internal/Query/index.d.ts +2 -0
  201. package/dist/types/src/internal/Query/index.d.ts.map +1 -0
  202. package/dist/types/src/internal/{Query.d.ts → Query/pretty.d.ts} +1 -1
  203. package/dist/types/src/internal/Query/pretty.d.ts.map +1 -0
  204. package/dist/types/src/internal/Ref/atoms.d.ts +10 -0
  205. package/dist/types/src/internal/Ref/atoms.d.ts.map +1 -0
  206. package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
  207. package/dist/types/src/internal/Ref/ref.d.ts +50 -19
  208. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
  209. package/dist/types/src/internal/Ref/utils.d.ts +8 -0
  210. package/dist/types/src/internal/Ref/utils.d.ts.map +1 -0
  211. package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
  212. package/dist/types/src/internal/Type/index.d.ts +1 -2
  213. package/dist/types/src/internal/Type/index.d.ts.map +1 -1
  214. package/dist/types/src/internal/Type/manipulation.d.ts +0 -1
  215. package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
  216. package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
  217. package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
  218. package/dist/types/src/internal/common/api/meta.d.ts +14 -11
  219. package/dist/types/src/internal/common/api/meta.d.ts.map +1 -1
  220. package/dist/types/src/internal/common/proxy/change-context.d.ts +1 -1
  221. package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -1
  222. package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -1
  223. package/dist/types/src/internal/common/proxy/errors.d.ts +1 -1
  224. package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -1
  225. package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -1
  226. package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -1
  227. package/dist/types/src/internal/common/proxy/make-object.d.ts +11 -5
  228. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
  229. package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -1
  230. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
  231. package/dist/types/src/internal/common/proxy/reactive-array.d.ts +1 -1
  232. package/dist/types/src/internal/common/proxy/reactive.d.ts +1 -1
  233. package/dist/types/src/internal/common/proxy/reactive.d.ts.map +1 -1
  234. package/dist/types/src/internal/common/proxy/reactive.test.d.ts +2 -0
  235. package/dist/types/src/internal/common/proxy/reactive.test.d.ts.map +1 -0
  236. package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
  237. package/dist/types/src/internal/common/proxy/typed-handler.d.ts +18 -2
  238. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
  239. package/dist/types/src/internal/common/types/base.d.ts +4 -4
  240. package/dist/types/src/internal/common/types/base.d.ts.map +1 -1
  241. package/dist/types/src/internal/common/types/entity.d.ts +62 -5
  242. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
  243. package/dist/types/src/internal/common/types/index.d.ts +1 -1
  244. package/dist/types/src/internal/common/types/index.d.ts.map +1 -1
  245. package/dist/types/src/internal/common/types/meta.d.ts +33 -12
  246. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
  247. package/dist/types/src/internal/common/types/model-symbols.d.ts +15 -4
  248. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -1
  249. package/dist/types/src/internal/common/types/typename.d.ts +7 -0
  250. package/dist/types/src/internal/common/types/typename.d.ts.map +1 -1
  251. package/dist/types/src/internal/common/types/version.d.ts +1 -1
  252. package/dist/types/src/internal/common/types/well-known-types.d.ts +11 -0
  253. package/dist/types/src/internal/common/types/well-known-types.d.ts.map +1 -0
  254. package/dist/types/src/internal/index.d.ts +2 -2
  255. package/dist/types/src/internal/index.d.ts.map +1 -1
  256. package/dist/types/src/testing/index.d.ts +1 -0
  257. package/dist/types/src/testing/index.d.ts.map +1 -1
  258. package/dist/types/src/testing/registry.d.ts +9 -0
  259. package/dist/types/src/testing/registry.d.ts.map +1 -0
  260. package/dist/types/src/testing/test-data.d.ts +8 -8
  261. package/dist/types/src/testing/test-data.d.ts.map +1 -1
  262. package/dist/types/src/testing/test-schema.d.ts +83 -89
  263. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  264. package/dist/types/src/testing/util.d.ts +5 -3
  265. package/dist/types/src/testing/util.d.ts.map +1 -1
  266. package/dist/types/tsconfig.tsbuildinfo +1 -1
  267. package/package.json +26 -24
  268. package/src/Annotation.test.ts +439 -0
  269. package/src/Annotation.ts +158 -4
  270. package/src/Collection.ts +5 -9
  271. package/src/Database.ts +93 -100
  272. package/src/Dataset.ts +10 -2
  273. package/src/Entity.test.ts +116 -6
  274. package/src/Entity.ts +134 -32
  275. package/src/Err.ts +4 -4
  276. package/src/Feed.ts +92 -44
  277. package/src/Filter.ts +70 -40
  278. package/src/Format.ts +0 -4
  279. package/src/Hypergraph.ts +14 -9
  280. package/src/Json.test.ts +175 -0
  281. package/src/Json.ts +103 -0
  282. package/src/Key.ts +1 -1
  283. package/src/Migration.ts +39 -19
  284. package/src/Obj.test.ts +122 -20
  285. package/src/Obj.ts +168 -91
  286. package/src/Order.ts +22 -0
  287. package/src/Query.test.ts +183 -154
  288. package/src/Query.ts +172 -85
  289. package/src/QueryResult.ts +26 -0
  290. package/src/Ref.ts +22 -4
  291. package/src/Registry.ts +155 -0
  292. package/src/Relation.test.ts +10 -10
  293. package/src/Relation.ts +116 -69
  294. package/src/Scope.ts +50 -0
  295. package/src/Tag.md +88 -0
  296. package/src/Tag.ts +49 -6
  297. package/src/Type.test.ts +223 -18
  298. package/src/Type.ts +609 -131
  299. package/src/View.ts +14 -23
  300. package/src/exemplars.test.ts +21 -0
  301. package/src/index.ts +4 -4
  302. package/src/internal/Annotation/annotations.test.ts +31 -11
  303. package/src/internal/Annotation/annotations.ts +143 -111
  304. package/src/internal/Annotation/dictionary.ts +47 -0
  305. package/src/internal/Annotation/entity-dictionary.ts +74 -0
  306. package/src/internal/Annotation/index.ts +4 -2
  307. package/src/internal/Annotation/util.ts +17 -8
  308. package/src/internal/Entity/api.ts +54 -7
  309. package/src/internal/Entity/entity.ts +196 -47
  310. package/src/internal/Entity/guard.ts +26 -0
  311. package/src/internal/Entity/index.ts +2 -0
  312. package/src/internal/Entity/model.ts +38 -28
  313. package/src/internal/Entity/object.ts +21 -5
  314. package/src/internal/Entity/relation.ts +68 -34
  315. package/src/internal/Entity/type-kind.ts +75 -0
  316. package/src/internal/Entity/type-uri.ts +92 -0
  317. package/src/internal/Entity/util.ts +9 -9
  318. package/src/internal/Format/date.ts +0 -4
  319. package/src/internal/Format/format.test.ts +21 -0
  320. package/src/internal/Format/index.ts +2 -3
  321. package/src/internal/Format/object.ts +21 -4
  322. package/src/internal/Format/types.ts +1 -1
  323. package/src/internal/JsonSchema/annotations.ts +1 -1
  324. package/src/internal/JsonSchema/json-schema-type.ts +4 -4
  325. package/src/internal/JsonSchema/json-schema.test.ts +71 -145
  326. package/src/internal/JsonSchema/json-schema.ts +49 -35
  327. package/src/internal/Obj/atoms.ts +244 -0
  328. package/src/internal/Obj/clone.ts +9 -4
  329. package/src/internal/Obj/create-object.test.ts +12 -10
  330. package/src/internal/Obj/create-object.ts +68 -22
  331. package/src/internal/Obj/index.ts +1 -1
  332. package/src/internal/Obj/inspect.ts +5 -3
  333. package/src/internal/Obj/json-serializer.test.ts +101 -22
  334. package/src/internal/Obj/json-serializer.ts +89 -33
  335. package/src/internal/Obj/set-value.test.ts +22 -45
  336. package/src/internal/Obj/set-value.ts +12 -19
  337. package/src/internal/Obj/snapshot.ts +13 -4
  338. package/src/internal/Obj/typed-object.test.ts +9 -11
  339. package/src/internal/Obj/typed-object.ts +1 -1
  340. package/src/internal/Query/index.ts +5 -0
  341. package/src/internal/{Query.ts → Query/pretty.ts} +40 -12
  342. package/src/internal/Ref/atoms.ts +20 -0
  343. package/src/internal/Ref/ref-array.ts +3 -3
  344. package/src/internal/Ref/ref.test.ts +18 -27
  345. package/src/internal/Ref/ref.ts +137 -59
  346. package/src/internal/Ref/utils.ts +45 -0
  347. package/src/internal/Type/compose.test.ts +3 -1
  348. package/src/internal/Type/index.ts +1 -2
  349. package/src/internal/Type/manipulation.ts +0 -25
  350. package/src/internal/Type/type-schema.ts +60 -0
  351. package/src/internal/common/README.md +2 -2
  352. package/src/internal/common/api/meta.ts +19 -17
  353. package/src/internal/common/proxy/change-context.ts +1 -1
  354. package/src/internal/common/proxy/change.test.ts +91 -83
  355. package/src/internal/common/proxy/errors.ts +2 -2
  356. package/src/internal/common/proxy/handler.test.ts +1 -1
  357. package/src/internal/common/proxy/json-serializer.ts +27 -16
  358. package/src/internal/common/proxy/make-object.ts +44 -20
  359. package/src/internal/common/proxy/ownership.ts +2 -2
  360. package/src/internal/common/proxy/reactive-array.ts +1 -1
  361. package/src/internal/common/proxy/reactive.test.ts +54 -0
  362. package/src/internal/common/proxy/reactive.ts +11 -2
  363. package/src/internal/common/proxy/schema.test.ts +48 -86
  364. package/src/internal/common/proxy/typed-handler.test.ts +12 -11
  365. package/src/internal/common/proxy/typed-handler.ts +78 -16
  366. package/src/internal/common/proxy/typed-object.test.ts +16 -28
  367. package/src/internal/common/types/base.ts +4 -4
  368. package/src/internal/common/types/entity.ts +80 -1
  369. package/src/internal/common/types/index.ts +6 -1
  370. package/src/internal/common/types/meta.ts +62 -20
  371. package/src/internal/common/types/model-symbols.ts +24 -4
  372. package/src/internal/common/types/typename.ts +39 -3
  373. package/src/internal/common/types/well-known-types.ts +15 -0
  374. package/src/internal/index.ts +6 -4
  375. package/src/testing/api.test.ts +15 -9
  376. package/src/testing/index.ts +1 -0
  377. package/src/testing/registry.ts +44 -0
  378. package/src/testing/test-data.ts +159 -99
  379. package/src/testing/test-schema.ts +22 -58
  380. package/src/testing/util.ts +14 -11
  381. package/dist/lib/neutral/Extension.mjs +0 -18
  382. package/dist/lib/neutral/SchemaRegistry.mjs +0 -2
  383. package/dist/lib/neutral/chunk-2KHZ36F5.mjs +0 -361
  384. package/dist/lib/neutral/chunk-2KHZ36F5.mjs.map +0 -7
  385. package/dist/lib/neutral/chunk-4OIBYSXE.mjs.map +0 -7
  386. package/dist/lib/neutral/chunk-4P3IXBLT.mjs +0 -45
  387. package/dist/lib/neutral/chunk-4P3IXBLT.mjs.map +0 -7
  388. package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
  389. package/dist/lib/neutral/chunk-B4BASU6W.mjs.map +0 -7
  390. package/dist/lib/neutral/chunk-BNCCGLJN.mjs +0 -7
  391. package/dist/lib/neutral/chunk-BNCCGLJN.mjs.map +0 -7
  392. package/dist/lib/neutral/chunk-BVOFLCVF.mjs.map +0 -7
  393. package/dist/lib/neutral/chunk-DQYLD2RB.mjs.map +0 -7
  394. package/dist/lib/neutral/chunk-EAMSSLZC.mjs.map +0 -7
  395. package/dist/lib/neutral/chunk-G3IQMKF7.mjs.map +0 -7
  396. package/dist/lib/neutral/chunk-GZQTCRJB.mjs.map +0 -7
  397. package/dist/lib/neutral/chunk-HBUZJNZO.mjs.map +0 -7
  398. package/dist/lib/neutral/chunk-JUXPFOEI.mjs.map +0 -7
  399. package/dist/lib/neutral/chunk-MOR5ERFM.mjs.map +0 -7
  400. package/dist/lib/neutral/chunk-OMUPQMLR.mjs.map +0 -7
  401. package/dist/lib/neutral/chunk-PHU22NLC.mjs +0 -136
  402. package/dist/lib/neutral/chunk-PHU22NLC.mjs.map +0 -7
  403. package/dist/lib/neutral/chunk-ROG4RXXL.mjs +0 -97
  404. package/dist/lib/neutral/chunk-ROG4RXXL.mjs.map +0 -7
  405. package/dist/lib/neutral/chunk-T6W2LEZU.mjs.map +0 -7
  406. package/dist/lib/neutral/chunk-TBKX6JQO.mjs.map +0 -7
  407. package/dist/lib/neutral/chunk-TU3GW67D.mjs.map +0 -7
  408. package/dist/lib/neutral/chunk-UBEZSGXY.mjs.map +0 -7
  409. package/dist/lib/neutral/chunk-UI6MWK5W.mjs.map +0 -7
  410. package/dist/lib/neutral/chunk-V36VO5SS.mjs.map +0 -7
  411. package/dist/lib/neutral/chunk-WAK4DMFV.mjs.map +0 -7
  412. package/dist/lib/neutral/chunk-YAHXAYOW.mjs +0 -56
  413. package/dist/lib/neutral/chunk-YAHXAYOW.mjs.map +0 -7
  414. package/dist/lib/neutral/chunk-YS6Q3XAD.mjs +0 -50
  415. package/dist/lib/neutral/chunk-YS6Q3XAD.mjs.map +0 -7
  416. package/dist/types/src/Extension.d.ts +0 -80
  417. package/dist/types/src/Extension.d.ts.map +0 -1
  418. package/dist/types/src/Extension.test.d.ts +0 -2
  419. package/dist/types/src/Extension.test.d.ts.map +0 -1
  420. package/dist/types/src/SchemaRegistry.d.ts +0 -84
  421. package/dist/types/src/SchemaRegistry.d.ts.map +0 -1
  422. package/dist/types/src/internal/Obj/ids.d.ts +0 -6
  423. package/dist/types/src/internal/Obj/ids.d.ts.map +0 -1
  424. package/dist/types/src/internal/Query.d.ts.map +0 -1
  425. package/dist/types/src/internal/Type/echo-schema.d.ts +0 -181
  426. package/dist/types/src/internal/Type/echo-schema.d.ts.map +0 -1
  427. package/dist/types/src/internal/Type/persistent-schema.d.ts +0 -20
  428. package/dist/types/src/internal/Type/persistent-schema.d.ts.map +0 -1
  429. package/src/Extension.test.ts +0 -235
  430. package/src/Extension.ts +0 -122
  431. package/src/SchemaRegistry.ts +0 -106
  432. package/src/internal/Obj/ids.ts +0 -12
  433. package/src/internal/Type/echo-schema.ts +0 -423
  434. package/src/internal/Type/persistent-schema.ts +0 -33
  435. /package/dist/lib/neutral/{Extension.mjs.map → Registry.mjs.map} +0 -0
  436. /package/dist/lib/neutral/{SchemaRegistry.mjs.map → Scope.mjs.map} +0 -0
  437. /package/dist/lib/neutral/{chunk-7RO7CPBZ.mjs.map → chunk-IGK6FN65.mjs.map} +0 -0
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import type * as Atom from '@effect-atom/atom/Atom';
5
6
  import * as Effect from 'effect/Effect';
6
7
  import * as Equal from 'effect/Equal';
7
8
  import * as Hash from 'effect/Hash';
@@ -16,12 +17,19 @@ import { Event } from '@dxos/async';
16
17
  import { type CustomInspectFunction, inspectCustom } from '@dxos/debug';
17
18
  import { EncodedReference } from '@dxos/echo-protocol';
18
19
  import { assertArgument, invariant } from '@dxos/invariant';
19
- import { DXN, ObjectId } from '@dxos/keys';
20
+ import { DXN, EID, EntityId, type URI } from '@dxos/keys';
20
21
 
21
22
  import * as Database from '../../Database';
22
- import { ReferenceAnnotationId, getSchemaDXN, getTypeAnnotation, getTypeIdentifierAnnotation } from '../Annotation';
23
- import type { AnyEntity, AnyProperties } from '../common/types';
23
+ import type * as Type from '../../Type';
24
+ import {
25
+ ReferenceAnnotationId,
26
+ getSchemaURI,
27
+ getTypeAnnotation,
28
+ getTypeIdentifierAnnotation,
29
+ } from '../Annotation/annotations';
30
+ import { type AnyEntity, type AnyProperties, type UnknownTypeSchema, getStaticTypeSchema } from '../common/types';
24
31
  import { type JsonSchemaType } from '../JsonSchema';
32
+ import * as RefAtoms from './atoms';
25
33
 
26
34
  /**
27
35
  * The `$id` and `$ref` fields for an ECHO reference schema.
@@ -31,7 +39,9 @@ export const JSON_SCHEMA_ECHO_REF_ID = '/schemas/echo/ref';
31
39
  export const getSchemaReference = (property: JsonSchemaType): { typename: string } | undefined => {
32
40
  const { $id, reference: { schema: { $ref } = {} } = {} } = property;
33
41
  if ($id === JSON_SCHEMA_ECHO_REF_ID && $ref) {
34
- return { typename: DXN.parse($ref).typename };
42
+ const parsed = DXN.tryMake($ref);
43
+ const typename = parsed ? DXN.getName(parsed) : undefined;
44
+ return typename ? { typename } : undefined;
35
45
  }
36
46
  };
37
47
 
@@ -40,7 +50,7 @@ export const createSchemaReference = (typename: string): Types.DeepMutable<JsonS
40
50
  $id: JSON_SCHEMA_ECHO_REF_ID,
41
51
  reference: {
42
52
  schema: {
43
- $ref: DXN.fromTypename(typename).toString(),
53
+ $ref: DXN.make(typename),
44
54
  },
45
55
  },
46
56
  };
@@ -82,7 +92,27 @@ export interface RefSchema<T extends AnyEntity> extends Schema.SchemaClass<Ref<T
82
92
  * Type of the `Ref` function and extra methods attached to it.
83
93
  */
84
94
  export interface RefFn {
85
- <S extends Schema.Schema.Any>(schema: S): RefSchema<Schema.Schema.Type<S>>;
95
+ // A reference target is a `Type.AnyEntity` entity (the canonical Option B
96
+ // input) or one of the well-known "any object" / "any relation" branded
97
+ // schemas (`Obj.Unknown` / `Relation.Unknown`). Arbitrary raw schemas are
98
+ // rejected.
99
+ //
100
+ // Referencing a type-kind entity (a meta-schema, e.g. `Type.Type`) yields a
101
+ // reference to a stored schema record; its loaded target is any registered
102
+ // entity (`Type.AnyEntity`), since a stored object/relation schema is itself a
103
+ // `Type.Type` record. Referencing an object/relation type yields a reference
104
+ // to an instance of that type.
105
+ <S extends Type.AnyEntity | UnknownTypeSchema<any, any> = Type.AnyEntity>(
106
+ schema: S,
107
+ ): RefSchema<
108
+ S extends Type.AnyType
109
+ ? Type.AnyEntity
110
+ : S extends Type.AnyObj | Type.AnyRelation
111
+ ? Type.InstanceType<S>
112
+ : S extends UnknownTypeSchema<infer A, any>
113
+ ? A
114
+ : never
115
+ >;
86
116
 
87
117
  /**
88
118
  * @returns True if the object is a reference.
@@ -92,7 +122,7 @@ export interface RefFn {
92
122
  /**
93
123
  * @returns True if the reference points to the given object id.
94
124
  */
95
- hasObjectId: (id: ObjectId) => (ref: Ref<any>) => boolean;
125
+ hasEntityId: (id: EntityId) => (ref: Ref<any>) => boolean;
96
126
 
97
127
  /**
98
128
  * @returns True if the schema is a reference schema.
@@ -111,15 +141,19 @@ export interface RefFn {
111
141
  make: <T extends AnyEntity>(object: T) => Ref<T>;
112
142
 
113
143
  /**
114
- * Constructs a reference that points to the object specified by the provided DXN.
144
+ * Constructs a reference that points to the object specified by the provided URI
145
+ * (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).
115
146
  */
116
- fromDXN: (dxn: DXN) => Ref<any>;
147
+ fromURI: (uri: URI.URI) => Ref<any>;
117
148
  }
118
149
 
119
150
  /**
120
151
  * Schema builder for references.
121
152
  */
122
- export const Ref: RefFn = <S extends Schema.Schema.Any>(schema: S): RefSchema<Schema.Schema.Type<S>> => {
153
+ export const Ref: RefFn = (input: any): RefSchema<any> => {
154
+ // `Type.Type` entities carry their source schema on the hidden slot; the
155
+ // branded `Obj.Unknown` / `Relation.Unknown` schemas are used directly.
156
+ const schema = getStaticTypeSchema(input) ?? input;
123
157
  assertArgument(Schema.isSchema(schema), 'schema', 'Must call with an instance of effect-schema');
124
158
  const annotation = getTypeAnnotation(schema);
125
159
  if (annotation == null) {
@@ -135,9 +169,9 @@ export const Ref: RefFn = <S extends Schema.Schema.Any>(schema: S): RefSchema<Sc
135
169
  */
136
170
  export interface Ref<T> extends Pipeable.Pipeable {
137
171
  /**
138
- * Target object DXN.
172
+ * Target URI (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).
139
173
  */
140
- get dxn(): DXN;
174
+ get uri(): URI.URI;
141
175
 
142
176
  /**
143
177
  * Returns true if the reference has a target available (inlined or resolver set).
@@ -164,6 +198,16 @@ export interface Ref<T> extends Pipeable.Pipeable {
164
198
 
165
199
  tryLoad(): Promise<T | undefined>;
166
200
 
201
+ /**
202
+ * Subscribe to the ref's resolution event.
203
+ * The callback fires when the target object becomes available in the working set
204
+ * (e.g. when its document is loaded after sibling-client mutation).
205
+ * Note: the resolver only schedules a notification when the target is requested
206
+ * via {@link target} while it is not yet loaded.
207
+ * @returns Function that unsubscribes the callback.
208
+ */
209
+ onResolved(callback: () => void): () => void;
210
+
167
211
  /**
168
212
  * Do not inline the target object in the reference.
169
213
  * Makes .target unavailable unless the reference is connected to a database context.
@@ -177,6 +221,13 @@ export interface Ref<T> extends Pipeable.Pipeable {
177
221
  */
178
222
  noInline(): Ref<T>;
179
223
 
224
+ /**
225
+ * Read-only atom for the ref target.
226
+ * Resolves once when the target loads; does NOT subscribe to target object mutations.
227
+ * Use `Obj.atom(ref)` if you need reactive snapshots that update on every object mutation.
228
+ */
229
+ get atom(): Atom.Atom<T | undefined>;
230
+
180
231
  /**
181
232
  * Serializes the reference to a JSON object.
182
233
  * The serialization format is compatible with the IPLD-style encoded references.
@@ -205,7 +256,10 @@ Ref.isRef = (obj: any): obj is Ref<any> => {
205
256
  return obj && typeof obj === 'object' && RefTypeId in obj;
206
257
  };
207
258
 
208
- Ref.hasObjectId = (id: ObjectId) => (ref: Ref<any>) => ref.dxn.isLocalObjectId() && ref.dxn.parts[1] === id;
259
+ Ref.hasEntityId = (id: EntityId) => (ref: Ref<any>) => {
260
+ const uri = EID.tryParse(ref.uri);
261
+ return uri !== undefined && EID.isLocal(uri) && EID.getEntityId(uri) === id;
262
+ };
209
263
 
210
264
  Ref.isRefSchema = (schema: Schema.Schema<any, any>): schema is RefSchema<any> => {
211
265
  return Ref.isRefSchemaAST(schema.ast);
@@ -220,16 +274,16 @@ Ref.make = <T extends AnyProperties>(obj: T): Ref<T> => {
220
274
  throw new TypeError('Expected: ECHO object.');
221
275
  }
222
276
 
223
- // TODO(dmaretskyi): Extract to `getObjectDXN` function.
277
+ // TODO(dmaretskyi): Extract to `getObjectEchoUri` function.
224
278
  const id = obj.id;
225
- invariant(ObjectId.isValid(id), 'Invalid object ID');
226
- const dxn = DXN.fromLocalObjectId(id);
227
- return new RefImpl(dxn, obj);
279
+ invariant(EntityId.isValid(id), 'Invalid object ID');
280
+ const uri = EID.make({ entityId: id });
281
+ return new RefImpl(uri, obj);
228
282
  };
229
283
 
230
- Ref.fromDXN = (dxn: DXN): Ref<any> => {
231
- assertArgument(dxn instanceof DXN, 'dxn', 'Expected DXN');
232
- return new RefImpl(dxn);
284
+ Ref.fromURI = (uri: URI.URI): Ref<any> => {
285
+ assertArgument(typeof uri === 'string', 'uri', 'Expected URI string');
286
+ return new RefImpl(uri);
233
287
  };
234
288
 
235
289
  /**
@@ -245,18 +299,18 @@ export type JsonSchemaReferenceInfo = {
245
299
  */
246
300
  // TODO(burdon): Move to json schema and make private?
247
301
  export const createEchoReferenceSchema = (
248
- echoId: string | undefined,
302
+ echoUri: string | undefined,
249
303
  typename: string | undefined,
250
304
  version: string | undefined,
251
305
  ): Schema.SchemaClass<Ref<any>, EncodedReference> => {
252
- if (!echoId && !typename) {
253
- throw new TypeError('Either echoId or typename must be provided.');
306
+ if (!echoUri && !typename) {
307
+ throw new TypeError('Either echoUri or typename must be provided.');
254
308
  }
255
309
 
256
310
  const referenceInfo: JsonSchemaReferenceInfo = {
257
311
  schema: {
258
312
  // TODO(dmaretskyi): Include version?
259
- $ref: echoId ?? DXN.fromTypename(typename!).toString(),
313
+ $ref: echoUri ?? DXN.make(typename!),
260
314
  },
261
315
  schemaVersion: version,
262
316
  };
@@ -269,7 +323,7 @@ export const createEchoReferenceSchema = (
269
323
  return (value) =>
270
324
  Effect.gen(function* () {
271
325
  if (Ref.isRef(value)) {
272
- return EncodedReference.fromDXN((value as Ref<any>).dxn);
326
+ return EncodedReference.fromURI((value as Ref<any>).uri);
273
327
  } else if (EncodedReference.isEncodedReference(value)) {
274
328
  return value;
275
329
  }
@@ -284,7 +338,7 @@ export const createEchoReferenceSchema = (
284
338
  // TODO(dmaretskyi): This branch seems to be taken by Schema.is
285
339
  if (Ref.isRef(value)) {
286
340
  if (Option.isSome(dbService)) {
287
- return dbService.value.db.makeRef(value.dxn);
341
+ return dbService.value.db.makeRef(value.uri);
288
342
  } else {
289
343
  return value;
290
344
  }
@@ -294,9 +348,9 @@ export const createEchoReferenceSchema = (
294
348
  return yield* Effect.fail(new ParseResult.Unexpected(value, 'reference'));
295
349
  }
296
350
  if (Option.isSome(dbService)) {
297
- return dbService.value.db.makeRef(EncodedReference.toDXN(value));
351
+ return dbService.value.db.makeRef(EncodedReference.toURI(value));
298
352
  } else {
299
- return Ref.fromDXN(EncodedReference.toDXN(value));
353
+ return Ref.fromURI(EncodedReference.toURI(value));
300
354
  }
301
355
  });
302
356
  },
@@ -330,23 +384,32 @@ export interface RefResolver {
330
384
  /**
331
385
  * Resolve ref synchronously from the objects in the working set.
332
386
  *
333
- * @param dxn
387
+ * @param uri
334
388
  * @param load If true the resolver should attempt to load the object from disk.
335
389
  * @param onLoad Callback to call when the object is loaded.
336
390
  */
337
- resolveSync(dxn: DXN, load: boolean, onLoad?: () => void): AnyProperties | undefined;
391
+ resolveSync(uri: URI.URI, load: boolean, onLoad?: () => void): AnyProperties | undefined;
338
392
 
339
393
  /**
340
394
  * Resolver ref asynchronously.
341
395
  */
342
- resolve(dxn: DXN): Promise<AnyProperties | undefined>;
396
+ resolve(uri: URI.URI): Promise<AnyProperties | undefined>;
343
397
 
344
398
  // TODO(dmaretskyi): Combine with `resolve`.
345
- resolveSchema(dxn: DXN): Promise<Schema.Schema.AnyNoContext | undefined>;
399
+ resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined>;
400
+
401
+ /**
402
+ * Resolve the source `Type.AnyEntity` entity for a type URI. Used by
403
+ * deserialization paths (`Obj.fromJSON`) to set the back-reference accessed
404
+ * via `Obj.getType` / `Entity.getType`. Optional — resolvers that only
405
+ * carry raw schemas may leave this unimplemented; the deserializer falls
406
+ * back to leaving the type entity unset.
407
+ */
408
+ resolveType?(uri: URI.URI): Promise<unknown | undefined>;
346
409
  }
347
410
 
348
411
  export class RefImpl<T> implements Ref<T> {
349
- #dxn: DXN;
412
+ #uri: URI.URI;
350
413
  #resolver?: RefResolver = undefined;
351
414
  #resolved = new Event<void>();
352
415
 
@@ -363,16 +426,16 @@ export class RefImpl<T> implements Ref<T> {
363
426
  this.#resolved.emit();
364
427
  };
365
428
 
366
- constructor(dxn: DXN, target?: T) {
367
- this.#dxn = dxn;
429
+ constructor(uri: URI.URI, target?: T) {
430
+ this.#uri = uri;
368
431
  this.#target = target;
369
432
  }
370
433
 
371
434
  /**
372
435
  * @inheritdoc
373
436
  */
374
- get dxn(): DXN {
375
- return this.#dxn;
437
+ get uri(): URI.URI {
438
+ return this.#uri;
376
439
  }
377
440
 
378
441
  /**
@@ -391,7 +454,7 @@ export class RefImpl<T> implements Ref<T> {
391
454
  }
392
455
 
393
456
  invariant(this.#resolver, 'Resolver is not set');
394
- return this.#resolver.resolveSync(this.#dxn, true, this.#resolverCallback) as T | undefined;
457
+ return this.#resolver.resolveSync(this.#uri, true, this.#resolverCallback) as T | undefined;
395
458
  }
396
459
 
397
460
  /**
@@ -402,7 +465,7 @@ export class RefImpl<T> implements Ref<T> {
402
465
  return this.#target;
403
466
  }
404
467
  invariant(this.#resolver, 'Resolver is not set');
405
- const obj = await this.#resolver.resolve(this.#dxn);
468
+ const obj = await this.#resolver.resolve(this.#uri);
406
469
  if (obj == null) {
407
470
  throw new Error('Object not found');
408
471
  }
@@ -417,7 +480,14 @@ export class RefImpl<T> implements Ref<T> {
417
480
  return this.#target;
418
481
  }
419
482
  invariant(this.#resolver, 'Resolver is not set');
420
- return (await this.#resolver.resolve(this.#dxn)) as T | undefined;
483
+ return (await this.#resolver.resolve(this.#uri)) as T | undefined;
484
+ }
485
+
486
+ /**
487
+ * @inheritdoc
488
+ */
489
+ onResolved(callback: () => void): () => void {
490
+ return this.#resolved.on(callback);
421
491
  }
422
492
 
423
493
  /**
@@ -426,14 +496,14 @@ export class RefImpl<T> implements Ref<T> {
426
496
  * Clones the reference object.
427
497
  */
428
498
  noInline(): RefImpl<T> {
429
- const ref = new RefImpl<T>(this.#dxn, undefined);
499
+ const ref = new RefImpl<T>(this.#uri, undefined);
430
500
  ref.#resolver = this.#resolver;
431
501
  return ref;
432
502
  }
433
503
 
434
504
  encode(): EncodedReference {
435
505
  return {
436
- '/': this.#dxn.toString(),
506
+ '/': this.#uri,
437
507
  ...(this.#target ? { target: this.#target } : {}),
438
508
  };
439
509
  }
@@ -453,7 +523,7 @@ export class RefImpl<T> implements Ref<T> {
453
523
  return `Ref(${this.#target.toString()})`;
454
524
  }
455
525
 
456
- return `Ref(${this.#dxn.toString()})`;
526
+ return `Ref(${this.#uri.toString()})`;
457
527
  }
458
528
 
459
529
  [inspectCustom]: CustomInspectFunction = (depth, options, inspect) => {
@@ -469,12 +539,16 @@ export class RefImpl<T> implements Ref<T> {
469
539
  * so without this, each access would create a separate cache entry.
470
540
  */
471
541
  [Hash.symbol](): number {
472
- return Hash.hash(this.#dxn.toString());
542
+ return Hash.hash(this.#uri.toString());
473
543
  }
474
544
 
475
545
  /** Effect Equal trait. See {@link Hash.symbol} for rationale. */
476
546
  [Equal.symbol](that: Equal.Equal): boolean {
477
- return that instanceof RefImpl && this.#dxn.toString() === that.dxn.toString();
547
+ return that instanceof RefImpl && this.#uri === that.uri;
548
+ }
549
+
550
+ get atom(): Atom.Atom<T | undefined> {
551
+ return RefAtoms.refSimpleFamily(this);
478
552
  }
479
553
 
480
554
  /**
@@ -521,8 +595,8 @@ const refVariance: Ref<any>[typeof RefTypeId] = {
521
595
  };
522
596
 
523
597
  export const refFromEncodedReference = (encodedReference: EncodedReference, resolver?: RefResolver): Ref<any> => {
524
- const dxn = DXN.parse(encodedReference['/']);
525
- const ref = new RefImpl(dxn);
598
+ const uri = EncodedReference.toURI(encodedReference);
599
+ const ref = new RefImpl(uri);
526
600
 
527
601
  // TODO(dmaretskyi): Handle inline target in the encoded reference.
528
602
 
@@ -533,23 +607,26 @@ export const refFromEncodedReference = (encodedReference: EncodedReference, reso
533
607
  };
534
608
 
535
609
  export class StaticRefResolver implements RefResolver {
536
- public objects = new Map<ObjectId, AnyProperties>();
537
- public schemas = new Map<DXN.String, Schema.Schema.AnyNoContext>();
610
+ public objects = new Map<EntityId, AnyProperties>();
611
+ public schemas = new Map<URI.URI, Schema.Schema.AnyNoContext>();
538
612
 
539
613
  addObject(obj: AnyProperties): this {
540
614
  this.objects.set(obj.id, obj);
541
615
  return this;
542
616
  }
543
617
 
544
- addSchema(schema: Schema.Schema.AnyNoContext): this {
545
- const dxn = getSchemaDXN(schema);
546
- invariant(dxn, 'Schema has no DXN');
547
- this.schemas.set(dxn.toString(), schema);
618
+ addSchema(input: Type.AnyEntity): this {
619
+ const schema = getStaticTypeSchema(input);
620
+ invariant(schema, 'Type entity is missing its source schema');
621
+ const uri = getSchemaURI(schema);
622
+ invariant(uri, 'Schema has no URI');
623
+ this.schemas.set(uri, schema);
548
624
  return this;
549
625
  }
550
626
 
551
- resolveSync(dxn: DXN, _load: boolean, _onLoad?: () => void): AnyProperties | undefined {
552
- const id = dxn?.asEchoDXN()?.echoId;
627
+ resolveSync(uri: URI.URI, _load: boolean, _onLoad?: () => void): AnyProperties | undefined {
628
+ const echoUri = EID.tryParse(uri);
629
+ const id = echoUri ? EID.getEntityId(echoUri) : undefined;
553
630
  if (id == null) {
554
631
  return undefined;
555
632
  }
@@ -557,8 +634,9 @@ export class StaticRefResolver implements RefResolver {
557
634
  return this.objects.get(id);
558
635
  }
559
636
 
560
- async resolve(dxn: DXN): Promise<AnyProperties | undefined> {
561
- const id = dxn?.asEchoDXN()?.echoId;
637
+ async resolve(uri: URI.URI): Promise<AnyProperties | undefined> {
638
+ const echoUri = EID.tryParse(uri);
639
+ const id = echoUri ? EID.getEntityId(echoUri) : undefined;
562
640
  if (id == null) {
563
641
  return undefined;
564
642
  }
@@ -566,7 +644,7 @@ export class StaticRefResolver implements RefResolver {
566
644
  return this.objects.get(id);
567
645
  }
568
646
 
569
- async resolveSchema(dxn: DXN): Promise<Schema.Schema.AnyNoContext | undefined> {
570
- return this.schemas.get(dxn.toString());
647
+ async resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined> {
648
+ return this.schemas.get(uri);
571
649
  }
572
650
  }
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import type * as Atom from '@effect-atom/atom/Atom';
6
+
7
+ import type { Ref } from './ref';
8
+
9
+ /**
10
+ * Internal helper for loading ref targets in atoms.
11
+ * Handles the common pattern of checking for loaded target and triggering async load.
12
+ */
13
+ export const loadRefTarget = <T, R>(
14
+ ref: Ref<T>,
15
+ get: Atom.Context,
16
+ onTargetAvailable: (target: T) => R,
17
+ ): R | undefined => {
18
+ // Accessing `ref.target` registers a resolution callback when the target is
19
+ // not yet loaded, so resolution can be observed via `ref.onResolved` below.
20
+ const currentTarget = ref.target;
21
+ if (currentTarget) {
22
+ return onTargetAvailable(currentTarget);
23
+ }
24
+
25
+ // Subscribe to the ref's resolution event in case the target loads later.
26
+ const unsubscribe = ref.onResolved(() => {
27
+ const target = ref.target;
28
+ if (target) {
29
+ get.setSelf(onTargetAvailable(target));
30
+ }
31
+ });
32
+ get.addFinalizer(unsubscribe);
33
+
34
+ // Also try async load (e.g. for objects that need disk loading).
35
+ void ref
36
+ .load()
37
+ .then((loadedTarget) => {
38
+ get.setSelf(onTargetAvailable(loadedTarget));
39
+ })
40
+ .catch(() => {
41
+ // Loading failed; the resolution subscription above will pick up cross-client updates.
42
+ });
43
+
44
+ return undefined;
45
+ };
@@ -5,6 +5,8 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import { describe, test } from 'vitest';
7
7
 
8
+ import { DXN } from '@dxos/keys';
9
+
8
10
  import { FieldPath } from '../Annotation';
9
11
  import { EchoObjectSchema } from '../Entity';
10
12
  import { FormatAnnotation, TypeFormat } from '../Format';
@@ -16,7 +18,7 @@ describe('schema composition', () => {
16
18
  const BaseType = Schema.Struct({
17
19
  name: Schema.String,
18
20
  email: Schema.String,
19
- }).pipe(EchoObjectSchema({ typename: 'com.example.person', version: '0.1.0' }));
21
+ }).pipe(EchoObjectSchema(DXN.make('com.example.person', '0.1.0')));
20
22
 
21
23
  const OverlaySchema = Schema.Struct({
22
24
  email: Schema.String.pipe(FieldPath('$.email'), FormatAnnotation.set(TypeFormat.Email)),
@@ -2,6 +2,5 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './echo-schema';
6
5
  export * from './manipulation';
7
- export * from './persistent-schema';
6
+ export * from './type-schema';
@@ -6,9 +6,6 @@ import * as Schema from 'effect/Schema';
6
6
  import * as SchemaAST from 'effect/SchemaAST';
7
7
 
8
8
  import { invariant } from '@dxos/invariant';
9
- import { DXN } from '@dxos/keys';
10
-
11
- import { type TypeAnnotation, TypeAnnotationId, TypeIdentifierAnnotationId } from '../Annotation';
12
9
 
13
10
  // TODO(ZaymonFC): Do this one at a time. This might be dangerous.
14
11
  export const addFieldsToSchema = (
@@ -68,25 +65,3 @@ export const updateFieldNameInSchema = (
68
65
  ),
69
66
  );
70
67
  };
71
-
72
- export const setTypenameInSchema = (
73
- schema: Schema.Schema.AnyNoContext,
74
- typename: string,
75
- ): Schema.Schema.AnyNoContext => {
76
- const existingAnnotation = schema.ast.annotations[TypeAnnotationId] as TypeAnnotation;
77
- invariant(existingAnnotation, `Missing ${String(TypeAnnotationId)}`);
78
-
79
- return schema.annotations({
80
- ...schema.ast.annotations,
81
- [TypeAnnotationId]: {
82
- kind: existingAnnotation.kind,
83
- typename,
84
- version: existingAnnotation.version,
85
- } satisfies TypeAnnotation,
86
- [SchemaAST.JSONSchemaAnnotationId]: {
87
- ...(schema.ast.annotations[SchemaAST.JSONSchemaAnnotationId] ?? {}),
88
- $id: schema.ast.annotations[TypeIdentifierAnnotationId] ?? DXN.fromTypename(typename).toString(),
89
- typename,
90
- },
91
- });
92
- };
@@ -0,0 +1,60 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { IconAnnotation, LabelAnnotation } from '../Annotation';
8
+ import { EntityKind, KindId, SchemaKindId, StaticTypeSchemaSlot } from '../common/types';
9
+ import { EchoTypeKindSchema, TypeMetaSchemaDXN } from '../Entity';
10
+ import { JsonSchemaType } from '../JsonSchema';
11
+
12
+ /**
13
+ * Raw struct backing {@link TypeSchema}. Exposed only so `TypeSchema`
14
+ * (the TS type) can derive its data fields via `Schema.Schema.Type<typeof ...>`;
15
+ * runtime callers should use {@link TypeSchema} (the piped, branded entity).
16
+ *
17
+ * `typename` and `version` are NOT data fields — they live in `EntityMeta.key` /
18
+ * `EntityMeta.version` (the canonical registry-provenance pair, queryable via
19
+ * `Filter.key(...)`). The same `jsonSchema` payload also embeds them so a
20
+ * standalone JSON-Schema export remains self-describing, but the schema-registry
21
+ * reads/writes them through meta.
22
+ */
23
+ const TypeSchemaStruct = Schema.Struct({
24
+ name: Schema.optional(Schema.String),
25
+ jsonSchema: JsonSchemaType,
26
+ });
27
+
28
+ /**
29
+ * Persistent representation of a schema.
30
+ */
31
+ export const TypeSchema = TypeSchemaStruct.pipe(
32
+ LabelAnnotation.set(['name']),
33
+ IconAnnotation.set({
34
+ icon: 'ph--database--regular',
35
+ hue: 'green',
36
+ }),
37
+ EchoTypeKindSchema(TypeMetaSchemaDXN),
38
+ );
39
+
40
+ /**
41
+ * Persistent representation of a schema — the runtime shape that
42
+ * `db.addType(Type.makeObjectFromJsonSchema(...))` produces
43
+ * and `Filter.type(Type.Type).run()` returns.
44
+ *
45
+ * Structurally identical to a static `Type.Type` entity: the entity-handler's
46
+ * `get` trap exposes `[SchemaKindId]` (derived from `system.kind` and
47
+ * `data.jsonSchema.entityKind`) and rebuilds `[StaticTypeSchemaSlot]` lazily
48
+ * from `jsonSchema`, so a persisted instance satisfies the public `Type<A>`
49
+ * interface without casting.
50
+ */
51
+ export type TypeSchema = Schema.Schema.Type<typeof TypeSchemaStruct> & {
52
+ /** Object identifier — injected by `EchoTypeKindSchema` and stamped at construction. */
53
+ readonly id: string;
54
+ /** Entity-kind discriminator (object/relation/type) carried on every entity instance. */
55
+ readonly [KindId]: EntityKind.Type;
56
+ /** Kind of schema described by this meta-instance — always `EntityKind.Type` for `Type.Type` itself. */
57
+ readonly [SchemaKindId]: EntityKind.Type;
58
+ /** Effect Schema rebuilt lazily from `jsonSchema`; satisfies `Type.getSchema(...)` without an extra cast. */
59
+ readonly [StaticTypeSchemaSlot]: Schema.Schema.AnyNoContext;
60
+ };
@@ -7,7 +7,7 @@
7
7
  - [x] Unify FOUR different nests of test schema.
8
8
  - [x] Remove @deprecated from internal methods and mark @internal (e.g., getSchemaDXN).
9
9
  - NOTE: Internal methods should not use the import \* from Obj/Type APIs.
10
- - [x] import ObjectId => @dxos/keys
10
+ - [x] import EntityId => @dxos/keys
11
11
  - [x] Entity.Any = Obj.Any | Relation.Any
12
12
  - NOTE: Relation does not extend (in not polymorphic with) Obj.
13
13
  - [x] import LabelAnnotation => Annotation.LabelAnnotation
@@ -99,4 +99,4 @@
99
99
  - [ ] ReactiveObject should specify id property? Reconcile AnyProperties, ReactiveObject, HasId, WithId, etc.
100
100
  - [ ] Can we us S.is(MyType) to detect objects with our types system? (Branding?)
101
101
  - [ ] Type.Expando doesn't work with AtomQuery result type (have to use Obj.Any instead).
102
- - [ ] Obj.Any doesn't work with Obj.change callback types (have to use `any` for the mutable parameter).
102
+ - [ ] Obj.Any doesn't work with Obj.update callback types (have to use `any` for the mutable parameter).