@dxos/echo 0.9.1-main.c7dcc2e112 → 0.9.1-staging.ee54ba693a

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 (278) hide show
  1. package/dist/lib/neutral/Annotation.mjs +22 -8
  2. package/dist/lib/neutral/Database.mjs +3 -3
  3. package/dist/lib/neutral/Entity.mjs +11 -11
  4. package/dist/lib/neutral/Err.mjs +7 -3
  5. package/dist/lib/neutral/Feed.mjs +15 -19
  6. package/dist/lib/neutral/Filter.mjs +13 -11
  7. package/dist/lib/neutral/Format.mjs +3 -7
  8. package/dist/lib/neutral/JsonSchema.mjs +7 -7
  9. package/dist/lib/neutral/Migration.mjs +11 -11
  10. package/dist/lib/neutral/Obj.mjs +15 -13
  11. package/dist/lib/neutral/Order.mjs +1 -1
  12. package/dist/lib/neutral/Query.mjs +17 -17
  13. package/dist/lib/neutral/QueryResult.mjs +1 -1
  14. package/dist/lib/neutral/Ref.mjs +6 -6
  15. package/dist/lib/neutral/Registry.mjs +1 -1
  16. package/dist/lib/neutral/Relation.mjs +12 -12
  17. package/dist/lib/neutral/Tag.mjs +15 -15
  18. package/dist/lib/neutral/Text.mjs +25 -0
  19. package/dist/lib/neutral/Text.mjs.map +7 -0
  20. package/dist/lib/neutral/Type.mjs +10 -10
  21. package/dist/lib/neutral/chunk-2HKGAQM4.mjs +1394 -0
  22. package/dist/lib/neutral/chunk-2HKGAQM4.mjs.map +7 -0
  23. package/dist/lib/neutral/{chunk-O6BH7EPN.mjs → chunk-2ZHECXUR.mjs} +5 -4
  24. package/dist/lib/neutral/chunk-2ZHECXUR.mjs.map +7 -0
  25. package/dist/lib/neutral/{chunk-AFANXSGV.mjs → chunk-3KTE2Y7Q.mjs} +20 -20
  26. package/dist/lib/neutral/chunk-3KTE2Y7Q.mjs.map +7 -0
  27. package/dist/lib/neutral/{chunk-WZ32BF53.mjs → chunk-3TN2VMI4.mjs} +49 -37
  28. package/dist/lib/neutral/chunk-3TN2VMI4.mjs.map +7 -0
  29. package/dist/lib/neutral/{chunk-E7IOTOZD.mjs → chunk-42L4HJ3Z.mjs} +11 -15
  30. package/dist/lib/neutral/chunk-42L4HJ3Z.mjs.map +7 -0
  31. package/dist/lib/neutral/{chunk-K3S7D5PR.mjs → chunk-4A2NWKRJ.mjs} +5 -5
  32. package/dist/lib/neutral/chunk-ACFAOTKJ.mjs +1531 -0
  33. package/dist/lib/neutral/chunk-ACFAOTKJ.mjs.map +7 -0
  34. package/dist/lib/neutral/{chunk-Z3WMRRAZ.mjs → chunk-BEFR7LEA.mjs} +11 -9
  35. package/dist/lib/neutral/{chunk-Z3WMRRAZ.mjs.map → chunk-BEFR7LEA.mjs.map} +1 -1
  36. package/dist/lib/neutral/{chunk-6M2Z6WBH.mjs → chunk-BXIKXT7Q.mjs} +2 -6
  37. package/dist/lib/neutral/{chunk-6M2Z6WBH.mjs.map → chunk-BXIKXT7Q.mjs.map} +1 -1
  38. package/dist/lib/neutral/{chunk-3JXQUMUI.mjs → chunk-C57XMMBY.mjs} +21 -20
  39. package/dist/lib/neutral/chunk-C57XMMBY.mjs.map +7 -0
  40. package/dist/lib/neutral/{chunk-JZ6LFQU5.mjs → chunk-C62JYFAD.mjs} +82 -8
  41. package/dist/lib/neutral/chunk-C62JYFAD.mjs.map +7 -0
  42. package/dist/lib/neutral/{chunk-TF5BSLF6.mjs → chunk-FSGX2R62.mjs} +3 -3
  43. package/dist/lib/neutral/chunk-FSGX2R62.mjs.map +7 -0
  44. package/dist/lib/neutral/{chunk-6CEISA3V.mjs → chunk-HBXT3GSB.mjs} +29 -15
  45. package/dist/lib/neutral/chunk-HBXT3GSB.mjs.map +7 -0
  46. package/dist/lib/neutral/{chunk-WU3GIANS.mjs → chunk-IQR45HAD.mjs} +1 -1
  47. package/dist/lib/neutral/chunk-IQR45HAD.mjs.map +7 -0
  48. package/dist/lib/neutral/{chunk-TFEWTY5A.mjs → chunk-KCBW4BR6.mjs} +4 -8
  49. package/dist/lib/neutral/chunk-KCBW4BR6.mjs.map +7 -0
  50. package/dist/lib/neutral/{chunk-4TPQZPLY.mjs → chunk-L3E5IXAE.mjs} +198 -30
  51. package/dist/lib/neutral/chunk-L3E5IXAE.mjs.map +7 -0
  52. package/dist/lib/neutral/{chunk-EVK6XBXO.mjs → chunk-PRC4FEKJ.mjs} +2 -2
  53. package/dist/lib/neutral/chunk-PRC4FEKJ.mjs.map +7 -0
  54. package/dist/lib/neutral/{chunk-NOL7O3BL.mjs → chunk-SCT6FFCR.mjs} +9 -4
  55. package/dist/lib/neutral/chunk-SCT6FFCR.mjs.map +7 -0
  56. package/dist/lib/neutral/{chunk-BBFJWWAV.mjs → chunk-TOCVVFK2.mjs} +26 -2
  57. package/dist/lib/neutral/chunk-TOCVVFK2.mjs.map +7 -0
  58. package/dist/lib/neutral/{chunk-A53NTBHE.mjs → chunk-U53LSQQA.mjs} +3 -3
  59. package/dist/lib/neutral/{chunk-A53NTBHE.mjs.map → chunk-U53LSQQA.mjs.map} +1 -1
  60. package/dist/lib/neutral/{chunk-PLDMJJJC.mjs → chunk-UGFFV2FR.mjs} +2 -2
  61. package/dist/lib/neutral/{chunk-35INCYOE.mjs → chunk-UWLP4RFM.mjs} +1 -1
  62. package/dist/lib/neutral/chunk-UWLP4RFM.mjs.map +7 -0
  63. package/dist/lib/neutral/{chunk-SZ5WB6HF.mjs → chunk-UZHCQ6NI.mjs} +13 -11
  64. package/dist/lib/neutral/{chunk-SZ5WB6HF.mjs.map → chunk-UZHCQ6NI.mjs.map} +3 -3
  65. package/dist/lib/neutral/{chunk-L3OBWBV2.mjs → chunk-WKIT2YY5.mjs} +2 -2
  66. package/dist/lib/neutral/{chunk-HGWQR5KH.mjs → chunk-XB6ISRAO.mjs} +27 -15
  67. package/dist/lib/neutral/chunk-XB6ISRAO.mjs.map +7 -0
  68. package/dist/lib/neutral/chunk-XXL42WCB.mjs +84 -0
  69. package/dist/lib/neutral/chunk-XXL42WCB.mjs.map +7 -0
  70. package/dist/lib/neutral/{chunk-5GAIWRQB.mjs → chunk-XXWK4J53.mjs} +27 -42
  71. package/dist/lib/neutral/chunk-XXWK4J53.mjs.map +7 -0
  72. package/dist/lib/neutral/index.mjs +30 -26
  73. package/dist/lib/neutral/internal/index.mjs +91 -69
  74. package/dist/lib/neutral/meta.json +1 -1
  75. package/dist/lib/neutral/testing/index.mjs +79 -60
  76. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  77. package/dist/types/src/Annotation.d.ts +35 -1
  78. package/dist/types/src/Annotation.d.ts.map +1 -1
  79. package/dist/types/src/Collection.d.ts +9 -8
  80. package/dist/types/src/Collection.d.ts.map +1 -1
  81. package/dist/types/src/Database.d.ts +16 -0
  82. package/dist/types/src/Database.d.ts.map +1 -1
  83. package/dist/types/src/Dataset.d.ts +1 -16
  84. package/dist/types/src/Dataset.d.ts.map +1 -1
  85. package/dist/types/src/Err.d.ts +67 -0
  86. package/dist/types/src/Err.d.ts.map +1 -1
  87. package/dist/types/src/Feed.d.ts +56 -80
  88. package/dist/types/src/Feed.d.ts.map +1 -1
  89. package/dist/types/src/Filter.d.ts +9 -1
  90. package/dist/types/src/Filter.d.ts.map +1 -1
  91. package/dist/types/src/Hypergraph.d.ts +2 -9
  92. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  93. package/dist/types/src/Migration.d.ts +1 -1
  94. package/dist/types/src/Migration.d.ts.map +1 -1
  95. package/dist/types/src/Obj.d.ts +31 -6
  96. package/dist/types/src/Obj.d.ts.map +1 -1
  97. package/dist/types/src/Order.d.ts +1 -1
  98. package/dist/types/src/Order.d.ts.map +1 -1
  99. package/dist/types/src/Query.d.ts +1 -1
  100. package/dist/types/src/Query.d.ts.map +1 -1
  101. package/dist/types/src/QueryResult.d.ts +2 -2
  102. package/dist/types/src/QueryResult.d.ts.map +1 -1
  103. package/dist/types/src/Ref.d.ts +8 -4
  104. package/dist/types/src/Ref.d.ts.map +1 -1
  105. package/dist/types/src/Registry.d.ts +1 -1
  106. package/dist/types/src/Relation.d.ts.map +1 -1
  107. package/dist/types/src/Tag.d.ts +11 -13
  108. package/dist/types/src/Tag.d.ts.map +1 -1
  109. package/dist/types/src/Text.d.ts +41 -0
  110. package/dist/types/src/Text.d.ts.map +1 -0
  111. package/dist/types/src/Text.test.d.ts +2 -0
  112. package/dist/types/src/Text.test.d.ts.map +1 -0
  113. package/dist/types/src/Type.d.ts +33 -20
  114. package/dist/types/src/Type.d.ts.map +1 -1
  115. package/dist/types/src/View.d.ts +8 -9
  116. package/dist/types/src/View.d.ts.map +1 -1
  117. package/dist/types/src/index.d.ts +1 -0
  118. package/dist/types/src/index.d.ts.map +1 -1
  119. package/dist/types/src/internal/Annotation/annotations.d.ts +9 -0
  120. package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
  121. package/dist/types/src/internal/Annotation/atoms.d.ts +14 -0
  122. package/dist/types/src/internal/Annotation/atoms.d.ts.map +1 -0
  123. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +13 -0
  124. package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -1
  125. package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
  126. package/dist/types/src/internal/Entity/guard.d.ts.map +1 -1
  127. package/dist/types/src/internal/Entity/model.d.ts +1 -1
  128. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  129. package/dist/types/src/internal/Entity/object.d.ts +5 -1
  130. package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
  131. package/dist/types/src/internal/Entity/relation.d.ts +7 -0
  132. package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
  133. package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -1
  134. package/dist/types/src/internal/Filter/index.d.ts +2 -0
  135. package/dist/types/src/internal/Filter/index.d.ts.map +1 -0
  136. package/dist/types/src/internal/Filter/match.d.ts +22 -0
  137. package/dist/types/src/internal/Filter/match.d.ts.map +1 -0
  138. package/dist/types/src/internal/Format/format.d.ts +0 -2
  139. package/dist/types/src/internal/Format/format.d.ts.map +1 -1
  140. package/dist/types/src/internal/Format/index.d.ts +2 -2
  141. package/dist/types/src/internal/Format/index.d.ts.map +1 -1
  142. package/dist/types/src/internal/Format/string.d.ts +0 -8
  143. package/dist/types/src/internal/Format/string.d.ts.map +1 -1
  144. package/dist/types/src/internal/Format/types.d.ts +2 -1
  145. package/dist/types/src/internal/Format/types.d.ts.map +1 -1
  146. package/dist/types/src/internal/Obj/atoms.d.ts +7 -3
  147. package/dist/types/src/internal/Obj/atoms.d.ts.map +1 -1
  148. package/dist/types/src/internal/Obj/clone.d.ts +2 -1
  149. package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
  150. package/dist/types/src/internal/Obj/create-object.d.ts +3 -4
  151. package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
  152. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
  153. package/dist/types/src/internal/Query/index.d.ts +1 -0
  154. package/dist/types/src/internal/Query/index.d.ts.map +1 -1
  155. package/dist/types/src/internal/Query/query-result-effect.d.ts +9 -0
  156. package/dist/types/src/internal/Query/query-result-effect.d.ts.map +1 -0
  157. package/dist/types/src/internal/Ref/atoms.d.ts +1 -2
  158. package/dist/types/src/internal/Ref/atoms.d.ts.map +1 -1
  159. package/dist/types/src/internal/Ref/ref.d.ts +13 -6
  160. package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
  161. package/dist/types/src/internal/common/atom-snapshot.d.ts +8 -0
  162. package/dist/types/src/internal/common/atom-snapshot.d.ts.map +1 -0
  163. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
  164. package/dist/types/src/internal/common/proxy/proxy-types.d.ts +12 -0
  165. package/dist/types/src/internal/common/proxy/proxy-types.d.ts.map +1 -1
  166. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts +25 -0
  167. package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
  168. package/dist/types/src/internal/common/proxy/schema-validator.d.ts +5 -0
  169. package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
  170. package/dist/types/src/internal/common/proxy/typed-handler.d.ts +17 -0
  171. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
  172. package/dist/types/src/internal/common/types/entity.d.ts +4 -4
  173. package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
  174. package/dist/types/src/internal/common/types/meta.d.ts +2 -4
  175. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
  176. package/dist/types/src/internal/index.d.ts +1 -0
  177. package/dist/types/src/internal/index.d.ts.map +1 -1
  178. package/dist/types/src/testing/test-schema.d.ts +42 -171
  179. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  180. package/dist/types/tsconfig.tsbuildinfo +1 -1
  181. package/package.json +20 -13
  182. package/src/Annotation.test.ts +257 -10
  183. package/src/Annotation.ts +55 -6
  184. package/src/Collection.ts +10 -12
  185. package/src/Database.ts +22 -20
  186. package/src/Err.ts +22 -0
  187. package/src/Feed.ts +114 -141
  188. package/src/Filter.test.ts +38 -0
  189. package/src/Filter.ts +17 -3
  190. package/src/Hypergraph.ts +2 -11
  191. package/src/Migration.ts +1 -1
  192. package/src/Obj.test.ts +92 -12
  193. package/src/Obj.ts +36 -5
  194. package/src/Order.ts +3 -3
  195. package/src/Query.test.ts +2 -2
  196. package/src/Query.ts +16 -16
  197. package/src/QueryResult.ts +2 -2
  198. package/src/Ref.ts +12 -4
  199. package/src/Registry.ts +1 -1
  200. package/src/Relation.ts +1 -1
  201. package/src/Tag.ts +12 -16
  202. package/src/Text.test.ts +186 -0
  203. package/src/Text.ts +116 -0
  204. package/src/Type.test.ts +52 -24
  205. package/src/Type.ts +69 -31
  206. package/src/View.ts +22 -30
  207. package/src/index.ts +1 -1
  208. package/src/internal/Annotation/annotations.ts +15 -2
  209. package/src/internal/Annotation/atoms.ts +107 -0
  210. package/src/internal/Annotation/entity-dictionary.ts +40 -37
  211. package/src/internal/Entity/api.ts +1 -1
  212. package/src/internal/Entity/guard.ts +2 -1
  213. package/src/internal/Entity/model.ts +2 -2
  214. package/src/internal/Entity/object.ts +14 -1
  215. package/src/internal/Entity/relation.ts +19 -0
  216. package/src/internal/Entity/type-uri.ts +3 -1
  217. package/src/internal/Filter/index.ts +5 -0
  218. package/src/internal/Filter/match.ts +284 -0
  219. package/src/internal/Format/format.ts +0 -2
  220. package/src/internal/Format/index.ts +2 -2
  221. package/src/internal/Format/string.ts +0 -12
  222. package/src/internal/Format/types.ts +4 -2
  223. package/src/internal/JsonSchema/json-schema.test.ts +82 -54
  224. package/src/internal/Obj/atoms.ts +31 -18
  225. package/src/internal/Obj/clone.ts +61 -20
  226. package/src/internal/Obj/create-object.test.ts +3 -3
  227. package/src/internal/Obj/create-object.ts +3 -4
  228. package/src/internal/Obj/inspect.ts +1 -1
  229. package/src/internal/Obj/json-serializer.test.ts +7 -5
  230. package/src/internal/Obj/json-serializer.ts +1 -1
  231. package/src/internal/Obj/schema-validator.test.ts +53 -0
  232. package/src/internal/Obj/set-value.test.ts +29 -19
  233. package/src/internal/Query/index.ts +1 -0
  234. package/src/internal/Query/query-result-effect.ts +35 -0
  235. package/src/internal/Ref/atoms.ts +23 -3
  236. package/src/internal/Ref/ref.test.ts +8 -8
  237. package/src/internal/Ref/ref.ts +26 -20
  238. package/src/internal/common/atom-snapshot.ts +19 -0
  239. package/src/internal/common/proxy/make-object.ts +1 -1
  240. package/src/internal/common/proxy/proxy-types.ts +20 -0
  241. package/src/internal/common/proxy/proxy-utils.ts +37 -1
  242. package/src/internal/common/proxy/reactive-array.ts +3 -3
  243. package/src/internal/common/proxy/reactive.test.ts +1 -1
  244. package/src/internal/common/proxy/schema-validator.ts +181 -8
  245. package/src/internal/common/proxy/typed-handler.ts +254 -76
  246. package/src/internal/common/types/entity.ts +15 -7
  247. package/src/internal/index.ts +1 -0
  248. package/src/testing/test-schema.ts +75 -90
  249. package/dist/lib/neutral/chunk-35INCYOE.mjs.map +0 -7
  250. package/dist/lib/neutral/chunk-3JXQUMUI.mjs.map +0 -7
  251. package/dist/lib/neutral/chunk-4TPQZPLY.mjs.map +0 -7
  252. package/dist/lib/neutral/chunk-5GAIWRQB.mjs.map +0 -7
  253. package/dist/lib/neutral/chunk-6CEISA3V.mjs.map +0 -7
  254. package/dist/lib/neutral/chunk-AFANXSGV.mjs.map +0 -7
  255. package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +0 -7
  256. package/dist/lib/neutral/chunk-E7IOTOZD.mjs.map +0 -7
  257. package/dist/lib/neutral/chunk-EVK6XBXO.mjs.map +0 -7
  258. package/dist/lib/neutral/chunk-HGWQR5KH.mjs.map +0 -7
  259. package/dist/lib/neutral/chunk-JZ6LFQU5.mjs.map +0 -7
  260. package/dist/lib/neutral/chunk-NOL7O3BL.mjs.map +0 -7
  261. package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +0 -7
  262. package/dist/lib/neutral/chunk-TF5BSLF6.mjs.map +0 -7
  263. package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +0 -7
  264. package/dist/lib/neutral/chunk-VQYL2OQF.mjs +0 -2353
  265. package/dist/lib/neutral/chunk-VQYL2OQF.mjs.map +0 -7
  266. package/dist/lib/neutral/chunk-WU3GIANS.mjs.map +0 -7
  267. package/dist/lib/neutral/chunk-WZ32BF53.mjs.map +0 -7
  268. package/dist/lib/neutral/chunk-X3NUUON4.mjs +0 -184
  269. package/dist/lib/neutral/chunk-X3NUUON4.mjs.map +0 -7
  270. package/dist/types/src/exemplars.test.d.ts +0 -2
  271. package/dist/types/src/exemplars.test.d.ts.map +0 -1
  272. package/dist/types/src/hierarchy.test.d.ts +0 -2
  273. package/dist/types/src/hierarchy.test.d.ts.map +0 -1
  274. package/src/exemplars.test.ts +0 -21
  275. package/src/hierarchy.test.ts +0 -33
  276. /package/dist/lib/neutral/{chunk-K3S7D5PR.mjs.map → chunk-4A2NWKRJ.mjs.map} +0 -0
  277. /package/dist/lib/neutral/{chunk-PLDMJJJC.mjs.map → chunk-UGFFV2FR.mjs.map} +0 -0
  278. /package/dist/lib/neutral/{chunk-L3OBWBV2.mjs.map → chunk-WKIT2YY5.mjs.map} +0 -0
@@ -41,13 +41,21 @@ export type SnapshotKindId = typeof SnapshotKindId;
41
41
  export const StaticTypeSchemaSlot = '~@dxos/echo/Type.StaticSchema' as const;
42
42
  export type StaticTypeSchemaSlot = typeof StaticTypeSchemaSlot;
43
43
 
44
+ /**
45
+ * Whether a value can carry an entity brand/slot. Class-declared types
46
+ * Class-declared types (`Type.makeObject`) are functions whose prototype chain reaches the entity,
47
+ * so brand/slot lookups must accept functions as well as plain objects.
48
+ */
49
+ const isBrandCarrier = (value: unknown): boolean =>
50
+ value != null && (typeof value === 'object' || typeof value === 'function');
51
+
44
52
  /**
45
53
  * Read the hidden `StaticTypeSchemaSlot` off any value that may carry one.
46
- * Returns `undefined` for raw schemas (no slot) and non-object inputs.
54
+ * Returns `undefined` for raw schemas (no slot) and inputs that cannot carry a brand.
47
55
  * Single point-of-cast for the slot lookup.
48
56
  */
49
57
  export const getStaticTypeSchema = (value: unknown): Schema.Schema.AnyNoContext | undefined => {
50
- if (value == null || typeof value !== 'object') {
58
+ if (!isBrandCarrier(value)) {
51
59
  return undefined;
52
60
  }
53
61
  return (value as { [StaticTypeSchemaSlot]?: Schema.Schema.AnyNoContext })[StaticTypeSchemaSlot];
@@ -55,11 +63,11 @@ export const getStaticTypeSchema = (value: unknown): Schema.Schema.AnyNoContext
55
63
 
56
64
  /**
57
65
  * Read the `[SchemaKindId]` brand off a value. Returns `undefined` for raw
58
- * schemas (which don't carry the brand on their static type) and non-object
59
- * inputs. Single point-of-cast for the brand lookup.
66
+ * schemas (which don't carry the brand on their static type) and inputs that
67
+ * cannot carry a brand. Single point-of-cast for the brand lookup.
60
68
  */
61
69
  export const getSchemaKind = (value: unknown): EntityKind | undefined => {
62
- if (value == null || typeof value !== 'object') {
70
+ if (!isBrandCarrier(value)) {
63
71
  return undefined;
64
72
  }
65
73
  return (value as { [SchemaKindId]?: EntityKind })[SchemaKindId];
@@ -67,10 +75,10 @@ export const getSchemaKind = (value: unknown): EntityKind | undefined => {
67
75
 
68
76
  /**
69
77
  * Read the `[KindId]` brand off a value. Returns `undefined` for raw schemas
70
- * and non-object inputs. Companion to {@link getSchemaKind}.
78
+ * and inputs that cannot carry a brand. Companion to {@link getSchemaKind}.
71
79
  */
72
80
  export const getEntityKindBrand = (value: unknown): EntityKind | undefined => {
73
- if (value == null || typeof value !== 'object') {
81
+ if (!isBrandCarrier(value)) {
74
82
  return undefined;
75
83
  }
76
84
  return (value as { [KindId]?: EntityKind })[KindId];
@@ -5,6 +5,7 @@
5
5
  export * from './Annotation';
6
6
  export * from './common';
7
7
  export * from './Entity';
8
+ export * from './Filter';
8
9
  export * from './Format';
9
10
  export * from './JsonSchema';
10
11
  // TODO(wittjosiah): Required to ensure types are portable (need to export all types required for downstream inference).
@@ -19,11 +19,9 @@ export namespace TestSchema {
19
19
  * Expando object is an object with an arbitrary set of properties.
20
20
  * This is the test variant with example.com namespace.
21
21
  */
22
- export const Expando = Schema.Struct({}, { key: Schema.String, value: Schema.Any }).pipe(
23
- Type.makeObject(DXN.make('com.example.type.expando', '0.1.0')),
24
- );
25
-
26
- export type Expando = Type.InstanceType<typeof Expando>;
22
+ export class Expando extends Type.makeObject<Expando>(DXN.make('com.example.type.expando', '0.1.0'))(
23
+ Schema.Struct({}, { key: Schema.String, value: Schema.Any }),
24
+ ) {}
27
25
 
28
26
  //
29
27
  // Example
@@ -62,10 +60,7 @@ export namespace TestSchema {
62
60
  export interface ExampleSchema extends Schema.Schema.Type<typeof ExampleSchema> {}
63
61
 
64
62
  /** @deprecated Use another test schema or create a specific local test schema. */
65
- export const Example = ExampleSchema.pipe(Type.makeObject(DXN.make('com.example.type.example', '0.1.0')));
66
-
67
- /** @deprecated Use another test schema or create a specific local test schema. */
68
- export interface Example extends Type.InstanceType<typeof Example> {}
63
+ export class Example extends Type.makeObject<Example>(DXN.make('com.example.type.example', '0.1.0'))(ExampleSchema) {}
69
64
 
70
65
  //
71
66
  // Message
@@ -81,100 +76,90 @@ export namespace TestSchema {
81
76
  ),
82
77
  });
83
78
 
84
- export const Message = MessageStruct.pipe(Type.makeObject(DXN.make('com.example.type.message', '0.1.0')));
85
-
86
- export type Message = Type.InstanceType<typeof Message>;
79
+ export class Message extends Type.makeObject<Message>(DXN.make('com.example.type.message', '0.1.0'))(MessageStruct) {}
87
80
 
88
81
  //
89
82
  // Organization
90
83
  //
91
84
 
92
- export const Organization = Schema.Struct({
93
- name: Schema.String,
94
- properties: Schema.optional(
95
- Schema.Record({
96
- key: Schema.String,
97
- value: Schema.String,
98
- }),
99
- ),
100
- }).pipe(Type.makeObject(DXN.make('com.example.type.organization', '0.1.0')));
101
-
102
- export type Organization = Type.InstanceType<typeof Organization>;
85
+ export class Organization extends Type.makeObject<Organization>(DXN.make('com.example.type.organization', '0.1.0'))(
86
+ Schema.Struct({
87
+ name: Schema.String,
88
+ properties: Schema.optional(
89
+ Schema.Record({
90
+ key: Schema.String,
91
+ value: Schema.String,
92
+ }),
93
+ ),
94
+ }),
95
+ ) {}
103
96
 
104
97
  //
105
98
  // Person
106
99
  //
107
100
 
108
- export const Person = Schema.Struct({
109
- name: Schema.String,
110
- username: Schema.String,
111
- email: Schema.String,
112
- age: Schema.Number.pipe(Schema.optional),
113
- tasks: Schema.Array(Schema.suspend((): Ref.RefSchema<Task> => Ref.Ref(Task))),
114
- employer: Schema.optional(Ref.Ref(Organization)),
115
- address: Schema.Struct({
116
- city: Schema.optional(Schema.String),
117
- state: Schema.optional(Schema.String),
118
- zip: Schema.optional(Schema.String),
119
- coordinates: Schema.Struct({
120
- lat: Schema.optional(Schema.Number),
121
- lng: Schema.optional(Schema.Number),
101
+ export class Person extends Type.makeObject<Person>(DXN.make('com.example.type.person', '0.1.0'))(
102
+ Schema.Struct({
103
+ name: Schema.String,
104
+ username: Schema.String,
105
+ email: Schema.String,
106
+ age: Schema.Number.pipe(Schema.optional),
107
+ tasks: Schema.Array(Schema.suspend((): Ref.RefSchema<Task> => Ref.Ref(Task))),
108
+ employer: Schema.optional(Ref.Ref(Organization)),
109
+ address: Schema.Struct({
110
+ city: Schema.optional(Schema.String),
111
+ state: Schema.optional(Schema.String),
112
+ zip: Schema.optional(Schema.String),
113
+ coordinates: Schema.Struct({
114
+ lat: Schema.optional(Schema.Number),
115
+ lng: Schema.optional(Schema.Number),
116
+ }),
122
117
  }),
123
- }),
124
- fields: Schema.Struct({
125
- label: Schema.String,
126
- value: Schema.String,
127
- }).pipe(Schema.Array, Schema.optional),
128
- }).pipe(Schema.partial, Type.makeObject(DXN.make('com.example.type.person', '0.1.0')));
129
-
130
- export interface Person extends Type.InstanceType<typeof Person> {}
118
+ fields: Schema.Struct({
119
+ label: Schema.String,
120
+ value: Schema.String,
121
+ }).pipe(Schema.Array, Schema.optional),
122
+ }).pipe(Schema.partial),
123
+ ) {}
131
124
 
132
125
  //
133
126
  // Task
134
127
  //
135
128
 
136
- export const Task = Schema.Struct({
137
- title: Schema.optional(Schema.String),
138
- deadline: Schema.optional(Schema.String),
139
- completed: Schema.optional(Schema.Boolean),
140
- assignee: Schema.optional(Ref.Ref(Person)),
141
- previous: Schema.optional(Schema.suspend((): Ref.RefSchema<Task> => Ref.Ref(Task))),
142
- subTasks: Schema.optional(Schema.Array(Schema.suspend((): Ref.RefSchema<Task> => Ref.Ref(Task)))),
143
- description: Schema.optional(Schema.String),
144
- }).pipe(Schema.partial, Type.makeObject(DXN.make('com.example.type.task', '0.1.0')));
145
-
146
- export interface Task extends Type.InstanceType<typeof Task> {}
129
+ export class Task extends Type.makeObject<Task>(DXN.make('com.example.type.task', '0.1.0'))(
130
+ Schema.Struct({
131
+ title: Schema.optional(Schema.String),
132
+ deadline: Schema.optional(Schema.String),
133
+ completed: Schema.optional(Schema.Boolean),
134
+ assignee: Schema.optional(Ref.Ref(Person)),
135
+ previous: Schema.optional(Schema.suspend((): Ref.RefSchema<Task> => Ref.Ref(Task))),
136
+ subTasks: Schema.optional(Schema.Array(Schema.suspend((): Ref.RefSchema<Task> => Ref.Ref(Task)))),
137
+ description: Schema.optional(Schema.String),
138
+ }).pipe(Schema.partial),
139
+ ) {}
147
140
 
148
141
  //
149
142
  // HasManager
150
143
  //
151
144
 
152
- export const HasManager = Schema.Struct({}).pipe(
153
- Type.makeRelation({
154
- dxn: DXN.make('com.example.type.hasManager', '0.1.0'),
155
- source: Person,
156
- target: Person,
157
- }),
158
- );
159
-
160
- export type HasManager = Type.InstanceType<typeof HasManager>;
145
+ export class HasManager extends Type.makeRelation<HasManager>(DXN.make('com.example.type.hasManager', '0.1.0'))({
146
+ source: Person,
147
+ target: Person,
148
+ })(Schema.Struct({})) {}
161
149
 
162
150
  //
163
151
  // EmployedBy
164
152
  //
165
153
 
166
- export const EmployedBy = Schema.Struct({
167
- role: Schema.String,
168
- since: Schema.optional(Schema.String),
169
- }).pipe(
170
- Type.makeRelation({
171
- dxn: DXN.make('com.example.type.employedBy', '0.1.0'),
172
- source: Person,
173
- target: Organization,
154
+ export class EmployedBy extends Type.makeRelation<EmployedBy>(DXN.make('com.example.type.employedBy', '0.1.0'))({
155
+ source: Person,
156
+ target: Organization,
157
+ })(
158
+ Schema.Struct({
159
+ role: Schema.String,
160
+ since: Schema.optional(Schema.String),
174
161
  }),
175
- );
176
-
177
- export type EmployedBy = Type.InstanceType<typeof EmployedBy>;
162
+ ) {}
178
163
 
179
164
  //
180
165
  // RecordType
@@ -186,19 +171,19 @@ export namespace TestSchema {
186
171
  WORK = 2,
187
172
  }
188
173
 
189
- export const Container = Schema.Struct({
190
- objects: Schema.Array(Ref.Ref(Obj.Unknown)),
191
- records: Schema.Array(
192
- Schema.partial(
193
- Schema.Struct({
194
- title: Schema.String,
195
- description: Schema.String,
196
- contacts: Schema.Array(Ref.Ref(Person)),
197
- type: Schema.Enums(RecordType),
198
- }),
174
+ export class Container extends Type.makeObject<Container>(DXN.make('com.example.type.container', '0.1.0'))(
175
+ Schema.Struct({
176
+ objects: Schema.Array(Ref.Ref(Obj.Unknown)),
177
+ records: Schema.Array(
178
+ Schema.partial(
179
+ Schema.Struct({
180
+ title: Schema.String,
181
+ description: Schema.String,
182
+ contacts: Schema.Array(Ref.Ref(Person)),
183
+ type: Schema.Enums(RecordType),
184
+ }),
185
+ ),
199
186
  ),
200
- ),
201
- }).pipe(Schema.partial, Type.makeObject(DXN.make('com.example.type.container', '0.1.0')));
202
-
203
- export type Container = Type.InstanceType<typeof Container>;
187
+ }).pipe(Schema.partial),
188
+ ) {}
204
189
  }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/QueryResult.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as Atom from '@effect-atom/atom/Atom';\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\n\nimport { type CleanupFn } from '@dxos/async';\n\nimport type * as Entity from './Entity';\n\n/**\n * Individual query result entry.\n */\nexport type Entry<T> = {\n id: string;\n\n /**\n * May not be present for remote results.\n */\n result?: T;\n\n match?: {\n // TODO(dmaretskyi): text positional info.\n\n /**\n * Higher means better match.\n */\n rank: number;\n };\n\n /**\n * Query resolution metadata.\n */\n // TODO(dmaretskyi): Rename to meta?\n resolution?: {\n // TODO(dmaretskyi): Make this more generic.\n source: 'remote' | 'local' | 'index';\n\n /**\n * Query resolution time in milliseconds.\n */\n time: number;\n };\n};\n\n/**\n * Invidual query result entry for a database Entity.\n */\nexport type EntityEntry<T extends Entity.Unknown = Entity.Unknown> = Entry<T>;\n\nexport type RunOptions = {\n timeout?: number;\n};\n\nexport type SubscriptionOptions = {\n /**\n * Fire the callback immediately.\n */\n fire?: boolean;\n};\n\n// TODO(burdon): Should T be constrained to Entity.Any?\nexport interface QueryResult<T> {\n /**\n * Currently available results along with their match metadata.\n */\n readonly entries: Entry<T>[];\n\n /**\n * Currently available results.\n */\n readonly results: T[];\n\n /**\n * Returns all known results.\n */\n run(opts?: RunOptions): Promise<T[]>;\n\n /**\n * Returns all known results along with their match metadata.\n */\n runEntries(opts?: RunOptions): Promise<Entry<T>[]>;\n\n /**\n * Returns currently available results synchronously.\n */\n runSync(): T[];\n\n /**\n * Returns currently available results synchronously along with their match metadata.\n */\n runSyncEntries(): Entry<T>[];\n\n /**\n * Returns first result.\n */\n first(opts?: RunOptions): Promise<T>;\n\n /**\n * Returns first result if there is one.\n */\n firstOrUndefined(opts?: RunOptions): Promise<T | undefined>;\n\n /**\n * Subscribes to changes in query results.\n */\n subscribe(callback?: (query: QueryResult<T>) => void, opts?: SubscriptionOptions): CleanupFn;\n\n /**\n * Self-updating atom. Updates automatically when query results change.\n *\n * Memoized per QueryResult instance — repeated accesses on the same instance return the same\n * Atom. Safe only when the QueryResult is itself held stable across re-renders (e.g. behind a\n * `useMemo`). It must NOT be used in graph-builder connectors/actions or other atom computes,\n * where `db.query(...)` is called fresh on each re-evaluation: every run constructs a new\n * QueryResult and so a new atom + subscription, leaking the previous ones. Use the memoized\n * {@link atom} family there instead.\n */\n readonly atom: Atom.Atom<T[]>;\n}\n\n/**\n * Effect that returns a QueryResult when evaluated, but also has shorthand methods for running the query or getting the first result.\n */\nexport interface QueryResultEffect<T, E, R> extends Effect.Effect<QueryResult<T>, E, R> {\n run: Effect.Effect<T[], E, R>;\n first: Effect.Effect<Option.Option<T>, E, R>;\n\n // TODO(dmaretskyi): Considering adding `atom`, but since `Database.query` is used in imperative code only, I dont think it will be useful.\n}\n"],
5
- "mappings": ";AAAA;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/index.ts", "../../../src/Hypergraph.ts", "../../../src/Json.ts", "../../../src/Collection.ts", "../../../src/View.ts", "../../../src/Dataset.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nexport { QueryAST } from '@dxos/echo-protocol';\nexport { DXN, EID, URI } from '@dxos/keys';\n\nexport * as Annotation from './Annotation';\nexport * as Database from './Database';\nexport * as Entity from './Entity';\n// TODO(burdon): Rename to Error (less problematic than Obj/Object).\nexport * as Err from './Err';\nexport * as Feed from './Feed';\nexport * as Filter from './Filter';\nexport * as Format from './Format';\nexport * as Hypergraph from './Hypergraph';\nexport * as Json from './Json';\nexport * as JsonSchema from './JsonSchema';\nexport * as Key from './Key';\nexport * as Migration from './Migration';\nexport * as Obj from './Obj';\nexport * as Order from './Order';\nexport * as Query from './Query';\nexport * as QueryResult from './QueryResult';\nexport * as Ref from './Ref';\nexport * as Registry from './Registry';\nexport * as Relation from './Relation';\nexport * as Scope from './Scope';\nexport * as Tag from './Tag';\nexport * as Type from './Type';\nexport * as Collection from './Collection';\nexport * as View from './View';\nexport * as Dataset from './Dataset';\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type URI } from '@dxos/keys';\n\nimport type * as Database from './Database';\nimport type * as Entity from './Entity';\nimport type * as internal from './internal';\nimport type * as Key from './Key';\nimport type * as Ref from './Ref';\nimport type * as Registry from './Registry';\n\n/**\n * Resolution context.\n * Affects how non-absolute DXNs are resolved.\n */\nexport interface RefResolutionContext {\n /**\n * Space that the resolution is happening from.\n */\n space?: Key.SpaceId;\n\n /**\n * Feed that the resolution is happening from.\n * This feed will be searched first, and then the space it belongs to.\n */\n feed?: URI.URI;\n}\n\nexport interface RefResolverOptions {\n /**\n * Resolution context.\n * Affects how non-absolute DXNs are resolved.\n */\n context?: RefResolutionContext;\n\n /**\n * Middleware to change the resolved object before returning it.\n * @deprecated On track to be removed.\n */\n middleware?: (obj: internal.AnyProperties) => internal.AnyProperties;\n}\n\n/**\n * Manages cross-space database interactions.\n */\nexport interface Hypergraph extends Database.Queryable {\n /**\n * In-process registry of keyed objects and static schema types.\n * Populated at startup via `registry.add(objects)` / `registry.add(schemas)`.\n * Queries that include no explicit from() clause will fan out to this registry automatically.\n */\n get registry(): Registry.Registry;\n\n /**\n * Query objects.\n */\n query: Database.QueryFn;\n\n /**\n * Creates a reference to an existing object in the database.\n *\n * NOTE: The reference may be dangling if the object is not present in the database.\n * NOTE: Difference from `Ref.fromURI`\n * `Ref.fromURI(dxn)` returns an unhydrated reference. The `.load` and `.target` APIs will not work.\n * `db.makeRef(dxn)` is preferable in cases with access to the database.\n */\n makeRef<T extends Entity.Unknown = Entity.Unknown>(uri: URI.URI): Ref.Ref<T>;\n\n /**\n * @param hostDb Host database for reference resolution.\n * @param middleware Called with the loaded object. The caller may change the object.\n * @returns Result of `onLoad`.\n */\n // TODO(dmaretskyi): Restructure API: Remove middleware.\n createRefResolver(options: RefResolverOptions): Ref.Resolver;\n\n /**\n * Get a database by space ID.\n * @returns The database for the given space ID, or undefined if not found.\n */\n getDatabase(spaceId: Key.SpaceId): Database.Database | undefined;\n}\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { EID } from '@dxos/keys';\n\nimport * as Database from './Database';\nimport * as Obj from './Obj';\n\n/**\n * `JSON.stringify` replacer signature.\n *\n * Defined here (rather than re-imported from a UI package) so other ECHO-aware utilities can\n * share a stable signature without creating a dependency edge into the UI tree.\n */\nexport type JsonReplacer = (key: string, value: any) => any;\n\nexport type CreateRefReplacerOptions = {\n db: Database.Database;\n /** How many ref hops to follow. `0` leaves all refs as-is. Default: `1`. */\n depth?: number;\n};\n\nconst isEncodedRef = (value: unknown): value is { '/': string } =>\n typeof value === 'object' &&\n value !== null &&\n Object.keys(value as object).length === 1 &&\n typeof (value as { '/': unknown })['/'] === 'string';\n\nconst toJson = (obj: Obj.Any): unknown => (typeof (obj as any).toJSON === 'function' ? (obj as any).toJSON() : obj);\n\n/**\n * Returns a {@link JsonReplacer} that inlines ECHO ref objects (`{ \"/\": \"echo:...\" }`) up to\n * `depth` ref hops. Beyond that depth refs are left in their encoded form.\n *\n * Implemented as a per-call `JSON.stringify` replacer (not a one-shot tree walk at root) so it\n * composes with wrappers like `safeStringify` that intercept the root call. JSON.stringify\n * already drives the recursion; we only need to (a) detect a ref at the current callback,\n * (b) resolve and return the target if hop budget remains, and (c) tag the returned object\n * with its hop count so children know how far in they are.\n *\n * The hop count is tracked per-object via a `WeakMap`: a ref-resolved target's children inherit\n * `parentHops + 1`; a regular intermediate object's children inherit `parentHops`. This makes the\n * budget count *ref hops*, not tree depth — a ref deep in a tree still resolves once when\n * `depth >= 1`.\n *\n * Note: ECHO objects' `toJSON` runs before the replacer is invoked, so by the time we see a\n * value refs are already encoded as `{ \"/\": \"dxn:...\" }`.\n */\nexport const createRefReplacer = ({ db, depth = 1 }: CreateRefReplacerOptions): JsonReplacer => {\n // Per-object hop count. Set when we return an object (via ref resolution or pass-through) so\n // the child callbacks (which carry that object as `this`) can read it.\n const hops = new WeakMap<object, number>();\n\n return function (this: any, key: string, value: any) {\n // Hop count for this call: hops at the parent, or 0 for the root.\n const parentHops = this && typeof this === 'object' ? (hops.get(this) ?? 0) : 0;\n if (isEncodedRef(value)) {\n if (parentHops >= depth) {\n return value;\n }\n\n // The `{ '/': string }` shape is shared with non-DXN IPLD-style refs (e.g. CIDs);\n // an unparseable string would otherwise crash the whole `JSON.stringify`.\n // Treat any parse miss as \"leave as-is\" rather than propagating.\n const dxnString = value['/'];\n if (!dxnString.startsWith('dxn:') && !dxnString.startsWith('echo:')) {\n return value;\n }\n\n let echoUri: string | undefined;\n try {\n const parsed = EID.tryParse(dxnString);\n echoUri = parsed ? EID.getEntityId(parsed) : undefined;\n } catch {\n return value;\n }\n\n if (!echoUri) {\n return value;\n }\n const target = db.getObjectById(echoUri);\n if (!target) {\n return value;\n }\n\n const encoded = toJson(target);\n if (encoded != null && typeof encoded === 'object') {\n // Children of the resolved target are one hop deeper.\n hops.set(encoded as object, parentHops + 1);\n }\n return encoded;\n }\n\n // Pass-through object: children inherit the parent's hop count (this branch doesn't burn\n // budget).\n if (value != null && typeof value === 'object') {\n hops.set(value, parentHops);\n }\n\n return value;\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { DXN } from '@dxos/keys';\n\nimport * as Annotation from './Annotation';\nimport * as internal from './internal';\nimport * as Obj from './Obj';\nimport * as Ref from './Ref';\nimport * as Type from './Type';\n\n/**\n * A an ordered set of objects.\n */\nexport const Collection = Schema.Struct({\n name: Schema.String.pipe(Schema.optional),\n objects: Schema.Array(Ref.Ref(Obj.Unknown)).pipe(internal.FormInputAnnotation.set(false)),\n}).pipe(\n Annotation.IconAnnotation.set({ icon: 'ph--folder--regular', hue: 'amber' }),\n Type.makeObject(DXN.make('org.dxos.type.collection', '0.1.0')),\n);\n\nexport type Collection = Type.InstanceType<typeof Collection>;\n\nexport const make = (props: Partial<Obj.MakeProps<typeof Collection>> = {}): Collection =>\n Obj.make(Collection, { objects: [], ...props });\n\nexport const isCollection: (value: unknown) => value is Collection = Obj.instanceOf(Collection);\n", "//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { QueryAST } from '@dxos/echo-protocol';\nimport { SchemaEx } from '@dxos/effect';\nimport { DXN, PublicKey } from '@dxos/keys';\n\nimport * as Annotation from './Annotation';\nimport * as Filter from './Filter';\nimport * as internal from './internal';\nimport * as Obj from './Obj';\nimport * as Query from './Query';\nimport * as Type from './Type';\n\n/**\n * Stored field metadata (e.g., for UX).\n */\nexport const FieldSchema = Schema.Struct({\n id: Schema.String,\n path: SchemaEx.JsonPath,\n visible: Schema.optional(Schema.Boolean),\n\n // TODO(wittjosiah): Presentation-specific?\n referencePath: Schema.optional(SchemaEx.JsonPath),\n});\n\nexport type FieldType = Schema.Schema.Type<typeof FieldSchema>;\n\nexport const KeyValueProps = Schema.Record({ key: Schema.String, value: Schema.Any });\n\nexport const createFieldId = () => PublicKey.random().truncate();\n\nexport const Projection = Schema.Struct({\n /**\n * Optional schema override used to customize the underlying schema.\n */\n schema: internal.JsonSchemaType.pipe(Schema.optional),\n\n /**\n * UX metadata associated with displayed fields (in table, form, etc.)\n */\n // TODO(wittjosiah): Should this just be an array of SchemaEx.JsonPath?\n fields: Schema.Array(FieldSchema),\n\n /**\n * The id for the field used to pivot the view.\n * E.g., the field to use for kanban columns or the field to use for map coordinates.\n */\n pivotFieldId: Schema.String.pipe(Schema.optional),\n});\n\nexport type Projection = Schema.Schema.Type<typeof Projection>;\n\n/**\n * Views are generated or user-defined projections of a schema's properties.\n * They are used to configure the visual representation of the data.\n */\nconst ViewSchema = Schema.Struct({\n /**\n * Query used to retrieve data.\n * Can be a user-provided query grammar string or a query AST.\n */\n query: Schema.Struct({\n raw: Schema.optional(Schema.String),\n ast: QueryAST.Query,\n }),\n\n /**\n * Projection of the data returned from the query.\n */\n projection: Projection,\n}).pipe(\n internal.HiddenAnnotation.set(true),\n Annotation.IconAnnotation.set({ icon: 'ph--funnel--regular', hue: 'green' }),\n Type.makeObject(DXN.make('org.dxos.type.view', '0.1.0')),\n);\n\n// NOTE: Declared as a named interface and the `View` const is annotated `Type.Obj<View>` so\n// downstream consumers see a named `View` type instead of the inlined `QueryAST.Query` union.\n// Without the named interface, embedding `Type.getSchema(View.View)` in a downstream\n// `Schema.Struct` triggers TS2742 portability errors (e.g. plugin-kanban, plugin-table).\n// TODO(wittjosiah): Find a better solution that doesn't require manually keeping the interface in sync.\nexport interface View extends Type.InstanceType<typeof ViewSchema> {}\n\nexport const View: Type.Obj<View> = ViewSchema as any;\n\nexport const make = (props: Partial<Obj.MakeProps<typeof View>>): View => {\n return Obj.make(View, {\n query: { ast: Query.select(Filter.nothing()).ast },\n projection: { fields: [] },\n ...props,\n });\n};\n", "//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport { pipe } from 'effect/Function';\nimport * as Predicate from 'effect/Predicate';\nimport * as Schema from 'effect/Schema';\n\nimport * as Collection from './Collection';\nimport * as Feed from './Feed';\nimport * as Obj from './Obj';\nimport * as Type from './Type';\nimport * as View from './View';\n\n/**\n * Abstract set of objects, represented by a view, feed, or collection.\n * Schema-level union of the underlying type entities (rebuilt via\n * `Type.getSchema`) so this can still be consumed by Schema-side APIs such\n * as `Filter.type(...)` on a union.\n */\nexport type Dataset = Feed.Feed | Collection.Collection | View.View;\nexport const Dataset = Schema.Union(\n Type.getSchema(Feed.Feed),\n Type.getSchema(Collection.Collection),\n Type.getSchema(View.View),\n);\n\nexport const isDataset: (value: unknown) => value is Dataset = pipe(\n Obj.instanceOf(Feed.Feed),\n Predicate.or(Obj.instanceOf(Collection.Collection)),\n Predicate.or(Obj.instanceOf(View.View)),\n);\n"],
5
- "mappings": "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",
6
- "names": ["QueryAST", "DXN", "EID", "URI", "EID", "isEncodedRef", "value", "Object", "keys", "length", "toJson", "obj", "toJSON", "createRefReplacer", "db", "depth", "hops", "WeakMap", "key", "parentHops", "get", "dxnString", "startsWith", "echoUri", "parsed", "tryParse", "getEntityId", "undefined", "target", "getObjectById", "encoded", "set", "make", "Schema", "DXN", "Collection", "Struct", "name", "String", "pipe", "optional", "objects", "Array", "Ref", "Unknown", "FormInputAnnotation", "set", "IconAnnotation", "icon", "hue", "makeObject", "DXN", "make", "props", "isCollection", "instanceOf", "make", "Schema", "QueryAST", "SchemaEx", "DXN", "PublicKey", "FieldSchema", "Struct", "id", "String", "path", "SchemaEx", "JsonPath", "visible", "optional", "Boolean", "referencePath", "KeyValueProps", "Record", "key", "value", "Any", "createFieldId", "PublicKey", "random", "truncate", "Projection", "schema", "JsonSchemaType", "pipe", "fields", "Array", "pivotFieldId", "ViewSchema", "query", "raw", "ast", "QueryAST", "Query", "projection", "HiddenAnnotation", "set", "IconAnnotation", "icon", "hue", "makeObject", "DXN", "make", "View", "props", "select", "nothing", "pipe", "Predicate", "Schema", "Dataset", "Union", "getSchema", "Feed", "Collection", "View", "isDataset", "pipe", "instanceOf", "or"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/internal/Ref/ref.ts", "../../../src/internal/Ref/atoms.ts", "../../../src/internal/Ref/utils.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport type * as Atom from '@effect-atom/atom/Atom';\nimport * as Effect from 'effect/Effect';\nimport * as Equal from 'effect/Equal';\nimport * as Hash from 'effect/Hash';\nimport * as Option from 'effect/Option';\nimport * as ParseResult from 'effect/ParseResult';\nimport * as Pipeable from 'effect/Pipeable';\nimport * as Schema from 'effect/Schema';\nimport * as SchemaAST from 'effect/SchemaAST';\nimport type * as Types from 'effect/Types';\n\nimport { Event } from '@dxos/async';\nimport { type CustomInspectFunction, inspectCustom } from '@dxos/debug';\nimport { EncodedReference } from '@dxos/echo-protocol';\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { DXN, EID, EntityId, type URI } from '@dxos/keys';\n\nimport * as Database from '../../Database';\nimport type * as Type from '../../Type';\nimport {\n ReferenceAnnotationId,\n getSchemaURI,\n getTypeAnnotation,\n getTypeIdentifierAnnotation,\n} from '../Annotation/annotations';\nimport { type AnyEntity, type AnyProperties, type UnknownTypeSchema, getStaticTypeSchema } from '../common/types';\nimport { type JsonSchemaType } from '../JsonSchema';\nimport * as RefAtoms from './atoms';\n\n/**\n * The `$id` and `$ref` fields for an ECHO reference schema.\n */\nexport const JSON_SCHEMA_ECHO_REF_ID = '/schemas/echo/ref';\n\nexport const getSchemaReference = (property: JsonSchemaType): { typename: string } | undefined => {\n const { $id, reference: { schema: { $ref } = {} } = {} } = property;\n if ($id === JSON_SCHEMA_ECHO_REF_ID && $ref) {\n const parsed = DXN.tryMake($ref);\n const typename = parsed ? DXN.getName(parsed) : undefined;\n return typename ? { typename } : undefined;\n }\n};\n\nexport const createSchemaReference = (typename: string): Types.DeepMutable<JsonSchemaType> => {\n return {\n $id: JSON_SCHEMA_ECHO_REF_ID,\n reference: {\n schema: {\n $ref: DXN.make(typename),\n },\n },\n };\n};\n\n/**\n * Runtime type-info for a reference extracted from effect AST.\n */\nexport type RefereneAST = {\n /**\n * Typename of linked schema.\n */\n typename: string;\n\n /**\n * Version of linked schema.\n */\n version: string;\n};\n\nexport const getReferenceAst = (ast: SchemaAST.AST): RefereneAST | undefined => {\n if (ast._tag !== 'Declaration' || !ast.annotations[ReferenceAnnotationId]) {\n return undefined;\n }\n return {\n typename: (ast.annotations[ReferenceAnnotationId] as any).typename,\n version: (ast.annotations[ReferenceAnnotationId] as any).version,\n };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const RefTypeId: unique symbol = Symbol.for('@dxos/echo/internal/Ref') as any;\n\n/**\n * Reference Schema.\n */\nexport interface RefSchema<T extends AnyEntity> extends Schema.SchemaClass<Ref<T>, EncodedReference> {}\n\n/**\n * Type of the `Ref` function and extra methods attached to it.\n */\nexport interface RefFn {\n // A reference target is a `Type.AnyEntity` entity (the canonical Option B\n // input) or one of the well-known \"any object\" / \"any relation\" branded\n // schemas (`Obj.Unknown` / `Relation.Unknown`). Arbitrary raw schemas are\n // rejected.\n //\n // Referencing a type-kind entity (a meta-schema, e.g. `Type.Type`) yields a\n // reference to a stored schema record; its loaded target is any registered\n // entity (`Type.AnyEntity`), since a stored object/relation schema is itself a\n // `Type.Type` record. Referencing an object/relation type yields a reference\n // to an instance of that type.\n <S extends Type.AnyEntity | UnknownTypeSchema<any, any> = Type.AnyEntity>(\n schema: S,\n ): RefSchema<\n S extends Type.AnyType\n ? Type.AnyEntity\n : S extends Type.AnyObj | Type.AnyRelation\n ? Type.InstanceType<S>\n : S extends UnknownTypeSchema<infer A, any>\n ? A\n : never\n >;\n\n /**\n * @returns True if the object is a reference.\n */\n isRef: (obj: unknown) => obj is Ref<any>;\n\n /**\n * @returns True if the reference points to the given object id.\n */\n hasEntityId: (id: EntityId) => (ref: Ref<any>) => boolean;\n\n /**\n * @returns True if the schema is a reference schema.\n */\n isRefSchema: (schema: Schema.Schema<any, any>) => schema is RefSchema<any>;\n\n /**\n * @returns True if the schema AST is a reference schema.\n */\n isRefSchemaAST: (ast: SchemaAST.AST) => boolean;\n\n /**\n * Constructs a reference that points to the given object.\n */\n // TODO(burdon): Narrow to Obj.Unknown?\n make: <T extends AnyEntity>(object: T) => Ref<T>;\n\n /**\n * Constructs a reference that points to the object specified by the provided URI\n * (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).\n */\n fromURI: (uri: URI.URI) => Ref<any>;\n}\n\n/**\n * Schema builder for references.\n */\nexport const Ref: RefFn = (input: any): RefSchema<any> => {\n // `Type.Type` entities carry their source schema on the hidden slot; the\n // branded `Obj.Unknown` / `Relation.Unknown` schemas are used directly.\n const schema = getStaticTypeSchema(input) ?? input;\n assertArgument(Schema.isSchema(schema), 'schema', 'Must call with an instance of effect-schema');\n const annotation = getTypeAnnotation(schema);\n if (annotation == null) {\n throw new Error('Reference target must be an ECHO schema.');\n }\n\n return createEchoReferenceSchema(getTypeIdentifierAnnotation(schema), annotation.typename, annotation.version);\n};\n\n/**\n * Represents materialized reference to a target.\n * This is the data type for the fields marked as ref.\n */\nexport interface Ref<T> extends Pipeable.Pipeable {\n /**\n * Target URI (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).\n */\n get uri(): URI.URI;\n\n /**\n * Returns true if the reference has a target available (inlined or resolver set).\n */\n get isAvailable(): boolean;\n\n /**\n * @returns The reference target.\n * May return `undefined` if the object is not loaded in the working set.\n * Accessing this property, even if it returns `undefined` will trigger the object to be loaded to the working set.\n */\n get target(): T | undefined;\n\n /**\n * @returns Promise that will resolves with the target object.\n * Will load the object from disk if it is not present in the working set.\n * @throws If the object is not available locally.\n */\n load(): Promise<T>;\n\n /**\n * @returns Promise that will resolves with the target object or undefined if the object is not loaded locally.\n */\n\n tryLoad(): Promise<T | undefined>;\n\n /**\n * Subscribe to the ref's resolution event.\n * The callback fires when the target object becomes available in the working set\n * (e.g. when its document is loaded after sibling-client mutation).\n * Note: the resolver only schedules a notification when the target is requested\n * via {@link target} while it is not yet loaded.\n * @returns Function that unsubscribes the callback.\n */\n onResolved(callback: () => void): () => void;\n\n /**\n * Do not inline the target object in the reference.\n * Makes .target unavailable unless the reference is connected to a database context.\n *\n * When serialized with toJSON, the difference is between:\n * `{ \"/\": \"dxn:...\" }`\n * and\n * `{ \"/\": \"dxn:...\", \"target\": { ... } }`\n *\n * Clones the reference object.\n */\n noInline(): Ref<T>;\n\n /**\n * Read-only atom for the ref target.\n * Resolves once when the target loads; does NOT subscribe to target object mutations.\n * Use `Obj.atom(ref)` if you need reactive snapshots that update on every object mutation.\n */\n get atom(): Atom.Atom<T | undefined>;\n\n /**\n * Serializes the reference to a JSON object.\n * The serialization format is compatible with the IPLD-style encoded references.\n * When a reference has a saved target (i.e. the target or object holding the reference is not in the database),\n * the target is included in the serialized object.\n *\n * Examples:\n * `{ \"/\": \"dxn:...\" }`\n * `{ \"/\": \"dxn:...\", \"target\": { ... } }`\n */\n encode(): EncodedReference;\n\n [RefTypeId]: {\n _T: T;\n };\n}\n\nexport declare namespace Ref {\n /**\n * Target of the reference.\n */\n export type Target<R> = R extends Ref<infer U> ? U : never;\n}\n\nRef.isRef = (obj: any): obj is Ref<any> => {\n return obj != null && typeof obj === 'object' && RefTypeId in obj;\n};\n\nRef.hasEntityId = (id: EntityId) => (ref: Ref<any>) => {\n const uri = EID.tryParse(ref.uri);\n return uri !== undefined && EID.isLocal(uri) && EID.getEntityId(uri) === id;\n};\n\nRef.isRefSchema = (schema: Schema.Schema<any, any>): schema is RefSchema<any> => {\n return Ref.isRefSchemaAST(schema.ast);\n};\n\nRef.isRefSchemaAST = (ast: SchemaAST.AST): boolean => {\n return SchemaAST.getAnnotation(ast, ReferenceAnnotationId).pipe(Option.isSome);\n};\n\nRef.make = <T extends AnyProperties>(obj: T): Ref<T> => {\n if (typeof obj !== 'object' || obj === null) {\n throw new TypeError('Expected: ECHO object.');\n }\n\n // TODO(dmaretskyi): Extract to `getObjectEchoUri` function.\n const id = obj.id;\n invariant(EntityId.isValid(id), 'Invalid object ID');\n const uri = EID.make({ entityId: id });\n const ref = new RefImpl(uri, obj);\n return ref;\n};\n\nRef.fromURI = (uri: URI.URI): Ref<any> => {\n assertArgument(typeof uri === 'string', 'uri', 'Expected URI string');\n return new RefImpl(uri);\n};\n\n/**\n * `reference` field on the schema object.\n */\nexport type JsonSchemaReferenceInfo = {\n schema: { $ref: string };\n schemaVersion?: string;\n};\n\n/**\n * @internal\n */\n// TODO(burdon): Move to json schema and make private?\nexport const createEchoReferenceSchema = (\n echoUri: string | undefined,\n typename: string | undefined,\n version: string | undefined,\n): Schema.SchemaClass<Ref<any>, EncodedReference> => {\n if (!echoUri && !typename) {\n throw new TypeError('Either echoUri or typename must be provided.');\n }\n\n const referenceInfo: JsonSchemaReferenceInfo = {\n schema: {\n // TODO(dmaretskyi): Include version?\n $ref: echoUri ?? DXN.make(typename!),\n },\n schemaVersion: version,\n };\n\n // TODO(dmaretskyi): Add name and description.\n const refSchema = Schema.declare<Ref<any>, EncodedReference, []>(\n [],\n {\n encode: () => {\n return (value) =>\n Effect.gen(function* () {\n if (Ref.isRef(value)) {\n return EncodedReference.fromURI((value as Ref<any>).uri);\n } else if (EncodedReference.isEncodedReference(value)) {\n return value;\n }\n throw new Error('Invalid reference');\n });\n },\n decode: () => {\n return (value) =>\n Effect.gen(function* () {\n const dbService = yield* Effect.serviceOption(Database.Service);\n\n // TODO(dmaretskyi): This branch seems to be taken by Schema.is\n if (Ref.isRef(value)) {\n if (Option.isSome(dbService)) {\n return dbService.value.db.makeRef(value.uri);\n } else {\n return value;\n }\n }\n\n if (!EncodedReference.isEncodedReference(value)) {\n return yield* Effect.fail(new ParseResult.Unexpected(value, 'reference'));\n }\n if (Option.isSome(dbService)) {\n return dbService.value.db.makeRef(EncodedReference.toURI(value));\n } else {\n return Ref.fromURI(EncodedReference.toURI(value));\n }\n });\n },\n },\n {\n jsonSchema: {\n // TODO(dmaretskyi): We should remove `$id` and keep `$ref` with a fully qualified name.\n $id: JSON_SCHEMA_ECHO_REF_ID,\n $ref: JSON_SCHEMA_ECHO_REF_ID,\n reference: referenceInfo,\n },\n [ReferenceAnnotationId]: {\n typename: typename ?? '',\n version,\n },\n },\n );\n\n return refSchema;\n};\n\nconst getSchemaExpectedName = (ast: SchemaAST.Annotated): string | undefined => {\n return SchemaAST.getIdentifierAnnotation(ast).pipe(\n Option.orElse(() => SchemaAST.getTitleAnnotation(ast)),\n Option.orElse(() => SchemaAST.getDescriptionAnnotation(ast)),\n Option.getOrElse(() => undefined),\n );\n};\n\n/**\n * Load-source ceiling for a resolution request. Cheaper tiers are always probed first; the\n * ceiling caps how far a request is allowed to reach:\n * - `working-set`: synchronous, in-memory only. A miss settles `unavailable` immediately.\n * - `disk`: probe the working set, then local storage; never the network.\n * - `network`: probe the working set, disk, then fetch from peers.\n *\n * `unavailable` is always relative to the requested ceiling (disk-unavailable ≠ network-unavailable).\n */\nexport type RefSource = 'working-set' | 'disk' | 'network';\n\n/**\n * A stateful, closure-aware handle to an in-flight (or settled) reference resolution.\n *\n * `ready` means the entity is FULLY USABLE: its own body and its strong-dependency closure are all\n * materialized. The body-vs-closure split is internal; `requesting` transparently covers \"a\n * dependency is still loading\".\n */\nexport interface RefResolverRequest {\n /**\n * `pending` is a one-way entry state (never re-entered). `requesting` means the body and/or\n * closure is still loading. `ready` means fully usable. `unavailable` means unreachable at the\n * requested ceiling.\n */\n readonly state: 'pending' | 'requesting' | 'ready' | 'unavailable';\n\n /**\n * Fires (deferred to a microtask) whenever {@link state} changes.\n */\n readonly stateChanged: Event<void>;\n\n /**\n * Synchronous snapshot of the resolved entity; defined iff `state === 'ready'`.\n */\n getResult(): AnyProperties | undefined;\n\n /**\n * Settles when `state ∈ {ready, unavailable}`.\n */\n wait(): Promise<AnyProperties | undefined>;\n\n /**\n * Decrements the refcount on the shared load op(s); cancels the underlying IO at zero.\n */\n abort(): void;\n}\n\nexport interface RefResolver {\n /**\n * Resolve a reference, returning a stateful handle. `source` is a required ceiling; cheaper\n * tiers are always probed first.\n */\n resolve(uri: URI.URI, options: { source: RefSource }): RefResolverRequest;\n\n /**\n * Resolve ref synchronously from the objects in the working set.\n *\n * @param uri\n * @param load If true the resolver should attempt to load the object from disk.\n * @param onLoad Callback to call when the object is loaded.\n * @deprecated Use {@link resolve} with `{ source: 'working-set' }`. Removed in Task 11.\n */\n resolveSync(uri: URI.URI, load: boolean, onLoad?: () => void): AnyProperties | undefined;\n\n /**\n * Resolver ref asynchronously.\n * @deprecated Use {@link resolve} with `{ source: 'network' }`. Removed in Task 11.\n */\n resolveLegacy(uri: URI.URI): Promise<AnyProperties | undefined>;\n\n /**\n * @deprecated Use {@link resolve} + `Type.getSchema`. Removed in Task 11.\n */\n resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined>;\n\n /**\n * Resolve the source `Type.AnyEntity` entity for a type URI. Used by\n * deserialization paths (`Obj.fromJSON`) to set the back-reference accessed\n * via `Obj.getType` / `Entity.getType`. Optional — resolvers that only\n * carry raw schemas may leave this unimplemented; the deserializer falls\n * back to leaving the type entity unset.\n * @deprecated Use {@link resolve}. Removed in Task 11.\n */\n resolveType?(uri: URI.URI): Promise<unknown | undefined>;\n}\n\n/**\n * A settled {@link RefResolverRequest} with a fixed `state` and `result`, used by resolvers\n * whose backends are fully synchronous (e.g. {@link StaticRefResolver}).\n */\nexport const makeSettledRequest = (\n state: RefResolverRequest['state'],\n result: AnyProperties | undefined,\n): RefResolverRequest => ({\n state,\n stateChanged: new Event<void>(),\n getResult: () => (state === 'ready' ? result : undefined),\n wait: async () => (state === 'ready' ? result : undefined),\n abort: () => {},\n});\n\nexport class RefImpl<T> implements Ref<T> {\n #uri: URI.URI;\n #resolver?: RefResolver = undefined;\n #resolved = new Event<void>();\n\n /**\n * Target is set when the reference is created from a specific object.\n * In this case, the target might not be in the database.\n */\n #target: T | undefined = undefined;\n\n /**\n * Callback to issue a reactive notification when object is resolved.\n */\n #resolverCallback = () => {\n this.#resolved.emit();\n };\n\n constructor(uri: URI.URI, target?: T) {\n this.#uri = uri;\n this.#target = target;\n }\n\n /**\n * @inheritdoc\n */\n get uri(): URI.URI {\n return this.#uri;\n }\n\n /**\n * @inheritdoc\n */\n get isAvailable(): boolean {\n return this.#target !== undefined || this.#resolver !== undefined;\n }\n\n /**\n * @inheritdoc\n */\n get target(): T | undefined {\n if (this.#target) {\n return this.#target;\n }\n\n invariant(this.#resolver, 'Resolver is not set');\n return this.#resolver.resolveSync(this.#uri, true, this.#resolverCallback) as T | undefined;\n }\n\n /**\n * @inheritdoc\n */\n async load(): Promise<T> {\n if (this.#target) {\n return this.#target;\n }\n invariant(this.#resolver, 'Resolver is not set');\n const obj = await this.#resolver.resolveLegacy(this.#uri);\n if (obj == null) {\n throw new Error('Object not found');\n }\n return obj as T;\n }\n\n /**\n * @inheritdoc\n */\n async tryLoad(): Promise<T | undefined> {\n if (this.#target) {\n return this.#target;\n }\n invariant(this.#resolver, 'Resolver is not set');\n return (await this.#resolver.resolveLegacy(this.#uri)) as T | undefined;\n }\n\n /**\n * @inheritdoc\n */\n onResolved(callback: () => void): () => void {\n return this.#resolved.on(callback);\n }\n\n /**\n * Do not inline the target object in the reference.\n * Makes .target unavailable unless the reference is connected to a database context.\n * Clones the reference object.\n */\n noInline(): RefImpl<T> {\n const ref = new RefImpl<T>(this.#uri, undefined);\n ref.#resolver = this.#resolver;\n return ref;\n }\n\n encode(): EncodedReference {\n return {\n '/': this.#uri,\n ...(this.#target ? { target: this.#target } : {}),\n };\n }\n\n /**\n * Serializes the reference to a JSON object.\n * The serialization format is compatible with the IPLD-style encoded references.\n * When a reference has a saved target (i.e. the target or object holding the reference is not in the database),\n * the target is included in the serialized object.\n */\n toJSON(): EncodedReference {\n return this.encode();\n }\n\n toString(): string {\n if (this.#target) {\n return `Ref(${this.#target.toString()})`;\n }\n\n return `Ref(${this.#uri.toString()})`;\n }\n\n [inspectCustom]: CustomInspectFunction = (depth, options, inspect) => {\n return this.toString();\n };\n\n [RefTypeId] = refVariance;\n\n /**\n * Effect Hash trait. Required for MutableHashMap-based caches (e.g., Atom.family)\n * to deduplicate Ref instances that point to the same object.\n * ECHO proxies return new RefImpl instances on every property access,\n * so without this, each access would create a separate cache entry.\n */\n [Hash.symbol](): number {\n return Hash.hash(this.#uri.toString());\n }\n\n /** Effect Equal trait. See {@link Hash.symbol} for rationale. */\n [Equal.symbol](that: Equal.Equal): boolean {\n return that instanceof RefImpl && this.#uri === that.uri;\n }\n\n get atom(): Atom.Atom<T | undefined> {\n return RefAtoms.refSimpleFamily(this);\n }\n\n /**\n * Internal method to set the resolver.\n *\n * @internal\n */\n _setResolver(resolver: RefResolver): void {\n this.#resolver = resolver;\n }\n\n /**\n * @internal\n */\n _getSavedTarget(): T | undefined {\n return this.#target;\n }\n\n pipe() {\n // eslint-disable-next-line prefer-rest-params\n return Pipeable.pipeArguments(this, arguments);\n }\n}\n\n/**\n * Internal API for setting the reference resolver.\n */\nexport const setRefResolver = (ref: Ref<any>, resolver: RefResolver) => {\n invariant(ref instanceof RefImpl, 'Ref is not an instance of RefImpl');\n ref._setResolver(resolver);\n};\n\n/**\n * Internal API for getting the saved target on a reference.\n */\nexport const getRefSavedTarget = (ref: Ref<any>): AnyProperties | undefined => {\n invariant(ref instanceof RefImpl, 'Ref is not an instance of RefImpl');\n return ref._getSavedTarget();\n};\n\n// Used to validate reference target type.\nconst refVariance: Ref<any>[typeof RefTypeId] = {\n _T: null as any,\n};\n\nexport const refFromEncodedReference = (encodedReference: EncodedReference, resolver?: RefResolver): Ref<any> => {\n const uri = EncodedReference.toURI(encodedReference);\n const ref = new RefImpl(uri);\n\n // TODO(dmaretskyi): Handle inline target in the encoded reference.\n\n if (resolver) {\n setRefResolver(ref, resolver);\n }\n return ref;\n};\n\nexport class StaticRefResolver implements RefResolver {\n public objects = new Map<EntityId, AnyProperties>();\n public schemas = new Map<URI.URI, Schema.Schema.AnyNoContext>();\n\n addObject(obj: AnyProperties): this {\n this.objects.set(obj.id, obj);\n return this;\n }\n\n addSchema(input: Type.AnyEntity): this {\n const schema = getStaticTypeSchema(input);\n invariant(schema, 'Type entity is missing its source schema');\n const uri = getSchemaURI(schema);\n invariant(uri, 'Schema has no URI');\n this.schemas.set(uri, schema);\n return this;\n }\n\n resolve(uri: URI.URI, _options: { source: RefSource }): RefResolverRequest {\n const obj = this.#lookup(uri);\n return makeSettledRequest(obj ? 'ready' : 'unavailable', obj);\n }\n\n resolveSync(uri: URI.URI, _load: boolean, _onLoad?: () => void): AnyProperties | undefined {\n return this.#lookup(uri);\n }\n\n async resolveLegacy(uri: URI.URI): Promise<AnyProperties | undefined> {\n return this.#lookup(uri);\n }\n\n async resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined> {\n return this.schemas.get(uri);\n }\n\n #lookup(uri: URI.URI): AnyProperties | undefined {\n const echoUri = EID.tryParse(uri);\n const id = echoUri ? EID.getEntityId(echoUri) : undefined;\n if (id == null) {\n return undefined;\n }\n return this.objects.get(id);\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Atom from '@effect-atom/atom/Atom';\n\nimport type { Ref } from './ref';\nimport { loadRefTarget } from './utils';\n\n/**\n * Atom family for ECHO refs.\n * Uses ref reference as key — same ref returns same atom.\n * This atom only updates once when the ref loads — it does not subscribe to target object changes.\n * Use `Obj.atom(ref)` if you need reactive snapshots of ECHO objects via a ref.\n */\nexport const refSimpleFamily = Atom.family(<T>(ref: Ref<T>): Atom.Atom<T | undefined> => {\n return Atom.make<T | undefined>((get) => {\n return loadRefTarget(ref, get, (target) => target);\n });\n});\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as Atom from '@effect-atom/atom/Atom';\n\nimport type { Ref } from './ref';\n\n/**\n * Internal helper for loading ref targets in atoms.\n * Handles the common pattern of checking for loaded target and triggering async load.\n */\nexport const loadRefTarget = <T, R>(\n ref: Ref<T>,\n get: Atom.Context,\n onTargetAvailable: (target: T) => R,\n): R | undefined => {\n // Accessing `ref.target` registers a resolution callback when the target is\n // not yet loaded, so resolution can be observed via `ref.onResolved` below.\n const currentTarget = ref.target;\n if (currentTarget) {\n return onTargetAvailable(currentTarget);\n }\n\n // Subscribe to the ref's resolution event in case the target loads later.\n const unsubscribe = ref.onResolved(() => {\n const target = ref.target;\n if (target) {\n get.setSelf(onTargetAvailable(target));\n }\n });\n get.addFinalizer(unsubscribe);\n\n // Also try async load (e.g. for objects that need disk loading).\n void ref\n .load()\n .then((loadedTarget) => {\n get.setSelf(onTargetAvailable(loadedTarget));\n })\n .catch(() => {\n // Loading failed; the resolution subscription above will pick up cross-client updates.\n });\n\n return undefined;\n};\n"],
5
- "mappings": "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",
6
- "names": ["Effect", "Equal", "Hash", "Option", "ParseResult", "Pipeable", "Schema", "SchemaAST", "Event", "inspectCustom", "EncodedReference", "assertArgument", "invariant", "DXN", "EID", "EntityId", "Atom", "loadRefTarget", "ref", "get", "onTargetAvailable", "currentTarget", "target", "unsubscribe", "onResolved", "setSelf", "addFinalizer", "load", "then", "loadedTarget", "catch", "undefined", "refSimpleFamily", "family", "ref", "make", "get", "loadRefTarget", "target", "reference", "$ref", "$id", "JSON_SCHEMA_ECHO_REF_ID", "parsed", "tryMake", "typename", "getName", "undefined", "schema", "version", "annotation", "getTypeAnnotation", "Error", "createEchoReferenceSchema", "isRef", "obj", "hasEntityId", "ref", "uri", "isRefSchema", "isRefSchemaAST", "ast", "make", "TypeError", "EID", "entityId", "id", "fromURI", "RefImpl", "referenceInfo", "schemaVersion", "Effect", "gen", "EncodedReference", "value", "Ref", "dbService", "Option", "isSome", "jsonSchema", "ReferenceAnnotationId", "getSchemaExpectedName", "stateChanged", "Event", "getResult", "wait", "state", "abort", "RefImpl", "undefined", "target", "invariant", "obj", "Error", "ref", "encode", "toString", "inspectCustom", "depth", "options", "inspect", "RefTypeId", "refVariance", "atom", "pipe", "_setResolver", "resolver", "_getSavedTarget", "uri", "schemas", "addObject", "objects", "set", "addSchema", "input", "schema", "getSchemaURI", "resolve", "makeSettledRequest", "resolveSync", "_onLoad", "resolveLegacy", "resolveSchema", "id"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/Feed.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport type * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\n\nimport { DXN, EID } from '@dxos/keys';\n\nimport * as Annotation from './Annotation';\nimport type * as Entity from './Entity';\nimport type * as Filter from './Filter';\nimport * as internal from './internal';\nimport * as Obj from './Obj';\nimport type * as Query from './Query';\nimport type * as QueryResult from './QueryResult';\nimport * as Type from './Type';\n\n/**\n * Runtime schema for a Feed object.\n *\n * @example\n * ```ts\n * const feed = Obj.make(Feed.Feed, { name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });\n * ```\n */\nexport const Feed = Schema.Struct({\n /** User-facing display name. */\n name: Schema.String.pipe(Schema.optional),\n /** Identifier for the feed's kind (e.g., plugin id). */\n kind: Schema.String.pipe(internal.FormInputAnnotation.set(false), Schema.optional),\n\n /**\n * Feed namespace.\n * Controls how feed data is stored and replicated.\n * - `data`: Data feed (default).\n * - `trace`: Trace feed.\n */\n namespace: Schema.optional(Schema.Literal('data', 'trace')),\n}).pipe(\n internal.HiddenAnnotation.set(true),\n Annotation.IconAnnotation.set({ icon: 'ph--rows--regular', hue: 'yellow' }),\n Type.makeObject(DXN.make('org.dxos.type.feed', '0.1.0')),\n);\n\n/**\n * TypeScript instance type for a Feed object.\n */\nexport type Feed = Type.InstanceType<typeof Feed>;\n\n//\n// Types\n//\n\n/**\n * Opaque cursor for iterating over feed items.\n */\n// TODO(dmaretskyi): T needs to be referenced in the type structure for typescript to respect it during inference and type-checking.\nexport interface Cursor<T = Obj.Snapshot> {\n readonly _tag: 'Cursor';\n}\n\n/**\n * Retention options for a feed.\n */\nexport interface RetentionOptions {\n /** Retain items after this cursor position. */\n // TODO(wittjosiah): Use FeedCursor from @dxos/feed?\n cursor?: string;\n}\n\n/**\n * Sync options for a feed.\n */\nexport interface SyncOptions {\n /** Push local changes to the server. Defaults to true. */\n shouldPush?: boolean;\n /** Pull remote changes from the server. Defaults to true. */\n shouldPull?: boolean;\n}\n\n/**\n * Queue replication backlog for a feed namespace.\n * `0` / `0` means caught up on pull and push.\n */\nexport interface SyncState {\n /** Blocks still to pull from remote. */\n blocksToPull: number;\n /** Unpositioned blocks still to push to remote. */\n blocksToPush: number;\n /** Total blocks stored locally for the feed namespace. */\n totalBlocks: number;\n}\n\n//\n// Factory\n//\n\n/**\n * Creates a new feed object.\n *\n * @example\n * ```ts\n * const feed = Feed.make({ name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });\n * ```\n */\n// TODO(wittjosiah): How to control the feed namespace (data/trace)? Why do feeds have namespaces?\nexport const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);\n\n/**\n * Returns the feed object's EID when the feed is stored in a space.\n *\n * Used internally by the feed service layer.\n */\nexport const getQueueUri = (feed: Feed): EID.EID | undefined => EID.tryParse(Obj.getURI(feed));\n\n//\n// Service\n//\n\n/**\n * Effect service for feed operations.\n * Provides the bridge to the underlying storage implementation.\n * Must be provided by the application layer (e.g., echo-db).\n */\nexport class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<\n FeedService,\n {\n /**\n * Appends items to a feed.\n */\n append(feed: Feed, items: Entity.Unknown[]): Promise<void>;\n\n /**\n * Removes items from a feed by ID.\n */\n remove(feed: Feed, ids: string[]): Promise<void>;\n\n /**\n * Queries items in a feed.\n */\n query: {\n <Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;\n <F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;\n };\n\n /**\n * Syncs the feed with the server.\n */\n sync(feed: Feed, options?: SyncOptions): Promise<void>;\n\n /**\n * Returns queue replication backlog for the feed's namespace.\n */\n getSyncState(feed: Feed): Promise<SyncState>;\n }\n>() {}\n\n/**\n * @deprecated Use `FeedService` instead.\n */\nexport type Service = FeedService;\n\n/**\n * @deprecated Use `FeedService` instead.\n */\nexport const Service = FeedService;\n\n/**\n * Effect context service that holds the current feed for a scoped operation.\n *\n * @deprecated Prefer threading a `Feed.Feed` explicitly through function signatures\n * over hiding it behind a context service.\n */\nexport class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<\n ContextFeedService,\n {\n readonly feed: Feed;\n }\n>() {\n static layer = (feed: Feed): Layer.Layer<ContextFeedService> => Layer.succeed(ContextFeedService, { feed });\n}\n\n/**\n * Layer that provides a Feed service that throws when accessed.\n * Useful as a default layer when no feed service is available.\n */\nexport const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService, {\n append: () => {\n throw new Error('Feed.FeedService not available');\n },\n remove: () => {\n throw new Error('Feed.FeedService not available');\n },\n query: () => {\n throw new Error('Feed.FeedService not available');\n },\n sync: () => {\n throw new Error('Feed.FeedService not available');\n },\n getSyncState: () => {\n throw new Error('Feed.FeedService not available');\n },\n} as Context.Tag.Service<FeedService>);\n\n//\n// Operations\n//\n\n/**\n * Appends items to a feed.\n *\n * @example\n * ```ts\n * yield* Feed.append(feed, [Obj.make(Notification, { title: 'Hello' })]);\n * ```\n */\nexport const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n yield* Effect.promise(() => service.append(feed, items));\n });\n\n/**\n * Removes items from a feed.\n *\n * @example\n * ```ts\n * yield* Feed.remove(feed, [item]);\n * ```\n */\n// TODO(dmaretskyi): Should we allow snapshots here? - what does it mean to remove a snapshot?\nexport const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n const ids = items.map((item) => item.id);\n yield* Effect.promise(() => service.remove(feed, ids));\n });\n\n/**\n * Creates a reactive query over items in a feed.\n *\n * In non-Effect code, query a feed directly through the database with a feed scope:\n * `db.query(Query.select(filter).from(Scope.feed(Feed.getQueueUri(feed))))`.\n *\n * @example\n * ```ts\n * const result = yield* Feed.query(feed, Filter.type(Person));\n * ```\n */\n// TODO(dmaretskyi): Suport chained queries:\n// const result = yield* feed.pipe(Feed.query(Filter.type(Person))); result.subscribe(...)\n// const objects = yield* feed.pipe(Feed.query(Filter.type(Person))).run;\n// const object = yield* feed.pipe(Feed.query(Filter.type(Person))).first;\n// ... unify for Database and schema queries.\nexport const query: {\n <Q extends Query.Any>(\n feed: Feed,\n query: Q,\n ): Effect.Effect<QueryResult.QueryResult<Query.Type<Q>>, never, FeedService>;\n <F extends Filter.Any>(\n feed: Feed,\n filter: F,\n ): Effect.Effect<QueryResult.QueryResult<Filter.Type<F>>, never, FeedService>;\n} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>\n FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));\n\n/**\n * Executes a feed query once and returns the results.\n *\n * @example\n * ```ts\n * const items = yield* Feed.runQuery(feed, Filter.type(Person));\n * ```\n */\nexport const runQuery: {\n <Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never, FeedService>;\n <F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never, FeedService>;\n} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>\n query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));\n\n/**\n * Syncs the feed with the server.\n *\n * @example\n * ```ts\n * yield* Feed.sync(feed);\n * yield* Feed.sync(feed, { shouldPush: false });\n * ```\n */\nexport const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n yield* Effect.promise(() => service.sync(feed, options));\n });\n\n/**\n * Returns queue replication backlog for the feed's namespace.\n *\n * @example\n * ```ts\n * const { blocksToPull, blocksToPush } = yield* Feed.getSyncState(feed);\n * ```\n */\nexport const getSyncState = (feed: Feed): Effect.Effect<SyncState, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n return yield* Effect.promise(() => service.getSyncState(feed));\n });\n\n/**\n * Creates a cursor for iterating over feed items.\n * Currently stubbed — cursor operations are not yet implemented.\n *\n * @example\n * ```ts\n * const cursor = yield* Feed.cursor<Person>(feed);\n * const item = yield* Feed.next(cursor);\n * ```\n */\n// TODO(wittjosiah): Implement cursor operations. Use Effect streams?\nexport const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, FeedService> =>\n Effect.succeed({ _tag: 'Cursor' } as Cursor<T>);\n\n/**\n * Returns the next item from a feed cursor.\n * Currently stubbed — cursor operations are not yet implemented.\n */\nexport const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, FeedService> =>\n Effect.die('Feed.next is not yet implemented');\n\n/**\n * Returns the next item from a feed cursor as an Option.\n * Currently stubbed — cursor operations are not yet implemented.\n */\nexport const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, FeedService> =>\n Effect.die('Feed.nextOption is not yet implemented');\n\n/**\n * Sets the local retention policy for a feed.\n * Currently stubbed — feeds do not yet support retention.\n *\n * @example\n * ```ts\n * yield* Feed.setRetention(feed, { count: 1000 });\n * ```\n */\n// TODO(dmaretskyi): Implement when feed retention is supported.\nexport const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>\n Effect.void;\n"],
5
- "mappings": "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",
6
- "names": ["make", "Context", "Effect", "Layer", "Schema", "DXN", "EID", "Feed", "Struct", "name", "String", "pipe", "optional", "kind", "FormInputAnnotation", "set", "namespace", "Literal", "HiddenAnnotation", "IconAnnotation", "icon", "hue", "makeObject", "DXN", "make", "props", "getQueueUri", "feed", "EID", "tryParse", "getURI", "FeedService", "Tag", "Service", "ContextFeedService", "layer", "succeed", "notAvailable", "append", "Error", "remove", "query", "sync", "getSyncState", "items", "gen", "service", "promise", "ids", "map", "item", "id", "queryOrFilter", "runQuery", "flatMap", "queryResult", "run", "options", "cursor", "_feed", "_tag", "next", "_cursor", "die", "nextOption", "setRetention", "_options", "void"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/Obj.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Effect from 'effect/Effect';\nimport * as Equal from 'effect/Equal';\nimport * as Function from 'effect/Function';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as Utils from 'effect/Utils';\n\nimport type { ForeignKey } from '@dxos/echo-protocol';\nimport { SchemaEx } from '@dxos/effect';\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { EntityId, type URI } from '@dxos/keys';\nimport { assumeType, deepMapValues } from '@dxos/util';\n\nimport type * as Database from './Database';\nimport * as Entity from './Entity';\nimport * as Err from './Err';\nimport * as internal from './internal';\nimport { getProxyTarget, isProxy } from './internal/common/proxy/proxy-utils';\nimport * as objInternal from './internal/Obj';\nimport * as Ref from './Ref';\nimport type * as Tag from './Tag';\nimport * as Type from './Type';\n\n/**\n * Base type for all ECHO objects.\n */\ninterface BaseObj extends internal.AnyEntity, Entity.OfKind<typeof Entity.Kind.Object> {}\n\n/**\n * Object type with specific properties.\n */\nexport type OfShape<Props> = BaseObj & Props;\n\n/**\n * Object with no known properties beyond id and kind.\n * Use this when the object's schema/properties are not known.\n * For objects with arbitrary properties, use `Obj.AnyProps`.\n *\n * NOTE: This is a TypeScript type only, not a schema.\n * To validate that a value is an ECHO object, use `Schema.is(Type.Obj)`.\n */\nexport interface Unknown extends BaseObj {}\n\n/**\n * Runtime Effect schema for any ECHO object.\n * Use for validation, parsing, or as a reference target for collections.\n *\n * NOTE: `Schema.is(Type.Obj)` does STRUCTURAL validation only (checks for `id` field).\n * Use `Obj.isObject()` for proper ECHO instance type guards that check the KindId brand.\n *\n * @example\n * ```ts\n * // Structural type guard (accepts any object with id field)\n * if (Schema.is(Type.Obj)(unknownValue)) { ... }\n *\n * // ECHO instance type guard (checks KindId brand)\n * if (Obj.isObject(unknownValue)) { ... }\n *\n * // Reference to any object type\n * const Collection = Schema.Struct({\n * objects: Schema.Array(Ref.Ref(Obj.Unknown)),\n * }).pipe(Type.makeObject(DXN.make('com.example.type.collection', '0.1.0')));\n * ```\n */\n// TODO(wittjosiah): Investigate if Schema.filter can validate KindId on ECHO instances.\n// Effect Schema normalizes proxy objects to plain objects before calling filter predicates.\n// Possible approaches: custom Schema.declare, AST manipulation, or upstream contribution.\nexport const Unknown: internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object> = Schema.Struct({\n id: Schema.String,\n}).pipe(\n Schema.extend(Schema.Record({ key: Schema.String, value: Schema.Unknown })),\n Schema.annotations({\n [internal.TypeAnnotationId]: {\n kind: Entity.Kind.Object,\n typename: internal.ANY_OBJECT_TYPENAME,\n version: internal.ANY_OBJECT_VERSION,\n },\n }),\n) as unknown as internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object>;\n\n/**\n * Object with arbitrary properties.\n *\n * NOTE: Due to how TypeScript works, this type is not assignable to a specific schema type.\n * In that case, use `Obj.instanceOf` to check if an object is of a specific type.\n *\n * Prefer using `Obj.Unknown` when you don't need to access arbitrary properties.\n */\nexport interface Any extends BaseObj, internal.AnyProperties {}\n\n/**\n * Base type for snapshot objects (has SnapshotKindId instead of KindId).\n */\ninterface BaseSnapshot extends internal.AnyEntity {\n readonly [Entity.SnapshotKindId]: typeof Entity.Kind.Object;\n readonly id: EntityId;\n}\n\n/**\n * Immutable snapshot of an ECHO object.\n * Branded with SnapshotKindId (not KindId).\n * Property values are frozen at the time the snapshot was created.\n * Returned by getSnapshot() and hooks like useObject().\n *\n * Snapshots are structurally identical to reactive objects but have a different brand,\n * making them distinguishable at the TypeScript level. Neither is assignable to the other.\n */\nexport type Snapshot<T extends Unknown = Unknown> = Omit<T, Entity.KindId> & BaseSnapshot;\n\n/**\n * JSON-encoded properties for objects.\n */\nexport interface BaseObjJson {\n id: string;\n}\n\n// Factory (not a shared const): each object must get its own `keys`/`tags`/`annotations` containers,\n// otherwise mutating one object's meta would leak into every other object via the shared references.\nconst defaultMeta = (): internal.EntityMeta => ({\n keys: [],\n tags: [],\n annotations: {},\n});\n\n// TODO(burdon): Should we allow the caller to set the id?\n/**\n * Props type for object creation with a given type. Accepts a `Type.AnyObj`\n * entity and derives the instance shape via `Type.InstanceType`. Relation-kind\n * entities are rejected at the type level — use `Relation.MakeProps` for those.\n *\n * When the schema is the unconstrained `Type.AnyObj` (`Obj<unknown>` — e.g. a\n * dynamic type from `schemaRegistry.register`), the instance shape is not\n * statically known, so data props widen to `Record<string, unknown>` and the\n * caller can pass arbitrary fields without a cast.\n */\nexport type MakeProps<S extends Type.AnyObj> = {\n id?: EntityId;\n [Meta]?: Partial<internal.EntityMeta>;\n [Parent]?: Unknown;\n // When the resolved instance has no known data keys, widen to a permissive\n // record (the `Obj<unknown>` case); otherwise use the precise property shape.\n // `[keyof …] extends [never]` is wrapped in tuples so the check is\n // non-distributive — a `never` instance type (e.g. when narrowing collapses\n // the schema) stays a single branch instead of distributing to `never`.\n} & ([keyof Entity.Properties<Type.InstanceType<S>>] extends [never]\n ? Record<string, unknown>\n : Entity.Properties<Type.InstanceType<S>>);\n\n/**\n * Creates a new echo object of the given schema or `Type.Type`.\n *\n * @param typeOrSchema - A static object schema (`Type.makeObject(...)`) or a\n * `Type.Type` entity (e.g. one returned by `db.addType(schemaEntity)`).\n * @param props - Object properties.\n *\n * Meta can be passed as a symbol in `props`.\n *\n * Example:\n * ```ts\n * const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });\n * ```\n *\n * Note: Only accepts object schemas / object-kind types, not relation schemas.\n * Use `Relation.make` for relations.\n */\nexport function make<T extends Type.AnyObj>(type: T, props: NoInfer<MakeProps<T>>): OfShape<Type.InstanceType<T>>;\nexport function make(input: Type.AnyObj, props: any): OfShape<any> {\n // `Type.Type` entities aren't `Schema.Schema` themselves; derive the Effect\n // Schema via `Type.getSchema(...)`. Pass the entity through to `makeObject`\n // so subsequent schema mutations (`Type.addFields`, etc.) propagate.\n const schema = Type.getSchema(input);\n assertArgument(\n internal.getTypeAnnotation(schema)?.kind === Entity.Kind.Object,\n 'schema',\n 'Expected an object schema',\n );\n\n let meta: internal.EntityMeta | undefined = undefined;\n\n // Set default fields on meta on creation.\n if (props[internal.MetaId] != null) {\n meta = { ...defaultMeta(), ...props[internal.MetaId] };\n delete props[internal.MetaId];\n }\n\n // Filter undefined values (Object.entries only returns string-keyed properties).\n const filterUndefined: any = Object.fromEntries(Object.entries(props).filter(([_, v]) => v !== undefined));\n\n // Copy symbol properties (like ParentId) that Object.entries doesn't include.\n for (const sym of Object.getOwnPropertySymbols(props)) {\n const value = (props as any)[sym];\n if (value !== undefined) {\n filterUndefined[sym] = value;\n }\n }\n\n return internal.makeObject(\n schema,\n filterUndefined,\n {\n ...defaultMeta(),\n ...meta,\n },\n input,\n );\n}\n\n/**\n * Determine if object is an ECHO object.\n */\nexport const isObject = (obj: unknown): obj is Unknown => {\n assumeType<internal.InternalObjectProps>(obj);\n return typeof obj === 'object' && obj !== null && obj[Entity.KindId] === Entity.Kind.Object;\n};\n\nexport const isSnapshot = (obj: unknown): obj is Snapshot => {\n assumeType<internal.InternalObjectProps>(obj);\n return typeof obj === 'object' && obj !== null && (obj as any)[Entity.SnapshotKindId] === Entity.Kind.Object;\n};\n\n/**\n * Subscribe to object updates.\n * The callback is called synchronously when the object is modified.\n * Only accepts reactive objects (not snapshots).\n * @returns Unsubscribe function.\n */\nexport const subscribe = (obj: Unknown, callback: () => void): (() => void) => {\n return internal.subscribe(obj, callback);\n};\n\n//\n// Snapshot\n//\n\n/**\n * Returns an immutable snapshot of an object.\n * The snapshot is branded with SnapshotKindId instead of KindId,\n * making it distinguishable from the reactive object at the type level.\n */\nexport const getSnapshot: <T extends Unknown>(obj: T) => Snapshot<T> = objInternal.getSnapshot as any;\n\n/**\n * Returns the reactive version of an object from the database, given its snapshot.\n * Inverse of `Obj.getSnapshot`.\n *\n * Uses `Obj.getDatabase` internally to get the database from the snapshot,\n * then resolves the reactive object by ID.\n *\n * @param snapshot - A snapshot of the object (from `Obj.getSnapshot`).\n * @returns Effect that succeeds with the reactive object, or fails with `GetReactiveError`.\n * @example\n * ```ts\n * const snapshot = Obj.getSnapshot(obj);\n * const reactive = Obj.getReactive(snapshot).pipe(\n * Effect.runSync\n * );\n * ```\n */\nexport const getReactive = <T extends Unknown>(snapshot: Snapshot<T>): Effect.Effect<T, Err.GetReactiveError> =>\n Effect.gen(function* () {\n const db = internal.getDatabase(snapshot);\n if (!db) {\n return yield* Effect.fail(new Err.GetReactiveError({ reason: 'no-database', snapshotId: snapshot.id }));\n }\n const obj = db.getObjectById(snapshot.id);\n if (!obj) {\n return yield* Effect.fail(new Err.GetReactiveError({ reason: 'object-not-found', snapshotId: snapshot.id }));\n }\n return obj as T;\n });\n\n/**\n * Like `Obj.getReactive` but returns `Option.none()` instead of failing when the object\n * cannot be resolved (no database, object not found).\n *\n * @param snapshot - A snapshot of the object (from `Obj.getSnapshot`).\n * @returns Effect that succeeds with `Option.some(reactive)` or `Option.none()`.\n */\nexport const getReactiveOption = <T extends Unknown>(snapshot: Snapshot<T>): Effect.Effect<Option.Option<T>, never> =>\n getReactive(snapshot).pipe(\n Effect.map(Option.some),\n Effect.catchAll(() => Effect.succeed(Option.none())),\n );\n\n/**\n * Synchronous version of `Obj.getReactive`. Returns the reactive object or throws\n * `GetReactiveError` when the object cannot be resolved (no database, object not found).\n *\n * @param snapshot - A snapshot of the object (from `Obj.getSnapshot`).\n * @returns The reactive object.\n * @throws {Err.GetReactiveError} When the object cannot be resolved.\n */\nexport const getReactiveOrThrow = <T extends Unknown>(snapshot: Snapshot<T>): T =>\n Effect.runSync(getReactive(snapshot));\n\nexport type CloneOptions = {\n /**\n * Retain the original object's ID.\n * @default false\n */\n retainId?: boolean;\n\n /**\n * Recursively clone referenced objects.\n * @default false\n */\n deep?: boolean;\n};\n\n/**\n * Clones an object or relation.\n * This does not clone referenced objects, only the properties in the object.\n * @returns A new object with the same schema and properties.\n */\nexport const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = objInternal.clone;\n\n//\n// Change\n//\n\n/**\n * Makes all properties mutable recursively.\n * Used to provide a mutable view of an object within `Obj.update`.\n */\nexport type Mutable<T> = internal.Mutable<T>;\n\n/**\n * Perform mutations on an echo object within a controlled context.\n *\n * All mutations within the callback are batched and trigger a single notification\n * when the callback completes. Direct mutations outside of `Obj.update` will throw\n * an error for echo objects.\n *\n * This function also works with nested objects within echo objects (e.g., Template structs)\n * that are reactive at runtime.\n *\n * @param obj - The echo object to mutate. Use `Relation.update` for relations.\n * @param callback - The callback that performs mutations on the object.\n *\n * @example\n * ```ts\n * const person = Obj.make(Person, { name: 'John', age: 25 });\n *\n * // Mutate within Obj.update\n * Obj.update(person, (obj) => {\n * obj.name = 'Jane';\n * obj.age = 30;\n * });\n * // ONE notification fires here\n *\n * // Direct mutation throws\n * person.name = 'Bob'; // Error: Cannot modify outside Obj.update()\n * ```\n *\n * Note: Only accepts objects. Use `Relation.update` for relations.\n */\nexport const update = <T extends Unknown>(obj: T, callback: internal.ChangeCallback<T>): void => {\n internal.change(obj, callback);\n};\n\n/**\n * Get a deeply nested property from an object.\n *\n * Similar to lodash.get and getDeep from @dxos/util.\n * This is the complementary function to setValue.\n * Accepts both reactive objects and snapshots.\n *\n * @param obj - The ECHO object to get the property from.\n * @param path - Path to the property (array of keys).\n * @returns The value at the path, or undefined if not found.\n *\n * @example\n * ```ts\n * const person = Obj.make(Person, {\n * name: 'John',\n * addresses: [{ street: '123 Main St' }]\n * });\n *\n * Obj.getValue(person, ['addresses', 0, 'street']); // '123 Main St'\n * Obj.getValue(person, ['addresses', 1, 'street']); // undefined\n * ```\n */\nexport const getValue = (obj: Unknown | Snapshot, path: readonly (string | number)[]): any => {\n return SchemaEx.getValue(obj, SchemaEx.createJsonPath(path));\n};\n\n/**\n * Set a deeply nested property on an object, using the object's schema to determine\n * whether to initialize nested data as an empty object or array.\n *\n * Similar to lodash.set and setDeep from @dxos/util, but schema-aware.\n * Must be called within an `Obj.update` callback.\n *\n * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`\n * parameters, so there is no compile-time error. Enforcement is runtime-only.\n *\n * @param obj - The mutable ECHO object to set the property on.\n * @param path - Path to the property (array of keys).\n * @param value - Value to set.\n * @returns The value that was set.\n *\n * @example\n * ```ts\n * const person = Obj.make(Person, { name: 'John' });\n * // Person schema has: addresses: Schema.Array(Address)\n * Obj.update(person, (obj) => {\n * Obj.setValue(obj, ['addresses', 0, 'street'], '123 Main St');\n * });\n * // Creates: person.addresses = [{ street: '123 Main St' }]\n * ```\n */\n// TODO(wittjosiah): Compute possible path values + type value based on generic object type.\nexport const setValue: (obj: Mutable<Unknown>, path: readonly (string | number)[], value: any) => void =\n objInternal.setValue as any;\n\n//\n// Type\n//\n\nexport const ID = EntityId;\nexport type ID = EntityId;\n\n/**\n * Test if an object is an instance of a given object type.\n *\n * @example\n * ```ts\n * const john = Obj.make(Person, { name: 'John' });\n * const isPerson = Obj.instanceOf(Person);\n * if (isPerson(john)) {\n * // john is Person\n * }\n * ```\n *\n * Only accepts `Type.AnyObj` — use `Relation.instanceOf` for relations and\n * `Type.isType(value)` to test for `Type.Type` meta-schema entities.\n */\nexport const instanceOf: {\n // Reject `Type.Type` at the type level — those are meta-schema entities, not\n // object instances. Use `Type.isType(value)` instead.\n <T extends Type.Type>(\n type: T,\n _hint?: never,\n // eslint-disable-next-line @typescript-eslint/unified-signatures\n ..._error: ['ERROR: Obj.instanceOf does not accept Type.Type; use Type.isType(value) instead']\n ): never;\n // Reject relation types — use `Relation.instanceOf` instead.\n <R extends Type.AnyRelation>(\n type: R,\n _hint?: never,\n // eslint-disable-next-line @typescript-eslint/unified-signatures\n ..._error: ['ERROR: Obj.instanceOf does not accept relation types; use Relation.instanceOf instead']\n ): never;\n <S extends Type.AnyObj>(schema: S): (value: unknown) => value is Type.InstanceType<S>;\n <S extends Type.AnyObj>(schema: S, value: unknown): value is Type.InstanceType<S>;\n} = ((...args: [schema: Type.AnyEntity, value?: unknown]) => {\n if (args.length === 1) {\n return (entity: unknown) => internal.isInstanceOf(args[0], entity);\n }\n\n return internal.isInstanceOf(args[0], args[1]);\n}) as any;\n\n/**\n * Test if a snapshot is an instance of a schema.\n * Mirrors `instanceOf` but only accepts values branded with SnapshotKindId.\n * Use when the value is known to be a snapshot (e.g. from `getSnapshot` or `useObject`).\n *\n * @example\n * ```ts\n * const snapshot = Obj.getSnapshot(person);\n * if (Obj.snapshotOf(Person, snapshot)) {\n * // snapshot is Obj.Snapshot<Person>\n * }\n * ```\n */\nexport const snapshotOf: {\n <S extends Type.AnyObj>(schema: S): (value: unknown) => value is Snapshot<Type.InstanceType<S>>;\n <S extends Type.AnyObj>(schema: S, value: unknown): value is Snapshot<Type.InstanceType<S>>;\n} = ((...args: [schema: Type.AnyObj, value: unknown] | [schema: Type.AnyObj]) => {\n const check = (entity: unknown) =>\n entity != null &&\n typeof entity === 'object' &&\n Entity.SnapshotKindId in entity &&\n internal.isInstanceOf(args[0], entity);\n\n if (args.length === 1) {\n return (entity: unknown) => check(entity);\n }\n\n return check(args[1]);\n}) as any;\n\nexport type { GetURIOptions } from './internal';\n\n// TODO(dmaretskyi): Allow returning undefined.\n/**\n * Get the URI of the object.\n * Accepts both reactive objects and snapshots.\n *\n * @param options.prefer - Controls the URI form (see {@link GetURIOptions}).\n */\nexport const getURI = (entity: Unknown | Snapshot, options?: internal.GetURIOptions): URI.URI => {\n assertArgument(!Schema.isSchema(entity), 'obj', 'Object should not be a schema.');\n return internal.getUri(entity, options);\n};\n\n/**\n * @returns The DXN of the object's type.\n * @example dxn:com.example.type.person:1.0.0\n * @throws If the object is missing its type (corrupted object).\n */\nexport const getTypeURI = (obj: Unknown | Snapshot): URI.URI => {\n const type = internal.getTypeURI(obj);\n invariant(type != null, 'Corrupted object: missing type.');\n return type;\n};\n\n/**\n * Get the type entity (`Type.AnyObj`) the object was created from.\n *\n * Returns `undefined` when the object's type isn't registered in this runtime\n * (e.g. a freshly deserialized snapshot whose type entity hasn't been wired\n * up yet, or an object loaded from storage before its schema is known). To\n * get the Effect Schema from the returned entity, use `Type.getSchema(...)`.\n */\nexport const getType = (obj: Unknown | Snapshot): Type.AnyObj | undefined =>\n internal.getType(obj) as Type.AnyObj | undefined;\n\n/**\n * @returns The typename of the object's type.\n * Accepts both reactive objects and snapshots.\n * @example `com.example.type.person`\n */\nexport const getTypename = (entity: Unknown | Snapshot): string | undefined => internal.getTypename(entity);\n\n//\n// Database\n//\n\n/**\n * Get the database the object belongs to.\n * Accepts both reactive objects and snapshots.\n *\n * @idiom org.dxos.echo.objGetDatabase\n * applies: Reaching an object's database — to query, add, or remove — when the surrounding Space is not otherwise needed\n * instead-of: `getSpace(obj)?.db` (resolving the whole Space just to read its `.db`)\n * uses: {@link getDatabase}\n */\nexport const getDatabase = (entity: Entity.Unknown | Entity.Snapshot): Database.Database | undefined =>\n internal.getDatabase(entity);\n\n//\n// Meta\n//\n\n/**\n * Property that accesses metadata for an entity.\n *\n * Alias for `Entity.Meta`.\n */\nexport const Meta = internal.MetaId;\n\n/**\n * Deeply read-only version of EntityMeta.\n * Prevents mutation at all nesting levels (e.g., `meta.keys.push()` is a TypeScript error).\n */\nexport type ReadonlyMeta = internal.ReadonlyMeta;\n\n/**\n * Mutable meta type returned by `Obj.getMeta` inside an `Obj.update` callback.\n */\nexport type Meta = internal.Meta;\n\n// TODO(burdon): Narrow type.\n// TODO(dmaretskyi): Allow returning undefined.\n/**\n * Get the metadata for an object.\n * Returns mutable meta when passed a mutable object (inside `Obj.update` callback).\n * Returns read-only meta when passed a regular object or snapshot.\n *\n * @example\n * ```ts\n * // Read-only access outside change callback\n * const meta = Obj.getMeta(person); // ReadonlyMeta\n *\n * // Mutable access inside change callback\n * Obj.update(person, (obj) => {\n * const meta = Obj.getMeta(obj); // EntityMeta (mutable)\n * meta.tags.push(Ref.make(tag)); // tags are refs to Tag objects\n * });\n * ```\n */\n// TODO(wittjosiah): When passed a Snapshot, should return a snapshot of meta, not the live meta proxy.\nexport function getMeta(entity: Mutable<Unknown>): Meta;\nexport function getMeta(entity: Unknown | Snapshot): ReadonlyMeta;\nexport function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): Meta | ReadonlyMeta {\n return internal.getMetaChecked(entity);\n}\n\n/**\n * @returns Foreign keys for the object from the specified source.\n * Accepts both reactive objects and snapshots.\n */\nexport const getKeys: {\n (entity: Unknown | Snapshot, source: string): ForeignKey[];\n (source: string): (entity: Unknown | Snapshot) => ForeignKey[];\n} = Function.dual(2, (entity: Unknown | Snapshot, source?: string): ForeignKey[] => internal.getKeys(entity, source!));\n\n/**\n * Delete all keys from the object for the specified source.\n * Must be called within an `Obj.update` callback.\n *\n * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`\n * parameters, so there is no compile-time error. Enforcement is runtime-only.\n */\nexport const deleteKeys = (entity: Mutable<Unknown>, source: string): void => internal.deleteKeys(entity, source);\n\n/**\n * Add a tag to the object.\n * Must be called within an `Obj.update` callback.\n *\n * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`\n * parameters, so there is no compile-time error. Enforcement is runtime-only.\n */\nexport const addTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.addTag(entity, tag);\n\n/**\n * Remove a tag from the object.\n * Must be called within an `Obj.update` callback.\n *\n * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`\n * parameters, so there is no compile-time error. Enforcement is runtime-only.\n */\nexport const removeTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.removeTag(entity, tag);\n\n/**\n * Check if the object is deleted.\n * Accepts both reactive objects and snapshots.\n */\n// TODO(dmaretskyi): Default to `false`.\nexport const isDeleted = (entity: Unknown | Snapshot): boolean => objInternal.isDeleted(entity);\n\n//\n// Annotations\n//\n\n/**\n * Get the label of the object.\n * Accepts both reactive objects and snapshots.\n *\n * @param options.fallback `'typename'` returns the object's typename when no\n * label is set (e.g. `org.dxos.type.table`).\n */\nexport const getLabel = (entity: Unknown | Snapshot, options?: internal.GetLabelOptions): string | undefined =>\n internal.getLabel(entity, options);\n\n/**\n * Set the label of the object.\n * Must be called within an `Obj.update` callback.\n *\n * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`\n * parameters, so there is no compile-time error. Enforcement is runtime-only.\n */\nexport const setLabel = (entity: Mutable<Unknown>, label: string): void => internal.setLabel(entity, label);\n\n/**\n * Get the description of the object.\n * Accepts both reactive objects and snapshots.\n */\nexport const getDescription = (entity: Unknown | Snapshot): string | undefined => internal.getDescription(entity);\n\n/**\n * Get the icon annotation for the object (or any entity), resolved via its type-level\n * `IconAnnotation`. Accepts both reactive entities and snapshots, and either Objects or\n * Relations — the underlying schema-based lookup works for both.\n *\n * Returns the full `{ icon, hue }` annotation; callers wanting just the icon name typically\n * write `Obj.getIcon(obj)?.icon ?? 'ph--cube--regular'`.\n */\nexport const getIcon = (entity: Entity.Unknown | Entity.Snapshot): internal.IconAnnotation | undefined =>\n internal.getIcon(entity);\n\n/**\n * Set the description of the object.\n * Must be called within an `Obj.update` callback.\n *\n * NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`\n * parameters, so there is no compile-time error. Enforcement is runtime-only.\n */\nexport const setDescription = (entity: Mutable<Unknown>, description: string): void =>\n internal.setDescription(entity, description);\n\n/**\n * Symbol to set parent when creating objects with `Obj.make`.\n * @example\n * ```ts\n * Obj.make(TestSchema.Person, {\n * [Obj.Parent]: parentObject,\n * name: 'John',\n * })\n * ```\n */\nexport const Parent: unique symbol = internal.ParentId as any;\n\n/**\n * Get the parent of an object.\n * The parent is always loaded together with the object.\n * Only objects are allowed to have a parent\n * @returns The parent object, or undefined if the object has no parent.\n */\nexport const getParent = (entity: Unknown | Snapshot): Unknown | undefined => {\n assertArgument(isObject(entity) || isSnapshot(entity), 'Expected an object');\n assumeType<internal.InternalObjectProps>(entity);\n return entity[internal.ParentId] as Unknown | undefined;\n};\n\n/**\n * Sets the parent of an object.\n * If a parent (or any transitive parent) is deleted, the object will be deleted.\n * Only objects are allowed to have a parent.\n */\nexport const setParent = (entity: Unknown, parent: Any | undefined) => {\n assertArgument(isObject(entity), 'Expected an object');\n assertArgument(parent === undefined || isObject(parent), 'Expected an object');\n assumeType<internal.InternalObjectProps>(entity);\n assumeType<internal.InternalObjectProps | undefined>(parent);\n entity[internal.ParentId] = parent;\n return entity;\n};\n\ninterface UpdateFromOptions<T> {\n exclude?: (keyof T)[];\n include?: (keyof T)[];\n}\n\nconst valuesEqual = (left: unknown, right: unknown): boolean => {\n if (left === right) {\n return true;\n }\n if (left === null || right === null) {\n return left === right;\n }\n if (typeof left !== 'object' || typeof right !== 'object') {\n return Utils.structuralRegion(() => Equal.equals(left, right));\n }\n if (Ref.isRef(left) && Ref.isRef(right)) {\n return left.uri === right.uri;\n }\n if (Ref.isRef(left) || Ref.isRef(right)) {\n return false;\n }\n if (Array.isArray(left) && Array.isArray(right)) {\n if (left.length !== right.length) {\n return false;\n }\n for (let index = 0; index < left.length; index++) {\n if (!valuesEqual(left[index], right[index])) {\n return false;\n }\n }\n return true;\n }\n if (Array.isArray(left) || Array.isArray(right)) {\n return false;\n }\n const leftRecord = left as Record<string, unknown>;\n const rightRecord = right as Record<string, unknown>;\n const keys = new Set([\n ...Object.keys(leftRecord).filter((key) => key !== 'id'),\n ...Object.keys(rightRecord).filter((key) => key !== 'id'),\n ]);\n for (const key of keys) {\n const leftHas = Object.hasOwn(leftRecord, key);\n const rightHas = Object.hasOwn(rightRecord, key);\n const leftValue = leftHas ? leftRecord[key] : undefined;\n const rightValue = rightHas ? rightRecord[key] : undefined;\n if (!valuesEqual(leftValue, rightValue)) {\n return false;\n }\n }\n return true;\n};\n\n/**\n * Breaks reactive proxies on assigned values so echo-db assignment accepts nested structs (same idea as link assignment).\n */\nconst prepareAssignValue = (value: unknown): unknown =>\n deepMapValues(value, (nested, recurse) => {\n if (nested === null || typeof nested !== 'object') {\n return nested;\n }\n if (Ref.isRef(nested)) {\n return nested;\n }\n if (Array.isArray(nested)) {\n return recurse(nested);\n }\n if (isProxy(nested)) {\n return recurse({ ...getProxyTarget(nested) });\n }\n return recurse(nested);\n });\n\n/**\n * For each key present on `source` (except `id`), assigns `target[key]` when the current value differs.\n * References are compared by target DXN; other values use Effect `Equal.equals` inside a structural region,\n * with recursive comparison for arrays and plain object-shaped property bags (excluding `id`).\n *\n * Must be called within an `Obj.update` callback.\n *\n * @returns Whether any property was updated.\n */\nexport const updateFrom = <T extends Unknown>(\n target: Mutable<T>,\n source: T,\n options?: UpdateFromOptions<T>,\n): boolean => {\n assertArgument(isObject(target), 'Expected an echo object target.');\n assertArgument(isObject(source), 'Expected an echo object source.');\n let keys = Object.keys(source as Record<string, unknown>).filter((key) => key !== 'id');\n if (options?.include !== undefined) {\n const include = new Set(options.include.map((key) => String(key)));\n keys = keys.filter((key) => include.has(key));\n }\n if (options?.exclude !== undefined) {\n const exclude = new Set(options.exclude.map((key) => String(key)));\n keys = keys.filter((key) => !exclude.has(key));\n }\n let updated = false;\n const sourceRecord = source as Record<string, unknown>;\n const targetRecord = target as Record<string, unknown>;\n for (const key of keys) {\n if (!Object.hasOwn(sourceRecord, key)) {\n continue;\n }\n const nextValue = sourceRecord[key];\n const prevValue = Object.hasOwn(targetRecord, key) ? targetRecord[key] : undefined;\n if (valuesEqual(prevValue, nextValue)) {\n continue;\n }\n targetRecord[key] = prepareAssignValue(nextValue) as never;\n updated = true;\n }\n return updated;\n};\n\n//\n// JSON\n//\n\n/**\n * JSON representation of an object.\n */\nexport type JSON = internal.ObjectJSON;\n\n/**\n * Converts object to its JSON representation.\n * Accepts both reactive objects and snapshots.\n *\n * The same algorithm is used when calling the standard `JSON.stringify(obj)` function.\n */\nexport const toJSON = (entity: Unknown | Snapshot): JSON => objInternal.objectToJSON(entity);\n\n/**\n * Creates an object from its json representation, performing schema validation.\n * References and schemas will be resolvable if the `refResolver` is provided.\n *\n * The function must be async to support resolving the schema as well as the relation endpoints.\n *\n * @param options.refResolver - Resolver for references. Produces hydrated references that can be resolved.\n * @param options.uri - Override object URI. Changes the result of `Obj.getURI`.\n * @param options.database - Database to associate with the object.\n */\nexport const fromJSON: (\n json: unknown,\n options?: { refResolver?: Ref.Resolver; uri?: URI.URI; database?: Database.Database; parent?: Unknown },\n) => Promise<Unknown> = objInternal.objectFromJSON as any;\n\n/**\n * Comparator function type for sorting objects.\n * Accepts both reactive objects and snapshots.\n */\nexport type Comparator = internal.Comparator<Unknown | Snapshot>;\n\nexport const sortByLabel: Comparator = internal.sortByLabel as Comparator;\nexport const sortByTypename: Comparator = internal.sortByTypename as Comparator;\nexport const sort = (...comparators: Comparator[]): Comparator => internal.sort(...comparators) as Comparator;\n\n//\n// Version\n//\n\nexport const VersionTypeId = internal.VersionTypeId;\nexport type VersionCompareResult = internal.VersionCompareResult;\n\n/**\n * Represent object version.\n * May be backed by Automerge.\n * Objects with no history are not versioned.\n */\nexport type Version = internal.EntityVersion;\n\nexport const isVersion = internal.isVersion;\nexport const versionValid = internal.versionValid;\nexport const compareVersions = internal.compareVersions;\nexport const encodeVersion = internal.encodeVersion;\nexport const decodeVersion = internal.decodeVersion;\n\n/**\n * Returns the version of the object.\n * Accepts both reactive objects and snapshots.\n */\nexport const version = (entity: Unknown | Snapshot): Version => internal.version(entity);\n\n//\n// Atoms\n//\n\nexport const atom = objInternal.makeAtom;\nexport const atomReactive = objInternal.makeWithReactive;\nexport const atomProperty = objInternal.makeProperty;\nexport const labelAtom = objInternal.makeLabelAtom;\nexport const labelProperty = internal.getLabelProperty;\n"],
5
- "mappings": "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",
6
- "names": ["Unknown", "VersionTypeId", "addTag", "clone", "compareVersions", "decodeVersion", "deleteKeys", "encodeVersion", "getDatabase", "getDescription", "getIcon", "getKeys", "getLabel", "getSnapshot", "getType", "getTypeURI", "getTypename", "isDeleted", "isVersion", "removeTag", "setDescription", "setLabel", "setValue", "sort", "sortByLabel", "sortByTypename", "subscribe", "version", "versionValid", "Effect", "Equal", "Function", "Option", "Schema", "Utils", "SchemaEx", "assertArgument", "invariant", "EntityId", "assumeType", "deepMapValues", "Schema", "Record", "key", "annotations", "TypeAnnotationId", "kind", "Kind", "typename", "ANY_OBJECT_TYPENAME", "version", "internal", "ANY_OBJECT_VERSION", "input", "meta", "undefined", "props", "defaultMeta", "MetaId", "Object", "getOwnPropertySymbols", "value", "filterUndefined", "sym", "isSnapshot", "obj", "subscribe", "Effect", "GetReactiveError", "reason", "snapshotId", "snapshot", "id", "setValue", "entity", "isInstanceOf", "args", "length", "check", "options", "invariant", "type", "getTypename", "getDatabase", "getMetaChecked", "isDeleted", "assumeType", "ParentId", "assertArgument", "parent", "isObject", "valuesEqual", "left", "Ref", "right", "isRef", "Array", "isArray", "index", "leftRecord", "keys", "Set", "rightRecord", "rightHas", "leftValue", "leftHas", "rightValue", "nested", "isProxy", "getProxyTarget", "source", "filter", "include", "map", "String", "exclude", "updated", "targetRecord", "hasOwn", "prevValue", "nextValue", "sortByTypename", "sort", "comparators", "versionValid", "compareVersions", "encodeVersion", "decodeVersion", "atomProperty", "objInternal", "labelAtom", "makeLabelAtom", "labelProperty", "getLabelProperty"]
7
- }