@vibecook/truffle-react 0.4.1 → 0.4.2
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/use-crdt-doc.d.ts +54 -0
- package/dist/use-crdt-doc.d.ts.map +1 -0
- package/dist/use-crdt-doc.js +85 -0
- package/dist/use-crdt-doc.js.map +1 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { useMesh, type UseMeshResult } from './use-mesh.js';
|
|
2
2
|
export { useAuth, type UseAuthResult, type AuthStatus } from './use-auth.js';
|
|
3
3
|
export { useSyncedStore, type UseSyncedStoreResult, type Slice, type StoreEvent, } from './use-synced-store.js';
|
|
4
|
+
export { useCrdtDoc, type UseCrdtDocResult } from './use-crdt-doc.js';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,KAAK,EACV,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,KAAK,EACV,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAuC,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,cAAc,GAIf,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAuC,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,cAAc,GAIf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAyB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { NapiNode } from '@vibecook/truffle';
|
|
2
|
+
/** Shape of the NAPI CrdtDoc instance returned by `node.crdtDoc()`. */
|
|
3
|
+
interface NapiCrdtDoc {
|
|
4
|
+
getDeepValue(): Record<string, unknown>;
|
|
5
|
+
commit(): void;
|
|
6
|
+
docId(): string;
|
|
7
|
+
mapInsert(container: string, key: string, value: unknown): void;
|
|
8
|
+
mapDelete(container: string, key: string): void;
|
|
9
|
+
listPush(container: string, value: unknown): void;
|
|
10
|
+
listInsert(container: string, index: number, value: unknown): void;
|
|
11
|
+
listDelete(container: string, index: number, len: number): void;
|
|
12
|
+
textInsert(container: string, pos: number, text: string): void;
|
|
13
|
+
textDelete(container: string, pos: number, len: number): void;
|
|
14
|
+
counterIncrement(container: string, value: number): void;
|
|
15
|
+
onChange(callback: (event: CrdtDocEvent) => void): void;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/** Events emitted by the CRDT document. */
|
|
19
|
+
interface CrdtDocEvent {
|
|
20
|
+
eventType: 'local_change' | 'remote_change' | 'peer_synced' | 'peer_left';
|
|
21
|
+
peerId?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface UseCrdtDocResult {
|
|
24
|
+
/** The NapiCrdtDoc instance, or null before initialization completes. */
|
|
25
|
+
doc: NapiCrdtDoc | null;
|
|
26
|
+
/** Reactive snapshot of the full document state (from `doc.getDeepValue()`). */
|
|
27
|
+
value: Record<string, unknown>;
|
|
28
|
+
/** True after the doc is created and the initial value has been loaded. */
|
|
29
|
+
isReady: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* React hook for a Truffle CRDT document.
|
|
33
|
+
*
|
|
34
|
+
* Provides reactive access to a Loro-backed CRDT document that is
|
|
35
|
+
* automatically synchronized across the mesh. The returned `value`
|
|
36
|
+
* updates on every local or remote change.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* const { doc, value, isReady } = useCrdtDoc(node, 'my-doc');
|
|
41
|
+
*
|
|
42
|
+
* // Write to the document
|
|
43
|
+
* if (doc) {
|
|
44
|
+
* doc.mapInsert('root', 'title', 'Hello');
|
|
45
|
+
* doc.commit();
|
|
46
|
+
* }
|
|
47
|
+
*
|
|
48
|
+
* // Read the reactive state
|
|
49
|
+
* console.log(value); // { root: { title: 'Hello' } }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function useCrdtDoc(node: NapiNode | null, docId: string): UseCrdtDocResult;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=use-crdt-doc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-crdt-doc.d.ts","sourceRoot":"","sources":["../src/use-crdt-doc.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAMlD,uEAAuE;AACvE,UAAU,WAAW;IACnB,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,IAAI,MAAM,CAAC;IAChB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAChE,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAClD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACnE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAChE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/D,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;IACxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,2CAA2C;AAC3C,UAAU,YAAY;IACpB,SAAS,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,GAAG,WAAW,CAAC;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACxB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAmEjF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* React hook for a Truffle CRDT document.
|
|
4
|
+
*
|
|
5
|
+
* Provides reactive access to a Loro-backed CRDT document that is
|
|
6
|
+
* automatically synchronized across the mesh. The returned `value`
|
|
7
|
+
* updates on every local or remote change.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* const { doc, value, isReady } = useCrdtDoc(node, 'my-doc');
|
|
12
|
+
*
|
|
13
|
+
* // Write to the document
|
|
14
|
+
* if (doc) {
|
|
15
|
+
* doc.mapInsert('root', 'title', 'Hello');
|
|
16
|
+
* doc.commit();
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* // Read the reactive state
|
|
20
|
+
* console.log(value); // { root: { title: 'Hello' } }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function useCrdtDoc(node, docId) {
|
|
24
|
+
const [doc, setDoc] = useState(null);
|
|
25
|
+
const [value, setValue] = useState({});
|
|
26
|
+
const [isReady, setIsReady] = useState(false);
|
|
27
|
+
const docRef = useRef(null);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!node) {
|
|
30
|
+
setDoc(null);
|
|
31
|
+
setValue({});
|
|
32
|
+
setIsReady(false);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
let cancelled = false;
|
|
36
|
+
// Track the pending doc so cleanup can reach it even if the await
|
|
37
|
+
// hasn't resolved yet (fixes leak on rapid node/docId changes).
|
|
38
|
+
let pendingDoc = null;
|
|
39
|
+
const init = async () => {
|
|
40
|
+
try {
|
|
41
|
+
// `crdtDoc` is not in the generated .d.ts yet (it was added after
|
|
42
|
+
// the last NAPI binding generation), so we cast through `any`.
|
|
43
|
+
const d = node.crdtDoc(docId);
|
|
44
|
+
pendingDoc = d;
|
|
45
|
+
if (cancelled) {
|
|
46
|
+
await d.stop();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
docRef.current = d;
|
|
50
|
+
setDoc(d);
|
|
51
|
+
// Load initial value
|
|
52
|
+
const initial = d.getDeepValue();
|
|
53
|
+
if (!cancelled) {
|
|
54
|
+
setValue(initial ?? {});
|
|
55
|
+
setIsReady(true);
|
|
56
|
+
}
|
|
57
|
+
// Subscribe to local + remote changes
|
|
58
|
+
d.onChange((_event) => {
|
|
59
|
+
if (cancelled)
|
|
60
|
+
return;
|
|
61
|
+
const updated = d.getDeepValue();
|
|
62
|
+
setValue(updated ?? {});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.error('useCrdtDoc: failed to initialize', err);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
init();
|
|
70
|
+
return () => {
|
|
71
|
+
cancelled = true;
|
|
72
|
+
const docToStop = docRef.current ?? pendingDoc;
|
|
73
|
+
if (docToStop) {
|
|
74
|
+
docToStop.stop().catch(() => { });
|
|
75
|
+
}
|
|
76
|
+
docRef.current = null;
|
|
77
|
+
pendingDoc = null;
|
|
78
|
+
setDoc(null);
|
|
79
|
+
setValue({});
|
|
80
|
+
setIsReady(false);
|
|
81
|
+
};
|
|
82
|
+
}, [node, docId]);
|
|
83
|
+
return { doc, value, isReady };
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=use-crdt-doc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-crdt-doc.js","sourceRoot":"","sources":["../src/use-crdt-doc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAuCpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAqB,EAAE,KAAa;IAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IACzD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAA0B,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,QAAQ,CAAC,EAAE,CAAC,CAAC;YACb,UAAU,CAAC,KAAK,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,kEAAkE;QAClE,gEAAgE;QAChE,IAAI,UAAU,GAAuB,IAAI,CAAC;QAE1C,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;YACtB,IAAI,CAAC;gBACH,kEAAkE;gBAClE,+DAA+D;gBAC/D,MAAM,CAAC,GAAiB,IAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACpD,UAAU,GAAG,CAAC,CAAC;gBACf,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;gBACnB,MAAM,CAAC,CAAC,CAAC,CAAC;gBAEV,qBAAqB;gBACrB,MAAM,OAAO,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC;gBACjC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;oBACxB,UAAU,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC;gBAED,sCAAsC;gBACtC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAoB,EAAE,EAAE;oBAClC,IAAI,SAAS;wBAAE,OAAO;oBACtB,MAAM,OAAO,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC;oBACjC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;YACzD,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,EAAE,CAAC;QAEP,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,IAAI,UAAU,CAAC;YAC/C,IAAI,SAAS,EAAE,CAAC;gBACd,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnC,CAAC;YACD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;YACtB,UAAU,GAAG,IAAI,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,QAAQ,CAAC,EAAE,CAAC,CAAC;YACb,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAElB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACjC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibecook/truffle-react",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "React hooks for Truffle mesh networking",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "James Yong",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dist"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@vibecook/truffle": "0.4.
|
|
45
|
+
"@vibecook/truffle": "0.4.2"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"react": ">=18"
|