@daiso-tech/core 0.39.0 → 0.40.0

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 (63) hide show
  1. package/dist/cache/contracts/cache-adapter.contract.d.ts +9 -9
  2. package/dist/cache/contracts/database-cache-adapter.contract.d.ts +10 -10
  3. package/dist/cache/implementations/adapters/no-op-cache-adapter/no-op-cache-adapter.d.ts +9 -9
  4. package/dist/cache/implementations/adapters/no-op-cache-adapter/no-op-cache-adapter.js.map +1 -1
  5. package/dist/cache/implementations/derivables/cache/cache.js.map +1 -1
  6. package/dist/event-bus/contracts/event-bus-adapter.contract.d.ts +3 -3
  7. package/dist/event-bus/implementations/adapters/no-op-event-bus-adapter/no-op-event-bus-adapter.d.ts +3 -3
  8. package/dist/event-bus/implementations/derivables/event-bus/event-bus.d.ts +1 -0
  9. package/dist/event-bus/implementations/derivables/event-bus/event-bus.js +26 -26
  10. package/dist/event-bus/implementations/derivables/event-bus/event-bus.js.map +1 -1
  11. package/dist/event-bus/implementations/derivables/event-bus/listener-store.d.ts +11 -4
  12. package/dist/event-bus/implementations/derivables/event-bus/listener-store.js +17 -12
  13. package/dist/event-bus/implementations/derivables/event-bus/listener-store.js.map +1 -1
  14. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js +17 -20
  15. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js.map +1 -1
  16. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js +159 -752
  17. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js.map +1 -1
  18. package/dist/lock/contracts/database-lock-adapter.contract.d.ts +52 -14
  19. package/dist/lock/contracts/lock-adapter.contract.d.ts +29 -8
  20. package/dist/lock/contracts/lock-adapter.contract.js +10 -1
  21. package/dist/lock/contracts/lock-adapter.contract.js.map +1 -1
  22. package/dist/lock/contracts/lock.contract.d.ts +17 -12
  23. package/dist/lock/contracts/lock.errors.d.ts +10 -0
  24. package/dist/lock/contracts/lock.errors.js +12 -0
  25. package/dist/lock/contracts/lock.errors.js.map +1 -1
  26. package/dist/lock/contracts/lock.events.d.ts +12 -0
  27. package/dist/lock/contracts/lock.events.js +1 -0
  28. package/dist/lock/contracts/lock.events.js.map +1 -1
  29. package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.d.ts +24 -6
  30. package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.js +126 -31
  31. package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.js.map +1 -1
  32. package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.d.ts +20 -7
  33. package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.js +59 -35
  34. package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.js.map +1 -1
  35. package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.d.ts +9 -9
  36. package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.js +150 -78
  37. package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.js.map +1 -1
  38. package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.d.ts +5 -5
  39. package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.js +3 -2
  40. package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.js.map +1 -1
  41. package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.d.ts +5 -5
  42. package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.js +44 -22
  43. package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.js.map +1 -1
  44. package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.d.ts +3 -3
  45. package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.js +42 -10
  46. package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.js.map +1 -1
  47. package/dist/lock/implementations/derivables/lock-provider/is-database-lock-adapter.js +7 -5
  48. package/dist/lock/implementations/derivables/lock-provider/is-database-lock-adapter.js.map +1 -1
  49. package/dist/lock/implementations/derivables/lock-provider/lock-provider.js.map +1 -1
  50. package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.d.ts +1 -1
  51. package/dist/lock/implementations/derivables/lock-provider/lock.d.ts +3 -2
  52. package/dist/lock/implementations/derivables/lock-provider/lock.js +60 -41
  53. package/dist/lock/implementations/derivables/lock-provider/lock.js.map +1 -1
  54. package/dist/lock/implementations/test-utilities/database-lock-adapter.test-suite.js +184 -166
  55. package/dist/lock/implementations/test-utilities/database-lock-adapter.test-suite.js.map +1 -1
  56. package/dist/lock/implementations/test-utilities/lock-adapter.test-suite.js +240 -41
  57. package/dist/lock/implementations/test-utilities/lock-adapter.test-suite.js.map +1 -1
  58. package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js +2700 -1510
  59. package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js.map +1 -1
  60. package/dist/utilities/contracts/deinitizable.contract.d.ts +1 -1
  61. package/dist/utilities/contracts/initizable.contract.d.ts +1 -1
  62. package/dist/utilities/contracts/prunable.contract.d.ts +1 -1
  63. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * @module Lock
3
3
  */
4
- import { UnexpectedError, } from "../../../../utilities/_module-exports.js";
5
- import { ObjectId } from "mongodb";
4
+ import {} from "../../../../utilities/_module-exports.js";
5
+ import { LOCK_REFRESH_RESULT, } from "../../../../lock/contracts/_module-exports.js";
6
6
  /**
7
7
  * To utilize the `MongodbLockAdapter`, you must install the [`"mongodb"`](https://www.npmjs.com/package/mongodb) package.
8
8
  *
@@ -41,109 +41,181 @@ export class MongodbLockAdapter {
41
41
  * Note the `init` method needs to be called before using the adapter.
42
42
  */
43
43
  async init() {
44
- await this.collection.createIndex({
45
- key: 1,
46
- }, {
47
- unique: true,
48
- });
49
- await this.collection.createIndex("expiresAt", {
50
- expireAfterSeconds: 0,
51
- });
44
+ // Should throw if the index already exists thats why the try catch is used.
45
+ try {
46
+ await this.collection.createIndex({
47
+ key: 1,
48
+ }, {
49
+ unique: true,
50
+ });
51
+ }
52
+ catch {
53
+ /* EMPTY */
54
+ }
55
+ // Should throw if the index already exists thats why the try catch is used.
56
+ try {
57
+ await this.collection.createIndex("expiration", {
58
+ expireAfterSeconds: 0,
59
+ });
60
+ }
61
+ catch {
62
+ /* EMPTY */
63
+ }
52
64
  }
53
65
  /**
54
66
  * Removes the collection where the lock keys are stored and all it's related indexes.
55
67
  * Note all lock data will be removed.
56
68
  */
57
69
  async deInit() {
58
- await this.collection.dropIndexes();
59
- await this.database.dropCollection(this.collectionName);
60
- }
61
- async insert(key, owner, expiration) {
62
- const insertResult = await this.collection.insertOne({
63
- _id: new ObjectId(),
64
- key,
65
- owner,
66
- expiresAt: expiration,
67
- });
68
- if (!insertResult.acknowledged) {
69
- throw new UnexpectedError("Mongodb insertion was not acknowledged");
70
+ // Should throw if the collection already does not exists thats why the try catch is used.
71
+ try {
72
+ await this.collection.dropIndexes();
73
+ }
74
+ catch {
75
+ /* EMPTY */
76
+ }
77
+ // Should throw if the collection already does not exists thats why the try catch is used.
78
+ try {
79
+ await this.database.dropCollection(this.collectionName);
80
+ }
81
+ catch {
82
+ /* EMPTY */
70
83
  }
71
84
  }
72
- async update(key, owner, expiration) {
73
- const updateResult = await this.collection.updateOne({
74
- key,
85
+ async acquire(key, owner, ttl) {
86
+ const expiration = ttl?.toEndDate() ?? null;
87
+ const isExpiredQuery = {
75
88
  $and: [
76
89
  {
77
- expiresAt: {
78
- $ne: null,
79
- },
90
+ $ne: ["$expiration", null],
80
91
  },
81
92
  {
82
- expiresAt: {
83
- $lte: new Date(),
84
- },
93
+ $lte: ["$expiration", new Date()],
85
94
  },
86
95
  ],
87
- }, {
88
- $set: {
89
- owner,
90
- expiresAt: expiration,
96
+ };
97
+ const lockData = await this.collection.findOneAndUpdate({
98
+ key,
99
+ }, [
100
+ {
101
+ $set: {
102
+ key,
103
+ owner: {
104
+ $ifNull: ["$owner", owner],
105
+ },
106
+ expiration: {
107
+ $ifNull: ["$expiration", expiration],
108
+ },
109
+ },
91
110
  },
111
+ {
112
+ $set: {
113
+ owner: {
114
+ $cond: {
115
+ if: isExpiredQuery,
116
+ then: owner,
117
+ else: "$owner",
118
+ },
119
+ },
120
+ expiration: {
121
+ $cond: {
122
+ if: isExpiredQuery,
123
+ then: expiration,
124
+ else: "$expiration",
125
+ },
126
+ },
127
+ },
128
+ },
129
+ ], {
130
+ upsert: true,
92
131
  });
93
- if (!updateResult.acknowledged) {
94
- throw new UnexpectedError("Mongodb update was not acknowledged");
132
+ if (lockData === null) {
133
+ return true;
95
134
  }
96
- return updateResult.modifiedCount; // > 0;
97
- }
98
- async remove(key, owner) {
99
- if (owner === null) {
100
- const deleteResult = await this.collection.deleteOne({
101
- key,
102
- });
103
- if (!deleteResult.acknowledged) {
104
- throw new UnexpectedError("Mongodb deletion was not acknowledged");
105
- }
106
- return;
135
+ if (lockData.expiration === null) {
136
+ return false;
107
137
  }
108
- const deleteResult = await this.collection.deleteOne({
138
+ return lockData.expiration <= new Date();
139
+ }
140
+ async release(key, owner) {
141
+ const isUnexpirableQuery = {
142
+ expiration: {
143
+ $eq: null,
144
+ },
145
+ };
146
+ const isUnexpiredQuery = {
147
+ expiration: {
148
+ $gt: new Date(),
149
+ },
150
+ };
151
+ const lockData = await this.collection.findOneAndDelete({
109
152
  key,
110
153
  owner,
154
+ $or: [isUnexpirableQuery, isUnexpiredQuery],
111
155
  });
112
- if (!deleteResult.acknowledged) {
113
- throw new UnexpectedError("Mongodb deletion was not acknowledged");
156
+ if (lockData === null) {
157
+ return false;
158
+ }
159
+ const { expiration } = lockData;
160
+ const hasNoExpiration = expiration === null;
161
+ if (hasNoExpiration) {
162
+ return true;
114
163
  }
164
+ const { owner: currentOwner } = lockData;
165
+ const isNotExpired = expiration > new Date();
166
+ const isCurrentOwner = owner === currentOwner;
167
+ return isNotExpired && isCurrentOwner;
115
168
  }
116
- async refresh(key, owner, expiration) {
117
- const updateResult = await this.collection.updateOne({
118
- key,
119
- owner,
120
- }, {
121
- $set: {
122
- expiresAt: expiration,
123
- },
124
- });
125
- if (!updateResult.acknowledged) {
126
- throw new UnexpectedError("Mongodb update was not acknowledged");
169
+ async forceRelease(key) {
170
+ const lockData = await this.collection.findOneAndDelete({ key });
171
+ if (lockData === null) {
172
+ return false;
127
173
  }
128
- return updateResult.modifiedCount; // > 0;
174
+ if (lockData.expiration === null) {
175
+ return true;
176
+ }
177
+ const isNotExpired = lockData.expiration >= new Date();
178
+ return isNotExpired;
129
179
  }
130
- async find(key) {
131
- const document = await this.collection.findOne({
132
- key: key,
133
- }, {
134
- projection: {
135
- _id: 0,
136
- owner: 1,
137
- expiresAt: 1,
180
+ async refresh(key, owner, ttl) {
181
+ const isUnexpiredQuery = {
182
+ $and: [
183
+ {
184
+ $ne: ["$expiration", null],
185
+ },
186
+ {
187
+ $gt: ["$expiration", new Date()],
188
+ },
189
+ ],
190
+ };
191
+ const lockData = await this.collection.findOneAndUpdate({
192
+ key,
193
+ }, [
194
+ {
195
+ $set: {
196
+ expiration: {
197
+ $cond: {
198
+ if: isUnexpiredQuery,
199
+ then: ttl.toEndDate(),
200
+ else: "$expiration",
201
+ },
202
+ },
203
+ },
138
204
  },
139
- });
140
- if (document === null) {
141
- return null;
205
+ ]);
206
+ if (lockData === null) {
207
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
142
208
  }
143
- return {
144
- owner: document.owner,
145
- expiration: document.expiresAt,
146
- };
209
+ if (lockData.owner !== owner) {
210
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
211
+ }
212
+ if (lockData.expiration === null) {
213
+ return LOCK_REFRESH_RESULT.UNEXPIRABLE_KEY;
214
+ }
215
+ if (lockData.expiration <= new Date()) {
216
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
217
+ }
218
+ return LOCK_REFRESH_RESULT.REFRESHED;
147
219
  }
148
220
  }
149
221
  //# sourceMappingURL=mongodb-lock-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mongodb-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mongodb-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * @module Lock
3
3
  */
4
4
  import type { TimeSpan } from "../../../../utilities/_module-exports.js";
5
- import type { ILockAdapter } from "../../../../lock/contracts/_module-exports.js";
5
+ import { type ILockAdapter, type LockRefreshResult } from "../../../../lock/contracts/_module-exports.js";
6
6
  /**
7
7
  * This `NoOpLockAdapter` will do nothing and is used for easily mocking {@link ILockProvider | `ILockProvider`} for testing.
8
8
  *
@@ -10,8 +10,8 @@ import type { ILockAdapter } from "../../../../lock/contracts/_module-exports.js
10
10
  * @group Adapters
11
11
  */
12
12
  export declare class NoOpLockAdapter implements ILockAdapter {
13
- acquire(_key: string, _owner: string, _ttl: TimeSpan | null): PromiseLike<boolean>;
14
- release(_key: string, _owner: string): PromiseLike<boolean>;
15
- forceRelease(_key: string): PromiseLike<void>;
16
- refresh(_key: string, _owner: string, _ttl: TimeSpan): PromiseLike<boolean>;
13
+ acquire(_key: string, _owner: string, _ttl: TimeSpan | null): Promise<boolean>;
14
+ release(_key: string, _owner: string): Promise<boolean>;
15
+ forceRelease(_key: string): Promise<boolean>;
16
+ refresh(_key: string, _owner: string, _ttl: TimeSpan): Promise<LockRefreshResult>;
17
17
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @module Lock
3
3
  */
4
+ import { LOCK_REFRESH_RESULT, } from "../../../../lock/contracts/_module-exports.js";
4
5
  /**
5
6
  * This `NoOpLockAdapter` will do nothing and is used for easily mocking {@link ILockProvider | `ILockProvider`} for testing.
6
7
  *
@@ -15,10 +16,10 @@ export class NoOpLockAdapter {
15
16
  return Promise.resolve(true);
16
17
  }
17
18
  forceRelease(_key) {
18
- return Promise.resolve();
19
+ return Promise.resolve(true);
19
20
  }
20
21
  refresh(_key, _owner, _ttl) {
21
- return Promise.resolve(true);
22
+ return Promise.resolve(LOCK_REFRESH_RESULT.REFRESHED);
22
23
  }
23
24
  }
24
25
  //# sourceMappingURL=no-op-lock-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-op-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACxB,OAAO,CACH,IAAY,EACZ,MAAc,EACd,IAAqB;QAErB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,IAAY,EAAE,MAAc;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,IAAY;QACrB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CACH,IAAY,EACZ,MAAc,EACd,IAAc;QAEd,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;CACJ"}
1
+ {"version":3,"file":"no-op-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACH,mBAAmB,GAGtB,MAAM,qCAAqC,CAAC;AAI7C;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACxB,OAAO,CACH,IAAY,EACZ,MAAc,EACd,IAAqB;QAErB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,IAAY,EAAE,MAAc;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,IAAY;QACrB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CACH,IAAY,EACZ,MAAc,EACd,IAAc;QAEd,OAAO,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACJ"}
@@ -2,14 +2,14 @@
2
2
  * @module Lock
3
3
  */
4
4
  import type { TimeSpan } from "../../../../utilities/_module-exports.js";
5
- import type { ILockAdapter } from "../../../../lock/contracts/_module-exports.js";
5
+ import { LOCK_REFRESH_RESULT, type ILockAdapter, type LockRefreshResult } from "../../../../lock/contracts/_module-exports.js";
6
6
  import type { Redis } from "ioredis";
7
7
  import type { Result } from "ioredis";
8
8
  declare module "ioredis" {
9
9
  interface RedisCommander<Context> {
10
- daiso_lock_acquire(key: string, owner: string, ttl: string): Result<number, Context>;
10
+ daiso_lock_acquire(key: string, owner: string, expiration: string): Result<number, Context>;
11
11
  daiso_lock_release(key: string, owner: string): Result<number, Context>;
12
- daiso_lock_refresh(key: string, owner: string, ttl: string): Result<number, Context>;
12
+ daiso_lock_refresh(key: string, owner: string, expiration: string, REFRESHED: typeof LOCK_REFRESH_RESULT.REFRESHED, UNOWNED_REFRESH: typeof LOCK_REFRESH_RESULT.UNOWNED_REFRESH, UNEXPIRABLE_KEY: typeof LOCK_REFRESH_RESULT.UNEXPIRABLE_KEY): Result<LockRefreshResult, Context>;
13
13
  }
14
14
  }
15
15
  /**
@@ -38,6 +38,6 @@ export declare class RedisLockAdapter implements ILockAdapter {
38
38
  private initRefreshComand;
39
39
  acquire(key: string, owner: string, ttl: TimeSpan | null): Promise<boolean>;
40
40
  release(key: string, owner: string): Promise<boolean>;
41
- forceRelease(key: string): Promise<void>;
42
- refresh(key: string, owner: string, ttl: TimeSpan): Promise<boolean>;
41
+ forceRelease(key: string): Promise<boolean>;
42
+ refresh(key: string, owner: string, ttl: TimeSpan): Promise<LockRefreshResult>;
43
43
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @module Lock
3
3
  */
4
+ import { LOCK_REFRESH_RESULT, } from "../../../../lock/contracts/_module-exports.js";
4
5
  /**
5
6
  * To utilize the `RedisLockAdapter`, you must install the [`"ioredis"`](https://www.npmjs.com/package/ioredis) package.
6
7
  *
@@ -36,21 +37,20 @@ export class RedisLockAdapter {
36
37
  lua: `
37
38
  local key = KEYS[1];
38
39
  local owner = ARGV[1];
39
- local ttl = ARGV[2]
40
-
41
- local hasKey = redis.call("exists", key)
42
- if hasKey == 1 then
40
+ local expiration = tonumber(ARGV[2])
41
+
42
+ if redis.call("exists", key) == 1 then
43
43
  return 0
44
44
  end
45
45
 
46
- if ttl == "null" then
46
+ if expiration == nil then
47
47
  redis.call("set", key, owner, "nx")
48
48
  else
49
- redis.call("set", key, owner, "px", ttl, "nx")
49
+ redis.call("set", key, owner, "px", expiration, "nx")
50
50
  end
51
51
 
52
52
  return 1
53
- `,
53
+ `,
54
54
  });
55
55
  }
56
56
  initReleaseCommand() {
@@ -63,14 +63,19 @@ export class RedisLockAdapter {
63
63
  local key = KEYS[1];
64
64
  local owner = ARGV[1];
65
65
 
66
- local owner_ = redis.call("get", key)
67
- if owner_ == owner then
68
- redis.call("del", key)
69
- return 1
66
+ if redis.call("exists", key) == 0 then
67
+ return 0
70
68
  end
69
+
70
+ local isNotCurrentOwner = redis.call("get", key) ~= owner
71
+ if isNotCurrentOwner then
72
+ return 0
73
+ end
74
+
75
+ redis.call("del", key)
71
76
 
72
- return 0
73
- `,
77
+ return 1
78
+ `,
74
79
  });
75
80
  }
76
81
  initRefreshComand() {
@@ -80,16 +85,33 @@ export class RedisLockAdapter {
80
85
  this.database.defineCommand("daiso_lock_refresh", {
81
86
  numberOfKeys: 1,
82
87
  lua: `
88
+ -- Arguments
83
89
  local key = KEYS[1];
84
90
  local owner = ARGV[1];
85
- local ttl = ARGV[2]
91
+ local expiration = ARGV[2]
92
+
93
+ -- Constant values
94
+ local REFRESHED = ARGV[3]
95
+ local UNOWNED_REFRESH = ARGV[4]
96
+ local UNEXPIRABLE_KEY = ARGV[5]
97
+
98
+ if redis.call("exists", key) == 0 then
99
+ return UNOWNED_REFRESH
100
+ end
101
+
102
+ local isNotCurrentOwner = redis.call("get", key) ~= owner
103
+ if redis.call("get", key) ~= owner then
104
+ return UNOWNED_REFRESH
105
+ end
86
106
 
87
- local owner_ = redis.call("get", key)
88
- if owner_ == owner then
89
- redis.call("pexpire", key, ttl)
90
- return 1
107
+ local currentExpiration = redis.call("pttl", key)
108
+ local isUnexpireable = currentExpiration == -1
109
+ if isUnexpireable then
110
+ return UNEXPIRABLE_KEY
91
111
  end
92
- return 0
112
+
113
+ redis.call("pexpire", key, expiration)
114
+ return REFRESHED
93
115
  `,
94
116
  });
95
117
  }
@@ -102,11 +124,11 @@ export class RedisLockAdapter {
102
124
  return result === 1;
103
125
  }
104
126
  async forceRelease(key) {
105
- await this.database.del(key);
127
+ const result = await this.database.del(key);
128
+ return result > 0;
106
129
  }
107
130
  async refresh(key, owner, ttl) {
108
- const result = await this.database.daiso_lock_refresh(key, owner, ttl.toMilliseconds().toString());
109
- return result === 1;
131
+ return await this.database.daiso_lock_refresh(key, owner, ttl.toMilliseconds().toString(), LOCK_REFRESH_RESULT.REFRESHED, LOCK_REFRESH_RESULT.UNOWNED_REFRESH, LOCK_REFRESH_RESULT.UNEXPIRABLE_KEY);
110
132
  }
111
133
  }
112
134
  //# sourceMappingURL=redis-lock-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redis-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAgB;IAWI;IAV7B;;;;;;;;;OASG;IACH,YAA6B,QAAe;QAAf,aAAQ,GAAR,QAAQ,CAAO;QACxC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAEO,iBAAiB;QACrB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC9C,YAAY,EAAE,CAAC;YACf,GAAG,EAAE;;;;;;;;;;;;;;;;;iBAiBA;SACR,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB;QACtB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC9C,YAAY,EAAE,CAAC;YACf,GAAG,EAAE;;;;;;;;;;;iBAWA;SACR,CAAC,CAAC;IACP,CAAC;IAEO,iBAAiB;QACrB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC9C,YAAY,EAAE,CAAC;YACf,GAAG,EAAE;;;;;;;;;;;aAWJ;SACJ,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,GAAoB;QAEpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CACjD,GAAG,EACH,KAAK,EACL,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,IAAI,CAAC,CACxC,CAAC;QACF,OAAO,MAAM,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClE,OAAO,MAAM,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC1B,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa,EAAE,GAAa;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CACjD,GAAG,EACH,KAAK,EACL,GAAG,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,CAClC,CAAC;QACF,OAAO,MAAM,KAAK,CAAC,CAAC;IACxB,CAAC;CACJ"}
1
+ {"version":3,"file":"redis-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACH,mBAAmB,GAGtB,MAAM,qCAAqC,CAAC;AAuB7C;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAgB;IAWI;IAV7B;;;;;;;;;OASG;IACH,YAA6B,QAAe;QAAf,aAAQ,GAAR,QAAQ,CAAO;QACxC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAEO,iBAAiB;QACrB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC9C,YAAY,EAAE,CAAC;YACf,GAAG,EAAE;;;;;;;;;;;;;;;;aAgBJ;SACJ,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB;QACtB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC9C,YAAY,EAAE,CAAC;YACf,GAAG,EAAE;;;;;;;;;;;;;;;;aAgBJ;SACJ,CAAC,CAAC;IACP,CAAC;IAEO,iBAAiB;QACrB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACzD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC9C,YAAY,EAAE,CAAC;YACf,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA4BJ;SACJ,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,GAAoB;QAEpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CACjD,GAAG,EACH,KAAK,EACL,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,IAAI,CAAC,CACxC,CAAC;QACF,OAAO,MAAM,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClE,OAAO,MAAM,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5C,OAAO,MAAM,GAAG,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,GAAa;QAEb,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CACzC,GAAG,EACH,KAAK,EACL,GAAG,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,EAC/B,mBAAmB,CAAC,SAAS,EAC7B,mBAAmB,CAAC,eAAe,EACnC,mBAAmB,CAAC,eAAe,CACtC,CAAC;IACN,CAAC;CACJ"}
@@ -2,7 +2,7 @@
2
2
  * @module Lock
3
3
  */
4
4
  import { type TimeSpan } from "../../../../utilities/_module-exports.js";
5
- import type { IDatabaseLockAdapter, ILockAdapter } from "../../../../lock/contracts/_module-exports.js";
5
+ import { type IDatabaseLockAdapter, type ILockAdapter, type LockRefreshResult } from "../../../../lock/contracts/_module-exports.js";
6
6
  /**
7
7
  * @internal
8
8
  */
@@ -11,6 +11,6 @@ export declare class DatabaseLockAdapter implements ILockAdapter {
11
11
  constructor(adapter: IDatabaseLockAdapter);
12
12
  acquire(key: string, owner: string, ttl: TimeSpan | null): Promise<boolean>;
13
13
  release(key: string, owner: string): Promise<boolean>;
14
- forceRelease(key: string): Promise<void>;
15
- refresh(key: string, owner: string, ttl: TimeSpan): Promise<boolean>;
14
+ forceRelease(key: string): Promise<boolean>;
15
+ refresh(key: string, owner: string, ttl: TimeSpan): Promise<LockRefreshResult>;
16
16
  }
@@ -2,6 +2,7 @@
2
2
  * @module Lock
3
3
  */
4
4
  import { UnexpectedError } from "../../../../utilities/_module-exports.js";
5
+ import { LOCK_REFRESH_RESULT, } from "../../../../lock/contracts/_module-exports.js";
5
6
  /**
6
7
  * @internal
7
8
  */
@@ -11,8 +12,8 @@ export class DatabaseLockAdapter {
11
12
  this.adapter = adapter;
12
13
  }
13
14
  async acquire(key, owner, ttl) {
14
- const expiration = ttl?.toEndDate() ?? null;
15
15
  try {
16
+ const expiration = ttl?.toEndDate() ?? null;
16
17
  // An error will be thrown if the lock already exists
17
18
  await this.adapter.insert(key, owner, expiration);
18
19
  return true;
@@ -21,25 +22,56 @@ export class DatabaseLockAdapter {
21
22
  if (error instanceof UnexpectedError) {
22
23
  throw error;
23
24
  }
24
- const result = await this.adapter.update(key, owner, expiration);
25
+ const expiration = ttl?.toEndDate() ?? null;
26
+ const result = await this.adapter.updateIfExpired(key, owner, expiration);
25
27
  return result > 0;
26
28
  }
27
29
  }
28
30
  async release(key, owner) {
29
- const lock = await this.adapter.find(key);
30
- if (lock === null) {
31
+ const lockData = await this.adapter.removeIfOwner(key, owner);
32
+ if (lockData === null) {
33
+ return false;
34
+ }
35
+ const { expiration } = lockData;
36
+ const hasNoExpiration = expiration === null;
37
+ if (hasNoExpiration) {
31
38
  return true;
32
39
  }
33
- await this.adapter.remove(key, owner);
34
- const isOwner = lock.owner === owner;
35
- return isOwner;
40
+ const { owner: currentOwner } = lockData;
41
+ const isNotExpired = expiration > new Date();
42
+ const isCurrentOwner = owner === currentOwner;
43
+ return isNotExpired && isCurrentOwner;
36
44
  }
37
45
  async forceRelease(key) {
38
- await this.adapter.remove(key, null);
46
+ const lockData = await this.adapter.remove(key);
47
+ if (lockData === null) {
48
+ return false;
49
+ }
50
+ if (lockData.expiration === null) {
51
+ return true;
52
+ }
53
+ return lockData.expiration > new Date();
39
54
  }
40
55
  async refresh(key, owner, ttl) {
41
- const result = await this.adapter.refresh(key, owner, ttl.toEndDate());
42
- return result > 0;
56
+ const lockData = await this.adapter.find(key);
57
+ if (lockData === null) {
58
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
59
+ }
60
+ if (lockData.owner !== owner) {
61
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
62
+ }
63
+ if (lockData.expiration === null) {
64
+ return LOCK_REFRESH_RESULT.UNEXPIRABLE_KEY;
65
+ }
66
+ if (lockData.expiration <= new Date()) {
67
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
68
+ }
69
+ const expiration = ttl.toEndDate();
70
+ const result = await this.adapter.updateExpirationIfOwner(key, owner, expiration);
71
+ if (result > 0) {
72
+ return LOCK_REFRESH_RESULT.REFRESHED;
73
+ }
74
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
43
75
  }
44
76
  }
45
77
  //# sourceMappingURL=database-lock-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"database-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/derivables/lock-provider/database-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAiB,MAAM,gCAAgC,CAAC;AAMhF;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACC;IAA7B,YAA6B,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAE9D,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,GAAoB;QAEpB,MAAM,UAAU,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC;QAE5C,IAAI,CAAC;YACD,qDAAqD;YACrD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAC;YAChB,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;YACjE,OAAO,MAAM,GAAG,CAAC,CAAC;QACtB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa;QACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;QACrC,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa,EAAE,GAAa;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACvE,OAAO,MAAM,GAAG,CAAC,CAAC;IACtB,CAAC;CACJ"}
1
+ {"version":3,"file":"database-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/derivables/lock-provider/database-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAiB,MAAM,gCAAgC,CAAC;AAChF,OAAO,EACH,mBAAmB,GAItB,MAAM,qCAAqC,CAAC;AAE7C;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACC;IAA7B,YAA6B,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAE9D,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,GAAoB;QAEpB,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC;YAC5C,qDAAqD;YACrD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACtB,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAC;YAChB,CAAC;YACD,MAAM,UAAU,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAC7C,GAAG,EACH,KAAK,EACL,UAAU,CACb,CAAC;YACF,OAAO,MAAM,GAAG,CAAC,CAAC;QACtB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAa;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;QAChC,MAAM,eAAe,GAAG,UAAU,KAAK,IAAI,CAAC;QAC5C,IAAI,eAAe,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC;QACzC,MAAM,YAAY,GAAG,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7C,MAAM,cAAc,GAAG,KAAK,KAAK,YAAY,CAAC;QAC9C,OAAO,YAAY,IAAI,cAAc,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,GAAa;QAEb,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,mBAAmB,CAAC,eAAe,CAAC;QAC/C,CAAC;QAED,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,mBAAmB,CAAC,eAAe,CAAC;QAC/C,CAAC;QAED,IAAI,QAAQ,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC/B,OAAO,mBAAmB,CAAC,eAAe,CAAC;QAC/C,CAAC;QAED,IAAI,QAAQ,CAAC,UAAU,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YACpC,OAAO,mBAAmB,CAAC,eAAe,CAAC;QAC/C,CAAC;QAED,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CACrD,GAAG,EACH,KAAK,EACL,UAAU,CACb,CAAC;QACF,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACb,OAAO,mBAAmB,CAAC,SAAS,CAAC;QACzC,CAAC;QACD,OAAO,mBAAmB,CAAC,eAAe,CAAC;IAC/C,CAAC;CACJ"}
@@ -5,12 +5,14 @@ export function isDatabaseLockAdapter(adapter) {
5
5
  const adapter_ = adapter;
6
6
  return (typeof adapter_["insert"] === "function" &&
7
7
  adapter_["insert"].length === 3 &&
8
- typeof adapter_["update"] === "function" &&
9
- adapter_["update"].length === 3 &&
8
+ typeof adapter_["updateIfExpired"] === "function" &&
9
+ adapter_["updateIfExpired"].length === 3 &&
10
10
  typeof adapter_["remove"] === "function" &&
11
- adapter_["remove"].length === 2 &&
12
- typeof adapter_["refresh"] === "function" &&
13
- adapter_["refresh"].length === 3 &&
11
+ adapter_["remove"].length === 1 &&
12
+ typeof adapter_["removeIfOwner"] === "function" &&
13
+ adapter_["removeIfOwner"].length === 2 &&
14
+ typeof adapter_["updateExpirationIfOwner"] === "function" &&
15
+ adapter_["updateExpirationIfOwner"].length === 3 &&
14
16
  typeof adapter_["find"] === "function" &&
15
17
  adapter_["find"].length === 1);
16
18
  }