@dxos/echo 0.8.4-main.dedc0f3 → 0.8.4-main.ead640a

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 (310) hide show
  1. package/dist/lib/browser/chunk-HKFCK2GL.mjs +175 -0
  2. package/dist/lib/browser/chunk-HKFCK2GL.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-MTR3E5S2.mjs → chunk-MAAYELT7.mjs} +501 -457
  4. package/dist/lib/browser/chunk-MAAYELT7.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-MB6MMNFP.mjs +3857 -0
  6. package/dist/lib/browser/chunk-MB6MMNFP.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +14 -5
  8. package/dist/lib/browser/internal/index.mjs +332 -0
  9. package/dist/lib/browser/internal/index.mjs.map +7 -0
  10. package/dist/lib/browser/meta.json +1 -1
  11. package/dist/lib/browser/query/index.mjs +15 -0
  12. package/dist/lib/browser/query/index.mjs.map +7 -0
  13. package/dist/lib/browser/testing/index.mjs +260 -32
  14. package/dist/lib/browser/testing/index.mjs.map +4 -4
  15. package/dist/lib/node-esm/{chunk-MYZLAJSR.mjs → chunk-5NWDGIBT.mjs} +501 -457
  16. package/dist/lib/node-esm/chunk-5NWDGIBT.mjs.map +7 -0
  17. package/dist/lib/node-esm/chunk-AUAH4E2J.mjs +175 -0
  18. package/dist/lib/node-esm/chunk-AUAH4E2J.mjs.map +7 -0
  19. package/dist/lib/node-esm/chunk-BQRA4VLX.mjs +3857 -0
  20. package/dist/lib/node-esm/chunk-BQRA4VLX.mjs.map +7 -0
  21. package/dist/lib/node-esm/index.mjs +14 -5
  22. package/dist/lib/node-esm/internal/index.mjs +332 -0
  23. package/dist/lib/node-esm/internal/index.mjs.map +7 -0
  24. package/dist/lib/node-esm/meta.json +1 -1
  25. package/dist/lib/node-esm/query/index.mjs +15 -0
  26. package/dist/lib/node-esm/query/index.mjs.map +7 -0
  27. package/dist/lib/node-esm/testing/index.mjs +260 -32
  28. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  29. package/dist/types/src/Obj.d.ts +22 -5
  30. package/dist/types/src/Obj.d.ts.map +1 -1
  31. package/dist/types/src/Ref.d.ts +1 -1
  32. package/dist/types/src/Ref.d.ts.map +1 -1
  33. package/dist/types/src/Relation.d.ts +5 -4
  34. package/dist/types/src/Relation.d.ts.map +1 -1
  35. package/dist/types/src/Type.d.ts +16 -17
  36. package/dist/types/src/Type.d.ts.map +1 -1
  37. package/dist/types/src/errors.d.ts +72 -0
  38. package/dist/types/src/errors.d.ts.map +1 -0
  39. package/dist/types/src/index.d.ts +3 -2
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/internal/ast/annotation-helper.d.ts +8 -0
  42. package/dist/types/src/internal/ast/annotation-helper.d.ts.map +1 -0
  43. package/dist/types/src/internal/ast/annotations.d.ts +125 -0
  44. package/dist/types/src/internal/ast/annotations.d.ts.map +1 -0
  45. package/dist/types/src/internal/ast/annotations.test.d.ts +2 -0
  46. package/dist/types/src/internal/ast/annotations.test.d.ts.map +1 -0
  47. package/dist/types/src/internal/ast/entity-kind.d.ts +10 -0
  48. package/dist/types/src/internal/ast/entity-kind.d.ts.map +1 -0
  49. package/dist/types/src/internal/ast/index.d.ts +5 -0
  50. package/dist/types/src/internal/ast/index.d.ts.map +1 -0
  51. package/dist/types/src/internal/ast/types.d.ts +6 -0
  52. package/dist/types/src/internal/ast/types.d.ts.map +1 -0
  53. package/dist/types/src/internal/formats/date.d.ts +63 -0
  54. package/dist/types/src/internal/formats/date.d.ts.map +1 -0
  55. package/dist/types/src/internal/formats/date.test.d.ts +2 -0
  56. package/dist/types/src/internal/formats/date.test.d.ts.map +1 -0
  57. package/dist/types/src/internal/formats/format.d.ts +30 -0
  58. package/dist/types/src/internal/formats/format.d.ts.map +1 -0
  59. package/dist/types/src/internal/formats/format.test.d.ts +2 -0
  60. package/dist/types/src/internal/formats/format.test.d.ts.map +1 -0
  61. package/dist/types/src/internal/formats/index.d.ts +8 -0
  62. package/dist/types/src/internal/formats/index.d.ts.map +1 -0
  63. package/dist/types/src/internal/formats/number.d.ts +31 -0
  64. package/dist/types/src/internal/formats/number.d.ts.map +1 -0
  65. package/dist/types/src/internal/formats/object.d.ts +35 -0
  66. package/dist/types/src/internal/formats/object.d.ts.map +1 -0
  67. package/dist/types/src/internal/formats/select.d.ts +11 -0
  68. package/dist/types/src/internal/formats/select.d.ts.map +1 -0
  69. package/dist/types/src/internal/formats/string.d.ts +38 -0
  70. package/dist/types/src/internal/formats/string.d.ts.map +1 -0
  71. package/dist/types/src/internal/formats/types.d.ts +68 -0
  72. package/dist/types/src/internal/formats/types.d.ts.map +1 -0
  73. package/dist/types/src/internal/index.d.ts +15 -0
  74. package/dist/types/src/internal/index.d.ts.map +1 -0
  75. package/dist/types/src/internal/json/annotations.d.ts +19 -0
  76. package/dist/types/src/internal/json/annotations.d.ts.map +1 -0
  77. package/dist/types/src/internal/json/effect-schema.test.d.ts +2 -0
  78. package/dist/types/src/internal/json/effect-schema.test.d.ts.map +1 -0
  79. package/dist/types/src/internal/json/index.d.ts +2 -0
  80. package/dist/types/src/internal/json/index.d.ts.map +1 -0
  81. package/dist/types/src/internal/json/json-schema.d.ts +28 -0
  82. package/dist/types/src/internal/json/json-schema.d.ts.map +1 -0
  83. package/dist/types/src/internal/json/json-schema.test.d.ts +2 -0
  84. package/dist/types/src/internal/json/json-schema.test.d.ts.map +1 -0
  85. package/dist/types/src/internal/json-schema/index.d.ts +3 -0
  86. package/dist/types/src/internal/json-schema/index.d.ts.map +1 -0
  87. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts +7 -0
  88. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +1 -0
  89. package/dist/types/src/internal/json-schema/json-schema-type.d.ts +250 -0
  90. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +1 -0
  91. package/dist/types/src/internal/object/accessors.d.ts +37 -0
  92. package/dist/types/src/internal/object/accessors.d.ts.map +1 -0
  93. package/dist/types/src/internal/object/common.d.ts +18 -0
  94. package/dist/types/src/internal/object/common.d.ts.map +1 -0
  95. package/dist/types/src/internal/object/create.d.ts +40 -0
  96. package/dist/types/src/internal/object/create.d.ts.map +1 -0
  97. package/dist/types/src/internal/object/create.test.d.ts +2 -0
  98. package/dist/types/src/internal/object/create.test.d.ts.map +1 -0
  99. package/dist/types/src/internal/object/deleted.d.ts +6 -0
  100. package/dist/types/src/internal/object/deleted.d.ts.map +1 -0
  101. package/dist/types/src/internal/object/entity.d.ts +33 -0
  102. package/dist/types/src/internal/object/entity.d.ts.map +1 -0
  103. package/dist/types/src/internal/object/expando.d.ts +14 -0
  104. package/dist/types/src/internal/object/expando.d.ts.map +1 -0
  105. package/dist/types/src/internal/object/ids.d.ts +6 -0
  106. package/dist/types/src/internal/object/ids.d.ts.map +1 -0
  107. package/dist/types/src/internal/object/index.d.ts +16 -0
  108. package/dist/types/src/internal/object/index.d.ts.map +1 -0
  109. package/dist/types/src/internal/object/inspect.d.ts +2 -0
  110. package/dist/types/src/internal/object/inspect.d.ts.map +1 -0
  111. package/dist/types/src/internal/object/json-serializer.d.ts +32 -0
  112. package/dist/types/src/internal/object/json-serializer.d.ts.map +1 -0
  113. package/dist/types/src/internal/object/json-serializer.test.d.ts +2 -0
  114. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +1 -0
  115. package/dist/types/src/internal/object/meta.d.ts +31 -0
  116. package/dist/types/src/internal/object/meta.d.ts.map +1 -0
  117. package/dist/types/src/internal/object/model.d.ts +117 -0
  118. package/dist/types/src/internal/object/model.d.ts.map +1 -0
  119. package/dist/types/src/internal/object/relation.d.ts +17 -0
  120. package/dist/types/src/internal/object/relation.d.ts.map +1 -0
  121. package/dist/types/src/internal/object/schema-validator.d.ts +15 -0
  122. package/dist/types/src/internal/object/schema-validator.d.ts.map +1 -0
  123. package/dist/types/src/internal/object/schema-validator.test.d.ts +2 -0
  124. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +1 -0
  125. package/dist/types/src/internal/object/typed-object.d.ts +31 -0
  126. package/dist/types/src/internal/object/typed-object.d.ts.map +1 -0
  127. package/dist/types/src/internal/object/typed-object.test.d.ts +2 -0
  128. package/dist/types/src/internal/object/typed-object.test.d.ts.map +1 -0
  129. package/dist/types/src/internal/object/typename.d.ts +15 -0
  130. package/dist/types/src/internal/object/typename.d.ts.map +1 -0
  131. package/dist/types/src/internal/object/version.d.ts +14 -0
  132. package/dist/types/src/internal/object/version.d.ts.map +1 -0
  133. package/dist/types/src/internal/projection/compose.d.ts +6 -0
  134. package/dist/types/src/internal/projection/compose.d.ts.map +1 -0
  135. package/dist/types/src/internal/projection/compose.test.d.ts +2 -0
  136. package/dist/types/src/internal/projection/compose.test.d.ts.map +1 -0
  137. package/dist/types/src/internal/projection/index.d.ts +2 -0
  138. package/dist/types/src/internal/projection/index.d.ts.map +1 -0
  139. package/dist/types/src/internal/proxy/handler.test.d.ts +2 -0
  140. package/dist/types/src/internal/proxy/handler.test.d.ts.map +1 -0
  141. package/dist/types/src/internal/proxy/reactive-object.d.ts +15 -0
  142. package/dist/types/src/internal/proxy/reactive-object.d.ts.map +1 -0
  143. package/dist/types/src/internal/proxy/schema.test.d.ts +2 -0
  144. package/dist/types/src/internal/proxy/schema.test.d.ts.map +1 -0
  145. package/dist/types/src/internal/proxy/typed-handler.d.ts +44 -0
  146. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +1 -0
  147. package/dist/types/src/internal/proxy/typed-handler.test.d.ts +2 -0
  148. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +1 -0
  149. package/dist/types/src/internal/proxy/typed-object.test.d.ts +2 -0
  150. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +1 -0
  151. package/dist/types/src/internal/query/index.d.ts +2 -0
  152. package/dist/types/src/internal/query/index.d.ts.map +1 -0
  153. package/dist/types/src/internal/query/query.d.ts +17 -0
  154. package/dist/types/src/internal/query/query.d.ts.map +1 -0
  155. package/dist/types/src/internal/ref/index.d.ts +3 -0
  156. package/dist/types/src/internal/ref/index.d.ts.map +1 -0
  157. package/dist/types/src/internal/ref/ref-array.d.ts +21 -0
  158. package/dist/types/src/internal/ref/ref-array.d.ts.map +1 -0
  159. package/dist/types/src/internal/ref/ref.d.ts +206 -0
  160. package/dist/types/src/internal/ref/ref.d.ts.map +1 -0
  161. package/dist/types/src/internal/ref/ref.test.d.ts +2 -0
  162. package/dist/types/src/internal/ref/ref.test.d.ts.map +1 -0
  163. package/dist/types/src/internal/schema/echo-schema.d.ts +168 -0
  164. package/dist/types/src/internal/schema/echo-schema.d.ts.map +1 -0
  165. package/dist/types/src/internal/schema/index.d.ts +7 -0
  166. package/dist/types/src/internal/schema/index.d.ts.map +1 -0
  167. package/dist/types/src/internal/schema/manipulation.d.ts +10 -0
  168. package/dist/types/src/internal/schema/manipulation.d.ts.map +1 -0
  169. package/dist/types/src/internal/schema/runtime-schema-registry.d.ts +18 -0
  170. package/dist/types/src/internal/schema/runtime-schema-registry.d.ts.map +1 -0
  171. package/dist/types/src/internal/schema/snapshot.d.ts +6 -0
  172. package/dist/types/src/internal/schema/snapshot.d.ts.map +1 -0
  173. package/dist/types/src/internal/schema/stored-schema.d.ts +13 -0
  174. package/dist/types/src/internal/schema/stored-schema.d.ts.map +1 -0
  175. package/dist/types/src/internal/testing/index.d.ts +3 -0
  176. package/dist/types/src/internal/testing/index.d.ts.map +1 -0
  177. package/dist/types/src/internal/testing/types.d.ts +455 -0
  178. package/dist/types/src/internal/testing/types.d.ts.map +1 -0
  179. package/dist/types/src/internal/testing/utils.d.ts +10 -0
  180. package/dist/types/src/internal/testing/utils.d.ts.map +1 -0
  181. package/dist/types/src/internal/types/index.d.ts +3 -0
  182. package/dist/types/src/internal/types/index.d.ts.map +1 -0
  183. package/dist/types/src/internal/types/types.d.ts +79 -0
  184. package/dist/types/src/internal/types/types.d.ts.map +1 -0
  185. package/dist/types/src/internal/types/types.test.d.ts +2 -0
  186. package/dist/types/src/internal/types/types.test.d.ts.map +1 -0
  187. package/dist/types/src/internal/types/util.d.ts +5 -0
  188. package/dist/types/src/internal/types/util.d.ts.map +1 -0
  189. package/dist/types/src/query/index.d.ts +2 -1
  190. package/dist/types/src/query/index.d.ts.map +1 -1
  191. package/dist/types/src/query/{dsl.d.ts → query.d.ts} +34 -24
  192. package/dist/types/src/query/query.d.ts.map +1 -0
  193. package/dist/types/src/query/query.test.d.ts +2 -0
  194. package/dist/types/src/query/query.test.d.ts.map +1 -0
  195. package/dist/types/src/query/tag.d.ts +17 -0
  196. package/dist/types/src/query/tag.d.ts.map +1 -0
  197. package/dist/types/src/testing/echo-schema.d.ts +7 -0
  198. package/dist/types/src/testing/echo-schema.d.ts.map +1 -0
  199. package/dist/types/src/testing/index.d.ts +2 -0
  200. package/dist/types/src/testing/index.d.ts.map +1 -1
  201. package/dist/types/src/testing/types.d.ts +18 -18
  202. package/dist/types/src/testing/types.d.ts.map +1 -1
  203. package/dist/types/tsconfig.tsbuildinfo +1 -1
  204. package/package.json +29 -17
  205. package/src/Obj.ts +77 -12
  206. package/src/Ref.ts +1 -2
  207. package/src/Relation.ts +15 -5
  208. package/src/Type.ts +29 -30
  209. package/src/errors.ts +18 -0
  210. package/src/index.ts +4 -2
  211. package/src/internal/ast/annotation-helper.ts +22 -0
  212. package/src/internal/ast/annotations.test.ts +98 -0
  213. package/src/internal/ast/annotations.ts +219 -0
  214. package/src/internal/ast/entity-kind.ts +15 -0
  215. package/src/internal/ast/index.ts +8 -0
  216. package/src/internal/ast/types.ts +17 -0
  217. package/src/internal/formats/date.test.ts +56 -0
  218. package/src/internal/formats/date.ts +217 -0
  219. package/src/internal/formats/format.test.ts +77 -0
  220. package/src/internal/formats/format.ts +52 -0
  221. package/src/internal/formats/index.ts +12 -0
  222. package/src/internal/formats/number.ts +89 -0
  223. package/src/internal/formats/object.ts +80 -0
  224. package/src/internal/formats/select.ts +16 -0
  225. package/src/internal/formats/string.ts +76 -0
  226. package/src/internal/formats/types.ts +175 -0
  227. package/src/internal/index.ts +22 -0
  228. package/src/internal/json/annotations.ts +50 -0
  229. package/src/internal/json/effect-schema.test.ts +143 -0
  230. package/src/internal/json/index.ts +5 -0
  231. package/src/internal/json/json-schema.test.ts +857 -0
  232. package/src/internal/json/json-schema.ts +519 -0
  233. package/src/internal/json-schema/index.ts +6 -0
  234. package/src/internal/json-schema/json-schema-normalize.ts +109 -0
  235. package/src/internal/json-schema/json-schema-type.ts +403 -0
  236. package/src/internal/object/accessors.ts +153 -0
  237. package/src/internal/object/common.ts +76 -0
  238. package/src/internal/object/create.test.ts +118 -0
  239. package/src/internal/object/create.ts +96 -0
  240. package/src/internal/object/deleted.ts +19 -0
  241. package/src/internal/object/entity.ts +248 -0
  242. package/src/internal/object/expando.ts +21 -0
  243. package/src/internal/object/ids.ts +12 -0
  244. package/src/internal/object/index.ts +19 -0
  245. package/src/internal/object/inspect.ts +48 -0
  246. package/src/internal/object/json-serializer.test.ts +99 -0
  247. package/src/internal/object/json-serializer.ts +225 -0
  248. package/src/internal/object/meta.ts +61 -0
  249. package/src/internal/object/model.ts +170 -0
  250. package/src/internal/object/relation.ts +24 -0
  251. package/src/internal/object/schema-validator.test.ts +186 -0
  252. package/src/internal/object/schema-validator.ts +241 -0
  253. package/src/internal/object/typed-object.test.ts +34 -0
  254. package/src/internal/object/typed-object.ts +88 -0
  255. package/src/internal/object/typename.ts +61 -0
  256. package/src/internal/object/version.ts +22 -0
  257. package/src/internal/projection/compose.test.ts +43 -0
  258. package/src/internal/projection/compose.ts +36 -0
  259. package/src/internal/projection/index.ts +5 -0
  260. package/src/internal/proxy/handler.test.ts +163 -0
  261. package/src/internal/proxy/reactive-object.ts +108 -0
  262. package/src/internal/proxy/schema.test.ts +136 -0
  263. package/src/internal/proxy/typed-handler.test.ts +102 -0
  264. package/src/internal/proxy/typed-handler.ts +228 -0
  265. package/src/internal/proxy/typed-object.test.ts +100 -0
  266. package/src/internal/query/index.ts +5 -0
  267. package/src/internal/query/query.ts +23 -0
  268. package/src/internal/ref/index.ts +6 -0
  269. package/src/internal/ref/ref-array.ts +39 -0
  270. package/src/internal/ref/ref.test.ts +100 -0
  271. package/src/internal/ref/ref.ts +521 -0
  272. package/src/internal/schema/echo-schema.ts +383 -0
  273. package/src/internal/schema/index.ts +10 -0
  274. package/src/internal/schema/manipulation.ts +92 -0
  275. package/src/internal/schema/runtime-schema-registry.ts +78 -0
  276. package/src/internal/schema/snapshot.ts +25 -0
  277. package/src/internal/schema/stored-schema.ts +26 -0
  278. package/src/internal/testing/index.ts +6 -0
  279. package/src/internal/testing/types.ts +211 -0
  280. package/src/internal/testing/utils.ts +54 -0
  281. package/src/internal/types/index.ts +6 -0
  282. package/src/internal/types/types.test.ts +48 -0
  283. package/src/internal/types/types.ts +176 -0
  284. package/src/internal/types/util.ts +9 -0
  285. package/src/query/index.ts +2 -1
  286. package/src/query/query.test.ts +401 -0
  287. package/src/query/{dsl.ts → query.ts} +131 -46
  288. package/src/query/tag.ts +37 -0
  289. package/src/test/api.test.ts +9 -9
  290. package/src/testing/echo-schema.ts +39 -0
  291. package/src/testing/index.ts +2 -0
  292. package/src/testing/types.ts +1 -1
  293. package/dist/lib/browser/chunk-MTR3E5S2.mjs.map +0 -7
  294. package/dist/lib/node-esm/chunk-MYZLAJSR.mjs.map +0 -7
  295. package/dist/types/src/experimental/database.d.ts +0 -8
  296. package/dist/types/src/experimental/database.d.ts.map +0 -1
  297. package/dist/types/src/experimental/index.d.ts +0 -1
  298. package/dist/types/src/experimental/index.d.ts.map +0 -1
  299. package/dist/types/src/experimental/queue.d.ts +0 -8
  300. package/dist/types/src/experimental/queue.d.ts.map +0 -1
  301. package/dist/types/src/experimental/space.d.ts +0 -8
  302. package/dist/types/src/experimental/space.d.ts.map +0 -1
  303. package/dist/types/src/query/dsl.d.ts.map +0 -1
  304. package/dist/types/src/query/dsl.test.d.ts +0 -2
  305. package/dist/types/src/query/dsl.test.d.ts.map +0 -1
  306. package/src/experimental/database.ts +0 -11
  307. package/src/experimental/index.ts +0 -7
  308. package/src/experimental/queue.ts +0 -11
  309. package/src/experimental/space.ts +0 -11
  310. package/src/query/dsl.test.ts +0 -332
@@ -2,21 +2,24 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
6
- import type { NonEmptyArray } from 'effect/Array';
7
- import type { Simplify } from 'effect/Schema';
5
+ import type * as EffectArray from 'effect/Array';
6
+ import * as Match from 'effect/Match';
7
+ import * as Schema from 'effect/Schema';
8
+ import type * as Types from 'effect/Types';
8
9
 
9
10
  import { raise } from '@dxos/debug';
10
11
  import { type ForeignKey, type QueryAST } from '@dxos/echo-protocol';
11
- import { getTypeReference } from '@dxos/echo-schema';
12
12
  import { assertArgument } from '@dxos/invariant';
13
13
  import { DXN, ObjectId } from '@dxos/keys';
14
14
 
15
+ import { getTypeReference } from '../internal';
16
+ import type * as Obj from '../Obj';
15
17
  import * as Ref from '../Ref';
16
18
  import type * as Type from '../Type';
17
19
 
18
20
  // TODO(dmaretskyi): Split up into interfaces for objects and relations so they can have separate verbs.
19
21
  // TODO(dmaretskyi): Undirected relation traversals.
22
+ // TODO(wittjosiah): Make Filter & Query pipeable.
20
23
 
21
24
  export interface Order<T> {
22
25
  // TODO(dmaretskyi): See new effect-schema approach to variance.
@@ -63,10 +66,18 @@ export interface Query<T> {
63
66
 
64
67
  /**
65
68
  * Traverse an outgoing reference.
66
- * @param key - Property path inside T that is a reference.
69
+ * @param key - Property path inside T that is a reference or optional reference.
67
70
  * @returns Query for the target of the reference.
68
71
  */
69
- reference<K extends RefPropKey<T>>(key: K): Query<T[K] extends Ref.Any ? Ref.Target<T[K]> : never>;
72
+ reference<K extends RefPropKey<T>>(
73
+ key: K,
74
+ ): Query<
75
+ T[K] extends Ref.Any
76
+ ? Ref.Target<T[K]>
77
+ : T[K] extends Ref.Any | undefined
78
+ ? Ref.Target<Exclude<T[K], undefined>>
79
+ : never
80
+ >;
70
81
 
71
82
  /**
72
83
  * Find objects referencing this object.
@@ -77,7 +88,7 @@ export interface Query<T> {
77
88
  // TODO(dmaretskyi): any way to enforce `Ref.Target<Schema.Schema.Type<S>[key]> == T`?
78
89
  // TODO(dmaretskyi): Ability to go through arrays of references.
79
90
  referencedBy<S extends Schema.Schema.All>(
80
- target: S,
91
+ target: S | string,
81
92
  key: RefPropKey<Schema.Schema.Type<S>>,
82
93
  ): Query<Schema.Schema.Type<S>>;
83
94
 
@@ -88,7 +99,7 @@ export interface Query<T> {
88
99
  * @param predicates - Predicates to filter the relation objects.
89
100
  */
90
101
  sourceOf<S extends Schema.Schema.All>(
91
- relation: S,
102
+ relation: S | string,
92
103
  predicates?: Filter.Props<Schema.Schema.Type<S>>,
93
104
  ): Query<Schema.Schema.Type<S>>;
94
105
 
@@ -99,7 +110,7 @@ export interface Query<T> {
99
110
  * @param predicates - Predicates to filter the relation objects.
100
111
  */
101
112
  targetOf<S extends Schema.Schema.All>(
102
- relation: S,
113
+ relation: S | string,
103
114
  predicates?: Filter.Props<Schema.Schema.Type<S>>,
104
115
  ): Query<Schema.Schema.Type<S>>;
105
116
 
@@ -121,7 +132,7 @@ export interface Query<T> {
121
132
  * @param order - Order to sort the results.
122
133
  * @returns Query for the ordered results.
123
134
  */
124
- orderBy(...order: NonEmptyArray<Order<T>>): Query<T>;
135
+ orderBy(...order: EffectArray.NonEmptyArray<Order<T>>): Query<T>;
125
136
 
126
137
  /**
127
138
  * Add options to a query.
@@ -151,7 +162,7 @@ interface QueryAPI {
151
162
  * Shorthand for: `Query.select(Filter.type(schema, predicates))`.
152
163
  */
153
164
  type<S extends Schema.Schema.All>(
154
- schema: S,
165
+ schema: S | string,
155
166
  predicates?: Filter.Props<Schema.Schema.Type<S>>,
156
167
  ): Query<Schema.Schema.Type<S>>;
157
168
 
@@ -185,7 +196,7 @@ export declare namespace Query {
185
196
 
186
197
  export interface Filter<T> {
187
198
  // TODO(dmaretskyi): See new effect-schema approach to variance.
188
- '~Filter': { value: T };
199
+ '~Filter': { value: Types.Contravariant<T> };
189
200
 
190
201
  ast: QueryAST.Filter;
191
202
  }
@@ -195,48 +206,56 @@ type Intersection<Types extends readonly unknown[]> = Types extends [infer First
195
206
  : unknown;
196
207
 
197
208
  interface FilterAPI {
198
- is(value: unknown): value is Filter<any>;
209
+ is(value: unknown): value is Filter.Any;
210
+
211
+ /** Construct a filter from an ast. */
212
+ fromAst(ast: QueryAST.Filter): Filter<Obj.Any>;
199
213
 
200
214
  /**
201
215
  * Filter that matches all objects.
202
216
  */
203
- everything(): Filter<any>;
217
+ // TODO(dmaretskyi): `Obj.Any` would be more type-safe, but causes annoying errors in existing code
218
+ everything(): Filter<Obj.AnyProps>;
204
219
 
205
220
  /**
206
221
  * Filter that matches no objects.
207
222
  */
223
+ // TODO(dmaretskyi): Filter<never>?
208
224
  nothing(): Filter<any>;
209
225
 
210
226
  /**
211
227
  * Filter by object IDs.
212
228
  */
213
229
  // TODO(dmaretskyi): Rename to `Filter.id`.
214
- ids(...id: ObjectId[]): Filter<any>;
230
+ ids(...id: ObjectId[]): Filter<Obj.AnyProps>;
215
231
 
216
232
  /**
217
233
  * Filter by type.
218
234
  */
219
235
  type<S extends Schema.Schema.All>(
220
- schema: S,
236
+ schema: S | string,
221
237
  props?: Filter.Props<Schema.Schema.Type<S>>,
222
238
  ): Filter<Schema.Schema.Type<S>>;
223
239
 
224
240
  /**
225
241
  * Filter by non-qualified typename.
226
242
  */
227
- typename(typename: string): Filter<any>;
243
+ typename(typename: string): Filter<Obj.AnyProps>;
228
244
 
229
245
  /**
230
246
  * Filter by fully qualified type DXN.
231
247
  */
232
- typeDXN(dxn: DXN): Filter<any>;
248
+ typeDXN(dxn: DXN): Filter<Obj.AnyProps>;
249
+
250
+ /**
251
+ * Filter by tag.
252
+ */
253
+ tag(tag: string): Filter<Obj.Any>;
233
254
 
234
255
  /**
235
256
  * Filter by properties.
236
- *
237
- * INTERNAL API: Do not use.
238
257
  */
239
- _props<T>(props: Filter.Props<T>): Filter<T>;
258
+ props<T>(props: Filter.Props<T>): Filter<T>;
240
259
 
241
260
  /**
242
261
  * Full-text or vector search.
@@ -293,12 +312,18 @@ interface FilterAPI {
293
312
  */
294
313
  in<T>(...values: T[]): Filter<T>;
295
314
 
315
+ /**
316
+ * Predicate for an array property to contain the provided value.
317
+ * @param value - Value to check against.
318
+ */
319
+ contains<T>(value: T): Filter<readonly T[] | undefined>;
320
+
296
321
  /**
297
322
  * Predicate for property to be in the provided range.
298
323
  * @param from - Start of the range (inclusive).
299
324
  * @param to - End of the range (exclusive).
300
325
  */
301
- between<T>(from: T, to: T): Filter<T>;
326
+ between<T>(from: T, to: T): Filter<unknown>;
302
327
 
303
328
  /**
304
329
  * Negate the filter.
@@ -328,11 +353,12 @@ export declare namespace Filter {
328
353
 
329
354
  type Type<F extends Any> = F extends Filter<infer T> ? T : never;
330
355
 
331
- type And<FS extends readonly Any[]> = Simplify<Intersection<{ [K in keyof FS]: Type<FS[K]> }>>;
356
+ type And<FS extends readonly Any[]> = Schema.Simplify<Intersection<{ [K in keyof FS]: Type<FS[K]> }>>;
332
357
 
333
- type Or<FS extends readonly Any[]> = Simplify<{ [K in keyof FS]: Type<FS[K]> }[number]>;
358
+ type Or<FS extends readonly Any[]> = Schema.Simplify<{ [K in keyof FS]: Type<FS[K]> }[number]>;
334
359
  }
335
360
 
361
+ // TODO(dmaretskyi): Separate object instead of statics for better devex with type errors.
336
362
  class FilterClass implements Filter<any> {
337
363
  private static variance: Filter<any>['~Filter'] = {} as Filter<any>['~Filter'];
338
364
 
@@ -340,6 +366,10 @@ class FilterClass implements Filter<any> {
340
366
  return typeof value === 'object' && value !== null && '~Filter' in value;
341
367
  }
342
368
 
369
+ static fromAst(ast: QueryAST.Filter): Filter<any> {
370
+ return new FilterClass(ast);
371
+ }
372
+
343
373
  static everything(): FilterClass {
344
374
  return new FilterClass({
345
375
  type: 'object',
@@ -387,10 +417,10 @@ class FilterClass implements Filter<any> {
387
417
  }
388
418
 
389
419
  static type<S extends Schema.Schema.All>(
390
- schema: S,
420
+ schema: S | string,
391
421
  props?: Filter.Props<Schema.Schema.Type<S>>,
392
422
  ): Filter<Schema.Schema.Type<S>> {
393
- const dxn = getTypeReference(schema)?.toDXN() ?? raise(new TypeError('Schema has no DXN'));
423
+ const dxn = getTypeDXNFromSpecifier(schema);
394
424
  return new FilterClass({
395
425
  type: 'object',
396
426
  typename: dxn.toString(),
@@ -415,10 +445,14 @@ class FilterClass implements Filter<any> {
415
445
  });
416
446
  }
417
447
 
418
- /**
419
- * @internal
420
- */
421
- static _props<T>(props: Filter.Props<T>): Filter<T> {
448
+ static tag(tag: string): Filter<any> {
449
+ return new FilterClass({
450
+ type: 'tag',
451
+ tag,
452
+ });
453
+ }
454
+
455
+ static props<T>(props: Filter.Props<T>): Filter<T> {
422
456
  return new FilterClass({
423
457
  type: 'object',
424
458
  typename: null,
@@ -434,8 +468,11 @@ class FilterClass implements Filter<any> {
434
468
  });
435
469
  }
436
470
 
437
- static foreignKeys<S extends Schema.Schema.All>(schema: S, keys: ForeignKey[]): Filter<Schema.Schema.Type<S>> {
438
- const dxn = getTypeReference(schema)?.toDXN() ?? raise(new TypeError('Schema has no DXN'));
471
+ static foreignKeys<S extends Schema.Schema.All>(
472
+ schema: S | string,
473
+ keys: ForeignKey[],
474
+ ): Filter<Schema.Schema.Type<S>> {
475
+ const dxn = getTypeDXNFromSpecifier(schema);
439
476
  return new FilterClass({
440
477
  type: 'object',
441
478
  typename: dxn.toString(),
@@ -503,7 +540,14 @@ class FilterClass implements Filter<any> {
503
540
  });
504
541
  }
505
542
 
506
- static between<T>(from: T, to: T): Filter<T> {
543
+ static contains<T>(value: T): Filter<readonly T[] | undefined> {
544
+ return new FilterClass({
545
+ type: 'contains',
546
+ value,
547
+ });
548
+ }
549
+
550
+ static between<T>(from: T, to: T): Filter<unknown> {
507
551
  return new FilterClass({
508
552
  type: 'range',
509
553
  from,
@@ -562,11 +606,38 @@ const propsFilterToAst = (predicates: Filter.Props<any>): Pick<QueryAST.FilterOb
562
606
  props: Object.fromEntries(
563
607
  Object.entries(predicates)
564
608
  .filter(([prop, _value]) => prop !== 'id')
565
- .map(([prop, predicate]) => [prop, Filter.is(predicate) ? predicate.ast : Filter.eq(predicate).ast]),
609
+ .map(([prop, predicate]) => [prop, processPredicate(predicate)]),
566
610
  ) as Record<string, QueryAST.Filter>,
567
611
  };
568
612
  };
569
613
 
614
+ const processPredicate = (predicate: any): QueryAST.Filter => {
615
+ return Match.value(predicate).pipe(
616
+ Match.withReturnType<QueryAST.Filter>(),
617
+ Match.when(Filter.is, (predicate) => predicate.ast),
618
+ // TODO(wittjosiah): Add support for array predicates.
619
+ Match.when(Array.isArray, (_predicate) => {
620
+ throw new Error('Array predicates are not yet supported.');
621
+ }),
622
+ Match.when(
623
+ (predicate: any) => !Ref.isRef(predicate) && typeof predicate === 'object' && predicate !== null,
624
+ (predicate) => {
625
+ const nestedProps = Object.fromEntries(
626
+ Object.entries(predicate).map(([key, value]) => [key, processPredicate(value)]),
627
+ );
628
+
629
+ return {
630
+ type: 'object',
631
+ typename: null,
632
+ props: nestedProps,
633
+ };
634
+ },
635
+ ),
636
+ Match.orElse((value) => Filter.eq(value).ast),
637
+ );
638
+ };
639
+
640
+ // TODO(dmaretskyi): Separate object instead of statics for better devex with type errors.
570
641
  class QueryClass implements Query<any> {
571
642
  private static variance: Query<any>['~Query'] = {} as Query<any>['~Query'];
572
643
 
@@ -585,7 +656,7 @@ class QueryClass implements Query<any> {
585
656
  });
586
657
  }
587
658
 
588
- static type(schema: Schema.Schema.All, predicates?: Filter.Props<unknown>): Query<any> {
659
+ static type(schema: Schema.Schema.All | string, predicates?: Filter.Props<unknown>): Query<any> {
589
660
  return new QueryClass({
590
661
  type: 'select',
591
662
  filter: FilterClass.type(schema, predicates).ast,
@@ -616,7 +687,7 @@ class QueryClass implements Query<any> {
616
687
 
617
688
  '~Query' = QueryClass.variance;
618
689
 
619
- select(filter: Filter<any> | Filter.Props<any>): Query<any> {
690
+ select(filter: Filter.Any | Filter.Props<any>): Query.Any {
620
691
  if (Filter.is(filter)) {
621
692
  return new QueryClass({
622
693
  type: 'filter',
@@ -627,12 +698,12 @@ class QueryClass implements Query<any> {
627
698
  return new QueryClass({
628
699
  type: 'filter',
629
700
  selection: this.ast,
630
- filter: FilterClass._props(filter).ast,
701
+ filter: FilterClass.props(filter).ast,
631
702
  });
632
703
  }
633
704
  }
634
705
 
635
- reference(key: string): Query<any> {
706
+ reference(key: string): Query.Any {
636
707
  return new QueryClass({
637
708
  type: 'reference-traversal',
638
709
  anchor: this.ast,
@@ -640,8 +711,8 @@ class QueryClass implements Query<any> {
640
711
  });
641
712
  }
642
713
 
643
- referencedBy(target: Schema.Schema.All, key: string): Query<any> {
644
- const dxn = getTypeReference(target)?.toDXN() ?? raise(new TypeError('Target schema has no DXN'));
714
+ referencedBy(target: Schema.Schema.All | string, key: string): Query.Any {
715
+ const dxn = getTypeDXNFromSpecifier(target);
645
716
  return new QueryClass({
646
717
  type: 'incoming-references',
647
718
  anchor: this.ast,
@@ -650,7 +721,7 @@ class QueryClass implements Query<any> {
650
721
  });
651
722
  }
652
723
 
653
- sourceOf(relation: Schema.Schema.All, predicates?: Filter.Props<unknown> | undefined): Query<any> {
724
+ sourceOf(relation: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Query.Any {
654
725
  return new QueryClass({
655
726
  type: 'relation',
656
727
  anchor: this.ast,
@@ -659,7 +730,7 @@ class QueryClass implements Query<any> {
659
730
  });
660
731
  }
661
732
 
662
- targetOf(relation: Schema.Schema.All, predicates?: Filter.Props<unknown> | undefined): Query<any> {
733
+ targetOf(relation: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Query.Any {
663
734
  return new QueryClass({
664
735
  type: 'relation',
665
736
  anchor: this.ast,
@@ -668,7 +739,7 @@ class QueryClass implements Query<any> {
668
739
  });
669
740
  }
670
741
 
671
- source(): Query<any> {
742
+ source(): Query.Any {
672
743
  return new QueryClass({
673
744
  type: 'relation-traversal',
674
745
  anchor: this.ast,
@@ -676,7 +747,7 @@ class QueryClass implements Query<any> {
676
747
  });
677
748
  }
678
749
 
679
- target(): Query<any> {
750
+ target(): Query.Any {
680
751
  return new QueryClass({
681
752
  type: 'relation-traversal',
682
753
  anchor: this.ast,
@@ -684,7 +755,7 @@ class QueryClass implements Query<any> {
684
755
  });
685
756
  }
686
757
 
687
- orderBy(...order: Order<any>[]): Query<any> {
758
+ orderBy(...order: Order<any>[]): Query.Any {
688
759
  return new QueryClass({
689
760
  type: 'order',
690
761
  query: this.ast,
@@ -692,7 +763,7 @@ class QueryClass implements Query<any> {
692
763
  });
693
764
  }
694
765
 
695
- options(options: QueryAST.QueryOptions): Query<any> {
766
+ options(options: QueryAST.QueryOptions): Query.Any {
696
767
  return new QueryClass({
697
768
  type: 'options',
698
769
  query: this.ast,
@@ -702,3 +773,17 @@ class QueryClass implements Query<any> {
702
773
  }
703
774
 
704
775
  export const Query: QueryAPI = QueryClass;
776
+
777
+ /**
778
+ * @param input schema or a typename string
779
+ * @return type DXN
780
+ */
781
+ const getTypeDXNFromSpecifier = (input: Schema.Schema.All | string): DXN => {
782
+ if (Schema.isSchema(input)) {
783
+ return getTypeReference(input)?.toDXN() ?? raise(new TypeError('Schema has no DXN'));
784
+ } else {
785
+ assertArgument(typeof input === 'string', 'input');
786
+ assertArgument(!input.startsWith('dxn:'), 'input');
787
+ return DXN.fromTypename(input);
788
+ }
789
+ };
@@ -0,0 +1,37 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { LabelAnnotation } from '../internal';
8
+ import * as Obj from '../Obj';
9
+ import * as Type from '../Type';
10
+
11
+ export const Tag = Schema.Struct({
12
+ label: Schema.String,
13
+ hue: Schema.optional(Schema.String), // TODO(burdon): Color name?
14
+ }).pipe(
15
+ Type.Obj({
16
+ typename: 'dxos.org/type/Tag',
17
+ version: '0.1.0',
18
+ }),
19
+ LabelAnnotation.set(['label']),
20
+ );
21
+ export type Tag = Schema.Schema.Type<typeof Tag>;
22
+
23
+ export const make = (props: Obj.MakeProps<typeof Tag>) => Obj.make(Tag, props);
24
+
25
+ export type TagMap = Record<string, Tag>;
26
+
27
+ export const sortTags = ({ label: a }: Tag, { label: b }: Tag) => a.localeCompare(b);
28
+
29
+ export const createTagList = (tags: TagMap): Tag[] =>
30
+ Object.entries(tags)
31
+ .map(([id, tag]) => ({ ...tag, id }))
32
+ .sort(sortTags);
33
+
34
+ export const findTagByLabel = (tags: TagMap | undefined, name: string): Tag | undefined => {
35
+ const entry = Object.entries(tags ?? {}).find(([_, tag]) => tag.label.toLowerCase() === name.toLowerCase());
36
+ return entry ? { ...entry[1], id: entry[0] } : undefined;
37
+ };
@@ -2,11 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
  import { describe, test } from 'vitest';
7
7
 
8
8
  import { raise } from '@dxos/debug';
9
- import { FormatAnnotation, FormatEnum } from '@dxos/echo-schema';
9
+ import { FormatAnnotation, FormatEnum } from '@dxos/echo/internal';
10
10
 
11
11
  import { type Live, Obj, Ref, Relation, Type } from '../index';
12
12
 
@@ -159,21 +159,21 @@ describe('Experimental API review', () => {
159
159
  });
160
160
 
161
161
  test.skip('type narrowing', () => {
162
- const a: Obj.Any | Relation.Any = null as any;
162
+ const any: Obj.Any | Relation.Any = null as any;
163
163
 
164
164
  {
165
- if (Obj.isObject(a)) {
166
- a;
165
+ if (Obj.isObject(any)) {
166
+ any;
167
167
  } else {
168
- a;
168
+ any;
169
169
  }
170
170
  }
171
171
 
172
172
  {
173
- if (Relation.isRelation(a)) {
174
- a;
173
+ if (Relation.isRelation(any)) {
174
+ any;
175
175
  } else {
176
- a;
176
+ any;
177
177
  }
178
178
  }
179
179
  });
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { effect } from '@preact/signals-core';
6
+ import type * as Schema from 'effect/Schema';
7
+
8
+ import { registerSignalsRuntime } from '@dxos/echo-signals';
9
+ import { assertArgument } from '@dxos/invariant';
10
+
11
+ import { EchoSchema, StoredSchema, getSchemaTypename, live, toJsonSchema } from '../internal';
12
+
13
+ // NOTE: Registration is done here is this is the module that calls out to `effect`.
14
+ registerSignalsRuntime();
15
+
16
+ /**
17
+ * Create a reactive mutable schema that updates when the JSON schema is updated.
18
+ */
19
+ // TODO(dmaretskyi): Should be replaced by registration of typed object.
20
+ export const createEchoSchema = (schema: Schema.Schema.AnyNoContext): EchoSchema => {
21
+ const typename = getSchemaTypename(schema);
22
+ assertArgument(typename, 'typename', 'Schema does not have a typename.');
23
+
24
+ const echoSchema = new EchoSchema(
25
+ live(StoredSchema, {
26
+ typename,
27
+ version: '0.1.0',
28
+ jsonSchema: toJsonSchema(schema),
29
+ }),
30
+ );
31
+
32
+ // TODO(burdon): Unsubscribe is never called.
33
+ effect(() => {
34
+ const _ = echoSchema.jsonSchema;
35
+ echoSchema._invalidate();
36
+ });
37
+
38
+ return echoSchema;
39
+ };
@@ -2,4 +2,6 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ export { prepareAstForCompare, Testing as TestingDeprecated, updateCounter } from '../internal/testing';
5
6
  export * from './types';
7
+ export * from './echo-schema';
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
7
  import { Type } from '..';
8
8