@daeda/mcp-pro 0.1.25 → 0.1.26
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/dist/index.js +99 -51
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2329,77 +2329,105 @@ var buildCappedSelectSql = (sql, maxRows) => {
|
|
|
2329
2329
|
};
|
|
2330
2330
|
|
|
2331
2331
|
// src/layers/MasterLockLive.ts
|
|
2332
|
-
import { createRequire } from "module";
|
|
2333
2332
|
import path2 from "path";
|
|
2334
|
-
import { mkdir, open } from "fs/promises";
|
|
2335
2333
|
import { Effect as Effect24, Layer as Layer2, Ref, pipe as pipe13 } from "effect";
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2334
|
+
|
|
2335
|
+
// src/layers/MasterLockDependencies.ts
|
|
2336
|
+
import { createRequire } from "module";
|
|
2337
|
+
import { mkdir } from "fs/promises";
|
|
2338
|
+
var loadProperLockfileModule = () => {
|
|
2339
2339
|
const requireFromHere = createRequire(import.meta.url);
|
|
2340
|
-
return requireFromHere("
|
|
2340
|
+
return requireFromHere("proper-lockfile");
|
|
2341
2341
|
};
|
|
2342
|
-
var
|
|
2342
|
+
var resolveMasterLockDependencies = (config, defaults) => ({
|
|
2343
2343
|
ensurePortalsDir: config.ensurePortalsDir ?? (async (dirPath) => {
|
|
2344
2344
|
await mkdir(dirPath, { recursive: true });
|
|
2345
2345
|
}),
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2346
|
+
acquireLock: config.acquireLock ?? (async (dirPath, options2) => {
|
|
2347
|
+
const release = await loadProperLockfileModule().lock(dirPath, options2);
|
|
2348
|
+
return { release };
|
|
2349
|
+
}),
|
|
2349
2350
|
setInterval: config.setInterval ?? ((callback, ms) => setInterval(callback, ms)),
|
|
2350
2351
|
clearInterval: config.clearInterval ?? ((timer) => clearInterval(timer)),
|
|
2351
2352
|
log: config.log ?? ((message) => console.error(message)),
|
|
2352
|
-
promotionPollMs: config.promotionPollMs ??
|
|
2353
|
+
promotionPollMs: config.promotionPollMs ?? defaults.promotionPollMs
|
|
2353
2354
|
});
|
|
2355
|
+
|
|
2356
|
+
// src/layers/MasterLockLive.ts
|
|
2357
|
+
var PROMOTION_POLL_MS = 3e3;
|
|
2358
|
+
var LOCK_STALE_MS = 5e3;
|
|
2359
|
+
var LOCK_UPDATE_MS = 2500;
|
|
2360
|
+
var lockFilePath = () => path2.join(PORTALS_DIR(), "master.lock");
|
|
2354
2361
|
var logMessage = (runtime, message) => Effect24.sync(() => runtime.deps.log(message));
|
|
2355
2362
|
var isLockConflictError = (error) => {
|
|
2356
2363
|
const code = error?.code;
|
|
2357
|
-
return code === "
|
|
2364
|
+
return code === "ELOCKED";
|
|
2358
2365
|
};
|
|
2359
2366
|
var ensurePortalsDir = (runtime) => Effect24.tryPromise({
|
|
2360
2367
|
try: () => runtime.deps.ensurePortalsDir(PORTALS_DIR()),
|
|
2361
2368
|
catch: (cause) => new Error(`Failed to create portals directory: ${String(cause)}`)
|
|
2362
2369
|
});
|
|
2363
|
-
var
|
|
2370
|
+
var releaseLease = (runtime, lease) => Effect24.tryPromise({
|
|
2364
2371
|
try: async () => {
|
|
2365
|
-
|
|
2366
|
-
await runtime.deps.unlock(handle.fd);
|
|
2367
|
-
} catch {
|
|
2368
|
-
}
|
|
2369
|
-
try {
|
|
2370
|
-
await handle.close();
|
|
2371
|
-
} catch {
|
|
2372
|
-
}
|
|
2372
|
+
await lease.release();
|
|
2373
2373
|
},
|
|
2374
|
-
catch: (cause) => new Error(`Failed to
|
|
2374
|
+
catch: (cause) => new Error(`Failed to release master lock lease: ${String(cause)}`)
|
|
2375
|
+
});
|
|
2376
|
+
var acquireLockOptions = (runtime) => ({
|
|
2377
|
+
lockfilePath: lockFilePath(),
|
|
2378
|
+
retries: 0,
|
|
2379
|
+
stale: LOCK_STALE_MS,
|
|
2380
|
+
update: LOCK_UPDATE_MS,
|
|
2381
|
+
realpath: true,
|
|
2382
|
+
onCompromised: (error) => {
|
|
2383
|
+
Effect24.runFork(
|
|
2384
|
+
pipe13(
|
|
2385
|
+
handleCompromisedLease(runtime, error),
|
|
2386
|
+
Effect24.catchAll(() => Effect24.void)
|
|
2387
|
+
)
|
|
2388
|
+
);
|
|
2389
|
+
}
|
|
2375
2390
|
});
|
|
2391
|
+
var handleCompromisedLease = (runtime, error) => pipe13(
|
|
2392
|
+
Ref.get(runtime.releasedRef),
|
|
2393
|
+
Effect24.flatMap((released) => {
|
|
2394
|
+
if (released) return Effect24.void;
|
|
2395
|
+
return pipe13(
|
|
2396
|
+
Ref.getAndSet(runtime.lockLeaseRef, null),
|
|
2397
|
+
Effect24.flatMap((lease) => {
|
|
2398
|
+
if (lease === null) return Effect24.void;
|
|
2399
|
+
return pipe13(
|
|
2400
|
+
logMessage(
|
|
2401
|
+
runtime,
|
|
2402
|
+
`[master-lock] master lease compromised: ${error.message}`
|
|
2403
|
+
),
|
|
2404
|
+
Effect24.flatMap(() => Ref.set(runtime.connectionTypeRef, "READ_ONLY")),
|
|
2405
|
+
Effect24.flatMap(() => startPromotionPolling(runtime))
|
|
2406
|
+
);
|
|
2407
|
+
})
|
|
2408
|
+
);
|
|
2409
|
+
})
|
|
2410
|
+
);
|
|
2376
2411
|
var tryAcquireMasterLock = (runtime) => pipe13(
|
|
2377
|
-
Ref.get(runtime.
|
|
2378
|
-
Effect24.flatMap((
|
|
2379
|
-
if (
|
|
2412
|
+
Ref.get(runtime.lockLeaseRef),
|
|
2413
|
+
Effect24.flatMap((existingLease) => {
|
|
2414
|
+
if (existingLease !== null) {
|
|
2380
2415
|
return Ref.get(runtime.connectionTypeRef);
|
|
2381
2416
|
}
|
|
2382
2417
|
return pipe13(
|
|
2383
2418
|
ensurePortalsDir(runtime),
|
|
2384
2419
|
Effect24.flatMap(
|
|
2385
2420
|
() => Effect24.tryPromise({
|
|
2386
|
-
try: () => runtime.deps.openLockFile(lockFilePath()),
|
|
2387
|
-
catch: (cause) => new Error(`Failed to open master lock file: ${String(cause)}`)
|
|
2388
|
-
})
|
|
2389
|
-
),
|
|
2390
|
-
Effect24.flatMap(
|
|
2391
|
-
(handle) => Effect24.tryPromise({
|
|
2392
2421
|
try: async () => {
|
|
2393
2422
|
try {
|
|
2394
|
-
await runtime.deps.
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
return { connectionType: "MASTER",
|
|
2423
|
+
const lease = await runtime.deps.acquireLock(
|
|
2424
|
+
PORTALS_DIR(),
|
|
2425
|
+
acquireLockOptions(runtime)
|
|
2426
|
+
);
|
|
2427
|
+
return { connectionType: "MASTER", lease };
|
|
2399
2428
|
} catch (error) {
|
|
2400
|
-
await handle.close();
|
|
2401
2429
|
if (isLockConflictError(error)) {
|
|
2402
|
-
return { connectionType: "READ_ONLY",
|
|
2430
|
+
return { connectionType: "READ_ONLY", lease: null };
|
|
2403
2431
|
}
|
|
2404
2432
|
throw error;
|
|
2405
2433
|
}
|
|
@@ -2408,10 +2436,21 @@ var tryAcquireMasterLock = (runtime) => pipe13(
|
|
|
2408
2436
|
})
|
|
2409
2437
|
),
|
|
2410
2438
|
Effect24.flatMap(
|
|
2411
|
-
({ connectionType,
|
|
2412
|
-
Ref.
|
|
2413
|
-
Effect24.flatMap(() =>
|
|
2414
|
-
|
|
2439
|
+
({ connectionType, lease }) => pipe13(
|
|
2440
|
+
Ref.get(runtime.releasedRef),
|
|
2441
|
+
Effect24.flatMap((released) => {
|
|
2442
|
+
if (!released || lease === null) {
|
|
2443
|
+
return pipe13(
|
|
2444
|
+
Ref.set(runtime.connectionTypeRef, connectionType),
|
|
2445
|
+
Effect24.flatMap(() => Ref.set(runtime.lockLeaseRef, lease)),
|
|
2446
|
+
Effect24.as(connectionType)
|
|
2447
|
+
);
|
|
2448
|
+
}
|
|
2449
|
+
return pipe13(
|
|
2450
|
+
releaseLease(runtime, lease),
|
|
2451
|
+
Effect24.flatMap(() => Effect24.succeed("READ_ONLY"))
|
|
2452
|
+
);
|
|
2453
|
+
})
|
|
2415
2454
|
)
|
|
2416
2455
|
)
|
|
2417
2456
|
);
|
|
@@ -2426,9 +2465,12 @@ var stopPromotionPolling = (runtime) => pipe13(
|
|
|
2426
2465
|
)
|
|
2427
2466
|
);
|
|
2428
2467
|
var tryPromoteToMaster = (runtime) => pipe13(
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2468
|
+
Effect24.all({
|
|
2469
|
+
promoting: Ref.get(runtime.promotingRef),
|
|
2470
|
+
released: Ref.get(runtime.releasedRef)
|
|
2471
|
+
}),
|
|
2472
|
+
Effect24.flatMap(({ promoting, released }) => {
|
|
2473
|
+
if (promoting || released) return Effect24.void;
|
|
2432
2474
|
return pipe13(
|
|
2433
2475
|
Ref.set(runtime.promotingRef, true),
|
|
2434
2476
|
Effect24.flatMap(
|
|
@@ -2478,20 +2520,26 @@ var startPromotionPolling = (runtime) => pipe13(
|
|
|
2478
2520
|
})
|
|
2479
2521
|
);
|
|
2480
2522
|
var releaseRuntime = (runtime) => pipe13(
|
|
2481
|
-
|
|
2482
|
-
Effect24.flatMap(() =>
|
|
2523
|
+
Ref.set(runtime.releasedRef, true),
|
|
2524
|
+
Effect24.flatMap(() => stopPromotionPolling(runtime)),
|
|
2525
|
+
Effect24.flatMap(() => Ref.getAndSet(runtime.lockLeaseRef, null)),
|
|
2483
2526
|
Effect24.flatMap(
|
|
2484
|
-
(
|
|
2527
|
+
(lease) => lease === null ? Effect24.void : releaseLease(runtime, lease)
|
|
2485
2528
|
),
|
|
2486
2529
|
Effect24.flatMap(() => Ref.set(runtime.connectionTypeRef, "READ_ONLY"))
|
|
2487
2530
|
);
|
|
2488
2531
|
var makeRuntime = (config = {}) => pipe13(
|
|
2489
2532
|
Effect24.all({
|
|
2490
|
-
deps: Effect24.sync(
|
|
2533
|
+
deps: Effect24.sync(
|
|
2534
|
+
() => resolveMasterLockDependencies(config, {
|
|
2535
|
+
promotionPollMs: PROMOTION_POLL_MS
|
|
2536
|
+
})
|
|
2537
|
+
),
|
|
2491
2538
|
connectionTypeRef: Ref.make("READ_ONLY"),
|
|
2492
|
-
|
|
2539
|
+
lockLeaseRef: Ref.make(null),
|
|
2493
2540
|
promotionTimerRef: Ref.make(null),
|
|
2494
|
-
promotingRef: Ref.make(false)
|
|
2541
|
+
promotingRef: Ref.make(false),
|
|
2542
|
+
releasedRef: Ref.make(false)
|
|
2495
2543
|
}),
|
|
2496
2544
|
Effect24.tap(
|
|
2497
2545
|
(runtime) => pipe13(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daeda/mcp-pro",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"description": "MCP server for HubSpot CRM — sync, query, and manage your portal data",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
36
36
|
"effect": "3.19.15",
|
|
37
37
|
"fflate": "^0.8.2",
|
|
38
|
-
"os-lock": "^2.0.0",
|
|
39
38
|
"papaparse": "^5.5.3",
|
|
39
|
+
"proper-lockfile": "^4.1.2",
|
|
40
40
|
"zod": "^3.23.8"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
},
|
|
50
50
|
"trustedDependencies": [
|
|
51
51
|
"fs-ext",
|
|
52
|
-
"
|
|
52
|
+
"proper-lockfile"
|
|
53
53
|
]
|
|
54
54
|
}
|