@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.
- package/README.md +5 -1
- package/dist/async/backof-policies/constant-backoff-policy/constant-backoff-policy.d.ts +1 -1
- package/dist/async/backof-policies/exponential-backoff-policy/exponential-backoff-policy.d.ts +2 -2
- package/dist/async/backof-policies/linear-backoff-policy/linear-backoff-policy.d.ts +1 -1
- package/dist/async/backof-policies/polynomial-backoff-policy/polynomial-backoff-policy.d.ts +2 -2
- package/dist/async/middlewares/bulkhead/bulkhead.middleware.d.ts +2 -2
- package/dist/async/middlewares/hedging/sequential-hedging.middleware.js +2 -2
- package/dist/async/middlewares/hedging/sequential-hedging.middleware.js.map +1 -1
- package/dist/async/middlewares/retry/retry.middleware.js +2 -2
- package/dist/async/middlewares/retry/retry.middleware.js.map +1 -1
- package/dist/async/middlewares/retry/retry.types.d.ts +1 -1
- package/dist/cache/contracts/cache-adapter.contract.d.ts +9 -9
- package/dist/cache/contracts/cache.contract.d.ts +7 -7
- package/dist/cache/contracts/cache.errors.d.ts +3 -26
- package/dist/cache/contracts/cache.errors.js +0 -47
- package/dist/cache/contracts/cache.errors.js.map +1 -1
- package/dist/cache/contracts/database-cache-adapter.contract.d.ts +10 -10
- package/dist/cache/implementations/adapters/kysely-cache-adapter/kysely-cache-adapter.d.ts +6 -5
- package/dist/cache/implementations/adapters/kysely-cache-adapter/kysely-cache-adapter.js +17 -13
- package/dist/cache/implementations/adapters/kysely-cache-adapter/kysely-cache-adapter.js.map +1 -1
- package/dist/cache/implementations/adapters/mongodb-cache-adapter/mongodb-cache-adapter.d.ts +15 -3
- package/dist/cache/implementations/adapters/mongodb-cache-adapter/mongodb-cache-adapter.js +25 -9
- package/dist/cache/implementations/adapters/mongodb-cache-adapter/mongodb-cache-adapter.js.map +1 -1
- package/dist/cache/implementations/adapters/no-op-cache-adapter/no-op-cache-adapter.d.ts +9 -9
- package/dist/cache/implementations/adapters/no-op-cache-adapter/no-op-cache-adapter.js.map +1 -1
- package/dist/cache/implementations/adapters/redis-cache-adapter/redis-cache-adapter.d.ts +1 -1
- package/dist/cache/implementations/adapters/redis-cache-adapter/redis-cache-adapter.js +1 -1
- package/dist/cache/implementations/adapters/redis-cache-adapter/utilities.js +2 -1
- package/dist/cache/implementations/adapters/redis-cache-adapter/utilities.js.map +1 -1
- package/dist/cache/implementations/derivables/cache/cache.d.ts +2 -2
- package/dist/cache/implementations/derivables/cache/cache.js +1 -1
- package/dist/cache/implementations/derivables/cache/cache.js.map +1 -1
- package/dist/collection/contracts/async-collection.contract.d.ts +0 -1
- package/dist/collection/contracts/async-collection.contract.js +3 -1
- package/dist/collection/contracts/async-collection.contract.js.map +1 -1
- package/dist/collection/contracts/collection.contract.d.ts +0 -1
- package/dist/collection/contracts/collection.contract.js +3 -1
- package/dist/collection/contracts/collection.contract.js.map +1 -1
- package/dist/collection/contracts/collection.errors.d.ts +1 -26
- package/dist/collection/contracts/collection.errors.js +0 -55
- package/dist/collection/contracts/collection.errors.js.map +1 -1
- package/dist/collection/implementations/async-iterable-collection/_shared/async-split-iterable.js +1 -1
- package/dist/collection/implementations/async-iterable-collection/_shared/async-split-iterable.js.map +1 -1
- package/dist/collection/implementations/async-iterable-collection/_shared/async-zip-iterable.js +1 -1
- package/dist/collection/implementations/async-iterable-collection/_shared/async-zip-iterable.js.map +1 -1
- package/dist/collection/implementations/async-iterable-collection/async-iterable-collection.js +9 -6
- package/dist/collection/implementations/async-iterable-collection/async-iterable-collection.js.map +1 -1
- package/dist/collection/implementations/iterable-collection/_shared/split-iterable.js +1 -1
- package/dist/collection/implementations/iterable-collection/_shared/split-iterable.js.map +1 -1
- package/dist/collection/implementations/iterable-collection/_shared/zip-iterable.js +1 -1
- package/dist/collection/implementations/iterable-collection/_shared/zip-iterable.js.map +1 -1
- package/dist/collection/implementations/iterable-collection/iterable-collection.js +9 -6
- package/dist/collection/implementations/iterable-collection/iterable-collection.js.map +1 -1
- package/dist/collection/implementations/list-collection/list-collection.js +12 -9
- package/dist/collection/implementations/list-collection/list-collection.js.map +1 -1
- package/dist/event-bus/contracts/_module-exports.d.ts +0 -1
- package/dist/event-bus/contracts/_module-exports.js +0 -1
- package/dist/event-bus/contracts/_module-exports.js.map +1 -1
- package/dist/event-bus/contracts/event-bus-adapter.contract.d.ts +3 -3
- package/dist/event-bus/implementations/adapters/no-op-event-bus-adapter/no-op-event-bus-adapter.d.ts +3 -3
- package/dist/event-bus/implementations/adapters/redis-pub-sub-event-bus-adapter/redis-pub-sub-event-bus-adapter.d.ts +2 -2
- package/dist/event-bus/implementations/adapters/redis-pub-sub-event-bus-adapter/redis-pub-sub-event-bus-adapter.js +3 -2
- package/dist/event-bus/implementations/adapters/redis-pub-sub-event-bus-adapter/redis-pub-sub-event-bus-adapter.js.map +1 -1
- package/dist/event-bus/implementations/derivables/event-bus/event-bus.d.ts +2 -1
- package/dist/event-bus/implementations/derivables/event-bus/event-bus.js +26 -26
- package/dist/event-bus/implementations/derivables/event-bus/event-bus.js.map +1 -1
- package/dist/event-bus/implementations/derivables/event-bus/listener-store.d.ts +11 -4
- package/dist/event-bus/implementations/derivables/event-bus/listener-store.js +17 -12
- package/dist/event-bus/implementations/derivables/event-bus/listener-store.js.map +1 -1
- package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js +17 -20
- package/dist/event-bus/implementations/test-utilities/event-bus-adapter.test-suite.js.map +1 -1
- package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js +159 -752
- package/dist/event-bus/implementations/test-utilities/event-bus.test-suite.js.map +1 -1
- package/dist/lock/contracts/database-lock-adapter.contract.d.ts +56 -16
- package/dist/lock/contracts/lock-adapter.contract.d.ts +32 -9
- package/dist/lock/contracts/lock-adapter.contract.js +10 -1
- package/dist/lock/contracts/lock-adapter.contract.js.map +1 -1
- package/dist/lock/contracts/lock.contract.d.ts +30 -25
- package/dist/lock/contracts/lock.errors.d.ts +11 -28
- package/dist/lock/contracts/lock.errors.js +10 -74
- package/dist/lock/contracts/lock.errors.js.map +1 -1
- package/dist/lock/contracts/lock.events.d.ts +15 -3
- package/dist/lock/contracts/lock.events.js +2 -1
- package/dist/lock/contracts/lock.events.js.map +1 -1
- package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.d.ts +40 -10
- package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.js +135 -37
- package/dist/lock/implementations/adapters/kysely-lock-adapter/kysely-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.d.ts +20 -7
- package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.js +59 -35
- package/dist/lock/implementations/adapters/memory-lock-adapter/memory-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.d.ts +23 -12
- package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.js +152 -87
- package/dist/lock/implementations/adapters/mongodb-lock-adapter/mongodb-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.d.ts +5 -5
- package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.js +3 -2
- package/dist/lock/implementations/adapters/no-op-lock-adapter/no-op-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.d.ts +6 -6
- package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.js +46 -24
- package/dist/lock/implementations/adapters/redis-lock-adapter/redis-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.d.ts +4 -4
- package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.js +45 -12
- package/dist/lock/implementations/derivables/lock-provider/database-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider/is-database-lock-adapter.js +7 -5
- package/dist/lock/implementations/derivables/lock-provider/is-database-lock-adapter.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider/lock-provider.d.ts +3 -3
- package/dist/lock/implementations/derivables/lock-provider/lock-provider.js +2 -3
- package/dist/lock/implementations/derivables/lock-provider/lock-provider.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.d.ts +1 -1
- package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.js +4 -3
- package/dist/lock/implementations/derivables/lock-provider/lock-serde-transformer.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider/lock-state.d.ts +8 -11
- package/dist/lock/implementations/derivables/lock-provider/lock-state.js +9 -26
- package/dist/lock/implementations/derivables/lock-provider/lock-state.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider/lock.d.ts +14 -16
- package/dist/lock/implementations/derivables/lock-provider/lock.js +106 -63
- package/dist/lock/implementations/derivables/lock-provider/lock.js.map +1 -1
- package/dist/lock/implementations/derivables/lock-provider-factory/lock-provider-factory.d.ts +2 -2
- package/dist/lock/implementations/derivables/lock-provider-factory/lock-provider-factory.js.map +1 -1
- package/dist/lock/implementations/test-utilities/database-lock-adapter.test-suite.js +184 -166
- package/dist/lock/implementations/test-utilities/database-lock-adapter.test-suite.js.map +1 -1
- package/dist/lock/implementations/test-utilities/lock-adapter.test-suite.js +240 -41
- package/dist/lock/implementations/test-utilities/lock-adapter.test-suite.js.map +1 -1
- package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js +2704 -1514
- package/dist/lock/implementations/test-utilities/lock-provider.test-suite.js.map +1 -1
- package/dist/serde/implementations/derivables/serde.d.ts +22 -22
- package/dist/utilities/classes/kysely-table-name-transformer-plugin/kysely-table-name-transformer-plugin.js +2 -1
- package/dist/utilities/classes/kysely-table-name-transformer-plugin/kysely-table-name-transformer-plugin.js.map +1 -1
- package/dist/utilities/classes/namespace/namespace.d.ts +3 -3
- package/dist/utilities/classes/namespace/namespace.js +2 -2
- package/dist/utilities/classes/namespace/namespace.js.map +1 -1
- package/dist/utilities/classes/time-span/time-span.d.ts +10 -2
- package/dist/utilities/classes/time-span/time-span.js +10 -2
- package/dist/utilities/classes/time-span/time-span.js.map +1 -1
- package/dist/utilities/contracts/deinitizable.contract.d.ts +1 -1
- package/dist/utilities/contracts/initizable.contract.d.ts +1 -1
- package/dist/utilities/contracts/prunable.contract.d.ts +1 -1
- package/dist/utilities/errors.d.ts +8 -0
- package/dist/utilities/errors.js +11 -0
- package/dist/utilities/errors.js.map +1 -1
- package/dist/utilities/functions/_module.d.ts +1 -0
- package/dist/utilities/functions/_module.js +1 -0
- package/dist/utilities/functions/_module.js.map +1 -1
- package/dist/utilities/functions/is-class.d.ts +4 -0
- package/dist/utilities/functions/is-class.js +4 -0
- package/dist/utilities/functions/is-class.js.map +1 -1
- package/dist/utilities/functions/is-positive-nbr.d.ts +8 -0
- package/dist/utilities/functions/is-positive-nbr.js +19 -0
- package/dist/utilities/functions/is-positive-nbr.js.map +1 -0
- package/package.json +1 -1
- package/dist/event-bus/contracts/event-bus.errors.d.ts +0 -40
- package/dist/event-bus/contracts/event-bus.errors.js +0 -62
- 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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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;
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
68
|
-
remove(key: string
|
|
69
|
-
|
|
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
|
|
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("
|
|
57
|
+
.dropIndex("lock_expiration")
|
|
46
58
|
.on("lock")
|
|
47
59
|
.execute();
|
|
48
60
|
}
|
|
49
61
|
catch {
|
|
50
62
|
/* EMPTY */
|
|
51
63
|
}
|
|
52
|
-
// Should
|
|
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
|
|
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
|
-
.
|
|
66
|
-
.addColumn("
|
|
67
|
-
.addColumn("
|
|
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
|
|
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("
|
|
88
|
+
.createIndex("lock_expiration")
|
|
78
89
|
.on("lock")
|
|
79
|
-
.columns(["
|
|
90
|
+
.columns(["expiration"])
|
|
80
91
|
.execute();
|
|
81
92
|
}
|
|
82
93
|
catch {
|
|
83
94
|
/* EMPTY */
|
|
84
95
|
}
|
|
85
96
|
if (this.shouldRemoveExpiredKeys) {
|
|
86
|
-
this.timeoutId =
|
|
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.
|
|
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
|
-
|
|
114
|
+
expiration: expiration?.getTime() ?? null,
|
|
104
115
|
})
|
|
105
116
|
.execute();
|
|
106
117
|
}
|
|
107
|
-
async
|
|
108
|
-
const
|
|
118
|
+
async updateIfExpired(key, owner, expiration) {
|
|
119
|
+
const result = await this.kysely
|
|
109
120
|
.updateTable("lock")
|
|
110
121
|
.where("lock.key", "=", key)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
eb("lock.
|
|
114
|
-
eb(
|
|
115
|
-
|
|
116
|
-
.set({
|
|
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(
|
|
132
|
+
return Number(result.numUpdatedRows);
|
|
119
133
|
}
|
|
120
|
-
async remove(key
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
128
|
-
|
|
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({
|
|
221
|
+
.set({
|
|
222
|
+
expiration: expiration.getTime(),
|
|
223
|
+
})
|
|
133
224
|
.executeTakeFirst();
|
|
134
|
-
return Number(
|
|
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
|
-
|
|
147
|
-
|
|
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;
|
|
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
|
|
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,
|
|
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<
|
|
36
|
-
refresh(key: string, owner: string,
|
|
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
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
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
|
-
|
|
40
|
-
}
|
|
51
|
+
hasExpiration: false,
|
|
52
|
+
};
|
|
53
|
+
this.map.set(key, lock);
|
|
41
54
|
}
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
else {
|
|
56
|
+
const timeoutId = setTimeout(() => {
|
|
44
57
|
this.map.delete(key);
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
}, ttl.toMilliseconds());
|
|
59
|
+
lock = {
|
|
60
|
+
owner,
|
|
61
|
+
hasExpiration: true,
|
|
62
|
+
timeoutId,
|
|
63
|
+
};
|
|
64
|
+
this.map.set(key, lock);
|
|
47
65
|
}
|
|
48
|
-
return
|
|
66
|
+
return true;
|
|
49
67
|
}
|
|
50
68
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
51
69
|
async release(key, owner) {
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
return
|
|
70
|
+
const lock = this.map.get(key);
|
|
71
|
+
if (lock === undefined) {
|
|
72
|
+
return false;
|
|
55
73
|
}
|
|
56
|
-
if (
|
|
74
|
+
if (lock.owner !== owner) {
|
|
57
75
|
return false;
|
|
58
76
|
}
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
67
|
-
|
|
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,
|
|
72
|
-
const
|
|
73
|
-
if (
|
|
74
|
-
return
|
|
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 (
|
|
77
|
-
return
|
|
101
|
+
if (lock.owner !== owner) {
|
|
102
|
+
return LOCK_REFRESH_RESULT.UNOWNED_REFRESH;
|
|
78
103
|
}
|
|
79
|
-
if (
|
|
80
|
-
return
|
|
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
|
-
...
|
|
84
|
-
|
|
112
|
+
...lock,
|
|
113
|
+
timeoutId,
|
|
85
114
|
});
|
|
86
|
-
|
|
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
|