@voltro/kv 0.86.0 → 0.88.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +5484 -0
  2. package/README.md +110 -0
  3. package/THIRD-PARTY-NOTICES.md +2 -482
  4. package/dist/Kv.js +1 -2
  5. package/dist/KvStore.js +1 -2
  6. package/dist/analytics.d.ts +337 -0
  7. package/dist/analytics.js +15 -0
  8. package/dist/backendMemory.js +1 -2
  9. package/dist/backendRedis.js +1 -2
  10. package/dist/cacheAtomicProtocol.js +257 -0
  11. package/dist/cacheAtomicScript.js +326 -0
  12. package/dist/cacheAtomicState.js +140 -0
  13. package/dist/connection.d.ts +990 -9
  14. package/dist/connection.js +336 -52
  15. package/dist/connectionAnalyticsConfig.js +152 -0
  16. package/dist/connectionConfigError.js +10 -0
  17. package/dist/connectionConfigProvider.js +110 -0
  18. package/dist/connectionDefinitions.js +284 -0
  19. package/dist/connectionMemory.js +206 -0
  20. package/dist/connectionMetrics.js +78 -0
  21. package/dist/connectionNamespace.js +18 -0
  22. package/dist/connectionNats.js +148 -0
  23. package/dist/connectionNatsConfig.js +86 -0
  24. package/dist/connectionNatsSubjects.js +15 -0
  25. package/dist/connectionOwner.js +43 -0
  26. package/dist/connectionPool.js +738 -0
  27. package/dist/connectionPrefix.js +36 -0
  28. package/dist/connectionScripts.js +3 -0
  29. package/dist/connectionSqlConfig.js +118 -0
  30. package/dist/connectionStorageConfig.js +189 -0
  31. package/dist/connectionStorageFacade.js +77 -0
  32. package/dist/connectionSubscriber.js +130 -0
  33. package/dist/driverModule.js +9 -0
  34. package/dist/errors.js +6 -3
  35. package/dist/expirySweep.js +1 -2
  36. package/dist/hot-contract.d.ts +297 -0
  37. package/dist/hot-contract.js +17 -0
  38. package/dist/hot-testing.d.ts +242 -0
  39. package/dist/hot-testing.js +1 -0
  40. package/dist/hot.d.ts +936 -0
  41. package/dist/hot.js +7 -0
  42. package/dist/hotMemory.js +45 -0
  43. package/dist/hotOperations.js +222 -0
  44. package/dist/hotRateLimit.js +102 -0
  45. package/dist/hotReadAvailability.js +18 -0
  46. package/dist/hotRedis.js +138 -0
  47. package/dist/hotRedisScript.js +3 -0
  48. package/dist/hotRouting.js +77 -0
  49. package/dist/hotState.js +181 -0
  50. package/dist/hotStoreConformance.js +365 -0
  51. package/dist/index.d.ts +113 -9
  52. package/dist/nativeRedisReads.js +77 -0
  53. package/dist/nativeRedisTopology.js +222 -0
  54. package/dist/redisDiagnostics.js +26 -0
  55. package/dist/redisReadPolicy.js +38 -0
  56. package/dist/sql.d.ts +77 -0
  57. package/dist/sql.js +0 -0
  58. package/dist/storage.d.ts +166 -0
  59. package/dist/storage.js +47 -0
  60. package/dist/storageAddress.js +19 -0
  61. package/package.json +49 -6
@@ -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 { }
@@ -0,0 +1,47 @@
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
+ // 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
+ export { e as StorageAddress, a as StorageError, o as forwardStorageProvider, t as isStorageKey, n as storageAddressIdentity, r as storageKeyProblem };
@@ -0,0 +1,19 @@
1
+ import { Schema as e } from "effect";
2
+ // 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
+ 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.86.0",
3
+ "version": "0.88.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,25 @@
37
67
  "engines": {
38
68
  "node": ">=24.0.0"
39
69
  },
40
- "optionalDependencies": {
41
- "@upstash/redis": "^1.38.4",
42
- "ioredis": "^5.11.1"
70
+ "dependencies": {
71
+ "@voltro/shared": "0.88.0"
43
72
  },
44
73
  "peerDependencies": {
45
- "effect": "4.0.1"
74
+ "effect": "4.1.0",
75
+ "@nats-io/transport-node": "^3.4.0",
76
+ "@upstash/redis": "^1.40.0",
77
+ "ioredis": "^6.0.0"
78
+ },
79
+ "peerDependenciesMeta": {
80
+ "@nats-io/transport-node": {
81
+ "optional": true
82
+ },
83
+ "@upstash/redis": {
84
+ "optional": true
85
+ },
86
+ "ioredis": {
87
+ "optional": true
88
+ }
46
89
  },
47
90
  "publishConfig": {
48
91
  "access": "public"