61
DataScript for Web Development

DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

  • Upload
    others

  • View
    16

  • Download
    0

Embed Size (px)

Citation preview

Page 1: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

DataScript for Web Development

Page 2: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Nikita Prokopovtonsky.meNovosibirsk, Russia

Page 3: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript
Page 4: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Server-side traditionally benefits from relational storage + queries

Rationale

Page 5: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Why web developers should limit themselves?

Page 6: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Datomic model feels right and was within my reach

Page 7: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

DataScript is a post-modern DB:

someone else’s good idea redone on a more primitive level

Page 8: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

<entity, attribute, value> triple store

What’s DataScript?

Page 9: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Database as an immutable value

Page 10: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Completely in-memory

Page 11: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Datalog queries over it

Page 12: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Tries to mimic Datomic API

Page 13: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Written in ClojureScript, JS bindings available

Page 14: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

(def conn (d/create-conn {:aka {:db/cardinality :db.cardinality/many }})]

(d/transact! conn [ {:db/id 1 :name “Ivan” :aka [“The Terrible”, “Durak”]}])

(d/q ‘[:find ?name :where [?e :aka “Durak”] [?e :name ?name]] @conn)

Page 15: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

(defn create-conn [schema]

(atom (empty-db schema)

:meta { :listeners (atom {}) }))

How it works?

Page 16: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

(defrecord DB [ schema eavt aevt avet max-eid max-tx ])

Page 17: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

(defn with [db datoms]

(→ db

(update-in [:eavt] into datoms)

(update-in [:aevt] into datoms)

Page 18: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

(defn transact [conn datoms]

(swap! conn with datom))

Page 19: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

In-house implementation of B+ tree (sorted set)

BTSet

Page 20: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Performance comparable with sorted-set:

~ 50% slower conj

~200% faster iterate

Page 21: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Binary search lookups, fast range scans, reverse iteration, fast first-time creation

Page 22: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

ClojureScript, but heavy use of JS arrays and APIs

Page 23: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

700 loc btset

550 loc query engine

1700 loc total

1200 loc tests

DataScript is lightweight

Page 24: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Unfortunate to be associated with the word “database”:

no networking, query over memory,

Page 25: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

no log, no history & compound indexes, no external segments, constant space operation

Page 26: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

DataScript is more of a persistent data structure.

It’s just three sorted sets, literally.

Page 27: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Every app has an ad-hoc state

Put everything in a database

How to use it

Page 28: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Non-trivial SPA has complex state

KV stores do not cut it

Page 29: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

No inherent hierarchy, very natural for any data:

sparse, irregular, hierarchical, graph

Page 30: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Faster data retrieval from big datasets: indexes + hash joins

Page 31: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Uniform solution for storage encourages decoupling and reusable components:

server sync, undo/redo, local caching, audit

Page 32: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Datoms, DB and transactions have standard way to be serialized

No need to invent format for delta exchange

Page 33: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Immutability + db as a value + transactions = always consistent render

Page 34: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Encourages to write decoupled, pure renders

Good fit for React and Flux

Page 35: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Example architecture: CatChat

github/tonsky/datascript-chat

Page 36: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript
Page 37: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript
Page 38: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Raw react render, pure, decoupled

Page 39: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Re-render triggered by database mutations, always top-down, full re-render

Page 40: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

“Server” sync, db cleanup all decoupled from render code

Page 41: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Operates in a bound space via cleanup

Page 42: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Second DB used to emulate server

Page 43: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Example architecture: Acha-Achaacha-acha.co

Page 44: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript
Page 45: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Whole DB prefetch:

no server fetch on any navigation, all queries and aggregations hap-pen on a client

Page 46: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Always up-to-date server sync:

initial dump + deltas via websock-et (tricky to do correctly)

Page 47: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Non-hierarchical layout:

user page, repo page, main page

Page 48: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

14K datoms in 100..150ms

Page 49: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Example architecture: Menu [WIP]github/tonsky/datascript-menu

Page 50: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript
Page 51: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Component can listen for a specific [e a v] pattern

Page 52: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Optimized for huge amount of listeners, e.g. every person component ever can subscribe to

[(:db/id person) :person/name _]

Page 53: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Similar to Om ref-cursors

Have to figure out how to play nicely with top-down rendering

Page 54: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Considered alpha stage

Project status

Page 55: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

No docs, must know/learn Datomic

Extensive acceptance tests suite helps

Page 56: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Almost no validation, silent fails/unexpected results instead

Page 57: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Occasional breaking changes (not significant though)

If it’s in Datomic and DataScript already, it probably won’t change

Page 58: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Cover all Datomic APIs

components lookup refs find specifications pull API

Future plans

Page 59: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Entry barrier: docs, tutorials, error reporting

Page 60: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

JVM Clojure port

Page 61: DataScript for Web Development clojure eXchange.pdf · ClojureScript, but heavy use of JS arrays and APIs. 700 loc btset 550 loc query engine 1700 loc total 1200 loc tests DataScript

Nikita Prokopov

github/tonsky/datascript

tonsky.me

Thanks! — Questions?