@dxos/echo 0.8.4-main.3a94e84 → 0.8.4-main.3c1ae3b

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 (478) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/browser/Annotation.mjs +31 -0
  3. package/dist/lib/browser/Annotation.mjs.map +7 -0
  4. package/dist/lib/browser/Database.mjs +14 -0
  5. package/dist/lib/browser/Database.mjs.map +7 -0
  6. package/dist/lib/browser/Entity.mjs +20 -0
  7. package/dist/lib/browser/Entity.mjs.map +7 -0
  8. package/dist/lib/browser/Err.mjs +11 -0
  9. package/dist/lib/browser/Err.mjs.map +7 -0
  10. package/dist/lib/browser/Filter.mjs +60 -0
  11. package/dist/lib/browser/Filter.mjs.map +7 -0
  12. package/dist/lib/browser/Format.mjs +67 -0
  13. package/dist/lib/browser/Format.mjs.map +7 -0
  14. package/dist/lib/browser/JsonSchema.mjs +18 -0
  15. package/dist/lib/browser/JsonSchema.mjs.map +7 -0
  16. package/dist/lib/browser/Key.mjs +13 -0
  17. package/dist/lib/browser/Key.mjs.map +7 -0
  18. package/dist/lib/browser/Obj.mjs +83 -0
  19. package/dist/lib/browser/Obj.mjs.map +7 -0
  20. package/dist/lib/browser/Order.mjs +11 -0
  21. package/dist/lib/browser/Order.mjs.map +7 -0
  22. package/dist/lib/browser/Query.mjs +25 -0
  23. package/dist/lib/browser/Query.mjs.map +7 -0
  24. package/dist/lib/browser/QueryResult.mjs +3 -0
  25. package/dist/lib/browser/QueryResult.mjs.map +7 -0
  26. package/dist/lib/browser/Ref.mjs +21 -0
  27. package/dist/lib/browser/Ref.mjs.map +7 -0
  28. package/dist/lib/browser/Relation.mjs +33 -0
  29. package/dist/lib/browser/Relation.mjs.map +7 -0
  30. package/dist/lib/browser/SchemaRegistry.mjs +3 -0
  31. package/dist/lib/browser/SchemaRegistry.mjs.map +7 -0
  32. package/dist/lib/browser/Tag.mjs +25 -0
  33. package/dist/lib/browser/Tag.mjs.map +7 -0
  34. package/dist/lib/browser/Type.mjs +38 -0
  35. package/dist/lib/browser/Type.mjs.map +7 -0
  36. package/dist/lib/browser/chunk-3B2G6BW4.mjs +74 -0
  37. package/dist/lib/browser/chunk-3B2G6BW4.mjs.map +7 -0
  38. package/dist/lib/browser/chunk-5IN7XBIQ.mjs +24 -0
  39. package/dist/lib/browser/chunk-5IN7XBIQ.mjs.map +7 -0
  40. package/dist/lib/browser/chunk-6XVZF5VJ.mjs +2924 -0
  41. package/dist/lib/browser/chunk-6XVZF5VJ.mjs.map +7 -0
  42. package/dist/lib/browser/chunk-AGOWBKY6.mjs +94 -0
  43. package/dist/lib/browser/chunk-AGOWBKY6.mjs.map +7 -0
  44. package/dist/lib/browser/chunk-BD6MRI4M.mjs +113 -0
  45. package/dist/lib/browser/chunk-BD6MRI4M.mjs.map +7 -0
  46. package/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
  47. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
  48. package/dist/lib/browser/chunk-DOPKE2FQ.mjs +32 -0
  49. package/dist/lib/browser/chunk-DOPKE2FQ.mjs.map +7 -0
  50. package/dist/lib/browser/chunk-ESLW4N7S.mjs +41 -0
  51. package/dist/lib/browser/chunk-ESLW4N7S.mjs.map +7 -0
  52. package/dist/lib/browser/chunk-F4YF6C3O.mjs +363 -0
  53. package/dist/lib/browser/chunk-F4YF6C3O.mjs.map +7 -0
  54. package/dist/lib/browser/chunk-FGFQWIZE.mjs +9 -0
  55. package/dist/lib/browser/chunk-FGFQWIZE.mjs.map +7 -0
  56. package/dist/lib/browser/chunk-INHXFXY5.mjs +22 -0
  57. package/dist/lib/browser/chunk-INHXFXY5.mjs.map +7 -0
  58. package/dist/lib/browser/chunk-JG4GH6LN.mjs +9 -0
  59. package/dist/lib/browser/chunk-JG4GH6LN.mjs.map +7 -0
  60. package/dist/lib/browser/chunk-MYCCGG2T.mjs +15 -0
  61. package/dist/lib/browser/chunk-MYCCGG2T.mjs.map +7 -0
  62. package/dist/lib/browser/chunk-NFH3POTD.mjs +37 -0
  63. package/dist/lib/browser/chunk-NFH3POTD.mjs.map +7 -0
  64. package/dist/lib/browser/chunk-O6FOICWT.mjs +57 -0
  65. package/dist/lib/browser/chunk-O6FOICWT.mjs.map +7 -0
  66. package/dist/lib/browser/chunk-P2B4BASR.mjs +288 -0
  67. package/dist/lib/browser/chunk-P2B4BASR.mjs.map +7 -0
  68. package/dist/lib/browser/chunk-QHC3ZYNC.mjs +152 -0
  69. package/dist/lib/browser/chunk-QHC3ZYNC.mjs.map +7 -0
  70. package/dist/lib/browser/chunk-QU7PWSZD.mjs +62 -0
  71. package/dist/lib/browser/chunk-QU7PWSZD.mjs.map +7 -0
  72. package/dist/lib/browser/chunk-RP4JV7FD.mjs +403 -0
  73. package/dist/lib/browser/chunk-RP4JV7FD.mjs.map +7 -0
  74. package/dist/lib/browser/chunk-V7TON6BX.mjs +151 -0
  75. package/dist/lib/browser/chunk-V7TON6BX.mjs.map +7 -0
  76. package/dist/lib/browser/chunk-WABSVOOX.mjs +303 -0
  77. package/dist/lib/browser/chunk-WABSVOOX.mjs.map +7 -0
  78. package/dist/lib/browser/chunk-XRHHSMHJ.mjs +39 -0
  79. package/dist/lib/browser/chunk-XRHHSMHJ.mjs.map +7 -0
  80. package/dist/lib/browser/chunk-ZIM3Y4ZK.mjs +38 -0
  81. package/dist/lib/browser/chunk-ZIM3Y4ZK.mjs.map +7 -0
  82. package/dist/lib/browser/index.mjs +72 -9
  83. package/dist/lib/browser/internal/index.mjs +347 -0
  84. package/dist/lib/browser/internal/index.mjs.map +7 -0
  85. package/dist/lib/browser/meta.json +1 -1
  86. package/dist/lib/browser/testing/index.mjs +322 -32
  87. package/dist/lib/browser/testing/index.mjs.map +4 -4
  88. package/dist/lib/node-esm/Annotation.mjs +31 -0
  89. package/dist/lib/node-esm/Annotation.mjs.map +7 -0
  90. package/dist/lib/node-esm/Database.mjs +14 -0
  91. package/dist/lib/node-esm/Database.mjs.map +7 -0
  92. package/dist/lib/node-esm/Entity.mjs +20 -0
  93. package/dist/lib/node-esm/Entity.mjs.map +7 -0
  94. package/dist/lib/node-esm/Err.mjs +11 -0
  95. package/dist/lib/node-esm/Err.mjs.map +7 -0
  96. package/dist/lib/node-esm/Filter.mjs +60 -0
  97. package/dist/lib/node-esm/Filter.mjs.map +7 -0
  98. package/dist/lib/node-esm/Format.mjs +67 -0
  99. package/dist/lib/node-esm/Format.mjs.map +7 -0
  100. package/dist/lib/node-esm/JsonSchema.mjs +18 -0
  101. package/dist/lib/node-esm/JsonSchema.mjs.map +7 -0
  102. package/dist/lib/node-esm/Key.mjs +13 -0
  103. package/dist/lib/node-esm/Key.mjs.map +7 -0
  104. package/dist/lib/node-esm/Obj.mjs +83 -0
  105. package/dist/lib/node-esm/Obj.mjs.map +7 -0
  106. package/dist/lib/node-esm/Order.mjs +11 -0
  107. package/dist/lib/node-esm/Order.mjs.map +7 -0
  108. package/dist/lib/node-esm/Query.mjs +25 -0
  109. package/dist/lib/node-esm/Query.mjs.map +7 -0
  110. package/dist/lib/node-esm/QueryResult.mjs +3 -0
  111. package/dist/lib/node-esm/QueryResult.mjs.map +7 -0
  112. package/dist/lib/node-esm/Ref.mjs +21 -0
  113. package/dist/lib/node-esm/Ref.mjs.map +7 -0
  114. package/dist/lib/node-esm/Relation.mjs +33 -0
  115. package/dist/lib/node-esm/Relation.mjs.map +7 -0
  116. package/dist/lib/node-esm/SchemaRegistry.mjs +3 -0
  117. package/dist/lib/node-esm/SchemaRegistry.mjs.map +7 -0
  118. package/dist/lib/node-esm/Tag.mjs +25 -0
  119. package/dist/lib/node-esm/Tag.mjs.map +7 -0
  120. package/dist/lib/node-esm/Type.mjs +38 -0
  121. package/dist/lib/node-esm/Type.mjs.map +7 -0
  122. package/dist/lib/node-esm/chunk-5M5P2DCR.mjs +32 -0
  123. package/dist/lib/node-esm/chunk-5M5P2DCR.mjs.map +7 -0
  124. package/dist/lib/node-esm/chunk-6OTQZKHX.mjs +303 -0
  125. package/dist/lib/node-esm/chunk-6OTQZKHX.mjs.map +7 -0
  126. package/dist/lib/node-esm/chunk-76LEDWHO.mjs +152 -0
  127. package/dist/lib/node-esm/chunk-76LEDWHO.mjs.map +7 -0
  128. package/dist/lib/node-esm/chunk-AGHZH33D.mjs +9 -0
  129. package/dist/lib/node-esm/chunk-AGHZH33D.mjs.map +7 -0
  130. package/dist/lib/node-esm/chunk-AJEMYSIR.mjs +22 -0
  131. package/dist/lib/node-esm/chunk-AJEMYSIR.mjs.map +7 -0
  132. package/dist/lib/node-esm/chunk-BJACR7QG.mjs +363 -0
  133. package/dist/lib/node-esm/chunk-BJACR7QG.mjs.map +7 -0
  134. package/dist/lib/node-esm/chunk-BYL2NPEA.mjs +37 -0
  135. package/dist/lib/node-esm/chunk-BYL2NPEA.mjs.map +7 -0
  136. package/dist/lib/node-esm/chunk-CCMFPJUT.mjs +74 -0
  137. package/dist/lib/node-esm/chunk-CCMFPJUT.mjs.map +7 -0
  138. package/dist/lib/node-esm/chunk-D5BW7KHR.mjs +39 -0
  139. package/dist/lib/node-esm/chunk-D5BW7KHR.mjs.map +7 -0
  140. package/dist/lib/node-esm/chunk-DJX53IQ3.mjs +2924 -0
  141. package/dist/lib/node-esm/chunk-DJX53IQ3.mjs.map +7 -0
  142. package/dist/lib/node-esm/chunk-FWTPV5QD.mjs +94 -0
  143. package/dist/lib/node-esm/chunk-FWTPV5QD.mjs.map +7 -0
  144. package/dist/lib/node-esm/chunk-HLUDHPFO.mjs +403 -0
  145. package/dist/lib/node-esm/chunk-HLUDHPFO.mjs.map +7 -0
  146. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  147. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  148. package/dist/lib/node-esm/chunk-JYZSF62S.mjs +113 -0
  149. package/dist/lib/node-esm/chunk-JYZSF62S.mjs.map +7 -0
  150. package/dist/lib/node-esm/chunk-KUX5JEL2.mjs +57 -0
  151. package/dist/lib/node-esm/chunk-KUX5JEL2.mjs.map +7 -0
  152. package/dist/lib/node-esm/chunk-LDXRA5TC.mjs +288 -0
  153. package/dist/lib/node-esm/chunk-LDXRA5TC.mjs.map +7 -0
  154. package/dist/lib/node-esm/chunk-MOWUEW5P.mjs +15 -0
  155. package/dist/lib/node-esm/chunk-MOWUEW5P.mjs.map +7 -0
  156. package/dist/lib/node-esm/chunk-NHYOREKX.mjs +62 -0
  157. package/dist/lib/node-esm/chunk-NHYOREKX.mjs.map +7 -0
  158. package/dist/lib/node-esm/chunk-QVZZHCDS.mjs +9 -0
  159. package/dist/lib/node-esm/chunk-QVZZHCDS.mjs.map +7 -0
  160. package/dist/lib/node-esm/chunk-W3OLV7MG.mjs +41 -0
  161. package/dist/lib/node-esm/chunk-W3OLV7MG.mjs.map +7 -0
  162. package/dist/lib/node-esm/chunk-W5AQXKVF.mjs +38 -0
  163. package/dist/lib/node-esm/chunk-W5AQXKVF.mjs.map +7 -0
  164. package/dist/lib/node-esm/chunk-YNBFXTDG.mjs +24 -0
  165. package/dist/lib/node-esm/chunk-YNBFXTDG.mjs.map +7 -0
  166. package/dist/lib/node-esm/chunk-Z53QIBP2.mjs +151 -0
  167. package/dist/lib/node-esm/chunk-Z53QIBP2.mjs.map +7 -0
  168. package/dist/lib/node-esm/index.mjs +72 -9
  169. package/dist/lib/node-esm/internal/index.mjs +347 -0
  170. package/dist/lib/node-esm/internal/index.mjs.map +7 -0
  171. package/dist/lib/node-esm/meta.json +1 -1
  172. package/dist/lib/node-esm/testing/index.mjs +322 -32
  173. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  174. package/dist/types/src/Annotation.d.ts +2 -0
  175. package/dist/types/src/Annotation.d.ts.map +1 -0
  176. package/dist/types/src/Database.d.ts +179 -0
  177. package/dist/types/src/Database.d.ts.map +1 -0
  178. package/dist/types/src/Entity.d.ts +36 -0
  179. package/dist/types/src/Entity.d.ts.map +1 -0
  180. package/dist/types/src/Err.d.ts +68 -0
  181. package/dist/types/src/Err.d.ts.map +1 -0
  182. package/dist/types/src/Filter.d.ts +120 -0
  183. package/dist/types/src/Filter.d.ts.map +1 -0
  184. package/dist/types/src/Format.d.ts +4 -0
  185. package/dist/types/src/Format.d.ts.map +1 -0
  186. package/dist/types/src/Hypergraph.d.ts +60 -0
  187. package/dist/types/src/Hypergraph.d.ts.map +1 -0
  188. package/dist/types/src/JsonSchema.d.ts +9 -0
  189. package/dist/types/src/JsonSchema.d.ts.map +1 -0
  190. package/dist/types/src/Key.d.ts +1 -0
  191. package/dist/types/src/Key.d.ts.map +1 -1
  192. package/dist/types/src/Obj.d.ts +152 -35
  193. package/dist/types/src/Obj.d.ts.map +1 -1
  194. package/dist/types/src/Order.d.ts +11 -0
  195. package/dist/types/src/Order.d.ts.map +1 -0
  196. package/dist/types/src/Query.d.ts +107 -0
  197. package/dist/types/src/Query.d.ts.map +1 -0
  198. package/dist/types/src/Query.test.d.ts +2 -0
  199. package/dist/types/src/Query.test.d.ts.map +1 -0
  200. package/dist/types/src/QueryResult.d.ts +84 -0
  201. package/dist/types/src/QueryResult.d.ts.map +1 -0
  202. package/dist/types/src/Ref.d.ts +12 -10
  203. package/dist/types/src/Ref.d.ts.map +1 -1
  204. package/dist/types/src/Relation.d.ts +20 -14
  205. package/dist/types/src/Relation.d.ts.map +1 -1
  206. package/dist/types/src/SchemaRegistry.d.ts +73 -0
  207. package/dist/types/src/SchemaRegistry.d.ts.map +1 -0
  208. package/dist/types/src/Tag.d.ts +17 -0
  209. package/dist/types/src/Tag.d.ts.map +1 -0
  210. package/dist/types/src/Type.d.ts +39 -50
  211. package/dist/types/src/Type.d.ts.map +1 -1
  212. package/dist/types/src/index.d.ts +15 -3
  213. package/dist/types/src/index.d.ts.map +1 -1
  214. package/dist/types/src/internal/annotations/annotations.d.ts +179 -0
  215. package/dist/types/src/internal/annotations/annotations.d.ts.map +1 -0
  216. package/dist/types/src/internal/annotations/annotations.test.d.ts +2 -0
  217. package/dist/types/src/internal/annotations/annotations.test.d.ts.map +1 -0
  218. package/dist/types/src/internal/annotations/index.d.ts +3 -0
  219. package/dist/types/src/internal/annotations/index.d.ts.map +1 -0
  220. package/dist/types/src/internal/annotations/util.d.ts +27 -0
  221. package/dist/types/src/internal/annotations/util.d.ts.map +1 -0
  222. package/dist/types/src/internal/entities/entity.d.ts +10 -0
  223. package/dist/types/src/internal/entities/entity.d.ts.map +1 -0
  224. package/dist/types/src/internal/entities/expando.d.ts +16 -0
  225. package/dist/types/src/internal/entities/expando.d.ts.map +1 -0
  226. package/dist/types/src/internal/entities/index.d.ts +6 -0
  227. package/dist/types/src/internal/entities/index.d.ts.map +1 -0
  228. package/dist/types/src/internal/entities/model.d.ts +70 -0
  229. package/dist/types/src/internal/entities/model.d.ts.map +1 -0
  230. package/dist/types/src/internal/entities/object.d.ts +11 -0
  231. package/dist/types/src/internal/entities/object.d.ts.map +1 -0
  232. package/dist/types/src/internal/entities/relation.d.ts +55 -0
  233. package/dist/types/src/internal/entities/relation.d.ts.map +1 -0
  234. package/dist/types/src/internal/entities/util.d.ts +2 -0
  235. package/dist/types/src/internal/entities/util.d.ts.map +1 -0
  236. package/dist/types/src/internal/formats/date.d.ts +63 -0
  237. package/dist/types/src/internal/formats/date.d.ts.map +1 -0
  238. package/dist/types/src/internal/formats/date.test.d.ts +2 -0
  239. package/dist/types/src/internal/formats/date.test.d.ts.map +1 -0
  240. package/dist/types/src/internal/formats/format.d.ts +32 -0
  241. package/dist/types/src/internal/formats/format.d.ts.map +1 -0
  242. package/dist/types/src/internal/formats/format.test.d.ts +2 -0
  243. package/dist/types/src/internal/formats/format.test.d.ts.map +1 -0
  244. package/dist/types/src/internal/formats/index.d.ts +8 -0
  245. package/dist/types/src/internal/formats/index.d.ts.map +1 -0
  246. package/dist/types/src/internal/formats/number.d.ts +31 -0
  247. package/dist/types/src/internal/formats/number.d.ts.map +1 -0
  248. package/dist/types/src/internal/formats/object.d.ts +35 -0
  249. package/dist/types/src/internal/formats/object.d.ts.map +1 -0
  250. package/dist/types/src/internal/formats/select.d.ts +13 -0
  251. package/dist/types/src/internal/formats/select.d.ts.map +1 -0
  252. package/dist/types/src/internal/formats/string.d.ts +42 -0
  253. package/dist/types/src/internal/formats/string.d.ts.map +1 -0
  254. package/dist/types/src/internal/formats/types.d.ts +72 -0
  255. package/dist/types/src/internal/formats/types.d.ts.map +1 -0
  256. package/dist/types/src/internal/index.d.ts +11 -0
  257. package/dist/types/src/internal/index.d.ts.map +1 -0
  258. package/dist/types/src/internal/json-schema/annotations.d.ts +19 -0
  259. package/dist/types/src/internal/json-schema/annotations.d.ts.map +1 -0
  260. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts +2 -0
  261. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +1 -0
  262. package/dist/types/src/internal/json-schema/index.d.ts +5 -0
  263. package/dist/types/src/internal/json-schema/index.d.ts.map +1 -0
  264. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts +7 -0
  265. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +1 -0
  266. package/dist/types/src/internal/json-schema/json-schema-type.d.ts +250 -0
  267. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +1 -0
  268. package/dist/types/src/internal/json-schema/json-schema.d.ts +29 -0
  269. package/dist/types/src/internal/json-schema/json-schema.d.ts.map +1 -0
  270. package/dist/types/src/internal/json-schema/json-schema.test.d.ts +2 -0
  271. package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +1 -0
  272. package/dist/types/src/internal/object/common.d.ts +18 -0
  273. package/dist/types/src/internal/object/common.d.ts.map +1 -0
  274. package/dist/types/src/internal/object/create-object.d.ts +39 -0
  275. package/dist/types/src/internal/object/create-object.d.ts.map +1 -0
  276. package/dist/types/src/internal/object/create-object.test.d.ts +2 -0
  277. package/dist/types/src/internal/object/create-object.test.d.ts.map +1 -0
  278. package/dist/types/src/internal/object/deleted.d.ts +6 -0
  279. package/dist/types/src/internal/object/deleted.d.ts.map +1 -0
  280. package/dist/types/src/internal/object/ids.d.ts +6 -0
  281. package/dist/types/src/internal/object/ids.d.ts.map +1 -0
  282. package/dist/types/src/internal/object/index.d.ts +8 -0
  283. package/dist/types/src/internal/object/index.d.ts.map +1 -0
  284. package/dist/types/src/internal/object/inspect.d.ts +2 -0
  285. package/dist/types/src/internal/object/inspect.d.ts.map +1 -0
  286. package/dist/types/src/internal/object/json-serializer.d.ts +31 -0
  287. package/dist/types/src/internal/object/json-serializer.d.ts.map +1 -0
  288. package/dist/types/src/internal/object/json-serializer.test.d.ts +2 -0
  289. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +1 -0
  290. package/dist/types/src/internal/object/schema-validator.d.ts +15 -0
  291. package/dist/types/src/internal/object/schema-validator.d.ts.map +1 -0
  292. package/dist/types/src/internal/object/schema-validator.test.d.ts +2 -0
  293. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +1 -0
  294. package/dist/types/src/internal/object/typed-object.d.ts +31 -0
  295. package/dist/types/src/internal/object/typed-object.d.ts.map +1 -0
  296. package/dist/types/src/internal/object/typed-object.test.d.ts +2 -0
  297. package/dist/types/src/internal/object/typed-object.test.d.ts.map +1 -0
  298. package/dist/types/src/internal/proxy/handler.test.d.ts +2 -0
  299. package/dist/types/src/internal/proxy/handler.test.d.ts.map +1 -0
  300. package/dist/types/src/internal/proxy/index.d.ts +3 -0
  301. package/dist/types/src/internal/proxy/index.d.ts.map +1 -0
  302. package/dist/types/src/internal/proxy/make-object.d.ts +16 -0
  303. package/dist/types/src/internal/proxy/make-object.d.ts.map +1 -0
  304. package/dist/types/src/internal/proxy/schema.test.d.ts +2 -0
  305. package/dist/types/src/internal/proxy/schema.test.d.ts.map +1 -0
  306. package/dist/types/src/internal/proxy/typed-handler.d.ts +44 -0
  307. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +1 -0
  308. package/dist/types/src/internal/proxy/typed-handler.test.d.ts +2 -0
  309. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +1 -0
  310. package/dist/types/src/internal/proxy/typed-object.test.d.ts +2 -0
  311. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +1 -0
  312. package/dist/types/src/internal/ref/index.d.ts +3 -0
  313. package/dist/types/src/internal/ref/index.d.ts.map +1 -0
  314. package/dist/types/src/internal/ref/ref-array.d.ts +21 -0
  315. package/dist/types/src/internal/ref/ref-array.d.ts.map +1 -0
  316. package/dist/types/src/internal/ref/ref.d.ts +209 -0
  317. package/dist/types/src/internal/ref/ref.d.ts.map +1 -0
  318. package/dist/types/src/internal/ref/ref.test.d.ts +2 -0
  319. package/dist/types/src/internal/ref/ref.test.d.ts.map +1 -0
  320. package/dist/types/src/internal/schema/compose.d.ts +6 -0
  321. package/dist/types/src/internal/schema/compose.d.ts.map +1 -0
  322. package/dist/types/src/internal/schema/compose.test.d.ts +2 -0
  323. package/dist/types/src/internal/schema/compose.test.d.ts.map +1 -0
  324. package/dist/types/src/internal/schema/echo-schema.d.ts +168 -0
  325. package/dist/types/src/internal/schema/echo-schema.d.ts.map +1 -0
  326. package/dist/types/src/internal/schema/index.d.ts +5 -0
  327. package/dist/types/src/internal/schema/index.d.ts.map +1 -0
  328. package/dist/types/src/internal/schema/manipulation.d.ts +10 -0
  329. package/dist/types/src/internal/schema/manipulation.d.ts.map +1 -0
  330. package/dist/types/src/internal/schema/persistent-schema.d.ts +18 -0
  331. package/dist/types/src/internal/schema/persistent-schema.d.ts.map +1 -0
  332. package/dist/types/src/internal/schema/snapshot.d.ts +6 -0
  333. package/dist/types/src/internal/schema/snapshot.d.ts.map +1 -0
  334. package/dist/types/src/internal/types/base.d.ts +37 -0
  335. package/dist/types/src/internal/types/base.d.ts.map +1 -0
  336. package/dist/types/src/internal/types/entity.d.ts +12 -0
  337. package/dist/types/src/internal/types/entity.d.ts.map +1 -0
  338. package/dist/types/src/internal/types/index.d.ts +6 -0
  339. package/dist/types/src/internal/types/index.d.ts.map +1 -0
  340. package/dist/types/src/internal/types/meta.d.ts +40 -0
  341. package/dist/types/src/internal/types/meta.d.ts.map +1 -0
  342. package/dist/types/src/internal/types/typename.d.ts +13 -0
  343. package/dist/types/src/internal/types/typename.d.ts.map +1 -0
  344. package/dist/types/src/internal/types/version.d.ts +15 -0
  345. package/dist/types/src/internal/types/version.d.ts.map +1 -0
  346. package/dist/types/src/{test → testing}/api.test.d.ts.map +1 -1
  347. package/dist/types/src/testing/index.d.ts +3 -1
  348. package/dist/types/src/testing/index.d.ts.map +1 -1
  349. package/dist/types/src/testing/test-data.d.ts +18 -0
  350. package/dist/types/src/testing/test-data.d.ts.map +1 -0
  351. package/dist/types/src/testing/test-schema.d.ts +407 -0
  352. package/dist/types/src/testing/test-schema.d.ts.map +1 -0
  353. package/dist/types/src/testing/util.d.ts +16 -0
  354. package/dist/types/src/testing/util.d.ts.map +1 -0
  355. package/dist/types/tsconfig.tsbuildinfo +1 -1
  356. package/package.json +164 -33
  357. package/src/Annotation.ts +17 -0
  358. package/src/Database.ts +308 -0
  359. package/src/Entity.ts +51 -0
  360. package/src/Err.ts +18 -0
  361. package/src/Filter.ts +376 -0
  362. package/src/Format.ts +9 -0
  363. package/src/Hypergraph.ts +74 -0
  364. package/src/JsonSchema.ts +16 -0
  365. package/src/Key.ts +3 -0
  366. package/src/Obj.ts +407 -71
  367. package/src/Order.ts +34 -0
  368. package/src/Query.test.ts +346 -0
  369. package/src/Query.ts +279 -0
  370. package/src/QueryResult.ts +109 -0
  371. package/src/Ref.ts +25 -9
  372. package/src/Relation.ts +72 -46
  373. package/src/SchemaRegistry.ts +92 -0
  374. package/src/Tag.ts +40 -0
  375. package/src/Type.ts +98 -84
  376. package/src/index.ts +17 -4
  377. package/src/internal/README.md +87 -0
  378. package/src/internal/annotations/annotations.test.ts +96 -0
  379. package/src/internal/annotations/annotations.ts +488 -0
  380. package/src/internal/annotations/index.ts +6 -0
  381. package/src/internal/annotations/util.ts +72 -0
  382. package/src/internal/entities/entity.ts +109 -0
  383. package/src/internal/entities/expando.ts +23 -0
  384. package/src/internal/entities/index.ts +9 -0
  385. package/src/internal/entities/model.ts +129 -0
  386. package/src/internal/entities/object.ts +45 -0
  387. package/src/internal/entities/relation.ts +155 -0
  388. package/src/internal/entities/util.ts +33 -0
  389. package/src/internal/formats/date.test.ts +56 -0
  390. package/src/internal/formats/date.ts +217 -0
  391. package/src/internal/formats/format.test.ts +77 -0
  392. package/src/internal/formats/format.ts +54 -0
  393. package/src/internal/formats/index.ts +12 -0
  394. package/src/internal/formats/number.ts +89 -0
  395. package/src/internal/formats/object.ts +80 -0
  396. package/src/internal/formats/select.ts +18 -0
  397. package/src/internal/formats/string.ts +81 -0
  398. package/src/internal/formats/types.ts +186 -0
  399. package/src/internal/index.ts +38 -0
  400. package/src/internal/json-schema/annotations.ts +50 -0
  401. package/src/internal/json-schema/effect-schema.test.ts +143 -0
  402. package/src/internal/json-schema/index.ts +8 -0
  403. package/src/internal/json-schema/json-schema-normalize.ts +109 -0
  404. package/src/internal/json-schema/json-schema-type.ts +404 -0
  405. package/src/internal/json-schema/json-schema.test.ts +861 -0
  406. package/src/internal/json-schema/json-schema.ts +528 -0
  407. package/src/internal/object/common.ts +75 -0
  408. package/src/internal/object/create-object.test.ts +116 -0
  409. package/src/internal/object/create-object.ts +95 -0
  410. package/src/internal/object/deleted.ts +19 -0
  411. package/src/internal/object/ids.ts +12 -0
  412. package/src/internal/object/index.ts +11 -0
  413. package/src/internal/object/inspect.ts +46 -0
  414. package/src/internal/object/json-serializer.test.ts +94 -0
  415. package/src/internal/object/json-serializer.ts +230 -0
  416. package/src/internal/object/schema-validator.test.ts +186 -0
  417. package/src/internal/object/schema-validator.ts +244 -0
  418. package/src/internal/object/typed-object.test.ts +34 -0
  419. package/src/internal/object/typed-object.ts +94 -0
  420. package/src/internal/proxy/handler.test.ts +173 -0
  421. package/src/internal/proxy/index.ts +6 -0
  422. package/src/internal/proxy/make-object.ts +113 -0
  423. package/src/internal/proxy/schema.test.ts +137 -0
  424. package/src/internal/proxy/typed-handler.test.ts +102 -0
  425. package/src/internal/proxy/typed-handler.ts +233 -0
  426. package/src/internal/proxy/typed-object.test.ts +105 -0
  427. package/src/internal/ref/index.ts +6 -0
  428. package/src/internal/ref/ref-array.ts +39 -0
  429. package/src/internal/ref/ref.test.ts +101 -0
  430. package/src/internal/ref/ref.ts +525 -0
  431. package/src/internal/schema/compose.test.ts +42 -0
  432. package/src/internal/schema/compose.ts +37 -0
  433. package/src/internal/schema/echo-schema.ts +385 -0
  434. package/src/internal/schema/index.ts +8 -0
  435. package/src/internal/schema/manipulation.ts +92 -0
  436. package/src/internal/schema/persistent-schema.ts +28 -0
  437. package/src/internal/schema/snapshot.ts +25 -0
  438. package/src/internal/types/base.ts +57 -0
  439. package/src/internal/types/entity.ts +23 -0
  440. package/src/internal/types/index.ts +9 -0
  441. package/src/internal/types/meta.ts +76 -0
  442. package/src/internal/types/typename.ts +45 -0
  443. package/src/internal/types/version.ts +20 -0
  444. package/src/testing/api.test.ts +100 -0
  445. package/src/testing/index.ts +3 -1
  446. package/src/testing/test-data.ts +130 -0
  447. package/src/testing/test-schema.ts +224 -0
  448. package/src/testing/util.ts +78 -0
  449. package/dist/lib/browser/chunk-EUA7CM23.mjs +0 -619
  450. package/dist/lib/browser/chunk-EUA7CM23.mjs.map +0 -7
  451. package/dist/lib/node-esm/chunk-IV6BWGHK.mjs +0 -619
  452. package/dist/lib/node-esm/chunk-IV6BWGHK.mjs.map +0 -7
  453. package/dist/types/src/experimental/database.d.ts +0 -8
  454. package/dist/types/src/experimental/database.d.ts.map +0 -1
  455. package/dist/types/src/experimental/index.d.ts +0 -1
  456. package/dist/types/src/experimental/index.d.ts.map +0 -1
  457. package/dist/types/src/experimental/queue.d.ts +0 -8
  458. package/dist/types/src/experimental/queue.d.ts.map +0 -1
  459. package/dist/types/src/experimental/space.d.ts +0 -8
  460. package/dist/types/src/experimental/space.d.ts.map +0 -1
  461. package/dist/types/src/query/dsl.d.ts +0 -218
  462. package/dist/types/src/query/dsl.d.ts.map +0 -1
  463. package/dist/types/src/query/dsl.test.d.ts +0 -2
  464. package/dist/types/src/query/dsl.test.d.ts.map +0 -1
  465. package/dist/types/src/query/index.d.ts +0 -2
  466. package/dist/types/src/query/index.d.ts.map +0 -1
  467. package/dist/types/src/testing/types.d.ts +0 -113
  468. package/dist/types/src/testing/types.d.ts.map +0 -1
  469. package/src/experimental/database.ts +0 -11
  470. package/src/experimental/index.ts +0 -7
  471. package/src/experimental/queue.ts +0 -11
  472. package/src/experimental/space.ts +0 -11
  473. package/src/query/dsl.test.ts +0 -323
  474. package/src/query/dsl.ts +0 -646
  475. package/src/query/index.ts +0 -5
  476. package/src/test/api.test.ts +0 -173
  477. package/src/testing/types.ts +0 -91
  478. /package/dist/types/src/{test → testing}/api.test.d.ts +0 -0
@@ -0,0 +1,116 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { inspect } from 'util';
6
+
7
+ import * as Schema from 'effect/Schema';
8
+ import { describe, expect, test } from 'vitest';
9
+
10
+ import { DXN } from '@dxos/keys';
11
+
12
+ import { Relation } from '../../index';
13
+ import { TestSchema } from '../../testing';
14
+ import { getSchemaDXN, getTypeDXN, isInstanceOf } from '../annotations';
15
+ import { ATTR_RELATION_SOURCE, ATTR_RELATION_TARGET } from '../entities';
16
+ import { ATTR_META, ATTR_TYPE, getSchema } from '../types';
17
+
18
+ import { createObject } from './create-object';
19
+ import { objectToJSON } from './json-serializer';
20
+
21
+ describe('create (static version)', () => {
22
+ test('defaults', ({ expect }) => {
23
+ const Contact = Schema.Struct({
24
+ name: Schema.String.pipe(
25
+ Schema.optional,
26
+ Schema.withConstructorDefault(() => 'Anonymous'),
27
+ ),
28
+ email: Schema.String.pipe(Schema.optional),
29
+ });
30
+
31
+ const obj = Contact.make({});
32
+ expect(obj.name).toBe('Anonymous');
33
+ });
34
+
35
+ test('create static object', () => {
36
+ const contact = createObject(TestSchema.Person, {
37
+ name: 'Bot',
38
+ email: 'bot@example.com',
39
+ });
40
+
41
+ expect(contact.id).toBeDefined();
42
+ expect(contact.name).toBe('Bot');
43
+ expect(contact.email).toBe('bot@example.com');
44
+ expect((contact as any)['@type']).toBeUndefined();
45
+ expect(getTypeDXN(contact)?.toString()).toBe(getSchemaDXN(TestSchema.Person)!.toString());
46
+ expect(isInstanceOf(TestSchema.Person, contact)).toBe(true);
47
+ });
48
+
49
+ test('JSON encoding', () => {
50
+ const contact = createObject(TestSchema.Person, {
51
+ name: 'Bot',
52
+ email: 'bot@example.com',
53
+ });
54
+
55
+ const json = JSON.parse(JSON.stringify(contact));
56
+ expect(json).toEqual({
57
+ id: contact.id,
58
+ '@type': DXN.fromTypenameAndVersion(TestSchema.Person.typename, TestSchema.Person.version).toString(),
59
+ '@meta': {
60
+ keys: [],
61
+ },
62
+ name: 'Bot',
63
+ email: 'bot@example.com',
64
+ });
65
+ expect(objectToJSON(contact)).toStrictEqual(json);
66
+ });
67
+
68
+ test('JSON encoding with relation', () => {
69
+ const person1 = createObject(TestSchema.Person, {
70
+ name: 'Alice',
71
+ email: 'alice@example.com',
72
+ });
73
+ const person2 = createObject(TestSchema.Person, {
74
+ name: 'Bob',
75
+ email: 'bob@example.com',
76
+ });
77
+
78
+ const manager = createObject(TestSchema.HasManager, {
79
+ [Relation.Source]: person1 as any,
80
+ [Relation.Target]: person2 as any,
81
+ });
82
+
83
+ const json = JSON.parse(JSON.stringify(manager));
84
+ expect(json).toEqual({
85
+ id: manager.id,
86
+ [ATTR_TYPE]: DXN.fromTypenameAndVersion(TestSchema.HasManager.typename, TestSchema.HasManager.version).toString(),
87
+ [ATTR_RELATION_SOURCE]: DXN.fromLocalObjectId(person1.id).toString(),
88
+ [ATTR_RELATION_TARGET]: DXN.fromLocalObjectId(person2.id).toString(),
89
+ [ATTR_META]: {
90
+ keys: [],
91
+ },
92
+ });
93
+ });
94
+
95
+ test('getSchema', () => {
96
+ const contact = createObject(TestSchema.Person, {
97
+ name: 'Bot',
98
+ email: 'bot@example.com',
99
+ });
100
+
101
+ expect(getSchema(contact)).toBe(TestSchema.Person);
102
+ });
103
+
104
+ test('inspect', () => {
105
+ const contact = createObject(TestSchema.Person, {
106
+ name: 'Bot',
107
+ email: 'bot@example.com',
108
+ });
109
+
110
+ const text = inspect(contact);
111
+ expect(text).toContain('Bot');
112
+ expect(text).toContain('bot@example.com');
113
+ expect(text).toContain('example.com/type/Person');
114
+ expect(text).toContain('0.1.0');
115
+ });
116
+ });
@@ -0,0 +1,95 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import type * as Schema from 'effect/Schema';
6
+
7
+ import { raise } from '@dxos/debug';
8
+ import { assertArgument, failedInvariant } from '@dxos/invariant';
9
+ import { ObjectId } from '@dxos/keys';
10
+ import { defineHiddenProperty } from '@dxos/live-object';
11
+
12
+ import { getSchemaDXN, getTypeAnnotation, setTypename } from '../annotations';
13
+ import {
14
+ RelationSourceDXNId,
15
+ RelationSourceId,
16
+ RelationTargetDXNId,
17
+ RelationTargetId,
18
+ assertObjectModel,
19
+ getObjectDXN,
20
+ } from '../entities';
21
+ import { EntityKind, KindId, MetaId, setSchema } from '../types';
22
+
23
+ import { attachedTypedObjectInspector } from './inspect';
24
+ import { attachTypedJsonSerializer } from './json-serializer';
25
+
26
+ export type CreateObjectProps<T> = T extends { id: string } ? Omit<T, 'id' | KindId> & { id?: string } : T;
27
+
28
+ /**
29
+ * Creates a new object instance from a schema and data, without signal reactivity.
30
+ * This static version creates plain JavaScript objects that are not reactive/observable.
31
+ * For reactive objects that automatically update UI when changed, use the regular live() function.
32
+ *
33
+ * @param schema - The Effect schema that defines the object's structure and type, piped into EchoObjectSchema
34
+ * @param data - The data to initialize the object with. The id and @type fields are handled automatically.
35
+ * @returns A new non-reactive object instance conforming to the schema
36
+ * @throws {Error} If the schema is not an object schema
37
+ * @throws {TypeError} If data contains an @type field
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const Contact = Schema.Struct({
42
+ * name: Schema.String,
43
+ * email: Schema.String,
44
+ * }).pipe(Type.Obj({
45
+ * typename: 'example.com/type/Person',
46
+ * version: '0.1.0',
47
+ * }))
48
+ *
49
+ * const contact = createObject(Contact, {
50
+ * name: "John",
51
+ * email: "john@example.com",
52
+ * })
53
+ * ```
54
+ */
55
+ // TODO(burdon): Make internal.
56
+ export const createObject = <S extends Schema.Schema.AnyNoContext>(
57
+ schema: S,
58
+ props: CreateObjectProps<Schema.Schema.Type<S>>,
59
+ ): CreateObjectProps<Schema.Schema.Type<S>> & { id: string; [KindId]: EntityKind } => {
60
+ const annotation = getTypeAnnotation(schema);
61
+ if (!annotation) {
62
+ throw new Error('Schema is not an ECHO schema');
63
+ }
64
+ assertArgument(!('@type' in props), 'data', '@type is not allowed');
65
+ assertArgument(!(RelationSourceDXNId in props), 'data', 'Relation source DXN is not allowed in the constructor');
66
+ assertArgument(!(RelationTargetDXNId in props), 'data', 'Relation target DXN is not allowed in the constructor');
67
+ assertArgument(
68
+ RelationSourceId in props === RelationTargetId in props,
69
+ 'data',
70
+ 'Relation source and target must be provided together',
71
+ );
72
+
73
+ // Raw object.
74
+ const obj = { ...props, id: props.id ?? ObjectId.random() };
75
+
76
+ // Metadata.
77
+ const kind = RelationSourceId in props ? EntityKind.Relation : EntityKind.Object;
78
+ defineHiddenProperty(obj, KindId, kind);
79
+ defineHiddenProperty(obj, MetaId, { keys: [] });
80
+ setSchema(obj, schema);
81
+ setTypename(obj, getSchemaDXN(schema) ?? failedInvariant('Missing schema DXN'));
82
+ attachTypedJsonSerializer(obj);
83
+ attachedTypedObjectInspector(obj);
84
+
85
+ // Relation.
86
+ if (kind === EntityKind.Relation) {
87
+ const sourceDXN = getObjectDXN(props[RelationSourceId]) ?? raise(new Error('Unresolved relation source'));
88
+ const targetDXN = getObjectDXN(props[RelationTargetId]) ?? raise(new Error('Unresolved relation target'));
89
+ defineHiddenProperty(obj, RelationSourceDXNId, sourceDXN);
90
+ defineHiddenProperty(obj, RelationTargetDXNId, targetDXN);
91
+ }
92
+
93
+ assertObjectModel(obj);
94
+ return obj;
95
+ };
@@ -0,0 +1,19 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ObjectDeletedId } from '../entities';
6
+ import { type AnyProperties } from '../types';
7
+
8
+ /**
9
+ * @returns `true` if the object has been marked as deleted.
10
+ */
11
+ export const isDeleted = (obj: AnyProperties): boolean => {
12
+ if ((obj as any)[ObjectDeletedId] === undefined) {
13
+ // TODO(dmaretskyi): Return to prior behavior of throwing.
14
+ // throw new Error('Object does not support deletion marker');
15
+ return false;
16
+ }
17
+
18
+ return (obj as any)[ObjectDeletedId] ?? false;
19
+ };
@@ -0,0 +1,12 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { DXN, ObjectId, QueueSubspaceTags, SpaceId } from '@dxos/keys';
6
+
7
+ /**
8
+ * @deprecated Use `db.queues.create()`
9
+ */
10
+ // TODO(burdon): Move to @dxos/keys.
11
+ export const createQueueDXN = (spaceId = SpaceId.random(), queueId = ObjectId.random()) =>
12
+ new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, spaceId, queueId]);
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './common';
6
+ export * from './create-object';
7
+ export * from './deleted';
8
+ export * from './ids';
9
+ export * from './json-serializer';
10
+ export * from './schema-validator';
11
+ export * from './typed-object';
@@ -0,0 +1,46 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import type { InspectOptionsStylized, inspect as inspectFn } from 'node:util';
6
+
7
+ import { type CustomInspectFunction, inspectCustom } from '@dxos/debug';
8
+
9
+ import { getTypeDXN } from '../annotations';
10
+ import { ATTR_META, ATTR_TYPE, type AnyEchoObject, MetaId } from '../types';
11
+
12
+ /*
13
+ * @internal
14
+ */
15
+ export const attachedTypedObjectInspector = (obj: any) => {
16
+ const descriptor = Object.getOwnPropertyDescriptor(obj, inspectCustom);
17
+ if (descriptor) {
18
+ return;
19
+ }
20
+
21
+ Object.defineProperty(obj, inspectCustom, {
22
+ value: typedObjectInspectFunction,
23
+ writable: false,
24
+ enumerable: false,
25
+ configurable: true,
26
+ });
27
+ };
28
+
29
+ // NOTE: KEEP as function.
30
+ const typedObjectInspectFunction: CustomInspectFunction<AnyEchoObject> = function (
31
+ this: AnyEchoObject,
32
+ depth: number,
33
+ options: InspectOptionsStylized,
34
+ inspect: typeof inspectFn,
35
+ ) {
36
+ const { id, ...props } = this;
37
+ return inspect(
38
+ {
39
+ id,
40
+ [ATTR_TYPE]: getTypeDXN(this),
41
+ ...props,
42
+ [ATTR_META]: (this as any)[MetaId], // TODO(dmaretskyi): Couldn't use getMeta since that throw's if the object has no meta.
43
+ },
44
+ options,
45
+ );
46
+ };
@@ -0,0 +1,94 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { DXN } from '@dxos/keys';
8
+
9
+ import { TestSchema } from '../../testing';
10
+ import { getSchemaDXN, getSchemaTypename, getTypeDXN, getTypename } from '../annotations';
11
+ import { RelationSourceId, RelationTargetId, getObjectDXN } from '../entities';
12
+ import { makeObject } from '../proxy';
13
+ import { Ref, StaticRefResolver } from '../ref';
14
+ import { ATTR_TYPE, EntityKind, KindId, MetaId, TypeId, getMeta, getSchema } from '../types';
15
+
16
+ import { createObject } from './create-object';
17
+ import { objectFromJSON, objectToJSON } from './json-serializer';
18
+
19
+ describe('Object JSON serializer', () => {
20
+ test('should serialize and deserialize object', async () => {
21
+ const contact = makeObject(TestSchema.Person, { name: 'Alice' });
22
+ getMeta(contact).keys.push({ id: '12345', source: 'example.com' });
23
+
24
+ const task = createObject(TestSchema.Task, {
25
+ title: 'Fix the tests',
26
+ assignee: Ref.make(contact),
27
+ });
28
+
29
+ const contactJson = objectToJSON(contact);
30
+ const taskJson = objectToJSON(task);
31
+
32
+ expect(contactJson.id).toBe(contact.id);
33
+ expect(contactJson[ATTR_TYPE]).toEqual(getSchemaDXN(TestSchema.Person)!.toString());
34
+ expect(contactJson.name).toEqual('Alice');
35
+
36
+ expect(taskJson.id).toBe(task.id);
37
+ expect(taskJson[ATTR_TYPE]).toEqual(getSchemaDXN(TestSchema.Task)!.toString());
38
+ expect(taskJson.title).toEqual('Fix the tests');
39
+ expect(taskJson.assignee).toEqual({ '/': DXN.fromLocalObjectId(contact.id).toString() });
40
+
41
+ const refResolver = new StaticRefResolver()
42
+ .addSchema(TestSchema.Person)
43
+ .addSchema(TestSchema.Task)
44
+ .addObject(contact)
45
+ .addObject(task);
46
+
47
+ const contactFromJson = (await objectFromJSON(contactJson, { refResolver })) as TestSchema.Person;
48
+ const taskFromJson = (await objectFromJSON(taskJson, { refResolver })) as TestSchema.Task;
49
+
50
+ expect(contactFromJson.id).toBe(contact.id);
51
+ expect(contactFromJson.name).toBe('Alice');
52
+ expect((contactFromJson as any)[TypeId]).toEqual(getSchemaDXN(TestSchema.Person));
53
+ expect((contactFromJson as any)[KindId]).toBe(EntityKind.Object);
54
+ expect((contactFromJson as any)[RelationSourceId]).toBeUndefined();
55
+ expect((contactFromJson as any)[RelationTargetId]).toBeUndefined();
56
+ expect((contactFromJson as any)[MetaId]).toEqual({
57
+ keys: [
58
+ {
59
+ id: '12345',
60
+ source: 'example.com',
61
+ },
62
+ ],
63
+ });
64
+ expect(getTypeDXN(contactFromJson)?.toString()).toBe(getSchemaDXN(TestSchema.Person)!.toString());
65
+ expect(getTypename(contactFromJson)).toBe(getSchemaTypename(TestSchema.Person));
66
+ expect(getObjectDXN(contactFromJson)?.toString()).toEqual(getObjectDXN(contact)?.toString());
67
+ expect(getSchema(contactFromJson)).toEqual(TestSchema.Person);
68
+
69
+ expect(taskFromJson.id).toBe(task.id);
70
+ expect(taskFromJson.title).toBe('Fix the tests');
71
+ expect(taskFromJson.assignee!.dxn).toEqual(DXN.fromLocalObjectId(contact.id));
72
+ expect(taskFromJson.assignee!.target).toEqual(contact);
73
+ expect(await taskFromJson.assignee!.load()).toEqual(contact);
74
+ expect((taskFromJson as any)[TypeId]).toEqual(getSchemaDXN(TestSchema.Task));
75
+ expect((taskFromJson as any)[KindId]).toBe(EntityKind.Object);
76
+ expect((taskFromJson as any)[RelationSourceId]).toBeUndefined();
77
+ expect((taskFromJson as any)[RelationTargetId]).toBeUndefined();
78
+ expect((taskFromJson as any)[MetaId]).toEqual({ keys: [] });
79
+ expect(getSchema(taskFromJson)).toEqual(TestSchema.Task);
80
+ });
81
+
82
+ test('serialize with unresolved schema', async () => {
83
+ const contact = createObject(TestSchema.Person, { name: 'Alice' });
84
+ const contactJson = objectToJSON(contact);
85
+ const contactFromJson: any = await objectFromJSON(contactJson);
86
+
87
+ expect(contactFromJson.id).toBe(contact.id);
88
+ expect(contactFromJson.name).toBe('Alice');
89
+ expect(getSchema(contactFromJson)).toBeUndefined();
90
+ expect(getTypename(contactFromJson)).toEqual(getSchemaTypename(TestSchema.Person));
91
+ expect(getObjectDXN(contactFromJson)).toEqual(getObjectDXN(contact));
92
+ expect(getTypeDXN(contactFromJson)).toEqual(getSchemaDXN(TestSchema.Person));
93
+ });
94
+ });
@@ -0,0 +1,230 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { raise } from '@dxos/debug';
8
+ import { type EncodedReference, type ObjectMeta, isEncodedReference } from '@dxos/echo-protocol';
9
+ import { assertArgument, invariant } from '@dxos/invariant';
10
+ import { DXN, ObjectId } from '@dxos/keys';
11
+ import { defineHiddenProperty } from '@dxos/live-object';
12
+ import { assumeType, deepMapValues, visitValues } from '@dxos/util';
13
+
14
+ import { getTypeDXN, setTypename } from '../annotations';
15
+ import {
16
+ ATTR_DELETED,
17
+ ATTR_RELATION_SOURCE,
18
+ ATTR_RELATION_TARGET,
19
+ ATTR_SELF_DXN,
20
+ type ObjectJSON,
21
+ RelationSourceDXNId,
22
+ RelationSourceId,
23
+ RelationTargetDXNId,
24
+ RelationTargetId,
25
+ SelfDXNId,
26
+ assertObjectModel,
27
+ } from '../entities';
28
+ import { Ref, type RefResolver, refFromEncodedReference, setRefResolver } from '../ref';
29
+ import {
30
+ ATTR_META,
31
+ ATTR_TYPE,
32
+ type AnyEchoObject,
33
+ EntityKind,
34
+ KindId,
35
+ MetaId,
36
+ ObjectMetaSchema,
37
+ TypeId,
38
+ setSchema,
39
+ } from '../types';
40
+
41
+ type DeepReplaceRef<T> =
42
+ T extends Ref<any>
43
+ ? EncodedReference
44
+ : T extends object
45
+ ? {
46
+ [K in keyof T]: DeepReplaceRef<T[K]>;
47
+ }
48
+ : T;
49
+
50
+ type SerializedObject<T extends { id: string }> = {
51
+ [K in keyof T]: DeepReplaceRef<T[K]>;
52
+ } & ObjectJSON;
53
+
54
+ /**
55
+ * Converts object to it's JSON representation.
56
+ */
57
+ export const objectToJSON = <T extends AnyEchoObject>(obj: T): SerializedObject<T> => {
58
+ const typename = getTypeDXN(obj)?.toString();
59
+ invariant(typename && typeof typename === 'string');
60
+ return typedJsonSerializer.call(obj);
61
+ };
62
+
63
+ /**
64
+ * Creates an object from it's json representation.
65
+ * Performs schema validation.
66
+ * References and schema will be resolvable if the `refResolver` is provided.
67
+ * The function need to be async to support resolving the schema as well as the relation endpoints.
68
+ */
69
+ export const objectFromJSON = async (
70
+ jsonData: unknown,
71
+ { refResolver, dxn }: { refResolver?: RefResolver; dxn?: DXN } = {},
72
+ ): Promise<AnyEchoObject> => {
73
+ assumeType<ObjectJSON>(jsonData);
74
+ assertArgument(typeof jsonData === 'object' && jsonData !== null, 'jsonData', 'expect object');
75
+ assertArgument(typeof jsonData[ATTR_TYPE] === 'string', 'jsonData[ATTR_TYPE]', 'expected object to have a type');
76
+ assertArgument(typeof jsonData.id === 'string', 'jsonData.id', 'expected object to have an id');
77
+
78
+ const type = DXN.parse(jsonData[ATTR_TYPE]);
79
+ const schema = await refResolver?.resolveSchema(type);
80
+ invariant(schema === undefined || Schema.isSchema(schema));
81
+
82
+ let obj: any;
83
+ if (schema != null) {
84
+ obj = await schema.pipe(Schema.decodeUnknownPromise)(jsonData);
85
+ if (refResolver) {
86
+ setRefResolverOnData(obj, refResolver);
87
+ }
88
+ } else {
89
+ obj = decodeGeneric(jsonData, { refResolver });
90
+ }
91
+
92
+ invariant(ObjectId.isValid(obj.id), 'Invalid object id');
93
+ setTypename(obj, type);
94
+ if (schema) {
95
+ setSchema(obj, schema);
96
+ }
97
+
98
+ const isRelation =
99
+ typeof jsonData[ATTR_RELATION_SOURCE] === 'string' || typeof jsonData[ATTR_RELATION_TARGET] === 'string';
100
+ if (isRelation) {
101
+ const sourceDxn: DXN = DXN.parse(jsonData[ATTR_RELATION_SOURCE] ?? raise(new TypeError('Missing relation source')));
102
+ const targetDxn: DXN = DXN.parse(jsonData[ATTR_RELATION_TARGET] ?? raise(new TypeError('Missing relation target')));
103
+
104
+ const source = (await refResolver?.resolve(sourceDxn)) as AnyEchoObject | undefined;
105
+ const target = (await refResolver?.resolve(targetDxn)) as AnyEchoObject | undefined;
106
+
107
+ defineHiddenProperty(obj, KindId, EntityKind.Relation);
108
+ defineHiddenProperty(obj, RelationSourceDXNId, sourceDxn);
109
+ defineHiddenProperty(obj, RelationTargetDXNId, targetDxn);
110
+ defineHiddenProperty(obj, RelationSourceId, source);
111
+ defineHiddenProperty(obj, RelationTargetId, target);
112
+ } else {
113
+ defineHiddenProperty(obj, KindId, EntityKind.Object);
114
+ }
115
+
116
+ if (typeof jsonData[ATTR_META] === 'object') {
117
+ const meta = await ObjectMetaSchema.pipe(Schema.decodeUnknownPromise)(jsonData[ATTR_META]);
118
+ invariant(Array.isArray(meta.keys));
119
+ defineHiddenProperty(obj, MetaId, meta);
120
+ }
121
+
122
+ if (dxn) {
123
+ defineHiddenProperty(obj, SelfDXNId, dxn);
124
+ }
125
+
126
+ assertObjectModel(obj);
127
+ invariant((obj as any)[ATTR_TYPE] === undefined, 'Invalid object model');
128
+ invariant((obj as any)[ATTR_META] === undefined, 'Invalid object model');
129
+ invariant((obj as any)[ATTR_DELETED] === undefined, 'Invalid object model');
130
+ invariant((obj as any)[ATTR_SELF_DXN] === undefined, 'Invalid object model');
131
+ invariant((obj as any)[ATTR_RELATION_SOURCE] === undefined, 'Invalid object model');
132
+ invariant((obj as any)[ATTR_RELATION_TARGET] === undefined, 'Invalid object model');
133
+ return obj;
134
+ };
135
+
136
+ const decodeGeneric = (jsonData: unknown, options: { refResolver?: RefResolver }) => {
137
+ const {
138
+ [ATTR_TYPE]: _type,
139
+ [ATTR_META]: _meta,
140
+ [ATTR_DELETED]: _deleted,
141
+ [ATTR_SELF_DXN]: _selfDxn,
142
+ [ATTR_RELATION_SOURCE]: _relationSource,
143
+ [ATTR_RELATION_TARGET]: _relationTarget,
144
+ ...props
145
+ } = jsonData as any;
146
+
147
+ return deepMapValues(props, (value, visitor) => {
148
+ if (isEncodedReference(value)) {
149
+ return refFromEncodedReference(value, options.refResolver);
150
+ }
151
+
152
+ return visitor(value);
153
+ });
154
+ };
155
+
156
+ export const setRefResolverOnData = (obj: AnyEchoObject, refResolver: RefResolver) => {
157
+ const visitor = (value: unknown) => {
158
+ if (Ref.isRef(value)) {
159
+ setRefResolver(value, refResolver);
160
+ } else {
161
+ visitValues(value, visitor);
162
+ }
163
+ };
164
+
165
+ visitor(obj);
166
+ };
167
+
168
+ export const attachTypedJsonSerializer = (obj: any) => {
169
+ const descriptor = Object.getOwnPropertyDescriptor(obj, 'toJSON');
170
+ if (descriptor) {
171
+ return;
172
+ }
173
+
174
+ Object.defineProperty(obj, 'toJSON', {
175
+ value: typedJsonSerializer,
176
+ writable: false,
177
+ enumerable: false,
178
+ // Setting `configurable` to false breaks proxy invariants, should be fixable.
179
+ configurable: true,
180
+ });
181
+ };
182
+
183
+ // NOTE: KEEP as function.
184
+ const typedJsonSerializer = function (this: any) {
185
+ const { id, ...rest } = this;
186
+ const result: any = {
187
+ id,
188
+ };
189
+
190
+ if (this[TypeId]) {
191
+ result[ATTR_TYPE] = this[TypeId].toString();
192
+ }
193
+
194
+ if (this[MetaId]) {
195
+ result[ATTR_META] = serializeMeta(this[MetaId]);
196
+ }
197
+
198
+ if (this[SelfDXNId]) {
199
+ result[ATTR_SELF_DXN] = this[SelfDXNId].toString();
200
+ }
201
+
202
+ if (this[RelationSourceDXNId]) {
203
+ const sourceDXN = this[RelationSourceDXNId];
204
+ invariant(sourceDXN instanceof DXN);
205
+ result[ATTR_RELATION_SOURCE] = sourceDXN.toString();
206
+ }
207
+ if (this[RelationTargetDXNId]) {
208
+ const targetDXN = this[RelationTargetDXNId];
209
+ invariant(targetDXN instanceof DXN);
210
+ result[ATTR_RELATION_TARGET] = targetDXN.toString();
211
+ }
212
+
213
+ Object.assign(result, serializeData(rest));
214
+ return result;
215
+ };
216
+
217
+ const serializeData = (data: unknown) => {
218
+ return deepMapValues(data, (value, recurse) => {
219
+ if (Ref.isRef(value)) {
220
+ // TODO(dmaretskyi): Should this be configurable?
221
+ return value.noInline().encode();
222
+ }
223
+
224
+ return recurse(value);
225
+ });
226
+ };
227
+
228
+ const serializeMeta = (meta: ObjectMeta) => {
229
+ return deepMapValues(meta, (value, recurse) => recurse(value));
230
+ };