cojson-storage-indexeddb 0.8.12 → 0.8.17

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.
@@ -2,9 +2,9 @@
2
2
  const isFunction = (func: any) => typeof func === "function";
3
3
 
4
4
  const isObject = (supposedObject: any) =>
5
- typeof supposedObject === "object" &&
6
- supposedObject !== null &&
7
- !Array.isArray(supposedObject);
5
+ typeof supposedObject === "object" &&
6
+ supposedObject !== null &&
7
+ !Array.isArray(supposedObject);
8
8
 
9
9
  const isThenable = (obj: any) => isObject(obj) && isFunction(obj.then);
10
10
 
@@ -13,14 +13,14 @@ const identity = (co: any) => co;
13
13
  export { isObject, isThenable, identity, isFunction };
14
14
 
15
15
  enum States {
16
- PENDING = "PENDING",
17
- RESOLVED = "RESOLVED",
18
- REJECTED = "REJECTED",
16
+ PENDING = "PENDING",
17
+ RESOLVED = "RESOLVED",
18
+ REJECTED = "REJECTED",
19
19
  }
20
20
 
21
21
  interface Handler<T, U> {
22
- onSuccess: HandlerOnSuccess<T, U>;
23
- onFail: HandlerOnFail<U>;
22
+ onSuccess: HandlerOnSuccess<T, U>;
23
+ onFail: HandlerOnFail<U>;
24
24
  }
25
25
 
26
26
  type HandlerOnSuccess<T, U = any> = (value: T) => U | Thenable<U>;
@@ -28,202 +28,197 @@ type HandlerOnFail<U = any> = (reason: any) => U | Thenable<U>;
28
28
  type Finally<U> = () => U | Thenable<U>;
29
29
 
30
30
  interface Thenable<T> {
31
- then<U>(
32
- onSuccess?: HandlerOnSuccess<T, U>,
33
- onFail?: HandlerOnFail<U>,
34
- ): Thenable<U>;
35
- then<U>(
36
- onSuccess?: HandlerOnSuccess<T, U>,
37
- onFail?: (reason: any) => void,
38
- ): Thenable<U>;
31
+ then<U>(
32
+ onSuccess?: HandlerOnSuccess<T, U>,
33
+ onFail?: HandlerOnFail<U>,
34
+ ): Thenable<U>;
35
+ then<U>(
36
+ onSuccess?: HandlerOnSuccess<T, U>,
37
+ onFail?: (reason: any) => void,
38
+ ): Thenable<U>;
39
39
  }
40
40
 
41
41
  type Resolve<R> = (value?: R | Thenable<R>) => void;
42
42
  type Reject = (value?: any) => void;
43
43
 
44
44
  export class SyncPromise<T> {
45
- private state: States = States.PENDING;
46
- private handlers: Handler<T, any>[] = [];
47
- private value: T | any;
48
-
49
- public constructor(
50
- callback: (resolve: Resolve<T>, reject: Reject) => void,
51
- ) {
52
- try {
53
- callback(this.resolve as Resolve<T>, this.reject);
54
- } catch (e) {
55
- this.reject(e);
56
- }
45
+ private state: States = States.PENDING;
46
+ private handlers: Handler<T, any>[] = [];
47
+ private value: T | any;
48
+
49
+ public constructor(callback: (resolve: Resolve<T>, reject: Reject) => void) {
50
+ try {
51
+ callback(this.resolve as Resolve<T>, this.reject);
52
+ } catch (e) {
53
+ this.reject(e);
57
54
  }
55
+ }
58
56
 
59
- private resolve = (value: T) => {
60
- return this.setResult(value, States.RESOLVED);
61
- };
62
-
63
- private reject = (reason: any) => {
64
- return this.setResult(reason, States.REJECTED);
65
- };
57
+ private resolve = (value: T) => {
58
+ return this.setResult(value, States.RESOLVED);
59
+ };
66
60
 
67
- private setResult = (value: T | any, state: States) => {
68
- const set = () => {
69
- if (this.state !== States.PENDING) {
70
- return null;
71
- }
61
+ private reject = (reason: any) => {
62
+ return this.setResult(reason, States.REJECTED);
63
+ };
72
64
 
73
- if (isThenable(value)) {
74
- return (value as Thenable<T>).then(this.resolve, this.reject);
75
- }
65
+ private setResult = (value: T | any, state: States) => {
66
+ const set = () => {
67
+ if (this.state !== States.PENDING) {
68
+ return null;
69
+ }
76
70
 
77
- this.value = value;
78
- this.state = state;
71
+ if (isThenable(value)) {
72
+ return (value as Thenable<T>).then(this.resolve, this.reject);
73
+ }
79
74
 
80
- return this.executeHandlers();
81
- };
75
+ this.value = value;
76
+ this.state = state;
82
77
 
83
- void set();
78
+ return this.executeHandlers();
84
79
  };
85
80
 
86
- private executeHandlers = () => {
87
- if (this.state === States.PENDING) {
88
- return null;
89
- }
90
-
91
- this.handlers.forEach((handler) => {
92
- if (this.state === States.REJECTED) {
93
- return handler.onFail(this.value);
94
- }
95
-
96
- return handler.onSuccess(this.value);
97
- });
98
-
99
- this.handlers = [];
100
- };
101
-
102
- private attachHandler = (handler: Handler<T, any>) => {
103
- this.handlers = [...this.handlers, handler];
104
-
105
- this.executeHandlers();
106
- };
107
-
108
- public then<U>(
109
- onSuccess: HandlerOnSuccess<T, U>,
110
- onFail?: HandlerOnFail<U>,
111
- ) {
112
- return new SyncPromise<U>((resolve, reject) => {
113
- return this.attachHandler({
114
- onSuccess: (result) => {
115
- try {
116
- return resolve(onSuccess(result));
117
- } catch (e) {
118
- return reject(e);
119
- }
120
- },
121
- onFail: (reason) => {
122
- if (!onFail) {
123
- return reject(reason);
124
- }
125
-
126
- try {
127
- return resolve(onFail(reason));
128
- } catch (e) {
129
- return reject(e);
130
- }
131
- },
132
- });
133
- });
134
- }
135
-
136
- public catch<U>(onFail: HandlerOnFail<U>) {
137
- return this.then<U>(identity, onFail);
138
- }
139
-
140
- // methods
141
-
142
- public toString() {
143
- return `[object SyncPromise]`;
144
- }
81
+ void set();
82
+ };
145
83
 
146
- public finally<U>(cb: Finally<U>) {
147
- return new SyncPromise<U>((resolve, reject) => {
148
- let co: U | any;
149
- let isRejected: boolean;
150
-
151
- return this.then(
152
- (value) => {
153
- isRejected = false;
154
- co = value;
155
- return cb();
156
- },
157
- (reason) => {
158
- isRejected = true;
159
- co = reason;
160
- return cb();
161
- },
162
- ).then(() => {
163
- if (isRejected) {
164
- return reject(co);
165
- }
166
-
167
- return resolve(co);
168
- });
169
- });
84
+ private executeHandlers = () => {
85
+ if (this.state === States.PENDING) {
86
+ return null;
170
87
  }
171
88
 
172
- public spread<U>(handler: (...args: any[]) => U) {
173
- return this.then<U>((collection) => {
174
- if (Array.isArray(collection)) {
175
- return handler(...collection);
176
- }
177
-
178
- return handler(collection);
179
- });
180
- }
181
-
182
- // static
183
-
184
- public static resolve<U = any>(value?: U | Thenable<U>) {
185
- return new SyncPromise<U>((resolve) => {
186
- return resolve(value);
187
- });
188
- }
189
-
190
- public static reject<U>(reason?: any) {
191
- return new SyncPromise<U>((_resolve, reject) => {
89
+ this.handlers.forEach((handler) => {
90
+ if (this.state === States.REJECTED) {
91
+ return handler.onFail(this.value);
92
+ }
93
+
94
+ return handler.onSuccess(this.value);
95
+ });
96
+
97
+ this.handlers = [];
98
+ };
99
+
100
+ private attachHandler = (handler: Handler<T, any>) => {
101
+ this.handlers = [...this.handlers, handler];
102
+
103
+ this.executeHandlers();
104
+ };
105
+
106
+ public then<U>(onSuccess: HandlerOnSuccess<T, U>, onFail?: HandlerOnFail<U>) {
107
+ return new SyncPromise<U>((resolve, reject) => {
108
+ return this.attachHandler({
109
+ onSuccess: (result) => {
110
+ try {
111
+ return resolve(onSuccess(result));
112
+ } catch (e) {
113
+ return reject(e);
114
+ }
115
+ },
116
+ onFail: (reason) => {
117
+ if (!onFail) {
192
118
  return reject(reason);
193
- });
194
- }
119
+ }
120
+
121
+ try {
122
+ return resolve(onFail(reason));
123
+ } catch (e) {
124
+ return reject(e);
125
+ }
126
+ },
127
+ });
128
+ });
129
+ }
130
+
131
+ public catch<U>(onFail: HandlerOnFail<U>) {
132
+ return this.then<U>(identity, onFail);
133
+ }
134
+
135
+ // methods
136
+
137
+ public toString() {
138
+ return `[object SyncPromise]`;
139
+ }
140
+
141
+ public finally<U>(cb: Finally<U>) {
142
+ return new SyncPromise<U>((resolve, reject) => {
143
+ let co: U | any;
144
+ let isRejected: boolean;
145
+
146
+ return this.then(
147
+ (value) => {
148
+ isRejected = false;
149
+ co = value;
150
+ return cb();
151
+ },
152
+ (reason) => {
153
+ isRejected = true;
154
+ co = reason;
155
+ return cb();
156
+ },
157
+ ).then(() => {
158
+ if (isRejected) {
159
+ return reject(co);
160
+ }
195
161
 
196
- public static all<U = any>(collection: (U | Thenable<U>)[]) {
197
- return new SyncPromise<U[]>((resolve, reject) => {
198
- if (!Array.isArray(collection)) {
199
- return reject(new TypeError("An array must be provided."));
200
- }
201
-
202
- if (collection.length === 0) {
203
- return resolve([]);
204
- }
205
-
206
- let counter = collection.length;
207
- const resolvedCollection: U[] = [];
208
-
209
- const tryResolve = (value: U, index: number) => {
210
- counter -= 1;
211
- resolvedCollection[index] = value;
212
-
213
- if (counter !== 0) {
214
- return null;
215
- }
216
-
217
- return resolve(resolvedCollection);
218
- };
219
-
220
- return collection.forEach((item, index) => {
221
- return SyncPromise.resolve(item)
222
- .then((value) => {
223
- return tryResolve(value, index);
224
- })
225
- .catch(reject);
226
- });
227
- });
228
- }
162
+ return resolve(co);
163
+ });
164
+ });
165
+ }
166
+
167
+ public spread<U>(handler: (...args: any[]) => U) {
168
+ return this.then<U>((collection) => {
169
+ if (Array.isArray(collection)) {
170
+ return handler(...collection);
171
+ }
172
+
173
+ return handler(collection);
174
+ });
175
+ }
176
+
177
+ // static
178
+
179
+ public static resolve<U = any>(value?: U | Thenable<U>) {
180
+ return new SyncPromise<U>((resolve) => {
181
+ return resolve(value);
182
+ });
183
+ }
184
+
185
+ public static reject<U>(reason?: any) {
186
+ return new SyncPromise<U>((_resolve, reject) => {
187
+ return reject(reason);
188
+ });
189
+ }
190
+
191
+ public static all<U = any>(collection: (U | Thenable<U>)[]) {
192
+ return new SyncPromise<U[]>((resolve, reject) => {
193
+ if (!Array.isArray(collection)) {
194
+ return reject(new TypeError("An array must be provided."));
195
+ }
196
+
197
+ if (collection.length === 0) {
198
+ return resolve([]);
199
+ }
200
+
201
+ let counter = collection.length;
202
+ const resolvedCollection: U[] = [];
203
+
204
+ const tryResolve = (value: U, index: number) => {
205
+ counter -= 1;
206
+ resolvedCollection[index] = value;
207
+
208
+ if (counter !== 0) {
209
+ return null;
210
+ }
211
+
212
+ return resolve(resolvedCollection);
213
+ };
214
+
215
+ return collection.forEach((item, index) => {
216
+ return SyncPromise.resolve(item)
217
+ .then((value) => {
218
+ return tryResolve(value, index);
219
+ })
220
+ .catch(reject);
221
+ });
222
+ });
223
+ }
229
224
  }
@@ -1,68 +1,68 @@
1
1
  import "fake-indexeddb/auto"; // Polyfill for IndexedDB
2
2
 
3
- import { expect, test } from "vitest";
4
3
  import { ControlledAgent, LocalNode, WasmCrypto } from "cojson";
4
+ import { expect, test } from "vitest";
5
5
  import { IDBStorage } from "../index.js";
6
6
 
7
7
  const Crypto = await WasmCrypto.create();
8
8
 
9
9
  test.skip("Should be able to initialize and load from empty DB", async () => {
10
- const agentSecret = Crypto.newRandomAgentSecret();
10
+ const agentSecret = Crypto.newRandomAgentSecret();
11
11
 
12
- const node = new LocalNode(
13
- new ControlledAgent(agentSecret, Crypto),
14
- Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
15
- Crypto,
16
- );
12
+ const node = new LocalNode(
13
+ new ControlledAgent(agentSecret, Crypto),
14
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
15
+ Crypto,
16
+ );
17
17
 
18
- node.syncManager.addPeer(await IDBStorage.asPeer({ trace: true }));
18
+ node.syncManager.addPeer(await IDBStorage.asPeer({ trace: true }));
19
19
 
20
- console.log("yay!");
20
+ console.log("yay!");
21
21
 
22
- const _group = node.createGroup();
22
+ const _group = node.createGroup();
23
23
 
24
- await new Promise((resolve) => setTimeout(resolve, 200));
24
+ await new Promise((resolve) => setTimeout(resolve, 200));
25
25
 
26
- expect(node.syncManager.peers["storage"]).toBeDefined();
26
+ expect(node.syncManager.peers["storage"]).toBeDefined();
27
27
  });
28
28
 
29
29
  test("Should be able to sync data to database and then load that from a new node", async () => {
30
- const agentSecret = Crypto.newRandomAgentSecret();
30
+ const agentSecret = Crypto.newRandomAgentSecret();
31
31
 
32
- const node1 = new LocalNode(
33
- new ControlledAgent(agentSecret, Crypto),
34
- Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
35
- Crypto,
36
- );
32
+ const node1 = new LocalNode(
33
+ new ControlledAgent(agentSecret, Crypto),
34
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
35
+ Crypto,
36
+ );
37
37
 
38
- node1.syncManager.addPeer(
39
- await IDBStorage.asPeer({ trace: true, localNodeName: "node1" }),
40
- );
38
+ node1.syncManager.addPeer(
39
+ await IDBStorage.asPeer({ trace: true, localNodeName: "node1" }),
40
+ );
41
41
 
42
- console.log("yay!");
42
+ console.log("yay!");
43
43
 
44
- const group = node1.createGroup();
44
+ const group = node1.createGroup();
45
45
 
46
- const map = group.createMap();
46
+ const map = group.createMap();
47
47
 
48
- map.set("hello", "world");
48
+ map.set("hello", "world");
49
49
 
50
- await new Promise((resolve) => setTimeout(resolve, 200));
50
+ await new Promise((resolve) => setTimeout(resolve, 200));
51
51
 
52
- const node2 = new LocalNode(
53
- new ControlledAgent(agentSecret, Crypto),
54
- Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
55
- Crypto,
56
- );
52
+ const node2 = new LocalNode(
53
+ new ControlledAgent(agentSecret, Crypto),
54
+ Crypto.newRandomSessionID(Crypto.getAgentID(agentSecret)),
55
+ Crypto,
56
+ );
57
57
 
58
- node2.syncManager.addPeer(
59
- await IDBStorage.asPeer({ trace: true, localNodeName: "node2" }),
60
- );
58
+ node2.syncManager.addPeer(
59
+ await IDBStorage.asPeer({ trace: true, localNodeName: "node2" }),
60
+ );
61
61
 
62
- const map2 = await node2.load(map.id);
63
- if (map2 === "unavailable") {
64
- throw new Error("Map is unavailable");
65
- }
62
+ const map2 = await node2.load(map.id);
63
+ if (map2 === "unavailable") {
64
+ throw new Error("Map is unavailable");
65
+ }
66
66
 
67
- expect(map2.get("hello")).toBe("world");
67
+ expect(map2.get("hello")).toBe("world");
68
68
  });
package/tsconfig.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "skipLibCheck": true,
10
10
  "forceConsistentCasingInFileNames": true,
11
11
  "noUncheckedIndexedAccess": true,
12
- "esModuleInterop": true,
12
+ "esModuleInterop": true
13
13
  },
14
- "include": ["./src/**/*"],
14
+ "include": ["./src/**/*"]
15
15
  }
package/.eslintrc.cjs DELETED
@@ -1,24 +0,0 @@
1
- module.exports = {
2
- extends: [
3
- "eslint:recommended",
4
- "plugin:@typescript-eslint/recommended",
5
- "plugin:require-extensions/recommended",
6
- "prettier"
7
- ],
8
- parser: "@typescript-eslint/parser",
9
- plugins: ["@typescript-eslint", "require-extensions"],
10
- parserOptions: {
11
- project: "./tsconfig.json",
12
- tsconfigRootDir: __dirname,
13
- },
14
- ignorePatterns: [".eslint.cjs"],
15
- root: true,
16
- rules: {
17
- "no-unused-vars": "off",
18
- "@typescript-eslint/no-unused-vars": [
19
- "error",
20
- { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
21
- ],
22
- "@typescript-eslint/no-floating-promises": "error",
23
- },
24
- }
package/.prettierrc.js DELETED
@@ -1,9 +0,0 @@
1
- /** @type {import("prettier").Config} */
2
- const config = {
3
- trailingComma: "all",
4
- tabWidth: 4,
5
- semi: true,
6
- singleQuote: false,
7
- };
8
-
9
- export default config;