8000 Add clarity to readme by becomingbabyman · Pull Request #6 · homebaseio/homebase-react · GitHub
[go: up one dir, main page]

Skip to content

Add clarity to readme #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 8, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 59 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Homebase React

> The graph database for simple React state management
> The graph database for delightful React state management

## Installation

Expand All @@ -24,38 +24,51 @@ You can clone and run our React code examples [here](https://github.com/homebase

## Purpose

We want software to be [local-first](https://news.ycombinator.com/item?id=21581444). That means we need to make it more convenient to work with complex data on clients.
We want data to be a first class citizen on the client. We love relational databases in our servers and we want that same experience in our React apps. In other words, we want our applications to be [local-first](https://news.ycombinator.com/item?id=21581444). That means we need to make it easier to work with complex data on clients.

Homebase React lets you plug a relational database into your React app.
Homebase React lets you plug a relational database into your React app with 3 lines of code. In fact it's the same database that powers Roam Research and many other ClojureScript applications, but with an API that's familiar to React and JS developers.

- Replace Redux with something simpler and more declarative
- Gain all the benefits of relational data like a single source of truth
- Query your database with a convenient JSON query syntax
- Query your database with datalog if you need more power
- Query your database with Clojure style datalog if you need more power
- Traverse your data graph like it's one big JSON object
- Stop spending time wiring up custom datatypes, reducers, caches and other bespoke state mumbo jumbo
- It's just data

It is immediately more intuitive than a denormalized JSON store, and over time it will get better as we add more local-first features to it.
We think that Homebase React is immediately more intuitive than any denormalized JSON store, and over time it will get better as we eliminate all the tedious aspects of manipulating data on clients.

## API Overview

### `HomebaseProvider`

The HomebaseProvider wraps your React app and makes a relational database accessible to all of your components. Configure it with `schema` and `initialData`.

```js
import { HomebaseProvider, useEntity, useTransact, useQuery } from 'homebase-react'

const config = {
// Schema is optional
// ref indicates a relationship
// unique enforces a uniqueness constraint
// Schema is not a type system like in most DBs.
// That is something we're considering, but for now it is
// mainly applied at query time to simplify relational queries.
// The only schema currently supported is:
// `type: 'ref'` which is a relationship and
// `unique: 'identity` which enforces a uniqueness constraint
// and let's you lookup entities by their unique attributes.
schema: {
todo: {
project: { type: 'ref' },
name: { unique: 'identity' }
}
},

// Initial data is what it sounds like.
// It's a transaction that runs on component mount.
// Use it to hydrate your app.
initialData: [
{ project: { id: -1, name: 'Do it' } }
{ todo: { project: -1, name: 'Make it' }}
{ project: { id: -1, name: 'Do it', owner: -2 } },
{ todo: { project: -1, name: 'Make it' } },
{ user: { id: -2, name: 'Arpegius' } }
]
}

Expand All @@ -68,52 +81,74 @@ const RootComponent = () => (

### `useEntity` and `entity.get`

```js
// Entities with unique attributes can be retrieved by those attributes
const [todo] = useEntity({ todo: { name: 'Make it' } })
Entities are the building blocks of the Homebase data model. They are like JSON objects with bonus features. In particular **you can traverse arbitrarily deep relationship without actually denormalizing and nesting your data**.

// Get attributes off an entity
todo.get('name') // => 'Make it'
```js
// You can get an entity by its id and get attributes off of it.
const [todo] = useEntity(2)
todo.get('id') // => 2
todo.get('name') // => 'Make it'

// You can also get an entity by its id
const [sameTodo] = useEntity(2)
// Entities with unique attributes can also be retrieved by those attributes.
const [sameTodo] = useEntity({ todo: { name: 'Make it' } })
sameTodo.get('id') // => 2

// And traverse relationships
todo.get('project', 'name') // => 'Do it'
// And most importantly you can traverse arbitrarily deep relationships.
sameTodo.get('project', 'owner', 'name') // => 'Arpegius'
```

### `useTransact`

Transactions let you create, update and delete multiple entities simultaneously. All changes will reactively update any components that depend on the changed data.

```js
const transact = useTransact()

// A transaction is an array of nested objects
// A transaction is an array of nested objects and or arrays.
// Leaving the id blank will create a new entity.
transact([{ todo: { name: 'New Todo', project: 1 } }])

// Update an entity by including its id
// Setting the id to a negative number is a temp id which
// allows multiple entities to be related to each other on creation.
transact([
{ project: { id: -123, name: 'New Project' } },
{ todo: { project: -123, name: 'New Todo' } },
])

// Update an entity by including its id.
// NOTE: that only the included attributes will be updated.
transact([{ project: { id: 1, name: 'Changed Project Title' } }])

// Delete an entity with retractEntity and its id
// To remove an attribute you have to explicitly set it to null.
transact([{ project: { id: 1, name: null } }])

// To delete an entire entity use retractEntity and its id
transact([['retractEntity', 1]])
```

### `useQuery`

Use queries to return an array of entities that meet a given criteria. Our query API is powered by datalog, but exposed as JSON similar to a JS SQL driver or Mongo DB. Datalog is similar to SQL and is incredibly powerful. However only a subset of features are currently available in JSON.

We are very interested in what features the community wants, and will prioritize based on feedback. In the meantime you can further filter results with JS `filter()` and `sort()`.

```js
// Finds any todo with a name
// Finds all todos with a name
const [todos] = useQuery({
$find: 'todo',
$where: { todo: { name: '$any' } }
})

// Returns an array of todo entities
todos.map(todo => todo.get('name'))
todos
.sort((todo1, todo2) => todo1.get('name') > todo2.get('name') ? 1 : -1)
.map(todo => todo.get('name'))
```

## Development

```bash
npm install
npx shadow-cljs watch :dev
```

Expand Down
0