motia 0.11.2-beta.156 → 0.11.2-beta.157-446581

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/cjs/__tests__/redis-memory-manager.test.d.ts +1 -0
  2. package/dist/cjs/__tests__/redis-memory-manager.test.js +174 -0
  3. package/dist/cjs/__tests__/test-helpers/redis-test-helper.d.ts +51 -0
  4. package/dist/cjs/__tests__/test-helpers/redis-test-helper.example.test.d.ts +1 -0
  5. package/dist/cjs/__tests__/test-helpers/redis-test-helper.example.test.js +83 -0
  6. package/dist/cjs/__tests__/test-helpers/redis-test-helper.js +101 -0
  7. package/dist/cjs/cloud/new-deployment/build.js +3 -1
  8. package/dist/cjs/create/interactive.js +1 -0
  9. package/dist/cjs/dev.js +9 -11
  10. package/dist/cjs/generate-locked-data.d.ts +2 -0
  11. package/dist/cjs/generate-locked-data.js +2 -2
  12. package/dist/cjs/generate-types.js +3 -1
  13. package/dist/cjs/redis-memory-manager.d.ts +7 -0
  14. package/dist/cjs/redis-memory-manager.js +124 -0
  15. package/dist/cjs/start.js +9 -3
  16. package/dist/esm/__tests__/redis-memory-manager.test.d.ts +1 -0
  17. package/dist/esm/__tests__/redis-memory-manager.test.js +172 -0
  18. package/dist/esm/__tests__/test-helpers/redis-test-helper.d.ts +51 -0
  19. package/dist/esm/__tests__/test-helpers/redis-test-helper.example.test.d.ts +1 -0
  20. package/dist/esm/__tests__/test-helpers/redis-test-helper.example.test.js +81 -0
  21. package/dist/esm/__tests__/test-helpers/redis-test-helper.js +94 -0
  22. package/dist/esm/cloud/new-deployment/build.js +3 -1
  23. package/dist/esm/create/interactive.js +1 -0
  24. package/dist/esm/dev.js +10 -9
  25. package/dist/esm/generate-locked-data.d.ts +2 -0
  26. package/dist/esm/generate-locked-data.js +2 -2
  27. package/dist/esm/generate-types.js +3 -1
  28. package/dist/esm/redis-memory-manager.d.ts +7 -0
  29. package/dist/esm/redis-memory-manager.js +119 -0
  30. package/dist/esm/start.js +10 -4
  31. package/dist/types/__tests__/redis-memory-manager.test.d.ts +1 -0
  32. package/dist/types/__tests__/test-helpers/redis-test-helper.d.ts +51 -0
  33. package/dist/types/__tests__/test-helpers/redis-test-helper.example.test.d.ts +1 -0
  34. package/dist/types/generate-locked-data.d.ts +2 -0
  35. package/dist/types/redis-memory-manager.d.ts +7 -0
  36. package/package.json +8 -4
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs_1 = require("fs");
4
+ const redis_1 = require("redis");
5
+ const redis_memory_server_1 = require("redis-memory-server");
6
+ const redis_memory_manager_1 = require("../redis-memory-manager");
7
+ jest.mock('fs');
8
+ jest.mock('redis');
9
+ jest.mock('redis-memory-server');
10
+ const mockMkdirSync = fs_1.mkdirSync;
11
+ const mockCreateClient = redis_1.createClient;
12
+ const mockRedisMemoryServer = redis_memory_server_1.RedisMemoryServer;
13
+ describe('redis-memory-manager', () => {
14
+ let mockRedisClient;
15
+ let mockServerInstance;
16
+ const originalEnv = process.env;
17
+ beforeEach(() => {
18
+ jest.clearAllMocks();
19
+ process.env = { ...originalEnv };
20
+ mockRedisClient = {
21
+ connect: jest.fn().mockResolvedValue(undefined),
22
+ quit: jest.fn().mockResolvedValue(undefined),
23
+ isOpen: true,
24
+ on: jest.fn(),
25
+ };
26
+ mockServerInstance = {
27
+ getHost: jest.fn().mockResolvedValue('127.0.0.1'),
28
+ getPort: jest.fn().mockResolvedValue(6379),
29
+ stop: jest.fn().mockResolvedValue(undefined),
30
+ };
31
+ mockCreateClient.mockReturnValue(mockRedisClient);
32
+ mockRedisMemoryServer.mockImplementation(() => mockServerInstance);
33
+ });
34
+ afterEach(async () => {
35
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
36
+ process.env = originalEnv;
37
+ });
38
+ describe('instanceRedisMemoryServer', () => {
39
+ it('should start Redis server and return client', async () => {
40
+ const baseDir = '/test/dir';
41
+ const client = await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
42
+ expect(mockMkdirSync).toHaveBeenCalledWith(baseDir, { recursive: true });
43
+ expect(mockRedisMemoryServer).toHaveBeenCalledWith({
44
+ instance: {
45
+ ip: '127.0.0.1',
46
+ args: ['--appendonly', 'yes', '--save', '900 1', '--save', '300 10', '--save', '60 100', '--dir', baseDir],
47
+ },
48
+ autoStart: true,
49
+ });
50
+ expect(mockServerInstance.getHost).toHaveBeenCalled();
51
+ expect(mockServerInstance.getPort).toHaveBeenCalled();
52
+ expect(mockCreateClient).toHaveBeenCalledWith({
53
+ socket: {
54
+ host: '127.0.0.1',
55
+ port: 6379,
56
+ reconnectStrategy: expect.any(Function),
57
+ connectTimeout: 10000,
58
+ },
59
+ });
60
+ expect(mockRedisClient.connect).toHaveBeenCalled();
61
+ expect(client).toBe(mockRedisClient);
62
+ });
63
+ it('should use custom host from environment variable', async () => {
64
+ process.env.MOTIA_REDIS_HOST = '192.168.1.1';
65
+ const baseDir = '/test/dir';
66
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, false);
67
+ expect(mockRedisMemoryServer).toHaveBeenCalledWith({
68
+ instance: expect.objectContaining({
69
+ ip: '192.168.1.1',
70
+ }),
71
+ autoStart: false,
72
+ });
73
+ });
74
+ it('should use custom port from environment variable', async () => {
75
+ process.env.MOTIA_REDIS_PORT = '6380';
76
+ const baseDir = '/test/dir';
77
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
78
+ expect(mockRedisMemoryServer).toHaveBeenCalledWith({
79
+ instance: expect.objectContaining({
80
+ port: 6380,
81
+ }),
82
+ autoStart: true,
83
+ });
84
+ });
85
+ it('should return existing client if already running', async () => {
86
+ const baseDir = '/test/dir';
87
+ const client1 = await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
88
+ const client2 = await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, false);
89
+ expect(client1).toBe(client2);
90
+ expect(mockRedisMemoryServer).toHaveBeenCalledTimes(1);
91
+ expect(mockCreateClient).toHaveBeenCalledTimes(1);
92
+ });
93
+ it('should set up error handler on client', async () => {
94
+ const baseDir = '/test/dir';
95
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
96
+ expect(mockRedisClient.on).toHaveBeenCalledWith('error', expect.any(Function));
97
+ });
98
+ it('should handle connection errors', async () => {
99
+ const baseDir = '/test/dir';
100
+ const error = new Error('Connection failed');
101
+ mockRedisClient.connect.mockRejectedValue(error);
102
+ await expect((0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true)).rejects.toThrow('Connection failed');
103
+ });
104
+ it('should handle server start errors', async () => {
105
+ const baseDir = '/test/dir';
106
+ const error = new Error('Server start failed');
107
+ mockServerInstance.getHost.mockRejectedValue(error);
108
+ await expect((0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true)).rejects.toThrow('Server start failed');
109
+ });
110
+ it('should implement reconnect strategy correctly', async () => {
111
+ const baseDir = '/test/dir';
112
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
113
+ const callArgs = mockCreateClient.mock.calls[0];
114
+ expect(callArgs).toBeDefined();
115
+ const socketConfig = callArgs?.[0]?.socket;
116
+ expect(socketConfig).toBeDefined();
117
+ const reconnectStrategy = socketConfig?.reconnectStrategy;
118
+ expect(reconnectStrategy).toBeDefined();
119
+ expect(typeof reconnectStrategy).toBe('function');
120
+ const mockError = new Error('test');
121
+ const strategyFn = reconnectStrategy;
122
+ expect(strategyFn(5, mockError)).toBe(500);
123
+ expect(strategyFn(10, mockError)).toBe(1000);
124
+ expect(strategyFn(11, mockError)).toBeInstanceOf(Error);
125
+ expect(strategyFn(11, mockError).message).toBe('Redis connection retry limit exceeded');
126
+ expect(strategyFn(15, mockError)).toBeInstanceOf(Error);
127
+ expect(strategyFn(20, mockError)).toBeInstanceOf(Error);
128
+ expect(strategyFn(30, mockError)).toBeInstanceOf(Error);
129
+ expect(strategyFn(50, mockError)).toBeInstanceOf(Error);
130
+ });
131
+ });
132
+ describe('stopRedisMemoryServer', () => {
133
+ it('should stop Redis server and close client', async () => {
134
+ const baseDir = '/test/dir';
135
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
136
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
137
+ expect(mockRedisClient.quit).toHaveBeenCalled();
138
+ expect(mockServerInstance.stop).toHaveBeenCalled();
139
+ });
140
+ it('should handle client close errors gracefully', async () => {
141
+ const baseDir = '/test/dir';
142
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
143
+ const error = new Error('Close failed');
144
+ mockRedisClient.quit.mockRejectedValue(error);
145
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
146
+ expect(mockRedisClient.quit).toHaveBeenCalled();
147
+ expect(mockServerInstance.stop).toHaveBeenCalled();
148
+ });
149
+ it('should handle server stop errors gracefully', async () => {
150
+ const baseDir = '/test/dir';
151
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
152
+ const error = new Error('Stop failed');
153
+ mockServerInstance.stop.mockRejectedValue(error);
154
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
155
+ expect(mockRedisClient.quit).toHaveBeenCalled();
156
+ expect(mockServerInstance.stop).toHaveBeenCalled();
157
+ });
158
+ it('should not throw if client is not open', async () => {
159
+ const baseDir = '/test/dir';
160
+ await (0, redis_memory_manager_1.instanceRedisMemoryServer)(baseDir, true);
161
+ Object.defineProperty(mockRedisClient, 'isOpen', {
162
+ value: false,
163
+ writable: true,
164
+ configurable: true,
165
+ });
166
+ await expect((0, redis_memory_manager_1.stopRedisMemoryServer)()).resolves.not.toThrow();
167
+ });
168
+ it('should do nothing if server is not running', async () => {
169
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
170
+ expect(mockRedisClient.quit).not.toHaveBeenCalled();
171
+ expect(mockServerInstance.stop).not.toHaveBeenCalled();
172
+ });
173
+ });
174
+ });
@@ -0,0 +1,51 @@
1
+ export interface MockRedisClient {
2
+ connect: jest.Mock<Promise<void>>;
3
+ quit: jest.Mock<Promise<void>>;
4
+ disconnect: jest.Mock<Promise<void>>;
5
+ isOpen: boolean;
6
+ on: jest.Mock;
7
+ get: jest.Mock<Promise<string | null>>;
8
+ set: jest.Mock<Promise<string | null>>;
9
+ del: jest.Mock<Promise<number>>;
10
+ exists: jest.Mock<Promise<number>>;
11
+ keys: jest.Mock<Promise<string[]>>;
12
+ flushAll: jest.Mock<Promise<string>>;
13
+ ping: jest.Mock<Promise<string>>;
14
+ xAdd: jest.Mock<Promise<string>>;
15
+ xRead: jest.Mock<Promise<unknown[]>>;
16
+ xReadGroup: jest.Mock<Promise<unknown[]>>;
17
+ xGroupCreate: jest.Mock<Promise<string>>;
18
+ xAck: jest.Mock<Promise<number>>;
19
+ hGet: jest.Mock<Promise<string | null>>;
20
+ hSet: jest.Mock<Promise<number>>;
21
+ hGetAll: jest.Mock<Promise<Record<string, string>>>;
22
+ hDel: jest.Mock<Promise<number>>;
23
+ hExists: jest.Mock<Promise<number>>;
24
+ expire: jest.Mock<Promise<number>>;
25
+ ttl: jest.Mock<Promise<number>>;
26
+ publish: jest.Mock<Promise<number>>;
27
+ [key: string]: unknown;
28
+ }
29
+ export interface RedisTestHelperOptions {
30
+ autoConnect?: boolean;
31
+ isOpen?: boolean;
32
+ }
33
+ export declare function createMockRedisClient(options?: RedisTestHelperOptions): MockRedisClient;
34
+ export declare function resetMockRedisClient(client: MockRedisClient): void;
35
+ export declare function setupRedisTestHelper(): {
36
+ mockClient: MockRedisClient;
37
+ reset: () => void;
38
+ };
39
+ export declare class RedisTestHelper {
40
+ private client;
41
+ constructor(options?: RedisTestHelperOptions);
42
+ getClient(): MockRedisClient;
43
+ reset(): void;
44
+ mockGet(key: string, value: string | null): void;
45
+ mockSet(_key: string, _value: string): void;
46
+ mockExists(key: string, exists: boolean): void;
47
+ mockKeys(_pattern: string, keys: string[]): void;
48
+ mockConnectError(error: Error): void;
49
+ mockQuitError(error: Error): void;
50
+ setConnectionState(isOpen: boolean): void;
51
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const redis_test_helper_1 = require("./redis-test-helper");
4
+ describe('RedisTestHelper Usage Examples', () => {
5
+ describe('using createMockRedisClient', () => {
6
+ it('should create a mock Redis client', async () => {
7
+ const mockClient = (0, redis_test_helper_1.createMockRedisClient)();
8
+ expect(mockClient.isOpen).toBe(true);
9
+ expect(mockClient.connect).toBeDefined();
10
+ expect(mockClient.quit).toBeDefined();
11
+ await mockClient.connect();
12
+ expect(mockClient.connect).toHaveBeenCalledTimes(1);
13
+ });
14
+ it('should create a disconnected client', () => {
15
+ const mockClient = (0, redis_test_helper_1.createMockRedisClient)({ isOpen: false });
16
+ expect(mockClient.isOpen).toBe(false);
17
+ });
18
+ it('should mock Redis operations', async () => {
19
+ const mockClient = (0, redis_test_helper_1.createMockRedisClient)();
20
+ mockClient.get.mockResolvedValue('test-value');
21
+ mockClient.set.mockResolvedValue('OK');
22
+ const value = await mockClient.get('test-key');
23
+ expect(value).toBe('test-value');
24
+ const result = await mockClient.set('test-key', 'test-value');
25
+ expect(result).toBe('OK');
26
+ });
27
+ });
28
+ describe('using setupRedisTestHelper', () => {
29
+ it('should provide reset functionality', () => {
30
+ const { mockClient, reset } = (0, redis_test_helper_1.setupRedisTestHelper)();
31
+ mockClient.get('key1');
32
+ expect(mockClient.get).toHaveBeenCalledTimes(1);
33
+ reset();
34
+ expect(mockClient.get).toHaveBeenCalledTimes(0);
35
+ });
36
+ });
37
+ describe('using RedisTestHelper class', () => {
38
+ let helper;
39
+ beforeEach(() => {
40
+ helper = new redis_test_helper_1.RedisTestHelper();
41
+ });
42
+ afterEach(() => {
43
+ helper.reset();
44
+ });
45
+ it('should provide convenient mock methods', async () => {
46
+ const client = helper.getClient();
47
+ helper.mockGet('user:123', 'John Doe');
48
+ const value = await client.get('user:123');
49
+ expect(value).toBe('John Doe');
50
+ helper.mockExists('user:123', true);
51
+ const exists = await client.exists('user:123');
52
+ expect(exists).toBe(1);
53
+ });
54
+ it('should handle connection errors', async () => {
55
+ const error = new Error('Connection failed');
56
+ helper.mockConnectError(error);
57
+ const client = helper.getClient();
58
+ await expect(client.connect()).rejects.toThrow('Connection failed');
59
+ });
60
+ it('should allow changing connection state', () => {
61
+ const client = helper.getClient();
62
+ expect(client.isOpen).toBe(true);
63
+ helper.setConnectionState(false);
64
+ expect(client.isOpen).toBe(false);
65
+ });
66
+ it('should mock keys operation', async () => {
67
+ helper.mockKeys('user:*', ['user:1', 'user:2', 'user:3']);
68
+ const client = helper.getClient();
69
+ const keys = await client.keys('user:*');
70
+ expect(keys).toEqual(['user:1', 'user:2', 'user:3']);
71
+ });
72
+ });
73
+ describe('integration with RedisClientType', () => {
74
+ it('should have required Redis client methods', () => {
75
+ const mockClient = (0, redis_test_helper_1.createMockRedisClient)();
76
+ expect(mockClient.connect).toBeDefined();
77
+ expect(mockClient.quit).toBeDefined();
78
+ expect(mockClient.isOpen).toBeDefined();
79
+ expect(typeof mockClient.connect).toBe('function');
80
+ expect(typeof mockClient.quit).toBe('function');
81
+ });
82
+ });
83
+ });
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisTestHelper = void 0;
4
+ exports.createMockRedisClient = createMockRedisClient;
5
+ exports.resetMockRedisClient = resetMockRedisClient;
6
+ exports.setupRedisTestHelper = setupRedisTestHelper;
7
+ function createMockRedisClient(options = {}) {
8
+ const { autoConnect = true, isOpen = true } = options;
9
+ const mockClient = {
10
+ connect: jest.fn().mockResolvedValue(undefined),
11
+ quit: jest.fn().mockResolvedValue(undefined),
12
+ disconnect: jest.fn().mockResolvedValue(undefined),
13
+ isOpen,
14
+ on: jest.fn(),
15
+ get: jest.fn().mockResolvedValue(null),
16
+ set: jest.fn().mockResolvedValue('OK'),
17
+ del: jest.fn().mockResolvedValue(1),
18
+ exists: jest.fn().mockResolvedValue(1),
19
+ keys: jest.fn().mockResolvedValue([]),
20
+ flushAll: jest.fn().mockResolvedValue('OK'),
21
+ ping: jest.fn().mockResolvedValue('PONG'),
22
+ xAdd: jest.fn().mockResolvedValue(''),
23
+ xRead: jest.fn().mockResolvedValue([]),
24
+ xReadGroup: jest.fn().mockResolvedValue([]),
25
+ xGroupCreate: jest.fn().mockResolvedValue('OK'),
26
+ xAck: jest.fn().mockResolvedValue(1),
27
+ hGet: jest.fn().mockResolvedValue(null),
28
+ hSet: jest.fn().mockResolvedValue(1),
29
+ hGetAll: jest.fn().mockResolvedValue({}),
30
+ hDel: jest.fn().mockResolvedValue(1),
31
+ hExists: jest.fn().mockResolvedValue(0),
32
+ expire: jest.fn().mockResolvedValue(1),
33
+ ttl: jest.fn().mockResolvedValue(-1),
34
+ publish: jest.fn().mockResolvedValue(0),
35
+ };
36
+ if (autoConnect) {
37
+ mockClient.connect.mockResolvedValue(undefined);
38
+ }
39
+ return mockClient;
40
+ }
41
+ function resetMockRedisClient(client) {
42
+ Object.keys(client).forEach((key) => {
43
+ if (jest.isMockFunction(client[key])) {
44
+ client[key].mockClear();
45
+ }
46
+ });
47
+ }
48
+ function setupRedisTestHelper() {
49
+ const mockClient = createMockRedisClient();
50
+ return {
51
+ mockClient,
52
+ reset: () => resetMockRedisClient(mockClient),
53
+ };
54
+ }
55
+ class RedisTestHelper {
56
+ constructor(options = {}) {
57
+ this.client = createMockRedisClient(options);
58
+ }
59
+ getClient() {
60
+ return this.client;
61
+ }
62
+ reset() {
63
+ resetMockRedisClient(this.client);
64
+ }
65
+ mockGet(key, value) {
66
+ this.client.get.mockImplementation((k) => {
67
+ if (k === key) {
68
+ return Promise.resolve(value);
69
+ }
70
+ return Promise.resolve(null);
71
+ });
72
+ }
73
+ mockSet(_key, _value) {
74
+ this.client.set.mockResolvedValue('OK');
75
+ }
76
+ mockExists(key, exists) {
77
+ this.client.exists.mockImplementation((k) => {
78
+ if (k === key) {
79
+ return Promise.resolve(exists ? 1 : 0);
80
+ }
81
+ return Promise.resolve(0);
82
+ });
83
+ }
84
+ mockKeys(_pattern, keys) {
85
+ this.client.keys.mockResolvedValue(keys);
86
+ }
87
+ mockConnectError(error) {
88
+ this.client.connect.mockRejectedValue(error);
89
+ }
90
+ mockQuitError(error) {
91
+ this.client.quit.mockRejectedValue(error);
92
+ }
93
+ setConnectionState(isOpen) {
94
+ Object.defineProperty(this.client, 'isOpen', {
95
+ value: isOpen,
96
+ writable: true,
97
+ configurable: true,
98
+ });
99
+ }
100
+ }
101
+ exports.RedisTestHelper = RedisTestHelper;
@@ -8,6 +8,7 @@ const core_1 = require("@motiadev/core");
8
8
  const printer_1 = require("@motiadev/core/dist/src/printer");
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const generate_locked_data_1 = require("../../generate-locked-data");
11
+ const redis_memory_manager_1 = require("../../redis-memory-manager");
11
12
  const build_error_1 = require("../../utils/errors/build.error");
12
13
  const builder_1 = require("../build/builder");
13
14
  const node_1 = require("../build/builders/node");
@@ -26,7 +27,8 @@ const build = async (listener) => {
26
27
  builder.registerBuilder('node', new node_1.NodeBuilder(builder, listener));
27
28
  fs_1.default.rmSync(constants_1.distDir, { recursive: true, force: true });
28
29
  fs_1.default.mkdirSync(constants_1.distDir, { recursive: true });
29
- const lockedData = new core_1.LockedData(constants_1.projectDir, new core_1.MemoryStreamAdapterManager(), new printer_1.NoPrinter());
30
+ const redisClient = await (0, redis_memory_manager_1.instanceRedisMemoryServer)(constants_1.projectDir, false);
31
+ const lockedData = new core_1.LockedData(constants_1.projectDir, new core_1.MemoryStreamAdapterManager(), new printer_1.NoPrinter(), redisClient);
30
32
  if (hasPythonSteps(stepFiles)) {
31
33
  builder.registerBuilder('python', new python_1.PythonBuilder(builder, listener));
32
34
  }
@@ -72,5 +72,6 @@ const createInteractive = async (args, context) => {
72
72
  cursorEnabled: true, // Default to true for cursor rules
73
73
  context,
74
74
  });
75
+ process.exit(0);
75
76
  };
76
77
  exports.createInteractive = createInteractive;
package/dist/cjs/dev.js CHANGED
@@ -1,18 +1,17 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.dev = void 0;
7
4
  const analytics_node_1 = require("@amplitude/analytics-node");
5
+ const adapter_redis_state_1 = require("@motiadev/adapter-redis-state");
6
+ const adapter_redis_streams_1 = require("@motiadev/adapter-redis-streams");
8
7
  const core_1 = require("@motiadev/core");
9
- const path_1 = __importDefault(require("path"));
10
8
  const endpoints_1 = require("./cloud/endpoints");
11
9
  const constants_1 = require("./constants");
12
10
  const dev_watchers_1 = require("./dev-watchers");
13
11
  const generate_locked_data_1 = require("./generate-locked-data");
14
12
  const load_motia_config_1 = require("./load-motia-config");
15
13
  const plugins_1 = require("./plugins");
14
+ const redis_memory_manager_1 = require("./redis-memory-manager");
16
15
  const activate_python_env_1 = require("./utils/activate-python-env");
17
16
  const analytics_1 = require("./utils/analytics");
18
17
  const version_1 = require("./version");
@@ -41,20 +40,18 @@ const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFileStora
41
40
  }
42
41
  const motiaFileStoragePath = motiaFileStorageDir || '.motia';
43
42
  const appConfig = await (0, load_motia_config_1.loadMotiaConfig)(baseDir);
43
+ const redisClient = await (0, redis_memory_manager_1.instanceRedisMemoryServer)(motiaFileStoragePath, true);
44
44
  const adapters = {
45
45
  eventAdapter: appConfig.adapters?.events || new core_1.DefaultQueueEventAdapter(),
46
46
  cronAdapter: appConfig.adapters?.cron || new core_1.DefaultCronAdapter(),
47
- streamAdapter: appConfig.adapters?.streams || new core_1.FileStreamAdapterManager(baseDir, motiaFileStoragePath),
47
+ streamAdapter: appConfig.adapters?.streams || new adapter_redis_streams_1.RedisStreamAdapterManager(redisClient),
48
48
  };
49
49
  const lockedData = await (0, generate_locked_data_1.generateLockedData)({
50
50
  projectDir: baseDir,
51
51
  streamAdapter: adapters.streamAdapter,
52
+ redisClient,
52
53
  });
53
- const state = appConfig.adapters?.state ||
54
- (0, core_1.createStateAdapter)({
55
- adapter: 'default',
56
- filePath: path_1.default.join(baseDir, motiaFileStoragePath),
57
- });
54
+ const state = appConfig.adapters?.state || new adapter_redis_state_1.RedisStateAdapter(redisClient);
58
55
  const config = { isVerbose };
59
56
  const motiaServer = (0, core_1.createServer)(lockedData, state, config, adapters, appConfig.app);
60
57
  const watcher = (0, dev_watchers_1.createDevWatchers)(lockedData, motiaServer, motiaServer.motiaEventManager, motiaServer.cronManager);
@@ -101,11 +98,11 @@ const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFileStora
101
98
  motiaServer.server.listen(port, hostname);
102
99
  console.log('🚀 Server ready and listening on port', port);
103
100
  console.log(`🔗 Open http://localhost:${port}${constants_1.workbenchBase} to open workbench 🛠️`);
104
- // 6) Gracefully shut down on SIGTERM
105
101
  process.on('SIGTERM', async () => {
106
102
  (0, core_1.trackEvent)('dev_server_shutdown', { reason: 'SIGTERM' });
107
103
  motiaServer.server.close();
108
104
  await watcher.stop();
105
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
109
106
  await (0, analytics_node_1.flush)().promise;
110
107
  process.exit(0);
111
108
  });
@@ -113,6 +110,7 @@ const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFileStora
113
110
  (0, core_1.trackEvent)('dev_server_shutdown', { reason: 'SIGINT' });
114
111
  motiaServer.server.close();
115
112
  await watcher.stop();
113
+ await (0, redis_memory_manager_1.stopRedisMemoryServer)();
116
114
  await (0, analytics_node_1.flush)().promise;
117
115
  process.exit(0);
118
116
  });
@@ -1,9 +1,11 @@
1
1
  import { LockedData, type Step, type StreamAdapterManager } from '@motiadev/core';
2
+ import type { RedisClientType } from 'redis';
2
3
  export declare const getStepFiles: (projectDir: string) => string[];
3
4
  export declare const getStreamFiles: (projectDir: string) => string[];
4
5
  export declare const collectFlows: (projectDir: string, lockedData: LockedData) => Promise<Step[]>;
5
6
  export declare const generateLockedData: (config: {
6
7
  projectDir: string;
7
8
  streamAdapter: StreamAdapterManager;
9
+ redisClient: RedisClientType;
8
10
  printerType?: "disabled" | "default";
9
11
  }) => Promise<LockedData>;
@@ -108,13 +108,13 @@ const collectFlows = async (projectDir, lockedData) => {
108
108
  exports.collectFlows = collectFlows;
109
109
  const generateLockedData = async (config) => {
110
110
  try {
111
- const { projectDir, streamAdapter, printerType = 'default' } = config;
111
+ const { projectDir, streamAdapter, printerType = 'default', redisClient } = config;
112
112
  const printer = printerType === 'disabled' ? new printer_1.NoPrinter() : new printer_1.Printer(projectDir);
113
113
  /*
114
114
  * NOTE: right now for performance and simplicity let's enforce a folder,
115
115
  * but we might want to remove this and scan the entire current directory
116
116
  */
117
- const lockedData = new core_1.LockedData(projectDir, streamAdapter, printer);
117
+ const lockedData = new core_1.LockedData(projectDir, streamAdapter, printer, redisClient);
118
118
  await (0, exports.collectFlows)(projectDir, lockedData);
119
119
  lockedData.saveTypes();
120
120
  return lockedData;
@@ -4,11 +4,13 @@ exports.generateTypes = void 0;
4
4
  const core_1 = require("@motiadev/core");
5
5
  const crypto_1 = require("crypto");
6
6
  const generate_locked_data_1 = require("./generate-locked-data");
7
+ const redis_memory_manager_1 = require("./redis-memory-manager");
7
8
  const version = `${(0, crypto_1.randomUUID)()}:${Math.floor(Date.now() / 1000)}`;
8
9
  const generateTypes = async (projectDir) => {
9
10
  const files = (0, generate_locked_data_1.getStepFiles)(projectDir);
10
11
  const streamsFiles = (0, generate_locked_data_1.getStreamFiles)(projectDir);
11
- const lockedData = new core_1.LockedData(projectDir, new core_1.MemoryStreamAdapterManager(), new core_1.Printer(projectDir));
12
+ const redisClient = await (0, redis_memory_manager_1.instanceRedisMemoryServer)(projectDir, false);
13
+ const lockedData = new core_1.LockedData(projectDir, new core_1.MemoryStreamAdapterManager(), new core_1.Printer(projectDir), redisClient);
12
14
  for (const filePath of files) {
13
15
  const config = await (0, core_1.getStepConfig)(filePath, projectDir);
14
16
  if (config) {
@@ -0,0 +1,7 @@
1
+ import { type RedisClientType } from 'redis';
2
+ export interface RedisConnectionInfo {
3
+ host: string;
4
+ port: number;
5
+ }
6
+ export declare const instanceRedisMemoryServer: (baseDir: string, autoStart?: boolean) => Promise<RedisClientType>;
7
+ export declare const stopRedisMemoryServer: () => Promise<void>;