# @nichoth/jazz-signals

> An example of Jazz + preact signals

Latest version **0.0.6** (published 2023-09-28) · ISC license · 0 weekly downloads

## Install

```sh
npm install @nichoth/jazz-signals
pnpm add @nichoth/jazz-signals
yarn add @nichoth/jazz-signals
bun add @nichoth/jazz-signals
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.6 |
| Published | 2023-09-28 |
| First published | 2023-09-01 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 8 |
| Unpacked size | 183.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | nichoth |
| Maintainers | nichoth |
| Keywords | jazz, preact, signals |

## Links

- npm: https://www.npmjs.com/package/@nichoth/jazz-signals
- Repository: https://github.com/nichoth/jazz-signals
- Homepage: https://github.com/nichoth/jazz-signals#readme
- Issues: https://github.com/nichoth/jazz-signals/issues
- npm.io page: https://npm.io/package/@nichoth/jazz-signals

## Dependencies (8)

- [cojson](https://npm.io/package/cojson.md) 0.2.2
- [route-event](https://npm.io/package/route-event.md) 4.1.10
- [jazz-browser](https://npm.io/package/jazz-browser.md) 0.2.0
- [clipboard-copy](https://npm.io/package/clipboard-copy.md) 4.0.1
- [@nichoth/events](https://npm.io/package/@nichoth/events.md) 3.1.6
- [@nichoth/routes](https://npm.io/package/@nichoth/routes.md) 3.0.7
- [@preact/signals](https://npm.io/package/@preact/signals.md) ^1.2.1
- [jazz-browser-auth-local](https://npm.io/package/jazz-browser-auth-local.md) 0.2.0

## Recent versions

- 0.0.6 (latest) — 2023-09-28
- 0.0.5 — 2023-09-28
- 0.0.4 — 2023-09-28
- 0.0.3 — 2023-09-03
- 0.0.0 — 2023-09-01

## README

# jazz signals
A library to help use [Jazz](https://jazz.tools/) with [preact signals](https://preactjs.com/blog/introducing-signals/).

## install
```bash
npm i -S @nichoth/jazz-signals
```

## develop
Start a local vite server

```bash
npm start
```

## API

### localAuth
Import a function `localAuth` that helps with authentication, and has a property `createState` that returns observable state. This will create and return a signal of a `localNode`, the object used for persistence/`telepathicState`.

```js
import { localAuth } from '@nichoth/jazz-signals'
```

### localAuth.createState
Create a state object that includes signals.

```ts
export interface LocalAuthState {
    authStatus:Signal<AuthStatus>;
    localNode:Signal<LocalNode|null>;
    logoutCount:Signal<number>;
    syncAddress?:string;
}

localAuth.createState = function ():LocalAuthState
```

The returned state object should be passed into the `localAuth` function. See an example [in the example app](https://github.com/nichoth/jazz-signals/blob/main/example/todo-app.tsx#L27).

The signals returned are plain signals; you [would want to wrap them in a call to `useMemo`](https://preactjs.com/guide/v10/signals/#local-state-with-signals) if you use them in a view component.

```ts
function localAuth (
    appName:string,
    appHostname:string|undefined,
    opts:LocalAuthState
):() => void
```

This will create a new [BrowserLocalAuth](https://github.com/gardencmp/jazz/tree/fe1092ccf639d5cdb5013056d1184a415af826d0/packages/jazz-browser-auth-local), and mutate the signals passed in as `opts:LocalAuthState`. The return value is a function that will unsubscribe from `BrowserLocalAuth`. See [the example](https://github.com/nichoth/jazz-signals/blob/main/example/todo-app.tsx#L76) for a demonstration of how the unsubscribe function can be used.

To check if you are logged in, look for the `authStatus.value.logout` property. If `.logout` exists, then you are logged in. Call `authStatus.value.signUp` or `authStatus.value.signIn` to handle creating an account and logging in, respectively. See [an example of handling auth](https://github.com/nichoth/jazz-signals/blob/main/example/state.ts#L130).


### telepathicSignal 
```ts
function telepathicSignal<T extends CoValueImpl> ({
    id,
    localNode
}:{
    id?:CoID<T>,
    localNode:Signal<LocalNode|null>
}):Signal<[ T|null, (()=>void)|null ]> {
```

-------

## example

### localAuth
An example of an application that consumes this package is in the [example directory](https://github.com/nichoth/jazz-signals/tree/main/example).

Create a localNode by mutating the signals that are passed in. Signals are created by `localNode.createState`.

You should create a state object first with `localAuth.createState`, then pass the state to `localAuth`.

```js
import { localAuth } from '@nichoth/jazz-signals'
import { useEffect, useMemo } from 'preact/hooks'

function MyComponent ({ appHostName, syncAddress, appName }) {
    const state = useMemo(() => localAuth.createState(), [])
    const { localNode } = state  // <-- a signal for our localNode

    /**
     * Handle auth, create a node
     */
    useEffect(() => {
        let unlisten:()=>void = () => null

        localAuth(appName, appHostName, { ...state }).then(_unlisten => {
            unlisten = _unlisten
        })

        return unlisten
    }, [appName, appHostName, syncAddress, logoutCount.value])
}
```

### telepathicSignal
Create a new signal that is subscribed to any changes from the `cojson`
object referenced by the given `id`.

```js
import { telepathicSignal } from '@nichoth/jazz-signals'

const mySignal = telepathicSignal({
    id: 'co_zPLDBXZD5UuZtYGzpqAvgAAHhs4',
    localNode
})
```

```jsx
import { telepathicSignal } from '@nichoth/jazz-signals'
import { useMemo } from 'preact/hooks'

function Component () {
    const projectSignal = useMemo(() => {
        return telepathicSignal({
            // get the `id` from the URL or something
            id: 'co_zPLDBXZD5UuZtYGzpqAvgAAHhs4',
            localNode  // <-- here we consume the localNode we created earlier
        })
    }, [params.id, localNode.value])

    const [project] = projectSignal.value

    // get tasks (the list of things to do)
    // this is where we subscribe to task changes
    const tasksSignal = useMemo(() => {
        if (!project) return signal([])
        // we depend on the 'tasks' key existing.
        const tasksId = project.get('tasks')

        return telepathicSignal({ id: tasksId, localNode })
    }, [project, localNode.value])

    const [tasks] = tasksSignal.value

    return (<div>
        <h2>{project.get('title')}</h2>

        <ul className="todo-list">
            {tasks?.map((taskId: CoID<Task>) => {
                // subscribe to each TODO list item
                const [task] = useMemo(
                    () => telepathicSignal<Task>({ id: taskId, localNode }),
                    [taskId, localNode.value]
                ).value

                // The view will re-render when the task updates.
                // This is magically in sync with multiple devices.
                // You can create an invitation for a second device, and changes
                // will automatically be visible in both places.
                return (<li key={taskId}>
                    {task?.get('done') ?
                        (<s>{task.get('text')}</s>) :
                        (<span>{task.get('text')}</span>)
                    }
                </li>)
            })}
        </ul>
    </div>)
}
```

---
_Source: https://npm.io/package/@nichoth/jazz-signals · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
