@frontmcp/utils 1.8.5 → 1.8.6
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/esm/index.mjs +33 -8
- package/index.js +33 -8
- package/package.json +2 -2
- package/storage/adapters/redis.d.ts +3 -1
package/esm/index.mjs
CHANGED
|
@@ -2982,25 +2982,29 @@ function getRedisClass() {
|
|
|
2982
2982
|
const msg = error instanceof Error ? error.message : String(error);
|
|
2983
2983
|
if (msg.includes("Dynamic require") || msg.includes("require is not defined")) {
|
|
2984
2984
|
throw new Error(
|
|
2985
|
-
`Failed to load ioredis: ${msg}. This typically happens with ESM bundlers (esbuild, Vite). Ensure your bundler externalizes ioredis or use CJS mode
|
|
2985
|
+
`Failed to load ioredis: ${msg}. This typically happens with ESM bundlers (esbuild, Vite). Ensure your bundler externalizes ioredis or use CJS mode.`,
|
|
2986
|
+
{ cause: error }
|
|
2986
2987
|
);
|
|
2987
2988
|
}
|
|
2988
|
-
throw new Error("ioredis is required for Redis storage adapter. Install it with: npm install ioredis"
|
|
2989
|
+
throw new Error("ioredis is required for Redis storage adapter. Install it with: npm install ioredis", {
|
|
2990
|
+
cause: error
|
|
2991
|
+
});
|
|
2989
2992
|
}
|
|
2990
2993
|
}
|
|
2991
2994
|
var RedisStorageAdapter;
|
|
2992
2995
|
var init_redis = __esm({
|
|
2993
2996
|
"libs/utils/src/storage/adapters/redis.ts"() {
|
|
2994
2997
|
"use strict";
|
|
2995
|
-
init_base();
|
|
2996
2998
|
init_errors();
|
|
2997
2999
|
init_utils();
|
|
3000
|
+
init_base();
|
|
2998
3001
|
RedisStorageAdapter = class extends BaseStorageAdapter {
|
|
2999
3002
|
backendName = "redis";
|
|
3000
3003
|
client;
|
|
3001
3004
|
subscriber;
|
|
3002
3005
|
options;
|
|
3003
3006
|
ownsClient;
|
|
3007
|
+
connecting;
|
|
3004
3008
|
keyPrefix;
|
|
3005
3009
|
subscriptionHandlers = /* @__PURE__ */ new Map();
|
|
3006
3010
|
constructor(options = {}) {
|
|
@@ -3030,21 +3034,42 @@ var init_redis = __esm({
|
|
|
3030
3034
|
// ============================================
|
|
3031
3035
|
async connect() {
|
|
3032
3036
|
if (this.connected) return;
|
|
3037
|
+
this.connecting ??= this.openConnection().finally(() => {
|
|
3038
|
+
this.connecting = void 0;
|
|
3039
|
+
});
|
|
3040
|
+
return this.connecting;
|
|
3041
|
+
}
|
|
3042
|
+
async openConnection() {
|
|
3043
|
+
let socketError;
|
|
3044
|
+
const recordSocketError = (error) => {
|
|
3045
|
+
socketError = error;
|
|
3046
|
+
};
|
|
3047
|
+
let client;
|
|
3033
3048
|
try {
|
|
3034
3049
|
if (this.options.client) {
|
|
3035
|
-
|
|
3050
|
+
client = this.options.client;
|
|
3036
3051
|
} else {
|
|
3037
3052
|
const RedisClass = getRedisClass();
|
|
3038
3053
|
if (this.options.url) {
|
|
3039
|
-
|
|
3054
|
+
client = new RedisClass(this.options.url, this.buildRedisOptions());
|
|
3040
3055
|
} else {
|
|
3041
|
-
|
|
3056
|
+
client = new RedisClass(this.buildRedisOptions());
|
|
3042
3057
|
}
|
|
3058
|
+
client.on("error", recordSocketError);
|
|
3043
3059
|
}
|
|
3044
|
-
await
|
|
3060
|
+
await client.ping();
|
|
3061
|
+
this.client = client;
|
|
3045
3062
|
this.connected = true;
|
|
3063
|
+
if (this.ownsClient) client.removeListener("error", recordSocketError);
|
|
3046
3064
|
} catch (e) {
|
|
3047
|
-
|
|
3065
|
+
if (this.ownsClient && client) {
|
|
3066
|
+
try {
|
|
3067
|
+
client.disconnect();
|
|
3068
|
+
} catch {
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
const cause = socketError ?? (e instanceof Error ? e : void 0);
|
|
3072
|
+
throw new StorageConnectionError("Failed to connect to Redis", cause, "redis");
|
|
3048
3073
|
}
|
|
3049
3074
|
}
|
|
3050
3075
|
async disconnect() {
|
package/index.js
CHANGED
|
@@ -2985,25 +2985,29 @@ function getRedisClass() {
|
|
|
2985
2985
|
const msg = error instanceof Error ? error.message : String(error);
|
|
2986
2986
|
if (msg.includes("Dynamic require") || msg.includes("require is not defined")) {
|
|
2987
2987
|
throw new Error(
|
|
2988
|
-
`Failed to load ioredis: ${msg}. This typically happens with ESM bundlers (esbuild, Vite). Ensure your bundler externalizes ioredis or use CJS mode
|
|
2988
|
+
`Failed to load ioredis: ${msg}. This typically happens with ESM bundlers (esbuild, Vite). Ensure your bundler externalizes ioredis or use CJS mode.`,
|
|
2989
|
+
{ cause: error }
|
|
2989
2990
|
);
|
|
2990
2991
|
}
|
|
2991
|
-
throw new Error("ioredis is required for Redis storage adapter. Install it with: npm install ioredis"
|
|
2992
|
+
throw new Error("ioredis is required for Redis storage adapter. Install it with: npm install ioredis", {
|
|
2993
|
+
cause: error
|
|
2994
|
+
});
|
|
2992
2995
|
}
|
|
2993
2996
|
}
|
|
2994
2997
|
var RedisStorageAdapter;
|
|
2995
2998
|
var init_redis = __esm({
|
|
2996
2999
|
"libs/utils/src/storage/adapters/redis.ts"() {
|
|
2997
3000
|
"use strict";
|
|
2998
|
-
init_base();
|
|
2999
3001
|
init_errors();
|
|
3000
3002
|
init_utils();
|
|
3003
|
+
init_base();
|
|
3001
3004
|
RedisStorageAdapter = class extends BaseStorageAdapter {
|
|
3002
3005
|
backendName = "redis";
|
|
3003
3006
|
client;
|
|
3004
3007
|
subscriber;
|
|
3005
3008
|
options;
|
|
3006
3009
|
ownsClient;
|
|
3010
|
+
connecting;
|
|
3007
3011
|
keyPrefix;
|
|
3008
3012
|
subscriptionHandlers = /* @__PURE__ */ new Map();
|
|
3009
3013
|
constructor(options = {}) {
|
|
@@ -3033,21 +3037,42 @@ var init_redis = __esm({
|
|
|
3033
3037
|
// ============================================
|
|
3034
3038
|
async connect() {
|
|
3035
3039
|
if (this.connected) return;
|
|
3040
|
+
this.connecting ??= this.openConnection().finally(() => {
|
|
3041
|
+
this.connecting = void 0;
|
|
3042
|
+
});
|
|
3043
|
+
return this.connecting;
|
|
3044
|
+
}
|
|
3045
|
+
async openConnection() {
|
|
3046
|
+
let socketError;
|
|
3047
|
+
const recordSocketError = (error) => {
|
|
3048
|
+
socketError = error;
|
|
3049
|
+
};
|
|
3050
|
+
let client;
|
|
3036
3051
|
try {
|
|
3037
3052
|
if (this.options.client) {
|
|
3038
|
-
|
|
3053
|
+
client = this.options.client;
|
|
3039
3054
|
} else {
|
|
3040
3055
|
const RedisClass = getRedisClass();
|
|
3041
3056
|
if (this.options.url) {
|
|
3042
|
-
|
|
3057
|
+
client = new RedisClass(this.options.url, this.buildRedisOptions());
|
|
3043
3058
|
} else {
|
|
3044
|
-
|
|
3059
|
+
client = new RedisClass(this.buildRedisOptions());
|
|
3045
3060
|
}
|
|
3061
|
+
client.on("error", recordSocketError);
|
|
3046
3062
|
}
|
|
3047
|
-
await
|
|
3063
|
+
await client.ping();
|
|
3064
|
+
this.client = client;
|
|
3048
3065
|
this.connected = true;
|
|
3066
|
+
if (this.ownsClient) client.removeListener("error", recordSocketError);
|
|
3049
3067
|
} catch (e) {
|
|
3050
|
-
|
|
3068
|
+
if (this.ownsClient && client) {
|
|
3069
|
+
try {
|
|
3070
|
+
client.disconnect();
|
|
3071
|
+
} catch {
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
const cause = socketError ?? (e instanceof Error ? e : void 0);
|
|
3075
|
+
throw new StorageConnectionError("Failed to connect to Redis", cause, "redis");
|
|
3051
3076
|
}
|
|
3052
3077
|
}
|
|
3053
3078
|
async disconnect() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/utils",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
4
4
|
"description": "Shared utility functions for FrontMCP - string manipulation, URI handling, path utilities, and more",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@noble/hashes": "^2.0.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
35
|
+
"@frontmcp/lazy-zod": "1.8.6",
|
|
36
36
|
"@vercel/kv": "^2.0.0 || ^3.0.0",
|
|
37
37
|
"ioredis": "^5.0.0"
|
|
38
38
|
},
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Redis-based storage implementation for production use.
|
|
5
5
|
* Uses ioredis with dynamic import for browser compatibility.
|
|
6
6
|
*/
|
|
7
|
+
import type { MessageHandler, RedisAdapterOptions, SetOptions, Unsubscribe } from '../types';
|
|
7
8
|
import { BaseStorageAdapter } from './base';
|
|
8
|
-
import type { RedisAdapterOptions, SetOptions, MessageHandler, Unsubscribe } from '../types';
|
|
9
9
|
type Redis = import('ioredis').Redis;
|
|
10
10
|
/**
|
|
11
11
|
* Redis storage adapter.
|
|
@@ -34,10 +34,12 @@ export declare class RedisStorageAdapter extends BaseStorageAdapter {
|
|
|
34
34
|
private subscriber?;
|
|
35
35
|
private readonly options;
|
|
36
36
|
private readonly ownsClient;
|
|
37
|
+
private connecting?;
|
|
37
38
|
private readonly keyPrefix;
|
|
38
39
|
private readonly subscriptionHandlers;
|
|
39
40
|
constructor(options?: RedisAdapterOptions);
|
|
40
41
|
connect(): Promise<void>;
|
|
42
|
+
private openConnection;
|
|
41
43
|
disconnect(): Promise<void>;
|
|
42
44
|
ping(): Promise<boolean>;
|
|
43
45
|
/**
|