@dabble/patches 0.2.2 → 0.2.4
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/client/PatchesDoc.d.ts +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +3 -2
- package/dist/json-patch/JSONPatch.d.ts +0 -9
- package/dist/json-patch/JSONPatch.js +0 -11
- package/dist/persist/IndexedDBStore.d.ts +7 -2
- package/dist/persist/IndexedDBStore.js +48 -29
- package/dist/types.d.ts +1 -0
- package/dist/utils.js +17 -3
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import type { Change, PatchesSnapshot } from '../types.js';
|
|
|
5
5
|
* Manages committed state, pending (local-only) changes, and
|
|
6
6
|
* changes currently being sent to the server.
|
|
7
7
|
*/
|
|
8
|
-
export declare class PatchesDoc<T extends object> {
|
|
8
|
+
export declare class PatchesDoc<T extends object = object> {
|
|
9
9
|
protected _id: string | null;
|
|
10
10
|
protected _state: T;
|
|
11
11
|
protected _committedState: T;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export
|
|
1
|
+
export { Delta } from '@dabble/delta';
|
|
2
|
+
export * from './client/Patches.js';
|
|
3
|
+
export * from './client/PatchesDoc.js';
|
|
4
|
+
export type * from './event-signal';
|
|
5
|
+
export type * from './json-patch/JSONPatch.js';
|
|
6
|
+
export type { ApplyJSONPatchOptions } from './json-patch/types.js';
|
|
7
|
+
export type * from './persist/PatchesStore.js';
|
|
3
8
|
export type * from './types';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export
|
|
1
|
+
export { Delta } from '@dabble/delta';
|
|
2
|
+
export * from './client/Patches.js';
|
|
3
|
+
export * from './client/PatchesDoc.js';
|
|
@@ -115,12 +115,3 @@ export declare class JSONPatch {
|
|
|
115
115
|
new (ops?: JSONPatchOp[], types?: JSONPatchOpHandlerMap): T;
|
|
116
116
|
}, ops?: JSONPatchOp[], types?: JSONPatchOpHandlerMap): T;
|
|
117
117
|
}
|
|
118
|
-
export type JSONPath<T> = T extends object ? T extends Array<infer U> ? {
|
|
119
|
-
readonly [K in keyof T & number]-?: JSONPathValue<U>;
|
|
120
|
-
} : {
|
|
121
|
-
readonly [K in keyof T as T[K] extends Function ? never : K]-?: JSONPathValue<NonNullable<T[K]>>;
|
|
122
|
-
} : never;
|
|
123
|
-
export type JSONPathValue<T> = {
|
|
124
|
-
toString(): string;
|
|
125
|
-
} & (T extends object ? JSONPath<T> : {});
|
|
126
|
-
export declare function createJSONPath<T = unknown>(): JSONPath<T>;
|
|
@@ -208,14 +208,3 @@ function checkPath(path) {
|
|
|
208
208
|
path = `/${path}`;
|
|
209
209
|
return path;
|
|
210
210
|
}
|
|
211
|
-
export function createJSONPath() {
|
|
212
|
-
const handler = {
|
|
213
|
-
get(target, prop) {
|
|
214
|
-
if (prop === 'toString') {
|
|
215
|
-
return () => target.path ?? '';
|
|
216
|
-
}
|
|
217
|
-
return new Proxy({ path: `${target.path}/${prop}` }, handler);
|
|
218
|
-
},
|
|
219
|
-
};
|
|
220
|
-
return new Proxy({ path: '' }, handler);
|
|
221
|
-
}
|
|
@@ -14,13 +14,18 @@ import type { PatchesStore, TrackedDoc } from './PatchesStore.js';
|
|
|
14
14
|
*/
|
|
15
15
|
export declare class IndexedDBStore implements PatchesStore {
|
|
16
16
|
private db;
|
|
17
|
-
private dbName
|
|
17
|
+
private dbName?;
|
|
18
18
|
private dbPromise;
|
|
19
19
|
/** Subscribe to be notified after local state changes are saved to the database. */
|
|
20
20
|
readonly onPendingChanges: import("../event-signal.js").Signal<(docId: string, changes: Change[]) => void>;
|
|
21
|
-
constructor(dbName
|
|
21
|
+
constructor(dbName?: string);
|
|
22
22
|
private initDB;
|
|
23
23
|
private getDB;
|
|
24
|
+
/**
|
|
25
|
+
* Set the name of the database, loads a new database connection.
|
|
26
|
+
* @param dbName - The new name of the database.
|
|
27
|
+
*/
|
|
28
|
+
setName(dbName: string): void;
|
|
24
29
|
/**
|
|
25
30
|
* Closes the database connection. After calling this method, the store
|
|
26
31
|
* will no longer be usable. A new instance must be created to reopen
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { signal } from '../event-signal.js';
|
|
2
2
|
import { transformPatch } from '../json-patch/transformPatch.js';
|
|
3
|
-
import { applyChanges } from '../utils.js';
|
|
3
|
+
import { applyChanges, deferred } from '../utils.js';
|
|
4
4
|
const DB_VERSION = 1;
|
|
5
5
|
const SNAPSHOT_INTERVAL = 200;
|
|
6
6
|
/**
|
|
@@ -21,36 +21,52 @@ export class IndexedDBStore {
|
|
|
21
21
|
/** Subscribe to be notified after local state changes are saved to the database. */
|
|
22
22
|
this.onPendingChanges = signal();
|
|
23
23
|
this.dbName = dbName;
|
|
24
|
-
this.dbPromise =
|
|
24
|
+
this.dbPromise = deferred();
|
|
25
|
+
if (this.dbName) {
|
|
26
|
+
this.initDB();
|
|
27
|
+
}
|
|
25
28
|
}
|
|
26
29
|
async initDB() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
30
|
+
if (!this.dbName)
|
|
31
|
+
return;
|
|
32
|
+
const request = indexedDB.open(this.dbName, DB_VERSION);
|
|
33
|
+
request.onerror = () => this.dbPromise.reject(request.error);
|
|
34
|
+
request.onsuccess = () => {
|
|
35
|
+
this.db = request.result;
|
|
36
|
+
this.dbPromise.resolve(this.db);
|
|
37
|
+
};
|
|
38
|
+
request.onupgradeneeded = event => {
|
|
39
|
+
const db = event.target.result;
|
|
40
|
+
// Create stores
|
|
41
|
+
if (!db.objectStoreNames.contains('snapshots')) {
|
|
42
|
+
db.createObjectStore('snapshots', { keyPath: 'docId' });
|
|
43
|
+
}
|
|
44
|
+
if (!db.objectStoreNames.contains('committedChanges')) {
|
|
45
|
+
db.createObjectStore('committedChanges', { keyPath: ['docId', 'rev'] });
|
|
46
|
+
}
|
|
47
|
+
if (!db.objectStoreNames.contains('pendingChanges')) {
|
|
48
|
+
db.createObjectStore('pendingChanges', { keyPath: ['docId', 'rev'] });
|
|
49
|
+
}
|
|
50
|
+
if (!db.objectStoreNames.contains('docs')) {
|
|
51
|
+
db.createObjectStore('docs', { keyPath: 'docId' });
|
|
52
|
+
}
|
|
53
|
+
};
|
|
51
54
|
}
|
|
52
55
|
getDB() {
|
|
53
|
-
return this.dbPromise;
|
|
56
|
+
return this.dbPromise.promise;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the name of the database, loads a new database connection.
|
|
60
|
+
* @param dbName - The new name of the database.
|
|
61
|
+
*/
|
|
62
|
+
setName(dbName) {
|
|
63
|
+
this.dbName = dbName;
|
|
64
|
+
if (this.db) {
|
|
65
|
+
this.db.close();
|
|
66
|
+
this.db = null;
|
|
67
|
+
this.dbPromise = deferred();
|
|
68
|
+
}
|
|
69
|
+
this.initDB();
|
|
54
70
|
}
|
|
55
71
|
/**
|
|
56
72
|
* Closes the database connection. After calling this method, the store
|
|
@@ -58,14 +74,17 @@ export class IndexedDBStore {
|
|
|
58
74
|
* the database.
|
|
59
75
|
*/
|
|
60
76
|
async close() {
|
|
61
|
-
await this.dbPromise;
|
|
77
|
+
await this.dbPromise.promise;
|
|
62
78
|
if (this.db) {
|
|
63
79
|
this.db.close();
|
|
64
80
|
this.db = null;
|
|
65
|
-
this.dbPromise =
|
|
81
|
+
this.dbPromise = deferred();
|
|
82
|
+
this.dbPromise.resolve(null);
|
|
66
83
|
}
|
|
67
84
|
}
|
|
68
85
|
async deleteDB() {
|
|
86
|
+
if (!this.dbName)
|
|
87
|
+
return;
|
|
69
88
|
await this.close();
|
|
70
89
|
await new Promise((resolve, reject) => {
|
|
71
90
|
const request = indexedDB.deleteDatabase(this.dbName);
|
package/dist/types.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -81,9 +81,23 @@ export function rebaseChanges(serverChanges, localChanges) {
|
|
|
81
81
|
export function deferred() {
|
|
82
82
|
let resolve;
|
|
83
83
|
let reject;
|
|
84
|
+
let _status = 'pending';
|
|
84
85
|
const promise = new Promise((_resolve, _reject) => {
|
|
85
|
-
resolve =
|
|
86
|
-
|
|
86
|
+
resolve = (value) => {
|
|
87
|
+
_resolve(value);
|
|
88
|
+
_status = 'fulfilled';
|
|
89
|
+
};
|
|
90
|
+
reject = (reason) => {
|
|
91
|
+
_reject(reason);
|
|
92
|
+
_status = 'rejected';
|
|
93
|
+
};
|
|
87
94
|
});
|
|
88
|
-
return {
|
|
95
|
+
return {
|
|
96
|
+
promise,
|
|
97
|
+
resolve,
|
|
98
|
+
reject,
|
|
99
|
+
get status() {
|
|
100
|
+
return _status;
|
|
101
|
+
},
|
|
102
|
+
};
|
|
89
103
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dabble/patches",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
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": {
|