diff --git a/.changeset/fifty-clocks-search.md b/.changeset/fifty-clocks-search.md new file mode 100644 index 00000000000..88c853f7b51 --- /dev/null +++ b/.changeset/fifty-clocks-search.md @@ -0,0 +1,5 @@ +--- +"@effect/experimental": minor +--- + +Change from `ioredis` package to `redis` package for redis persistence layer. diff --git a/packages/experimental/package.json b/packages/experimental/package.json index 0d994a059b5..21130ed6eb8 100644 --- a/packages/experimental/package.json +++ b/packages/experimental/package.json @@ -51,11 +51,11 @@ "peerDependencies": { "@effect/platform": "workspace:^", "effect": "workspace:^", - "ioredis": "^5", + "redis": "^5", "lmdb": "^3" }, "peerDependenciesMeta": { - "ioredis": { + "redis": { "optional": true }, "lmdb": { @@ -66,7 +66,7 @@ "@cloudflare/workers-types": "^4.20250515.0", "@effect/platform-node": "workspace:^", "@types/ws": "^8.18.1", - "ioredis": "^5.6.1", + "redis": "^5.8.3", "lmdb": "^3.3.0" } } diff --git a/packages/experimental/src/Persistence/Redis.ts b/packages/experimental/src/Persistence/Redis.ts index 5beab532915..5a3ede7bae5 100644 --- a/packages/experimental/src/Persistence/Redis.ts +++ b/packages/experimental/src/Persistence/Redis.ts @@ -9,18 +9,18 @@ import * as Effect from "effect/Effect" import { identity } from "effect/Function" import * as Layer from "effect/Layer" import * as Option from "effect/Option" -import type { RedisOptions } from "ioredis" -import { Redis } from "ioredis" +import type { RedisClientOptions } from "redis" +import { createClient } from "redis" import * as Persistence from "../Persistence.js" /** * @since 1.0.0 * @category constructors */ -export const make = Effect.fnUntraced(function*(options: RedisOptions) { +export const make = Effect.fnUntraced(function*(options: RedisClientOptions) { const redis = yield* Effect.acquireRelease( - Effect.sync(() => new Redis(options)), - (redis) => Effect.promise(() => redis.quit()) + Effect.promise(() => createClient(options).connect()), + (redis) => Effect.sync(() => redis.destroy()) ) return Persistence.BackingPersistence.of({ [Persistence.BackingPersistenceTypeId]: Persistence.BackingPersistenceTypeId, @@ -48,7 +48,7 @@ export const make = Effect.fnUntraced(function*(options: RedisOptions) { getMany: (keys) => Effect.flatMap( Effect.tryPromise({ - try: () => redis.mget(keys.map(prefixed)), + try: () => redis.mGet(keys.map(prefixed)), catch: (error) => Persistence.PersistenceBackingError.make("getMany", error) }), Effect.forEach(parse("getMany")) @@ -63,7 +63,9 @@ export const make = Effect.fnUntraced(function*(options: RedisOptions) { try: (value) => ttl._tag === "None" ? redis.set(prefixed(key), value) - : redis.set(prefixed(key), value, "PX", Duration.toMillis(ttl.value)), + : redis.set(prefixed(key), value, { + expiration: { type: "PX", value: Duration.toMillis(ttl.value) } + }), catch: (error) => Persistence.PersistenceBackingError.make("set", error) } ), @@ -79,9 +81,9 @@ export const make = Effect.fnUntraced(function*(options: RedisOptions) { } } const multi = redis.multi() - multi.mset(sets) + multi.mSet(Object.fromEntries(sets)) for (const [key, ms] of expires) { - multi.pexpire(key, ms) + multi.pExpire(key, ms) } return Effect.tryPromise({ try: () => multi.exec(), @@ -107,7 +109,7 @@ export const make = Effect.fnUntraced(function*(options: RedisOptions) { * @category layers */ export const layer = ( - options: RedisOptions + options: RedisClientOptions ): Layer.Layer => Layer.scoped( Persistence.BackingPersistence, @@ -119,7 +121,7 @@ export const layer = ( * @category layers */ export const layerConfig = ( - options: Config.Config.Wrap + options: Config.Config.Wrap ): Layer.Layer => Layer.scoped( Persistence.BackingPersistence, @@ -131,7 +133,7 @@ export const layerConfig = ( * @category layers */ export const layerResult = ( - options: RedisOptions + options: RedisClientOptions ): Layer.Layer => Persistence.layerResult.pipe( Layer.provide(layer(options)) @@ -142,7 +144,7 @@ export const layerResult = ( * @category layers */ export const layerResultConfig = ( - options: Config.Config.Wrap + options: Config.Config.Wrap ): Layer.Layer => Persistence.layerResult.pipe( Layer.provide(layerConfig(options)) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 330986cad2a..325cc0df226 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -422,12 +422,12 @@ importers: '@types/ws': specifier: ^8.18.1 version: 8.18.1 - ioredis: - specifier: ^5.6.1 - version: 5.6.1 lmdb: specifier: ^3.3.0 version: 3.4.1 + redis: + specifier: ^5.8.3 + version: 5.8.3 publishDirectory: dist packages/opentelemetry: @@ -2010,9 +2010,6 @@ packages: cpu: [x64] os: [win32] - '@ioredis/commands@1.2.0': - resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} - '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -2510,6 +2507,34 @@ packages: '@types/react': optional: true + '@redis/bloom@5.8.3': + resolution: {integrity: sha512-1eldTzHvdW3Oi0TReb8m1yiFt8ZwyF6rv1NpZyG5R4TpCwuAdKQetBKoCw7D96tNFgsVVd6eL+NaGZZCqhRg4g==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.3 + + '@redis/client@5.8.3': + resolution: {integrity: sha512-MZVUE+l7LmMIYlIjubPosruJ9ltSLGFmJqsXApTqPLyHLjsJUSAbAJb/A3N34fEqean4ddiDkdWzNu4ZKPvRUg==} + engines: {node: '>= 18'} + + '@redis/json@5.8.3': + resolution: {integrity: sha512-DRR09fy/u8gynHGJ4gzXYeM7D8nlS6EMv5o+h20ndTJiAc7RGR01fdk2FNjnn1Nz5PjgGGownF+s72bYG4nZKQ==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.3 + + '@redis/search@5.8.3': + resolution: {integrity: sha512-EMIvEeGRR2I0BJEz4PV88DyCuPmMT1rDtznlsHY3cKSDcc9vj0Q411jUnX0iU2vVowUgWn/cpySKjpXdZ8m+5g==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.3 + + '@redis/time-series@5.8.3': + resolution: {integrity: sha512-5Jwy3ilsUYQjzpE7WZ1lEeG1RkqQ5kHtwV1p8yxXHSEmyUbC/T/AVgyjMcm52Olj/Ov/mhDKjx6ndYUi14bXsw==} + engines: {node: '>= 18'} + peerDependencies: + '@redis/client': ^5.8.3 + '@rollup/rollup-android-arm-eabi@4.45.1': resolution: {integrity: sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==} cpu: [arm] @@ -4619,10 +4644,6 @@ packages: peerDependencies: fp-ts: ^2.5.0 - ioredis@5.6.1: - resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} - engines: {node: '>=12.22.0'} - is-alphabetical@1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} @@ -5090,15 +5111,9 @@ packages: lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - lodash.isarguments@3.1.0: - resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - lodash.isboolean@3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} @@ -5915,13 +5930,9 @@ packages: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} - redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} - - redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} + redis@5.8.3: + resolution: {integrity: sha512-MfSrfV6+tEfTw8c4W0yFp6XWX8Il4laGU7Bx4kvW4uiYM1AuZ3KGqEGt1LdQHeD1nEyLpIWetZ/SpY3kkbgrYw==} + engines: {node: '>= 18'} reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} @@ -6237,9 +6248,6 @@ packages: resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} engines: {node: '>=6'} - standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -7906,8 +7914,6 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true - '@ioredis/commands@1.2.0': {} - '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -8421,6 +8427,26 @@ snapshots: optionalDependencies: '@types/react': 19.1.8 + '@redis/bloom@5.8.3(@redis/client@5.8.3)': + dependencies: + '@redis/client': 5.8.3 + + '@redis/client@5.8.3': + dependencies: + cluster-key-slot: 1.1.2 + + '@redis/json@5.8.3(@redis/client@5.8.3)': + dependencies: + '@redis/client': 5.8.3 + + '@redis/search@5.8.3(@redis/client@5.8.3)': + dependencies: + '@redis/client': 5.8.3 + + '@redis/time-series@5.8.3(@redis/client@5.8.3)': + dependencies: + '@redis/client': 5.8.3 + '@rollup/rollup-android-arm-eabi@4.45.1': optional: true @@ -10755,20 +10781,6 @@ snapshots: dependencies: fp-ts: 2.16.10 - ioredis@5.6.1: - dependencies: - '@ioredis/commands': 1.2.0 - cluster-key-slot: 1.1.2 - debug: 4.4.1 - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - is-alphabetical@1.0.4: {} is-alphanumerical@1.0.4: @@ -11286,12 +11298,8 @@ snapshots: lodash.camelcase@4.3.0: {} - lodash.defaults@4.2.0: {} - lodash.includes@4.3.0: {} - lodash.isarguments@3.1.0: {} - lodash.isboolean@3.0.3: {} lodash.isinteger@4.0.4: {} @@ -12299,11 +12307,13 @@ snapshots: tiny-invariant: 1.3.3 tslib: 2.8.1 - redis-errors@1.2.0: {} - - redis-parser@3.0.0: + redis@5.8.3: dependencies: - redis-errors: 1.2.0 + '@redis/bloom': 5.8.3(@redis/client@5.8.3) + '@redis/client': 5.8.3 + '@redis/json': 5.8.3(@redis/client@5.8.3) + '@redis/search': 5.8.3(@redis/client@5.8.3) + '@redis/time-series': 5.8.3(@redis/client@5.8.3) reflect.getprototypeof@1.0.10: dependencies: @@ -12670,8 +12680,6 @@ snapshots: dependencies: type-fest: 0.7.1 - standard-as-callback@2.1.0: {} - statuses@1.5.0: {} statuses@2.0.1: {}