@pikku/redis 0.11.2 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -1
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/redis-agent-run-service.d.ts +24 -0
- package/dist/src/redis-agent-run-service.js +141 -0
- package/dist/src/redis-agent-run-service.js.map +1 -0
- package/dist/src/redis-channel-store.d.ts +3 -2
- package/dist/src/redis-channel-store.js.map +1 -1
- package/dist/src/redis-deployment-service.d.ts +19 -0
- package/dist/src/redis-deployment-service.js +111 -0
- package/dist/src/redis-deployment-service.js.map +1 -0
- package/dist/src/redis-eventhub-store.d.ts +1 -1
- package/dist/src/redis-workflow-run-service.d.ts +35 -0
- package/dist/src/redis-workflow-run-service.js +167 -0
- package/dist/src/redis-workflow-run-service.js.map +1 -0
- package/dist/src/redis-workflow-service.d.ts +9 -2
- package/dist/src/redis-workflow-service.js +48 -16
- package/dist/src/redis-workflow-service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/index.ts +5 -0
- package/src/redis-agent-run-service.ts +181 -0
- package/src/redis-channel-store.ts +3 -2
- package/src/redis-deployment-service.ts +153 -0
- package/src/redis-eventhub-store.ts +1 -1
- package/src/redis-workflow-run-service.ts +227 -0
- package/src/redis-workflow-service.ts +77 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
## 0.
|
|
1
|
+
## 0.12.0
|
|
2
|
+
|
|
3
|
+
## 0.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e04531f: Code quality improvements: resolve oxlint warnings and apply autofixes across the codebase (unused bindings, unnecessary constructors, prefer `const` over `let`, etc.). No behaviour changes.
|
|
8
|
+
- Updated dependencies [62a8725]
|
|
9
|
+
- Updated dependencies [a3bdb0d]
|
|
10
|
+
- Updated dependencies [e0349ff]
|
|
11
|
+
- Updated dependencies [62a8725]
|
|
12
|
+
- Updated dependencies [e04531f]
|
|
13
|
+
- Updated dependencies [62a8725]
|
|
14
|
+
- Updated dependencies [a83efb8]
|
|
15
|
+
- Updated dependencies [8eed717]
|
|
16
|
+
- Updated dependencies [62a8725]
|
|
17
|
+
- Updated dependencies [62a8725]
|
|
18
|
+
- Updated dependencies [62a8725]
|
|
19
|
+
- @pikku/core@0.12.1
|
|
20
|
+
|
|
21
|
+
### New Features
|
|
22
|
+
|
|
23
|
+
- `RedisDeploymentService` for Redis-based service discovery with TTL heartbeats
|
|
24
|
+
|
|
25
|
+
## 0.11.2
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
- f35e89da: Add workflow graph support to RedisWorkflowService
|
|
30
|
+
- Add `inline` field to workflow runs
|
|
31
|
+
- Add `getCompletedGraphState` method for graph execution
|
|
32
|
+
- Add `setBranchTaken` method for graph branching
|
|
2
33
|
|
|
3
34
|
## 0.11.2
|
|
4
35
|
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export { RedisChannelStore } from './redis-channel-store.js';
|
|
2
|
+
export { RedisDeploymentService } from './redis-deployment-service.js';
|
|
2
3
|
export { RedisEventHubStore } from './redis-eventhub-store.js';
|
|
3
4
|
export { RedisWorkflowService } from './redis-workflow-service.js';
|
|
5
|
+
export { RedisWorkflowRunService } from './redis-workflow-run-service.js';
|
|
6
|
+
export type { WorkflowRunService } from '@pikku/core/workflow';
|
|
7
|
+
export { RedisAgentRunService } from './redis-agent-run-service.js';
|
|
8
|
+
export type { AgentRunService, AgentRunRow } from '@pikku/core/ai-agent';
|
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { RedisChannelStore } from './redis-channel-store.js';
|
|
2
|
+
export { RedisDeploymentService } from './redis-deployment-service.js';
|
|
2
3
|
export { RedisEventHubStore } from './redis-eventhub-store.js';
|
|
3
4
|
export { RedisWorkflowService } from './redis-workflow-service.js';
|
|
5
|
+
export { RedisWorkflowRunService } from './redis-workflow-run-service.js';
|
|
6
|
+
export { RedisAgentRunService } from './redis-agent-run-service.js';
|
|
4
7
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAEzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AIThread, AIMessage, AgentRunRow, AgentRunService } from '@pikku/core/ai-agent';
|
|
2
|
+
import type { Redis } from 'ioredis';
|
|
3
|
+
export declare class RedisAgentRunService implements AgentRunService {
|
|
4
|
+
private redis;
|
|
5
|
+
private keyPrefix;
|
|
6
|
+
constructor(redis: Redis, keyPrefix?: string);
|
|
7
|
+
private threadKey;
|
|
8
|
+
private threadsIndexKey;
|
|
9
|
+
private messagesKey;
|
|
10
|
+
private runKey;
|
|
11
|
+
private threadRunsKey;
|
|
12
|
+
private agentThreadsKey;
|
|
13
|
+
listThreads(options?: {
|
|
14
|
+
agentName?: string;
|
|
15
|
+
limit?: number;
|
|
16
|
+
offset?: number;
|
|
17
|
+
}): Promise<AIThread[]>;
|
|
18
|
+
getThread(threadId: string): Promise<AIThread | null>;
|
|
19
|
+
getThreadMessages(threadId: string): Promise<AIMessage[]>;
|
|
20
|
+
getThreadRuns(threadId: string): Promise<AgentRunRow[]>;
|
|
21
|
+
deleteThread(threadId: string): Promise<boolean>;
|
|
22
|
+
getDistinctAgentNames(): Promise<string[]>;
|
|
23
|
+
private scanKeys;
|
|
24
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
export class RedisAgentRunService {
|
|
2
|
+
redis;
|
|
3
|
+
keyPrefix;
|
|
4
|
+
constructor(redis, keyPrefix = 'ai') {
|
|
5
|
+
this.redis = redis;
|
|
6
|
+
this.keyPrefix = keyPrefix;
|
|
7
|
+
}
|
|
8
|
+
threadKey(threadId) {
|
|
9
|
+
return `${this.keyPrefix}:thread:${threadId}`;
|
|
10
|
+
}
|
|
11
|
+
threadsIndexKey() {
|
|
12
|
+
return `${this.keyPrefix}:threads`;
|
|
13
|
+
}
|
|
14
|
+
messagesKey(threadId) {
|
|
15
|
+
return `${this.keyPrefix}:messages:${threadId}`;
|
|
16
|
+
}
|
|
17
|
+
runKey(runId) {
|
|
18
|
+
return `${this.keyPrefix}:run:${runId}`;
|
|
19
|
+
}
|
|
20
|
+
threadRunsKey(threadId) {
|
|
21
|
+
return `${this.keyPrefix}:thread-runs:${threadId}`;
|
|
22
|
+
}
|
|
23
|
+
agentThreadsKey(agentName) {
|
|
24
|
+
return `${this.keyPrefix}:agent-threads:${agentName}`;
|
|
25
|
+
}
|
|
26
|
+
async listThreads(options) {
|
|
27
|
+
const { agentName, limit = 50, offset = 0 } = options ?? {};
|
|
28
|
+
let threadIds;
|
|
29
|
+
if (agentName) {
|
|
30
|
+
const allIds = await this.redis.smembers(this.agentThreadsKey(agentName));
|
|
31
|
+
const threadsWithScores = [];
|
|
32
|
+
for (const id of allIds) {
|
|
33
|
+
const score = await this.redis.zscore(this.threadsIndexKey(), id);
|
|
34
|
+
if (score) {
|
|
35
|
+
threadsWithScores.push({ id, score: Number(score) });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
threadsWithScores.sort((a, b) => b.score - a.score);
|
|
39
|
+
threadIds = threadsWithScores.map((t) => t.id);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
threadIds = await this.redis.zrevrange(this.threadsIndexKey(), 0, -1);
|
|
43
|
+
}
|
|
44
|
+
const paged = threadIds.slice(offset, offset + limit);
|
|
45
|
+
const threads = [];
|
|
46
|
+
for (const id of paged) {
|
|
47
|
+
const thread = await this.getThread(id);
|
|
48
|
+
if (thread)
|
|
49
|
+
threads.push(thread);
|
|
50
|
+
}
|
|
51
|
+
return threads;
|
|
52
|
+
}
|
|
53
|
+
async getThread(threadId) {
|
|
54
|
+
const data = await this.redis.hgetall(this.threadKey(threadId));
|
|
55
|
+
if (!data.id)
|
|
56
|
+
return null;
|
|
57
|
+
return {
|
|
58
|
+
id: data.id,
|
|
59
|
+
resourceId: data.resourceId,
|
|
60
|
+
title: data.title || undefined,
|
|
61
|
+
metadata: data.metadata ? JSON.parse(data.metadata) : undefined,
|
|
62
|
+
createdAt: new Date(Number(data.createdAt)),
|
|
63
|
+
updatedAt: new Date(Number(data.updatedAt)),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async getThreadMessages(threadId) {
|
|
67
|
+
const entries = await this.redis.zrange(this.messagesKey(threadId), 0, -1);
|
|
68
|
+
return entries.map((entry) => {
|
|
69
|
+
const msg = JSON.parse(entry);
|
|
70
|
+
return {
|
|
71
|
+
...msg,
|
|
72
|
+
createdAt: new Date(msg.createdAt),
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async getThreadRuns(threadId) {
|
|
77
|
+
const runIds = await this.redis.zrevrange(this.threadRunsKey(threadId), 0, -1);
|
|
78
|
+
const runs = [];
|
|
79
|
+
for (const runId of runIds) {
|
|
80
|
+
const data = await this.redis.hgetall(this.runKey(runId));
|
|
81
|
+
if (!data.runId)
|
|
82
|
+
continue;
|
|
83
|
+
runs.push({
|
|
84
|
+
runId: data.runId,
|
|
85
|
+
agentName: data.agentName,
|
|
86
|
+
threadId: data.threadId,
|
|
87
|
+
resourceId: data.resourceId,
|
|
88
|
+
status: data.status,
|
|
89
|
+
suspendReason: data.suspendReason || undefined,
|
|
90
|
+
missingRpcs: data.missingRpcs
|
|
91
|
+
? JSON.parse(data.missingRpcs)
|
|
92
|
+
: undefined,
|
|
93
|
+
usageInputTokens: Number(data.usageInputTokens || 0),
|
|
94
|
+
usageOutputTokens: Number(data.usageOutputTokens || 0),
|
|
95
|
+
usageModel: data.usageModel,
|
|
96
|
+
createdAt: new Date(Number(data.createdAt)),
|
|
97
|
+
updatedAt: new Date(Number(data.updatedAt)),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return runs;
|
|
101
|
+
}
|
|
102
|
+
async deleteThread(threadId) {
|
|
103
|
+
const exists = await this.redis.exists(this.threadKey(threadId));
|
|
104
|
+
if (!exists)
|
|
105
|
+
return false;
|
|
106
|
+
const runIds = await this.redis.zrange(this.threadRunsKey(threadId), 0, -1);
|
|
107
|
+
const keysToDelete = [
|
|
108
|
+
this.threadKey(threadId),
|
|
109
|
+
this.messagesKey(threadId),
|
|
110
|
+
this.threadRunsKey(threadId),
|
|
111
|
+
];
|
|
112
|
+
for (const runId of runIds) {
|
|
113
|
+
const agentName = await this.redis.hget(this.runKey(runId), 'agentName');
|
|
114
|
+
keysToDelete.push(this.runKey(runId));
|
|
115
|
+
if (agentName) {
|
|
116
|
+
await this.redis.srem(this.agentThreadsKey(agentName), threadId);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
await this.redis.zrem(this.threadsIndexKey(), threadId);
|
|
120
|
+
if (keysToDelete.length > 0) {
|
|
121
|
+
await this.redis.del(...keysToDelete);
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
async getDistinctAgentNames() {
|
|
126
|
+
const keys = await this.scanKeys(`${this.keyPrefix}:agent-threads:*`);
|
|
127
|
+
const prefix = `${this.keyPrefix}:agent-threads:`;
|
|
128
|
+
return keys.map((k) => k.slice(prefix.length)).sort();
|
|
129
|
+
}
|
|
130
|
+
async scanKeys(pattern) {
|
|
131
|
+
const keys = [];
|
|
132
|
+
let cursor = '0';
|
|
133
|
+
do {
|
|
134
|
+
const [newCursor, foundKeys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
135
|
+
cursor = newCursor;
|
|
136
|
+
keys.push(...foundKeys);
|
|
137
|
+
} while (cursor !== '0');
|
|
138
|
+
return keys;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=redis-agent-run-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-agent-run-service.js","sourceRoot":"","sources":["../../src/redis-agent-run-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { CoreUserSession } from '@pikku/core';
|
|
2
|
-
import { Channel
|
|
1
|
+
import type { CoreUserSession } from '@pikku/core';
|
|
2
|
+
import type { Channel } from '@pikku/core/channel';
|
|
3
|
+
import { ChannelStore } from '@pikku/core/channel';
|
|
3
4
|
import { Redis, type RedisOptions } from 'ioredis';
|
|
4
5
|
export declare class RedisChannelStore extends ChannelStore {
|
|
5
6
|
private redis;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-channel-store.js","sourceRoot":"","sources":["../../src/redis-channel-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"redis-channel-store.js","sourceRoot":"","sources":["../../src/redis-channel-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DeploymentService, DeploymentServiceConfig, DeploymentConfig, DeploymentInfo } from '@pikku/core/services';
|
|
2
|
+
import { Redis, type RedisOptions } from 'ioredis';
|
|
3
|
+
export declare class RedisDeploymentService implements DeploymentService {
|
|
4
|
+
private redis;
|
|
5
|
+
private keyPrefix;
|
|
6
|
+
private ownsConnection;
|
|
7
|
+
private heartbeatTimer?;
|
|
8
|
+
private deploymentConfig?;
|
|
9
|
+
private heartbeatInterval;
|
|
10
|
+
private heartbeatTtl;
|
|
11
|
+
constructor(config: DeploymentServiceConfig, connectionOrConfig: Redis | RedisOptions | string, keyPrefix?: string);
|
|
12
|
+
private deploymentKey;
|
|
13
|
+
private functionsIndexKey;
|
|
14
|
+
init(): Promise<void>;
|
|
15
|
+
start(config: DeploymentConfig): Promise<void>;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
findFunction(name: string): Promise<DeploymentInfo[]>;
|
|
18
|
+
private sendHeartbeat;
|
|
19
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { getAllFunctionNames } from '@pikku/core/function';
|
|
2
|
+
import { Redis } from 'ioredis';
|
|
3
|
+
export class RedisDeploymentService {
|
|
4
|
+
redis;
|
|
5
|
+
keyPrefix;
|
|
6
|
+
ownsConnection;
|
|
7
|
+
heartbeatTimer;
|
|
8
|
+
deploymentConfig;
|
|
9
|
+
heartbeatInterval;
|
|
10
|
+
heartbeatTtl;
|
|
11
|
+
constructor(config, connectionOrConfig, keyPrefix = 'pikku') {
|
|
12
|
+
this.heartbeatInterval = config.heartbeatInterval ?? 10000;
|
|
13
|
+
this.heartbeatTtl = config.heartbeatTtl ?? 30000;
|
|
14
|
+
this.keyPrefix = keyPrefix;
|
|
15
|
+
if (connectionOrConfig instanceof Redis) {
|
|
16
|
+
this.redis = connectionOrConfig;
|
|
17
|
+
this.ownsConnection = false;
|
|
18
|
+
}
|
|
19
|
+
else if (typeof connectionOrConfig === 'string') {
|
|
20
|
+
this.redis = new Redis(connectionOrConfig);
|
|
21
|
+
this.ownsConnection = true;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
this.redis = new Redis(connectionOrConfig);
|
|
25
|
+
this.ownsConnection = true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
deploymentKey(deploymentId) {
|
|
29
|
+
return `${this.keyPrefix}:deployment:${deploymentId}`;
|
|
30
|
+
}
|
|
31
|
+
functionsIndexKey(funcName) {
|
|
32
|
+
return `${this.keyPrefix}:fn:${funcName}`;
|
|
33
|
+
}
|
|
34
|
+
async init() { }
|
|
35
|
+
async start(config) {
|
|
36
|
+
const functions = config.functions ?? getAllFunctionNames();
|
|
37
|
+
this.deploymentConfig = { ...config, functions };
|
|
38
|
+
const ttlSeconds = Math.ceil(this.heartbeatTtl / 1000);
|
|
39
|
+
const expiryScore = Date.now() + this.heartbeatTtl;
|
|
40
|
+
const pipeline = this.redis.pipeline();
|
|
41
|
+
pipeline.hset(this.deploymentKey(config.deploymentId), {
|
|
42
|
+
endpoint: config.endpoint,
|
|
43
|
+
functions: JSON.stringify(functions),
|
|
44
|
+
});
|
|
45
|
+
pipeline.expire(this.deploymentKey(config.deploymentId), ttlSeconds);
|
|
46
|
+
for (const fn of functions) {
|
|
47
|
+
pipeline.zadd(this.functionsIndexKey(fn), expiryScore, config.deploymentId);
|
|
48
|
+
}
|
|
49
|
+
await pipeline.exec();
|
|
50
|
+
this.heartbeatTimer = setInterval(() => this.sendHeartbeat(), this.heartbeatInterval);
|
|
51
|
+
}
|
|
52
|
+
async stop() {
|
|
53
|
+
if (this.heartbeatTimer) {
|
|
54
|
+
clearInterval(this.heartbeatTimer);
|
|
55
|
+
this.heartbeatTimer = undefined;
|
|
56
|
+
}
|
|
57
|
+
if (this.deploymentConfig) {
|
|
58
|
+
const { deploymentId, functions } = this.deploymentConfig;
|
|
59
|
+
const pipeline = this.redis.pipeline();
|
|
60
|
+
pipeline.del(this.deploymentKey(deploymentId));
|
|
61
|
+
for (const fn of functions) {
|
|
62
|
+
pipeline.zrem(this.functionsIndexKey(fn), deploymentId);
|
|
63
|
+
}
|
|
64
|
+
await pipeline.exec();
|
|
65
|
+
}
|
|
66
|
+
if (this.ownsConnection) {
|
|
67
|
+
await this.redis.quit();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async findFunction(name) {
|
|
71
|
+
const indexKey = this.functionsIndexKey(name);
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
const pipeline = this.redis.pipeline();
|
|
74
|
+
pipeline.zremrangebyscore(indexKey, '-inf', now);
|
|
75
|
+
pipeline.zrangebyscore(indexKey, now, '+inf');
|
|
76
|
+
const pipelineResults = await pipeline.exec();
|
|
77
|
+
const deploymentIds = pipelineResults?.[1]?.[1] ?? [];
|
|
78
|
+
if (deploymentIds.length === 0) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
const results = [];
|
|
82
|
+
for (const deploymentId of deploymentIds) {
|
|
83
|
+
const endpoint = await this.redis.hget(this.deploymentKey(deploymentId), 'endpoint');
|
|
84
|
+
if (endpoint) {
|
|
85
|
+
results.push({ deploymentId, endpoint });
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
await this.redis.zrem(indexKey, deploymentId);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return results;
|
|
92
|
+
}
|
|
93
|
+
async sendHeartbeat() {
|
|
94
|
+
if (!this.deploymentConfig)
|
|
95
|
+
return;
|
|
96
|
+
const { deploymentId, functions } = this.deploymentConfig;
|
|
97
|
+
const ttlSeconds = Math.ceil(this.heartbeatTtl / 1000);
|
|
98
|
+
const expiryScore = Date.now() + this.heartbeatTtl;
|
|
99
|
+
try {
|
|
100
|
+
const pipeline = this.redis.pipeline();
|
|
101
|
+
pipeline.expire(this.deploymentKey(deploymentId), ttlSeconds);
|
|
102
|
+
for (const fn of functions) {
|
|
103
|
+
pipeline.zadd(this.functionsIndexKey(fn), expiryScore, deploymentId);
|
|
104
|
+
}
|
|
105
|
+
await pipeline.exec();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=redis-deployment-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-deployment-service.js","sourceRoot":"","sources":["../../src/redis-deployment-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { WorkflowRun, StepState, WorkflowRunService } from '@pikku/core/workflow';
|
|
2
|
+
import type { Redis } from 'ioredis';
|
|
3
|
+
export declare class RedisWorkflowRunService implements WorkflowRunService {
|
|
4
|
+
private redis;
|
|
5
|
+
private keyPrefix;
|
|
6
|
+
constructor(redis: Redis, keyPrefix?: string);
|
|
7
|
+
private runKey;
|
|
8
|
+
private stepKeyPattern;
|
|
9
|
+
private stepHistoryKey;
|
|
10
|
+
private versionKey;
|
|
11
|
+
listRuns(options?: {
|
|
12
|
+
workflowName?: string;
|
|
13
|
+
status?: string;
|
|
14
|
+
limit?: number;
|
|
15
|
+
offset?: number;
|
|
16
|
+
}): Promise<WorkflowRun[]>;
|
|
17
|
+
getRun(id: string): Promise<WorkflowRun | null>;
|
|
18
|
+
getRunSteps(runId: string): Promise<Array<StepState & {
|
|
19
|
+
stepName: string;
|
|
20
|
+
rpcName?: string;
|
|
21
|
+
data?: any;
|
|
22
|
+
}>>;
|
|
23
|
+
getRunHistory(runId: string): Promise<Array<StepState & {
|
|
24
|
+
stepName: string;
|
|
25
|
+
}>>;
|
|
26
|
+
getDistinctWorkflowNames(): Promise<string[]>;
|
|
27
|
+
getWorkflowVersion(name: string, graphHash: string): Promise<{
|
|
28
|
+
graph: any;
|
|
29
|
+
source: string;
|
|
30
|
+
} | null>;
|
|
31
|
+
deleteRun(id: string): Promise<boolean>;
|
|
32
|
+
private mapRunData;
|
|
33
|
+
private extractStepName;
|
|
34
|
+
private scanKeys;
|
|
35
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export class RedisWorkflowRunService {
|
|
2
|
+
redis;
|
|
3
|
+
keyPrefix;
|
|
4
|
+
constructor(redis, keyPrefix = 'workflows') {
|
|
5
|
+
this.redis = redis;
|
|
6
|
+
this.keyPrefix = keyPrefix;
|
|
7
|
+
}
|
|
8
|
+
runKey(runId) {
|
|
9
|
+
return `${this.keyPrefix}:run:${runId}`;
|
|
10
|
+
}
|
|
11
|
+
stepKeyPattern(runId) {
|
|
12
|
+
return `${this.keyPrefix}:step:${runId}:*`;
|
|
13
|
+
}
|
|
14
|
+
stepHistoryKey(stepId) {
|
|
15
|
+
return `${this.keyPrefix}:step-history:${stepId}`;
|
|
16
|
+
}
|
|
17
|
+
versionKey(name, graphHash) {
|
|
18
|
+
return `${this.keyPrefix}:version:${name}:${graphHash}`;
|
|
19
|
+
}
|
|
20
|
+
async listRuns(options) {
|
|
21
|
+
const { workflowName, status, limit = 50, offset = 0 } = options ?? {};
|
|
22
|
+
const runKeys = await this.scanKeys(`${this.keyPrefix}:run:*`);
|
|
23
|
+
const runs = [];
|
|
24
|
+
for (const key of runKeys) {
|
|
25
|
+
const data = await this.redis.hgetall(key);
|
|
26
|
+
if (!data.id)
|
|
27
|
+
continue;
|
|
28
|
+
if (workflowName && data.workflow !== workflowName)
|
|
29
|
+
continue;
|
|
30
|
+
if (status && data.status !== status)
|
|
31
|
+
continue;
|
|
32
|
+
runs.push(this.mapRunData(data));
|
|
33
|
+
}
|
|
34
|
+
runs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
35
|
+
return runs.slice(offset, offset + limit);
|
|
36
|
+
}
|
|
37
|
+
async getRun(id) {
|
|
38
|
+
const data = await this.redis.hgetall(this.runKey(id));
|
|
39
|
+
if (!data.id)
|
|
40
|
+
return null;
|
|
41
|
+
return this.mapRunData(data);
|
|
42
|
+
}
|
|
43
|
+
async getRunSteps(runId) {
|
|
44
|
+
const stepKeys = await this.scanKeys(this.stepKeyPattern(runId));
|
|
45
|
+
const steps = [];
|
|
46
|
+
for (const key of stepKeys) {
|
|
47
|
+
const data = await this.redis.hgetall(key);
|
|
48
|
+
if (!data.stepId)
|
|
49
|
+
continue;
|
|
50
|
+
steps.push({
|
|
51
|
+
stepId: data.stepId,
|
|
52
|
+
stepName: this.extractStepName(key, runId),
|
|
53
|
+
rpcName: data.rpcName || undefined,
|
|
54
|
+
data: data.data ? JSON.parse(data.data) : undefined,
|
|
55
|
+
status: data.status,
|
|
56
|
+
result: data.result ? JSON.parse(data.result) : undefined,
|
|
57
|
+
error: data.error ? JSON.parse(data.error) : undefined,
|
|
58
|
+
attemptCount: Number(data.attemptCount || 1),
|
|
59
|
+
retries: data.retries ? Number(data.retries) : undefined,
|
|
60
|
+
retryDelay: data.retryDelay || undefined,
|
|
61
|
+
createdAt: new Date(Number(data.createdAt)),
|
|
62
|
+
updatedAt: new Date(Number(data.updatedAt)),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
steps.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
66
|
+
return steps;
|
|
67
|
+
}
|
|
68
|
+
async getRunHistory(runId) {
|
|
69
|
+
const stepKeys = await this.scanKeys(this.stepKeyPattern(runId));
|
|
70
|
+
const allHistoryEntries = [];
|
|
71
|
+
for (const key of stepKeys) {
|
|
72
|
+
const data = await this.redis.hgetall(key);
|
|
73
|
+
if (!data.stepId)
|
|
74
|
+
continue;
|
|
75
|
+
const historyEntries = await this.redis.zrange(this.stepHistoryKey(data.stepId), 0, -1);
|
|
76
|
+
for (const entryStr of historyEntries) {
|
|
77
|
+
const entry = JSON.parse(entryStr);
|
|
78
|
+
allHistoryEntries.push({
|
|
79
|
+
stepId: entry.stepId,
|
|
80
|
+
stepName: entry.stepName,
|
|
81
|
+
status: entry.status,
|
|
82
|
+
result: entry.result ? JSON.parse(entry.result) : undefined,
|
|
83
|
+
error: entry.error ? JSON.parse(entry.error) : undefined,
|
|
84
|
+
attemptCount: entry.attemptCount,
|
|
85
|
+
retries: entry.retries,
|
|
86
|
+
retryDelay: entry.retryDelay,
|
|
87
|
+
createdAt: new Date(entry.createdAt),
|
|
88
|
+
updatedAt: new Date(entry.createdAt),
|
|
89
|
+
runningAt: entry.runningAt ? new Date(entry.runningAt) : undefined,
|
|
90
|
+
scheduledAt: entry.scheduledAt
|
|
91
|
+
? new Date(entry.scheduledAt)
|
|
92
|
+
: undefined,
|
|
93
|
+
succeededAt: entry.succeededAt
|
|
94
|
+
? new Date(entry.succeededAt)
|
|
95
|
+
: undefined,
|
|
96
|
+
failedAt: entry.failedAt ? new Date(entry.failedAt) : undefined,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return allHistoryEntries.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
101
|
+
}
|
|
102
|
+
async getDistinctWorkflowNames() {
|
|
103
|
+
const runKeys = await this.scanKeys(`${this.keyPrefix}:run:*`);
|
|
104
|
+
const names = new Set();
|
|
105
|
+
for (const key of runKeys) {
|
|
106
|
+
const workflow = await this.redis.hget(key, 'workflow');
|
|
107
|
+
if (workflow)
|
|
108
|
+
names.add(workflow);
|
|
109
|
+
}
|
|
110
|
+
return [...names].sort();
|
|
111
|
+
}
|
|
112
|
+
async getWorkflowVersion(name, graphHash) {
|
|
113
|
+
const data = await this.redis.hgetall(this.versionKey(name, graphHash));
|
|
114
|
+
if (!data.graph)
|
|
115
|
+
return null;
|
|
116
|
+
return {
|
|
117
|
+
graph: JSON.parse(data.graph),
|
|
118
|
+
source: data.source,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async deleteRun(id) {
|
|
122
|
+
const exists = await this.redis.exists(this.runKey(id));
|
|
123
|
+
if (!exists)
|
|
124
|
+
return false;
|
|
125
|
+
const stepKeys = await this.scanKeys(this.stepKeyPattern(id));
|
|
126
|
+
const keysToDelete = [this.runKey(id)];
|
|
127
|
+
for (const stepKey of stepKeys) {
|
|
128
|
+
const stepId = await this.redis.hget(stepKey, 'stepId');
|
|
129
|
+
keysToDelete.push(stepKey);
|
|
130
|
+
if (stepId) {
|
|
131
|
+
keysToDelete.push(this.stepHistoryKey(stepId));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
await this.redis.del(...keysToDelete);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
mapRunData(data) {
|
|
138
|
+
return {
|
|
139
|
+
id: data.id,
|
|
140
|
+
workflow: data.workflow,
|
|
141
|
+
status: data.status,
|
|
142
|
+
input: JSON.parse(data.input),
|
|
143
|
+
output: data.output ? JSON.parse(data.output) : undefined,
|
|
144
|
+
error: data.error ? JSON.parse(data.error) : undefined,
|
|
145
|
+
inline: data.inline === 'true' ? true : undefined,
|
|
146
|
+
graphHash: data.graphHash || undefined,
|
|
147
|
+
wire: data.wire ? JSON.parse(data.wire) : { type: 'unknown' },
|
|
148
|
+
createdAt: new Date(Number(data.createdAt)),
|
|
149
|
+
updatedAt: new Date(Number(data.updatedAt)),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
extractStepName(key, runId) {
|
|
153
|
+
const prefix = `${this.keyPrefix}:step:${runId}:`;
|
|
154
|
+
return key.slice(prefix.length);
|
|
155
|
+
}
|
|
156
|
+
async scanKeys(pattern) {
|
|
157
|
+
const keys = [];
|
|
158
|
+
let cursor = '0';
|
|
159
|
+
do {
|
|
160
|
+
const [newCursor, foundKeys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
161
|
+
cursor = newCursor;
|
|
162
|
+
keys.push(...foundKeys);
|
|
163
|
+
} while (cursor !== '0');
|
|
164
|
+
return keys;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=redis-workflow-run-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-workflow-run-service.js","sourceRoot":"","sources":["../../src/redis-workflow-run-service.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,uBAAuB;IAExB;IACA;IAFV,YACU,KAAY,EACZ,YAAY,WAAW;QADvB,UAAK,GAAL,KAAK,CAAO;QACZ,cAAS,GAAT,SAAS,CAAc;IAC9B,CAAC;IAEI,MAAM,CAAC,KAAa;QAC1B,OAAO,GAAG,IAAI,CAAC,SAAS,QAAQ,KAAK,EAAE,CAAA;IACzC,CAAC;IAEO,cAAc,CAAC,KAAa;QAClC,OAAO,GAAG,IAAI,CAAC,SAAS,SAAS,KAAK,IAAI,CAAA;IAC5C,CAAC;IAEO,cAAc,CAAC,MAAc;QACnC,OAAO,GAAG,IAAI,CAAC,SAAS,iBAAiB,MAAM,EAAE,CAAA;IACnD,CAAC;IAEO,UAAU,CAAC,IAAY,EAAE,SAAiB;QAChD,OAAO,GAAG,IAAI,CAAC,SAAS,YAAY,IAAI,IAAI,SAAS,EAAE,CAAA;IACzD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAKd;QACC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;QAEtE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAA;QAE9D,MAAM,IAAI,GAAkB,EAAE,CAAA;QAC9B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC1C,IAAI,CAAC,IAAI,CAAC,EAAE;gBAAE,SAAQ;YAEtB,IAAI,YAAY,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY;gBAAE,SAAQ;YAC5D,IAAI,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;gBAAE,SAAQ;YAE9C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;QAClC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QAElE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QACtD,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QACzB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAAa;QAIb,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;QAEhE,MAAM,KAAK,GAEP,EAAE,CAAA;QAEN,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,SAAQ;YAE1B,KAAK,CAAC,IAAI,CAAC;gBACT,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC;gBAC1C,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,SAAS;gBAClC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;gBACnD,MAAM,EAAE,IAAI,CAAC,MAAa;gBAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;gBACzD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBACtD,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;gBAC5C,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;gBACxD,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,SAAS;gBACxC,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC3C,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aAC5C,CAAC,CAAA;QACJ,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QAEnE,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,KAAa;QAEb,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;QAEhE,MAAM,iBAAiB,GAA4C,EAAE,CAAA;QAErE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,SAAQ;YAE1B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAC5C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAChC,CAAC,EACD,CAAC,CAAC,CACH,CAAA;YAED,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAClC,iBAAiB,CAAC,IAAI,CAAC;oBACrB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;oBAC3D,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;oBACxD,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;oBACpC,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;oBACpC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;oBAClE,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC5B,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;wBAC7B,CAAC,CAAC,SAAS;oBACb,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC5B,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;wBAC7B,CAAC,CAAC,SAAS;oBACb,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;iBAChE,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,CAC3B,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CACxD,CAAA;IACH,CAAC;IAED,KAAK,CAAC,wBAAwB;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAA;QAE9D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;QAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YACvD,IAAI,QAAQ;gBAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACnC,CAAC;QAED,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,IAAY,EACZ,SAAiB;QAEjB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAA;QACvE,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAC5B,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAO;SACrB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QACvD,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAA;QAEzB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;QAE7D,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QAEtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YACvD,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAA;YAChD,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAA;QACrC,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,UAAU,CAAC,IAA4B;QAC7C,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAG;YACZ,QAAQ,EAAE,IAAI,CAAC,QAAS;YACxB,MAAM,EAAE,IAAI,CAAC,MAAyB;YACtC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAM,CAAC;YAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YACzD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;YACtD,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACjD,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,SAAS;YACtC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE;YAC7D,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAU,CAAC,CAAC;YAC5C,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAU,CAAC,CAAC;SAC7C,CAAA;IACH,CAAC;IAEO,eAAe,CAAC,GAAW,EAAE,KAAa;QAChD,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,SAAS,KAAK,GAAG,CAAA;QACjD,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACjC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,OAAe;QACpC,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,IAAI,MAAM,GAAG,GAAG,CAAA;QAChB,GAAG,CAAC;YACF,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAClD,MAAM,EACN,OAAO,EACP,OAAO,EACP,OAAO,EACP,GAAG,CACJ,CAAA;YACD,MAAM,GAAG,SAAS,CAAA;YAClB,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAA;QACzB,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAC;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
|