# hummhive-react-web-data

Power your React site with public and/or encrypted members-only data from HummHive.

This package abstracts all the encryption, decryption, public/private key generation and HummHive data-bridge calls into a React Context Object that contains:

1. A HummHive state object
2. Actions to fetch or create data
3. A set of React Hooks to simplify usage of encrypted blob data.

## Installation

1. Install with `npm install @hummhive/react-web-data`

## Usage Examples

#### Using state

```javascript
import React, { useContext } from 'react';
import { HummContext } from '@hummhive/react-web-data';

const MyComponent = () => {
  const { state } = useContext(HummContext);

  return <h1>Hello {state.hive.name}</h1>;
};
```

#### Fetching state

```javascript
import React, { useEffect, useContext } from 'react';
import { HummContext } from '@hummhive/react-web-data';

const MyComponent = () => {
  const { state, actions } = useContext(HummContext);

  // fetch hive data when the component mounts
  useEffect(() => {
    if (!state.hive) actions.getHive();
  }, []);

  if (!state.hive) return <p>Loading...</p>;

  return <h1>Hello {state.hive.name}</h1>;
};
```

#### Joining a Hive

```javascript
import React, { useEffect, useContext, useState } from 'react';
import { HummContext } from '@hummhive/react-web-data';

const MyComponent = () => {
  const { state, actions } = useContext(HummContext);
  const [error, setError] = useState(null);

  const handleJoin = async () => {
    try {
      await actions.joinHive(state.hive, USERNAME, EMAIL, GROUP_ID);
    } catch (err) {
      setError(err.message);
    }
  };

  return <button onClick={handleJoin}>Join</button>;
};
```

## The State Object

```javascript
const { state } = useContext(HummContext);
```

The state object contains all the data you need to build a HummHive website.

| Name                | Type                                         | Notes                                                                                                            |
| ------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| isLoggedIn          | boolean                                      |
| memberStatus        | 'non-member' \| 'pending-member' \| 'member' |
| keySet              | MemberKeys                                   |
| keySetBase64        | MemberKeysBase64                             |
| secretKeyBase64     | string                                       | The base64 of the member encryption secret key byte array concatenated to the end of the signing key byte array. |
| hive                | Hive                                         |
| me                  | Member                                       |
| groups              | Array\<Group>                                | A list of groups available to join.                                                                              |
| isLoadingStoryIndex | Boolean                                      |                                                                                                                  |
| storyIndex          | Array\<StoryIndex>                           | An index of stories published using @honeyworks/editor                                                           |
| story               | Stories                                      | A map of stories published using @honeyworks/editor                                                              |
| loadingStories      | Array\<string>                               | A list of story IDs that are currently being fetched                                                             |

#### Types

```typescript
type Hive = {
  name: string;
  description: string;
  signingPublicKey: string;
  encryptionPublicKey: string;
  createdAt: string;
  updatedAt: string;
};

type Member = {
  id: string;
  email: string;
  username: string;
  hive: string;
  role: string;
  groups: Array<GroupMembership>;
  encryptionPublicKey: string;
  signingPublicKey: string;
  createdAt: string;
  updatedAt: string;
};

type GroupMembership = {
  expiration: string;
  groupId: string;
  intervalCount: bigint;
  joinedAt: string;
};

type Group = {
  id: string;
  name: string;
  description: string;
  amount: bigint;
  currency: string;
  interval: string;
  isActive: boolean;
};

type StoryIndex = {
  id: string;
  title: string;
  slug: string;
  createdAt: string;
  updatedAt: string;
  publishedAt: string;
  summary: string;
};

type Stories = {
  [storyId: string]: Story;
};
type Story = {
  id: string;
  title: string;
  slug: string;
  createdAt: string;
  updatedAt: string;
  publishedAt: string;
  summary: string;
};

type MemberKeys = {
  signing: KeyPair;
  encryption: KeyPair;
};

type KeyPair = {
  public: ByteArray;
  secret: ByteArray;
};

type ByteArray = Array<bigint>;

type MemberKeysBase64 = {
  signing: KeyPairBase64;
  encryption: KeyPairBase64;
};

type KeyPairBase64 = {
  public: string;
  secret: string;
};
```

## Actions

```javascript
const { actions } = useContext(HummContext);
```

The actions object contains all the functions you need in order to hydrate the state object, join a Hive, login and logout.

```typescript
getHive(): Promise<void>
```

```typescript
joinHive(hive: Hive, username: string, email: string, groupId: string): Promise<void>
```

```typescript
getMe(): Promise<void>
```

```typescript
getGroups(): Promise<void>
```

```typescript
login(base64KeySet: string): Promise<void>
```

```typescript
logout(): Promise<void>
```

```typescript
getStoryIndex(): Promise<void>
```

```typescript
getStory(id: string): Promise<void>
```

## Hooks

```javascript
import { HummHooks } from '@hummhive/react-web-data';
```

Currently the only available hook is `useBlob`. This handles the fetching and decryption of blobs within a component.

```typescript
useBlob(filename: string): { blob: DOMString, isLoading: boolean, error: string }
```
