@dabble/patches 0.7.6 → 0.7.8
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/{BaseDoc-DkP3tUhT.d.ts → BaseDoc-_Rsau70J.d.ts} +9 -9
- package/dist/algorithms/lww/consolidateOps.d.ts +1 -1
- package/dist/algorithms/lww/consolidateOps.js +42 -0
- package/dist/client/BaseDoc.d.ts +1 -1
- package/dist/client/BaseDoc.js +2 -2
- package/dist/client/ClientAlgorithm.d.ts +1 -1
- package/dist/client/IndexedDBStore.d.ts +11 -11
- package/dist/client/IndexedDBStore.js +14 -14
- package/dist/client/LWWAlgorithm.d.ts +1 -1
- package/dist/client/LWWDoc.d.ts +3 -3
- package/dist/client/LWWIndexedDBStore.d.ts +1 -1
- package/dist/client/OTAlgorithm.d.ts +1 -1
- package/dist/client/OTDoc.d.ts +1 -1
- package/dist/client/OTIndexedDBStore.d.ts +1 -1
- package/dist/client/Patches.d.ts +12 -6
- package/dist/client/PatchesDoc.d.ts +1 -1
- package/dist/client/factories.d.ts +1 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/net/PatchesClient.d.ts +1 -1
- package/dist/net/PatchesClient.js +2 -2
- package/dist/net/PatchesSync.d.ts +1 -1
- package/dist/net/index.d.ts +1 -1
- package/dist/net/protocol/JSONRPCClient.js +2 -0
- package/dist/net/protocol/JSONRPCServer.js +7 -1
- package/dist/net/protocol/types.d.ts +1 -1
- package/dist/net/websocket/WebSocketServer.d.ts +4 -10
- package/dist/net/websocket/WebSocketServer.js +5 -9
- package/dist/server/LWWBranchManager.d.ts +2 -2
- package/dist/server/LWWBranchManager.js +3 -3
- package/dist/server/OTBranchManager.d.ts +1 -1
- package/dist/server/OTBranchManager.js +2 -2
- package/dist/server/branchUtils.d.ts +1 -1
- package/dist/server/branchUtils.js +2 -2
- package/dist/shared/doc-manager.d.ts +3 -3
- package/dist/shared/doc-manager.js +2 -2
- package/dist/solid/context.d.ts +1 -1
- package/dist/solid/doc-manager.d.ts +1 -1
- package/dist/solid/index.d.ts +1 -1
- package/dist/solid/primitives.d.ts +10 -5
- package/dist/solid/primitives.js +80 -132
- package/dist/vue/composables.d.ts +9 -4
- package/dist/vue/composables.js +93 -148
- package/dist/vue/doc-manager.d.ts +1 -1
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/managed-docs.d.ts +10 -1
- package/dist/vue/managed-docs.js +3 -2
- package/dist/vue/provider.d.ts +1 -1
- package/package.json +1 -1
|
@@ -39,19 +39,17 @@ class WebSocketServer {
|
|
|
39
39
|
/**
|
|
40
40
|
* Subscribes the client to one or more documents to receive real-time updates.
|
|
41
41
|
* If a document has been deleted (tombstone exists), sends immediate docDeleted notification.
|
|
42
|
-
* @param
|
|
43
|
-
* @param params.ids - Document ID or IDs to subscribe to
|
|
42
|
+
* @param ids - Document ID or IDs to subscribe to
|
|
44
43
|
*/
|
|
45
|
-
async subscribe(
|
|
44
|
+
async subscribe(ids) {
|
|
46
45
|
const ctx = getAuthContext();
|
|
47
46
|
if (!ctx?.clientId) return [];
|
|
48
|
-
const { ids } = params;
|
|
49
47
|
const allIds = Array.isArray(ids) ? ids : [ids];
|
|
50
48
|
const allowed = [];
|
|
51
49
|
await Promise.all(
|
|
52
50
|
allIds.map(async (id) => {
|
|
53
51
|
try {
|
|
54
|
-
if (await this.auth.canAccess(ctx, id, "read", "subscribe"
|
|
52
|
+
if (await this.auth.canAccess(ctx, id, "read", "subscribe")) {
|
|
55
53
|
allowed.push(id);
|
|
56
54
|
}
|
|
57
55
|
} catch (err) {
|
|
@@ -75,13 +73,11 @@ class WebSocketServer {
|
|
|
75
73
|
}
|
|
76
74
|
/**
|
|
77
75
|
* Unsubscribes the client from one or more documents.
|
|
78
|
-
* @param
|
|
79
|
-
* @param params.ids - Document ID or IDs to unsubscribe from
|
|
76
|
+
* @param ids - Document ID or IDs to unsubscribe from
|
|
80
77
|
*/
|
|
81
|
-
async unsubscribe(
|
|
78
|
+
async unsubscribe(ids) {
|
|
82
79
|
const ctx = getAuthContext();
|
|
83
80
|
if (!ctx?.clientId) return [];
|
|
84
|
-
const { ids } = params;
|
|
85
81
|
return this.transport.removeSubscription(ctx.clientId, Array.isArray(ids) ? ids : [ids]);
|
|
86
82
|
}
|
|
87
83
|
}
|
|
@@ -64,11 +64,11 @@ declare class LWWBranchManager implements BranchManager {
|
|
|
64
64
|
* @param branchId - The branch document ID.
|
|
65
65
|
* @param status - The status to set (defaults to 'closed').
|
|
66
66
|
*/
|
|
67
|
-
closeBranch(branchId: string, status?: Exclude<BranchStatus, 'open'>): Promise<void>;
|
|
67
|
+
closeBranch(branchId: string, status?: Exclude<BranchStatus, 'open'> | null): Promise<void>;
|
|
68
68
|
/**
|
|
69
69
|
* Merges a branch back into its source document.
|
|
70
70
|
*
|
|
71
|
-
* LWW merge
|
|
71
|
+
* LWW merge algorithm:
|
|
72
72
|
* 1. Get all ops changes made on the branch since it was created
|
|
73
73
|
* 2. Apply those changes to the source document
|
|
74
74
|
* 3. Timestamps automatically resolve any conflicts (later wins)
|
|
@@ -61,13 +61,13 @@ class LWWBranchManager {
|
|
|
61
61
|
* @param branchId - The branch document ID.
|
|
62
62
|
* @param status - The status to set (defaults to 'closed').
|
|
63
63
|
*/
|
|
64
|
-
async closeBranch(branchId, status
|
|
65
|
-
await this.store.updateBranch(branchId, { status });
|
|
64
|
+
async closeBranch(branchId, status) {
|
|
65
|
+
await this.store.updateBranch(branchId, { status: status ?? "closed" });
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Merges a branch back into its source document.
|
|
69
69
|
*
|
|
70
|
-
* LWW merge
|
|
70
|
+
* LWW merge algorithm:
|
|
71
71
|
* 1. Get all ops changes made on the branch since it was created
|
|
72
72
|
* 2. Apply those changes to the source document
|
|
73
73
|
* 3. Timestamps automatically resolve any conflicts (later wins)
|
|
@@ -60,7 +60,7 @@ declare class OTBranchManager implements BranchManager {
|
|
|
60
60
|
* @param branchId - The ID of the branch to close.
|
|
61
61
|
* @param status - The status to set for the branch.
|
|
62
62
|
*/
|
|
63
|
-
closeBranch(branchId: string, status?: Exclude<BranchStatus, 'open'>): Promise<void>;
|
|
63
|
+
closeBranch(branchId: string, status?: Exclude<BranchStatus, 'open'> | null): Promise<void>;
|
|
64
64
|
/**
|
|
65
65
|
* Merges changes from a branch back into its source document.
|
|
66
66
|
* @param branchId - The ID of the branch document to merge.
|
|
@@ -70,8 +70,8 @@ class OTBranchManager {
|
|
|
70
70
|
* @param branchId - The ID of the branch to close.
|
|
71
71
|
* @param status - The status to set for the branch.
|
|
72
72
|
*/
|
|
73
|
-
async closeBranch(branchId, status
|
|
74
|
-
await this.store.updateBranch(branchId, { status });
|
|
73
|
+
async closeBranch(branchId, status) {
|
|
74
|
+
await this.store.updateBranch(branchId, { status: status ?? "closed" });
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Merges changes from a branch back into its source document.
|
|
@@ -77,6 +77,6 @@ declare function wrapMergeCommit<T>(branchId: string, sourceDocId: string, commi
|
|
|
77
77
|
*/
|
|
78
78
|
declare function closeBranch(store: {
|
|
79
79
|
updateBranch(branchId: string, updates: Partial<Pick<Branch, 'status' | 'name'>>): Promise<void>;
|
|
80
|
-
}, branchId: string, status?: Exclude<BranchStatus, 'open'>): Promise<void>;
|
|
80
|
+
}, branchId: string, status?: Exclude<BranchStatus, 'open'> | null): Promise<void>;
|
|
81
81
|
|
|
82
82
|
export { type BranchIdGenerator, type BranchLoader, assertBranchMetadata, assertBranchOpenForMerge, assertNotABranch, branchManagerApi, closeBranch, createBranchRecord, generateBranchId, wrapMergeCommit };
|
|
@@ -51,8 +51,8 @@ async function wrapMergeCommit(branchId, sourceDocId, commitFn) {
|
|
|
51
51
|
throw new Error(`Merge failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
async function closeBranch(store, branchId, status
|
|
55
|
-
await store.updateBranch(branchId, { status });
|
|
54
|
+
async function closeBranch(store, branchId, status) {
|
|
55
|
+
await store.updateBranch(branchId, { status: status ?? "closed" });
|
|
56
56
|
}
|
|
57
57
|
export {
|
|
58
58
|
assertBranchMetadata,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Patches } from '../client/Patches.js';
|
|
2
|
-
import { a as PatchesDoc } from '../BaseDoc-
|
|
1
|
+
import { Patches, OpenDocOptions } from '../client/Patches.js';
|
|
2
|
+
import { a as PatchesDoc } from '../BaseDoc-_Rsau70J.js';
|
|
3
3
|
import '../event-signal.js';
|
|
4
4
|
import '../json-patch/types.js';
|
|
5
5
|
import '../types.js';
|
|
@@ -31,7 +31,7 @@ declare class DocManager {
|
|
|
31
31
|
* @param docId - Document ID to open
|
|
32
32
|
* @returns Promise resolving to PatchesDoc instance
|
|
33
33
|
*/
|
|
34
|
-
openDoc<T extends object>(patches: Patches, docId: string): Promise<PatchesDoc<T>>;
|
|
34
|
+
openDoc<T extends object>(patches: Patches, docId: string, opts?: OpenDocOptions): Promise<PatchesDoc<T>>;
|
|
35
35
|
/**
|
|
36
36
|
* Closes a document with reference counting.
|
|
37
37
|
*
|
|
@@ -13,7 +13,7 @@ class DocManager {
|
|
|
13
13
|
* @param docId - Document ID to open
|
|
14
14
|
* @returns Promise resolving to PatchesDoc instance
|
|
15
15
|
*/
|
|
16
|
-
async openDoc(patches, docId) {
|
|
16
|
+
async openDoc(patches, docId, opts) {
|
|
17
17
|
const currentCount = this.refCounts.get(docId) || 0;
|
|
18
18
|
if (currentCount === 0 && this.pendingOps.has(docId)) {
|
|
19
19
|
const doc = await this.pendingOps.get(docId);
|
|
@@ -28,7 +28,7 @@ class DocManager {
|
|
|
28
28
|
}
|
|
29
29
|
return doc;
|
|
30
30
|
}
|
|
31
|
-
const openPromise = patches.openDoc(docId);
|
|
31
|
+
const openPromise = patches.openDoc(docId, opts);
|
|
32
32
|
this.pendingOps.set(docId, openPromise);
|
|
33
33
|
try {
|
|
34
34
|
const doc = await openPromise;
|
package/dist/solid/context.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import '../types.js';
|
|
|
7
7
|
import '../json-patch/JSONPatch.js';
|
|
8
8
|
import '@dabble/delta';
|
|
9
9
|
import '../client/ClientAlgorithm.js';
|
|
10
|
-
import '../BaseDoc-
|
|
10
|
+
import '../BaseDoc-_Rsau70J.js';
|
|
11
11
|
import '../client/PatchesStore.js';
|
|
12
12
|
import '../net/protocol/types.js';
|
|
13
13
|
import '../net/protocol/JSONRPCClient.js';
|
package/dist/solid/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import '../types.js';
|
|
|
11
11
|
import '../json-patch/JSONPatch.js';
|
|
12
12
|
import '@dabble/delta';
|
|
13
13
|
import '../client/ClientAlgorithm.js';
|
|
14
|
-
import '../BaseDoc-
|
|
14
|
+
import '../BaseDoc-_Rsau70J.js';
|
|
15
15
|
import '../client/PatchesStore.js';
|
|
16
16
|
import '../net/PatchesSync.js';
|
|
17
17
|
import '../net/protocol/types.js';
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { Accessor } from 'solid-js';
|
|
2
|
-
import {
|
|
2
|
+
import { OpenDocOptions } from '../client/Patches.js';
|
|
3
|
+
import { a as PatchesDoc } from '../BaseDoc-_Rsau70J.js';
|
|
3
4
|
import { JSONPatch } from '../json-patch/JSONPatch.js';
|
|
4
5
|
import { ChangeMutator } from '../types.js';
|
|
5
6
|
import '../event-signal.js';
|
|
6
7
|
import '../json-patch/types.js';
|
|
8
|
+
import '../client/ClientAlgorithm.js';
|
|
9
|
+
import '../client/PatchesStore.js';
|
|
7
10
|
import '@dabble/delta';
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Options for usePatchesDoc primitive (eager mode with docId).
|
|
11
14
|
*/
|
|
12
|
-
interface UsePatchesDocOptions {
|
|
15
|
+
interface UsePatchesDocOptions extends OpenDocOptions {
|
|
13
16
|
/**
|
|
14
17
|
* Controls document lifecycle management on cleanup.
|
|
15
18
|
*
|
|
@@ -89,8 +92,9 @@ interface UsePatchesDocLazyReturn<T extends object> extends UsePatchesDocReturn<
|
|
|
89
92
|
* Open a document by path. Closes any previously loaded document first.
|
|
90
93
|
*
|
|
91
94
|
* @param docPath - The document path to open
|
|
95
|
+
* @param options - Optional algorithm and metadata overrides
|
|
92
96
|
*/
|
|
93
|
-
load: (docPath: string) => Promise<void>;
|
|
97
|
+
load: (docPath: string, options?: OpenDocOptions) => Promise<void>;
|
|
94
98
|
/**
|
|
95
99
|
* Close the current document, unsubscribe, and reset all state.
|
|
96
100
|
* Calls `patches.closeDoc()` but does not untrack — tracking is managed separately.
|
|
@@ -102,8 +106,9 @@ interface UsePatchesDocLazyReturn<T extends object> extends UsePatchesDocReturn<
|
|
|
102
106
|
*
|
|
103
107
|
* @param docPath - The document path to create
|
|
104
108
|
* @param initialState - Initial state object or JSONPatch to apply
|
|
109
|
+
* @param options - Optional algorithm and metadata overrides
|
|
105
110
|
*/
|
|
106
|
-
create: (docPath: string, initialState: T | JSONPatch) => Promise<void>;
|
|
111
|
+
create: (docPath: string, initialState: T | JSONPatch, options?: OpenDocOptions) => Promise<void>;
|
|
107
112
|
}
|
|
108
113
|
/**
|
|
109
114
|
* Solid primitive for reactive Patches document state.
|
|
@@ -185,7 +190,7 @@ type MaybeAccessor<T> = T | Accessor<T>;
|
|
|
185
190
|
/**
|
|
186
191
|
* Props for the Provider component returned by createPatchesDoc.
|
|
187
192
|
*/
|
|
188
|
-
interface PatchesDocProviderProps {
|
|
193
|
+
interface PatchesDocProviderProps extends OpenDocOptions {
|
|
189
194
|
docId: MaybeAccessor<string>;
|
|
190
195
|
autoClose?: boolean | 'untrack';
|
|
191
196
|
children: any;
|
package/dist/solid/primitives.js
CHANGED
|
@@ -10,47 +10,87 @@ import {
|
|
|
10
10
|
import { JSONPatch } from "../json-patch/JSONPatch.js";
|
|
11
11
|
import { usePatchesContext } from "./context.js";
|
|
12
12
|
import { getDocManager } from "./doc-manager.js";
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
return _usePatchesDocEager(docIdOrOptions, options ?? {});
|
|
16
|
-
}
|
|
17
|
-
return _usePatchesDocLazy(docIdOrOptions ?? {});
|
|
18
|
-
}
|
|
19
|
-
function _usePatchesDocEager(docId, options) {
|
|
20
|
-
const { patches } = usePatchesContext();
|
|
21
|
-
const autoClose = options.autoClose ?? false;
|
|
22
|
-
const shouldUntrack = autoClose === "untrack";
|
|
13
|
+
function createDocReactiveState(options) {
|
|
14
|
+
const { initialLoading = true, transformState, changeBehavior } = options;
|
|
23
15
|
const [doc, setDoc] = createSignal(void 0);
|
|
24
16
|
const [data, setData] = createSignal(void 0);
|
|
25
|
-
const [loading, setLoading] = createSignal(
|
|
17
|
+
const [loading, setLoading] = createSignal(initialLoading);
|
|
26
18
|
const [error, setError] = createSignal(null);
|
|
27
19
|
const [rev, setRev] = createSignal(0);
|
|
28
20
|
const [hasPending, setHasPending] = createSignal(false);
|
|
29
|
-
const manager = getDocManager(patches);
|
|
30
|
-
const docIdAccessor = toAccessor(docId);
|
|
31
21
|
function setupDoc(patchesDoc) {
|
|
32
22
|
setDoc(patchesDoc);
|
|
33
23
|
const unsubState = patchesDoc.subscribe((state) => {
|
|
24
|
+
if (transformState && state) {
|
|
25
|
+
state = transformState(state, patchesDoc);
|
|
26
|
+
}
|
|
34
27
|
setData(() => state);
|
|
35
28
|
setRev(patchesDoc.committedRev);
|
|
36
29
|
setHasPending(patchesDoc.hasPending);
|
|
37
30
|
});
|
|
38
|
-
onCleanup(() => unsubState());
|
|
39
31
|
const unsubSync = patchesDoc.onSyncing((syncState) => {
|
|
40
32
|
setLoading(syncState === "initial" || syncState === "updating");
|
|
41
33
|
setError(syncState instanceof Error ? syncState : null);
|
|
42
34
|
});
|
|
43
|
-
onCleanup(() => unsubSync());
|
|
44
35
|
setLoading(patchesDoc.syncing !== null);
|
|
36
|
+
return () => {
|
|
37
|
+
unsubState();
|
|
38
|
+
unsubSync();
|
|
39
|
+
};
|
|
45
40
|
}
|
|
41
|
+
function resetSignals() {
|
|
42
|
+
setDoc(void 0);
|
|
43
|
+
setData(void 0);
|
|
44
|
+
setLoading(false);
|
|
45
|
+
setError(null);
|
|
46
|
+
setRev(0);
|
|
47
|
+
setHasPending(false);
|
|
48
|
+
}
|
|
49
|
+
function change(mutator) {
|
|
50
|
+
if (changeBehavior === "throw") {
|
|
51
|
+
const currentDoc = doc();
|
|
52
|
+
if (!currentDoc) {
|
|
53
|
+
throw new Error("Cannot make changes: document not loaded yet");
|
|
54
|
+
}
|
|
55
|
+
currentDoc.change(mutator);
|
|
56
|
+
} else {
|
|
57
|
+
doc()?.change(mutator);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const baseReturn = {
|
|
61
|
+
data,
|
|
62
|
+
loading,
|
|
63
|
+
error,
|
|
64
|
+
rev,
|
|
65
|
+
hasPending,
|
|
66
|
+
change,
|
|
67
|
+
doc
|
|
68
|
+
};
|
|
69
|
+
return { doc, setDoc, data, setData, loading, setLoading, error, setError, rev, setRev, hasPending, setHasPending, setupDoc, resetSignals, change, baseReturn };
|
|
70
|
+
}
|
|
71
|
+
function usePatchesDoc(docIdOrOptions, options) {
|
|
72
|
+
if (typeof docIdOrOptions === "string" || typeof docIdOrOptions === "function") {
|
|
73
|
+
return _usePatchesDocEager(docIdOrOptions, options ?? {});
|
|
74
|
+
}
|
|
75
|
+
return _usePatchesDocLazy(docIdOrOptions ?? {});
|
|
76
|
+
}
|
|
77
|
+
function _usePatchesDocEager(docId, options) {
|
|
78
|
+
const { patches } = usePatchesContext();
|
|
79
|
+
const { autoClose = false, algorithm, metadata } = options;
|
|
80
|
+
const shouldUntrack = autoClose === "untrack";
|
|
81
|
+
const openDocOpts = { algorithm, metadata };
|
|
82
|
+
const manager = getDocManager(patches);
|
|
83
|
+
const { setupDoc, setError, setLoading, baseReturn } = createDocReactiveState({ changeBehavior: "throw" });
|
|
84
|
+
const docIdAccessor = toAccessor(docId);
|
|
46
85
|
if (autoClose) {
|
|
47
86
|
const [docResource] = createResource(docIdAccessor, async (id) => {
|
|
48
|
-
return await manager.openDoc(patches, id);
|
|
87
|
+
return await manager.openDoc(patches, id, openDocOpts);
|
|
49
88
|
});
|
|
50
89
|
createEffect(() => {
|
|
51
90
|
const loadedDoc = docResource();
|
|
52
91
|
if (loadedDoc) {
|
|
53
|
-
setupDoc(loadedDoc);
|
|
92
|
+
const unsub = setupDoc(loadedDoc);
|
|
93
|
+
onCleanup(() => unsub());
|
|
54
94
|
}
|
|
55
95
|
const resourceError = docResource.error;
|
|
56
96
|
if (resourceError) {
|
|
@@ -72,75 +112,31 @@ function _usePatchesDocEager(docId, options) {
|
|
|
72
112
|
);
|
|
73
113
|
}
|
|
74
114
|
manager.incrementRefCount(id);
|
|
75
|
-
setupDoc(patchesDoc);
|
|
115
|
+
const unsub = setupDoc(patchesDoc);
|
|
76
116
|
onCleanup(() => {
|
|
117
|
+
unsub();
|
|
77
118
|
manager.decrementRefCount(id);
|
|
78
119
|
});
|
|
79
120
|
});
|
|
80
121
|
}
|
|
81
|
-
|
|
82
|
-
const currentDoc = doc();
|
|
83
|
-
if (!currentDoc) {
|
|
84
|
-
throw new Error("Cannot make changes: document not loaded yet");
|
|
85
|
-
}
|
|
86
|
-
currentDoc.change(mutator);
|
|
87
|
-
}
|
|
88
|
-
return {
|
|
89
|
-
data,
|
|
90
|
-
loading,
|
|
91
|
-
error,
|
|
92
|
-
rev,
|
|
93
|
-
hasPending,
|
|
94
|
-
change,
|
|
95
|
-
doc
|
|
96
|
-
};
|
|
122
|
+
return baseReturn;
|
|
97
123
|
}
|
|
98
124
|
function _usePatchesDocLazy(options) {
|
|
99
125
|
const { patches } = usePatchesContext();
|
|
100
126
|
const { idProp } = options;
|
|
101
|
-
|
|
127
|
+
const { setupDoc, resetSignals, setError, setLoading, baseReturn } = createDocReactiveState({
|
|
128
|
+
initialLoading: false,
|
|
129
|
+
changeBehavior: "noop",
|
|
130
|
+
transformState: idProp ? (state, patchesDoc) => ({ ...state, [idProp]: patchesDoc.id }) : void 0
|
|
131
|
+
});
|
|
102
132
|
let unsubscribe = null;
|
|
103
133
|
const [path, setPath] = createSignal(null);
|
|
104
|
-
const [doc, setDoc] = createSignal(void 0);
|
|
105
|
-
const [data, setData] = createSignal(void 0);
|
|
106
|
-
const [loading, setLoading] = createSignal(false);
|
|
107
|
-
const [error, setError] = createSignal(null);
|
|
108
|
-
const [rev, setRev] = createSignal(0);
|
|
109
|
-
const [hasPending, setHasPending] = createSignal(false);
|
|
110
|
-
function setupDoc(patchesDoc) {
|
|
111
|
-
currentDoc = patchesDoc;
|
|
112
|
-
setDoc(patchesDoc);
|
|
113
|
-
unsubscribe = patchesDoc.subscribe((state) => {
|
|
114
|
-
if (state && idProp && currentDoc) {
|
|
115
|
-
state = { ...state, [idProp]: currentDoc.id };
|
|
116
|
-
}
|
|
117
|
-
setData(() => state);
|
|
118
|
-
setRev(patchesDoc.committedRev);
|
|
119
|
-
setHasPending(patchesDoc.hasPending);
|
|
120
|
-
});
|
|
121
|
-
const unsubSync = patchesDoc.onSyncing((syncState) => {
|
|
122
|
-
setLoading(syncState === "initial" || syncState === "updating");
|
|
123
|
-
setError(syncState instanceof Error ? syncState : null);
|
|
124
|
-
});
|
|
125
|
-
const origUnsub = unsubscribe;
|
|
126
|
-
unsubscribe = () => {
|
|
127
|
-
origUnsub();
|
|
128
|
-
unsubSync();
|
|
129
|
-
};
|
|
130
|
-
setLoading(patchesDoc.syncing !== null);
|
|
131
|
-
}
|
|
132
134
|
function teardown() {
|
|
133
135
|
unsubscribe?.();
|
|
134
136
|
unsubscribe = null;
|
|
135
|
-
|
|
136
|
-
setDoc(void 0);
|
|
137
|
-
setData(void 0);
|
|
138
|
-
setLoading(false);
|
|
139
|
-
setError(null);
|
|
140
|
-
setRev(0);
|
|
141
|
-
setHasPending(false);
|
|
137
|
+
resetSignals();
|
|
142
138
|
}
|
|
143
|
-
async function load(docPath) {
|
|
139
|
+
async function load(docPath, options2) {
|
|
144
140
|
if (path()) {
|
|
145
141
|
const prevPath = path();
|
|
146
142
|
teardown();
|
|
@@ -148,8 +144,8 @@ function _usePatchesDocLazy(options) {
|
|
|
148
144
|
}
|
|
149
145
|
setPath(docPath);
|
|
150
146
|
try {
|
|
151
|
-
const patchesDoc = await patches.openDoc(docPath);
|
|
152
|
-
setupDoc(patchesDoc);
|
|
147
|
+
const patchesDoc = await patches.openDoc(docPath, options2);
|
|
148
|
+
unsubscribe = setupDoc(patchesDoc);
|
|
153
149
|
} catch (err) {
|
|
154
150
|
setError(err);
|
|
155
151
|
setLoading(false);
|
|
@@ -163,8 +159,8 @@ function _usePatchesDocLazy(options) {
|
|
|
163
159
|
await patches.closeDoc(prevPath);
|
|
164
160
|
}
|
|
165
161
|
}
|
|
166
|
-
async function create(docPath, initialState) {
|
|
167
|
-
const newDoc = await patches.openDoc(docPath);
|
|
162
|
+
async function create(docPath, initialState, options2) {
|
|
163
|
+
const newDoc = await patches.openDoc(docPath, options2);
|
|
168
164
|
newDoc.change((patch, root) => {
|
|
169
165
|
if (initialState instanceof JSONPatch) {
|
|
170
166
|
patch.ops = initialState.ops;
|
|
@@ -176,22 +172,7 @@ function _usePatchesDocLazy(options) {
|
|
|
176
172
|
});
|
|
177
173
|
await patches.closeDoc(docPath);
|
|
178
174
|
}
|
|
179
|
-
|
|
180
|
-
currentDoc?.change(mutator);
|
|
181
|
-
}
|
|
182
|
-
return {
|
|
183
|
-
data,
|
|
184
|
-
loading,
|
|
185
|
-
error,
|
|
186
|
-
rev,
|
|
187
|
-
hasPending,
|
|
188
|
-
change,
|
|
189
|
-
doc,
|
|
190
|
-
path,
|
|
191
|
-
load,
|
|
192
|
-
close,
|
|
193
|
-
create
|
|
194
|
-
};
|
|
175
|
+
return { ...baseReturn, path, load, close, create };
|
|
195
176
|
}
|
|
196
177
|
function usePatchesSync() {
|
|
197
178
|
const { sync } = usePatchesContext();
|
|
@@ -225,36 +206,18 @@ function createPatchesDoc(name) {
|
|
|
225
206
|
const manager = getDocManager(patches);
|
|
226
207
|
const autoClose = props.autoClose ?? false;
|
|
227
208
|
const shouldUntrack = autoClose === "untrack";
|
|
228
|
-
const
|
|
229
|
-
const
|
|
230
|
-
const [loading, setLoading] = createSignal(true);
|
|
231
|
-
const [error, setError] = createSignal(null);
|
|
232
|
-
const [rev, setRev] = createSignal(0);
|
|
233
|
-
const [hasPending, setHasPending] = createSignal(false);
|
|
234
|
-
function setupDoc(patchesDoc) {
|
|
235
|
-
setDoc(patchesDoc);
|
|
236
|
-
const unsubState = patchesDoc.subscribe((state) => {
|
|
237
|
-
setData(() => state);
|
|
238
|
-
setRev(patchesDoc.committedRev);
|
|
239
|
-
setHasPending(patchesDoc.hasPending);
|
|
240
|
-
});
|
|
241
|
-
onCleanup(() => unsubState());
|
|
242
|
-
const unsubSync = patchesDoc.onSyncing((syncState) => {
|
|
243
|
-
setLoading(syncState === "initial" || syncState === "updating");
|
|
244
|
-
setError(syncState instanceof Error ? syncState : null);
|
|
245
|
-
});
|
|
246
|
-
onCleanup(() => unsubSync());
|
|
247
|
-
setLoading(patchesDoc.syncing !== null);
|
|
248
|
-
}
|
|
209
|
+
const openDocOpts = { algorithm: props.algorithm, metadata: props.metadata };
|
|
210
|
+
const { setupDoc, setError, setLoading, baseReturn } = createDocReactiveState({ changeBehavior: "throw" });
|
|
249
211
|
const docIdAccessor = toAccessor(props.docId);
|
|
250
212
|
if (autoClose) {
|
|
251
213
|
const [docResource] = createResource(docIdAccessor, async (id) => {
|
|
252
|
-
return await manager.openDoc(patches, id);
|
|
214
|
+
return await manager.openDoc(patches, id, openDocOpts);
|
|
253
215
|
});
|
|
254
216
|
createEffect(() => {
|
|
255
217
|
const loadedDoc = docResource();
|
|
256
218
|
if (loadedDoc) {
|
|
257
|
-
setupDoc(loadedDoc);
|
|
219
|
+
const unsub = setupDoc(loadedDoc);
|
|
220
|
+
onCleanup(() => unsub());
|
|
258
221
|
}
|
|
259
222
|
const resourceError = docResource.error;
|
|
260
223
|
if (resourceError) {
|
|
@@ -286,7 +249,8 @@ function createPatchesDoc(name) {
|
|
|
286
249
|
);
|
|
287
250
|
}
|
|
288
251
|
manager.incrementRefCount(id);
|
|
289
|
-
setupDoc(patchesDoc);
|
|
252
|
+
const unsub = setupDoc(patchesDoc);
|
|
253
|
+
onCleanup(() => unsub());
|
|
290
254
|
return id;
|
|
291
255
|
});
|
|
292
256
|
onCleanup(() => {
|
|
@@ -294,23 +258,7 @@ function createPatchesDoc(name) {
|
|
|
294
258
|
manager.decrementRefCount(id);
|
|
295
259
|
});
|
|
296
260
|
}
|
|
297
|
-
|
|
298
|
-
const currentDoc = doc();
|
|
299
|
-
if (!currentDoc) {
|
|
300
|
-
throw new Error("Cannot make changes: document not loaded yet");
|
|
301
|
-
}
|
|
302
|
-
currentDoc.change(mutator);
|
|
303
|
-
}
|
|
304
|
-
const value = {
|
|
305
|
-
data,
|
|
306
|
-
loading,
|
|
307
|
-
error,
|
|
308
|
-
rev,
|
|
309
|
-
hasPending,
|
|
310
|
-
change,
|
|
311
|
-
doc
|
|
312
|
-
};
|
|
313
|
-
return /* @__PURE__ */ React.createElement(Context.Provider, { value, children: props.children });
|
|
261
|
+
return /* @__PURE__ */ React.createElement(Context.Provider, { value: baseReturn, children: props.children });
|
|
314
262
|
}
|
|
315
263
|
function useDoc() {
|
|
316
264
|
const context = useContext(Context);
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { ShallowRef, Ref, MaybeRef } from 'vue';
|
|
2
|
-
import {
|
|
2
|
+
import { OpenDocOptions } from '../client/Patches.js';
|
|
3
|
+
import { a as PatchesDoc } from '../BaseDoc-_Rsau70J.js';
|
|
3
4
|
import { JSONPatch } from '../json-patch/JSONPatch.js';
|
|
4
5
|
import { ChangeMutator } from '../types.js';
|
|
5
6
|
import '../event-signal.js';
|
|
6
7
|
import '../json-patch/types.js';
|
|
8
|
+
import '../client/ClientAlgorithm.js';
|
|
9
|
+
import '../client/PatchesStore.js';
|
|
7
10
|
import '@dabble/delta';
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Options for usePatchesDoc composable (eager mode with docId).
|
|
11
14
|
*/
|
|
12
|
-
interface UsePatchesDocOptions {
|
|
15
|
+
interface UsePatchesDocOptions extends OpenDocOptions {
|
|
13
16
|
/**
|
|
14
17
|
* Controls document lifecycle management on component unmount.
|
|
15
18
|
*
|
|
@@ -89,8 +92,9 @@ interface UsePatchesDocLazyReturn<T extends object> extends UsePatchesDocReturn<
|
|
|
89
92
|
* Open a document by path. Closes any previously loaded document first.
|
|
90
93
|
*
|
|
91
94
|
* @param docPath - The document path to open
|
|
95
|
+
* @param options - Optional algorithm and metadata overrides
|
|
92
96
|
*/
|
|
93
|
-
load: (docPath: string) => Promise<void>;
|
|
97
|
+
load: (docPath: string, options?: OpenDocOptions) => Promise<void>;
|
|
94
98
|
/**
|
|
95
99
|
* Close the current document, unsubscribe, and reset all state.
|
|
96
100
|
* Calls `patches.closeDoc()` but does not untrack — tracking is managed separately.
|
|
@@ -102,8 +106,9 @@ interface UsePatchesDocLazyReturn<T extends object> extends UsePatchesDocReturn<
|
|
|
102
106
|
*
|
|
103
107
|
* @param docPath - The document path to create
|
|
104
108
|
* @param initialState - Initial state object or JSONPatch to apply
|
|
109
|
+
* @param options - Optional algorithm and metadata overrides
|
|
105
110
|
*/
|
|
106
|
-
create: (docPath: string, initialState: T | JSONPatch) => Promise<void>;
|
|
111
|
+
create: (docPath: string, initialState: T | JSONPatch, options?: OpenDocOptions) => Promise<void>;
|
|
107
112
|
}
|
|
108
113
|
/**
|
|
109
114
|
* Vue composable for reactive Patches document state.
|