@alchemy.run/node-utils 0.0.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/lib/adapter.d.ts +14 -0
- package/lib/adapter.d.ts.map +1 -0
- package/lib/adapter.js +65 -0
- package/lib/adapter.js.map +1 -0
- package/lib/exit-hook.d.ts +22 -0
- package/lib/exit-hook.d.ts.map +1 -0
- package/lib/exit-hook.js +86 -0
- package/lib/exit-hook.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +24 -0
- package/lib/index.js.map +1 -0
- package/lib/lockfile.d.ts +53 -0
- package/lib/lockfile.d.ts.map +1 -0
- package/lib/lockfile.js +287 -0
- package/lib/lockfile.js.map +1 -0
- package/lib/mtime-precision.d.ts +11 -0
- package/lib/mtime-precision.d.ts.map +1 -0
- package/lib/mtime-precision.js +40 -0
- package/lib/mtime-precision.js.map +1 -0
- package/lib/retry.d.ts +56 -0
- package/lib/retry.d.ts.map +1 -0
- package/lib/retry.js +199 -0
- package/lib/retry.js.map +1 -0
- package/package.json +27 -0
- package/src/adapter.ts +94 -0
- package/src/exit-hook.ts +96 -0
- package/src/index.ts +46 -0
- package/src/lockfile.ts +502 -0
- package/src/mtime-precision.ts +83 -0
- package/src/retry.ts +309 -0
package/lib/adapter.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type AnyFs = Record<string, any>;
|
|
2
|
+
type AsyncMethod = (...args: any[]) => void;
|
|
3
|
+
export declare function toPromise<T = any>(method: AsyncMethod): (...args: any[]) => Promise<T>;
|
|
4
|
+
export declare function toSync<T = any>(method: AsyncMethod): (...args: any[]) => T;
|
|
5
|
+
export interface SyncOptions {
|
|
6
|
+
fs?: AnyFs;
|
|
7
|
+
retries?: number | {
|
|
8
|
+
retries?: number;
|
|
9
|
+
};
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
export declare function toSyncOptions(options?: SyncOptions): SyncOptions;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEjC,KAAK,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;AA0B5C,wBAAgB,SAAS,CAAC,CAAC,GAAG,GAAG,EAC/B,MAAM,EAAE,WAAW,GAClB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAahC;AAED,wBAAgB,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAkB1E;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,CAoBhE"}
|
package/lib/adapter.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
function createSyncFs(fs) {
|
|
3
|
+
const methods = ["mkdir", "realpath", "stat", "rmdir", "utimes"];
|
|
4
|
+
const newFs = { ...fs };
|
|
5
|
+
methods.forEach((method) => {
|
|
6
|
+
newFs[method] = (...args) => {
|
|
7
|
+
const callback = args.pop();
|
|
8
|
+
let ret;
|
|
9
|
+
try {
|
|
10
|
+
ret = fs[`${method}Sync`](...args);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
return callback(err);
|
|
14
|
+
}
|
|
15
|
+
callback(null, ret);
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
return newFs;
|
|
19
|
+
}
|
|
20
|
+
// ----------------------------------------------------------
|
|
21
|
+
export function toPromise(method) {
|
|
22
|
+
return (...args) => new Promise((resolve, reject) => {
|
|
23
|
+
args.push((err, result) => {
|
|
24
|
+
if (err) {
|
|
25
|
+
reject(err);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
resolve(result);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
method(...args);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function toSync(method) {
|
|
35
|
+
return (...args) => {
|
|
36
|
+
let err;
|
|
37
|
+
let result;
|
|
38
|
+
args.push((_err, _result) => {
|
|
39
|
+
err = _err;
|
|
40
|
+
result = _result;
|
|
41
|
+
});
|
|
42
|
+
method(...args);
|
|
43
|
+
if (err) {
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function toSyncOptions(options) {
|
|
50
|
+
// Shallow clone options because we are going to mutate them
|
|
51
|
+
const next = { ...options };
|
|
52
|
+
// Transform fs to use the sync methods instead
|
|
53
|
+
next.fs = createSyncFs(next.fs || fs);
|
|
54
|
+
// Retries are not allowed because it requires the flow to be sync
|
|
55
|
+
if ((typeof next.retries === "number" && next.retries > 0) ||
|
|
56
|
+
(next.retries &&
|
|
57
|
+
typeof next.retries.retries === "number" &&
|
|
58
|
+
next.retries.retries > 0)) {
|
|
59
|
+
throw Object.assign(new Error("Cannot use retries with the sync api"), {
|
|
60
|
+
code: "ESYNC",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return next;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAMzB,SAAS,YAAY,CAAC,EAAS;IAC7B,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAC;IAC1E,MAAM,KAAK,GAAU,EAAE,GAAG,EAAE,EAAE,CAAC;IAE/B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACzB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAiB,CAAC;YAC3C,IAAI,GAAG,CAAC;YAER,IAAI,CAAC;gBACH,GAAG,GAAG,EAAE,CAAC,GAAG,MAAM,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACrC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,GAA4B,CAAC,CAAC;YAChD,CAAC;YAED,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,6DAA6D;AAE7D,MAAM,UAAU,SAAS,CACvB,MAAmB;IAEnB,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE,CACxB,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACjC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAiC,EAAE,MAAS,EAAE,EAAE;YACzD,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,MAAM,CAAU,MAAmB;IACjD,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE;QACxB,IAAI,GAA6C,CAAC;QAClD,IAAI,MAAqB,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAkC,EAAE,OAAU,EAAE,EAAE;YAC3D,GAAG,GAAG,IAAI,CAAC;YACX,MAAM,GAAG,OAAO,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;QAEhB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC;AAQD,MAAM,UAAU,aAAa,CAAC,OAAqB;IACjD,4DAA4D;IAC5D,MAAM,IAAI,GAAgB,EAAE,GAAG,OAAO,EAAE,CAAC;IAEzC,+CAA+C;IAC/C,IAAI,CAAC,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtC,kEAAkE;IAClE,IACE,CAAC,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACtD,CAAC,IAAI,CAAC,OAAO;YACX,OAAQ,IAAI,CAAC,OAAgC,CAAC,OAAO,KAAK,QAAQ;YAChE,IAAI,CAAC,OAAgC,CAAC,OAAkB,GAAG,CAAC,CAAC,EACjE,CAAC;QACD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,EAAE;YACrE,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight replacement for the `exit-hook` npm package.
|
|
3
|
+
*
|
|
4
|
+
* The third-party `exit-hook` registers process listeners (`exit`, `SIGINT`,
|
|
5
|
+
* `SIGTERM`, and `message`) that are never removed — even after every
|
|
6
|
+
* callback has been unregistered. Those dangling listeners are harmless in
|
|
7
|
+
* long-running processes, but in short-lived child processes (e.g. those
|
|
8
|
+
* spawned by `node --test`) they can prevent clean exit by holding refs on
|
|
9
|
+
* handles such as the IPC channel.
|
|
10
|
+
*
|
|
11
|
+
* This module tracks the number of active registrations and removes **all**
|
|
12
|
+
* process listeners once the last registration is unregistered, so they
|
|
13
|
+
* cannot keep the event loop alive after dispose.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Register a callback to run when the process exits. Returns a function
|
|
17
|
+
* that unregisters the callback. When the last callback is unregistered,
|
|
18
|
+
* all underlying process listeners are removed so they cannot keep the
|
|
19
|
+
* event loop alive.
|
|
20
|
+
*/
|
|
21
|
+
export declare function exitHook(callback: () => void): () => void;
|
|
22
|
+
//# sourceMappingURL=exit-hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-hook.d.ts","sourceRoot":"","sources":["../src/exit-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+DH;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAazD"}
|
package/lib/exit-hook.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight replacement for the `exit-hook` npm package.
|
|
3
|
+
*
|
|
4
|
+
* The third-party `exit-hook` registers process listeners (`exit`, `SIGINT`,
|
|
5
|
+
* `SIGTERM`, and `message`) that are never removed — even after every
|
|
6
|
+
* callback has been unregistered. Those dangling listeners are harmless in
|
|
7
|
+
* long-running processes, but in short-lived child processes (e.g. those
|
|
8
|
+
* spawned by `node --test`) they can prevent clean exit by holding refs on
|
|
9
|
+
* handles such as the IPC channel.
|
|
10
|
+
*
|
|
11
|
+
* This module tracks the number of active registrations and removes **all**
|
|
12
|
+
* process listeners once the last registration is unregistered, so they
|
|
13
|
+
* cannot keep the event loop alive after dispose.
|
|
14
|
+
*/
|
|
15
|
+
const callbacks = new Set();
|
|
16
|
+
let registered = false;
|
|
17
|
+
let called = false;
|
|
18
|
+
function runCallbacks() {
|
|
19
|
+
if (called) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
called = true;
|
|
23
|
+
for (const callback of callbacks) {
|
|
24
|
+
callback();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function onExit() {
|
|
28
|
+
runCallbacks();
|
|
29
|
+
}
|
|
30
|
+
function onSignalInt() {
|
|
31
|
+
runCallbacks();
|
|
32
|
+
// eslint-disable-next-line unicorn/no-process-exit -- intentional: replicate default SIGINT behavior
|
|
33
|
+
process.exit(128 + 2);
|
|
34
|
+
}
|
|
35
|
+
function onSignalTerm() {
|
|
36
|
+
runCallbacks();
|
|
37
|
+
// eslint-disable-next-line unicorn/no-process-exit -- intentional: replicate default SIGTERM behavior
|
|
38
|
+
process.exit(128 + 15);
|
|
39
|
+
}
|
|
40
|
+
function onMessage(message) {
|
|
41
|
+
if (message === "shutdown") {
|
|
42
|
+
runCallbacks();
|
|
43
|
+
// eslint-disable-next-line unicorn/no-process-exit -- intentional: PM2 graceful shutdown
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function addListeners() {
|
|
48
|
+
registered = true;
|
|
49
|
+
called = false;
|
|
50
|
+
process.on("exit", onExit);
|
|
51
|
+
process.on("SIGINT", onSignalInt);
|
|
52
|
+
process.on("SIGTERM", onSignalTerm);
|
|
53
|
+
// Only listen for IPC "shutdown" messages (PM2 support) when the process
|
|
54
|
+
// actually has an IPC channel. Even without this guard the listener is
|
|
55
|
+
// harmless when there is no channel, but being explicit avoids any
|
|
56
|
+
// accidental ref of a future channel.
|
|
57
|
+
if (process.send !== undefined) {
|
|
58
|
+
process.on("message", onMessage);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function removeListeners() {
|
|
62
|
+
registered = false;
|
|
63
|
+
process.removeListener("exit", onExit);
|
|
64
|
+
process.removeListener("SIGINT", onSignalInt);
|
|
65
|
+
process.removeListener("SIGTERM", onSignalTerm);
|
|
66
|
+
process.removeListener("message", onMessage);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Register a callback to run when the process exits. Returns a function
|
|
70
|
+
* that unregisters the callback. When the last callback is unregistered,
|
|
71
|
+
* all underlying process listeners are removed so they cannot keep the
|
|
72
|
+
* event loop alive.
|
|
73
|
+
*/
|
|
74
|
+
export function exitHook(callback) {
|
|
75
|
+
callbacks.add(callback);
|
|
76
|
+
if (!registered) {
|
|
77
|
+
addListeners();
|
|
78
|
+
}
|
|
79
|
+
return () => {
|
|
80
|
+
callbacks.delete(callback);
|
|
81
|
+
if (callbacks.size === 0 && registered) {
|
|
82
|
+
removeListeners();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=exit-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-hook.js","sourceRoot":"","sources":["../src/exit-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AACxC,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,IAAI,MAAM,GAAG,KAAK,CAAC;AAEnB,SAAS,YAAY;IACnB,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IACD,MAAM,GAAG,IAAI,CAAC;IACd,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,MAAM;IACb,YAAY,EAAE,CAAC;AACjB,CAAC;AAED,SAAS,WAAW;IAClB,YAAY,EAAE,CAAC;IACf,qGAAqG;IACrG,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,YAAY;IACnB,YAAY,EAAE,CAAC;IACf,sGAAsG;IACtG,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,SAAS,CAAC,OAAgB;IACjC,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,YAAY,EAAE,CAAC;QACf,yFAAyF;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,YAAY;IACnB,UAAU,GAAG,IAAI,CAAC;IAClB,MAAM,GAAG,KAAK,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACpC,yEAAyE;IACzE,wEAAwE;IACxE,mEAAmE;IACnE,sCAAsC;IACtC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,UAAU,GAAG,KAAK,CAAC;IACnB,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC9C,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAChD,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAoB;IAC3C,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAExB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;IACjB,CAAC;IAED,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3B,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;YACvC,eAAe,EAAE,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CheckOptions, LockOptions, ReleaseFn, UnlockOptions } from "./lockfile.ts";
|
|
2
|
+
export type { CheckOptions, LockOptions, ReleaseFn, UnlockOptions };
|
|
3
|
+
export declare function lock(file: string, options?: LockOptions): Promise<() => Promise<void>>;
|
|
4
|
+
export declare function lockSync(file: string, options?: LockOptions): () => void;
|
|
5
|
+
export declare function unlock(file: string, options?: UnlockOptions): Promise<void>;
|
|
6
|
+
export declare function unlockSync(file: string, options?: UnlockOptions): void;
|
|
7
|
+
export declare function check(file: string, options?: CheckOptions): Promise<boolean>;
|
|
8
|
+
export declare function checkSync(file: string, options?: CheckOptions): boolean;
|
|
9
|
+
export default lock;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,aAAa,EACd,MAAM,eAAe,CAAC;AAGvB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AAEpE,wBAAsB,IAAI,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAI9B;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,IAAI,CAOxE;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAEtE;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAEvE;AAED,eAAe,IAAI,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { toPromise, toSync, toSyncOptions } from "./adapter.js";
|
|
2
|
+
import * as lockfile from "./lockfile.js";
|
|
3
|
+
export async function lock(file, options) {
|
|
4
|
+
const release = await toPromise(lockfile.lock)(file, options);
|
|
5
|
+
return toPromise(release);
|
|
6
|
+
}
|
|
7
|
+
export function lockSync(file, options) {
|
|
8
|
+
const release = toSync(lockfile.lock)(file, toSyncOptions(options));
|
|
9
|
+
return toSync(release);
|
|
10
|
+
}
|
|
11
|
+
export function unlock(file, options) {
|
|
12
|
+
return toPromise(lockfile.unlock)(file, options);
|
|
13
|
+
}
|
|
14
|
+
export function unlockSync(file, options) {
|
|
15
|
+
return toSync(lockfile.unlock)(file, toSyncOptions(options));
|
|
16
|
+
}
|
|
17
|
+
export function check(file, options) {
|
|
18
|
+
return toPromise(lockfile.check)(file, options);
|
|
19
|
+
}
|
|
20
|
+
export function checkSync(file, options) {
|
|
21
|
+
return toSync(lockfile.check)(file, toSyncOptions(options));
|
|
22
|
+
}
|
|
23
|
+
export default lock;
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAOhE,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAI1C,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,IAAY,EACZ,OAAqB;IAErB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAY,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEzE,OAAO,SAAS,CAAO,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAqB;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAY,QAAQ,CAAC,IAAI,CAAC,CAC9C,IAAI,EACJ,aAAa,CAAC,OAAO,CAAC,CACvB,CAAC;IAEF,OAAO,MAAM,CAAO,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,OAAuB;IAC1D,OAAO,SAAS,CAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,OAAuB;IAC9D,OAAO,MAAM,CAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,OAAsB;IACxD,OAAO,SAAS,CAAU,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,OAAsB;IAC5D,OAAO,MAAM,CAAU,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { MtimePrecision } from "./mtime-precision.ts";
|
|
2
|
+
import * as retry from "./retry.ts";
|
|
3
|
+
type AnyFs = Record<string, any>;
|
|
4
|
+
export interface LockOptions {
|
|
5
|
+
stale?: number;
|
|
6
|
+
update?: number | null;
|
|
7
|
+
realpath?: boolean;
|
|
8
|
+
retries?: number | retry.OperationOptions;
|
|
9
|
+
fs?: AnyFs;
|
|
10
|
+
onCompromised?: (err: Error) => void;
|
|
11
|
+
lockfilePath?: string;
|
|
12
|
+
}
|
|
13
|
+
interface ResolvedLockOptions {
|
|
14
|
+
stale: number;
|
|
15
|
+
update: number;
|
|
16
|
+
realpath: boolean;
|
|
17
|
+
retries: retry.OperationOptions;
|
|
18
|
+
fs: AnyFs;
|
|
19
|
+
onCompromised: (err: Error) => void;
|
|
20
|
+
lockfilePath?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface UnlockOptions {
|
|
23
|
+
realpath?: boolean;
|
|
24
|
+
fs?: AnyFs;
|
|
25
|
+
lockfilePath?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface CheckOptions {
|
|
28
|
+
stale?: number;
|
|
29
|
+
realpath?: boolean;
|
|
30
|
+
fs?: AnyFs;
|
|
31
|
+
lockfilePath?: string;
|
|
32
|
+
}
|
|
33
|
+
interface InternalLock {
|
|
34
|
+
lockfilePath: string;
|
|
35
|
+
mtime: Date;
|
|
36
|
+
mtimePrecision: MtimePrecision;
|
|
37
|
+
options: ResolvedLockOptions;
|
|
38
|
+
lastUpdate: number;
|
|
39
|
+
updateDelay?: number | null;
|
|
40
|
+
updateTimeout?: ReturnType<typeof setTimeout> | null;
|
|
41
|
+
released?: boolean;
|
|
42
|
+
}
|
|
43
|
+
type ReleaseCallback = (err?: NodeJS.ErrnoException | null) => void;
|
|
44
|
+
export type ReleaseFn = (releasedCallback?: ReleaseCallback) => void;
|
|
45
|
+
type LockCallback = (err: NodeJS.ErrnoException | null, release?: ReleaseFn) => void;
|
|
46
|
+
type UnlockCallback = (err?: NodeJS.ErrnoException | null) => void;
|
|
47
|
+
type CheckCallback = (err: NodeJS.ErrnoException | null, locked?: boolean) => void;
|
|
48
|
+
export declare function lock(file: string, options: LockOptions | undefined, callback: LockCallback): void;
|
|
49
|
+
export declare function unlock(file: string, options: UnlockOptions | undefined, callback: UnlockCallback): void;
|
|
50
|
+
export declare function check(file: string, options: CheckOptions | undefined, callback: CheckCallback): void;
|
|
51
|
+
export declare function getLocks(): Record<string, InternalLock>;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=lockfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"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"}
|
package/lib/lockfile.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { exitHook } from "./exit-hook.js";
|
|
4
|
+
import * as mtimePrecision from "./mtime-precision.js";
|
|
5
|
+
import * as retry from "./retry.js";
|
|
6
|
+
const locks = {};
|
|
7
|
+
function getLockFile(file, options) {
|
|
8
|
+
return options.lockfilePath || `${file}.lock`;
|
|
9
|
+
}
|
|
10
|
+
function resolveCanonicalPath(file, options, callback) {
|
|
11
|
+
if (!options.realpath) {
|
|
12
|
+
return callback(null, path.resolve(file));
|
|
13
|
+
}
|
|
14
|
+
// Use realpath to resolve symlinks
|
|
15
|
+
// It also resolves relative paths
|
|
16
|
+
options.fs.realpath(file, callback);
|
|
17
|
+
}
|
|
18
|
+
function acquireLock(file, options, callback) {
|
|
19
|
+
const lockfilePath = getLockFile(file, options);
|
|
20
|
+
// Use mkdir to create the lockfile (atomic operation)
|
|
21
|
+
options.fs.mkdir(lockfilePath, (err) => {
|
|
22
|
+
if (!err) {
|
|
23
|
+
// At this point, we acquired the lock!
|
|
24
|
+
// Probe the mtime precision
|
|
25
|
+
return mtimePrecision.probe(lockfilePath, options.fs, (err, mtime, precision) => {
|
|
26
|
+
/* istanbul ignore if */
|
|
27
|
+
if (err) {
|
|
28
|
+
options.fs.rmdir(lockfilePath, () => { });
|
|
29
|
+
return callback(err);
|
|
30
|
+
}
|
|
31
|
+
callback(null, mtime, precision);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// If error is not EEXIST then some other error occurred while locking
|
|
35
|
+
if (err.code !== "EEXIST") {
|
|
36
|
+
return callback(err);
|
|
37
|
+
}
|
|
38
|
+
// Otherwise, check if lock is stale by analyzing the file mtime
|
|
39
|
+
if (options.stale <= 0) {
|
|
40
|
+
return callback(Object.assign(new Error("Lock file is already being held"), {
|
|
41
|
+
code: "ELOCKED",
|
|
42
|
+
file,
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
options.fs.stat(lockfilePath, (err, stat) => {
|
|
46
|
+
if (err) {
|
|
47
|
+
// Retry if the lockfile has been removed (meanwhile)
|
|
48
|
+
// Skip stale check to avoid recursiveness
|
|
49
|
+
if (err.code === "ENOENT") {
|
|
50
|
+
return acquireLock(file, { ...options, stale: 0 }, callback);
|
|
51
|
+
}
|
|
52
|
+
return callback(err);
|
|
53
|
+
}
|
|
54
|
+
if (!isLockStale(stat, options)) {
|
|
55
|
+
return callback(Object.assign(new Error("Lock file is already being held"), {
|
|
56
|
+
code: "ELOCKED",
|
|
57
|
+
file,
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
// If it's stale, remove it and try again!
|
|
61
|
+
// Skip stale check to avoid recursiveness
|
|
62
|
+
removeLock(file, options, (err) => {
|
|
63
|
+
if (err) {
|
|
64
|
+
return callback(err);
|
|
65
|
+
}
|
|
66
|
+
acquireLock(file, { ...options, stale: 0 }, callback);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function isLockStale(stat, options) {
|
|
72
|
+
return stat.mtime.getTime() < Date.now() - options.stale;
|
|
73
|
+
}
|
|
74
|
+
function removeLock(file, options, callback) {
|
|
75
|
+
options.fs.rmdir(getLockFile(file, options), (err) => {
|
|
76
|
+
if (err && err.code !== "ENOENT") {
|
|
77
|
+
return callback(err);
|
|
78
|
+
}
|
|
79
|
+
callback();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function updateLock(file, options) {
|
|
83
|
+
const lock = locks[file];
|
|
84
|
+
/* istanbul ignore if */
|
|
85
|
+
if (lock.updateTimeout) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
lock.updateDelay = lock.updateDelay || options.update;
|
|
89
|
+
lock.updateTimeout = setTimeout(() => {
|
|
90
|
+
lock.updateTimeout = null;
|
|
91
|
+
// Stat the file to check if mtime is still ours
|
|
92
|
+
// If it is, we can still recover from a system sleep or a busy event loop
|
|
93
|
+
options.fs.stat(lock.lockfilePath, (err, stat) => {
|
|
94
|
+
const isOverThreshold = lock.lastUpdate + options.stale < Date.now();
|
|
95
|
+
// If it failed to update the lockfile, keep trying unless
|
|
96
|
+
// the lockfile was deleted or we are over the threshold
|
|
97
|
+
if (err) {
|
|
98
|
+
if (err.code === "ENOENT" || isOverThreshold) {
|
|
99
|
+
return setLockAsCompromised(file, lock, Object.assign(err, { code: "ECOMPROMISED" }));
|
|
100
|
+
}
|
|
101
|
+
lock.updateDelay = 1000;
|
|
102
|
+
return updateLock(file, options);
|
|
103
|
+
}
|
|
104
|
+
const isMtimeOurs = lock.mtime.getTime() === stat.mtime.getTime();
|
|
105
|
+
if (!isMtimeOurs) {
|
|
106
|
+
return setLockAsCompromised(file, lock, Object.assign(new Error("Unable to update lock within the stale threshold"), { code: "ECOMPROMISED" }));
|
|
107
|
+
}
|
|
108
|
+
const mtime = mtimePrecision.getMtime(lock.mtimePrecision);
|
|
109
|
+
options.fs.utimes(lock.lockfilePath, mtime, mtime, (err) => {
|
|
110
|
+
const isOverThreshold = lock.lastUpdate + options.stale < Date.now();
|
|
111
|
+
if (lock.released) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// If it failed to update the lockfile, keep trying unless
|
|
115
|
+
// the lockfile was deleted or we are over the threshold
|
|
116
|
+
if (err) {
|
|
117
|
+
if (err.code === "ENOENT" || isOverThreshold) {
|
|
118
|
+
return setLockAsCompromised(file, lock, Object.assign(err, { code: "ECOMPROMISED" }));
|
|
119
|
+
}
|
|
120
|
+
lock.updateDelay = 1000;
|
|
121
|
+
return updateLock(file, options);
|
|
122
|
+
}
|
|
123
|
+
// All ok, keep updating..
|
|
124
|
+
lock.mtime = mtime;
|
|
125
|
+
lock.lastUpdate = Date.now();
|
|
126
|
+
lock.updateDelay = null;
|
|
127
|
+
updateLock(file, options);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}, lock.updateDelay);
|
|
131
|
+
// Unref the timer so that the nodejs process can exit freely
|
|
132
|
+
// This is safe because all acquired locks will be automatically released
|
|
133
|
+
// on process exit
|
|
134
|
+
// We first check that `lock.updateTimeout.unref` exists because some users
|
|
135
|
+
// may be using this module outside of NodeJS (e.g., in an electron app),
|
|
136
|
+
// and in those cases `setTimeout` returns an integer.
|
|
137
|
+
/* istanbul ignore else */
|
|
138
|
+
if (lock.updateTimeout &&
|
|
139
|
+
lock.updateTimeout.unref) {
|
|
140
|
+
lock.updateTimeout.unref();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function setLockAsCompromised(file, lock, err) {
|
|
144
|
+
lock.released = true;
|
|
145
|
+
// Cancel lock mtime update
|
|
146
|
+
/* istanbul ignore if */
|
|
147
|
+
if (lock.updateTimeout) {
|
|
148
|
+
clearTimeout(lock.updateTimeout);
|
|
149
|
+
}
|
|
150
|
+
if (locks[file] === lock) {
|
|
151
|
+
delete locks[file];
|
|
152
|
+
}
|
|
153
|
+
lock.options.onCompromised(err);
|
|
154
|
+
}
|
|
155
|
+
// ----------------------------------------------------------
|
|
156
|
+
export function lock(file, options, callback) {
|
|
157
|
+
/* istanbul ignore next */
|
|
158
|
+
const merged = {
|
|
159
|
+
stale: 10000,
|
|
160
|
+
update: null,
|
|
161
|
+
realpath: true,
|
|
162
|
+
retries: 0,
|
|
163
|
+
fs: fs,
|
|
164
|
+
onCompromised: ((err) => {
|
|
165
|
+
throw err;
|
|
166
|
+
}),
|
|
167
|
+
...options,
|
|
168
|
+
};
|
|
169
|
+
const retriesValue = merged.retries || 0;
|
|
170
|
+
const resolved = {
|
|
171
|
+
stale: Math.max(merged.stale || 0, 2000),
|
|
172
|
+
update: 0,
|
|
173
|
+
realpath: merged.realpath,
|
|
174
|
+
retries: typeof retriesValue === "number"
|
|
175
|
+
? { retries: retriesValue }
|
|
176
|
+
: retriesValue,
|
|
177
|
+
fs: merged.fs,
|
|
178
|
+
onCompromised: merged.onCompromised,
|
|
179
|
+
lockfilePath: merged.lockfilePath,
|
|
180
|
+
};
|
|
181
|
+
const updateRaw = merged.update == null ? resolved.stale / 2 : merged.update || 0;
|
|
182
|
+
resolved.update = Math.max(Math.min(updateRaw, resolved.stale / 2), 1000);
|
|
183
|
+
// Resolve to a canonical file path
|
|
184
|
+
resolveCanonicalPath(file, resolved, (err, file) => {
|
|
185
|
+
if (err) {
|
|
186
|
+
return callback(err);
|
|
187
|
+
}
|
|
188
|
+
// Attempt to acquire the lock
|
|
189
|
+
const operation = retry.operation(resolved.retries);
|
|
190
|
+
operation.attempt(() => {
|
|
191
|
+
acquireLock(file, resolved, (err, mtime, precision) => {
|
|
192
|
+
if (operation.retry(err)) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (err) {
|
|
196
|
+
return callback(operation.mainError());
|
|
197
|
+
}
|
|
198
|
+
// We now own the lock
|
|
199
|
+
const internalLock = (locks[file] = {
|
|
200
|
+
lockfilePath: getLockFile(file, resolved),
|
|
201
|
+
mtime: mtime,
|
|
202
|
+
mtimePrecision: precision,
|
|
203
|
+
options: resolved,
|
|
204
|
+
lastUpdate: Date.now(),
|
|
205
|
+
});
|
|
206
|
+
// We must keep the lock fresh to avoid staleness
|
|
207
|
+
updateLock(file, resolved);
|
|
208
|
+
callback(null, (releasedCallback) => {
|
|
209
|
+
if (internalLock.released) {
|
|
210
|
+
return (releasedCallback &&
|
|
211
|
+
releasedCallback(Object.assign(new Error("Lock is already released"), {
|
|
212
|
+
code: "ERELEASED",
|
|
213
|
+
})));
|
|
214
|
+
}
|
|
215
|
+
// Not necessary to use realpath twice when unlocking
|
|
216
|
+
unlock(file, { ...resolved, realpath: false }, releasedCallback || (() => { }));
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
export function unlock(file, options, callback) {
|
|
223
|
+
const resolved = {
|
|
224
|
+
fs: fs,
|
|
225
|
+
realpath: true,
|
|
226
|
+
...options,
|
|
227
|
+
};
|
|
228
|
+
// Resolve to a canonical file path
|
|
229
|
+
resolveCanonicalPath(file, resolved, (err, file) => {
|
|
230
|
+
if (err) {
|
|
231
|
+
return callback(err);
|
|
232
|
+
}
|
|
233
|
+
const lock = locks[file];
|
|
234
|
+
if (!lock) {
|
|
235
|
+
return callback(Object.assign(new Error("Lock is not acquired/owned by you"), {
|
|
236
|
+
code: "ENOTACQUIRED",
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
if (lock.updateTimeout) {
|
|
240
|
+
clearTimeout(lock.updateTimeout);
|
|
241
|
+
}
|
|
242
|
+
lock.released = true;
|
|
243
|
+
delete locks[file];
|
|
244
|
+
removeLock(file, resolved, callback);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
export function check(file, options, callback) {
|
|
248
|
+
const resolved = {
|
|
249
|
+
stale: 10000,
|
|
250
|
+
realpath: true,
|
|
251
|
+
fs: fs,
|
|
252
|
+
...options,
|
|
253
|
+
};
|
|
254
|
+
resolved.stale = Math.max(resolved.stale || 0, 2000);
|
|
255
|
+
// Resolve to a canonical file path
|
|
256
|
+
resolveCanonicalPath(file, resolved, (err, file) => {
|
|
257
|
+
if (err) {
|
|
258
|
+
return callback(err);
|
|
259
|
+
}
|
|
260
|
+
// Check if lockfile exists
|
|
261
|
+
resolved.fs.stat(getLockFile(file, resolved), (err, stat) => {
|
|
262
|
+
if (err) {
|
|
263
|
+
// If does not exist, file is not locked. Otherwise, callback with error
|
|
264
|
+
return err.code === "ENOENT" ? callback(null, false) : callback(err);
|
|
265
|
+
}
|
|
266
|
+
// Otherwise, check if lock is stale by analyzing the file mtime
|
|
267
|
+
return callback(null, !isLockStale(stat, resolved));
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
export function getLocks() {
|
|
272
|
+
return locks;
|
|
273
|
+
}
|
|
274
|
+
// Remove acquired locks on exit
|
|
275
|
+
/* istanbul ignore next */
|
|
276
|
+
exitHook(() => {
|
|
277
|
+
for (const file in locks) {
|
|
278
|
+
const options = locks[file].options;
|
|
279
|
+
try {
|
|
280
|
+
options.fs.rmdirSync(getLockFile(file, options));
|
|
281
|
+
}
|
|
282
|
+
catch (e) {
|
|
283
|
+
/* Empty */
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
//# sourceMappingURL=lockfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Stats } from "node:fs";
|
|
2
|
+
export type MtimePrecision = "s" | "ms";
|
|
3
|
+
export interface MtimePrecisionFs {
|
|
4
|
+
stat(path: string, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
|
|
5
|
+
utimes(path: string, atime: Date, mtime: Date, callback: (err: NodeJS.ErrnoException | null) => void): void;
|
|
6
|
+
}
|
|
7
|
+
type ProbeCallback = (err: NodeJS.ErrnoException | null, mtime?: Date, precision?: MtimePrecision) => void;
|
|
8
|
+
export declare function probe(file: string, fs: MtimePrecisionFs, callback: ProbeCallback): void;
|
|
9
|
+
export declare function getMtime(precision: MtimePrecision): Date;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=mtime-precision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mtime-precision.d.ts","sourceRoot":"","sources":["../src/mtime-precision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC;AAExC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAClE,IAAI,CAAC;IACR,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,KAAK,IAAI,GACpD,IAAI,CAAC;CACT;AAED,KAAK,aAAa,GAAG,CACnB,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EACjC,KAAK,CAAC,EAAE,IAAI,EACZ,SAAS,CAAC,EAAE,cAAc,KACvB,IAAI,CAAC;AAQV,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,gBAAgB,EACpB,QAAQ,EAAE,aAAa,GACtB,IAAI,CAuCN;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAQxD"}
|