UNPKG

loccon

Version:

A simple local context storage and management tool with CLI and web interfaces. Store, search, and organize code snippets, notes, and development contexts with sharded JSON storage.

113 lines 4.07 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FileLock = void 0; const path = __importStar(require("path")); const fs = __importStar(require("fs-extra")); class FileLock { constructor(storagePath, lockTimeout = 5000) { this.acquired = false; this.lockPath = path.join(storagePath, '.lock'); this.lockTimeout = lockTimeout; } async acquire() { const startTime = Date.now(); while (Date.now() - startTime < this.lockTimeout) { try { // Try to create lock file exclusively await fs.writeFile(this.lockPath, process.pid.toString(), { flag: 'wx' }); this.acquired = true; return; } catch (error) { // Lock file exists, check if process is still running if (await this.isStale()) { await this.forceRelease(); continue; } // Wait a bit before retrying await new Promise(resolve => setTimeout(resolve, 100)); } } throw new Error(`Failed to acquire lock within ${this.lockTimeout}ms`); } async release() { if (this.acquired) { try { await fs.unlink(this.lockPath); this.acquired = false; } catch (error) { // Lock file might have been cleaned up already } } } async isStale() { try { const lockContent = await fs.readFile(this.lockPath, 'utf8'); const lockPid = parseInt(lockContent.trim()); // Check if the process is still running try { process.kill(lockPid, 0); // Signal 0 doesn't kill, just checks existence return false; // Process is still running } catch (error) { return true; // Process doesn't exist, lock is stale } } catch (error) { return true; // Can't read lock file, consider it stale } } async forceRelease() { try { await fs.unlink(this.lockPath); } catch (error) { // Ignore errors when force releasing } } static async cleanupStaleLocks(storagePath) { const lockPath = path.join(storagePath, '.lock'); if (await fs.pathExists(lockPath)) { const lock = new FileLock(storagePath); if (await lock.isStale()) { await lock.forceRelease(); } } } } exports.FileLock = FileLock; //# sourceMappingURL=filelock.js.map