Skip to content

fix(dx): alias schema to lookup helpers #72

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
Mar 6, 2021
Merged
Show file tree
Hide file tree
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
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