@daiso-tech/core 0.38.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 (152) hide show
  1. package/README.md +5 -1
  2. package/dist/async/backof-policies/constant-backoff-policy/constant-backoff-policy.d.ts +1 -1
  3. package/dist/async/backof-policies/exponential-backoff-policy/exponential-backoff-policy.d.ts +2 -2
  4. package/dist/async/backof-policies/linear-backoff-policy/linear-backoff-policy.d.ts +1 -1
  5. package/dist/async/backof-policies/polynomial-backoff-policy/polynomial-backoff-policy.d.ts +2 -2
  6. package/dist/async/middlewares/bulkhead/bulkhead.middleware.d.ts +2 -2
  7. package/dist/async/middlewares/hedging/sequential-hedging.middleware.js +2 -2
  8. package/dist/async/middlewares/hedging/sequential-hedging.middleware.js.map +1 -1
  9. package/dist/async/middlewares/retry/retry.middleware.js +2 -2
  10. package/dist/async/middlewares/retry/retry.middleware.js.map +1 -1
  11. package/dist/async/middlewares/retry/retry.types.d.ts +1 -1
  12. package/dist/cache/contracts/cache-adapter.contract.d.ts +9 -9
  13. package/dist/cache/contracts/cache.contract.d.ts +7 -7
  14. package/dist/cache/contracts/cache.errors.d.ts +3 -26
  15. package/dist/cache/contracts/cache.errors.js +0 -47
  16. package/dist/cache/contracts/cache.errors.js.map +1 -1
  17. package/dist/cache/contracts/database-cache-adapter.contract.d.ts +10 -10
  18. package/dist/cache/implementations/adapters/kysely-cache-adapter/kysely-cache-adapter.d.ts +6 -5
  19. package/dist/cache/implementations/adapters/kysely-cache-adapter/kysely-cache-adapter.js +17 -13
  20. package/dist/cache/implementations/adapters/kysely-cache-adapter/kysely-cache-adapter.js.map +1 -1
  21. package/dist/cache/implementations/adapters/mongodb-cache-adapter/mongodb-cache-adapter.d.ts +15 -3
  22. package/dist/cache/implementations/adapters/mongodb-cache-adapter/mongodb-cache-adapter.js +25 -9
  23. package/dist/cache/implementations/adapters/mongodb-cache-adapter/mongodb-cache-adapter.js.map +1 -1
  24. package/dist/cache/implementations/adapters/no-op-cache-adapter/no-op-cache-adapter.d.ts +9 -9
  25. package/dist/cache/implementations/adapters/no-op-cache-adapter/no-op-cache-adapter.js.map +1 -1
  26. package/dist/cache/implementations/adapters/redis-cache-adapter/redis-cache-adapter.d.ts +1 -1
  27. package/dist/cache/implementations/adapters/redis-cache-adapter/redis-cache-adapter.js +1 -1
  28. package/dist/cache/implementations/adapters/redis-cache-adapter/utilities.js +2 -1
  29. package/dist/cache/implementations/adapters/redis-cache-adapter/utilities.js.map +1 -1
  30. package/dist/cache/implementations/derivables/cache/cache.d.ts +2 -2
  31. package/dist/cache/implementations/derivables/cache/cache.js +1 -1
  32. package/dist/cache/implementations/derivables/cache/cache.js.map +1 -1
  33. package/dist/collection/contracts/async-collection.contract.d.ts +0 -1
  34. package/dist/collection/contracts/async-collection.contract.js +3 -1
  35. package/dist/collection/contracts/async-collection.contract.js.map +1 -1
  36. package/dist/collection/contracts/collection.contract.d.ts +0 -1
  37. package/dist/collection/contracts/collection.contract.js +3 -1
  38. package/dist/collection/contracts/collection.contract.js.map +1 -1
  39. package/dist/collection/contracts/collection.errors.d.ts +1 -26
  40. package/dist/collection/contracts/collection.errors.js +0 -55
  41. package/dist/collection/contracts/collection.errors.js.map +1 -1
  42. package/dist/collection/implementations/async-iterable-collection/_shared/async-split-iterable.js +1 -1
  43. package/dist/collection/implementations/async-iterable-collection/_shared/async-split-iterable.js.map +1 -1
  44. package/dist/collection/implementations/async-iterable-collection/_shared/async-zip-iterable.js +1 -1
  45. package/dist/collection/implementations/async-iterable-collection/_shared/async-zip-iterable.js.map +1 -1
  46. package/dist/collection/implementations/async-iterable-collection/async-iterable-collection.js +9 -6
  47. package/dist/collection/implementations/async-iterable-collection/async-iterable-collection.js.map +1 -1
  48. package/dist/collection/implementations/iterable-collection/_shared/split-iterable.js +1 -1
  49. package/dist/collection/implementations/iterable-collection/_shared/split-iterable.js.map +1 -1
  50. package/dist/collection/implementations/iterable-collection/_shared/zip-iterable.js +1 -1
  51. package/dist/collection/implementations/iterable-collection/_shared/zip-iterable.js.map +1 -1
  52. package/dist/collection/implementations/iterable-collection/iterable-collection.js +9 -6
  53. package/dist/collection/implementations/iterable-collection/iterable-collection.js.map +1 -1
  54. package/dist/collection/implementations/list-collection/list-collection.js +12 -9
  55. package/dist/collection/implementations/list-collection/list-collection.js.map +1 -1
  56. package/dist/event-bus/contracts/_module-exports.d.ts +0 -1
  57. package/dist/event-bus/contracts/_module-exports.js +0 -1
  58. package/dist/event-bus/contracts/_module-exports.js.map +1 -1
  59. package/dist/event-bus/contracts/event-bus-adapter.contract.d.ts +3 -3
  60. package/dist/event-bus/implementations/adapters/no-op-event-bus-adapter/no-op-event-bus-adapter.d.ts +3 -3
  61. package/dist/event-bus/implementations/adapters/redis-pub-sub-event-bus-adapter/redis-pub-sub-event-bus-adapter.d.ts +2 -2
  62. package/dist/event-bus/implementations/adapters/redis-pub-sub-event-bus-adapter/redis-pub-sub-event-bus-adapter.js +3 -2
  63. package/dist/event-bus/implementations/adapters/redis-pub-sub-event-bus-adapter/redis-pub-sub-event-bus-adapter.js.map +1 -1
  64. package/dist/event-bus/implementations/derivables/event-bus/event-bus.d.ts +2 -1
  65. package/dist/event-bus/implementations/derivables/event-bus/event-bus.js +26 -26
  66. package/dist/event-bus/implementations/derivables/event-bus/event-bus.js.map +1 -1
  67. package/dist/event-bus/implementations/derivables/event-bus/listener-store.d.ts +11 -4
  68. package/dist/event-bus/implementations/derivables/event-bus/listener-store.js +17 -12
  69. package/dist/event-bus/implementations/derivables/event-bus/listener-store.js.map +1 -1
  70. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js +17 -20
  71. package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js.map +1 -1
  72. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js +159 -752
  73. package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js.map +1 -1
  74. package/dist/lock/contracts/database-lock-adapter.contract.d.ts +56 -16
  75. package/dist/lock/contracts/lock-adapter.contract.d.ts +32 -9
  76. package/dist/lock/contracts/lock-adapter.contract.js +10 -1
  77. package/dist/lock/contracts/lock-adapter.contract.js.map +1 -1
  78. package/dist/lock/contracts/lock.contract.d.ts +30 -25
  79. package/dist/lock/contracts/lock.errors.d.ts +11 -28
  80. package/dist/lock/contracts/lock.errors.js +10 -74
  81. package/dist/lock/contracts/lock.errors.js.map +1 -1
  82. package/dist/lock/contracts/lock.events.d.ts +15 -3
  83. package/dist/lock/contracts/lock.events.js +2 -1
  84. package/dist/lock/contracts/lock.events.js.map +1 -1
  85. package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.d.ts +40 -10
  86. package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.js +135 -37
  87. package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.js.map +1 -1
  88. package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.d.ts +20 -7
  89. package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.js +59 -35
  90. package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.js.map +1 -1
  91. package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.d.ts +23 -12
  92. package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.js +152 -87
  93. package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.js.map +1 -1
  94. package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.d.ts +5 -5
  95. package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.js +3 -2
  96. package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.js.map +1 -1
  97. package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.d.ts +6 -6
  98. package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.js +46 -24
  99. package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.js.map +1 -1
  100. package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.d.ts +4 -4
  101. package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.js +45 -12
  102. package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.js.map +1 -1
  103. package/dist/lock/implementations/derivables/lock-provider/is-database-lock-adapter.js +7 -5
  104. package/dist/lock/implementations/derivables/lock-provider/is-database-lock-adapter.js.map +1 -1
  105. package/dist/lock/implementations/derivables/lock-provider/lock-provider.d.ts +3 -3
  106. package/dist/lock/implementations/derivables/lock-provider/lock-provider.js +2 -3
  107. package/dist/lock/implementations/derivables/lock-provider/lock-provider.js.map +1 -1
  108. package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.d.ts +1 -1
  109. package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.js +4 -3
  110. package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.js.map +1 -1
  111. package/dist/lock/implementations/derivables/lock-provider/lock-state.d.ts +8 -11
  112. package/dist/lock/implementations/derivables/lock-provider/lock-state.js +9 -26
  113. package/dist/lock/implementations/derivables/lock-provider/lock-state.js.map +1 -1
  114. package/dist/lock/implementations/derivables/lock-provider/lock.d.ts +14 -16
  115. package/dist/lock/implementations/derivables/lock-provider/lock.js +106 -63
  116. package/dist/lock/implementations/derivables/lock-provider/lock.js.map +1 -1
  117. package/dist/lock/implementations/derivables/lock-provider-factory/lock-provider-factory.d.ts +2 -2
  118. package/dist/lock/implementations/derivables/lock-provider-factory/lock-provider-factory.js.map +1 -1
  119. package/dist/lock/implementations/test-utilities/database-lock-adapter.test-suite.js +184 -166
  120. package/dist/lock/implementations/test-utilities/database-lock-adapter.test-suite.js.map +1 -1
  121. package/dist/lock/implementations/test-utilities/lock-adapter.test-suite.js +240 -41
  122. package/dist/lock/implementations/test-utilities/lock-adapter.test-suite.js.map +1 -1
  123. package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js +2704 -1514
  124. package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js.map +1 -1
  125. package/dist/serde/implementations/derivables/serde.d.ts +22 -22
  126. package/dist/utilities/classes/kysely-table-name-transformer-plugin/kysely-table-name-transformer-plugin.js +2 -1
  127. package/dist/utilities/classes/kysely-table-name-transformer-plugin/kysely-table-name-transformer-plugin.js.map +1 -1
  128. package/dist/utilities/classes/namespace/namespace.d.ts +3 -3
  129. package/dist/utilities/classes/namespace/namespace.js +2 -2
  130. package/dist/utilities/classes/namespace/namespace.js.map +1 -1
  131. package/dist/utilities/classes/time-span/time-span.d.ts +10 -2
  132. package/dist/utilities/classes/time-span/time-span.js +10 -2
  133. package/dist/utilities/classes/time-span/time-span.js.map +1 -1
  134. package/dist/utilities/contracts/deinitizable.contract.d.ts +1 -1
  135. package/dist/utilities/contracts/initizable.contract.d.ts +1 -1
  136. package/dist/utilities/contracts/prunable.contract.d.ts +1 -1
  137. package/dist/utilities/errors.d.ts +8 -0
  138. package/dist/utilities/errors.js +11 -0
  139. package/dist/utilities/errors.js.map +1 -1
  140. package/dist/utilities/functions/_module.d.ts +1 -0
  141. package/dist/utilities/functions/_module.js +1 -0
  142. package/dist/utilities/functions/_module.js.map +1 -1
  143. package/dist/utilities/functions/is-class.d.ts +4 -0
  144. package/dist/utilities/functions/is-class.js +4 -0
  145. package/dist/utilities/functions/is-class.js.map +1 -1
  146. package/dist/utilities/functions/is-positive-nbr.d.ts +8 -0
  147. package/dist/utilities/functions/is-positive-nbr.js +19 -0
  148. package/dist/utilities/functions/is-positive-nbr.js.map +1 -0
  149. package/package.json +1 -1
  150. package/dist/event-bus/contracts/event-bus.errors.d.ts +0 -40
  151. package/dist/event-bus/contracts/event-bus.errors.js +0 -62
  152. package/dist/event-bus/contracts/event-bus.errors.js.map +0 -1
@@ -52,13 +52,23 @@ export type UnownedRefreshTryLockEvent = {
52
52
  key: string;
53
53
  owner: string;
54
54
  };
55
+ /**
56
+ * The event is dispatched when trying to refefresh a lock that is unexpireable.
57
+ *
58
+ * IMPORT_PATH: `"@daiso-tech/core/lock/contracts"`
59
+ * @group Events
60
+ */
61
+ export type UnexpireableKeyRefreshTryLockEvent = {
62
+ key: string;
63
+ owner: string;
64
+ };
55
65
  /**
56
66
  * The event is dispatched when trying to acquire a lock that is owned by a different owner.
57
67
  *
58
68
  * IMPORT_PATH: `"@daiso-tech/core/lock/contracts"`
59
69
  * @group Events
60
70
  */
61
- export type NotAvailableLockEvent = {
71
+ export type UnavailableLockEvent = {
62
72
  key: string;
63
73
  owner: string;
64
74
  };
@@ -94,7 +104,8 @@ export declare const LOCK_EVENTS: {
94
104
  readonly RELEASED: "RELEASED";
95
105
  readonly UNOWNED_RELEASE_TRY: "UNOWNED_RELEASE_TRY";
96
106
  readonly UNOWNED_REFRESH_TRY: "UNOWNED_REFRESH_TRY";
97
- readonly NOT_AVAILABLE: "NOT_AVAILABLE";
107
+ readonly UNEXPIREABLE_KEY_REFRESH_TRY: "UNEXPIREABLE_KEY_REFRESH_TRY";
108
+ readonly UNAVAILABLE: "UNAVAILABLE";
98
109
  readonly FORCE_RELEASED: "FORCE_RELEASED";
99
110
  readonly REFRESHED: "REFRESHED";
100
111
  readonly UNEXPECTED_ERROR: "UNEXPECTED_ERROR";
@@ -109,7 +120,8 @@ export type LockEventMap = {
109
120
  [LOCK_EVENTS.RELEASED]: ReleasedLockEvent;
110
121
  [LOCK_EVENTS.UNOWNED_RELEASE_TRY]: UnownedReleaseTryLockEvent;
111
122
  [LOCK_EVENTS.UNOWNED_REFRESH_TRY]: UnownedRefreshTryLockEvent;
112
- [LOCK_EVENTS.NOT_AVAILABLE]: NotAvailableLockEvent;
123
+ [LOCK_EVENTS.UNEXPIREABLE_KEY_REFRESH_TRY]: UnexpireableKeyRefreshTryLockEvent;
124
+ [LOCK_EVENTS.UNAVAILABLE]: UnavailableLockEvent;
113
125
  [LOCK_EVENTS.FORCE_RELEASED]: ForceReleasedLockEvent;
114
126
  [LOCK_EVENTS.REFRESHED]: RefreshedLockEvent;
115
127
  [LOCK_EVENTS.UNEXPECTED_ERROR]: UnexpectedErrorLockEvent;
@@ -11,7 +11,8 @@ export const LOCK_EVENTS = {
11
11
  RELEASED: "RELEASED",
12
12
  UNOWNED_RELEASE_TRY: "UNOWNED_RELEASE_TRY",
13
13
  UNOWNED_REFRESH_TRY: "UNOWNED_REFRESH_TRY",
14
- NOT_AVAILABLE: "NOT_AVAILABLE",
14
+ UNEXPIREABLE_KEY_REFRESH_TRY: "UNEXPIREABLE_KEY_REFRESH_TRY",
15
+ UNAVAILABLE: "UNAVAILABLE",
15
16
  FORCE_RELEASED: "FORCE_RELEASED",
16
17
  REFRESHED: "REFRESHED",
17
18
  UNEXPECTED_ERROR: "UNEXPECTED_ERROR",
@@ -1 +1 @@
1
- {"version":3,"file":"lock.events.js","sourceRoot":"","sources":["../../../src/lock/contracts/lock.events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,mBAAmB,EAAE,qBAAqB;IAC1C,mBAAmB,EAAE,qBAAqB;IAC1C,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,WAAW;IACtB,gBAAgB,EAAE,kBAAkB;CAC9B,CAAC"}
1
+ {"version":3,"file":"lock.events.js","sourceRoot":"","sources":["../../../src/lock/contracts/lock.events.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2GH;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,mBAAmB,EAAE,qBAAqB;IAC1C,mBAAmB,EAAE,qBAAqB;IAC1C,4BAA4B,EAAE,8BAA8B;IAC5D,WAAW,EAAE,aAAa;IAC1B,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,WAAW;IACtB,gBAAgB,EAAE,kBAAkB;CAC9B,CAAC"}
@@ -1,25 +1,25 @@
1
1
  /**
2
2
  * @module Lock
3
3
  */
4
- import type { IDatabaseLockAdapter, ILockData } from "../../../../lock/contracts/_module-exports.js";
5
- import type { Kysely } from "kysely";
4
+ import type { IDatabaseLockAdapter, ILockData, ILockExpirationData } from "../../../../lock/contracts/_module-exports.js";
5
+ import { type Kysely } from "kysely";
6
6
  import { type IDeinitizable, type IInitizable, type IPrunable, TimeSpan } from "../../../../utilities/_module-exports.js";
7
7
  /**
8
8
  *
9
9
  * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
10
10
  * @group Adapters
11
11
  */
12
- type KyselyLockAdapterTable = {
12
+ export type KyselyLockAdapterTable = {
13
13
  key: string;
14
14
  owner: string;
15
- expiresAt: number | string | null;
15
+ expiration: number | bigint | string | null;
16
16
  };
17
17
  /**
18
18
  *
19
19
  * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
20
20
  * @group Adapters
21
21
  */
22
- type KyselyLockAdapterTables = {
22
+ export type KyselyLockAdapterTables = {
23
23
  lock: KyselyLockAdapterTable;
24
24
  };
25
25
  /**
@@ -27,12 +27,39 @@ type KyselyLockAdapterTables = {
27
27
  * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
28
28
  * @group Adapters
29
29
  */
30
- type KyselyLockAdapterSettings = {
30
+ export type KyselyLockAdapterSettings = {
31
31
  kysely: Kysely<KyselyLockAdapterTables>;
32
+ /**
33
+ * @default
34
+ * ```ts
35
+ * TimeSpan.fromMinutes(1)
36
+ * ```
37
+ */
32
38
  expiredKeysRemovalInterval?: TimeSpan;
39
+ /**
40
+ * @default true
41
+ */
33
42
  shouldRemoveExpiredKeys?: boolean;
43
+ /**
44
+ * @default
45
+ * ```ts
46
+ * () => new Date()
47
+ * ```
48
+ */
49
+ currentDate?: () => Date;
50
+ /**
51
+ * @default
52
+ * ```ts
53
+ * globalThis.setInterval
54
+ * ```
55
+ */
56
+ setInterval?: typeof setInterval;
34
57
  };
35
58
  /**
59
+ * To utilize the `KyselyLockAdapter`, you must install the [`"kysely"`](https://www.npmjs.com/package/kysely) package and configure a `Kysely` class instance.
60
+ *
61
+ * Note in order to use `KyselyLockAdapter` correctly, ensure you use a single, consistent database across all server instances.
62
+ * The adapter have been tested with `sqlite`, `postgres` and `mysql` databases.
36
63
  *
37
64
  * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
38
65
  * @group Adapters
@@ -42,6 +69,9 @@ export declare class KyselyLockAdapter implements IDatabaseLockAdapter, IDeiniti
42
69
  private readonly expiredKeysRemovalInterval;
43
70
  private readonly shouldRemoveExpiredKeys;
44
71
  private timeoutId;
72
+ private readonly currentDate;
73
+ private readonly setInterval;
74
+ private readonly isMysql;
45
75
  /**
46
76
  * @example
47
77
  * ```ts
@@ -64,9 +94,9 @@ export declare class KyselyLockAdapter implements IDatabaseLockAdapter, IDeiniti
64
94
  init(): Promise<void>;
65
95
  removeAllExpired(): Promise<void>;
66
96
  insert(key: string, owner: string, expiration: Date | null): Promise<void>;
67
- update(key: string, owner: string, expiration: Date | null): Promise<number>;
68
- remove(key: string, owner: string | null): Promise<void>;
69
- refresh(key: string, owner: string, expiration: Date): Promise<number>;
97
+ updateIfExpired(key: string, owner: string, expiration: Date | null): Promise<number>;
98
+ remove(key: string): Promise<ILockExpirationData | null>;
99
+ removeIfOwner(key: string, owner: string): Promise<ILockData | null>;
100
+ updateExpirationIfOwner(key: string, owner: string, expiration: Date): Promise<number>;
70
101
  find(key: string): Promise<ILockData | null>;
71
102
  }
72
- export {};
@@ -1,8 +1,13 @@
1
1
  /**
2
2
  * @module Lock
3
3
  */
4
+ import { MysqlAdapter } from "kysely";
4
5
  import { TimeSpan, } from "../../../../utilities/_module-exports.js";
5
6
  /**
7
+ * To utilize the `KyselyLockAdapter`, you must install the [`"kysely"`](https://www.npmjs.com/package/kysely) package and configure a `Kysely` class instance.
8
+ *
9
+ * Note in order to use `KyselyLockAdapter` correctly, ensure you use a single, consistent database across all server instances.
10
+ * The adapter have been tested with `sqlite`, `postgres` and `mysql` databases.
6
11
  *
7
12
  * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
8
13
  * @group Adapters
@@ -12,6 +17,9 @@ export class KyselyLockAdapter {
12
17
  expiredKeysRemovalInterval;
13
18
  shouldRemoveExpiredKeys;
14
19
  timeoutId = null;
20
+ currentDate;
21
+ setInterval;
22
+ isMysql;
15
23
  /**
16
24
  * @example
17
25
  * ```ts
@@ -30,26 +38,30 @@ export class KyselyLockAdapter {
30
38
  * ```
31
39
  */
32
40
  constructor(settings) {
33
- const { kysely, expiredKeysRemovalInterval = TimeSpan.fromMinutes(1), shouldRemoveExpiredKeys = true, } = settings;
41
+ const { kysely, expiredKeysRemovalInterval = TimeSpan.fromMinutes(1), shouldRemoveExpiredKeys = true, currentDate = () => new Date(), setInterval = globalThis.setInterval, } = settings;
34
42
  this.expiredKeysRemovalInterval = expiredKeysRemovalInterval;
35
43
  this.shouldRemoveExpiredKeys = shouldRemoveExpiredKeys;
36
44
  this.kysely = kysely;
45
+ this.isMysql =
46
+ this.kysely.getExecutor().adapter instanceof MysqlAdapter;
47
+ this.currentDate = currentDate;
48
+ this.setInterval = setInterval;
37
49
  }
38
50
  async deInit() {
39
51
  if (this.shouldRemoveExpiredKeys && this.timeoutId !== null) {
40
52
  clearTimeout(this.timeoutId);
41
53
  }
42
- // Should not throw if the index does not exists thats why the try catch is used.
54
+ // Should throw if the index does not exists thats why the try catch is used.
43
55
  try {
44
56
  await this.kysely.schema
45
- .dropIndex("lock_expiresAt")
57
+ .dropIndex("lock_expiration")
46
58
  .on("lock")
47
59
  .execute();
48
60
  }
49
61
  catch {
50
62
  /* EMPTY */
51
63
  }
52
- // Should not throw if the table does not exists thats why the try catch is used.
64
+ // Should throw if the table does not exists thats why the try catch is used.
53
65
  try {
54
66
  await this.kysely.schema.dropTable("lock").execute();
55
67
  }
@@ -58,32 +70,31 @@ export class KyselyLockAdapter {
58
70
  }
59
71
  }
60
72
  async init() {
61
- // Should not throw if the table already exists thats why the try catch is used.
73
+ // Should throw if the table already exists thats why the try catch is used.
62
74
  try {
63
75
  await this.kysely.schema
64
76
  .createTable("lock")
65
- .ifNotExists()
66
- .addColumn("key", "varchar(255)", (col) => col.primaryKey())
67
- .addColumn("owner", "varchar(255)")
68
- .addColumn("expiresAt", "bigint")
77
+ .addColumn("key", "varchar(255)", (col) => col.notNull().primaryKey())
78
+ .addColumn("owner", "varchar(255)", (col) => col.notNull())
79
+ .addColumn("expiration", "bigint")
69
80
  .execute();
70
81
  }
71
82
  catch {
72
83
  /* EMPTY */
73
84
  }
74
- // Should not throw if the index already exists thats why the try catch is used.
85
+ // Should throw if the index already exists thats why the try catch is used.
75
86
  try {
76
87
  await this.kysely.schema
77
- .createIndex("lock_expiresAt")
88
+ .createIndex("lock_expiration")
78
89
  .on("lock")
79
- .columns(["expiresAt"])
90
+ .columns(["expiration"])
80
91
  .execute();
81
92
  }
82
93
  catch {
83
94
  /* EMPTY */
84
95
  }
85
96
  if (this.shouldRemoveExpiredKeys) {
86
- this.timeoutId = setTimeout(() => {
97
+ this.timeoutId = this.setInterval(() => {
87
98
  void this.removeAllExpired();
88
99
  }, this.expiredKeysRemovalInterval.toMilliseconds());
89
100
  }
@@ -91,7 +102,7 @@ export class KyselyLockAdapter {
91
102
  async removeAllExpired() {
92
103
  await this.kysely
93
104
  .deleteFrom("lock")
94
- .where("lock.expiresAt", "<=", new Date().getTime())
105
+ .where("lock.expiration", "<=", this.currentDate().getTime())
95
106
  .execute();
96
107
  }
97
108
  async insert(key, owner, expiration) {
@@ -100,51 +111,138 @@ export class KyselyLockAdapter {
100
111
  .values({
101
112
  key,
102
113
  owner,
103
- expiresAt: expiration?.getTime() ?? null,
114
+ expiration: expiration?.getTime() ?? null,
104
115
  })
105
116
  .execute();
106
117
  }
107
- async update(key, owner, expiration) {
108
- const updateResult = await this.kysely
118
+ async updateIfExpired(key, owner, expiration) {
119
+ const result = await this.kysely
109
120
  .updateTable("lock")
110
121
  .where("lock.key", "=", key)
111
- // Has expired
112
- .where((eb) => eb.and([
113
- eb("lock.expiresAt", "is not", null),
114
- eb("lock.expiresAt", "<=", Date.now()),
115
- ]))
116
- .set({ owner, expiresAt: expiration?.getTime() ?? null })
122
+ .where((eb) => {
123
+ const hasExpiration = eb("lock.expiration", "is not", null);
124
+ const hasExpired = eb("lock.expiration", "<=", Date.now());
125
+ return eb.and([hasExpiration, hasExpired]);
126
+ })
127
+ .set({
128
+ owner,
129
+ expiration: expiration?.getTime() ?? null,
130
+ })
117
131
  .executeTakeFirst();
118
- return Number(updateResult.numUpdatedRows); // > 0;
132
+ return Number(result.numUpdatedRows);
119
133
  }
120
- async remove(key, owner) {
121
- await this.kysely
122
- .deleteFrom("lock")
123
- .where("lock.key", "=", key)
124
- .$if(owner !== null, (query) => query.where("lock.owner", "=", owner))
125
- .execute();
134
+ async remove(key) {
135
+ let result;
136
+ if (this.isMysql) {
137
+ result = await this.kysely
138
+ .transaction()
139
+ .setIsolationLevel("serializable")
140
+ .execute(async (trx) => {
141
+ const row = await trx
142
+ .selectFrom("lock")
143
+ .select("lock.expiration")
144
+ .where("lock.key", "=", key)
145
+ .executeTakeFirst();
146
+ await trx
147
+ .deleteFrom("lock")
148
+ .where("lock.key", "=", key)
149
+ .executeTakeFirst();
150
+ return row;
151
+ });
152
+ }
153
+ else {
154
+ result = await this.kysely
155
+ .deleteFrom("lock")
156
+ .where("lock.key", "=", key)
157
+ .returning(["lock.expiration"])
158
+ .executeTakeFirst();
159
+ }
160
+ if (result === undefined) {
161
+ return null;
162
+ }
163
+ if (result.expiration === null) {
164
+ return {
165
+ expiration: null,
166
+ };
167
+ }
168
+ return {
169
+ expiration: new Date(Number(result.expiration)),
170
+ };
126
171
  }
127
- async refresh(key, owner, expiration) {
128
- const updateResult = await this.kysely
172
+ async removeIfOwner(key, owner) {
173
+ let row;
174
+ if (this.isMysql) {
175
+ row = await this.kysely
176
+ .transaction()
177
+ .setIsolationLevel("serializable")
178
+ .execute(async (trx) => {
179
+ const row = await trx
180
+ .selectFrom("lock")
181
+ .where("lock.key", "=", key)
182
+ .where("lock.owner", "=", owner)
183
+ .select(["lock.expiration", "lock.owner"])
184
+ .executeTakeFirst();
185
+ await trx
186
+ .deleteFrom("lock")
187
+ .where("lock.key", "=", key)
188
+ .where("lock.owner", "=", owner)
189
+ .execute();
190
+ return row;
191
+ });
192
+ }
193
+ else {
194
+ row = await this.kysely
195
+ .deleteFrom("lock")
196
+ .where("lock.key", "=", key)
197
+ .where("lock.owner", "=", owner)
198
+ .returning(["lock.expiration", "lock.owner"])
199
+ .executeTakeFirst();
200
+ }
201
+ if (row === undefined) {
202
+ return null;
203
+ }
204
+ const { expiration } = row;
205
+ if (expiration === null) {
206
+ return {
207
+ owner: row.owner,
208
+ expiration: null,
209
+ };
210
+ }
211
+ return {
212
+ owner: row.owner,
213
+ expiration: new Date(Number(expiration)),
214
+ };
215
+ }
216
+ async updateExpirationIfOwner(key, owner, expiration) {
217
+ const result = await this.kysely
129
218
  .updateTable("lock")
130
219
  .where("lock.key", "=", key)
131
220
  .where("lock.owner", "=", owner)
132
- .set({ expiresAt: expiration.getTime() })
221
+ .set({
222
+ expiration: expiration.getTime(),
223
+ })
133
224
  .executeTakeFirst();
134
- return Number(updateResult.numUpdatedRows); // > 0;
225
+ return Number(result.numUpdatedRows);
135
226
  }
136
227
  async find(key) {
137
228
  const row = await this.kysely
138
229
  .selectFrom("lock")
230
+ .select(["lock.owner", "lock.expiration"])
139
231
  .where("lock.key", "=", key)
140
- .select(["lock.owner", "lock.expiresAt"])
141
232
  .executeTakeFirst();
142
233
  if (row === undefined) {
143
234
  return null;
144
235
  }
236
+ const { owner, expiration } = row;
237
+ if (expiration === null) {
238
+ return {
239
+ owner,
240
+ expiration: null,
241
+ };
242
+ }
145
243
  return {
146
- expiration: row.expiresAt ? new Date(Number(row.expiresAt)) : null,
147
- owner: row.owner,
244
+ owner,
245
+ expiration: new Date(Number(expiration)),
148
246
  };
149
247
  }
150
248
  }
@@ -1 +1 @@
1
- {"version":3,"file":"kysely-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EAIH,QAAQ,GACX,MAAM,gCAAgC,CAAC;AAkCxC;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAGT,MAAM,CAAkC;IACxC,0BAA0B,CAAW;IACrC,uBAAuB,CAAU;IAC1C,SAAS,GACb,IAAI,CAAC;IAET;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,QAAmC;QAC3C,MAAM,EACF,MAAM,EACN,0BAA0B,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EACpD,uBAAuB,GAAG,IAAI,GACjC,GAAG,QAAQ,CAAC;QACb,IAAI,CAAC,0BAA0B,GAAG,0BAA0B,CAAC;QAC7D,IAAI,CAAC,uBAAuB,GAAG,uBAAuB,CAAC;QACvD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,MAAM;QACR,IAAI,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1D,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;QAED,iFAAiF;QACjF,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM;iBACnB,SAAS,CAAC,gBAAgB,CAAC;iBAC3B,EAAE,CAAC,MAAM,CAAC;iBACV,OAAO,EAAE,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACL,WAAW;QACf,CAAC;QAED,iFAAiF;QACjF,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACL,WAAW;QACf,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACN,gFAAgF;QAChF,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM;iBACnB,WAAW,CAAC,MAAM,CAAC;iBACnB,WAAW,EAAE;iBACb,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;iBAC3D,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC;iBAClC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC;iBAChC,OAAO,EAAE,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACL,WAAW;QACf,CAAC;QAED,gFAAgF;QAChF,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM;iBACnB,WAAW,CAAC,gBAAgB,CAAC;iBAC7B,EAAE,CAAC,MAAM,CAAC;iBACV,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC;iBACtB,OAAO,EAAE,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACL,WAAW;QACf,CAAC;QAED,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC7B,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACjC,CAAC,EAAE,IAAI,CAAC,0BAA0B,CAAC,cAAc,EAAE,CAAC,CAAC;QACzD,CAAC;IACL,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,MAAM,IAAI,CAAC,MAAM;aACZ,UAAU,CAAC,MAAM,CAAC;aAClB,KAAK,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;aACnD,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CACR,GAAW,EACX,KAAa,EACb,UAAuB;QAEvB,MAAM,IAAI,CAAC,MAAM;aACZ,UAAU,CAAC,MAAM,CAAC;aAClB,MAAM,CAAC;YACJ,GAAG;YACH,KAAK;YACL,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,IAAI;SAC3C,CAAC;aACD,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CACR,GAAW,EACX,KAAa,EACb,UAAuB;QAEvB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM;aACjC,WAAW,CAAC,MAAM,CAAC;aACnB,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC;YAC5B,cAAc;aACb,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CACV,EAAE,CAAC,GAAG,CAAC;YACH,EAAE,CAAC,gBAAgB,EAAE,QAAQ,EAAE,IAAI,CAAC;YACpC,EAAE,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;SACzC,CAAC,CACL;aACA,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;aACxD,gBAAgB,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO;IACvD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,KAAoB;QAC1C,MAAM,IAAI,CAAC,MAAM;aACZ,UAAU,CAAC,MAAM,CAAC;aAClB,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC;aAC3B,GAAG,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAC3B,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC,CACxC;aACA,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,OAAO,CACT,GAAW,EACX,KAAa,EACb,UAAgB;QAEhB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM;aACjC,WAAW,CAAC,MAAM,CAAC;aACnB,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC;aAC3B,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC;aAC/B,GAAG,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;aACxC,gBAAgB,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO;IACvD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QAClB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM;aACxB,UAAU,CAAC,MAAM,CAAC;aAClB,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC;aAC3B,MAAM,CAAC,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;aACxC,gBAAgB,EAAE,CAAC;QACxB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO;YACH,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;YAClE,KAAK,EAAE,GAAG,CAAC,KAAK;SACnB,CAAC;IACN,CAAC;CACJ"}
1
+ {"version":3,"file":"kysely-lock-adapter.js","sourceRoot":"","sources":["../../../../../src/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,21 @@
1
1
  /**
2
2
  * @module Lock
3
3
  */
4
- import type { TimeSpan } from "../../../../utilities/_module-exports.js";
5
- import type { ILockAdapter, ILockData } from "../../../../lock/contracts/_module-exports.js";
4
+ import type { IDeinitizable, TimeSpan } from "../../../../utilities/_module-exports.js";
5
+ import { type ILockAdapter, type LockRefreshResult } from "../../../../lock/contracts/_module-exports.js";
6
+ /**
7
+ *
8
+ * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
9
+ * @group Adapters
10
+ */
11
+ export type MemoryLockData = {
12
+ owner: string;
13
+ hasExpiration: true;
14
+ timeoutId: string | number | NodeJS.Timeout;
15
+ } | {
16
+ owner: string;
17
+ hasExpiration: false;
18
+ };
6
19
  /**
7
20
  * Note the `MemoryLockAdapter` is limited to single process usage and cannot be shared across multiple servers or different processes.
8
21
  * This adapter is meant to be used for testing.
@@ -10,9 +23,8 @@ import type { ILockAdapter, ILockData } from "../../../../lock/contracts/_module
10
23
  * IMPORT_PATH: `"@daiso-tech/core/lock/adapters"`
11
24
  * @group Adapters
12
25
  */
13
- export declare class MemoryLockAdapter implements ILockAdapter {
26
+ export declare class MemoryLockAdapter implements ILockAdapter, IDeinitizable {
14
27
  private readonly map;
15
- private readonly timeoutMap;
16
28
  /**
17
29
  * @example
18
30
  * ```ts
@@ -29,9 +41,10 @@ export declare class MemoryLockAdapter implements ILockAdapter {
29
41
  * const lockAdapter = new MemoryLockAdapter(map);
30
42
  * ```
31
43
  */
32
- constructor(map?: Map<string, ILockData>);
44
+ constructor(map?: Map<string, MemoryLockData>);
45
+ deInit(): Promise<void>;
33
46
  acquire(key: string, owner: string, ttl: TimeSpan | null): Promise<boolean>;
34
47
  release(key: string, owner: string): Promise<boolean>;
35
- forceRelease(key: string): Promise<void>;
36
- refresh(key: string, owner: string, time: TimeSpan): Promise<boolean>;
48
+ forceRelease(key: string): Promise<boolean>;
49
+ refresh(key: string, owner: string, ttl: TimeSpan): Promise<LockRefreshResult>;
37
50
  }
@@ -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
  * Note the `MemoryLockAdapter` is limited to single process usage and cannot be shared across multiple servers or different processes.
6
7
  * This adapter is meant to be used for testing.
@@ -10,7 +11,6 @@
10
11
  */
11
12
  export class MemoryLockAdapter {
12
13
  map;
13
- timeoutMap = new Map();
14
14
  /**
15
15
  * @example
16
16
  * ```ts
@@ -31,64 +31,88 @@ export class MemoryLockAdapter {
31
31
  this.map = map;
32
32
  }
33
33
  // eslint-disable-next-line @typescript-eslint/require-await
34
+ async deInit() {
35
+ for (const [key, lockData] of this.map) {
36
+ if (lockData.hasExpiration) {
37
+ clearTimeout(lockData.timeoutId);
38
+ }
39
+ this.map.delete(key);
40
+ }
41
+ }
42
+ // eslint-disable-next-line @typescript-eslint/require-await
34
43
  async acquire(key, owner, ttl) {
35
- const hasNotKey = !this.map.has(key);
36
- if (hasNotKey) {
37
- this.map.set(key, {
44
+ let lock = this.map.get(key);
45
+ if (lock !== undefined) {
46
+ return false;
47
+ }
48
+ if (ttl === null) {
49
+ lock = {
38
50
  owner,
39
- expiration: ttl?.toEndDate() ?? null,
40
- });
51
+ hasExpiration: false,
52
+ };
53
+ this.map.set(key, lock);
41
54
  }
42
- if (hasNotKey && ttl !== null) {
43
- this.timeoutMap.set(key, setTimeout(() => {
55
+ else {
56
+ const timeoutId = setTimeout(() => {
44
57
  this.map.delete(key);
45
- this.timeoutMap.delete(key);
46
- }, ttl.toMilliseconds()));
58
+ }, ttl.toMilliseconds());
59
+ lock = {
60
+ owner,
61
+ hasExpiration: true,
62
+ timeoutId,
63
+ };
64
+ this.map.set(key, lock);
47
65
  }
48
- return hasNotKey;
66
+ return true;
49
67
  }
50
68
  // eslint-disable-next-line @typescript-eslint/require-await
51
69
  async release(key, owner) {
52
- const data = this.map.get(key);
53
- if (data === undefined) {
54
- return true;
70
+ const lock = this.map.get(key);
71
+ if (lock === undefined) {
72
+ return false;
55
73
  }
56
- if (data.owner !== owner) {
74
+ if (lock.owner !== owner) {
57
75
  return false;
58
76
  }
59
- clearTimeout(this.timeoutMap.get(key));
60
- this.timeoutMap.delete(key);
77
+ if (lock.hasExpiration) {
78
+ clearTimeout(lock.timeoutId);
79
+ }
61
80
  this.map.delete(key);
62
81
  return true;
63
82
  }
64
83
  // eslint-disable-next-line @typescript-eslint/require-await
65
84
  async forceRelease(key) {
66
- clearTimeout(this.timeoutMap.get(key));
67
- this.timeoutMap.delete(key);
85
+ const lock = this.map.get(key);
86
+ if (lock === undefined) {
87
+ return false;
88
+ }
89
+ if (lock.hasExpiration) {
90
+ clearTimeout(lock.timeoutId);
91
+ }
68
92
  this.map.delete(key);
93
+ return true;
69
94
  }
70
95
  // eslint-disable-next-line @typescript-eslint/require-await
71
- async refresh(key, owner, time) {
72
- const data = this.map.get(key);
73
- if (data === undefined) {
74
- return true;
96
+ async refresh(key, owner, ttl) {
97
+ const lock = this.map.get(key);
98
+ if (lock === undefined) {
99
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
75
100
  }
76
- if (data.owner !== owner) {
77
- return false;
101
+ if (lock.owner !== owner) {
102
+ return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
78
103
  }
79
- if (data.expiration === null) {
80
- return true;
104
+ if (!lock.hasExpiration) {
105
+ return LOCK_REFRESH_RESULT.UNEXPIRABLE_KEY;
81
106
  }
107
+ clearTimeout(lock.timeoutId);
108
+ const timeoutId = setTimeout(() => {
109
+ this.map.delete(key);
110
+ }, ttl.toMilliseconds());
82
111
  this.map.set(key, {
83
- ...data,
84
- expiration: time.toEndDate(),
112
+ ...lock,
113
+ timeoutId,
85
114
  });
86
- clearTimeout(this.timeoutMap.get(key));
87
- this.timeoutMap.set(key, setTimeout(() => {
88
- this.timeoutMap.delete(key);
89
- this.map.delete(key);
90
- }, time.toMilliseconds()));
91
- return true;
115
+ return LOCK_REFRESH_RESULT.REFRESHED;
92
116
  }
93
117
  }
94
118
  //# sourceMappingURL=memory-lock-adapter.js.map