@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
@@ -8,10 +8,11 @@ import { type InspectOptionsStylized } from 'node:util';
8
8
 
9
9
  import { Event } from '@dxos/async';
10
10
  import { inspectCustom } from '@dxos/debug';
11
- import { invariant } from '@dxos/invariant';
11
+ import { assertArgument, invariant } from '@dxos/invariant';
12
12
 
13
- import { getSchemaDXN } from '../../Annotation';
14
- import { ObjectDeletedId, ParentId, SchemaId, TypeId } from '../types';
13
+ import { getSchemaURI } from '../../Annotation/annotations';
14
+ import { toEffectSchema } from '../../JsonSchema/json-schema';
15
+ import { ObjectDeletedId, ParentId, SchemaId, StaticTypeSchemaSlot, TypeEntityId, TypeId } from '../types';
15
16
  import { executeChange, isInChangeContext, queueNotification } from './change-context';
16
17
  import { defineHiddenProperty } from './define-hidden-property';
17
18
  import { createPropertyDeleteError } from './errors';
@@ -142,7 +143,7 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
142
143
  private constructor() {}
143
144
 
144
145
  init(target: ProxyTarget): void {
145
- invariant(typeof target === 'object' && target !== null);
146
+ assertArgument(typeof target === 'object' && target !== null, 'target');
146
147
  invariant(SchemaId in target, 'Schema is not defined for the target');
147
148
 
148
149
  // Only set EventId on root objects (those without an owner).
@@ -208,6 +209,27 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
208
209
  // Uses target as both the context key and event target for non-database objects.
209
210
  return (callback: (obj: any) => void) => executeChange(target, target, receiver, callback);
210
211
  }
212
+ case TypeEntityId: {
213
+ // The back-reference to the type entity is metadata — return the raw
214
+ // value so we don't re-wrap an already-reactive `Type.Type` entity in
215
+ // another proxy (which would fail the SchemaId-in-target invariant).
216
+ return Reflect.get(target, prop, receiver);
217
+ }
218
+ case StaticTypeSchemaSlot: {
219
+ // Lazily rebuild the source Effect Schema from `jsonSchema` and cache it on
220
+ // the slot; the set-trap invalidates the cache when `jsonSchema` is mutated.
221
+ const existing = Reflect.get(target, prop, receiver);
222
+ if (existing !== undefined) {
223
+ return existing;
224
+ }
225
+ const jsonSchema = (target as any).jsonSchema;
226
+ if (jsonSchema == null) {
227
+ return undefined;
228
+ }
229
+ const rebuilt = toEffectSchema(jsonSchema);
230
+ defineHiddenProperty(target, StaticTypeSchemaSlot, rebuilt);
231
+ return rebuilt;
232
+ }
211
233
  }
212
234
 
213
235
  // Handle getter properties.
@@ -226,7 +248,7 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
226
248
  set(target: ProxyTarget, prop: string | symbol, value: any, receiver: any): boolean {
227
249
  const echoRoot = getEchoRoot(target);
228
250
 
229
- // Check readonly enforcement - mutations only allowed within Obj.change().
251
+ // Check readonly enforcement - mutations only allowed within Obj.update().
230
252
  // Skip check if the object is still being initialized (no ChangeId handler yet).
231
253
  // Also skip for non-initialized root objects (those without EventId).
232
254
  // Skip for symbol properties (internal infrastructure, not user data).
@@ -234,8 +256,8 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
234
256
  const isSymbolProp = typeof prop === 'symbol';
235
257
  if (isInitialized && !isSymbolProp && !isInChangeContext(echoRoot)) {
236
258
  throw new Error(
237
- `Cannot modify object property "${String(prop)}" outside of Obj.change(). ` +
238
- 'Use Obj.change(obj, (mutableObj) => { mutableObj.property = value; }) instead.',
259
+ `Cannot modify object property "${String(prop)}" outside of Obj.update(). ` +
260
+ 'Use Obj.update(obj, (mutableObj) => { mutableObj.property = value; }) instead.',
239
261
  );
240
262
  }
241
263
 
@@ -245,6 +267,11 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
245
267
  batchEvents(() => {
246
268
  const { echoRoot: _, preparedValue } = this._prepareValueForAssignment(target, prop, value);
247
269
  result = Reflect.set(target, prop, preparedValue, receiver);
270
+ // Invalidate the cached source Effect Schema when `jsonSchema` changes
271
+ // (e.g. `Type.addFields`) so `Type.getSchema` rebuilds from the new shape.
272
+ if (prop === 'jsonSchema') {
273
+ Reflect.deleteProperty(target, StaticTypeSchemaSlot);
274
+ }
248
275
  // Queue notification instead of emitting immediately (batched).
249
276
  if (isInitialized) {
250
277
  queueNotification(echoRoot);
@@ -265,7 +292,7 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
265
292
  deleteProperty(target: ProxyTarget, property: string | symbol): boolean {
266
293
  const echoRoot = getEchoRoot(target);
267
294
 
268
- // Check readonly enforcement - mutations only allowed within Obj.change().
295
+ // Check readonly enforcement - mutations only allowed within Obj.update().
269
296
  // Skip for symbol properties (internal infrastructure, not user data).
270
297
  const isInitialized = (echoRoot as any)[ChangeId] === true || EventId in echoRoot;
271
298
  const isSymbolProp = typeof property === 'symbol';
@@ -283,15 +310,15 @@ export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
283
310
  defineProperty(target: ProxyTarget, property: string | symbol, attributes: PropertyDescriptor): boolean {
284
311
  const echoRoot = getEchoRoot(target);
285
312
 
286
- // Check readonly enforcement - mutations only allowed within Obj.change().
313
+ // Check readonly enforcement - mutations only allowed within Obj.update().
287
314
  // Skip check if the object is still being initialized (no ChangeId handler yet).
288
315
  // Skip for symbol properties (internal infrastructure, not user data).
289
316
  const isInitialized = ChangeId in echoRoot || EventId in echoRoot;
290
317
  const isSymbolProp = typeof property === 'symbol';
291
318
  if (isInitialized && !isSymbolProp && !isInChangeContext(echoRoot)) {
292
319
  throw new Error(
293
- `Cannot modify object property "${String(property)}" outside of Obj.change(). ` +
294
- 'Use Obj.change(obj, (mutableObj) => { mutableObj.property = value; }) instead.',
320
+ `Cannot modify object property "${String(property)}" outside of Obj.update(). ` +
321
+ 'Use Obj.update(obj, (mutableObj) => { mutableObj.property = value; }) instead.',
295
322
  );
296
323
  }
297
324
 
@@ -400,16 +427,49 @@ const toJSON = (target: ProxyTarget): any => {
400
427
  return { '@type': 'TypedReactiveObject', ...target };
401
428
  };
402
429
 
430
+ /**
431
+ * Pointer to a `Type.Type` entity, stamped as the back-reference (`TypeEntityId`)
432
+ * on instances and read by the `SchemaId` getter installed below.
433
+ *
434
+ * Structural shape (not `Type.AnyEntity`) because `internal/common/proxy/`
435
+ * can't import the top-level `Type` module without a cycle. Every kind of
436
+ * `Type.Type` entity satisfies this shape:
437
+ * - Static (`Type.makeObject(dxn)` pipe) — slot set directly on the object.
438
+ * - Persisted (echo-handler-wrapped) — slot exposed via that handler's
439
+ * `get` trap (rebuilds from `data.jsonSchema`).
440
+ * - In-memory pre-persist (`Type.makeObjectFromJsonSchema`) — slot exposed
441
+ * via the `case StaticTypeSchemaSlot:` arm in this file's `get` trap.
442
+ */
443
+ export type TypeSource = { readonly [StaticTypeSchemaSlot]?: Schema.Schema.AnyNoContext };
444
+
403
445
  /**
404
446
  * Recursively set AST on all potential proxy targets.
405
447
  */
406
- const setSchemaProperties = (obj: any, schema: Schema.Schema.AnyNoContext) => {
407
- const schemaType = getSchemaDXN(schema);
448
+ const setSchemaProperties = (obj: any, schema: Schema.Schema.AnyNoContext, typeSource?: TypeSource) => {
449
+ const schemaType = getSchemaURI(schema);
408
450
  if (schemaType != null) {
409
451
  defineHiddenProperty(obj, TypeId, schemaType);
410
452
  }
411
453
 
412
- defineHiddenProperty(obj, SchemaId, schema);
454
+ if (typeSource != null) {
455
+ // Keep a back-reference to the type entity so `Obj.getType` /
456
+ // `Relation.getType` / `Entity.getType` can return it.
457
+ defineHiddenProperty(obj, TypeEntityId, typeSource);
458
+
459
+ // Install `SchemaId` as a getter that reads through the entity's static
460
+ // schema slot. The three entity shapes (static / persisted / in-memory
461
+ // pre-persist) each populate the slot via their own get-trap path, so
462
+ // `Type.update` / `Type.addFields` mutations propagate into validation
463
+ // for objects created via `Obj.make(typeEntity, ...)` without this file
464
+ // having to rebuild from `jsonSchema` itself.
465
+ Object.defineProperty(obj, SchemaId, {
466
+ get: () => typeSource[StaticTypeSchemaSlot] ?? schema,
467
+ enumerable: false,
468
+ configurable: true,
469
+ });
470
+ } else {
471
+ defineHiddenProperty(obj, SchemaId, schema);
472
+ }
413
473
  for (const key in obj) {
414
474
  if (isValidProxyTarget(obj[key])) {
415
475
  const elementSchema = SchemaValidator.getTargetPropertySchema(obj, key);
@@ -420,7 +480,9 @@ const setSchemaProperties = (obj: any, schema: Schema.Schema.AnyNoContext) => {
420
480
  }
421
481
  };
422
482
 
423
- export const prepareTypedTarget = <T>(target: T, schema: Schema.Schema<T>) => {
483
+ // Accepts any encoded type: the typed handler operates on the decoded representation, so schemas
484
+ // whose encoded form differs (e.g. refs encode as `{ '/': uri }`) are valid here.
485
+ export const prepareTypedTarget = <T>(target: T, schema: Schema.Schema<T, any>, typeSource?: TypeSource) => {
424
486
  // log.info('prepareTypedTarget', { target, schema });
425
487
  if (!SchemaAST.isTypeLiteral(schema.ast)) {
426
488
  throw new Error('schema has to describe an object type');
@@ -429,7 +491,7 @@ export const prepareTypedTarget = <T>(target: T, schema: Schema.Schema<T>) => {
429
491
  SchemaValidator.validateSchema(schema);
430
492
  const _ = Schema.asserts(schema)(target);
431
493
  makeArraysReactive(target);
432
- setSchemaProperties(target, schema);
494
+ setSchemaProperties(target, schema, typeSource);
433
495
  };
434
496
 
435
497
  const makeArraysReactive = (target: any) => {
@@ -6,6 +6,10 @@ import * as Schema from 'effect/Schema';
6
6
  import type * as Types from 'effect/Types';
7
7
  import { describe, expect, test } from 'vitest';
8
8
 
9
+ import { DXN } from '@dxos/keys';
10
+
11
+ import * as Obj from '../../../Obj';
12
+ import * as Type from '../../../Type';
9
13
  import { EchoObjectSchema } from '../../Entity';
10
14
  import { getSchema } from '../types';
11
15
  import { makeObject } from './make-object';
@@ -13,14 +17,9 @@ import { change } from './reactive';
13
17
 
14
18
  const Organization = Schema.Struct({
15
19
  name: Schema.String,
16
- }).pipe(
17
- EchoObjectSchema({
18
- typename: 'com.example.type.organization',
19
- version: '0.1.0',
20
- }),
21
- );
20
+ }).pipe(EchoObjectSchema(DXN.make('com.example.type.organization', '0.1.0')));
22
21
 
23
- interface Organization extends Schema.Schema.Type<typeof Organization> {}
22
+ type Organization = Type.InstanceType<typeof Organization>;
24
23
 
25
24
  const Contact = Schema.Struct(
26
25
  {
@@ -30,27 +29,21 @@ const Contact = Schema.Struct(
30
29
  key: Schema.String,
31
30
  value: Schema.Any,
32
31
  },
33
- ).pipe(
34
- Schema.partial,
35
- EchoObjectSchema({
36
- typename: 'com.example.type.person',
37
- version: '0.1.0',
38
- }),
39
- );
32
+ ).pipe(Schema.partial, EchoObjectSchema(DXN.make('com.example.type.person', '0.1.0')));
40
33
 
41
- interface Contact extends Schema.Schema.Type<typeof Contact> {}
34
+ type Contact = Type.InstanceType<typeof Contact>;
42
35
 
43
- const TEST_ORG: Omit<Organization, 'id'> = { name: 'Test' };
36
+ const TEST_ORG = { name: 'Test' } satisfies Pick<Organization, 'name'>;
44
37
 
45
38
  describe('EchoObjectSchema class DSL', () => {
46
39
  test('can get object schema', async () => {
47
- const obj = makeObject(Organization, TEST_ORG);
48
- expect(getSchema(obj)).to.deep.eq(Organization);
40
+ const obj = Obj.make(Organization, TEST_ORG);
41
+ expect(getSchema(obj)).to.deep.eq(Type.getSchema(Organization));
49
42
  });
50
43
 
51
44
  describe('class options', () => {
52
45
  test('can assign undefined to partial fields', async () => {
53
- const person = makeObject(Contact, { name: 'John' });
46
+ const person = Obj.make(Contact, { name: 'John' });
54
47
  change(person, (p) => {
55
48
  p.name = undefined;
56
49
  p.recordField = 'hello';
@@ -86,7 +79,7 @@ describe('EchoObjectSchema class DSL', () => {
86
79
  }
87
80
 
88
81
  {
89
- // Plain object (not a reactive proxy) - doesn't need Obj.change.
82
+ // Plain object (not a reactive proxy) - doesn't need Obj.update.
90
83
  // Note: Schema.Schema.Type generates readonly types, so we cast to mutable for plain objects.
91
84
  type Test1 = Types.Mutable<Schema.Schema.Type<typeof schema>>;
92
85
 
@@ -98,14 +91,9 @@ describe('EchoObjectSchema class DSL', () => {
98
91
  {
99
92
  const Test2 = Schema.Struct({
100
93
  meta: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),
101
- }).pipe(
102
- EchoObjectSchema({
103
- typename: 'org.dxos.type.functionTrigger',
104
- version: '0.1.0',
105
- }),
106
- );
107
-
108
- const object = makeObject(Test2, {});
94
+ }).pipe(EchoObjectSchema(DXN.make('org.dxos.type.functionTrigger', '0.1.0')));
95
+
96
+ const object = Obj.make(Test2, {});
109
97
  change(object, (o) => {
110
98
  (o.meta ??= {}).test = 100;
111
99
  });
@@ -5,9 +5,9 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import * as SchemaAST from 'effect/SchemaAST';
7
7
 
8
- import { type ObjectId } from '@dxos/keys';
8
+ import { type EntityId } from '@dxos/keys';
9
9
 
10
- import { type ATTR_META, type ObjectMeta } from './meta';
10
+ import { type ATTR_META, type EntityMeta } from './meta';
11
11
 
12
12
  /**
13
13
  * Base type for all data objects (reactive, ECHO, and other raw objects).
@@ -23,7 +23,7 @@ export type AnyProperties = Record<string, any>;
23
23
  */
24
24
  // TODO(wittjosiah): Remove. Prefer higher level types (e.g. Entity.Unknown).
25
25
  export interface AnyEntity {
26
- readonly id: ObjectId;
26
+ readonly id: EntityId;
27
27
  }
28
28
 
29
29
  export type ExcludeId<T extends AnyProperties> = Omit<T, 'id'>;
@@ -31,7 +31,7 @@ export type ExcludeId<T extends AnyProperties> = Omit<T, 'id'>;
31
31
  export type PropertyKey<T extends AnyProperties> = Extract<keyof ExcludeId<T>, string>;
32
32
 
33
33
  // TODO(dmaretskyi): Remove. This should be using the symbol type.
34
- type WithMeta = { [ATTR_META]?: ObjectMeta };
34
+ type WithMeta = { [ATTR_META]?: EntityMeta };
35
35
 
36
36
  /**
37
37
  * The raw object should not include the ECHO id, but may include metadata.
@@ -33,11 +33,90 @@ export const SnapshotKindId = '~@dxos/echo/SnapshotKind' as const;
33
33
  export type SnapshotKindId = typeof SnapshotKindId;
34
34
 
35
35
  /**
36
- * Kinds of entities stored in ECHO: objects and relations.
36
+ * Hidden slot on a static `Type.Type` entity that holds the source Effect
37
+ * Schema. `Type.getSchema(...)` reads this for static types; persisted types
38
+ * rebuild from `jsonSchema` instead. Stored as a string key for declaration
39
+ * portability (see KindId comment above).
40
+ */
41
+ export const StaticTypeSchemaSlot = '~@dxos/echo/Type.StaticSchema' as const;
42
+ export type StaticTypeSchemaSlot = typeof StaticTypeSchemaSlot;
43
+
44
+ /**
45
+ * Read the hidden `StaticTypeSchemaSlot` off any value that may carry one.
46
+ * Returns `undefined` for raw schemas (no slot) and non-object inputs.
47
+ * Single point-of-cast for the slot lookup.
48
+ */
49
+ export const getStaticTypeSchema = (value: unknown): Schema.Schema.AnyNoContext | undefined => {
50
+ if (value == null || typeof value !== 'object') {
51
+ return undefined;
52
+ }
53
+ return (value as { [StaticTypeSchemaSlot]?: Schema.Schema.AnyNoContext })[StaticTypeSchemaSlot];
54
+ };
55
+
56
+ /**
57
+ * Read the `[SchemaKindId]` brand off a value. Returns `undefined` for raw
58
+ * schemas (which don't carry the brand on their static type) and non-object
59
+ * inputs. Single point-of-cast for the brand lookup.
60
+ */
61
+ export const getSchemaKind = (value: unknown): EntityKind | undefined => {
62
+ if (value == null || typeof value !== 'object') {
63
+ return undefined;
64
+ }
65
+ return (value as { [SchemaKindId]?: EntityKind })[SchemaKindId];
66
+ };
67
+
68
+ /**
69
+ * Read the `[KindId]` brand off a value. Returns `undefined` for raw schemas
70
+ * and non-object inputs. Companion to {@link getSchemaKind}.
71
+ */
72
+ export const getEntityKindBrand = (value: unknown): EntityKind | undefined => {
73
+ if (value == null || typeof value !== 'object') {
74
+ return undefined;
75
+ }
76
+ return (value as { [KindId]?: EntityKind })[KindId];
77
+ };
78
+
79
+ /**
80
+ * Phantom string key on `Type<A>` entities that carries the instance type `A`.
81
+ * Lets internal helpers (`makeObject`, `createObject`, etc.) pattern-match the
82
+ * instance type from an entity input without importing from the top-level
83
+ * `Type` module. Mirrors `Type.InstancePhantomId` (declared in `Type.ts`).
84
+ *
85
+ * Stored as a string key so declarations remain portable across packages
86
+ * (see KindId comment above).
87
+ */
88
+ export const InstancePhantomId = '~@dxos/echo/Type.Instance' as const;
89
+ export type InstancePhantomId = typeof InstancePhantomId;
90
+
91
+ /**
92
+ * Nominal brand carried by the well-known "any object" / "any relation"
93
+ * schemas (`Obj.Unknown`, `Relation.Unknown`). The brand lets `Ref.Ref`,
94
+ * `Filter.type`, and `Query.type` accept these schemas in addition to
95
+ * `Type.Type` entities, without opening the door to arbitrary raw schemas.
96
+ *
97
+ * Stored as a string key so declarations remain portable across packages
98
+ * (see KindId comment above).
99
+ */
100
+ export const UnknownTypeSchemaBrandId = '~@dxos/echo/UnknownTypeSchemaBrand' as const;
101
+ export type UnknownTypeSchemaBrandId = typeof UnknownTypeSchemaBrandId;
102
+
103
+ /**
104
+ * Schema-side companion to `Type.Type` entities for the "any object" /
105
+ * "any relation" cases. Branded so `Ref.Ref` / `Filter.type` / `Query.type`
106
+ * can pattern-match on it; arbitrary `Schema.Schema` values do not satisfy
107
+ * this shape.
108
+ */
109
+ export interface UnknownTypeSchema<A, K extends EntityKind> extends Schema.Schema<A, any, never> {
110
+ readonly [UnknownTypeSchemaBrandId]: K;
111
+ }
112
+
113
+ /**
114
+ * Kinds of entities stored in ECHO: objects, relations, and types.
37
115
  */
38
116
  export enum EntityKind {
39
117
  Object = 'object',
40
118
  Relation = 'relation',
119
+ Type = 'type',
41
120
  }
42
121
 
43
122
  export const EntityKindSchema = Schema.Enums(EntityKind);
@@ -4,7 +4,12 @@
4
4
 
5
5
  export * from './base';
6
6
  export * from './entity';
7
- export * from './meta';
7
+ // NOTE: `./meta` is intentionally NOT re-exported here. It depends on the Ref schema (`Ref/ref`),
8
+ // which transitively pulls in `Annotation` + `Database`; re-exporting it from this low-level barrel
9
+ // — imported by `Annotation/util`, `Annotation/annotations`, `Entity/type-uri`, and `Ref/ref` —
10
+ // would create an eval-order cycle (TDZ on `createAnnotationHelper`). Import meta from `./meta`
11
+ // directly, or from the top-level `@dxos/echo/internal` barrel (re-exported there after Ref loads).
8
12
  export * from './model-symbols';
9
13
  export * from './typename';
10
14
  export * from './version';
15
+ export * from './well-known-types';
@@ -4,43 +4,85 @@
4
4
 
5
5
  import * as Schema from 'effect/Schema';
6
6
 
7
- import { ForeignKey } from '@dxos/echo-protocol';
7
+ import { type EncodedReference, ForeignKey } from '@dxos/echo-protocol';
8
8
  import { invariant } from '@dxos/invariant';
9
+ import { DXN } from '@dxos/keys';
9
10
  import { type Comparator, intersection } from '@dxos/util';
10
11
 
11
- import type * as Entity from '../../../Entity';
12
+ import type * as Tag from '../../../Tag';
13
+ import { Dictionary } from '../../Annotation/dictionary';
14
+ // `meta` is no longer re-exported from the `common/types` barrel (see ./index.ts), so importing the
15
+ // Ref schema builder here no longer forms an eval-order cycle with `Annotation`/`Database`.
16
+ import { type Ref, createEchoReferenceSchema } from '../../Ref/ref';
12
17
  import { type AnyProperties } from './base';
18
+ import { MetaId } from './model-symbols';
19
+ import { TagTypeDXN } from './well-known-types';
13
20
 
14
21
  /**
15
22
  * Property name for meta when object is serialized to JSON.
16
23
  */
17
24
  export const ATTR_META = '@meta';
18
25
 
19
- /**
20
- * Metadata section.
21
- */
22
- export const MetaId: Entity.Meta = Symbol.for('@dxos/echo/Meta') as any;
23
-
24
26
  //
25
- // ObjectMeta
27
+ // EntityMeta
26
28
  //
27
29
 
28
- // TODO(dmaretskyi): Rename to ObjectMeta
29
- export const ObjectMetaSchema = Schema.Struct({
30
+ /**
31
+ * Schema for references to {@link Tag} objects stored in {@link EntityMetaSchema.tags}.
32
+ *
33
+ * Built from the shared {@link createEchoReferenceSchema} (the same builder `Ref.Ref` uses) via
34
+ * `Schema.suspend`, so it reuses the canonical ref codec rather than duplicating it. The Tag type
35
+ * identity comes from the shared {@link TagTypeDXN} constant; `suspend` defers construction until
36
+ * first use, and `Tag` is referenced type-only, so no `Tag` value import is needed.
37
+ */
38
+ const TagRefSchema = Schema.suspend(
39
+ (): Schema.Schema<Ref<Tag.Tag>, EncodedReference> =>
40
+ // The factory yields a loosely-typed `Ref<any>` schema; narrow it to the Tag-typed ref.
41
+ createEchoReferenceSchema(undefined, DXN.getName(TagTypeDXN), DXN.getVersion(TagTypeDXN)) as Schema.Schema<
42
+ Ref<Tag.Tag>,
43
+ EncodedReference
44
+ >,
45
+ );
46
+
47
+ export const EntityMetaSchema = Schema.Struct({
30
48
  keys: Schema.Array(ForeignKey),
31
49
 
32
50
  /**
33
- * A set of tags.
34
- * Tags are arbitrary application-defined strings.
35
- * ECHO makes no assumptions about the tag structure.
51
+ * Tags applied to this entity, as references to {@link Tag} objects.
52
+ */
53
+ tags: Schema.Array(TagRefSchema),
54
+
55
+ /**
56
+ * Fully-qualified registry key for the object (FQN format, e.g. `org.example.type.foo`).
57
+ * Identifies the canonical registry entry the object instance was created from.
58
+ */
59
+ key: Schema.optional(Schema.String),
60
+
61
+ /**
62
+ * Semantic version of the registry entry the object was created from.
63
+ * Must be a valid semver string (e.g. `1.2.3`).
64
+ */
65
+ version: Schema.optional(Schema.String),
66
+
67
+ /**
68
+ * Dictionary of annotations to this entity.
69
+ */
70
+ annotations: Dictionary,
71
+
72
+ /**
73
+ * Unix ms timestamp when this entity was created.
74
+ * Read-only; sourced from the system section of the automerge document — not stored in meta.
75
+ */
76
+ createdAt: Schema.optional(Schema.Number),
77
+
78
+ /**
79
+ * Unix ms timestamp of the last automerge change on this entity's document.
80
+ * Read-only; derived from the automerge change graph — not stored in meta.
36
81
  */
37
- // TODO(dmaretskyi): Has to be optional for compatibility with old data.
38
- // Defaulting to an empty array is possible but requires a bit more work.
39
- // TODO(dmaretskyi): In automerge this should be a map of { [tag]: boolean } for uniqueness and conflict resolution.
40
- tags: Schema.optional(Schema.Array(Schema.String)),
82
+ updatedAt: Schema.optional(Schema.Number),
41
83
  });
42
84
 
43
- export type ObjectMeta = Schema.Schema.Type<typeof ObjectMetaSchema>;
85
+ export type EntityMeta = Schema.Schema.Type<typeof EntityMetaSchema>;
44
86
 
45
87
  /*
46
88
  * Get metadata from object.
@@ -49,9 +91,9 @@ export type ObjectMeta = Schema.Schema.Type<typeof ObjectMetaSchema>;
49
91
  * @internal (use Obj.getMeta or Relation.getMeta)
50
92
  */
51
93
  // TODO(burdon): Refine type to BaseObj.
52
- export const getMeta = (obj: AnyProperties): ObjectMeta => {
94
+ export const getMeta = (obj: AnyProperties): EntityMeta => {
53
95
  const metadata = (obj as any)[MetaId];
54
- invariant(metadata, 'ObjectMeta not found.');
96
+ invariant(metadata, 'EntityMeta not found.');
55
97
  return metadata;
56
98
  };
57
99
 
@@ -2,6 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ // TODO(rename): These internal entity-wide symbols/types still use the `Object*` prefix but apply
6
+ // to all entities (objects AND relations). Rename to `Entity*` in a follow-up pass (deferred from the
7
+ // EchoURI→EID / ObjectId→EntityId / ObjectMeta→EntityMeta rename, which covered only public SDK API):
8
+ // ObjectCore, ObjectInternals, ObjectVersion, ObjectVersionId, ObjectDeletedId, ObjectDatabaseId,
9
+ // ObjectLoader, ObjectDocumentLoaded, ObjectUnavailable.
10
+ // (ObjectMigration / ObjectMigrationContext intentionally excluded — object-only, not entity-wide.)
11
+
5
12
  /**
6
13
  * Internal symbol/string constants for the echo object model.
7
14
  * Defined in common/ so proxy/ can use them without importing from Entity/.
@@ -9,14 +16,19 @@
9
16
  */
10
17
 
11
18
  /**
12
- * Property name for self DXN when object is serialized to JSON.
19
+ * Property name for the object's own URI when serialized to JSON.
20
+ */
21
+ export const ATTR_SELF_URI = '@uri';
22
+
23
+ /**
24
+ * @deprecated Legacy JSON property name accepted on read for backward compat.
13
25
  */
14
- export const ATTR_SELF_DXN = '@dxn';
26
+ export const ATTR_SELF_URI_LEGACY = '@dxn';
15
27
 
16
28
  /**
17
- * DXN to the object itself.
29
+ * Symbol carrying the object's own URI on live entities.
18
30
  */
19
- export const SelfDXNId = Symbol.for('@dxos/echo/DXN');
31
+ export const SelfURIId = Symbol.for('@dxos/echo/URI');
20
32
 
21
33
  /**
22
34
  * Property name for deleted when object is serialized to JSON.
@@ -67,3 +79,11 @@ export const RelationTargetId: unique symbol = Symbol.for('@dxos/echo/RelationTa
67
79
  * Used to access relation target DXN on live ECHO objects.
68
80
  */
69
81
  export const RelationTargetDXNId: unique symbol = Symbol.for('@dxos/echo/RelationTargetDXN');
82
+
83
+ /**
84
+ * Symbol carrying the entity metadata (EntityMeta) on live ECHO entities.
85
+ * Must be importable by both meta.ts (which depends on the Ref schema) and
86
+ * Entity/api.ts (which is transitively imported by the Ref schema), so it
87
+ * cannot live in either of those files without creating an import cycle.
88
+ */
89
+ export const MetaId = Symbol.for('@dxos/echo/Meta');
@@ -30,11 +30,20 @@ export const ATTR_PARENT = '@parent';
30
30
  export const ParentId = Symbol.for('@dxos/echo/Parent');
31
31
 
32
32
  /**
33
- * Returns the schema for the given object if one is defined.
33
+ * Reference to the object's type entity (`Type.Obj`, `Type.Relation`, or
34
+ * `Type.Type`). Set at instance creation by `createObject` / `makeObject`
35
+ * when the entity is known. Public read-back via `Obj.getType` / `Relation.getType`
36
+ * / `Entity.getType`.
37
+ */
38
+ export const TypeEntityId = Symbol.for('@dxos/echo/TypeEntity');
39
+
40
+ /**
41
+ * Returns the Effect Schema for the given object if one is defined.
34
42
  *
35
- * @internal (Use Obj.getSchema)
43
+ * @internal
44
+ * Internal callers needing schema-side validation read from `SchemaId`.
45
+ * Public callers should use `Type.getSchema(Obj.getType(obj))` instead.
36
46
  */
37
- // TODO(burdon): Narrow type.
38
47
  // TODO(dmaretskyi): For echo objects, this always returns the root schema.
39
48
  export const getSchema = (obj: unknown | undefined): Schema.Schema.AnyNoContext | undefined => {
40
49
  if (obj) {
@@ -53,3 +62,30 @@ export const setSchema = (obj: any, schema: Schema.Schema.AnyNoContext): void =>
53
62
  configurable: false,
54
63
  });
55
64
  };
65
+
66
+ /**
67
+ * Returns the type entity (`Type.AnyEntity`) for the given instance.
68
+ * Set at instance creation; every entity has a type. Defensive: returns
69
+ * undefined for null/undefined input so callers can safely probe arbitrary
70
+ * values via this helper.
71
+ *
72
+ * @internal Re-exported via `Obj.getType` / `Relation.getType` / `Entity.getType`.
73
+ */
74
+ export const getType = (obj: unknown): unknown => {
75
+ if (obj == null) {
76
+ return undefined;
77
+ }
78
+ return (obj as any)[TypeEntityId];
79
+ };
80
+
81
+ /**
82
+ * @internal
83
+ */
84
+ export const setType = (obj: any, type: unknown): void => {
85
+ Object.defineProperty(obj, TypeEntityId, {
86
+ value: type,
87
+ writable: false,
88
+ enumerable: false,
89
+ configurable: true,
90
+ });
91
+ };
@@ -0,0 +1,15 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { DXN } from '@dxos/keys';
6
+
7
+ /**
8
+ * DXN identity of the system {@link Tag} type.
9
+ *
10
+ * Defined in this low-level leaf so it can be shared by the public `Tag` type (which brands the
11
+ * schema with this DXN) and by `EntityMetaSchema.tags` (which builds a `Ref<Tag>` schema from it)
12
+ * without either importing the other — `Tag` is top-level and `meta` is deep-internal, so a direct
13
+ * dependency between them would form an eval-order cycle.
14
+ */
15
+ export const TagTypeDXN = DXN.make('org.dxos.type.tag', '0.1.0');
@@ -2,9 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- // TODO(burdon): Import directly (not part of ECHO API).
6
- export { JsonPath, JsonProp, getValue, splitJsonPath } from '@dxos/effect';
7
-
8
5
  export * from './Annotation';
9
6
  export * from './common';
10
7
  export * from './Entity';
@@ -12,6 +9,11 @@ export * from './Format';
12
9
  export * from './JsonSchema';
13
10
  // TODO(wittjosiah): Required to ensure types are portable (need to export all types required for downstream inference).
14
11
  export * from './Obj';
15
- export * from './Query';
12
+ export { prettyFilter, prettyQuery } from './Query/pretty';
16
13
  export * from './Ref';
17
14
  export * from './Type';
15
+
16
+ // Re-exported here (not from the low-level `common/types` barrel) so consumers keep importing meta
17
+ // from `@dxos/echo/internal`, while that barrel stays free of the Ref/Annotation eval cycle. Placed
18
+ // after `./Ref` so the ref schema `meta` depends on is initialized first.
19
+ export * from './common/types/meta';