@jtfmumm/patchwork-standalone-frame 0.3.1 → 0.4.0
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/README.md +26 -7
- package/dist/index.d.ts +3 -4
- package/dist/index.js +30 -30
- package/package.json +1 -1
- package/src/frame.tsx +2 -4
- package/src/index.ts +3 -4
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ pnpm add -D @jtfmumm/automerge-deps @jtfmumm/patchwork-standalone-vite vite
|
|
|
32
32
|
|
|
33
33
|
### 3. Configure automerge-deps
|
|
34
34
|
|
|
35
|
-
Create `automerge-deps.json` to specify the tool and sync server:
|
|
35
|
+
Create `automerge-deps.json` to specify the tool and sync server for fetching the tool:
|
|
36
36
|
|
|
37
37
|
```json
|
|
38
38
|
{
|
|
@@ -57,13 +57,13 @@ This downloads the tool's FolderDoc from the sync server and writes it to `node_
|
|
|
57
57
|
```typescript
|
|
58
58
|
import { Repo } from "@automerge/automerge-repo";
|
|
59
59
|
import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb";
|
|
60
|
-
import {
|
|
60
|
+
import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
|
|
61
61
|
import { mountStandaloneApp } from "@jtfmumm/patchwork-standalone-frame";
|
|
62
62
|
import { plugins } from "my-tool";
|
|
63
63
|
|
|
64
64
|
const repo = new Repo({
|
|
65
65
|
storage: new IndexedDBStorageAdapter(),
|
|
66
|
-
network: [new
|
|
66
|
+
network: [new WebSocketClientAdapter("wss://your-sync-server.example.com")],
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
const root = document.getElementById("root");
|
|
@@ -177,8 +177,27 @@ Pass `{ legacyMode: true, repo }` to use a plain automerge repo without keyhive.
|
|
|
177
177
|
|
|
178
178
|
### Keyhive mode (default)
|
|
179
179
|
|
|
180
|
-
When `legacyMode` is not set, the frame initializes keyhive automatically, including WASM loading, repo creation, and access control.
|
|
180
|
+
When `legacyMode` is not set, the frame initializes keyhive automatically, including WASM loading, repo creation, and access control.
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
```typescript
|
|
183
|
+
import { plugins } from "my-tool";
|
|
184
|
+
|
|
185
|
+
mountStandaloneApp(root, plugins, {
|
|
186
|
+
syncUrl: "wss://your-keyhive-sync-server.example.com",
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Config options
|
|
191
|
+
|
|
192
|
+
| Option | Description |
|
|
193
|
+
|--------|-------------|
|
|
194
|
+
| `legacyMode` | Use plain automerge docs without keyhive. Default: `false` |
|
|
195
|
+
| `repo` | Pre-built repo for legacy mode. Required when `legacyMode` is `true` |
|
|
196
|
+
| `syncUrl` | WebSocket sync server URL for keyhive mode |
|
|
197
|
+
|
|
198
|
+
The sync server URL is resolved in this order:
|
|
199
|
+
|
|
200
|
+
1. `config.syncUrl`
|
|
201
|
+
2. `VITE_SYNC_URL` environment variable
|
|
202
|
+
3. `tool.syncUrl` from the registration
|
|
203
|
+
4. `ws://localhost:3030` (default)
|
package/dist/index.d.ts
CHANGED
|
@@ -15,17 +15,16 @@ export interface ToolRegistration<D = unknown> {
|
|
|
15
15
|
isDocReady?: (doc: D) => boolean;
|
|
16
16
|
render: (handle: DocHandle<D>, element: ToolElement) => (() => void);
|
|
17
17
|
}
|
|
18
|
-
/** Duck-typed doc handle — structurally compatible with automerge-repo DocHandle */
|
|
18
|
+
/** Duck-typed doc handle — structurally compatible with automerge-repo 2.5.x DocHandle */
|
|
19
19
|
export interface FrameDocHandle<D = unknown> {
|
|
20
20
|
url: string;
|
|
21
21
|
doc(): D | undefined;
|
|
22
|
-
whenReady(): Promise<unknown>;
|
|
23
22
|
on(event: string, cb: (...args: unknown[]) => void): void;
|
|
24
23
|
off(event: string, cb: (...args: unknown[]) => void): void;
|
|
25
24
|
}
|
|
26
|
-
/** Duck-typed repo — structurally compatible with automerge-repo Repo */
|
|
25
|
+
/** Duck-typed repo — structurally compatible with automerge-repo 2.5.x Repo */
|
|
27
26
|
export interface FrameRepo {
|
|
28
|
-
find<D = unknown>(url: string): FrameDocHandle<D
|
|
27
|
+
find<D = unknown>(url: string): Promise<FrameDocHandle<D>>;
|
|
29
28
|
create<D = unknown>(initialValue: D): FrameDocHandle<D>;
|
|
30
29
|
delete(url: string): void;
|
|
31
30
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { delegateEvents as xe, createComponent as m, insert as f, effect as D, style as E, memo as Z, setStyleProperty as X, template as w, use as Ee, setAttribute as
|
|
1
|
+
import { delegateEvents as xe, createComponent as m, insert as f, effect as D, style as E, memo as Z, setStyleProperty as X, template as w, use as Ee, setAttribute as Re, render as Pe } from "solid-js/web";
|
|
2
2
|
import { createSignal as x, createEffect as ie, onCleanup as q, createMemo as we, Show as _, For as Me, onMount as $e } from "solid-js";
|
|
3
3
|
const Fe = 100;
|
|
4
4
|
function Oe(e, t) {
|
|
@@ -15,18 +15,18 @@ function ve(e, t) {
|
|
|
15
15
|
return [];
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function He(e, t, l) {
|
|
19
19
|
localStorage.setItem(Oe(e, t), JSON.stringify(l));
|
|
20
20
|
}
|
|
21
21
|
function Ie(e, t, l, g) {
|
|
22
22
|
const u = ve(e, t), p = u.findIndex(($) => $.url === l);
|
|
23
23
|
p !== -1 ? (u[p].title = g, u[p].lastOpened = Date.now()) : u.push({ url: l, title: g, lastOpened: Date.now() }), u.sort(($, v) => v.lastOpened - $.lastOpened);
|
|
24
24
|
const k = u.slice(0, Fe);
|
|
25
|
-
return
|
|
25
|
+
return He(e, t, k), k;
|
|
26
26
|
}
|
|
27
27
|
function Ne(e, t, l) {
|
|
28
28
|
const g = ve(e, t).filter((u) => u.url !== l);
|
|
29
|
-
return
|
|
29
|
+
return He(e, t, g), g;
|
|
30
30
|
}
|
|
31
31
|
function Ve(e) {
|
|
32
32
|
const t = "automerge:";
|
|
@@ -95,14 +95,14 @@ const Ze = {
|
|
|
95
95
|
margin: "12px 0"
|
|
96
96
|
};
|
|
97
97
|
function et(e) {
|
|
98
|
-
const [t, l] = x(""), [g, u] = x({}), [p, k] = x(!0), [$, v] = x(void 0), [N, U] = x(!1), [oe,
|
|
98
|
+
const [t, l] = x(""), [g, u] = x({}), [p, k] = x(!0), [$, v] = x(void 0), [N, U] = x(!1), [oe, R] = x(null), [A, ae] = x(null), [ee, te] = x(null), [G, be] = x("");
|
|
99
99
|
ie(() => {
|
|
100
100
|
if (!e.isOpen) return;
|
|
101
101
|
let a = !1;
|
|
102
102
|
(async () => {
|
|
103
103
|
const s = await ye();
|
|
104
104
|
if (a) return;
|
|
105
|
-
|
|
105
|
+
R(s.docIdFromAutomergeUrl(e.docUrl));
|
|
106
106
|
const C = e.hive.active.individual.id;
|
|
107
107
|
ae(C ? s.uint8ArrayToHex(C.toBytes()) : null);
|
|
108
108
|
const z = e.hive.syncServer;
|
|
@@ -299,8 +299,8 @@ function et(e) {
|
|
|
299
299
|
children: ([S, K]) => {
|
|
300
300
|
const V = S === A(), M = S === ee(), n = S === G(), r = De.indexOf($()), h = De.indexOf(K), c = r >= 0 && h >= 0 && h <= r && !V && !M, b = () => V ? "You" : M ? "Sync Server" : n ? "Public" : pe(S);
|
|
301
301
|
return (() => {
|
|
302
|
-
var y = Xe(), J = y.firstChild,
|
|
303
|
-
return X(
|
|
302
|
+
var y = Xe(), J = y.firstChild, H = J.firstChild, W = H.nextSibling;
|
|
303
|
+
return X(H, "color", V ? "#7ab4f5" : n ? "#b5bd68" : "#edf2f7"), f(H, b), f(W, K), f(y, m(_, {
|
|
304
304
|
when: c,
|
|
305
305
|
get children() {
|
|
306
306
|
var o = Qe();
|
|
@@ -385,12 +385,12 @@ function it(e) {
|
|
|
385
385
|
}, v.$$keydown = (A) => {
|
|
386
386
|
A.key === "Enter" && u();
|
|
387
387
|
}, v.$$input = (A) => l(A.currentTarget.value);
|
|
388
|
-
var
|
|
389
|
-
return typeof
|
|
388
|
+
var R = g;
|
|
389
|
+
return typeof R == "function" ? Ee(R, v) : g = v, U.$$click = () => e.onCancel(), oe.$$click = () => u(), D((A) => {
|
|
390
390
|
var ae = Ce, ee = {
|
|
391
391
|
...Se
|
|
392
392
|
}, te = e.defaultTitle;
|
|
393
|
-
return A.e = E(p, ae, A.e), A.t = E(k, ee, A.t), te !== A.a &&
|
|
393
|
+
return A.e = E(p, ae, A.e), A.t = E(k, ee, A.t), te !== A.a && Re(v, "placeholder", A.a = te), A;
|
|
394
394
|
}, {
|
|
395
395
|
e: void 0,
|
|
396
396
|
t: void 0,
|
|
@@ -403,17 +403,17 @@ xe(["click", "input", "keydown"]);
|
|
|
403
403
|
const ot = {};
|
|
404
404
|
var at = /* @__PURE__ */ w('<div style="padding:8px 10px;color:#6b7280;font-style:italic">No documents yet'), lt = /* @__PURE__ */ w('<div style="position:absolute;top:34px;left:0;background:#191e24;border:1px solid #2a323c;border-radius:4px;max-height:400px;overflow-y:auto;min-width:280px;max-width:420px;z-index:1000;box-shadow:0 4px 12px rgba(0,0,0,0.4)">'), ct = /* @__PURE__ */ w('<button style="background:none;border:1px solid #2a323c;color:#edf2f7;font-size:13px;padding:4px 10px;border-radius:4px;cursor:pointer;white-space:nowrap">Share'), st = /* @__PURE__ */ w('<button title="Copy automerge URL"style="background:none;border:1px solid #2a323c;font-size:13px;padding:4px 10px;border-radius:4px;cursor:pointer;white-space:nowrap">'), dt = /* @__PURE__ */ w('<button style="background:none;border:1px solid #2a323c;font-size:13px;padding:4px 10px;border-radius:4px;cursor:pointer;white-space:nowrap">'), ut = /* @__PURE__ */ w('<button style="background:none;border:1px solid #944;color:#c66;font-size:13px;padding:4px 10px;border-radius:4px;cursor:pointer;white-space:nowrap">Remove Doc'), ft = /* @__PURE__ */ w('<div style=display:flex;flex-direction:column;height:100vh;background:#1d232a><div style="display:flex;align-items:center;height:52px;min-height:52px;background:#191e24;color:#edf2f7;font-size:14px;font-family:system-ui, sans-serif;padding:0 12px;border-bottom:1px solid #15191e;box-sizing:border-box"><button style="background:none;border:1px solid #2a323c;color:#edf2f7;font-size:13px;padding:4px 10px;border-radius:4px;cursor:pointer;flex-shrink:0;margin-right:12px;white-space:nowrap">+ New</button><input type=text placeholder="Paste automerge:… URL"style="background:#15191e;border:1px solid #2a323c;color:#edf2f7;font-size:13px;padding:4px 10px;border-radius:4px;width:200px;min-width:80px;flex-shrink:1;margin-right:12px;outline:none"><div data-doc-switcher style=position:relative;flex:1;min-width:120px><button style="background:none;border:none;color:#edf2f7;font-size:14px;cursor:pointer;padding:4px 8px;border-radius:4px;max-width:100%;display:flex;align-items:center;gap:4px"><span style=overflow:hidden;text-overflow:ellipsis;white-space:nowrap></span><span style=flex-shrink:0>▾</span></button></div><div style=display:flex;align-items:center;flex-shrink:0;gap:8px></div></div><div style=flex:1;min-height:0;overflow:hidden>'), ht = /* @__PURE__ */ w('<div style="padding:8px 12px;cursor:pointer;border-bottom:1px solid #15191e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"> <span style=color:#6b7280;font-size:12px>'), gt = /* @__PURE__ */ w('<div style="width:24px;height:24px;border:2px solid #2a323c;border-top-color:#6b7280;border-radius:50%;animation:spin 0.8s linear infinite">'), pt = /* @__PURE__ */ w('<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;height:100%;background:#1d232a;font-family:system-ui, sans-serif;font-size:14px">'), mt = /* @__PURE__ */ w("<div style=height:100%>");
|
|
405
405
|
function yt(e) {
|
|
406
|
-
const t = e.tool, [l, g] = x(null), [u, p] = x("..."), [k, $] = x([]), [v, N] = x(!1), [U, oe] = x(null), [
|
|
406
|
+
const t = e.tool, [l, g] = x(null), [u, p] = x("..."), [k, $] = x([]), [v, N] = x(!1), [U, oe] = x(null), [R, A] = x(""), [ae, ee] = x(!1), [te, G] = x(!1), [be, Q] = x(!1), [le, fe] = x(!1), [he, ge] = x(!1), [ne, pe] = x(!1), [re, a] = x(!1), [s, C] = x(null), [z, P] = x(!1);
|
|
407
407
|
let T, L = null, F = 0;
|
|
408
408
|
function j(n) {
|
|
409
409
|
L && (L(), L = null);
|
|
410
410
|
const r = n.doc(), h = r ? t.getTitle(r) : t.defaultTitle;
|
|
411
|
-
p(h), $(Ie(t.id,
|
|
411
|
+
p(h), $(Ie(t.id, R(), n.url, h));
|
|
412
412
|
const c = () => {
|
|
413
413
|
const b = n.doc();
|
|
414
414
|
if (b) {
|
|
415
415
|
const y = t.getTitle(b);
|
|
416
|
-
p(y), $(Ie(t.id,
|
|
416
|
+
p(y), $(Ie(t.id, R(), n.url, y));
|
|
417
417
|
}
|
|
418
418
|
};
|
|
419
419
|
n.on("change", c), L = () => n.off("change", c);
|
|
@@ -425,8 +425,8 @@ function yt(e) {
|
|
|
425
425
|
const {
|
|
426
426
|
docIdFromAutomergeUrl: h,
|
|
427
427
|
Identifier: c
|
|
428
|
-
} = await import("@automerge/automerge-repo-keyhive"), b = h(n), y = r.active.individual.id, J = c.publicId(), [
|
|
429
|
-
return console.log(`[${t.name}] Access check for ${n.slice(0, 30)}...: my=${
|
|
428
|
+
} = await import("@automerge/automerge-repo-keyhive"), b = h(n), y = r.active.individual.id, J = c.publicId(), [H, W] = await Promise.all([r.accessForDoc(y, b).catch(() => null), r.accessForDoc(J, b).catch(() => null)]);
|
|
429
|
+
return console.log(`[${t.name}] Access check for ${n.slice(0, 30)}...: my=${H}, public=${W}`), !!(H || W);
|
|
430
430
|
} catch (h) {
|
|
431
431
|
return console.error(`[${t.name}] Access check error for ${n}:`, h), !0;
|
|
432
432
|
}
|
|
@@ -445,15 +445,15 @@ function yt(e) {
|
|
|
445
445
|
const y = b.doc();
|
|
446
446
|
return y ? t.isDocReady ? t.isDocReady(y) : !!y : !1;
|
|
447
447
|
};
|
|
448
|
-
let c = T.find(n);
|
|
449
|
-
if (
|
|
448
|
+
let c = await T.find(n);
|
|
449
|
+
if (r !== F) return;
|
|
450
450
|
if (!h(c)) {
|
|
451
451
|
console.log(`[${t.name}] Doc incomplete, forcing re-sync for: ${n.slice(0, 30)}...`);
|
|
452
452
|
try {
|
|
453
453
|
T.delete(n);
|
|
454
454
|
} catch {
|
|
455
455
|
}
|
|
456
|
-
if (await new Promise((b) => setTimeout(b, 100)), r !== F || (c = T.find(n),
|
|
456
|
+
if (await new Promise((b) => setTimeout(b, 100)), r !== F || (c = await T.find(n), r !== F)) return;
|
|
457
457
|
}
|
|
458
458
|
if (!h(c) && (se(n), await new Promise((b) => {
|
|
459
459
|
const y = () => {
|
|
@@ -468,7 +468,7 @@ function yt(e) {
|
|
|
468
468
|
}, 3e4);
|
|
469
469
|
}), r !== F))
|
|
470
470
|
return;
|
|
471
|
-
P(!1), se(n), localStorage.setItem(me(t.id,
|
|
471
|
+
P(!1), se(n), localStorage.setItem(me(t.id, R()), n), j(c), g(c);
|
|
472
472
|
} catch (h) {
|
|
473
473
|
if (r !== F) return;
|
|
474
474
|
console.error(`[${t.name}] Failed to load doc: ${n}`, h), P(!1), a(!0), C(n), se(n);
|
|
@@ -481,16 +481,16 @@ function yt(e) {
|
|
|
481
481
|
};
|
|
482
482
|
const h = U();
|
|
483
483
|
let c;
|
|
484
|
-
h ? (c = await T.create2(r), console.log(`[${t.name}] Created document (keyhive): ${c.url}`), await h.addSyncServerPullToDoc(c.url), await h.keyhiveStorage.saveKeyhiveWithHash(h.keyhive)) : (c = T.create(r), console.log(`[${t.name}] Created document (legacy): ${c.url}`)), g(c), se(c.url), localStorage.setItem(me(t.id,
|
|
484
|
+
h ? (c = await T.create2(r), console.log(`[${t.name}] Created document (keyhive): ${c.url}`), await h.addSyncServerPullToDoc(c.url), await h.keyhiveStorage.saveKeyhiveWithHash(h.keyhive)) : (c = T.create(r), console.log(`[${t.name}] Created document (legacy): ${c.url}`)), g(c), se(c.url), localStorage.setItem(me(t.id, R()), c.url), j(c);
|
|
485
485
|
}
|
|
486
486
|
function K() {
|
|
487
|
-
L && (L(), L = null), g(null), p("..."), a(!1), C(null), localStorage.removeItem(me(t.id,
|
|
487
|
+
L && (L(), L = null), g(null), p("..."), a(!1), C(null), localStorage.removeItem(me(t.id, R())), window.history.replaceState(null, "", window.location.pathname);
|
|
488
488
|
}
|
|
489
489
|
function V() {
|
|
490
490
|
const n = l();
|
|
491
491
|
if (!n) return;
|
|
492
492
|
const r = n.url;
|
|
493
|
-
K(), T.delete(r), $(Ne(t.id,
|
|
493
|
+
K(), T.delete(r), $(Ne(t.id, R(), r));
|
|
494
494
|
}
|
|
495
495
|
async function M() {
|
|
496
496
|
const n = U();
|
|
@@ -521,7 +521,7 @@ function yt(e) {
|
|
|
521
521
|
BrowserWebSocketClientAdapter: b
|
|
522
522
|
}, y] = await Promise.all([import("@automerge/automerge-repo"), import("@automerge/automerge-repo-storage-indexeddb"), import("@automerge/automerge-repo-network-websocket"), import("@automerge/automerge-repo-keyhive")]);
|
|
523
523
|
y.initKeyhiveWasm();
|
|
524
|
-
const J = new c(`${t.id}-keyhive`),
|
|
524
|
+
const J = new c(`${t.id}-keyhive`), H = ot?.VITE_SYNC_URL, W = new b(e.config?.syncUrl || H || t.syncUrl || "ws://localhost:3030"), o = `${t.id}-${Math.random().toString(36).slice(2)}`, d = await y.initializeAutomergeRepoKeyhive({
|
|
525
525
|
storage: J,
|
|
526
526
|
peerIdSuffix: o,
|
|
527
527
|
networkAdapter: W,
|
|
@@ -554,7 +554,7 @@ function yt(e) {
|
|
|
554
554
|
console.log(`[${t.name}] Loading doc from hash: ${n}`), await i(n);
|
|
555
555
|
return;
|
|
556
556
|
}
|
|
557
|
-
const r = localStorage.getItem(me(t.id,
|
|
557
|
+
const r = localStorage.getItem(me(t.id, R()));
|
|
558
558
|
if (r) {
|
|
559
559
|
console.log(`[${t.name}] Found existing doc: ${r}`), await i(r);
|
|
560
560
|
return;
|
|
@@ -574,7 +574,7 @@ function yt(e) {
|
|
|
574
574
|
}), (() => {
|
|
575
575
|
var n = ft(), r = n.firstChild, h = r.firstChild, c = h.nextSibling, b = c.nextSibling, y = b.firstChild, J = y.firstChild;
|
|
576
576
|
J.nextSibling;
|
|
577
|
-
var
|
|
577
|
+
var H = b.nextSibling, W = r.nextSibling;
|
|
578
578
|
return h.$$click = () => Q(!0), c.$$keydown = (o) => {
|
|
579
579
|
if (o.key === "Enter") {
|
|
580
580
|
const d = o.currentTarget.value.trim();
|
|
@@ -618,7 +618,7 @@ function yt(e) {
|
|
|
618
618
|
}
|
|
619
619
|
}), null), o;
|
|
620
620
|
}
|
|
621
|
-
}), null), f(
|
|
621
|
+
}), null), f(H, m(_, {
|
|
622
622
|
get when() {
|
|
623
623
|
return Z(() => !!l())() && U();
|
|
624
624
|
},
|
|
@@ -626,7 +626,7 @@ function yt(e) {
|
|
|
626
626
|
var o = ct();
|
|
627
627
|
return o.$$click = () => ee(!0), o;
|
|
628
628
|
}
|
|
629
|
-
}), null), f(
|
|
629
|
+
}), null), f(H, m(_, {
|
|
630
630
|
get when() {
|
|
631
631
|
return l();
|
|
632
632
|
},
|
|
@@ -637,7 +637,7 @@ function yt(e) {
|
|
|
637
637
|
d && (await navigator.clipboard.writeText(d.url), ge(!0), setTimeout(() => ge(!1), 1500));
|
|
638
638
|
}, f(o, () => he() ? "Copied!" : "Copy URL"), D((d) => X(o, "color", he() ? "#b5bd68" : "#edf2f7")), o;
|
|
639
639
|
}
|
|
640
|
-
}), null), f(
|
|
640
|
+
}), null), f(H, m(_, {
|
|
641
641
|
get when() {
|
|
642
642
|
return U();
|
|
643
643
|
},
|
|
@@ -645,7 +645,7 @@ function yt(e) {
|
|
|
645
645
|
var o = dt();
|
|
646
646
|
return o.$$click = () => void M(), f(o, () => le() ? "Copied!" : "Contact Card"), D((d) => X(o, "color", le() ? "#b5bd68" : "#edf2f7")), o;
|
|
647
647
|
}
|
|
648
|
-
}), null), f(
|
|
648
|
+
}), null), f(H, m(_, {
|
|
649
649
|
get when() {
|
|
650
650
|
return l();
|
|
651
651
|
},
|
package/package.json
CHANGED
package/src/frame.tsx
CHANGED
|
@@ -115,8 +115,7 @@ export function StandaloneApp<D>(props: { tool: ToolRegistration<D>; config?: St
|
|
|
115
115
|
return tool.isDocReady ? tool.isDocReady(d) : !!d;
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
-
let docHandle = repo.find<D>(url);
|
|
119
|
-
await docHandle.whenReady();
|
|
118
|
+
let docHandle = await repo.find<D>(url);
|
|
120
119
|
if (gen !== loadGeneration) return;
|
|
121
120
|
|
|
122
121
|
if (!isDocReady(docHandle)) {
|
|
@@ -125,8 +124,7 @@ export function StandaloneApp<D>(props: { tool: ToolRegistration<D>; config?: St
|
|
|
125
124
|
await new Promise((r) => setTimeout(r, 100));
|
|
126
125
|
if (gen !== loadGeneration) return;
|
|
127
126
|
|
|
128
|
-
docHandle = repo.find<D>(url);
|
|
129
|
-
await docHandle.whenReady();
|
|
127
|
+
docHandle = await repo.find<D>(url);
|
|
130
128
|
if (gen !== loadGeneration) return;
|
|
131
129
|
}
|
|
132
130
|
|
package/src/index.ts
CHANGED
|
@@ -18,18 +18,17 @@ export interface ToolRegistration<D = unknown> {
|
|
|
18
18
|
render: (handle: DocHandle<D>, element: ToolElement) => (() => void);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/** Duck-typed doc handle — structurally compatible with automerge-repo DocHandle */
|
|
21
|
+
/** Duck-typed doc handle — structurally compatible with automerge-repo 2.5.x DocHandle */
|
|
22
22
|
export interface FrameDocHandle<D = unknown> {
|
|
23
23
|
url: string;
|
|
24
24
|
doc(): D | undefined;
|
|
25
|
-
whenReady(): Promise<unknown>;
|
|
26
25
|
on(event: string, cb: (...args: unknown[]) => void): void;
|
|
27
26
|
off(event: string, cb: (...args: unknown[]) => void): void;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
/** Duck-typed repo — structurally compatible with automerge-repo Repo */
|
|
29
|
+
/** Duck-typed repo — structurally compatible with automerge-repo 2.5.x Repo */
|
|
31
30
|
export interface FrameRepo {
|
|
32
|
-
find<D = unknown>(url: string): FrameDocHandle<D
|
|
31
|
+
find<D = unknown>(url: string): Promise<FrameDocHandle<D>>;
|
|
33
32
|
create<D = unknown>(initialValue: D): FrameDocHandle<D>;
|
|
34
33
|
delete(url: string): void;
|
|
35
34
|
}
|