@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
package/src/View.ts CHANGED
@@ -8,7 +8,7 @@ import * as Schema from 'effect/Schema';
8
8
 
9
9
  import { QueryAST } from '@dxos/echo-protocol';
10
10
  import { JsonPath } from '@dxos/effect';
11
- import { PublicKey } from '@dxos/keys';
11
+ import { DXN, PublicKey } from '@dxos/keys';
12
12
 
13
13
  import * as Annotation from './Annotation';
14
14
  import * as Filter from './Filter';
@@ -75,27 +75,18 @@ const ViewSchema = Schema.Struct({
75
75
  */
76
76
  projection: Projection,
77
77
  }).pipe(
78
- Type.object({
79
- typename: 'org.dxos.type.view',
80
- version: '0.1.0',
81
- }),
82
- internal.SystemTypeAnnotation.set(true),
83
- Annotation.IconAnnotation.set({
84
- icon: 'ph--funnel--regular',
85
- hue: 'green',
86
- }),
78
+ internal.HiddenAnnotation.set(true),
79
+ Annotation.IconAnnotation.set({ icon: 'ph--funnel--regular', hue: 'green' }),
80
+ Type.makeObject(DXN.make('org.dxos.type.view', '0.1.0')),
87
81
  );
88
82
 
89
- export interface View extends Schema.Schema.Type<typeof ViewSchema> {}
90
-
91
- /**
92
- * View instance type.
93
- */
94
- // NOTE: This interface is explicitly defined rather than derived from the schema to avoid
95
- // TypeScript "cannot be named" portability errors. The schema contains QueryAST.Query which
96
- // references internal @dxos/echo-protocol module paths. Without this explicit interface,
97
- // any schema using Ref.Ref(View) would inherit the non-portable type and fail to compile.
83
+ // NOTE: Declared as a named interface and the `View` const is annotated `Type.Obj<View>` so
84
+ // downstream consumers see a named `View` type instead of the inlined `QueryAST.Query` union.
85
+ // Without the named interface, embedding `Type.getSchema(View.View)` in a downstream
86
+ // `Schema.Struct` triggers TS2742 portability errors (e.g. plugin-kanban, plugin-table).
98
87
  // TODO(wittjosiah): Find a better solution that doesn't require manually keeping the interface in sync.
88
+ export interface View extends Type.InstanceType<typeof ViewSchema> {}
89
+
99
90
  export const View: Type.Obj<View> = ViewSchema as any;
100
91
 
101
92
  export const make = (props: Partial<Obj.MakeProps<typeof View>>): View => {
package/src/index.ts CHANGED
@@ -3,8 +3,7 @@
3
3
  //
4
4
 
5
5
  export { QueryAST } from '@dxos/echo-protocol';
6
- // TODO(wittjosiah): Refactor DXN to not use statics similar to Query.
7
- export { DXN } from '@dxos/keys';
6
+ export { DXN, EID, URI } from '@dxos/keys';
8
7
 
9
8
  export * as Annotation from './Annotation';
10
9
  export * as Database from './Database';
@@ -24,11 +23,14 @@ export * as Order from './Order';
24
23
  export * as Query from './Query';
25
24
  export * as QueryResult from './QueryResult';
26
25
  export * as Ref from './Ref';
26
+ export * as Registry from './Registry';
27
27
  export * as Relation from './Relation';
28
- export * as SchemaRegistry from './SchemaRegistry';
28
+ export * as Scope from './Scope';
29
+ export * as StateMap from './StateMap';
29
30
  export * as Tag from './Tag';
31
+ export * as TagIndex from './TagIndex';
32
+ export * as Tagging from './Tagging';
30
33
  export * as Type from './Type';
31
34
  export * as Collection from './Collection';
32
35
  export * as View from './View';
33
36
  export * as Dataset from './Dataset';
34
- export * as Extension from './Extension';
@@ -5,8 +5,13 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import { describe, test } from 'vitest';
7
7
 
8
+ import { DXN } from '@dxos/keys';
9
+
10
+ import { createEchoSchema } from '../../testing';
11
+ import * as Type from '../../Type';
12
+ import { EntityKind } from '../common/types';
8
13
  import { EchoObjectSchema } from '../Entity';
9
- import { LabelAnnotation, TypenameSchema, VersionSchema, getLabelWithSchema } from './annotations';
14
+ import { LabelAnnotation, TypenameSchema, VersionSchema, getLabelWithSchema, getTypeAnnotation } from './annotations';
10
15
 
11
16
  // TODO(dmaretskyi): Use one of the testing schemas.
12
17
  const TestObject = Schema.Struct({
@@ -17,14 +22,9 @@ const TestObject = Schema.Struct({
17
22
 
18
23
  type TestObject = Schema.Schema.Type<typeof TestObject>;
19
24
 
20
- const TestEchoSchema = TestObject.pipe(
21
- EchoObjectSchema({
22
- typename: 'org.dxos.type.test',
23
- version: '0.1.0',
24
- }),
25
- );
25
+ const TestEchoSchema = TestObject.pipe(EchoObjectSchema(DXN.make('org.dxos.type.test', '0.1.0')));
26
26
 
27
- type TestEchoSchema = Schema.Schema.Type<typeof TestEchoSchema>;
27
+ type TestEchoSchema = Type.InstanceType<typeof TestEchoSchema>;
28
28
 
29
29
  describe('annotations', () => {
30
30
  describe('Typename', () => {
@@ -132,14 +132,34 @@ describe('annotations', () => {
132
132
  });
133
133
 
134
134
  test('should return label from echo object', ({ expect }) => {
135
- const obj: TestEchoSchema = {
135
+ const obj = {
136
136
  id: 'test',
137
137
  name: 'Primary Name',
138
138
  fallbackName: 'Fallback Name',
139
139
  other: 'Other',
140
- };
140
+ } as unknown as TestEchoSchema;
141
+
142
+ expect(getLabelWithSchema(Type.getSchema(TestEchoSchema), obj)).toEqual('Primary Name');
143
+ });
144
+ });
145
+
146
+ // `getTypeAnnotation` reads annotations from an Effect Schema. To read off a
147
+ // `Type.Type` entity (static or persisted), unwrap with `Type.getSchema(entity)`
148
+ // first — that handles both the static `StaticTypeSchemaSlot` case and the
149
+ // persisted `jsonSchema` rebuild case.
150
+ describe('getTypeAnnotation via Type.getSchema(entity)', () => {
151
+ test('returns TypeAnnotation for a static Type.Obj entity', ({ expect }) => {
152
+ const annotation = getTypeAnnotation(Type.getSchema(TestEchoSchema));
153
+ expect(annotation).toBeDefined();
154
+ expect(annotation?.kind).toBe(EntityKind.Object);
155
+ expect(annotation?.typename).toBe('org.dxos.type.test');
156
+ });
141
157
 
142
- expect(getLabelWithSchema(TestEchoSchema, obj)).toEqual('Primary Name');
158
+ test('returns TypeAnnotation for a persisted Type.Type entity', ({ expect }) => {
159
+ const persisted = createEchoSchema(Type.getSchema(TestEchoSchema));
160
+ const annotation = getTypeAnnotation(Type.getSchema(persisted));
161
+ expect(annotation).toBeDefined();
162
+ expect(annotation?.typename).toBe('org.dxos.type.test');
143
163
  });
144
164
  });
145
165
  });
@@ -7,15 +7,17 @@ import * as Option from 'effect/Option';
7
7
  import * as Schema from 'effect/Schema';
8
8
  import * as SchemaAST from 'effect/SchemaAST';
9
9
 
10
- import { raise } from '@dxos/debug';
11
10
  import { type JsonPath, getField } from '@dxos/effect';
12
11
  import { assertArgument, invariant } from '@dxos/invariant';
13
- import { DXN } from '@dxos/keys';
12
+ import { DXN, URI } from '@dxos/keys';
14
13
  import { type Primitive } from '@dxos/util';
15
14
 
15
+ import type * as Annotation from '../../Annotation';
16
16
  import { type Mutable } from '../common/proxy';
17
17
  import { type AnyProperties, EntityKind, TypeId, getSchema } from '../common/types';
18
- import { type AnnotationHelper, createAnnotationHelper } from './util';
18
+ import { createAnnotationHelper } from './util';
19
+
20
+ const ANNOTATION_TYPE_ID: Annotation.TypeId = '~@dxos/echo/Annotation' as const;
19
21
 
20
22
  /**
21
23
  * @internal
@@ -46,39 +48,27 @@ export const getTypeIdentifierAnnotation = (schema: Schema.Schema.All) =>
46
48
  )(schema.ast);
47
49
 
48
50
  /**
49
- * @returns DXN of the schema.
51
+ * @returns The schema's type identifier URI — whichever URI fits.
52
+ *
53
+ * - Stored (dynamic) schemas: the schema-as-object's EID, so loaded objects ride
54
+ * along with their schema as a strong dependency.
55
+ * - Non-stored (static) schemas: the typename DXN built from `TypeAnnotation`.
50
56
  *
51
- * For non-stored schema returns `dxn:type:`.
52
- * For stored schema returns `dxn:echo:`.
57
+ * This URI is what gets written to an object's `system.type`; queries that filter by
58
+ * type also use it (see `Filter.type` / `getTypeURIFromSpecifier`), so both sides
59
+ * stay symmetric without per-schema branching.
53
60
  */
54
- export const getSchemaDXN = (schema: Schema.Schema.All): DXN | undefined => {
61
+ export const getSchemaURI = (schema: Schema.Schema.All): URI.URI | undefined => {
55
62
  assertArgument(Schema.isSchema(schema), 'schema', 'invalid schema');
56
63
  const id = getTypeIdentifierAnnotation(schema);
57
64
  if (id) {
58
- return DXN.parse(id);
65
+ return URI.make(id);
59
66
  }
60
-
61
- // TODO(dmaretskyi): Add support for dynamic schema.
62
67
  const objectAnnotation = getTypeAnnotation(schema);
63
- if (!objectAnnotation) {
64
- return undefined;
65
- }
66
-
67
- return DXN.fromTypenameAndVersion(objectAnnotation.typename, objectAnnotation.version);
68
- };
69
-
70
- /**
71
- * @param input schema or a typename string.
72
- * @return type DXN.
73
- */
74
- export const getTypeDXNFromSpecifier = (input: Schema.Schema.All | string): DXN => {
75
- if (Schema.isSchema(input)) {
76
- return getSchemaDXN(input) ?? raise(new TypeError('Schema has no DXN'));
77
- } else {
78
- assertArgument(typeof input === 'string', 'input');
79
- assertArgument(!input.startsWith('dxn:'), 'input');
80
- return DXN.fromTypename(input);
68
+ if (objectAnnotation) {
69
+ return DXN.make(objectAnnotation.typename, objectAnnotation.version);
81
70
  }
71
+ return undefined;
82
72
  };
83
73
 
84
74
  //
@@ -186,8 +176,15 @@ export const getTypename = (obj: AnyProperties): string | undefined => {
186
176
  // Try to extract typename from DXN.
187
177
  return getSchemaTypename(schema);
188
178
  } else {
189
- const type = getTypeDXN(obj);
190
- return type?.asTypeDXN()?.type;
179
+ // `obj` may be an arbitrary value (e.g. from `isInstanceOf`); read TypeId
180
+ // directly so we return undefined for non-entities instead of throwing.
181
+ const type = (obj as any)?.[TypeId];
182
+ // Parse the URI string to extract typename.
183
+ if (DXN.isDXN(type)) {
184
+ const parsed = DXN.tryMake(type);
185
+ return parsed && DXN.getName(parsed);
186
+ }
187
+ return undefined;
191
188
  }
192
189
  };
193
190
 
@@ -195,8 +192,8 @@ export const getTypename = (obj: AnyProperties): string | undefined => {
195
192
  * @internal (use Type.setTypename)
196
193
  */
197
194
  // TODO(dmaretskyi): Rename setTypeDXN.
198
- export const setTypename = (obj: any, typename: DXN): void => {
199
- invariant(typename instanceof DXN, 'Invalid type.');
195
+ export const setTypename = (obj: any, typename: URI.URI): void => {
196
+ assertArgument(typeof typename === 'string', 'typename', 'Invalid type.');
200
197
  Object.defineProperty(obj, TypeId, {
201
198
  value: typename,
202
199
  writable: false,
@@ -206,68 +203,25 @@ export const setTypename = (obj: any, typename: DXN): void => {
206
203
  };
207
204
 
208
205
  /**
209
- * @returns Object type as {@link DXN}.
210
- * @returns undefined if the object doesn't have a type.
206
+ * @returns Object type URI — either a typename {@link DXN} or an `echo:` reference to a stored Schema object.
207
+ * @returns undefined if the object has no registered type URI (e.g. unresolved query result).
211
208
  * @example `dxn:com.example.type.person:1.0.0`
209
+ * @example `echo:/01KKKG2FHWCMTR0BY00GJSVT1X` (stored schema)
212
210
  *
213
- * @internal (use Obj.getTypeDXN)
211
+ * @internal (use Obj.getTypeURI)
214
212
  */
215
- // TODO(burdon): Narrow type.
216
- export const getTypeDXN = (obj: AnyProperties): DXN | undefined => {
217
- if (!obj) {
213
+ export const getTypeURI = (obj: AnyProperties): URI.URI | undefined => {
214
+ if (obj == null) {
218
215
  return undefined;
219
216
  }
220
-
221
217
  const type = (obj as any)[TypeId];
222
- if (!type) {
218
+ if (type == null) {
223
219
  return undefined;
224
220
  }
225
-
226
- invariant(type instanceof DXN, 'Invalid object.');
221
+ invariant(URI.isURI(type), 'Invalid object.');
227
222
  return type;
228
223
  };
229
224
 
230
- /**
231
- * Checks if the object is an instance of the schema.
232
- * Only typename is compared, the schema version is ignored.
233
- *
234
- * The following cases are considered to mean that the object is an instance of the schema:
235
- * - Object was created with this exact schema.
236
- * - Object was created with a different version of this schema.
237
- * - Object was created with a different schema (maybe dynamic) that has the same typename.
238
- */
239
- // TODO(burdon): Can we use `Schema.is`?
240
- export const isInstanceOf = <Schema extends Schema.Schema.AnyNoContext>(
241
- schema: Schema,
242
- object: any,
243
- ): object is Schema.Schema.Type<Schema> => {
244
- if (object == null) {
245
- return false;
246
- }
247
-
248
- const schemaDXN = getSchemaDXN(schema);
249
- if (!schemaDXN) {
250
- throw new Error('Schema must have an object annotation.');
251
- }
252
-
253
- const type = getTypeDXN(object);
254
- if (type && DXN.equals(type, schemaDXN)) {
255
- return true;
256
- }
257
-
258
- const typename = getTypename(object);
259
- if (!typename) {
260
- return false;
261
- }
262
-
263
- const typeDXN = schemaDXN.asTypeDXN();
264
- if (!typeDXN) {
265
- return false;
266
- }
267
-
268
- return typeDXN.type === typename;
269
- };
270
-
271
225
  //
272
226
  // PropertyMeta
273
227
  //
@@ -286,6 +240,12 @@ export type PropertyMetaAnnotation = {
286
240
 
287
241
  // TODO(wittjosiah): Align with other annotations.
288
242
  // TODO(wittjosiah): Why is this separate from FormatAnnotation?
243
+ /**
244
+ * Apply property-level metadata to an Effect schema. Only accepts
245
+ * `Schema.Schema.Any` — apply BEFORE wrapping the schema with
246
+ * `Type.makeObject` / `Type.makeRelation`. To read property meta off a
247
+ * `Type.Type` entity, unwrap it first with `Type.getSchema(entity)`.
248
+ */
289
249
  export const PropertyMeta = (name: string, value: PropertyMetaValue) => {
290
250
  return <A, I, R>(self: Schema.Schema<A, I, R>): Schema.Schema<A, I, R> => {
291
251
  const existingMeta = self.ast.annotations[PropertyMetaAnnotationId] as PropertyMetaAnnotation;
@@ -323,10 +283,10 @@ export const SchemaMetaSymbol = Symbol.for('@dxos/schema/SchemaMeta');
323
283
  export type SchemaMeta = TypeMeta & { id: string };
324
284
 
325
285
  /**
326
- * Identifies a schema as a schema for a hidden system type.
286
+ * Identifies a schema as hidden from user-facing surfaces (like dotfiles — visible only via an advanced setting).
327
287
  */
328
- export const SystemTypeAnnotationId = Symbol.for('@dxos/schema/annotation/SystemType');
329
- export const SystemTypeAnnotation = createAnnotationHelper<boolean>(SystemTypeAnnotationId);
288
+ export const HiddenAnnotationId = Symbol.for('@dxos/schema/annotation/Hidden');
289
+ export const HiddenAnnotation = createAnnotationHelper<boolean>(HiddenAnnotationId);
330
290
 
331
291
  /**
332
292
  * Identifies label property or JSON path expression.
@@ -446,6 +406,13 @@ export const setDescriptionWithSchema = <S extends Schema.Schema.Any>(
446
406
  export const FormInputAnnotationId = Symbol.for('@dxos/schema/annotation/FormInput');
447
407
  export const FormInputAnnotation = createAnnotationHelper<boolean>(FormInputAnnotationId);
448
408
 
409
+ /**
410
+ * When set on a `Ref` property, the form renders the referenced object's own
411
+ * fields inline (a nested form bound to the target) instead of a picker.
412
+ */
413
+ export const FormInlineAnnotationId = Symbol.for('@dxos/schema/annotation/FormInline');
414
+ export const FormInlineAnnotation = createAnnotationHelper<boolean>(FormInlineAnnotationId);
415
+
449
416
  /**
450
417
  * Default field to be used on referenced schema to lookup the value.
451
418
  */
@@ -471,26 +438,29 @@ interface MakeAnnoationsProps<T> {
471
438
  schema: Schema.Schema<T, any, never>;
472
439
  }
473
440
 
474
- // TODO(wittjosiah): Comment.
475
- export const makeUserAnnotation = <T>(props: MakeAnnoationsProps<T>): AnnotationHelper<T> => {
441
+ // Annotation ids use the same NSID / reverse-DNS format as TypenameSchema —
442
+ // dot-separated segments, middle segments may be hyphenated, final segment may be camelCase.
443
+ // At least 3 segments are required (e.g. org.dxos.annotation.example).
444
+ export const makeUserAnnotation = <T>(props: MakeAnnoationsProps<T>): Annotation.Annotation<T> => {
476
445
  assertArgument(
477
- /^[a-z][a-z0-9]*(\.[a-z][a-z0-9-]*){2,}$/.test(props.id),
446
+ /^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?){2,}(\.[a-zA-Z]([a-zA-Z0-9]{0,62})?)?$/.test(
447
+ props.id,
448
+ ),
478
449
  'id',
479
- 'Annotation id must be in the FQN format (org.dxos.annotation.example).',
450
+ 'Annotation id must be in the FQN format (org.dxos.annotation.example or org.dxos.space.rootCollection).',
480
451
  );
481
452
 
482
- const getFromAst = (ast: SchemaAST.AST) =>
483
- SchemaAST.getAnnotation<PropertyMetaAnnotation>(PropertyMetaAnnotationId)(ast).pipe(
484
- Option.flatMap((meta) => Option.fromNullable(meta[props.id])),
485
- Option.map(Schema.decodeUnknownSync(props.schema)),
486
- );
487
-
488
- return {
489
- get: (schema) => getFromAst(schema.ast),
490
- getFromAst: (ast) => getFromAst(ast),
453
+ const annotation: Annotation.Annotation<T> = {
454
+ [ANNOTATION_TYPE_ID]: { _Type: {} as T },
455
+ key: props.id as Annotation.Key,
456
+ schema: props.schema,
457
+ get: (schema) => getFromAst(schema.ast, annotation),
458
+ getFromAst: (ast) => getFromAst(ast, annotation),
491
459
  set: (value) =>
492
460
  PropertyMeta(props.id, Schema.encodeSync(props.schema)(value)) as <S extends Schema.Schema.Any>(schema: S) => S,
493
461
  };
462
+
463
+ return annotation;
494
464
  };
495
465
 
496
466
  const IconAnnotationSchema = Schema.Struct({
@@ -518,7 +488,6 @@ const IconAnnotationSchema = Schema.Struct({
518
488
  * - 'pink'
519
489
  * - 'rose'
520
490
  */
521
-
522
491
  hue: Schema.optional(Schema.String),
523
492
  });
524
493
 
@@ -545,15 +514,36 @@ export const IconFromRefAnnotation = makeUserAnnotation<string>({
545
514
  schema: Schema.String,
546
515
  });
547
516
 
517
+ /**
518
+ * Options for {@link getLabel}.
519
+ */
520
+ export type GetLabelOptions = {
521
+ /**
522
+ * Strategy for deriving a label when the entity has no `LabelAnnotation` value.
523
+ * - `'typename'`: use the entity's typename (e.g. `org.dxos.type.table`).
524
+ * Useful for Card.Title chrome that must always display something, even
525
+ * for unlabeled objects.
526
+ */
527
+ fallback?: 'typename';
528
+ };
529
+
548
530
  /**
549
531
  * Get the label of an entity.
550
532
  * Accepts both reactive entities and snapshots.
533
+ *
534
+ * If `options.fallback === 'typename'` and no label is set, returns the
535
+ * entity's typename instead.
551
536
  */
552
- export const getLabel = (entity: AnyProperties): string | undefined => {
537
+ export const getLabel = (entity: AnyProperties, options?: GetLabelOptions): string | undefined => {
553
538
  const schema = getSchema(entity);
554
- if (schema != null) {
555
- return getLabelWithSchema(schema, entity);
539
+ const label = schema != null ? getLabelWithSchema(schema, entity) : undefined;
540
+ if (label != null) {
541
+ return label;
542
+ }
543
+ if (options?.fallback === 'typename') {
544
+ return getTypename(entity);
556
545
  }
546
+ return undefined;
557
547
  };
558
548
 
559
549
  /**
@@ -578,6 +568,26 @@ export const getDescription = (entity: AnyProperties): string | undefined => {
578
568
  }
579
569
  };
580
570
 
571
+ /**
572
+ * Get the icon annotation for an entity, resolved via its type-level `IconAnnotation`.
573
+ * Accepts both reactive entities and snapshots.
574
+ *
575
+ * Returns the full `{ icon, hue }` annotation so callers can use both the phosphor icon
576
+ * name and the suggested colour. Callers wanting just the icon name typically write
577
+ * `Obj.getIcon(obj)?.icon ?? 'ph--cube--regular'`.
578
+ *
579
+ * Note: this is the "static" icon from the object's own schema. It does not follow
580
+ * `IconFromRefAnnotation` delegation — call sites needing that (e.g. app-graph node
581
+ * builders) should resolve the ref themselves.
582
+ */
583
+ export const getIcon = (entity: AnyProperties): IconAnnotation | undefined => {
584
+ const schema = getSchema(entity);
585
+ if (schema == null) {
586
+ return undefined;
587
+ }
588
+ return Option.getOrUndefined(IconAnnotation.get(schema));
589
+ };
590
+
581
591
  /**
582
592
  * Set the description of an entity.
583
593
  * Must be called within an Obj.update or Relation.update callback.
@@ -588,3 +598,12 @@ export const setDescription = (entity: Mutable<AnyProperties>, description: stri
588
598
  setDescriptionWithSchema(schema, entity, description);
589
599
  }
590
600
  };
601
+
602
+ export { Dictionary, Key, getDictionary, setDictionary } from './dictionary';
603
+
604
+ export const getFromAst = <T>(ast: SchemaAST.AST, annotation: Annotation.Annotation<T>): Option.Option<T> => {
605
+ return SchemaAST.getAnnotation<PropertyMetaAnnotation>(PropertyMetaAnnotationId)(ast).pipe(
606
+ Option.flatMap((meta) => Option.fromNullable(meta[annotation.key])),
607
+ Option.map(Schema.decodeUnknownSync(annotation.schema)),
608
+ );
609
+ };
@@ -0,0 +1,47 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Function from 'effect/Function';
6
+ import * as Option from 'effect/Option';
7
+ import * as Schema from 'effect/Schema';
8
+ import * as Types from 'effect/Types';
9
+
10
+ import type * as Annotation from '../../Annotation';
11
+
12
+ /**
13
+ * Unique identifier for an annotation.
14
+ */
15
+ export const Key = Schema.String.pipe(Schema.brand('~@dxos/echo/AnnotationKey'));
16
+ export type Key = Schema.Schema.Type<typeof Key>;
17
+
18
+ /**
19
+ * Set of annotation values stored on entity meta or nested in schemas.
20
+ */
21
+ export const Dictionary = Schema.Record({ key: Key, value: Schema.Unknown });
22
+ export interface Dictionary extends Schema.Schema.Type<typeof Dictionary> {}
23
+
24
+ /**
25
+ * Get the value of an annotation from a dictionary.
26
+ */
27
+ export const getDictionary = <T>(
28
+ values: Annotation.Dictionary,
29
+ annotation: Annotation.Annotation<T>,
30
+ ): Option.Option<T> => {
31
+ if (!(annotation.key in values)) {
32
+ return Option.none();
33
+ }
34
+
35
+ return Function.pipe(values[annotation.key], Schema.decodeUnknownSync(annotation.schema), Option.some);
36
+ };
37
+
38
+ /**
39
+ * Set the value of an annotation in a dictionary.
40
+ */
41
+ export const setDictionary = <T>(
42
+ values: Types.Mutable<Annotation.Dictionary>,
43
+ annotation: Annotation.Annotation<T>,
44
+ value: T,
45
+ ): void => {
46
+ values[annotation.key] = Schema.encodeSync(annotation.schema)(value);
47
+ };
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Option from 'effect/Option';
6
+
7
+ import type * as Annotation from '../../Annotation';
8
+ import type * as Entity from '../../Entity';
9
+ import { getMetaChecked } from '../common/api/meta';
10
+ import { type Mutable } from '../common/proxy/reactive';
11
+ import { isEntity, isSnapshot } from '../Entity/guard';
12
+ import { getDictionary, setDictionary } from './dictionary';
13
+
14
+ /**
15
+ * Get the value of an annotation from an entity instance or snapshot.
16
+ */
17
+ export const get = <T>(
18
+ target: Entity.Unknown | Entity.Snapshot,
19
+ annotation: Annotation.Annotation<T>,
20
+ ): Option.Option<T> => {
21
+ if (isEntity(target) || isSnapshot(target)) {
22
+ const meta = getMetaChecked(target);
23
+ return getDictionary(meta.annotations, annotation);
24
+ } else {
25
+ throw new TypeError('Target is not an annotation target.');
26
+ }
27
+ };
28
+
29
+ /**
30
+ * Set the value of an annotation on an entity instance.
31
+ * Must be called with a mutable entity — i.e. inside an `Obj.update` callback.
32
+ */
33
+ export const set = <T>(target: Mutable<Entity.Unknown>, annotation: Annotation.Annotation<T>, value: T): void => {
34
+ if (isEntity(target)) {
35
+ const meta = getMetaChecked(target);
36
+ setDictionary(meta.annotations, annotation, value);
37
+ } else {
38
+ throw new TypeError('Target is not an annotation target.');
39
+ }
40
+ };
@@ -2,6 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './annotations';
6
- export * from './sorting';
5
+ export * from './dictionary';
7
6
  export * from './util';
7
+ export * from './sorting';
8
+ export * from './annotations';
9
+ export * from './entity-dictionary';
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import type * as Option from 'effect/Option';
5
+ import * as Option from 'effect/Option';
6
6
  import type * as Schema from 'effect/Schema';
7
7
  import * as SchemaAST from 'effect/SchemaAST';
8
8
 
@@ -13,7 +13,12 @@ import { EntityKind } from '../common/types';
13
13
 
14
14
  export interface AnnotationHelper<T> {
15
15
  /**
16
- * Get the annotation value from the schema.
16
+ * Get the annotation value from an Effect schema.
17
+ *
18
+ * Only accepts `Schema.Schema.Any` — to read an annotation off a `Type.Type`
19
+ * entity, unwrap it first with `Type.getSchema(entity)`. This keeps the
20
+ * annotation pipeline single-shaped and forces annotations to live on the
21
+ * source schema, not on the post-construction Type entity.
17
22
  */
18
23
  get: (schema: Schema.Schema.Any) => Option.Option<T>;
19
24
  /**
@@ -21,7 +26,11 @@ export interface AnnotationHelper<T> {
21
26
  */
22
27
  getFromAst: (ast: SchemaAST.AST) => Option.Option<T>;
23
28
  /**
24
- * Set the annotation value on the schema.
29
+ * Set the annotation on an Effect schema.
30
+ *
31
+ * Only accepts `Schema.Schema.Any` — annotations must be applied to the
32
+ * source schema BEFORE wrapping it with `Type.makeObject` / `Type.makeRelation`.
33
+ * In a pipe, place every `Annotation.X.set(...)` before the `Type.make...` step.
25
34
  */
26
35
  set: (value: T) => <S extends Schema.Schema.Any>(schema: S) => S;
27
36
  }
@@ -30,13 +39,14 @@ export interface AnnotationHelper<T> {
30
39
  * Note: only for system annotations.
31
40
  */
32
41
  // TODO(dmaretskyi): Rename to createSystemAnnotationHelper.
42
+ // TODO(dmaretskyi): REconcile with Annotation.make.
33
43
  export const createAnnotationHelper = <T>(id: symbol): AnnotationHelper<T> => {
34
44
  return {
35
45
  get: (schema) => SchemaAST.getAnnotation(schema.ast, id),
36
46
  getFromAst: (ast) => SchemaAST.getAnnotation(ast, id),
37
47
  set:
38
48
  (value) =>
39
- <S extends Schema.Schema.Any>(schema: S) =>
49
+ <S extends Schema.Schema.Any>(schema: S): S =>
40
50
  schema.annotations({ [id]: value }) as S,
41
51
  };
42
52
  };
@@ -69,13 +79,12 @@ export const makeTypeJsonSchemaAnnotation = (options: {
69
79
  assertArgument(!!options.relationSource === (options.kind === EntityKind.Relation), 'relationSource');
70
80
  assertArgument(!!options.relationTarget === (options.kind === EntityKind.Relation), 'relationTarget');
71
81
 
72
- const obj = {
73
- // TODO(dmaretskyi): Should this include the version?
74
- $id: options.identifier ?? DXN.fromTypename(options.typename).toString(),
82
+ const obj: Record<string, unknown> = {
83
+ $id: options.identifier ?? DXN.make(options.typename, options.version),
75
84
  entityKind: options.kind,
76
85
  version: options.version,
77
86
  typename: options.typename,
78
- } as any;
87
+ };
79
88
  if (options.kind === EntityKind.Relation) {
80
89
  obj.relationSource = { $ref: options.relationSource };
81
90
  obj.relationTarget = { $ref: options.relationTarget };