@adaptivestone/framework 5.0.0-beta.7 → 5.0.0-beta.8

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/CHANGELOG.md CHANGED
@@ -1,9 +1,12 @@
1
- ### 5.0.0-beta.7
2
- [UPDATE] update deps
3
- [UPDATE] change vitest shutdown behavior as mongo driver v6.13 change befaviur that affect us (MongoClient.close now closes any outstanding cursors)
1
+ ### 5.0.0-beta.8
4
2
 
3
+ [UPDATE] update deps
4
+ [NEW] Lock model for workingwir locks via mongoDB
5
5
 
6
+ ### 5.0.0-beta.7
6
7
 
8
+ [UPDATE] update deps
9
+ [UPDATE] change vitest shutdown behavior as mongo driver v6.13 change befaviur that affect us (MongoClient.close now closes any outstanding cursors)
7
10
 
8
11
  ### 5.0.0-beta.5
9
12
 
package/jsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "module": "NodeNext",
4
- "target": "ES2022",
4
+ "target": "ES2024",
5
5
  "moduleResolution": "nodenext",
6
6
  "checkJs": true
7
7
  },
package/models/Lock.js ADDED
@@ -0,0 +1,107 @@
1
+ import AbstractModel from '../modules/AbstractModel.js';
2
+
3
+ class Lock extends AbstractModel {
4
+ initHooks() {
5
+ this.mongooseSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
6
+ }
7
+
8
+ // eslint-disable-next-line class-methods-use-this
9
+ get modelSchema() {
10
+ return {
11
+ _id: { type: String, required: true },
12
+ expiredAt: {
13
+ type: Date,
14
+ },
15
+ };
16
+ }
17
+
18
+ /**
19
+ * acquire lock based on lock name
20
+ * @param {string} name
21
+ * @param {number} [ttlSeconds=30]
22
+ * @returns {Promise<boolean>}
23
+ */
24
+ static async acquireLock(name, ttlSeconds = 30) {
25
+ try {
26
+ await this.create({
27
+ _id: name,
28
+ expiredAt: new Date(Date.now() + ttlSeconds * 1000),
29
+ });
30
+ } catch (error) {
31
+ if (error.code !== 11000) {
32
+ // not a duplicate leys
33
+ throw error;
34
+ }
35
+ return false;
36
+ }
37
+ return true;
38
+ }
39
+
40
+ /**
41
+ * release lock based on lock name
42
+ * @param {string} name
43
+ * @returns {Promise<boolean>}
44
+ */
45
+ static async releaseLock(name) {
46
+ const res = await this.deleteOne({ _id: name });
47
+ if (res.acknowledged && res.deletedCount) {
48
+ return true;
49
+ }
50
+ return false;
51
+ }
52
+
53
+ /**
54
+ * wait lock based on lock name
55
+ * @param {string} name
56
+ * @returns {Promise}
57
+ */
58
+ static async waitForUnlock(name) {
59
+ const res = await this.findOne({ _id: name });
60
+ if (!res) {
61
+ return Promise.resolve();
62
+ }
63
+
64
+ return new Promise((resolve) => {
65
+ const stream = this.watch([
66
+ { $match: { operationType: 'delete', 'documentKey._id': name } },
67
+ ]);
68
+ stream.on('change', () => {
69
+ stream.close();
70
+ resolve();
71
+ });
72
+ });
73
+ }
74
+
75
+ /**
76
+ * get lock remaining time based on lock name
77
+ * @param {string} name
78
+ * @returns {Promise<{ttl: number}>}
79
+ */
80
+ static async getLockData(name) {
81
+ const res = await this.findOne({ _id: name });
82
+ if (!res) {
83
+ return { ttl: 0 };
84
+ }
85
+ return { ttl: res.expiredAt.getTime() - Date.now() };
86
+ }
87
+
88
+ /**
89
+ * get lock remaining time based on lock name
90
+ * @param {string[]} names
91
+ * @returns {Promise<{name: string, ttl: number}[]>}
92
+ */
93
+ static async getLocksData(names) {
94
+ const res = await this.find({ _id: { $in: names } });
95
+ const lockMap = new Map(res.map((lock) => [lock._id, lock]));
96
+
97
+ return names.map((name) => {
98
+ const lock = lockMap.get(name);
99
+ return {
100
+ name,
101
+ ttl: lock ? lock.expiredAt.getTime() - Date.now() : 0,
102
+ };
103
+ });
104
+ }
105
+ }
106
+
107
+ export default Lock;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptivestone/framework",
3
- "version": "5.0.0-beta.7",
3
+ "version": "5.0.0-beta.8",
4
4
  "description": "Adaptive stone node js framework",
5
5
  "main": "index.js",
6
6
  "type": "module",