@walkeros/server-destination-redis 3.4.0-next-1776749829492

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/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # @walkeros/server-destination-redis
2
+
3
+ Server-side Redis Streams destination for
4
+ [walkerOS](https://github.com/elbwalker/walkerOS). Appends events to a Redis
5
+ Stream via `ioredis` XADD, with optional MAXLEN trimming, JSON or flat
6
+ serialization, and graceful shutdown.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @walkeros/server-destination-redis
12
+ ```
13
+
14
+ ## Quick Start
15
+
16
+ ```json
17
+ {
18
+ "destinations": {
19
+ "redis": {
20
+ "package": "@walkeros/server-destination-redis",
21
+ "config": {
22
+ "settings": {
23
+ "redis": {
24
+ "streamKey": "walkeros:events",
25
+ "url": "redis://localhost:6379"
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ ## Settings
35
+
36
+ | Setting | Type | Required | Default | Description |
37
+ | --------------------- | -------------------- | -------- | -------- | --------------------------------------------------------------- |
38
+ | `redis.streamKey` | `string` | Yes | -- | Redis stream key name |
39
+ | `redis.url` | `string` | No | -- | Redis connection URL (`redis://` or `rediss://`) |
40
+ | `redis.options` | `RedisClientOptions` | No | -- | ioredis connection options (host, port, password, db, tls, ...) |
41
+ | `redis.maxLen` | `number` | No | -- | Max stream length (approximate MAXLEN trimming) |
42
+ | `redis.exactTrimming` | `boolean` | No | `false` | Use exact MAXLEN instead of approximate |
43
+ | `redis.serialization` | `'json' \| 'flat'` | No | `'json'` | Event serialization mode |
44
+
45
+ ## Per-rule mapping overrides
46
+
47
+ | Setting | Type | Description |
48
+ | ---------------------------- | -------- | --------------------------------- |
49
+ | `mapping.settings.streamKey` | `string` | Override stream key for this rule |
50
+
51
+ ## Serialization Modes
52
+
53
+ - **`json`** (default): Stores the full event as a single `event` field with a
54
+ JSON string value. Preserves nested structure, easy to deserialize downstream.
55
+ - **`flat`**: Stores top-level event fields as separate stream entry fields.
56
+ Nested objects are JSON-encoded. Useful for XREAD filtering on specific
57
+ fields.
58
+
59
+ ## Shutdown
60
+
61
+ The destination calls `quit()` on the Redis client during `destroy()`, ensuring
62
+ all in-flight XADD commands complete. User-provided clients are not closed.
63
+
64
+ ## Providers
65
+
66
+ Works with any Redis 5.0+ server supporting Streams: Redis Cloud, Upstash,
67
+ ElastiCache, MemoryDB, Azure Cache, Memorystore, self-hosted.
package/dist/dev.d.mts ADDED
@@ -0,0 +1,196 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer } from '@walkeros/server-core';
4
+ import { Flow } from '@walkeros/core';
5
+
6
+ declare const RedisSettingsSchema: z.ZodObject<{
7
+ streamKey: z.ZodString;
8
+ url: z.ZodOptional<z.ZodString>;
9
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
10
+ maxLen: z.ZodOptional<z.ZodNumber>;
11
+ exactTrimming: z.ZodOptional<z.ZodBoolean>;
12
+ serialization: z.ZodOptional<z.ZodEnum<{
13
+ json: "json";
14
+ flat: "flat";
15
+ }>>;
16
+ }, z.core.$strip>;
17
+ declare const SettingsSchema: z.ZodObject<{
18
+ redis: z.ZodObject<{
19
+ streamKey: z.ZodString;
20
+ url: z.ZodOptional<z.ZodString>;
21
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
22
+ maxLen: z.ZodOptional<z.ZodNumber>;
23
+ exactTrimming: z.ZodOptional<z.ZodBoolean>;
24
+ serialization: z.ZodOptional<z.ZodEnum<{
25
+ json: "json";
26
+ flat: "flat";
27
+ }>>;
28
+ }, z.core.$strip>;
29
+ }, z.core.$strip>;
30
+ type Settings$1 = z.infer<typeof SettingsSchema>;
31
+
32
+ declare const MappingSchema: z.ZodObject<{
33
+ streamKey: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strip>;
35
+ type Mapping = z.infer<typeof MappingSchema>;
36
+
37
+ declare const settings: _walkeros_core_dev.JSONSchema;
38
+ declare const mapping: _walkeros_core_dev.JSONSchema;
39
+
40
+ type index$1_Mapping = Mapping;
41
+ declare const index$1_MappingSchema: typeof MappingSchema;
42
+ declare const index$1_RedisSettingsSchema: typeof RedisSettingsSchema;
43
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
44
+ declare const index$1_mapping: typeof mapping;
45
+ declare const index$1_settings: typeof settings;
46
+ declare namespace index$1 {
47
+ export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, index$1_RedisSettingsSchema as RedisSettingsSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
48
+ }
49
+
50
+ /**
51
+ * Arguments passed to Redis XADD. Strings or numbers (for MAXLEN counts).
52
+ */
53
+ type XaddArg = string | number;
54
+ /**
55
+ * Mock-friendly Redis pipeline interface. Accumulates commands and
56
+ * executes them with a single round-trip via exec().
57
+ */
58
+ interface RedisPipelineMock {
59
+ xadd: (...args: XaddArg[]) => RedisPipelineMock;
60
+ exec: () => Promise<Array<[Error | null, unknown]> | null>;
61
+ }
62
+ /**
63
+ * Mock-friendly Redis client interface used by the destination.
64
+ * Tests provide this via env.Redis; production creates a real ioredis
65
+ * client and uses it directly.
66
+ */
67
+ interface RedisClientMock {
68
+ xadd: (...args: XaddArg[]) => Promise<string | null>;
69
+ pipeline: () => RedisPipelineMock;
70
+ quit: () => Promise<string>;
71
+ on?: (event: string, listener: (...args: unknown[]) => void) => unknown;
72
+ }
73
+ /**
74
+ * Constructor signature for the Redis client. Accepts either a URL
75
+ * string or an options object, matching ioredis's dual signature.
76
+ */
77
+ interface RedisClientConstructor {
78
+ new (url: string): RedisClientMock;
79
+ new (options: RedisClientOptions): RedisClientMock;
80
+ }
81
+ /**
82
+ * Minimal ioredis options subset the destination passes through.
83
+ * Unknown options are preserved for the SDK to handle.
84
+ */
85
+ interface RedisClientOptions {
86
+ host?: string;
87
+ port?: number;
88
+ username?: string;
89
+ password?: string;
90
+ db?: number;
91
+ tls?: boolean | Record<string, unknown>;
92
+ connectTimeout?: number;
93
+ commandTimeout?: number;
94
+ [key: string]: unknown;
95
+ }
96
+ type SerializationMode = 'json' | 'flat';
97
+ interface RedisSettings {
98
+ /** Redis stream key name (e.g. 'walkeros:events'). */
99
+ streamKey: string;
100
+ /** Redis connection URL (e.g. 'redis://localhost:6379' or 'rediss://...'). */
101
+ url?: string;
102
+ /** ioredis connection options (used if no url provided). */
103
+ options?: RedisClientOptions;
104
+ /**
105
+ * Maximum stream length. Enables MAXLEN trimming on every XADD.
106
+ * Uses approximate (~) trimming by default for performance.
107
+ * Omit for unlimited stream length.
108
+ */
109
+ maxLen?: number;
110
+ /**
111
+ * Use exact MAXLEN instead of approximate (~).
112
+ * Not recommended for production -- significantly slower.
113
+ * Default: false (approximate trimming).
114
+ */
115
+ exactTrimming?: boolean;
116
+ /**
117
+ * Serialization mode for the event payload.
118
+ * - 'json': Single 'event' field with JSON string (default)
119
+ * - 'flat': Top-level event fields as separate stream fields
120
+ */
121
+ serialization?: SerializationMode;
122
+ _client?: RedisClientMock;
123
+ _ownedClient?: boolean;
124
+ }
125
+ interface Settings {
126
+ redis: RedisSettings;
127
+ }
128
+ /**
129
+ * Env -- optional Redis SDK override. Production leaves this undefined
130
+ * and the destination creates real ioredis client instances. Tests provide
131
+ * mocks via env.Redis.
132
+ */
133
+ interface Env extends DestinationServer.Env {
134
+ Redis?: {
135
+ Client: RedisClientConstructor;
136
+ };
137
+ }
138
+
139
+ declare const push: Env;
140
+ declare const simulation: string[];
141
+
142
+ declare const env_push: typeof push;
143
+ declare const env_simulation: typeof simulation;
144
+ declare namespace env {
145
+ export { env_push as push, env_simulation as simulation };
146
+ }
147
+
148
+ /**
149
+ * Extended step example that may carry destination-level settings overrides.
150
+ */
151
+ type RedisStepExample = Flow.StepExample & {
152
+ settings?: Partial<Settings>;
153
+ };
154
+ /**
155
+ * Default JSON serialization -- single 'event' field with full event JSON.
156
+ */
157
+ declare const jsonDefault: RedisStepExample;
158
+ /**
159
+ * Order event -- verifies different event types pass through correctly.
160
+ */
161
+ declare const orderComplete: RedisStepExample;
162
+ /**
163
+ * With MAXLEN approximate trimming -- trimming args inserted before '*'.
164
+ */
165
+ declare const withMaxLen: RedisStepExample;
166
+ /**
167
+ * Exact MAXLEN trimming -- no '~' between MAXLEN and the count.
168
+ */
169
+ declare const withExactTrim: RedisStepExample;
170
+ /**
171
+ * Stream key override per rule -- routes this event to a dedicated stream.
172
+ */
173
+ declare const streamKeyOverride: RedisStepExample;
174
+ /**
175
+ * Ignored event -- mapping.ignore: true produces no xadd call.
176
+ */
177
+ declare const ignoredEvent: RedisStepExample;
178
+
179
+ type step_RedisStepExample = RedisStepExample;
180
+ declare const step_ignoredEvent: typeof ignoredEvent;
181
+ declare const step_jsonDefault: typeof jsonDefault;
182
+ declare const step_orderComplete: typeof orderComplete;
183
+ declare const step_streamKeyOverride: typeof streamKeyOverride;
184
+ declare const step_withExactTrim: typeof withExactTrim;
185
+ declare const step_withMaxLen: typeof withMaxLen;
186
+ declare namespace step {
187
+ export { type step_RedisStepExample as RedisStepExample, step_ignoredEvent as ignoredEvent, step_jsonDefault as jsonDefault, step_orderComplete as orderComplete, step_streamKeyOverride as streamKeyOverride, step_withExactTrim as withExactTrim, step_withMaxLen as withMaxLen };
188
+ }
189
+
190
+ declare const index_env: typeof env;
191
+ declare const index_step: typeof step;
192
+ declare namespace index {
193
+ export { index_env as env, index_step as step };
194
+ }
195
+
196
+ export { index as examples, index$1 as schemas };
package/dist/dev.d.ts ADDED
@@ -0,0 +1,196 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer } from '@walkeros/server-core';
4
+ import { Flow } from '@walkeros/core';
5
+
6
+ declare const RedisSettingsSchema: z.ZodObject<{
7
+ streamKey: z.ZodString;
8
+ url: z.ZodOptional<z.ZodString>;
9
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
10
+ maxLen: z.ZodOptional<z.ZodNumber>;
11
+ exactTrimming: z.ZodOptional<z.ZodBoolean>;
12
+ serialization: z.ZodOptional<z.ZodEnum<{
13
+ json: "json";
14
+ flat: "flat";
15
+ }>>;
16
+ }, z.core.$strip>;
17
+ declare const SettingsSchema: z.ZodObject<{
18
+ redis: z.ZodObject<{
19
+ streamKey: z.ZodString;
20
+ url: z.ZodOptional<z.ZodString>;
21
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
22
+ maxLen: z.ZodOptional<z.ZodNumber>;
23
+ exactTrimming: z.ZodOptional<z.ZodBoolean>;
24
+ serialization: z.ZodOptional<z.ZodEnum<{
25
+ json: "json";
26
+ flat: "flat";
27
+ }>>;
28
+ }, z.core.$strip>;
29
+ }, z.core.$strip>;
30
+ type Settings$1 = z.infer<typeof SettingsSchema>;
31
+
32
+ declare const MappingSchema: z.ZodObject<{
33
+ streamKey: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strip>;
35
+ type Mapping = z.infer<typeof MappingSchema>;
36
+
37
+ declare const settings: _walkeros_core_dev.JSONSchema;
38
+ declare const mapping: _walkeros_core_dev.JSONSchema;
39
+
40
+ type index$1_Mapping = Mapping;
41
+ declare const index$1_MappingSchema: typeof MappingSchema;
42
+ declare const index$1_RedisSettingsSchema: typeof RedisSettingsSchema;
43
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
44
+ declare const index$1_mapping: typeof mapping;
45
+ declare const index$1_settings: typeof settings;
46
+ declare namespace index$1 {
47
+ export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, index$1_RedisSettingsSchema as RedisSettingsSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
48
+ }
49
+
50
+ /**
51
+ * Arguments passed to Redis XADD. Strings or numbers (for MAXLEN counts).
52
+ */
53
+ type XaddArg = string | number;
54
+ /**
55
+ * Mock-friendly Redis pipeline interface. Accumulates commands and
56
+ * executes them with a single round-trip via exec().
57
+ */
58
+ interface RedisPipelineMock {
59
+ xadd: (...args: XaddArg[]) => RedisPipelineMock;
60
+ exec: () => Promise<Array<[Error | null, unknown]> | null>;
61
+ }
62
+ /**
63
+ * Mock-friendly Redis client interface used by the destination.
64
+ * Tests provide this via env.Redis; production creates a real ioredis
65
+ * client and uses it directly.
66
+ */
67
+ interface RedisClientMock {
68
+ xadd: (...args: XaddArg[]) => Promise<string | null>;
69
+ pipeline: () => RedisPipelineMock;
70
+ quit: () => Promise<string>;
71
+ on?: (event: string, listener: (...args: unknown[]) => void) => unknown;
72
+ }
73
+ /**
74
+ * Constructor signature for the Redis client. Accepts either a URL
75
+ * string or an options object, matching ioredis's dual signature.
76
+ */
77
+ interface RedisClientConstructor {
78
+ new (url: string): RedisClientMock;
79
+ new (options: RedisClientOptions): RedisClientMock;
80
+ }
81
+ /**
82
+ * Minimal ioredis options subset the destination passes through.
83
+ * Unknown options are preserved for the SDK to handle.
84
+ */
85
+ interface RedisClientOptions {
86
+ host?: string;
87
+ port?: number;
88
+ username?: string;
89
+ password?: string;
90
+ db?: number;
91
+ tls?: boolean | Record<string, unknown>;
92
+ connectTimeout?: number;
93
+ commandTimeout?: number;
94
+ [key: string]: unknown;
95
+ }
96
+ type SerializationMode = 'json' | 'flat';
97
+ interface RedisSettings {
98
+ /** Redis stream key name (e.g. 'walkeros:events'). */
99
+ streamKey: string;
100
+ /** Redis connection URL (e.g. 'redis://localhost:6379' or 'rediss://...'). */
101
+ url?: string;
102
+ /** ioredis connection options (used if no url provided). */
103
+ options?: RedisClientOptions;
104
+ /**
105
+ * Maximum stream length. Enables MAXLEN trimming on every XADD.
106
+ * Uses approximate (~) trimming by default for performance.
107
+ * Omit for unlimited stream length.
108
+ */
109
+ maxLen?: number;
110
+ /**
111
+ * Use exact MAXLEN instead of approximate (~).
112
+ * Not recommended for production -- significantly slower.
113
+ * Default: false (approximate trimming).
114
+ */
115
+ exactTrimming?: boolean;
116
+ /**
117
+ * Serialization mode for the event payload.
118
+ * - 'json': Single 'event' field with JSON string (default)
119
+ * - 'flat': Top-level event fields as separate stream fields
120
+ */
121
+ serialization?: SerializationMode;
122
+ _client?: RedisClientMock;
123
+ _ownedClient?: boolean;
124
+ }
125
+ interface Settings {
126
+ redis: RedisSettings;
127
+ }
128
+ /**
129
+ * Env -- optional Redis SDK override. Production leaves this undefined
130
+ * and the destination creates real ioredis client instances. Tests provide
131
+ * mocks via env.Redis.
132
+ */
133
+ interface Env extends DestinationServer.Env {
134
+ Redis?: {
135
+ Client: RedisClientConstructor;
136
+ };
137
+ }
138
+
139
+ declare const push: Env;
140
+ declare const simulation: string[];
141
+
142
+ declare const env_push: typeof push;
143
+ declare const env_simulation: typeof simulation;
144
+ declare namespace env {
145
+ export { env_push as push, env_simulation as simulation };
146
+ }
147
+
148
+ /**
149
+ * Extended step example that may carry destination-level settings overrides.
150
+ */
151
+ type RedisStepExample = Flow.StepExample & {
152
+ settings?: Partial<Settings>;
153
+ };
154
+ /**
155
+ * Default JSON serialization -- single 'event' field with full event JSON.
156
+ */
157
+ declare const jsonDefault: RedisStepExample;
158
+ /**
159
+ * Order event -- verifies different event types pass through correctly.
160
+ */
161
+ declare const orderComplete: RedisStepExample;
162
+ /**
163
+ * With MAXLEN approximate trimming -- trimming args inserted before '*'.
164
+ */
165
+ declare const withMaxLen: RedisStepExample;
166
+ /**
167
+ * Exact MAXLEN trimming -- no '~' between MAXLEN and the count.
168
+ */
169
+ declare const withExactTrim: RedisStepExample;
170
+ /**
171
+ * Stream key override per rule -- routes this event to a dedicated stream.
172
+ */
173
+ declare const streamKeyOverride: RedisStepExample;
174
+ /**
175
+ * Ignored event -- mapping.ignore: true produces no xadd call.
176
+ */
177
+ declare const ignoredEvent: RedisStepExample;
178
+
179
+ type step_RedisStepExample = RedisStepExample;
180
+ declare const step_ignoredEvent: typeof ignoredEvent;
181
+ declare const step_jsonDefault: typeof jsonDefault;
182
+ declare const step_orderComplete: typeof orderComplete;
183
+ declare const step_streamKeyOverride: typeof streamKeyOverride;
184
+ declare const step_withExactTrim: typeof withExactTrim;
185
+ declare const step_withMaxLen: typeof withMaxLen;
186
+ declare namespace step {
187
+ export { type step_RedisStepExample as RedisStepExample, step_ignoredEvent as ignoredEvent, step_jsonDefault as jsonDefault, step_orderComplete as orderComplete, step_streamKeyOverride as streamKeyOverride, step_withExactTrim as withExactTrim, step_withMaxLen as withMaxLen };
188
+ }
189
+
190
+ declare const index_env: typeof env;
191
+ declare const index_step: typeof step;
192
+ declare namespace index {
193
+ export { index_env as env, index_step as step };
194
+ }
195
+
196
+ export { index as examples, index$1 as schemas };
package/dist/dev.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,i=(e,r)=>{for(var s in r)t(e,s,{get:r[s],enumerable:!0})},n={};i(n,{examples:()=>w,schemas:()=>a}),module.exports=(e=n,((e,i,n,a)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let d of s(i))o.call(e,d)||d===n||t(e,d,{get:()=>i[d],enumerable:!(a=r(i,d))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};i(a,{MappingSchema:()=>v,RedisSettingsSchema:()=>m,SettingsSchema:()=>c,mapping:()=>g,settings:()=>u});var d=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),m=l.z.object({streamKey:l.z.string().min(1).describe("Redis stream key name (like 'walkeros:events'). All events are appended to this stream via XADD."),url:l.z.string().describe("Redis connection URL (like 'redis://localhost:6379' or 'rediss://:password@host:6380'). Supports redis:// and rediss:// (TLS) protocols.").optional(),options:l.z.record(l.z.string(),l.z.unknown()).describe("ioredis connection options. Used when url is not provided. Supports host, port, password, db, tls, and all other ioredis options.").optional(),maxLen:l.z.number().int().positive().describe("Maximum stream length. Enables approximate MAXLEN trimming on every XADD to bound memory usage (like 50000).").optional(),exactTrimming:l.z.boolean().describe("Use exact MAXLEN instead of approximate (~). Not recommended for production. Default: false.").optional(),serialization:l.z.enum(["json","flat"]).describe("Serialization mode. 'json' stores the full event as a single 'event' field (default). 'flat' stores top-level event fields as separate stream entry fields.").optional()}),c=l.z.object({redis:m.describe("Redis Streams configuration (like { streamKey: 'walkeros:events', url: 'redis://localhost:6379' })")}),p=require("@walkeros/core/dev"),v=p.z.object({streamKey:p.z.string().optional().describe("Override Redis stream key for this rule. Takes precedence over settings.redis.streamKey.")}),u=(0,d.zodToSchema)(c),g=(0,d.zodToSchema)(v),w={};i(w,{env:()=>b,step:()=>y});var b={};i(b,{push:()=>k,simulation:()=>x});var f=()=>Promise.resolve("1700000100000-0"),h=()=>Promise.resolve("OK");var k={Redis:{Client:class{constructor(e){this.xadd=f,this.quit=h}pipeline(){return function(){const e={xadd:()=>e,exec:()=>Promise.resolve([])};return e}()}on(){return this}}}},x=["call:client.xadd"],y={};i(y,{ignoredEvent:()=>L,jsonDefault:()=>z,orderComplete:()=>E,streamKeyOverride:()=>K,withExactTrim:()=>O,withMaxLen:()=>S});var j=require("@walkeros/core"),z={in:(0,j.getEvent)("page view",{timestamp:1700000100}),out:[["client.xadd",["walkeros:events","*","event","json:event"]]]},E={in:(0,j.getEvent)("order complete",{timestamp:1700000101,data:{id:"ORD-400",total:99.99,currency:"EUR"}}),out:[["client.xadd",["walkeros:events","*","event","json:event"]]]},S={in:(0,j.getEvent)("product view",{timestamp:1700000102,data:{id:"SKU-123",name:"Widget"}}),settings:{redis:{streamKey:"walkeros:events",maxLen:5e4}},out:[["client.xadd",["walkeros:events","MAXLEN","~",5e4,"*","event","json:event"]]]},O={in:(0,j.getEvent)("page view",{timestamp:1700000103}),settings:{redis:{streamKey:"walkeros:events",maxLen:5e3,exactTrimming:!0}},out:[["client.xadd",["walkeros:events","MAXLEN",5e3,"*","event","json:event"]]]},K={in:(0,j.getEvent)("order complete",{timestamp:1700000104,data:{id:"ORD-500",total:42}}),mapping:{settings:{streamKey:"walkeros:orders"}},out:[["client.xadd",["walkeros:orders","*","event","json:event"]]]},L={in:(0,j.getEvent)("debug noise",{timestamp:1700000105}),mapping:{ignore:!0},out:[]};//# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, RedisSettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const RedisSettingsSchema = z.object({\n streamKey: z\n .string()\n .min(1)\n .describe(\n \"Redis stream key name (like 'walkeros:events'). All events are appended to this stream via XADD.\",\n ),\n url: z\n .string()\n .describe(\n \"Redis connection URL (like 'redis://localhost:6379' or 'rediss://:password@host:6380'). Supports redis:// and rediss:// (TLS) protocols.\",\n )\n .optional(),\n options: z\n .record(z.string(), z.unknown())\n .describe(\n 'ioredis connection options. Used when url is not provided. Supports host, port, password, db, tls, and all other ioredis options.',\n )\n .optional(),\n maxLen: z\n .number()\n .int()\n .positive()\n .describe(\n 'Maximum stream length. Enables approximate MAXLEN trimming on every XADD to bound memory usage (like 50000).',\n )\n .optional(),\n exactTrimming: z\n .boolean()\n .describe(\n 'Use exact MAXLEN instead of approximate (~). Not recommended for production. Default: false.',\n )\n .optional(),\n serialization: z\n .enum(['json', 'flat'])\n .describe(\n \"Serialization mode. 'json' stores the full event as a single 'event' field (default). 'flat' stores top-level event fields as separate stream entry fields.\",\n )\n .optional(),\n});\n\nexport const SettingsSchema = z.object({\n redis: RedisSettingsSchema.describe(\n \"Redis Streams configuration (like { streamKey: 'walkeros:events', url: 'redis://localhost:6379' })\",\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n streamKey: z\n .string()\n .optional()\n .describe(\n 'Override Redis stream key for this rule. Takes precedence over settings.redis.streamKey.',\n ),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n Env,\n RedisClientConstructor,\n RedisClientMock,\n RedisPipelineMock,\n XaddArg,\n} from '../types';\n\n// Narrow helper type aliases so the mock SDK is typed explicitly without `any`.\ntype XaddFn = (...args: XaddArg[]) => Promise<string | null>;\ntype QuitFn = () => Promise<string>;\n\nconst asyncXadd: XaddFn = () => Promise.resolve('1700000100000-0');\nconst asyncQuit: QuitFn = () => Promise.resolve('OK');\n\nfunction createMockPipeline(): RedisPipelineMock {\n const pipeline: RedisPipelineMock = {\n xadd: () => pipeline,\n exec: () => Promise.resolve([]),\n };\n return pipeline;\n}\n\nclass MockRedisClient implements RedisClientMock {\n constructor(_urlOrOptions: string | Record<string, unknown>) {}\n xadd: XaddFn = asyncXadd;\n pipeline(): RedisPipelineMock {\n return createMockPipeline();\n }\n quit: QuitFn = asyncQuit;\n on(): unknown {\n return this;\n }\n}\n\nconst MockRedisConstructor: RedisClientConstructor = MockRedisClient;\n\nexport const push: Env = {\n Redis: {\n Client: MockRedisConstructor,\n },\n};\n\nexport const simulation = ['call:client.xadd'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type RedisStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Default JSON serialization -- single 'event' field with full event JSON.\n */\nexport const jsonDefault: RedisStepExample = {\n in: getEvent('page view', {\n timestamp: 1700000100,\n }),\n out: [['client.xadd', ['walkeros:events', '*', 'event', 'json:event']]],\n};\n\n/**\n * Order event -- verifies different event types pass through correctly.\n */\nexport const orderComplete: RedisStepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000101,\n data: { id: 'ORD-400', total: 99.99, currency: 'EUR' },\n }),\n out: [['client.xadd', ['walkeros:events', '*', 'event', 'json:event']]],\n};\n\n/**\n * With MAXLEN approximate trimming -- trimming args inserted before '*'.\n */\nexport const withMaxLen: RedisStepExample = {\n in: getEvent('product view', {\n timestamp: 1700000102,\n data: { id: 'SKU-123', name: 'Widget' },\n }),\n settings: {\n redis: {\n streamKey: 'walkeros:events',\n maxLen: 50000,\n },\n },\n out: [\n [\n 'client.xadd',\n ['walkeros:events', 'MAXLEN', '~', 50000, '*', 'event', 'json:event'],\n ],\n ],\n};\n\n/**\n * Exact MAXLEN trimming -- no '~' between MAXLEN and the count.\n */\nexport const withExactTrim: RedisStepExample = {\n in: getEvent('page view', {\n timestamp: 1700000103,\n }),\n settings: {\n redis: {\n streamKey: 'walkeros:events',\n maxLen: 5000,\n exactTrimming: true,\n },\n },\n out: [\n [\n 'client.xadd',\n ['walkeros:events', 'MAXLEN', 5000, '*', 'event', 'json:event'],\n ],\n ],\n};\n\n/**\n * Stream key override per rule -- routes this event to a dedicated stream.\n */\nexport const streamKeyOverride: RedisStepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000104,\n data: { id: 'ORD-500', total: 42 },\n }),\n mapping: {\n settings: {\n streamKey: 'walkeros:orders',\n },\n },\n out: [['client.xadd', ['walkeros:orders', '*', 'event', 'json:event']]],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no xadd call.\n */\nexport const ignoredEvent: RedisStepExample = {\n in: getEvent('debug noise', {\n timestamp: 1700000105,\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,cAA4B;;;ACA5B,iBAAkB;AAEX,IAAM,sBAAsB,aAAE,OAAO;AAAA,EAC1C,WAAW,aACR,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,KAAK,aACF,OAAO,EACP;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,SAAS,aACN,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAC9B;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,QAAQ,aACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAe,aACZ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAe,aACZ,KAAK,CAAC,QAAQ,MAAM,CAAC,EACrB;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;AAEM,IAAM,iBAAiB,aAAE,OAAO;AAAA,EACrC,OAAO,oBAAoB;AAAA,IACzB;AAAA,EACF;AACF,CAAC;;;AC/CD,IAAAC,cAAkB;AAEX,IAAM,gBAAgB,cAAE,OAAO;AAAA,EACpC,WAAW,cACR,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;;;AFDM,IAAM,eAAW,yBAAY,cAAc;AAC3C,IAAM,cAAU,yBAAY,aAAa;;;AGThD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAYA,IAAM,YAAoB,MAAM,QAAQ,QAAQ,iBAAiB;AACjE,IAAM,YAAoB,MAAM,QAAQ,QAAQ,IAAI;AAEpD,SAAS,qBAAwC;AAC/C,QAAM,WAA8B;AAAA,IAClC,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAChC;AACA,SAAO;AACT;AAEA,IAAM,kBAAN,MAAiD;AAAA,EAC/C,YAAY,eAAiD;AAC7D,gBAAe;AAIf,gBAAe;AAAA,EAL+C;AAAA,EAE9D,WAA8B;AAC5B,WAAO,mBAAmB;AAAA,EAC5B;AAAA,EAEA,KAAc;AACZ,WAAO;AAAA,EACT;AACF;AAEA,IAAM,uBAA+C;AAE9C,IAAM,OAAY;AAAA,EACvB,OAAO;AAAA,IACL,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,aAAa,CAAC,kBAAkB;;;AC3C7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAyB;AAalB,IAAM,cAAgC;AAAA,EAC3C,QAAI,sBAAS,aAAa;AAAA,IACxB,WAAW;AAAA,EACb,CAAC;AAAA,EACD,KAAK,CAAC,CAAC,eAAe,CAAC,mBAAmB,KAAK,SAAS,YAAY,CAAC,CAAC;AACxE;AAKO,IAAM,gBAAkC;AAAA,EAC7C,QAAI,sBAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,WAAW,OAAO,OAAO,UAAU,MAAM;AAAA,EACvD,CAAC;AAAA,EACD,KAAK,CAAC,CAAC,eAAe,CAAC,mBAAmB,KAAK,SAAS,YAAY,CAAC,CAAC;AACxE;AAKO,IAAM,aAA+B;AAAA,EAC1C,QAAI,sBAAS,gBAAgB;AAAA,IAC3B,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,WAAW,MAAM,SAAS;AAAA,EACxC,CAAC;AAAA,EACD,UAAU;AAAA,IACR,OAAO;AAAA,MACL,WAAW;AAAA,MACX,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA,CAAC,mBAAmB,UAAU,KAAK,KAAO,KAAK,SAAS,YAAY;AAAA,IACtE;AAAA,EACF;AACF;AAKO,IAAM,gBAAkC;AAAA,EAC7C,QAAI,sBAAS,aAAa;AAAA,IACxB,WAAW;AAAA,EACb,CAAC;AAAA,EACD,UAAU;AAAA,IACR,OAAO;AAAA,MACL,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA,CAAC,mBAAmB,UAAU,KAAM,KAAK,SAAS,YAAY;AAAA,IAChE;AAAA,EACF;AACF;AAKO,IAAM,oBAAsC;AAAA,EACjD,QAAI,sBAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,WAAW,OAAO,GAAG;AAAA,EACnC,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EACA,KAAK,CAAC,CAAC,eAAe,CAAC,mBAAmB,KAAK,SAAS,YAAY,CAAC,CAAC;AACxE;AAKO,IAAM,eAAiC;AAAA,EAC5C,QAAI,sBAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,EACb,CAAC;AAAA,EACD,SAAS,EAAE,QAAQ,KAAK;AAAA,EACxB,KAAK,CAAC;AACR;","names":["import_dev","import_dev"]}
package/dist/dev.mjs ADDED
@@ -0,0 +1 @@
1
+ var e=Object.defineProperty,t=(t,s)=>{for(var r in s)e(t,r,{get:s[r],enumerable:!0})},s={};t(s,{MappingSchema:()=>d,RedisSettingsSchema:()=>i,SettingsSchema:()=>a,mapping:()=>m,settings:()=>l});import{zodToSchema as r}from"@walkeros/core/dev";import{z as o}from"@walkeros/core/dev";var i=o.object({streamKey:o.string().min(1).describe("Redis stream key name (like 'walkeros:events'). All events are appended to this stream via XADD."),url:o.string().describe("Redis connection URL (like 'redis://localhost:6379' or 'rediss://:password@host:6380'). Supports redis:// and rediss:// (TLS) protocols.").optional(),options:o.record(o.string(),o.unknown()).describe("ioredis connection options. Used when url is not provided. Supports host, port, password, db, tls, and all other ioredis options.").optional(),maxLen:o.number().int().positive().describe("Maximum stream length. Enables approximate MAXLEN trimming on every XADD to bound memory usage (like 50000).").optional(),exactTrimming:o.boolean().describe("Use exact MAXLEN instead of approximate (~). Not recommended for production. Default: false.").optional(),serialization:o.enum(["json","flat"]).describe("Serialization mode. 'json' stores the full event as a single 'event' field (default). 'flat' stores top-level event fields as separate stream entry fields.").optional()}),a=o.object({redis:i.describe("Redis Streams configuration (like { streamKey: 'walkeros:events', url: 'redis://localhost:6379' })")});import{z as n}from"@walkeros/core/dev";var d=n.object({streamKey:n.string().optional().describe("Override Redis stream key for this rule. Takes precedence over settings.redis.streamKey.")}),l=r(a),m=r(d),p={};t(p,{env:()=>c,step:()=>k});var c={};t(c,{push:()=>g,simulation:()=>w});var v=()=>Promise.resolve("1700000100000-0"),u=()=>Promise.resolve("OK");var g={Redis:{Client:class{constructor(e){this.xadd=v,this.quit=u}pipeline(){return function(){const e={xadd:()=>e,exec:()=>Promise.resolve([])};return e}()}on(){return this}}}},w=["call:client.xadd"],k={};t(k,{ignoredEvent:()=>S,jsonDefault:()=>f,orderComplete:()=>h,streamKeyOverride:()=>j,withExactTrim:()=>y,withMaxLen:()=>b});import{getEvent as x}from"@walkeros/core";var f={in:x("page view",{timestamp:1700000100}),out:[["client.xadd",["walkeros:events","*","event","json:event"]]]},h={in:x("order complete",{timestamp:1700000101,data:{id:"ORD-400",total:99.99,currency:"EUR"}}),out:[["client.xadd",["walkeros:events","*","event","json:event"]]]},b={in:x("product view",{timestamp:1700000102,data:{id:"SKU-123",name:"Widget"}}),settings:{redis:{streamKey:"walkeros:events",maxLen:5e4}},out:[["client.xadd",["walkeros:events","MAXLEN","~",5e4,"*","event","json:event"]]]},y={in:x("page view",{timestamp:1700000103}),settings:{redis:{streamKey:"walkeros:events",maxLen:5e3,exactTrimming:!0}},out:[["client.xadd",["walkeros:events","MAXLEN",5e3,"*","event","json:event"]]]},j={in:x("order complete",{timestamp:1700000104,data:{id:"ORD-500",total:42}}),mapping:{settings:{streamKey:"walkeros:orders"}},out:[["client.xadd",["walkeros:orders","*","event","json:event"]]]},S={in:x("debug noise",{timestamp:1700000105}),mapping:{ignore:!0},out:[]};export{p as examples,s as schemas};//# sourceMappingURL=dev.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, RedisSettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const RedisSettingsSchema = z.object({\n streamKey: z\n .string()\n .min(1)\n .describe(\n \"Redis stream key name (like 'walkeros:events'). All events are appended to this stream via XADD.\",\n ),\n url: z\n .string()\n .describe(\n \"Redis connection URL (like 'redis://localhost:6379' or 'rediss://:password@host:6380'). Supports redis:// and rediss:// (TLS) protocols.\",\n )\n .optional(),\n options: z\n .record(z.string(), z.unknown())\n .describe(\n 'ioredis connection options. Used when url is not provided. Supports host, port, password, db, tls, and all other ioredis options.',\n )\n .optional(),\n maxLen: z\n .number()\n .int()\n .positive()\n .describe(\n 'Maximum stream length. Enables approximate MAXLEN trimming on every XADD to bound memory usage (like 50000).',\n )\n .optional(),\n exactTrimming: z\n .boolean()\n .describe(\n 'Use exact MAXLEN instead of approximate (~). Not recommended for production. Default: false.',\n )\n .optional(),\n serialization: z\n .enum(['json', 'flat'])\n .describe(\n \"Serialization mode. 'json' stores the full event as a single 'event' field (default). 'flat' stores top-level event fields as separate stream entry fields.\",\n )\n .optional(),\n});\n\nexport const SettingsSchema = z.object({\n redis: RedisSettingsSchema.describe(\n \"Redis Streams configuration (like { streamKey: 'walkeros:events', url: 'redis://localhost:6379' })\",\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n streamKey: z\n .string()\n .optional()\n .describe(\n 'Override Redis stream key for this rule. Takes precedence over settings.redis.streamKey.',\n ),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n Env,\n RedisClientConstructor,\n RedisClientMock,\n RedisPipelineMock,\n XaddArg,\n} from '../types';\n\n// Narrow helper type aliases so the mock SDK is typed explicitly without `any`.\ntype XaddFn = (...args: XaddArg[]) => Promise<string | null>;\ntype QuitFn = () => Promise<string>;\n\nconst asyncXadd: XaddFn = () => Promise.resolve('1700000100000-0');\nconst asyncQuit: QuitFn = () => Promise.resolve('OK');\n\nfunction createMockPipeline(): RedisPipelineMock {\n const pipeline: RedisPipelineMock = {\n xadd: () => pipeline,\n exec: () => Promise.resolve([]),\n };\n return pipeline;\n}\n\nclass MockRedisClient implements RedisClientMock {\n constructor(_urlOrOptions: string | Record<string, unknown>) {}\n xadd: XaddFn = asyncXadd;\n pipeline(): RedisPipelineMock {\n return createMockPipeline();\n }\n quit: QuitFn = asyncQuit;\n on(): unknown {\n return this;\n }\n}\n\nconst MockRedisConstructor: RedisClientConstructor = MockRedisClient;\n\nexport const push: Env = {\n Redis: {\n Client: MockRedisConstructor,\n },\n};\n\nexport const simulation = ['call:client.xadd'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type RedisStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Default JSON serialization -- single 'event' field with full event JSON.\n */\nexport const jsonDefault: RedisStepExample = {\n in: getEvent('page view', {\n timestamp: 1700000100,\n }),\n out: [['client.xadd', ['walkeros:events', '*', 'event', 'json:event']]],\n};\n\n/**\n * Order event -- verifies different event types pass through correctly.\n */\nexport const orderComplete: RedisStepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000101,\n data: { id: 'ORD-400', total: 99.99, currency: 'EUR' },\n }),\n out: [['client.xadd', ['walkeros:events', '*', 'event', 'json:event']]],\n};\n\n/**\n * With MAXLEN approximate trimming -- trimming args inserted before '*'.\n */\nexport const withMaxLen: RedisStepExample = {\n in: getEvent('product view', {\n timestamp: 1700000102,\n data: { id: 'SKU-123', name: 'Widget' },\n }),\n settings: {\n redis: {\n streamKey: 'walkeros:events',\n maxLen: 50000,\n },\n },\n out: [\n [\n 'client.xadd',\n ['walkeros:events', 'MAXLEN', '~', 50000, '*', 'event', 'json:event'],\n ],\n ],\n};\n\n/**\n * Exact MAXLEN trimming -- no '~' between MAXLEN and the count.\n */\nexport const withExactTrim: RedisStepExample = {\n in: getEvent('page view', {\n timestamp: 1700000103,\n }),\n settings: {\n redis: {\n streamKey: 'walkeros:events',\n maxLen: 5000,\n exactTrimming: true,\n },\n },\n out: [\n [\n 'client.xadd',\n ['walkeros:events', 'MAXLEN', 5000, '*', 'event', 'json:event'],\n ],\n ],\n};\n\n/**\n * Stream key override per rule -- routes this event to a dedicated stream.\n */\nexport const streamKeyOverride: RedisStepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000104,\n data: { id: 'ORD-500', total: 42 },\n }),\n mapping: {\n settings: {\n streamKey: 'walkeros:orders',\n },\n },\n out: [['client.xadd', ['walkeros:orders', '*', 'event', 'json:event']]],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no xadd call.\n */\nexport const ignoredEvent: RedisStepExample = {\n in: getEvent('debug noise', {\n timestamp: 1700000105,\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["z"]}
@@ -0,0 +1,144 @@
1
+ import { DestinationServer } from '@walkeros/server-core';
2
+ import { Flow } from '@walkeros/core';
3
+
4
+ /**
5
+ * Arguments passed to Redis XADD. Strings or numbers (for MAXLEN counts).
6
+ */
7
+ type XaddArg = string | number;
8
+ /**
9
+ * Mock-friendly Redis pipeline interface. Accumulates commands and
10
+ * executes them with a single round-trip via exec().
11
+ */
12
+ interface RedisPipelineMock {
13
+ xadd: (...args: XaddArg[]) => RedisPipelineMock;
14
+ exec: () => Promise<Array<[Error | null, unknown]> | null>;
15
+ }
16
+ /**
17
+ * Mock-friendly Redis client interface used by the destination.
18
+ * Tests provide this via env.Redis; production creates a real ioredis
19
+ * client and uses it directly.
20
+ */
21
+ interface RedisClientMock {
22
+ xadd: (...args: XaddArg[]) => Promise<string | null>;
23
+ pipeline: () => RedisPipelineMock;
24
+ quit: () => Promise<string>;
25
+ on?: (event: string, listener: (...args: unknown[]) => void) => unknown;
26
+ }
27
+ /**
28
+ * Constructor signature for the Redis client. Accepts either a URL
29
+ * string or an options object, matching ioredis's dual signature.
30
+ */
31
+ interface RedisClientConstructor {
32
+ new (url: string): RedisClientMock;
33
+ new (options: RedisClientOptions): RedisClientMock;
34
+ }
35
+ /**
36
+ * Minimal ioredis options subset the destination passes through.
37
+ * Unknown options are preserved for the SDK to handle.
38
+ */
39
+ interface RedisClientOptions {
40
+ host?: string;
41
+ port?: number;
42
+ username?: string;
43
+ password?: string;
44
+ db?: number;
45
+ tls?: boolean | Record<string, unknown>;
46
+ connectTimeout?: number;
47
+ commandTimeout?: number;
48
+ [key: string]: unknown;
49
+ }
50
+ type SerializationMode = 'json' | 'flat';
51
+ interface RedisSettings {
52
+ /** Redis stream key name (e.g. 'walkeros:events'). */
53
+ streamKey: string;
54
+ /** Redis connection URL (e.g. 'redis://localhost:6379' or 'rediss://...'). */
55
+ url?: string;
56
+ /** ioredis connection options (used if no url provided). */
57
+ options?: RedisClientOptions;
58
+ /**
59
+ * Maximum stream length. Enables MAXLEN trimming on every XADD.
60
+ * Uses approximate (~) trimming by default for performance.
61
+ * Omit for unlimited stream length.
62
+ */
63
+ maxLen?: number;
64
+ /**
65
+ * Use exact MAXLEN instead of approximate (~).
66
+ * Not recommended for production -- significantly slower.
67
+ * Default: false (approximate trimming).
68
+ */
69
+ exactTrimming?: boolean;
70
+ /**
71
+ * Serialization mode for the event payload.
72
+ * - 'json': Single 'event' field with JSON string (default)
73
+ * - 'flat': Top-level event fields as separate stream fields
74
+ */
75
+ serialization?: SerializationMode;
76
+ _client?: RedisClientMock;
77
+ _ownedClient?: boolean;
78
+ }
79
+ interface Settings {
80
+ redis: RedisSettings;
81
+ }
82
+ /**
83
+ * Env -- optional Redis SDK override. Production leaves this undefined
84
+ * and the destination creates real ioredis client instances. Tests provide
85
+ * mocks via env.Redis.
86
+ */
87
+ interface Env extends DestinationServer.Env {
88
+ Redis?: {
89
+ Client: RedisClientConstructor;
90
+ };
91
+ }
92
+
93
+ declare const push: Env;
94
+ declare const simulation: string[];
95
+
96
+ declare const env_push: typeof push;
97
+ declare const env_simulation: typeof simulation;
98
+ declare namespace env {
99
+ export { env_push as push, env_simulation as simulation };
100
+ }
101
+
102
+ /**
103
+ * Extended step example that may carry destination-level settings overrides.
104
+ */
105
+ type RedisStepExample = Flow.StepExample & {
106
+ settings?: Partial<Settings>;
107
+ };
108
+ /**
109
+ * Default JSON serialization -- single 'event' field with full event JSON.
110
+ */
111
+ declare const jsonDefault: RedisStepExample;
112
+ /**
113
+ * Order event -- verifies different event types pass through correctly.
114
+ */
115
+ declare const orderComplete: RedisStepExample;
116
+ /**
117
+ * With MAXLEN approximate trimming -- trimming args inserted before '*'.
118
+ */
119
+ declare const withMaxLen: RedisStepExample;
120
+ /**
121
+ * Exact MAXLEN trimming -- no '~' between MAXLEN and the count.
122
+ */
123
+ declare const withExactTrim: RedisStepExample;
124
+ /**
125
+ * Stream key override per rule -- routes this event to a dedicated stream.
126
+ */
127
+ declare const streamKeyOverride: RedisStepExample;
128
+ /**
129
+ * Ignored event -- mapping.ignore: true produces no xadd call.
130
+ */
131
+ declare const ignoredEvent: RedisStepExample;
132
+
133
+ type step_RedisStepExample = RedisStepExample;
134
+ declare const step_ignoredEvent: typeof ignoredEvent;
135
+ declare const step_jsonDefault: typeof jsonDefault;
136
+ declare const step_orderComplete: typeof orderComplete;
137
+ declare const step_streamKeyOverride: typeof streamKeyOverride;
138
+ declare const step_withExactTrim: typeof withExactTrim;
139
+ declare const step_withMaxLen: typeof withMaxLen;
140
+ declare namespace step {
141
+ export { type step_RedisStepExample as RedisStepExample, step_ignoredEvent as ignoredEvent, step_jsonDefault as jsonDefault, step_orderComplete as orderComplete, step_streamKeyOverride as streamKeyOverride, step_withExactTrim as withExactTrim, step_withMaxLen as withMaxLen };
142
+ }
143
+
144
+ export { env, step };