@dabble/patches 0.2.7 → 0.2.9

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.
@@ -30,35 +30,87 @@ export declare class Patches {
30
30
  readonly onUntrackDocs: import("../event-signal.js").Signal<(docIds: string[]) => void>;
31
31
  readonly onDeleteDoc: import("../event-signal.js").Signal<(docId: string) => void>;
32
32
  constructor(opts: PatchesOptions);
33
+ /**
34
+ * Tracks the given document IDs, adding them to the set of tracked documents and notifying listeners.
35
+ * Tracked docs are kept in sync with the server, even when not open locally.
36
+ * This allows for background syncing and updates of unopened documents.
37
+ * @param docIds - Array of document IDs to track.
38
+ */
33
39
  trackDocs(docIds: string[]): Promise<void>;
40
+ /**
41
+ * Untracks the given document IDs, removing them from the set of tracked documents and notifying listeners.
42
+ * Untracked docs will no longer be kept in sync with the server, even if not open locally.
43
+ * Closes any open docs and removes them from the store.
44
+ * @param docIds - Array of document IDs to untrack.
45
+ */
34
46
  untrackDocs(docIds: string[]): Promise<void>;
47
+ /**
48
+ * Opens a document by ID, loading its state from the store and setting up change listeners.
49
+ * If the doc is already open, returns the existing instance.
50
+ * @param docId - The document ID to open.
51
+ * @param opts - Optional metadata to merge with the doc's metadata.
52
+ * @returns The opened PatchesDoc instance.
53
+ */
35
54
  openDoc<T extends object>(docId: string, opts?: {
36
55
  metadata?: Record<string, any>;
37
56
  }): Promise<PatchesDoc<T>>;
38
- closeDoc(docId: string): Promise<void>;
57
+ /**
58
+ * Closes an open document by ID, removing listeners and optionally untracking it.
59
+ * @param docId - The document ID to close.
60
+ * @param options - Optional: set untrack to true to also untrack the doc.
61
+ */
62
+ closeDoc(docId: string, { untrack }?: {
63
+ untrack?: boolean;
64
+ }): Promise<void>;
65
+ /**
66
+ * Deletes a document by ID, closing it if open, untracking it, and removing it from the store.
67
+ * Emits the onDeleteDoc signal.
68
+ * @param docId - The document ID to delete.
69
+ */
39
70
  deleteDoc(docId: string): Promise<void>;
40
71
  /**
41
- * Gets all tracked document IDs that are currently open.
42
- * Used by PatchesSync to check which docs need syncing.
72
+ * Gets all tracked document IDs that are currently open in memory.
73
+ * Used by PatchesSync to determine which docs need syncing.
74
+ * @returns Array of open document IDs.
43
75
  */
44
76
  getOpenDocIds(): string[];
45
77
  /**
46
- * Retrieves changes for a document that should be sent to the server.
78
+ * Retrieves local changes for a document that should be sent to the server.
47
79
  * Used by PatchesSync during synchronization.
80
+ * @param docId - The document ID to get changes for.
81
+ * @returns Array of Change objects to send to the server.
48
82
  */
49
83
  getDocChanges(docId: string): Change[];
50
84
  /**
51
- * Handles failure to send changes to the server.
85
+ * Handles a failure to send changes to the server for a given document.
52
86
  * Used by PatchesSync to requeue changes after failures.
87
+ * @param docId - The document ID for which sending failed.
53
88
  */
54
89
  handleSendFailure(docId: string): void;
55
90
  /**
56
- * Apply server changes to a document.
91
+ * Applies server-confirmed changes to a document.
57
92
  * Used by PatchesSync to update documents with server changes.
93
+ * @param docId - The document ID to apply changes to.
94
+ * @param changes - Array of Change objects from the server.
58
95
  */
59
96
  applyServerChanges(docId: string, changes: Change[]): void;
97
+ /**
98
+ * Closes all open documents and cleans up listeners and store connections.
99
+ * Should be called when shutting down the client.
100
+ */
60
101
  close(): void;
102
+ /**
103
+ * Sets up a listener for local changes on a PatchesDoc, saving pending changes to the store.
104
+ * @param docId - The document ID being managed.
105
+ * @param doc - The PatchesDoc instance to listen to.
106
+ * @returns An Unsubscriber function to remove the listener.
107
+ */
61
108
  protected _setupLocalDocListener(docId: string, doc: PatchesDoc<any>): Unsubscriber;
109
+ /**
110
+ * Internal handler for applying server commits to a document and emitting errors if needed.
111
+ * @param docId - The document ID to update.
112
+ * @param changes - Array of Change objects from the server.
113
+ */
62
114
  private _handleServerCommit;
63
115
  }
64
116
  export {};
@@ -15,6 +15,11 @@ export class Patches {
15
15
  this.onTrackDocs = signal();
16
16
  this.onUntrackDocs = signal();
17
17
  this.onDeleteDoc = signal();
18
+ /**
19
+ * Internal handler for applying server commits to a document and emitting errors if needed.
20
+ * @param docId - The document ID to update.
21
+ * @param changes - Array of Change objects from the server.
22
+ */
18
23
  this._handleServerCommit = (docId, changes) => {
19
24
  const managedDoc = this.docs.get(docId);
20
25
  if (managedDoc) {
@@ -36,6 +41,12 @@ export class Patches {
36
41
  });
37
42
  }
38
43
  // --- Public API Methods ---
44
+ /**
45
+ * Tracks the given document IDs, adding them to the set of tracked documents and notifying listeners.
46
+ * Tracked docs are kept in sync with the server, even when not open locally.
47
+ * This allows for background syncing and updates of unopened documents.
48
+ * @param docIds - Array of document IDs to track.
49
+ */
39
50
  async trackDocs(docIds) {
40
51
  docIds = docIds.filter(id => !this.trackedDocs.has(id));
41
52
  if (!docIds.length)
@@ -44,6 +55,12 @@ export class Patches {
44
55
  this.onTrackDocs.emit(docIds);
45
56
  await this.store.trackDocs(docIds);
46
57
  }
58
+ /**
59
+ * Untracks the given document IDs, removing them from the set of tracked documents and notifying listeners.
60
+ * Untracked docs will no longer be kept in sync with the server, even if not open locally.
61
+ * Closes any open docs and removes them from the store.
62
+ * @param docIds - Array of document IDs to untrack.
63
+ */
47
64
  async untrackDocs(docIds) {
48
65
  docIds = docIds.filter(id => this.trackedDocs.has(id));
49
66
  if (!docIds.length)
@@ -56,10 +73,19 @@ export class Patches {
56
73
  // Remove from store
57
74
  await this.store.untrackDocs(docIds);
58
75
  }
76
+ /**
77
+ * Opens a document by ID, loading its state from the store and setting up change listeners.
78
+ * If the doc is already open, returns the existing instance.
79
+ * @param docId - The document ID to open.
80
+ * @param opts - Optional metadata to merge with the doc's metadata.
81
+ * @returns The opened PatchesDoc instance.
82
+ */
59
83
  async openDoc(docId, opts = {}) {
60
84
  const existing = this.docs.get(docId);
61
85
  if (existing)
62
86
  return existing.doc;
87
+ // Ensure the doc is tracked before proceeding
88
+ await this.trackDocs([docId]);
63
89
  // Load initial state from store
64
90
  const snapshot = await this.store.getDoc(docId);
65
91
  const initialState = (snapshot?.state ?? {});
@@ -74,13 +100,26 @@ export class Patches {
74
100
  this.docs.set(docId, { doc, onChangeUnsubscriber: unsub });
75
101
  return doc;
76
102
  }
77
- async closeDoc(docId) {
103
+ /**
104
+ * Closes an open document by ID, removing listeners and optionally untracking it.
105
+ * @param docId - The document ID to close.
106
+ * @param options - Optional: set untrack to true to also untrack the doc.
107
+ */
108
+ async closeDoc(docId, { untrack = false } = {}) {
78
109
  const managed = this.docs.get(docId);
79
110
  if (managed) {
80
111
  managed.onChangeUnsubscriber();
81
112
  this.docs.delete(docId);
113
+ if (untrack) {
114
+ await this.untrackDocs([docId]);
115
+ }
82
116
  }
83
117
  }
118
+ /**
119
+ * Deletes a document by ID, closing it if open, untracking it, and removing it from the store.
120
+ * Emits the onDeleteDoc signal.
121
+ * @param docId - The document ID to delete.
122
+ */
84
123
  async deleteDoc(docId) {
85
124
  // Close if open locally
86
125
  if (this.docs.has(docId)) {
@@ -95,15 +134,18 @@ export class Patches {
95
134
  this.onDeleteDoc.emit(docId);
96
135
  }
97
136
  /**
98
- * Gets all tracked document IDs that are currently open.
99
- * Used by PatchesSync to check which docs need syncing.
137
+ * Gets all tracked document IDs that are currently open in memory.
138
+ * Used by PatchesSync to determine which docs need syncing.
139
+ * @returns Array of open document IDs.
100
140
  */
101
141
  getOpenDocIds() {
102
142
  return Array.from(this.docs.keys());
103
143
  }
104
144
  /**
105
- * Retrieves changes for a document that should be sent to the server.
145
+ * Retrieves local changes for a document that should be sent to the server.
106
146
  * Used by PatchesSync during synchronization.
147
+ * @param docId - The document ID to get changes for.
148
+ * @returns Array of Change objects to send to the server.
107
149
  */
108
150
  getDocChanges(docId) {
109
151
  const doc = this.docs.get(docId)?.doc;
@@ -119,8 +161,9 @@ export class Patches {
119
161
  }
120
162
  }
121
163
  /**
122
- * Handles failure to send changes to the server.
164
+ * Handles a failure to send changes to the server for a given document.
123
165
  * Used by PatchesSync to requeue changes after failures.
166
+ * @param docId - The document ID for which sending failed.
124
167
  */
125
168
  handleSendFailure(docId) {
126
169
  const doc = this.docs.get(docId)?.doc;
@@ -129,12 +172,18 @@ export class Patches {
129
172
  }
130
173
  }
131
174
  /**
132
- * Apply server changes to a document.
175
+ * Applies server-confirmed changes to a document.
133
176
  * Used by PatchesSync to update documents with server changes.
177
+ * @param docId - The document ID to apply changes to.
178
+ * @param changes - Array of Change objects from the server.
134
179
  */
135
180
  applyServerChanges(docId, changes) {
136
181
  this._handleServerCommit(docId, changes);
137
182
  }
183
+ /**
184
+ * Closes all open documents and cleans up listeners and store connections.
185
+ * Should be called when shutting down the client.
186
+ */
138
187
  close() {
139
188
  // Clean up local PatchesDoc listeners
140
189
  this.docs.forEach(managed => managed.onChangeUnsubscriber());
@@ -143,6 +192,12 @@ export class Patches {
143
192
  void this.store.close();
144
193
  }
145
194
  // --- Internal Handlers ---
195
+ /**
196
+ * Sets up a listener for local changes on a PatchesDoc, saving pending changes to the store.
197
+ * @param docId - The document ID being managed.
198
+ * @param doc - The PatchesDoc instance to listen to.
199
+ * @returns An Unsubscriber function to remove the listener.
200
+ */
146
201
  _setupLocalDocListener(docId, doc) {
147
202
  return doc.onChange(async () => {
148
203
  const changes = doc.getUpdatesForServer();
@@ -30,8 +30,6 @@ export declare class PatchesDoc<T extends object = object> {
30
30
  get id(): string | null;
31
31
  /** Current local state (committed + sending + pending). */
32
32
  get state(): T;
33
- /** Alias for state. */
34
- get value(): T;
35
33
  /** Last committed revision number from the server. */
36
34
  get committedRev(): number;
37
35
  /** Are there changes currently awaiting server confirmation? */
@@ -37,10 +37,6 @@ export class PatchesDoc {
37
37
  get state() {
38
38
  return this._state;
39
39
  }
40
- /** Alias for state. */
41
- get value() {
42
- return this._state;
43
- }
44
40
  /** Last committed revision number from the server. */
45
41
  get committedRev() {
46
42
  return this._committedRev;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { Delta } from '@dabble/delta';
2
2
  export * from './client/Patches.js';
3
3
  export * from './client/PatchesDoc.js';
4
- export type * from './event-signal';
5
- export type * from './json-patch/JSONPatch.js';
4
+ export * from './event-signal';
5
+ export * from './json-patch/JSONPatch.js';
6
6
  export type { ApplyJSONPatchOptions } from './json-patch/types.js';
7
7
  export type * from './persist/PatchesStore.js';
8
8
  export type * from './types';
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export { Delta } from '@dabble/delta';
2
2
  export * from './client/Patches.js';
3
3
  export * from './client/PatchesDoc.js';
4
+ export * from './event-signal';
5
+ export * from './json-patch/JSONPatch.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dabble/patches",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Immutable JSON Patch implementation based on RFC 6902 supporting operational transformation and last-writer-wins",
5
5
  "author": "Jacob Wright <jacwright@gmail.com>",
6
6
  "bugs": {