mongo-locks 3.1.1 → 3.1.2
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/commonjs/index.d.ts +47 -0
- package/dist/commonjs/index.js +45 -57
- package/dist/commonjs/index.js.map +1 -0
- package/dist/esm/index.d.ts +47 -0
- package/dist/esm/index.js +45 -57
- package/dist/esm/index.js.map +1 -0
- package/package.json +2 -2
- package/tsconfig.json +9 -16
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Collection, ObjectId } from "mongodb";
|
|
2
|
+
export declare class MongoLocksError extends Error {
|
|
3
|
+
constructor(message?: string);
|
|
4
|
+
}
|
|
5
|
+
interface LockModel {
|
|
6
|
+
_id: ObjectId;
|
|
7
|
+
action: unknown;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
refreshedAt: Date;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
}
|
|
12
|
+
declare class Lock {
|
|
13
|
+
_id: ObjectId;
|
|
14
|
+
action: unknown;
|
|
15
|
+
collection: Collection<LockModel>;
|
|
16
|
+
constructor(_id: ObjectId, action: unknown, collection: Collection<LockModel>);
|
|
17
|
+
locked: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Instead of calling `this.free` directly you can use the `using` syntax
|
|
20
|
+
*
|
|
21
|
+
* @returns true if the lock was successfully released. False if the lock was not found
|
|
22
|
+
*/
|
|
23
|
+
free(): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Refreshes the lock's TTL
|
|
26
|
+
*
|
|
27
|
+
* Automatically called every 10 seconds if the lock is still active, no
|
|
28
|
+
* need to call this manually
|
|
29
|
+
*
|
|
30
|
+
* @returns true if the lock was successfully refreshed. False if the lock was not found
|
|
31
|
+
*/
|
|
32
|
+
refresh(): Promise<boolean>;
|
|
33
|
+
[Symbol.dispose](): void;
|
|
34
|
+
[Symbol.asyncDispose](): Promise<boolean>;
|
|
35
|
+
}
|
|
36
|
+
export declare class LockManager {
|
|
37
|
+
collection: Collection<LockModel>;
|
|
38
|
+
MongoLocksError: typeof MongoLocksError;
|
|
39
|
+
constructor(collection: Collection);
|
|
40
|
+
/**
|
|
41
|
+
* Creates a DB lock based on the key provided
|
|
42
|
+
*
|
|
43
|
+
* @returns a function that when called will release the lock
|
|
44
|
+
*/
|
|
45
|
+
lock(key: unknown): Promise<Lock | null>;
|
|
46
|
+
}
|
|
47
|
+
export type { LockModel, Lock };
|
package/dist/commonjs/index.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.LockManager = exports.MongoLocksError = void 0;
|
|
13
4
|
const mongodb_1 = require("mongodb");
|
|
@@ -22,36 +13,37 @@ const makeKey = (key) => {
|
|
|
22
13
|
return Array.isArray(key) ? { _key_array: key } : key;
|
|
23
14
|
};
|
|
24
15
|
class Lock {
|
|
16
|
+
_id;
|
|
17
|
+
action;
|
|
18
|
+
collection;
|
|
25
19
|
constructor(_id, action, collection) {
|
|
26
20
|
this._id = _id;
|
|
27
21
|
this.action = action;
|
|
28
22
|
this.collection = collection;
|
|
29
|
-
this.locked = true;
|
|
30
23
|
if (this.locked) {
|
|
31
|
-
(() =>
|
|
24
|
+
(async () => {
|
|
32
25
|
while (this.locked) {
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
27
|
+
await this.refresh().catch(() => {
|
|
35
28
|
console.error("Failed to refresh lock", action);
|
|
36
29
|
});
|
|
37
30
|
}
|
|
38
|
-
})
|
|
31
|
+
})();
|
|
39
32
|
}
|
|
40
33
|
}
|
|
34
|
+
locked = true;
|
|
41
35
|
/**
|
|
42
36
|
* Instead of calling `this.free` directly you can use the `using` syntax
|
|
43
37
|
*
|
|
44
38
|
* @returns true if the lock was successfully released. False if the lock was not found
|
|
45
39
|
*/
|
|
46
|
-
free() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return result.deletedCount === 1;
|
|
54
|
-
});
|
|
40
|
+
async free() {
|
|
41
|
+
if (!this.locked) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
this.locked = false;
|
|
45
|
+
const result = await this.collection.deleteOne({ _id: this._id });
|
|
46
|
+
return result.deletedCount === 1;
|
|
55
47
|
}
|
|
56
48
|
/**
|
|
57
49
|
* Refreshes the lock's TTL
|
|
@@ -61,28 +53,25 @@ class Lock {
|
|
|
61
53
|
*
|
|
62
54
|
* @returns true if the lock was successfully refreshed. False if the lock was not found
|
|
63
55
|
*/
|
|
64
|
-
refresh() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return this.locked;
|
|
72
|
-
});
|
|
56
|
+
async refresh() {
|
|
57
|
+
if (!this.locked) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const res = await this.collection.updateOne({ _id: this._id }, { $set: { refreshedAt: new Date(), expiresAt: new Date(Date.now() + 60_000) } });
|
|
61
|
+
this.locked = res.matchedCount === 1;
|
|
62
|
+
return this.locked;
|
|
73
63
|
}
|
|
74
64
|
[Symbol.dispose]() {
|
|
75
65
|
this.free();
|
|
76
66
|
}
|
|
77
|
-
[Symbol.asyncDispose]() {
|
|
78
|
-
return
|
|
79
|
-
return this.free();
|
|
80
|
-
});
|
|
67
|
+
async [Symbol.asyncDispose]() {
|
|
68
|
+
return this.free();
|
|
81
69
|
}
|
|
82
70
|
}
|
|
83
71
|
class LockManager {
|
|
72
|
+
collection;
|
|
73
|
+
MongoLocksError = MongoLocksError;
|
|
84
74
|
constructor(collection) {
|
|
85
|
-
this.MongoLocksError = MongoLocksError;
|
|
86
75
|
this.collection = collection;
|
|
87
76
|
collection.createIndex({ action: 1 }, { unique: true });
|
|
88
77
|
collection.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
@@ -92,27 +81,26 @@ class LockManager {
|
|
|
92
81
|
*
|
|
93
82
|
* @returns a function that when called will release the lock
|
|
94
83
|
*/
|
|
95
|
-
lock(key) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
throw err;
|
|
84
|
+
async lock(key) {
|
|
85
|
+
const lockId = makeKey(key);
|
|
86
|
+
const id = new mongodb_1.ObjectId();
|
|
87
|
+
try {
|
|
88
|
+
await this.collection.insertOne({
|
|
89
|
+
_id: id,
|
|
90
|
+
action: lockId,
|
|
91
|
+
createdAt: new Date(),
|
|
92
|
+
refreshedAt: new Date(),
|
|
93
|
+
expiresAt: new Date(Date.now() + 60_000),
|
|
94
|
+
});
|
|
95
|
+
return new Lock(id, lockId, this.collection);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
if (err instanceof Error && "code" in err && err.code === 11000) {
|
|
99
|
+
return null;
|
|
114
100
|
}
|
|
115
|
-
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
116
103
|
}
|
|
117
104
|
}
|
|
118
105
|
exports.LockManager = LockManager;
|
|
106
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Collection, ObjectId } from "mongodb";
|
|
2
|
+
export declare class MongoLocksError extends Error {
|
|
3
|
+
constructor(message?: string);
|
|
4
|
+
}
|
|
5
|
+
interface LockModel {
|
|
6
|
+
_id: ObjectId;
|
|
7
|
+
action: unknown;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
refreshedAt: Date;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
}
|
|
12
|
+
declare class Lock {
|
|
13
|
+
_id: ObjectId;
|
|
14
|
+
action: unknown;
|
|
15
|
+
collection: Collection<LockModel>;
|
|
16
|
+
constructor(_id: ObjectId, action: unknown, collection: Collection<LockModel>);
|
|
17
|
+
locked: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Instead of calling `this.free` directly you can use the `using` syntax
|
|
20
|
+
*
|
|
21
|
+
* @returns true if the lock was successfully released. False if the lock was not found
|
|
22
|
+
*/
|
|
23
|
+
free(): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Refreshes the lock's TTL
|
|
26
|
+
*
|
|
27
|
+
* Automatically called every 10 seconds if the lock is still active, no
|
|
28
|
+
* need to call this manually
|
|
29
|
+
*
|
|
30
|
+
* @returns true if the lock was successfully refreshed. False if the lock was not found
|
|
31
|
+
*/
|
|
32
|
+
refresh(): Promise<boolean>;
|
|
33
|
+
[Symbol.dispose](): void;
|
|
34
|
+
[Symbol.asyncDispose](): Promise<boolean>;
|
|
35
|
+
}
|
|
36
|
+
export declare class LockManager {
|
|
37
|
+
collection: Collection<LockModel>;
|
|
38
|
+
MongoLocksError: typeof MongoLocksError;
|
|
39
|
+
constructor(collection: Collection);
|
|
40
|
+
/**
|
|
41
|
+
* Creates a DB lock based on the key provided
|
|
42
|
+
*
|
|
43
|
+
* @returns a function that when called will release the lock
|
|
44
|
+
*/
|
|
45
|
+
lock(key: unknown): Promise<Lock | null>;
|
|
46
|
+
}
|
|
47
|
+
export type { LockModel, Lock };
|
package/dist/esm/index.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { ObjectId } from "mongodb";
|
|
11
2
|
export class MongoLocksError extends Error {
|
|
12
3
|
constructor(message) {
|
|
@@ -18,36 +9,37 @@ const makeKey = (key) => {
|
|
|
18
9
|
return Array.isArray(key) ? { _key_array: key } : key;
|
|
19
10
|
};
|
|
20
11
|
class Lock {
|
|
12
|
+
_id;
|
|
13
|
+
action;
|
|
14
|
+
collection;
|
|
21
15
|
constructor(_id, action, collection) {
|
|
22
16
|
this._id = _id;
|
|
23
17
|
this.action = action;
|
|
24
18
|
this.collection = collection;
|
|
25
|
-
this.locked = true;
|
|
26
19
|
if (this.locked) {
|
|
27
|
-
(() =>
|
|
20
|
+
(async () => {
|
|
28
21
|
while (this.locked) {
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
23
|
+
await this.refresh().catch(() => {
|
|
31
24
|
console.error("Failed to refresh lock", action);
|
|
32
25
|
});
|
|
33
26
|
}
|
|
34
|
-
})
|
|
27
|
+
})();
|
|
35
28
|
}
|
|
36
29
|
}
|
|
30
|
+
locked = true;
|
|
37
31
|
/**
|
|
38
32
|
* Instead of calling `this.free` directly you can use the `using` syntax
|
|
39
33
|
*
|
|
40
34
|
* @returns true if the lock was successfully released. False if the lock was not found
|
|
41
35
|
*/
|
|
42
|
-
free() {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return result.deletedCount === 1;
|
|
50
|
-
});
|
|
36
|
+
async free() {
|
|
37
|
+
if (!this.locked) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
this.locked = false;
|
|
41
|
+
const result = await this.collection.deleteOne({ _id: this._id });
|
|
42
|
+
return result.deletedCount === 1;
|
|
51
43
|
}
|
|
52
44
|
/**
|
|
53
45
|
* Refreshes the lock's TTL
|
|
@@ -57,28 +49,25 @@ class Lock {
|
|
|
57
49
|
*
|
|
58
50
|
* @returns true if the lock was successfully refreshed. False if the lock was not found
|
|
59
51
|
*/
|
|
60
|
-
refresh() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return this.locked;
|
|
68
|
-
});
|
|
52
|
+
async refresh() {
|
|
53
|
+
if (!this.locked) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const res = await this.collection.updateOne({ _id: this._id }, { $set: { refreshedAt: new Date(), expiresAt: new Date(Date.now() + 60_000) } });
|
|
57
|
+
this.locked = res.matchedCount === 1;
|
|
58
|
+
return this.locked;
|
|
69
59
|
}
|
|
70
60
|
[Symbol.dispose]() {
|
|
71
61
|
this.free();
|
|
72
62
|
}
|
|
73
|
-
[Symbol.asyncDispose]() {
|
|
74
|
-
return
|
|
75
|
-
return this.free();
|
|
76
|
-
});
|
|
63
|
+
async [Symbol.asyncDispose]() {
|
|
64
|
+
return this.free();
|
|
77
65
|
}
|
|
78
66
|
}
|
|
79
67
|
export class LockManager {
|
|
68
|
+
collection;
|
|
69
|
+
MongoLocksError = MongoLocksError;
|
|
80
70
|
constructor(collection) {
|
|
81
|
-
this.MongoLocksError = MongoLocksError;
|
|
82
71
|
this.collection = collection;
|
|
83
72
|
collection.createIndex({ action: 1 }, { unique: true });
|
|
84
73
|
collection.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
@@ -88,26 +77,25 @@ export class LockManager {
|
|
|
88
77
|
*
|
|
89
78
|
* @returns a function that when called will release the lock
|
|
90
79
|
*/
|
|
91
|
-
lock(key) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
throw err;
|
|
80
|
+
async lock(key) {
|
|
81
|
+
const lockId = makeKey(key);
|
|
82
|
+
const id = new ObjectId();
|
|
83
|
+
try {
|
|
84
|
+
await this.collection.insertOne({
|
|
85
|
+
_id: id,
|
|
86
|
+
action: lockId,
|
|
87
|
+
createdAt: new Date(),
|
|
88
|
+
refreshedAt: new Date(),
|
|
89
|
+
expiresAt: new Date(Date.now() + 60_000),
|
|
90
|
+
});
|
|
91
|
+
return new Lock(id, lockId, this.collection);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (err instanceof Error && "code" in err && err.code === 11000) {
|
|
95
|
+
return null;
|
|
110
96
|
}
|
|
111
|
-
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
112
99
|
}
|
|
113
100
|
}
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAED,MAAM,OAAO,GAAG,CAAC,GAAY,EAAE,EAAE;IAC/B,4CAA4C;IAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACxD,CAAC,CAAC;AAUF,MAAM,IAAI;IACW;IAAsB;IAAwB;IAAjE,YAAmB,GAAa,EAAS,MAAe,EAAS,UAAiC;QAA/E,QAAG,GAAH,GAAG,CAAU;QAAS,WAAM,GAAN,MAAM,CAAS;QAAS,eAAU,GAAV,UAAU,CAAuB;QAChG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,CAAC,KAAK,IAAI,EAAE;gBACV,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;oBACnB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;oBAC5D,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;wBAC9B,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;oBAClD,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;IACH,CAAC;IAED,MAAM,GAAG,IAAI,CAAC;IAEd;;;;OAIG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAClE,OAAO,MAAM,CAAC,YAAY,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CACzC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EACjB,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,CAChF,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC;QAErC,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;CACF;AAED,MAAM,OAAO,WAAW;IACtB,UAAU,CAAwB;IAClC,eAAe,GAAG,eAAe,CAAC;IAElC,YAAY,UAAsB;QAChC,IAAI,CAAC,UAAU,GAAG,UAA8C,CAAC;QAEjE,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,UAAU,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,GAAY;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAE1B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC9B,GAAG,EAAE,EAAE;gBACP,MAAM,EAAE,MAAM;gBACd,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,WAAW,EAAE,IAAI,IAAI,EAAE;gBACvB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;aACzC,CAAC,CAAC;YAEH,OAAO,IAAI,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAChE,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongo-locks",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.2",
|
|
5
5
|
"description": "Simple and bountiful locks to avoid doing the same operation multiple times",
|
|
6
6
|
"main": "./dist/commonjs/index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@types/node": "^22.12.7",
|
|
33
33
|
"mongodb": "^6.5.0",
|
|
34
34
|
"tshy": "^3.1.0",
|
|
35
|
-
"typescript": "^5.
|
|
35
|
+
"typescript": "^5.9.0"
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
package/tsconfig.json
CHANGED
|
@@ -2,20 +2,13 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"strict": true,
|
|
4
4
|
/* Basic Options */
|
|
5
|
-
"target": "
|
|
6
|
-
"module": "
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
"outDir": "./dist"
|
|
5
|
+
"target": "es2022",
|
|
6
|
+
"module": "NodeNext",
|
|
7
|
+
"moduleResolution": "NodeNext",
|
|
8
|
+
"declaration": true /* Generates corresponding '.d.ts' file. */,
|
|
9
|
+
"sourceMap": true /* Generates corresponding '.map' file. */,
|
|
10
|
+
"outDir": "./dist" /* Redirect output structure to the directory. */
|
|
11
11
|
},
|
|
12
|
-
"include": [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
],
|
|
16
|
-
"exclude": [
|
|
17
|
-
"node_modules",
|
|
18
|
-
"dist",
|
|
19
|
-
"**/*.spec.ts"
|
|
20
|
-
]
|
|
21
|
-
}
|
|
12
|
+
"include": ["src/**/*.ts", "index.ts"],
|
|
13
|
+
"exclude": ["node_modules", "dist", "**/*.spec.ts"]
|
|
14
|
+
}
|