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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +7 -7
  3. package/dist/lib/neutral/Annotation.mjs +29 -6
  4. package/dist/lib/neutral/Database.mjs +8 -9
  5. package/dist/lib/neutral/Entity.mjs +29 -18
  6. package/dist/lib/neutral/Err.mjs +3 -3
  7. package/dist/lib/neutral/Feed.mjs +27 -19
  8. package/dist/lib/neutral/Filter.mjs +25 -15
  9. package/dist/lib/neutral/Format.mjs +23 -3
  10. package/dist/lib/neutral/JsonSchema.mjs +7 -8
  11. package/dist/lib/neutral/Key.mjs +9 -5
  12. package/dist/lib/neutral/Migration.mjs +18 -0
  13. package/dist/lib/neutral/Obj.mjs +25 -19
  14. package/dist/lib/neutral/Order.mjs +1 -1
  15. package/dist/lib/neutral/Query.mjs +19 -16
  16. package/dist/lib/neutral/QueryResult.mjs +1 -1
  17. package/dist/lib/neutral/Ref.mjs +10 -9
  18. package/dist/lib/neutral/Registry.mjs +14 -0
  19. package/dist/lib/neutral/Registry.mjs.map +7 -0
  20. package/dist/lib/neutral/Relation.mjs +26 -24
  21. package/dist/lib/neutral/Scope.mjs +12 -0
  22. package/dist/lib/neutral/Scope.mjs.map +7 -0
  23. package/dist/lib/neutral/Tag.mjs +17 -13
  24. package/dist/lib/neutral/Type.mjs +52 -26
  25. package/dist/lib/neutral/chunk-3DKP2EIN.mjs +31 -0
  26. package/dist/lib/neutral/chunk-3DKP2EIN.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-4BB4MFCN.mjs +154 -0
  28. package/dist/lib/neutral/chunk-4BB4MFCN.mjs.map +7 -0
  29. package/dist/lib/neutral/{chunk-CIRHIEMW.mjs → chunk-4SFPZJVA.mjs} +92 -112
  30. package/dist/lib/neutral/chunk-4SFPZJVA.mjs.map +7 -0
  31. package/dist/lib/neutral/{chunk-YWXWXIE5.mjs → chunk-4Z6GET2X.mjs} +3 -3
  32. package/dist/lib/neutral/chunk-4Z6GET2X.mjs.map +7 -0
  33. package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7LOUAPYZ.mjs} +9 -5
  34. package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +7 -0
  35. package/dist/lib/neutral/{chunk-43Y5DOS6.mjs → chunk-7OAFN3OX.mjs} +75 -112
  36. package/dist/lib/neutral/chunk-7OAFN3OX.mjs.map +7 -0
  37. package/dist/lib/neutral/{chunk-BOZZPUXE.mjs → chunk-7PRCIDHH.mjs} +41 -81
  38. package/dist/lib/neutral/chunk-7PRCIDHH.mjs.map +7 -0
  39. package/dist/lib/neutral/{chunk-UBEZSGXY.mjs → chunk-BBFJWWAV.mjs} +6 -6
  40. package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +7 -0
  41. package/dist/lib/neutral/chunk-BDQGMDIX.mjs +132 -0
  42. package/dist/lib/neutral/chunk-BDQGMDIX.mjs.map +7 -0
  43. package/dist/lib/neutral/chunk-CGTI5MXO.mjs +36 -0
  44. package/dist/lib/neutral/chunk-CGTI5MXO.mjs.map +7 -0
  45. package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-DKLUHO4T.mjs} +1 -1
  46. package/dist/lib/neutral/chunk-DKLUHO4T.mjs.map +7 -0
  47. package/dist/lib/neutral/chunk-DMN2CKPX.mjs +93 -0
  48. package/dist/lib/neutral/chunk-DMN2CKPX.mjs.map +7 -0
  49. package/dist/lib/neutral/{chunk-UTBRYVQC.mjs → chunk-G6CFWUYH.mjs} +2 -2
  50. package/dist/lib/neutral/chunk-H26LSXVJ.mjs +653 -0
  51. package/dist/lib/neutral/chunk-H26LSXVJ.mjs.map +7 -0
  52. package/dist/lib/neutral/{chunk-FXEG7EOK.mjs → chunk-J3MNM65T.mjs} +9 -6
  53. package/dist/lib/neutral/chunk-J3MNM65T.mjs.map +7 -0
  54. package/dist/lib/neutral/chunk-JE7AOSWF.mjs +247 -0
  55. package/dist/lib/neutral/chunk-JE7AOSWF.mjs.map +7 -0
  56. package/dist/lib/neutral/chunk-LAF3LSWI.mjs +379 -0
  57. package/dist/lib/neutral/chunk-LAF3LSWI.mjs.map +7 -0
  58. package/dist/lib/neutral/chunk-LMNRFOVB.mjs +108 -0
  59. package/dist/lib/neutral/chunk-LMNRFOVB.mjs.map +7 -0
  60. package/dist/lib/neutral/{chunk-WYOKA6AE.mjs → chunk-O6BH7EPN.mjs} +31 -4
  61. package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +7 -0
  62. package/dist/lib/neutral/{chunk-KTAWP7GI.mjs → chunk-OIYW7R2G.mjs} +99 -46
  63. package/dist/lib/neutral/chunk-OIYW7R2G.mjs.map +7 -0
  64. package/dist/lib/neutral/{chunk-TQQZLKB7.mjs → chunk-OYUG4FHF.mjs} +648 -1228
  65. package/dist/lib/neutral/chunk-OYUG4FHF.mjs.map +7 -0
  66. package/dist/lib/neutral/{chunk-NQRLRYJM.mjs → chunk-Q5FKCVBC.mjs} +173 -60
  67. package/dist/lib/neutral/chunk-Q5FKCVBC.mjs.map +7 -0
  68. package/dist/lib/neutral/chunk-Q62IHV2N.mjs +41 -0
  69. package/dist/lib/neutral/chunk-Q62IHV2N.mjs.map +7 -0
  70. package/dist/lib/neutral/{chunk-UFDK26FO.mjs → chunk-QVJDDG44.mjs} +69 -34
  71. package/dist/lib/neutral/chunk-QVJDDG44.mjs.map +7 -0
  72. package/dist/lib/neutral/{chunk-B5OXLWZL.mjs → chunk-TFEWTY5A.mjs} +155 -129
  73. package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +7 -0
  74. package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-TTCSATUD.mjs} +1 -1
  75. package/dist/lib/neutral/{chunk-FZO7LQO7.mjs → chunk-VKWOFXT2.mjs} +22 -2
  76. package/dist/lib/neutral/{chunk-FZO7LQO7.mjs.map → chunk-VKWOFXT2.mjs.map} +1 -1
  77. package/dist/lib/neutral/{chunk-NXMFBIT5.mjs → chunk-ZACMEAYV.mjs} +89 -23
  78. package/dist/lib/neutral/chunk-ZACMEAYV.mjs.map +7 -0
  79. package/dist/lib/neutral/index.mjs +58 -38
  80. package/dist/lib/neutral/internal/index.mjs +131 -64
  81. package/dist/lib/neutral/meta.json +1 -1
  82. package/dist/lib/neutral/testing/index.mjs +222 -177
  83. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  84. package/dist/types/src/Annotation.d.ts +108 -4
  85. package/dist/types/src/Annotation.d.ts.map +1 -1
  86. package/dist/types/src/Annotation.test.d.ts +2 -0
  87. package/dist/types/src/Annotation.test.d.ts.map +1 -0
  88. package/dist/types/src/Collection.d.ts +2 -3
  89. package/dist/types/src/Collection.d.ts.map +1 -1
  90. package/dist/types/src/Database.d.ts +56 -24
  91. package/dist/types/src/Database.d.ts.map +1 -1
  92. package/dist/types/src/Dataset.d.ts +17 -6
  93. package/dist/types/src/Dataset.d.ts.map +1 -1
  94. package/dist/types/src/Entity.d.ts +102 -26
  95. package/dist/types/src/Entity.d.ts.map +1 -1
  96. package/dist/types/src/Err.d.ts +27 -27
  97. package/dist/types/src/Err.d.ts.map +1 -1
  98. package/dist/types/src/Feed.d.ts +89 -25
  99. package/dist/types/src/Feed.d.ts.map +1 -1
  100. package/dist/types/src/Filter.d.ts +74 -11
  101. package/dist/types/src/Filter.d.ts.map +1 -1
  102. package/dist/types/src/Filter.test.d.ts +2 -0
  103. package/dist/types/src/Filter.test.d.ts.map +1 -0
  104. package/dist/types/src/Hypergraph.d.ts +14 -9
  105. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  106. package/dist/types/src/Json.d.ts +33 -0
  107. package/dist/types/src/Json.d.ts.map +1 -0
  108. package/dist/types/src/Json.test.d.ts +2 -0
  109. package/dist/types/src/Json.test.d.ts.map +1 -0
  110. package/dist/types/src/JsonSchema.d.ts +2 -2
  111. package/dist/types/src/JsonSchema.d.ts.map +1 -1
  112. package/dist/types/src/Key.d.ts +1 -1
  113. package/dist/types/src/Key.d.ts.map +1 -1
  114. package/dist/types/src/Migration.d.ts +72 -0
  115. package/dist/types/src/Migration.d.ts.map +1 -0
  116. package/dist/types/src/Obj.d.ts +108 -65
  117. package/dist/types/src/Obj.d.ts.map +1 -1
  118. package/dist/types/src/Order.d.ts.map +1 -1
  119. package/dist/types/src/Query.d.ts +35 -10
  120. package/dist/types/src/Query.d.ts.map +1 -1
  121. package/dist/types/src/QueryResult.d.ts +9 -0
  122. package/dist/types/src/QueryResult.d.ts.map +1 -1
  123. package/dist/types/src/Ref.d.ts +15 -7
  124. package/dist/types/src/Ref.d.ts.map +1 -1
  125. package/dist/types/src/Registry.d.ts +131 -0
  126. package/dist/types/src/Registry.d.ts.map +1 -0
  127. package/dist/types/src/Relation.d.ts +72 -44
  128. package/dist/types/src/Relation.d.ts.map +1 -1
  129. package/dist/types/src/Scope.d.ts +34 -0
  130. package/dist/types/src/Scope.d.ts.map +1 -0
  131. package/dist/types/src/StateMap.d.ts +32 -0
  132. package/dist/types/src/StateMap.d.ts.map +1 -0
  133. package/dist/types/src/StateMap.test.d.ts +2 -0
  134. package/dist/types/src/StateMap.test.d.ts.map +1 -0
  135. package/dist/types/src/Tag.d.ts +21 -5
  136. package/dist/types/src/Tag.d.ts.map +1 -1
  137. package/dist/types/src/TagIndex.d.ts +36 -0
  138. package/dist/types/src/TagIndex.d.ts.map +1 -0
  139. package/dist/types/src/TagIndex.test.d.ts +2 -0
  140. package/dist/types/src/TagIndex.test.d.ts.map +1 -0
  141. package/dist/types/src/Tagging.d.ts +31 -0
  142. package/dist/types/src/Tagging.d.ts.map +1 -0
  143. package/dist/types/src/Type.d.ts +357 -96
  144. package/dist/types/src/Type.d.ts.map +1 -1
  145. package/dist/types/src/View.d.ts +2 -5
  146. package/dist/types/src/View.d.ts.map +1 -1
  147. package/dist/types/src/exemplars.test.d.ts +2 -0
  148. package/dist/types/src/exemplars.test.d.ts.map +1 -0
  149. package/dist/types/src/index.d.ts +8 -2
  150. package/dist/types/src/index.d.ts.map +1 -1
  151. package/dist/types/src/internal/Annotation/annotations.d.ts +79 -37
  152. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
  153. package/dist/types/src/internal/Annotation/dictionary.d.ts +24 -0
  154. package/dist/types/src/internal/Annotation/dictionary.d.ts.map +1 -0
  155. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +14 -0
  156. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -0
  157. package/dist/types/src/internal/Annotation/index.d.ts +4 -2
  158. package/dist/types/src/internal/Annotation/index.d.ts.map +1 -1
  159. package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -1
  160. package/dist/types/src/internal/Annotation/util.d.ts +14 -5
  161. package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
  162. package/dist/types/src/internal/Entity/api.d.ts +3 -3
  163. package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
  164. package/dist/types/src/internal/Entity/entity.d.ts +72 -8
  165. package/dist/types/src/internal/Entity/entity.d.ts.map +1 -1
  166. package/dist/types/src/internal/Entity/guard.d.ts +10 -0
  167. package/dist/types/src/internal/Entity/guard.d.ts.map +1 -0
  168. package/dist/types/src/internal/Entity/index.d.ts +2 -0
  169. package/dist/types/src/internal/Entity/index.d.ts.map +1 -1
  170. package/dist/types/src/internal/Entity/model.d.ts +20 -17
  171. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  172. package/dist/types/src/internal/Entity/object.d.ts +3 -3
  173. package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
  174. package/dist/types/src/internal/Entity/relation.d.ts +30 -7
  175. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
  176. package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
  177. package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
  178. package/dist/types/src/internal/Entity/type-uri.d.ts +25 -0
  179. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
  180. package/dist/types/src/internal/Entity/version.d.ts.map +1 -1
  181. package/dist/types/src/internal/Format/date.d.ts.map +1 -1
  182. package/dist/types/src/internal/Format/format.d.ts +3 -2
  183. package/dist/types/src/internal/Format/format.d.ts.map +1 -1
  184. package/dist/types/src/internal/Format/index.d.ts +2 -2
  185. package/dist/types/src/internal/Format/index.d.ts.map +1 -1
  186. package/dist/types/src/internal/Format/number.d.ts.map +1 -1
  187. package/dist/types/src/internal/Format/object.d.ts +3 -1
  188. package/dist/types/src/internal/Format/object.d.ts.map +1 -1
  189. package/dist/types/src/internal/Format/types.d.ts.map +1 -1
  190. package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -1
  191. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts +28 -28
  192. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
  193. package/dist/types/src/internal/JsonSchema/json-schema.d.ts +3 -2
  194. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
  195. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
  196. package/dist/types/src/internal/Obj/common.d.ts.map +1 -1
  197. package/dist/types/src/internal/Obj/create-object.d.ts +11 -12
  198. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
  199. package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -1
  200. package/dist/types/src/internal/Obj/index.d.ts +0 -1
  201. package/dist/types/src/internal/Obj/index.d.ts.map +1 -1
  202. package/dist/types/src/internal/Obj/json-serializer.d.ts +11 -10
  203. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
  204. package/dist/types/src/internal/Obj/set-value.d.ts +1 -1
  205. package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -1
  206. package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -1
  207. package/dist/types/src/internal/Obj/typed-object.d.ts +1 -1
  208. package/dist/types/src/internal/Query.d.ts +10 -0
  209. package/dist/types/src/internal/Query.d.ts.map +1 -0
  210. package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
  211. package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -1
  212. package/dist/types/src/internal/Ref/ref.d.ts +42 -19
  213. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
  214. package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
  215. package/dist/types/src/internal/Type/index.d.ts +1 -2
  216. package/dist/types/src/internal/Type/index.d.ts.map +1 -1
  217. package/dist/types/src/internal/Type/manipulation.d.ts +0 -1
  218. package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
  219. package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
  220. package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
  221. package/dist/types/src/internal/common/api/meta.d.ts +14 -11
  222. package/dist/types/src/internal/common/api/meta.d.ts.map +1 -1
  223. package/dist/types/src/internal/common/proxy/change-context.d.ts +1 -1
  224. package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -1
  225. package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -1
  226. package/dist/types/src/internal/common/proxy/errors.d.ts +1 -1
  227. package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -1
  228. package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -1
  229. package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -1
  230. package/dist/types/src/internal/common/proxy/make-object.d.ts +11 -5
  231. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
  232. package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -1
  233. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
  234. package/dist/types/src/internal/common/proxy/reactive-array.d.ts +1 -1
  235. package/dist/types/src/internal/common/proxy/reactive.d.ts +1 -1
  236. package/dist/types/src/internal/common/proxy/reactive.d.ts.map +1 -1
  237. package/dist/types/src/internal/common/proxy/reactive.test.d.ts +2 -0
  238. package/dist/types/src/internal/common/proxy/reactive.test.d.ts.map +1 -0
  239. package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
  240. package/dist/types/src/internal/common/proxy/typed-handler.d.ts +18 -2
  241. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
  242. package/dist/types/src/internal/common/types/base.d.ts +4 -4
  243. package/dist/types/src/internal/common/types/base.d.ts.map +1 -1
  244. package/dist/types/src/internal/common/types/entity.d.ts +63 -6
  245. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
  246. package/dist/types/src/internal/common/types/index.d.ts +1 -1
  247. package/dist/types/src/internal/common/types/index.d.ts.map +1 -1
  248. package/dist/types/src/internal/common/types/meta.d.ts +23 -7
  249. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
  250. package/dist/types/src/internal/common/types/model-symbols.d.ts +8 -4
  251. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -1
  252. package/dist/types/src/internal/common/types/typename.d.ts +7 -0
  253. package/dist/types/src/internal/common/types/typename.d.ts.map +1 -1
  254. package/dist/types/src/internal/common/types/version.d.ts +1 -1
  255. package/dist/types/src/internal/common/types/well-known-types.d.ts +11 -0
  256. package/dist/types/src/internal/common/types/well-known-types.d.ts.map +1 -0
  257. package/dist/types/src/internal/index.d.ts +2 -0
  258. package/dist/types/src/internal/index.d.ts.map +1 -1
  259. package/dist/types/src/testing/test-data.d.ts +8 -8
  260. package/dist/types/src/testing/test-data.d.ts.map +1 -1
  261. package/dist/types/src/testing/test-schema.d.ts +83 -89
  262. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  263. package/dist/types/src/testing/util.d.ts +5 -3
  264. package/dist/types/src/testing/util.d.ts.map +1 -1
  265. package/dist/types/tsconfig.tsbuildinfo +1 -1
  266. package/package.json +27 -19
  267. package/src/Annotation.test.ts +439 -0
  268. package/src/Annotation.ts +152 -4
  269. package/src/Collection.ts +6 -5
  270. package/src/Database.ts +117 -57
  271. package/src/Dataset.ts +10 -2
  272. package/src/Entity.test.ts +116 -6
  273. package/src/Entity.ts +130 -31
  274. package/src/Err.ts +4 -4
  275. package/src/Feed.ts +138 -43
  276. package/src/Filter.test.ts +90 -0
  277. package/src/Filter.ts +143 -27
  278. package/src/Hypergraph.ts +14 -9
  279. package/src/Json.test.ts +175 -0
  280. package/src/Json.ts +103 -0
  281. package/src/Key.ts +1 -1
  282. package/src/Migration.ts +114 -0
  283. package/src/Obj.test.ts +122 -19
  284. package/src/Obj.ts +279 -97
  285. package/src/Query.test.ts +317 -131
  286. package/src/Query.ts +181 -73
  287. package/src/QueryResult.ts +11 -0
  288. package/src/Ref.ts +22 -4
  289. package/src/Registry.ts +155 -0
  290. package/src/Relation.test.ts +10 -10
  291. package/src/Relation.ts +112 -71
  292. package/src/Scope.ts +50 -0
  293. package/src/StateMap.test.ts +56 -0
  294. package/src/StateMap.ts +99 -0
  295. package/src/Tag.md +88 -0
  296. package/src/Tag.ts +49 -6
  297. package/src/TagIndex.test.ts +57 -0
  298. package/src/TagIndex.ts +110 -0
  299. package/src/Tagging.ts +83 -0
  300. package/src/Type.test.ts +223 -18
  301. package/src/Type.ts +602 -132
  302. package/src/View.ts +11 -15
  303. package/src/exemplars.test.ts +21 -0
  304. package/src/index.ts +9 -3
  305. package/src/internal/Annotation/annotations.test.ts +82 -13
  306. package/src/internal/Annotation/annotations.ts +153 -115
  307. package/src/internal/Annotation/dictionary.ts +47 -0
  308. package/src/internal/Annotation/entity-dictionary.ts +40 -0
  309. package/src/internal/Annotation/index.ts +4 -2
  310. package/src/internal/Annotation/sorting.ts +0 -1
  311. package/src/internal/Annotation/util.ts +17 -8
  312. package/src/internal/Entity/api.ts +7 -8
  313. package/src/internal/Entity/entity.ts +196 -47
  314. package/src/internal/Entity/guard.ts +26 -0
  315. package/src/internal/Entity/index.ts +2 -0
  316. package/src/internal/Entity/model.ts +37 -28
  317. package/src/internal/Entity/object.ts +21 -6
  318. package/src/internal/Entity/relation.ts +68 -34
  319. package/src/internal/Entity/type-kind.ts +75 -0
  320. package/src/internal/Entity/type-uri.ts +87 -0
  321. package/src/internal/Entity/util.ts +10 -9
  322. package/src/internal/Entity/version.ts +0 -1
  323. package/src/internal/Format/date.test.ts +0 -1
  324. package/src/internal/Format/date.ts +0 -4
  325. package/src/internal/Format/format.test.ts +21 -1
  326. package/src/internal/Format/index.ts +2 -3
  327. package/src/internal/Format/object.ts +21 -4
  328. package/src/internal/Format/types.ts +1 -1
  329. package/src/internal/JsonSchema/annotations.ts +1 -1
  330. package/src/internal/JsonSchema/json-schema-type.ts +1 -1
  331. package/src/internal/JsonSchema/json-schema.test.ts +55 -142
  332. package/src/internal/JsonSchema/json-schema.ts +44 -31
  333. package/src/internal/Obj/clone.ts +9 -4
  334. package/src/internal/Obj/create-object.test.ts +13 -13
  335. package/src/internal/Obj/create-object.ts +68 -24
  336. package/src/internal/Obj/deleted.ts +1 -1
  337. package/src/internal/Obj/index.ts +0 -1
  338. package/src/internal/Obj/inspect.ts +4 -3
  339. package/src/internal/Obj/json-serializer.test.ts +102 -24
  340. package/src/internal/Obj/json-serializer.ts +105 -43
  341. package/src/internal/Obj/set-value.test.ts +31 -54
  342. package/src/internal/Obj/set-value.ts +1 -1
  343. package/src/internal/Obj/snapshot.ts +11 -4
  344. package/src/internal/Obj/typed-object.test.ts +9 -11
  345. package/src/internal/Obj/typed-object.ts +1 -1
  346. package/src/internal/Query.ts +159 -0
  347. package/src/internal/Ref/ref-array.ts +3 -4
  348. package/src/internal/Ref/ref.test.ts +17 -27
  349. package/src/internal/Ref/ref.ts +124 -59
  350. package/src/internal/Type/compose.test.ts +3 -2
  351. package/src/internal/Type/index.ts +1 -2
  352. package/src/internal/Type/manipulation.ts +0 -25
  353. package/src/internal/Type/type-schema.ts +60 -0
  354. package/src/internal/common/README.md +2 -2
  355. package/src/internal/common/api/meta.ts +19 -17
  356. package/src/internal/common/proxy/change-context.ts +1 -1
  357. package/src/internal/common/proxy/change.test.ts +118 -110
  358. package/src/internal/common/proxy/errors.ts +2 -2
  359. package/src/internal/common/proxy/handler.test.ts +1 -3
  360. package/src/internal/common/proxy/json-serializer.ts +26 -16
  361. package/src/internal/common/proxy/make-object.ts +43 -21
  362. package/src/internal/common/proxy/ownership.ts +2 -3
  363. package/src/internal/common/proxy/reactive-array.ts +1 -1
  364. package/src/internal/common/proxy/reactive.test.ts +54 -0
  365. package/src/internal/common/proxy/reactive.ts +11 -3
  366. package/src/internal/common/proxy/schema.test.ts +48 -86
  367. package/src/internal/common/proxy/typed-handler.test.ts +12 -12
  368. package/src/internal/common/proxy/typed-handler.ts +79 -19
  369. package/src/internal/common/proxy/typed-object.test.ts +16 -29
  370. package/src/internal/common/types/base.ts +4 -4
  371. package/src/internal/common/types/entity.ts +81 -2
  372. package/src/internal/common/types/index.ts +6 -1
  373. package/src/internal/common/types/meta.ts +49 -15
  374. package/src/internal/common/types/model-symbols.ts +16 -4
  375. package/src/internal/common/types/typename.ts +39 -3
  376. package/src/internal/common/types/well-known-types.ts +15 -0
  377. package/src/internal/index.ts +6 -0
  378. package/src/testing/api.test.ts +15 -10
  379. package/src/testing/test-data.ts +159 -100
  380. package/src/testing/test-schema.ts +22 -58
  381. package/src/testing/util.ts +14 -11
  382. package/dist/lib/neutral/SchemaRegistry.mjs +0 -2
  383. package/dist/lib/neutral/chunk-43Y5DOS6.mjs.map +0 -7
  384. package/dist/lib/neutral/chunk-724GQYEN.mjs +0 -56
  385. package/dist/lib/neutral/chunk-724GQYEN.mjs.map +0 -7
  386. package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
  387. package/dist/lib/neutral/chunk-B5OXLWZL.mjs.map +0 -7
  388. package/dist/lib/neutral/chunk-BNCCGLJN.mjs +0 -7
  389. package/dist/lib/neutral/chunk-BNCCGLJN.mjs.map +0 -7
  390. package/dist/lib/neutral/chunk-BOZZPUXE.mjs.map +0 -7
  391. package/dist/lib/neutral/chunk-CIRHIEMW.mjs.map +0 -7
  392. package/dist/lib/neutral/chunk-DYDJBZEG.mjs +0 -102
  393. package/dist/lib/neutral/chunk-DYDJBZEG.mjs.map +0 -7
  394. package/dist/lib/neutral/chunk-FXEG7EOK.mjs.map +0 -7
  395. package/dist/lib/neutral/chunk-KTAWP7GI.mjs.map +0 -7
  396. package/dist/lib/neutral/chunk-NEGC54NE.mjs +0 -130
  397. package/dist/lib/neutral/chunk-NEGC54NE.mjs.map +0 -7
  398. package/dist/lib/neutral/chunk-NQRLRYJM.mjs.map +0 -7
  399. package/dist/lib/neutral/chunk-NXMFBIT5.mjs.map +0 -7
  400. package/dist/lib/neutral/chunk-OENWMTE6.mjs +0 -45
  401. package/dist/lib/neutral/chunk-OENWMTE6.mjs.map +0 -7
  402. package/dist/lib/neutral/chunk-OMUPQMLR.mjs.map +0 -7
  403. package/dist/lib/neutral/chunk-RMLF7JOZ.mjs +0 -97
  404. package/dist/lib/neutral/chunk-RMLF7JOZ.mjs.map +0 -7
  405. package/dist/lib/neutral/chunk-SEMVAGBM.mjs +0 -355
  406. package/dist/lib/neutral/chunk-SEMVAGBM.mjs.map +0 -7
  407. package/dist/lib/neutral/chunk-TQQZLKB7.mjs.map +0 -7
  408. package/dist/lib/neutral/chunk-UBEZSGXY.mjs.map +0 -7
  409. package/dist/lib/neutral/chunk-UFDK26FO.mjs.map +0 -7
  410. package/dist/lib/neutral/chunk-VA2F47ZC.mjs +0 -152
  411. package/dist/lib/neutral/chunk-VA2F47ZC.mjs.map +0 -7
  412. package/dist/lib/neutral/chunk-WYOKA6AE.mjs.map +0 -7
  413. package/dist/lib/neutral/chunk-YWXWXIE5.mjs.map +0 -7
  414. package/dist/types/src/SchemaRegistry.d.ts +0 -84
  415. package/dist/types/src/SchemaRegistry.d.ts.map +0 -1
  416. package/dist/types/src/internal/Obj/ids.d.ts +0 -6
  417. package/dist/types/src/internal/Obj/ids.d.ts.map +0 -1
  418. package/dist/types/src/internal/Type/echo-schema.d.ts +0 -181
  419. package/dist/types/src/internal/Type/echo-schema.d.ts.map +0 -1
  420. package/dist/types/src/internal/Type/persistent-schema.d.ts +0 -20
  421. package/dist/types/src/internal/Type/persistent-schema.d.ts.map +0 -1
  422. package/src/SchemaRegistry.ts +0 -106
  423. package/src/internal/Obj/ids.ts +0 -12
  424. package/src/internal/Type/echo-schema.ts +0 -424
  425. package/src/internal/Type/persistent-schema.ts +0 -33
  426. /package/dist/lib/neutral/{SchemaRegistry.mjs.map → Migration.mjs.map} +0 -0
  427. /package/dist/lib/neutral/{chunk-UTBRYVQC.mjs.map → chunk-G6CFWUYH.mjs.map} +0 -0
  428. /package/dist/lib/neutral/{chunk-UI6MWK5W.mjs.map → chunk-TTCSATUD.mjs.map} +0 -0
package/src/Obj.ts CHANGED
@@ -5,23 +5,27 @@
5
5
  // @import-as-namespace
6
6
 
7
7
  import * as Effect from 'effect/Effect';
8
+ import * as Equal from 'effect/Equal';
8
9
  import * as Function from 'effect/Function';
9
10
  import * as Option from 'effect/Option';
10
11
  import * as Schema from 'effect/Schema';
12
+ import * as Utils from 'effect/Utils';
11
13
 
12
14
  import type { ForeignKey } from '@dxos/echo-protocol';
13
15
  import { createJsonPath } from '@dxos/effect';
14
- import { assertArgument } from '@dxos/invariant';
15
- import { type DXN, ObjectId } from '@dxos/keys';
16
- import { assumeType } from '@dxos/util';
16
+ import { assertArgument, invariant } from '@dxos/invariant';
17
+ import { DXN, EntityId, type URI } from '@dxos/keys';
18
+ import { assumeType, deepMapValues } from '@dxos/util';
17
19
 
18
20
  import type * as Database from './Database';
19
21
  import * as Entity from './Entity';
20
22
  import * as Err from './Err';
21
- import * as objInternal from './internal/Obj';
22
23
  import * as internal from './internal';
23
- import type * as Ref from './Ref';
24
- import type * as Type from './Type';
24
+ import { getProxyTarget, isProxy } from './internal/common/proxy/proxy-utils';
25
+ import * as objInternal from './internal/Obj';
26
+ import * as Ref from './Ref';
27
+ import type * as Tag from './Tag';
28
+ import * as Type from './Type';
25
29
 
26
30
  /**
27
31
  * Base type for all ECHO objects.
@@ -61,27 +65,24 @@ export interface Unknown extends BaseObj {}
61
65
  * // Reference to any object type
62
66
  * const Collection = Schema.Struct({
63
67
  * objects: Schema.Array(Ref.Ref(Obj.Unknown)),
64
- * }).pipe(Type.object({ typename: 'Collection', version: '0.1.0' }));
68
+ * }).pipe(Type.makeObject(DXN.make('com.example.type.collection', '0.1.0')));
65
69
  * ```
66
70
  */
67
71
  // TODO(wittjosiah): Investigate if Schema.filter can validate KindId on ECHO instances.
68
72
  // Effect Schema normalizes proxy objects to plain objects before calling filter predicates.
69
73
  // Possible approaches: custom Schema.declare, AST manipulation, or upstream contribution.
70
- export const Unknown: Type.Obj<Unknown> = Schema.Struct({
74
+ export const Unknown: internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object> = Schema.Struct({
71
75
  id: Schema.String,
72
76
  }).pipe(
73
77
  Schema.extend(Schema.Record({ key: Schema.String, value: Schema.Unknown })),
74
- // TODO(dmaretskyi): Clean this up.
75
- // NOTE: The EchoObjectSchema annotation is required for Ref.Ref(Obj.Unknown) to work.
76
- // The typename/version only satisfy ECHO schema machinery for reference targets.
77
- internal.EchoObjectSchema({ typename: internal.ANY_OBJECT_TYPENAME, version: internal.ANY_OBJECT_VERSION }),
78
- (schema) =>
79
- Object.assign(schema, {
80
- [internal.SchemaKindId]: (schema as any)[internal.SchemaKindId],
81
- }) as unknown as Type.Obj<Unknown>,
82
- );
83
-
84
- /**
78
+ Schema.annotations({
79
+ [internal.TypeAnnotationId]: {
80
+ kind: Entity.Kind.Object,
81
+ typename: internal.ANY_OBJECT_TYPENAME,
82
+ version: internal.ANY_OBJECT_VERSION,
83
+ },
84
+ }),
85
+ ) as unknown as internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object>;
85
86
 
86
87
  /**
87
88
  * Object with arbitrary properties.
@@ -98,7 +99,7 @@ export interface Any extends BaseObj, internal.AnyProperties {}
98
99
  */
99
100
  interface BaseSnapshot extends internal.AnyEntity {
100
101
  readonly [Entity.SnapshotKindId]: typeof Entity.Kind.Object;
101
- readonly id: ObjectId;
102
+ readonly id: EntityId;
102
103
  }
103
104
 
104
105
  /**
@@ -119,30 +120,44 @@ export interface BaseObjJson {
119
120
  id: string;
120
121
  }
121
122
 
122
- const defaultMeta: internal.ObjectMeta = {
123
+ // Factory (not a shared const): each object must get its own `keys`/`tags`/`annotations` containers,
124
+ // otherwise mutating one object's meta would leak into every other object via the shared references.
125
+ const defaultMeta = (): internal.EntityMeta => ({
123
126
  keys: [],
124
- };
125
-
126
- type MakePropsInternal<T extends Unknown> = {
127
- id?: ObjectId;
128
- [Meta]?: Partial<internal.ObjectMeta>;
129
- } & Entity.Properties<T>;
127
+ tags: [],
128
+ annotations: {},
129
+ });
130
130
 
131
131
  // TODO(burdon): Should we allow the caller to set the id?
132
132
  /**
133
- * Props type for object creation with a given schema.
133
+ * Props type for object creation with a given type. Accepts a `Type.AnyObj`
134
+ * entity and derives the instance shape via `Type.InstanceType`. Relation-kind
135
+ * entities are rejected at the type level — use `Relation.MakeProps` for those.
136
+ *
137
+ * When the schema is the unconstrained `Type.AnyObj` (`Obj<unknown>` — e.g. a
138
+ * dynamic type from `schemaRegistry.register`), the instance shape is not
139
+ * statically known, so data props widen to `Record<string, unknown>` and the
140
+ * caller can pass arbitrary fields without a cast.
134
141
  */
135
- export type MakeProps<S extends Schema.Schema.AnyNoContext> = {
136
- id?: ObjectId;
137
- [Meta]?: Partial<internal.ObjectMeta>;
142
+ export type MakeProps<S extends Type.AnyObj> = {
143
+ id?: EntityId;
144
+ [Meta]?: Partial<internal.EntityMeta>;
138
145
  [Parent]?: Unknown;
139
- } & MakePropsInternal<Schema.Schema.Type<S>>;
146
+ // When the resolved instance has no known data keys, widen to a permissive
147
+ // record (the `Obj<unknown>` case); otherwise use the precise property shape.
148
+ // `[keyof …] extends [never]` is wrapped in tuples so the check is
149
+ // non-distributive — a `never` instance type (e.g. when narrowing collapses
150
+ // the schema) stays a single branch instead of distributing to `never`.
151
+ } & ([keyof Entity.Properties<Type.InstanceType<S>>] extends [never]
152
+ ? Record<string, unknown>
153
+ : Entity.Properties<Type.InstanceType<S>>);
140
154
 
141
155
  /**
142
- * Creates a new echo object of the given schema.
143
- * @param schema - Object schema.
156
+ * Creates a new echo object of the given schema or `Type.Type`.
157
+ *
158
+ * @param typeOrSchema - A static object schema (`Type.makeObject(...)`) or a
159
+ * `Type.Type` entity (e.g. one returned by `db.addType(schemaEntity)`).
144
160
  * @param props - Object properties.
145
- * @param meta - Object metadata (deprecated) -- pass with Obj.Meta.
146
161
  *
147
162
  * Meta can be passed as a symbol in `props`.
148
163
  *
@@ -151,23 +166,26 @@ export type MakeProps<S extends Schema.Schema.AnyNoContext> = {
151
166
  * const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });
152
167
  * ```
153
168
  *
154
- * Note: Only accepts object schemas, not relation schemas. Use `Relation.make` for relations.
169
+ * Note: Only accepts object schemas / object-kind types, not relation schemas.
170
+ * Use `Relation.make` for relations.
155
171
  */
156
- export const make = <S extends Type.AnyObj>(
157
- schema: S,
158
- props: NoInfer<MakeProps<S>>,
159
- ): OfShape<Schema.Schema.Type<S>> => {
172
+ export function make<T extends Type.AnyObj>(type: T, props: NoInfer<MakeProps<T>>): OfShape<Type.InstanceType<T>>;
173
+ export function make(input: Type.AnyObj, props: any): OfShape<any> {
174
+ // `Type.Type` entities aren't `Schema.Schema` themselves; derive the Effect
175
+ // Schema via `Type.getSchema(...)`. Pass the entity through to `makeObject`
176
+ // so subsequent schema mutations (`Type.addFields`, etc.) propagate.
177
+ const schema = Type.getSchema(input);
160
178
  assertArgument(
161
179
  internal.getTypeAnnotation(schema)?.kind === Entity.Kind.Object,
162
180
  'schema',
163
181
  'Expected an object schema',
164
182
  );
165
183
 
166
- let meta: internal.ObjectMeta | undefined = undefined;
184
+ let meta: internal.EntityMeta | undefined = undefined;
167
185
 
168
186
  // Set default fields on meta on creation.
169
187
  if (props[internal.MetaId] != null) {
170
- meta = { ...structuredClone(defaultMeta), ...props[internal.MetaId] };
188
+ meta = { ...defaultMeta(), ...props[internal.MetaId] };
171
189
  delete props[internal.MetaId];
172
190
  }
173
191
 
@@ -182,11 +200,16 @@ export const make = <S extends Type.AnyObj>(
182
200
  }
183
201
  }
184
202
 
185
- return internal.makeObject<Schema.Schema.Type<S>>(schema, filterUndefined as any, {
186
- ...defaultMeta,
187
- ...meta,
188
- });
189
- };
203
+ return internal.makeObject(
204
+ schema,
205
+ filterUndefined,
206
+ {
207
+ ...defaultMeta(),
208
+ ...meta,
209
+ },
210
+ input,
211
+ );
212
+ }
190
213
 
191
214
  /**
192
215
  * Determine if object is an ECHO object.
@@ -303,7 +326,7 @@ export const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = objI
303
326
 
304
327
  /**
305
328
  * Makes all properties mutable recursively.
306
- * Used to provide a mutable view of an object within `Obj.change`.
329
+ * Used to provide a mutable view of an object within `Obj.update`.
307
330
  */
308
331
  export type Mutable<T> = internal.Mutable<T>;
309
332
 
@@ -311,33 +334,33 @@ export type Mutable<T> = internal.Mutable<T>;
311
334
  * Perform mutations on an echo object within a controlled context.
312
335
  *
313
336
  * All mutations within the callback are batched and trigger a single notification
314
- * when the callback completes. Direct mutations outside of `Obj.change` will throw
337
+ * when the callback completes. Direct mutations outside of `Obj.update` will throw
315
338
  * an error for echo objects.
316
339
  *
317
340
  * This function also works with nested objects within echo objects (e.g., Template structs)
318
341
  * that are reactive at runtime.
319
342
  *
320
- * @param obj - The echo object to mutate. Use `Relation.change` for relations.
343
+ * @param obj - The echo object to mutate. Use `Relation.update` for relations.
321
344
  * @param callback - The callback that performs mutations on the object.
322
345
  *
323
346
  * @example
324
347
  * ```ts
325
348
  * const person = Obj.make(Person, { name: 'John', age: 25 });
326
349
  *
327
- * // Mutate within Obj.change
328
- * Obj.change(person, (p) => {
329
- * p.name = 'Jane';
330
- * p.age = 30;
350
+ * // Mutate within Obj.update
351
+ * Obj.update(person, (obj) => {
352
+ * obj.name = 'Jane';
353
+ * obj.age = 30;
331
354
  * });
332
355
  * // ONE notification fires here
333
356
  *
334
357
  * // Direct mutation throws
335
- * person.name = 'Bob'; // Error: Cannot modify outside Obj.change()
358
+ * person.name = 'Bob'; // Error: Cannot modify outside Obj.update()
336
359
  * ```
337
360
  *
338
- * Note: Only accepts objects. Use `Relation.change` for relations.
361
+ * Note: Only accepts objects. Use `Relation.update` for relations.
339
362
  */
340
- export const change = <T extends Unknown>(obj: T, callback: internal.ChangeCallback<T>): void => {
363
+ export const update = <T extends Unknown>(obj: T, callback: internal.ChangeCallback<T>): void => {
341
364
  internal.change(obj, callback);
342
365
  };
343
366
 
@@ -372,7 +395,7 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
372
395
  * whether to initialize nested data as an empty object or array.
373
396
  *
374
397
  * Similar to lodash.set and setDeep from @dxos/util, but schema-aware.
375
- * Must be called within an `Obj.change` callback.
398
+ * Must be called within an `Obj.update` callback.
376
399
  *
377
400
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
378
401
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
@@ -386,8 +409,8 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
386
409
  * ```ts
387
410
  * const person = Obj.make(Person, { name: 'John' });
388
411
  * // Person schema has: addresses: Schema.Array(Address)
389
- * Obj.change(person, (p) => {
390
- * Obj.setValue(p, ['addresses', 0, 'street'], '123 Main St');
412
+ * Obj.update(person, (obj) => {
413
+ * Obj.setValue(obj, ['addresses', 0, 'street'], '123 Main St');
391
414
  * });
392
415
  * // Creates: person.addresses = [{ street: '123 Main St' }]
393
416
  * ```
@@ -400,12 +423,12 @@ export const setValue: (obj: Mutable<Unknown>, path: readonly (string | number)[
400
423
  // Type
401
424
  //
402
425
 
403
- // TODO(burdon): To discuss: prefer over ObjectId or Key.ObjectId or Type.ID?
404
- export const ID = ObjectId;
405
- export type ID = ObjectId;
426
+ export const ID = EntityId;
427
+ export type ID = EntityId;
406
428
 
407
429
  /**
408
- * Test if object or relation is an instance of a schema.
430
+ * Test if an object is an instance of a given object type.
431
+ *
409
432
  * @example
410
433
  * ```ts
411
434
  * const john = Obj.make(Person, { name: 'John' });
@@ -414,11 +437,29 @@ export type ID = ObjectId;
414
437
  * // john is Person
415
438
  * }
416
439
  * ```
440
+ *
441
+ * Only accepts `Type.AnyObj` — use `Relation.instanceOf` for relations and
442
+ * `Type.isType(value)` to test for `Type.Type` meta-schema entities.
417
443
  */
418
444
  export const instanceOf: {
419
- <S extends Type.AnyEntity>(schema: S): (value: unknown) => value is Schema.Schema.Type<S>;
420
- <S extends Type.AnyEntity>(schema: S, value: unknown): value is Schema.Schema.Type<S>;
421
- } = ((...args: [schema: Type.AnyEntity, value: unknown] | [schema: Type.AnyEntity]) => {
445
+ // Reject `Type.Type` at the type level those are meta-schema entities, not
446
+ // object instances. Use `Type.isType(value)` instead.
447
+ <T extends Type.Type>(
448
+ type: T,
449
+ _hint?: never,
450
+ // eslint-disable-next-line @typescript-eslint/unified-signatures
451
+ ..._error: ['ERROR: Obj.instanceOf does not accept Type.Type; use Type.isType(value) instead']
452
+ ): never;
453
+ // Reject relation types — use `Relation.instanceOf` instead.
454
+ <R extends Type.AnyRelation>(
455
+ type: R,
456
+ _hint?: never,
457
+ // eslint-disable-next-line @typescript-eslint/unified-signatures
458
+ ..._error: ['ERROR: Obj.instanceOf does not accept relation types; use Relation.instanceOf instead']
459
+ ): never;
460
+ <S extends Type.AnyObj>(schema: S): (value: unknown) => value is Type.InstanceType<S>;
461
+ <S extends Type.AnyObj>(schema: S, value: unknown): value is Type.InstanceType<S>;
462
+ } = ((...args: [schema: Type.AnyEntity, value?: unknown]) => {
422
463
  if (args.length === 1) {
423
464
  return (entity: unknown) => internal.isInstanceOf(args[0], entity);
424
465
  }
@@ -440,9 +481,9 @@ export const instanceOf: {
440
481
  * ```
441
482
  */
442
483
  export const snapshotOf: {
443
- <S extends Type.AnyEntity>(schema: S): (value: unknown) => value is Snapshot<Schema.Schema.Type<S>>;
444
- <S extends Type.AnyEntity>(schema: S, value: unknown): value is Snapshot<Schema.Schema.Type<S>>;
445
- } = ((...args: [schema: Type.AnyEntity, value: unknown] | [schema: Type.AnyEntity]) => {
484
+ <S extends Type.AnyObj>(schema: S): (value: unknown) => value is Snapshot<Type.InstanceType<S>>;
485
+ <S extends Type.AnyObj>(schema: S, value: unknown): value is Snapshot<Type.InstanceType<S>>;
486
+ } = ((...args: [schema: Type.AnyObj, value: unknown] | [schema: Type.AnyObj]) => {
446
487
  const check = (entity: unknown) =>
447
488
  entity != null &&
448
489
  typeof entity === 'object' &&
@@ -458,27 +499,37 @@ export const snapshotOf: {
458
499
 
459
500
  // TODO(dmaretskyi): Allow returning undefined.
460
501
  /**
461
- * Get the DXN of the object.
502
+ * Get the canonical URI of the object. Returns `URI.URI` (today always an EID,
503
+ * but future entity kinds may surface other URI schemes — narrow with
504
+ * `EID.parse(uri)` or `DXN.tryMake(uri)` at the point of use).
462
505
  * Accepts both reactive objects and snapshots.
463
506
  */
464
- export const getDXN = (entity: Unknown | Snapshot): DXN => {
507
+ export const getURI = (entity: Unknown | Snapshot): URI.URI => {
465
508
  assertArgument(!Schema.isSchema(entity), 'obj', 'Object should not be a schema.');
466
- return internal.getDXN(entity);
509
+ return internal.getUri(entity);
467
510
  };
468
511
 
469
512
  /**
470
513
  * @returns The DXN of the object's type.
471
514
  * @example dxn:com.example.type.person:1.0.0
515
+ * @throws If the object is missing its type (corrupted object).
472
516
  */
473
- // TODO(wittjosiah): Narrow types.
474
- export const getTypeDXN: (obj: unknown | undefined) => DXN | undefined = internal.getTypeDXN as any;
517
+ export const getTypeURI = (obj: Unknown | Snapshot): URI.URI => {
518
+ const type = internal.getTypeURI(obj);
519
+ invariant(type != null, 'Corrupted object: missing type.');
520
+ return type;
521
+ };
475
522
 
476
523
  /**
477
- * Get the schema of the object.
478
- * Returns the branded ECHO schema used to create the object.
524
+ * Get the type entity (`Type.AnyObj`) the object was created from.
525
+ *
526
+ * Returns `undefined` when the object's type isn't registered in this runtime
527
+ * (e.g. a freshly deserialized snapshot whose type entity hasn't been wired
528
+ * up yet, or an object loaded from storage before its schema is known). To
529
+ * get the Effect Schema from the returned entity, use `Type.getSchema(...)`.
479
530
  */
480
- // TODO(wittjosiah): Narrow types.
481
- export const getSchema: (obj: unknown | undefined) => Type.AnyEntity | undefined = internal.getSchema as any;
531
+ export const getType = (obj: Unknown | Snapshot): Type.AnyObj | undefined =>
532
+ internal.getType(obj) as Type.AnyObj | undefined;
482
533
 
483
534
  /**
484
535
  * @returns The typename of the object's type.
@@ -510,13 +561,13 @@ export const getDatabase = (entity: Entity.Unknown | Entity.Snapshot): Database.
510
561
  export const Meta = internal.MetaId;
511
562
 
512
563
  /**
513
- * Deeply read-only version of ObjectMeta.
564
+ * Deeply read-only version of EntityMeta.
514
565
  * Prevents mutation at all nesting levels (e.g., `meta.keys.push()` is a TypeScript error).
515
566
  */
516
567
  export type ReadonlyMeta = internal.ReadonlyMeta;
517
568
 
518
569
  /**
519
- * Mutable meta type returned by `Obj.getMeta` inside an `Obj.change` callback.
570
+ * Mutable meta type returned by `Obj.getMeta` inside an `Obj.update` callback.
520
571
  */
521
572
  export type Meta = internal.Meta;
522
573
 
@@ -524,7 +575,7 @@ export type Meta = internal.Meta;
524
575
  // TODO(dmaretskyi): Allow returning undefined.
525
576
  /**
526
577
  * Get the metadata for an object.
527
- * Returns mutable meta when passed a mutable object (inside `Obj.change` callback).
578
+ * Returns mutable meta when passed a mutable object (inside `Obj.update` callback).
528
579
  * Returns read-only meta when passed a regular object or snapshot.
529
580
  *
530
581
  * @example
@@ -533,10 +584,9 @@ export type Meta = internal.Meta;
533
584
  * const meta = Obj.getMeta(person); // ReadonlyMeta
534
585
  *
535
586
  * // Mutable access inside change callback
536
- * Obj.change(person, (p) => {
537
- * const meta = Obj.getMeta(p); // ObjectMeta (mutable)
538
- * meta.tags ??= [];
539
- * meta.tags.push('important');
587
+ * Obj.update(person, (obj) => {
588
+ * const meta = Obj.getMeta(obj); // EntityMeta (mutable)
589
+ * meta.tags.push(Ref.make(tag)); // tags are refs to Tag objects
540
590
  * });
541
591
  * ```
542
592
  */
@@ -558,7 +608,7 @@ export const getKeys: {
558
608
 
559
609
  /**
560
610
  * Delete all keys from the object for the specified source.
561
- * Must be called within an `Obj.change` callback.
611
+ * Must be called within an `Obj.update` callback.
562
612
  *
563
613
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
564
614
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
@@ -567,21 +617,21 @@ export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => in
567
617
 
568
618
  /**
569
619
  * Add a tag to the object.
570
- * Must be called within an `Obj.change` callback.
620
+ * Must be called within an `Obj.update` callback.
571
621
  *
572
622
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
573
623
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
574
624
  */
575
- export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.addTag(entity, tag);
625
+ export const addTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.addTag(entity, tag);
576
626
 
577
627
  /**
578
628
  * Remove a tag from the object.
579
- * Must be called within an `Obj.change` callback.
629
+ * Must be called within an `Obj.update` callback.
580
630
  *
581
631
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
582
632
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
583
633
  */
584
- export const removeTag = (entity: Mutable<Unknown>, tag: string): void => internal.removeTag(entity, tag);
634
+ export const removeTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.removeTag(entity, tag);
585
635
 
586
636
  /**
587
637
  * Check if the object is deleted.
@@ -597,12 +647,16 @@ export const isDeleted = (entity: Unknown | Snapshot): boolean => objInternal.is
597
647
  /**
598
648
  * Get the label of the object.
599
649
  * Accepts both reactive objects and snapshots.
650
+ *
651
+ * @param options.fallback `'typename'` returns the object's typename when no
652
+ * label is set (e.g. `org.dxos.type.table`).
600
653
  */
601
- export const getLabel = (entity: Unknown | Snapshot): string | undefined => internal.getLabel(entity);
654
+ export const getLabel = (entity: Unknown | Snapshot, options?: internal.GetLabelOptions): string | undefined =>
655
+ internal.getLabel(entity, options);
602
656
 
603
657
  /**
604
658
  * Set the label of the object.
605
- * Must be called within an `Obj.change` callback.
659
+ * Must be called within an `Obj.update` callback.
606
660
  *
607
661
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
608
662
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
@@ -615,9 +669,20 @@ export const setLabel = (entity: Mutable<Unknown>, label: string): void => inter
615
669
  */
616
670
  export const getDescription = (entity: Unknown | Snapshot): string | undefined => internal.getDescription(entity);
617
671
 
672
+ /**
673
+ * Get the icon annotation for the object (or any entity), resolved via its type-level
674
+ * `IconAnnotation`. Accepts both reactive entities and snapshots, and either Objects or
675
+ * Relations — the underlying schema-based lookup works for both.
676
+ *
677
+ * Returns the full `{ icon, hue }` annotation; callers wanting just the icon name typically
678
+ * write `Obj.getIcon(obj)?.icon ?? 'ph--cube--regular'`.
679
+ */
680
+ export const getIcon = (entity: Entity.Unknown | Entity.Snapshot): internal.IconAnnotation | undefined =>
681
+ internal.getIcon(entity);
682
+
618
683
  /**
619
684
  * Set the description of the object.
620
- * Must be called within an `Obj.change` callback.
685
+ * Must be called within an `Obj.update` callback.
621
686
  *
622
687
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
623
688
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
@@ -644,7 +709,7 @@ export const Parent: unique symbol = internal.ParentId as any;
644
709
  * @returns The parent object, or undefined if the object has no parent.
645
710
  */
646
711
  export const getParent = (entity: Unknown | Snapshot): Unknown | undefined => {
647
- assertArgument(isObject(entity), 'Expected an object');
712
+ assertArgument(isObject(entity) || isSnapshot(entity), 'Expected an object');
648
713
  assumeType<internal.InternalObjectProps>(entity);
649
714
  return entity[internal.ParentId] as Unknown | undefined;
650
715
  };
@@ -660,6 +725,123 @@ export const setParent = (entity: Unknown, parent: Any | undefined) => {
660
725
  assumeType<internal.InternalObjectProps>(entity);
661
726
  assumeType<internal.InternalObjectProps | undefined>(parent);
662
727
  entity[internal.ParentId] = parent;
728
+ return entity;
729
+ };
730
+
731
+ interface UpdateFromOptions<T> {
732
+ exclude?: (keyof T)[];
733
+ include?: (keyof T)[];
734
+ }
735
+
736
+ const valuesEqual = (left: unknown, right: unknown): boolean => {
737
+ if (left === right) {
738
+ return true;
739
+ }
740
+ if (left === null || right === null) {
741
+ return left === right;
742
+ }
743
+ if (typeof left !== 'object' || typeof right !== 'object') {
744
+ return Utils.structuralRegion(() => Equal.equals(left, right));
745
+ }
746
+ if (Ref.isRef(left) && Ref.isRef(right)) {
747
+ return left.uri === right.uri;
748
+ }
749
+ if (Ref.isRef(left) || Ref.isRef(right)) {
750
+ return false;
751
+ }
752
+ if (Array.isArray(left) && Array.isArray(right)) {
753
+ if (left.length !== right.length) {
754
+ return false;
755
+ }
756
+ for (let index = 0; index < left.length; index++) {
757
+ if (!valuesEqual(left[index], right[index])) {
758
+ return false;
759
+ }
760
+ }
761
+ return true;
762
+ }
763
+ if (Array.isArray(left) || Array.isArray(right)) {
764
+ return false;
765
+ }
766
+ const leftRecord = left as Record<string, unknown>;
767
+ const rightRecord = right as Record<string, unknown>;
768
+ const keys = new Set([
769
+ ...Object.keys(leftRecord).filter((key) => key !== 'id'),
770
+ ...Object.keys(rightRecord).filter((key) => key !== 'id'),
771
+ ]);
772
+ for (const key of keys) {
773
+ const leftHas = Object.hasOwn(leftRecord, key);
774
+ const rightHas = Object.hasOwn(rightRecord, key);
775
+ const leftValue = leftHas ? leftRecord[key] : undefined;
776
+ const rightValue = rightHas ? rightRecord[key] : undefined;
777
+ if (!valuesEqual(leftValue, rightValue)) {
778
+ return false;
779
+ }
780
+ }
781
+ return true;
782
+ };
783
+
784
+ /**
785
+ * Breaks reactive proxies on assigned values so echo-db assignment accepts nested structs (same idea as link assignment).
786
+ */
787
+ const prepareAssignValue = (value: unknown): unknown =>
788
+ deepMapValues(value, (nested, recurse) => {
789
+ if (nested === null || typeof nested !== 'object') {
790
+ return nested;
791
+ }
792
+ if (Ref.isRef(nested)) {
793
+ return nested;
794
+ }
795
+ if (Array.isArray(nested)) {
796
+ return recurse(nested);
797
+ }
798
+ if (isProxy(nested)) {
799
+ return recurse({ ...getProxyTarget(nested) });
800
+ }
801
+ return recurse(nested);
802
+ });
803
+
804
+ /**
805
+ * For each key present on `source` (except `id`), assigns `target[key]` when the current value differs.
806
+ * References are compared by target DXN; other values use Effect `Equal.equals` inside a structural region,
807
+ * with recursive comparison for arrays and plain object-shaped property bags (excluding `id`).
808
+ *
809
+ * Must be called within an `Obj.update` callback.
810
+ *
811
+ * @returns Whether any property was updated.
812
+ */
813
+ export const updateFrom = <T extends Unknown>(
814
+ target: Mutable<T>,
815
+ source: T,
816
+ options?: UpdateFromOptions<T>,
817
+ ): boolean => {
818
+ assertArgument(isObject(target), 'Expected an echo object target.');
819
+ assertArgument(isObject(source), 'Expected an echo object source.');
820
+ let keys = Object.keys(source as Record<string, unknown>).filter((key) => key !== 'id');
821
+ if (options?.include !== undefined) {
822
+ const include = new Set(options.include.map((key) => String(key)));
823
+ keys = keys.filter((key) => include.has(key));
824
+ }
825
+ if (options?.exclude !== undefined) {
826
+ const exclude = new Set(options.exclude.map((key) => String(key)));
827
+ keys = keys.filter((key) => !exclude.has(key));
828
+ }
829
+ let updated = false;
830
+ const sourceRecord = source as Record<string, unknown>;
831
+ const targetRecord = target as Record<string, unknown>;
832
+ for (const key of keys) {
833
+ if (!Object.hasOwn(sourceRecord, key)) {
834
+ continue;
835
+ }
836
+ const nextValue = sourceRecord[key];
837
+ const prevValue = Object.hasOwn(targetRecord, key) ? targetRecord[key] : undefined;
838
+ if (valuesEqual(prevValue, nextValue)) {
839
+ continue;
840
+ }
841
+ targetRecord[key] = prepareAssignValue(nextValue) as never;
842
+ updated = true;
843
+ }
844
+ return updated;
663
845
  };
664
846
 
665
847
  //
@@ -686,12 +868,12 @@ export const toJSON = (entity: Unknown | Snapshot): JSON => objInternal.objectTo
686
868
  * The function must be async to support resolving the schema as well as the relation endpoints.
687
869
  *
688
870
  * @param options.refResolver - Resolver for references. Produces hydrated references that can be resolved.
689
- * @param options.dxn - Override object DXN. Changes the result of `Obj.getDXN`.
871
+ * @param options.uri - Override object URI. Changes the result of `Obj.getURI`.
690
872
  * @param options.database - Database to associate with the object.
691
873
  */
692
874
  export const fromJSON: (
693
875
  json: unknown,
694
- options?: { refResolver?: Ref.Resolver; dxn?: DXN; database?: Database.Database },
876
+ options?: { refResolver?: Ref.Resolver; uri?: URI.URI; database?: Database.Database; parent?: Unknown },
695
877
  ) => Promise<Unknown> = objInternal.objectFromJSON as any;
696
878
 
697
879
  /**