Skip to content

Commit

Permalink
Merge pull request #22 from sep2/chore/format
Browse files Browse the repository at this point in the history
chore: format code
  • Loading branch information
johannes-lindgren authored Jan 23, 2025
2 parents a347f74 + a8b7340 commit 8ef2b9a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 70 deletions.
18 changes: 9 additions & 9 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ enableGlobalCache: false
nodeLinker: pnp

packageExtensions:
"@typescript-eslint/parser@*":
dependencies:
typescript: "*"
"@typescript-eslint/typescript-estree@*":
dependencies:
typescript: "*"
eslint-module-utils@*:
dependencies:
typescript: "*"
'@typescript-eslint/parser@*':
dependencies:
typescript: '*'
'@typescript-eslint/typescript-estree@*':
dependencies:
typescript: '*'
eslint-module-utils@*:
dependencies:
typescript: '*'

yarnPath: .yarn/releases/yarn-4.0.1.cjs
49 changes: 20 additions & 29 deletions packages/immer-yjs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,68 @@ All notable changes to this project will be documented in this file. See [standa

## 1.1.0 (2022-11-11)


### ⚠ BREAKING CHANGES

* update deps to latest
- update deps to latest

### Features

* add option to configure applyPatch ([41cb3e8](https://github.com/sep2/immer-yjs/commit/41cb3e8dd316bbfd19045aba2590ccb331be523d))
* export default bind ([e54e3cc](https://github.com/sep2/immer-yjs/commit/e54e3cca0a8df6971fbe821be00af3440bcd5b9e))

- add option to configure applyPatch ([41cb3e8](https://github.com/sep2/immer-yjs/commit/41cb3e8dd316bbfd19045aba2590ccb331be523d))
- export default bind ([e54e3cc](https://github.com/sep2/immer-yjs/commit/e54e3cca0a8df6971fbe821be00af3440bcd5b9e))

### Bug Fixes

* bundle badge ([a1c77dd](https://github.com/sep2/immer-yjs/commit/a1c77dded078b33e8f0c1507847052b21589b59d))
* handle replace array.length operation ([e4fbe7a](https://github.com/sep2/immer-yjs/commit/e4fbe7a17f311a7d885ed7e4a67ce854c8dafd1e))
* support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))

- bundle badge ([a1c77dd](https://github.com/sep2/immer-yjs/commit/a1c77dded078b33e8f0c1507847052b21589b59d))
- handle replace array.length operation ([e4fbe7a](https://github.com/sep2/immer-yjs/commit/e4fbe7a17f311a7d885ed7e4a67ce854c8dafd1e))
- support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))

* update deps to latest ([d53c096](https://github.com/sep2/immer-yjs/commit/d53c0969cf459423648e7dc723eae5a7c7826d70))
- update deps to latest ([d53c096](https://github.com/sep2/immer-yjs/commit/d53c0969cf459423648e7dc723eae5a7c7826d70))

## 1.0.0 (2022-04-27)

Bump to 1.0.0 because of this issue [standard-version#539](https://github.com/conventional-changelog/standard-version/issues/539)

### ⚠ BREAKING CHANGES

* update deps to latest
- update deps to latest

### Features

* add option to configure applyPatch ([41cb3e8](https://github.com/sep2/immer-yjs/commit/41cb3e8dd316bbfd19045aba2590ccb331be523d))
* export default bind ([e54e3cc](https://github.com/sep2/immer-yjs/commit/e54e3cca0a8df6971fbe821be00af3440bcd5b9e))

- add option to configure applyPatch ([41cb3e8](https://github.com/sep2/immer-yjs/commit/41cb3e8dd316bbfd19045aba2590ccb331be523d))
- export default bind ([e54e3cc](https://github.com/sep2/immer-yjs/commit/e54e3cca0a8df6971fbe821be00af3440bcd5b9e))

### Bug Fixes

* bundle badge ([a1c77dd](https://github.com/sep2/immer-yjs/commit/a1c77dded078b33e8f0c1507847052b21589b59d))
* support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))

- bundle badge ([a1c77dd](https://github.com/sep2/immer-yjs/commit/a1c77dded078b33e8f0c1507847052b21589b59d))
- support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))

* update deps to latest ([d53c096](https://github.com/sep2/immer-yjs/commit/d53c0969cf459423648e7dc723eae5a7c7826d70))
- update deps to latest ([d53c096](https://github.com/sep2/immer-yjs/commit/d53c0969cf459423648e7dc723eae5a7c7826d70))

### [0.1.4](https://github.com/sep2/immer-yjs/compare/v0.1.3...v0.1.4) (2022-03-17)


### Bug Fixes

* bundle badge ([a1c77dd](https://github.com/sep2/immer-yjs/commit/a1c77dded078b33e8f0c1507847052b21589b59d))
- bundle badge ([a1c77dd](https://github.com/sep2/immer-yjs/commit/a1c77dded078b33e8f0c1507847052b21589b59d))

### 0.1.3 (2022-03-08)


### Features

* add option to configure applyPatch ([41cb3e8](https://github.com/sep2/immer-yjs/commit/41cb3e8dd316bbfd19045aba2590ccb331be523d))
* export default bind ([e54e3cc](https://github.com/sep2/immer-yjs/commit/e54e3cca0a8df6971fbe821be00af3440bcd5b9e))

- add option to configure applyPatch ([41cb3e8](https://github.com/sep2/immer-yjs/commit/41cb3e8dd316bbfd19045aba2590ccb331be523d))
- export default bind ([e54e3cc](https://github.com/sep2/immer-yjs/commit/e54e3cca0a8df6971fbe821be00af3440bcd5b9e))

### Bug Fixes

* support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))
- support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))

### 0.1.2 (2022-03-08)


### Features

* add option to configure applyPatch ([d20b970](https://github.com/sep2/immer-yjs/commit/d20b970c4a75801230b3eb6094d290db62386e6d))
- add option to configure applyPatch ([d20b970](https://github.com/sep2/immer-yjs/commit/d20b970c4a75801230b3eb6094d290db62386e6d))

### 0.0.9 (2022-03-04)


### Bug Fixes

* support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))
- support mutating root type ([0a42efe](https://github.com/sep2/immer-yjs/commit/0a42efed8c2249d640d9bbcf4279fe3d555d7560))
1 change: 0 additions & 1 deletion packages/immer-yjs/readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# immer-yjs

[![npm](https://img.shields.io/npm/v/immer-yjs.svg)](https://www.npmjs.com/package/immer-yjs)
Expand Down
65 changes: 34 additions & 31 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,57 @@
Combine immer & y.js

# What is this

[immer](https://github.com/immerjs/immer) is a library for easy immutable data manipulation using plain json structure. [y.js](https://github.com/yjs/yjs) is a CRDT library with mutation-based API. `immer-yjs` allows manipulating `y.js` data types with the api provided by `immer`.

* Two-way binding between y.js and plain (nested) json object/array.
* Efficient snapshot update with structural sharing, same as `immer`.
* Updates to `y.js` are explicitly batched in transaction, you control the transaction boundary.
* Always opt-in, non-intrusive by nature (the snapshot is just a plain object after all).
* The snapshot shape & y.js binding aims to be fully customizable.
* Typescript all the way (pure js is also supported).
* Code is simple and small, no magic hidden behind, no vendor-locking.
- Two-way binding between y.js and plain (nested) json object/array.
- Efficient snapshot update with structural sharing, same as `immer`.
- Updates to `y.js` are explicitly batched in transaction, you control the transaction boundary.
- Always opt-in, non-intrusive by nature (the snapshot is just a plain object after all).
- The snapshot shape & y.js binding aims to be fully customizable.
- Typescript all the way (pure js is also supported).
- Code is simple and small, no magic hidden behind, no vendor-locking.

Do:

```js
// any operation supported by immer
update(state => {
update((state) => {
state.nested[0].key = {
id: 123,
p1: "a",
p2: ["a", "b", "c"],
p1: 'a',
p2: ['a', 'b', 'c'],
}
})
```

Instead of:

```js
Y.transact(state.doc, () => {
const val = new Y.Map()
val.set("id", 123)
val.set("p1", "a")
val.set('id', 123)
val.set('p1', 'a')

const arr = new Y.Array()
arr.push(["a", "b", "c"])
val.set("p2", arr)
arr.push(['a', 'b', 'c'])
val.set('p2', arr)

state.get("nested").get(0).set("key", val)
state.get('nested').get(0).set('key', val)
})
```


# Installation
`yarn add immer-yjs immer yjs`

`yarn add immer-yjs immer yjs`

# Documentation

1. `import { bind } from 'immer-yjs'`.
2. Create a binder: `const binder = bind(doc.getMap("state"))`.
3. Add subscription to the snapshot: `binder.subscribe(listener)`.
1. Mutations in `y.js` data types will trigger snapshot subscriptions.
2. Calling `update(...)` (similar to `produce(...)` in `immer`) will update their corresponding `y.js` types and also trigger snapshot subscriptions.
1. Mutations in `y.js` data types will trigger snapshot subscriptions.
2. Calling `update(...)` (similar to `produce(...)` in `immer`) will update their corresponding `y.js` types and also trigger snapshot subscriptions.
4. Call `binder.get()` to get the latest snapshot.
5. (Optionally) call `binder.unbind()` to release the observer.

Expand All @@ -62,12 +65,15 @@ Y.transact(state.doc, () => {
`Y.XmlElement` & `Y.Text` have no equivalent to json data types, so they are not supported by default. If you want to use them, please use the `y.js` top-level type (e.g. `doc.getText("xxx")`) directly, or see **Customize binding & schema** section below.

## With Vanilla Javascript/Typescript

πŸš€πŸš€πŸš€ [Please see the test for detailed usage.](https://github.com/sep2/immer-yjs/blob/main/packages/immer-yjs/src/immer-yjs.test.ts) πŸš€πŸš€πŸš€

## Customize binding & schema

Use the [`applyPatch` option](https://github.com/sep2/immer-yjs/blob/6b50fdfa85c9ca8ac850075bda7ef456337c7d55/packages/immer-yjs/src/immer-yjs.test.ts#L136) to customize it. Check the [discussion](https://github.com/sep2/immer-yjs/issues/1) for detailed background. **This section will likely be removed since it is not functioning properly. A new impl may be needed**

## Integration with React

By leveraging [useSyncExternalStoreWithSelector](https://github.com/reactwg/react-18/discussions/86).

```tsx
Expand All @@ -88,27 +94,22 @@ const binder = bind<State>(doc.getMap('data'))

// define a helper hook
function useImmerYjs<Selection>(selector: (state: State) => Selection) {
const selection = useSyncExternalStoreWithSelector(
binder.subscribe,
binder.get,
binder.get,
selector,
)
const selection = useSyncExternalStoreWithSelector(binder.subscribe, binder.get, binder.get, selector)

return [selection, binder.update]
}

// optionally set initial data
binder.update(state => {
state.nested = [{count: 0}]
binder.update((state) => {
state.nested = [{ count: 0 }]
})

// use in component
function Component() {
const [count, update] = useImmerYjs((s) => s.nested[0].count)

const handleClick = () => {
update(s => {
update((s) => {
// any operation supported by immer
s.nested[0].count++
})
Expand All @@ -123,17 +124,19 @@ binder.unbind()
```

## Integration with other frameworks
Please submit with sample code by PR, helps needed.

Please submit with sample code by PR, helps needed.

# Demos

Data will sync between multiple browser tabs automatically.
* [Messages Object](https://codesandbox.io/s/immer-yjs-demo-6e0znb)

- [Messages Object](https://codesandbox.io/s/immer-yjs-demo-6e0znb)

# Changelog
[Changelog](https://github.com/sep2/immer-yjs/blob/main/packages/immer-yjs/CHANGELOG.md)

[Changelog](https://github.com/sep2/immer-yjs/blob/main/packages/immer-yjs/CHANGELOG.md)

# Similar projects

[valtio-yjs](https://github.com/dai-shi/valtio-yjs)

0 comments on commit 8ef2b9a

Please sign in to comment.