@acmekit/locking-redis 2.13.1

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.
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@acmekit/types").ModuleProviderExports;
2
+ export default _default;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAOA,wBAGE"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@acmekit/framework/utils");
7
+ const loaders_1 = __importDefault(require("./loaders"));
8
+ const redis_lock_1 = require("./services/redis-lock");
9
+ const services = [redis_lock_1.RedisLockingProvider];
10
+ const loaders = [loaders_1.default];
11
+ exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.LOCKING, {
12
+ services,
13
+ loaders,
14
+ });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,oDAAkE;AAClE,wDAA8B;AAC9B,sDAA4D;AAE5D,MAAM,QAAQ,GAAG,CAAC,iCAAoB,CAAC,CAAA;AACvC,MAAM,OAAO,GAAG,CAAC,iBAAM,CAAC,CAAA;AAExB,kBAAe,IAAA,sBAAc,EAAC,eAAO,CAAC,OAAO,EAAE;IAC7C,QAAQ;IACR,OAAO;CACR,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { ProviderLoaderOptions } from "@acmekit/types";
2
+ declare const _default: ({ container, logger, options, moduleOptions, }: ProviderLoaderOptions) => Promise<void>;
3
+ export default _default;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loaders/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;yBAKhC,gDAKnB,qBAAqB,KAAG,OAAO,CAAC,IAAI,CAAC;AALxC,wBAkCC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@acmekit/framework/utils");
7
+ const awilix_1 = require("@acmekit/framework/awilix");
8
+ const ioredis_1 = __importDefault(require("ioredis"));
9
+ exports.default = async ({ container, logger, options, moduleOptions, }) => {
10
+ const { redisUrl, redisOptions, namespace } = options;
11
+ if (!redisUrl) {
12
+ throw Error(`No "redisUrl" provided in "${utils_1.Modules.LOCKING}" module, "locking-redis" provider options. It is required for the "locking-redis" Module provider.`);
13
+ }
14
+ const connection = new ioredis_1.default(redisUrl, {
15
+ // Lazy connect to properly handle connection errors
16
+ lazyConnect: true,
17
+ ...(redisOptions ?? {}),
18
+ });
19
+ try {
20
+ await connection.connect();
21
+ logger?.info(`Connection to Redis in "locking-redis" provider established`);
22
+ }
23
+ catch (err) {
24
+ logger?.error(`An error occurred while connecting to Redis in provider "locking-redis": ${err}`);
25
+ }
26
+ container.register({
27
+ redisClient: (0, awilix_1.asValue)(connection),
28
+ prefix: (0, awilix_1.asValue)(namespace ?? "acmekit_lock:"),
29
+ });
30
+ };
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/loaders/index.ts"],"names":[],"mappings":";;;;;AAAA,oDAAkD;AAGlD,sDAAmD;AACnD,sDAA2B;AAE3B,kBAAe,KAAK,EAAE,EACpB,SAAS,EACT,MAAM,EACN,OAAO,EACP,aAAa,GACS,EAAiB,EAAE;IACzC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,GACzC,OAAkC,CAAA;IAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,KAAK,CACT,8BAA8B,eAAO,CAAC,OAAO,qGAAqG,CACnJ,CAAA;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,iBAAK,CAAC,QAAQ,EAAE;QACrC,oDAAoD;QACpD,WAAW,EAAE,IAAI;QACjB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;KACxB,CAAC,CAAA;IAEF,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,OAAO,EAAE,CAAA;QAC1B,MAAM,EAAE,IAAI,CAAC,6DAA6D,CAAC,CAAA;IAC7E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,KAAK,CACX,4EAA4E,GAAG,EAAE,CAClF,CAAA;IACH,CAAC;IAED,SAAS,CAAC,QAAQ,CAAC;QACjB,WAAW,EAAE,IAAA,gBAAO,EAAC,UAAU,CAAC;QAChC,MAAM,EAAE,IAAA,gBAAO,EAAC,SAAS,IAAI,eAAe,CAAC;KAC9C,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,42 @@
1
+ import { ILockingProvider } from "@acmekit/types";
2
+ import { RedisCacheModuleOptions } from "../types";
3
+ import { Redis } from "ioredis";
4
+ export declare class RedisLockingProvider implements ILockingProvider {
5
+ static identifier: string;
6
+ protected redisClient: Redis & {
7
+ acquireLock: (key: string, ownerId: string, ttl: number, awaitQueue?: boolean) => Promise<number>;
8
+ releaseLock: (key: string, ownerId: string) => Promise<number>;
9
+ };
10
+ protected keyNamePrefix: string;
11
+ protected waitLockingTimeout: number;
12
+ protected defaultRetryInterval: number;
13
+ protected maximumRetryInterval: number;
14
+ constructor({ redisClient, prefix }: {
15
+ redisClient: any;
16
+ prefix: any;
17
+ }, options: RedisCacheModuleOptions);
18
+ private getKeyName;
19
+ execute<T>(keys: string | string[], job: () => Promise<T>, args?: {
20
+ timeout?: number;
21
+ }): Promise<T>;
22
+ acquire(keys: string | string[], args?: {
23
+ ownerId?: string;
24
+ expire?: number;
25
+ awaitQueue?: boolean;
26
+ }): Promise<void>;
27
+ acquire_(keys: string | string[], args?: {
28
+ ownerId?: string;
29
+ expire?: number;
30
+ awaitQueue?: boolean;
31
+ }, cancellationToken?: {
32
+ cancelled: boolean;
33
+ }): Promise<void>;
34
+ release(keys: string | string[], args?: {
35
+ ownerId?: string | null;
36
+ }): Promise<boolean>;
37
+ releaseAll(args?: {
38
+ ownerId?: string | null;
39
+ }): Promise<void>;
40
+ private getTimeout;
41
+ }
42
+ //# sourceMappingURL=redis-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-lock.d.ts","sourceRoot":"","sources":["../../src/services/redis-lock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAG/B,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,MAAM,CAAC,UAAU,SAAkB;IAEnC,SAAS,CAAC,WAAW,EAAE,KAAK,GAAG;QAC7B,WAAW,EAAE,CACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,OAAO,KACjB,OAAO,CAAC,MAAM,CAAC,CAAA;QACpB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;KAC/D,CAAA;IACD,SAAS,CAAC,aAAa,EAAE,MAAM,CAAA;IAC/B,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAI;IACxC,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAI;IAC1C,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAM;gBAEhC,EAAE,WAAW,EAAE,MAAM,EAAE;;;KAAA,EAAE,OAAO,EAAE,uBAAuB;IA0ErE,OAAO,CAAC,UAAU;IAIZ,OAAO,CAAC,CAAC,EACb,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACrB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,GACA,OAAO,CAAC,CAAC,CAAC;IA+BP,OAAO,CACX,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,GACA,OAAO,CAAC,IAAI,CAAC;IAIV,QAAQ,CACZ,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,EACD,iBAAiB,CAAC,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GACzC,OAAO,CAAC,IAAI,CAAC;IAqDV,OAAO,CACX,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACxB,GACA,OAAO,CAAC,OAAO,CAAC;IAeb,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAwCrD,UAAU;CAUzB"}
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisLockingProvider = void 0;
4
+ const utils_1 = require("@acmekit/framework/utils");
5
+ const promises_1 = require("node:timers/promises");
6
+ class RedisLockingProvider {
7
+ constructor({ redisClient, prefix }, options) {
8
+ this.waitLockingTimeout = 5;
9
+ this.defaultRetryInterval = 5;
10
+ this.maximumRetryInterval = 200;
11
+ this.redisClient = redisClient;
12
+ this.keyNamePrefix = prefix ?? "acmekit_lock:";
13
+ if (!isNaN(+options?.waitLockingTimeout)) {
14
+ this.waitLockingTimeout = +options.waitLockingTimeout;
15
+ }
16
+ if (!isNaN(+options?.defaultRetryInterval)) {
17
+ this.defaultRetryInterval = +options.defaultRetryInterval;
18
+ }
19
+ if (!isNaN(+options?.maximumRetryInterval)) {
20
+ this.maximumRetryInterval = +options.maximumRetryInterval;
21
+ }
22
+ // Define the custom command for acquiring locks
23
+ this.redisClient.defineCommand("acquireLock", {
24
+ numberOfKeys: 1,
25
+ lua: `
26
+ local key = KEYS[1]
27
+ local ownerId = ARGV[1]
28
+ local ttl = tonumber(ARGV[2])
29
+ local awaitQueue = ARGV[3] == 'true'
30
+
31
+ local setArgs = {key, ownerId, 'NX'}
32
+ if ttl > 0 then
33
+ table.insert(setArgs, 'EX')
34
+ table.insert(setArgs, ttl)
35
+ end
36
+
37
+ local setResult = redis.call('SET', unpack(setArgs))
38
+
39
+ if setResult then
40
+ return 1
41
+ elseif not awaitQueue then
42
+ -- Key already exists; retrieve the current ownerId
43
+ local currentOwnerId = redis.call('GET', key)
44
+ if currentOwnerId == '*' then
45
+ return 0
46
+ elseif currentOwnerId == ownerId then
47
+ setArgs = {key, ownerId, 'XX'}
48
+ if ttl > 0 then
49
+ table.insert(setArgs, 'EX')
50
+ table.insert(setArgs, ttl)
51
+ end
52
+ redis.call('SET', unpack(setArgs))
53
+ return 1
54
+ else
55
+ return 0
56
+ end
57
+ else
58
+ return 0
59
+ end
60
+
61
+ `,
62
+ });
63
+ // Define the custom command for releasing locks
64
+ this.redisClient.defineCommand("releaseLock", {
65
+ numberOfKeys: 1,
66
+ lua: `
67
+ local key = KEYS[1]
68
+ local ownerId = ARGV[1]
69
+
70
+ if redis.call('GET', key) == ownerId then
71
+ return redis.call('DEL', key)
72
+ else
73
+ return 0
74
+ end
75
+ `,
76
+ });
77
+ }
78
+ getKeyName(key) {
79
+ return `${this.keyNamePrefix}${key}`;
80
+ }
81
+ async execute(keys, job, args) {
82
+ const timeout = Math.max(args?.timeout ?? this.waitLockingTimeout, 1);
83
+ const timeoutSeconds = Number.isNaN(timeout) ? 1 : timeout;
84
+ const cancellationToken = { cancelled: false };
85
+ const promises = [];
86
+ if (timeoutSeconds > 0) {
87
+ promises.push(this.getTimeout(timeoutSeconds, cancellationToken));
88
+ }
89
+ const ONE_MINUTE = 60;
90
+ promises.push(this.acquire_(keys, {
91
+ awaitQueue: true,
92
+ expire: args?.timeout ? timeoutSeconds : ONE_MINUTE,
93
+ }, cancellationToken));
94
+ await Promise.race(promises);
95
+ try {
96
+ return await job();
97
+ }
98
+ finally {
99
+ await this.release(keys);
100
+ }
101
+ }
102
+ async acquire(keys, args) {
103
+ return this.acquire_(keys, args);
104
+ }
105
+ async acquire_(keys, args, cancellationToken) {
106
+ keys = Array.isArray(keys) ? keys : [keys];
107
+ const timeout = Math.max(args?.expire ?? this.waitLockingTimeout, 1);
108
+ const timeoutSeconds = Number.isNaN(timeout) ? 1 : timeout;
109
+ let retryTimes = 0;
110
+ const ownerId = args?.ownerId ?? "*";
111
+ const awaitQueue = args?.awaitQueue ?? false;
112
+ const acquirePromises = keys.map(async (key) => {
113
+ const errMessage = `Failed to acquire lock for key "${key}"`;
114
+ const keyName = this.getKeyName(key);
115
+ const acquireLock = async () => {
116
+ while (true) {
117
+ if (cancellationToken?.cancelled) {
118
+ throw new Error(errMessage);
119
+ }
120
+ const result = await this.redisClient.acquireLock(keyName, ownerId, args?.expire ? timeoutSeconds : 0, awaitQueue);
121
+ if (result === 1) {
122
+ break;
123
+ }
124
+ else {
125
+ if (awaitQueue) {
126
+ // Wait for a short period before retrying
127
+ await (0, promises_1.setTimeout)(Math.min(this.defaultRetryInterval +
128
+ (retryTimes / 10) * this.defaultRetryInterval, this.maximumRetryInterval));
129
+ retryTimes++;
130
+ }
131
+ else {
132
+ throw new Error(errMessage);
133
+ }
134
+ }
135
+ }
136
+ };
137
+ await acquireLock();
138
+ });
139
+ await (0, utils_1.promiseAll)(acquirePromises);
140
+ }
141
+ async release(keys, args) {
142
+ const ownerId = args?.ownerId ?? "*";
143
+ keys = Array.isArray(keys) ? keys : [keys];
144
+ const releasePromises = keys.map(async (key) => {
145
+ const keyName = this.getKeyName(key);
146
+ const result = await this.redisClient.releaseLock(keyName, ownerId);
147
+ return result === 1;
148
+ });
149
+ const results = await (0, utils_1.promiseAll)(releasePromises);
150
+ return results.every((released) => released);
151
+ }
152
+ async releaseAll(args) {
153
+ const ownerId = args?.ownerId ?? "*";
154
+ const pattern = `${this.keyNamePrefix}*`;
155
+ let cursor = "0";
156
+ do {
157
+ const result = await this.redisClient.scan(cursor, "MATCH", pattern, "COUNT", 100);
158
+ cursor = result[0];
159
+ const keys = result[1];
160
+ if (keys.length > 0) {
161
+ const pipeline = this.redisClient.pipeline();
162
+ keys.forEach((key) => {
163
+ pipeline.get(key);
164
+ });
165
+ const currentOwners = await pipeline.exec();
166
+ const deletePipeline = this.redisClient.pipeline();
167
+ keys.forEach((key, idx) => {
168
+ const currentOwner = currentOwners?.[idx]?.[1];
169
+ if (currentOwner === ownerId) {
170
+ deletePipeline.unlink(key);
171
+ }
172
+ });
173
+ await deletePipeline.exec();
174
+ }
175
+ } while (cursor !== "0");
176
+ }
177
+ async getTimeout(seconds, cancellationToken) {
178
+ return new Promise(async (_, reject) => {
179
+ await (0, promises_1.setTimeout)(seconds * 1000);
180
+ cancellationToken.cancelled = true;
181
+ reject(new Error("Timed-out acquiring lock."));
182
+ });
183
+ }
184
+ }
185
+ exports.RedisLockingProvider = RedisLockingProvider;
186
+ RedisLockingProvider.identifier = "locking-redis";
187
+ //# sourceMappingURL=redis-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-lock.js","sourceRoot":"","sources":["../../src/services/redis-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"root":["../src/index.ts","../src/loaders/index.ts","../src/services/redis-lock.ts","../src/types/index.ts"],"version":"5.9.3"}
@@ -0,0 +1,39 @@
1
+ import { RedisOptions } from "ioredis";
2
+ /**
3
+ * Module config type
4
+ */
5
+ export type RedisCacheModuleOptions = {
6
+ /**
7
+ * Time to keep data in cache (in seconds)
8
+ */
9
+ ttl?: number;
10
+ /**
11
+ * Redis connection string
12
+ */
13
+ redisUrl?: string;
14
+ /**
15
+ * Redis client options
16
+ */
17
+ redisOptions?: RedisOptions;
18
+ /**
19
+ * Prefix for event keys
20
+ * @default `acmekit_lock:`
21
+ */
22
+ namespace?: string;
23
+ /**
24
+ * Time to wait for lock (in seconds)
25
+ * @default 5
26
+ */
27
+ waitLockingTimeout?: number;
28
+ /**
29
+ * Default retry interval (in milliseconds)
30
+ * @default 5
31
+ */
32
+ defaultRetryInterval?: number;
33
+ /**
34
+ * Maximum retry interval (in milliseconds)
35
+ * @default 200
36
+ */
37
+ maximumRetryInterval?: number;
38
+ };
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@acmekit/locking-redis",
3
+ "version": "2.13.1",
4
+ "description": "Redis Lock for AcmeKit",
5
+ "main": "dist/index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/acmekit/acmekit",
9
+ "directory": "packages/modules/providers/locking-redis"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "!dist/**/__tests__",
14
+ "!dist/**/__mocks__",
15
+ "!dist/**/__fixtures__"
16
+ ],
17
+ "engines": {
18
+ "node": ">=20"
19
+ },
20
+ "author": "AcmeKit",
21
+ "license": "MIT",
22
+ "devDependencies": {
23
+ "@acmekit/framework": "2.13.1"
24
+ },
25
+ "peerDependencies": {
26
+ "@acmekit/framework": "2.13.1"
27
+ },
28
+ "dependencies": {
29
+ "ioredis": "^5.4.1"
30
+ },
31
+ "scripts": {
32
+ "watch": "yarn run -T tsc --build --watch",
33
+ "watch:test": "yarn run -T tsc --build tsconfig.spec.json --watch",
34
+ "resolve:aliases": "yarn run -T tsc --showConfig -p tsconfig.json > tsconfig.resolved.json && yarn run -T tsc-alias -p tsconfig.resolved.json && yarn run -T rimraf tsconfig.resolved.json",
35
+ "build": "yarn run -T rimraf dist && yarn run -T tsc --build && npm run resolve:aliases",
36
+ "test": "../../../../node_modules/.bin/jest --passWithNoTests src",
37
+ "test:integration": "../../../../node_modules/.bin/jest --passWithNoTests --forceExit --testPathPattern=\"integration-tests/__tests__/.*\\.spec\\.ts\""
38
+ },
39
+ "keywords": [
40
+ "acmekit-providers",
41
+ "acmekit-providers-locking"
42
+ ]
43
+ }