@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
package/src/Feed.ts CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  import * as Context from 'effect/Context';
8
8
  import * as Effect from 'effect/Effect';
9
+ import * as Function from 'effect/Function';
9
10
  import * as Layer from 'effect/Layer';
10
11
  import type * as Option from 'effect/Option';
11
12
  import * as Schema from 'effect/Schema';
@@ -13,9 +14,11 @@ import * as Schema from 'effect/Schema';
13
14
  import { DXN, EID } from '@dxos/keys';
14
15
 
15
16
  import * as Annotation from './Annotation';
17
+ import * as Database from './Database';
16
18
  import type * as Entity from './Entity';
17
19
  import type * as Filter from './Filter';
18
20
  import * as internal from './internal';
21
+ import * as queryInternal from './internal/Query';
19
22
  import * as Obj from './Obj';
20
23
  import type * as Query from './Query';
21
24
  import type * as QueryResult from './QueryResult';
@@ -29,29 +32,25 @@ import * as Type from './Type';
29
32
  * const feed = Obj.make(Feed.Feed, { name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
30
33
  * ```
31
34
  */
32
- export const Feed = Schema.Struct({
33
- /** User-facing display name. */
34
- name: Schema.String.pipe(Schema.optional),
35
- /** Identifier for the feed's kind (e.g., plugin id). */
36
- kind: Schema.String.pipe(internal.FormInputAnnotation.set(false), Schema.optional),
35
+ export class Feed extends Type.makeObject<Feed>(DXN.make('org.dxos.type.feed', '0.1.0'))(
36
+ Schema.Struct({
37
+ /** User-facing display name. */
38
+ name: Schema.String.pipe(Schema.optional),
39
+ /** Identifier for the feed's kind (e.g., plugin id). */
40
+ kind: Schema.String.pipe(internal.FormInputAnnotation.set(false), Schema.optional),
37
41
 
38
- /**
39
- * Feed namespace.
40
- * Controls how feed data is stored and replicated.
41
- * - `data`: Data feed (default).
42
- * - `trace`: Trace feed.
43
- */
44
- namespace: Schema.optional(Schema.Literal('data', 'trace')),
45
- }).pipe(
46
- internal.HiddenAnnotation.set(true),
47
- Annotation.IconAnnotation.set({ icon: 'ph--rows--regular', hue: 'yellow' }),
48
- Type.makeObject(DXN.make('org.dxos.type.feed', '0.1.0')),
49
- );
50
-
51
- /**
52
- * TypeScript instance type for a Feed object.
53
- */
54
- export type Feed = Type.InstanceType<typeof Feed>;
42
+ /**
43
+ * Feed namespace.
44
+ * Controls how feed data is stored and replicated.
45
+ * - `data`: Data feed (default).
46
+ * - `trace`: Trace feed.
47
+ */
48
+ namespace: Schema.optional(Schema.Literal('data', 'trace')),
49
+ }).pipe(
50
+ internal.HiddenAnnotation.set(true),
51
+ Annotation.IconAnnotation.set({ icon: 'ph--rows--regular', hue: 'yellow' }),
52
+ ),
53
+ ) {}
55
54
 
56
55
  //
57
56
  // Types
@@ -97,27 +96,19 @@ export interface SyncState {
97
96
  totalBlocks: number;
98
97
  }
99
98
 
100
- //
101
- // Factory
102
- //
103
-
104
99
  /**
105
- * Creates a new feed object.
106
- *
107
- * @example
108
- * ```ts
109
- * const feed = Feed.make({ name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
110
- * ```
111
- */
112
- // TODO(wittjosiah): How to control the feed namespace (data/trace)? Why do feeds have namespaces?
113
- export const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);
114
-
115
- /**
116
- * Returns the feed object's EID when the feed is stored in a space.
117
- *
118
- * Used internally by the feed service layer.
100
+ * Effect service tag for injecting a Feed into effect operations.
101
+ * Used to provide a specific feed to operations that operate on it without threading
102
+ * the feed as an explicit parameter through every call site.
119
103
  */
120
- export const getQueueUri = (feed: Feed): EID.EID | undefined => EID.tryParse(Obj.getURI(feed));
104
+ export class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<
105
+ ContextFeedService,
106
+ {
107
+ readonly feed: Feed;
108
+ }
109
+ >() {
110
+ static layer = (feed: Feed) => Layer.succeed(ContextFeedService, { feed });
111
+ }
121
112
 
122
113
  //
123
114
  // Service
@@ -125,70 +116,25 @@ export const getQueueUri = (feed: Feed): EID.EID | undefined => EID.tryParse(Obj
125
116
 
126
117
  /**
127
118
  * Effect service for feed operations.
128
- * Provides the bridge to the underlying storage implementation.
129
- * Must be provided by the application layer (e.g., echo-db).
119
+ * @deprecated Use `Database.Service` instead feed operations now run directly on the database.
130
120
  */
131
121
  export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
132
122
  FeedService,
133
123
  {
134
- /**
135
- * Appends items to a feed.
136
- */
137
124
  append(feed: Feed, items: Entity.Unknown[]): Promise<void>;
138
-
139
- /**
140
- * Removes items from a feed by ID.
141
- */
142
125
  remove(feed: Feed, ids: string[]): Promise<void>;
143
-
144
- /**
145
- * Queries items in a feed.
146
- */
147
126
  query: {
148
127
  <Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;
149
128
  <F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;
150
129
  };
151
-
152
- /**
153
- * Syncs the feed with the server.
154
- */
155
130
  sync(feed: Feed, options?: SyncOptions): Promise<void>;
156
-
157
- /**
158
- * Returns queue replication backlog for the feed's namespace.
159
- */
160
131
  getSyncState(feed: Feed): Promise<SyncState>;
161
132
  }
162
133
  >() {}
163
134
 
164
135
  /**
165
- * @deprecated Use `FeedService` instead.
166
- */
167
- export type Service = FeedService;
168
-
169
- /**
170
- * @deprecated Use `FeedService` instead.
171
- */
172
- export const Service = FeedService;
173
-
174
- /**
175
- * Effect context service that holds the current feed for a scoped operation.
176
- *
177
- * @deprecated Prefer threading a `Feed.Feed` explicitly through function signatures
178
- * over hiding it behind a context service.
179
- */
180
- export class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<
181
- ContextFeedService,
182
- {
183
- readonly feed: Feed;
184
- }
185
- >() {
186
- static layer = (feed: Feed): Layer.Layer<ContextFeedService> => Layer.succeed(ContextFeedService, { feed });
187
- }
188
-
189
- /**
190
- * Layer that provides a Feed service that throws when accessed.
191
- * Useful as a default layer when no feed service is available.
136
+ * Layer that provides a `FeedService` that throws when accessed.
137
+ * @deprecated Use `Database.layer(db)` instead.
192
138
  */
193
139
  export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService, {
194
140
  append: () => {
@@ -198,7 +144,7 @@ export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService,
198
144
  throw new Error('Feed.FeedService not available');
199
145
  },
200
146
  query: () => {
201
- throw new Error('Feed.FeedService not available');
147
+ throw new Error('Feed.FeedService not available') as never;
202
148
  },
203
149
  sync: () => {
204
150
  throw new Error('Feed.FeedService not available');
@@ -208,6 +154,28 @@ export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService,
208
154
  },
209
155
  } as Context.Tag.Service<FeedService>);
210
156
 
157
+ //
158
+ // Factory
159
+ //
160
+
161
+ /**
162
+ * Creates a new feed object.
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * const feed = Feed.make({ name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
167
+ * ```
168
+ */
169
+ // TODO(wittjosiah): How to control the feed namespace (data/trace)? Why do feeds have namespaces?
170
+ export const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);
171
+
172
+ /**
173
+ * Returns the feed object's EID when the feed is stored in a space.
174
+ *
175
+ * Used internally by the feed service layer.
176
+ */
177
+ export const getQueueUri = (feed: Feed): EID.EID | undefined => EID.tryParse(Obj.getURI(feed));
178
+
211
179
  //
212
180
  // Operations
213
181
  //
@@ -220,11 +188,10 @@ export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService,
220
188
  * yield* Feed.append(feed, [Obj.make(Notification, { title: 'Hello' })]);
221
189
  * ```
222
190
  */
223
- export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, FeedService> =>
224
- Effect.gen(function* () {
225
- const service = yield* FeedService;
226
- yield* Effect.promise(() => service.append(feed, items));
227
- });
191
+ export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, Database.Service> =>
192
+ Database.Service.pipe(Effect.flatMap(({ db }) => Effect.promise(() => db.appendToFeed(feed, items)))).pipe(
193
+ Effect.withSpan('Feed.append'),
194
+ );
228
195
 
229
196
  /**
230
197
  * Removes items from a feed.
@@ -235,54 +202,61 @@ export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void,
235
202
  * ```
236
203
  */
237
204
  // TODO(dmaretskyi): Should we allow snapshots here? - what does it mean to remove a snapshot?
238
- export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, FeedService> =>
239
- Effect.gen(function* () {
240
- const service = yield* FeedService;
241
- const ids = items.map((item) => item.id);
242
- yield* Effect.promise(() => service.remove(feed, ids));
243
- });
205
+ export const remove = (
206
+ feed: Feed,
207
+ items: (Entity.Unknown | Obj.Snapshot)[],
208
+ ): Effect.Effect<void, never, Database.Service> =>
209
+ Database.Service.pipe(
210
+ Effect.flatMap(({ db }) =>
211
+ Effect.promise(() =>
212
+ db.removeFeedItemsByIds(
213
+ feed,
214
+ items.map((item) => item.id),
215
+ ),
216
+ ),
217
+ ),
218
+ ).pipe(Effect.withSpan('Feed.remove'));
244
219
 
245
220
  /**
246
221
  * Creates a reactive query over items in a feed.
247
222
  *
223
+ * Returns a {@link QueryResult.QueryResultEffect}: yielding it produces a subscribable
224
+ * `QueryResult`, while its `.run` / `.first` shorthands execute the query once. This mirrors
225
+ * `Database.query` so feed and database queries chain identically.
226
+ *
227
+ * Supports both data-first and data-last (curried) forms; the latter composes with `pipe`.
228
+ *
248
229
  * In non-Effect code, query a feed directly through the database with a feed scope:
249
230
  * `db.query(Query.select(filter).from(Scope.feed(Feed.getQueueUri(feed))))`.
250
231
  *
251
232
  * @example
252
233
  * ```ts
253
234
  * const result = yield* Feed.query(feed, Filter.type(Person));
235
+ * result.subscribe(...);
236
+ *
237
+ * const objects = yield* Feed.query(feed, Filter.type(Person)).run;
238
+ * const object = yield* Feed.query(feed, Filter.type(Person)).first;
239
+ *
240
+ * // Data-last (curried) form composes with `pipe`:
241
+ * const objects = yield* pipe(feed, Feed.query(Filter.type(Person))).run;
254
242
  * ```
255
243
  */
256
- // TODO(dmaretskyi): Suport chained queries:
257
- // const result = yield* feed.pipe(Feed.query(Filter.type(Person))); result.subscribe(...)
258
- // const objects = yield* feed.pipe(Feed.query(Filter.type(Person))).run;
259
- // const object = yield* feed.pipe(Feed.query(Filter.type(Person))).first;
260
- // ... unify for Database and schema queries.
261
244
  export const query: {
245
+ <Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResultEffect<Query.Type<Q>, never, Database.Service>;
246
+ <F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResultEffect<Filter.Type<F>, never, Database.Service>;
262
247
  <Q extends Query.Any>(
263
- feed: Feed,
264
248
  query: Q,
265
- ): Effect.Effect<QueryResult.QueryResult<Query.Type<Q>>, never, FeedService>;
249
+ ): (feed: Feed) => QueryResult.QueryResultEffect<Query.Type<Q>, never, Database.Service>;
266
250
  <F extends Filter.Any>(
267
- feed: Feed,
268
251
  filter: F,
269
- ): Effect.Effect<QueryResult.QueryResult<Filter.Type<F>>, never, FeedService>;
270
- } = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
271
- FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));
272
-
273
- /**
274
- * Executes a feed query once and returns the results.
275
- *
276
- * @example
277
- * ```ts
278
- * const items = yield* Feed.runQuery(feed, Filter.type(Person));
279
- * ```
280
- */
281
- export const runQuery: {
282
- <Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never, FeedService>;
283
- <F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never, FeedService>;
284
- } = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
285
- query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
252
+ ): (feed: Feed) => QueryResult.QueryResultEffect<Filter.Type<F>, never, Database.Service>;
253
+ } = Function.dual(2, (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
254
+ Database.Service.pipe(
255
+ Effect.map(({ db }) => db.queryFeed(feed, queryOrFilter)),
256
+ Effect.withSpan('Feed.query'),
257
+ queryInternal.makeQueryResultEffect,
258
+ ),
259
+ );
286
260
 
287
261
  /**
288
262
  * Syncs the feed with the server.
@@ -293,11 +267,10 @@ export const runQuery: {
293
267
  * yield* Feed.sync(feed, { shouldPush: false });
294
268
  * ```
295
269
  */
296
- export const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, FeedService> =>
297
- Effect.gen(function* () {
298
- const service = yield* FeedService;
299
- yield* Effect.promise(() => service.sync(feed, options));
300
- });
270
+ export const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, Database.Service> =>
271
+ Database.Service.pipe(Effect.flatMap(({ db }) => Effect.promise(() => db.syncFeed(feed, options)))).pipe(
272
+ Effect.withSpan('Feed.sync'),
273
+ );
301
274
 
302
275
  /**
303
276
  * Returns queue replication backlog for the feed's namespace.
@@ -307,11 +280,10 @@ export const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, nev
307
280
  * const { blocksToPull, blocksToPush } = yield* Feed.getSyncState(feed);
308
281
  * ```
309
282
  */
310
- export const getSyncState = (feed: Feed): Effect.Effect<SyncState, never, FeedService> =>
311
- Effect.gen(function* () {
312
- const service = yield* FeedService;
313
- return yield* Effect.promise(() => service.getSyncState(feed));
314
- });
283
+ export const getSyncState = (feed: Feed): Effect.Effect<SyncState, never, Database.Service> =>
284
+ Database.Service.pipe(Effect.flatMap(({ db }) => Effect.promise(() => db.getFeedSyncState(feed)))).pipe(
285
+ Effect.withSpan('Feed.getSyncState'),
286
+ );
315
287
 
316
288
  /**
317
289
  * Creates a cursor for iterating over feed items.
@@ -324,22 +296,23 @@ export const getSyncState = (feed: Feed): Effect.Effect<SyncState, never, FeedSe
324
296
  * ```
325
297
  */
326
298
  // TODO(wittjosiah): Implement cursor operations. Use Effect streams?
327
- export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, FeedService> =>
299
+ export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, Database.Service> =>
328
300
  Effect.succeed({ _tag: 'Cursor' } as Cursor<T>);
329
301
 
330
302
  /**
331
303
  * Returns the next item from a feed cursor.
332
304
  * Currently stubbed — cursor operations are not yet implemented.
333
305
  */
334
- export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, FeedService> =>
306
+ export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, Database.Service> =>
335
307
  Effect.die('Feed.next is not yet implemented');
336
308
 
337
309
  /**
338
310
  * Returns the next item from a feed cursor as an Option.
339
311
  * Currently stubbed — cursor operations are not yet implemented.
340
312
  */
341
- export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, FeedService> =>
342
- Effect.die('Feed.nextOption is not yet implemented');
313
+ export const nextOption = <T = Obj.Snapshot>(
314
+ _cursor: Cursor<T>,
315
+ ): Effect.Effect<Option.Option<T>, never, Database.Service> => Effect.die('Feed.nextOption is not yet implemented');
343
316
 
344
317
  /**
345
318
  * Sets the local retention policy for a feed.
@@ -351,5 +324,5 @@ export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<
351
324
  * ```
352
325
  */
353
326
  // TODO(dmaretskyi): Implement when feed retention is supported.
354
- export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>
327
+ export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, Database.Service> =>
355
328
  Effect.void;
@@ -4,7 +4,11 @@
4
4
 
5
5
  import { describe, expect, test } from 'vitest';
6
6
 
7
+ import { DXN } from '@dxos/keys';
8
+
7
9
  import * as Filter from './Filter';
10
+ import * as Obj from './Obj';
11
+ import { TestSchema } from './testing/test-schema';
8
12
 
9
13
  describe('Filter timestamp builders', () => {
10
14
  test('updated({ after }) produces correct AST', () => {
@@ -88,3 +92,37 @@ describe('Filter timestamp builders', () => {
88
92
  expect(Filter.is(f)).toBe(true);
89
93
  });
90
94
  });
95
+
96
+ describe('toPredicate', () => {
97
+ test('matches by type', () => {
98
+ const expando = Obj.make(TestSchema.Expando, { title: 'test' });
99
+ const match = Filter.toPredicate(Filter.type(TestSchema.Expando));
100
+ expect(match(expando)).toBe(true);
101
+ });
102
+
103
+ test('rejects wrong type', () => {
104
+ const person = Obj.make(TestSchema.Person, { name: 'Alice' });
105
+ const match = Filter.toPredicate(Filter.type(TestSchema.Expando));
106
+ expect(match(person)).toBe(false);
107
+ });
108
+
109
+ test('matches property constraints', () => {
110
+ const expando = Obj.make(TestSchema.Expando, { title: 'test', value: 100 });
111
+ const match = Filter.toPredicate(Filter.type(TestSchema.Expando, { title: 'test' }));
112
+ expect(match(expando)).toBe(true);
113
+ expect(Filter.toPredicate(Filter.type(TestSchema.Expando, { value: 200 }))(expando)).toBe(false);
114
+ });
115
+
116
+ test('matches or filters', () => {
117
+ const chat = DXN.make('org.dxos.type.assistant.chat', '0.1.0');
118
+ const agent = DXN.make('org.dxos.type.agent', '0.1.0');
119
+ const expando = Obj.make(TestSchema.Expando, {});
120
+ const match = Filter.toPredicate(Filter.or(Filter.type(chat), Filter.type(agent), Filter.type(TestSchema.Expando)));
121
+ expect(match(expando)).toBe(true);
122
+ });
123
+
124
+ test('dual form', () => {
125
+ const expando = Obj.make(TestSchema.Expando, {});
126
+ expect(Filter.toPredicate(expando, Filter.type(TestSchema.Expando))).toBe(true);
127
+ });
128
+ });
package/src/Filter.ts CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  // @import-as-namespace
6
6
 
7
+ import * as Function from 'effect/Function';
7
8
  import * as Match from 'effect/Match';
8
9
  import * as Schema from 'effect/Schema';
9
10
  import * as SchemaAST from 'effect/SchemaAST';
@@ -13,17 +14,17 @@ import { type ForeignKey, type QueryAST } from '@dxos/echo-protocol';
13
14
  import { assertArgument } from '@dxos/invariant';
14
15
  import { EID, EntityId, type URI } from '@dxos/keys';
15
16
 
17
+ import type * as Entity from './Entity';
16
18
  import * as internal from './internal';
17
19
  import type * as Obj from './Obj';
18
20
  import * as Ref from './Ref';
19
21
  // eslint-disable-next-line @dxos/rules/import-as-namespace
20
22
  import type * as Type$ from './Type';
21
-
22
23
  export interface Filter<T> {
23
24
  // TODO(dmaretskyi): See new effect-schema approach to variance.
24
25
  '~Filter': { value: Types.Covariant<T> };
25
26
 
26
- ast: QueryAST.Filter;
27
+ 'ast': QueryAST.Filter;
27
28
  }
28
29
 
29
30
  export type Props<T> = {
@@ -38,7 +39,7 @@ export type Type<F extends Any> = F extends Filter<infer T> ? T : never;
38
39
  class FilterClass implements Any {
39
40
  private static 'variance': Any['~Filter'] = {} as Any['~Filter'];
40
41
 
41
- constructor(public readonly ast: QueryAST.Filter) {}
42
+ 'constructor'(public readonly ast: QueryAST.Filter) {}
42
43
 
43
44
  '~Filter' = FilterClass.variance;
44
45
  }
@@ -482,3 +483,16 @@ const processPredicate = (predicate: any): QueryAST.Filter => {
482
483
  * Returns a human-readable string representation of a Filter AST.
483
484
  */
484
485
  export const pretty = (filter: Any): string => internal.prettyFilter(filter.ast);
486
+
487
+ /**
488
+ * Create a predicate from a filter.
489
+ */
490
+ export const toPredicate: {
491
+ <T extends Entity.Unknown>(filter: Filter<T>): (entity: Entity.Unknown) => entity is T;
492
+ <T extends Entity.Unknown>(entity: Entity.Unknown, filter: Filter<T>): entity is T;
493
+ } = Function.dual<
494
+ <T extends Entity.Unknown>(filter: Filter<T>) => (entity: Entity.Unknown) => entity is T,
495
+ <T extends Entity.Unknown>(entity: Entity.Unknown, filter: Filter<T>) => entity is T
496
+ >(2, <T extends Entity.Unknown>(entity: Entity.Unknown, filter: Filter<T>): entity is T =>
497
+ internal.filterMatchEntity(filter.ast, entity),
498
+ );
package/src/Hypergraph.ts CHANGED
@@ -6,7 +6,6 @@ import { type URI } from '@dxos/keys';
6
6
 
7
7
  import type * as Database from './Database';
8
8
  import type * as Entity from './Entity';
9
- import type * as internal from './internal';
10
9
  import type * as Key from './Key';
11
10
  import type * as Ref from './Ref';
12
11
  import type * as Registry from './Registry';
@@ -34,12 +33,6 @@ export interface RefResolverOptions {
34
33
  * Affects how non-absolute DXNs are resolved.
35
34
  */
36
35
  context?: RefResolutionContext;
37
-
38
- /**
39
- * Middleware to change the resolved object before returning it.
40
- * @deprecated On track to be removed.
41
- */
42
- middleware?: (obj: internal.AnyProperties) => internal.AnyProperties;
43
36
  }
44
37
 
45
38
  /**
@@ -69,11 +62,9 @@ export interface Hypergraph extends Database.Queryable {
69
62
  makeRef<T extends Entity.Unknown = Entity.Unknown>(uri: URI.URI): Ref.Ref<T>;
70
63
 
71
64
  /**
72
- * @param hostDb Host database for reference resolution.
73
- * @param middleware Called with the loaded object. The caller may change the object.
74
- * @returns Result of `onLoad`.
65
+ * Create a resolver that dereferences `Ref`s against this graph. Persisted schema objects are
66
+ * surfaced as their registered `Type.Type` entity.
75
67
  */
76
- // TODO(dmaretskyi): Restructure API: Remove middleware.
77
68
  createRefResolver(options: RefResolverOptions): Ref.Resolver;
78
69
 
79
70
  /**
package/src/Migration.ts CHANGED
@@ -10,7 +10,7 @@ import { type URI } from '@dxos/keys';
10
10
 
11
11
  import type * as Database from './Database';
12
12
  import type * as Entity from './Entity';
13
- import { MetaId, type EntityMeta, getSchemaURI } from './internal';
13
+ import { type EntityMeta, MetaId, getSchemaURI } from './internal';
14
14
  import * as Type from './Type';
15
15
 
16
16
  /**