universal-lock 0.0.1 → 0.0.2

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,2 @@
1
+ import { Backend } from "../types";
2
+ export declare const fileBackendFactory: (lockFolderPath: string) => Backend;
@@ -0,0 +1,2 @@
1
+ import { BackendFactory } from "../types";
2
+ export declare const memoryBackendFactory: BackendFactory;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- import { test } from "./util";
2
- export default test;
1
+ import { lockFactory, lockDecoratoryFactory } from "./lock";
2
+ import { memoryBackendFactory } from "./backends/MemoryBackend";
3
+ export { memoryBackendFactory, lockFactory, lockDecoratoryFactory, };
package/dist/index.umd.js CHANGED
@@ -4,21 +4,132 @@
4
4
  else if(typeof define === 'function' && define.amd)
5
5
  define([], factory);
6
6
  else if(typeof exports === 'object')
7
- exports["SnapshotDB"] = factory();
7
+ exports["UniversalLock"] = factory();
8
8
  else
9
- root["SnapshotDB"] = factory();
9
+ root["UniversalLock"] = factory();
10
10
  })(this, function() {
11
11
  return /******/ (function() { // webpackBootstrap
12
12
  /******/ "use strict";
13
13
  /******/ var __webpack_modules__ = ({
14
14
 
15
+ /***/ 112:
16
+ /***/ (function(__unused_webpack_module, exports) {
17
+
18
+
19
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
20
+ exports.memoryBackendFactory = void 0;
21
+ exports.memoryBackendFactory = ((locks = {}) => {
22
+ const setup = async () => { };
23
+ const acquire = async (lockName, stale) => {
24
+ const now = Date.now();
25
+ const lockExists = !!locks[lockName];
26
+ const lockExpired = lockExists && locks[lockName] + stale < now;
27
+ if (!lockExists || lockExpired) {
28
+ locks[lockName] = now;
29
+ }
30
+ else {
31
+ throw new Error(`${lockName} already locked`);
32
+ }
33
+ };
34
+ const renew = async (lockName) => {
35
+ locks[lockName] = Date.now();
36
+ };
37
+ const release = async (lockName) => {
38
+ delete locks[lockName];
39
+ };
40
+ return {
41
+ setup,
42
+ acquire,
43
+ renew,
44
+ release,
45
+ };
46
+ });
47
+
48
+
49
+ /***/ }),
50
+
51
+ /***/ 340:
52
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
53
+
54
+
55
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
56
+ exports.lockFactory = lockFactory;
57
+ exports.lockDecoratoryFactory = lockDecoratoryFactory;
58
+ const util_1 = __webpack_require__(639);
59
+ const defaultConfiguration = {
60
+ acquireInterval: 250,
61
+ acquireFailTimeout: 5000,
62
+ stale: 1000,
63
+ renewInterval: 250,
64
+ runningTimeout: 2000,
65
+ };
66
+ function lockFactory({ setup, acquire, renew, release }, configuration = {}) {
67
+ const { acquireInterval, acquireFailTimeout, stale, renewInterval, runningTimeout, } = Object.assign(Object.assign({}, defaultConfiguration), configuration);
68
+ const setupPromise = setup();
69
+ return {
70
+ async acquire(lockName) {
71
+ await setupPromise;
72
+ return new Promise((resolve) => {
73
+ const stopAcquireInterval = (0, util_1.asyncInterval)(async () => {
74
+ try {
75
+ await acquire(lockName, stale);
76
+ const stopRenewInterval = (0, util_1.asyncInterval)(async () => {
77
+ await renew(lockName);
78
+ }, renewInterval);
79
+ const releaseLock = async () => {
80
+ await stopRenewInterval();
81
+ await release(lockName);
82
+ };
83
+ stopAcquireInterval().then(() => {
84
+ resolve(releaseLock);
85
+ });
86
+ }
87
+ catch (e) { }
88
+ }, acquireInterval);
89
+ });
90
+ }
91
+ };
92
+ }
93
+ function lockDecoratoryFactory(lock) {
94
+ return (lockName, fn) => {
95
+ return async (...args) => {
96
+ const release = await lock.acquire(lockName);
97
+ try {
98
+ return await fn(...args);
99
+ }
100
+ finally {
101
+ await release();
102
+ }
103
+ };
104
+ };
105
+ }
106
+
107
+
108
+ /***/ }),
109
+
15
110
  /***/ 639:
16
111
  /***/ (function(__unused_webpack_module, exports) {
17
112
 
18
113
 
19
114
  Object.defineProperty(exports, "__esModule", ({ value: true }));
20
- exports.test = test;
21
- function test() { }
115
+ exports.asyncInterval = exports.sleep = void 0;
116
+ const sleep = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
117
+ exports.sleep = sleep;
118
+ const asyncInterval = (handler, timeout) => {
119
+ let running = true;
120
+ (async () => {
121
+ while (running) {
122
+ await handler();
123
+ if (!running)
124
+ break;
125
+ await (0, exports.sleep)(timeout);
126
+ }
127
+ })();
128
+ return async () => {
129
+ running = false;
130
+ };
131
+ };
132
+ exports.asyncInterval = asyncInterval;
22
133
 
23
134
 
24
135
  /***/ })
@@ -56,8 +167,12 @@ var __webpack_exports__ = {};
56
167
  var exports = __webpack_exports__;
57
168
 
58
169
  Object.defineProperty(exports, "__esModule", ({ value: true }));
59
- const util_1 = __webpack_require__(639);
60
- exports["default"] = util_1.test;
170
+ exports.lockDecoratoryFactory = exports.lockFactory = exports.memoryBackendFactory = void 0;
171
+ const lock_1 = __webpack_require__(340);
172
+ Object.defineProperty(exports, "lockFactory", ({ enumerable: true, get: function () { return lock_1.lockFactory; } }));
173
+ Object.defineProperty(exports, "lockDecoratoryFactory", ({ enumerable: true, get: function () { return lock_1.lockDecoratoryFactory; } }));
174
+ const MemoryBackend_1 = __webpack_require__(112);
175
+ Object.defineProperty(exports, "memoryBackendFactory", ({ enumerable: true, get: function () { return MemoryBackend_1.memoryBackendFactory; } }));
61
176
 
62
177
  }();
63
178
  /******/ return __webpack_exports__;
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACVA;AACA;AACA;AACA;;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACvBA;AACA;AACA;AACA","sources":["webpack://UniversalLock/webpack/universalModuleDefinition","webpack://UniversalLock/./src/util.ts","webpack://UniversalLock/webpack/bootstrap","webpack://UniversalLock/./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"UniversalLock\"] = factory();\n\telse\n\t\troot[\"UniversalLock\"] = factory();\n})(this, function() {\nreturn ","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.test = test;\nfunction test() { }\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst util_1 = require(\"./util\");\nexports.default = util_1.test;\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"index.umd.js","mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack://UniversalLock/webpack/universalModuleDefinition","webpack://UniversalLock/./src/backends/MemoryBackend.ts","webpack://UniversalLock/./src/lock.ts","webpack://UniversalLock/./src/util.ts","webpack://UniversalLock/webpack/bootstrap","webpack://UniversalLock/./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"UniversalLock\"] = factory();\n\telse\n\t\troot[\"UniversalLock\"] = factory();\n})(this, function() {\nreturn ","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.memoryBackendFactory = void 0;\nexports.memoryBackendFactory = ((locks = {}) => {\n const setup = async () => { };\n const acquire = async (lockName, stale) => {\n const now = Date.now();\n const lockExists = !!locks[lockName];\n const lockExpired = lockExists && locks[lockName] + stale < now;\n if (!lockExists || lockExpired) {\n locks[lockName] = now;\n }\n else {\n throw new Error(`${lockName} already locked`);\n }\n };\n const renew = async (lockName) => {\n locks[lockName] = Date.now();\n };\n const release = async (lockName) => {\n delete locks[lockName];\n };\n return {\n setup,\n acquire,\n renew,\n release,\n };\n});\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.lockFactory = lockFactory;\nexports.lockDecoratoryFactory = lockDecoratoryFactory;\nconst util_1 = require(\"./util\");\nconst defaultConfiguration = {\n acquireInterval: 250,\n acquireFailTimeout: 5000,\n stale: 1000,\n renewInterval: 250,\n runningTimeout: 2000,\n};\nfunction lockFactory({ setup, acquire, renew, release }, configuration = {}) {\n const { acquireInterval, acquireFailTimeout, stale, renewInterval, runningTimeout, } = Object.assign(Object.assign({}, defaultConfiguration), configuration);\n const setupPromise = setup();\n return {\n async acquire(lockName) {\n await setupPromise;\n return new Promise((resolve) => {\n const stopAcquireInterval = (0, util_1.asyncInterval)(async () => {\n try {\n await acquire(lockName, stale);\n const stopRenewInterval = (0, util_1.asyncInterval)(async () => {\n await renew(lockName);\n }, renewInterval);\n const releaseLock = async () => {\n await stopRenewInterval();\n await release(lockName);\n };\n stopAcquireInterval().then(() => {\n resolve(releaseLock);\n });\n }\n catch (e) { }\n }, acquireInterval);\n });\n }\n };\n}\nfunction lockDecoratoryFactory(lock) {\n return (lockName, fn) => {\n return async (...args) => {\n const release = await lock.acquire(lockName);\n try {\n return await fn(...args);\n }\n finally {\n await release();\n }\n };\n };\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.asyncInterval = exports.sleep = void 0;\nconst sleep = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nexports.sleep = sleep;\nconst asyncInterval = (handler, timeout) => {\n let running = true;\n (async () => {\n while (running) {\n await handler();\n if (!running)\n break;\n await (0, exports.sleep)(timeout);\n }\n })();\n return async () => {\n running = false;\n };\n};\nexports.asyncInterval = asyncInterval;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.lockDecoratoryFactory = exports.lockFactory = exports.memoryBackendFactory = void 0;\nconst lock_1 = require(\"./lock\");\nObject.defineProperty(exports, \"lockFactory\", { enumerable: true, get: function () { return lock_1.lockFactory; } });\nObject.defineProperty(exports, \"lockDecoratoryFactory\", { enumerable: true, get: function () { return lock_1.lockDecoratoryFactory; } });\nconst MemoryBackend_1 = require(\"./backends/MemoryBackend\");\nObject.defineProperty(exports, \"memoryBackendFactory\", { enumerable: true, get: function () { return MemoryBackend_1.memoryBackendFactory; } });\n"],"names":[],"sourceRoot":""}
package/dist/lock.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { AsyncFunction, Lock, Backend, LockConfiguration } from "./types";
2
+ export declare function lockFactory({ setup, acquire, renew, release }: Backend, configuration?: Partial<LockConfiguration>): Lock;
3
+ export declare function lockDecoratoryFactory(lock: Lock): <F extends AsyncFunction>(lockName: string, fn: F) => (...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>;
@@ -0,0 +1,24 @@
1
+ export type AsyncFunction<R extends any = any, P extends any[] = any[]> = (...args: P) => Promise<R>;
2
+ export type BackendSetupFunction = () => Promise<void>;
3
+ export type BackendAcquireFunction = (lockName: string, stale: number) => Promise<void>;
4
+ export type BackendRenewFunction = (lockName: string) => Promise<void>;
5
+ export type BackendReleaseFunction = (lockName: string) => Promise<void>;
6
+ export type Backend = {
7
+ setup: BackendSetupFunction;
8
+ acquire: BackendAcquireFunction;
9
+ renew: BackendRenewFunction;
10
+ release: BackendReleaseFunction;
11
+ };
12
+ export type BackendFactory = (...args: any[]) => Backend;
13
+ export type LockConfiguration = {
14
+ acquireInterval: number;
15
+ acquireFailTimeout: number;
16
+ stale: number;
17
+ renewInterval: number;
18
+ runningTimeout: number;
19
+ };
20
+ export type LockReleaseFunction = () => Promise<void>;
21
+ export type LockAcquireFunction = (lockName: string) => Promise<LockReleaseFunction>;
22
+ export type Lock = {
23
+ acquire: LockAcquireFunction;
24
+ };
package/dist/util.d.ts CHANGED
@@ -1 +1,3 @@
1
- export declare function test(): void;
1
+ import { AsyncFunction } from "./types";
2
+ export declare const sleep: (ms: number) => Promise<unknown>;
3
+ export declare const asyncInterval: <H extends AsyncFunction<void, []>>(handler: H, timeout: number) => () => Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-lock",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "UniversalLock",
5
5
  "main": "dist/index.umd.js",
6
6
  "types": "dist/index.d.ts",
@@ -21,7 +21,6 @@
21
21
  },
22
22
  "keywords": [
23
23
  "UniversalLock",
24
- "Snapshot",
25
24
  "Database",
26
25
  "nosql"
27
26
  ],