https://github.com/nichoth/jazz-signals-v1
Use Jazz with preact signals
https://github.com/nichoth/jazz-signals-v1
Last synced: about 1 year ago
JSON representation
Use Jazz with preact signals
- Host: GitHub
- URL: https://github.com/nichoth/jazz-signals-v1
- Owner: nichoth
- License: agpl-3.0
- Created: 2023-08-30T03:31:09.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-09-28T19:44:49.000Z (almost 3 years ago)
- Last Synced: 2025-01-13T17:24:21.521Z (over 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 248 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
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;
localNode:Signal;
logoutCount:Signal;
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 ({
id,
localNode
}:{
id?:CoID,
localNode:Signal
}):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 (
{project.get('title')}
{tasks?.map((taskId: CoID) => {
// subscribe to each TODO list item
const [task] = useMemo(
() => telepathicSignal({ 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 (
-
{task?.get('done') ?
({task.get('text')}) :
({task.get('text')})
}
)
})}
)
}
```