@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 +67 -0
- package/dist/dev.d.mts +196 -0
- package/dist/dev.d.ts +196 -0
- package/dist/dev.js +1 -0
- package/dist/dev.js.map +1 -0
- package/dist/dev.mjs +1 -0
- package/dist/dev.mjs.map +1 -0
- package/dist/examples/index.d.mts +144 -0
- package/dist/examples/index.d.ts +144 -0
- package/dist/examples/index.js +146 -0
- package/dist/examples/index.mjs +124 -0
- package/dist/index.d.mts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -0
- package/dist/walkerOS.json +611 -0
- package/package.json +76 -0
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
|
package/dist/dev.js.map
ADDED
|
@@ -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":"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","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
|
package/dist/dev.mjs.map
ADDED
|
@@ -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 };
|