@dxos/echo 0.8.4-main.84f28bd → 0.8.4-main.937b3ca

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 (553) hide show
  1. package/README.md +2 -3
  2. package/dist/lib/browser/Annotation.mjs +33 -0
  3. package/dist/lib/browser/Annotation.mjs.map +7 -0
  4. package/dist/lib/browser/Database.mjs +18 -0
  5. package/dist/lib/browser/Database.mjs.map +7 -0
  6. package/dist/lib/browser/Entity.mjs +52 -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 +62 -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 +20 -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 +91 -0
  19. package/dist/lib/browser/Obj.mjs.map +7 -0
  20. package/dist/lib/browser/Order.mjs +13 -0
  21. package/dist/lib/browser/Order.mjs.map +7 -0
  22. package/dist/lib/browser/Query.mjs +27 -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 +23 -0
  27. package/dist/lib/browser/Ref.mjs.map +7 -0
  28. package/dist/lib/browser/Relation.mjs +85 -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 +26 -0
  33. package/dist/lib/browser/Tag.mjs.map +7 -0
  34. package/dist/lib/browser/Type.mjs +48 -0
  35. package/dist/lib/browser/Type.mjs.map +7 -0
  36. package/dist/lib/browser/chunk-22JMFST2.mjs +24 -0
  37. package/dist/lib/browser/chunk-22JMFST2.mjs.map +7 -0
  38. package/dist/lib/browser/chunk-2SBB7OWV.mjs +250 -0
  39. package/dist/lib/browser/chunk-2SBB7OWV.mjs.map +7 -0
  40. package/dist/lib/browser/chunk-6L5HHUVU.mjs +158 -0
  41. package/dist/lib/browser/chunk-6L5HHUVU.mjs.map +7 -0
  42. package/dist/lib/browser/chunk-7STIBCP7.mjs +133 -0
  43. package/dist/lib/browser/chunk-7STIBCP7.mjs.map +7 -0
  44. package/dist/lib/browser/chunk-BJPE6CIC.mjs +3847 -0
  45. package/dist/lib/browser/chunk-BJPE6CIC.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-CJ5YELTO.mjs +39 -0
  49. package/dist/lib/browser/chunk-CJ5YELTO.mjs.map +7 -0
  50. package/dist/lib/browser/chunk-FPOISFQK.mjs +40 -0
  51. package/dist/lib/browser/chunk-FPOISFQK.mjs.map +7 -0
  52. package/dist/lib/browser/chunk-FRDT7RA4.mjs +403 -0
  53. package/dist/lib/browser/chunk-FRDT7RA4.mjs.map +7 -0
  54. package/dist/lib/browser/chunk-INHXFXY5.mjs +22 -0
  55. package/dist/lib/browser/chunk-INHXFXY5.mjs.map +7 -0
  56. package/dist/lib/browser/chunk-IXVWLTG7.mjs +9 -0
  57. package/dist/lib/browser/chunk-IXVWLTG7.mjs.map +7 -0
  58. package/dist/lib/browser/chunk-JMKVF2YQ.mjs +43 -0
  59. package/dist/lib/browser/chunk-JMKVF2YQ.mjs.map +7 -0
  60. package/dist/lib/browser/chunk-KQQGVHFN.mjs +143 -0
  61. package/dist/lib/browser/chunk-KQQGVHFN.mjs.map +7 -0
  62. package/dist/lib/browser/chunk-MYCCGG2T.mjs +15 -0
  63. package/dist/lib/browser/chunk-MYCCGG2T.mjs.map +7 -0
  64. package/dist/lib/browser/chunk-NOPVNWPT.mjs +204 -0
  65. package/dist/lib/browser/chunk-NOPVNWPT.mjs.map +7 -0
  66. package/dist/lib/browser/chunk-PQZW3S6L.mjs +74 -0
  67. package/dist/lib/browser/chunk-PQZW3S6L.mjs.map +7 -0
  68. package/dist/lib/browser/chunk-RK4Z4JUZ.mjs +283 -0
  69. package/dist/lib/browser/chunk-RK4Z4JUZ.mjs.map +7 -0
  70. package/dist/lib/browser/chunk-U2J7TA7K.mjs +57 -0
  71. package/dist/lib/browser/chunk-U2J7TA7K.mjs.map +7 -0
  72. package/dist/lib/browser/chunk-W5D2GWAW.mjs +98 -0
  73. package/dist/lib/browser/chunk-W5D2GWAW.mjs.map +7 -0
  74. package/dist/lib/browser/chunk-XDIUHAAX.mjs +41 -0
  75. package/dist/lib/browser/chunk-XDIUHAAX.mjs.map +7 -0
  76. package/dist/lib/browser/chunk-YKTSSMDS.mjs +69 -0
  77. package/dist/lib/browser/chunk-YKTSSMDS.mjs.map +7 -0
  78. package/dist/lib/browser/chunk-ZAGAOZVY.mjs +288 -0
  79. package/dist/lib/browser/chunk-ZAGAOZVY.mjs.map +7 -0
  80. package/dist/lib/browser/chunk-ZHXZGIXD.mjs +9 -0
  81. package/dist/lib/browser/chunk-ZHXZGIXD.mjs.map +7 -0
  82. package/dist/lib/browser/index.mjs +72 -9
  83. package/dist/lib/browser/internal/index.mjs +457 -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 +332 -35
  87. package/dist/lib/browser/testing/index.mjs.map +4 -4
  88. package/dist/lib/node-esm/Annotation.mjs +33 -0
  89. package/dist/lib/node-esm/Annotation.mjs.map +7 -0
  90. package/dist/lib/node-esm/Database.mjs +18 -0
  91. package/dist/lib/node-esm/Database.mjs.map +7 -0
  92. package/dist/lib/node-esm/Entity.mjs +52 -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 +62 -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 +20 -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 +91 -0
  105. package/dist/lib/node-esm/Obj.mjs.map +7 -0
  106. package/dist/lib/node-esm/Order.mjs +13 -0
  107. package/dist/lib/node-esm/Order.mjs.map +7 -0
  108. package/dist/lib/node-esm/Query.mjs +27 -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 +23 -0
  113. package/dist/lib/node-esm/Ref.mjs.map +7 -0
  114. package/dist/lib/node-esm/Relation.mjs +85 -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 +26 -0
  119. package/dist/lib/node-esm/Tag.mjs.map +7 -0
  120. package/dist/lib/node-esm/Type.mjs +48 -0
  121. package/dist/lib/node-esm/Type.mjs.map +7 -0
  122. package/dist/lib/node-esm/chunk-4PNXQA64.mjs +250 -0
  123. package/dist/lib/node-esm/chunk-4PNXQA64.mjs.map +7 -0
  124. package/dist/lib/node-esm/chunk-5OBN7GZW.mjs +158 -0
  125. package/dist/lib/node-esm/chunk-5OBN7GZW.mjs.map +7 -0
  126. package/dist/lib/node-esm/chunk-AJEMYSIR.mjs +22 -0
  127. package/dist/lib/node-esm/chunk-AJEMYSIR.mjs.map +7 -0
  128. package/dist/lib/node-esm/chunk-ANLVLWME.mjs +98 -0
  129. package/dist/lib/node-esm/chunk-ANLVLWME.mjs.map +7 -0
  130. package/dist/lib/node-esm/chunk-DMR7OAFK.mjs +57 -0
  131. package/dist/lib/node-esm/chunk-DMR7OAFK.mjs.map +7 -0
  132. package/dist/lib/node-esm/chunk-FWTSPIFF.mjs +133 -0
  133. package/dist/lib/node-esm/chunk-FWTSPIFF.mjs.map +7 -0
  134. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  135. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  136. package/dist/lib/node-esm/chunk-ILMLLM4R.mjs +204 -0
  137. package/dist/lib/node-esm/chunk-ILMLLM4R.mjs.map +7 -0
  138. package/dist/lib/node-esm/chunk-K37NA7PO.mjs +43 -0
  139. package/dist/lib/node-esm/chunk-K37NA7PO.mjs.map +7 -0
  140. package/dist/lib/node-esm/chunk-LT3H4JOX.mjs +3847 -0
  141. package/dist/lib/node-esm/chunk-LT3H4JOX.mjs.map +7 -0
  142. package/dist/lib/node-esm/chunk-MOLNWFNL.mjs +9 -0
  143. package/dist/lib/node-esm/chunk-MOLNWFNL.mjs.map +7 -0
  144. package/dist/lib/node-esm/chunk-MOWUEW5P.mjs +15 -0
  145. package/dist/lib/node-esm/chunk-MOWUEW5P.mjs.map +7 -0
  146. package/dist/lib/node-esm/chunk-NBWL7UCZ.mjs +40 -0
  147. package/dist/lib/node-esm/chunk-NBWL7UCZ.mjs.map +7 -0
  148. package/dist/lib/node-esm/chunk-NRN3ZW2T.mjs +143 -0
  149. package/dist/lib/node-esm/chunk-NRN3ZW2T.mjs.map +7 -0
  150. package/dist/lib/node-esm/chunk-QLI2EIJ2.mjs +41 -0
  151. package/dist/lib/node-esm/chunk-QLI2EIJ2.mjs.map +7 -0
  152. package/dist/lib/node-esm/chunk-QYR67VBV.mjs +288 -0
  153. package/dist/lib/node-esm/chunk-QYR67VBV.mjs.map +7 -0
  154. package/dist/lib/node-esm/chunk-UKGVOINP.mjs +9 -0
  155. package/dist/lib/node-esm/chunk-UKGVOINP.mjs.map +7 -0
  156. package/dist/lib/node-esm/chunk-W6QIEBTQ.mjs +403 -0
  157. package/dist/lib/node-esm/chunk-W6QIEBTQ.mjs.map +7 -0
  158. package/dist/lib/node-esm/chunk-XHJRMQZD.mjs +69 -0
  159. package/dist/lib/node-esm/chunk-XHJRMQZD.mjs.map +7 -0
  160. package/dist/lib/node-esm/chunk-Y75VU7LB.mjs +74 -0
  161. package/dist/lib/node-esm/chunk-Y75VU7LB.mjs.map +7 -0
  162. package/dist/lib/node-esm/chunk-YOLH5KS4.mjs +283 -0
  163. package/dist/lib/node-esm/chunk-YOLH5KS4.mjs.map +7 -0
  164. package/dist/lib/node-esm/chunk-YQ2NWGL5.mjs +39 -0
  165. package/dist/lib/node-esm/chunk-YQ2NWGL5.mjs.map +7 -0
  166. package/dist/lib/node-esm/chunk-ZBB67AKD.mjs +24 -0
  167. package/dist/lib/node-esm/chunk-ZBB67AKD.mjs.map +7 -0
  168. package/dist/lib/node-esm/index.mjs +72 -9
  169. package/dist/lib/node-esm/internal/index.mjs +457 -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 +332 -35
  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 +194 -0
  177. package/dist/types/src/Database.d.ts.map +1 -0
  178. package/dist/types/src/Entity.d.ts +142 -0
  179. package/dist/types/src/Entity.d.ts.map +1 -0
  180. package/dist/types/src/Entity.test.d.ts +2 -0
  181. package/dist/types/src/Entity.test.d.ts.map +1 -0
  182. package/dist/types/src/Err.d.ts +64 -0
  183. package/dist/types/src/Err.d.ts.map +1 -0
  184. package/dist/types/src/Filter.d.ts +120 -0
  185. package/dist/types/src/Filter.d.ts.map +1 -0
  186. package/dist/types/src/Format.d.ts +4 -0
  187. package/dist/types/src/Format.d.ts.map +1 -0
  188. package/dist/types/src/Hypergraph.d.ts +60 -0
  189. package/dist/types/src/Hypergraph.d.ts.map +1 -0
  190. package/dist/types/src/JsonSchema.d.ts +9 -0
  191. package/dist/types/src/JsonSchema.d.ts.map +1 -0
  192. package/dist/types/src/Key.d.ts +1 -0
  193. package/dist/types/src/Key.d.ts.map +1 -1
  194. package/dist/types/src/Obj.d.ts +344 -34
  195. package/dist/types/src/Obj.d.ts.map +1 -1
  196. package/dist/types/src/Obj.test.d.ts +2 -0
  197. package/dist/types/src/Obj.test.d.ts.map +1 -0
  198. package/dist/types/src/Order.d.ts +16 -0
  199. package/dist/types/src/Order.d.ts.map +1 -0
  200. package/dist/types/src/Query.d.ts +115 -0
  201. package/dist/types/src/Query.d.ts.map +1 -0
  202. package/dist/types/src/Query.test.d.ts +2 -0
  203. package/dist/types/src/Query.test.d.ts.map +1 -0
  204. package/dist/types/src/QueryResult.d.ts +80 -0
  205. package/dist/types/src/QueryResult.d.ts.map +1 -0
  206. package/dist/types/src/Ref.d.ts +13 -11
  207. package/dist/types/src/Ref.d.ts.map +1 -1
  208. package/dist/types/src/Relation.d.ts +242 -19
  209. package/dist/types/src/Relation.d.ts.map +1 -1
  210. package/dist/types/src/Relation.test.d.ts +2 -0
  211. package/dist/types/src/Relation.test.d.ts.map +1 -0
  212. package/dist/types/src/SchemaRegistry.d.ts +84 -0
  213. package/dist/types/src/SchemaRegistry.d.ts.map +1 -0
  214. package/dist/types/src/Tag.d.ts +17 -0
  215. package/dist/types/src/Tag.d.ts.map +1 -0
  216. package/dist/types/src/Type.d.ts +225 -73
  217. package/dist/types/src/Type.d.ts.map +1 -1
  218. package/dist/types/src/Type.test.d.ts +2 -0
  219. package/dist/types/src/Type.test.d.ts.map +1 -0
  220. package/dist/types/src/index.d.ts +15 -3
  221. package/dist/types/src/index.d.ts.map +1 -1
  222. package/dist/types/src/internal/annotations/annotations.d.ts +170 -0
  223. package/dist/types/src/internal/annotations/annotations.d.ts.map +1 -0
  224. package/dist/types/src/internal/annotations/annotations.test.d.ts +2 -0
  225. package/dist/types/src/internal/annotations/annotations.test.d.ts.map +1 -0
  226. package/dist/types/src/internal/annotations/index.d.ts +3 -0
  227. package/dist/types/src/internal/annotations/index.d.ts.map +1 -0
  228. package/dist/types/src/internal/annotations/util.d.ts +27 -0
  229. package/dist/types/src/internal/annotations/util.d.ts.map +1 -0
  230. package/dist/types/src/internal/api/annotations.d.ts +23 -0
  231. package/dist/types/src/internal/api/annotations.d.ts.map +1 -0
  232. package/dist/types/src/internal/api/entity.d.ts +13 -0
  233. package/dist/types/src/internal/api/entity.d.ts.map +1 -0
  234. package/dist/types/src/internal/api/index.d.ts +15 -0
  235. package/dist/types/src/internal/api/index.d.ts.map +1 -0
  236. package/dist/types/src/internal/api/meta.d.ts +42 -0
  237. package/dist/types/src/internal/api/meta.d.ts.map +1 -0
  238. package/dist/types/src/internal/api/sorting.d.ts +24 -0
  239. package/dist/types/src/internal/api/sorting.d.ts.map +1 -0
  240. package/dist/types/src/internal/api/version.d.ts +42 -0
  241. package/dist/types/src/internal/api/version.d.ts.map +1 -0
  242. package/dist/types/src/internal/entities/entity.d.ts +20 -0
  243. package/dist/types/src/internal/entities/entity.d.ts.map +1 -0
  244. package/dist/types/src/internal/entities/index.d.ts +6 -0
  245. package/dist/types/src/internal/entities/index.d.ts.map +1 -0
  246. package/dist/types/src/internal/entities/model.d.ts +77 -0
  247. package/dist/types/src/internal/entities/model.d.ts.map +1 -0
  248. package/dist/types/src/internal/entities/object.d.ts +18 -0
  249. package/dist/types/src/internal/entities/object.d.ts.map +1 -0
  250. package/dist/types/src/internal/entities/relation.d.ts +62 -0
  251. package/dist/types/src/internal/entities/relation.d.ts.map +1 -0
  252. package/dist/types/src/internal/entities/util.d.ts +2 -0
  253. package/dist/types/src/internal/entities/util.d.ts.map +1 -0
  254. package/dist/types/src/internal/formats/date.d.ts +63 -0
  255. package/dist/types/src/internal/formats/date.d.ts.map +1 -0
  256. package/dist/types/src/internal/formats/date.test.d.ts +2 -0
  257. package/dist/types/src/internal/formats/date.test.d.ts.map +1 -0
  258. package/dist/types/src/internal/formats/format.d.ts +32 -0
  259. package/dist/types/src/internal/formats/format.d.ts.map +1 -0
  260. package/dist/types/src/internal/formats/format.test.d.ts +2 -0
  261. package/dist/types/src/internal/formats/format.test.d.ts.map +1 -0
  262. package/dist/types/src/internal/formats/index.d.ts +8 -0
  263. package/dist/types/src/internal/formats/index.d.ts.map +1 -0
  264. package/dist/types/src/internal/formats/number.d.ts +31 -0
  265. package/dist/types/src/internal/formats/number.d.ts.map +1 -0
  266. package/dist/types/src/internal/formats/object.d.ts +35 -0
  267. package/dist/types/src/internal/formats/object.d.ts.map +1 -0
  268. package/dist/types/src/internal/formats/select.d.ts +13 -0
  269. package/dist/types/src/internal/formats/select.d.ts.map +1 -0
  270. package/dist/types/src/internal/formats/string.d.ts +42 -0
  271. package/dist/types/src/internal/formats/string.d.ts.map +1 -0
  272. package/dist/types/src/internal/formats/types.d.ts +72 -0
  273. package/dist/types/src/internal/formats/types.d.ts.map +1 -0
  274. package/dist/types/src/internal/index.d.ts +12 -0
  275. package/dist/types/src/internal/index.d.ts.map +1 -0
  276. package/dist/types/src/internal/json-schema/annotations.d.ts +19 -0
  277. package/dist/types/src/internal/json-schema/annotations.d.ts.map +1 -0
  278. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts +2 -0
  279. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +1 -0
  280. package/dist/types/src/internal/json-schema/index.d.ts +5 -0
  281. package/dist/types/src/internal/json-schema/index.d.ts.map +1 -0
  282. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts +7 -0
  283. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +1 -0
  284. package/dist/types/src/internal/json-schema/json-schema-type.d.ts +250 -0
  285. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +1 -0
  286. package/dist/types/src/internal/json-schema/json-schema.d.ts +29 -0
  287. package/dist/types/src/internal/json-schema/json-schema.d.ts.map +1 -0
  288. package/dist/types/src/internal/json-schema/json-schema.test.d.ts +2 -0
  289. package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +1 -0
  290. package/dist/types/src/internal/object/clone.d.ts +8 -0
  291. package/dist/types/src/internal/object/clone.d.ts.map +1 -0
  292. package/dist/types/src/internal/object/common.d.ts +18 -0
  293. package/dist/types/src/internal/object/common.d.ts.map +1 -0
  294. package/dist/types/src/internal/object/create-object.d.ts +39 -0
  295. package/dist/types/src/internal/object/create-object.d.ts.map +1 -0
  296. package/dist/types/src/internal/object/create-object.test.d.ts +2 -0
  297. package/dist/types/src/internal/object/create-object.test.d.ts.map +1 -0
  298. package/dist/types/src/internal/object/deleted.d.ts +6 -0
  299. package/dist/types/src/internal/object/deleted.d.ts.map +1 -0
  300. package/dist/types/src/internal/object/ids.d.ts +6 -0
  301. package/dist/types/src/internal/object/ids.d.ts.map +1 -0
  302. package/dist/types/src/internal/object/index.d.ts +11 -0
  303. package/dist/types/src/internal/object/index.d.ts.map +1 -0
  304. package/dist/types/src/internal/object/inspect.d.ts +2 -0
  305. package/dist/types/src/internal/object/inspect.d.ts.map +1 -0
  306. package/dist/types/src/internal/object/json-serializer.d.ts +37 -0
  307. package/dist/types/src/internal/object/json-serializer.d.ts.map +1 -0
  308. package/dist/types/src/internal/object/json-serializer.test.d.ts +2 -0
  309. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +1 -0
  310. package/dist/types/src/internal/object/schema-validator.d.ts +2 -0
  311. package/dist/types/src/internal/object/schema-validator.d.ts.map +1 -0
  312. package/dist/types/src/internal/object/schema-validator.test.d.ts +2 -0
  313. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +1 -0
  314. package/dist/types/src/internal/object/set-value.d.ts +7 -0
  315. package/dist/types/src/internal/object/set-value.d.ts.map +1 -0
  316. package/dist/types/src/internal/object/set-value.test.d.ts +2 -0
  317. package/dist/types/src/internal/object/set-value.test.d.ts.map +1 -0
  318. package/dist/types/src/internal/object/snapshot.d.ts +6 -0
  319. package/dist/types/src/internal/object/snapshot.d.ts.map +1 -0
  320. package/dist/types/src/internal/object/typed-object.d.ts +25 -0
  321. package/dist/types/src/internal/object/typed-object.d.ts.map +1 -0
  322. package/dist/types/src/internal/object/typed-object.test.d.ts +2 -0
  323. package/dist/types/src/internal/object/typed-object.test.d.ts.map +1 -0
  324. package/dist/types/src/internal/proxy/change-context.d.ts +55 -0
  325. package/dist/types/src/internal/proxy/change-context.d.ts.map +1 -0
  326. package/dist/types/src/internal/proxy/change.test.d.ts +2 -0
  327. package/dist/types/src/internal/proxy/change.test.d.ts.map +1 -0
  328. package/dist/types/src/internal/proxy/define-hidden-property.d.ts +5 -0
  329. package/dist/types/src/internal/proxy/define-hidden-property.d.ts.map +1 -0
  330. package/dist/types/src/internal/proxy/errors.d.ts +19 -0
  331. package/dist/types/src/internal/proxy/errors.d.ts.map +1 -0
  332. package/dist/types/src/internal/proxy/event-batch.d.ts +10 -0
  333. package/dist/types/src/internal/proxy/event-batch.d.ts.map +1 -0
  334. package/dist/types/src/internal/proxy/handler.test.d.ts +2 -0
  335. package/dist/types/src/internal/proxy/handler.test.d.ts.map +1 -0
  336. package/dist/types/src/internal/proxy/index.d.ts +14 -0
  337. package/dist/types/src/internal/proxy/index.d.ts.map +1 -0
  338. package/dist/types/src/internal/proxy/json-serializer.d.ts +6 -0
  339. package/dist/types/src/internal/proxy/json-serializer.d.ts.map +1 -0
  340. package/dist/types/src/internal/proxy/make-object.d.ts +14 -0
  341. package/dist/types/src/internal/proxy/make-object.d.ts.map +1 -0
  342. package/dist/types/src/internal/proxy/ownership.d.ts +57 -0
  343. package/dist/types/src/internal/proxy/ownership.d.ts.map +1 -0
  344. package/dist/types/src/internal/proxy/proxy-types.d.ts +18 -0
  345. package/dist/types/src/internal/proxy/proxy-types.d.ts.map +1 -0
  346. package/dist/types/src/internal/proxy/proxy-utils.d.ts +47 -0
  347. package/dist/types/src/internal/proxy/proxy-utils.d.ts.map +1 -0
  348. package/dist/types/src/internal/proxy/reactive-array.d.ts +8 -0
  349. package/dist/types/src/internal/proxy/reactive-array.d.ts.map +1 -0
  350. package/dist/types/src/internal/proxy/reactive.d.ts +39 -0
  351. package/dist/types/src/internal/proxy/reactive.d.ts.map +1 -0
  352. package/dist/types/src/internal/proxy/schema-validator.d.ts +15 -0
  353. package/dist/types/src/internal/proxy/schema-validator.d.ts.map +1 -0
  354. package/dist/types/src/internal/proxy/schema.test.d.ts +2 -0
  355. package/dist/types/src/internal/proxy/schema.test.d.ts.map +1 -0
  356. package/dist/types/src/internal/proxy/symbols.d.ts +3 -0
  357. package/dist/types/src/internal/proxy/symbols.d.ts.map +1 -0
  358. package/dist/types/src/internal/proxy/typed-handler.d.ts +47 -0
  359. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +1 -0
  360. package/dist/types/src/internal/proxy/typed-handler.test.d.ts +2 -0
  361. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +1 -0
  362. package/dist/types/src/internal/proxy/typed-object.test.d.ts +2 -0
  363. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +1 -0
  364. package/dist/types/src/internal/ref/index.d.ts +3 -0
  365. package/dist/types/src/internal/ref/index.d.ts.map +1 -0
  366. package/dist/types/src/internal/ref/ref-array.d.ts +21 -0
  367. package/dist/types/src/internal/ref/ref-array.d.ts.map +1 -0
  368. package/dist/types/src/internal/ref/ref.d.ts +217 -0
  369. package/dist/types/src/internal/ref/ref.d.ts.map +1 -0
  370. package/dist/types/src/internal/ref/ref.test.d.ts +2 -0
  371. package/dist/types/src/internal/ref/ref.test.d.ts.map +1 -0
  372. package/dist/types/src/internal/schema/compose.d.ts +6 -0
  373. package/dist/types/src/internal/schema/compose.d.ts.map +1 -0
  374. package/dist/types/src/internal/schema/compose.test.d.ts +2 -0
  375. package/dist/types/src/internal/schema/compose.test.d.ts.map +1 -0
  376. package/dist/types/src/internal/schema/echo-schema.d.ts +180 -0
  377. package/dist/types/src/internal/schema/echo-schema.d.ts.map +1 -0
  378. package/dist/types/src/internal/schema/index.d.ts +4 -0
  379. package/dist/types/src/internal/schema/index.d.ts.map +1 -0
  380. package/dist/types/src/internal/schema/manipulation.d.ts +10 -0
  381. package/dist/types/src/internal/schema/manipulation.d.ts.map +1 -0
  382. package/dist/types/src/internal/schema/persistent-schema.d.ts +20 -0
  383. package/dist/types/src/internal/schema/persistent-schema.d.ts.map +1 -0
  384. package/dist/types/src/internal/types/base.d.ts +26 -0
  385. package/dist/types/src/internal/types/base.d.ts.map +1 -0
  386. package/dist/types/src/internal/types/entity.d.ts +37 -0
  387. package/dist/types/src/internal/types/entity.d.ts.map +1 -0
  388. package/dist/types/src/internal/types/index.d.ts +6 -0
  389. package/dist/types/src/internal/types/index.d.ts.map +1 -0
  390. package/dist/types/src/internal/types/meta.d.ts +32 -0
  391. package/dist/types/src/internal/types/meta.d.ts.map +1 -0
  392. package/dist/types/src/internal/types/typename.d.ts +13 -0
  393. package/dist/types/src/internal/types/typename.d.ts.map +1 -0
  394. package/dist/types/src/internal/types/version.d.ts +15 -0
  395. package/dist/types/src/internal/types/version.d.ts.map +1 -0
  396. package/dist/types/src/{test → testing}/api.test.d.ts.map +1 -1
  397. package/dist/types/src/testing/index.d.ts +3 -1
  398. package/dist/types/src/testing/index.d.ts.map +1 -1
  399. package/dist/types/src/testing/test-data.d.ts +18 -0
  400. package/dist/types/src/testing/test-data.d.ts.map +1 -0
  401. package/dist/types/src/testing/test-schema.d.ts +303 -0
  402. package/dist/types/src/testing/test-schema.d.ts.map +1 -0
  403. package/dist/types/src/testing/util.d.ts +21 -0
  404. package/dist/types/src/testing/util.d.ts.map +1 -0
  405. package/dist/types/tsconfig.tsbuildinfo +1 -1
  406. package/package.json +166 -33
  407. package/src/Annotation.ts +18 -0
  408. package/src/Database.ts +336 -0
  409. package/src/Entity.test.ts +22 -0
  410. package/src/Entity.ts +217 -0
  411. package/src/Err.ts +18 -0
  412. package/src/Filter.ts +376 -0
  413. package/src/Format.ts +9 -0
  414. package/src/Hypergraph.ts +74 -0
  415. package/src/JsonSchema.ts +16 -0
  416. package/src/Key.ts +3 -0
  417. package/src/Obj.test.ts +386 -0
  418. package/src/Obj.ts +509 -85
  419. package/src/Order.ts +44 -0
  420. package/src/Query.test.ts +465 -0
  421. package/src/Query.ts +296 -0
  422. package/src/QueryResult.ts +106 -0
  423. package/src/Ref.ts +25 -9
  424. package/src/Relation.test.ts +82 -0
  425. package/src/Relation.ts +414 -51
  426. package/src/SchemaRegistry.ts +105 -0
  427. package/src/Tag.ts +40 -0
  428. package/src/Type.test.ts +52 -0
  429. package/src/Type.ts +360 -112
  430. package/src/index.ts +17 -4
  431. package/src/internal/README.md +102 -0
  432. package/src/internal/annotations/annotations.test.ts +96 -0
  433. package/src/internal/annotations/annotations.ts +460 -0
  434. package/src/internal/annotations/index.ts +6 -0
  435. package/src/internal/annotations/util.ts +72 -0
  436. package/src/internal/api/annotations.ts +60 -0
  437. package/src/internal/api/entity.ts +29 -0
  438. package/src/internal/api/index.ts +19 -0
  439. package/src/internal/api/meta.ts +88 -0
  440. package/src/internal/api/sorting.ts +53 -0
  441. package/src/internal/api/version.ts +96 -0
  442. package/src/internal/entities/entity.ts +126 -0
  443. package/src/internal/entities/index.ts +9 -0
  444. package/src/internal/entities/model.ts +134 -0
  445. package/src/internal/entities/object.ts +60 -0
  446. package/src/internal/entities/relation.ts +173 -0
  447. package/src/internal/entities/util.ts +33 -0
  448. package/src/internal/formats/date.test.ts +56 -0
  449. package/src/internal/formats/date.ts +217 -0
  450. package/src/internal/formats/format.test.ts +77 -0
  451. package/src/internal/formats/format.ts +54 -0
  452. package/src/internal/formats/index.ts +12 -0
  453. package/src/internal/formats/number.ts +89 -0
  454. package/src/internal/formats/object.ts +80 -0
  455. package/src/internal/formats/select.ts +18 -0
  456. package/src/internal/formats/string.ts +81 -0
  457. package/src/internal/formats/types.ts +186 -0
  458. package/src/internal/index.ts +39 -0
  459. package/src/internal/json-schema/annotations.ts +50 -0
  460. package/src/internal/json-schema/effect-schema.test.ts +143 -0
  461. package/src/internal/json-schema/index.ts +8 -0
  462. package/src/internal/json-schema/json-schema-normalize.ts +109 -0
  463. package/src/internal/json-schema/json-schema-type.ts +404 -0
  464. package/src/internal/json-schema/json-schema.test.ts +861 -0
  465. package/src/internal/json-schema/json-schema.ts +528 -0
  466. package/src/internal/object/clone.ts +48 -0
  467. package/src/internal/object/common.ts +75 -0
  468. package/src/internal/object/create-object.test.ts +116 -0
  469. package/src/internal/object/create-object.ts +95 -0
  470. package/src/internal/object/deleted.ts +19 -0
  471. package/src/internal/object/ids.ts +12 -0
  472. package/src/internal/object/index.ts +14 -0
  473. package/src/internal/object/inspect.ts +46 -0
  474. package/src/internal/object/json-serializer.test.ts +97 -0
  475. package/src/internal/object/json-serializer.ts +188 -0
  476. package/src/internal/object/schema-validator.test.ts +186 -0
  477. package/src/internal/object/schema-validator.ts +6 -0
  478. package/src/internal/object/set-value.test.ts +281 -0
  479. package/src/internal/object/set-value.ts +165 -0
  480. package/src/internal/object/snapshot.ts +70 -0
  481. package/src/internal/object/typed-object.test.ts +34 -0
  482. package/src/internal/object/typed-object.ts +30 -0
  483. package/src/internal/proxy/change-context.ts +138 -0
  484. package/src/internal/proxy/change.test.ts +519 -0
  485. package/src/internal/proxy/define-hidden-property.ts +14 -0
  486. package/src/internal/proxy/errors.ts +42 -0
  487. package/src/internal/proxy/event-batch.ts +44 -0
  488. package/src/internal/proxy/handler.test.ts +123 -0
  489. package/src/internal/proxy/index.ts +17 -0
  490. package/src/internal/proxy/json-serializer.ts +87 -0
  491. package/src/internal/proxy/make-object.ts +96 -0
  492. package/src/internal/proxy/ownership.ts +253 -0
  493. package/src/internal/proxy/proxy-types.ts +23 -0
  494. package/src/internal/proxy/proxy-utils.ts +150 -0
  495. package/src/internal/proxy/reactive-array.ts +71 -0
  496. package/src/internal/proxy/reactive.ts +69 -0
  497. package/src/internal/proxy/schema-validator.ts +244 -0
  498. package/src/internal/proxy/schema.test.ts +145 -0
  499. package/src/internal/proxy/symbols.ts +7 -0
  500. package/src/internal/proxy/typed-handler.test.ts +318 -0
  501. package/src/internal/proxy/typed-handler.ts +442 -0
  502. package/src/internal/proxy/typed-object.test.ts +116 -0
  503. package/src/internal/ref/index.ts +6 -0
  504. package/src/internal/ref/ref-array.ts +39 -0
  505. package/src/internal/ref/ref.test.ts +101 -0
  506. package/src/internal/ref/ref.ts +548 -0
  507. package/src/internal/schema/compose.test.ts +42 -0
  508. package/src/internal/schema/compose.ts +36 -0
  509. package/src/internal/schema/echo-schema.ts +423 -0
  510. package/src/internal/schema/index.ts +7 -0
  511. package/src/internal/schema/manipulation.ts +92 -0
  512. package/src/internal/schema/persistent-schema.ts +27 -0
  513. package/src/internal/types/base.ts +43 -0
  514. package/src/internal/types/entity.ts +54 -0
  515. package/src/internal/types/index.ts +9 -0
  516. package/src/internal/types/meta.ts +66 -0
  517. package/src/internal/types/typename.ts +45 -0
  518. package/src/internal/types/version.ts +20 -0
  519. package/src/testing/api.test.ts +126 -0
  520. package/src/testing/index.ts +3 -1
  521. package/src/testing/test-data.ts +130 -0
  522. package/src/testing/test-schema.ts +238 -0
  523. package/src/testing/util.ts +85 -0
  524. package/dist/lib/browser/chunk-SVSJEELN.mjs +0 -619
  525. package/dist/lib/browser/chunk-SVSJEELN.mjs.map +0 -7
  526. package/dist/lib/node-esm/chunk-53HXWYR6.mjs +0 -619
  527. package/dist/lib/node-esm/chunk-53HXWYR6.mjs.map +0 -7
  528. package/dist/types/src/experimental/database.d.ts +0 -8
  529. package/dist/types/src/experimental/database.d.ts.map +0 -1
  530. package/dist/types/src/experimental/index.d.ts +0 -1
  531. package/dist/types/src/experimental/index.d.ts.map +0 -1
  532. package/dist/types/src/experimental/queue.d.ts +0 -8
  533. package/dist/types/src/experimental/queue.d.ts.map +0 -1
  534. package/dist/types/src/experimental/space.d.ts +0 -8
  535. package/dist/types/src/experimental/space.d.ts.map +0 -1
  536. package/dist/types/src/query/dsl.d.ts +0 -218
  537. package/dist/types/src/query/dsl.d.ts.map +0 -1
  538. package/dist/types/src/query/dsl.test.d.ts +0 -2
  539. package/dist/types/src/query/dsl.test.d.ts.map +0 -1
  540. package/dist/types/src/query/index.d.ts +0 -2
  541. package/dist/types/src/query/index.d.ts.map +0 -1
  542. package/dist/types/src/testing/types.d.ts +0 -113
  543. package/dist/types/src/testing/types.d.ts.map +0 -1
  544. package/src/experimental/database.ts +0 -11
  545. package/src/experimental/index.ts +0 -7
  546. package/src/experimental/queue.ts +0 -11
  547. package/src/experimental/space.ts +0 -11
  548. package/src/query/dsl.test.ts +0 -323
  549. package/src/query/dsl.ts +0 -646
  550. package/src/query/index.ts +0 -5
  551. package/src/test/api.test.ts +0 -173
  552. package/src/testing/types.ts +0 -91
  553. /package/dist/types/src/{test → testing}/api.test.d.ts +0 -0
@@ -0,0 +1,519 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import * as Obj from '../../Obj';
8
+ import * as Relation from '../../Relation';
9
+ import { TestSchema } from '../../testing';
10
+
11
+ /**
12
+ * Tests for Obj.change context enforcement and mutator type safety.
13
+ *
14
+ * These tests verify:
15
+ * 1. Mutator functions require Mutable<T> at compile-time.
16
+ * 2. getMeta returns ReadonlyMeta outside change callbacks and ObjectMeta inside.
17
+ * 3. Mutations outside Obj.change throw at runtime.
18
+ * 4. Nested object/property mutations work correctly.
19
+ * 5. Array mutations (push, pop, splice) require change context.
20
+ * 6. Property delete requires change context.
21
+ */
22
+ describe('Obj.change enforcement', () => {
23
+ describe('compile-time and runtime safety', () => {
24
+ test('direct property mutation outside change throws', ({ expect }) => {
25
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
26
+
27
+ // Direct property mutation should throw.
28
+ expect(() => {
29
+ // @ts-expect-error Testing runtime error for readonly property mutation.
30
+ obj.name = 'New Name';
31
+ }).toThrow(/outside of Obj.change/);
32
+ });
33
+
34
+ test('Obj.setValue outside change throws', ({ expect }) => {
35
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
36
+
37
+ // No compile-time error: TypeScript's structural typing allows readonly objects
38
+ // to be passed to Mutable<T> parameters. Enforcement is runtime-only.
39
+ expect(() => Obj.setValue(obj, ['name'], 'value')).toThrow(/outside of Obj.change/);
40
+ });
41
+
42
+ test('Obj.addTag outside change throws', ({ expect }) => {
43
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
44
+
45
+ // No compile-time error: TypeScript's structural typing allows readonly objects
46
+ // to be passed to Mutable<T> parameters. Enforcement is runtime-only.
47
+ expect(() => Obj.addTag(obj, 'tag')).toThrow(/outside of Obj.change/);
48
+ });
49
+
50
+ test('getMeta mutation outside change throws', ({ expect }) => {
51
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
52
+ const meta = Obj.getMeta(obj);
53
+
54
+ // Runtime errors for direct meta mutations.
55
+ expect(() => ((meta as any).keys = [])).toThrow(/outside of Obj.change/);
56
+ expect(() => ((meta as any).tags = ['tag'])).toThrow(/outside of Obj.change/);
57
+ });
58
+
59
+ test('getMeta returns mutable ObjectMeta inside change callback', ({ expect }) => {
60
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
61
+
62
+ Obj.change(obj, (mutableObj) => {
63
+ const meta = Obj.getMeta(mutableObj);
64
+
65
+ // These should compile without errors because meta is ObjectMeta (mutable).
66
+ meta.keys = [];
67
+ meta.tags = ['tag'];
68
+ meta.keys.push({ source: 'test', id: '123' });
69
+ });
70
+
71
+ expect(Obj.getMeta(obj).tags).toEqual(['tag']);
72
+ expect(Obj.getMeta(obj).keys).toHaveLength(1);
73
+ });
74
+
75
+ test('mutators work inside change callback', ({ expect }) => {
76
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
77
+
78
+ // These should compile without errors inside change callback.
79
+ Obj.change(obj, (mutableObj) => {
80
+ Obj.addTag(mutableObj, 'my-tag');
81
+ Obj.setValue(mutableObj, ['name'], 'Updated');
82
+ });
83
+
84
+ expect(obj.name).toBe('Updated');
85
+ expect(Obj.getMeta(obj).tags).toContain('my-tag');
86
+ });
87
+
88
+ test('Relation property mutation outside change throws', ({ expect }) => {
89
+ const source = Obj.make(TestSchema.Person, { name: 'Alice' });
90
+ const target = Obj.make(TestSchema.Person, { name: 'Bob' });
91
+ const rel = Relation.make(TestSchema.HasManager, {
92
+ [Relation.Source]: source,
93
+ [Relation.Target]: target,
94
+ });
95
+
96
+ // Direct property mutation should throw.
97
+ expect(() => {
98
+ // @ts-expect-error Testing runtime error for readonly property mutation.
99
+ rel.title = 'Manager';
100
+ }).toThrow(/outside of Obj.change/);
101
+ });
102
+
103
+ test('Relation.addTag outside change throws', ({ expect }) => {
104
+ const source = Obj.make(TestSchema.Person, { name: 'Alice' });
105
+ const target = Obj.make(TestSchema.Person, { name: 'Bob' });
106
+ const rel = Relation.make(TestSchema.HasManager, {
107
+ [Relation.Source]: source,
108
+ [Relation.Target]: target,
109
+ });
110
+
111
+ // No compile-time error: TypeScript's structural typing allows readonly objects
112
+ // to be passed to Mutable<T> parameters. Enforcement is runtime-only.
113
+ expect(() => Relation.addTag(rel, 'tag')).toThrow(/outside of Obj.change/);
114
+ });
115
+ });
116
+
117
+ describe('behavior', () => {
118
+ test('setLabel and getLabel work correctly with Person schema', ({ expect }) => {
119
+ // Person schema has name as the label field.
120
+ const obj = Obj.make(TestSchema.Person, { name: 'John' });
121
+
122
+ // Person schema uses 'name' as label field.
123
+ expect(Obj.getLabel(obj)).toBe('John');
124
+
125
+ Obj.change(obj, (o) => {
126
+ Obj.setLabel(o, 'Jane');
127
+ });
128
+
129
+ // setLabel updates the name field.
130
+ expect(Obj.getLabel(obj)).toBe('Jane');
131
+ expect(obj.name).toBe('Jane');
132
+ });
133
+
134
+ test('setDescription works on schemas with description annotation', ({ expect }) => {
135
+ // Person schema may not have a description field, but we can still test the API.
136
+ const obj = Obj.make(TestSchema.Person, { name: 'John' });
137
+
138
+ // Description is undefined if not set.
139
+ expect(Obj.getDescription(obj)).toBeUndefined();
140
+
141
+ // setDescription only works if schema has description annotation.
142
+ // For schemas without it, this is a no-op.
143
+ Obj.change(obj, (o) => {
144
+ Obj.setDescription(o, 'My Description');
145
+ });
146
+
147
+ // Verify setDescription doesn't throw.
148
+ expect(true).toBe(true);
149
+ });
150
+
151
+ test('addTag and removeTag work correctly', ({ expect }) => {
152
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
153
+
154
+ expect(Obj.getMeta(obj).tags).toBeUndefined();
155
+
156
+ Obj.change(obj, (o) => {
157
+ Obj.addTag(o, 'tag-1');
158
+ Obj.addTag(o, 'tag-2');
159
+ });
160
+
161
+ expect(Obj.getMeta(obj).tags).toEqual(['tag-1', 'tag-2']);
162
+
163
+ Obj.change(obj, (o) => {
164
+ Obj.removeTag(o, 'tag-1');
165
+ });
166
+
167
+ expect(Obj.getMeta(obj).tags).toEqual(['tag-2']);
168
+ });
169
+
170
+ test('deleteKeys removes foreign keys by source', ({ expect }) => {
171
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
172
+
173
+ Obj.change(obj, (o) => {
174
+ const meta = Obj.getMeta(o);
175
+ meta.keys.push({ source: 'source-a', id: '1' });
176
+ meta.keys.push({ source: 'source-a', id: '2' });
177
+ meta.keys.push({ source: 'source-b', id: '3' });
178
+ });
179
+
180
+ expect(Obj.getMeta(obj).keys).toHaveLength(3);
181
+
182
+ Obj.change(obj, (o) => {
183
+ Obj.deleteKeys(o, 'source-a');
184
+ });
185
+
186
+ expect(Obj.getMeta(obj).keys).toHaveLength(1);
187
+ expect(Obj.getMeta(obj).keys[0].source).toBe('source-b');
188
+ });
189
+
190
+ test('setValue sets nested properties', ({ expect }) => {
191
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
192
+
193
+ Obj.change(obj, (o) => {
194
+ Obj.setValue(o, ['name'], 'Updated Name');
195
+ });
196
+
197
+ expect(obj.name).toBe('Updated Name');
198
+ });
199
+
200
+ test('getMeta is mutable inside change and changes persist', ({ expect }) => {
201
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
202
+
203
+ Obj.change(obj, (o) => {
204
+ const meta = Obj.getMeta(o);
205
+ meta.tags = ['tag-1', 'tag-2'];
206
+ meta.keys.push({ source: 'external', id: '123' });
207
+ });
208
+
209
+ // Changes should persist after the change callback.
210
+ expect(Obj.getMeta(obj).tags).toEqual(['tag-1', 'tag-2']);
211
+ expect(Obj.getMeta(obj).keys).toEqual([{ source: 'external', id: '123' }]);
212
+ });
213
+
214
+ test('multiple mutations in single change all persist', ({ expect }) => {
215
+ const obj = Obj.make(TestSchema.Person, { name: 'Test' });
216
+
217
+ Obj.change(obj, (o) => {
218
+ o.name = 'Name 1';
219
+ o.name = 'Name 2';
220
+ o.name = 'Name 3';
221
+ Obj.addTag(o, 'tag-1');
222
+ Obj.addTag(o, 'tag-2');
223
+ });
224
+
225
+ // All mutations should persist.
226
+ expect(obj.name).toBe('Name 3');
227
+ expect(Obj.getMeta(obj).tags).toEqual(['tag-1', 'tag-2']);
228
+ });
229
+ });
230
+
231
+ describe('notifications', () => {
232
+ test('batched notifications - only one per Obj.change', ({ expect }) => {
233
+ const obj = Obj.make(TestSchema.Person, { name: 'John' });
234
+
235
+ let notificationCount = 0;
236
+ const unsubscribe = Obj.subscribe(obj, () => {
237
+ notificationCount++;
238
+ });
239
+
240
+ Obj.change(obj, (p) => {
241
+ p.name = 'Jane';
242
+ p.age = 30;
243
+ });
244
+
245
+ // Should only fire one notification for all changes.
246
+ expect(notificationCount).toBe(1);
247
+
248
+ unsubscribe();
249
+ });
250
+ });
251
+
252
+ describe('nested mutations', () => {
253
+ test('nested object property mutation within Obj.change', ({ expect }) => {
254
+ const obj = Obj.make(TestSchema.Person, {
255
+ name: 'John',
256
+ address: { city: 'NYC', coordinates: {} },
257
+ });
258
+
259
+ Obj.change(obj, (p) => {
260
+ p.address!.state = 'NY';
261
+ });
262
+
263
+ expect(obj.address?.state).toBe('NY');
264
+ expect(obj.address?.city).toBe('NYC');
265
+ });
266
+
267
+ test('deeply nested property mutation within Obj.change (2 levels)', ({ expect }) => {
268
+ const obj = Obj.make(TestSchema.Person, {
269
+ name: 'John',
270
+ address: { city: 'NYC', coordinates: { lat: 40.7128, lng: -74.006 } },
271
+ });
272
+
273
+ Obj.change(obj, (p) => {
274
+ p.address!.coordinates!.lat = 51.5074;
275
+ p.address!.coordinates!.lng = -0.1278;
276
+ });
277
+
278
+ expect(obj.address?.coordinates?.lat).toBe(51.5074);
279
+ expect(obj.address?.coordinates?.lng).toBe(-0.1278);
280
+ });
281
+
282
+ test('nested object mutation outside Obj.change throws (1 level deep)', ({ expect }) => {
283
+ const obj = Obj.make(TestSchema.Person, {
284
+ name: 'John',
285
+ address: { city: 'NYC', coordinates: {} },
286
+ });
287
+
288
+ expect(() => {
289
+ // @ts-expect-error - nested property assignment is readonly.
290
+ obj.address!.city = 'LA';
291
+ }).toThrow(/outside of Obj.change/);
292
+ });
293
+
294
+ test('deeply nested mutation outside Obj.change throws (2 levels deep)', ({ expect }) => {
295
+ const obj = Obj.make(TestSchema.Person, {
296
+ name: 'John',
297
+ address: { city: 'NYC', coordinates: { lat: 40.7128, lng: -74.006 } },
298
+ });
299
+
300
+ expect(() => {
301
+ // @ts-expect-error - deeply nested property assignment should be caught.
302
+ obj.address!.coordinates!.lat = 0;
303
+ }).toThrow(/outside of Obj.change/);
304
+ });
305
+
306
+ test('nested Obj.change calls work correctly', ({ expect }) => {
307
+ const obj = Obj.make(TestSchema.Person, { name: 'John' });
308
+
309
+ Obj.change(obj, (p) => {
310
+ p.name = 'Jane';
311
+
312
+ // Nested change should work (already in change context).
313
+ Obj.change(obj, (p2) => {
314
+ p2.age = 30;
315
+ });
316
+ });
317
+
318
+ expect(obj.name).toBe('Jane');
319
+ expect(obj.age).toBe(30);
320
+ });
321
+
322
+ test('error in callback does not leave object in broken state', ({ expect }) => {
323
+ const obj = Obj.make(TestSchema.Person, { name: 'John' });
324
+
325
+ expect(() => {
326
+ Obj.change(obj, (p) => {
327
+ p.name = 'Jane';
328
+ throw new Error('Test error');
329
+ });
330
+ }).toThrow('Test error');
331
+
332
+ // Object should still be readonly after error.
333
+ expect(() => {
334
+ // @ts-expect-error Testing runtime error for readonly property mutation.
335
+ obj.name = 'Bob';
336
+ }).toThrow(/outside of Obj.change/);
337
+ });
338
+ });
339
+
340
+ describe('array mutations', () => {
341
+ test('array push within Obj.change', ({ expect }) => {
342
+ const obj = Obj.make(TestSchema.Person, {
343
+ name: 'John',
344
+ fields: [{ label: 'tag1', value: 'val1' }],
345
+ });
346
+
347
+ Obj.change(obj, (p) => {
348
+ p.fields!.push({ label: 'tag2', value: 'val2' });
349
+ });
350
+
351
+ expect(obj.fields).toHaveLength(2);
352
+ expect(obj.fields![1].label).toBe('tag2');
353
+ });
354
+
355
+ test('array pop within Obj.change', ({ expect }) => {
356
+ const obj = Obj.make(TestSchema.Person, {
357
+ name: 'John',
358
+ fields: [
359
+ { label: 'a', value: '1' },
360
+ { label: 'b', value: '2' },
361
+ ],
362
+ });
363
+
364
+ let popped: any;
365
+ Obj.change(obj, (p) => {
366
+ popped = p.fields!.pop();
367
+ });
368
+
369
+ expect(popped.label).toBe('b');
370
+ expect(obj.fields).toHaveLength(1);
371
+ });
372
+
373
+ test('array splice within Obj.change', ({ expect }) => {
374
+ const obj = Obj.make(TestSchema.Person, {
375
+ name: 'John',
376
+ fields: [
377
+ { label: 'a', value: '1' },
378
+ { label: 'b', value: '2' },
379
+ { label: 'c', value: '3' },
380
+ ],
381
+ });
382
+
383
+ Obj.change(obj, (p) => {
384
+ p.fields!.splice(1, 1, { label: 'x', value: 'x' });
385
+ });
386
+
387
+ expect(obj.fields).toHaveLength(3);
388
+ expect(obj.fields![1].label).toBe('x');
389
+ });
390
+
391
+ test('array push outside Obj.change throws', ({ expect }) => {
392
+ const obj = Obj.make(TestSchema.Person, {
393
+ name: 'John',
394
+ fields: [{ label: 'tag1', value: 'val1' }],
395
+ });
396
+
397
+ expect(() => {
398
+ // @ts-expect-error Testing runtime error for readonly array mutation.
399
+ obj.fields!.push({ label: 'tag2', value: 'val2' });
400
+ }).toThrow(/array\.push\(\).*outside of Obj\.change/);
401
+ });
402
+
403
+ test('array pop outside Obj.change throws', ({ expect }) => {
404
+ const obj = Obj.make(TestSchema.Person, {
405
+ name: 'John',
406
+ fields: [{ label: 'tag1', value: 'val1' }],
407
+ });
408
+
409
+ expect(() => {
410
+ // @ts-expect-error Testing runtime error for readonly array mutation.
411
+ obj.fields!.pop();
412
+ }).toThrow(/array\.pop\(\).*outside of Obj\.change/);
413
+ });
414
+
415
+ test('array splice outside Obj.change throws', ({ expect }) => {
416
+ const obj = Obj.make(TestSchema.Person, {
417
+ name: 'John',
418
+ fields: [{ label: 'tag1', value: 'val1' }],
419
+ });
420
+
421
+ expect(() => {
422
+ // @ts-expect-error Testing runtime error for readonly array mutation.
423
+ obj.fields!.splice(0, 1);
424
+ }).toThrow(/array\.splice\(\).*outside of Obj\.change/);
425
+ });
426
+ });
427
+
428
+ describe('property delete', () => {
429
+ test('delete property within Obj.change', ({ expect }) => {
430
+ const obj = Obj.make(TestSchema.Person, { name: 'John', age: 25 });
431
+
432
+ Obj.change(obj, (p) => {
433
+ delete p.age;
434
+ });
435
+
436
+ expect(obj.age).toBeUndefined();
437
+ });
438
+
439
+ test('delete property outside Obj.change throws', ({ expect }) => {
440
+ const obj = Obj.make(TestSchema.Person, { name: 'John', age: 25 });
441
+
442
+ expect(() => {
443
+ // @ts-expect-error Testing runtime error for readonly property delete.
444
+ delete obj.age;
445
+ }).toThrow(/delete object property.*outside of Obj\.change/);
446
+ });
447
+ });
448
+
449
+ describe('Relation mutators', () => {
450
+ test('Relation.getMeta is mutable inside Relation.change', ({ expect }) => {
451
+ const source = Obj.make(TestSchema.Person, { name: 'Alice' });
452
+ const target = Obj.make(TestSchema.Person, { name: 'Bob' });
453
+ const rel = Relation.make(TestSchema.HasManager, {
454
+ [Relation.Source]: source,
455
+ [Relation.Target]: target,
456
+ });
457
+
458
+ Relation.change(rel, (r) => {
459
+ const meta = Relation.getMeta(r);
460
+ meta.tags = ['rel-tag'];
461
+ meta.keys.push({ source: 'rel-source', id: 'rel-key' });
462
+ });
463
+
464
+ expect(Relation.getMeta(rel).tags).toEqual(['rel-tag']);
465
+ expect(Relation.getMeta(rel).keys).toHaveLength(1);
466
+ });
467
+
468
+ test('Relation mutators work inside change callback', ({ expect }) => {
469
+ const source = Obj.make(TestSchema.Person, { name: 'Alice' });
470
+ const target = Obj.make(TestSchema.Person, { name: 'Bob' });
471
+ const rel = Relation.make(TestSchema.HasManager, {
472
+ [Relation.Source]: source,
473
+ [Relation.Target]: target,
474
+ });
475
+
476
+ Relation.change(rel, (r) => {
477
+ Relation.addTag(r, 'important');
478
+ });
479
+
480
+ expect(Relation.getMeta(rel).tags).toContain('important');
481
+
482
+ Relation.change(rel, (r) => {
483
+ Relation.removeTag(r, 'important');
484
+ });
485
+
486
+ expect(Relation.getMeta(rel).tags).not.toContain('important');
487
+ });
488
+ });
489
+
490
+ describe('object references', () => {
491
+ test('assigning root ECHO objects directly throws - must use Ref.make', ({ expect }) => {
492
+ const obj = Obj.make(TestSchema.Expando, {});
493
+ const other = Obj.make(TestSchema.Expando, { string: 'bar' });
494
+
495
+ // Direct assignment of root ECHO objects (created with Obj.make) is not allowed.
496
+ expect(() => {
497
+ Obj.change(obj, (o) => {
498
+ o.other = other;
499
+ });
500
+ }).toThrow(/Object references must be wrapped with `Ref\.make`/);
501
+ });
502
+
503
+ test('plain nested objects use parent change context', ({ expect }) => {
504
+ const obj = Obj.make(TestSchema.Expando, {});
505
+
506
+ // Assign a plain object (not created with Obj.make).
507
+ Obj.change(obj, (o) => {
508
+ o.nested = { value: 'initial' };
509
+ });
510
+ expect(obj.nested.value).toBe('initial');
511
+
512
+ // Modify plain nested object through parent's change context.
513
+ Obj.change(obj, (o) => {
514
+ o.nested.value = 'modified';
515
+ });
516
+ expect(obj.nested.value).toBe('modified');
517
+ });
518
+ });
519
+ });
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ /**
6
+ * Define a non-enumerable property on an object.
7
+ */
8
+ export const defineHiddenProperty = (object: any, key: string | symbol, value: any) => {
9
+ Object.defineProperty(object, key, {
10
+ enumerable: false,
11
+ configurable: true,
12
+ value,
13
+ });
14
+ };
@@ -0,0 +1,42 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ /**
6
+ * Error thrown when attempting to mutate an object outside of an Obj.change() context.
7
+ */
8
+ export class MutationOutsideChangeContextError extends Error {
9
+ constructor(operation: string, suggestion: string) {
10
+ super(
11
+ `Cannot ${operation} outside of Obj.change(). Use Obj.change(obj, (mutableObj) => { ${suggestion} }) instead.`,
12
+ );
13
+ this.name = 'MutationOutsideChangeContextError';
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Create an error for attempting to set a property outside of a change context.
19
+ */
20
+ export const createPropertySetError = (prop: string | symbol): MutationOutsideChangeContextError => {
21
+ return new MutationOutsideChangeContextError(
22
+ `modify object property "${String(prop)}"`,
23
+ `mutableObj.${String(prop)} = value;`,
24
+ );
25
+ };
26
+
27
+ /**
28
+ * Create an error for attempting to delete a property outside of a change context.
29
+ */
30
+ export const createPropertyDeleteError = (prop: string | symbol): MutationOutsideChangeContextError => {
31
+ return new MutationOutsideChangeContextError(
32
+ `delete object property "${String(prop)}"`,
33
+ `delete mutableObj.${String(prop)};`,
34
+ );
35
+ };
36
+
37
+ /**
38
+ * Create an error for attempting to call an array method outside of a change context.
39
+ */
40
+ export const createArrayMethodError = (method: string): MutationOutsideChangeContextError => {
41
+ return new MutationOutsideChangeContextError(`call array.${method}()`, `mutableObj.array.${method}(...);`);
42
+ };
@@ -0,0 +1,44 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { EventId } from './symbols';
6
+
7
+ /**
8
+ * Simple batching mechanism for EventId emissions.
9
+ * When batch depth > 0, events are collected instead of emitted immediately.
10
+ * When batch depth returns to 0, pending events are emitted.
11
+ */
12
+ let eventBatchDepth = 0;
13
+ const pendingEventTargets = new Set<object>();
14
+
15
+ /**
16
+ * Run a callback in a batched context for EventId emissions.
17
+ * Multiple mutations within the batch will only emit one event per target.
18
+ */
19
+ export const batchEvents = (callback: () => void): void => {
20
+ eventBatchDepth++;
21
+ try {
22
+ callback();
23
+ } finally {
24
+ eventBatchDepth--;
25
+ if (eventBatchDepth === 0) {
26
+ // Emit pending events.
27
+ for (const target of pendingEventTargets) {
28
+ (target as any)[EventId]?.emit();
29
+ }
30
+ pendingEventTargets.clear();
31
+ }
32
+ }
33
+ };
34
+
35
+ /**
36
+ * Emit an event on a target, respecting batching.
37
+ */
38
+ export const emitEvent = (target: object): void => {
39
+ if (eventBatchDepth > 0) {
40
+ pendingEventTargets.add(target);
41
+ } else {
42
+ (target as any)[EventId]?.emit();
43
+ }
44
+ };