automerge-repo-solid-primitives
Advanced tools
Comparing version 1.0.3 to 1.1.0
@@ -1,52 +0,52 @@ | ||
import { createContext as W, useContext as x, createResource as p, createEffect as O, on as A, onCleanup as D, $PROXY as s, $TRACK as k, getListener as R, batch as F, createSignal as z, getOwner as H, runWithOwner as L } from "solid-js"; | ||
import { fromAutomerge as V, apply as q } from "cabbages"; | ||
const M = W(null); | ||
function X() { | ||
const e = x(M); | ||
import { createContext as F, useContext as D, createResource as j, createEffect as p, on as $, onCleanup as _, $PROXY as s, $TRACK as k, getListener as R, batch as q, createSignal as z, getOwner as H, runWithOwner as L } from "solid-js"; | ||
import { fromAutomerge as V, apply as M } from "cabbages"; | ||
const C = F(null); | ||
function v() { | ||
const e = D(C); | ||
if (!e) throw new Error("Please wrap me in a <RepoContext value={repo}>"); | ||
return e; | ||
} | ||
function Y(e) { | ||
let n = X(), [t, { mutate: r }] = p(e, (o) => { | ||
if (!o) | ||
return; | ||
let f = n.find(o); | ||
return f.isReady() ? f : f.whenReady().then(() => f); | ||
function X(e, n) { | ||
let t = D(C); | ||
if (!n?.repo && !t) | ||
throw new Error("use outside <RepoContext> requires options.repo"); | ||
let o = n?.repo || t, [r, { mutate: f }] = j(e, (c) => { | ||
if (!c) return; | ||
let i = o.find(c); | ||
return i.isReady() ? i : i.whenReady().then(() => i); | ||
}); | ||
return O( | ||
A([e], () => { | ||
e() || r(); | ||
}) | ||
), t; | ||
return p($(e, (c) => c || f())), r; | ||
} | ||
function ee(e, n) { | ||
let t = Y(e), [r, { refetch: o, mutate: f }] = p(t, (c) => c.doc(), { | ||
initialValue: t()?.docSync(), | ||
storage: n?.storage | ||
let t = X(e, n), [o, { refetch: r, mutate: f }] = j(t, (i) => i.doc(), { | ||
initialValue: t()?.docSync() | ||
}); | ||
return O( | ||
A(t, (c) => { | ||
c?.on("change", o), c?.on("delete", o), D(() => { | ||
c?.off("change", o), c?.off("delete", o); | ||
function c() { | ||
f(), r(); | ||
} | ||
return p( | ||
$(t, (i) => { | ||
i?.on("change", r), i?.on("delete", c), _(() => { | ||
i?.off("change", r), i?.off("delete", c); | ||
}); | ||
}) | ||
), O(A(t, (c) => c || f())), O(A(e, (c) => c || f)), [ | ||
r, | ||
(c, u) => { | ||
t()?.change(c, u); | ||
), p($(e, (i) => i || f())), [ | ||
o, | ||
(i, u) => { | ||
t()?.change(i, u); | ||
} | ||
]; | ||
} | ||
const b = Symbol("store-raw"), a = Symbol("store-node"), l = Symbol("store-has"), _ = Symbol("store-self"); | ||
function C(e) { | ||
const O = Symbol("store-raw"), a = Symbol("store-node"), l = Symbol("store-has"), x = Symbol("store-self"); | ||
function E(e) { | ||
let n = e[s]; | ||
if (!n && (Object.defineProperty(e, s, { | ||
value: n = new Proxy(e, I) | ||
value: n = new Proxy(e, G) | ||
}), !Array.isArray(e))) { | ||
const t = Object.keys(e), r = Object.getOwnPropertyDescriptors(e); | ||
for (let o = 0, f = t.length; o < f; o++) { | ||
const c = t[o]; | ||
r[c].get && Object.defineProperty(e, c, { | ||
enumerable: r[c].enumerable, | ||
get: r[c].get.bind(n) | ||
const t = Object.keys(e), o = Object.getOwnPropertyDescriptors(e); | ||
for (let r = 0, f = t.length; r < f; r++) { | ||
const c = t[r]; | ||
o[c].get && Object.defineProperty(e, c, { | ||
enumerable: o[c].enumerable, | ||
get: o[c].get.bind(n) | ||
}); | ||
@@ -61,19 +61,19 @@ } | ||
} | ||
function g(e, n = /* @__PURE__ */ new Set()) { | ||
let t, r, o, f; | ||
if (t = e != null && e[b]) return t; | ||
function y(e, n = /* @__PURE__ */ new Set()) { | ||
let t, o, r, f; | ||
if (t = e != null && e[O]) return t; | ||
if (!d(e) || n.has(e)) return e; | ||
if (Array.isArray(e)) { | ||
Object.isFrozen(e) ? e = e.slice(0) : n.add(e); | ||
for (let c = 0, u = e.length; c < u; c++) | ||
o = e[c], (r = g(o, n)) !== o && (e[c] = r); | ||
for (let c = 0, i = e.length; c < i; c++) | ||
r = e[c], (o = y(r, n)) !== r && (e[c] = o); | ||
} else { | ||
Object.isFrozen(e) ? e = Object.assign({}, e) : n.add(e); | ||
const c = Object.keys(e), u = Object.getOwnPropertyDescriptors(e); | ||
for (let i = 0, $ = c.length; i < $; i++) | ||
f = c[i], !u[f].get && (o = e[f], (r = g(o, n)) !== o && (e[f] = r)); | ||
const c = Object.keys(e), i = Object.getOwnPropertyDescriptors(e); | ||
for (let u = 0, P = c.length; u < P; u++) | ||
f = c[u], !i[f].get && (r = e[f], (o = y(r, n)) !== r && (e[f] = o)); | ||
} | ||
return e; | ||
} | ||
function P(e, n) { | ||
function A(e, n) { | ||
let t = e[n]; | ||
@@ -86,35 +86,35 @@ return t || Object.defineProperty(e, n, { | ||
if (e[n]) return e[n]; | ||
const [r, o] = z(t, { | ||
const [o, r] = z(t, { | ||
equals: !1, | ||
internal: !0 | ||
}); | ||
return r.$ = o, e[n] = r; | ||
return o.$ = r, e[n] = o; | ||
} | ||
function B(e, n) { | ||
function Y(e, n) { | ||
const t = Reflect.getOwnPropertyDescriptor(e, n); | ||
return !t || t.get || !t.configurable || n === s || n === a || (delete t.value, delete t.writable, t.get = () => e[s][n]), t; | ||
} | ||
function E(e) { | ||
R() && h(P(e, a), _)(); | ||
function K(e) { | ||
R() && h(A(e, a), x)(); | ||
} | ||
function G(e) { | ||
return E(e), Reflect.ownKeys(e); | ||
function B(e) { | ||
return K(e), Reflect.ownKeys(e); | ||
} | ||
const I = { | ||
const G = { | ||
get(e, n, t) { | ||
if (n === b) return e; | ||
if (n === O) return e; | ||
if (n === s) return t; | ||
if (n === k) | ||
return E(e), t; | ||
const r = P(e, a), o = r[n]; | ||
let f = o ? o() : e[n]; | ||
return K(e), t; | ||
const o = A(e, a), r = o[n]; | ||
let f = r ? r() : e[n]; | ||
if (n === a || n === l || n === "__proto__") return f; | ||
if (!o) { | ||
if (!r) { | ||
const c = Object.getOwnPropertyDescriptor(e, n); | ||
R() && (typeof f != "function" || e.hasOwnProperty(n)) && !(c && c.get) && (f = h(r, n, f)()); | ||
R() && (typeof f != "function" || e.hasOwnProperty(n)) && !(c && c.get) && (f = h(o, n, f)()); | ||
} | ||
return d(f) ? C(f) : f; | ||
return d(f) ? E(f) : f; | ||
}, | ||
has(e, n) { | ||
return n === b || n === s || n === k || n === a || n === l || n === "__proto__" ? !0 : (R() && h(P(e, l), n)(), n in e); | ||
return n === O || n === s || n === k || n === a || n === l || n === "__proto__" ? !0 : (R() && h(A(e, l), n)(), n in e); | ||
}, | ||
@@ -127,93 +127,93 @@ set() { | ||
}, | ||
ownKeys: G, | ||
getOwnPropertyDescriptor: B | ||
ownKeys: B, | ||
getOwnPropertyDescriptor: Y | ||
}; | ||
function y(e, n, t, r = !1) { | ||
if (!r && e[n] === t) return; | ||
const o = e[n], f = e.length; | ||
t === void 0 ? (delete e[n], e[l] && e[l][n] && o !== void 0 && e[l][n].$()) : (e[n] = t, e[l] && e[l][n] && o === void 0 && e[l][n].$()); | ||
let c = P(e, a), u; | ||
if ((u = h(c, n, o)) && u.$(() => t), Array.isArray(e) && e.length !== f) { | ||
for (let i = e.length; i < f; i++) (u = c[i]) && u.$(); | ||
(u = h(c, "length", f)) && u.$(e.length); | ||
function g(e, n, t, o = !1) { | ||
if (!o && e[n] === t) return; | ||
const r = e[n], f = e.length; | ||
t === void 0 ? (delete e[n], e[l] && e[l][n] && r !== void 0 && e[l][n].$()) : (e[n] = t, e[l] && e[l][n] && r === void 0 && e[l][n].$()); | ||
let c = A(e, a), i; | ||
if ((i = h(c, n, r)) && i.$(() => t), Array.isArray(e) && e.length !== f) { | ||
for (let u = e.length; u < f; u++) (i = c[u]) && i.$(); | ||
(i = h(c, "length", f)) && i.$(e.length); | ||
} | ||
(u = c[_]) && u.$(); | ||
(i = c[x]) && i.$(); | ||
} | ||
function K(e, n) { | ||
function N(e, n) { | ||
const t = Object.keys(n); | ||
for (let r = 0; r < t.length; r += 1) { | ||
const o = t[r]; | ||
y(e, o, n[o]); | ||
for (let o = 0; o < t.length; o += 1) { | ||
const r = t[o]; | ||
g(e, r, n[r]); | ||
} | ||
} | ||
function J(e, n) { | ||
if (typeof n == "function" && (n = n(e)), n = g(n), Array.isArray(n)) { | ||
function I(e, n) { | ||
if (typeof n == "function" && (n = n(e)), n = y(n), Array.isArray(n)) { | ||
if (e === n) return; | ||
let t = 0, r = n.length; | ||
for (; t < r; t++) { | ||
const o = n[t]; | ||
e[t] !== o && y(e, t, o); | ||
let t = 0, o = n.length; | ||
for (; t < o; t++) { | ||
const r = n[t]; | ||
e[t] !== r && g(e, t, r); | ||
} | ||
y(e, "length", r); | ||
} else K(e, n); | ||
g(e, "length", o); | ||
} else N(e, n); | ||
} | ||
function w(e, n, t = []) { | ||
let r, o = e; | ||
let o, r = e; | ||
if (n.length > 1) { | ||
r = n.shift(); | ||
const c = typeof r, u = Array.isArray(e); | ||
if (Array.isArray(r)) { | ||
for (let i = 0; i < r.length; i++) | ||
w(e, [r[i]].concat(n), t); | ||
o = n.shift(); | ||
const c = typeof o, i = Array.isArray(e); | ||
if (Array.isArray(o)) { | ||
for (let u = 0; u < o.length; u++) | ||
w(e, [o[u]].concat(n), t); | ||
return; | ||
} else if (u && c === "function") { | ||
for (let i = 0; i < e.length; i++) | ||
r(e[i], i) && w(e, [i].concat(n), t); | ||
} else if (i && c === "function") { | ||
for (let u = 0; u < e.length; u++) | ||
o(e[u], u) && w(e, [u].concat(n), t); | ||
return; | ||
} else if (u && c === "object") { | ||
} else if (i && c === "object") { | ||
const { | ||
from: i = 0, | ||
to: $ = e.length - 1, | ||
by: T = 1 | ||
} = r; | ||
for (let j = i; j <= $; j += T) | ||
w(e, [j].concat(n), t); | ||
from: u = 0, | ||
to: P = e.length - 1, | ||
by: W = 1 | ||
} = o; | ||
for (let S = u; S <= P; S += W) | ||
w(e, [S].concat(n), t); | ||
return; | ||
} else if (n.length > 1) { | ||
w(e[r], n, [r].concat(t)); | ||
w(e[o], n, [o].concat(t)); | ||
return; | ||
} | ||
o = e[r], t = [r].concat(t); | ||
r = e[o], t = [o].concat(t); | ||
} | ||
let f = n[0]; | ||
typeof f == "function" && (f = f(o, t), f === o) || r === void 0 && f == null || (f = g(f), r === void 0 || d(o) && d(f) && !Array.isArray(f) ? K(o, f) : y(e, r, f)); | ||
typeof f == "function" && (f = f(r, t), f === r) || o === void 0 && f == null || (f = y(f), o === void 0 || d(r) && d(f) && !Array.isArray(f) ? N(r, f) : g(e, o, f)); | ||
} | ||
function Q(...[e, n]) { | ||
const t = g(e || {}), r = Array.isArray(t), o = C(t); | ||
function J(...[e, n]) { | ||
const t = y(e || {}), o = Array.isArray(t), r = E(t); | ||
function f(...c) { | ||
F(() => { | ||
r && c.length === 1 ? J(t, c[0]) : w(t, c); | ||
q(() => { | ||
o && c.length === 1 ? I(t, c[0]) : w(t, c); | ||
}); | ||
} | ||
return [o, f]; | ||
return [r, f]; | ||
} | ||
const S = /* @__PURE__ */ new WeakMap(), N = { | ||
const b = /* @__PURE__ */ new WeakMap(), T = { | ||
get(e, n) { | ||
if (n === b) return e; | ||
if (n === O) return e; | ||
const t = e[n]; | ||
let r; | ||
return d(t) ? S.get(t) || (S.set(t, r = new Proxy(t, N)), r) : t; | ||
let o; | ||
return d(t) ? b.get(t) || (b.set(t, o = new Proxy(t, T)), o) : t; | ||
}, | ||
set(e, n, t) { | ||
return y(e, n, g(t)), !0; | ||
return g(e, n, y(t)), !0; | ||
}, | ||
deleteProperty(e, n) { | ||
return y(e, n, void 0, !0), !0; | ||
return g(e, n, void 0, !0), !0; | ||
} | ||
}; | ||
function U(e) { | ||
function Q(e) { | ||
return (n) => { | ||
if (d(n)) { | ||
let t; | ||
(t = S.get(n)) || S.set(n, t = new Proxy(n, N)), e(t); | ||
(t = b.get(n)) || b.set(n, t = new Proxy(n, T)), e(t); | ||
} | ||
@@ -223,34 +223,33 @@ return n; | ||
} | ||
function Z(e) { | ||
return U((n) => { | ||
function U(e) { | ||
return Q((n) => { | ||
for (let t of e) { | ||
const [r, o, f] = V(t); | ||
q(r, n, o, f); | ||
const [o, r, f] = V(t); | ||
M(o, n, r, f); | ||
} | ||
}); | ||
} | ||
function ne(e, n) { | ||
let t = H(), [r] = p( | ||
function ne(e) { | ||
let n = H(), [t] = j( | ||
e, | ||
async (o) => { | ||
await o.whenReady(); | ||
let [f, c] = Q(o.docSync()); | ||
function u(i) { | ||
c(Z(i.patches)); | ||
let [r, f] = J(o.docSync()); | ||
function c(i) { | ||
f(U(i.patches)); | ||
} | ||
return o.on("change", u), L(t, () => D(() => o.off("change", u))), f; | ||
return o.on("change", c), L(n, () => _(() => o.off("change", c))), r; | ||
}, | ||
{ | ||
initialValue: e()?.docSync(), | ||
storage: n?.storage | ||
initialValue: e()?.docSync() | ||
} | ||
); | ||
return r; | ||
return t; | ||
} | ||
export { | ||
M as RepoContext, | ||
C as RepoContext, | ||
ne as createDocumentStore, | ||
ee as useDocument, | ||
Y as useHandle, | ||
X as useRepo | ||
X as useHandle, | ||
v as useRepo | ||
}; |
@@ -1,8 +0,7 @@ | ||
import { AnyDocumentId, ChangeFn, Doc, DocHandle } from '@automerge/automerge-repo/slim'; | ||
import { AnyDocumentId, ChangeFn, Doc } from '@automerge/automerge-repo/slim'; | ||
import { ChangeOptions } from '@automerge/automerge/slim/next'; | ||
import { Resource, ResourceOptions } from 'solid-js'; | ||
import { Resource } from 'solid-js'; | ||
import { BaseOptions } from './types.ts'; | ||
export declare function useDocument<T>(id: () => AnyDocumentId | undefined, options?: { | ||
storage?: ResourceOptions<Doc<T>, DocHandle<T>>["storage"]; | ||
}): [ | ||
export declare function useDocument<T>(id: () => AnyDocumentId | undefined, options?: BaseOptions): [ | ||
Resource<Doc<T> | undefined>, | ||
@@ -9,0 +8,0 @@ (changeFn: ChangeFn<T>, options?: ChangeOptions<T> | undefined) => void |
import { AnyDocumentId, DocHandle } from '@automerge/automerge-repo/slim'; | ||
import { Resource } from 'solid-js'; | ||
import { BaseOptions } from './types.ts'; | ||
@@ -9,3 +10,3 @@ /** A hook which returns a {@link DocHandle} identified by a URL. | ||
*/ | ||
export declare function useHandle<T>(id: () => AnyDocumentId | undefined): Resource<DocHandle<T> | undefined>; | ||
export declare function useHandle<T>(id: () => AnyDocumentId | undefined, options?: BaseOptions): Resource<DocHandle<T> | undefined>; | ||
//# sourceMappingURL=handle.d.ts.map |
import { ChangeFn, Doc, DocHandle } from '@automerge/automerge-repo'; | ||
import { Accessor, ResourceOptions } from 'solid-js'; | ||
import { Accessor } from 'solid-js'; | ||
import { Store } from 'solid-js/store'; | ||
export type DocumentStore<T> = [Store<Doc<T>>, (fn: ChangeFn<T>) => void]; | ||
export interface DocumentStoreOptions<T> { | ||
storage?: ResourceOptions<Doc<T>, DocHandle<T>>["storage"]; | ||
} | ||
export declare function createDocumentStore<T>(handle: Accessor<DocHandle<T> | undefined>, options?: DocumentStoreOptions<T>): import('solid-js').Resource<Doc<T>>; | ||
export declare function createDocumentStore<T>(handle: Accessor<DocHandle<T> | undefined>): import('solid-js').Resource<Doc<T>>; | ||
//# sourceMappingURL=document-store.d.ts.map |
{ | ||
"name": "automerge-repo-solid-primitives", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "automerge-repo primitives for your solidjs app", | ||
@@ -17,26 +17,22 @@ "type": "module", | ||
"@automerge/automerge": "^2.2.8", | ||
"@automerge/automerge-repo": "^1.2.1", | ||
"@automerge/automerge-repo-network-broadcastchannel": "^1.2.1", | ||
"@automerge/automerge-repo-network-websocket": "^1.2.1", | ||
"@automerge/automerge-repo-storage-indexeddb": "^1.2.1", | ||
"@automerge/automerge-repo": "2.0.0-alpha.11", | ||
"@solidjs/testing-library": "^0.8.9", | ||
"@testing-library/jest-dom": "^6.4.8", | ||
"@testing-library/jest-dom": "^6.5.0", | ||
"@testing-library/user-event": "^14.5.2", | ||
"eslint": "^9.8.0", | ||
"eslint-plugin-solid": "^0.14.1", | ||
"eslint": "^9.11.0", | ||
"eslint-plugin-solid": "^0.14.3", | ||
"globals": "^15.9.0", | ||
"jsdom": "^24.1.1", | ||
"jsdom": "^24.1.3", | ||
"prettier": "^3.3.3", | ||
"rollup-plugin-visualizer": "^5.12.0", | ||
"solid-js": "^1.8.19", | ||
"typescript": "^5.5.4", | ||
"typescript-eslint": "^8.0.1", | ||
"vite": "^5.3.5", | ||
"solid-js": "^1.8.22", | ||
"typescript": "^5.6.2", | ||
"typescript-eslint": "^8.6.0", | ||
"vite": "^5.4.7", | ||
"vite-plugin-dts": "4.0.0-beta.2", | ||
"vite-plugin-solid": "^2.10.2", | ||
"vite-plugin-wasm": "^3.3.0", | ||
"vitest": "^2.0.5" | ||
"vitest": "^2.1.1" | ||
}, | ||
"peerDependencies": { | ||
"@automerge/automerge-repo": "^1.2.1", | ||
"solid-js": "^1.8.19" | ||
@@ -43,0 +39,0 @@ }, |
# Solid Primitives for Automerge Repo | ||
These hooks are provided as helpers for using Automerge in your SolidJS project. | ||
Helpers for using <a href="https://automerge.org/docs/repositories/"> | ||
<img alt="" src=.assets/automerge.png width=22 height=22> | ||
Automerge | ||
</a> with <a href="https://www.solidjs.com/"> | ||
<img alt="" src=.assets/solid.png width=22 height=22> | ||
SolidJS | ||
</a>. | ||
## `<RepoProvider repo={Repo}/>` | ||
## RepoContext | ||
Wrapper context required in Automerge-Repo Solid apps | ||
A convenience context for Automerge-Repo Solid apps. Optional: if you prefer you | ||
can pass a repo as an option to `useHandle` or `useDocument`. | ||
## `useRepo(): Repo` | ||
```tsx | ||
<RepoContext.Provider repo={Repo}> | ||
<App /> | ||
</RepoContext.Provider> | ||
``` | ||
Get a the current repo from the context. | ||
## useRepo | ||
## `useHandle<T>(() => AnyDocumentId): Resource<Handle>` | ||
Get the repo from the [context](#repocontext). | ||
Get a handle from the repo. | ||
```ts | ||
useRepo(): Repo | ||
``` | ||
## `useDocument<T>(() => AnyDocumentId): [Resource<T>, (fn: changeFn<T>) => void]` | ||
### e.g. | ||
Get a document and change function from the repo. | ||
```ts | ||
let repo = useRepo() | ||
``` | ||
## `createDocumentStore<T>(() => Handle<T>): Resource<Doc<T>>` | ||
## useHandle | ||
Create a store for a handle's document. We subscribe to the handle's changes, | ||
and apply the incoming patches to the precise the fields of the store that have | ||
changed to provide fine-grained reactivity that's consistent across space and | ||
time. | ||
Get a [handle](https://automerge.org/docs/repositories/dochandles/) from the repo as a [resource](https://docs.solidjs.com/reference/basic-reactivity/create-resource). | ||
```ts | ||
useHandle<T>( | ||
() => AnyDocumentId, | ||
options?: {repo: Repo} | ||
): Resource<Handle<T>> | ||
``` | ||
### e.g. | ||
```ts | ||
let handle = useHandle(id) | ||
// or | ||
let handle = useHandle(id, {repo}) | ||
``` | ||
The `repo` option can be left out if you are using [RepoContext](#repocontext). | ||
## useDocument | ||
Get a document and change function from the repo as a [resource](https://docs.solidjs.com/reference/basic-reactivity/create-resource). | ||
```ts | ||
useDocument<T>( | ||
() => AnyDocumentId, | ||
options?: {repo: Repo} | ||
): [Resource<T>, (fn: changeFn<T>) => void] | ||
``` | ||
### e.g. | ||
```ts | ||
let [doc, change] = useDocument(id) | ||
// or | ||
let [doc, change] = useDocument(id, {repo}) | ||
``` | ||
The `repo` option can be left out if you are using [RepoContext](#repocontext). | ||
## createDocumentStore | ||
Create a store for a handle's document. It's subscribed to the handle's changes, | ||
and converts incoming automerge operations to store updates, providing | ||
fine-grained reactivity that's consistent across space and time. | ||
```ts | ||
createDocumentStore<T>( | ||
() => Handle<T> | ||
): Resource<Doc<T>> | ||
``` | ||
### e.g. | ||
```ts | ||
let handle = useHandle(id, {repo}) | ||
let doc = createDocumentStore(handle) | ||
return <h1>{doc.items[1].title}</h1> | ||
``` |
@@ -16,10 +16,8 @@ import type { | ||
type Resource, | ||
type ResourceOptions, | ||
} from "solid-js" | ||
import type {BaseOptions} from "./types.ts" | ||
export function useDocument<T>( | ||
id: () => AnyDocumentId | undefined, | ||
options?: { | ||
storage?: ResourceOptions<Doc<T>, DocHandle<T>>["storage"] | ||
} | ||
options?: BaseOptions | ||
): [ | ||
@@ -29,3 +27,3 @@ Resource<Doc<T> | undefined>, | ||
] { | ||
let handle = useHandle<T>(id) | ||
let handle = useHandle<T>(id, options) | ||
let [doc, {refetch, mutate}] = createResource< | ||
@@ -36,12 +34,16 @@ Doc<T | undefined>, | ||
initialValue: handle()?.docSync(), | ||
storage: options?.storage, | ||
}) | ||
function ondelete() { | ||
mutate() | ||
refetch() | ||
} | ||
createEffect( | ||
on(handle, handle => { | ||
handle?.on("change", refetch) | ||
handle?.on("delete", refetch) | ||
handle?.on("delete", ondelete) | ||
onCleanup(() => { | ||
handle?.off("change", refetch) | ||
handle?.off("delete", refetch) | ||
handle?.off("delete", ondelete) | ||
}) | ||
@@ -51,4 +53,3 @@ }) | ||
createEffect(on(handle, handle => handle || mutate())) | ||
createEffect(on(id, id => id || mutate)) | ||
createEffect(on(id, id => id || mutate())) | ||
@@ -55,0 +56,0 @@ return [ |
import type {AnyDocumentId, DocHandle} from "@automerge/automerge-repo/slim" | ||
import {useRepo} from "./repo.ts" | ||
import {createEffect, createResource, on, type Resource} from "solid-js" | ||
import {RepoContext} from "./repo.ts" | ||
import { | ||
createEffect, | ||
createResource, | ||
on, | ||
useContext, | ||
type Resource, | ||
} from "solid-js" | ||
import type {BaseOptions} from "./types.ts" | ||
// todo is this complicated for no reason? | ||
// should i just return the result of repo.find(id())? | ||
/** A hook which returns a {@link DocHandle} identified by a URL. | ||
@@ -14,27 +18,18 @@ * | ||
export function useHandle<T>( | ||
id: () => AnyDocumentId | undefined | ||
id: () => AnyDocumentId | undefined, | ||
options?: BaseOptions | ||
): Resource<DocHandle<T> | undefined> { | ||
let repo = useRepo() | ||
let contextRepo = useContext(RepoContext) | ||
if (!options?.repo && !contextRepo) { | ||
throw new Error("use outside <RepoContext> requires options.repo") | ||
} | ||
let repo = (options?.repo || contextRepo)! | ||
let [handle, {mutate}] = createResource(id, id => { | ||
if (!id) { | ||
return | ||
} | ||
if (!id) return | ||
let handle = repo.find<T>(id) | ||
if (handle.isReady()) { | ||
return handle | ||
} | ||
if (handle.isReady()) return handle | ||
return handle.whenReady().then(() => handle) | ||
}) | ||
createEffect( | ||
on([id], () => { | ||
if (!id()) { | ||
mutate() | ||
} | ||
}) | ||
) | ||
createEffect(on(id, id => id || mutate())) | ||
return handle | ||
} |
import {Repo} from "@automerge/automerge-repo/slim" | ||
import {createContext, useContext, type JSXElement} from "solid-js" | ||
import {createContext, useContext} from "solid-js" | ||
@@ -4,0 +4,0 @@ /** |
@@ -8,3 +8,3 @@ import {createResource, getOwner, onCleanup, runWithOwner} from "solid-js" | ||
} from "@automerge/automerge-repo" | ||
import type {Accessor, ResourceOptions} from "solid-js" | ||
import type {Accessor} from "solid-js" | ||
import {createStore, produce, type Store} from "solid-js/store" | ||
@@ -25,9 +25,4 @@ import type {Patch} from "@automerge/automerge" | ||
export interface DocumentStoreOptions<T> { | ||
storage?: ResourceOptions<Doc<T>, DocHandle<T>>["storage"] | ||
} | ||
export function createDocumentStore<T>( | ||
handle: Accessor<DocHandle<T> | undefined>, | ||
options?: DocumentStoreOptions<T> | ||
handle: Accessor<DocHandle<T> | undefined> | ||
) { | ||
@@ -40,3 +35,2 @@ let owner = getOwner() | ||
await handle.whenReady() | ||
let [document, update] = createStore(handle.docSync() as Doc<T>) | ||
@@ -47,2 +41,3 @@ | ||
} | ||
handle.on("change", patch) | ||
@@ -54,3 +49,2 @@ runWithOwner(owner, () => onCleanup(() => handle.off("change", patch))) | ||
initialValue: handle()?.docSync(), | ||
storage: options?.storage, | ||
} | ||
@@ -57,0 +51,0 @@ ) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
65375
2
19
42
1112
98