Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/earthstar-project/react-earthstar

A UI toolkit for making collaborative, offline-first applets for small groups.
https://github.com/earthstar-project/react-earthstar

decentralized earthstar react

Last synced: 3 months ago
JSON representation

A UI toolkit for making collaborative, offline-first applets for small groups.

Awesome Lists containing this project

README

        

# react-earthstar

## What is this?

A library of React hooks and components for usage with
[Earthstar](https://earthstar-project.org), storage for private, distributed,
offline-first application.

This library is just a few small hooks for subscribing to some events in
Earthstar, with the same API for querying and writing data.

It's recommended that you check out Earthstar's
[README](https://github.com/earthstar-project/earthstar) before reading on if
you haven't already.

## Getting started

First, install `react-earthstar` and `earthstar` as dependencies to your
project:

```
npm install earthstar react-earthstar
```

Here's a basic applet which creates a IndexedDB replica for a `+gardening`
share, and renders a list of notes using `useReplica`.

```jsx
import * as Earthstar from "earthstar";
import { useReplica } from 'react-earthstar';

// You get the share address and secret from someone else,
// Or using Earthstar.Crypto.generateShareKeypair()

const MY_SHARE_ADDRESS =
"+gardening.bhyux4opeug2ieqcy36exrf4qymc56adwll4zeazm42oamxtr7heq";

const MY_SHARE_SECRET = "buaqth6jr5wkksnhdlpfi64cqcnjzfx3r6cssnfqdvitjmfygsk3q";

const replica = new Earthstar.Replica({
driver: new ReplicaDriverWeb(MY_SHARE_ADDRESS),
shareSecret: MY_SHARE_SECRET,
});

function App() {
const cache = useReplica(replica);

// This will update whenever a document with a path starting with '/notes' updates.
const notes = cache.queryDocs({
filter: {
pathStartsWith: "/notes",
author:
},
});

return (


My notes


{ notes.map((noteDoc) =>
  • noteDoc.text

  • )}


    );
    }
    ```

    ## Hooks

    ### `useReplica`

    This is the workhorse of the library, used for querying documents from replicas.

    ```js
    const replica = useReplica(myReplica);

    const txtDocs = replica.queryDocs({ filter: { pathEndsWith: ".txt" } });
    ```

    This hook returns an instance of Earthstar's
    [`ReplicaCache` class](https://doc.deno.land/https://deno.land/x/[email protected]/mod.ts/~/ReplicaCache),
    with the exact same API as `Replica` except synchronous.

    When you query docs the replica keeps track of what was queried for, and only
    updates React when the results of those queries are updated. This results in a
    best-of-both-worlds API where we can have the same API as the vanilla Earthstar
    library, and components which only re-render when they need to. Nice!

    ### `usePeerReplicas`

    Returns an updating array of `Replica` for a given `Peer`.

    ```js
    function ReplicaList() {
    const replicas = usePeerReplicas(myPeer);

    return (


    My replicas



      {replicas.map((replica) =>
    • {replica.share}
    • )}


    );
    }
    ```

    ### `useAuthorSettings`

    Returns a getter and setter for the `SharedSettings`' current author setting.
    Uses the `SharedSettingsContext`.

    ```js
    function CurrentAuthorAddress() {
    const [author, setAuthor] = useAuthorSettings();

    return

    {author.address}
    ;
    }
    ```

    ### `useShareSettings`

    Returns the shares + a callback to add a share + a callback to remove a share
    from `SharedSettings`' shares setting. Uses the `SharedSettingsContext`.

    ```js
    function KnownShares() {
    const [shares, addShare, removeShare] = useAuthorSettings();

    return (


    My shares



      {shares.map((share) =>
    • {share}
    • )}


    );
    }
    ```

    ### `useShareSecretSettings`

    Returns the secrets + a callback to add a secret + a callback to remove a secret
    from `SharedSettings`' share secrets setting. Uses the `SharedSettingsContext`.

    ```js
    function KnownSecrets() {
    const [secrets, addSecret, removeSecret] = useAuthorSettings();

    return (


    Known secrets...p



      {Object.keys(secrets).map((share) => (
    • {share} {secrets["share"] ? "✓" : "???"}

    • ))}


    );
    }
    ```

    ### `useServerSettings`

    Returns the server + a callback to add a server + a callback to remove a server
    from `SharedSettings`' servers setting. Uses the `SharedSettingsContext`.

    ```js
    function KnownShares() {
    const [servers, addServer, removeServer] = useAuthorSettings();

    return (


    My servers



      {servers.map((share) =>
    • {server}
    • )}


    );
    }
    ```

    ## Components

    ### ``

    If you're going to use any of the settings hooks, you should provide a single
    instance of `SharedSettings` as a context for them:

    ```js
    const settings = new Earthstar.SharedSettings();

    function App() {
    return (

    // Components which use useAuthorSettings, useShareSettings etc.


    );
    }
    ```

    ### ``

    Renders the human readable portion of a share address, and omits the public key:
    e.g. '+gardening.bhyux4opeug2ieqcy36exrf4qymc56adwll4zeazm42oamxtr7heq' becomes
    '+gardening'. Also renders an identicon next to the address to make it harder
    for shares to be mistaken for one another. Good for making sure you don't
    disclose share addresses to people looking over your users' shoulders.

    ```jsx

    ```

    Also takes an `iconSize` prop (side size in `px`), and a `viewingAuthorSecret`
    prop. The latter prop is used as a salt for generating the identicon, making it
    so that each user has their own identicon for each share, making them harder for
    an attacker to imitate. If available, pass the current user's keypair secret to
    this prop.

    ### ``

    Renders the shortname portion of an identity's address, omitting the public key,
    e.g. `@cinn.euu8euheuigoe...` just becomes `@cinn`.

    ```jsx

    ```

    Also takes an `iconSize` prop (side size in `px`), and a `viewingAuthorSecret`
    prop. The latter prop is used as a salt for generating the identicon, making it
    so that each user has their own identicon for each share, making them harder for
    an attacker to imitate. If available, pass the current user's keypair secret to
    this prop.