@dxos/echo 0.8.4-main.84f28bd → 0.8.4-main.ae835ea

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 (313) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/browser/chunk-JUTFUT73.mjs +175 -0
  3. package/dist/lib/browser/chunk-JUTFUT73.mjs.map +7 -0
  4. package/dist/lib/browser/chunk-KEBVBR65.mjs +3727 -0
  5. package/dist/lib/browser/chunk-KEBVBR65.mjs.map +7 -0
  6. package/dist/lib/browser/chunk-WO76TDT6.mjs +814 -0
  7. package/dist/lib/browser/chunk-WO76TDT6.mjs.map +7 -0
  8. package/dist/lib/browser/index.mjs +17 -4
  9. package/dist/lib/browser/internal/index.mjs +336 -0
  10. package/dist/lib/browser/internal/index.mjs.map +7 -0
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/query/index.mjs +15 -0
  13. package/dist/lib/browser/query/index.mjs.map +7 -0
  14. package/dist/lib/browser/testing/index.mjs +245 -32
  15. package/dist/lib/browser/testing/index.mjs.map +4 -4
  16. package/dist/lib/node-esm/chunk-DWZYQ2UR.mjs +3727 -0
  17. package/dist/lib/node-esm/chunk-DWZYQ2UR.mjs.map +7 -0
  18. package/dist/lib/node-esm/chunk-KBD3A2I6.mjs +175 -0
  19. package/dist/lib/node-esm/chunk-KBD3A2I6.mjs.map +7 -0
  20. package/dist/lib/node-esm/chunk-ZSSII3JW.mjs +814 -0
  21. package/dist/lib/node-esm/chunk-ZSSII3JW.mjs.map +7 -0
  22. package/dist/lib/node-esm/index.mjs +17 -4
  23. package/dist/lib/node-esm/internal/index.mjs +336 -0
  24. package/dist/lib/node-esm/internal/index.mjs.map +7 -0
  25. package/dist/lib/node-esm/meta.json +1 -1
  26. package/dist/lib/node-esm/query/index.mjs +15 -0
  27. package/dist/lib/node-esm/query/index.mjs.map +7 -0
  28. package/dist/lib/node-esm/testing/index.mjs +245 -32
  29. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  30. package/dist/types/src/Obj.d.ts +123 -16
  31. package/dist/types/src/Obj.d.ts.map +1 -1
  32. package/dist/types/src/Ref.d.ts +1 -1
  33. package/dist/types/src/Ref.d.ts.map +1 -1
  34. package/dist/types/src/Relation.d.ts +11 -8
  35. package/dist/types/src/Relation.d.ts.map +1 -1
  36. package/dist/types/src/Type.d.ts +17 -18
  37. package/dist/types/src/Type.d.ts.map +1 -1
  38. package/dist/types/src/errors.d.ts +72 -0
  39. package/dist/types/src/errors.d.ts.map +1 -0
  40. package/dist/types/src/index.d.ts +3 -1
  41. package/dist/types/src/index.d.ts.map +1 -1
  42. package/dist/types/src/internal/ast/annotation-helper.d.ts +8 -0
  43. package/dist/types/src/internal/ast/annotation-helper.d.ts.map +1 -0
  44. package/dist/types/src/internal/ast/annotations.d.ts +131 -0
  45. package/dist/types/src/internal/ast/annotations.d.ts.map +1 -0
  46. package/dist/types/src/internal/ast/annotations.test.d.ts +2 -0
  47. package/dist/types/src/internal/ast/annotations.test.d.ts.map +1 -0
  48. package/dist/types/src/internal/ast/entity-kind.d.ts +10 -0
  49. package/dist/types/src/internal/ast/entity-kind.d.ts.map +1 -0
  50. package/dist/types/src/internal/ast/index.d.ts +5 -0
  51. package/dist/types/src/internal/ast/index.d.ts.map +1 -0
  52. package/dist/types/src/internal/ast/types.d.ts +6 -0
  53. package/dist/types/src/internal/ast/types.d.ts.map +1 -0
  54. package/dist/types/src/internal/formats/date.d.ts +63 -0
  55. package/dist/types/src/internal/formats/date.d.ts.map +1 -0
  56. package/dist/types/src/internal/formats/date.test.d.ts +2 -0
  57. package/dist/types/src/internal/formats/date.test.d.ts.map +1 -0
  58. package/dist/types/src/internal/formats/format.d.ts +30 -0
  59. package/dist/types/src/internal/formats/format.d.ts.map +1 -0
  60. package/dist/types/src/internal/formats/format.test.d.ts +2 -0
  61. package/dist/types/src/internal/formats/format.test.d.ts.map +1 -0
  62. package/dist/types/src/internal/formats/index.d.ts +8 -0
  63. package/dist/types/src/internal/formats/index.d.ts.map +1 -0
  64. package/dist/types/src/internal/formats/number.d.ts +31 -0
  65. package/dist/types/src/internal/formats/number.d.ts.map +1 -0
  66. package/dist/types/src/internal/formats/object.d.ts +35 -0
  67. package/dist/types/src/internal/formats/object.d.ts.map +1 -0
  68. package/dist/types/src/internal/formats/select.d.ts +11 -0
  69. package/dist/types/src/internal/formats/select.d.ts.map +1 -0
  70. package/dist/types/src/internal/formats/string.d.ts +38 -0
  71. package/dist/types/src/internal/formats/string.d.ts.map +1 -0
  72. package/dist/types/src/internal/formats/types.d.ts +68 -0
  73. package/dist/types/src/internal/formats/types.d.ts.map +1 -0
  74. package/dist/types/src/internal/index.d.ts +15 -0
  75. package/dist/types/src/internal/index.d.ts.map +1 -0
  76. package/dist/types/src/internal/json/annotations.d.ts +19 -0
  77. package/dist/types/src/internal/json/annotations.d.ts.map +1 -0
  78. package/dist/types/src/internal/json/effect-schema.test.d.ts +2 -0
  79. package/dist/types/src/internal/json/effect-schema.test.d.ts.map +1 -0
  80. package/dist/types/src/internal/json/index.d.ts +2 -0
  81. package/dist/types/src/internal/json/index.d.ts.map +1 -0
  82. package/dist/types/src/internal/json/json-schema.d.ts +28 -0
  83. package/dist/types/src/internal/json/json-schema.d.ts.map +1 -0
  84. package/dist/types/src/internal/json/json-schema.test.d.ts +2 -0
  85. package/dist/types/src/internal/json/json-schema.test.d.ts.map +1 -0
  86. package/dist/types/src/internal/json-schema/index.d.ts +3 -0
  87. package/dist/types/src/internal/json-schema/index.d.ts.map +1 -0
  88. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts +7 -0
  89. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +1 -0
  90. package/dist/types/src/internal/json-schema/json-schema-type.d.ts +250 -0
  91. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +1 -0
  92. package/dist/types/src/internal/object/accessors.d.ts +37 -0
  93. package/dist/types/src/internal/object/accessors.d.ts.map +1 -0
  94. package/dist/types/src/internal/object/common.d.ts +18 -0
  95. package/dist/types/src/internal/object/common.d.ts.map +1 -0
  96. package/dist/types/src/internal/object/create.d.ts +40 -0
  97. package/dist/types/src/internal/object/create.d.ts.map +1 -0
  98. package/dist/types/src/internal/object/create.test.d.ts +2 -0
  99. package/dist/types/src/internal/object/create.test.d.ts.map +1 -0
  100. package/dist/types/src/internal/object/deleted.d.ts +6 -0
  101. package/dist/types/src/internal/object/deleted.d.ts.map +1 -0
  102. package/dist/types/src/internal/object/entity.d.ts +33 -0
  103. package/dist/types/src/internal/object/entity.d.ts.map +1 -0
  104. package/dist/types/src/internal/object/expando.d.ts +14 -0
  105. package/dist/types/src/internal/object/expando.d.ts.map +1 -0
  106. package/dist/types/src/internal/object/ids.d.ts +6 -0
  107. package/dist/types/src/internal/object/ids.d.ts.map +1 -0
  108. package/dist/types/src/internal/object/index.d.ts +16 -0
  109. package/dist/types/src/internal/object/index.d.ts.map +1 -0
  110. package/dist/types/src/internal/object/inspect.d.ts +2 -0
  111. package/dist/types/src/internal/object/inspect.d.ts.map +1 -0
  112. package/dist/types/src/internal/object/json-serializer.d.ts +32 -0
  113. package/dist/types/src/internal/object/json-serializer.d.ts.map +1 -0
  114. package/dist/types/src/internal/object/json-serializer.test.d.ts +2 -0
  115. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +1 -0
  116. package/dist/types/src/internal/object/meta.d.ts +31 -0
  117. package/dist/types/src/internal/object/meta.d.ts.map +1 -0
  118. package/dist/types/src/internal/object/model.d.ts +117 -0
  119. package/dist/types/src/internal/object/model.d.ts.map +1 -0
  120. package/dist/types/src/internal/object/relation.d.ts +17 -0
  121. package/dist/types/src/internal/object/relation.d.ts.map +1 -0
  122. package/dist/types/src/internal/object/schema-validator.d.ts +15 -0
  123. package/dist/types/src/internal/object/schema-validator.d.ts.map +1 -0
  124. package/dist/types/src/internal/object/schema-validator.test.d.ts +2 -0
  125. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +1 -0
  126. package/dist/types/src/internal/object/typed-object.d.ts +31 -0
  127. package/dist/types/src/internal/object/typed-object.d.ts.map +1 -0
  128. package/dist/types/src/internal/object/typed-object.test.d.ts +2 -0
  129. package/dist/types/src/internal/object/typed-object.test.d.ts.map +1 -0
  130. package/dist/types/src/internal/object/typename.d.ts +15 -0
  131. package/dist/types/src/internal/object/typename.d.ts.map +1 -0
  132. package/dist/types/src/internal/object/version.d.ts +14 -0
  133. package/dist/types/src/internal/object/version.d.ts.map +1 -0
  134. package/dist/types/src/internal/projection/compose.d.ts +6 -0
  135. package/dist/types/src/internal/projection/compose.d.ts.map +1 -0
  136. package/dist/types/src/internal/projection/compose.test.d.ts +2 -0
  137. package/dist/types/src/internal/projection/compose.test.d.ts.map +1 -0
  138. package/dist/types/src/internal/projection/index.d.ts +2 -0
  139. package/dist/types/src/internal/projection/index.d.ts.map +1 -0
  140. package/dist/types/src/internal/proxy/handler.test.d.ts +2 -0
  141. package/dist/types/src/internal/proxy/handler.test.d.ts.map +1 -0
  142. package/dist/types/src/internal/proxy/reactive-object.d.ts +15 -0
  143. package/dist/types/src/internal/proxy/reactive-object.d.ts.map +1 -0
  144. package/dist/types/src/internal/proxy/schema.test.d.ts +2 -0
  145. package/dist/types/src/internal/proxy/schema.test.d.ts.map +1 -0
  146. package/dist/types/src/internal/proxy/typed-handler.d.ts +44 -0
  147. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +1 -0
  148. package/dist/types/src/internal/proxy/typed-handler.test.d.ts +2 -0
  149. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +1 -0
  150. package/dist/types/src/internal/proxy/typed-object.test.d.ts +2 -0
  151. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +1 -0
  152. package/dist/types/src/internal/query/index.d.ts +2 -0
  153. package/dist/types/src/internal/query/index.d.ts.map +1 -0
  154. package/dist/types/src/internal/query/query.d.ts +17 -0
  155. package/dist/types/src/internal/query/query.d.ts.map +1 -0
  156. package/dist/types/src/internal/ref/index.d.ts +3 -0
  157. package/dist/types/src/internal/ref/index.d.ts.map +1 -0
  158. package/dist/types/src/internal/ref/ref-array.d.ts +21 -0
  159. package/dist/types/src/internal/ref/ref-array.d.ts.map +1 -0
  160. package/dist/types/src/internal/ref/ref.d.ts +206 -0
  161. package/dist/types/src/internal/ref/ref.d.ts.map +1 -0
  162. package/dist/types/src/internal/ref/ref.test.d.ts +2 -0
  163. package/dist/types/src/internal/ref/ref.test.d.ts.map +1 -0
  164. package/dist/types/src/internal/schema/echo-schema.d.ts +168 -0
  165. package/dist/types/src/internal/schema/echo-schema.d.ts.map +1 -0
  166. package/dist/types/src/internal/schema/index.d.ts +7 -0
  167. package/dist/types/src/internal/schema/index.d.ts.map +1 -0
  168. package/dist/types/src/internal/schema/manipulation.d.ts +10 -0
  169. package/dist/types/src/internal/schema/manipulation.d.ts.map +1 -0
  170. package/dist/types/src/internal/schema/runtime-schema-registry.d.ts +18 -0
  171. package/dist/types/src/internal/schema/runtime-schema-registry.d.ts.map +1 -0
  172. package/dist/types/src/internal/schema/snapshot.d.ts +6 -0
  173. package/dist/types/src/internal/schema/snapshot.d.ts.map +1 -0
  174. package/dist/types/src/internal/schema/stored-schema.d.ts +13 -0
  175. package/dist/types/src/internal/schema/stored-schema.d.ts.map +1 -0
  176. package/dist/types/src/internal/testing/index.d.ts +3 -0
  177. package/dist/types/src/internal/testing/index.d.ts.map +1 -0
  178. package/dist/types/src/internal/testing/types.d.ts +455 -0
  179. package/dist/types/src/internal/testing/types.d.ts.map +1 -0
  180. package/dist/types/src/internal/testing/utils.d.ts +10 -0
  181. package/dist/types/src/internal/testing/utils.d.ts.map +1 -0
  182. package/dist/types/src/internal/types/index.d.ts +3 -0
  183. package/dist/types/src/internal/types/index.d.ts.map +1 -0
  184. package/dist/types/src/internal/types/types.d.ts +79 -0
  185. package/dist/types/src/internal/types/types.d.ts.map +1 -0
  186. package/dist/types/src/internal/types/types.test.d.ts +2 -0
  187. package/dist/types/src/internal/types/types.test.d.ts.map +1 -0
  188. package/dist/types/src/internal/types/util.d.ts +5 -0
  189. package/dist/types/src/internal/types/util.d.ts.map +1 -0
  190. package/dist/types/src/query/index.d.ts +2 -1
  191. package/dist/types/src/query/index.d.ts.map +1 -1
  192. package/dist/types/src/query/{dsl.d.ts → query.d.ts} +52 -22
  193. package/dist/types/src/query/query.d.ts.map +1 -0
  194. package/dist/types/src/query/query.test.d.ts +2 -0
  195. package/dist/types/src/query/query.test.d.ts.map +1 -0
  196. package/dist/types/src/query/tag.d.ts +17 -0
  197. package/dist/types/src/query/tag.d.ts.map +1 -0
  198. package/dist/types/src/testing/echo-schema.d.ts +7 -0
  199. package/dist/types/src/testing/echo-schema.d.ts.map +1 -0
  200. package/dist/types/src/testing/index.d.ts +2 -0
  201. package/dist/types/src/testing/index.d.ts.map +1 -1
  202. package/dist/types/src/testing/types.d.ts +18 -18
  203. package/dist/types/src/testing/types.d.ts.map +1 -1
  204. package/dist/types/tsconfig.tsbuildinfo +1 -1
  205. package/package.json +34 -16
  206. package/src/Obj.ts +279 -29
  207. package/src/Ref.ts +1 -2
  208. package/src/Relation.ts +25 -13
  209. package/src/Type.ts +32 -31
  210. package/src/errors.ts +18 -0
  211. package/src/index.ts +4 -1
  212. package/src/internal/ast/annotation-helper.ts +22 -0
  213. package/src/internal/ast/annotations.test.ts +98 -0
  214. package/src/internal/ast/annotations.ts +226 -0
  215. package/src/internal/ast/entity-kind.ts +15 -0
  216. package/src/internal/ast/index.ts +8 -0
  217. package/src/internal/ast/types.ts +17 -0
  218. package/src/internal/formats/date.test.ts +56 -0
  219. package/src/internal/formats/date.ts +217 -0
  220. package/src/internal/formats/format.test.ts +77 -0
  221. package/src/internal/formats/format.ts +52 -0
  222. package/src/internal/formats/index.ts +12 -0
  223. package/src/internal/formats/number.ts +89 -0
  224. package/src/internal/formats/object.ts +80 -0
  225. package/src/internal/formats/select.ts +16 -0
  226. package/src/internal/formats/string.ts +76 -0
  227. package/src/internal/formats/types.ts +175 -0
  228. package/src/internal/index.ts +22 -0
  229. package/src/internal/json/annotations.ts +50 -0
  230. package/src/internal/json/effect-schema.test.ts +143 -0
  231. package/src/internal/json/index.ts +5 -0
  232. package/src/internal/json/json-schema.test.ts +857 -0
  233. package/src/internal/json/json-schema.ts +519 -0
  234. package/src/internal/json-schema/index.ts +6 -0
  235. package/src/internal/json-schema/json-schema-normalize.ts +109 -0
  236. package/src/internal/json-schema/json-schema-type.ts +403 -0
  237. package/src/internal/object/accessors.ts +153 -0
  238. package/src/internal/object/common.ts +76 -0
  239. package/src/internal/object/create.test.ts +118 -0
  240. package/src/internal/object/create.ts +96 -0
  241. package/src/internal/object/deleted.ts +19 -0
  242. package/src/internal/object/entity.ts +248 -0
  243. package/src/internal/object/expando.ts +21 -0
  244. package/src/internal/object/ids.ts +12 -0
  245. package/src/internal/object/index.ts +19 -0
  246. package/src/internal/object/inspect.ts +48 -0
  247. package/src/internal/object/json-serializer.test.ts +99 -0
  248. package/src/internal/object/json-serializer.ts +225 -0
  249. package/src/internal/object/meta.ts +61 -0
  250. package/src/internal/object/model.ts +170 -0
  251. package/src/internal/object/relation.ts +24 -0
  252. package/src/internal/object/schema-validator.test.ts +186 -0
  253. package/src/internal/object/schema-validator.ts +241 -0
  254. package/src/internal/object/typed-object.test.ts +34 -0
  255. package/src/internal/object/typed-object.ts +88 -0
  256. package/src/internal/object/typename.ts +61 -0
  257. package/src/internal/object/version.ts +22 -0
  258. package/src/internal/projection/compose.test.ts +43 -0
  259. package/src/internal/projection/compose.ts +36 -0
  260. package/src/internal/projection/index.ts +5 -0
  261. package/src/internal/proxy/handler.test.ts +163 -0
  262. package/src/internal/proxy/reactive-object.ts +108 -0
  263. package/src/internal/proxy/schema.test.ts +136 -0
  264. package/src/internal/proxy/typed-handler.test.ts +102 -0
  265. package/src/internal/proxy/typed-handler.ts +228 -0
  266. package/src/internal/proxy/typed-object.test.ts +100 -0
  267. package/src/internal/query/index.ts +5 -0
  268. package/src/internal/query/query.ts +23 -0
  269. package/src/internal/ref/index.ts +6 -0
  270. package/src/internal/ref/ref-array.ts +39 -0
  271. package/src/internal/ref/ref.test.ts +100 -0
  272. package/src/internal/ref/ref.ts +521 -0
  273. package/src/internal/schema/echo-schema.ts +383 -0
  274. package/src/internal/schema/index.ts +10 -0
  275. package/src/internal/schema/manipulation.ts +92 -0
  276. package/src/internal/schema/runtime-schema-registry.ts +78 -0
  277. package/src/internal/schema/snapshot.ts +25 -0
  278. package/src/internal/schema/stored-schema.ts +26 -0
  279. package/src/internal/testing/index.ts +6 -0
  280. package/src/internal/testing/types.ts +211 -0
  281. package/src/internal/testing/utils.ts +54 -0
  282. package/src/internal/types/index.ts +6 -0
  283. package/src/internal/types/types.test.ts +48 -0
  284. package/src/internal/types/types.ts +176 -0
  285. package/src/internal/types/util.ts +9 -0
  286. package/src/query/index.ts +2 -1
  287. package/src/query/query.test.ts +401 -0
  288. package/src/query/{dsl.ts → query.ts} +188 -45
  289. package/src/query/tag.ts +37 -0
  290. package/src/test/api.test.ts +17 -10
  291. package/src/testing/echo-schema.ts +39 -0
  292. package/src/testing/index.ts +2 -0
  293. package/src/testing/types.ts +1 -1
  294. package/dist/lib/browser/chunk-SVSJEELN.mjs +0 -619
  295. package/dist/lib/browser/chunk-SVSJEELN.mjs.map +0 -7
  296. package/dist/lib/node-esm/chunk-53HXWYR6.mjs +0 -619
  297. package/dist/lib/node-esm/chunk-53HXWYR6.mjs.map +0 -7
  298. package/dist/types/src/experimental/database.d.ts +0 -8
  299. package/dist/types/src/experimental/database.d.ts.map +0 -1
  300. package/dist/types/src/experimental/index.d.ts +0 -1
  301. package/dist/types/src/experimental/index.d.ts.map +0 -1
  302. package/dist/types/src/experimental/queue.d.ts +0 -8
  303. package/dist/types/src/experimental/queue.d.ts.map +0 -1
  304. package/dist/types/src/experimental/space.d.ts +0 -8
  305. package/dist/types/src/experimental/space.d.ts.map +0 -1
  306. package/dist/types/src/query/dsl.d.ts.map +0 -1
  307. package/dist/types/src/query/dsl.test.d.ts +0 -2
  308. package/dist/types/src/query/dsl.test.d.ts.map +0 -1
  309. package/src/experimental/database.ts +0 -11
  310. package/src/experimental/index.ts +0 -7
  311. package/src/experimental/queue.ts +0 -11
  312. package/src/experimental/space.ts +0 -11
  313. package/src/query/dsl.test.ts +0 -323
@@ -0,0 +1,403 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { JsonPath, type JsonProp } from '@dxos/effect';
8
+
9
+ import { EntityKindSchema } from '../ast';
10
+ import { FormatAnnotation, FormatEnum } from '../formats';
11
+
12
+ //
13
+ // JSON Schema
14
+ //
15
+
16
+ // TODO(burdon): Reuse/reconcile with ScalarTypeEnum (handle arrays).
17
+ const SimpleTypes = Schema.Literal('array', 'boolean', 'integer', 'null', 'number', 'object', 'string');
18
+
19
+ const NonNegativeInteger = Schema.Number.pipe(Schema.greaterThanOrEqualTo(0));
20
+
21
+ const StringArray = Schema.Array(Schema.String).pipe(Schema.mutable);
22
+
23
+ const JsonSchemaOrBoolean = Schema.Union(
24
+ Schema.suspend(() => JsonSchemaType),
25
+ Schema.Boolean,
26
+ );
27
+
28
+ /**
29
+ * Go under the `annotations` property.
30
+ */
31
+ export const JsonSchemaEchoAnnotations = Schema.Struct({
32
+ /**
33
+ * Label for this schema.
34
+ * Mapped from {@link LabelAnnotationId}.
35
+ */
36
+ labelProp: Schema.optional(Schema.Union(JsonPath, Schema.Array(JsonPath))),
37
+
38
+ /**
39
+ * Generator function for this schema.
40
+ * Mapped from {@link GeneratorAnnotationId}.
41
+ */
42
+ generator: Schema.optional(Schema.Union(Schema.String, Schema.Tuple(Schema.String, Schema.Number))),
43
+
44
+ /**
45
+ * {@link PropertyMeta} annotations get serialized here.
46
+ */
47
+ meta: Schema.optional(
48
+ Schema.Record({
49
+ key: Schema.String,
50
+ value: Schema.Any,
51
+ }).pipe(Schema.mutable),
52
+ ),
53
+
54
+ /**
55
+ * @deprecated
56
+ */
57
+ // TODO(dmaretskyi): We risk old schema not passing validation due to the extra fields. Remove when we are sure this is safe
58
+ type: Schema.optional(
59
+ Schema.Struct({
60
+ typename: Schema.String,
61
+ version: Schema.String,
62
+
63
+ // Not used.
64
+ schemaId: Schema.optional(Schema.String),
65
+ }).pipe(Schema.mutable),
66
+ ),
67
+
68
+ /**
69
+ * @deprecated Superseded by `meta`.
70
+ */
71
+ annotations: Schema.optional(
72
+ Schema.Record({
73
+ key: Schema.String,
74
+ value: Schema.Any,
75
+ }).pipe(Schema.mutable),
76
+ ),
77
+ }).pipe(Schema.mutable);
78
+ export type JsonSchemaEchoAnnotations = Schema.Schema.Type<typeof JsonSchemaEchoAnnotations>;
79
+
80
+ /**
81
+ * Describes a schema for the JSON-schema objects stored in ECHO.
82
+ * Contains extensions for ECHO (e.g., references).
83
+ * Ref: https://json-schema.org/draft-07/schema
84
+ */
85
+ // TODO(burdon): Integrate with Effect Serializable?
86
+ // TODO(dmaretskyi): Update to latest draft: https://json-schema.org/draft/2020-12
87
+ const _JsonSchemaType = Schema.Struct({
88
+ /**
89
+ * Identifier for this schema.
90
+ * This schema might be referenced by $ref clause in other schemas.
91
+ */
92
+ // TODO(dmaretskyi): Specify how the ids are generated.
93
+ // TODO(dmaretskyi): For type dxns, should this include the version?
94
+ $id: Schema.optional(Schema.String),
95
+
96
+ /**
97
+ * Schema of this schema.
98
+ * Set to "https://json-schema.org/draft-07/schema".
99
+ */
100
+ $schema: Schema.optional(Schema.String),
101
+
102
+ /**
103
+ * Reference to another schema.
104
+ */
105
+ $ref: Schema.optional(Schema.String),
106
+
107
+ /**
108
+ * Comments are ignored when interpreting the schema.
109
+ */
110
+ $comment: Schema.optional(Schema.String),
111
+
112
+ /**
113
+ * Defines whether this schema is an object schema or a relation schema.
114
+ */
115
+ entityKind: Schema.optional(EntityKindSchema),
116
+
117
+ /**
118
+ * Typename of this schema.
119
+ * Only on schema representing an ECHO object.
120
+ *
121
+ * @example 'example.com/type/MyType'
122
+ */
123
+ typename: Schema.optional(Schema.String),
124
+
125
+ /**
126
+ * Version of this schema.
127
+ * Custom dialect for ECHO.
128
+ */
129
+ version: Schema.optional(Schema.String),
130
+
131
+ /**
132
+ * Target of this relation.
133
+ * Only for relation schemas.
134
+ * The referenced schema must be an object schema.
135
+ */
136
+ relationTarget: Schema.optional(Schema.suspend(() => JsonSchemaType)),
137
+
138
+ /**
139
+ * Source of this relation.
140
+ * Only for relation schemas.
141
+ * The referenced schema must be an object schema.
142
+ */
143
+ relationSource: Schema.optional(Schema.suspend(() => JsonSchemaType)),
144
+
145
+ /**
146
+ * Title of this schema.
147
+ */
148
+ title: Schema.optional(Schema.String),
149
+
150
+ /**
151
+ * Description of this schema.
152
+ */
153
+ description: Schema.optional(Schema.String),
154
+
155
+ /**
156
+ * Whether this schema is read-only.
157
+ */
158
+ readOnly: Schema.optional(Schema.Boolean),
159
+
160
+ /**
161
+ * Whether this schema is write-only.
162
+ */
163
+ writeOnly: Schema.optional(Schema.Boolean),
164
+
165
+ /**
166
+ * Examples of instances of this schema.
167
+ */
168
+ examples: Schema.optional(Schema.Array(Schema.Any)),
169
+
170
+ /**
171
+ * Default value for this schema.
172
+ */
173
+ default: Schema.optional(Schema.Any),
174
+
175
+ /**
176
+ * This schema only matches values that are equal to this value.
177
+ */
178
+ const: Schema.optional(Schema.Any),
179
+
180
+ /**
181
+ * This schema only matches one of the values in this array.
182
+ */
183
+ enum: Schema.optional(Schema.Array(Schema.Any)),
184
+
185
+ /**
186
+ * Base type of the schema.
187
+ */
188
+ type: Schema.optional(Schema.Union(SimpleTypes, Schema.Array(SimpleTypes))),
189
+
190
+ //
191
+ // Numbers.
192
+ //
193
+
194
+ multipleOf: Schema.optional(Schema.Number.pipe(Schema.greaterThan(0))),
195
+ maximum: Schema.optional(Schema.Number),
196
+ exclusiveMaximum: Schema.optional(Schema.Number),
197
+ minimum: Schema.optional(Schema.Number),
198
+ exclusiveMinimum: Schema.optional(Schema.Number),
199
+
200
+ //
201
+ // Strings.
202
+ //
203
+
204
+ maxLength: Schema.optional(NonNegativeInteger),
205
+
206
+ /**
207
+ * Regex pattern for strings.
208
+ */
209
+ pattern: Schema.optional(Schema.String.pipe(FormatAnnotation.set(FormatEnum.Regex))),
210
+
211
+ /**
212
+ * Serialized from {@link FormatAnnotationId}.
213
+ */
214
+ format: Schema.optional(Schema.String),
215
+
216
+ //
217
+ // Arrays
218
+ //
219
+
220
+ minLength: Schema.optional(NonNegativeInteger),
221
+ items: Schema.optional(
222
+ Schema.Union(
223
+ Schema.suspend(() => JsonSchemaType),
224
+ Schema.Array(Schema.suspend(() => JsonSchemaType)),
225
+ ),
226
+ ),
227
+ additionalItems: Schema.optional(
228
+ Schema.Union(
229
+ Schema.suspend(() => JsonSchemaType),
230
+ Schema.Boolean,
231
+ ),
232
+ ),
233
+ maxItems: Schema.optional(NonNegativeInteger),
234
+ minItems: Schema.optional(NonNegativeInteger),
235
+ uniqueItems: Schema.optional(Schema.Boolean),
236
+ contains: Schema.optional(Schema.suspend(() => JsonSchemaType)),
237
+
238
+ //
239
+ // Objects
240
+ //
241
+
242
+ maxProperties: Schema.optional(NonNegativeInteger),
243
+ minProperties: Schema.optional(NonNegativeInteger),
244
+ required: Schema.optional(StringArray),
245
+
246
+ /**
247
+ * Non-standard JSON Schema extension.
248
+ * Defines the order of properties in the object.
249
+ * The unmentioned properties are placed at the end.
250
+ *
251
+ * Related: https://github.com/json-schema/json-schema/issues/119
252
+ */
253
+ propertyOrder: Schema.optional(StringArray),
254
+
255
+ additionalProperties: Schema.optional(JsonSchemaOrBoolean),
256
+ properties: Schema.optional(
257
+ Schema.Record({
258
+ key: Schema.String,
259
+ value: Schema.suspend(() => JsonSchemaType),
260
+ }).pipe(Schema.mutable),
261
+ ),
262
+ patternProperties: Schema.optional(
263
+ Schema.Record({
264
+ key: Schema.String,
265
+ value: Schema.suspend(() => JsonSchemaType),
266
+ }).pipe(Schema.mutable),
267
+ ),
268
+ propertyNames: Schema.optional(Schema.suspend(() => JsonSchemaType)),
269
+
270
+ definitions: Schema.optional(
271
+ Schema.mutable(
272
+ Schema.Record({
273
+ key: Schema.String,
274
+ value: Schema.suspend(() => JsonSchemaType),
275
+ }),
276
+ ),
277
+ ),
278
+ dependencies: Schema.optional(
279
+ Schema.Record({
280
+ key: Schema.String,
281
+ value: Schema.suspend(() => Schema.Union(Schema.String, StringArray, JsonSchemaType)).annotations({
282
+ identifier: 'dependency',
283
+ description: 'Dependency',
284
+ }),
285
+ }),
286
+ ),
287
+
288
+ contentMediaType: Schema.optional(Schema.String),
289
+ contentEncoding: Schema.optional(Schema.String),
290
+
291
+ if: Schema.optional(Schema.suspend(() => JsonSchemaType)),
292
+ then: Schema.optional(Schema.suspend(() => JsonSchemaType)),
293
+ else: Schema.optional(Schema.suspend(() => JsonSchemaType)),
294
+ allOf: Schema.optional(Schema.Array(Schema.suspend(() => JsonSchemaType))),
295
+ anyOf: Schema.optional(Schema.Array(Schema.suspend(() => JsonSchemaType))),
296
+ oneOf: Schema.optional(Schema.Array(Schema.suspend(() => JsonSchemaType))),
297
+ not: Schema.optional(Schema.suspend(() => JsonSchemaType)),
298
+ $defs: Schema.optional(
299
+ Schema.mutable(
300
+ Schema.Record({
301
+ key: Schema.String,
302
+ value: Schema.suspend(() => JsonSchemaType),
303
+ }),
304
+ ),
305
+ ),
306
+
307
+ //
308
+ // ECHO extensions.
309
+ //
310
+
311
+ currency: Schema.optional(Schema.String),
312
+
313
+ reference: Schema.optional(
314
+ Schema.mutable(
315
+ Schema.Struct({
316
+ schema: Schema.suspend(() => JsonSchemaType),
317
+ schemaVersion: Schema.optional(Schema.String),
318
+ schemaObject: Schema.optional(Schema.String),
319
+ }),
320
+ ),
321
+ ),
322
+
323
+ /**
324
+ * ECHO-specific annotations.
325
+ */
326
+ // TODO(dmaretskyi): Since we are adding a lot of new extensions to the JSON Schema, it is safer to namespace them here.
327
+ annotations: Schema.optional(Schema.mutable(JsonSchemaEchoAnnotations)),
328
+
329
+ /**
330
+ * @deprecated Use `annotations` instead.
331
+ */
332
+ echo: Schema.optional(Schema.mutable(JsonSchemaEchoAnnotations)),
333
+ }).annotations({ identifier: 'jsonSchema', description: 'JSON Schema' });
334
+
335
+ export const JsonSchemaFields = Object.keys(_JsonSchemaType.fields);
336
+
337
+ /**
338
+ * https://json-schema.org/draft-07/schema
339
+ */
340
+ export interface JsonSchemaType extends Schema.Schema.Type<Schema.mutable<typeof _JsonSchemaType>> {}
341
+
342
+ export const JsonSchemaType: Schema.Schema<JsonSchemaType> = _JsonSchemaType.pipe(Schema.mutable);
343
+
344
+ // TODO(burdon): Factor out JSON schema utils.
345
+
346
+ export const getSchemaProperty = (schema: JsonSchemaType, property: JsonProp): JsonSchemaType | undefined => {
347
+ return schema.properties?.[property];
348
+ };
349
+
350
+ // TODO(burdon): Properties should be ordered.
351
+ export const setSchemaProperty = (schema: JsonSchemaType, property: JsonProp, value: JsonSchemaType) => {
352
+ schema.properties ??= {};
353
+ schema.properties[property] = value;
354
+ return schema;
355
+ };
356
+
357
+ /**
358
+ * @internal
359
+ */
360
+ export const ECHO_ANNOTATIONS_NS_DEPRECATED_KEY: keyof JsonSchemaType = 'echo';
361
+
362
+ /**
363
+ * @internal
364
+ */
365
+ export const ECHO_ANNOTATIONS_NS_KEY = 'annotations';
366
+
367
+ /**
368
+ * @internal
369
+ * @returns ECHO annotations namespace object in its normalized form.
370
+ *
371
+ * `meta` holds PropertyMeta annotations.
372
+ * `annotations` holds other annotations.
373
+ */
374
+ export const getNormalizedEchoAnnotations = (obj: JsonSchemaType): JsonSchemaEchoAnnotations | undefined => {
375
+ if (obj[ECHO_ANNOTATIONS_NS_KEY] != null && obj[ECHO_ANNOTATIONS_NS_DEPRECATED_KEY] != null) {
376
+ return normalizeEchoAnnotations({
377
+ ...obj[ECHO_ANNOTATIONS_NS_DEPRECATED_KEY],
378
+ ...obj[ECHO_ANNOTATIONS_NS_KEY],
379
+ });
380
+ } else if (obj[ECHO_ANNOTATIONS_NS_KEY] != null) {
381
+ return normalizeEchoAnnotations(obj[ECHO_ANNOTATIONS_NS_KEY]!);
382
+ } else if (obj[ECHO_ANNOTATIONS_NS_DEPRECATED_KEY] != null) {
383
+ return normalizeEchoAnnotations(obj[ECHO_ANNOTATIONS_NS_DEPRECATED_KEY]!);
384
+ } else {
385
+ return undefined;
386
+ }
387
+ };
388
+
389
+ const normalizeEchoAnnotations = (obj: JsonSchemaEchoAnnotations): JsonSchemaEchoAnnotations => {
390
+ if (!obj.annotations) {
391
+ return obj;
392
+ } else {
393
+ const res = {
394
+ ...obj,
395
+ meta: {
396
+ ...obj.annotations,
397
+ ...(obj.meta ?? {}),
398
+ },
399
+ };
400
+ delete res.annotations;
401
+ return res;
402
+ }
403
+ };
@@ -0,0 +1,153 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Option from 'effect/Option';
6
+ import * as Schema from 'effect/Schema';
7
+
8
+ import { type JsonPath, getField } from '@dxos/effect';
9
+ import { assertArgument, invariant } from '@dxos/invariant';
10
+ import { DXN, ObjectId } from '@dxos/keys';
11
+ import { assumeType } from '@dxos/util';
12
+
13
+ import { DescriptionAnnotation, LabelAnnotation } from '../ast';
14
+
15
+ import { type InternalObjectProps, SchemaId, SelfDXNId } from './model';
16
+
17
+ //
18
+ // Accessors based on model.
19
+ //
20
+
21
+ /**
22
+ * Returns a DXN for an object or schema.
23
+ * @deprecated Use `Obj.getDXN`.
24
+ */
25
+ export const getObjectDXN = (object: any): DXN | undefined => {
26
+ invariant(!Schema.isSchema(object), 'schema not allowed in this function');
27
+ assertArgument(typeof object === 'object' && object != null, 'object', 'expected object');
28
+ assumeType<InternalObjectProps>(object);
29
+
30
+ if (object[SelfDXNId]) {
31
+ invariant(object[SelfDXNId] instanceof DXN, 'Invalid object model: invalid self dxn');
32
+ return object[SelfDXNId];
33
+ }
34
+
35
+ if (!ObjectId.isValid(object.id)) {
36
+ throw new TypeError('Object id is not valid.');
37
+ }
38
+
39
+ return DXN.fromLocalObjectId(object.id);
40
+ };
41
+
42
+ /**
43
+ * Returns the schema for the given object if one is defined.
44
+ */
45
+ // TODO(burdon): Reconcile with `getTypename`.
46
+ // TODO(dmaretskyi): For echo objects, this always returns the root schema.
47
+ export const getSchema = (obj: unknown | undefined): Schema.Schema.AnyNoContext | undefined => {
48
+ if (obj) {
49
+ return (obj as any)[SchemaId];
50
+ }
51
+ };
52
+
53
+ /**
54
+ * Internal use only.
55
+ */
56
+ export const setSchema = (obj: any, schema: Schema.Schema.AnyNoContext) => {
57
+ Object.defineProperty(obj, SchemaId, {
58
+ value: schema,
59
+ writable: false,
60
+ enumerable: false,
61
+ configurable: false,
62
+ });
63
+ };
64
+
65
+ /**
66
+ * @deprecated Use {@link Obj.getLabel} instead.
67
+ * Returns the label for a given object based on {@link LabelAnnotationId}.
68
+ */
69
+ export const getLabelForObject = (obj: unknown | undefined): string | undefined => {
70
+ const schema = getSchema(obj);
71
+ if (schema) {
72
+ return getLabel(schema, obj);
73
+ }
74
+ };
75
+
76
+ /**
77
+ * Returns the label for a given object based on {@link LabelAnnotationId}.
78
+ */
79
+ // TODO(burdon): Convert to JsonPath?
80
+ export const getLabel = <S extends Schema.Schema.Any>(schema: S, object: Schema.Schema.Type<S>): string | undefined => {
81
+ const annotation = LabelAnnotation.get(schema).pipe(Option.getOrElse(() => ['name']));
82
+ for (const accessor of annotation) {
83
+ assertArgument(
84
+ typeof accessor === 'string',
85
+ 'accessor',
86
+ 'Label annotation must be a string or an array of strings',
87
+ );
88
+ const value = getField(object, accessor as JsonPath);
89
+ switch (typeof value) {
90
+ case 'string':
91
+ case 'number':
92
+ case 'boolean':
93
+ case 'bigint':
94
+ case 'symbol':
95
+ return value.toString();
96
+ case 'undefined':
97
+ case 'object':
98
+ case 'function':
99
+ continue;
100
+ }
101
+ }
102
+
103
+ return undefined;
104
+ };
105
+
106
+ /**
107
+ * Sets the label for a given object based on {@link LabelAnnotationId}.
108
+ */
109
+ export const setLabel = <S extends Schema.Schema.Any>(schema: S, object: Schema.Schema.Type<S>, label: string) => {
110
+ const annotation = LabelAnnotation.get(schema).pipe(
111
+ Option.map((field) => field[0]),
112
+ Option.getOrElse(() => 'name'),
113
+ );
114
+ object[annotation] = label;
115
+ };
116
+
117
+ /**
118
+ * Returns the label for a given object based on {@link LabelAnnotationId}.
119
+ */
120
+ // TODO(burdon): Convert to JsonPath?
121
+ export const getDescription = <S extends Schema.Schema.Any>(
122
+ schema: S,
123
+ object: Schema.Schema.Type<S>,
124
+ ): string | undefined => {
125
+ const accessor = DescriptionAnnotation.get(schema).pipe(Option.getOrElse(() => 'description'));
126
+ assertArgument(typeof accessor === 'string', 'accessor', 'Description annotation must be a string');
127
+ const value = getField(object, accessor as JsonPath);
128
+ switch (typeof value) {
129
+ case 'string':
130
+ case 'number':
131
+ case 'boolean':
132
+ case 'bigint':
133
+ case 'symbol':
134
+ return value.toString();
135
+ case 'undefined':
136
+ case 'object':
137
+ case 'function':
138
+ default:
139
+ return undefined;
140
+ }
141
+ };
142
+
143
+ /**
144
+ * Sets the description for a given object based on {@link DescriptionAnnotationId}.
145
+ */
146
+ export const setDescription = <S extends Schema.Schema.Any>(
147
+ schema: S,
148
+ object: Schema.Schema.Type<S>,
149
+ description: string,
150
+ ) => {
151
+ const accessor = DescriptionAnnotation.get(schema).pipe(Option.getOrElse(() => 'description'));
152
+ object[accessor] = description;
153
+ };
@@ -0,0 +1,76 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { type BaseObject } from '../types';
8
+
9
+ import { getTypename } from './typename';
10
+
11
+ // TODO(dmaretskyi): Rename to represent commonality between objects and relations (e.g. `entity`).
12
+ export type TypedObjectOptions = {
13
+ // TODO(burdon): Document.
14
+ partial?: true;
15
+ // TODO(burdon): Document.
16
+ record?: true;
17
+ };
18
+
19
+ /**
20
+ *
21
+ */
22
+ // TODO(burdon): Comment required.
23
+ // TODO(dmaretskyi): Rename to represent commonality between objects and relations (e.g. `entity`).
24
+ type SimplifiedSchemaFields<
25
+ SchemaFields extends Schema.Struct.Fields,
26
+ Options extends TypedObjectOptions,
27
+ > = Options['partial'] extends boolean
28
+ ? Schema.SimplifyMutable<Partial<Schema.Struct.Type<SchemaFields>>>
29
+ : Schema.SimplifyMutable<Schema.Struct.Type<SchemaFields>>;
30
+
31
+ /**
32
+ *
33
+ */
34
+ // TODO(burdon): Comment required.
35
+ // TODO(dmaretskyi): Rename to represent commonality between objects and relations (e.g. `entity`).
36
+ export type TypedObjectFields<
37
+ SchemaFields extends Schema.Struct.Fields,
38
+ Options extends TypedObjectOptions,
39
+ > = SimplifiedSchemaFields<SchemaFields, Options> & { id: string } & (Options['record'] extends boolean
40
+ ? Schema.SimplifyMutable<Schema.IndexSignature.Type<Schema.IndexSignature.Records>>
41
+ : {});
42
+
43
+ export const makeTypedEntityClass = (
44
+ typename: string,
45
+ version: string,
46
+ baseSchema: Schema.Schema.AnyNoContext,
47
+ ): Schema.SchemaClass<any> => {
48
+ return class {
49
+ // Implement TypedObject properties.
50
+ static readonly typename = typename;
51
+ static readonly version = version;
52
+
53
+ // Implement Schema.Schema properties.
54
+ // TODO(burdon): Comment required.
55
+ static readonly [Schema.TypeId] = schemaVariance;
56
+ static readonly ast = baseSchema.ast;
57
+ static readonly annotations = baseSchema.annotations.bind(baseSchema);
58
+ static readonly pipe = baseSchema.pipe.bind(baseSchema);
59
+
60
+ // TODO(burdon): Comment required.
61
+ static [Symbol.hasInstance](obj: BaseObject) {
62
+ return obj != null && getTypename(obj) === typename;
63
+ }
64
+
65
+ // TODO(burdon): Throw APIError.
66
+ private constructor() {
67
+ throw new Error('Use live(Typename, { ...fields }) to instantiate an object.');
68
+ }
69
+ } as any;
70
+ };
71
+
72
+ const schemaVariance = {
73
+ _A: (_: any) => _,
74
+ _I: (_: any) => _,
75
+ _R: (_: never) => _,
76
+ };