Skip to content

Commit

Permalink
fix(dx): alias schema to lookup helpers (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
becomingbabyman authored Mar 6, 2021
1 parent b1201ed commit 4a7b1f9
Show file tree
Hide file tree
Showing 25 changed files with 399 additions and 349 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,18 @@ You can clone and run our React code examples [here](examples/).

### `HomebaseProvider`

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

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

const config = {
// Schema is not a type system,
// it's a way to simplify relational queries at query time.
// The schema currently supported is:
// Lookup helpers simplify relational queries at query time.
// The helpers currently supported are:
// `type: 'ref'` which is a relationship and
// `unique: 'identity` which enforces a uniqueness constraint
// and lets you lookup entities by their unique attributes.
schema: {
lookupHelpers: {
todo: {
project: { type: 'ref', cardinality: 'one' },
name: { unique: 'identity' }
Expand Down Expand Up @@ -174,7 +173,7 @@ todos

This hook returns the current database client with some helpful functions for syncing data with a backend.

- `client.dbToString()` serializes the whole db including the schema to a string
- `client.dbToString()` serializes the whole db including the lookupHelpers to a string
- `client.dbFromString('a serialized db string')` replaces the current db
- `client.dbToDatoms()` returns an array of all the facts aka datoms saved in the db
- datoms are the smallest unit of data in the database, like a key value pair but better
Expand Down
17 changes: 7 additions & 10 deletions docs/0300|Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,21 @@ import { HomebaseProvider, useTransact, useQuery, useEntity } from 'homebase-rea

export const App = () => {
return (
<HomebaseProvider config={{ schema, initialData }}>
<HomebaseProvider config={{ lookupHelpers, initialData }}>
<Todos/>
</HomebaseProvider>
)
}
```

## Schema
## Lookup Helpers

Unlike other state managers, Homebase does not try to create yet another design pattern for state. Instead, we store state in a way we already know and love: as a relational graph database.

Like any good database we support schema on read.

At the moment schema is only for relationships and uniqueness constraints. It does not support typing of attributes, e.g. strings, integers, dates. We're working on adding the option to opt into schema on write support. This will provide basic type checking like you see in SQL.
Lookup helpers make relationships and uniqueness constraints something you declare once and then never need to worry about again. Subsequent queries and transactions will take these properties into account so you never have to write a join query.

```jsx
const schema = {
const lookupHelpers = {
project: {
name: {
unique: 'identity'
Expand Down Expand Up @@ -91,7 +89,7 @@ And now we're ready to go. 🚀

```jsx
const config = {
schema,
lookupHelpers,
initialData
}
```
Expand Down Expand Up @@ -348,10 +346,9 @@ export const App = () => {
}

const config = {
// Schema is only used to enforce
// Lookup helpers are used to enforce
// unique constraints and relationships.
// It is not a type system, yet.
schema: {
lookupHelpers: {
project: { name: { unique: 'identity' } },
todo: {
// refs are relationships
Expand Down
13 changes: 6 additions & 7 deletions docs/0400|API.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
## `HomebaseProvider`

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

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

const config = {
// Schema is not a type system,
// it's a way to simplify relational queries at query time.
// The schema currently supported is:
// Lookup helpers are a way to simplify relational queries at query time.
// The helpers currently supported are:
// `type: 'ref'` which is a relationship and
// `unique: 'identity` which enforces a uniqueness constraint
// and lets you lookup entities by their unique attributes.
schema: {
lookupHelpers: {
todo: {
project: { type: 'ref', cardinality: 'one' },
name: { unique: 'identity' }
Expand Down Expand Up @@ -121,7 +120,7 @@ todos

This hook returns the current database client with some helpful functions for syncing data with a backend.

- `client.dbToString()` serializes the whole db including the schema to a string
- `client.dbToString()` serializes the whole db including the lookupHelpers to a string
- `client.dbFromString('a serialized db string')` replaces the current db
- `client.dbToDatoms()` returns an array of all the facts aka datoms saved in the db
- datoms are the smallest unit of data in the database, like a key value pair but better
Expand All @@ -141,7 +140,7 @@ Arrays and arbitrary JSON are partially supported for convenience. However in mo

```js
const config = {
schema: {
lookupHelpers: {
company: {
numbers: { type: 'ref', cardinality: 'many' },
projects: { type: 'ref', cardinality: 'many' },
Expand Down
2 changes: 1 addition & 1 deletion examples/counter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"homebase-react": "^0.1.0",
"homebase-react": "latest",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.0",
Expand Down
8 changes: 4 additions & 4 deletions examples/counter/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5348,10 +5348,10 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"

homebase-react@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.1.0.tgz#e27a5b6bf6511b61cdc27b8b0ada31483bd1d997"
integrity sha512-q/+AiV8hVda/nYZ2oPstCyZJ+AjIDQsRGuTxZhBfl/Ew7aRCrNvBE3SI+ZWy9Qa6wTOC6e9qG3azgbLTLNIQxQ==
homebase-react@latest:
version "0.5.2"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.5.2.tgz#27dc72989921f79174584dc557a488a20b930543"
integrity sha512-cJNcmsEbDg0F/fhSkUfe3lJ/tqhgOk/rHE7iC6zoUah9xufuFfNTwaxaArqdyF4m3SxWASCA4DznKYXFUZs9vQ==

hoopy@^0.1.4:
version "0.1.4"
Expand Down
2 changes: 1 addition & 1 deletion examples/roam/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"autoprefixer": "^9",
"firebase": "^8.2.6",
"firebaseui": "^4.7.3",
"homebase-react": "^0.5.1",
"homebase-react": "latest",
"lodash": "^4.17.20",
"nanoid": "^3.1.20",
"postcss": "^7",
Expand Down
2 changes: 1 addition & 1 deletion examples/roam/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ const NotLoggedInBanner = () => {
}

const config = {
schema: {
lookupHelpers: {
block: {
uid: { unique: 'identity' },
title: { unique: 'identity' },
Expand Down
2 changes: 1 addition & 1 deletion examples/roam/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6298,7 +6298,7 @@ hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0:
dependencies:
react-is "^16.7.0"

homebase-react@^0.5.1:
homebase-react@latest:
version "0.5.2"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.5.2.tgz#27dc72989921f79174584dc557a488a20b930543"
integrity sha512-cJNcmsEbDg0F/fhSkUfe3lJ/tqhgOk/rHE7iC6zoUah9xufuFfNTwaxaArqdyF4m3SxWASCA4DznKYXFUZs9vQ==
Expand Down
2 changes: 1 addition & 1 deletion examples/todo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"homebase-react": "^0.1.1",
"homebase-react": "latest",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.0",
Expand Down
7 changes: 3 additions & 4 deletions examples/todo/src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HomebaseProvider, useEntity, useQuery, useTransact } from 'homebase-react'
import React from 'react'
import { HomebaseProvider, useEntity, useTransact, useQuery } from 'homebase-react'
import './App.css'

export default function App() {
Expand All @@ -11,10 +11,9 @@ export default function App() {
}

const config = {
// Schema is only used to enforce
// Lookup helpers are used to enforce
// unique constraints and relationships.
// It is not a type system, yet.
schema: {
lookupHelpers: {
project: { name: { unique: 'identity' } },
todo: {
// refs are relationships
Expand Down
8 changes: 4 additions & 4 deletions examples/todo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5348,10 +5348,10 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"

homebase-react@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.1.1.tgz#13291d4b4dd294ed9d1f425eb773da17b803eedc"
integrity sha512-waiDZEAJoT2ozSXkqZftyLq7x5PNtKivWb19HCccgw9Cd96SVPxA6LLQ0rql5YAU4TG/6eVgCjtLZc8KI/QVWQ==
homebase-react@latest:
version "0.5.2"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.5.2.tgz#27dc72989921f79174584dc557a488a20b930543"
integrity sha512-cJNcmsEbDg0F/fhSkUfe3lJ/tqhgOk/rHE7iC6zoUah9xufuFfNTwaxaArqdyF4m3SxWASCA4DznKYXFUZs9vQ==

hoopy@^0.1.4:
version "0.1.4"
Expand Down
2 changes: 1 addition & 1 deletion examples/typescript-firebase-todo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@types/react-dom": "^16.9.8",
"firebase": "^8.1.1",
"firebaseui": "^4.7.1",
"homebase-react": "^0.3.9",
"homebase-react": "latest",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.0",
Expand Down
5 changes: 2 additions & 3 deletions examples/typescript-firebase-todo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ export default function App() {
declare const window: any;

const config = {
// Schema is only used to enforce
// Lookup helpers are used to enforce
// unique constraints and relationships.
// It is not a type system, yet.
schema: {
lookupHelpers: {
user: { uid: { unique: 'identity' } },
todo: {
// refs are relationships
Expand Down
8 changes: 4 additions & 4 deletions examples/typescript-firebase-todo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5821,10 +5821,10 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"

homebase-react@^0.3.9:
version "0.3.9"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.3.9.tgz#52bc4b3df131328818e86b6de54ef22ca087565f"
integrity sha512-rkFVL20wU0YcRf2/n0uKiAf+XJhUG6A1UkXbrJ9ibsFlVwLyeNN3MnT5WCmg/Q268rd9B3q88A2awb93uKgBLg==
homebase-react@latest:
version "0.5.2"
resolved "https://registry.yarnpkg.com/homebase-react/-/homebase-react-0.5.2.tgz#27dc72989921f79174584dc557a488a20b930543"
integrity sha512-cJNcmsEbDg0F/fhSkUfe3lJ/tqhgOk/rHE7iC6zoUah9xufuFfNTwaxaArqdyF4m3SxWASCA4DznKYXFUZs9vQ==

hoopy@^0.1.4:
version "0.1.4"
Expand Down
68 changes: 38 additions & 30 deletions src/dev/example/js/array.jsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
import React from 'react'

const { HomebaseProvider, useTransact, useEntity } = window.homebase.react

const config = {
schema: {
store: {
items: { type: 'ref', cardinality: 'many' }
lookupHelpers: {
store: {
items: { type: 'ref', cardinality: 'many' },
},
item: {
date: { type: 'ref', cardinality: 'one' },
},
item: {
date: { type: 'ref', cardinality: 'one' }
}
},
initialData: [{
store: {
identity: 'store 1',
items: [
{ item: { name: 'item 1' } },
{ item: { name: 'item 2' } },
{ item: { name: 'item 3' } },
{ item: { name: 'item 4' } },
{ item: { name: 'item 5', date: { year: 2021, month: 1, day: 3 } } },
]
}
}]
initialData: [
{
store: {
identity: 'store 1',
items: [
{ item: { name: 'item 1' } },
{ item: { name: 'item 2' } },
{ item: { name: 'item 3' } },
{ item: { name: 'item 4' } },
{ item: { name: 'item 5', date: { year: 2021, month: 1, day: 3 } } },
],
},
},
],
}

export const App = () => (
<HomebaseProvider config={config}>
<Items/>
<Items />
</HomebaseProvider>
)

Expand All @@ -35,30 +38,35 @@ const Items = () => {
const [transact] = useTransact()

let newI = null
const onDragOver = React.useCallback(e => {
const onDragOver = React.useCallback((e) => {
e.preventDefault()
newI = parseInt(e.target.dataset.index)
})

const reorder = React.useCallback((id, orderMin, orderMax) => {
const order = (orderMin + orderMax) / 2.0
transact([{'homebase.array': {id, order}}])
}, [transact])
const reorder = React.useCallback(
(id, orderMin, orderMax) => {
const order = (orderMin + orderMax) / 2.0
transact([{ 'homebase.array': { id, order } }])
},
[transact],
)

return (
<div>
{store.get('items').map((item, i) => (
<div
<div
key={item.get('ref', 'id')}
style={{ cursor: 'move' }}
data-index={i}
draggable
onDragOver={onDragOver}
onDragEnd={e => reorder(
item.get('id'),
newI > 0 && store.get('items', newI - 1, 'order') || 0,
store.get('items', newI, 'order'),
)}
onDragEnd={(e) =>
reorder(
item.get('id'),
(newI > 0 && store.get('items', newI - 1, 'order')) || 0,
store.get('items', newI, 'order'),
)
}
>
{item.get('ref', 'name')} &nbsp;
<small>{item.get('ref', 'date', 'year')}</small>
Expand Down
Loading

4 comments on commit 4a7b1f9

@vercel
Copy link

@vercel vercel bot commented on 4a7b1f9 Mar 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 4a7b1f9 Mar 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 4a7b1f9 Mar 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

homebase-example-todo – ./examples/todo

homebase-example-todo-git-master-homebaseio.vercel.app
homebase-example-todo.vercel.app
homebase-example-todo-homebaseio.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 4a7b1f9 Mar 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.