@dxos/echo 0.8.4-main.d05539e30a → 0.8.4-main.d9fc60f731

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 (378) hide show
  1. package/README.md +4 -4
  2. package/dist/lib/neutral/Annotation.mjs +27 -6
  3. package/dist/lib/neutral/Database.mjs +6 -11
  4. package/dist/lib/neutral/Entity.mjs +25 -16
  5. package/dist/lib/neutral/Err.mjs +3 -3
  6. package/dist/lib/neutral/Feed.mjs +19 -17
  7. package/dist/lib/neutral/Filter.mjs +13 -13
  8. package/dist/lib/neutral/Format.mjs +23 -3
  9. package/dist/lib/neutral/JsonSchema.mjs +7 -8
  10. package/dist/lib/neutral/Key.mjs +9 -5
  11. package/dist/lib/neutral/Migration.mjs +11 -10
  12. package/dist/lib/neutral/Obj.mjs +21 -18
  13. package/dist/lib/neutral/Query.mjs +17 -17
  14. package/dist/lib/neutral/QueryResult.mjs +1 -1
  15. package/dist/lib/neutral/Ref.mjs +10 -11
  16. package/dist/lib/neutral/Registry.mjs +14 -0
  17. package/dist/lib/neutral/Relation.mjs +24 -23
  18. package/dist/lib/neutral/Scope.mjs +12 -0
  19. package/dist/lib/neutral/Tag.mjs +17 -14
  20. package/dist/lib/neutral/Type.mjs +52 -26
  21. package/dist/lib/neutral/chunk-3DKP2EIN.mjs +31 -0
  22. package/dist/lib/neutral/chunk-3DKP2EIN.mjs.map +7 -0
  23. package/dist/lib/neutral/chunk-4BB4MFCN.mjs +154 -0
  24. package/dist/lib/neutral/chunk-4BB4MFCN.mjs.map +7 -0
  25. package/dist/lib/neutral/{chunk-PT37DG2F.mjs → chunk-4SFPZJVA.mjs} +82 -74
  26. package/dist/lib/neutral/chunk-4SFPZJVA.mjs.map +7 -0
  27. package/dist/lib/neutral/{chunk-APHSOTIX.mjs → chunk-4Z6GET2X.mjs} +3 -3
  28. package/dist/lib/neutral/{chunk-APHSOTIX.mjs.map → chunk-4Z6GET2X.mjs.map} +2 -2
  29. package/dist/lib/neutral/{chunk-7RVZT53K.mjs → chunk-7LOUAPYZ.mjs} +9 -5
  30. package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +7 -0
  31. package/dist/lib/neutral/{chunk-BMB7IHGB.mjs → chunk-7OAFN3OX.mjs} +70 -57
  32. package/dist/lib/neutral/chunk-7OAFN3OX.mjs.map +7 -0
  33. package/dist/lib/neutral/{chunk-MLS7U7AT.mjs → chunk-7PRCIDHH.mjs} +41 -28
  34. package/dist/lib/neutral/chunk-7PRCIDHH.mjs.map +7 -0
  35. package/dist/lib/neutral/{chunk-ZISMEVKD.mjs → chunk-BBFJWWAV.mjs} +6 -6
  36. package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +7 -0
  37. package/dist/lib/neutral/{chunk-ZFACXBY6.mjs → chunk-BDQGMDIX.mjs} +30 -34
  38. package/dist/lib/neutral/chunk-BDQGMDIX.mjs.map +7 -0
  39. package/dist/lib/neutral/chunk-CGTI5MXO.mjs +36 -0
  40. package/dist/lib/neutral/chunk-CGTI5MXO.mjs.map +7 -0
  41. package/dist/lib/neutral/{chunk-V72DY6LU.mjs → chunk-DKLUHO4T.mjs} +1 -1
  42. package/dist/lib/neutral/chunk-DKLUHO4T.mjs.map +7 -0
  43. package/dist/lib/neutral/chunk-DMN2CKPX.mjs +93 -0
  44. package/dist/lib/neutral/chunk-DMN2CKPX.mjs.map +7 -0
  45. package/dist/lib/neutral/{chunk-QRZ2I3ZM.mjs → chunk-G6CFWUYH.mjs} +2 -2
  46. package/dist/lib/neutral/chunk-H26LSXVJ.mjs +653 -0
  47. package/dist/lib/neutral/chunk-H26LSXVJ.mjs.map +7 -0
  48. package/dist/lib/neutral/{chunk-N7VOEPSV.mjs → chunk-J3MNM65T.mjs} +9 -9
  49. package/dist/lib/neutral/chunk-J3MNM65T.mjs.map +7 -0
  50. package/dist/lib/neutral/chunk-JE7AOSWF.mjs +247 -0
  51. package/dist/lib/neutral/chunk-JE7AOSWF.mjs.map +7 -0
  52. package/dist/lib/neutral/chunk-LAF3LSWI.mjs +379 -0
  53. package/dist/lib/neutral/chunk-LAF3LSWI.mjs.map +7 -0
  54. package/dist/lib/neutral/chunk-LMNRFOVB.mjs +108 -0
  55. package/dist/lib/neutral/chunk-LMNRFOVB.mjs.map +7 -0
  56. package/dist/lib/neutral/{chunk-N4B7FHQT.mjs → chunk-O6BH7EPN.mjs} +30 -3
  57. package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +7 -0
  58. package/dist/lib/neutral/{chunk-Q7ZL2P5H.mjs → chunk-OIYW7R2G.mjs} +62 -46
  59. package/dist/lib/neutral/chunk-OIYW7R2G.mjs.map +7 -0
  60. package/dist/lib/neutral/{chunk-G54OX4IX.mjs → chunk-OYUG4FHF.mjs} +527 -847
  61. package/dist/lib/neutral/chunk-OYUG4FHF.mjs.map +7 -0
  62. package/dist/lib/neutral/{chunk-J54QMAKF.mjs → chunk-Q5FKCVBC.mjs} +64 -59
  63. package/dist/lib/neutral/chunk-Q5FKCVBC.mjs.map +7 -0
  64. package/dist/lib/neutral/{chunk-FIWO2FZK.mjs → chunk-Q62IHV2N.mjs} +12 -7
  65. package/dist/lib/neutral/chunk-Q62IHV2N.mjs.map +7 -0
  66. package/dist/lib/neutral/{chunk-SCPFDS2E.mjs → chunk-QVJDDG44.mjs} +65 -34
  67. package/dist/lib/neutral/chunk-QVJDDG44.mjs.map +7 -0
  68. package/dist/lib/neutral/{chunk-TRPZU2HV.mjs → chunk-TFEWTY5A.mjs} +155 -129
  69. package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +7 -0
  70. package/dist/lib/neutral/{chunk-44HT3MEC.mjs → chunk-VKWOFXT2.mjs} +22 -2
  71. package/dist/lib/neutral/{chunk-44HT3MEC.mjs.map → chunk-VKWOFXT2.mjs.map} +1 -1
  72. package/dist/lib/neutral/{chunk-APJKDGFL.mjs → chunk-ZACMEAYV.mjs} +24 -24
  73. package/dist/lib/neutral/chunk-ZACMEAYV.mjs.map +7 -0
  74. package/dist/lib/neutral/index.mjs +50 -40
  75. package/dist/lib/neutral/internal/index.mjs +125 -64
  76. package/dist/lib/neutral/meta.json +1 -1
  77. package/dist/lib/neutral/testing/index.mjs +88 -99
  78. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  79. package/dist/types/src/Annotation.d.ts +108 -4
  80. package/dist/types/src/Annotation.d.ts.map +1 -1
  81. package/dist/types/src/Annotation.test.d.ts +2 -0
  82. package/dist/types/src/Annotation.test.d.ts.map +1 -0
  83. package/dist/types/src/Collection.d.ts +2 -3
  84. package/dist/types/src/Collection.d.ts.map +1 -1
  85. package/dist/types/src/Database.d.ts +50 -30
  86. package/dist/types/src/Database.d.ts.map +1 -1
  87. package/dist/types/src/Dataset.d.ts +16 -6
  88. package/dist/types/src/Dataset.d.ts.map +1 -1
  89. package/dist/types/src/Entity.d.ts +89 -19
  90. package/dist/types/src/Entity.d.ts.map +1 -1
  91. package/dist/types/src/Err.d.ts +9 -9
  92. package/dist/types/src/Err.d.ts.map +1 -1
  93. package/dist/types/src/Feed.d.ts +35 -12
  94. package/dist/types/src/Feed.d.ts.map +1 -1
  95. package/dist/types/src/Filter.d.ts +21 -8
  96. package/dist/types/src/Filter.d.ts.map +1 -1
  97. package/dist/types/src/Hypergraph.d.ts +13 -8
  98. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  99. package/dist/types/src/Json.d.ts.map +1 -1
  100. package/dist/types/src/JsonSchema.d.ts +1 -1
  101. package/dist/types/src/JsonSchema.d.ts.map +1 -1
  102. package/dist/types/src/Key.d.ts +1 -1
  103. package/dist/types/src/Key.d.ts.map +1 -1
  104. package/dist/types/src/Migration.d.ts +15 -12
  105. package/dist/types/src/Migration.d.ts.map +1 -1
  106. package/dist/types/src/Obj.d.ts +69 -40
  107. package/dist/types/src/Obj.d.ts.map +1 -1
  108. package/dist/types/src/Query.d.ts +24 -10
  109. package/dist/types/src/Query.d.ts.map +1 -1
  110. package/dist/types/src/QueryResult.d.ts +9 -0
  111. package/dist/types/src/QueryResult.d.ts.map +1 -1
  112. package/dist/types/src/Ref.d.ts +15 -8
  113. package/dist/types/src/Ref.d.ts.map +1 -1
  114. package/dist/types/src/Registry.d.ts +131 -0
  115. package/dist/types/src/Registry.d.ts.map +1 -0
  116. package/dist/types/src/Relation.d.ts +55 -26
  117. package/dist/types/src/Relation.d.ts.map +1 -1
  118. package/dist/types/src/Scope.d.ts +34 -0
  119. package/dist/types/src/Scope.d.ts.map +1 -0
  120. package/dist/types/src/StateMap.d.ts +32 -0
  121. package/dist/types/src/StateMap.d.ts.map +1 -0
  122. package/dist/types/src/StateMap.test.d.ts +2 -0
  123. package/dist/types/src/StateMap.test.d.ts.map +1 -0
  124. package/dist/types/src/Tag.d.ts +19 -3
  125. package/dist/types/src/Tag.d.ts.map +1 -1
  126. package/dist/types/src/TagIndex.d.ts +36 -0
  127. package/dist/types/src/TagIndex.d.ts.map +1 -0
  128. package/dist/types/src/TagIndex.test.d.ts +2 -0
  129. package/dist/types/src/TagIndex.test.d.ts.map +1 -0
  130. package/dist/types/src/Tagging.d.ts +31 -0
  131. package/dist/types/src/Tagging.d.ts.map +1 -0
  132. package/dist/types/src/Type.d.ts +356 -95
  133. package/dist/types/src/Type.d.ts.map +1 -1
  134. package/dist/types/src/View.d.ts +1 -4
  135. package/dist/types/src/View.d.ts.map +1 -1
  136. package/dist/types/src/index.d.ts +6 -3
  137. package/dist/types/src/index.d.ts.map +1 -1
  138. package/dist/types/src/internal/Annotation/annotations.d.ts +68 -36
  139. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
  140. package/dist/types/src/internal/Annotation/dictionary.d.ts +24 -0
  141. package/dist/types/src/internal/Annotation/dictionary.d.ts.map +1 -0
  142. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +14 -0
  143. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -0
  144. package/dist/types/src/internal/Annotation/index.d.ts +4 -2
  145. package/dist/types/src/internal/Annotation/index.d.ts.map +1 -1
  146. package/dist/types/src/internal/Annotation/util.d.ts +13 -4
  147. package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
  148. package/dist/types/src/internal/Entity/api.d.ts +3 -3
  149. package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
  150. package/dist/types/src/internal/Entity/entity.d.ts +72 -8
  151. package/dist/types/src/internal/Entity/entity.d.ts.map +1 -1
  152. package/dist/types/src/internal/Entity/guard.d.ts +10 -0
  153. package/dist/types/src/internal/Entity/guard.d.ts.map +1 -0
  154. package/dist/types/src/internal/Entity/index.d.ts +2 -0
  155. package/dist/types/src/internal/Entity/index.d.ts.map +1 -1
  156. package/dist/types/src/internal/Entity/model.d.ts +18 -17
  157. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  158. package/dist/types/src/internal/Entity/object.d.ts +3 -3
  159. package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
  160. package/dist/types/src/internal/Entity/relation.d.ts +30 -7
  161. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
  162. package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
  163. package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
  164. package/dist/types/src/internal/Entity/type-uri.d.ts +25 -0
  165. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
  166. package/dist/types/src/internal/Format/date.d.ts.map +1 -1
  167. package/dist/types/src/internal/Format/format.d.ts +3 -2
  168. package/dist/types/src/internal/Format/format.d.ts.map +1 -1
  169. package/dist/types/src/internal/Format/index.d.ts +2 -2
  170. package/dist/types/src/internal/Format/index.d.ts.map +1 -1
  171. package/dist/types/src/internal/Format/object.d.ts +3 -1
  172. package/dist/types/src/internal/Format/object.d.ts.map +1 -1
  173. package/dist/types/src/internal/JsonSchema/json-schema.d.ts +2 -1
  174. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
  175. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
  176. package/dist/types/src/internal/Obj/create-object.d.ts +11 -12
  177. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
  178. package/dist/types/src/internal/Obj/index.d.ts +0 -1
  179. package/dist/types/src/internal/Obj/index.d.ts.map +1 -1
  180. package/dist/types/src/internal/Obj/json-serializer.d.ts +8 -8
  181. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
  182. package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -1
  183. package/dist/types/src/internal/Obj/typed-object.d.ts +1 -1
  184. package/dist/types/src/internal/Query.d.ts.map +1 -1
  185. package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
  186. package/dist/types/src/internal/Ref/ref.d.ts +29 -19
  187. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
  188. package/dist/types/src/internal/Type/index.d.ts +1 -2
  189. package/dist/types/src/internal/Type/index.d.ts.map +1 -1
  190. package/dist/types/src/internal/Type/manipulation.d.ts +0 -1
  191. package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
  192. package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
  193. package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
  194. package/dist/types/src/internal/common/api/meta.d.ts +11 -8
  195. package/dist/types/src/internal/common/api/meta.d.ts.map +1 -1
  196. package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -1
  197. package/dist/types/src/internal/common/proxy/make-object.d.ts +11 -5
  198. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
  199. package/dist/types/src/internal/common/proxy/typed-handler.d.ts +18 -2
  200. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
  201. package/dist/types/src/internal/common/types/base.d.ts +4 -4
  202. package/dist/types/src/internal/common/types/entity.d.ts +59 -2
  203. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
  204. package/dist/types/src/internal/common/types/index.d.ts +1 -1
  205. package/dist/types/src/internal/common/types/index.d.ts.map +1 -1
  206. package/dist/types/src/internal/common/types/meta.d.ts +13 -7
  207. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
  208. package/dist/types/src/internal/common/types/model-symbols.d.ts +8 -4
  209. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -1
  210. package/dist/types/src/internal/common/types/typename.d.ts +7 -0
  211. package/dist/types/src/internal/common/types/typename.d.ts.map +1 -1
  212. package/dist/types/src/internal/common/types/well-known-types.d.ts +11 -0
  213. package/dist/types/src/internal/common/types/well-known-types.d.ts.map +1 -0
  214. package/dist/types/src/internal/index.d.ts +1 -0
  215. package/dist/types/src/internal/index.d.ts.map +1 -1
  216. package/dist/types/src/testing/test-schema.d.ts +32 -38
  217. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  218. package/dist/types/src/testing/util.d.ts +5 -3
  219. package/dist/types/src/testing/util.d.ts.map +1 -1
  220. package/dist/types/tsconfig.tsbuildinfo +1 -1
  221. package/package.json +21 -23
  222. package/src/Annotation.test.ts +439 -0
  223. package/src/Annotation.ts +151 -4
  224. package/src/Collection.ts +5 -9
  225. package/src/Database.ts +86 -61
  226. package/src/Dataset.ts +10 -2
  227. package/src/Entity.test.ts +116 -6
  228. package/src/Entity.ts +116 -23
  229. package/src/Err.ts +4 -4
  230. package/src/Feed.ts +57 -40
  231. package/src/Filter.ts +49 -27
  232. package/src/Hypergraph.ts +13 -8
  233. package/src/Json.test.ts +4 -4
  234. package/src/Json.ts +7 -6
  235. package/src/Key.ts +1 -1
  236. package/src/Migration.ts +27 -19
  237. package/src/Obj.test.ts +19 -8
  238. package/src/Obj.ts +131 -70
  239. package/src/Query.test.ts +147 -151
  240. package/src/Query.ts +133 -75
  241. package/src/QueryResult.ts +11 -0
  242. package/src/Ref.ts +21 -5
  243. package/src/Registry.ts +155 -0
  244. package/src/Relation.test.ts +10 -10
  245. package/src/Relation.ts +89 -52
  246. package/src/Scope.ts +50 -0
  247. package/src/StateMap.test.ts +56 -0
  248. package/src/StateMap.ts +99 -0
  249. package/src/Tag.md +88 -0
  250. package/src/Tag.ts +49 -6
  251. package/src/TagIndex.test.ts +57 -0
  252. package/src/TagIndex.ts +110 -0
  253. package/src/Tagging.ts +83 -0
  254. package/src/Type.test.ts +223 -18
  255. package/src/Type.ts +601 -131
  256. package/src/View.ts +10 -19
  257. package/src/index.ts +6 -4
  258. package/src/internal/Annotation/annotations.test.ts +31 -11
  259. package/src/internal/Annotation/annotations.ts +122 -103
  260. package/src/internal/Annotation/dictionary.ts +47 -0
  261. package/src/internal/Annotation/entity-dictionary.ts +40 -0
  262. package/src/internal/Annotation/index.ts +4 -2
  263. package/src/internal/Annotation/util.ts +17 -8
  264. package/src/internal/Entity/api.ts +7 -7
  265. package/src/internal/Entity/entity.ts +196 -47
  266. package/src/internal/Entity/guard.ts +26 -0
  267. package/src/internal/Entity/index.ts +2 -0
  268. package/src/internal/Entity/model.ts +35 -28
  269. package/src/internal/Entity/object.ts +21 -5
  270. package/src/internal/Entity/relation.ts +68 -34
  271. package/src/internal/Entity/type-kind.ts +75 -0
  272. package/src/internal/Entity/type-uri.ts +87 -0
  273. package/src/internal/Entity/util.ts +10 -9
  274. package/src/internal/Format/date.ts +0 -4
  275. package/src/internal/Format/format.test.ts +21 -0
  276. package/src/internal/Format/index.ts +2 -3
  277. package/src/internal/Format/object.ts +21 -4
  278. package/src/internal/Format/types.ts +1 -1
  279. package/src/internal/JsonSchema/annotations.ts +1 -1
  280. package/src/internal/JsonSchema/json-schema.test.ts +54 -140
  281. package/src/internal/JsonSchema/json-schema.ts +44 -30
  282. package/src/internal/Obj/clone.ts +9 -4
  283. package/src/internal/Obj/create-object.test.ts +12 -10
  284. package/src/internal/Obj/create-object.ts +67 -22
  285. package/src/internal/Obj/index.ts +0 -1
  286. package/src/internal/Obj/inspect.ts +4 -3
  287. package/src/internal/Obj/json-serializer.test.ts +100 -21
  288. package/src/internal/Obj/json-serializer.ts +93 -38
  289. package/src/internal/Obj/set-value.test.ts +7 -30
  290. package/src/internal/Obj/snapshot.ts +11 -4
  291. package/src/internal/Obj/typed-object.test.ts +9 -11
  292. package/src/internal/Obj/typed-object.ts +1 -1
  293. package/src/internal/Query.ts +14 -11
  294. package/src/internal/Ref/ref-array.ts +3 -3
  295. package/src/internal/Ref/ref.test.ts +17 -26
  296. package/src/internal/Ref/ref.ts +107 -59
  297. package/src/internal/Type/compose.test.ts +3 -1
  298. package/src/internal/Type/index.ts +1 -2
  299. package/src/internal/Type/manipulation.ts +0 -25
  300. package/src/internal/Type/type-schema.ts +60 -0
  301. package/src/internal/common/README.md +1 -1
  302. package/src/internal/common/api/meta.ts +16 -14
  303. package/src/internal/common/proxy/change.test.ts +35 -27
  304. package/src/internal/common/proxy/handler.test.ts +1 -1
  305. package/src/internal/common/proxy/json-serializer.ts +26 -16
  306. package/src/internal/common/proxy/make-object.ts +43 -20
  307. package/src/internal/common/proxy/ownership.ts +2 -2
  308. package/src/internal/common/proxy/schema.test.ts +48 -86
  309. package/src/internal/common/proxy/typed-handler.test.ts +12 -11
  310. package/src/internal/common/proxy/typed-handler.ts +71 -9
  311. package/src/internal/common/proxy/typed-object.test.ts +15 -27
  312. package/src/internal/common/types/base.ts +4 -4
  313. package/src/internal/common/types/entity.ts +80 -1
  314. package/src/internal/common/types/index.ts +6 -1
  315. package/src/internal/common/types/meta.ts +37 -14
  316. package/src/internal/common/types/model-symbols.ts +16 -4
  317. package/src/internal/common/types/typename.ts +39 -3
  318. package/src/internal/common/types/well-known-types.ts +15 -0
  319. package/src/internal/index.ts +5 -0
  320. package/src/testing/api.test.ts +15 -9
  321. package/src/testing/test-data.ts +24 -24
  322. package/src/testing/test-schema.ts +22 -58
  323. package/src/testing/util.ts +14 -11
  324. package/dist/lib/neutral/Extension.mjs +0 -18
  325. package/dist/lib/neutral/SchemaRegistry.mjs +0 -2
  326. package/dist/lib/neutral/chunk-5SL5LDLD.mjs +0 -47
  327. package/dist/lib/neutral/chunk-5SL5LDLD.mjs.map +0 -7
  328. package/dist/lib/neutral/chunk-7RVZT53K.mjs.map +0 -7
  329. package/dist/lib/neutral/chunk-APJKDGFL.mjs.map +0 -7
  330. package/dist/lib/neutral/chunk-BICZKPQG.mjs +0 -7
  331. package/dist/lib/neutral/chunk-BICZKPQG.mjs.map +0 -7
  332. package/dist/lib/neutral/chunk-BMB7IHGB.mjs.map +0 -7
  333. package/dist/lib/neutral/chunk-FIWO2FZK.mjs.map +0 -7
  334. package/dist/lib/neutral/chunk-G54OX4IX.mjs.map +0 -7
  335. package/dist/lib/neutral/chunk-GWFFC34K.mjs +0 -50
  336. package/dist/lib/neutral/chunk-GWFFC34K.mjs.map +0 -7
  337. package/dist/lib/neutral/chunk-I2DARWPX.mjs +0 -128
  338. package/dist/lib/neutral/chunk-I2DARWPX.mjs.map +0 -7
  339. package/dist/lib/neutral/chunk-J54QMAKF.mjs.map +0 -7
  340. package/dist/lib/neutral/chunk-MGSQGHOD.mjs +0 -206
  341. package/dist/lib/neutral/chunk-MGSQGHOD.mjs.map +0 -7
  342. package/dist/lib/neutral/chunk-MLS7U7AT.mjs.map +0 -7
  343. package/dist/lib/neutral/chunk-N4B7FHQT.mjs.map +0 -7
  344. package/dist/lib/neutral/chunk-N7VOEPSV.mjs.map +0 -7
  345. package/dist/lib/neutral/chunk-PSZBLH53.mjs +0 -81
  346. package/dist/lib/neutral/chunk-PSZBLH53.mjs.map +0 -7
  347. package/dist/lib/neutral/chunk-PT37DG2F.mjs.map +0 -7
  348. package/dist/lib/neutral/chunk-Q2KKKJSV.mjs +0 -56
  349. package/dist/lib/neutral/chunk-Q2KKKJSV.mjs.map +0 -7
  350. package/dist/lib/neutral/chunk-Q7ZL2P5H.mjs.map +0 -7
  351. package/dist/lib/neutral/chunk-SCPFDS2E.mjs.map +0 -7
  352. package/dist/lib/neutral/chunk-TNBK56IN.mjs +0 -350
  353. package/dist/lib/neutral/chunk-TNBK56IN.mjs.map +0 -7
  354. package/dist/lib/neutral/chunk-TRPZU2HV.mjs.map +0 -7
  355. package/dist/lib/neutral/chunk-V72DY6LU.mjs.map +0 -7
  356. package/dist/lib/neutral/chunk-ZFACXBY6.mjs.map +0 -7
  357. package/dist/lib/neutral/chunk-ZISMEVKD.mjs.map +0 -7
  358. package/dist/types/src/Extension.d.ts +0 -80
  359. package/dist/types/src/Extension.d.ts.map +0 -1
  360. package/dist/types/src/Extension.test.d.ts +0 -2
  361. package/dist/types/src/Extension.test.d.ts.map +0 -1
  362. package/dist/types/src/SchemaRegistry.d.ts +0 -84
  363. package/dist/types/src/SchemaRegistry.d.ts.map +0 -1
  364. package/dist/types/src/internal/Obj/ids.d.ts +0 -6
  365. package/dist/types/src/internal/Obj/ids.d.ts.map +0 -1
  366. package/dist/types/src/internal/Type/echo-schema.d.ts +0 -181
  367. package/dist/types/src/internal/Type/echo-schema.d.ts.map +0 -1
  368. package/dist/types/src/internal/Type/persistent-schema.d.ts +0 -20
  369. package/dist/types/src/internal/Type/persistent-schema.d.ts.map +0 -1
  370. package/src/Extension.test.ts +0 -235
  371. package/src/Extension.ts +0 -122
  372. package/src/SchemaRegistry.ts +0 -106
  373. package/src/internal/Obj/ids.ts +0 -12
  374. package/src/internal/Type/echo-schema.ts +0 -423
  375. package/src/internal/Type/persistent-schema.ts +0 -33
  376. /package/dist/lib/neutral/{Extension.mjs.map → Registry.mjs.map} +0 -0
  377. /package/dist/lib/neutral/{SchemaRegistry.mjs.map → Scope.mjs.map} +0 -0
  378. /package/dist/lib/neutral/{chunk-QRZ2I3ZM.mjs.map → chunk-G6CFWUYH.mjs.map} +0 -0
@@ -0,0 +1,57 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import { describe, expect, test } from 'vitest';
7
+
8
+ import { DXN } from '@dxos/keys';
9
+
10
+ import * as Obj from './Obj';
11
+ import * as TagIndex from './TagIndex';
12
+ import * as Type from './Type';
13
+
14
+ /** A minimal item standing in for an immutable feed object. */
15
+ const Item = Schema.Struct({
16
+ text: Schema.String,
17
+ }).pipe(Type.makeObject(DXN.make('org.dxos.test.TagIndexItem', '0.1.0')));
18
+
19
+ /** A host object carrying a tag index alongside (a notional feed of) items. */
20
+ const Host = Schema.Struct({
21
+ tags: TagIndex.field(),
22
+ }).pipe(Type.makeObject(DXN.make('org.dxos.test.TagIndexHost', '0.1.0')));
23
+
24
+ describe('TagIndex', () => {
25
+ test('sets, unsets, and inverts feed-object tags', () => {
26
+ const host = Obj.make(Host, {});
27
+ const tags = TagIndex.bind(host, 'tags');
28
+
29
+ const a = Obj.make(Item, { text: 'a' });
30
+ const b = Obj.make(Item, { text: 'b' });
31
+ const urgent = 'dxn:tag:urgent';
32
+ const later = 'dxn:tag:later';
33
+
34
+ tags.setTag(urgent, a.id);
35
+ tags.setTag(urgent, b.id);
36
+ tags.setTag(later, b.id);
37
+ // Idempotent.
38
+ tags.setTag(urgent, a.id);
39
+
40
+ // Filter the feed by tag: tag -> object ids.
41
+ expect([...tags.objects(urgent)]).toEqual([a.id, b.id]);
42
+ expect([...tags.objects(later)]).toEqual([b.id]);
43
+ expect([...tags.objects('dxn:tag:missing')]).toEqual([]);
44
+
45
+ // Inverse: object -> tag ids.
46
+ expect(tags.tags(b.id).sort()).toEqual([later, urgent]);
47
+ expect(tags.tags(a.id)).toEqual([urgent]);
48
+ expect(tags.tagIds().sort()).toEqual([later, urgent]);
49
+
50
+ // Unset prunes the membership; emptying a tag drops the key.
51
+ tags.unsetTag(urgent, a.id);
52
+ expect([...tags.objects(urgent)]).toEqual([b.id]);
53
+ tags.unsetTag(urgent, b.id);
54
+ expect([...tags.objects(urgent)]).toEqual([]);
55
+ expect(tags.tagIds()).toEqual([later]);
56
+ });
57
+ });
@@ -0,0 +1,110 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import * as Schema from 'effect/Schema';
8
+
9
+ import { FormInputAnnotation } from './internal';
10
+ import * as Obj from './Obj';
11
+
12
+ /**
13
+ * An inverse tag index: an in-document `Record<tagId, objectId[]>` mapping a tag id to the ids of
14
+ * the objects carrying that tag.
15
+ *
16
+ * Mutable database objects track their tags in `Obj.getMeta(obj).tags` (an array of tag ids).
17
+ * Immutable feed/queue objects cannot carry their own meta, so this index — managed alongside the
18
+ * feed on its host object — augments that same process for them. Tags are sparse, so keying by tag
19
+ * id (rather than object id) keeps the index small and makes "filter the feed by tag" a single
20
+ * lookup.
21
+ *
22
+ * The tag id is an existing {@link Tag} object's id/URI; labels are never duplicated here — they
23
+ * live on the {@link Tag} object and stay editable in one place.
24
+ */
25
+
26
+ /** Read/write accessor over a host object's tag-index field, bound to a single field key. */
27
+ export interface Accessor {
28
+ /** All tag ids present in the index. */
29
+ tagIds(): string[];
30
+ /** Object ids carrying the given tag; `[]` when the tag is absent (filter the feed by tag). */
31
+ objects(tagId: string): readonly string[];
32
+ /** Inverse lookup: the tag ids applied to the given object id. */
33
+ tags(objectId: string): string[];
34
+ /** Applies a tag to an object (creating the tag entry when absent); idempotent. */
35
+ setTag(tagId: string, objectId: string): void;
36
+ /** Removes a tag from an object, pruning the tag entry when it empties. */
37
+ unsetTag(tagId: string, objectId: string): void;
38
+ }
39
+
40
+ /**
41
+ * Schema fragment for a tag-index field. Splice into a host Struct. Optional record, hidden from
42
+ * forms. Keyed by tag id; the value is the array of object ids carrying that tag.
43
+ */
44
+ export const field = () =>
45
+ Schema.Record({ key: Schema.String, value: Schema.Array(Obj.ID) }).pipe(
46
+ FormInputAnnotation.set(false),
47
+ Schema.optional,
48
+ );
49
+
50
+ /** Binds an {@link Accessor} over `host[key]`; all mutations go through `Obj.update`. */
51
+ export const bind = (host: Obj.Any, key: string): Accessor => {
52
+ type Record_ = Record<string, string[]>;
53
+
54
+ // The field is addressed by a runtime key, so the ECHO object is viewed as a keyed record — a
55
+ // deliberate type-system boundary (dynamic field access — the field name is a parameter).
56
+ const asView = (obj: Obj.Any) => obj as unknown as Record<string, Record_ | undefined>;
57
+ const read = (): Record_ => asView(host)[key] ?? {};
58
+
59
+ // Mutate the live typed record in place (do NOT reassign the whole tree); assigning a detached
60
+ // plain object tree bypasses ECHO's schema-aware conversion and stores arrays as numeric-keyed
61
+ // objects. Mutating the typed proxy (and assigning real arrays to its values) preserves arrays.
62
+ const write = (mutate: (record: Record_) => void): void => {
63
+ Obj.update(host, (host) => {
64
+ const view = asView(host);
65
+ if (view[key] === undefined) {
66
+ view[key] = {};
67
+ }
68
+ // Re-read after assignment: the assignment expression yields the plain RHS, not the
69
+ // ECHO-backed reactive record, so mutating that would not persist.
70
+ mutate(view[key]!);
71
+ });
72
+ };
73
+
74
+ // Existence check via `Object.keys` — ECHO's reactive record proxy auto-vivifies missing keys on
75
+ // direct access, so `record[tagId]` is not reliably `undefined` for absent tags.
76
+ const has = (record: Record_, tagId: string): boolean => Object.keys(record).includes(tagId);
77
+
78
+ return {
79
+ tagIds: () => Object.keys(read()),
80
+ objects: (tagId) => {
81
+ const record = read();
82
+ return has(record, tagId) ? record[tagId] : [];
83
+ },
84
+ tags: (objectId) => {
85
+ const record = read();
86
+ return Object.keys(record).filter((tagId) => record[tagId].includes(objectId));
87
+ },
88
+ setTag: (tagId, objectId) =>
89
+ write((record) => {
90
+ // Use `has` (not `record[tagId]`) for absence — the proxy auto-vivifies missing keys.
91
+ if (!has(record, tagId)) {
92
+ record[tagId] = [objectId];
93
+ } else if (!record[tagId].includes(objectId)) {
94
+ record[tagId] = [...record[tagId], objectId];
95
+ }
96
+ }),
97
+ unsetTag: (tagId, objectId) =>
98
+ write((record) => {
99
+ if (!has(record, tagId)) {
100
+ return;
101
+ }
102
+ const next = record[tagId].filter((existing) => existing !== objectId);
103
+ if (next.length === 0) {
104
+ delete record[tagId];
105
+ } else {
106
+ record[tagId] = next;
107
+ }
108
+ }),
109
+ };
110
+ };
package/src/Tagging.ts ADDED
@@ -0,0 +1,83 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import { EID, URI } from '@dxos/keys';
8
+
9
+ import type * as Database from './Database';
10
+ import * as Obj from './Obj';
11
+ import * as Ref from './Ref';
12
+ import type * as Tag from './Tag';
13
+ import * as TagIndex from './TagIndex';
14
+
15
+ /**
16
+ * Unified tag handling for objects whether their tags live on the object (mutable database objects)
17
+ * or alongside it (immutable feed/queue objects).
18
+ *
19
+ * - Mutable database objects track their tags in `Obj.getMeta(obj).tags` (an array of `Ref<Tag>`).
20
+ * - Immutable feed objects can't carry their own meta, so their tags live in a {@link TagIndex} on
21
+ * a host object; pass that host via {@link Options.host}.
22
+ *
23
+ * Either way the tag id is an existing {@link Tag} object's id/URI, so the same tag applies across
24
+ * mutable and immutable objects and its label is resolved (and edited) in one place. This API works
25
+ * in terms of those URI tag ids; on the mutable path it converts to/from the stored `Ref<Tag>`.
26
+ */
27
+ export interface Options {
28
+ /** Host object whose tag index holds tags for the (immutable) object. Omit for mutable objects. */
29
+ host?: Obj.Any;
30
+ /** Tag-index field name on the host (default `tags`). */
31
+ key?: string;
32
+ }
33
+
34
+ const DEFAULT_KEY = 'tags';
35
+
36
+ /** Returns the tag ids (URIs) applied to an object. */
37
+ export const get = (object: Obj.Any, options: Options = {}): string[] => {
38
+ const { host, key = DEFAULT_KEY } = options;
39
+ if (host) {
40
+ return TagIndex.bind(host, key).tags(object.id);
41
+ }
42
+ return Obj.getMeta(object).tags.map((tag) => tag.uri);
43
+ };
44
+
45
+ /** Applies a tag (by id/URI) to an object (idempotent). */
46
+ export const set = (object: Obj.Any, tagId: string, options: Options = {}): void => {
47
+ const { host, key = DEFAULT_KEY } = options;
48
+ if (host) {
49
+ TagIndex.bind(host, key).setTag(tagId, object.id);
50
+ return;
51
+ }
52
+ // Stored tag refs are canonical EIDs (read-time upgrade normalizes legacy DXN ids); normalize the
53
+ // incoming id the same way so dedupe compares like-for-like.
54
+ const id = EID.tryParse(tagId) ?? tagId;
55
+ Obj.update(object, (object) => {
56
+ const meta = Obj.getMeta(object);
57
+ if (!meta.tags.some((tag) => tag.uri === id)) {
58
+ meta.tags.push(Ref.fromURI(URI.make(id)));
59
+ }
60
+ });
61
+ };
62
+
63
+ /** Removes a tag (by id/URI) from an object. No-op when not present. */
64
+ export const unset = (object: Obj.Any, tagId: string, options: Options = {}): void => {
65
+ const { host, key = DEFAULT_KEY } = options;
66
+ if (host) {
67
+ TagIndex.bind(host, key).unsetTag(tagId, object.id);
68
+ return;
69
+ }
70
+ const id = EID.tryParse(tagId) ?? tagId;
71
+ Obj.update(object, (object) => {
72
+ const meta = Obj.getMeta(object);
73
+ for (let i = meta.tags.length - 1; i >= 0; i--) {
74
+ if (meta.tags[i].uri === id) {
75
+ meta.tags.splice(i, 1);
76
+ }
77
+ }
78
+ });
79
+ };
80
+
81
+ /** Resolves tag ids (URIs) to {@link Tag} object refs via the database. */
82
+ export const resolve = (db: Pick<Database.Database, 'makeRef'>, tagIds: readonly string[]): Ref.Ref<Tag.Tag>[] =>
83
+ tagIds.map((id) => db.makeRef<Tag.Tag>(URI.make(id)));
package/src/Type.test.ts CHANGED
@@ -5,6 +5,10 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import { describe, test } from 'vitest';
7
7
 
8
+ import { DXN, EntityId } from '@dxos/keys';
9
+
10
+ import * as Entity from './Entity';
11
+ import * as JsonSchema from './JsonSchema';
8
12
  import * as Obj from './Obj';
9
13
  import * as Relation from './Relation';
10
14
  import { TestSchema } from './testing';
@@ -12,16 +16,9 @@ import * as Type from './Type';
12
16
 
13
17
  describe('Type', () => {
14
18
  describe('Obj.Unknown schema', () => {
15
- test('has SchemaKindId for schema type checking', ({ expect }) => {
16
- // Type.isObjectSchema uses SchemaKindId to check if a schema is an object schema.
17
- expect(Type.isObjectSchema(Obj.Unknown)).toBe(true);
18
- expect(Type.isObjectSchema(TestSchema.Person)).toBe(true);
19
- expect(Type.isObjectSchema(Relation.Unknown)).toBe(false);
20
- });
21
-
22
19
  test('Schema.is validates structural compatibility only', ({ expect }) => {
23
- // Schema.is does structural validation (has id field).
24
- // It accepts both ECHO objects and plain objects with compatible structure.
20
+ // Schema.is does structural validation (has id field). `Obj.Unknown` IS
21
+ // a raw Effect Schema (branded with EchoSchemaKind), so pass it directly.
25
22
  expect(Schema.is(Obj.Unknown)({ id: 'plain-object' })).toBe(true);
26
23
  const obj = Obj.make(TestSchema.Person, { name: 'Test' });
27
24
  expect(Schema.is(Obj.Unknown)(obj)).toBe(true);
@@ -29,16 +26,9 @@ describe('Type', () => {
29
26
  });
30
27
 
31
28
  describe('Relation.Unknown schema', () => {
32
- test('has SchemaKindId for schema type checking', ({ expect }) => {
33
- // Type.isRelationSchema uses SchemaKindId to check if a schema is a relation schema.
34
- expect(Type.isRelationSchema(Relation.Unknown)).toBe(true);
35
- expect(Type.isRelationSchema(TestSchema.HasManager)).toBe(true);
36
- expect(Type.isRelationSchema(Obj.Unknown)).toBe(false);
37
- });
38
-
39
29
  test('Schema.is validates structural compatibility only', ({ expect }) => {
40
- // Schema.is does structural validation (has id field).
41
- // It accepts both ECHO relations and plain objects with compatible structure.
30
+ // Schema.is does structural validation (has id field). `Relation.Unknown`
31
+ // IS a raw Effect Schema (branded with EchoSchemaKind), so pass it directly.
42
32
  expect(Schema.is(Relation.Unknown)({ id: 'plain-object' })).toBe(true);
43
33
  const obj1 = Obj.make(TestSchema.Person, { name: 'Alice' });
44
34
  const obj2 = Obj.make(TestSchema.Person, { name: 'Bob' });
@@ -49,4 +39,219 @@ describe('Type', () => {
49
39
  expect(Schema.is(Relation.Unknown)(rel)).toBe(true);
50
40
  });
51
41
  });
42
+
43
+ describe('Type.Type meta-schema', () => {
44
+ test('Type.Type is branded as the type entity kind', ({ expect }) => {
45
+ // The Type.Type entity itself is an in-memory object (KindId=Object) that
46
+ // *declares* a type-kind schema (SchemaKindId=Type).
47
+ expect(Type.isTypeKind(Type.Type)).toBe(true);
48
+ expect(Type.isObject(Type.Type)).toBe(false);
49
+ expect(Type.isRelation(Type.Type)).toBe(false);
50
+ });
51
+
52
+ test('static object/relation types are not type-kind', ({ expect }) => {
53
+ expect(Type.isTypeKind(TestSchema.Person)).toBe(false);
54
+ expect(Type.isTypeKind(TestSchema.HasManager)).toBe(false);
55
+ });
56
+
57
+ test('Type.getMeta(Type.Type) reports key/version of the meta-schema', ({ expect }) => {
58
+ // `Type.getMeta` returns the entity's `EntityMeta`. For the static
59
+ // `Type.Type` meta-schema entity the key/version reflect its registry
60
+ // identity. The schema-kind brand is on `[SchemaKindId]`, not in meta.
61
+ const meta = Type.getMeta(Type.Type);
62
+ expect(meta.key).toBe('org.dxos.type.schema');
63
+ expect(meta.version).toBe('0.1.0');
64
+ expect(Type.isTypeKind(Type.Type)).toBe(true);
65
+ });
66
+
67
+ test('Type.getURI(Type.Type) returns the meta-schema DXN', ({ expect }) => {
68
+ expect(Type.getURI(Type.Type).toString()).toBe('dxn:org.dxos.type.schema:0.1.0');
69
+ });
70
+ });
71
+
72
+ describe('Type.makeObjectFromJsonSchema', () => {
73
+ test('creates an instance branded KindId=type', ({ expect }) => {
74
+ const entity = Type.makeObjectFromJsonSchema({
75
+ typename: 'com.example.type.test',
76
+ version: '0.1.0',
77
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({ field: Schema.Number })),
78
+ });
79
+ expect((entity as any)[Entity.KindId]).toBe(Entity.Kind.Type);
80
+ // `typename` / `version` are not direct fields on a persisted `Type.Type`;
81
+ // they live in `EntityMeta` (the canonical registry-provenance pair).
82
+ // Read them via the helpers (or `Type.getMeta`).
83
+ expect(Type.getTypename(entity)).toBe('com.example.type.test');
84
+ expect(Type.getVersion(entity)).toBe('0.1.0');
85
+ expect(entity.jsonSchema).toBeDefined();
86
+ });
87
+
88
+ test('defaults version to 0.0.0 for drafts', ({ expect }) => {
89
+ const draft = Type.makeObjectFromJsonSchema({
90
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({ field: Schema.String })),
91
+ });
92
+ // Drafts default version to `'0.0.0'` in `EntityMeta.version`; the
93
+ // typename (`EntityMeta.key`) is undefined until set.
94
+ expect(Type.getVersion(draft)).toBe('0.0.0');
95
+ const meta = Type.getMeta(draft);
96
+ expect(meta.key).toBeUndefined();
97
+ expect(meta.version).toBe('0.0.0');
98
+ });
99
+
100
+ test('assigns a stable id', ({ expect }) => {
101
+ const a = Type.makeObjectFromJsonSchema({ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})) });
102
+ const b = Type.makeObjectFromJsonSchema({ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})) });
103
+ expect(typeof a.id).toBe('string');
104
+ expect(a.id).not.toBe(b.id);
105
+ });
106
+
107
+ test('result satisfies isType', ({ expect }) => {
108
+ const entity = Type.makeObjectFromJsonSchema({
109
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({ field: Schema.Number })),
110
+ });
111
+ expect(Type.isType(entity)).toBe(true);
112
+ });
113
+ });
114
+
115
+ describe('Type.makeRelationFromJsonSchema', () => {
116
+ test('embeds source/target DXNs into jsonSchema', ({ expect }) => {
117
+ const entity = Type.makeRelationFromJsonSchema({
118
+ typename: 'com.example.type.testRel',
119
+ version: '0.1.0',
120
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({ note: Schema.String })),
121
+ source: TestSchema.Person,
122
+ target: TestSchema.Organization,
123
+ });
124
+ expect((entity as any)[Entity.KindId]).toBe(Entity.Kind.Type);
125
+ expect(entity.jsonSchema.entityKind).toBe(Entity.Kind.Relation);
126
+ expect((entity.jsonSchema as any).relationSource?.$ref).toBe(Type.getURI(TestSchema.Person).toString());
127
+ expect((entity.jsonSchema as any).relationTarget?.$ref).toBe(Type.getURI(TestSchema.Organization).toString());
128
+ });
129
+
130
+ test('accepts Obj.Unknown as source/target', ({ expect }) => {
131
+ const entity = Type.makeRelationFromJsonSchema({
132
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})),
133
+ source: Obj.Unknown,
134
+ target: Obj.Unknown,
135
+ });
136
+ const unknownURI = 'dxn:org.dxos.schema.anyObject:0.0.0';
137
+ expect((entity.jsonSchema as any).relationSource?.$ref).toBe(unknownURI);
138
+ expect((entity.jsonSchema as any).relationTarget?.$ref).toBe(unknownURI);
139
+ });
140
+
141
+ test('defaults version to 0.0.0 for drafts', ({ expect }) => {
142
+ const draft = Type.makeRelationFromJsonSchema({
143
+ jsonSchema: JsonSchema.toJsonSchema(Schema.Struct({})),
144
+ source: TestSchema.Person,
145
+ target: TestSchema.Person,
146
+ });
147
+ expect(Type.getVersion(draft)).toBe('0.0.0');
148
+ const meta = Type.getMeta(draft);
149
+ expect(meta.key).toBeUndefined();
150
+ expect(meta.version).toBe('0.0.0');
151
+ });
152
+ });
153
+
154
+ describe('Obj/Relation/Entity.getType', () => {
155
+ test('Obj.getType returns the static type entity for instances of Type.makeObject', ({ expect }) => {
156
+ const person = Obj.make(TestSchema.Person, { name: 'Alice' });
157
+ expect(Obj.getType(person)).toBe(TestSchema.Person);
158
+ });
159
+
160
+ test('Relation.getType returns the static type entity for instances of Type.makeRelation', ({ expect }) => {
161
+ const a = Obj.make(TestSchema.Person, { name: 'A' });
162
+ const b = Obj.make(TestSchema.Person, { name: 'B' });
163
+ const rel = Relation.make(TestSchema.HasManager, {
164
+ [Relation.Source]: a,
165
+ [Relation.Target]: b,
166
+ });
167
+ expect(Relation.getType(rel)).toBe(TestSchema.HasManager);
168
+ });
169
+
170
+ test('Entity.getType narrows uniformly across object/relation instances', ({ expect }) => {
171
+ const person = Obj.make(TestSchema.Person, { name: 'A' });
172
+ const a = Obj.make(TestSchema.Person, { name: 'A' });
173
+ const b = Obj.make(TestSchema.Person, { name: 'B' });
174
+ const rel = Relation.make(TestSchema.HasManager, {
175
+ [Relation.Source]: a,
176
+ [Relation.Target]: b,
177
+ });
178
+ expect(Entity.getType(person)).toBe(TestSchema.Person);
179
+ expect(Entity.getType(rel)).toBe(TestSchema.HasManager);
180
+ });
181
+ });
182
+
183
+ describe('static type factories', () => {
184
+ test('Type.makeObject stamps schema-kind=object', ({ expect }) => {
185
+ expect((TestSchema.Person as any)['~@dxos/echo/SchemaKind']).toBe(Entity.Kind.Object);
186
+ expect(Type.isObject(TestSchema.Person)).toBe(true);
187
+ });
188
+
189
+ test('Type.makeRelation stamps schema-kind=relation', ({ expect }) => {
190
+ expect((TestSchema.HasManager as any)['~@dxos/echo/SchemaKind']).toBe(Entity.Kind.Relation);
191
+ expect(Type.isRelation(TestSchema.HasManager)).toBe(true);
192
+ });
193
+
194
+ test('Type.getURI returns the DXN for static types', ({ expect }) => {
195
+ expect(Type.getURI(TestSchema.Person).toString()).toBe('dxn:com.example.type.person:0.1.0');
196
+ expect(Type.getURI(TestSchema.HasManager).toString()).toBe('dxn:com.example.type.hasManager:0.1.0');
197
+ });
198
+ });
199
+
200
+ describe('deterministic id default', () => {
201
+ // The default id is `EntityId.deterministic(typename, version)` — required so that
202
+ // `Type.makeObject(...)` never calls `crypto.getRandomValues()` at module-evaluation
203
+ // time (forbidden by Cloudflare workerd in global scope).
204
+ const personDxn = DXN.make('com.example.type.deterministic.person', '0.1.0');
205
+ const worksForDxn = DXN.make('com.example.type.deterministic.worksFor', '0.1.0');
206
+
207
+ test('Type.makeObject with the same DXN twice yields entities with identical ids', ({ expect }) => {
208
+ const a = Schema.Struct({ name: Schema.String }).pipe(Type.makeObject(personDxn));
209
+ const b = Schema.Struct({ name: Schema.String }).pipe(Type.makeObject(personDxn));
210
+ expect(a.id).toBe(b.id);
211
+ expect(a.id).toBe(EntityId.deterministic('com.example.type.deterministic.person', '0.1.0'));
212
+ });
213
+
214
+ test('different versions produce different ids', ({ expect }) => {
215
+ const v1 = Schema.Struct({ name: Schema.String }).pipe(
216
+ Type.makeObject(DXN.make('com.example.type.deterministic.person', '0.1.0')),
217
+ );
218
+ const v2 = Schema.Struct({ name: Schema.String }).pipe(
219
+ Type.makeObject(DXN.make('com.example.type.deterministic.person', '0.2.0')),
220
+ );
221
+ expect(v1.id).not.toBe(v2.id);
222
+ });
223
+
224
+ test('Type.makeObject({ id }) override is honoured', ({ expect }) => {
225
+ const explicit = EntityId.random();
226
+ const entity = Schema.Struct({ name: Schema.String }).pipe(Type.makeObject(personDxn, { id: explicit }));
227
+ expect(entity.id).toBe(explicit);
228
+ // And the default still kicks in when no override is supplied.
229
+ const defaultEntity = Schema.Struct({ name: Schema.String }).pipe(Type.makeObject(personDxn));
230
+ expect(defaultEntity.id).not.toBe(explicit);
231
+ });
232
+
233
+ test('Type.makeRelation defaults id to deterministic(typename, version)', ({ expect }) => {
234
+ const a = Schema.Struct({ since: Schema.Number }).pipe(
235
+ Type.makeRelation({ dxn: worksForDxn, source: TestSchema.Person, target: TestSchema.Organization }),
236
+ );
237
+ const b = Schema.Struct({ since: Schema.Number }).pipe(
238
+ Type.makeRelation({ dxn: worksForDxn, source: TestSchema.Person, target: TestSchema.Organization }),
239
+ );
240
+ expect(a.id).toBe(b.id);
241
+ expect(a.id).toBe(EntityId.deterministic('com.example.type.deterministic.worksFor', '0.1.0'));
242
+ });
243
+
244
+ test('Type.makeRelation({ id }) override is honoured', ({ expect }) => {
245
+ const explicit = EntityId.random();
246
+ const entity = Schema.Struct({ since: Schema.Number }).pipe(
247
+ Type.makeRelation({
248
+ dxn: worksForDxn,
249
+ source: TestSchema.Person,
250
+ target: TestSchema.Organization,
251
+ id: explicit,
252
+ }),
253
+ );
254
+ expect(entity.id).toBe(explicit);
255
+ });
256
+ });
52
257
  });