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.
- package/.circleci/config.yml +405 -0
- package/.circleci/scripts/gen_ci.clj +194 -0
- package/.cirrus.yml +60 -0
- package/.clj-kondo/babashka/sci/config.edn +1 -0
- package/.clj-kondo/babashka/sci/sci/core.clj +9 -0
- package/.clj-kondo/config.edn +95 -0
- package/.dir-locals.el +2 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/1-bug-report.yml +68 -0
- package/.github/ISSUE_TEMPLATE/2-feature-request.yml +28 -0
- package/.github/ISSUE_TEMPLATE/config.yml +6 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/workflows/native-image.yml +84 -0
- package/LICENSE +203 -0
- package/README.md +273 -0
- package/bb/deps.edn +9 -0
- package/bb/resources/github-fingerprints +3 -0
- package/bb/resources/native-image-tests/run-bb-pod-tests.clj +162 -0
- package/bb/resources/native-image-tests/run-libdatahike-tests +12 -0
- package/bb/resources/native-image-tests/run-native-image-tests +74 -0
- package/bb/resources/native-image-tests/run-python-tests +22 -0
- package/bb/resources/native-image-tests/testconfig.attr-refs.edn +6 -0
- package/bb/resources/native-image-tests/testconfig.edn +5 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/bb/resources/template/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/bb/resources/template/pom.xml +22 -0
- package/bb/src/tools/build.clj +132 -0
- package/bb/src/tools/clj_kondo.clj +32 -0
- package/bb/src/tools/deploy.clj +26 -0
- package/bb/src/tools/examples.clj +19 -0
- package/bb/src/tools/npm.clj +100 -0
- package/bb/src/tools/python.clj +14 -0
- package/bb/src/tools/release.clj +94 -0
- package/bb/src/tools/test.clj +148 -0
- package/bb/src/tools/version.clj +47 -0
- package/bb.edn +269 -0
- package/benchmark/src/benchmark/cli.clj +195 -0
- package/benchmark/src/benchmark/compare.clj +157 -0
- package/benchmark/src/benchmark/config.clj +316 -0
- package/benchmark/src/benchmark/measure.clj +187 -0
- package/benchmark/src/benchmark/store.clj +190 -0
- package/benchmark/test/benchmark/measure_test.clj +156 -0
- package/build.clj +30 -0
- package/config.edn +49 -0
- package/deps.edn +138 -0
- package/dev/sandbox.clj +82 -0
- package/dev/sandbox.cljs +127 -0
- package/dev/sandbox_benchmarks.clj +27 -0
- package/dev/sandbox_client.clj +87 -0
- package/dev/sandbox_transact_bench.clj +109 -0
- package/dev/user.clj +79 -0
- package/doc/README.md +96 -0
- package/doc/adl/README.md +6 -0
- package/doc/adl/adr-000-adr.org +28 -0
- package/doc/adl/adr-001-attribute-references.org +15 -0
- package/doc/adl/adr-002-build-tooling.org +54 -0
- package/doc/adl/adr-003-db-meta-data.md +52 -0
- package/doc/adl/adr-004-github-flow.md +40 -0
- package/doc/adl/adr-XYZ-template.md +30 -0
- package/doc/adl/index.org +3 -0
- package/doc/assets/datahike-logo.svg +3 -0
- package/doc/assets/datahiking-invoice.org +85 -0
- package/doc/assets/hhtree2.png +0 -0
- package/doc/assets/network_topology.svg +624 -0
- package/doc/assets/perf.png +0 -0
- package/doc/assets/schema_mindmap.mm +132 -0
- package/doc/assets/schema_mindmap.svg +970 -0
- package/doc/assets/temporal_index.mm +74 -0
- package/doc/backend-development.md +78 -0
- package/doc/bb-pod.md +89 -0
- package/doc/benchmarking.md +360 -0
- package/doc/bindings/edn-conversion.md +383 -0
- package/doc/cli.md +162 -0
- package/doc/cljdoc.edn +27 -0
- package/doc/cljs-support.md +133 -0
- package/doc/config.md +406 -0
- package/doc/contributing.md +114 -0
- package/doc/datalog-vs-sql.md +210 -0
- package/doc/datomic_differences.md +109 -0
- package/doc/development/pull-api-ns.md +186 -0
- package/doc/development/pull-frame-state-diagram.jpg +0 -0
- package/doc/distributed.md +566 -0
- package/doc/entity_spec.md +92 -0
- package/doc/gc.md +273 -0
- package/doc/java-api.md +808 -0
- package/doc/javascript-api.md +421 -0
- package/doc/libdatahike.md +86 -0
- package/doc/logging_and_error_handling.md +43 -0
- package/doc/norms.md +66 -0
- package/doc/schema-migration.md +85 -0
- package/doc/schema.md +287 -0
- package/doc/storage-backends.md +363 -0
- package/doc/store-id-refactoring.md +596 -0
- package/doc/time_variance.md +325 -0
- package/doc/unstructured.md +167 -0
- package/doc/versioning.md +261 -0
- package/examples/basic/README.md +19 -0
- package/examples/basic/deps.edn +6 -0
- package/examples/basic/docker-compose.yml +13 -0
- package/examples/basic/src/examples/core.clj +60 -0
- package/examples/basic/src/examples/schema.clj +155 -0
- package/examples/basic/src/examples/store.clj +60 -0
- package/examples/basic/src/examples/time_travel.clj +185 -0
- package/examples/java/.settings/org.eclipse.core.resources.prefs +3 -0
- package/examples/java/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/examples/java/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/examples/java/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/examples/java/README.md +162 -0
- package/examples/java/pom.xml +62 -0
- package/examples/java/src/main/java/examples/QuickStart.java +115 -0
- package/examples/java/src/main/java/examples/SchemaExample.java +148 -0
- package/examples/java/src/main/java/examples/TimeTravelExample.java +121 -0
- package/flake.lock +27 -0
- package/flake.nix +27 -0
- package/http-server/datahike/http/middleware.clj +75 -0
- package/http-server/datahike/http/server.clj +269 -0
- package/java/src/datahike/java/Database.java +274 -0
- package/java/src/datahike/java/Datahike.java +281 -0
- package/java/src/datahike/java/DatahikeGeneratedTest.java +349 -0
- package/java/src/datahike/java/DatahikeTest.java +370 -0
- package/java/src/datahike/java/EDN.java +170 -0
- package/java/src/datahike/java/IEntity.java +11 -0
- package/java/src/datahike/java/Keywords.java +161 -0
- package/java/src/datahike/java/SchemaFlexibility.java +52 -0
- package/java/src/datahike/java/Util.java +219 -0
- package/karma.conf.js +19 -0
- package/libdatahike/compile-cpp +7 -0
- package/libdatahike/src/datahike/impl/LibDatahikeBase.java +203 -0
- package/libdatahike/src/datahike/impl/libdatahike.clj +59 -0
- package/libdatahike/src/test_cpp.cpp +61 -0
- package/npm-package/PUBLISHING.md +140 -0
- package/npm-package/README.md +226 -0
- package/npm-package/package.template.json +34 -0
- package/npm-package/test-isomorphic.ts +281 -0
- package/npm-package/test.js +557 -0
- package/npm-package/typescript-test.ts +70 -0
- package/package.json +16 -0
- package/pydatahike/README.md +569 -0
- package/pydatahike/pyproject.toml +91 -0
- package/pydatahike/setup.py +42 -0
- package/pydatahike/src/datahike/__init__.py +134 -0
- package/pydatahike/src/datahike/_native.py +250 -0
- package/pydatahike/src/datahike/_version.py +2 -0
- package/pydatahike/src/datahike/database.py +722 -0
- package/pydatahike/src/datahike/edn.py +311 -0
- package/pydatahike/src/datahike/py.typed +0 -0
- package/pydatahike/tests/conftest.py +17 -0
- package/pydatahike/tests/test_basic.py +170 -0
- package/pydatahike/tests/test_database.py +51 -0
- package/pydatahike/tests/test_edn_conversion.py +299 -0
- package/pydatahike/tests/test_query.py +99 -0
- package/pydatahike/tests/test_schema.py +55 -0
- package/resources/clj-kondo.exports/io.replikativ/datahike/config.edn +5 -0
- package/resources/example_server.edn +4 -0
- package/shadow-cljs.edn +56 -0
- package/src/data_readers.clj +7 -0
- package/src/datahike/api/impl.cljc +176 -0
- package/src/datahike/api/specification.cljc +633 -0
- package/src/datahike/api/types.cljc +261 -0
- package/src/datahike/api.cljc +41 -0
- package/src/datahike/array.cljc +99 -0
- package/src/datahike/cli.clj +166 -0
- package/src/datahike/cljs.cljs +6 -0
- package/src/datahike/codegen/cli.clj +406 -0
- package/src/datahike/codegen/clj_kondo.clj +291 -0
- package/src/datahike/codegen/java.clj +403 -0
- package/src/datahike/codegen/naming.cljc +33 -0
- package/src/datahike/codegen/native.clj +559 -0
- package/src/datahike/codegen/pod.clj +488 -0
- package/src/datahike/codegen/python.clj +838 -0
- package/src/datahike/codegen/report.clj +55 -0
- package/src/datahike/codegen/typescript.clj +262 -0
- package/src/datahike/codegen/validation.clj +145 -0
- package/src/datahike/config.cljc +294 -0
- package/src/datahike/connections.cljc +16 -0
- package/src/datahike/connector.cljc +265 -0
- package/src/datahike/constants.cljc +142 -0
- package/src/datahike/core.cljc +297 -0
- package/src/datahike/datom.cljc +459 -0
- package/src/datahike/db/interface.cljc +119 -0
- package/src/datahike/db/search.cljc +305 -0
- package/src/datahike/db/transaction.cljc +937 -0
- package/src/datahike/db/utils.cljc +338 -0
- package/src/datahike/db.cljc +956 -0
- package/src/datahike/experimental/unstructured.cljc +126 -0
- package/src/datahike/experimental/versioning.cljc +172 -0
- package/src/datahike/externs.js +31 -0
- package/src/datahike/gc.cljc +69 -0
- package/src/datahike/http/client.clj +188 -0
- package/src/datahike/http/writer.clj +79 -0
- package/src/datahike/impl/entity.cljc +218 -0
- package/src/datahike/index/interface.cljc +93 -0
- package/src/datahike/index/persistent_set.cljc +469 -0
- package/src/datahike/index/utils.cljc +44 -0
- package/src/datahike/index.cljc +32 -0
- package/src/datahike/js/api.cljs +172 -0
- package/src/datahike/js/api_macros.clj +22 -0
- package/src/datahike/js.cljs +163 -0
- package/src/datahike/json.cljc +209 -0
- package/src/datahike/lru.cljc +146 -0
- package/src/datahike/migrate.clj +39 -0
- package/src/datahike/norm/norm.clj +245 -0
- package/src/datahike/online_gc.cljc +252 -0
- package/src/datahike/pod.clj +155 -0
- package/src/datahike/pull_api.cljc +325 -0
- package/src/datahike/query.cljc +1945 -0
- package/src/datahike/query_stats.cljc +88 -0
- package/src/datahike/readers.cljc +62 -0
- package/src/datahike/remote.cljc +218 -0
- package/src/datahike/schema.cljc +228 -0
- package/src/datahike/schema_cache.cljc +42 -0
- package/src/datahike/spec.cljc +101 -0
- package/src/datahike/store.cljc +80 -0
- package/src/datahike/tools.cljc +308 -0
- package/src/datahike/transit.cljc +80 -0
- package/src/datahike/writer.cljc +239 -0
- package/src/datahike/writing.cljc +362 -0
- package/src/deps.cljs +1 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/insert.cljc +76 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/upsert.cljc +128 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree.cljc +213 -0
- package/test/datahike/backward_compatibility_test/src/backward_test.clj +37 -0
- package/test/datahike/integration_test/config_record_file_test.clj +14 -0
- package/test/datahike/integration_test/config_record_test.clj +14 -0
- package/test/datahike/integration_test/depr_config_uri_test.clj +15 -0
- package/test/datahike/integration_test/return_map_test.clj +62 -0
- package/test/datahike/integration_test.cljc +67 -0
- package/test/datahike/norm/norm_test.clj +124 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/01-transact-basic-characters.edn +2 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/02 add occupation.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/checksums.edn +12 -0
- package/test/datahike/norm/resources/simple-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/checksums.edn +6 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/norm/resources/tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-fn-test/second/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/test/api_test.cljc +895 -0
- package/test/datahike/test/array_test.cljc +40 -0
- package/test/datahike/test/attribute_refs/datoms_test.cljc +140 -0
- package/test/datahike/test/attribute_refs/db_test.cljc +42 -0
- package/test/datahike/test/attribute_refs/differences_test.cljc +515 -0
- package/test/datahike/test/attribute_refs/entity_test.cljc +89 -0
- package/test/datahike/test/attribute_refs/pull_api_test.cljc +320 -0
- package/test/datahike/test/attribute_refs/query_find_specs_test.cljc +59 -0
- package/test/datahike/test/attribute_refs/query_fns_test.cljc +130 -0
- package/test/datahike/test/attribute_refs/query_interop_test.cljc +47 -0
- package/test/datahike/test/attribute_refs/query_not_test.cljc +193 -0
- package/test/datahike/test/attribute_refs/query_or_test.cljc +137 -0
- package/test/datahike/test/attribute_refs/query_pull_test.cljc +156 -0
- package/test/datahike/test/attribute_refs/query_rules_test.cljc +176 -0
- package/test/datahike/test/attribute_refs/query_test.cljc +241 -0
- package/test/datahike/test/attribute_refs/temporal_search.cljc +22 -0
- package/test/datahike/test/attribute_refs/transact_test.cljc +220 -0
- package/test/datahike/test/attribute_refs/utils.cljc +128 -0
- package/test/datahike/test/cache_test.cljc +38 -0
- package/test/datahike/test/components_test.cljc +92 -0
- package/test/datahike/test/config_test.cljc +158 -0
- package/test/datahike/test/core_test.cljc +105 -0
- package/test/datahike/test/datom_test.cljc +44 -0
- package/test/datahike/test/db_test.cljc +54 -0
- package/test/datahike/test/entity_spec_test.cljc +159 -0
- package/test/datahike/test/entity_test.cljc +103 -0
- package/test/datahike/test/explode_test.cljc +143 -0
- package/test/datahike/test/filter_test.cljc +75 -0
- package/test/datahike/test/gc_test.cljc +159 -0
- package/test/datahike/test/http/server_test.clj +192 -0
- package/test/datahike/test/http/writer_test.clj +86 -0
- package/test/datahike/test/ident_test.cljc +32 -0
- package/test/datahike/test/index_test.cljc +345 -0
- package/test/datahike/test/insert.cljc +125 -0
- package/test/datahike/test/java_bindings_test.clj +6 -0
- package/test/datahike/test/listen_test.cljc +41 -0
- package/test/datahike/test/lookup_refs_test.cljc +266 -0
- package/test/datahike/test/lru_test.cljc +27 -0
- package/test/datahike/test/migrate_test.clj +297 -0
- package/test/datahike/test/model/core.cljc +376 -0
- package/test/datahike/test/model/invariant.cljc +142 -0
- package/test/datahike/test/model/rng.cljc +82 -0
- package/test/datahike/test/model_test.clj +217 -0
- package/test/datahike/test/nodejs_test.cljs +262 -0
- package/test/datahike/test/online_gc_test.cljc +475 -0
- package/test/datahike/test/pod_test.clj +369 -0
- package/test/datahike/test/pull_api_test.cljc +474 -0
- package/test/datahike/test/purge_test.cljc +144 -0
- package/test/datahike/test/query_aggregates_test.cljc +101 -0
- package/test/datahike/test/query_find_specs_test.cljc +52 -0
- package/test/datahike/test/query_fns_test.cljc +523 -0
- package/test/datahike/test/query_interop_test.cljc +47 -0
- package/test/datahike/test/query_not_test.cljc +189 -0
- package/test/datahike/test/query_or_test.cljc +158 -0
- package/test/datahike/test/query_pull_test.cljc +147 -0
- package/test/datahike/test/query_rules_test.cljc +248 -0
- package/test/datahike/test/query_stats_test.cljc +218 -0
- package/test/datahike/test/query_test.cljc +984 -0
- package/test/datahike/test/schema_test.cljc +424 -0
- package/test/datahike/test/specification_test.cljc +30 -0
- package/test/datahike/test/store_test.cljc +78 -0
- package/test/datahike/test/stress_test.cljc +57 -0
- package/test/datahike/test/time_variance_test.cljc +518 -0
- package/test/datahike/test/tools_test.clj +134 -0
- package/test/datahike/test/transact_test.cljc +518 -0
- package/test/datahike/test/tuples_test.cljc +564 -0
- package/test/datahike/test/unstructured_test.cljc +291 -0
- package/test/datahike/test/upsert_impl_test.cljc +205 -0
- package/test/datahike/test/upsert_test.cljc +363 -0
- package/test/datahike/test/utils.cljc +110 -0
- package/test/datahike/test/validation_test.cljc +48 -0
- package/test/datahike/test/versioning_test.cljc +56 -0
- package/test/datahike/test.cljc +66 -0
- 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 #"<" "<")
|
|
216
|
+
(str/replace #">" ">")
|
|
217
|
+
(str/replace #"&" "&")
|
|
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)))
|