@dxos/lock-file 0.8.4-main.e098934 → 0.8.4-main.e8ec1fe

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.
@@ -3,33 +3,98 @@ import { createRequire } from 'node:module';const require = createRequire(import
3
3
  // src/lock-file.ts
4
4
  import { existsSync } from "node:fs";
5
5
  import { constants, open } from "node:fs/promises";
6
- import { flock } from "fs-ext";
6
+
7
+ // src/sys.ts
8
+ import { platform } from "node:os";
9
+ var LOCK_SH = 1;
10
+ var LOCK_EX = 2;
11
+ var LOCK_NB = 4;
12
+ var LOCK_UN = 8;
13
+ var LockfileSys = class {
14
+ _init = null;
15
+ _koffi = null;
16
+ _libc = null;
17
+ _flockNative = null;
18
+ async init() {
19
+ await (this._init ??= this._runInit());
20
+ }
21
+ async _runInit() {
22
+ this._koffi = await import("koffi");
23
+ switch (platform()) {
24
+ case "darwin":
25
+ this._libc = this._koffi.load("libc.dylib");
26
+ break;
27
+ case "linux":
28
+ this._libc = this._koffi.load("libc.so.6");
29
+ break;
30
+ default:
31
+ throw new Error(`Unsupported platform: ${platform()}`);
32
+ }
33
+ this._flockNative = this._libc.func("flock", "int", [
34
+ "int",
35
+ "int"
36
+ ]);
37
+ }
38
+ flock(fd, operation) {
39
+ if (!this._flockNative) {
40
+ throw new Error("flock not initialized");
41
+ }
42
+ let op = 0;
43
+ switch (operation) {
44
+ case "ex":
45
+ op = LOCK_EX;
46
+ break;
47
+ case "exnb":
48
+ op = LOCK_EX | LOCK_NB;
49
+ break;
50
+ case "sh":
51
+ op = LOCK_SH;
52
+ break;
53
+ case "shnb":
54
+ op = LOCK_SH | LOCK_NB;
55
+ break;
56
+ case "un":
57
+ op = LOCK_UN;
58
+ break;
59
+ default:
60
+ throw new Error(`Invalid flock operation: ${operation}`);
61
+ }
62
+ const result = this._flockNative(fd, op);
63
+ if (result !== 0) {
64
+ const errno = this._koffi.errno();
65
+ const errorMessages = {
66
+ 11: "Resource temporarily unavailable (EAGAIN/EWOULDBLOCK)",
67
+ 13: "Permission denied (EACCES)",
68
+ 22: "Invalid argument (EINVAL)",
69
+ 9: "Bad file descriptor (EBADF)",
70
+ 35: "Resource temporarily unavailable (EAGAIN on macOS)"
71
+ };
72
+ const errorMessage = errorMessages[errno] || `Unknown error (errno: ${errno})`;
73
+ throw new Error(`flock failed: ${errorMessage}`);
74
+ }
75
+ }
76
+ };
77
+
78
+ // src/lock-file.ts
79
+ var sys = new LockfileSys();
7
80
  var LockFile = class _LockFile {
8
81
  static async acquire(filename) {
9
- const handle = await open(filename, constants.O_CREAT);
10
- await new Promise((resolve, reject) => {
11
- flock(handle.fd, "exnb", async (err) => {
12
- if (err) {
13
- reject(err);
14
- await handle.close();
15
- return;
16
- }
17
- resolve();
18
- });
19
- });
20
- return handle;
82
+ await sys.init();
83
+ const handle = await open(filename, constants.O_CREAT | constants.O_RDWR);
84
+ try {
85
+ sys.flock(handle.fd, "exnb");
86
+ return handle;
87
+ } catch (err) {
88
+ await handle.close();
89
+ throw err;
90
+ }
21
91
  }
22
92
  static async release(handle) {
23
- await new Promise((resolve, reject) => {
24
- flock(handle.fd, "un", (err) => {
25
- if (err) {
26
- reject(err);
27
- return;
28
- }
29
- resolve();
30
- });
31
- });
32
- await handle.close();
93
+ try {
94
+ sys.flock(handle.fd, "un");
95
+ } finally {
96
+ await handle.close();
97
+ }
33
98
  }
34
99
  static async isLocked(filename) {
35
100
  if (!existsSync(filename)) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/lock-file.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { existsSync } from 'node:fs';\nimport { type FileHandle, constants, open } from 'node:fs/promises';\n\nimport { flock } from 'fs-ext';\n\nexport class LockFile {\n static async acquire(filename: string): Promise<FileHandle> {\n const handle = await open(filename, constants.O_CREAT);\n await new Promise<void>((resolve, reject) => {\n flock(handle.fd, 'exnb', async (err) => {\n if (err) {\n reject(err);\n await handle.close();\n return;\n }\n resolve();\n });\n });\n return handle;\n }\n\n static async release(handle: FileHandle): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n flock(handle.fd, 'un', (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n });\n await handle.close();\n }\n\n static async isLocked(filename: string): Promise<boolean> {\n if (!existsSync(filename)) {\n return false;\n }\n try {\n const handle = await LockFile.acquire(filename);\n await LockFile.release(handle);\n\n return false;\n } catch (e) {\n return true;\n }\n }\n}\n"],
5
- "mappings": ";;;AAIA,SAASA,kBAAkB;AAC3B,SAA0BC,WAAWC,YAAY;AAEjD,SAASC,aAAa;AAEf,IAAMC,WAAN,MAAMA,UAAAA;EACX,aAAaC,QAAQC,UAAuC;AAC1D,UAAMC,SAAS,MAAMC,KAAKF,UAAUG,UAAUC,OAAO;AACrD,UAAM,IAAIC,QAAc,CAACC,SAASC,WAAAA;AAChCC,YAAMP,OAAOQ,IAAI,QAAQ,OAAOC,QAAAA;AAC9B,YAAIA,KAAK;AACPH,iBAAOG,GAAAA;AACP,gBAAMT,OAAOU,MAAK;AAClB;QACF;AACAL,gBAAAA;MACF,CAAA;IACF,CAAA;AACA,WAAOL;EACT;EAEA,aAAaW,QAAQX,QAAmC;AACtD,UAAM,IAAII,QAAc,CAACC,SAASC,WAAAA;AAChCC,YAAMP,OAAOQ,IAAI,MAAM,CAACC,QAAAA;AACtB,YAAIA,KAAK;AACPH,iBAAOG,GAAAA;AACP;QACF;AACAJ,gBAAAA;MACF,CAAA;IACF,CAAA;AACA,UAAML,OAAOU,MAAK;EACpB;EAEA,aAAaE,SAASb,UAAoC;AACxD,QAAI,CAACc,WAAWd,QAAAA,GAAW;AACzB,aAAO;IACT;AACA,QAAI;AACF,YAAMC,SAAS,MAAMH,UAASC,QAAQC,QAAAA;AACtC,YAAMF,UAASc,QAAQX,MAAAA;AAEvB,aAAO;IACT,SAASc,GAAG;AACV,aAAO;IACT;EACF;AACF;",
6
- "names": ["existsSync", "constants", "open", "flock", "LockFile", "acquire", "filename", "handle", "open", "constants", "O_CREAT", "Promise", "resolve", "reject", "flock", "fd", "err", "close", "release", "isLocked", "existsSync", "e"]
3
+ "sources": ["../../../src/lock-file.ts", "../../../src/sys.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { existsSync } from 'node:fs';\nimport { type FileHandle, constants, open } from 'node:fs/promises';\n\nimport { LockfileSys } from './sys';\n\nconst sys = new LockfileSys();\n\nexport class LockFile {\n static async acquire(filename: string): Promise<FileHandle> {\n await sys.init();\n\n const handle = await open(filename, constants.O_CREAT | constants.O_RDWR);\n\n try {\n // Try to acquire exclusive non-blocking lock\n sys.flock(handle.fd, 'exnb');\n return handle;\n } catch (err) {\n // Close the file handle if we can't acquire the lock\n await handle.close();\n throw err;\n }\n }\n\n static async release(handle: FileHandle): Promise<void> {\n try {\n // Release the lock\n sys.flock(handle.fd, 'un');\n } finally {\n await handle.close();\n }\n }\n\n static async isLocked(filename: string): Promise<boolean> {\n if (!existsSync(filename)) {\n return false;\n }\n try {\n const handle = await LockFile.acquire(filename);\n await LockFile.release(handle);\n return false;\n } catch (e) {\n return true;\n }\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { platform } from 'node:os';\n\nimport type * as koffi from 'koffi';\n\n// flock constants\nconst LOCK_SH = 1; // Shared lock\nconst LOCK_EX = 2; // Exclusive lock\nconst LOCK_NB = 4; // Non-blocking\nconst LOCK_UN = 8; // Unlock\n\nexport class LockfileSys {\n private _init: Promise<void> | null = null;\n\n private _koffi: typeof koffi | null = null;\n private _libc: koffi.IKoffiLib | null = null;\n private _flockNative: koffi.KoffiFunction | null = null;\n\n async init() {\n await (this._init ??= this._runInit());\n }\n\n private async _runInit() {\n this._koffi = await import('koffi');\n switch (platform()) {\n case 'darwin':\n this._libc = this._koffi.load('libc.dylib');\n break;\n case 'linux':\n this._libc = this._koffi.load('libc.so.6');\n break;\n default:\n throw new Error(`Unsupported platform: ${platform()}`);\n }\n this._flockNative = this._libc.func('flock', 'int', ['int', 'int']);\n }\n\n flock(fd: number, operation: string) {\n if (!this._flockNative) {\n throw new Error('flock not initialized');\n }\n let op = 0;\n\n switch (operation) {\n case 'ex':\n op = LOCK_EX;\n break;\n case 'exnb':\n op = LOCK_EX | LOCK_NB;\n break;\n case 'sh':\n op = LOCK_SH;\n break;\n case 'shnb':\n op = LOCK_SH | LOCK_NB;\n break;\n case 'un':\n op = LOCK_UN;\n break;\n default:\n throw new Error(`Invalid flock operation: ${operation}`);\n }\n\n const result = this._flockNative!(fd, op);\n\n if (result !== 0) {\n // Get the errno to provide a more meaningful error\n const errno = this._koffi!.errno();\n const errorMessages: { [key: number]: string } = {\n 11: 'Resource temporarily unavailable (EAGAIN/EWOULDBLOCK)',\n 13: 'Permission denied (EACCES)',\n 22: 'Invalid argument (EINVAL)',\n 9: 'Bad file descriptor (EBADF)',\n 35: 'Resource temporarily unavailable (EAGAIN on macOS)',\n };\n\n const errorMessage = errorMessages[errno] || `Unknown error (errno: ${errno})`;\n throw new Error(`flock failed: ${errorMessage}`);\n }\n }\n}\n"],
5
+ "mappings": ";;;AAIA,SAASA,kBAAkB;AAC3B,SAA0BC,WAAWC,YAAY;;;ACDjD,SAASC,gBAAgB;AAKzB,IAAMC,UAAU;AAChB,IAAMC,UAAU;AAChB,IAAMC,UAAU;AAChB,IAAMC,UAAU;AAET,IAAMC,cAAN,MAAMA;EACHC,QAA8B;EAE9BC,SAA8B;EAC9BC,QAAgC;EAChCC,eAA2C;EAEnD,MAAMC,OAAO;AACX,WAAO,KAAKJ,UAAU,KAAKK,SAAQ;EACrC;EAEA,MAAcA,WAAW;AACvB,SAAKJ,SAAS,MAAM,OAAO,OAAA;AAC3B,YAAQK,SAAAA,GAAAA;MACN,KAAK;AACH,aAAKJ,QAAQ,KAAKD,OAAOM,KAAK,YAAA;AAC9B;MACF,KAAK;AACH,aAAKL,QAAQ,KAAKD,OAAOM,KAAK,WAAA;AAC9B;MACF;AACE,cAAM,IAAIC,MAAM,yBAAyBF,SAAAA,CAAAA,EAAY;IACzD;AACA,SAAKH,eAAe,KAAKD,MAAMO,KAAK,SAAS,OAAO;MAAC;MAAO;KAAM;EACpE;EAEAC,MAAMC,IAAYC,WAAmB;AACnC,QAAI,CAAC,KAAKT,cAAc;AACtB,YAAM,IAAIK,MAAM,uBAAA;IAClB;AACA,QAAIK,KAAK;AAET,YAAQD,WAAAA;MACN,KAAK;AACHC,aAAKjB;AACL;MACF,KAAK;AACHiB,aAAKjB,UAAUC;AACf;MACF,KAAK;AACHgB,aAAKlB;AACL;MACF,KAAK;AACHkB,aAAKlB,UAAUE;AACf;MACF,KAAK;AACHgB,aAAKf;AACL;MACF;AACE,cAAM,IAAIU,MAAM,4BAA4BI,SAAAA,EAAW;IAC3D;AAEA,UAAME,SAAS,KAAKX,aAAcQ,IAAIE,EAAAA;AAEtC,QAAIC,WAAW,GAAG;AAEhB,YAAMC,QAAQ,KAAKd,OAAQc,MAAK;AAChC,YAAMC,gBAA2C;QAC/C,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,GAAG;QACH,IAAI;MACN;AAEA,YAAMC,eAAeD,cAAcD,KAAAA,KAAU,yBAAyBA,KAAAA;AACtE,YAAM,IAAIP,MAAM,iBAAiBS,YAAAA,EAAc;IACjD;EACF;AACF;;;AD1EA,IAAMC,MAAM,IAAIC,YAAAA;AAET,IAAMC,WAAN,MAAMA,UAAAA;EACX,aAAaC,QAAQC,UAAuC;AAC1D,UAAMJ,IAAIK,KAAI;AAEd,UAAMC,SAAS,MAAMC,KAAKH,UAAUI,UAAUC,UAAUD,UAAUE,MAAM;AAExE,QAAI;AAEFV,UAAIW,MAAML,OAAOM,IAAI,MAAA;AACrB,aAAON;IACT,SAASO,KAAK;AAEZ,YAAMP,OAAOQ,MAAK;AAClB,YAAMD;IACR;EACF;EAEA,aAAaE,QAAQT,QAAmC;AACtD,QAAI;AAEFN,UAAIW,MAAML,OAAOM,IAAI,IAAA;IACvB,UAAA;AACE,YAAMN,OAAOQ,MAAK;IACpB;EACF;EAEA,aAAaE,SAASZ,UAAoC;AACxD,QAAI,CAACa,WAAWb,QAAAA,GAAW;AACzB,aAAO;IACT;AACA,QAAI;AACF,YAAME,SAAS,MAAMJ,UAASC,QAAQC,QAAAA;AACtC,YAAMF,UAASa,QAAQT,MAAAA;AACvB,aAAO;IACT,SAASY,GAAG;AACV,aAAO;IACT;EACF;AACF;",
6
+ "names": ["existsSync", "constants", "open", "platform", "LOCK_SH", "LOCK_EX", "LOCK_NB", "LOCK_UN", "LockfileSys", "_init", "_koffi", "_libc", "_flockNative", "init", "_runInit", "platform", "load", "Error", "func", "flock", "fd", "operation", "op", "result", "errno", "errorMessages", "errorMessage", "sys", "LockfileSys", "LockFile", "acquire", "filename", "init", "handle", "open", "constants", "O_CREAT", "O_RDWR", "flock", "fd", "err", "close", "release", "isLocked", "existsSync", "e"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"src/lock-file.ts":{"bytes":4402,"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"fs-ext","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":457,"imports":[{"path":"src/lock-file.ts","kind":"import-statement","original":"./lock-file"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":2341},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"fs-ext","kind":"import-statement","external":true}],"exports":["LockFile"],"entryPoint":"src/index.ts","inputs":{"src/lock-file.ts":{"bytesInOutput":1030},"src/index.ts":{"bytesInOutput":0}},"bytes":1201}}}
1
+ {"inputs":{"src/sys.ts":{"bytes":7760,"imports":[{"path":"node:os","kind":"import-statement","external":true},{"path":"koffi","kind":"dynamic-import","external":true}],"format":"esm"},"src/lock-file.ts":{"bytes":4271,"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"src/sys.ts","kind":"import-statement","original":"./sys"}],"format":"esm"},"src/index.ts":{"bytes":457,"imports":[{"path":"src/lock-file.ts","kind":"import-statement","original":"./lock-file"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5854},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:fs/promises","kind":"import-statement","external":true},{"path":"node:os","kind":"import-statement","external":true},{"path":"koffi","kind":"dynamic-import","external":true}],"exports":["LockFile"],"entryPoint":"src/index.ts","inputs":{"src/lock-file.ts":{"bytesInOutput":831},"src/sys.ts":{"bytesInOutput":1806},"src/index.ts":{"bytesInOutput":0}},"bytes":2844}}}
@@ -1 +1 @@
1
- {"version":3,"file":"lock-file.d.ts","sourceRoot":"","sources":["../../../src/lock-file.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAIpE,qBAAa,QAAQ;WACN,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;WAe9C,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;WAa1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAa1D"}
1
+ {"version":3,"file":"lock-file.d.ts","sourceRoot":"","sources":["../../../src/lock-file.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAMpE,qBAAa,QAAQ;WACN,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;WAgB9C,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;WAS1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAY1D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=locker-subprocess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locker-subprocess.d.ts","sourceRoot":"","sources":["../../../src/locker-subprocess.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ export declare class LockfileSys {
2
+ private _init;
3
+ private _koffi;
4
+ private _libc;
5
+ private _flockNative;
6
+ init(): Promise<void>;
7
+ private _runInit;
8
+ flock(fd: number, operation: string): void;
9
+ }
10
+ //# sourceMappingURL=sys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sys.d.ts","sourceRoot":"","sources":["../../../src/sys.ts"],"names":[],"mappings":"AAcA,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAA8B;IAE3C,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,YAAY,CAAoC;IAElD,IAAI;YAII,QAAQ;IAetB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CA2CpC"}