@lickle/lock 0.0.1-alpha.1 → 0.0.1-alpha.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.
Files changed (91) hide show
  1. package/README.md +182 -76
  2. package/cjs.js +57 -57
  3. package/dist/cjs/core/guard.d.ts +50 -0
  4. package/dist/cjs/core/guard.d.ts.map +1 -0
  5. package/dist/cjs/{backend → core}/guard.js +43 -11
  6. package/dist/cjs/core/guard.js.map +1 -0
  7. package/dist/cjs/core/index.d.ts +8 -0
  8. package/dist/cjs/core/index.d.ts.map +1 -0
  9. package/dist/cjs/core/index.js +41 -0
  10. package/dist/cjs/core/index.js.map +1 -0
  11. package/dist/cjs/core/locking.d.ts +23 -0
  12. package/dist/cjs/core/locking.d.ts.map +1 -0
  13. package/dist/cjs/core/locking.js +93 -0
  14. package/dist/cjs/core/locking.js.map +1 -0
  15. package/dist/cjs/core/node.d.ts +19 -0
  16. package/dist/cjs/core/node.d.ts.map +1 -0
  17. package/dist/cjs/core/node.js +69 -0
  18. package/dist/cjs/core/node.js.map +1 -0
  19. package/dist/cjs/core/types.d.ts +49 -0
  20. package/dist/cjs/core/types.d.ts.map +1 -0
  21. package/dist/cjs/core/types.js +13 -0
  22. package/dist/cjs/core/types.js.map +1 -0
  23. package/dist/cjs/index.d.ts +43 -34
  24. package/dist/cjs/index.d.ts.map +1 -1
  25. package/dist/cjs/index.js +59 -39
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/esm/core/guard.d.ts +50 -0
  28. package/dist/esm/core/guard.d.ts.map +1 -0
  29. package/dist/esm/{backend → core}/guard.js +40 -9
  30. package/dist/esm/core/guard.js.map +1 -0
  31. package/dist/esm/core/index.d.ts +8 -0
  32. package/dist/esm/core/index.d.ts.map +1 -0
  33. package/dist/esm/core/index.js +21 -0
  34. package/dist/esm/core/index.js.map +1 -0
  35. package/dist/esm/core/locking.d.ts +23 -0
  36. package/dist/esm/core/locking.d.ts.map +1 -0
  37. package/dist/esm/core/locking.js +56 -0
  38. package/dist/esm/core/locking.js.map +1 -0
  39. package/dist/esm/core/node.d.ts +19 -0
  40. package/dist/esm/core/node.d.ts.map +1 -0
  41. package/dist/esm/core/node.js +61 -0
  42. package/dist/esm/core/node.js.map +1 -0
  43. package/dist/esm/core/types.d.ts +49 -0
  44. package/dist/esm/core/types.d.ts.map +1 -0
  45. package/dist/esm/core/types.js +9 -0
  46. package/dist/esm/core/types.js.map +1 -0
  47. package/dist/esm/index.d.ts +43 -34
  48. package/dist/esm/index.d.ts.map +1 -1
  49. package/dist/esm/index.js +53 -34
  50. package/dist/esm/index.js.map +1 -1
  51. package/esm.js +58 -58
  52. package/index.d.ts +32 -8
  53. package/package.json +6 -6
  54. package/dist/cjs/backend/guard.d.ts +0 -31
  55. package/dist/cjs/backend/guard.d.ts.map +0 -1
  56. package/dist/cjs/backend/guard.js.map +0 -1
  57. package/dist/cjs/backend/index.d.ts +0 -8
  58. package/dist/cjs/backend/index.d.ts.map +0 -1
  59. package/dist/cjs/backend/index.js +0 -31
  60. package/dist/cjs/backend/index.js.map +0 -1
  61. package/dist/cjs/backend/lockable.d.ts +0 -15
  62. package/dist/cjs/backend/lockable.d.ts.map +0 -1
  63. package/dist/cjs/backend/lockable.js +0 -76
  64. package/dist/cjs/backend/lockable.js.map +0 -1
  65. package/dist/cjs/backend/node.d.ts +0 -36
  66. package/dist/cjs/backend/node.d.ts.map +0 -1
  67. package/dist/cjs/backend/node.js +0 -118
  68. package/dist/cjs/backend/node.js.map +0 -1
  69. package/dist/cjs/backend/types.d.ts +0 -36
  70. package/dist/cjs/backend/types.d.ts.map +0 -1
  71. package/dist/cjs/backend/types.js +0 -3
  72. package/dist/cjs/backend/types.js.map +0 -1
  73. package/dist/esm/backend/guard.d.ts +0 -31
  74. package/dist/esm/backend/guard.d.ts.map +0 -1
  75. package/dist/esm/backend/guard.js.map +0 -1
  76. package/dist/esm/backend/index.d.ts +0 -8
  77. package/dist/esm/backend/index.d.ts.map +0 -1
  78. package/dist/esm/backend/index.js +0 -13
  79. package/dist/esm/backend/index.js.map +0 -1
  80. package/dist/esm/backend/lockable.d.ts +0 -15
  81. package/dist/esm/backend/lockable.d.ts.map +0 -1
  82. package/dist/esm/backend/lockable.js +0 -39
  83. package/dist/esm/backend/lockable.js.map +0 -1
  84. package/dist/esm/backend/node.d.ts +0 -36
  85. package/dist/esm/backend/node.d.ts.map +0 -1
  86. package/dist/esm/backend/node.js +0 -109
  87. package/dist/esm/backend/node.js.map +0 -1
  88. package/dist/esm/backend/types.d.ts +0 -36
  89. package/dist/esm/backend/types.d.ts.map +0 -1
  90. package/dist/esm/backend/types.js +0 -2
  91. package/dist/esm/backend/types.js.map +0 -1
@@ -0,0 +1,23 @@
1
+ import { type FileDescriptor, type Locker } from './types.js';
2
+ /**
3
+ * Lifecycle hooks called when locks are acquired and released.
4
+ * Used by backends to track active locks for cleanup on exit or signals.
5
+ */
6
+ export interface LockHooks {
7
+ /** Called after a lock is successfully acquired. */
8
+ register: (fd: FileDescriptor) => Promise<void>;
9
+ /** Called when a lock is released (even if unlock itself fails). */
10
+ unregister: (fd: FileDescriptor) => Promise<void>;
11
+ }
12
+ /**
13
+ * Create a {@link Locker} backed by native OS locks.
14
+ *
15
+ * Whole-file locks use `flock(2)` on Unix and `LockFileEx` on Windows.
16
+ * Range locks use `fcntl(2)` OFD locks on Linux, POSIX record locks on
17
+ * macOS/BSD, and ranged `LockFileEx` on Windows.
18
+ *
19
+ * If `hooks` are provided they are called after lock acquisition and on
20
+ * release, allowing backends to track active locks for cleanup.
21
+ */
22
+ export declare const createLocker: (hooks?: LockHooks) => Locker;
23
+ //# sourceMappingURL=locking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locking.d.ts","sourceRoot":"","sources":["../../../lib/core/locking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,cAAc,EAAE,KAAK,MAAM,EAAmB,MAAM,YAAY,CAAA;AAGhH;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,QAAQ,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,oEAAoE;IACpE,UAAU,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,KAAG,MAqC/C,CAAA"}
@@ -0,0 +1,56 @@
1
+ import { Lock, resolveFd } from './types.js';
2
+ import * as native from '#native';
3
+ /**
4
+ * Create a {@link Locker} backed by native OS locks.
5
+ *
6
+ * Whole-file locks use `flock(2)` on Unix and `LockFileEx` on Windows.
7
+ * Range locks use `fcntl(2)` OFD locks on Linux, POSIX record locks on
8
+ * macOS/BSD, and ranged `LockFileEx` on Windows.
9
+ *
10
+ * If `hooks` are provided they are called after lock acquisition and on
11
+ * release, allowing backends to track active locks for cleanup.
12
+ */
13
+ export const createLocker = (hooks) => ({
14
+ async lock(fd, type, range, options) {
15
+ const d = resolveFd(fd);
16
+ await native.lock(d, toNativeLock(type), range, options);
17
+ try {
18
+ await hooks?.register(d);
19
+ }
20
+ catch (err) {
21
+ try {
22
+ native.lockSync(d, native.Lock.Unlock, range);
23
+ }
24
+ catch { }
25
+ throw err;
26
+ }
27
+ },
28
+ async tryLock(fd, type, range) {
29
+ const d = resolveFd(fd);
30
+ const locked = await native.tryLock(d, toNativeLock(type), range);
31
+ if (!locked)
32
+ return false;
33
+ try {
34
+ await hooks?.register(d);
35
+ return true;
36
+ }
37
+ catch (err) {
38
+ try {
39
+ native.lockSync(d, native.Lock.Unlock, range);
40
+ }
41
+ catch { }
42
+ throw err;
43
+ }
44
+ },
45
+ async unlock(fd, range) {
46
+ const d = resolveFd(fd);
47
+ try {
48
+ native.lockSync(d, native.Lock.Unlock, range);
49
+ }
50
+ finally {
51
+ await hooks?.unregister(d);
52
+ }
53
+ },
54
+ });
55
+ const toNativeLock = (type) => (type === Lock.Exclusive ? native.Lock.Exclusive : native.Lock.Shared);
56
+ //# sourceMappingURL=locking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locking.js","sourceRoot":"","sources":["../../../lib/core/locking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAChH,OAAO,KAAK,MAAM,MAAM,SAAS,CAAA;AAajC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAiB,EAAU,EAAE,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,EAAkB,EAAE,IAAU,EAAE,KAAiB,EAAE,OAAqB;QACjF,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QACxD,IAAI,CAAC;YACH,MAAM,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC/C,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAkB,EAAE,IAAU,EAAE,KAAiB;QAC7D,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAA;QACjE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAA;QACzB,IAAI,CAAC;YACH,MAAM,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;YACxB,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC/C,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAkB,EAAE,KAAiB;QAChD,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,IAAI,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC/C,CAAC;gBAAS,CAAC;YACT,MAAM,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,YAAY,GAAG,CAAC,IAAU,EAAe,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import fs from 'node:fs';
2
+ import { type Fs, FileDescriptor } from './types.js';
3
+ import { type LockHooks } from './locking.js';
4
+ /** Node.js file handle type alias. */
5
+ export type NodeFileHandle = fs.promises.FileHandle;
6
+ /** Create a Node.js filesystem that opens files with appropriate flags for the lock type. */
7
+ export declare const createNodeFs: () => Fs<NodeFileHandle>;
8
+ /**
9
+ * Track active locks by file descriptor and ensure they are released on process exit.
10
+ */
11
+ export declare class NodeLockHooks implements LockHooks {
12
+ private _active;
13
+ register(fd: FileDescriptor): Promise<void>;
14
+ unregister(fd: FileDescriptor): Promise<void>;
15
+ private _listen;
16
+ private _unlisten;
17
+ private _onExit;
18
+ }
19
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../lib/core/node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,SAAS,CAAA;AAExB,OAAO,EAAE,KAAK,EAAE,EAAQ,cAAc,EAAa,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C,sCAAsC;AACtC,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAA;AAEnD,6FAA6F;AAC7F,eAAO,MAAM,YAAY,QAAO,EAAE,CAAC,cAAc,CAQhD,CAAA;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC7C,OAAO,CAAC,OAAO,CAA4B;IAErC,QAAQ,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,UAAU,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,OAAO,CASd;CACF"}
@@ -0,0 +1,61 @@
1
+ import { isMainThread, parentPort } from 'node:worker_threads';
2
+ import fs from 'node:fs';
3
+ import { Lock, resolveFd } from './types.js';
4
+ /** Create a Node.js filesystem that opens files with appropriate flags for the lock type. */
5
+ export const createNodeFs = () => {
6
+ return {
7
+ async open(file, type) {
8
+ const flags = type === Lock.Exclusive ? fs.constants.O_CREAT | fs.constants.O_RDWR : fs.constants.O_RDONLY;
9
+ const handle = await fs.promises.open(file, flags);
10
+ return handle;
11
+ },
12
+ };
13
+ };
14
+ /**
15
+ * Track active locks by file descriptor and ensure they are released on process exit.
16
+ */
17
+ export class NodeLockHooks {
18
+ _active = new Map();
19
+ async register(fd) {
20
+ if (this._active.size === 0)
21
+ this._listen();
22
+ const d = resolveFd(fd);
23
+ this._active.set(d, (this._active.get(d) ?? 0) + 1);
24
+ }
25
+ async unregister(fd) {
26
+ const d = resolveFd(fd);
27
+ const count = this._active.get(d);
28
+ if (count !== undefined) {
29
+ if (count <= 1)
30
+ this._active.delete(d);
31
+ else
32
+ this._active.set(d, count - 1);
33
+ }
34
+ if (this._active.size === 0)
35
+ this._unlisten();
36
+ }
37
+ _listen() {
38
+ if (isMainThread)
39
+ process.on('exit', this._onExit);
40
+ else
41
+ parentPort?.on('close', this._onExit);
42
+ }
43
+ _unlisten() {
44
+ if (isMainThread)
45
+ process.off('exit', this._onExit);
46
+ else
47
+ parentPort?.off('close', this._onExit);
48
+ }
49
+ _onExit = () => {
50
+ for (const fd of Array.from(this._active.keys()).reverse()) {
51
+ try {
52
+ fs.closeSync(fd);
53
+ }
54
+ catch {
55
+ // EBADF expected if already closed
56
+ }
57
+ }
58
+ this._active.clear();
59
+ };
60
+ }
61
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../lib/core/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,MAAM,SAAS,CAAA;AAExB,OAAO,EAAW,IAAI,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAA;AAMrE,6FAA6F;AAC7F,MAAM,CAAC,MAAM,YAAY,GAAG,GAAuB,EAAE;IACnD,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAU;YACjC,MAAM,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAA;YAC1G,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAClD,OAAO,MAAM,CAAA;QACf,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,OAAO,aAAa;IAChB,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE3C,KAAK,CAAC,QAAQ,CAAC,EAAkB;QAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,OAAO,EAAE,CAAA;QAC3C,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAkB;QACjC,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,KAAK,IAAI,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;;gBACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;QACrC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,SAAS,EAAE,CAAA;IAC/C,CAAC;IAEO,OAAO;QACb,IAAI,YAAY;YAAE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;;YAC7C,UAAU,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5C,CAAC;IAEO,SAAS;QACf,IAAI,YAAY;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;;YAC9C,UAAU,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC7C,CAAC;IAEO,OAAO,GAAG,GAAS,EAAE;QAC3B,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC;gBACH,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;YACrC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC,CAAA;CACF"}
@@ -0,0 +1,49 @@
1
+ /** Filesystem abstraction for opening lock files. */
2
+ export interface Fs<H extends FileHandle> {
3
+ /** Open (or create) the lock file and return a handle. */
4
+ open(file: string, type: Lock): Promise<H>;
5
+ }
6
+ /** Lock/unlock operations, separated from file opening for composability. */
7
+ export interface Locker {
8
+ /** Acquire a lock, polling until available or timeout is reached. */
9
+ lock: (fd: FileDescriptor, type: Lock, range?: LockRange, options?: PollOptions) => Promise<void>;
10
+ /** Try to acquire a lock without waiting. Return true if acquired. */
11
+ tryLock: (fd: FileDescriptor, type: Lock, range?: LockRange) => Promise<boolean>;
12
+ /** Release a previously acquired lock. */
13
+ unlock: (fd: FileDescriptor, range?: LockRange) => Promise<void>;
14
+ }
15
+ /** Lock mode: exclusive (write) or shared (read). */
16
+ export declare enum Lock {
17
+ Exclusive = 0,
18
+ Shared = 1
19
+ }
20
+ /** Options for polling lock acquisition. */
21
+ export interface PollOptions {
22
+ /** Polling interval in milliseconds. */
23
+ pollMs?: number;
24
+ /** Maximum wait time in milliseconds. */
25
+ timeout?: number;
26
+ /** Multiplier applied to pollMs after each failed attempt (e.g. 2 = exponential backoff). */
27
+ backoff?: number;
28
+ }
29
+ /** Byte range within a file to lock. Used for range-level locking. */
30
+ export interface LockRange {
31
+ /** Starting byte offset. */
32
+ offset: number;
33
+ /** Number of bytes to lock. */
34
+ length: number;
35
+ }
36
+ /** An open file handle with a descriptor and a close method. */
37
+ export interface FileHandle {
38
+ /** The numeric file descriptor. */
39
+ fd: number;
40
+ /** Close the file handle. */
41
+ close: () => Promise<void>;
42
+ }
43
+ /** File descriptor or file descriptor object. */
44
+ export type FileDescriptor = {
45
+ fd: number;
46
+ } | number;
47
+ /** @internal */
48
+ export declare const resolveFd: (fd: FileDescriptor) => number;
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/core/types.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,WAAW,EAAE,CAAC,CAAC,SAAS,UAAU;IACtC,0DAA0D;IAC1D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC3C;AAED,6EAA6E;AAC7E,MAAM,WAAW,MAAM;IACrB,qEAAqE;IACrE,IAAI,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACjG,sEAAsE;IACtE,OAAO,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAChF,0CAA0C;IAC1C,MAAM,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACjE;AAED,qDAAqD;AACrD,oBAAY,IAAI;IACd,SAAS,IAAA;IACT,MAAM,IAAA;CACP;AAED,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,sEAAsE;AACtE,MAAM,WAAW,SAAS;IACxB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,6BAA6B;IAC7B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,iDAAiD;AACjD,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAA;AAEpD,gBAAgB;AAChB,eAAO,MAAM,SAAS,GAAI,IAAI,cAAc,KAAG,MAA+C,CAAA"}
@@ -0,0 +1,9 @@
1
+ /** Lock mode: exclusive (write) or shared (read). */
2
+ export var Lock;
3
+ (function (Lock) {
4
+ Lock[Lock["Exclusive"] = 0] = "Exclusive";
5
+ Lock[Lock["Shared"] = 1] = "Shared";
6
+ })(Lock || (Lock = {}));
7
+ /** @internal */
8
+ export const resolveFd = (fd) => (typeof fd === 'number' ? fd : fd.fd);
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/core/types.ts"],"names":[],"mappings":"AAgBA,qDAAqD;AACrD,MAAM,CAAN,IAAY,IAGX;AAHD,WAAY,IAAI;IACd,yCAAS,CAAA;IACT,mCAAM,CAAA;AACR,CAAC,EAHW,IAAI,KAAJ,IAAI,QAGf;AA+BD,gBAAgB;AAChB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAkB,EAAU,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA"}
@@ -1,54 +1,63 @@
1
- import { type Backend, type FileHandle, type NodeFileHandle, FileGuard } from './backend/index.js';
2
- export * from './backend/index.js';
1
+ import { type NodeFileHandle, type LockRange, type PollOptions, type Lock, type FileHandle, type FileDescriptor, type Fs, type Locker, FileLockGuard, LockGuard } from './core/index.js';
2
+ export * from './core/index.js';
3
+ /** Options for specifying a custom locker and/or byte range. */
4
+ export interface LockingOptions {
5
+ /** Custom locker implementation. Uses the default native locker if omitted. */
6
+ locking?: Locker;
7
+ /** Byte range to lock. Locks the entire file if omitted. */
8
+ range?: LockRange;
9
+ }
3
10
  /**
4
- * Acquire an exclusive (write) lock on a file, polling until available.
5
- * Creates the file if it does not exist.
11
+ * Acquire a lock on an already-open file handle.
6
12
  *
7
13
  * @example
8
- * const guard = await exclusive('/tmp/my.lock')
9
- * try { /* critical section *\/ } finally { await guard.drop() }
14
+ * import fs from 'node:fs/promises'
15
+ * const handle = await fs.open('/tmp/my.lock', 'r+')
16
+ * await using guard = await lock(handle, Lock.Exclusive)
17
+ */
18
+ export declare const lock: <H extends FileHandle = NodeFileHandle>(handle: H, type: Lock, options?: LockingOptions & PollOptions) => Promise<LockGuard<H>>;
19
+ /**
20
+ * Try to acquire a lock on an already-open file handle without waiting.
10
21
  *
11
22
  * @example
12
- * await using guard = await exclusive('/tmp/my.lock', { timeout: 5000 })
23
+ * import fs from 'node:fs/promises'
24
+ * const handle = await fs.open('/tmp/my.lock', 'r+')
25
+ * const guard = await tryLock(handle, Lock.Exclusive)
26
+ * if (guard) { /* acquired *\/ }
13
27
  */
14
- export declare const exclusive: <H extends FileHandle = NodeFileHandle>(file: string, options?: {
15
- backend?: Backend<H>;
16
- pollMs?: number;
17
- timeout?: number;
18
- }) => Promise<FileGuard<H>>;
28
+ export declare const tryLock: <H extends FileDescriptor>(handle: H, type: Lock, options?: LockingOptions & PollOptions) => Promise<LockGuard<H> | undefined>;
19
29
  /**
20
- * Try to acquire an exclusive lock without waiting.
21
- * Return undefined if the lock is already held.
30
+ * Release a lock on a file descriptor or file handle.
22
31
  *
23
32
  * @example
24
- * const guard = await tryExclusive('/tmp/my.lock')
25
- * if (guard) { /* acquired *\/ }
33
+ * import fs from 'node:fs/promises'
34
+ * const handle = await fs.open('/tmp/my.lock', 'r+')
35
+ * await lock(handle, Lock.Exclusive)
36
+ * // ... critical section ...
37
+ * await unlock(handle)
26
38
  */
27
- export declare const tryExclusive: <H extends FileHandle = NodeFileHandle>(file: string, options?: {
28
- backend?: Backend<H>;
29
- }) => Promise<FileGuard<H> | undefined>;
39
+ export declare const unlock: <H extends FileDescriptor>(handle: H, options?: LockingOptions) => Promise<void>;
40
+ /** Options for open-and-lock functions that manage the file lifecycle. */
41
+ export interface OpenLockOptions<H extends FileHandle> extends LockingOptions {
42
+ /** Custom filesystem for opening files. Uses the default Node.js fs if omitted. */
43
+ fs?: Fs<H>;
44
+ }
30
45
  /**
31
- * Acquire a shared (read) lock on a file, polling until available.
32
- * Multiple shared locks may be held concurrently.
33
- * Creates the file if it does not exist.
46
+ * Open a file and acquire a lock, polling until available. Closes the file on failure.
47
+ *
48
+ * @example
49
+ * await using guard = await openLock('/tmp/my.lock', Lock.Exclusive)
34
50
  *
35
51
  * @example
36
- * await using guard = await shared('/tmp/my.lock')
52
+ * await using guard = await openLock('/tmp/my.lock', Lock.Shared, { timeout: 5000 })
37
53
  */
38
- export declare const shared: <H extends FileHandle = NodeFileHandle>(file: string, options?: {
39
- backend?: Backend<H>;
40
- pollMs?: number;
41
- timeout?: number;
42
- }) => Promise<FileGuard<H>>;
54
+ export declare const openLock: <H extends FileHandle = NodeFileHandle>(file: string, type: Lock, options?: OpenLockOptions<H> & PollOptions) => Promise<FileLockGuard<H>>;
43
55
  /**
44
- * Try to acquire a shared lock without waiting.
45
- * Return undefined if an exclusive lock is already held.
56
+ * Open a file and try to acquire a lock without waiting. Closes the file if not acquired.
46
57
  *
47
58
  * @example
48
- * const guard = await tryShared('/tmp/my.lock')
59
+ * const guard = await tryOpenLock('/tmp/my.lock', Lock.Exclusive)
49
60
  * if (guard) { /* acquired *\/ }
50
61
  */
51
- export declare const tryShared: <H extends FileHandle = NodeFileHandle>(file: string, options?: {
52
- backend?: Backend<H>;
53
- }) => Promise<FileGuard<H> | undefined>;
62
+ export declare const tryOpenLock: <H extends FileHandle = NodeFileHandle>(file: string, type: Lock, options?: OpenLockOptions<H>) => Promise<FileLockGuard<H> | undefined>;
54
63
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,SAAS,EAAkB,MAAM,oBAAoB,CAAA;AAClH,cAAc,oBAAoB,CAAA;AAElC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EACnE,MAAM,MAAM,EACZ,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KACpE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAA4C,CAAA;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EACtE,MAAM,MAAM,EACZ,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,KACjC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAA+C,CAAA;AAElF;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EAChE,MAAM,MAAM,EACZ,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KACpE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAyC,CAAA;AAEhE;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EACnE,MAAM,MAAM,EACZ,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,KACjC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAA4C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,EAAE,EACP,KAAK,MAAM,EACX,aAAa,EACb,SAAS,EAGV,MAAM,iBAAiB,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAE/B,gEAAgE;AAChE,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EAC9D,QAAQ,CAAC,EACT,MAAM,IAAI,EACV,UAAU,cAAc,GAAG,WAAW,KACrC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAItB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAAU,CAAC,SAAS,cAAc,EACpD,QAAQ,CAAC,EACT,MAAM,IAAI,EACV,UAAU,cAAc,GAAG,WAAW,KACrC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAKlC,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,GAAU,CAAC,SAAS,cAAc,EAAE,QAAQ,CAAC,EAAE,UAAU,cAAc,KAAG,OAAO,CAAC,IAAI,CAGxG,CAAA;AAED,0EAA0E;AAC1E,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,UAAU,CAAE,SAAQ,cAAc;IAC3E,mFAAmF;IACnF,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;CACX;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EAClE,MAAM,MAAM,EACZ,MAAM,IAAI,EACV,UAAU,eAAe,CAAC,CAAC,CAAC,GAAG,WAAW,KACzC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAS1B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAU,CAAC,SAAS,UAAU,GAAG,cAAc,EACrE,MAAM,MAAM,EACZ,MAAM,IAAI,EACV,UAAU,eAAe,CAAC,CAAC,CAAC,KAC3B,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAYtC,CAAA"}
package/dist/esm/index.js CHANGED
@@ -1,63 +1,82 @@
1
- import { FileGuard, defaultBackend } from './backend/index.js';
2
- export * from './backend/index.js';
1
+ import { FileLockGuard, LockGuard, defaultFs, defaultLocking, } from './core/index.js';
2
+ export * from './core/index.js';
3
3
  /**
4
- * Acquire an exclusive (write) lock on a file, polling until available.
5
- * Creates the file if it does not exist.
4
+ * Acquire a lock on an already-open file handle.
6
5
  *
7
6
  * @example
8
- * const guard = await exclusive('/tmp/my.lock')
9
- * try { /* critical section *\/ } finally { await guard.drop() }
10
- *
11
- * @example
12
- * await using guard = await exclusive('/tmp/my.lock', { timeout: 5000 })
7
+ * import fs from 'node:fs/promises'
8
+ * const handle = await fs.open('/tmp/my.lock', 'r+')
9
+ * await using guard = await lock(handle, Lock.Exclusive)
13
10
  */
14
- export const exclusive = async (file, options) => acquireLock(file, 'exclusive', options);
11
+ export const lock = async (handle, type, options) => {
12
+ const { locking = defaultLocking() } = options ?? {};
13
+ await locking.lock(handle, type, options?.range, options);
14
+ return new LockGuard(locking, handle, options?.range);
15
+ };
15
16
  /**
16
- * Try to acquire an exclusive lock without waiting.
17
- * Return undefined if the lock is already held.
17
+ * Try to acquire a lock on an already-open file handle without waiting.
18
18
  *
19
19
  * @example
20
- * const guard = await tryExclusive('/tmp/my.lock')
20
+ * import fs from 'node:fs/promises'
21
+ * const handle = await fs.open('/tmp/my.lock', 'r+')
22
+ * const guard = await tryLock(handle, Lock.Exclusive)
21
23
  * if (guard) { /* acquired *\/ }
22
24
  */
23
- export const tryExclusive = async (file, options) => tryAcquireLock(file, 'exclusive', options);
25
+ export const tryLock = async (handle, type, options) => {
26
+ const { locking = defaultLocking() } = options ?? {};
27
+ const result = await locking.tryLock(handle, type, options?.range);
28
+ if (result)
29
+ return new LockGuard(locking, handle, options?.range);
30
+ return undefined;
31
+ };
24
32
  /**
25
- * Acquire a shared (read) lock on a file, polling until available.
26
- * Multiple shared locks may be held concurrently.
27
- * Creates the file if it does not exist.
33
+ * Release a lock on a file descriptor or file handle.
28
34
  *
29
35
  * @example
30
- * await using guard = await shared('/tmp/my.lock')
36
+ * import fs from 'node:fs/promises'
37
+ * const handle = await fs.open('/tmp/my.lock', 'r+')
38
+ * await lock(handle, Lock.Exclusive)
39
+ * // ... critical section ...
40
+ * await unlock(handle)
31
41
  */
32
- export const shared = async (file, options) => acquireLock(file, 'shared', options);
42
+ export const unlock = async (handle, options) => {
43
+ const { locking = defaultLocking() } = options ?? {};
44
+ await locking.unlock(handle, options?.range);
45
+ };
33
46
  /**
34
- * Try to acquire a shared lock without waiting.
35
- * Return undefined if an exclusive lock is already held.
47
+ * Open a file and acquire a lock, polling until available. Closes the file on failure.
36
48
  *
37
49
  * @example
38
- * const guard = await tryShared('/tmp/my.lock')
39
- * if (guard) { /* acquired *\/ }
50
+ * await using guard = await openLock('/tmp/my.lock', Lock.Exclusive)
51
+ *
52
+ * @example
53
+ * await using guard = await openLock('/tmp/my.lock', Lock.Shared, { timeout: 5000 })
40
54
  */
41
- export const tryShared = async (file, options) => tryAcquireLock(file, 'shared', options);
42
- const acquireLock = async (file, mode, options) => {
43
- const { backend = defaultBackend() } = options ?? {};
44
- const handle = await backend.open(file);
55
+ export const openLock = async (file, type, options) => {
56
+ const { fs = defaultFs() } = options ?? {};
57
+ const handle = await fs.open(file, type);
45
58
  try {
46
- await backend.lock(handle, mode, options);
47
- return new FileGuard(backend, handle);
59
+ return new FileLockGuard(await lock(handle, type, options), handle);
48
60
  }
49
61
  catch (error) {
50
62
  await handle.close();
51
63
  throw error;
52
64
  }
53
65
  };
54
- const tryAcquireLock = async (file, mode, options) => {
55
- const { backend = defaultBackend() } = options ?? {};
56
- const handle = await backend.open(file);
66
+ /**
67
+ * Open a file and try to acquire a lock without waiting. Closes the file if not acquired.
68
+ *
69
+ * @example
70
+ * const guard = await tryOpenLock('/tmp/my.lock', Lock.Exclusive)
71
+ * if (guard) { /* acquired *\/ }
72
+ */
73
+ export const tryOpenLock = async (file, type, options) => {
74
+ const { fs = defaultFs() } = options ?? {};
75
+ const handle = await fs.open(file, type);
57
76
  try {
58
- const result = await backend.tryLock(handle, mode);
77
+ const result = await tryLock(handle, type, options);
59
78
  if (result)
60
- return new FileGuard(backend, handle);
79
+ return new FileLockGuard(result, handle);
61
80
  await handle.close();
62
81
  return undefined;
63
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsD,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAClH,cAAc,oBAAoB,CAAA;AAElC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,IAAY,EACZ,OAAqE,EAC9C,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,IAAY,EACZ,OAAkC,EACC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;AAElF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EACzB,IAAY,EACZ,OAAqE,EAC9C,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;AAEhE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,IAAY,EACZ,OAAkC,EACC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;AAE/E,MAAM,WAAW,GAAG,KAAK,EACvB,IAAY,EACZ,IAA4B,EAC5B,OAAqE,EAC9C,EAAE;IACzB,MAAM,EAAE,OAAO,GAAG,cAAc,EAA2B,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAC7E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QACzC,OAAO,IAAI,SAAS,CAAI,OAAO,EAAE,MAAM,CAAC,CAAA;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,KAAK,EAC1B,IAAY,EACZ,IAA4B,EAC5B,OAAkC,EACC,EAAE;IACrC,MAAM,EAAE,OAAO,GAAG,cAAc,EAA2B,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAC7E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAClD,IAAI,MAAM;YAAE,OAAO,IAAI,SAAS,CAAI,OAAO,EAAE,MAAM,CAAC,CAAA;QACpD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,OAAO,SAAS,CAAA;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"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"}