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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (602) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +9 -9
  3. package/dist/lib/neutral/Annotation.mjs +7 -3
  4. package/dist/lib/neutral/Database.mjs +8 -4
  5. package/dist/lib/neutral/Entity.mjs +35 -18
  6. package/dist/lib/neutral/Err.mjs +3 -1
  7. package/dist/lib/neutral/Extension.mjs +18 -0
  8. package/dist/lib/neutral/Extension.mjs.map +7 -0
  9. package/dist/lib/neutral/Feed.mjs +54 -0
  10. package/dist/lib/neutral/Feed.mjs.map +7 -0
  11. package/dist/lib/neutral/Filter.mjs +25 -12
  12. package/dist/lib/neutral/Format.mjs +23 -3
  13. package/dist/lib/neutral/JsonSchema.mjs +9 -9
  14. package/dist/lib/neutral/Key.mjs +7 -3
  15. package/dist/lib/neutral/Migration.mjs +18 -0
  16. package/dist/lib/neutral/Migration.mjs.map +7 -0
  17. package/dist/lib/neutral/Obj.mjs +41 -23
  18. package/dist/lib/neutral/Order.mjs +1 -1
  19. package/dist/lib/neutral/Query.mjs +21 -9
  20. package/dist/lib/neutral/QueryResult.mjs +1 -1
  21. package/dist/lib/neutral/Ref.mjs +13 -9
  22. package/dist/lib/neutral/Relation.mjs +34 -23
  23. package/dist/lib/neutral/SchemaRegistry.mjs +1 -1
  24. package/dist/lib/neutral/Tag.mjs +14 -10
  25. package/dist/lib/neutral/Type.mjs +52 -36
  26. package/dist/lib/neutral/{chunk-K5K3Z62A.mjs → chunk-4SYHDOQA.mjs} +14 -6
  27. package/dist/lib/neutral/chunk-4SYHDOQA.mjs.map +7 -0
  28. package/dist/lib/neutral/{chunk-XAJMXQ4H.mjs → chunk-4U7OD55H.mjs} +6 -2
  29. package/dist/lib/neutral/chunk-4U7OD55H.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-52NG2XEE.mjs +34 -0
  31. package/dist/lib/neutral/chunk-52NG2XEE.mjs.map +7 -0
  32. package/dist/lib/neutral/{chunk-KB7RIVLK.mjs → chunk-A5HDDVKS.mjs} +33 -6
  33. package/dist/lib/neutral/chunk-A5HDDVKS.mjs.map +7 -0
  34. package/dist/lib/neutral/{chunk-DLPC7DHQ.mjs → chunk-EZ4XJFHJ.mjs} +9 -11
  35. package/dist/lib/neutral/chunk-EZ4XJFHJ.mjs.map +7 -0
  36. package/dist/lib/neutral/{chunk-ZAHWXGK4.mjs → chunk-F625JEZB.mjs} +97 -19
  37. package/dist/lib/neutral/chunk-F625JEZB.mjs.map +7 -0
  38. package/dist/lib/neutral/chunk-FFCN66OF.mjs +420 -0
  39. package/dist/lib/neutral/chunk-FFCN66OF.mjs.map +7 -0
  40. package/dist/lib/neutral/{chunk-RPB6V4BE.mjs → chunk-GOHDOJE3.mjs} +16 -3
  41. package/dist/lib/neutral/chunk-GOHDOJE3.mjs.map +7 -0
  42. package/dist/lib/neutral/chunk-GWFFC34K.mjs +50 -0
  43. package/dist/lib/neutral/chunk-GWFFC34K.mjs.map +7 -0
  44. package/dist/lib/neutral/chunk-J7QWJQQV.mjs +318 -0
  45. package/dist/lib/neutral/chunk-J7QWJQQV.mjs.map +7 -0
  46. package/dist/lib/neutral/{chunk-QARLJVDB.mjs → chunk-JTHNDGAR.mjs} +8 -4
  47. package/dist/lib/neutral/chunk-JTHNDGAR.mjs.map +7 -0
  48. package/dist/lib/neutral/chunk-K5RH2PBH.mjs +361 -0
  49. package/dist/lib/neutral/chunk-K5RH2PBH.mjs.map +7 -0
  50. package/dist/lib/neutral/{chunk-RIMHNJ3E.mjs → chunk-KHRAQDYX.mjs} +138 -91
  51. package/dist/lib/neutral/chunk-KHRAQDYX.mjs.map +7 -0
  52. package/dist/lib/neutral/chunk-L65CW5EI.mjs +156 -0
  53. package/dist/lib/neutral/chunk-L65CW5EI.mjs.map +7 -0
  54. package/dist/lib/neutral/chunk-LNZIPZX6.mjs +2186 -0
  55. package/dist/lib/neutral/chunk-LNZIPZX6.mjs.map +7 -0
  56. package/dist/lib/neutral/chunk-MPXUNTME.mjs +41 -0
  57. package/dist/lib/neutral/chunk-MPXUNTME.mjs.map +7 -0
  58. package/dist/lib/neutral/{chunk-7WE7SBA2.mjs → chunk-O2EOH7XQ.mjs} +152 -134
  59. package/dist/lib/neutral/chunk-O2EOH7XQ.mjs.map +7 -0
  60. package/dist/lib/neutral/{chunk-MTEHHY62.mjs → chunk-Q7ID37KF.mjs} +121 -94
  61. package/dist/lib/neutral/chunk-Q7ID37KF.mjs.map +7 -0
  62. package/dist/lib/neutral/chunk-QLYEQ5VA.mjs +205 -0
  63. package/dist/lib/neutral/chunk-QLYEQ5VA.mjs.map +7 -0
  64. package/dist/lib/neutral/chunk-SSDGRJ3A.mjs +747 -0
  65. package/dist/lib/neutral/chunk-SSDGRJ3A.mjs.map +7 -0
  66. package/dist/lib/neutral/{chunk-ROKO4RKJ.mjs → chunk-TTCSATUD.mjs} +2 -2
  67. package/dist/lib/neutral/chunk-TTCSATUD.mjs.map +7 -0
  68. package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-UEFRFUYC.mjs} +8 -4
  69. package/dist/lib/neutral/chunk-UEFRFUYC.mjs.map +7 -0
  70. package/dist/lib/neutral/chunk-UN7K472Q.mjs +132 -0
  71. package/dist/lib/neutral/chunk-UN7K472Q.mjs.map +7 -0
  72. package/dist/lib/neutral/chunk-UQAMAXDU.mjs +243 -0
  73. package/dist/lib/neutral/chunk-UQAMAXDU.mjs.map +7 -0
  74. package/dist/lib/neutral/{chunk-4L6DOFXP.mjs → chunk-V5NE2X7Y.mjs} +1 -1
  75. package/dist/lib/neutral/chunk-V5NE2X7Y.mjs.map +7 -0
  76. package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-V72DY6LU.mjs} +1 -1
  77. package/dist/lib/neutral/chunk-ZII2BGPM.mjs +269 -0
  78. package/dist/lib/neutral/chunk-ZII2BGPM.mjs.map +7 -0
  79. package/dist/lib/neutral/{chunk-N2QNHMT5.mjs → chunk-ZM7VFIS2.mjs} +22 -2
  80. package/dist/lib/neutral/chunk-ZM7VFIS2.mjs.map +7 -0
  81. package/dist/lib/neutral/index.mjs +56 -29
  82. package/dist/lib/neutral/internal/index.mjs +128 -77
  83. package/dist/lib/neutral/meta.json +1 -1
  84. package/dist/lib/neutral/testing/index.mjs +226 -174
  85. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  86. package/dist/types/src/Annotation.d.ts +3 -3
  87. package/dist/types/src/Annotation.d.ts.map +1 -1
  88. package/dist/types/src/Collection.d.ts +15 -0
  89. package/dist/types/src/Collection.d.ts.map +1 -0
  90. package/dist/types/src/Database.d.ts +27 -42
  91. package/dist/types/src/Database.d.ts.map +1 -1
  92. package/dist/types/src/Dataset.d.ts +29 -0
  93. package/dist/types/src/Dataset.d.ts.map +1 -0
  94. package/dist/types/src/Entity.d.ts +123 -29
  95. package/dist/types/src/Entity.d.ts.map +1 -1
  96. package/dist/types/src/Err.d.ts +56 -13
  97. package/dist/types/src/Err.d.ts.map +1 -1
  98. package/dist/types/src/Extension.d.ts +80 -0
  99. package/dist/types/src/Extension.d.ts.map +1 -0
  100. package/dist/types/src/Extension.test.d.ts +2 -0
  101. package/dist/types/src/Extension.test.d.ts.map +1 -0
  102. package/dist/types/src/Feed.d.ts +229 -0
  103. package/dist/types/src/Feed.d.ts.map +1 -0
  104. package/dist/types/src/Filter.d.ts +74 -11
  105. package/dist/types/src/Filter.d.ts.map +1 -1
  106. package/dist/types/src/Filter.test.d.ts +2 -0
  107. package/dist/types/src/Filter.test.d.ts.map +1 -0
  108. package/dist/types/src/Format.d.ts +3 -3
  109. package/dist/types/src/Format.d.ts.map +1 -1
  110. package/dist/types/src/Hypergraph.d.ts +15 -10
  111. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  112. package/dist/types/src/Json.d.ts +33 -0
  113. package/dist/types/src/Json.d.ts.map +1 -0
  114. package/dist/types/src/Json.test.d.ts +2 -0
  115. package/dist/types/src/Json.test.d.ts.map +1 -0
  116. package/dist/types/src/JsonSchema.d.ts +11 -4
  117. package/dist/types/src/JsonSchema.d.ts.map +1 -1
  118. package/dist/types/src/Key.d.ts +1 -1
  119. package/dist/types/src/Key.d.ts.map +1 -1
  120. package/dist/types/src/Migration.d.ts +72 -0
  121. package/dist/types/src/Migration.d.ts.map +1 -0
  122. package/dist/types/src/Obj.d.ts +201 -77
  123. package/dist/types/src/Obj.d.ts.map +1 -1
  124. package/dist/types/src/Order.d.ts.map +1 -1
  125. package/dist/types/src/Query.d.ts +117 -17
  126. package/dist/types/src/Query.d.ts.map +1 -1
  127. package/dist/types/src/Ref.d.ts +66 -10
  128. package/dist/types/src/Ref.d.ts.map +1 -1
  129. package/dist/types/src/Relation.d.ts +127 -54
  130. package/dist/types/src/Relation.d.ts.map +1 -1
  131. package/dist/types/src/SchemaRegistry.d.ts +12 -13
  132. package/dist/types/src/SchemaRegistry.d.ts.map +1 -1
  133. package/dist/types/src/Tag.d.ts +4 -3
  134. package/dist/types/src/Tag.d.ts.map +1 -1
  135. package/dist/types/src/Type.d.ts +337 -218
  136. package/dist/types/src/Type.d.ts.map +1 -1
  137. package/dist/types/src/View.d.ts +65 -0
  138. package/dist/types/src/View.d.ts.map +1 -0
  139. package/dist/types/src/exemplars.test.d.ts +2 -0
  140. package/dist/types/src/exemplars.test.d.ts.map +1 -0
  141. package/dist/types/src/index.d.ts +8 -1
  142. package/dist/types/src/index.d.ts.map +1 -1
  143. package/dist/types/src/internal/{annotations → Annotation}/annotations.d.ts +98 -24
  144. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -0
  145. package/dist/types/src/internal/Annotation/annotations.test.d.ts.map +1 -0
  146. package/dist/types/src/internal/Annotation/index.d.ts +4 -0
  147. package/dist/types/src/internal/Annotation/index.d.ts.map +1 -0
  148. package/dist/types/src/internal/{api → Annotation}/sorting.d.ts +1 -1
  149. package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -0
  150. package/dist/types/src/internal/{annotations → Annotation}/util.d.ts +15 -6
  151. package/dist/types/src/internal/Annotation/util.d.ts.map +1 -0
  152. package/dist/types/src/internal/Entity/api.d.ts +13 -0
  153. package/dist/types/src/internal/Entity/api.d.ts.map +1 -0
  154. package/dist/types/src/internal/Entity/entity.d.ts +67 -0
  155. package/dist/types/src/internal/Entity/entity.d.ts.map +1 -0
  156. package/dist/types/src/internal/Entity/index.d.ts +10 -0
  157. package/dist/types/src/internal/Entity/index.d.ts.map +1 -0
  158. package/dist/types/src/internal/Entity/model.d.ts +57 -0
  159. package/dist/types/src/internal/Entity/model.d.ts.map +1 -0
  160. package/dist/types/src/internal/{entities → Entity}/object.d.ts +3 -3
  161. package/dist/types/src/internal/Entity/object.d.ts.map +1 -0
  162. package/dist/types/src/internal/Entity/relation.d.ts +51 -0
  163. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -0
  164. package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
  165. package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
  166. package/dist/types/src/internal/Entity/type-uri.d.ts +25 -0
  167. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
  168. package/dist/types/src/internal/Entity/util.d.ts.map +1 -0
  169. package/dist/types/src/internal/{api → Entity}/version.d.ts +1 -1
  170. package/dist/types/src/internal/Entity/version.d.ts.map +1 -0
  171. package/dist/types/src/internal/Format/date.d.ts.map +1 -0
  172. package/dist/types/src/internal/Format/date.test.d.ts.map +1 -0
  173. package/dist/types/src/internal/{formats → Format}/format.d.ts +2 -1
  174. package/dist/types/src/internal/Format/format.d.ts.map +1 -0
  175. package/dist/types/src/internal/Format/format.test.d.ts.map +1 -0
  176. package/dist/types/src/internal/{formats → Format}/index.d.ts +2 -2
  177. package/dist/types/src/internal/Format/index.d.ts.map +1 -0
  178. package/dist/types/src/internal/Format/number.d.ts.map +1 -0
  179. package/dist/types/src/internal/Format/object.d.ts.map +1 -0
  180. package/dist/types/src/internal/Format/select.d.ts.map +1 -0
  181. package/dist/types/src/internal/Format/string.d.ts.map +1 -0
  182. package/dist/types/src/internal/{formats → Format}/types.d.ts +1 -1
  183. package/dist/types/src/internal/Format/types.d.ts.map +1 -0
  184. package/dist/types/src/internal/{json-schema → JsonSchema}/annotations.d.ts +1 -1
  185. package/dist/types/src/internal/JsonSchema/annotations.d.ts.map +1 -0
  186. package/dist/types/src/internal/JsonSchema/effect-schema.test.d.ts.map +1 -0
  187. package/dist/types/src/internal/JsonSchema/index.d.ts.map +1 -0
  188. package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -0
  189. package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema-type.d.ts +37 -37
  190. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -0
  191. package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema.d.ts +3 -2
  192. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -0
  193. package/dist/types/src/internal/JsonSchema/json-schema.test.d.ts.map +1 -0
  194. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -0
  195. package/dist/types/src/internal/Obj/common.d.ts.map +1 -0
  196. package/dist/types/src/internal/{object → Obj}/create-object.d.ts +10 -12
  197. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -0
  198. package/dist/types/src/internal/Obj/create-object.test.d.ts.map +1 -0
  199. package/dist/types/src/internal/{object → Obj}/deleted.d.ts +1 -1
  200. package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -0
  201. package/dist/types/src/internal/{object → Obj}/index.d.ts +0 -1
  202. package/dist/types/src/internal/Obj/index.d.ts.map +1 -0
  203. package/dist/types/src/internal/Obj/inspect.d.ts.map +1 -0
  204. package/dist/types/src/internal/{object → Obj}/json-serializer.d.ts +16 -8
  205. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -0
  206. package/dist/types/src/internal/Obj/json-serializer.test.d.ts.map +1 -0
  207. package/dist/types/src/internal/Obj/schema-validator.d.ts +2 -0
  208. package/dist/types/src/internal/Obj/schema-validator.d.ts.map +1 -0
  209. package/dist/types/src/internal/Obj/schema-validator.test.d.ts.map +1 -0
  210. package/dist/types/src/internal/{object → Obj}/set-value.d.ts +2 -2
  211. package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -0
  212. package/dist/types/src/internal/Obj/set-value.test.d.ts.map +1 -0
  213. package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -0
  214. package/dist/types/src/internal/{object → Obj}/typed-object.d.ts +5 -5
  215. package/dist/types/src/internal/Obj/typed-object.d.ts.map +1 -0
  216. package/dist/types/src/internal/Obj/typed-object.test.d.ts.map +1 -0
  217. package/dist/types/src/internal/Query.d.ts +10 -0
  218. package/dist/types/src/internal/Query.d.ts.map +1 -0
  219. package/dist/types/src/internal/Ref/index.d.ts.map +1 -0
  220. package/dist/types/src/internal/{ref → Ref}/ref-array.d.ts +1 -1
  221. package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -0
  222. package/dist/types/src/internal/{ref → Ref}/ref.d.ts +42 -19
  223. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -0
  224. package/dist/types/src/internal/Ref/ref.test.d.ts.map +1 -0
  225. package/dist/types/src/internal/{schema → Type}/compose.d.ts +1 -1
  226. package/dist/types/src/internal/Type/compose.d.ts.map +1 -0
  227. package/dist/types/src/internal/Type/compose.test.d.ts.map +1 -0
  228. package/dist/types/src/internal/Type/index.d.ts +3 -0
  229. package/dist/types/src/internal/Type/index.d.ts.map +1 -0
  230. package/dist/types/src/internal/{schema → Type}/manipulation.d.ts +0 -1
  231. package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -0
  232. package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
  233. package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
  234. package/dist/types/src/internal/{api → common/api}/index.d.ts +0 -4
  235. package/dist/types/src/internal/common/api/index.d.ts.map +1 -0
  236. package/dist/types/src/internal/{api → common/api}/meta.d.ts +3 -3
  237. package/dist/types/src/internal/common/api/meta.d.ts.map +1 -0
  238. package/dist/types/src/internal/common/index.d.ts +4 -0
  239. package/dist/types/src/internal/common/index.d.ts.map +1 -0
  240. package/dist/types/src/internal/{proxy → common/proxy}/change-context.d.ts +1 -1
  241. package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -0
  242. package/dist/types/src/internal/common/proxy/change.test.d.ts.map +1 -0
  243. package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -0
  244. package/dist/types/src/internal/{proxy → common/proxy}/errors.d.ts +1 -1
  245. package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -0
  246. package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -0
  247. package/dist/types/src/internal/common/proxy/handler.test.d.ts.map +1 -0
  248. package/dist/types/src/internal/common/proxy/index.d.ts.map +1 -0
  249. package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -0
  250. package/dist/types/src/internal/common/proxy/make-object.d.ts +19 -0
  251. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -0
  252. package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -0
  253. package/dist/types/src/internal/common/proxy/proxy-types.d.ts.map +1 -0
  254. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -0
  255. package/dist/types/src/internal/{proxy → common/proxy}/reactive-array.d.ts +1 -1
  256. package/dist/types/src/internal/common/proxy/reactive-array.d.ts.map +1 -0
  257. package/dist/types/src/internal/{proxy → common/proxy}/reactive.d.ts +2 -2
  258. package/dist/types/src/internal/{proxy → common/proxy}/reactive.d.ts.map +1 -1
  259. package/dist/types/src/internal/common/proxy/reactive.test.d.ts +2 -0
  260. package/dist/types/src/internal/common/proxy/reactive.test.d.ts.map +1 -0
  261. package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -0
  262. package/dist/types/src/internal/common/proxy/schema.test.d.ts.map +1 -0
  263. package/dist/types/src/internal/common/proxy/symbols.d.ts.map +1 -0
  264. package/dist/types/src/internal/{proxy → common/proxy}/typed-handler.d.ts +18 -2
  265. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -0
  266. package/dist/types/src/internal/common/proxy/typed-handler.test.d.ts.map +1 -0
  267. package/dist/types/src/internal/common/proxy/typed-object.test.d.ts.map +1 -0
  268. package/dist/types/src/internal/{types → common/types}/base.d.ts +1 -0
  269. package/dist/types/src/internal/common/types/base.d.ts.map +1 -0
  270. package/dist/types/src/internal/common/types/entity.d.ts +94 -0
  271. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -0
  272. package/dist/types/src/internal/{types → common/types}/index.d.ts +1 -0
  273. package/dist/types/src/internal/common/types/index.d.ts.map +1 -0
  274. package/dist/types/src/internal/{types → common/types}/meta.d.ts +12 -1
  275. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -0
  276. package/dist/types/src/internal/common/types/model-symbols.d.ts +58 -0
  277. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -0
  278. package/dist/types/src/internal/{types → common/types}/typename.d.ts +7 -0
  279. package/dist/types/src/internal/common/types/typename.d.ts.map +1 -0
  280. package/dist/types/src/internal/{types → common/types}/version.d.ts +2 -2
  281. package/dist/types/src/internal/common/types/version.d.ts.map +1 -0
  282. package/dist/types/src/internal/index.d.ts +9 -10
  283. package/dist/types/src/internal/index.d.ts.map +1 -1
  284. package/dist/types/src/testing/test-data.d.ts +8 -8
  285. package/dist/types/src/testing/test-data.d.ts.map +1 -1
  286. package/dist/types/src/testing/test-schema.d.ts +77 -82
  287. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  288. package/dist/types/src/testing/util.d.ts +5 -3
  289. package/dist/types/src/testing/util.d.ts.map +1 -1
  290. package/dist/types/tsconfig.tsbuildinfo +1 -1
  291. package/package.json +30 -15
  292. package/src/Annotation.ts +7 -3
  293. package/src/Collection.ts +36 -0
  294. package/src/Database.ts +80 -77
  295. package/src/Dataset.ts +34 -0
  296. package/src/Entity.test.ts +116 -6
  297. package/src/Entity.ts +181 -66
  298. package/src/Err.ts +25 -3
  299. package/src/Extension.test.ts +235 -0
  300. package/src/Extension.ts +122 -0
  301. package/src/Feed.ts +356 -0
  302. package/src/Filter.test.ts +90 -0
  303. package/src/Filter.ts +152 -21
  304. package/src/Format.ts +3 -3
  305. package/src/Hypergraph.ts +16 -11
  306. package/src/Json.test.ts +175 -0
  307. package/src/Json.ts +103 -0
  308. package/src/JsonSchema.ts +14 -4
  309. package/src/Key.ts +1 -1
  310. package/src/Migration.ts +114 -0
  311. package/src/Obj.test.ts +158 -20
  312. package/src/Obj.ts +451 -183
  313. package/src/Order.ts +3 -1
  314. package/src/Query.test.ts +446 -89
  315. package/src/Query.ts +300 -35
  316. package/src/Ref.ts +83 -12
  317. package/src/Relation.test.ts +16 -10
  318. package/src/Relation.ts +236 -165
  319. package/src/SchemaRegistry.ts +13 -17
  320. package/src/Tag.ts +9 -9
  321. package/src/Type.test.ts +169 -24
  322. package/src/Type.ts +561 -354
  323. package/src/View.ts +101 -0
  324. package/src/exemplars.test.ts +21 -0
  325. package/src/index.ts +9 -2
  326. package/src/internal/Annotation/annotations.test.ts +165 -0
  327. package/src/internal/{annotations → Annotation}/annotations.ts +181 -101
  328. package/src/internal/{annotations → Annotation}/index.ts +1 -0
  329. package/src/internal/{api → Annotation}/sorting.ts +2 -4
  330. package/src/internal/{annotations → Annotation}/util.ts +17 -9
  331. package/src/internal/{api/entity.ts → Entity/api.ts} +9 -8
  332. package/src/internal/Entity/entity.ts +246 -0
  333. package/src/internal/{entities → Entity}/index.ts +4 -0
  334. package/src/internal/{entities → Entity}/model.ts +42 -60
  335. package/src/internal/{entities → Entity}/object.ts +13 -6
  336. package/src/internal/Entity/relation.ts +179 -0
  337. package/src/internal/Entity/type-kind.ts +67 -0
  338. package/src/internal/Entity/type-uri.ts +87 -0
  339. package/src/internal/Entity/util.ts +34 -0
  340. package/src/internal/{api → Entity}/version.ts +2 -2
  341. package/src/internal/{formats → Format}/date.test.ts +1 -2
  342. package/src/internal/{formats → Format}/date.ts +0 -4
  343. package/src/internal/{formats → Format}/format.test.ts +1 -2
  344. package/src/internal/{formats → Format}/index.ts +2 -3
  345. package/src/internal/{formats → Format}/types.ts +2 -2
  346. package/src/internal/{json-schema → JsonSchema}/annotations.ts +3 -3
  347. package/src/internal/{json-schema → JsonSchema}/json-schema-type.ts +4 -4
  348. package/src/internal/{json-schema → JsonSchema}/json-schema.test.ts +64 -151
  349. package/src/internal/{json-schema → JsonSchema}/json-schema.ts +47 -28
  350. package/src/internal/{object → Obj}/clone.ts +10 -6
  351. package/src/internal/{object → Obj}/common.ts +2 -2
  352. package/src/internal/{object → Obj}/create-object.test.ts +13 -14
  353. package/src/internal/Obj/create-object.ts +135 -0
  354. package/src/internal/{object → Obj}/deleted.ts +2 -2
  355. package/src/internal/{object → Obj}/index.ts +0 -1
  356. package/src/internal/{object → Obj}/inspect.ts +3 -3
  357. package/src/internal/Obj/json-serializer.test.ts +185 -0
  358. package/src/internal/{object → Obj}/json-serializer.ts +108 -45
  359. package/src/internal/{object → Obj}/schema-validator.ts +1 -1
  360. package/src/internal/{object → Obj}/set-value.test.ts +31 -54
  361. package/src/internal/{object → Obj}/set-value.ts +3 -3
  362. package/src/internal/{object → Obj}/snapshot.ts +41 -23
  363. package/src/internal/Obj/typed-object.test.ts +32 -0
  364. package/src/internal/{object → Obj}/typed-object.ts +5 -5
  365. package/src/internal/Query.ts +156 -0
  366. package/src/internal/{ref → Ref}/ref-array.ts +1 -2
  367. package/src/internal/{ref → Ref}/ref.test.ts +16 -26
  368. package/src/internal/{ref → Ref}/ref.ts +117 -57
  369. package/src/internal/{schema → Type}/compose.test.ts +6 -5
  370. package/src/internal/{schema → Type}/compose.ts +1 -1
  371. package/src/internal/Type/index.ts +6 -0
  372. package/src/internal/{schema → Type}/manipulation.ts +0 -25
  373. package/src/internal/Type/type-schema.ts +60 -0
  374. package/src/internal/{README.md → common/README.md} +2 -2
  375. package/src/internal/{api → common/api}/index.ts +0 -4
  376. package/src/internal/{api → common/api}/meta.ts +3 -3
  377. package/src/internal/common/index.ts +7 -0
  378. package/src/internal/{proxy → common/proxy}/change-context.ts +1 -1
  379. package/src/internal/{proxy → common/proxy}/change.test.ts +97 -97
  380. package/src/internal/{proxy → common/proxy}/errors.ts +2 -2
  381. package/src/internal/{proxy → common/proxy}/handler.test.ts +2 -4
  382. package/src/internal/{proxy → common/proxy}/json-serializer.ts +20 -14
  383. package/src/internal/{proxy → common/proxy}/make-object.ts +37 -15
  384. package/src/internal/{proxy → common/proxy}/ownership.ts +0 -1
  385. package/src/internal/{proxy → common/proxy}/reactive-array.ts +1 -1
  386. package/src/internal/common/proxy/reactive.test.ts +54 -0
  387. package/src/internal/{proxy → common/proxy}/reactive.ts +12 -4
  388. package/src/internal/common/proxy/schema.test.ts +107 -0
  389. package/src/internal/{proxy → common/proxy}/typed-handler.test.ts +15 -15
  390. package/src/internal/{proxy → common/proxy}/typed-handler.ts +75 -18
  391. package/src/internal/{proxy → common/proxy}/typed-object.test.ts +17 -30
  392. package/src/internal/{types → common/types}/base.ts +1 -1
  393. package/src/internal/common/types/entity.ts +133 -0
  394. package/src/internal/{types → common/types}/index.ts +1 -0
  395. package/src/internal/{types → common/types}/meta.ts +15 -1
  396. package/src/internal/common/types/model-symbols.ts +74 -0
  397. package/src/internal/common/types/typename.ts +91 -0
  398. package/src/internal/{types → common/types}/version.ts +2 -3
  399. package/src/internal/index.ts +9 -31
  400. package/src/testing/api.test.ts +15 -12
  401. package/src/testing/test-data.ts +158 -99
  402. package/src/testing/test-schema.ts +33 -67
  403. package/src/testing/util.ts +14 -11
  404. package/dist/lib/neutral/chunk-2AF5GMG6.mjs +0 -171
  405. package/dist/lib/neutral/chunk-2AF5GMG6.mjs.map +0 -7
  406. package/dist/lib/neutral/chunk-4L6DOFXP.mjs.map +0 -7
  407. package/dist/lib/neutral/chunk-7WE7SBA2.mjs.map +0 -7
  408. package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
  409. package/dist/lib/neutral/chunk-DLPC7DHQ.mjs.map +0 -7
  410. package/dist/lib/neutral/chunk-EBUAT5ID.mjs +0 -229
  411. package/dist/lib/neutral/chunk-EBUAT5ID.mjs.map +0 -7
  412. package/dist/lib/neutral/chunk-K5K3Z62A.mjs.map +0 -7
  413. package/dist/lib/neutral/chunk-KB7RIVLK.mjs.map +0 -7
  414. package/dist/lib/neutral/chunk-LKFNEFHF.mjs +0 -130
  415. package/dist/lib/neutral/chunk-LKFNEFHF.mjs.map +0 -7
  416. package/dist/lib/neutral/chunk-MTEHHY62.mjs.map +0 -7
  417. package/dist/lib/neutral/chunk-N2QNHMT5.mjs.map +0 -7
  418. package/dist/lib/neutral/chunk-QARLJVDB.mjs.map +0 -7
  419. package/dist/lib/neutral/chunk-RIMHNJ3E.mjs.map +0 -7
  420. package/dist/lib/neutral/chunk-ROKO4RKJ.mjs.map +0 -7
  421. package/dist/lib/neutral/chunk-RPB6V4BE.mjs.map +0 -7
  422. package/dist/lib/neutral/chunk-TLGNKUUG.mjs +0 -3905
  423. package/dist/lib/neutral/chunk-TLGNKUUG.mjs.map +0 -7
  424. package/dist/lib/neutral/chunk-TQT6WTIJ.mjs +0 -142
  425. package/dist/lib/neutral/chunk-TQT6WTIJ.mjs.map +0 -7
  426. package/dist/lib/neutral/chunk-VUQGRDRI.mjs +0 -97
  427. package/dist/lib/neutral/chunk-VUQGRDRI.mjs.map +0 -7
  428. package/dist/lib/neutral/chunk-X2MPMYYN.mjs +0 -13
  429. package/dist/lib/neutral/chunk-X2MPMYYN.mjs.map +0 -7
  430. package/dist/lib/neutral/chunk-XAJMXQ4H.mjs.map +0 -7
  431. package/dist/lib/neutral/chunk-ZAHWXGK4.mjs.map +0 -7
  432. package/dist/types/src/internal/annotations/annotations.d.ts.map +0 -1
  433. package/dist/types/src/internal/annotations/annotations.test.d.ts.map +0 -1
  434. package/dist/types/src/internal/annotations/index.d.ts +0 -3
  435. package/dist/types/src/internal/annotations/index.d.ts.map +0 -1
  436. package/dist/types/src/internal/annotations/util.d.ts.map +0 -1
  437. package/dist/types/src/internal/api/annotations.d.ts +0 -23
  438. package/dist/types/src/internal/api/annotations.d.ts.map +0 -1
  439. package/dist/types/src/internal/api/entity.d.ts +0 -13
  440. package/dist/types/src/internal/api/entity.d.ts.map +0 -1
  441. package/dist/types/src/internal/api/index.d.ts.map +0 -1
  442. package/dist/types/src/internal/api/meta.d.ts.map +0 -1
  443. package/dist/types/src/internal/api/sorting.d.ts.map +0 -1
  444. package/dist/types/src/internal/api/version.d.ts.map +0 -1
  445. package/dist/types/src/internal/entities/entity.d.ts +0 -20
  446. package/dist/types/src/internal/entities/entity.d.ts.map +0 -1
  447. package/dist/types/src/internal/entities/index.d.ts +0 -6
  448. package/dist/types/src/internal/entities/index.d.ts.map +0 -1
  449. package/dist/types/src/internal/entities/model.d.ts +0 -79
  450. package/dist/types/src/internal/entities/model.d.ts.map +0 -1
  451. package/dist/types/src/internal/entities/object.d.ts.map +0 -1
  452. package/dist/types/src/internal/entities/relation.d.ts +0 -62
  453. package/dist/types/src/internal/entities/relation.d.ts.map +0 -1
  454. package/dist/types/src/internal/entities/util.d.ts.map +0 -1
  455. package/dist/types/src/internal/formats/date.d.ts.map +0 -1
  456. package/dist/types/src/internal/formats/date.test.d.ts.map +0 -1
  457. package/dist/types/src/internal/formats/format.d.ts.map +0 -1
  458. package/dist/types/src/internal/formats/format.test.d.ts.map +0 -1
  459. package/dist/types/src/internal/formats/index.d.ts.map +0 -1
  460. package/dist/types/src/internal/formats/number.d.ts.map +0 -1
  461. package/dist/types/src/internal/formats/object.d.ts.map +0 -1
  462. package/dist/types/src/internal/formats/select.d.ts.map +0 -1
  463. package/dist/types/src/internal/formats/string.d.ts.map +0 -1
  464. package/dist/types/src/internal/formats/types.d.ts.map +0 -1
  465. package/dist/types/src/internal/json-schema/annotations.d.ts.map +0 -1
  466. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +0 -1
  467. package/dist/types/src/internal/json-schema/index.d.ts.map +0 -1
  468. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +0 -1
  469. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +0 -1
  470. package/dist/types/src/internal/json-schema/json-schema.d.ts.map +0 -1
  471. package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +0 -1
  472. package/dist/types/src/internal/object/clone.d.ts.map +0 -1
  473. package/dist/types/src/internal/object/common.d.ts.map +0 -1
  474. package/dist/types/src/internal/object/create-object.d.ts.map +0 -1
  475. package/dist/types/src/internal/object/create-object.test.d.ts.map +0 -1
  476. package/dist/types/src/internal/object/deleted.d.ts.map +0 -1
  477. package/dist/types/src/internal/object/ids.d.ts +0 -6
  478. package/dist/types/src/internal/object/ids.d.ts.map +0 -1
  479. package/dist/types/src/internal/object/index.d.ts.map +0 -1
  480. package/dist/types/src/internal/object/inspect.d.ts.map +0 -1
  481. package/dist/types/src/internal/object/json-serializer.d.ts.map +0 -1
  482. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +0 -1
  483. package/dist/types/src/internal/object/schema-validator.d.ts +0 -2
  484. package/dist/types/src/internal/object/schema-validator.d.ts.map +0 -1
  485. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +0 -1
  486. package/dist/types/src/internal/object/set-value.d.ts.map +0 -1
  487. package/dist/types/src/internal/object/set-value.test.d.ts.map +0 -1
  488. package/dist/types/src/internal/object/snapshot.d.ts.map +0 -1
  489. package/dist/types/src/internal/object/typed-object.d.ts.map +0 -1
  490. package/dist/types/src/internal/object/typed-object.test.d.ts.map +0 -1
  491. package/dist/types/src/internal/proxy/change-context.d.ts.map +0 -1
  492. package/dist/types/src/internal/proxy/change.test.d.ts.map +0 -1
  493. package/dist/types/src/internal/proxy/define-hidden-property.d.ts.map +0 -1
  494. package/dist/types/src/internal/proxy/errors.d.ts.map +0 -1
  495. package/dist/types/src/internal/proxy/event-batch.d.ts.map +0 -1
  496. package/dist/types/src/internal/proxy/handler.test.d.ts.map +0 -1
  497. package/dist/types/src/internal/proxy/index.d.ts.map +0 -1
  498. package/dist/types/src/internal/proxy/json-serializer.d.ts.map +0 -1
  499. package/dist/types/src/internal/proxy/make-object.d.ts +0 -14
  500. package/dist/types/src/internal/proxy/make-object.d.ts.map +0 -1
  501. package/dist/types/src/internal/proxy/ownership.d.ts.map +0 -1
  502. package/dist/types/src/internal/proxy/proxy-types.d.ts.map +0 -1
  503. package/dist/types/src/internal/proxy/proxy-utils.d.ts.map +0 -1
  504. package/dist/types/src/internal/proxy/reactive-array.d.ts.map +0 -1
  505. package/dist/types/src/internal/proxy/schema-validator.d.ts.map +0 -1
  506. package/dist/types/src/internal/proxy/schema.test.d.ts.map +0 -1
  507. package/dist/types/src/internal/proxy/symbols.d.ts.map +0 -1
  508. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +0 -1
  509. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +0 -1
  510. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +0 -1
  511. package/dist/types/src/internal/ref/index.d.ts.map +0 -1
  512. package/dist/types/src/internal/ref/ref-array.d.ts.map +0 -1
  513. package/dist/types/src/internal/ref/ref.d.ts.map +0 -1
  514. package/dist/types/src/internal/ref/ref.test.d.ts.map +0 -1
  515. package/dist/types/src/internal/schema/compose.d.ts.map +0 -1
  516. package/dist/types/src/internal/schema/compose.test.d.ts.map +0 -1
  517. package/dist/types/src/internal/schema/echo-schema.d.ts +0 -181
  518. package/dist/types/src/internal/schema/echo-schema.d.ts.map +0 -1
  519. package/dist/types/src/internal/schema/index.d.ts +0 -4
  520. package/dist/types/src/internal/schema/index.d.ts.map +0 -1
  521. package/dist/types/src/internal/schema/manipulation.d.ts.map +0 -1
  522. package/dist/types/src/internal/schema/persistent-schema.d.ts +0 -20
  523. package/dist/types/src/internal/schema/persistent-schema.d.ts.map +0 -1
  524. package/dist/types/src/internal/types/base.d.ts.map +0 -1
  525. package/dist/types/src/internal/types/entity.d.ts +0 -37
  526. package/dist/types/src/internal/types/entity.d.ts.map +0 -1
  527. package/dist/types/src/internal/types/index.d.ts.map +0 -1
  528. package/dist/types/src/internal/types/meta.d.ts.map +0 -1
  529. package/dist/types/src/internal/types/typename.d.ts.map +0 -1
  530. package/dist/types/src/internal/types/version.d.ts.map +0 -1
  531. package/src/internal/annotations/annotations.test.ts +0 -96
  532. package/src/internal/api/annotations.ts +0 -60
  533. package/src/internal/entities/entity.ts +0 -126
  534. package/src/internal/entities/relation.ts +0 -171
  535. package/src/internal/entities/util.ts +0 -33
  536. package/src/internal/object/create-object.ts +0 -95
  537. package/src/internal/object/ids.ts +0 -12
  538. package/src/internal/object/json-serializer.test.ts +0 -98
  539. package/src/internal/object/typed-object.test.ts +0 -34
  540. package/src/internal/proxy/schema.test.ts +0 -145
  541. package/src/internal/schema/echo-schema.ts +0 -424
  542. package/src/internal/schema/index.ts +0 -7
  543. package/src/internal/schema/persistent-schema.ts +0 -28
  544. package/src/internal/types/entity.ts +0 -54
  545. package/src/internal/types/typename.ts +0 -55
  546. /package/dist/lib/neutral/{chunk-OMUPQMLR.mjs.map → chunk-V72DY6LU.mjs.map} +0 -0
  547. /package/dist/types/src/internal/{annotations → Annotation}/annotations.test.d.ts +0 -0
  548. /package/dist/types/src/internal/{entities → Entity}/util.d.ts +0 -0
  549. /package/dist/types/src/internal/{formats → Format}/date.d.ts +0 -0
  550. /package/dist/types/src/internal/{formats → Format}/date.test.d.ts +0 -0
  551. /package/dist/types/src/internal/{formats → Format}/format.test.d.ts +0 -0
  552. /package/dist/types/src/internal/{formats → Format}/number.d.ts +0 -0
  553. /package/dist/types/src/internal/{formats → Format}/object.d.ts +0 -0
  554. /package/dist/types/src/internal/{formats → Format}/select.d.ts +0 -0
  555. /package/dist/types/src/internal/{formats → Format}/string.d.ts +0 -0
  556. /package/dist/types/src/internal/{json-schema → JsonSchema}/effect-schema.test.d.ts +0 -0
  557. /package/dist/types/src/internal/{json-schema → JsonSchema}/index.d.ts +0 -0
  558. /package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema-normalize.d.ts +0 -0
  559. /package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema.test.d.ts +0 -0
  560. /package/dist/types/src/internal/{object → Obj}/clone.d.ts +0 -0
  561. /package/dist/types/src/internal/{object → Obj}/common.d.ts +0 -0
  562. /package/dist/types/src/internal/{object → Obj}/create-object.test.d.ts +0 -0
  563. /package/dist/types/src/internal/{object → Obj}/inspect.d.ts +0 -0
  564. /package/dist/types/src/internal/{object → Obj}/json-serializer.test.d.ts +0 -0
  565. /package/dist/types/src/internal/{object → Obj}/schema-validator.test.d.ts +0 -0
  566. /package/dist/types/src/internal/{object → Obj}/set-value.test.d.ts +0 -0
  567. /package/dist/types/src/internal/{object → Obj}/snapshot.d.ts +0 -0
  568. /package/dist/types/src/internal/{object → Obj}/typed-object.test.d.ts +0 -0
  569. /package/dist/types/src/internal/{ref → Ref}/index.d.ts +0 -0
  570. /package/dist/types/src/internal/{ref → Ref}/ref.test.d.ts +0 -0
  571. /package/dist/types/src/internal/{schema → Type}/compose.test.d.ts +0 -0
  572. /package/dist/types/src/internal/{proxy → common/proxy}/change.test.d.ts +0 -0
  573. /package/dist/types/src/internal/{proxy → common/proxy}/define-hidden-property.d.ts +0 -0
  574. /package/dist/types/src/internal/{proxy → common/proxy}/event-batch.d.ts +0 -0
  575. /package/dist/types/src/internal/{proxy → common/proxy}/handler.test.d.ts +0 -0
  576. /package/dist/types/src/internal/{proxy → common/proxy}/index.d.ts +0 -0
  577. /package/dist/types/src/internal/{proxy → common/proxy}/json-serializer.d.ts +0 -0
  578. /package/dist/types/src/internal/{proxy → common/proxy}/ownership.d.ts +0 -0
  579. /package/dist/types/src/internal/{proxy → common/proxy}/proxy-types.d.ts +0 -0
  580. /package/dist/types/src/internal/{proxy → common/proxy}/proxy-utils.d.ts +0 -0
  581. /package/dist/types/src/internal/{proxy → common/proxy}/schema-validator.d.ts +0 -0
  582. /package/dist/types/src/internal/{proxy → common/proxy}/schema.test.d.ts +0 -0
  583. /package/dist/types/src/internal/{proxy → common/proxy}/symbols.d.ts +0 -0
  584. /package/dist/types/src/internal/{proxy → common/proxy}/typed-handler.test.d.ts +0 -0
  585. /package/dist/types/src/internal/{proxy → common/proxy}/typed-object.test.d.ts +0 -0
  586. /package/src/internal/{formats → Format}/format.ts +0 -0
  587. /package/src/internal/{formats → Format}/number.ts +0 -0
  588. /package/src/internal/{formats → Format}/object.ts +0 -0
  589. /package/src/internal/{formats → Format}/select.ts +0 -0
  590. /package/src/internal/{formats → Format}/string.ts +0 -0
  591. /package/src/internal/{json-schema → JsonSchema}/effect-schema.test.ts +0 -0
  592. /package/src/internal/{json-schema → JsonSchema}/index.ts +0 -0
  593. /package/src/internal/{json-schema → JsonSchema}/json-schema-normalize.ts +0 -0
  594. /package/src/internal/{object → Obj}/schema-validator.test.ts +0 -0
  595. /package/src/internal/{ref → Ref}/index.ts +0 -0
  596. /package/src/internal/{proxy → common/proxy}/define-hidden-property.ts +0 -0
  597. /package/src/internal/{proxy → common/proxy}/event-batch.ts +0 -0
  598. /package/src/internal/{proxy → common/proxy}/index.ts +0 -0
  599. /package/src/internal/{proxy → common/proxy}/proxy-types.ts +0 -0
  600. /package/src/internal/{proxy → common/proxy}/proxy-utils.ts +0 -0
  601. /package/src/internal/{proxy → common/proxy}/schema-validator.ts +0 -0
  602. /package/src/internal/{proxy → common/proxy}/symbols.ts +0 -0
package/src/Obj.ts CHANGED
@@ -2,83 +2,39 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ // @import-as-namespace
6
+
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Equal from 'effect/Equal';
5
9
  import * as Function from 'effect/Function';
10
+ import * as Option from 'effect/Option';
6
11
  import * as Schema from 'effect/Schema';
12
+ import * as Utils from 'effect/Utils';
7
13
 
8
14
  import type { ForeignKey } from '@dxos/echo-protocol';
9
- import { createJsonPath, getValue as getValue$ } from '@dxos/effect';
10
- import { assertArgument } from '@dxos/invariant';
11
- import { type DXN, ObjectId } from '@dxos/keys';
12
- import { assumeType } from '@dxos/util';
15
+ import { createJsonPath } from '@dxos/effect';
16
+ import { assertArgument, invariant } from '@dxos/invariant';
17
+ import { DXN, ObjectId, type URI } from '@dxos/keys';
18
+ import { assumeType, deepMapValues } from '@dxos/util';
13
19
 
14
20
  import type * as Database from './Database';
15
21
  import * as Entity from './Entity';
16
- import {
17
- type ObjectJSON as APIJSON,
18
- type AnyEntity,
19
- type AnyProperties,
20
- type Comparator as ApiComparator,
21
- type Meta as ApiMeta,
22
- type ReadonlyMeta as ApiReadonlyMeta,
23
- type EntityVersion as ApiVersion,
24
- type ChangeCallback,
25
- type InternalObjectProps,
26
- type KindId,
27
- MetaId,
28
- type Mutable,
29
- type ObjectMeta,
30
- // TODO(dmaretskyi): Export ParentId?
31
- ParentId,
32
- type SnapshotKindId,
33
- type VersionCompareResult,
34
- VersionTypeId,
35
- addTag as addTag$,
36
- change as change$,
37
- clone as clone$,
38
- compareVersions,
39
- decodeVersion,
40
- deleteKeys as deleteKeys$,
41
- encodeVersion,
42
- getDXN as getDXN$,
43
- getDatabase as getDatabase$,
44
- getDescription as getDescription$,
45
- getKeys as getKeys$,
46
- getLabel as getLabel$,
47
- getMetaChecked as getMeta$,
48
- getSchema as getSchema$,
49
- getSnapshot as getSnapshot$,
50
- getTypeAnnotation,
51
- getTypeDXN as getTypeDXN$,
52
- getTypename as getTypename$,
53
- isDeleted as isDeleted$,
54
- isInstanceOf,
55
- isVersion,
56
- makeObject,
57
- objectFromJSON,
58
- removeTag as removeTag$,
59
- setDescription as setDescription$,
60
- setLabel as setLabel$,
61
- setValue as setValue$,
62
- sort as sort$,
63
- sortByLabel as sortByLabel$,
64
- sortByTypename as sortByTypename$,
65
- subscribe as subscribe$,
66
- objectToJSON as toJSON$,
67
- version as version$,
68
- versionValid,
69
- } from './internal';
70
- import type * as Ref from './Ref';
71
- import type * as Type from './Type';
22
+ import * as Err from './Err';
23
+ import * as internal from './internal';
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 * as Type from './Type';
72
28
 
73
29
  /**
74
30
  * Base type for all ECHO objects.
75
31
  */
76
- interface BaseObj extends AnyEntity, Entity.OfKind<typeof Entity.Kind.Object> {}
32
+ interface BaseObj extends internal.AnyEntity, Entity.OfKind<typeof Entity.Kind.Object> {}
77
33
 
78
34
  /**
79
35
  * Object type with specific properties.
80
36
  */
81
- export type Obj<Props> = BaseObj & Props;
37
+ export type OfShape<Props> = BaseObj & Props;
82
38
 
83
39
  /**
84
40
  * Object with no known properties beyond id and kind.
@@ -90,6 +46,43 @@ export type Obj<Props> = BaseObj & Props;
90
46
  */
91
47
  export interface Unknown extends BaseObj {}
92
48
 
49
+ /**
50
+ * Runtime Effect schema for any ECHO object.
51
+ * Use for validation, parsing, or as a reference target for collections.
52
+ *
53
+ * NOTE: `Schema.is(Type.Obj)` does STRUCTURAL validation only (checks for `id` field).
54
+ * Use `Obj.isObject()` for proper ECHO instance type guards that check the KindId brand.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * // Structural type guard (accepts any object with id field)
59
+ * if (Schema.is(Type.Obj)(unknownValue)) { ... }
60
+ *
61
+ * // ECHO instance type guard (checks KindId brand)
62
+ * if (Obj.isObject(unknownValue)) { ... }
63
+ *
64
+ * // Reference to any object type
65
+ * const Collection = Schema.Struct({
66
+ * objects: Schema.Array(Ref.Ref(Obj.Unknown)),
67
+ * }).pipe(Type.makeObject(DXN.make('com.example.type.collection', '0.1.0')));
68
+ * ```
69
+ */
70
+ // TODO(wittjosiah): Investigate if Schema.filter can validate KindId on ECHO instances.
71
+ // Effect Schema normalizes proxy objects to plain objects before calling filter predicates.
72
+ // Possible approaches: custom Schema.declare, AST manipulation, or upstream contribution.
73
+ export const Unknown: internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object> = Schema.Struct({
74
+ id: Schema.String,
75
+ }).pipe(
76
+ Schema.extend(Schema.Record({ key: Schema.String, value: Schema.Unknown })),
77
+ Schema.annotations({
78
+ [internal.TypeAnnotationId]: {
79
+ kind: Entity.Kind.Object,
80
+ typename: internal.ANY_OBJECT_TYPENAME,
81
+ version: internal.ANY_OBJECT_VERSION,
82
+ },
83
+ }),
84
+ ) as unknown as internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object>;
85
+
93
86
  /**
94
87
  * Object with arbitrary properties.
95
88
  *
@@ -98,13 +91,13 @@ export interface Unknown extends BaseObj {}
98
91
  *
99
92
  * Prefer using `Obj.Unknown` when you don't need to access arbitrary properties.
100
93
  */
101
- export interface Any extends BaseObj, AnyProperties {}
94
+ export interface Any extends BaseObj, internal.AnyProperties {}
102
95
 
103
96
  /**
104
97
  * Base type for snapshot objects (has SnapshotKindId instead of KindId).
105
98
  */
106
- interface BaseSnapshot extends AnyEntity {
107
- readonly [SnapshotKindId]: typeof Entity.Kind.Object;
99
+ interface BaseSnapshot extends internal.AnyEntity {
100
+ readonly [Entity.SnapshotKindId]: typeof Entity.Kind.Object;
108
101
  readonly id: ObjectId;
109
102
  }
110
103
 
@@ -117,32 +110,49 @@ interface BaseSnapshot extends AnyEntity {
117
110
  * Snapshots are structurally identical to reactive objects but have a different brand,
118
111
  * making them distinguishable at the TypeScript level. Neither is assignable to the other.
119
112
  */
120
- export type Snapshot<T extends Unknown = Unknown> = Omit<T, KindId> & BaseSnapshot;
113
+ export type Snapshot<T extends Unknown = Unknown> = Omit<T, Entity.KindId> & BaseSnapshot;
114
+
115
+ /**
116
+ * JSON-encoded properties for objects.
117
+ */
118
+ export interface BaseObjJson {
119
+ id: string;
120
+ }
121
121
 
122
- const defaultMeta: ObjectMeta = {
122
+ const defaultMeta: internal.ObjectMeta = {
123
123
  keys: [],
124
124
  };
125
125
 
126
- type Props<T = any> = {
127
- id?: ObjectId;
128
- [Meta]?: Partial<ObjectMeta>;
129
- } & Type.Properties<T>;
130
-
131
126
  // TODO(burdon): Should we allow the caller to set the id?
132
127
  /**
133
- * Props type for object creation with a given schema.
128
+ * Props type for object creation with a given type. Accepts a `Type.AnyObj`
129
+ * entity and derives the instance shape via `Type.InstanceType`. Relation-kind
130
+ * entities are rejected at the type level — use `Relation.MakeProps` for those.
131
+ *
132
+ * When the schema is the unconstrained `Type.AnyObj` (`Obj<unknown>` — e.g. a
133
+ * dynamic type from `schemaRegistry.register`), the instance shape is not
134
+ * statically known, so data props widen to `Record<string, unknown>` and the
135
+ * caller can pass arbitrary fields without a cast.
134
136
  */
135
- export type MakeProps<S extends Schema.Schema.AnyNoContext> = {
137
+ export type MakeProps<S extends Type.AnyObj> = {
136
138
  id?: ObjectId;
137
- [Meta]?: Partial<ObjectMeta>;
139
+ [Meta]?: Partial<internal.ObjectMeta>;
138
140
  [Parent]?: Unknown;
139
- } & NoInfer<Props<Schema.Schema.Type<S>>>;
141
+ // When the resolved instance has no known data keys, widen to a permissive
142
+ // record (the `Obj<unknown>` case); otherwise use the precise property shape.
143
+ // `[keyof …] extends [never]` is wrapped in tuples so the check is
144
+ // non-distributive — a `never` instance type (e.g. when narrowing collapses
145
+ // the schema) stays a single branch instead of distributing to `never`.
146
+ } & ([keyof Entity.Properties<Type.InstanceType<S>>] extends [never]
147
+ ? Record<string, unknown>
148
+ : Entity.Properties<Type.InstanceType<S>>);
140
149
 
141
150
  /**
142
- * Creates a new echo object of the given schema.
143
- * @param schema - Object schema.
151
+ * Creates a new echo object of the given schema or `Type.Type`.
152
+ *
153
+ * @param typeOrSchema - A static object schema (`Type.makeObject(...)`) or a
154
+ * `Type.Type` entity (e.g. one returned by `db.schemaRegistry.register`).
144
155
  * @param props - Object properties.
145
- * @param meta - Object metadata (deprecated) -- pass with Obj.Meta.
146
156
  *
147
157
  * Meta can be passed as a symbol in `props`.
148
158
  *
@@ -151,25 +161,27 @@ export type MakeProps<S extends Schema.Schema.AnyNoContext> = {
151
161
  * const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });
152
162
  * ```
153
163
  *
154
- * Note: Only accepts object schemas, not relation schemas. Use `Relation.make` for relations.
164
+ * Note: Only accepts object schemas / object-kind types, not relation schemas.
165
+ * Use `Relation.make` for relations.
155
166
  */
156
- export const make: {
157
- <S extends Type.Obj.Any>(schema: S, props: MakeProps<S>): Obj<Schema.Schema.Type<S>>;
158
- /**
159
- * @deprecated Pass meta as in the example: `Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' })`.
160
- */
161
- <S extends Type.Obj.Any>(schema: S, props: MakeProps<S>, meta: Partial<ObjectMeta>): Obj<Schema.Schema.Type<S>>;
162
- } = <S extends Type.Obj.Any>(
163
- schema: S,
164
- props: MakeProps<S>,
165
- meta?: Partial<ObjectMeta>,
166
- ): Obj<Schema.Schema.Type<S>> => {
167
- assertArgument(getTypeAnnotation(schema)?.kind === Entity.Kind.Object, 'schema', 'Expected an object schema');
167
+ export function make<T extends Type.AnyObj>(type: T, props: NoInfer<MakeProps<T>>): OfShape<Type.InstanceType<T>>;
168
+ export function make(input: Type.AnyObj, props: any): OfShape<any> {
169
+ // `Type.Type` entities aren't `Schema.Schema` themselves; derive the Effect
170
+ // Schema via `Type.getSchema(...)`. Pass the entity through to `makeObject`
171
+ // so subsequent schema mutations (`Type.addFields`, etc.) propagate.
172
+ const schema = Type.getSchema(input);
173
+ assertArgument(
174
+ internal.getTypeAnnotation(schema)?.kind === Entity.Kind.Object,
175
+ 'schema',
176
+ 'Expected an object schema',
177
+ );
178
+
179
+ let meta: internal.ObjectMeta | undefined = undefined;
168
180
 
169
181
  // Set default fields on meta on creation.
170
- if (props[MetaId] != null) {
171
- meta = { ...structuredClone(defaultMeta), ...props[MetaId] };
172
- delete props[MetaId];
182
+ if (props[internal.MetaId] != null) {
183
+ meta = { ...structuredClone(defaultMeta), ...props[internal.MetaId] };
184
+ delete props[internal.MetaId];
173
185
  }
174
186
 
175
187
  // Filter undefined values (Object.entries only returns string-keyed properties).
@@ -183,20 +195,30 @@ export const make: {
183
195
  }
184
196
  }
185
197
 
186
- return makeObject<Schema.Schema.Type<S>>(schema, filterUndefined as any, {
187
- ...defaultMeta,
188
- ...meta,
189
- });
190
- };
198
+ return internal.makeObject(
199
+ schema,
200
+ filterUndefined,
201
+ {
202
+ ...defaultMeta,
203
+ ...meta,
204
+ },
205
+ input,
206
+ );
207
+ }
191
208
 
192
209
  /**
193
210
  * Determine if object is an ECHO object.
194
211
  */
195
212
  export const isObject = (obj: unknown): obj is Unknown => {
196
- assumeType<InternalObjectProps>(obj);
213
+ assumeType<internal.InternalObjectProps>(obj);
197
214
  return typeof obj === 'object' && obj !== null && obj[Entity.KindId] === Entity.Kind.Object;
198
215
  };
199
216
 
217
+ export const isSnapshot = (obj: unknown): obj is Snapshot => {
218
+ assumeType<internal.InternalObjectProps>(obj);
219
+ return typeof obj === 'object' && obj !== null && (obj as any)[Entity.SnapshotKindId] === Entity.Kind.Object;
220
+ };
221
+
200
222
  /**
201
223
  * Subscribe to object updates.
202
224
  * The callback is called synchronously when the object is modified.
@@ -204,7 +226,7 @@ export const isObject = (obj: unknown): obj is Unknown => {
204
226
  * @returns Unsubscribe function.
205
227
  */
206
228
  export const subscribe = (obj: Unknown, callback: () => void): (() => void) => {
207
- return subscribe$(obj, callback);
229
+ return internal.subscribe(obj, callback);
208
230
  };
209
231
 
210
232
  //
@@ -216,7 +238,61 @@ export const subscribe = (obj: Unknown, callback: () => void): (() => void) => {
216
238
  * The snapshot is branded with SnapshotKindId instead of KindId,
217
239
  * making it distinguishable from the reactive object at the type level.
218
240
  */
219
- export const getSnapshot: <T extends Unknown>(obj: T) => Snapshot<T> = getSnapshot$ as any;
241
+ export const getSnapshot: <T extends Unknown>(obj: T) => Snapshot<T> = objInternal.getSnapshot as any;
242
+
243
+ /**
244
+ * Returns the reactive version of an object from the database, given its snapshot.
245
+ * Inverse of `Obj.getSnapshot`.
246
+ *
247
+ * Uses `Obj.getDatabase` internally to get the database from the snapshot,
248
+ * then resolves the reactive object by ID.
249
+ *
250
+ * @param snapshot - A snapshot of the object (from `Obj.getSnapshot`).
251
+ * @returns Effect that succeeds with the reactive object, or fails with `GetReactiveError`.
252
+ * @example
253
+ * ```ts
254
+ * const snapshot = Obj.getSnapshot(obj);
255
+ * const reactive = Obj.getReactive(snapshot).pipe(
256
+ * Effect.runSync
257
+ * );
258
+ * ```
259
+ */
260
+ export const getReactive = <T extends Unknown>(snapshot: Snapshot<T>): Effect.Effect<T, Err.GetReactiveError> =>
261
+ Effect.gen(function* () {
262
+ const db = internal.getDatabase(snapshot);
263
+ if (!db) {
264
+ return yield* Effect.fail(new Err.GetReactiveError({ reason: 'no-database', snapshotId: snapshot.id }));
265
+ }
266
+ const obj = db.getObjectById(snapshot.id);
267
+ if (!obj) {
268
+ return yield* Effect.fail(new Err.GetReactiveError({ reason: 'object-not-found', snapshotId: snapshot.id }));
269
+ }
270
+ return obj as T;
271
+ });
272
+
273
+ /**
274
+ * Like `Obj.getReactive` but returns `Option.none()` instead of failing when the object
275
+ * cannot be resolved (no database, object not found).
276
+ *
277
+ * @param snapshot - A snapshot of the object (from `Obj.getSnapshot`).
278
+ * @returns Effect that succeeds with `Option.some(reactive)` or `Option.none()`.
279
+ */
280
+ export const getReactiveOption = <T extends Unknown>(snapshot: Snapshot<T>): Effect.Effect<Option.Option<T>, never> =>
281
+ getReactive(snapshot).pipe(
282
+ Effect.map(Option.some),
283
+ Effect.catchAll(() => Effect.succeed(Option.none())),
284
+ );
285
+
286
+ /**
287
+ * Synchronous version of `Obj.getReactive`. Returns the reactive object or throws
288
+ * `GetReactiveError` when the object cannot be resolved (no database, object not found).
289
+ *
290
+ * @param snapshot - A snapshot of the object (from `Obj.getSnapshot`).
291
+ * @returns The reactive object.
292
+ * @throws {Err.GetReactiveError} When the object cannot be resolved.
293
+ */
294
+ export const getReactiveOrThrow = <T extends Unknown>(snapshot: Snapshot<T>): T =>
295
+ Effect.runSync(getReactive(snapshot));
220
296
 
221
297
  export type CloneOptions = {
222
298
  /**
@@ -237,7 +313,7 @@ export type CloneOptions = {
237
313
  * This does not clone referenced objects, only the properties in the object.
238
314
  * @returns A new object with the same schema and properties.
239
315
  */
240
- export const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = clone$;
316
+ export const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = objInternal.clone;
241
317
 
242
318
  //
243
319
  // Change
@@ -245,42 +321,42 @@ export const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = clon
245
321
 
246
322
  /**
247
323
  * Makes all properties mutable recursively.
248
- * Used to provide a mutable view of an object within `Obj.change`.
324
+ * Used to provide a mutable view of an object within `Obj.update`.
249
325
  */
250
- export type { Mutable };
326
+ export type Mutable<T> = internal.Mutable<T>;
251
327
 
252
328
  /**
253
329
  * Perform mutations on an echo object within a controlled context.
254
330
  *
255
331
  * All mutations within the callback are batched and trigger a single notification
256
- * when the callback completes. Direct mutations outside of `Obj.change` will throw
332
+ * when the callback completes. Direct mutations outside of `Obj.update` will throw
257
333
  * an error for echo objects.
258
334
  *
259
335
  * This function also works with nested objects within echo objects (e.g., Template structs)
260
336
  * that are reactive at runtime.
261
337
  *
262
- * @param obj - The echo object to mutate. Use `Relation.change` for relations.
338
+ * @param obj - The echo object to mutate. Use `Relation.update` for relations.
263
339
  * @param callback - The callback that performs mutations on the object.
264
340
  *
265
341
  * @example
266
342
  * ```ts
267
343
  * const person = Obj.make(Person, { name: 'John', age: 25 });
268
344
  *
269
- * // Mutate within Obj.change
270
- * Obj.change(person, (p) => {
271
- * p.name = 'Jane';
272
- * p.age = 30;
345
+ * // Mutate within Obj.update
346
+ * Obj.update(person, (obj) => {
347
+ * obj.name = 'Jane';
348
+ * obj.age = 30;
273
349
  * });
274
350
  * // ONE notification fires here
275
351
  *
276
352
  * // Direct mutation throws
277
- * person.name = 'Bob'; // Error: Cannot modify outside Obj.change()
353
+ * person.name = 'Bob'; // Error: Cannot modify outside Obj.update()
278
354
  * ```
279
355
  *
280
- * Note: Only accepts objects. Use `Relation.change` for relations.
356
+ * Note: Only accepts objects. Use `Relation.update` for relations.
281
357
  */
282
- export const change = <T extends Unknown>(obj: T, callback: ChangeCallback<T>): void => {
283
- change$(obj, callback);
358
+ export const update = <T extends Unknown>(obj: T, callback: internal.ChangeCallback<T>): void => {
359
+ internal.change(obj, callback);
284
360
  };
285
361
 
286
362
  /**
@@ -306,7 +382,7 @@ export const change = <T extends Unknown>(obj: T, callback: ChangeCallback<T>):
306
382
  * ```
307
383
  */
308
384
  export const getValue = (obj: Unknown | Snapshot, path: readonly (string | number)[]): any => {
309
- return getValue$(obj, createJsonPath(path));
385
+ return internal.getValue(obj, createJsonPath(path));
310
386
  };
311
387
 
312
388
  /**
@@ -314,7 +390,7 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
314
390
  * whether to initialize nested data as an empty object or array.
315
391
  *
316
392
  * Similar to lodash.set and setDeep from @dxos/util, but schema-aware.
317
- * Must be called within an `Obj.change` callback.
393
+ * Must be called within an `Obj.update` callback.
318
394
  *
319
395
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
320
396
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
@@ -328,15 +404,15 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
328
404
  * ```ts
329
405
  * const person = Obj.make(Person, { name: 'John' });
330
406
  * // Person schema has: addresses: Schema.Array(Address)
331
- * Obj.change(person, (p) => {
332
- * Obj.setValue(p, ['addresses', 0, 'street'], '123 Main St');
407
+ * Obj.update(person, (obj) => {
408
+ * Obj.setValue(obj, ['addresses', 0, 'street'], '123 Main St');
333
409
  * });
334
410
  * // Creates: person.addresses = [{ street: '123 Main St' }]
335
411
  * ```
336
412
  */
337
413
  // TODO(wittjosiah): Compute possible path values + type value based on generic object type.
338
414
  export const setValue: (obj: Mutable<Unknown>, path: readonly (string | number)[], value: any) => void =
339
- setValue$ as any;
415
+ objInternal.setValue as any;
340
416
 
341
417
  //
342
418
  // Type
@@ -347,7 +423,8 @@ export const ID = ObjectId;
347
423
  export type ID = ObjectId;
348
424
 
349
425
  /**
350
- * Test if object or relation is an instance of a schema.
426
+ * Test if an object is an instance of a given object type.
427
+ *
351
428
  * @example
352
429
  * ```ts
353
430
  * const john = Obj.make(Person, { name: 'John' });
@@ -356,48 +433,106 @@ export type ID = ObjectId;
356
433
  * // john is Person
357
434
  * }
358
435
  * ```
436
+ *
437
+ * Only accepts `Type.AnyObj` — use `Relation.instanceOf` for relations and
438
+ * `Type.isType(value)` to test for `Type.Type` meta-schema entities.
359
439
  */
360
440
  export const instanceOf: {
361
- <S extends Type.Entity.Any>(schema: S): (value: unknown) => value is Schema.Schema.Type<S>;
362
- <S extends Type.Entity.Any>(schema: S, value: unknown): value is Schema.Schema.Type<S>;
363
- } = ((...args: [schema: Type.Entity.Any, value: unknown] | [schema: Type.Entity.Any]) => {
441
+ // Reject `Type.Type` at the type level those are meta-schema entities, not
442
+ // object instances. Use `Type.isType(value)` instead.
443
+ <T extends Type.Type>(
444
+ type: T,
445
+ _hint?: never,
446
+ // eslint-disable-next-line @typescript-eslint/unified-signatures
447
+ ..._error: ['ERROR: Obj.instanceOf does not accept Type.Type; use Type.isType(value) instead']
448
+ ): never;
449
+ // Reject relation types — use `Relation.instanceOf` instead.
450
+ <R extends Type.AnyRelation>(
451
+ type: R,
452
+ _hint?: never,
453
+ // eslint-disable-next-line @typescript-eslint/unified-signatures
454
+ ..._error: ['ERROR: Obj.instanceOf does not accept relation types; use Relation.instanceOf instead']
455
+ ): never;
456
+ <S extends Type.AnyObj>(schema: S): (value: unknown) => value is Type.InstanceType<S>;
457
+ <S extends Type.AnyObj>(schema: S, value: unknown): value is Type.InstanceType<S>;
458
+ } = ((...args: [schema: Type.AnyEntity, value?: unknown]) => {
459
+ if (args.length === 1) {
460
+ return (entity: unknown) => internal.isInstanceOf(args[0], entity);
461
+ }
462
+
463
+ return internal.isInstanceOf(args[0], args[1]);
464
+ }) as any;
465
+
466
+ /**
467
+ * Test if a snapshot is an instance of a schema.
468
+ * Mirrors `instanceOf` but only accepts values branded with SnapshotKindId.
469
+ * Use when the value is known to be a snapshot (e.g. from `getSnapshot` or `useObject`).
470
+ *
471
+ * @example
472
+ * ```ts
473
+ * const snapshot = Obj.getSnapshot(person);
474
+ * if (Obj.snapshotOf(Person, snapshot)) {
475
+ * // snapshot is Obj.Snapshot<Person>
476
+ * }
477
+ * ```
478
+ */
479
+ export const snapshotOf: {
480
+ <S extends Type.AnyObj>(schema: S): (value: unknown) => value is Snapshot<Type.InstanceType<S>>;
481
+ <S extends Type.AnyObj>(schema: S, value: unknown): value is Snapshot<Type.InstanceType<S>>;
482
+ } = ((...args: [schema: Type.AnyObj, value: unknown] | [schema: Type.AnyObj]) => {
483
+ const check = (entity: unknown) =>
484
+ entity != null &&
485
+ typeof entity === 'object' &&
486
+ Entity.SnapshotKindId in entity &&
487
+ internal.isInstanceOf(args[0], entity);
488
+
364
489
  if (args.length === 1) {
365
- return (entity: unknown) => isInstanceOf(args[0], entity);
490
+ return (entity: unknown) => check(entity);
366
491
  }
367
492
 
368
- return isInstanceOf(args[0], args[1]);
493
+ return check(args[1]);
369
494
  }) as any;
370
495
 
371
496
  // TODO(dmaretskyi): Allow returning undefined.
372
497
  /**
373
- * Get the DXN of the object.
498
+ * Get the canonical URI of the object. Returns `URI.URI` (today always an EchoURI,
499
+ * but future entity kinds may surface other URI schemes — narrow with
500
+ * `EchoURI.parse(uri)` or `DXN.tryMake(uri)` at the point of use).
374
501
  * Accepts both reactive objects and snapshots.
375
502
  */
376
- export const getDXN = (entity: Unknown | Snapshot): DXN => {
503
+ export const getURI = (entity: Unknown | Snapshot): URI.URI => {
377
504
  assertArgument(!Schema.isSchema(entity), 'obj', 'Object should not be a schema.');
378
- return getDXN$(entity);
505
+ return internal.getUri(entity);
379
506
  };
380
507
 
381
508
  /**
382
509
  * @returns The DXN of the object's type.
383
- * @example dxn:example.com/type/Person:1.0.0
510
+ * @example dxn:com.example.type.person:1.0.0
511
+ * @throws If the object is missing its type (corrupted object).
384
512
  */
385
- // TODO(wittjosiah): Narrow types.
386
- export const getTypeDXN: (obj: unknown | undefined) => DXN | undefined = getTypeDXN$ as any;
513
+ export const getTypeURI = (obj: Unknown | Snapshot): URI.URI => {
514
+ const type = internal.getTypeURI(obj);
515
+ invariant(type != null, 'Corrupted object: missing type.');
516
+ return type;
517
+ };
387
518
 
388
519
  /**
389
- * Get the schema of the object.
390
- * Returns the branded ECHO schema used to create the object.
520
+ * Get the type entity (`Type.AnyObj`) the object was created from.
521
+ *
522
+ * Returns `undefined` when the object's type isn't registered in this runtime
523
+ * (e.g. a freshly deserialized snapshot whose type entity hasn't been wired
524
+ * up yet, or an object loaded from storage before its schema is known). To
525
+ * get the Effect Schema from the returned entity, use `Type.getSchema(...)`.
391
526
  */
392
- // TODO(wittjosiah): Narrow types.
393
- export const getSchema: (obj: unknown | undefined) => Type.Entity.Any | undefined = getSchema$ as any;
527
+ export const getType = (obj: Unknown | Snapshot): Type.AnyObj | undefined =>
528
+ internal.getType(obj) as Type.AnyObj | undefined;
394
529
 
395
530
  /**
396
531
  * @returns The typename of the object's type.
397
532
  * Accepts both reactive objects and snapshots.
398
- * @example `example.com/type/Person`
533
+ * @example `com.example.type.person`
399
534
  */
400
- export const getTypename = (entity: Unknown | Snapshot): string | undefined => getTypename$(entity);
535
+ export const getTypename = (entity: Unknown | Snapshot): string | undefined => internal.getTypename(entity);
401
536
 
402
537
  //
403
538
  // Database
@@ -408,30 +543,35 @@ export const getTypename = (entity: Unknown | Snapshot): string | undefined => g
408
543
  * Accepts both reactive objects and snapshots.
409
544
  */
410
545
  export const getDatabase = (entity: Entity.Unknown | Entity.Snapshot): Database.Database | undefined =>
411
- getDatabase$(entity);
546
+ internal.getDatabase(entity);
412
547
 
413
548
  //
414
549
  // Meta
415
550
  //
416
551
 
417
- export const Meta: unique symbol = MetaId as any;
552
+ /**
553
+ * Property that accesses metadata for an entity.
554
+ *
555
+ * Alias for `Entity.Meta`.
556
+ */
557
+ export const Meta = internal.MetaId;
418
558
 
419
559
  /**
420
560
  * Deeply read-only version of ObjectMeta.
421
561
  * Prevents mutation at all nesting levels (e.g., `meta.keys.push()` is a TypeScript error).
422
562
  */
423
- export type ReadonlyMeta = ApiReadonlyMeta;
563
+ export type ReadonlyMeta = internal.ReadonlyMeta;
424
564
 
425
565
  /**
426
- * Mutable meta type returned by `Obj.getMeta` inside an `Obj.change` callback.
566
+ * Mutable meta type returned by `Obj.getMeta` inside an `Obj.update` callback.
427
567
  */
428
- export type Meta = ApiMeta;
568
+ export type Meta = internal.Meta;
429
569
 
430
570
  // TODO(burdon): Narrow type.
431
571
  // TODO(dmaretskyi): Allow returning undefined.
432
572
  /**
433
573
  * Get the metadata for an object.
434
- * Returns mutable meta when passed a mutable object (inside `Obj.change` callback).
574
+ * Returns mutable meta when passed a mutable object (inside `Obj.update` callback).
435
575
  * Returns read-only meta when passed a regular object or snapshot.
436
576
  *
437
577
  * @example
@@ -440,8 +580,8 @@ export type Meta = ApiMeta;
440
580
  * const meta = Obj.getMeta(person); // ReadonlyMeta
441
581
  *
442
582
  * // Mutable access inside change callback
443
- * Obj.change(person, (p) => {
444
- * const meta = Obj.getMeta(p); // ObjectMeta (mutable)
583
+ * Obj.update(person, (obj) => {
584
+ * const meta = Obj.getMeta(obj); // ObjectMeta (mutable)
445
585
  * meta.tags ??= [];
446
586
  * meta.tags.push('important');
447
587
  * });
@@ -451,7 +591,7 @@ export type Meta = ApiMeta;
451
591
  export function getMeta(entity: Mutable<Unknown>): Meta;
452
592
  export function getMeta(entity: Unknown | Snapshot): ReadonlyMeta;
453
593
  export function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): Meta | ReadonlyMeta {
454
- return getMeta$(entity);
594
+ return internal.getMetaChecked(entity);
455
595
  }
456
596
 
457
597
  /**
@@ -461,41 +601,41 @@ export function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): Meta | R
461
601
  export const getKeys: {
462
602
  (entity: Unknown | Snapshot, source: string): ForeignKey[];
463
603
  (source: string): (entity: Unknown | Snapshot) => ForeignKey[];
464
- } = Function.dual(2, (entity: Unknown | Snapshot, source?: string): ForeignKey[] => getKeys$(entity, source!));
604
+ } = Function.dual(2, (entity: Unknown | Snapshot, source?: string): ForeignKey[] => internal.getKeys(entity, source!));
465
605
 
466
606
  /**
467
607
  * Delete all keys from the object for the specified source.
468
- * Must be called within an `Obj.change` callback.
608
+ * Must be called within an `Obj.update` callback.
469
609
  *
470
610
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
471
611
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
472
612
  */
473
- export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => deleteKeys$(entity, source);
613
+ export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => internal.deleteKeys(entity, source);
474
614
 
475
615
  /**
476
616
  * Add a tag to the object.
477
- * Must be called within an `Obj.change` callback.
617
+ * Must be called within an `Obj.update` callback.
478
618
  *
479
619
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
480
620
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
481
621
  */
482
- export const addTag = (entity: Mutable<Unknown>, tag: string): void => addTag$(entity, tag);
622
+ export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.addTag(entity, tag);
483
623
 
484
624
  /**
485
625
  * Remove a tag from the object.
486
- * Must be called within an `Obj.change` callback.
626
+ * Must be called within an `Obj.update` callback.
487
627
  *
488
628
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
489
629
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
490
630
  */
491
- export const removeTag = (entity: Mutable<Unknown>, tag: string): void => removeTag$(entity, tag);
631
+ export const removeTag = (entity: Mutable<Unknown>, tag: string): void => internal.removeTag(entity, tag);
492
632
 
493
633
  /**
494
634
  * Check if the object is deleted.
495
635
  * Accepts both reactive objects and snapshots.
496
636
  */
497
637
  // TODO(dmaretskyi): Default to `false`.
498
- export const isDeleted = (entity: Unknown | Snapshot): boolean => isDeleted$(entity);
638
+ export const isDeleted = (entity: Unknown | Snapshot): boolean => objInternal.isDeleted(entity);
499
639
 
500
640
  //
501
641
  // Annotations
@@ -504,33 +644,37 @@ export const isDeleted = (entity: Unknown | Snapshot): boolean => isDeleted$(ent
504
644
  /**
505
645
  * Get the label of the object.
506
646
  * Accepts both reactive objects and snapshots.
647
+ *
648
+ * @param options.fallback `'typename'` returns the object's typename when no
649
+ * label is set (e.g. `org.dxos.type.table`).
507
650
  */
508
- export const getLabel = (entity: Unknown | Snapshot): string | undefined => getLabel$(entity);
651
+ export const getLabel = (entity: Unknown | Snapshot, options?: internal.GetLabelOptions): string | undefined =>
652
+ internal.getLabel(entity, options);
509
653
 
510
654
  /**
511
655
  * Set the label of the object.
512
- * Must be called within an `Obj.change` callback.
656
+ * Must be called within an `Obj.update` callback.
513
657
  *
514
658
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
515
659
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
516
660
  */
517
- export const setLabel = (entity: Mutable<Unknown>, label: string): void => setLabel$(entity, label);
661
+ export const setLabel = (entity: Mutable<Unknown>, label: string): void => internal.setLabel(entity, label);
518
662
 
519
663
  /**
520
664
  * Get the description of the object.
521
665
  * Accepts both reactive objects and snapshots.
522
666
  */
523
- export const getDescription = (entity: Unknown | Snapshot): string | undefined => getDescription$(entity);
667
+ export const getDescription = (entity: Unknown | Snapshot): string | undefined => internal.getDescription(entity);
524
668
 
525
669
  /**
526
670
  * Set the description of the object.
527
- * Must be called within an `Obj.change` callback.
671
+ * Must be called within an `Obj.update` callback.
528
672
  *
529
673
  * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
530
674
  * parameters, so there is no compile-time error. Enforcement is runtime-only.
531
675
  */
532
676
  export const setDescription = (entity: Mutable<Unknown>, description: string): void =>
533
- setDescription$(entity, description);
677
+ internal.setDescription(entity, description);
534
678
 
535
679
  /**
536
680
  * Symbol to set parent when creating objects with `Obj.make`.
@@ -542,7 +686,7 @@ export const setDescription = (entity: Mutable<Unknown>, description: string): v
542
686
  * })
543
687
  * ```
544
688
  */
545
- export const Parent: unique symbol = ParentId as any;
689
+ export const Parent: unique symbol = internal.ParentId as any;
546
690
 
547
691
  /**
548
692
  * Get the parent of an object.
@@ -551,9 +695,9 @@ export const Parent: unique symbol = ParentId as any;
551
695
  * @returns The parent object, or undefined if the object has no parent.
552
696
  */
553
697
  export const getParent = (entity: Unknown | Snapshot): Unknown | undefined => {
554
- assertArgument(isObject(entity), 'Expected an object');
555
- assumeType<InternalObjectProps>(entity);
556
- return entity[ParentId] as Unknown | undefined;
698
+ assertArgument(isObject(entity) || isSnapshot(entity), 'Expected an object');
699
+ assumeType<internal.InternalObjectProps>(entity);
700
+ return entity[internal.ParentId] as Unknown | undefined;
557
701
  };
558
702
 
559
703
  /**
@@ -564,9 +708,126 @@ export const getParent = (entity: Unknown | Snapshot): Unknown | undefined => {
564
708
  export const setParent = (entity: Unknown, parent: Any | undefined) => {
565
709
  assertArgument(isObject(entity), 'Expected an object');
566
710
  assertArgument(parent === undefined || isObject(parent), 'Expected an object');
567
- assumeType<InternalObjectProps>(entity);
568
- assumeType<InternalObjectProps | undefined>(parent);
569
- entity[ParentId] = parent;
711
+ assumeType<internal.InternalObjectProps>(entity);
712
+ assumeType<internal.InternalObjectProps | undefined>(parent);
713
+ entity[internal.ParentId] = parent;
714
+ return entity;
715
+ };
716
+
717
+ interface UpdateFromOptions<T> {
718
+ exclude?: (keyof T)[];
719
+ include?: (keyof T)[];
720
+ }
721
+
722
+ const valuesEqual = (left: unknown, right: unknown): boolean => {
723
+ if (left === right) {
724
+ return true;
725
+ }
726
+ if (left === null || right === null) {
727
+ return left === right;
728
+ }
729
+ if (typeof left !== 'object' || typeof right !== 'object') {
730
+ return Utils.structuralRegion(() => Equal.equals(left, right));
731
+ }
732
+ if (Ref.isRef(left) && Ref.isRef(right)) {
733
+ return left.uri === right.uri;
734
+ }
735
+ if (Ref.isRef(left) || Ref.isRef(right)) {
736
+ return false;
737
+ }
738
+ if (Array.isArray(left) && Array.isArray(right)) {
739
+ if (left.length !== right.length) {
740
+ return false;
741
+ }
742
+ for (let index = 0; index < left.length; index++) {
743
+ if (!valuesEqual(left[index], right[index])) {
744
+ return false;
745
+ }
746
+ }
747
+ return true;
748
+ }
749
+ if (Array.isArray(left) || Array.isArray(right)) {
750
+ return false;
751
+ }
752
+ const leftRecord = left as Record<string, unknown>;
753
+ const rightRecord = right as Record<string, unknown>;
754
+ const keys = new Set([
755
+ ...Object.keys(leftRecord).filter((key) => key !== 'id'),
756
+ ...Object.keys(rightRecord).filter((key) => key !== 'id'),
757
+ ]);
758
+ for (const key of keys) {
759
+ const leftHas = Object.hasOwn(leftRecord, key);
760
+ const rightHas = Object.hasOwn(rightRecord, key);
761
+ const leftValue = leftHas ? leftRecord[key] : undefined;
762
+ const rightValue = rightHas ? rightRecord[key] : undefined;
763
+ if (!valuesEqual(leftValue, rightValue)) {
764
+ return false;
765
+ }
766
+ }
767
+ return true;
768
+ };
769
+
770
+ /**
771
+ * Breaks reactive proxies on assigned values so echo-db assignment accepts nested structs (same idea as link assignment).
772
+ */
773
+ const prepareAssignValue = (value: unknown): unknown =>
774
+ deepMapValues(value, (nested, recurse) => {
775
+ if (nested === null || typeof nested !== 'object') {
776
+ return nested;
777
+ }
778
+ if (Ref.isRef(nested)) {
779
+ return nested;
780
+ }
781
+ if (Array.isArray(nested)) {
782
+ return recurse(nested);
783
+ }
784
+ if (isProxy(nested)) {
785
+ return recurse({ ...getProxyTarget(nested) });
786
+ }
787
+ return recurse(nested);
788
+ });
789
+
790
+ /**
791
+ * For each key present on `source` (except `id`), assigns `target[key]` when the current value differs.
792
+ * References are compared by target DXN; other values use Effect `Equal.equals` inside a structural region,
793
+ * with recursive comparison for arrays and plain object-shaped property bags (excluding `id`).
794
+ *
795
+ * Must be called within an `Obj.update` callback.
796
+ *
797
+ * @returns Whether any property was updated.
798
+ */
799
+ export const updateFrom = <T extends Unknown>(
800
+ target: Mutable<T>,
801
+ source: T,
802
+ options?: UpdateFromOptions<T>,
803
+ ): boolean => {
804
+ assertArgument(isObject(target), 'Expected an echo object target.');
805
+ assertArgument(isObject(source), 'Expected an echo object source.');
806
+ let keys = Object.keys(source as Record<string, unknown>).filter((key) => key !== 'id');
807
+ if (options?.include !== undefined) {
808
+ const include = new Set(options.include.map((key) => String(key)));
809
+ keys = keys.filter((key) => include.has(key));
810
+ }
811
+ if (options?.exclude !== undefined) {
812
+ const exclude = new Set(options.exclude.map((key) => String(key)));
813
+ keys = keys.filter((key) => !exclude.has(key));
814
+ }
815
+ let updated = false;
816
+ const sourceRecord = source as Record<string, unknown>;
817
+ const targetRecord = target as Record<string, unknown>;
818
+ for (const key of keys) {
819
+ if (!Object.hasOwn(sourceRecord, key)) {
820
+ continue;
821
+ }
822
+ const nextValue = sourceRecord[key];
823
+ const prevValue = Object.hasOwn(targetRecord, key) ? targetRecord[key] : undefined;
824
+ if (valuesEqual(prevValue, nextValue)) {
825
+ continue;
826
+ }
827
+ targetRecord[key] = prepareAssignValue(nextValue) as never;
828
+ updated = true;
829
+ }
830
+ return updated;
570
831
  };
571
832
 
572
833
  //
@@ -576,7 +837,7 @@ export const setParent = (entity: Unknown, parent: Any | undefined) => {
576
837
  /**
577
838
  * JSON representation of an object.
578
839
  */
579
- export type JSON = APIJSON;
840
+ export type JSON = internal.ObjectJSON;
580
841
 
581
842
  /**
582
843
  * Converts object to its JSON representation.
@@ -584,7 +845,7 @@ export type JSON = APIJSON;
584
845
  *
585
846
  * The same algorithm is used when calling the standard `JSON.stringify(obj)` function.
586
847
  */
587
- export const toJSON = (entity: Unknown | Snapshot): JSON => toJSON$(entity);
848
+ export const toJSON = (entity: Unknown | Snapshot): JSON => objInternal.objectToJSON(entity);
588
849
 
589
850
  /**
590
851
  * Creates an object from its json representation, performing schema validation.
@@ -593,39 +854,46 @@ export const toJSON = (entity: Unknown | Snapshot): JSON => toJSON$(entity);
593
854
  * The function must be async to support resolving the schema as well as the relation endpoints.
594
855
  *
595
856
  * @param options.refResolver - Resolver for references. Produces hydrated references that can be resolved.
596
- * @param options.dxn - Override object DXN. Changes the result of `Obj.getDXN`.
857
+ * @param options.uri - Override object URI. Changes the result of `Obj.getURI`.
858
+ * @param options.database - Database to associate with the object.
597
859
  */
598
- export const fromJSON: (json: unknown, options?: { refResolver?: Ref.Resolver; dxn?: DXN }) => Promise<Unknown> =
599
- objectFromJSON as any;
860
+ export const fromJSON: (
861
+ json: unknown,
862
+ options?: { refResolver?: Ref.Resolver; uri?: URI.URI; database?: Database.Database; parent?: Unknown },
863
+ ) => Promise<Unknown> = objInternal.objectFromJSON as any;
600
864
 
601
865
  /**
602
866
  * Comparator function type for sorting objects.
603
867
  * Accepts both reactive objects and snapshots.
604
868
  */
605
- export type Comparator = ApiComparator<Unknown | Snapshot>;
869
+ export type Comparator = internal.Comparator<Unknown | Snapshot>;
606
870
 
607
- export const sortByLabel: Comparator = sortByLabel$ as Comparator;
608
- export const sortByTypename: Comparator = sortByTypename$ as Comparator;
609
- export const sort = (...comparators: Comparator[]): Comparator => sort$(...comparators) as Comparator;
871
+ export const sortByLabel: Comparator = internal.sortByLabel as Comparator;
872
+ export const sortByTypename: Comparator = internal.sortByTypename as Comparator;
873
+ export const sort = (...comparators: Comparator[]): Comparator => internal.sort(...comparators) as Comparator;
610
874
 
611
875
  //
612
876
  // Version
613
877
  //
614
878
 
615
- export { VersionTypeId };
616
- export type { VersionCompareResult };
879
+ export const VersionTypeId = internal.VersionTypeId;
880
+ export type VersionCompareResult = internal.VersionCompareResult;
617
881
 
618
882
  /**
619
883
  * Represent object version.
620
884
  * May be backed by Automerge.
621
885
  * Objects with no history are not versioned.
622
886
  */
623
- export type Version = ApiVersion;
887
+ export type Version = internal.EntityVersion;
624
888
 
625
- export { isVersion, versionValid, compareVersions, encodeVersion, decodeVersion };
889
+ export const isVersion = internal.isVersion;
890
+ export const versionValid = internal.versionValid;
891
+ export const compareVersions = internal.compareVersions;
892
+ export const encodeVersion = internal.encodeVersion;
893
+ export const decodeVersion = internal.decodeVersion;
626
894
 
627
895
  /**
628
896
  * Returns the version of the object.
629
897
  * Accepts both reactive objects and snapshots.
630
898
  */
631
- export const version = (entity: Unknown | Snapshot): Version => version$(entity);
899
+ export const version = (entity: Unknown | Snapshot): Version => internal.version(entity);