@automerge/automerge-repo-solid-primitives 2.5.4 → 2.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/createDocSignal.d.ts +10 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +33 -2
- package/dist/index.js.map +1 -1
- package/dist/makeDocSignal.d.ts +10 -0
- package/dist/useDocSignal.d.ts +10 -0
- package/package.json +3 -3
- package/readme.md +54 -0
- package/src/createDocSignal.ts +33 -0
- package/src/index.ts +3 -0
- package/src/makeDocSignal.ts +24 -0
- package/src/useDocSignal.ts +22 -0
- package/test/useDocSignal.test.tsx +302 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Accessor } from 'solid-js';
|
|
2
|
+
import { Doc, DocHandle } from '@automerge/automerge-repo/slim';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* a light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
6
|
+
* and not _how_.
|
|
7
|
+
* @param handle an Automerge
|
|
8
|
+
* [DocHandle](https://automerge.org/automerge-repo/classes/_automerge_automerge_repo.DocHandle.html)
|
|
9
|
+
*/
|
|
10
|
+
export default function makeDocSignal<T extends object>(handle: DocHandle<T>): Accessor<Doc<T> | undefined>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AutomergeUrl, Doc, DocHandle } from '@automerge/automerge-repo/slim';
|
|
2
|
+
import { MaybeAccessor, UseDocHandleOptions } from './types.js';
|
|
3
|
+
import { Accessor, Resource } from 'solid-js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* a light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
7
|
+
* and not _how_. returns [doc, handle] from a URL.
|
|
8
|
+
* @param url a function that returns a url
|
|
9
|
+
*/
|
|
10
|
+
export default function useDocSignal<T extends object>(url: MaybeAccessor<AutomergeUrl | undefined>, options?: UseDocHandleOptions): [Accessor<Doc<T> | undefined>, Resource<DocHandle<T> | undefined>];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo-solid-primitives",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.6",
|
|
4
4
|
"description": "Access Automerge Repo in your SolidJS application",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@automerge/automerge": "3.0.0",
|
|
17
|
-
"@automerge/automerge-repo": "2.5.
|
|
17
|
+
"@automerge/automerge-repo": "2.5.6",
|
|
18
18
|
"@solidjs/testing-library": "^0.8.10",
|
|
19
19
|
"@testing-library/jest-dom": "^6.6.3",
|
|
20
20
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
]
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "38d06b9d9ef0bbe1e0693d3b859015f38897f34b"
|
|
47
47
|
}
|
package/readme.md
CHANGED
|
@@ -75,6 +75,60 @@ const doc = makeDocumentProjection<{ items: { title: string }[] }>(handle)
|
|
|
75
75
|
return <h1>{doc.items[1].title}</h1>
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
## useDocSignal
|
|
79
|
+
|
|
80
|
+
A light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
81
|
+
and not _how_. Returns `[doc, handle]`.
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
useDocSignal<T>(
|
|
85
|
+
() => AutomergeURL,
|
|
86
|
+
options?: {repo: Repo}
|
|
87
|
+
): [Accessor<Doc<T>>, Resource<DocHandle<T>>]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// example
|
|
92
|
+
const [url, setURL] = createSignal<AutomergeUrl>(props.url)
|
|
93
|
+
const [doc, handle] = useDocSignal(url, { repo })
|
|
94
|
+
|
|
95
|
+
const inc = () => handle()?.change(d => d.count++)
|
|
96
|
+
return <button onclick={inc}>{doc()?.count}</button>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The `{repo}` option can be left out if you are using [RepoContext](#repocontext).
|
|
100
|
+
|
|
101
|
+
## createDocSignal
|
|
102
|
+
|
|
103
|
+
A light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
104
|
+
and not _how_. Takes a signal `DocHandle`.
|
|
105
|
+
|
|
106
|
+
Underlying primitive for [`useDocSignal`](#usedocsignal).
|
|
107
|
+
|
|
108
|
+
Works with [`useDocHandle`](#usedochandle).
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
createDocSignal<T>(() => DocHandle<T>): Accessor<Doc<T>>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## makeDocSignal
|
|
115
|
+
|
|
116
|
+
Just like `createDocSignal`, but without a reactive input.
|
|
117
|
+
|
|
118
|
+
Underlying primitive for [`createDocSignal`](#createdocsignal).
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
makeDocSignal<T>(handle: DocHandle<T>): Accessor<Doc<T>>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
// example
|
|
126
|
+
const handle = repo.find(url)
|
|
127
|
+
const doc = makeDocSignal<{ count: number }>(handle)
|
|
128
|
+
|
|
129
|
+
return <span>{doc()?.count}</span>
|
|
130
|
+
```
|
|
131
|
+
|
|
78
132
|
## useDocHandle
|
|
79
133
|
|
|
80
134
|
Get a [DocHandle](https://automerge.org/docs/repositories/dochandles/) from the
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createEffect, onCleanup, type Accessor } from "solid-js"
|
|
2
|
+
import { createSignal } from "solid-js"
|
|
3
|
+
import type { Doc, DocHandle } from "@automerge/automerge-repo/slim"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* a light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
7
|
+
* and not _how_. works with {@link useDocHandle}.
|
|
8
|
+
* @param handle an accessor (signal/resource) of a
|
|
9
|
+
* [DocHandle](https://automerge.org/automerge-repo/classes/_automerge_automerge_repo.DocHandle.html)
|
|
10
|
+
*/
|
|
11
|
+
export default function createDocSignal<T extends object>(
|
|
12
|
+
handle: Accessor<DocHandle<T> | undefined>
|
|
13
|
+
): Accessor<Doc<T> | undefined> {
|
|
14
|
+
const [signal, setSignal] = createSignal<Doc<T> | undefined>(handle()?.doc())
|
|
15
|
+
|
|
16
|
+
createEffect(() => {
|
|
17
|
+
const h = handle()
|
|
18
|
+
|
|
19
|
+
function update() {
|
|
20
|
+
setSignal(() => h?.doc() as Doc<T> | undefined)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// sync the signal with the current handle's doc
|
|
24
|
+
update()
|
|
25
|
+
|
|
26
|
+
if (h) {
|
|
27
|
+
h.on("change", update)
|
|
28
|
+
onCleanup(() => h.off("change", update))
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
return signal
|
|
33
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,5 +3,8 @@ export { default as useDocument } from "./useDocument.js"
|
|
|
3
3
|
export { default as useDocHandle } from "./useDocHandle.js"
|
|
4
4
|
export { default as makeDocumentProjection } from "./makeDocumentProjection.js"
|
|
5
5
|
export { default as createDocumentProjection } from "./createDocumentProjection.js"
|
|
6
|
+
export { default as makeDocSignal } from "./makeDocSignal.js"
|
|
7
|
+
export { default as createDocSignal } from "./createDocSignal.js"
|
|
8
|
+
export { default as useDocSignal } from "./useDocSignal.js"
|
|
6
9
|
export { default as useRepo } from "./useRepo.js"
|
|
7
10
|
export { RepoContext } from "./context.js"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { onCleanup, type Accessor } from "solid-js"
|
|
2
|
+
import { createSignal } from "solid-js"
|
|
3
|
+
import type { Doc, DocHandle } from "@automerge/automerge-repo/slim"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* a light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
7
|
+
* and not _how_.
|
|
8
|
+
* @param handle an Automerge
|
|
9
|
+
* [DocHandle](https://automerge.org/automerge-repo/classes/_automerge_automerge_repo.DocHandle.html)
|
|
10
|
+
*/
|
|
11
|
+
export default function makeDocSignal<T extends object>(
|
|
12
|
+
handle: DocHandle<T>
|
|
13
|
+
): Accessor<Doc<T> | undefined> {
|
|
14
|
+
const [signal, setSignal] = createSignal<Doc<T> | undefined>(handle.doc())
|
|
15
|
+
|
|
16
|
+
function update() {
|
|
17
|
+
setSignal(() => handle.doc() as Doc<T> | undefined)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
handle.on("change", update)
|
|
21
|
+
onCleanup(() => handle.off("change", update))
|
|
22
|
+
|
|
23
|
+
return signal
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AutomergeUrl,
|
|
3
|
+
Doc,
|
|
4
|
+
DocHandle,
|
|
5
|
+
} from "@automerge/automerge-repo/slim"
|
|
6
|
+
import useDocHandle from "./useDocHandle.js"
|
|
7
|
+
import createDocSignal from "./createDocSignal.js"
|
|
8
|
+
import type { MaybeAccessor, UseDocHandleOptions } from "./types.js"
|
|
9
|
+
import type { Accessor, Resource } from "solid-js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* a light coarse-grained primitive when you care only _that_ a doc has changed,
|
|
13
|
+
* and not _how_. returns [doc, handle] from a URL.
|
|
14
|
+
* @param url a function that returns a url
|
|
15
|
+
*/
|
|
16
|
+
export default function useDocSignal<T extends object>(
|
|
17
|
+
url: MaybeAccessor<AutomergeUrl | undefined>,
|
|
18
|
+
options?: UseDocHandleOptions
|
|
19
|
+
): [Accessor<Doc<T> | undefined>, Resource<DocHandle<T> | undefined>] {
|
|
20
|
+
const handle = useDocHandle<T>(url, options)
|
|
21
|
+
return [createDocSignal<T>(handle), handle] as const
|
|
22
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { type PeerId, Repo, type AutomergeUrl } from "@automerge/automerge-repo"
|
|
2
|
+
import { renderHook, testEffect } from "@solidjs/testing-library"
|
|
3
|
+
import { describe, expect, it, vi } from "vitest"
|
|
4
|
+
import { RepoContext } from "../src/context.js"
|
|
5
|
+
import { createEffect, createSignal, type ParentComponent } from "solid-js"
|
|
6
|
+
import useDocSignal from "../src/useDocSignal.js"
|
|
7
|
+
|
|
8
|
+
interface ExampleDoc {
|
|
9
|
+
key: string
|
|
10
|
+
array: number[]
|
|
11
|
+
nested: { title: string }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe("useDocSignal", () => {
|
|
15
|
+
function setup() {
|
|
16
|
+
const repo = new Repo({
|
|
17
|
+
peerId: "bob" as PeerId,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const create = () =>
|
|
21
|
+
repo.create<ExampleDoc>({
|
|
22
|
+
key: "value",
|
|
23
|
+
array: [1, 2, 3],
|
|
24
|
+
nested: { title: "hello" },
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const wrapper: ParentComponent = props => {
|
|
28
|
+
return (
|
|
29
|
+
<RepoContext.Provider value={repo}>
|
|
30
|
+
{props.children}
|
|
31
|
+
</RepoContext.Provider>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
repo,
|
|
37
|
+
wrapper,
|
|
38
|
+
create,
|
|
39
|
+
options: { repo },
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
it("should return the initial document value", async () => {
|
|
44
|
+
const { create, options } = setup()
|
|
45
|
+
|
|
46
|
+
await testEffect(done => {
|
|
47
|
+
const [doc] = useDocSignal<ExampleDoc>(create().url, options)
|
|
48
|
+
createEffect((run: number = 0) => {
|
|
49
|
+
if (run == 0) {
|
|
50
|
+
expect(doc()?.key).toBe("value")
|
|
51
|
+
done()
|
|
52
|
+
}
|
|
53
|
+
return run + 1
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("should notify on a property change", async () => {
|
|
59
|
+
const { create, options } = setup()
|
|
60
|
+
|
|
61
|
+
await testEffect(done => {
|
|
62
|
+
const [doc, handle] = useDocSignal<ExampleDoc>(create().url, options)
|
|
63
|
+
createEffect((run: number = 0) => {
|
|
64
|
+
if (run == 0) {
|
|
65
|
+
expect(doc()?.key).toBe("value")
|
|
66
|
+
handle()?.change(doc => (doc.key = "hello world!"))
|
|
67
|
+
} else if (run == 1) {
|
|
68
|
+
expect(doc()?.key).toBe("hello world!")
|
|
69
|
+
handle()?.change(doc => (doc.key = "friday night!"))
|
|
70
|
+
} else if (run == 2) {
|
|
71
|
+
expect(doc()?.key).toBe("friday night!")
|
|
72
|
+
done()
|
|
73
|
+
}
|
|
74
|
+
return run + 1
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("should return the handle as the second element", async () => {
|
|
80
|
+
const { create, options } = setup()
|
|
81
|
+
const created = create()
|
|
82
|
+
|
|
83
|
+
await testEffect(done => {
|
|
84
|
+
const [, handle] = useDocSignal<ExampleDoc>(created.url, options)
|
|
85
|
+
createEffect((run: number = 0) => {
|
|
86
|
+
if (run == 0) {
|
|
87
|
+
expect(handle()).not.toBe(undefined)
|
|
88
|
+
expect(handle()?.url).toBe(created.url)
|
|
89
|
+
done()
|
|
90
|
+
}
|
|
91
|
+
return run + 1
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it("should update when an array element changes", async () => {
|
|
97
|
+
const { create, options } = setup()
|
|
98
|
+
|
|
99
|
+
await testEffect(done => {
|
|
100
|
+
const [doc, handle] = useDocSignal<ExampleDoc>(create().url, options)
|
|
101
|
+
createEffect((run: number = 0) => {
|
|
102
|
+
if (run == 0) {
|
|
103
|
+
expect(doc()?.array).toEqual([1, 2, 3])
|
|
104
|
+
handle()?.change(doc => doc.array.push(4))
|
|
105
|
+
} else if (run == 1) {
|
|
106
|
+
expect(doc()?.array).toEqual([1, 2, 3, 4])
|
|
107
|
+
done()
|
|
108
|
+
}
|
|
109
|
+
return run + 1
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it("should update when a nested property changes", async () => {
|
|
115
|
+
const { create, options } = setup()
|
|
116
|
+
|
|
117
|
+
await testEffect(done => {
|
|
118
|
+
const [doc, handle] = useDocSignal<ExampleDoc>(create().url, options)
|
|
119
|
+
createEffect((run: number = 0) => {
|
|
120
|
+
if (run == 0) {
|
|
121
|
+
expect(doc()?.nested.title).toBe("hello")
|
|
122
|
+
handle()?.change(doc => (doc.nested.title = "world"))
|
|
123
|
+
} else if (run == 1) {
|
|
124
|
+
expect(doc()?.nested.title).toBe("world")
|
|
125
|
+
done()
|
|
126
|
+
}
|
|
127
|
+
return run + 1
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it("should work with a signal url", async () => {
|
|
133
|
+
const { create, wrapper } = setup()
|
|
134
|
+
const [url, setURL] = createSignal<AutomergeUrl>()
|
|
135
|
+
const {
|
|
136
|
+
result: [doc, handle],
|
|
137
|
+
owner,
|
|
138
|
+
} = renderHook(useDocSignal<ExampleDoc>, {
|
|
139
|
+
initialProps: [url],
|
|
140
|
+
wrapper,
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const done = testEffect(done => {
|
|
144
|
+
createEffect((run: number = 0) => {
|
|
145
|
+
if (run == 0) {
|
|
146
|
+
expect(doc()).toBeUndefined()
|
|
147
|
+
setURL(create().url)
|
|
148
|
+
} else if (run == 1) {
|
|
149
|
+
expect(doc()?.key).toBe("value")
|
|
150
|
+
handle()?.change(doc => (doc.key = "hello world!"))
|
|
151
|
+
} else if (run == 2) {
|
|
152
|
+
expect(doc()?.key).toBe("hello world!")
|
|
153
|
+
setURL(create().url)
|
|
154
|
+
} else if (run == 3) {
|
|
155
|
+
expect(doc()?.key).toBe("value")
|
|
156
|
+
done()
|
|
157
|
+
}
|
|
158
|
+
return run + 1
|
|
159
|
+
})
|
|
160
|
+
}, owner!)
|
|
161
|
+
return done
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it("should clear the signal when the url returns to nothing", async () => {
|
|
165
|
+
const { create, options } = setup()
|
|
166
|
+
const [url, setURL] = createSignal<AutomergeUrl>()
|
|
167
|
+
|
|
168
|
+
const done = testEffect(done => {
|
|
169
|
+
const [doc, handle] = useDocSignal<ExampleDoc>(url, options)
|
|
170
|
+
createEffect((run: number = 0) => {
|
|
171
|
+
if (run == 0) {
|
|
172
|
+
expect(handle()).toBe(undefined)
|
|
173
|
+
setURL(create().url)
|
|
174
|
+
} else if (run == 1) {
|
|
175
|
+
expect(doc()?.key).toBe("value")
|
|
176
|
+
expect(handle()).not.toBe(undefined)
|
|
177
|
+
setURL(undefined)
|
|
178
|
+
} else if (run == 2) {
|
|
179
|
+
expect(handle()).toBe(undefined)
|
|
180
|
+
setURL(create().url)
|
|
181
|
+
} else if (run == 3) {
|
|
182
|
+
expect(doc()?.key).toBe("value")
|
|
183
|
+
expect(handle()).not.toBe(undefined)
|
|
184
|
+
done()
|
|
185
|
+
}
|
|
186
|
+
return run + 1
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
return done
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it("should work without a context if given a repo in options", async () => {
|
|
193
|
+
const { create, repo } = setup()
|
|
194
|
+
|
|
195
|
+
await testEffect(done => {
|
|
196
|
+
const [doc] = useDocSignal<ExampleDoc>(create().url, { repo })
|
|
197
|
+
createEffect((run: number = 0) => {
|
|
198
|
+
if (run == 0) {
|
|
199
|
+
expect(doc()?.key).toBe("value")
|
|
200
|
+
done()
|
|
201
|
+
}
|
|
202
|
+
return run + 1
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it("should be coarse-grained: any change triggers re-read of the whole doc", async () => {
|
|
208
|
+
const { create, options } = setup()
|
|
209
|
+
|
|
210
|
+
const signalFn = vi.fn()
|
|
211
|
+
|
|
212
|
+
await testEffect(done => {
|
|
213
|
+
const [doc, handle] = useDocSignal<ExampleDoc>(create().url, options)
|
|
214
|
+
createEffect((run: number = 0) => {
|
|
215
|
+
signalFn(doc()?.key, doc()?.array)
|
|
216
|
+
if (run == 0) {
|
|
217
|
+
expect(doc()?.key).toBe("value")
|
|
218
|
+
expect(doc()?.array).toEqual([1, 2, 3])
|
|
219
|
+
// Change only the array — should still trigger the signal
|
|
220
|
+
handle()?.change(doc => doc.array.push(4))
|
|
221
|
+
} else if (run == 1) {
|
|
222
|
+
// The whole doc is refreshed, so we see the array change
|
|
223
|
+
expect(doc()?.array).toEqual([1, 2, 3, 4])
|
|
224
|
+
// key remains unchanged
|
|
225
|
+
expect(doc()?.key).toBe("value")
|
|
226
|
+
// Now change only the key
|
|
227
|
+
handle()?.change(doc => (doc.key = "updated"))
|
|
228
|
+
} else if (run == 2) {
|
|
229
|
+
expect(doc()?.key).toBe("updated")
|
|
230
|
+
expect(doc()?.array).toEqual([1, 2, 3, 4])
|
|
231
|
+
done()
|
|
232
|
+
}
|
|
233
|
+
return run + 1
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
// The signal callback should have been called 3 times (once per run)
|
|
238
|
+
expect(signalFn).toHaveBeenCalledTimes(3)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
it("should work with a slow handle", async () => {
|
|
242
|
+
const { repo } = setup()
|
|
243
|
+
|
|
244
|
+
const slowHandle = repo.create({
|
|
245
|
+
key: "slow",
|
|
246
|
+
array: [],
|
|
247
|
+
nested: { title: "slow" },
|
|
248
|
+
})
|
|
249
|
+
const originalFind = repo.find.bind(repo)
|
|
250
|
+
repo.find = vi.fn().mockImplementation(async (...args) => {
|
|
251
|
+
await new Promise(resolve => setTimeout(resolve, 100))
|
|
252
|
+
// @ts-expect-error i'm ok i promise
|
|
253
|
+
return await originalFind(...args)
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
const done = testEffect(done => {
|
|
257
|
+
const [doc] = useDocSignal<ExampleDoc>(() => slowHandle.url, {
|
|
258
|
+
repo,
|
|
259
|
+
"~skipInitialValue": true,
|
|
260
|
+
})
|
|
261
|
+
createEffect((run: number = 0) => {
|
|
262
|
+
if (run == 0) {
|
|
263
|
+
expect(doc()?.key).toBeUndefined()
|
|
264
|
+
} else if (run == 1) {
|
|
265
|
+
expect(doc()?.key).toBe("slow")
|
|
266
|
+
done()
|
|
267
|
+
}
|
|
268
|
+
return run + 1
|
|
269
|
+
})
|
|
270
|
+
})
|
|
271
|
+
repo.find = originalFind
|
|
272
|
+
return done
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it("should not apply updates from a previous handle after url changes", async () => {
|
|
276
|
+
const { create, options } = setup()
|
|
277
|
+
const h1 = create()
|
|
278
|
+
const h2 = create()
|
|
279
|
+
|
|
280
|
+
const [url, setURL] = createSignal<AutomergeUrl>(h1.url)
|
|
281
|
+
|
|
282
|
+
const done = testEffect(done => {
|
|
283
|
+
const [doc, handle] = useDocSignal<ExampleDoc>(url, options)
|
|
284
|
+
createEffect((run: number = 0) => {
|
|
285
|
+
if (run == 0) {
|
|
286
|
+
expect(doc()?.key).toBe("value")
|
|
287
|
+
// Switch to h2
|
|
288
|
+
setURL(h2.url)
|
|
289
|
+
} else if (run == 1) {
|
|
290
|
+
expect(doc()?.key).toBe("value")
|
|
291
|
+
// Change h2
|
|
292
|
+
handle()?.change(doc => (doc.key = "from h2"))
|
|
293
|
+
} else if (run == 2) {
|
|
294
|
+
expect(doc()?.key).toBe("from h2")
|
|
295
|
+
done()
|
|
296
|
+
}
|
|
297
|
+
return run + 1
|
|
298
|
+
})
|
|
299
|
+
})
|
|
300
|
+
return done
|
|
301
|
+
})
|
|
302
|
+
})
|