@dxos/echo 0.10.0 → 0.11.1

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 (274) hide show
  1. package/dist/lib/Annotation.mjs +3 -0
  2. package/dist/lib/Blob.mjs +160 -0
  3. package/dist/lib/Blob.mjs.map +1 -0
  4. package/dist/lib/Database.mjs +2 -0
  5. package/dist/lib/Entity.mjs +231 -0
  6. package/dist/lib/Entity.mjs.map +1 -0
  7. package/dist/lib/Err.mjs +105 -0
  8. package/dist/lib/Err.mjs.map +1 -0
  9. package/dist/lib/Feed.mjs +338 -0
  10. package/dist/lib/Feed.mjs.map +1 -0
  11. package/dist/lib/Filter.mjs +380 -0
  12. package/dist/lib/Filter.mjs.map +1 -0
  13. package/dist/lib/Format.mjs +47 -0
  14. package/dist/lib/Format.mjs.map +1 -0
  15. package/dist/lib/JsonSchema.mjs +21 -0
  16. package/dist/lib/JsonSchema.mjs.map +1 -0
  17. package/dist/lib/Key.mjs +15 -0
  18. package/dist/lib/Key.mjs.map +1 -0
  19. package/dist/lib/Migration.mjs +38 -0
  20. package/dist/lib/Migration.mjs.map +1 -0
  21. package/dist/lib/Obj.mjs +660 -0
  22. package/dist/lib/Obj.mjs.map +1 -0
  23. package/dist/lib/Order.mjs +65 -0
  24. package/dist/lib/Order.mjs.map +1 -0
  25. package/dist/lib/Query.mjs +336 -0
  26. package/dist/lib/Query.mjs.map +1 -0
  27. package/dist/lib/QueryResult.mjs +7 -0
  28. package/dist/lib/QueryResult.mjs.map +1 -0
  29. package/dist/lib/Ref.mjs +44 -0
  30. package/dist/lib/Ref.mjs.map +1 -0
  31. package/dist/lib/Registry.mjs +35 -0
  32. package/dist/lib/Registry.mjs.map +1 -0
  33. package/dist/lib/Relation.mjs +397 -0
  34. package/dist/lib/Relation.mjs.map +1 -0
  35. package/dist/lib/Scope.mjs +51 -0
  36. package/dist/lib/Scope.mjs.map +1 -0
  37. package/dist/lib/Tag.mjs +70 -0
  38. package/dist/lib/Tag.mjs.map +1 -0
  39. package/dist/lib/Text.mjs +82 -0
  40. package/dist/lib/Text.mjs.map +1 -0
  41. package/dist/lib/Type.mjs +371 -0
  42. package/dist/lib/Type.mjs.map +1 -0
  43. package/dist/lib/chunk-Annotation.mjs +221 -0
  44. package/dist/lib/chunk-Annotation.mjs.map +1 -0
  45. package/dist/lib/chunk-Database.mjs +918 -0
  46. package/dist/lib/chunk-Database.mjs.map +1 -0
  47. package/dist/lib/chunk-atom-snapshot.mjs +249 -0
  48. package/dist/lib/chunk-atom-snapshot.mjs.map +1 -0
  49. package/dist/lib/chunk-internal.mjs +2775 -0
  50. package/dist/lib/chunk-internal.mjs.map +1 -0
  51. package/dist/lib/chunk-json-schema.mjs +660 -0
  52. package/dist/lib/chunk-json-schema.mjs.map +1 -0
  53. package/dist/lib/chunk-number.mjs +164 -0
  54. package/dist/lib/chunk-number.mjs.map +1 -0
  55. package/dist/lib/chunk-ref-array.mjs +31 -0
  56. package/dist/lib/chunk-ref-array.mjs.map +1 -0
  57. package/dist/lib/chunk-ref.mjs +590 -0
  58. package/dist/lib/chunk-ref.mjs.map +1 -0
  59. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  60. package/dist/lib/chunk-select.mjs +186 -0
  61. package/dist/lib/chunk-select.mjs.map +1 -0
  62. package/dist/lib/chunk-src.mjs +234 -0
  63. package/dist/lib/chunk-src.mjs.map +1 -0
  64. package/dist/lib/chunk-util.mjs +140 -0
  65. package/dist/lib/chunk-util.mjs.map +1 -0
  66. package/dist/lib/index.mjs +24 -0
  67. package/dist/lib/internal.mjs +10 -0
  68. package/dist/lib/testing.mjs +346 -0
  69. package/dist/lib/testing.mjs.map +1 -0
  70. package/dist/types/src/Aggregate.d.ts +86 -0
  71. package/dist/types/src/Aggregate.d.ts.map +1 -0
  72. package/dist/types/src/Blob.d.ts +153 -0
  73. package/dist/types/src/Blob.d.ts.map +1 -0
  74. package/dist/types/src/Blob.test.d.ts +2 -0
  75. package/dist/types/src/Blob.test.d.ts.map +1 -0
  76. package/dist/types/src/Database.d.ts +153 -4
  77. package/dist/types/src/Database.d.ts.map +1 -1
  78. package/dist/types/src/Err.d.ts +116 -0
  79. package/dist/types/src/Err.d.ts.map +1 -1
  80. package/dist/types/src/Feed.d.ts +116 -28
  81. package/dist/types/src/Feed.d.ts.map +1 -1
  82. package/dist/types/src/Feed.test.d.ts +2 -0
  83. package/dist/types/src/Feed.test.d.ts.map +1 -0
  84. package/dist/types/src/Filter.d.ts +14 -6
  85. package/dist/types/src/Filter.d.ts.map +1 -1
  86. package/dist/types/src/Hypergraph.d.ts +18 -0
  87. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  88. package/dist/types/src/Json.d.ts.map +1 -1
  89. package/dist/types/src/Obj.d.ts +14 -1
  90. package/dist/types/src/Obj.d.ts.map +1 -1
  91. package/dist/types/src/Order.d.ts +9 -3
  92. package/dist/types/src/Order.d.ts.map +1 -1
  93. package/dist/types/src/Query.d.ts +107 -26
  94. package/dist/types/src/Query.d.ts.map +1 -1
  95. package/dist/types/src/Relation.d.ts +6 -0
  96. package/dist/types/src/Relation.d.ts.map +1 -1
  97. package/dist/types/src/Type.d.ts.map +1 -1
  98. package/dist/types/src/View.d.ts +1 -1
  99. package/dist/types/src/index.d.ts +2 -0
  100. package/dist/types/src/index.d.ts.map +1 -1
  101. package/dist/types/src/internal/Entity/api.d.ts +6 -0
  102. package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
  103. package/dist/types/src/internal/Entity/model.d.ts +3 -2
  104. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  105. package/dist/types/src/internal/Filter/match.d.ts.map +1 -1
  106. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts +34 -8
  107. package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
  108. package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
  109. package/dist/types/src/internal/Obj/atoms.d.ts.map +1 -1
  110. package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
  111. package/dist/types/src/internal/Query/pretty.d.ts.map +1 -1
  112. package/dist/types/src/internal/Query/query-result-effect.d.ts.map +1 -1
  113. package/dist/types/src/internal/common/proxy/make-object.d.ts +13 -0
  114. package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
  115. package/dist/types/src/internal/common/proxy/reactive.d.ts.map +1 -1
  116. package/dist/types/src/internal/common/proxy/symbols.d.ts.map +1 -1
  117. package/dist/types/src/internal/common/proxy/typed-handler.d.ts +12 -0
  118. package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
  119. package/dist/types/src/internal/common/types/index.d.ts +1 -0
  120. package/dist/types/src/internal/common/types/index.d.ts.map +1 -1
  121. package/dist/types/src/internal/common/types/model-symbols.d.ts +5 -0
  122. package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -1
  123. package/dist/types/src/internal/common/types/projection.d.ts +32 -0
  124. package/dist/types/src/internal/common/types/projection.d.ts.map +1 -0
  125. package/dist/types/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +40 -35
  127. package/src/Aggregate.ts +105 -0
  128. package/src/Blob.test.ts +45 -0
  129. package/src/Blob.ts +205 -0
  130. package/src/Database.ts +207 -17
  131. package/src/Err.ts +36 -0
  132. package/src/Feed.test.ts +188 -0
  133. package/src/Feed.ts +238 -62
  134. package/src/Filter.ts +28 -10
  135. package/src/Hypergraph.ts +18 -0
  136. package/src/Json.ts +1 -0
  137. package/src/Obj.test.ts +2 -2
  138. package/src/Obj.ts +21 -1
  139. package/src/Order.ts +16 -9
  140. package/src/Query.test.ts +319 -2
  141. package/src/Query.ts +165 -51
  142. package/src/Relation.ts +14 -0
  143. package/src/Type.ts +5 -6
  144. package/src/index.ts +2 -0
  145. package/src/internal/Entity/api.ts +11 -1
  146. package/src/internal/Entity/model.ts +3 -0
  147. package/src/internal/Filter/match.ts +30 -1
  148. package/src/internal/JsonSchema/json-schema-type.ts +14 -2
  149. package/src/internal/JsonSchema/json-schema.test.ts +28 -1
  150. package/src/internal/JsonSchema/json-schema.ts +33 -6
  151. package/src/internal/Obj/atoms.ts +4 -2
  152. package/src/internal/Obj/json-serializer.test.ts +162 -2
  153. package/src/internal/Obj/json-serializer.ts +6 -0
  154. package/src/internal/Query/pretty.ts +19 -1
  155. package/src/internal/Query/query-result-effect.ts +2 -4
  156. package/src/internal/Ref/atoms.ts +1 -1
  157. package/src/internal/common/proxy/change-context.ts +1 -1
  158. package/src/internal/common/proxy/make-object.ts +42 -3
  159. package/src/internal/common/proxy/reactive.ts +5 -0
  160. package/src/internal/common/proxy/symbols.ts +1 -0
  161. package/src/internal/common/proxy/typed-handler.ts +71 -29
  162. package/src/internal/common/types/index.ts +1 -0
  163. package/src/internal/common/types/model-symbols.ts +6 -0
  164. package/src/internal/common/types/projection.ts +45 -0
  165. package/src/testing/test-data.ts +14 -14
  166. package/dist/lib/neutral/Annotation.mjs +0 -90
  167. package/dist/lib/neutral/Annotation.mjs.map +0 -7
  168. package/dist/lib/neutral/Database.mjs +0 -42
  169. package/dist/lib/neutral/Database.mjs.map +0 -7
  170. package/dist/lib/neutral/Entity.mjs +0 -76
  171. package/dist/lib/neutral/Entity.mjs.map +0 -7
  172. package/dist/lib/neutral/Err.mjs +0 -16
  173. package/dist/lib/neutral/Err.mjs.map +0 -7
  174. package/dist/lib/neutral/Feed.mjs +0 -50
  175. package/dist/lib/neutral/Feed.mjs.map +0 -7
  176. package/dist/lib/neutral/Filter.mjs +0 -72
  177. package/dist/lib/neutral/Filter.mjs.map +0 -7
  178. package/dist/lib/neutral/Format.mjs +0 -82
  179. package/dist/lib/neutral/Format.mjs.map +0 -7
  180. package/dist/lib/neutral/JsonSchema.mjs +0 -18
  181. package/dist/lib/neutral/JsonSchema.mjs.map +0 -7
  182. package/dist/lib/neutral/Key.mjs +0 -16
  183. package/dist/lib/neutral/Key.mjs.map +0 -7
  184. package/dist/lib/neutral/Migration.mjs +0 -18
  185. package/dist/lib/neutral/Migration.mjs.map +0 -7
  186. package/dist/lib/neutral/Obj.mjs +0 -128
  187. package/dist/lib/neutral/Obj.mjs.map +0 -7
  188. package/dist/lib/neutral/Order.mjs +0 -16
  189. package/dist/lib/neutral/Order.mjs.map +0 -7
  190. package/dist/lib/neutral/Query.mjs +0 -38
  191. package/dist/lib/neutral/Query.mjs.map +0 -7
  192. package/dist/lib/neutral/QueryResult.mjs +0 -2
  193. package/dist/lib/neutral/QueryResult.mjs.map +0 -7
  194. package/dist/lib/neutral/Ref.mjs +0 -25
  195. package/dist/lib/neutral/Ref.mjs.map +0 -7
  196. package/dist/lib/neutral/Registry.mjs +0 -14
  197. package/dist/lib/neutral/Registry.mjs.map +0 -7
  198. package/dist/lib/neutral/Relation.mjs +0 -97
  199. package/dist/lib/neutral/Relation.mjs.map +0 -7
  200. package/dist/lib/neutral/Scope.mjs +0 -12
  201. package/dist/lib/neutral/Scope.mjs.map +0 -7
  202. package/dist/lib/neutral/Tag.mjs +0 -32
  203. package/dist/lib/neutral/Tag.mjs.map +0 -7
  204. package/dist/lib/neutral/Text.mjs +0 -25
  205. package/dist/lib/neutral/Text.mjs.map +0 -7
  206. package/dist/lib/neutral/Type.mjs +0 -65
  207. package/dist/lib/neutral/Type.mjs.map +0 -7
  208. package/dist/lib/neutral/chunk-2HKGAQM4.mjs +0 -1394
  209. package/dist/lib/neutral/chunk-2HKGAQM4.mjs.map +0 -7
  210. package/dist/lib/neutral/chunk-2ZHECXUR.mjs +0 -95
  211. package/dist/lib/neutral/chunk-2ZHECXUR.mjs.map +0 -7
  212. package/dist/lib/neutral/chunk-3KTE2Y7Q.mjs +0 -336
  213. package/dist/lib/neutral/chunk-3KTE2Y7Q.mjs.map +0 -7
  214. package/dist/lib/neutral/chunk-3TN2VMI4.mjs +0 -714
  215. package/dist/lib/neutral/chunk-3TN2VMI4.mjs.map +0 -7
  216. package/dist/lib/neutral/chunk-42L4HJ3Z.mjs +0 -104
  217. package/dist/lib/neutral/chunk-42L4HJ3Z.mjs.map +0 -7
  218. package/dist/lib/neutral/chunk-4A2NWKRJ.mjs +0 -747
  219. package/dist/lib/neutral/chunk-4A2NWKRJ.mjs.map +0 -7
  220. package/dist/lib/neutral/chunk-7LOUAPYZ.mjs +0 -25
  221. package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +0 -7
  222. package/dist/lib/neutral/chunk-ACFAOTKJ.mjs +0 -1531
  223. package/dist/lib/neutral/chunk-ACFAOTKJ.mjs.map +0 -7
  224. package/dist/lib/neutral/chunk-BEFR7LEA.mjs +0 -170
  225. package/dist/lib/neutral/chunk-BEFR7LEA.mjs.map +0 -7
  226. package/dist/lib/neutral/chunk-BXIKXT7Q.mjs +0 -89
  227. package/dist/lib/neutral/chunk-BXIKXT7Q.mjs.map +0 -7
  228. package/dist/lib/neutral/chunk-C57XMMBY.mjs +0 -206
  229. package/dist/lib/neutral/chunk-C57XMMBY.mjs.map +0 -7
  230. package/dist/lib/neutral/chunk-C62JYFAD.mjs +0 -183
  231. package/dist/lib/neutral/chunk-C62JYFAD.mjs.map +0 -7
  232. package/dist/lib/neutral/chunk-FSGX2R62.mjs +0 -48
  233. package/dist/lib/neutral/chunk-FSGX2R62.mjs.map +0 -7
  234. package/dist/lib/neutral/chunk-HBXT3GSB.mjs +0 -459
  235. package/dist/lib/neutral/chunk-HBXT3GSB.mjs.map +0 -7
  236. package/dist/lib/neutral/chunk-IQR45HAD.mjs +0 -31
  237. package/dist/lib/neutral/chunk-IQR45HAD.mjs.map +0 -7
  238. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  239. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  240. package/dist/lib/neutral/chunk-KCBW4BR6.mjs +0 -424
  241. package/dist/lib/neutral/chunk-KCBW4BR6.mjs.map +0 -7
  242. package/dist/lib/neutral/chunk-L3E5IXAE.mjs +0 -575
  243. package/dist/lib/neutral/chunk-L3E5IXAE.mjs.map +0 -7
  244. package/dist/lib/neutral/chunk-PRC4FEKJ.mjs +0 -56
  245. package/dist/lib/neutral/chunk-PRC4FEKJ.mjs.map +0 -7
  246. package/dist/lib/neutral/chunk-SCT6FFCR.mjs +0 -351
  247. package/dist/lib/neutral/chunk-SCT6FFCR.mjs.map +0 -7
  248. package/dist/lib/neutral/chunk-TOCVVFK2.mjs +0 -75
  249. package/dist/lib/neutral/chunk-TOCVVFK2.mjs.map +0 -7
  250. package/dist/lib/neutral/chunk-U53LSQQA.mjs +0 -41
  251. package/dist/lib/neutral/chunk-U53LSQQA.mjs.map +0 -7
  252. package/dist/lib/neutral/chunk-UGFFV2FR.mjs +0 -27
  253. package/dist/lib/neutral/chunk-UGFFV2FR.mjs.map +0 -7
  254. package/dist/lib/neutral/chunk-UWLP4RFM.mjs +0 -7
  255. package/dist/lib/neutral/chunk-UWLP4RFM.mjs.map +0 -7
  256. package/dist/lib/neutral/chunk-UZHCQ6NI.mjs +0 -283
  257. package/dist/lib/neutral/chunk-UZHCQ6NI.mjs.map +0 -7
  258. package/dist/lib/neutral/chunk-WISOH2XH.mjs +0 -36
  259. package/dist/lib/neutral/chunk-WISOH2XH.mjs.map +0 -7
  260. package/dist/lib/neutral/chunk-WKIT2YY5.mjs +0 -34
  261. package/dist/lib/neutral/chunk-WKIT2YY5.mjs.map +0 -7
  262. package/dist/lib/neutral/chunk-XB6ISRAO.mjs +0 -271
  263. package/dist/lib/neutral/chunk-XB6ISRAO.mjs.map +0 -7
  264. package/dist/lib/neutral/chunk-XXL42WCB.mjs +0 -84
  265. package/dist/lib/neutral/chunk-XXL42WCB.mjs.map +0 -7
  266. package/dist/lib/neutral/chunk-XXWK4J53.mjs +0 -117
  267. package/dist/lib/neutral/chunk-XXWK4J53.mjs.map +0 -7
  268. package/dist/lib/neutral/index.mjs +0 -115
  269. package/dist/lib/neutral/index.mjs.map +0 -7
  270. package/dist/lib/neutral/internal/index.mjs +0 -581
  271. package/dist/lib/neutral/internal/index.mjs.map +0 -7
  272. package/dist/lib/neutral/meta.json +0 -1
  273. package/dist/lib/neutral/testing/index.mjs +0 -477
  274. package/dist/lib/neutral/testing/index.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/echo",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "description": "ECHO API",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,122 +16,127 @@
16
16
  ".": {
17
17
  "source": "./src/index.ts",
18
18
  "types": "./dist/types/src/index.d.ts",
19
- "default": "./dist/lib/neutral/index.mjs"
19
+ "import": "./dist/lib/index.mjs"
20
20
  },
21
21
  "./internal": {
22
22
  "source": "./src/internal/index.ts",
23
23
  "types": "./dist/types/src/internal/index.d.ts",
24
- "default": "./dist/lib/neutral/internal/index.mjs"
24
+ "import": "./dist/lib/internal.mjs"
25
25
  },
26
26
  "./testing": {
27
27
  "source": "./src/testing/index.ts",
28
28
  "types": "./dist/types/src/testing/index.d.ts",
29
- "default": "./dist/lib/neutral/testing/index.mjs"
29
+ "import": "./dist/lib/testing.mjs"
30
30
  },
31
31
  "./Annotation": {
32
32
  "source": "./src/Annotation.ts",
33
33
  "types": "./dist/types/src/Annotation.d.ts",
34
- "default": "./dist/lib/neutral/Annotation.mjs"
34
+ "import": "./dist/lib/Annotation.mjs"
35
+ },
36
+ "./Blob": {
37
+ "source": "./src/Blob.ts",
38
+ "types": "./dist/types/src/Blob.d.ts",
39
+ "import": "./dist/lib/Blob.mjs"
35
40
  },
36
41
  "./Database": {
37
42
  "source": "./src/Database.ts",
38
43
  "types": "./dist/types/src/Database.d.ts",
39
- "default": "./dist/lib/neutral/Database.mjs"
44
+ "import": "./dist/lib/Database.mjs"
40
45
  },
41
46
  "./Entity": {
42
47
  "source": "./src/Entity.ts",
43
48
  "types": "./dist/types/src/Entity.d.ts",
44
- "default": "./dist/lib/neutral/Entity.mjs"
49
+ "import": "./dist/lib/Entity.mjs"
45
50
  },
46
51
  "./Err": {
47
52
  "source": "./src/Err.ts",
48
53
  "types": "./dist/types/src/Err.d.ts",
49
- "default": "./dist/lib/neutral/Err.mjs"
54
+ "import": "./dist/lib/Err.mjs"
50
55
  },
51
56
  "./Feed": {
52
57
  "source": "./src/Feed.ts",
53
58
  "types": "./dist/types/src/Feed.d.ts",
54
- "default": "./dist/lib/neutral/Feed.mjs"
59
+ "import": "./dist/lib/Feed.mjs"
55
60
  },
56
61
  "./Filter": {
57
62
  "source": "./src/Filter.ts",
58
63
  "types": "./dist/types/src/Filter.d.ts",
59
- "default": "./dist/lib/neutral/Filter.mjs"
64
+ "import": "./dist/lib/Filter.mjs"
60
65
  },
61
66
  "./Format": {
62
67
  "source": "./src/Format.ts",
63
68
  "types": "./dist/types/src/Format.d.ts",
64
- "default": "./dist/lib/neutral/Format.mjs"
69
+ "import": "./dist/lib/Format.mjs"
65
70
  },
66
71
  "./JsonSchema": {
67
72
  "source": "./src/JsonSchema.ts",
68
73
  "types": "./dist/types/src/JsonSchema.d.ts",
69
- "default": "./dist/lib/neutral/JsonSchema.mjs"
74
+ "import": "./dist/lib/JsonSchema.mjs"
70
75
  },
71
76
  "./Key": {
72
77
  "source": "./src/Key.ts",
73
78
  "types": "./dist/types/src/Key.d.ts",
74
- "default": "./dist/lib/neutral/Key.mjs"
79
+ "import": "./dist/lib/Key.mjs"
75
80
  },
76
81
  "./Migration": {
77
82
  "source": "./src/Migration.ts",
78
83
  "types": "./dist/types/src/Migration.d.ts",
79
- "default": "./dist/lib/neutral/Migration.mjs"
84
+ "import": "./dist/lib/Migration.mjs"
80
85
  },
81
86
  "./Obj": {
82
87
  "source": "./src/Obj.ts",
83
88
  "types": "./dist/types/src/Obj.d.ts",
84
- "default": "./dist/lib/neutral/Obj.mjs"
89
+ "import": "./dist/lib/Obj.mjs"
85
90
  },
86
91
  "./Order": {
87
92
  "source": "./src/Order.ts",
88
93
  "types": "./dist/types/src/Order.d.ts",
89
- "default": "./dist/lib/neutral/Order.mjs"
94
+ "import": "./dist/lib/Order.mjs"
90
95
  },
91
96
  "./Query": {
92
97
  "source": "./src/Query.ts",
93
98
  "types": "./dist/types/src/Query.d.ts",
94
- "default": "./dist/lib/neutral/Query.mjs"
99
+ "import": "./dist/lib/Query.mjs"
95
100
  },
96
101
  "./QueryResult": {
97
102
  "source": "./src/QueryResult.ts",
98
103
  "types": "./dist/types/src/QueryResult.d.ts",
99
- "default": "./dist/lib/neutral/QueryResult.mjs"
104
+ "import": "./dist/lib/QueryResult.mjs"
100
105
  },
101
106
  "./Ref": {
102
107
  "source": "./src/Ref.ts",
103
108
  "types": "./dist/types/src/Ref.d.ts",
104
- "default": "./dist/lib/neutral/Ref.mjs"
109
+ "import": "./dist/lib/Ref.mjs"
105
110
  },
106
111
  "./Registry": {
107
112
  "source": "./src/Registry.ts",
108
113
  "types": "./dist/types/src/Registry.d.ts",
109
- "default": "./dist/lib/neutral/Registry.mjs"
114
+ "import": "./dist/lib/Registry.mjs"
110
115
  },
111
116
  "./Relation": {
112
117
  "source": "./src/Relation.ts",
113
118
  "types": "./dist/types/src/Relation.d.ts",
114
- "default": "./dist/lib/neutral/Relation.mjs"
119
+ "import": "./dist/lib/Relation.mjs"
115
120
  },
116
121
  "./Scope": {
117
122
  "source": "./src/Scope.ts",
118
123
  "types": "./dist/types/src/Scope.d.ts",
119
- "default": "./dist/lib/neutral/Scope.mjs"
124
+ "import": "./dist/lib/Scope.mjs"
120
125
  },
121
126
  "./Tag": {
122
127
  "source": "./src/Tag.ts",
123
128
  "types": "./dist/types/src/Tag.d.ts",
124
- "default": "./dist/lib/neutral/Tag.mjs"
129
+ "import": "./dist/lib/Tag.mjs"
125
130
  },
126
131
  "./Text": {
127
132
  "source": "./src/Text.ts",
128
133
  "types": "./dist/types/src/Text.d.ts",
129
- "default": "./dist/lib/neutral/Text.mjs"
134
+ "import": "./dist/lib/Text.mjs"
130
135
  },
131
136
  "./Type": {
132
137
  "source": "./src/Type.ts",
133
138
  "types": "./dist/types/src/Type.d.ts",
134
- "default": "./dist/lib/neutral/Type.mjs"
139
+ "import": "./dist/lib/Type.mjs"
135
140
  }
136
141
  },
137
142
  "files": [
@@ -142,16 +147,16 @@
142
147
  "@effect-atom/atom": "^0.5.3",
143
148
  "effect": "3.21.4",
144
149
  "semver": "^7.7.4",
145
- "@dxos/async": "0.10.0",
146
- "@dxos/debug": "0.10.0",
147
- "@dxos/echo-protocol": "0.10.0",
148
- "@dxos/effect": "0.10.0",
149
- "@dxos/errors": "0.10.0",
150
- "@dxos/keys": "0.10.0",
151
- "@dxos/invariant": "0.10.0",
152
- "@dxos/util": "0.10.0",
153
- "@dxos/log": "0.10.0",
154
- "@dxos/node-std": "0.10.0"
150
+ "@dxos/async": "0.11.1",
151
+ "@dxos/debug": "0.11.1",
152
+ "@dxos/echo-protocol": "0.11.1",
153
+ "@dxos/effect": "0.11.1",
154
+ "@dxos/errors": "0.11.1",
155
+ "@dxos/invariant": "0.11.1",
156
+ "@dxos/keys": "0.11.1",
157
+ "@dxos/log": "0.11.1",
158
+ "@dxos/node-std": "0.11.1",
159
+ "@dxos/util": "0.11.1"
155
160
  },
156
161
  "devDependencies": {
157
162
  "@types/node": "22.10.2",
@@ -0,0 +1,105 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import type * as EffectTypes from 'effect/Types';
8
+
9
+ import type { QueryAST } from '@dxos/echo-protocol';
10
+
11
+ import type * as Order from './Order';
12
+ import type * as Query from './Query';
13
+
14
+ /**
15
+ * The aggregate spec sans name; the name is supplied by the `Query.aggregate` record key. A tagged
16
+ * union per kind so `property`/`limit`/`order` are present exactly when the kind uses them (no
17
+ * unused optional fields to guard against at read sites).
18
+ */
19
+ export type Spec =
20
+ | { kind: 'group'; property: string }
21
+ | { kind: 'max'; property: string }
22
+ | { kind: 'min'; property: string }
23
+ | { kind: 'items'; limit?: number; order?: readonly QueryAST.Order[] }
24
+ | { kind: 'count' };
25
+
26
+ export const AggregateTypeId = '~@dxos/echo/Aggregate' as const;
27
+ export type AggregateTypeId = typeof AggregateTypeId;
28
+
29
+ /**
30
+ * A per-group aggregate declaration, materialised as a top-level field on the flat result record
31
+ * `Query.aggregate` produces and orderable via a following `orderBy(Order.property(name))`. Name it
32
+ * via the record passed to `Query.aggregate({ name: Aggregate.max('created') })`.
33
+ *
34
+ * `T` is the query's element type (so a reduced/grouped property is checked against it); `V` is the
35
+ * value the aggregate produces. {@link group} entries define the grouping keys; a record with no
36
+ * `group` entries aggregates the entire input into a single row.
37
+ */
38
+ export interface Aggregate<T, V> {
39
+ readonly [AggregateTypeId]: { element: T; value: V };
40
+
41
+ spec: Spec;
42
+ }
43
+
44
+ export type Any = Aggregate<any, any>;
45
+
46
+ /** Extracts the value type a {@link Aggregate} produces. */
47
+ export type ValueOf<A> = A extends Aggregate<any, infer V> ? V : never;
48
+
49
+ /** Computes the flat result type of `Query.aggregate(aggregates)` for a given aggregate record `A`. */
50
+ export type AggregationResult<A extends Record<string, Any>> = EffectTypes.Simplify<
51
+ Query.AggregateResult & { readonly [N in keyof A]: ValueOf<A[N]> }
52
+ >;
53
+
54
+ class AggregateClass<T, V> implements Aggregate<T, V> {
55
+ private static 'variance': Aggregate<any, any>[AggregateTypeId] = {} as Aggregate<any, any>[AggregateTypeId];
56
+
57
+ static is(value: unknown): value is Any {
58
+ return typeof value === 'object' && value !== null && AggregateTypeId in value;
59
+ }
60
+
61
+ constructor(public readonly spec: Spec) {}
62
+
63
+ [AggregateTypeId] = AggregateClass.variance as Aggregate<T, V>[AggregateTypeId];
64
+ }
65
+
66
+ /**
67
+ * Group members by a scalar property. The record key names the result field carrying the coerced
68
+ * group-key value; multiple `group` entries form a composite key. Members whose property is missing,
69
+ * `null`, `undefined`, or non-scalar group under the `null` key, so the field value is `T[K] | null`.
70
+ */
71
+ export const group = <T, K extends keyof T & string>(property: K): Aggregate<T, T[K] | null> =>
72
+ new AggregateClass({ kind: 'group', property });
73
+
74
+ /**
75
+ * Aggregate the maximum of a scalar property across the group's members.
76
+ * `T` is inferred from the `Query.aggregate` context, so `property` is checked against the query's
77
+ * element type (like {@link Order.property}).
78
+ */
79
+ export const max = <T, K extends keyof T & string>(property: K): Aggregate<T, T[K] | null> =>
80
+ new AggregateClass({ kind: 'max', property });
81
+
82
+ /**
83
+ * Aggregate the minimum of a scalar property across the group's members.
84
+ */
85
+ export const min = <T, K extends keyof T & string>(property: K): Aggregate<T, T[K] | null> =>
86
+ new AggregateClass({ kind: 'min', property });
87
+
88
+ /**
89
+ * Collect the group's members, optionally ordered by `order` and capped to `limit` per group.
90
+ * Opt-in — groups carry no members unless this aggregate is declared.
91
+ *
92
+ * `order` is this aggregate's own per-group ordering — independent of any `orderBy` elsewhere in
93
+ * the query, which orders the whole input stream (and, following `aggregate`, the resulting
94
+ * groups), not this aggregate's member selection. Without `order`, members keep whatever order
95
+ * they arrived in from a preceding `orderBy` (unspecified if there is none), so a per-group
96
+ * top-`limit` moved position in the chain would silently change; declaring `order` here makes the
97
+ * ordering explicit and local to this aggregate regardless of where it sits.
98
+ */
99
+ export const items = <T>(options?: { limit?: number; order?: Order.Any[] }): Aggregate<T, T[]> =>
100
+ new AggregateClass({ kind: 'items', limit: options?.limit, order: options?.order?.map((order) => order.ast) });
101
+
102
+ /**
103
+ * Count the group's members. Opt-in — groups carry no count unless this aggregate is declared.
104
+ */
105
+ export const count = <T>(): Aggregate<T, number> => new AggregateClass({ kind: 'count' });
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import { describe, test } from 'vitest';
7
+
8
+ import * as Blob from './Blob';
9
+
10
+ describe('Blob', () => {
11
+ test('inline data schema roundtrip', ({ expect }) => {
12
+ const bytes = new Uint8Array([1, 2, 3, 4]);
13
+ const data = Blob.inlineData(bytes);
14
+ const decoded = Schema.decodeUnknownSync(Blob.BlobData)(data);
15
+ expect(decoded).toEqual({ _tag: 'inline', bytes });
16
+ });
17
+
18
+ test('external data schema roundtrip', ({ expect }) => {
19
+ const uri = 'ni:///sha-256;3q2-7w';
20
+ const data = Blob.externalData(uri);
21
+ const decoded = Schema.decodeUnknownSync(Blob.BlobData)(data);
22
+ expect(decoded).toEqual({ _tag: 'external', uri });
23
+ });
24
+
25
+ test('rejects an unknown tag', ({ expect }) => {
26
+ expect(() => Schema.decodeUnknownSync(Blob.BlobData)({ _tag: 'bogus' })).toThrow();
27
+ });
28
+
29
+ test('make constructs a valid Blob object', ({ expect }) => {
30
+ const bytes = new Uint8Array([1, 2, 3]);
31
+ const blob = Blob.make({ type: 'image/png', size: bytes.length, data: Blob.inlineData(bytes) });
32
+ expect(blob.type).toBe('image/png');
33
+ expect(blob.size).toBe(bytes.length);
34
+ expect(blob.data).toEqual({ _tag: 'inline', bytes });
35
+ });
36
+
37
+ test('Storage constants', ({ expect }) => {
38
+ expect(Blob.Storage.inline).toBe('inline');
39
+ expect(Blob.Storage.edge).toBe('edge');
40
+ });
41
+
42
+ test('Scheme constants', ({ expect }) => {
43
+ expect(Blob.Scheme.ni).toBe('ni');
44
+ });
45
+ });
package/src/Blob.ts ADDED
@@ -0,0 +1,205 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Option from 'effect/Option';
9
+ import * as Schema from 'effect/Schema';
10
+
11
+ import { DXN } from '@dxos/keys';
12
+
13
+ import * as Annotation from './Annotation';
14
+ import * as Database from './Database';
15
+ import * as Err from './Err';
16
+ import * as internal from './internal';
17
+ import * as Obj from './Obj';
18
+ import * as Type from './Type';
19
+
20
+ /**
21
+ * Inline blob data: bytes stored directly on the ECHO object.
22
+ */
23
+ export const InlineData = Schema.TaggedStruct('inline', {
24
+ bytes: Schema.Uint8ArrayFromSelf.annotations({ jsonSchema: { type: 'string', contentEncoding: 'base64' } }),
25
+ });
26
+
27
+ /**
28
+ * External blob data: bytes stored by a registered blob backend, addressed by `uri`.
29
+ */
30
+ export const ExternalData = Schema.TaggedStruct('external', {
31
+ /**
32
+ * URI locating the bytes. The scheme selects the backend at read time (e.g. `ni:///sha-256;…` for
33
+ * the edge backend — an RFC 6920 content digest, not a backend name — or `wnfs://…` for the
34
+ * plugin-wnfs extension), resolved via the scheme→backend map built from `registerBlobBackend`
35
+ * calls. Core code never parses or constructs backend-specific URIs beyond reading the scheme.
36
+ *
37
+ * @see {@link https://www.rfc-editor.org/rfc/rfc6920 RFC 6920} for the `ni:` URI format.
38
+ */
39
+ uri: Schema.String,
40
+ });
41
+
42
+ export const BlobData = Schema.Union(InlineData, ExternalData);
43
+ export type BlobData = Schema.Schema.Type<typeof BlobData>;
44
+
45
+ /**
46
+ * Runtime schema for a Blob object.
47
+ *
48
+ * NOTE: This export shadows the DOM `Blob` global within modules that import it as a namespace.
49
+ * Code that needs the DOM class should use `globalThis.Blob` explicitly.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const blob = yield* Blob.fromBytes(bytes, { type: 'image/png' });
54
+ * ```
55
+ */
56
+ export class Blob extends Type.makeObject<Blob>(DXN.make('org.dxos.type.blob', '0.1.0'))(
57
+ Schema.Struct({
58
+ /** MIME type. */
59
+ type: Schema.optional(Schema.String),
60
+ size: Schema.Number,
61
+ data: BlobData,
62
+ }).pipe(
63
+ internal.HiddenAnnotation.set(true),
64
+ Annotation.IconAnnotation.set({ icon: 'ph--file--regular', hue: 'teal' }),
65
+ ),
66
+ ) {}
67
+
68
+ //
69
+ // Storage constants
70
+ //
71
+
72
+ /**
73
+ * Storage backend names, selected at write time via {@link FromBytesOptions.storage}. Call sites
74
+ * always use these constants, never raw string literals. Extensions (e.g. plugin-wnfs) define
75
+ * their own storage names in their own package — core code knows nothing of them.
76
+ *
77
+ * Distinct from {@link Scheme}: a storage name picks *where* to write, a URI scheme describes
78
+ * *what the identifier is* at read time. They coincide for backends with no content-addressing
79
+ * (e.g. wnfs uses `'wnfs'` for both), but the edge backend's storage name (`'edge'`) differs from
80
+ * its URI scheme (`Scheme.ni`) because the identifier it produces is a content hash, not an
81
+ * edge-specific address.
82
+ */
83
+ export const Storage = { inline: 'inline', edge: 'edge' } as const;
84
+ export type Storage = (typeof Storage)[keyof typeof Storage];
85
+
86
+ /**
87
+ * URI schemes claimed by core backends (see `BlobBackend.schemes` in `@dxos/echo-protocol`).
88
+ *
89
+ * `ni` marks an {@link https://www.rfc-editor.org/rfc/rfc6920 RFC 6920} Named Information URI whose
90
+ * authority is empty and whose path carries a registered hash-algorithm name plus a base64url-encoded
91
+ * digest (e.g. `ni:///sha-256;UyaQNQIUxQKgg1jVMKMbg1Yr8Rrb2Y3RaOx2N0mVJhc`, produced by the edge
92
+ * backend). The scheme names *what the identifier is* — a content digest over the complete blob —
93
+ * not which backend wrote it, so any backend or cache that can resolve that digest may claim it.
94
+ * The URI is an identity claim, not a retrievability promise; transport is selected by the registered
95
+ * backend at read time.
96
+ *
97
+ * Extensions (e.g. plugin-wnfs) define their own schemes in their own package.
98
+ */
99
+ export const Scheme = { ni: 'ni' } as const;
100
+ export type Scheme = (typeof Scheme)[keyof typeof Scheme];
101
+
102
+ //
103
+ // Factory
104
+ //
105
+
106
+ export const MAX_INLINE_SIZE = 4 * 1024 * 1024;
107
+
108
+ /**
109
+ * Creates a new blob object. Does not add it to the database — see {@link fromBytes}.
110
+ */
111
+ export const make = (props: Obj.MakeProps<typeof Blob>): Blob => Obj.make(Blob, props);
112
+
113
+ /**
114
+ * Creates an inline {@link BlobData} variant that embeds raw bytes on the ECHO object.
115
+ */
116
+ export const inlineData = (bytes: Uint8Array): BlobData => ({ _tag: 'inline', bytes });
117
+
118
+ /**
119
+ * Creates an external {@link BlobData} variant that references bytes held by a registered backend.
120
+ * @param uri - Backend-scoped URI, e.g. as returned by a `BlobBackend.put` call.
121
+ */
122
+ export const externalData = (uri: string): BlobData => ({ _tag: 'external', uri });
123
+
124
+ export interface FromBytesOptions {
125
+ /** MIME type. */
126
+ type?: string;
127
+ /**
128
+ * Storage backend name. Defaults to the registry's configured default (initially `'inline'`;
129
+ * `@dxos/client` marks `'edge'` as the default when configured).
130
+ */
131
+ storage?: Storage | (string & {});
132
+ }
133
+
134
+ //
135
+ // Operations
136
+ //
137
+
138
+ /**
139
+ * Hashes and uploads `bytes` via the chosen storage backend (a no-op for `inline`), returning an
140
+ * un-added Blob object. The caller is responsible for adding it to the database.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * const blob = yield* Blob.fromBytes(bytes, { type: 'image/png' });
145
+ * yield* Database.add(blob);
146
+ * ```
147
+ */
148
+ export const fromBytes = (
149
+ bytes: Uint8Array,
150
+ options?: FromBytesOptions,
151
+ ): Effect.Effect<Blob, Err.BlobTooLargeError | Err.BlobWriteError, Database.Service> =>
152
+ Database.Service.pipe(
153
+ Effect.flatMap(({ db }) =>
154
+ Effect.tryPromise({
155
+ try: () => db.createBlob(bytes, options),
156
+ catch: (error) =>
157
+ error instanceof Err.BlobTooLargeError || error instanceof Err.BlobWriteError
158
+ ? error
159
+ : new Err.BlobWriteError({ backend: options?.storage ?? 'unknown' }, { cause: error }),
160
+ }),
161
+ ),
162
+ ).pipe(Effect.withSpan('Blob.fromBytes'));
163
+
164
+ /**
165
+ * Loads a blob's bytes. Inline: read directly off the object. External: dispatched to the
166
+ * registered backend for the URI's scheme.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * const bytes = yield* Blob.read(blob);
171
+ * ```
172
+ */
173
+ export const read = (blob: Blob): Effect.Effect<Uint8Array, Err.BlobNotAvailableError, Database.Service> =>
174
+ Database.Service.pipe(
175
+ Effect.flatMap(({ db }) =>
176
+ Effect.tryPromise({
177
+ try: () => db.readBlob(blob),
178
+ catch: (error) =>
179
+ error instanceof Err.BlobNotAvailableError
180
+ ? error
181
+ : new Err.BlobNotAvailableError(
182
+ { backend: 'unknown', key: blob.id, reason: 'not-found' },
183
+ { cause: error },
184
+ ),
185
+ }),
186
+ ),
187
+ ).pipe(Effect.withSpan('Blob.read'));
188
+
189
+ /**
190
+ * Checks whether a blob's bytes are currently available.
191
+ */
192
+ export const exists = (blob: Blob): Effect.Effect<boolean, never, Database.Service> =>
193
+ Database.Service.pipe(Effect.flatMap(({ db }) => Effect.promise(() => db.blobExists(blob)))).pipe(
194
+ Effect.withSpan('Blob.exists'),
195
+ );
196
+
197
+ /**
198
+ * Returns a renderable URL for the blob: inline blobs resolve to a `data:` URL; external blobs
199
+ * are resolved by the registered backend's `getUrl`, if it implements one.
200
+ */
201
+ export const url = (blob: Blob): Effect.Effect<Option.Option<string>, never, Database.Service> =>
202
+ Database.Service.pipe(
203
+ Effect.flatMap(({ db }) => Effect.promise(() => db.getBlobUrl(blob))),
204
+ Effect.map(Option.fromNullable),
205
+ ).pipe(Effect.withSpan('Blob.url'));