@peerbit/react 0.0.33 → 0.0.35

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.
Files changed (71) hide show
  1. package/dist/src/index.d.ts +5 -0
  2. package/dist/src/index.d.ts.map +1 -0
  3. package/dist/src/index.js +5 -0
  4. package/dist/src/index.js.map +1 -0
  5. package/{lib/esm → dist/src}/lockstorage.d.ts +1 -0
  6. package/dist/src/lockstorage.d.ts.map +1 -0
  7. package/{lib/esm → dist/src}/lockstorage.js +2 -5
  8. package/dist/src/lockstorage.js.map +1 -0
  9. package/{lib/esm → dist/src}/useMount.d.ts +1 -0
  10. package/dist/src/useMount.d.ts.map +1 -0
  11. package/dist/src/useMount.js.map +1 -0
  12. package/{lib/esm → dist/src}/usePeer.d.ts +7 -3
  13. package/dist/src/usePeer.d.ts.map +1 -0
  14. package/{lib/esm → dist/src}/usePeer.js +25 -20
  15. package/dist/src/usePeer.js.map +1 -0
  16. package/{lib/esm → dist/src}/utils.d.ts +2 -4
  17. package/dist/src/utils.d.ts.map +1 -0
  18. package/{lib/esm → dist/src}/utils.js +17 -69
  19. package/dist/src/utils.js.map +1 -0
  20. package/package.json +59 -56
  21. package/src/index.ts +4 -14
  22. package/src/lockstorage.ts +224 -233
  23. package/src/useMount.ts +15 -0
  24. package/src/usePeer.tsx +406 -419
  25. package/src/utils.ts +99 -168
  26. package/README.md +0 -24
  27. package/lib/esm/__tests__/lockstorage.test.d.ts +0 -1
  28. package/lib/esm/__tests__/lockstorage.test.js +0 -237
  29. package/lib/esm/__tests__/lockstorage.test.js.map +0 -1
  30. package/lib/esm/__tests__/singletonLock.test.d.ts +0 -1
  31. package/lib/esm/__tests__/singletonLock.test.js +0 -71
  32. package/lib/esm/__tests__/singletonLock.test.js.map +0 -1
  33. package/lib/esm/__tests__/useQuery.dom.test.d.ts +0 -1
  34. package/lib/esm/__tests__/useQuery.dom.test.js +0 -433
  35. package/lib/esm/__tests__/useQuery.dom.test.js.map +0 -1
  36. package/lib/esm/__tests__/utils.test.d.ts +0 -1
  37. package/lib/esm/__tests__/utils.test.js +0 -66
  38. package/lib/esm/__tests__/utils.test.js.map +0 -1
  39. package/lib/esm/index.d.ts +0 -8
  40. package/lib/esm/index.js +0 -9
  41. package/lib/esm/index.js.map +0 -1
  42. package/lib/esm/lockstorage.js.map +0 -1
  43. package/lib/esm/useCount.d.ts +0 -11
  44. package/lib/esm/useCount.js +0 -43
  45. package/lib/esm/useCount.js.map +0 -1
  46. package/lib/esm/useLocal.d.ts +0 -20
  47. package/lib/esm/useLocal.js +0 -73
  48. package/lib/esm/useLocal.js.map +0 -1
  49. package/lib/esm/useMount.js.map +0 -1
  50. package/lib/esm/useOnline.d.ts +0 -11
  51. package/lib/esm/useOnline.js +0 -65
  52. package/lib/esm/useOnline.js.map +0 -1
  53. package/lib/esm/usePeer.js.map +0 -1
  54. package/lib/esm/useProgram.d.ts +0 -16
  55. package/lib/esm/useProgram.js +0 -114
  56. package/lib/esm/useProgram.js.map +0 -1
  57. package/lib/esm/useQuery.d.ts +0 -49
  58. package/lib/esm/useQuery.js +0 -418
  59. package/lib/esm/useQuery.js.map +0 -1
  60. package/lib/esm/utils.js.map +0 -1
  61. package/src/__tests__/lockstorage.test.ts +0 -285
  62. package/src/__tests__/singletonLock.test.ts +0 -85
  63. package/src/__tests__/useQuery.dom.test.ts +0 -518
  64. package/src/__tests__/utils.test.ts +0 -90
  65. package/src/useCount.tsx +0 -63
  66. package/src/useLocal.tsx +0 -125
  67. package/src/useMount.tsx +0 -15
  68. package/src/useOnline.tsx +0 -85
  69. package/src/useProgram.tsx +0 -148
  70. package/src/useQuery.tsx +0 -548
  71. /package/{lib/esm → dist/src}/useMount.js +0 -0
package/src/utils.ts CHANGED
@@ -1,198 +1,129 @@
1
- import { serialize, deserialize } from "@dao-xyz/borsh";
2
- import { Ed25519Keypair, toBase64, fromBase64 } from "@peerbit/crypto";
3
- import { FastMutex } from "./lockstorage.js";
4
- import { v4 as uuid } from "uuid";
1
+ import { deserialize, serialize } from "@dao-xyz/borsh";
2
+ import { Ed25519Keypair, fromBase64, toBase64 } from "@peerbit/crypto";
5
3
  import sodium from "libsodium-wrappers";
4
+ import { v4 as uuid } from "uuid";
5
+ import { FastMutex } from "./lockstorage.ts";
6
6
 
7
7
  const CLIENT_ID_STORAGE_KEY = "CLIENT_ID";
8
+ const ID_COUNTER_KEY = "idc/";
9
+
10
+ const getKeyId = (prefix: string, id: number) => `${prefix}/${id}`;
11
+
8
12
  export const cookiesWhereClearedJustNow = () => {
9
- const lastPersistedAt = localStorage.getItem("lastPersistedAt");
10
- if (lastPersistedAt) {
11
- return false;
12
- }
13
- localStorage.setItem("lastPersistedAt", Date.now().toString());
14
- return true;
13
+ const lastPersistedAt = localStorage.getItem("lastPersistedAt");
14
+ if (lastPersistedAt) {
15
+ return false;
16
+ }
17
+ localStorage.setItem("lastPersistedAt", Date.now().toString());
18
+ return true;
15
19
  };
16
20
 
17
21
  export const getClientId = (type: "session" | "local") => {
18
- const storage = type === "session" ? sessionStorage : localStorage;
19
- const idFromStorage = storage.getItem(CLIENT_ID_STORAGE_KEY);
20
- if (idFromStorage) {
21
- return idFromStorage;
22
- } else {
23
- const id = uuid(); // generate unique UUID
24
- storage.setItem(CLIENT_ID_STORAGE_KEY, id);
25
- return id;
26
- }
22
+ const storage = type === "session" ? sessionStorage : localStorage;
23
+ const idFromStorage = storage.getItem(CLIENT_ID_STORAGE_KEY);
24
+ if (idFromStorage) {
25
+ return idFromStorage;
26
+ }
27
+ const id = uuid();
28
+ storage.setItem(CLIENT_ID_STORAGE_KEY, id);
29
+ return id;
27
30
  };
28
31
 
29
- const ID_COUNTER_KEY = "idc/";
30
-
31
- const getKeyId = (prefix: string, id: number) => prefix + "/" + id;
32
-
33
32
  export const releaseKey = (path: string, lock: FastMutex) => {
34
- lock.release(path);
33
+ lock.release(path);
35
34
  };
36
35
 
37
36
  export const getFreeKeypair = async (
38
- id: string = "",
39
- lock: FastMutex,
40
- lockCondition: () => boolean = () => true,
41
- options?: {
42
- releaseLockIfSameId?: boolean;
43
- releaseFirstLock?: boolean;
44
- }
37
+ id = "",
38
+ lock: FastMutex,
39
+ lockCondition: () => boolean = () => true,
40
+ options?: {
41
+ releaseLockIfSameId?: boolean;
42
+ releaseFirstLock?: boolean;
43
+ },
45
44
  ) => {
46
- await sodium.ready;
47
- const idCounterKey = ID_COUNTER_KEY + id;
48
- await lock.lock(idCounterKey, () => true);
49
- let idCounter = JSON.parse(localStorage.getItem(idCounterKey) || "0");
50
- for (let i = 0; i < 10000; i++) {
51
- const key = getKeyId(id, i);
52
- let lockedInfo = lock.getLockedInfo(key);
53
- /* console.log(
54
- "KEY KEY AT",
55
- key,
56
- id,
57
- i,
58
- lockedInfo,
59
- lockedInfo === lock.clientId,
60
- options
61
- );
62
- */
63
- if (lockedInfo) {
64
- if (
65
- (lockedInfo === lock.clientId &&
66
- options?.releaseLockIfSameId) ||
67
- options?.releaseFirstLock
68
- ) {
69
- await lock.release(key); // Release lock
70
- } else {
71
- continue;
72
- }
73
- }
74
-
75
- await lock.lock(key, lockCondition);
76
-
77
- localStorage.setItem(
78
- idCounterKey,
79
- JSON.stringify(Math.max(idCounter, i + 1))
80
- );
81
- await lock.release(idCounterKey);
82
- return {
83
- index: i,
84
- path: key,
85
- key: await getKeypair(key),
86
- };
87
- }
88
- throw new Error("Failed to resolve key");
45
+ await sodium.ready;
46
+ const idCounterKey = ID_COUNTER_KEY + id;
47
+ await lock.lock(idCounterKey, () => true);
48
+ let idCounter = JSON.parse(localStorage.getItem(idCounterKey) || "0");
49
+ for (let i = 0; i < 10000; i++) {
50
+ const key = getKeyId(id, i);
51
+ const lockedInfo = lock.getLockedInfo(key);
52
+ if (lockedInfo) {
53
+ if (
54
+ (lockedInfo === lock.clientId && options?.releaseLockIfSameId) ||
55
+ options?.releaseFirstLock
56
+ ) {
57
+ await lock.release(key);
58
+ } else {
59
+ continue;
60
+ }
61
+ }
62
+
63
+ await lock.lock(key, lockCondition);
64
+ localStorage.setItem(
65
+ idCounterKey,
66
+ JSON.stringify(Math.max(idCounter, i + 1)),
67
+ );
68
+ await lock.release(idCounterKey);
69
+ return {
70
+ index: i,
71
+ path: key,
72
+ key: await getKeypair(key),
73
+ };
74
+ }
75
+ throw new Error("Failed to resolve key");
89
76
  };
90
77
 
91
- export const getAllKeyPairs = async (id: string = "") => {
92
- const idCounterKey = ID_COUNTER_KEY + id;
93
- const counter = JSON.parse(localStorage.getItem(idCounterKey) || "0");
94
- let ret: Ed25519Keypair[] = [];
95
- for (let i = 0; i < counter; i++) {
96
- const key = getKeyId(id, i);
97
- const kp = loadKeypair(key);
98
- if (kp) {
99
- ret.push(kp);
100
- }
101
- }
102
- return ret;
78
+ export const getAllKeyPairs = async (id = "") => {
79
+ const idCounterKey = ID_COUNTER_KEY + id;
80
+ const counter = JSON.parse(localStorage.getItem(idCounterKey) || "0");
81
+ const ret: Ed25519Keypair[] = [];
82
+ for (let i = 0; i < counter; i++) {
83
+ const key = getKeyId(id, i);
84
+ const kp = loadKeypair(key);
85
+ if (kp) {
86
+ ret.push(kp);
87
+ }
88
+ }
89
+ return ret;
103
90
  };
104
91
 
105
- let _getKeypair: Promise<any>;
92
+ let _getKeypair: Promise<Ed25519Keypair> | undefined;
106
93
 
107
94
  export const getKeypair = async (keyName: string): Promise<Ed25519Keypair> => {
108
- await _getKeypair;
109
- const fn = async () => {
110
- let keypair: Ed25519Keypair | undefined = loadKeypair(keyName);
111
- if (keypair) {
112
- return keypair;
113
- }
114
-
115
- keypair = await Ed25519Keypair.create();
116
- saveKeypair(keyName, keypair);
117
- return keypair;
118
- };
119
- _getKeypair = fn();
120
- return _getKeypair;
95
+ await _getKeypair;
96
+ const fn = async () => {
97
+ let keypair = loadKeypair(keyName);
98
+ if (keypair) {
99
+ return keypair;
100
+ }
101
+
102
+ keypair = await Ed25519Keypair.create();
103
+ saveKeypair(keyName, keypair);
104
+ return keypair;
105
+ };
106
+ _getKeypair = fn();
107
+ return _getKeypair;
121
108
  };
122
109
 
123
110
  const saveKeypair = (path: string, key: Ed25519Keypair) => {
124
- const str = toBase64(serialize(key));
125
- localStorage.setItem("_keys/" + path, str);
111
+ const str = toBase64(serialize(key));
112
+ localStorage.setItem(`_keys/${path}`, str);
126
113
  };
127
114
 
128
115
  const loadKeypair = (path: string) => {
129
- let item = localStorage.getItem("_keys/" + path);
130
- if (!item) {
131
- return;
132
- }
133
- return deserialize(fromBase64(item), Ed25519Keypair);
116
+ const item = localStorage.getItem(`_keys/${path}`);
117
+ if (!item) {
118
+ return undefined;
119
+ }
120
+ return deserialize(fromBase64(item), Ed25519Keypair);
134
121
  };
135
122
 
136
123
  export const inIframe = () => {
137
- try {
138
- return window.self !== window.top;
139
- } catch (e) {
140
- return true;
141
- }
124
+ try {
125
+ return window.self !== window.top;
126
+ } catch {
127
+ return true;
128
+ }
142
129
  };
143
-
144
- export function debounceLeadingTrailing<
145
- T extends (this: any, ...args: any[]) => void,
146
- >(
147
- func: T,
148
- delay: number
149
- ): ((this: ThisParameterType<T>, ...args: Parameters<T>) => void) & {
150
- cancel: () => void;
151
- } {
152
- let timeoutId: ReturnType<typeof setTimeout> | null = null;
153
- let lastArgs: Parameters<T> | null = null;
154
- let lastThis: any;
155
- let pendingTrailing = false;
156
-
157
- const debounced = function (
158
- this: ThisParameterType<T>,
159
- ...args: Parameters<T>
160
- ) {
161
- if (!timeoutId) {
162
- // Leading call: no timer means this is the first call in this period.
163
- func.apply(this, args);
164
- } else {
165
- // Subsequent calls during the delay mark that a trailing call is needed.
166
- pendingTrailing = true;
167
- }
168
- // Always update with the most recent context and arguments.
169
- lastArgs = args;
170
- lastThis = this;
171
-
172
- // Reset the timer.
173
- if (timeoutId) {
174
- clearTimeout(timeoutId);
175
- }
176
- timeoutId = setTimeout(() => {
177
- timeoutId = null;
178
- // If there were any calls during the delay, call the function on the trailing edge.
179
- if (pendingTrailing && lastArgs) {
180
- func.apply(lastThis, lastArgs);
181
- }
182
- // Reset the trailing flag after the trailing call.
183
- pendingTrailing = false;
184
- }, delay);
185
- } as ((this: ThisParameterType<T>, ...args: Parameters<T>) => void) & {
186
- cancel: () => void;
187
- };
188
-
189
- debounced.cancel = () => {
190
- if (timeoutId) {
191
- clearTimeout(timeoutId);
192
- timeoutId = null;
193
- }
194
- pendingTrailing = false;
195
- };
196
-
197
- return debounced;
198
- }
package/README.md DELETED
@@ -1,24 +0,0 @@
1
- # @peerbit/react utils
2
-
3
- This package includes hooks and utilities used across the examples.
4
-
5
- ## Tests
6
-
7
- - Unit tests run with Mocha against the compiled ESM output.
8
- - There is an opt-in reproduction test for a previously observed persistent lock issue.
9
-
10
- Run all tests:
11
-
12
- ```sh
13
- yarn test
14
- ```
15
-
16
- Run only the persistent-lock repro (intentionally fails):
17
-
18
- ```sh
19
- yarn test:repro-lock
20
- ```
21
-
22
- Notes:
23
- - The repro is gated via `REPRO_LOCK_FAIL=1` and is excluded from normal `yarn test` and CI.
24
- - It simulates sequential sessions sharing a persisted localStorage directory and expects the second session to fail acquiring the singleton lock.
@@ -1 +0,0 @@
1
- export {};
@@ -1,237 +0,0 @@
1
- /*
2
- ISC License (ISC)
3
- Copyright (c) 2016, Wes Cruver <chieffancypants@gmail.com>
4
-
5
- Permission to use, copy, modify, and/or distribute this software for any purpose
6
- with or without fee is hereby granted, provided that the above copyright notice
7
- and this permission notice appear in all copies.
8
-
9
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
11
- FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
13
- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14
- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
15
- THIS SOFTWARE.
16
- */
17
- import { FastMutex } from "../lockstorage.js";
18
- import sinon from "sinon";
19
- import nodelocalstorage from "node-localstorage";
20
- import { expect } from "chai";
21
- import { delay } from "@peerbit/time";
22
- import { beforeAll, afterAll, beforeEach, afterEach, describe, it, } from "vitest";
23
- describe("FastMutex", () => {
24
- let sandbox;
25
- beforeAll(() => {
26
- var LocalStorage = nodelocalstorage.LocalStorage;
27
- var localStorage = new LocalStorage("./tmp/FastMutex");
28
- localStorage.clear();
29
- globalThis.localStorage = localStorage;
30
- });
31
- afterAll(() => {
32
- globalThis.localStorage.clear();
33
- });
34
- beforeEach(() => {
35
- sandbox = sinon.createSandbox();
36
- localStorage.clear();
37
- });
38
- afterEach(() => {
39
- sandbox.restore();
40
- localStorage.clear();
41
- expect(localStorage.length).to.eq(0);
42
- });
43
- it("should immediately establish a lock when there is no contention", async () => {
44
- const fm1 = new FastMutex({ localStorage: localStorage });
45
- expect(fm1.isLocked("clientId")).to.be.false;
46
- const stats = await fm1.lock("clientId");
47
- expect(fm1.isLocked("clientId")).to.be.true;
48
- });
49
- it("When another client has a lock (Y is not 0), it should restart to acquire a lock at a later time", function () {
50
- const fm1 = new FastMutex({
51
- xPrefix: "xPrefix_",
52
- yPrefix: "yPrefix_",
53
- localStorage: localStorage,
54
- });
55
- const key = "clientId";
56
- fm1.setItem(`yPrefix_${key}`, "someOtherMutexId");
57
- setTimeout(() => {
58
- localStorage.removeItem(`yPrefix_${key}`);
59
- }, 20);
60
- return fm1.lock(key).then(() => {
61
- expect(fm1.getLockedInfo(key)).to.exist;
62
- });
63
- });
64
- it("when contending for a lock and ultimately losing, it should restart", () => {
65
- const key = "somekey";
66
- const fm = new FastMutex({
67
- localStorage: localStorage,
68
- clientId: "uniqueId",
69
- });
70
- const stub = sandbox.stub(fm, "getItem");
71
- // Set up scenario for lock contention where we lost Y
72
- stub.onCall(0).returns(null); // getItem Y
73
- stub.onCall(1).returns("lockcontention"); // getItem X
74
- stub.onCall(2).returns("youLostTheLock"); // getItem Y
75
- // fastmutex should have restarted, so let's free up the lock:
76
- stub.onCall(3).returns(null);
77
- stub.onCall(4).returns("uniqueId");
78
- return fm.lock(key).then((stats) => {
79
- expect(stats.restartCount).to.eq(1);
80
- expect(stats.locksLost).to.eq(1);
81
- expect(stats.contentionCount).to.eq(1);
82
- });
83
- });
84
- it("When contending for a lock and ultimately winning, it should not restart", () => {
85
- const key = "somekey";
86
- const fm = new FastMutex({
87
- localStorage: localStorage,
88
- clientId: "uniqueId",
89
- });
90
- const stub = sandbox.stub(fm, "getItem");
91
- // Set up scenario for lock contention where we lost Y
92
- stub.onCall(0).returns(null); // getItem Y
93
- stub.onCall(1).returns("lockContention");
94
- stub.onCall(2).returns("uniqueId");
95
- const spy = sandbox.spy(fm, "lock");
96
- return fm.lock(key).then((stats) => {
97
- expect(stats.restartCount).to.eq(0);
98
- expect(stats.locksLost).to.eq(0);
99
- expect(stats.contentionCount).to.eq(1);
100
- expect(spy.callCount).to.eq(1);
101
- });
102
- });
103
- // This is just to ensure that the internals of FastMutex have prefixes on the
104
- // X and Y locks such that two different FM clients can acquire locks on
105
- // different keys concurrently without clashing.
106
- it("should not clash with other fastMutex locks", async () => {
107
- const yPrefix = "yLock";
108
- const xPrefix = "xLock";
109
- const opts = { localStorage, yPrefix, xPrefix };
110
- const fm1 = new FastMutex(opts);
111
- const fm2 = new FastMutex(opts);
112
- let lock1Acquired = false;
113
- let lock2Acquired = false;
114
- /* eslint-disable jest/valid-expect-in-promise */
115
- const lock1Promise = fm1.lock("lock1").then((stats) => {
116
- lock1Acquired = true;
117
- expect(localStorage.getItem(yPrefix + "lock1")).to.exist;
118
- return stats;
119
- });
120
- /* eslint-disable jest/valid-expect-in-promise */
121
- const lock2Promise = fm2.lock("lock2").then((stats) => {
122
- lock2Acquired = true;
123
- expect(localStorage.getItem(yPrefix + "lock2")).to.exist;
124
- return stats;
125
- });
126
- await Promise.all([lock1Promise, lock2Promise]).then(() => {
127
- expect(lock1Acquired).to.be.true;
128
- expect(lock2Acquired).to.be.true;
129
- });
130
- });
131
- it("release() should remove the y lock in localStorage", () => {
132
- const key = "somekey";
133
- const fm1 = new FastMutex({
134
- localStorage: localStorage,
135
- clientId: "releaseTestId",
136
- yPrefix: "yLock",
137
- });
138
- return fm1
139
- .lock(key)
140
- .then(() => {
141
- expect(fm1.getItem("yLock" + key)).to.eq("releaseTestId");
142
- return fm1.release(key);
143
- })
144
- .then(() => {
145
- expect(fm1.getItem("yLock" + key)).to.be.undefined;
146
- });
147
- });
148
- // this is essentially just a better way to test that two locks cannot get
149
- // an exclusive lock until the other releases. It's a bit more accurate
150
- // than the test above ("release should remove the y lock in localstorage")
151
- it("two clients should never get locks at the same time", function () {
152
- const fm1 = new FastMutex({ localStorage: localStorage });
153
- const fm2 = new FastMutex({ localStorage: localStorage });
154
- let fm1LockReleased = false;
155
- const lockHoldTime = 10;
156
- return fm1
157
- .lock("clientId")
158
- .then(() => {
159
- // before the lock is released, try to establish another lock:
160
- var lock2Promise = fm2.lock("clientId");
161
- expect(fm1LockReleased).to.be.false;
162
- // in a few milliseconds, release the lock
163
- setTimeout(() => {
164
- fm1.release("clientId");
165
- fm1LockReleased = true;
166
- }, lockHoldTime);
167
- return lock2Promise;
168
- })
169
- .then((lock2) => {
170
- // this will only execute once the other lock was released
171
- expect(fm1LockReleased).to.be.true;
172
- });
173
- });
174
- it("should throw if lock is never acquired after set time period", async () => {
175
- const fm1 = new FastMutex({ localStorage: localStorage, timeout: 50 });
176
- const fm2 = new FastMutex({ localStorage: localStorage, timeout: 50 });
177
- await fm1.lock("timeoutTest");
178
- const start = Date.now();
179
- let threw = false;
180
- try {
181
- await fm2.lock("timeoutTest");
182
- }
183
- catch (e) {
184
- threw = true;
185
- }
186
- const elapsed = Date.now() - start;
187
- expect(threw).to.be.true;
188
- expect(elapsed).to.be.greaterThan(0);
189
- });
190
- it("should ignore expired locks", async () => {
191
- const fm1 = new FastMutex({
192
- localStorage: localStorage,
193
- timeout: 5000,
194
- yPrefix: "yLock",
195
- clientId: "timeoutClient",
196
- });
197
- const expiredRecord = {
198
- expiresAt: new Date().getTime() - 5000,
199
- value: "oldclient",
200
- };
201
- localStorage.setItem("yLocktimeoutTest", JSON.stringify(expiredRecord));
202
- expect(JSON.parse(localStorage.getItem("yLocktimeoutTest")).value).to.eq("oldclient");
203
- await fm1.lock("timeoutTest"); // should not throw
204
- });
205
- it("should reset the client stats after lock is released", async () => {
206
- // without resetting the stats, the acquireStart will always be set, and
207
- // after `timeout` ms, will be unable to acquire a lock anymore
208
- const fm1 = new FastMutex({ localStorage: localStorage, timeout: 50 });
209
- let keepLock = true;
210
- let keepLockFn = () => keepLock;
211
- await fm1.lock("resetStats", keepLockFn);
212
- expect(fm1.isLocked("resetStats")).to.be.true;
213
- keepLock = false;
214
- await delay(100); // await timeout
215
- expect(fm1.isLocked("resetStats")).to.be.false;
216
- const p = fm1.lock("resetStats").then(() => fm1.release("resetStats"));
217
- await p; // should not throw
218
- });
219
- it("can keep lock with callback function", async () => {
220
- const fm1 = new FastMutex({ localStorage: localStorage, timeout: 50 });
221
- await fm1.lock("x");
222
- await fm1.release("x");
223
- expect(fm1.isLocked("x")).to.be.false;
224
- await fm1.lock("x").then(() => fm1.release("x"));
225
- });
226
- it("should reset the client stats if the lock has expired", async () => {
227
- // in the event a lock cannot be acquired within `timeout`, acquireStart
228
- // will never be reset, and a subsequent call (after the `timeout`) would
229
- // immediately fail
230
- const fm1 = new FastMutex({ localStorage: localStorage, timeout: 50 });
231
- await fm1.lock("resetStats");
232
- // try to acquire a lock after `timeout`:
233
- await delay(75); // a small buffer over timeout to avoid flakiness
234
- await fm1.lock("resetStats"); // should not throw
235
- });
236
- });
237
- //# sourceMappingURL=lockstorage.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lockstorage.test.js","sourceRoot":"","sources":["../../../src/__tests__/lockstorage.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,71 +0,0 @@
1
- import { expect } from "chai";
2
- import nodelocalstorage from "node-localstorage";
3
- import { FastMutex } from "../lockstorage.js";
4
- import { beforeAll, beforeEach, afterEach, describe, it } from "vitest";
5
- describe("FastMutex singleton semantics", () => {
6
- let localStorage;
7
- beforeAll(() => {
8
- const LocalStorage = nodelocalstorage.LocalStorage;
9
- localStorage = new LocalStorage("./tmp/FastMutex-singleton");
10
- globalThis.localStorage = localStorage;
11
- });
12
- beforeEach(() => {
13
- localStorage.clear();
14
- });
15
- afterEach(() => {
16
- localStorage.clear();
17
- expect(localStorage.length).to.eq(0);
18
- });
19
- it("allows same-session to reacquire the singleton lock when replaceIfSameClient is true", async () => {
20
- const key = "localId-singleton";
21
- const fm1 = new FastMutex({
22
- localStorage,
23
- clientId: "session-1",
24
- timeout: 200,
25
- });
26
- // First acquire and keep the lock alive
27
- await fm1.lock(key, () => true);
28
- expect(fm1.isLocked(key)).to.be.true;
29
- // Reacquire from the same client with replaceIfSameClient
30
- const start = Date.now();
31
- await fm1.lock(key, () => true, { replaceIfSameClient: true });
32
- const elapsed = Date.now() - start;
33
- // Should not time out and should be very fast
34
- expect(elapsed).to.be.lessThan(100);
35
- expect(fm1.isLocked(key)).to.be.true;
36
- fm1.release(key);
37
- expect(fm1.isLocked(key)).to.be.false;
38
- });
39
- it("blocks a different session while held, then allows after release", async () => {
40
- const key = "localId-singleton";
41
- const fm1 = new FastMutex({
42
- localStorage,
43
- clientId: "session-1",
44
- timeout: 500,
45
- });
46
- const fm2 = new FastMutex({
47
- localStorage,
48
- clientId: "session-2",
49
- timeout: 100, // short timeout to trigger failure while held
50
- });
51
- await fm1.lock(key, () => true);
52
- expect(fm1.isLocked(key)).to.be.true;
53
- // Attempt to acquire from a different client should fail within timeout
54
- let failed = false;
55
- try {
56
- await fm2.lock(key, () => true);
57
- }
58
- catch (e) {
59
- failed = true;
60
- }
61
- expect(failed).to.be.true;
62
- // After release, the second client should be able to acquire
63
- fm1.release(key);
64
- expect(fm1.isLocked(key)).to.be.false;
65
- await fm2.lock(key, () => true);
66
- expect(fm2.isLocked(key)).to.be.true;
67
- fm2.release(key);
68
- expect(fm2.isLocked(key)).to.be.false;
69
- });
70
- });
71
- //# sourceMappingURL=singletonLock.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"singletonLock.test.js","sourceRoot":"","sources":["../../../src/__tests__/singletonLock.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};