biff.crux

Helper functions for Crux.

Also includes "Biff transactions" and "Biff queries", both of which are
patterned after Firebase's. Biff transactions provide a higher level
interface over crux.api/start-node. Biff queries are less
powerful than crux.api/q, but they support subscriptions (efficiently).

authorize

multimethod

Extend this multimethod to provide authorization rules.

See https://biff.findka.com/#authorization-rules

biff-q

(biff-q {:keys [biff.crux/db biff.crux/fn-whitelist], :as sys} {:keys [id where doc-type], :as query})
Executes a Biff query.

db:           A delayed Crux DB.
fn-whitelist: A collection of symbols for functions that are allowed to run
              in the Crux query. Symbols for non-core functions must be
              fully-qualified.
query:        See https://biff.findka.com/#subscription-query-format.

check-read

(check-read sys {:keys [docs query db]})
Checks if a read operation passes authorization rules.

Returns nil on success, otherwise returns the first unauthorized document.

query: See https://biff.findka.com/#subscription-query-format

check-write

(check-write sys tx-info)
Checks if a write operation passes authorization rules.

Returns nil on success, otherwise returns the first unauthorized change (see
get-changes).

tx-info: See get-tx-info.

get-changes

(get-changes {:keys [db server-timestamp biff-tx random-uuids]})
Return a list of changes that will occur after a transaction.

See https://biff.findka.com/#tx-docs.

server-timestamp: A Date object.
random-uuids:     A list of UUIDs to use for new documents.
biff-tx:          See https://biff.findka.com/#transactions.
db:               A Crux DB.

Each change is a map with the following keys:
:before   - The affected document's current value.
:after    - The affected document's value after the transaction occurs.
:tx-item  - An element of biff-tx.
:doc-type
:doc-id

get-tx-info

(get-tx-info {:keys [biff/schema biff.crux/db]} biff-tx)
Return a map with information needed to authorize and run a transaction.

schema:  An implementation of biff.util.protocols/Schema.
db:      A delayed Crux DB.
biff-tx: See https://biff.findka.com/#transactions.

Returns the following keys:
:crux-tx            - A Crux transaction.
:changes            - See get-changes.
:server-timestamp   - A Date object.
:db-before          - @db.
:db-after           - (crux.api/with-tx @db crux-tx).

handle-subscribe-event!

(handle-subscribe-event! {event-id :id, {:keys [query action]} :?data, :keys [client-id biff.crux/subscriptions biff/uid biff.sente/send-fn], :as sys})
Sends query results to the client and subscribes them to future changes.

See use-crux-sub-notifier and https://biff.findka.com/#subscriptions.

lazy-q

(lazy-q db query f)
Calls crux.api/open-q and passes a lazy seq of the results to f.

f must process the results eagerly.

normalize-tx-doc

(normalize-tx-doc {:keys [server-timestamp doc-id tx-doc before]})
Converts a TX doc to a Crux doc.

server-timestamp: A Date object.
doc-id:           The Crux document ID.
before:           The Crux document's current value (i.e. before the
                  transaction). nil if the document is being created.
tx-doc:           See https://biff.findka.com/#transactions.

q-entity

(q-entity db kvs)
Retrieve the first document that matches a set of kv pairs.

Example:

(q-entity db [[:user/email "foo@example.com"]])
=> {:crux.db/id #uuid "some-uuid"
    :user/email "foo@example.com"}

start-node

(start-node {:keys [topology dir opts jdbc-spec pool-opts]})
A higher-level version of crux.api/start-node.

Calls crux.api/sync before returning the node.

topology   - One of #{:standalone :jdbc}.
dir        - A path to store RocksDB instances in.
jdbc-spec,
pool-opts  - Maps to pass as
             {:crux.jdbc/connection-pool
              {:db-spec jdbc-spec :pool-opts pool-opts ...}}.
             (Used only when topology is :jdbc).
opts       - Additional options to pass to crux.api/start-node.

submit-tx

(submit-tx {:biff.crux/keys [node authorize], :as sys} biff-tx)
Submits a Biff transaction.

node:      A Crux node.
authorize: true if the transaction is required to pass authorization rules
           (default false).
biff-tx:   See https://biff.findka.com/#transactions.

use-crux

(use-crux {:biff.crux/keys [topology dir opts], :as sys})
A Biff component for Crux.

Sets :biff.crux/node to the crux node.

topology,
dir,
opts                  - passed to start-node.
biff.crux.jdbc/*      - passed to start-node as jdbc-spec, without the namespace.
biff.crux.jdbc-pool/* - passed to start-node as pool-opts, without the namespace.

use-crux-sub-notifier

(use-crux-sub-notifier {:keys [biff.sente/connected-uids biff.crux/node], :as sys})
Sends new query results to subscribed clients.

See https://biff.findka.com/#subscription-interface.

Sets :biff.crux/subscriptions to (atom #{}). To add subscriptions, insert
maps with these keys:
:biff/uid  - The subscriber's UID.
:client-id - The subscriber's Sente client ID.
:event-id  - The Sente event ID used to send this transaction.
:query     - The Biff query (see https://biff.findka.com/#subscription-query-format)

Adds a watch to connected-uids and removes subscriptions if their clients
disconnect.

wrap-db

(wrap-db handler {:keys [node]})
Sets :biff.crux/db to a delayed db value on incoming requests.