datahike-browser-tests 1.0.0

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 (324) hide show
  1. package/.circleci/config.yml +405 -0
  2. package/.circleci/scripts/gen_ci.clj +194 -0
  3. package/.cirrus.yml +60 -0
  4. package/.clj-kondo/babashka/sci/config.edn +1 -0
  5. package/.clj-kondo/babashka/sci/sci/core.clj +9 -0
  6. package/.clj-kondo/config.edn +95 -0
  7. package/.dir-locals.el +2 -0
  8. package/.github/FUNDING.yml +3 -0
  9. package/.github/ISSUE_TEMPLATE/1-bug-report.yml +68 -0
  10. package/.github/ISSUE_TEMPLATE/2-feature-request.yml +28 -0
  11. package/.github/ISSUE_TEMPLATE/config.yml +6 -0
  12. package/.github/pull_request_template.md +24 -0
  13. package/.github/workflows/native-image.yml +84 -0
  14. package/LICENSE +203 -0
  15. package/README.md +273 -0
  16. package/bb/deps.edn +9 -0
  17. package/bb/resources/github-fingerprints +3 -0
  18. package/bb/resources/native-image-tests/run-bb-pod-tests.clj +162 -0
  19. package/bb/resources/native-image-tests/run-libdatahike-tests +12 -0
  20. package/bb/resources/native-image-tests/run-native-image-tests +74 -0
  21. package/bb/resources/native-image-tests/run-python-tests +22 -0
  22. package/bb/resources/native-image-tests/testconfig.attr-refs.edn +6 -0
  23. package/bb/resources/native-image-tests/testconfig.edn +5 -0
  24. package/bb/resources/template/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
  25. package/bb/resources/template/.settings/org.eclipse.jdt.core.prefs +9 -0
  26. package/bb/resources/template/.settings/org.eclipse.m2e.core.prefs +4 -0
  27. package/bb/resources/template/pom.xml +22 -0
  28. package/bb/src/tools/build.clj +132 -0
  29. package/bb/src/tools/clj_kondo.clj +32 -0
  30. package/bb/src/tools/deploy.clj +26 -0
  31. package/bb/src/tools/examples.clj +19 -0
  32. package/bb/src/tools/npm.clj +100 -0
  33. package/bb/src/tools/python.clj +14 -0
  34. package/bb/src/tools/release.clj +94 -0
  35. package/bb/src/tools/test.clj +148 -0
  36. package/bb/src/tools/version.clj +47 -0
  37. package/bb.edn +269 -0
  38. package/benchmark/src/benchmark/cli.clj +195 -0
  39. package/benchmark/src/benchmark/compare.clj +157 -0
  40. package/benchmark/src/benchmark/config.clj +316 -0
  41. package/benchmark/src/benchmark/measure.clj +187 -0
  42. package/benchmark/src/benchmark/store.clj +190 -0
  43. package/benchmark/test/benchmark/measure_test.clj +156 -0
  44. package/build.clj +30 -0
  45. package/config.edn +49 -0
  46. package/deps.edn +138 -0
  47. package/dev/sandbox.clj +82 -0
  48. package/dev/sandbox.cljs +127 -0
  49. package/dev/sandbox_benchmarks.clj +27 -0
  50. package/dev/sandbox_client.clj +87 -0
  51. package/dev/sandbox_transact_bench.clj +109 -0
  52. package/dev/user.clj +79 -0
  53. package/doc/README.md +96 -0
  54. package/doc/adl/README.md +6 -0
  55. package/doc/adl/adr-000-adr.org +28 -0
  56. package/doc/adl/adr-001-attribute-references.org +15 -0
  57. package/doc/adl/adr-002-build-tooling.org +54 -0
  58. package/doc/adl/adr-003-db-meta-data.md +52 -0
  59. package/doc/adl/adr-004-github-flow.md +40 -0
  60. package/doc/adl/adr-XYZ-template.md +30 -0
  61. package/doc/adl/index.org +3 -0
  62. package/doc/assets/datahike-logo.svg +3 -0
  63. package/doc/assets/datahiking-invoice.org +85 -0
  64. package/doc/assets/hhtree2.png +0 -0
  65. package/doc/assets/network_topology.svg +624 -0
  66. package/doc/assets/perf.png +0 -0
  67. package/doc/assets/schema_mindmap.mm +132 -0
  68. package/doc/assets/schema_mindmap.svg +970 -0
  69. package/doc/assets/temporal_index.mm +74 -0
  70. package/doc/backend-development.md +78 -0
  71. package/doc/bb-pod.md +89 -0
  72. package/doc/benchmarking.md +360 -0
  73. package/doc/bindings/edn-conversion.md +383 -0
  74. package/doc/cli.md +162 -0
  75. package/doc/cljdoc.edn +27 -0
  76. package/doc/cljs-support.md +133 -0
  77. package/doc/config.md +406 -0
  78. package/doc/contributing.md +114 -0
  79. package/doc/datalog-vs-sql.md +210 -0
  80. package/doc/datomic_differences.md +109 -0
  81. package/doc/development/pull-api-ns.md +186 -0
  82. package/doc/development/pull-frame-state-diagram.jpg +0 -0
  83. package/doc/distributed.md +566 -0
  84. package/doc/entity_spec.md +92 -0
  85. package/doc/gc.md +273 -0
  86. package/doc/java-api.md +808 -0
  87. package/doc/javascript-api.md +421 -0
  88. package/doc/libdatahike.md +86 -0
  89. package/doc/logging_and_error_handling.md +43 -0
  90. package/doc/norms.md +66 -0
  91. package/doc/schema-migration.md +85 -0
  92. package/doc/schema.md +287 -0
  93. package/doc/storage-backends.md +363 -0
  94. package/doc/store-id-refactoring.md +596 -0
  95. package/doc/time_variance.md +325 -0
  96. package/doc/unstructured.md +167 -0
  97. package/doc/versioning.md +261 -0
  98. package/examples/basic/README.md +19 -0
  99. package/examples/basic/deps.edn +6 -0
  100. package/examples/basic/docker-compose.yml +13 -0
  101. package/examples/basic/src/examples/core.clj +60 -0
  102. package/examples/basic/src/examples/schema.clj +155 -0
  103. package/examples/basic/src/examples/store.clj +60 -0
  104. package/examples/basic/src/examples/time_travel.clj +185 -0
  105. package/examples/java/.settings/org.eclipse.core.resources.prefs +3 -0
  106. package/examples/java/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
  107. package/examples/java/.settings/org.eclipse.jdt.core.prefs +9 -0
  108. package/examples/java/.settings/org.eclipse.m2e.core.prefs +4 -0
  109. package/examples/java/README.md +162 -0
  110. package/examples/java/pom.xml +62 -0
  111. package/examples/java/src/main/java/examples/QuickStart.java +115 -0
  112. package/examples/java/src/main/java/examples/SchemaExample.java +148 -0
  113. package/examples/java/src/main/java/examples/TimeTravelExample.java +121 -0
  114. package/flake.lock +27 -0
  115. package/flake.nix +27 -0
  116. package/http-server/datahike/http/middleware.clj +75 -0
  117. package/http-server/datahike/http/server.clj +269 -0
  118. package/java/src/datahike/java/Database.java +274 -0
  119. package/java/src/datahike/java/Datahike.java +281 -0
  120. package/java/src/datahike/java/DatahikeGeneratedTest.java +349 -0
  121. package/java/src/datahike/java/DatahikeTest.java +370 -0
  122. package/java/src/datahike/java/EDN.java +170 -0
  123. package/java/src/datahike/java/IEntity.java +11 -0
  124. package/java/src/datahike/java/Keywords.java +161 -0
  125. package/java/src/datahike/java/SchemaFlexibility.java +52 -0
  126. package/java/src/datahike/java/Util.java +219 -0
  127. package/karma.conf.js +19 -0
  128. package/libdatahike/compile-cpp +7 -0
  129. package/libdatahike/src/datahike/impl/LibDatahikeBase.java +203 -0
  130. package/libdatahike/src/datahike/impl/libdatahike.clj +59 -0
  131. package/libdatahike/src/test_cpp.cpp +61 -0
  132. package/npm-package/PUBLISHING.md +140 -0
  133. package/npm-package/README.md +226 -0
  134. package/npm-package/package.template.json +34 -0
  135. package/npm-package/test-isomorphic.ts +281 -0
  136. package/npm-package/test.js +557 -0
  137. package/npm-package/typescript-test.ts +70 -0
  138. package/package.json +16 -0
  139. package/pydatahike/README.md +569 -0
  140. package/pydatahike/pyproject.toml +91 -0
  141. package/pydatahike/setup.py +42 -0
  142. package/pydatahike/src/datahike/__init__.py +134 -0
  143. package/pydatahike/src/datahike/_native.py +250 -0
  144. package/pydatahike/src/datahike/_version.py +2 -0
  145. package/pydatahike/src/datahike/database.py +722 -0
  146. package/pydatahike/src/datahike/edn.py +311 -0
  147. package/pydatahike/src/datahike/py.typed +0 -0
  148. package/pydatahike/tests/conftest.py +17 -0
  149. package/pydatahike/tests/test_basic.py +170 -0
  150. package/pydatahike/tests/test_database.py +51 -0
  151. package/pydatahike/tests/test_edn_conversion.py +299 -0
  152. package/pydatahike/tests/test_query.py +99 -0
  153. package/pydatahike/tests/test_schema.py +55 -0
  154. package/resources/clj-kondo.exports/io.replikativ/datahike/config.edn +5 -0
  155. package/resources/example_server.edn +4 -0
  156. package/shadow-cljs.edn +56 -0
  157. package/src/data_readers.clj +7 -0
  158. package/src/datahike/api/impl.cljc +176 -0
  159. package/src/datahike/api/specification.cljc +633 -0
  160. package/src/datahike/api/types.cljc +261 -0
  161. package/src/datahike/api.cljc +41 -0
  162. package/src/datahike/array.cljc +99 -0
  163. package/src/datahike/cli.clj +166 -0
  164. package/src/datahike/cljs.cljs +6 -0
  165. package/src/datahike/codegen/cli.clj +406 -0
  166. package/src/datahike/codegen/clj_kondo.clj +291 -0
  167. package/src/datahike/codegen/java.clj +403 -0
  168. package/src/datahike/codegen/naming.cljc +33 -0
  169. package/src/datahike/codegen/native.clj +559 -0
  170. package/src/datahike/codegen/pod.clj +488 -0
  171. package/src/datahike/codegen/python.clj +838 -0
  172. package/src/datahike/codegen/report.clj +55 -0
  173. package/src/datahike/codegen/typescript.clj +262 -0
  174. package/src/datahike/codegen/validation.clj +145 -0
  175. package/src/datahike/config.cljc +294 -0
  176. package/src/datahike/connections.cljc +16 -0
  177. package/src/datahike/connector.cljc +265 -0
  178. package/src/datahike/constants.cljc +142 -0
  179. package/src/datahike/core.cljc +297 -0
  180. package/src/datahike/datom.cljc +459 -0
  181. package/src/datahike/db/interface.cljc +119 -0
  182. package/src/datahike/db/search.cljc +305 -0
  183. package/src/datahike/db/transaction.cljc +937 -0
  184. package/src/datahike/db/utils.cljc +338 -0
  185. package/src/datahike/db.cljc +956 -0
  186. package/src/datahike/experimental/unstructured.cljc +126 -0
  187. package/src/datahike/experimental/versioning.cljc +172 -0
  188. package/src/datahike/externs.js +31 -0
  189. package/src/datahike/gc.cljc +69 -0
  190. package/src/datahike/http/client.clj +188 -0
  191. package/src/datahike/http/writer.clj +79 -0
  192. package/src/datahike/impl/entity.cljc +218 -0
  193. package/src/datahike/index/interface.cljc +93 -0
  194. package/src/datahike/index/persistent_set.cljc +469 -0
  195. package/src/datahike/index/utils.cljc +44 -0
  196. package/src/datahike/index.cljc +32 -0
  197. package/src/datahike/js/api.cljs +172 -0
  198. package/src/datahike/js/api_macros.clj +22 -0
  199. package/src/datahike/js.cljs +163 -0
  200. package/src/datahike/json.cljc +209 -0
  201. package/src/datahike/lru.cljc +146 -0
  202. package/src/datahike/migrate.clj +39 -0
  203. package/src/datahike/norm/norm.clj +245 -0
  204. package/src/datahike/online_gc.cljc +252 -0
  205. package/src/datahike/pod.clj +155 -0
  206. package/src/datahike/pull_api.cljc +325 -0
  207. package/src/datahike/query.cljc +1945 -0
  208. package/src/datahike/query_stats.cljc +88 -0
  209. package/src/datahike/readers.cljc +62 -0
  210. package/src/datahike/remote.cljc +218 -0
  211. package/src/datahike/schema.cljc +228 -0
  212. package/src/datahike/schema_cache.cljc +42 -0
  213. package/src/datahike/spec.cljc +101 -0
  214. package/src/datahike/store.cljc +80 -0
  215. package/src/datahike/tools.cljc +308 -0
  216. package/src/datahike/transit.cljc +80 -0
  217. package/src/datahike/writer.cljc +239 -0
  218. package/src/datahike/writing.cljc +362 -0
  219. package/src/deps.cljs +1 -0
  220. package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/insert.cljc +76 -0
  221. package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/upsert.cljc +128 -0
  222. package/src-hitchhiker-tree/datahike/index/hitchhiker_tree.cljc +213 -0
  223. package/test/datahike/backward_compatibility_test/src/backward_test.clj +37 -0
  224. package/test/datahike/integration_test/config_record_file_test.clj +14 -0
  225. package/test/datahike/integration_test/config_record_test.clj +14 -0
  226. package/test/datahike/integration_test/depr_config_uri_test.clj +15 -0
  227. package/test/datahike/integration_test/return_map_test.clj +62 -0
  228. package/test/datahike/integration_test.cljc +67 -0
  229. package/test/datahike/norm/norm_test.clj +124 -0
  230. package/test/datahike/norm/resources/naming-and-sorting-test/001-a1-example.edn +5 -0
  231. package/test/datahike/norm/resources/naming-and-sorting-test/002-a2-example.edn +5 -0
  232. package/test/datahike/norm/resources/naming-and-sorting-test/003-tx-fn-test.edn +1 -0
  233. package/test/datahike/norm/resources/naming-and-sorting-test/004-tx-data-and-tx-fn-test.edn +5 -0
  234. package/test/datahike/norm/resources/naming-and-sorting-test/01-transact-basic-characters.edn +2 -0
  235. package/test/datahike/norm/resources/naming-and-sorting-test/02 add occupation.edn +5 -0
  236. package/test/datahike/norm/resources/naming-and-sorting-test/checksums.edn +12 -0
  237. package/test/datahike/norm/resources/simple-test/001-a1-example.edn +5 -0
  238. package/test/datahike/norm/resources/simple-test/002-a2-example.edn +5 -0
  239. package/test/datahike/norm/resources/simple-test/checksums.edn +4 -0
  240. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/001-a1-example.edn +5 -0
  241. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/002-a2-example.edn +5 -0
  242. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/003-tx-fn-test.edn +1 -0
  243. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/checksums.edn +6 -0
  244. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/004-tx-data-and-tx-fn-test.edn +5 -0
  245. package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/checksums.edn +2 -0
  246. package/test/datahike/norm/resources/tx-fn-test/first/001-a1-example.edn +5 -0
  247. package/test/datahike/norm/resources/tx-fn-test/first/002-a2-example.edn +5 -0
  248. package/test/datahike/norm/resources/tx-fn-test/first/checksums.edn +4 -0
  249. package/test/datahike/norm/resources/tx-fn-test/second/003-tx-fn-test.edn +1 -0
  250. package/test/datahike/norm/resources/tx-fn-test/second/checksums.edn +2 -0
  251. package/test/datahike/test/api_test.cljc +895 -0
  252. package/test/datahike/test/array_test.cljc +40 -0
  253. package/test/datahike/test/attribute_refs/datoms_test.cljc +140 -0
  254. package/test/datahike/test/attribute_refs/db_test.cljc +42 -0
  255. package/test/datahike/test/attribute_refs/differences_test.cljc +515 -0
  256. package/test/datahike/test/attribute_refs/entity_test.cljc +89 -0
  257. package/test/datahike/test/attribute_refs/pull_api_test.cljc +320 -0
  258. package/test/datahike/test/attribute_refs/query_find_specs_test.cljc +59 -0
  259. package/test/datahike/test/attribute_refs/query_fns_test.cljc +130 -0
  260. package/test/datahike/test/attribute_refs/query_interop_test.cljc +47 -0
  261. package/test/datahike/test/attribute_refs/query_not_test.cljc +193 -0
  262. package/test/datahike/test/attribute_refs/query_or_test.cljc +137 -0
  263. package/test/datahike/test/attribute_refs/query_pull_test.cljc +156 -0
  264. package/test/datahike/test/attribute_refs/query_rules_test.cljc +176 -0
  265. package/test/datahike/test/attribute_refs/query_test.cljc +241 -0
  266. package/test/datahike/test/attribute_refs/temporal_search.cljc +22 -0
  267. package/test/datahike/test/attribute_refs/transact_test.cljc +220 -0
  268. package/test/datahike/test/attribute_refs/utils.cljc +128 -0
  269. package/test/datahike/test/cache_test.cljc +38 -0
  270. package/test/datahike/test/components_test.cljc +92 -0
  271. package/test/datahike/test/config_test.cljc +158 -0
  272. package/test/datahike/test/core_test.cljc +105 -0
  273. package/test/datahike/test/datom_test.cljc +44 -0
  274. package/test/datahike/test/db_test.cljc +54 -0
  275. package/test/datahike/test/entity_spec_test.cljc +159 -0
  276. package/test/datahike/test/entity_test.cljc +103 -0
  277. package/test/datahike/test/explode_test.cljc +143 -0
  278. package/test/datahike/test/filter_test.cljc +75 -0
  279. package/test/datahike/test/gc_test.cljc +159 -0
  280. package/test/datahike/test/http/server_test.clj +192 -0
  281. package/test/datahike/test/http/writer_test.clj +86 -0
  282. package/test/datahike/test/ident_test.cljc +32 -0
  283. package/test/datahike/test/index_test.cljc +345 -0
  284. package/test/datahike/test/insert.cljc +125 -0
  285. package/test/datahike/test/java_bindings_test.clj +6 -0
  286. package/test/datahike/test/listen_test.cljc +41 -0
  287. package/test/datahike/test/lookup_refs_test.cljc +266 -0
  288. package/test/datahike/test/lru_test.cljc +27 -0
  289. package/test/datahike/test/migrate_test.clj +297 -0
  290. package/test/datahike/test/model/core.cljc +376 -0
  291. package/test/datahike/test/model/invariant.cljc +142 -0
  292. package/test/datahike/test/model/rng.cljc +82 -0
  293. package/test/datahike/test/model_test.clj +217 -0
  294. package/test/datahike/test/nodejs_test.cljs +262 -0
  295. package/test/datahike/test/online_gc_test.cljc +475 -0
  296. package/test/datahike/test/pod_test.clj +369 -0
  297. package/test/datahike/test/pull_api_test.cljc +474 -0
  298. package/test/datahike/test/purge_test.cljc +144 -0
  299. package/test/datahike/test/query_aggregates_test.cljc +101 -0
  300. package/test/datahike/test/query_find_specs_test.cljc +52 -0
  301. package/test/datahike/test/query_fns_test.cljc +523 -0
  302. package/test/datahike/test/query_interop_test.cljc +47 -0
  303. package/test/datahike/test/query_not_test.cljc +189 -0
  304. package/test/datahike/test/query_or_test.cljc +158 -0
  305. package/test/datahike/test/query_pull_test.cljc +147 -0
  306. package/test/datahike/test/query_rules_test.cljc +248 -0
  307. package/test/datahike/test/query_stats_test.cljc +218 -0
  308. package/test/datahike/test/query_test.cljc +984 -0
  309. package/test/datahike/test/schema_test.cljc +424 -0
  310. package/test/datahike/test/specification_test.cljc +30 -0
  311. package/test/datahike/test/store_test.cljc +78 -0
  312. package/test/datahike/test/stress_test.cljc +57 -0
  313. package/test/datahike/test/time_variance_test.cljc +518 -0
  314. package/test/datahike/test/tools_test.clj +134 -0
  315. package/test/datahike/test/transact_test.cljc +518 -0
  316. package/test/datahike/test/tuples_test.cljc +564 -0
  317. package/test/datahike/test/unstructured_test.cljc +291 -0
  318. package/test/datahike/test/upsert_impl_test.cljc +205 -0
  319. package/test/datahike/test/upsert_test.cljc +363 -0
  320. package/test/datahike/test/utils.cljc +110 -0
  321. package/test/datahike/test/validation_test.cljc +48 -0
  322. package/test/datahike/test/versioning_test.cljc +56 -0
  323. package/test/datahike/test.cljc +66 -0
  324. package/tests.edn +24 -0
@@ -0,0 +1,261 @@
1
+ (ns datahike.api.types
2
+ "Malli type schemas for Datahike API.
3
+
4
+ This namespace replaces datahike.spec with malli-based schemas.
5
+ Schemas are used for:
6
+ - API specification
7
+ - Runtime validation
8
+ - Code generation (Java, CLI, TypeScript)
9
+ - Documentation generation"
10
+ (:require [malli.core :as m]
11
+ [malli.util :as mu]
12
+ [malli.error :as me]
13
+ [datahike.connector :refer [connection?]]
14
+ [datahike.datom :refer [datom?]]
15
+ [datahike.db.utils :as dbu])
16
+ #?(:clj
17
+ (:import [java.util Date])))
18
+
19
+ ;; =============================================================================
20
+ ;; Helper Predicates
21
+ ;; =============================================================================
22
+
23
+ (defn date? [d]
24
+ #?(:cljs (instance? js/Date d)
25
+ :clj (instance? Date d)))
26
+
27
+ ;; ============================================================================
28
+ ;; Core Type Schemas
29
+ ;; =============================================================================
30
+
31
+ (def SDB
32
+ "Immutable database value."
33
+ [:fn {:error/message "must be a Datahike database"}
34
+ dbu/db?])
35
+
36
+ (def SConfig
37
+ "Database configuration.
38
+
39
+ Can be:
40
+ - Map with :store key (primary format)
41
+ - URI string (deprecated)"
42
+ [:or
43
+ [:map {:closed false}]
44
+ :string])
45
+
46
+ (def SConnection
47
+ "Database connection reference."
48
+ [:fn {:error/message "must be a Datahike connection"}
49
+ connection?])
50
+
51
+ (def SEId
52
+ "Entity identifier.
53
+
54
+ Can be:
55
+ - Number (entity ID)
56
+ - Sequential (lookup ref [:attr value])
57
+ - Keyword (for schema entities)"
58
+ [:or [:fn number?]
59
+ [:sequential :any]
60
+ :keyword])
61
+
62
+ (def SDatom
63
+ "Single datom (immutable fact)."
64
+ [:fn {:error/message "must be a Datom"}
65
+ datom?])
66
+
67
+ (def SDatoms
68
+ "Collection of datoms."
69
+ [:sequential SDatom])
70
+
71
+ (def STxMeta
72
+ "Transaction metadata - optional collection."
73
+ [:maybe :any])
74
+
75
+ (def STransactionReport
76
+ "Transaction result map.
77
+
78
+ Keys:
79
+ - :db-before - Database before transaction
80
+ - :db-after - Database after transaction
81
+ - :tx-data - Datoms added/retracted
82
+ - :tempids - Temp ID to entity ID mapping
83
+ - :tx-meta - Transaction metadata (optional)"
84
+ [:map
85
+ [:db-before SDB]
86
+ [:db-after SDB]
87
+ [:tx-data SDatoms]
88
+ [:tempids :map]
89
+ [:tx-meta {:optional true} STxMeta]])
90
+
91
+ (def STransactions
92
+ "Transaction data - collection of transaction forms."
93
+ [:sequential :any])
94
+
95
+ (def SPullOptions
96
+ "Pull pattern options map."
97
+ [:map
98
+ [:selector [:vector :any]]
99
+ [:eid SEId]])
100
+
101
+ (def SQueryArgs
102
+ "Query arguments map."
103
+ [:map
104
+ [:query [:or :string [:vector :any] :map]]
105
+ [:args {:optional true} [:sequential :any]]
106
+ [:limit {:optional true} :int]
107
+ [:offset {:optional true} :int]])
108
+
109
+ (def SWithArgs
110
+ "Arguments for 'with' operation."
111
+ [:map
112
+ [:tx-data STransactions]
113
+ [:tx-meta {:optional true} STxMeta]])
114
+
115
+ (def SIndexLookupArgs
116
+ "Index lookup arguments."
117
+ [:map
118
+ [:index [:enum :eavt :aevt :avet]]
119
+ [:components {:optional true} [:maybe [:sequential :any]]]])
120
+
121
+ (def SIndexRangeArgs
122
+ "Index range query arguments."
123
+ [:map
124
+ [:attrid :keyword]
125
+ [:start :any]
126
+ [:end :any]])
127
+
128
+ (def SSchema
129
+ "Database schema - map of attributes to schema entries."
130
+ [:map-of :any :any])
131
+
132
+ (def SMetrics
133
+ "Database metrics map."
134
+ [:map
135
+ [:count :int]
136
+ [:avet-count :int]
137
+ [:per-attr-counts :map]
138
+ [:per-entity-counts :map]
139
+ [:temporal-count {:optional true} :int]
140
+ [:temporal-avet-count {:optional true} :int]])
141
+
142
+ (def time-point?
143
+ "Time point - transaction ID (int) or Date."
144
+ [:or :int
145
+ [:fn {:error/message "must be a Date"}
146
+ date?]])
147
+
148
+ ;; =============================================================================
149
+ ;; Malli Registry
150
+ ;; =============================================================================
151
+
152
+ (def registry
153
+ "Malli registry containing all Datahike type schemas.
154
+ This allows schemas to reference each other by keyword and enables
155
+ proper integration with reitit coercion."
156
+ (merge
157
+ (m/default-schemas)
158
+ {:datahike/SDB SDB
159
+ :datahike/SConfig SConfig
160
+ :datahike/SConnection SConnection
161
+ :datahike/SEId SEId
162
+ :datahike/SDatom SDatom
163
+ :datahike/SDatoms SDatoms
164
+ :datahike/STxMeta STxMeta
165
+ :datahike/STransactionReport STransactionReport
166
+ :datahike/STransactions STransactions
167
+ :datahike/SPullOptions SPullOptions
168
+ :datahike/SQueryArgs SQueryArgs
169
+ :datahike/SWithArgs SWithArgs
170
+ :datahike/SIndexLookupArgs SIndexLookupArgs
171
+ :datahike/SIndexRangeArgs SIndexRangeArgs
172
+ :datahike/SSchema SSchema
173
+ :datahike/SMetrics SMetrics
174
+ :datahike/time-point? time-point?}))
175
+
176
+ ;; =============================================================================
177
+ ;; Type Mappings for Code Generation
178
+ ;; =============================================================================
179
+
180
+ (def malli->java-type
181
+ "Malli schema to Java type mapping."
182
+ {:SConfig "Map<String, Object>"
183
+ :SConnection "datahike.connector.Connection"
184
+ :SDB "datahike.db.DB"
185
+ :SEId "Object"
186
+ :SDatom "datahike.datom.Datom"
187
+ :SDatoms "List<Datom>"
188
+ :STransactions "List<Object>"
189
+ :STransactionReport "Map<String, Object>"
190
+ :SSchema "Map<Object, Object>"
191
+ :SMetrics "Map<String, Object>"
192
+ :SPullOptions "Map<String, Object>"
193
+ :SQueryArgs "Map<String, Object>"
194
+ :SIndexLookupArgs "Map<String, Object>"
195
+ :SIndexRangeArgs "Map<String, Object>"
196
+ :SWithArgs "Map<String, Object>"
197
+ ;; Primitives
198
+ :boolean "boolean"
199
+ :int "int"
200
+ :long "long"
201
+ :double "double"
202
+ :string "String"
203
+ :keyword "String"
204
+ :any "Object"
205
+ :nil "void"
206
+ ;; Collections
207
+ :vector "List"
208
+ :map "Map"
209
+ :set "Set"
210
+ :sequential "List"})
211
+
212
+ (def malli->typescript-type
213
+ "Malli schema to TypeScript type mapping."
214
+ {:SConfig "DatabaseConfig"
215
+ :SConnection "Connection"
216
+ :SDB "Database"
217
+ :SEId "number | [string, any] | string"
218
+ :SDatom "Datom"
219
+ :SDatoms "Datom[]"
220
+ :STransactions "Transaction[]"
221
+ :STransactionReport "TransactionReport"
222
+ :SSchema "Record<string, any>"
223
+ :SMetrics "Metrics"
224
+ :SPullOptions "PullOptions"
225
+ :SQueryArgs "QueryArgs"
226
+ :SIndexLookupArgs "IndexLookupArgs"
227
+ :SIndexRangeArgs "IndexRangeArgs"
228
+ :SWithArgs "WithArgs"
229
+ ;; Primitives
230
+ :boolean "boolean"
231
+ :int "number"
232
+ :long "number"
233
+ :double "number"
234
+ :string "string"
235
+ :keyword "string"
236
+ :any "any"
237
+ :nil "null"
238
+ ;; Collections
239
+ :vector "Array<any>"
240
+ :map "Record<string, any>"
241
+ :set "Set<any>"
242
+ :sequential "Array<any>"})
243
+
244
+ ;; =============================================================================
245
+ ;; Validation Helpers
246
+ ;; =============================================================================
247
+
248
+ (defn validate
249
+ "Validate data against schema."
250
+ [schema data]
251
+ (m/validate schema data))
252
+
253
+ (defn explain
254
+ "Explain validation errors."
255
+ [schema data]
256
+ (m/explain schema data))
257
+
258
+ (defn humanize
259
+ "Get human-readable validation errors."
260
+ [explanation]
261
+ (me/humanize explanation))
@@ -0,0 +1,41 @@
1
+ (ns datahike.api
2
+ "Public API for datahike. Expanded from api.specification."
3
+ (:refer-clojure :exclude [filter])
4
+ #?(:cljs (:require-macros [datahike.api :refer [emit-api]]))
5
+ (:require [datahike.connector :as dc]
6
+ [datahike.config :as config]
7
+ [datahike.api.specification :refer [api-specification malli-schema->argslist]]
8
+ [datahike.api.impl]
9
+ [datahike.writer :as dw]
10
+ #?(:clj [datahike.http.writer])
11
+ [datahike.writing :as writing]
12
+ [konserve.store]
13
+ [datahike.constants :as const]
14
+ [datahike.core :as dcore]
15
+ [datahike.pull-api :as dp]
16
+ [datahike.query :as dq]
17
+ [datahike.schema :as ds]
18
+ [datahike.tools :as dt]
19
+ [datahike.db :as db #?@(:cljs [:refer [HistoricalDB AsOfDB SinceDB FilteredDB]])]
20
+ [datahike.db.interface :as dbi]
21
+ [datahike.db.transaction :as dbt]
22
+ [datahike.impl.entity :as de])
23
+ #?(:clj
24
+ (:import [clojure.lang Keyword PersistentArrayMap]
25
+ [datahike.db HistoricalDB AsOfDB SinceDB FilteredDB]
26
+ [datahike.impl.entity Entity])))
27
+
28
+ (defmacro ^:private emit-api []
29
+ `(do
30
+ ~@(reduce
31
+ (fn [acc [n {:keys [args doc impl]}]]
32
+ (conj acc
33
+ `(def
34
+ ~(with-meta n
35
+ {:arglists `(malli-schema->argslist (quote ~args))
36
+ :doc doc})
37
+ ~impl)))
38
+ ()
39
+ (into (sorted-map) api-specification))))
40
+
41
+ (emit-api)
@@ -0,0 +1,99 @@
1
+ (ns ^:no-doc datahike.array
2
+ #?(:cljs (:require [goog.array]))
3
+ #?(:clj (:import [java.util Arrays])))
4
+
5
+ #?(:clj
6
+ nil
7
+ #_(defonce ^:private hh-node-ns
8
+ (try
9
+ (require 'hitchhiker.tree.node)
10
+ (find-ns 'hitchhiker.tree.node)
11
+ (catch Exception _ nil))))
12
+
13
+ #?(:clj
14
+ (defn java8? []
15
+ (try
16
+ (= 8 (Integer/parseInt (subs (System/getProperty "java.specification.version") 2)))
17
+ (catch Exception _
18
+ false))))
19
+
20
+ #?(:clj
21
+ ;; meta data doesn't get expanded in macros :/
22
+ (defn array-compare [a b] (Arrays/compare ^bytes a ^bytes b)))
23
+
24
+ #?(:clj
25
+ (defmacro raw-array-compare [a b]
26
+ (if (java8?)
27
+ ;; slow fallback for Java 8, but has same semantics
28
+ `(let [bl# (alength ~b)
29
+ al# (alength ~a)]
30
+ (loop [i# 1]
31
+ (cond (and (> i# bl#) (> i# al#))
32
+ 0
33
+
34
+ (> i# bl#)
35
+ 1 ;; b is a prefix of a
36
+
37
+ (> i# al#)
38
+ -1 ;; a is a prefix of b
39
+
40
+ :else
41
+ (let [ec# (compare (aget ~a (dec i#)) (aget ~b (dec i#)))]
42
+ (if (not (zero? ec#))
43
+ ec#
44
+ (recur (inc i#)))))))
45
+ `(array-compare ~a ~b))))
46
+
47
+ #?(:cljs
48
+ (defn bytes? [x]
49
+ (and (instance? js/ArrayBuffer (.-buffer x))
50
+ (number? (.-byteLength x)))))
51
+
52
+ (defn compare-arrays
53
+ "Compare two arrays a and b element-wise in ascending order. If one array is a
54
+ prefix of another then it comes first."
55
+ [a b]
56
+ #?(:cljs (goog.array/compare3 a b)
57
+ :clj
58
+ (if (not (and (bytes? a) (bytes? b)))
59
+ (try
60
+ (compare a b)
61
+ (catch ClassCastException _
62
+ #_(if hh-node-ns
63
+ (let [order-fn (ns-resolve hh-node-ns '-order-on-edn-types)]
64
+ (- (order-fn a) (order-fn b)))
65
+ ;; Fallback when hitchhiker-tree not available
66
+ (compare (class a) (class b)))))
67
+ (raw-array-compare a b))))
68
+
69
+ (defn string-from-bytes
70
+ "Represents a byte array as a string. Two byte arrays are said to be equal iff their corresponding values after applying this function are equal. That way, we rely on the equality and hash code implementations of the String class to compare byte arrays."
71
+ [x]
72
+ #?(:cljs (.decode (js/TextDecoder. "utf8") x)
73
+ :clj
74
+ (let [n (alength x)
75
+ dst (char-array n)]
76
+ (dotimes [i n]
77
+ (aset dst i (char (aget x i))))
78
+ (String. dst))))
79
+
80
+ (defrecord WrappedBytes [string-repr])
81
+
82
+ (defn wrap-comparable
83
+ "This functions is such that `(a= x y)` is equivalent to `(= (wrap-comparable x) (wrap-comparable y))`. This lets us also use these semantics in hash-sets or as keys in maps."
84
+ [x]
85
+ (if (bytes? x)
86
+ (WrappedBytes. #?(:clj (string-from-bytes x)
87
+ :cljs x))
88
+ x))
89
+
90
+ (defn a=
91
+ "Extension of Clojure's equality to things we also want to treat like values,
92
+ e.g. certain array types."
93
+ [a b]
94
+ (or (= a b)
95
+ #?(:clj (and (bytes? a)
96
+ (bytes? b)
97
+ (zero? (compare-arrays a b)))
98
+ :cljs (or (identical? a b)
99
+ (zero? (compare-arrays a b))))))
@@ -0,0 +1,166 @@
1
+ (ns datahike.cli
2
+ (:gen-class)
3
+ (:require [clojure.java.io :as io]
4
+ [clojure.pprint :refer [pprint]]
5
+ [clojure.string :as str]
6
+ [clojure.tools.cli :refer [parse-opts]]
7
+ [datahike.api :as d]
8
+ [datahike.pod :refer [run-pod]]
9
+ [datahike.codegen.cli :as cli-gen]
10
+ [clojure.edn :as edn]
11
+ [jsonista.core :as j]
12
+ [datahike.json :as json]
13
+ [clj-cbor.core :as cbor]
14
+ [taoensso.timbre :as log])
15
+ (:import [java.util Date]))
16
+
17
+ ;; This file is following https://github.com/clojure/tools.cli
18
+
19
+ (when-not (= "true" (System/getenv "BABASHKA_POD"))
20
+ (log/merge-config!
21
+ {:appenders {:println {:enabled? false} ;; leave a "paper trail"
22
+ :stderr {:doc "Always prints to *err*"
23
+ :enabled? true
24
+ :fn (fn log-to-stderr [{:keys [output_]}]
25
+ (binding [*out* *err*]
26
+ (println (force output_))))}}}))
27
+
28
+ (defn get-version []
29
+ (or
30
+ ;; Try to read version from resource file (generated at build time)
31
+ (try
32
+ (some-> (io/resource "DATAHIKE_VERSION")
33
+ slurp
34
+ str/trim)
35
+ (catch Exception _ nil))
36
+ ;; Fallback for development builds
37
+ "development build"))
38
+
39
+ (defn usage [options-summary]
40
+ (cli-gen/generate-help options-summary))
41
+
42
+ (defn error-msg [errors]
43
+ (str "The following errors occurred while parsing your command:\n\n"
44
+ (str/join \newline errors)))
45
+
46
+ (def cli-options
47
+ ;; An option with a required argument
48
+ (let [formats #{:json :edn :pprint :cbor}]
49
+ [["-f" "--format FORMAT" "Output format for the result."
50
+ :default :edn
51
+ :parse-fn keyword
52
+ :validate [formats (str "Must be one of: " (str/join ", " formats))]]
53
+ ["-if" "--input-format FORMAT" "Input format for the transaction."
54
+ :default :edn
55
+ :parse-fn keyword
56
+ :validate [formats (str "Must be one of: " (str/join ", " formats))]]
57
+ [nil "--tx-file PATH" "Use this input file for transactions instead of command line or STDIN."
58
+ :default nil
59
+ :validate [#(.exists (io/file %)) "Transaction file does not exist."]]
60
+ ;; A non-idempotent option (:default is applied first)
61
+ ["-v" nil "Verbosity level"
62
+ :id :verbosity
63
+ :default 0
64
+ :update-fn inc]
65
+ ;; A boolean option defaulting to nil
66
+ ["-h" "--help"]
67
+ [nil "--version" "Show version"]]))
68
+
69
+ (defn validate-args
70
+ "Validate command line arguments. Either return a map indicating the program
71
+ should exit (with a error message, and optional ok status), or a map
72
+ indicating the command the program should execute and the options provided."
73
+ [args]
74
+ (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)
75
+ pod? (= "true" (System/getenv "BABASHKA_POD"))
76
+ command-index (cli-gen/build-command-index)]
77
+ (cond
78
+ pod?
79
+ {:action :pod :options options}
80
+
81
+ (:help options) ; help => exit OK with usage summary
82
+ {:exit-message (usage summary) :ok? true :options options}
83
+
84
+ (:version options) ; version => exit OK with version string
85
+ {:exit-message (str "Datahike " (get-version)) :ok? true :options options}
86
+
87
+ errors ; errors => exit with description of errors
88
+ {:exit-message (error-msg errors) :options options}
89
+
90
+ ;; Try to match command (could be multi-part like "db exists")
91
+ (seq arguments)
92
+ (let [;; Try 2-part command first (e.g., "db exists")
93
+ two-part (str/join " " (take 2 arguments))
94
+ one-part (first arguments)
95
+
96
+ [cmd-str remaining-args]
97
+ (cond
98
+ (get command-index two-part)
99
+ [two-part (drop 2 arguments)]
100
+
101
+ (get command-index one-part)
102
+ [one-part (rest arguments)]
103
+
104
+ :else
105
+ [nil arguments])]
106
+
107
+ (if cmd-str
108
+ {:command cmd-str
109
+ :options options
110
+ :arguments (vec remaining-args)}
111
+ {:exit-message (str "Unknown command: " (str/join " " (take 2 arguments))
112
+ "\n\nUse 'dthk --help' to see available commands.")
113
+ :options options}))
114
+
115
+ :else ; No arguments
116
+ {:exit-message (usage summary)
117
+ :options options})))
118
+
119
+ (defn exit [status msg]
120
+ (println msg)
121
+ (System/exit status))
122
+
123
+ (defn report [format out]
124
+ (case format
125
+ :json (println (j/write-value-as-string out))
126
+ :edn (println (pr-str out))
127
+ :pprint (pprint out)
128
+ :cbor (.write System/out ^bytes (cbor/encode out))))
129
+
130
+ (defn -main [& args]
131
+ (let [{:keys [action command options arguments exit-message ok?]}
132
+ (validate-args args)]
133
+ ;; Set logging level
134
+ (case (int (:verbosity options))
135
+ 0 (log/set-level! :warn)
136
+ 1 (log/set-level! :info)
137
+ 2 (log/set-level! :debug)
138
+ 3 (log/set-level! :trace)
139
+ (exit 1 (str "Verbosity level not supported: " (:verbosity options))))
140
+
141
+ (cond
142
+ ;; Exit with message
143
+ exit-message
144
+ (exit (if ok? 0 1) exit-message)
145
+
146
+ ;; Babashka pod mode
147
+ (= action :pod)
148
+ (run-pod args)
149
+
150
+ ;; Execute command via generated dispatch
151
+ command
152
+ (try
153
+ (let [result (cli-gen/dispatch-command
154
+ (str/split command #"\s+")
155
+ arguments
156
+ options)]
157
+ (report (:format options) result))
158
+ (catch Exception e
159
+ (println "❌ Error executing command:" (.getMessage e))
160
+ (when (>= (:verbosity options) 2)
161
+ (.printStackTrace e))
162
+ (exit 1 "")))
163
+
164
+ ;; No command provided
165
+ :else
166
+ (exit 1 (usage (:summary (parse-opts args cli-options)))))))
@@ -0,0 +1,6 @@
1
+ (ns datahike.cljs
2
+ "ClojureScript implementations for clojure-only symbols")
3
+
4
+ ;; Conversions
5
+
6
+ (def Throwable js/Error)