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,403 @@
1
+ (ns datahike.codegen.java
2
+ "Generate Java source code from API specification.
3
+
4
+ This namespace generates DatahikeGenerated.java containing all
5
+ static method bindings from the universal API specification."
6
+ (:require [datahike.api.specification :refer [api-specification]]
7
+ [clojure.string :as str]
8
+ [clojure.java.io :as io]))
9
+
10
+ ;; =============================================================================
11
+ ;; Type Mapping: Malli Schema -> Java
12
+ ;; =============================================================================
13
+
14
+ (defn malli->java-type
15
+ "Map malli schema to Java type string.
16
+ Uses strongest Java collection interface we can safely cast to."
17
+ [schema]
18
+ (cond
19
+ ;; Keyword schemas (primitives and basic types)
20
+ (keyword? schema)
21
+ (case schema
22
+ :any "Object"
23
+ :nil "void"
24
+ :boolean "boolean"
25
+ :int "int"
26
+ :long "long"
27
+ :double "double"
28
+ :string "String"
29
+ :keyword "Object" ; clojure.lang.Keyword
30
+ :symbol "Object"
31
+ :map "Map<?,?>"
32
+ :vector "List<?>"
33
+ :sequential "Iterable<?>"
34
+ :set "Set<?>"
35
+ "Object")
36
+
37
+ ;; Symbol schemas (type references)
38
+ (symbol? schema)
39
+ (let [schema-name (name schema)]
40
+ (case schema-name
41
+ ;; Semantic Datahike types
42
+ "SConnection" "Object"
43
+ "SDB" "Object"
44
+ "SEntity" "Object"
45
+ "STransactionReport" "Map<String,Object>"
46
+ "SSchema" "Map<Object,Object>"
47
+ "SMetrics" "Map<String,Object>"
48
+ "SDatoms" "Iterable<?>"
49
+ "SEId" "Object"
50
+ "SPullPattern" "String"
51
+ "SConfig" "Map<String,Object>"
52
+ "STransactions" "List"
53
+ "SQueryArgs" "Object"
54
+ ;; Default
55
+ "Object"))
56
+
57
+ ;; Vector schemas (compound types)
58
+ (vector? schema)
59
+ (let [[op & args] schema]
60
+ (case op
61
+ ;; [:or Type1 Type2] -> Object (can't determine at compile time)
62
+ :or "Object"
63
+
64
+ ;; [:maybe Type] -> Object (nullable)
65
+ :maybe (let [inner (malli->java-type (first args))]
66
+ ;; Box primitives for nullable
67
+ (case inner
68
+ "boolean" "Boolean"
69
+ "int" "Integer"
70
+ "long" "Long"
71
+ "double" "Double"
72
+ inner))
73
+
74
+ ;; [:sequential Type] -> Iterable<?>
75
+ :sequential "Iterable<?>"
76
+
77
+ ;; [:vector Type] -> List<Type>
78
+ :vector
79
+ (str "List<?>")
80
+
81
+ ;; [:set Type] -> Set<Type>
82
+ :set
83
+ (str "Set<?>")
84
+
85
+ ;; [:map ...] -> Map
86
+ :map "Map<?,?>"
87
+
88
+ ;; [:function ...] or [:=> ...] - extract return type
89
+ (:function :=>)
90
+ (if (= op :=>)
91
+ (malli->java-type (nth schema 2)) ; [:=> input output]
92
+ (malli->java-type (second schema))) ; [:function [:=> ...]]
93
+
94
+ ;; [:cat ...] - args tuple, not a return type
95
+ :cat "Object"
96
+
97
+ ;; Default
98
+ "Object"))
99
+
100
+ ;; inst? predicate -> Date
101
+ (= schema 'inst?) "Date"
102
+
103
+ ;; Default
104
+ :else "Object"))
105
+
106
+ (defn param-type->java
107
+ "Map parameter type to Java type string."
108
+ [schema]
109
+ (cond
110
+ ;; Keyword type references with datahike/ prefix
111
+ (and (keyword? schema)
112
+ (= (namespace schema) "datahike"))
113
+ (let [type-name (name schema)]
114
+ (case type-name
115
+ "SConfig" "Map<String,Object>"
116
+ "SConnection" "Object"
117
+ "SDB" "Object"
118
+ "STransactions" "List"
119
+ "SPullPattern" "String"
120
+ "SEId" "Object"
121
+ "Object"))
122
+
123
+ ;; inst? predicate
124
+ (= schema 'inst?) "Date"
125
+
126
+ ;; Default to general type mapping
127
+ :else (malli->java-type schema)))
128
+
129
+ ;; =============================================================================
130
+ ;; Name Conversion
131
+ ;; =============================================================================
132
+
133
+ (defn clj-name->java-method
134
+ "Convert Clojure operation name to Java method name.
135
+ Examples: database-exists? -> databaseExists
136
+ gc-storage -> gcStorage
137
+ transact! -> transactAsync"
138
+ [op-name]
139
+ (let [s (name op-name)
140
+ ;; Handle ! suffix -> Async
141
+ has-bang? (str/ends-with? s "!")
142
+ ;; Remove trailing ! and ?
143
+ clean (str/replace s #"[!?]$" "")
144
+ ;; Split on hyphens
145
+ parts (str/split clean #"-")
146
+ ;; camelCase
147
+ base (apply str (first parts)
148
+ (map str/capitalize (rest parts)))]
149
+ ;; Add Async suffix if had !
150
+ (if has-bang?
151
+ (str base "Async")
152
+ base)))
153
+
154
+ ;; =============================================================================
155
+ ;; Parameter Extraction
156
+ ;; =============================================================================
157
+
158
+ (defn extract-params-from-schema
159
+ "Extract parameter list from malli function schema.
160
+ Returns vector of {:name :type} maps."
161
+ [args-schema]
162
+ (cond
163
+ ;; [:=> [:cat Type1 Type2] Return]
164
+ (and (vector? args-schema)
165
+ (= :=> (first args-schema)))
166
+ (let [[_ input-schema _] args-schema]
167
+ (when (and (vector? input-schema)
168
+ (= :cat (first input-schema)))
169
+ (vec
170
+ (map-indexed
171
+ (fn [idx param-schema]
172
+ {:name (str "arg" idx)
173
+ :type (param-type->java param-schema)})
174
+ (rest input-schema)))))
175
+
176
+ ;; [:function [:=> ...] [:=> ...]] - multi-arity, return all arities
177
+ (and (vector? args-schema)
178
+ (= :function (first args-schema)))
179
+ :multi-arity ; Signal to caller
180
+
181
+ ;; Default
182
+ :else []))
183
+
184
+ (defn extract-multi-arity-params
185
+ "Extract all arities from multi-arity function schema.
186
+ Returns vector of param-lists, each being a vector of {:name :type} maps."
187
+ [args-schema]
188
+ (when (and (vector? args-schema)
189
+ (= :function (first args-schema)))
190
+ (vec
191
+ (map extract-params-from-schema (rest args-schema)))))
192
+
193
+ ;; =============================================================================
194
+ ;; IFn Declaration Generation
195
+ ;; =============================================================================
196
+
197
+ (defn generate-ifn-declarations
198
+ "Generate static IFn field declarations for all operations."
199
+ []
200
+ (str/join "\n"
201
+ (for [[op-name _] (sort-by first api-specification)]
202
+ (let [fn-var-name (str (clj-name->java-method op-name) "Fn")
203
+ clj-op-name (name op-name)]
204
+ (str " protected static final IFn " fn-var-name
205
+ " = Clojure.var(\"datahike.api\", \"" clj-op-name "\");")))))
206
+
207
+ ;; =============================================================================
208
+ ;; Javadoc Generation
209
+ ;; =============================================================================
210
+
211
+ (defn escape-javadoc
212
+ "Escape special characters for javadoc."
213
+ [s]
214
+ (-> s
215
+ (str/replace #"<" "&lt;")
216
+ (str/replace #">" "&gt;")
217
+ (str/replace #"&" "&amp;")
218
+ (str/replace #"@" "{@literal @}")))
219
+
220
+ (defn format-javadoc
221
+ "Format a docstring and examples as javadoc comment."
222
+ [doc examples]
223
+ (when doc
224
+ (let [lines (str/split-lines doc)
225
+ doc-lines (map #(str " * " (escape-javadoc %)) lines)
226
+ ;; Add examples if available
227
+ example-lines (when (seq examples)
228
+ (concat
229
+ [" * "
230
+ " * <h3>Examples:</h3>"
231
+ " * <pre>{@code"]
232
+ (mapcat
233
+ (fn [{:keys [desc code]}]
234
+ (concat
235
+ [(str " * // " (escape-javadoc desc))]
236
+ (map #(str " * " (escape-javadoc %))
237
+ (str/split-lines code))))
238
+ (take 2 examples))
239
+ [" * }</pre>"]))]
240
+ (str " /**\n"
241
+ (str/join "\n" (concat doc-lines example-lines))
242
+ "\n */"))))
243
+
244
+ ;; =============================================================================
245
+ ;; Method Body Generation
246
+ ;; =============================================================================
247
+
248
+ (defn needs-normalization?
249
+ "Check if a parameter type needs Java→Clojure collection normalization."
250
+ [param-type]
251
+ (or (= param-type "List")
252
+ (= param-type "List<?>")
253
+ (= param-type "Map<?,?>")
254
+ (= param-type "Map<String,Object>")))
255
+
256
+ (defn convert-arg
257
+ "Generate conversion code for an argument.
258
+ Applies normalization to Java collection types automatically."
259
+ [{:keys [type name]}]
260
+ (if (needs-normalization? type)
261
+ (str "Util.normalizeCollections(" name ")")
262
+ name))
263
+
264
+ (defn generate-method-body
265
+ "Generate method body that invokes Clojure function."
266
+ [op-name params return-type]
267
+ (let [fn-var-name (str (clj-name->java-method op-name) "Fn")
268
+ ;; Determine if we need varargs handling
269
+ has-varargs? (some #(str/includes? (:name %) "...") params)
270
+ ;; Convert arguments (auto-normalize Java collections)
271
+ converted-args (map convert-arg params)
272
+ arg-str (str/join ", " converted-args)]
273
+ (cond
274
+ ;; Void return
275
+ (= return-type "void")
276
+ (str " " fn-var-name ".invoke(" arg-str ");\n")
277
+
278
+ ;; Transaction report needs conversion back to Java Map
279
+ (= return-type "Map<String,Object>")
280
+ (str " APersistentMap result = (APersistentMap) " fn-var-name ".invoke("
281
+ arg-str ");\n"
282
+ " return Util.clojureMapToJavaMap(result);\n")
283
+
284
+ ;; Varargs handling (like q, datoms)
285
+ has-varargs?
286
+ (str " List<Object> args = new ArrayList<>();\n"
287
+ (str/join "\n" (map #(str " args.add(" % ");") converted-args))
288
+ "\n"
289
+ " return (" return-type ") " fn-var-name ".applyTo(RT.seq(args));\n")
290
+
291
+ ;; Simple return with cast
292
+ :else
293
+ (str " return (" return-type ") " fn-var-name ".invoke("
294
+ arg-str ");\n"))))
295
+
296
+ ;; =============================================================================
297
+ ;; Method Generation
298
+ ;; =============================================================================
299
+
300
+ (defn generate-method
301
+ "Generate a single static method from spec entry."
302
+ [[op-name {:keys [args ret doc examples]}]]
303
+ (let [method-name (clj-name->java-method op-name)
304
+ return-type (malli->java-type ret)
305
+ javadoc (format-javadoc doc examples)]
306
+
307
+ ;; Check for multi-arity
308
+ (if (= :multi-arity (extract-params-from-schema args))
309
+ ;; Generate multiple overloads
310
+ (let [arities (extract-multi-arity-params args)]
311
+ (str/join "\n\n"
312
+ (for [params arities]
313
+ (let [param-str (str/join ", "
314
+ (map-indexed
315
+ (fn [idx {:keys [type name]}]
316
+ (str type " " name))
317
+ params))]
318
+ (str (when javadoc (str javadoc "\n"))
319
+ " public static " return-type " " method-name
320
+ "(" param-str ") {\n"
321
+ (generate-method-body op-name params return-type)
322
+ " }")))))
323
+
324
+ ;; Single arity
325
+ (let [params (extract-params-from-schema args)
326
+ param-str (str/join ", "
327
+ (map-indexed
328
+ (fn [idx {:keys [type name]}]
329
+ (str type " " name))
330
+ params))]
331
+ (str (when javadoc (str javadoc "\n"))
332
+ " public static " return-type " " method-name
333
+ "(" param-str ") {\n"
334
+ (generate-method-body op-name params return-type)
335
+ " }")))))
336
+
337
+ ;; =============================================================================
338
+ ;; Full Class Generation
339
+ ;; =============================================================================
340
+
341
+ (defn generate-java-class
342
+ "Generate complete DatahikeGenerated.java source."
343
+ []
344
+ (str
345
+ "package datahike.java;\n\n"
346
+ "import clojure.java.api.Clojure;\n"
347
+ "import clojure.lang.IFn;\n"
348
+ "import clojure.lang.APersistentMap;\n"
349
+ "import clojure.lang.RT;\n"
350
+ "import java.util.*;\n\n"
351
+ "/**\n"
352
+ " * Generated Datahike API bindings.\n"
353
+ " * DO NOT EDIT - Generated from datahike.api.specification\n"
354
+ " *\n"
355
+ " * This class is package-private. Use the public Datahike facade instead.\n"
356
+ " */\n"
357
+ "class DatahikeGenerated {\n\n"
358
+ " // ===== Generated IFn Static Fields =====\n\n"
359
+ (generate-ifn-declarations)
360
+ "\n\n"
361
+ " // ===== Static Initialization =====\n\n"
362
+ " static {\n"
363
+ " IFn require = Clojure.var(\"clojure.core\", \"require\");\n"
364
+ " require.invoke(Clojure.read(\"datahike.api\"));\n"
365
+ " }\n\n"
366
+ " // ===== Generated Static Methods =====\n\n"
367
+ (str/join "\n\n" (map generate-method (sort-by first api-specification)))
368
+ "\n}\n"))
369
+
370
+ ;; =============================================================================
371
+ ;; File Writing
372
+ ;; =============================================================================
373
+
374
+ (defn write-generated-source
375
+ "Write generated Java source to file."
376
+ [output-dir]
377
+ (let [package-dir (io/file output-dir "datahike" "java")
378
+ java-file (io/file package-dir "DatahikeGenerated.java")]
379
+ (.mkdirs package-dir)
380
+ (spit java-file (generate-java-class))
381
+ (println "Generated:" (.getPath java-file))
382
+ {:generated-files [(.getPath java-file)]}))
383
+
384
+ (defn -main
385
+ "CLI entry point for Java source generation."
386
+ [& args]
387
+ (let [output-dir (or (first args) "java/src-generated")]
388
+ (println "Generating Java API from specification...")
389
+ (write-generated-source output-dir)
390
+ (println "Done.")))
391
+
392
+ (comment
393
+ ;; Test generation
394
+ (println (generate-java-class))
395
+
396
+ ;; Generate to file
397
+ (write-generated-source "java/src-generated")
398
+
399
+ ;; Test type mapping
400
+ (malli->java-type :boolean) ; => "boolean"
401
+ (malli->java-type :datahike/SConnection) ; => "Object"
402
+ (malli->java-type [:sequential :any]) ; => "Iterable<?>"
403
+ )
@@ -0,0 +1,33 @@
1
+ (ns datahike.codegen.naming
2
+ "Shared naming conventions for JavaScript API.
3
+ Used by both api_macros.clj and typescript.clj to ensure consistency."
4
+ (:require [clojure.string :as str]))
5
+
6
+ ;; Functions to skip in JS export (ClojureScript incompatible or aliases)
7
+ ;; - transact: synchronous version that throws error in ClojureScript
8
+ ;; use transact! instead (which becomes 'transact' in JS)
9
+ (def js-skip-list #{'transact})
10
+
11
+ (defn clj-name->js-name
12
+ "Convert Clojure kebab-case to JavaScript camelCase.
13
+
14
+ Examples:
15
+ database-exists? -> databaseExists
16
+ create-database -> createDatabase
17
+ transact! -> transact (removes the !)
18
+ with -> withDb (avoids JS reserved keyword)"
19
+ [clj-name]
20
+ (let [s (name clj-name)
21
+ ;; Remove trailing ? or !
22
+ s (cond-> s
23
+ (str/ends-with? s "?") (subs 0 (dec (count s)))
24
+ (str/ends-with? s "!") (subs 0 (dec (count s))))
25
+ ;; Split on hyphens
26
+ parts (str/split s #"-")
27
+ ;; camelCase: first part lowercase, rest capitalized
28
+ base-name (str (first parts)
29
+ (apply str (map str/capitalize (rest parts))))]
30
+ ;; Handle JavaScript reserved words
31
+ (if (= base-name "with")
32
+ "withDb"
33
+ base-name)))