{"id":16538344,"url":"https://github.com/japgolly/webapp-util","last_synced_at":"2026-02-03T05:08:43.583Z","repository":{"id":40251712,"uuid":"363522878","full_name":"japgolly/webapp-util","owner":"japgolly","description":"Scala Webapp Utilities","archived":false,"fork":false,"pushed_at":"2023-09-04T20:22:44.000Z","size":689,"stargazers_count":17,"open_issues_count":5,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T00:01:30.435Z","etag":null,"topics":["http","indexeddb","scala","scalajs","test","testing","webapp","websocket","webworker"],"latest_commit_sha":null,"homepage":"https://japgolly.github.io/webapp-util/","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/japgolly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"japgolly"}},"created_at":"2021-05-01T22:53:16.000Z","updated_at":"2023-11-21T16:32:56.000Z","dependencies_parsed_at":"2024-10-28T10:17:20.032Z","dependency_job_id":"fb50c3e7-dd0b-4bab-b6ed-37748e933dff","html_url":"https://github.com/japgolly/webapp-util","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japgolly%2Fwebapp-util","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japgolly%2Fwebapp-util/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japgolly%2Fwebapp-util/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japgolly%2Fwebapp-util/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/japgolly","download_url":"https://codeload.github.com/japgolly/webapp-util/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244772607,"owners_count":20508024,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http","indexeddb","scala","scalajs","test","testing","webapp","websocket","webworker"],"created_at":"2024-10-11T18:45:03.873Z","updated_at":"2026-02-03T05:08:43.577Z","avatar_url":"https://github.com/japgolly.png","language":"Scala","readme":"# Scala Webapp Utilities\n[![Build Status](https://travis-ci.org/japgolly/webapp-util.svg?branch=master)](https://travis-ci.org/japgolly/webapp-util)\n[![Latest Version](https://maven-badges.herokuapp.com/maven-central/com.github.japgolly.webapp-util/core_2.13/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.japgolly.webapp-util/core_2.13)\n\nThis library was initially extracted (with permission) from the closed-source [ShipReq](https://blog.shipreq.com/about/)\nwhere it when through many evolutions, and was battled-tested on a real-world, large and complex project.\nIt was ported without git commit history, so please understand that in this case,\nthe low commit count is not an indication of immaturity.\n\n```scala\nval WebappUtilVer = \"\u003cversion\u003e\"\n\n// Minimal\n\"com.github.japgolly.webapp-util\" %%% \"core\"             % WebappUtilVer\n\"com.github.japgolly.webapp-util\" %%% \"test\"             % WebappUtilVer % Test\n\n// Node-specific additional testing support\n\"com.github.japgolly.webapp-util\" %%% \"test-node\"        % WebappUtilVer % Test\n\n// Requiring Boopickle\n\"com.github.japgolly.webapp-util\" %%% \"core-boopickle\"   % WebappUtilVer\n\"com.github.japgolly.webapp-util\" %%% \"test-boopickle\"   % WebappUtilVer % Test\n\n// Cats Effect support\n\"com.github.japgolly.webapp-util\" %%% \"core-cats-effect\" % WebappUtilVer\n\"com.github.japgolly.webapp-util\" %%% \"test-cats-effect\" % WebappUtilVer % Test\n\n// Circe JSON support\n\"com.github.japgolly.webapp-util\" %%% \"core-circe\"       % WebappUtilVer\n\"com.github.japgolly.webapp-util\" %%% \"test-circe\"       % WebappUtilVer % Test\n\n// HttpClient implementation using okhttp4\n\"com.github.japgolly.webapp-util\"  %% \"core-okhttp4\"     % WebappUtilVer\n\n// Postgres support via Doobie and Cats Effect\n\"com.github.japgolly.webapp-util\"  %% \"db-postgres\"      % WebappUtilVer\n\"com.github.japgolly.webapp-util\"  %% \"test-db-postgres\" % WebappUtilVer % Test\n```\n\n\n# Included\n\n## The `core` module:\n\n* `japgolly.webapputil.general`\n  * [`AsyncFunction`](./core/js/src/main/scala/japgolly/webapputil/general/AsyncFunction.scala) - an async, failable function *(JS only)*\n  * [`Enabled`](./core/shared/src/main/scala/japgolly/webapputil/general/Enabled.scala) - type-safe union of `Enabled | Disabled`\n  * [`ErrorMsg`](./core/shared/src/main/scala/japgolly/webapputil/general/ErrorMsg.scala) - typed error message, with some util and predefined cases\n  * [`JsExt`](./core/js/src/main/scala/japgolly/webapputil/general/JsExt.scala) - JS-only implicit extensions *(JS only)*\n  * [`LazyVal`](./core/shared/src/main/scala/japgolly/webapputil/general/LazyVal.scala) - lightweight `lazy val` as a portable value\n  * [`LoggerJs`](./core/js/src/main/scala/japgolly/webapputil/general/LoggerJs.scala) - simple logger *(JS only)*\n  * [`Permission`](./core/shared/src/main/scala/japgolly/webapputil/general/Permission.scala) - type-safe union of `Allow | Deny`\n  * [`Protocol`](./core/shared/src/main/scala/japgolly/webapputil/general/Protocol.scala) - abstract definitions of protocols\n  * [`Retries`](./core/shared/src/main/scala/japgolly/webapputil/general/Retries.scala) - immutable retry policy\n  * [`ThreadUtils`](./core/jvm/src/main/scala/japgolly/webapputil/general/ThreadUtils.scala) - thread groups, thread pools, `ExecutionContext` util, shutdown hooks  *(JVM only)*\n  * [`TimersJs`](./core/js/src/main/scala/japgolly/webapputil/general/TimersJs.scala) - API over JS timers *(JS only)*\n  * [`Url`](./core/shared/src/main/scala/japgolly/webapputil/general/Url.scala) - types for URLs\n  * [`VarJs`](./core/js/src/main/scala/japgolly/webapputil/general/VarJs.scala) - immutable reference to a potentially abstract, potentially mutable variable *(JS only)*\n  * [`Version`](./core/shared/src/main/scala/japgolly/webapputil/general/Version.scala) - types for a version with a major and minor component\n\n* `japgolly.webapputil.ajax`\n  * [`AjaxProtocol`](./core/shared/src/main/scala/japgolly/webapputil/ajax/AjaxProtocol.scala) - protocol for an AJAX endpoint\n  * [`AjaxClient`](./core/js/src/main/scala/japgolly/webapputil/ajax/AjaxClient.scala) - means for a client to perform AJAX calls *(JS only)*\n\n* `japgolly.webapputil.binary`\n  * [`BinaryData`](./core/shared/src/main/scala/japgolly/webapputil/binary/BinaryData.scala) - immutable representation of BinaryData\n  * [`BinaryFormat`](./core/js/src/main/scala/japgolly/webapputil/binary/BinaryFormat.scala) - converts a type to a binary format and back *(JS only)*\n  * [`BinaryJs`](./core/js/src/main/scala/japgolly/webapputil/binary/BinaryJs.scala) - functions for conversion between various JS binary data types *(JS only)*\n  * [`BinaryString`](./core/js/src/main/scala/japgolly/webapputil/binary/BinaryString.scala) - binary data efficiently encoded as a UTF-16 string *(JS only)*\n  * [`CodecEngine`](./core/shared/src/main/scala/japgolly/webapputil/binary/CodecEngine.scala) - capability to encode and decode binary data given a codec typeclass\n  * [`Compression`](./core/js/src/main/scala/japgolly/webapputil/binary/Compression.scala) - binary compression and decompression *(JS only)*\n  * [`Encryption`](./core/js/src/main/scala/japgolly/webapputil/binary/Encryption.scala) - binary encryption and decryption *(JS only)*\n  * [`Pako`](./core/js/src/main/scala/japgolly/webapputil/binary/Pako.scala) - facade for the JS `pako` library with provides zlib compression \u0026 decompression *(JS only)*\n\n* `japgolly.webapputil.browser`\n  * [`WindowConfirm`](./core/js/src/main/scala/japgolly/webapputil/browser/WindowConfirm.scala) - abstraction over `window.confirm` *(JS only)*\n  * [`WindowLocation`](./core/js/src/main/scala/japgolly/webapputil/browser/WindowLocation.scala) - abstraction over `window.location` *(JS only)*\n  * [`WindowPrompt`](./core/js/src/main/scala/japgolly/webapputil/browser/WindowPrompt.scala) - abstraction over `window.prompt` *(JS only)*\n\n* `japgolly.webapputil.entrypoint`\n  * [`EntrypointDef`](./core/shared/src/main/scala/japgolly/webapputil/entrypoint/EntrypointDef.scala) - definition of a JS app entrypoint\n  * [`Entrypoint`](./core/js/src/main/scala/japgolly/webapputil/entrypoint/Entrypoint.scala) - abstract class for a JS app entrypoint *(JS only)*\n  * [`EntrypointInvoker`](./core/jvm/src/main/scala/japgolly/webapputil/entrypoint/EntrypointInvoker.scala) - generate JS to invoke an entrypoint *(JVM only)*\n  * [`Html`](./core/jvm/src/main/scala/japgolly/webapputil/entrypoint/Html.scala) - HTML content *(JVM only)*\n  * [`Js`](./core/jvm/src/main/scala/japgolly/webapputil/entrypoint/Js.scala) - typed text representing JavaScript code (plus some util) *(JVM only)*\n  * [`LoadJs`](./core/jvm/src/main/scala/japgolly/webapputil/entrypoint/LoadJs.scala) - define a bundle of JS assets to be loaded via `loadjs` before entrypoint invocation *(JVM only)*\n\n* `japgolly.webapputil.http`\n  * [`Cookie`](./core/shared/src/main/scala/japgolly/webapputil/http/Cookie.scala) - abstract HTTP cookie and associated util\n  * [`HttpClient`](./core/shared/src/main/scala/japgolly/webapputil/http/HttpClient.scala) - abstract HTTP (invocation) client\n  * `UrlEncoder` - cross-platform URL encoding and decoding\n\n* `japgolly.webapputil.locks`\n  * [`LockMechanism`](./core/jvm/src/main/scala/japgolly/webapputil/locks/LockMechanism.scala) - means of implicitly specifying how to acquire locks *(JVM only)*\n  * [`LockUtils`](./core/jvm/src/main/scala/japgolly/webapputil/locks/LockUtils.scala) - helpers around Java locks *(JVM only)*\n  * [`GenericSharedLock.Safe`](./core/shared/src/main/scala/japgolly/webapputil/locks/GenericSharedLock.scala) - shared lock APIs that are FP-safe (consistent between JVM and JS)\n  * [`GenericSharedLock.Unsafe`](./core/shared/src/main/scala/japgolly/webapputil/locks/GenericSharedLock.scala) - shared lock APIs that are FP-unsafe, in that not effect type is used (consistent between JVM and JS)\n  * `SharedLock` - lock that can be safely shared between threads *(different API between JVM \u0026 JS)*\n  * `SharedLock.ReadWrite` - read/write lock that can be safely shared between threads *(different API between JVM \u0026 JS)*\n\n* `japgolly.webapputil.websocket`\n  * [`WebSocket`](./core/js/src/main/scala/japgolly/webapputil/websocket/WebSocket.scala) - abstract API over a websocket connection *(JS only)*\n  * [`WebSocketClient`](./core/js/src/main/scala/japgolly/webapputil/websocket/WebSocketClient.scala) - high-level, managed websocket connection from client to server, supporting things like authorisation, auto-reconnection, retries, session expiry ([`TLA+ spec`](./TLA+/websocket_client.tla)) *(JS only)*\n  * [`WebSocketServerUtil`](./core/jvm/src/main/scala/japgolly/webapputil/websocket/WebSocketServerUtil.scala) - util for writing server-side websockets *(JVM only)*\n  * [`WebSocketShared`](./core/shared/src/main/scala/japgolly/webapputil/websocket/WebSocketShared.scala) - definitions and util shared between websocket client and server\n\n* `japgolly.webapputil.webstorage` *(JS only)*\n  * [`AbstractWebStorage`](./core/js/src/main/scala/japgolly/webapputil/webstorage/AbstractWebStorage.scala) - API over webstorage with some impls\n  * [`KeyCodec`](./core/js/src/main/scala/japgolly/webapputil/indexeddb/KeyCodec.scala) - codec between an arbitrary type and a webstorage key\n  * [`ValueCodec`](./core/js/src/main/scala/japgolly/webapputil/indexeddb/ValueCodec.scala) - codec between an arbitrary type and a webstorage value\n  * [`WebStorageKey`](./core/js/src/main/scala/japgolly/webapputil/webstorage/WebStorageKey.scala) - high-level interface to data in webstorage\n\n* `japgolly.webapputil.webworker` *(JS only)*\n  * [`AbstractWebWorker`](./core/js/src/main/scala/japgolly/webapputil/webworker/AbstractWebWorker.scala) - web worker client \u0026 server API\n  * [`ManagedWebWorker`](./core/js/src/main/scala/japgolly/webapputil/webworker/ManagedWebWorker.scala) - web worker client \u0026 server implementations that handle all the low-level work\n  * [`OnError`](./core/js/src/main/scala/japgolly/webapputil/webworker/OnError.scala) - web worker error handler\n  * [`WebWorkerProtocol`](./core/js/src/main/scala/japgolly/webapputil/webworker/WebWorkerProtocol.scala) - protocol API for communication between web worker client and server\n\n* `japgolly.webapputil.experimental.indexeddb` *(JS only)*\n  * [`IndexedDb`](./core/js/src/main/scala/japgolly/webapputil/experimental/indexeddb/IndexedDb.scala) - monadic API over IndexedDb that enforces transaction rules at compile-time, and provides higher-level ops such as atomic async modification *(JS only)*\n  * [`IndexedDbKey`](./core/js/src/main/scala/japgolly/webapputil/experimental/indexeddb/IndexedDbKey.scala) - typed key for use in IndexedDb *(JS only)*\n  * [`KeyCodec`](./core/js/src/main/scala/japgolly/webapputil/experimental/indexeddb/KeyCodec.scala) - codec between an arbitrary type and a IndexedDb key *(JS only)*\n  * [`ObjectStoreDef`](./core/js/src/main/scala/japgolly/webapputil/experimental/indexeddb/ObjectStoreDef.scala) - IndexedDb store and codecs *(JS only)*\n  * [`ValueCodec`](./core/js/src/main/scala/japgolly/webapputil/experimental/indexeddb/ValueCodec.scala) - codec between an arbitrary type and a IndexedDb value *(JS only)*\n\n## The `test` module:\n\n* `japgolly.webapputil.test`\n  * [`BinaryTestUtil`](./testCore/shared/src/main/scala/japgolly/webapputil/test/BinaryTestUtil.scala) - util for testing binary data\n  * [`TestAjaxClient`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestAjaxClient.scala) - `AjaxClient` instance for use in tests *(JS only)*\n  * [`TestHttpClient`](./testCore/shared/src/main/scala/japgolly/webapputil/test/TestHttpClient.scala) - `HttpClient` instance for use in tests\n  * [`TestTimersJs`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestTimersJs.scala) - `TimersJs` instance for use in tests *(JS only)*\n  * [`TestWebSocket`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestWebSocket.scala) - `WebSocket` instance for use in tests *(JS only)*\n  * [`TestWebWorker`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestWebWorker.scala) - in-memory instances of `AbstractWebWorker` client and server API for use in tests *(JS only)*\n  * [`TestWindowConfirm`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestWindowConfirm.scala) - `WindowConfirm` instance for use in tests *(JS only)*\n  * [`TestWindowLocation`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestWindowLocation.scala) - `WindowLocation` instance for use in tests *(JS only)*\n  * [`TestWindowPrompt`](./testCore/js/src/main/scala/japgolly/webapputil/test/TestWindowPrompt.scala) - `WindowPrompt` instance for use in tests *(JS only)*\n\n## The `test-node` module:\n\n* `japgolly.webapputil.test.node` *(JS only)*\n  * [`TestNode`](./testNode/src/main/scala/japgolly/webapputil/test/node/TestNode.scala) - util for testing using Node\n\n## The `core-boopickle` module:\n\n* `japgolly.webapputil.boopickle`\n  * [`BinaryFormatExt`](./coreBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/BinaryFormatExt.scala) - additional functionality around `BinaryFormat` *(JS only)*\n  * [`BinaryWebWorkerProtocol`](./coreBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/BinaryWebWorkerProtocol.scala) - implementation of `WebWorkerProtocol` that uses boopickle for message encoding *(JS only)*\n  * [`BoopickleCodecEngine`](./coreBoopickle/shared/src/main/scala/japgolly/webapputil/boopickle/BoopickleCodecEngine.scala) - implementation of `CodecEngine` for boopickle\n  * [`BoopickleWebSocketClient`](./coreBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/BoopickleWebSocketClient.scala) - implementation of `WebSocketClient` that uses boopickle for message encoding *(JS only)*\n  * [`EncryptionEngine`](./coreBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/EncryptionEngine.scala) - implementation of `Encryption.Engine` *(JS only)*\n  * [`EntrypointDefExt`](./coreBoopickle/shared/src/main/scala/japgolly/webapputil/boopickle/EntrypointDefExt.scala) - additional functionality around `EntrypointDef`\n  * [`PicklerUtil`](./coreBoopickle/shared/src/main/scala/japgolly/webapputil/boopickle/PicklerUtil.scala) - util around, and implementations of, Boopickle `Pickler`s\n  * [`SafePickler`](./coreBoopickle/shared/src/main/scala/japgolly/webapputil/boopickle/SafePickler.scala) - safer version of a Boopickle `Pickler` with versioning support\n  * [`SafePicklerUtil`](./coreBoopickle/shared/src/main/scala/japgolly/webapputil/boopickle/SafePicklerUtil.scala) - util for working with `SafePickler` versions during (de)serialisation\n\n* `japgolly.webapputil.boopickle.experimental`\n  * [`IndexedDbExt`](./coreBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/experimental/IndexedDbExt.scala) - additional functionality around IndexedDb *(JS only)*\n\n## The `test-boopickle` module:\n\n* `japgolly.webapputil.boopickle.test`\n  * [`TestEncryption`](./testBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/test/TestEncryption.scala) - util for testing encryption *(JS only)*\n  * [`WebSocketTestUtil`](./testBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/test/WebSocketTestUtil.scala) - util for testing WebSocket code *(JS only)*\n\n* `japgolly.webapputil.boopickle.test.experimental`\n  * [`TestIndexedDb`](./testBoopickle/js/src/main/scala/japgolly/webapputil/boopickle/test/experimental/TestIndexedDb.scala) - util for testing IndexedDb code *(JS only)*\n\n## The `core-cats-effect` module:\n* `japgolly.webapputil.cats.effect`\n  * Implicits so that `IO` is recognised as an effect type usable by the rest of the this library.\n    * `Effect.Async[IO]`\n    * `Effect.Sync[IO]` *(JVM only)*\n  * [`ThreadUtilsIO`](./coreCatsEffect/jvm/src/main/scala/japgolly/webapputil/cats/effect/ThreadUtilsIO.scala) - thread pools, scheduling, shutdown hooks, `IO` runtimes *(JVM only)*\n\n## The `test-cats-effect` module:\n\n* `japgolly.webapputil.cats.effect.test`\n  * [`TestHttpClientIO`](./testCatsEffect/jvm/src/main/scala/japgolly/webapputil/cats/effect/test/package.scala) *(JVM only)*\n\n## The `core-circe` module:\n\n* `japgolly.webapputil.circe`\n  * [`JsonAjaxClient`](./coreCirce/js/src/main/scala/japgolly/webapputil/circe/JsonAjaxClientModule.scala) - implementation of `AjaxClient` that uses JSON and `JsonCodec` *(JS only)*\n  * [`JsonCodec`](./coreCirce/shared/src/main/scala/japgolly/webapputil/circe/JsonCodec.scala) - composition of Circe's `Encoder` and `Decoder` into a single typeclass\n  * [`JsonEntrypointCodec`](./coreCirce/shared/src/main/scala/japgolly/webapputil/circe/JsonEntrypointCodec.scala) - creates instances of `EntrypointDef.Codec` using Circe codecs\n  * [`JsonUtil`](./coreCirce/shared/src/main/scala/japgolly/webapputil/circe/JsonUtil.scala) - util to supplement Circe\n  * Extension methods available via `import japgolly.webapputil.circe._`\n    * `HttpClient.Body.json` to create response bodies as JSON\n    * `HttpClient.Body#parseJsonBody` to parse request bodies as JSON\n\n## The `test-circe` module:\n\n* `japgolly.webapputil.circe.test`\n  * [`JsonTestUtil`](./testCirce/shared/src/main/scala/japgolly/webapputil/circe/test/JsonTestUtil.scala) - util to test JSON codecs\n  * [`TestJsonAjaxClient`](./testCirce/js/src/main/scala/japgolly/webapputil/circe/test/package.scala) - implementation of `TestAjaxClient` that uses JSON and `JsonCodec` *(JS only)*\n\n## The `core-okhttp4` module: *(JVM only)*\n\n* `japgolly.webapputil.okhttp4`\n  * [`OkHttp4Client`](./coreOkHttp4/src/main/scala/japgolly/webapputil/okhttp4/OkHttp4Client.scala) - implementation of `HttpClient` using okhttp4\n\n## The `db-postgres` module: *(JVM only)*\n\n* `japgolly.webapputil.db`\n  * [`Db`](./dbPostgres/src/main/scala/japgolly/webapputil/db/Db.scala) - connection to the database\n  * [`DbConfig`](./dbPostgres/src/main/scala/japgolly/webapputil/db/DbConfig.scala) - DB config definitions, i.e. to load DB details at runtime on app startup\n  * [`DbMigration`](./dbPostgres/src/main/scala/japgolly/webapputil/db/DbMigration.scala) - manages DB schema migrations (via [Flyway](https://flywaydb.org))\n  * [`DoobieCodecs`](./dbPostgres/src/main/scala/japgolly/webapputil/db/DoobieCodecs.scala) - a few generic codecs for Doobie\n  * [`DoobieHelpers`](./dbPostgres/src/main/scala/japgolly/webapputil/db/DoobieHelpers.scala) - helpers for Doobie\n  * [`JdbcLogging`](./dbPostgres/src/main/scala/japgolly/webapputil/db/JdbcLogging.scala) - times and logs JDBC calls\n  * [`SqlTracer`](./dbPostgres/src/main/scala/japgolly/webapputil/db/SqlTracer.scala) - modularised behaviour around JDBC calls\n  * [`XA`](./dbPostgres/src/main/scala/japgolly/webapputil/db/XA.scala) - wrapper around `Transactor[IO]` (used to be more and may again)\n\n## The `test-db-postgres` module: *(JVM only)*\n\n* `japgolly.webapputil.db.test`\n  * [`DbTable`](./testDbPostgres/src/main/scala/japgolly/webapputil/db/test/DbTable.scala) - util around DB tables and row counting\n  * [`DelegateConnection`](./testDbPostgres/src/main/scala/japgolly/webapputil/db/test/DelegateConnection.scala) - `java.sql.Connection` instance that routes all calls to a delegated connection\n  * [`TestDb`](./testDbPostgres/src/main/scala/japgolly/webapputil/db/test/TestDb.scala) - provides access to a test DB, manages things like migration, and util\n  * [`TestDbConfig`](./testDbPostgres/src/main/scala/japgolly/webapputil/db/test/TestDbConfig.scala) - easily load DB config from tests\n  * [`TestDbHelpers`](./testDbPostgres/src/main/scala/japgolly/webapputil/db/test/TestDbHelpers.scala) - DB util helpful during testing\n  * [`TestXA`](./testDbPostgres/src/main/scala/japgolly/webapputil/db/test/TestXA.scala) - a live connection to the DB, and util to make testing as easy as possible\n\n\n# TODO:\n\n* Add examples\n* Add ScalaDoc and proper doc\n\n\n# Support\nIf you like what I do\n—my OSS libraries, my contributions to other OSS libs, [my programming blog](https://japgolly.blogspot.com)—\nand you'd like to support me, more content, more lib maintenance, [please become a patron](https://www.patreon.com/japgolly)!\nI do all my OSS work unpaid so showing your support will make a big difference.\n","funding_links":["https://patreon.com/japgolly","https://www.patreon.com/japgolly)!"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjapgolly%2Fwebapp-util","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjapgolly%2Fwebapp-util","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjapgolly%2Fwebapp-util/lists"}