@voltro/kv 0.85.0 → 0.87.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/CHANGELOG.md +5987 -0
- package/README.md +110 -0
- package/THIRD-PARTY-NOTICES.md +865 -2
- package/dist/Kv.js +19 -0
- package/dist/KvStore.js +5 -0
- package/dist/analytics.d.ts +337 -0
- package/dist/analytics.js +16 -0
- package/dist/backendMemory.js +36 -0
- package/dist/backendRedis.js +48 -0
- package/dist/cacheAtomicProtocol.js +247 -0
- package/dist/cacheAtomicScript.js +309 -0
- package/dist/cacheAtomicState.js +141 -0
- package/dist/connection.d.ts +990 -9
- package/dist/connection.js +361 -2
- package/dist/connectionAnalyticsConfig.js +153 -0
- package/dist/connectionConfigProvider.js +111 -0
- package/dist/connectionDefinitions.js +285 -0
- package/dist/connectionMemory.js +207 -0
- package/dist/connectionMetrics.js +79 -0
- package/dist/connectionNamespace.js +19 -0
- package/dist/connectionNats.js +148 -0
- package/dist/connectionNatsConfig.js +87 -0
- package/dist/connectionNatsSubjects.js +16 -0
- package/dist/connectionOwner.js +44 -0
- package/dist/connectionPool.js +738 -0
- package/dist/connectionPrefix.js +37 -0
- package/dist/connectionScripts.js +4 -0
- package/dist/connectionSqlConfig.js +119 -0
- package/dist/connectionStorageConfig.js +190 -0
- package/dist/connectionStorageFacade.js +78 -0
- package/dist/connectionSubscriber.js +130 -0
- package/dist/errors.js +13 -0
- package/dist/expirySweep.js +26 -0
- package/dist/hot-contract.d.ts +297 -0
- package/dist/hot-contract.js +18 -0
- package/dist/hot-testing.d.ts +229 -0
- package/dist/hot-testing.js +1 -0
- package/dist/hot.d.ts +936 -0
- package/dist/hot.js +7 -0
- package/dist/hotMemory.js +46 -0
- package/dist/hotOperations.js +223 -0
- package/dist/hotRateLimit.js +103 -0
- package/dist/hotReadAvailability.js +19 -0
- package/dist/hotRedis.js +139 -0
- package/dist/hotRedisScript.js +4 -0
- package/dist/hotRouting.js +78 -0
- package/dist/hotState.js +182 -0
- package/dist/hotStoreConformance.js +367 -0
- package/dist/index.d.ts +113 -9
- package/dist/index.js +7 -115
- package/dist/nativeRedisReads.js +78 -0
- package/dist/nativeRedisTopology.js +221 -0
- package/dist/redisDiagnostics.js +27 -0
- package/dist/redisReadPolicy.js +39 -0
- package/dist/sql.d.ts +77 -0
- package/dist/sql.js +0 -0
- package/dist/storage.d.ts +166 -0
- package/dist/storage.js +48 -0
- package/dist/storageAddress.js +20 -0
- package/package.json +43 -3
- package/dist/connection-Dsn5fgcH.js +0 -84
package/dist/sql.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Config } from 'effect';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { Schema } from 'effect';
|
|
4
|
+
import { SqlClient } from 'effect/sql';
|
|
5
|
+
import { Stream } from 'effect';
|
|
6
|
+
import { YieldableError } from 'effect/Cause';
|
|
7
|
+
|
|
8
|
+
declare interface ConnectionContext {
|
|
9
|
+
readonly tenantId: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** An environment declaration, never the environment value itself. */
|
|
13
|
+
declare interface ConnectionEnv {
|
|
14
|
+
readonly _tag: 'ConnectionEnv';
|
|
15
|
+
readonly name: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export declare interface DynamicSqlConnection {
|
|
19
|
+
readonly _tag: 'DynamicSqlConnection';
|
|
20
|
+
readonly resolve: (context: ConnectionContext) => Effect.Effect<SqlConnectionConfig, KvError>;
|
|
21
|
+
readonly ttlMs: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare class KvError extends KvError_base {
|
|
25
|
+
get message(): string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare const KvError_base: Schema.Class<KvError, Schema.TaggedStruct<"KvError", {
|
|
29
|
+
/** Which op failed: 'get' | 'set' | 'delete' | 'has' | 'clear' |
|
|
30
|
+
* 'list' | 'connect' | 'serialize' | 'deserialize'. */
|
|
31
|
+
readonly operation: Schema.String;
|
|
32
|
+
/** The key (or connection name) involved; '' where not applicable. */
|
|
33
|
+
readonly key: Schema.String;
|
|
34
|
+
/** `String(originalError)` — round-trip-safe diagnostic form. */
|
|
35
|
+
readonly cause: Schema.String;
|
|
36
|
+
}>, YieldableError>;
|
|
37
|
+
|
|
38
|
+
/** A whole operation (including its transaction) borrows one physical generation.
|
|
39
|
+
* Do not return the client, a deferred statement or a stream from use: execute it
|
|
40
|
+
* inside the callback. Use stream for a lazy result that must retain its lease. */
|
|
41
|
+
export declare interface SqlConnection {
|
|
42
|
+
readonly dialect: SqlConnectionConfig['dialect'];
|
|
43
|
+
readonly use: <A, E, R>(run: (client: SqlClient.SqlClient) => Effect.Effect<A, E, R>) => Effect.Effect<A, E | KvError | Config.ConfigError, R>;
|
|
44
|
+
readonly stream: <A, E, R>(run: (client: SqlClient.SqlClient) => Stream.Stream<A, E, R>) => Stream.Stream<A, E | KvError | Config.ConfigError, R>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Additional SQL target. The primary DataStore retains its own configuration. */
|
|
48
|
+
export declare interface SqlConnectionConfig {
|
|
49
|
+
readonly dialect: SqlConnectionDialect;
|
|
50
|
+
readonly url: string;
|
|
51
|
+
readonly tls?: 'auto' | 'required';
|
|
52
|
+
readonly maxConnections?: number;
|
|
53
|
+
readonly acquireTimeoutMs?: number;
|
|
54
|
+
readonly acquireQueueLimit?: number;
|
|
55
|
+
readonly statementTimeoutMs?: number;
|
|
56
|
+
readonly schema?: string;
|
|
57
|
+
readonly label?: string;
|
|
58
|
+
readonly region?: string;
|
|
59
|
+
readonly source?: 'config' | 'override';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export declare type SqlConnectionConnector = (config: SqlConnectionConfig) => Effect.Effect<SqlConnectionTransport, KvError>;
|
|
63
|
+
|
|
64
|
+
export declare interface SqlConnectionDefinition extends Omit<SqlConnectionConfig, 'url' | 'source'> {
|
|
65
|
+
readonly url: ConnectionEnv;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export declare type SqlConnectionDialect = 'postgres' | 'mysql' | 'mariadb' | 'mssql' | 'sqlite' | 'turso';
|
|
69
|
+
|
|
70
|
+
/** Connector-owned resources; a consumer never receives physical disposal. */
|
|
71
|
+
export declare interface SqlConnectionTransport {
|
|
72
|
+
readonly client: SqlClient.SqlClient;
|
|
73
|
+
readonly probe: Effect.Effect<void, KvError>;
|
|
74
|
+
readonly close: Effect.Effect<void>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { }
|
package/dist/sql.js
ADDED
|
File without changes
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
import { Stream } from 'effect';
|
|
4
|
+
import { YieldableError } from 'effect/Cause';
|
|
5
|
+
|
|
6
|
+
export declare type ByteStream = Stream.Stream<Uint8Array, StorageError>;
|
|
7
|
+
|
|
8
|
+
declare interface ConnectionMetadata {
|
|
9
|
+
readonly tls?: 'auto' | 'required';
|
|
10
|
+
readonly persistence?: 'required' | 'optional' | 'none';
|
|
11
|
+
readonly keyPrefix?: string;
|
|
12
|
+
/** Explicit opt-in when a production connection intentionally uses a shared namespace. */
|
|
13
|
+
readonly allowSharedNamespace?: boolean;
|
|
14
|
+
readonly region?: string;
|
|
15
|
+
readonly label?: string;
|
|
16
|
+
readonly acl?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Stable consumer identity while boot replaces its transport with a borrowed port. */
|
|
20
|
+
export declare const forwardStorageProvider: (current: () => StorageProvider) => StorageProvider;
|
|
21
|
+
|
|
22
|
+
export declare const isStorageKey: (value: string) => boolean;
|
|
23
|
+
|
|
24
|
+
export declare interface ObjectMeta {
|
|
25
|
+
readonly size: number;
|
|
26
|
+
readonly etag?: string;
|
|
27
|
+
/** Read-only metadata for lazy, leased streaming reads. */
|
|
28
|
+
readonly contentType?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A logical destination label, tenant and provider key identify one object. */
|
|
32
|
+
export declare const StorageAddress: Schema.Struct<{
|
|
33
|
+
readonly destination: Schema.String;
|
|
34
|
+
readonly tenantId: Schema.NullOr<Schema.String>;
|
|
35
|
+
readonly key: Schema.String;
|
|
36
|
+
}>;
|
|
37
|
+
|
|
38
|
+
export declare type StorageAddress = Schema.Schema.Type<typeof StorageAddress>;
|
|
39
|
+
|
|
40
|
+
/** Tuple encoding cannot alias delimiter-bearing labels, tenants or keys. */
|
|
41
|
+
export declare const storageAddressIdentity: (address: StorageAddress) => string;
|
|
42
|
+
|
|
43
|
+
/** Resolved values stay server-side and never enter inspection snapshots. */
|
|
44
|
+
export declare interface StorageConnectionConfig extends ConnectionMetadata {
|
|
45
|
+
readonly provider: StorageProviderName;
|
|
46
|
+
readonly bucket?: string;
|
|
47
|
+
readonly root?: string;
|
|
48
|
+
readonly endpoint?: string;
|
|
49
|
+
readonly accessKeyId?: string;
|
|
50
|
+
readonly secretAccessKey?: string;
|
|
51
|
+
readonly accountName?: string;
|
|
52
|
+
readonly accountKey?: string;
|
|
53
|
+
readonly connectionString?: string;
|
|
54
|
+
readonly cdnBaseUrl?: string;
|
|
55
|
+
readonly forcePathStyle?: boolean;
|
|
56
|
+
readonly publicAcl?: boolean;
|
|
57
|
+
readonly source?: 'config' | 'environment' | 'override';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export declare type StorageConnectionConnector = (config: StorageConnectionConfig, context: StorageConnectionOpenContext) => Effect.Effect<StorageConnectionTransport, StorageError>;
|
|
61
|
+
|
|
62
|
+
export declare interface StorageConnectionOpenContext {
|
|
63
|
+
/** Local state belongs to this registry identity, preserved across physical rotation. */
|
|
64
|
+
readonly memory?: Map<string, StoredObject>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** A transport is created lazily; only the registry owns its physical disposal. */
|
|
68
|
+
export declare interface StorageConnectionTransport {
|
|
69
|
+
readonly provider: StorageProvider;
|
|
70
|
+
readonly probe: Effect.Effect<void, StorageError>;
|
|
71
|
+
readonly close: Effect.Effect<void>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export declare interface StorageDestination {
|
|
75
|
+
readonly destination: string;
|
|
76
|
+
/** Borrowed transport; its registry owns connections and operation leases. */
|
|
77
|
+
readonly provider: StorageProvider;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Select new writes separately from resolving immutable SQL ownership. */
|
|
81
|
+
export declare interface StorageDestinationRouter {
|
|
82
|
+
readonly select: (tenantId: string | null) => Effect.Effect<StorageDestination, StorageError>;
|
|
83
|
+
readonly resolve: (address: StorageAddress) => Effect.Effect<StorageProvider, StorageError>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The object transport error, shared with the storage plugin's wire contract. */
|
|
87
|
+
export declare class StorageError extends StorageError_base {
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
declare const StorageError_base: Schema.Class<StorageError, Schema.TaggedStruct<"StorageError", {
|
|
91
|
+
readonly provider: Schema.String;
|
|
92
|
+
readonly message: Schema.String;
|
|
93
|
+
readonly transient: Schema.Boolean;
|
|
94
|
+
readonly status: Schema.optional<Schema.Number>;
|
|
95
|
+
/** Cleanup was not confirmed; inspect the destination before another write. */
|
|
96
|
+
readonly outcome: Schema.optional<Schema.Literal<"unknown">>;
|
|
97
|
+
}>, YieldableError>;
|
|
98
|
+
|
|
99
|
+
/** Logical object keys never contain filesystem traversal or empty segments. */
|
|
100
|
+
export declare const storageKeyProblem: (value: string) => string | undefined;
|
|
101
|
+
|
|
102
|
+
/** Server-side physical identity; never serialize a namespace into inspection. */
|
|
103
|
+
export declare interface StorageObjectLocation {
|
|
104
|
+
readonly namespace: string | object;
|
|
105
|
+
readonly key: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Opaque keyed bytes; policy and durable references belong to the plugin. */
|
|
109
|
+
export declare interface StorageProvider {
|
|
110
|
+
/** Stable, credential-independent SHA-256 identity of this physical key namespace. */
|
|
111
|
+
readonly objectNamespace: Effect.Effect<string, StorageError>;
|
|
112
|
+
/** Canonical container and physical key, including connection prefixes. */
|
|
113
|
+
readonly objectLocation?: (key: string) => Effect.Effect<StorageObjectLocation, StorageError>;
|
|
114
|
+
readonly root?: string;
|
|
115
|
+
readonly name: string;
|
|
116
|
+
readonly presigns: boolean;
|
|
117
|
+
readonly put: (key: string, bytes: Uint8Array, meta: {
|
|
118
|
+
readonly contentType: string;
|
|
119
|
+
readonly public?: boolean;
|
|
120
|
+
}) => Effect.Effect<ObjectMeta, StorageError>;
|
|
121
|
+
readonly get: (key: string) => Effect.Effect<StoredObject, StorageError>;
|
|
122
|
+
readonly delete: (key: string) => Effect.Effect<void, StorageError>;
|
|
123
|
+
readonly getUrl: (key: string, expiresInSec: number) => Effect.Effect<string, StorageError>;
|
|
124
|
+
readonly publicUrl?: (key: string) => string | null;
|
|
125
|
+
readonly setObjectPublic?: (key: string, isPublic: boolean) => Effect.Effect<void, StorageError>;
|
|
126
|
+
readonly getUploadUrl?: (key: string, expiresInSec: number, contentType: string) => Effect.Effect<string, StorageError>;
|
|
127
|
+
readonly createMultipartUpload?: (key: string, contentType: string, opts?: {
|
|
128
|
+
readonly public?: boolean;
|
|
129
|
+
}) => Effect.Effect<{
|
|
130
|
+
readonly uploadId: string;
|
|
131
|
+
}, StorageError>;
|
|
132
|
+
readonly presignUploadPart?: (key: string, uploadId: string, partNumber: number, expiresInSec: number) => Effect.Effect<string, StorageError>;
|
|
133
|
+
readonly completeMultipartUpload?: (key: string, uploadId: string, parts: ReadonlyArray<{
|
|
134
|
+
readonly partNumber: number;
|
|
135
|
+
readonly etag: string;
|
|
136
|
+
}>) => Effect.Effect<{
|
|
137
|
+
readonly etag?: string;
|
|
138
|
+
}, StorageError>;
|
|
139
|
+
readonly abortMultipartUpload?: (key: string, uploadId: string) => Effect.Effect<void, StorageError>;
|
|
140
|
+
readonly head: (key: string) => Effect.Effect<ObjectMeta | null, StorageError>;
|
|
141
|
+
readonly getStream?: (key: string) => Effect.Effect<StoredStream, StorageError>;
|
|
142
|
+
readonly putStream?: (key: string, stream: ByteStream, meta: {
|
|
143
|
+
readonly contentType: string;
|
|
144
|
+
readonly public?: boolean;
|
|
145
|
+
readonly totalSize?: number;
|
|
146
|
+
}) => Effect.Effect<ObjectMeta, StorageError>;
|
|
147
|
+
readonly getRange?: (key: string, start: number, endInclusive: number) => Effect.Effect<Uint8Array, StorageError>;
|
|
148
|
+
readonly bindDataStore?: (store: unknown) => void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export declare type StorageProviderName = 's3' | 'minio' | 'azure' | 'filesystem' | 'memory' | 'database';
|
|
152
|
+
|
|
153
|
+
export declare interface StoredObject {
|
|
154
|
+
readonly bytes: Uint8Array;
|
|
155
|
+
readonly contentType: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export declare interface StoredStream {
|
|
159
|
+
readonly stream: ByteStream;
|
|
160
|
+
readonly contentType: string;
|
|
161
|
+
readonly size?: number;
|
|
162
|
+
/** Release an opened body even if cancellation precedes its first pull. */
|
|
163
|
+
readonly close?: Effect.Effect<void>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { }
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StorageAddress as e, isStorageKey as t, storageAddressIdentity as n, storageKeyProblem as r } from "./storageAddress.js";
|
|
2
|
+
import { Schema as i } from "effect";
|
|
3
|
+
//#region src/connectionStorage.ts
|
|
4
|
+
var a = class extends i.TaggedError()("StorageError", {
|
|
5
|
+
provider: i.String,
|
|
6
|
+
message: i.String,
|
|
7
|
+
transient: i.Boolean,
|
|
8
|
+
status: i.optional(i.Number),
|
|
9
|
+
outcome: i.optional(i.Literal("unknown"))
|
|
10
|
+
}) {}, o = (e) => {
|
|
11
|
+
let t = {
|
|
12
|
+
get objectNamespace() {
|
|
13
|
+
return e().objectNamespace;
|
|
14
|
+
},
|
|
15
|
+
get name() {
|
|
16
|
+
return e().name;
|
|
17
|
+
},
|
|
18
|
+
get presigns() {
|
|
19
|
+
return e().presigns;
|
|
20
|
+
},
|
|
21
|
+
put: (...t) => e().put(...t),
|
|
22
|
+
get: (...t) => e().get(...t),
|
|
23
|
+
delete: (...t) => e().delete(...t),
|
|
24
|
+
getUrl: (...t) => e().getUrl(...t),
|
|
25
|
+
head: (...t) => e().head(...t)
|
|
26
|
+
}, n = {};
|
|
27
|
+
for (let t of [
|
|
28
|
+
"objectLocation",
|
|
29
|
+
"root",
|
|
30
|
+
"publicUrl",
|
|
31
|
+
"setObjectPublic",
|
|
32
|
+
"getUploadUrl",
|
|
33
|
+
"createMultipartUpload",
|
|
34
|
+
"presignUploadPart",
|
|
35
|
+
"completeMultipartUpload",
|
|
36
|
+
"abortMultipartUpload",
|
|
37
|
+
"getStream",
|
|
38
|
+
"putStream",
|
|
39
|
+
"getRange",
|
|
40
|
+
"bindDataStore"
|
|
41
|
+
]) n[t] = {
|
|
42
|
+
enumerable: !0,
|
|
43
|
+
get: () => e()[t]
|
|
44
|
+
};
|
|
45
|
+
return Object.defineProperties(t, n);
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { e as StorageAddress, a as StorageError, o as forwardStorageProvider, t as isStorageKey, n as storageAddressIdentity, r as storageKeyProblem };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Schema as e } from "effect";
|
|
2
|
+
//#region src/storageAddress.ts
|
|
3
|
+
var t = (e) => {
|
|
4
|
+
if (e.length === 0) return "empty";
|
|
5
|
+
if (e.includes("\0")) return "contains NUL";
|
|
6
|
+
if (e.includes("\\")) return "contains a backslash";
|
|
7
|
+
if (e.startsWith("/") || /^[a-z]:/i.test(e)) return "starts with a path separator";
|
|
8
|
+
if (/[\uD800-\uDFFF]/u.test(e)) return "contains an unpaired surrogate";
|
|
9
|
+
if (e.split("/").some((e) => e === "" || e === "." || e === "..")) return "contains an empty, \".\" or \"..\" segment";
|
|
10
|
+
}, n = (e) => t(e) === void 0, r = e.Struct({
|
|
11
|
+
destination: e.String.pipe(e.check(e.isMinLength(1)), e.check(e.isMaxLength(512)), e.check(e.makeFilter((e) => !e.includes("\0") && !/[\uD800-\uDFFF]/u.test(e)))),
|
|
12
|
+
tenantId: e.NullOr(e.String.pipe(e.check(e.isMinLength(1)), e.check(e.makeFilter((e) => !e.includes("\0") && !/[\uD800-\uDFFF]/u.test(e))))),
|
|
13
|
+
key: e.String.pipe(e.check(e.makeFilter(n)))
|
|
14
|
+
}), i = (e) => JSON.stringify([
|
|
15
|
+
e.destination,
|
|
16
|
+
e.tenantId,
|
|
17
|
+
e.key
|
|
18
|
+
]);
|
|
19
|
+
//#endregion
|
|
20
|
+
export { r as StorageAddress, n as isStorageKey, i as storageAddressIdentity, t as storageKeyProblem };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/kv",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"description": "Named RESP connection registry + durable key-value primitive. One config surface for many Redis-family connections (Redis/Valkey/KeyDB/Dragonfly/Upstash) shared across cache, rate-limit, RYW and broadcast; plus a durable, tenant-scoped KV store distinct from the best-effort cache.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -28,7 +28,37 @@
|
|
|
28
28
|
"import": "./dist/connection.js",
|
|
29
29
|
"default": "./dist/connection.js"
|
|
30
30
|
},
|
|
31
|
-
"./package.json": "./package.json"
|
|
31
|
+
"./package.json": "./package.json",
|
|
32
|
+
"./hot": {
|
|
33
|
+
"types": "./dist/hot.d.ts",
|
|
34
|
+
"import": "./dist/hot.js",
|
|
35
|
+
"default": "./dist/hot.js"
|
|
36
|
+
},
|
|
37
|
+
"./hot/testing": {
|
|
38
|
+
"types": "./dist/hot-testing.d.ts",
|
|
39
|
+
"import": "./dist/hot-testing.js",
|
|
40
|
+
"default": "./dist/hot-testing.js"
|
|
41
|
+
},
|
|
42
|
+
"./hot/contract": {
|
|
43
|
+
"types": "./dist/hot-contract.d.ts",
|
|
44
|
+
"import": "./dist/hot-contract.js",
|
|
45
|
+
"default": "./dist/hot-contract.js"
|
|
46
|
+
},
|
|
47
|
+
"./storage": {
|
|
48
|
+
"types": "./dist/storage.d.ts",
|
|
49
|
+
"import": "./dist/storage.js",
|
|
50
|
+
"default": "./dist/storage.js"
|
|
51
|
+
},
|
|
52
|
+
"./analytics": {
|
|
53
|
+
"types": "./dist/analytics.d.ts",
|
|
54
|
+
"import": "./dist/analytics.js",
|
|
55
|
+
"default": "./dist/analytics.js"
|
|
56
|
+
},
|
|
57
|
+
"./sql": {
|
|
58
|
+
"types": "./dist/sql.d.ts",
|
|
59
|
+
"import": "./dist/sql.js",
|
|
60
|
+
"default": "./dist/sql.js"
|
|
61
|
+
}
|
|
32
62
|
},
|
|
33
63
|
"main": "./dist/index.js",
|
|
34
64
|
"module": "./dist/index.js",
|
|
@@ -37,12 +67,22 @@
|
|
|
37
67
|
"engines": {
|
|
38
68
|
"node": ">=24.0.0"
|
|
39
69
|
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"@voltro/shared": "0.87.0"
|
|
72
|
+
},
|
|
40
73
|
"optionalDependencies": {
|
|
74
|
+
"@nats-io/transport-node": "^3.4.0",
|
|
41
75
|
"@upstash/redis": "^1.38.4",
|
|
42
76
|
"ioredis": "^5.11.1"
|
|
43
77
|
},
|
|
44
78
|
"peerDependencies": {
|
|
45
|
-
"effect": "4.0.1"
|
|
79
|
+
"effect": "4.0.1",
|
|
80
|
+
"vitest": ">=3.0.0"
|
|
81
|
+
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"vitest": {
|
|
84
|
+
"optional": true
|
|
85
|
+
}
|
|
46
86
|
},
|
|
47
87
|
"publishConfig": {
|
|
48
88
|
"access": "public"
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { Config as e, Context as t, Effect as n, HashMap as r, Layer as i, Option as a, Schedule as o, Schema as s, Scope as c, SynchronizedRef as l } from "effect";
|
|
2
|
-
//#region src/errors.ts
|
|
3
|
-
var u = class extends s.TaggedError()("KvError", {
|
|
4
|
-
operation: s.String,
|
|
5
|
-
key: s.String,
|
|
6
|
-
cause: s.String
|
|
7
|
-
}) {}, d = (e) => ({
|
|
8
|
-
get: (t) => e.get(t),
|
|
9
|
-
set: (t, n) => e.set(t, n),
|
|
10
|
-
psetex: (t, n, r) => e.psetex(t, n, r),
|
|
11
|
-
del: (t) => t.length === 0 ? Promise.resolve(0) : e.del(...t),
|
|
12
|
-
exists: (t) => e.exists(t),
|
|
13
|
-
eval: (t, n, ...r) => e.eval(t, n, ...r),
|
|
14
|
-
zrange: (t) => e.zrange(t, 0, -1),
|
|
15
|
-
scan: async (t, n, r) => {
|
|
16
|
-
let [i, a] = await e.scan(t, "MATCH", n, "COUNT", r);
|
|
17
|
-
return {
|
|
18
|
-
cursor: i,
|
|
19
|
-
keys: a
|
|
20
|
-
};
|
|
21
|
-
},
|
|
22
|
-
close: () => e.quit().then(() => void 0).catch(() => {
|
|
23
|
-
try {
|
|
24
|
-
e.disconnect();
|
|
25
|
-
} catch {}
|
|
26
|
-
})
|
|
27
|
-
}), f = (e) => ({
|
|
28
|
-
get: (t) => e.get(t),
|
|
29
|
-
set: (t, n) => e.set(t, n),
|
|
30
|
-
psetex: (t, n, r) => e.psetex(t, n, r),
|
|
31
|
-
del: (t) => t.length === 0 ? Promise.resolve(0) : e.del(...t),
|
|
32
|
-
exists: (t) => e.exists(t),
|
|
33
|
-
eval: (t, n, ...r) => e.eval(t, r.slice(0, n), r.slice(n)),
|
|
34
|
-
zrange: (t) => e.zrange(t, 0, -1),
|
|
35
|
-
scan: async (t, n, r) => {
|
|
36
|
-
let [i, a] = await e.scan(t, {
|
|
37
|
-
match: n,
|
|
38
|
-
count: r
|
|
39
|
-
});
|
|
40
|
-
return {
|
|
41
|
-
cursor: String(i),
|
|
42
|
-
keys: a
|
|
43
|
-
};
|
|
44
|
-
},
|
|
45
|
-
close: () => Promise.resolve()
|
|
46
|
-
}), p = (e) => e.toUpperCase().replace(/[^A-Z0-9]+/g, "_"), m = ["resp", "http"], h = (t) => n.gen(function* () {
|
|
47
|
-
let n = p(t), r = yield* e.String(`${n}_REDIS_URL`).pipe(e.orElse(() => e.String("REDIS_URL"))), i = yield* e.Literals(m, `${n}_REDIS_DRIVER`).pipe(e.option), o = a.isSome(i) ? i.value : yield* e.Literals(m, "REDIS_DRIVER").pipe(e.withDefault("resp")), s = yield* e.String(`${n}_REDIS_TOKEN`).pipe(e.orElse(() => e.String("REDIS_TOKEN")), e.orElse(() => e.String("UPSTASH_REDIS_REST_TOKEN")), e.option), c = yield* e.String(`${n}_REDIS_KEY_PREFIX`).pipe(e.option);
|
|
48
|
-
return {
|
|
49
|
-
url: r,
|
|
50
|
-
driver: o,
|
|
51
|
-
...a.isSome(s) ? { token: s.value } : {},
|
|
52
|
-
...a.isSome(c) ? { keyPrefix: c.value } : {}
|
|
53
|
-
};
|
|
54
|
-
}), g = (e) => n.tryPromise({
|
|
55
|
-
try: async () => {
|
|
56
|
-
if (e.driver === "http") {
|
|
57
|
-
let t = await import("@upstash/redis"), n = typeof t.default == "function" ? t.default : t.default?.Redis, r = t.Redis ?? n;
|
|
58
|
-
if (!r) throw Error("@upstash/redis: Redis constructor not found in module");
|
|
59
|
-
return f(new r({
|
|
60
|
-
url: e.url,
|
|
61
|
-
token: e.token,
|
|
62
|
-
automaticDeserialization: !1
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
let t = (await import("ioredis")).default, n = new t(e.url);
|
|
66
|
-
return n.on("error", () => {}), d(n);
|
|
67
|
-
},
|
|
68
|
-
catch: (e) => new u({
|
|
69
|
-
operation: "connect",
|
|
70
|
-
key: "",
|
|
71
|
-
cause: String(e)
|
|
72
|
-
})
|
|
73
|
-
}), _ = o.max([o.exponential("10 millis"), o.recurs(2)]), v = class extends t.Service()("@voltro/RedisConnections") {}, y = i.effect(v, n.gen(function* () {
|
|
74
|
-
let e = yield* n.scope, t = yield* l.make(r.empty()), i = (e) => h(e);
|
|
75
|
-
return {
|
|
76
|
-
client: (o) => l.modifyEffect(t, (t) => {
|
|
77
|
-
let s = r.get(t, o);
|
|
78
|
-
return a.isSome(s) ? n.succeed([s.value, t]) : i(o).pipe(n.flatMap(g), n.tap((t) => c.addFinalizer(e, n.promise(() => t.close().catch(() => void 0)))), n.map((e) => [e, r.set(t, o, e)]));
|
|
79
|
-
}),
|
|
80
|
-
config: i
|
|
81
|
-
};
|
|
82
|
-
}));
|
|
83
|
-
//#endregion
|
|
84
|
-
export { y as a, h as i, _ as n, u as o, g as r, v as t };
|