motia 0.14.0-beta.165-198270 → 0.14.0-beta.165-275091

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.
@@ -37,12 +37,10 @@ var RedisMemoryManager = class {
37
37
  args: [
38
38
  "--appendonly",
39
39
  "yes",
40
+ "--appendfsync",
41
+ "everysec",
40
42
  "--save",
41
- "900 1",
42
- "--save",
43
- "300 10",
44
- "--save",
45
- "60 100",
43
+ "\"\"",
46
44
  "--dir",
47
45
  baseDir
48
46
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"redis-memory-manager.mjs","names":["instance: RedisMemoryInstancePropT"],"sources":["../src/redis-memory-manager.ts"],"sourcesContent":["import { mkdirSync } from 'fs'\nimport { createClient, type RedisClientType } from 'redis'\nimport { RedisMemoryServer } from 'redis-memory-server'\nimport type { RedisMemoryInstancePropT } from 'redis-memory-server/lib/types'\n\nexport interface RedisConnectionInfo {\n host: string\n port: number\n}\n\nclass RedisMemoryManager {\n private server: RedisMemoryServer | null = null\n private client: RedisClientType | null = null\n private running = false\n private cleanupHandlersRegistered = false\n\n private registerCleanupHandlers(): void {\n if (this.cleanupHandlersRegistered) return\n\n process.on('exit', () => {\n if (this.client?.isOpen && this.running) {\n this.client.quit().catch((error: unknown) => {\n console.error('[Redis Memory Server] Error closing client on exit:', error)\n })\n }\n if (this.server && this.running) {\n this.server.stop().catch((error: unknown) => {\n console.error('[Redis Memory Server] Error stopping on exit:', error)\n })\n }\n })\n\n process.on('SIGTERM', async () => {\n await this.stop()\n })\n\n process.on('SIGINT', async () => {\n await this.stop()\n })\n\n this.cleanupHandlersRegistered = true\n }\n\n async start(baseDir: string, autoStart: boolean): Promise<RedisClientType> {\n if (this.client && this.running) {\n return this.client\n }\n\n try {\n mkdirSync(baseDir, { recursive: true })\n\n const instance: RedisMemoryInstancePropT = {\n ip: process.env.MOTIA_REDIS_HOST || '127.0.0.1',\n args: ['--appendonly', 'yes', '--save', '900 1', '--save', '300 10', '--save', '60 100', '--dir', baseDir],\n }\n\n if (process.env.MOTIA_REDIS_PORT) {\n instance.port = parseInt(process.env.MOTIA_REDIS_PORT || '6379')\n }\n\n this.server = new RedisMemoryServer({\n instance,\n autoStart,\n })\n\n const host = await this.server.getHost()\n const port = await this.server.getPort()\n\n this.client = createClient({\n socket: {\n host,\n port,\n noDelay: true,\n keepAlive: true,\n reconnectStrategy: (retries: number) => {\n if (retries > 10) {\n return new Error('Redis connection retry limit exceeded')\n }\n return Math.min(retries * 100, 3000)\n },\n connectTimeout: 10000,\n },\n })\n\n this.client.on('error', (err: Error) => {\n if (err.message.includes('ECONNRESET') || err.message.includes('ECONNREFUSED')) {\n return\n }\n console.error('[Redis Memory Server] Client error:', err)\n })\n\n await this.client.connect()\n\n this.running = true\n this.registerCleanupHandlers()\n console.log(`[Redis Memory Server] Started on ${host}:${port}`)\n\n return this.client\n } catch (error) {\n console.error('[Redis Memory Server] Failed to start:', error)\n throw error\n }\n }\n\n async stop(): Promise<void> {\n if (this.client && this.running) {\n try {\n if (this.client.isOpen) {\n await this.client.quit().catch()\n }\n this.client = null\n } catch (error) {}\n }\n\n if (this.server && this.running) {\n try {\n await this.server.stop()\n this.running = false\n } catch (error) {\n console.error('[Redis Memory Server] Error stopping:', error)\n } finally {\n this.server = null\n }\n }\n }\n\n isRunning(): boolean {\n return this.running\n }\n\n getClient(): RedisClientType | null {\n return this.client\n }\n}\n\nconst manager = new RedisMemoryManager()\n\nexport const instanceRedisMemoryServer = (baseDir: string, autoStart: boolean = true): Promise<RedisClientType> =>\n manager.start(baseDir, autoStart)\n\nexport const stopRedisMemoryServer = (): Promise<void> => manager.stop()\n"],"mappings":";;;;;AAUA,IAAM,qBAAN,MAAyB;;gBACoB;gBACF;iBACvB;mCACkB;;CAEpC,AAAQ,0BAAgC;AACtC,MAAI,KAAK,0BAA2B;AAEpC,UAAQ,GAAG,cAAc;AACvB,OAAI,KAAK,QAAQ,UAAU,KAAK,QAC9B,MAAK,OAAO,MAAM,CAAC,OAAO,UAAmB;AAC3C,YAAQ,MAAM,uDAAuD,MAAM;KAC3E;AAEJ,OAAI,KAAK,UAAU,KAAK,QACtB,MAAK,OAAO,MAAM,CAAC,OAAO,UAAmB;AAC3C,YAAQ,MAAM,iDAAiD,MAAM;KACrE;IAEJ;AAEF,UAAQ,GAAG,WAAW,YAAY;AAChC,SAAM,KAAK,MAAM;IACjB;AAEF,UAAQ,GAAG,UAAU,YAAY;AAC/B,SAAM,KAAK,MAAM;IACjB;AAEF,OAAK,4BAA4B;;CAGnC,MAAM,MAAM,SAAiB,WAA8C;AACzE,MAAI,KAAK,UAAU,KAAK,QACtB,QAAO,KAAK;AAGd,MAAI;AACF,aAAU,SAAS,EAAE,WAAW,MAAM,CAAC;GAEvC,MAAMA,WAAqC;IACzC,IAAI,QAAQ,IAAI,oBAAoB;IACpC,MAAM;KAAC;KAAgB;KAAO;KAAU;KAAS;KAAU;KAAU;KAAU;KAAU;KAAS;KAAQ;IAC3G;AAED,OAAI,QAAQ,IAAI,iBACd,UAAS,OAAO,SAAS,QAAQ,IAAI,oBAAoB,OAAO;AAGlE,QAAK,SAAS,IAAI,kBAAkB;IAClC;IACA;IACD,CAAC;GAEF,MAAM,OAAO,MAAM,KAAK,OAAO,SAAS;GACxC,MAAM,OAAO,MAAM,KAAK,OAAO,SAAS;AAExC,QAAK,SAAS,aAAa,EACzB,QAAQ;IACN;IACA;IACA,SAAS;IACT,WAAW;IACX,oBAAoB,YAAoB;AACtC,SAAI,UAAU,GACZ,wBAAO,IAAI,MAAM,wCAAwC;AAE3D,YAAO,KAAK,IAAI,UAAU,KAAK,IAAK;;IAEtC,gBAAgB;IACjB,EACF,CAAC;AAEF,QAAK,OAAO,GAAG,UAAU,QAAe;AACtC,QAAI,IAAI,QAAQ,SAAS,aAAa,IAAI,IAAI,QAAQ,SAAS,eAAe,CAC5E;AAEF,YAAQ,MAAM,uCAAuC,IAAI;KACzD;AAEF,SAAM,KAAK,OAAO,SAAS;AAE3B,QAAK,UAAU;AACf,QAAK,yBAAyB;AAC9B,WAAQ,IAAI,oCAAoC,KAAK,GAAG,OAAO;AAE/D,UAAO,KAAK;WACL,OAAO;AACd,WAAQ,MAAM,0CAA0C,MAAM;AAC9D,SAAM;;;CAIV,MAAM,OAAsB;AAC1B,MAAI,KAAK,UAAU,KAAK,QACtB,KAAI;AACF,OAAI,KAAK,OAAO,OACd,OAAM,KAAK,OAAO,MAAM,CAAC,OAAO;AAElC,QAAK,SAAS;WACP,OAAO;AAGlB,MAAI,KAAK,UAAU,KAAK,QACtB,KAAI;AACF,SAAM,KAAK,OAAO,MAAM;AACxB,QAAK,UAAU;WACR,OAAO;AACd,WAAQ,MAAM,yCAAyC,MAAM;YACrD;AACR,QAAK,SAAS;;;CAKpB,YAAqB;AACnB,SAAO,KAAK;;CAGd,YAAoC;AAClC,SAAO,KAAK;;;AAIhB,MAAM,UAAU,IAAI,oBAAoB;AAExC,MAAa,6BAA6B,SAAiB,YAAqB,SAC9E,QAAQ,MAAM,SAAS,UAAU;AAEnC,MAAa,8BAA6C,QAAQ,MAAM"}
1
+ {"version":3,"file":"redis-memory-manager.mjs","names":["instance: RedisMemoryInstancePropT"],"sources":["../src/redis-memory-manager.ts"],"sourcesContent":["import { mkdirSync } from 'fs'\nimport { createClient, type RedisClientType } from 'redis'\nimport { RedisMemoryServer } from 'redis-memory-server'\nimport type { RedisMemoryInstancePropT } from 'redis-memory-server/lib/types'\n\nexport interface RedisConnectionInfo {\n host: string\n port: number\n}\n\nclass RedisMemoryManager {\n private server: RedisMemoryServer | null = null\n private client: RedisClientType | null = null\n private running = false\n private cleanupHandlersRegistered = false\n\n private registerCleanupHandlers(): void {\n if (this.cleanupHandlersRegistered) return\n\n process.on('exit', () => {\n if (this.client?.isOpen && this.running) {\n this.client.quit().catch((error: unknown) => {\n console.error('[Redis Memory Server] Error closing client on exit:', error)\n })\n }\n if (this.server && this.running) {\n this.server.stop().catch((error: unknown) => {\n console.error('[Redis Memory Server] Error stopping on exit:', error)\n })\n }\n })\n\n process.on('SIGTERM', async () => {\n await this.stop()\n })\n\n process.on('SIGINT', async () => {\n await this.stop()\n })\n\n this.cleanupHandlersRegistered = true\n }\n\n async start(baseDir: string, autoStart: boolean): Promise<RedisClientType> {\n if (this.client && this.running) {\n return this.client\n }\n\n try {\n mkdirSync(baseDir, { recursive: true })\n\n const instance: RedisMemoryInstancePropT = {\n ip: process.env.MOTIA_REDIS_HOST || '127.0.0.1',\n args: ['--appendonly', 'yes', '--appendfsync', 'everysec', '--save', '\"\"', '--dir', baseDir],\n }\n\n if (process.env.MOTIA_REDIS_PORT) {\n instance.port = parseInt(process.env.MOTIA_REDIS_PORT || '6379')\n }\n\n this.server = new RedisMemoryServer({\n instance,\n autoStart,\n })\n\n const host = await this.server.getHost()\n const port = await this.server.getPort()\n\n this.client = createClient({\n socket: {\n host,\n port,\n noDelay: true,\n keepAlive: true,\n reconnectStrategy: (retries: number) => {\n if (retries > 10) {\n return new Error('Redis connection retry limit exceeded')\n }\n return Math.min(retries * 100, 3000)\n },\n connectTimeout: 10000,\n },\n })\n\n this.client.on('error', (err: Error) => {\n if (err.message.includes('ECONNRESET') || err.message.includes('ECONNREFUSED')) {\n return\n }\n console.error('[Redis Memory Server] Client error:', err)\n })\n\n await this.client.connect()\n\n this.running = true\n this.registerCleanupHandlers()\n console.log(`[Redis Memory Server] Started on ${host}:${port}`)\n\n return this.client\n } catch (error) {\n console.error('[Redis Memory Server] Failed to start:', error)\n throw error\n }\n }\n\n async stop(): Promise<void> {\n if (this.client && this.running) {\n try {\n if (this.client.isOpen) {\n await this.client.quit().catch()\n }\n this.client = null\n } catch (error) {}\n }\n\n if (this.server && this.running) {\n try {\n await this.server.stop()\n this.running = false\n } catch (error) {\n console.error('[Redis Memory Server] Error stopping:', error)\n } finally {\n this.server = null\n }\n }\n }\n\n isRunning(): boolean {\n return this.running\n }\n\n getClient(): RedisClientType | null {\n return this.client\n }\n}\n\nconst manager = new RedisMemoryManager()\n\nexport const instanceRedisMemoryServer = (baseDir: string, autoStart: boolean = true): Promise<RedisClientType> =>\n manager.start(baseDir, autoStart)\n\nexport const stopRedisMemoryServer = (): Promise<void> => manager.stop()\n"],"mappings":";;;;;AAUA,IAAM,qBAAN,MAAyB;;gBACoB;gBACF;iBACvB;mCACkB;;CAEpC,AAAQ,0BAAgC;AACtC,MAAI,KAAK,0BAA2B;AAEpC,UAAQ,GAAG,cAAc;AACvB,OAAI,KAAK,QAAQ,UAAU,KAAK,QAC9B,MAAK,OAAO,MAAM,CAAC,OAAO,UAAmB;AAC3C,YAAQ,MAAM,uDAAuD,MAAM;KAC3E;AAEJ,OAAI,KAAK,UAAU,KAAK,QACtB,MAAK,OAAO,MAAM,CAAC,OAAO,UAAmB;AAC3C,YAAQ,MAAM,iDAAiD,MAAM;KACrE;IAEJ;AAEF,UAAQ,GAAG,WAAW,YAAY;AAChC,SAAM,KAAK,MAAM;IACjB;AAEF,UAAQ,GAAG,UAAU,YAAY;AAC/B,SAAM,KAAK,MAAM;IACjB;AAEF,OAAK,4BAA4B;;CAGnC,MAAM,MAAM,SAAiB,WAA8C;AACzE,MAAI,KAAK,UAAU,KAAK,QACtB,QAAO,KAAK;AAGd,MAAI;AACF,aAAU,SAAS,EAAE,WAAW,MAAM,CAAC;GAEvC,MAAMA,WAAqC;IACzC,IAAI,QAAQ,IAAI,oBAAoB;IACpC,MAAM;KAAC;KAAgB;KAAO;KAAiB;KAAY;KAAU;KAAM;KAAS;KAAQ;IAC7F;AAED,OAAI,QAAQ,IAAI,iBACd,UAAS,OAAO,SAAS,QAAQ,IAAI,oBAAoB,OAAO;AAGlE,QAAK,SAAS,IAAI,kBAAkB;IAClC;IACA;IACD,CAAC;GAEF,MAAM,OAAO,MAAM,KAAK,OAAO,SAAS;GACxC,MAAM,OAAO,MAAM,KAAK,OAAO,SAAS;AAExC,QAAK,SAAS,aAAa,EACzB,QAAQ;IACN;IACA;IACA,SAAS;IACT,WAAW;IACX,oBAAoB,YAAoB;AACtC,SAAI,UAAU,GACZ,wBAAO,IAAI,MAAM,wCAAwC;AAE3D,YAAO,KAAK,IAAI,UAAU,KAAK,IAAK;;IAEtC,gBAAgB;IACjB,EACF,CAAC;AAEF,QAAK,OAAO,GAAG,UAAU,QAAe;AACtC,QAAI,IAAI,QAAQ,SAAS,aAAa,IAAI,IAAI,QAAQ,SAAS,eAAe,CAC5E;AAEF,YAAQ,MAAM,uCAAuC,IAAI;KACzD;AAEF,SAAM,KAAK,OAAO,SAAS;AAE3B,QAAK,UAAU;AACf,QAAK,yBAAyB;AAC9B,WAAQ,IAAI,oCAAoC,KAAK,GAAG,OAAO;AAE/D,UAAO,KAAK;WACL,OAAO;AACd,WAAQ,MAAM,0CAA0C,MAAM;AAC9D,SAAM;;;CAIV,MAAM,OAAsB;AAC1B,MAAI,KAAK,UAAU,KAAK,QACtB,KAAI;AACF,OAAI,KAAK,OAAO,OACd,OAAM,KAAK,OAAO,MAAM,CAAC,OAAO;AAElC,QAAK,SAAS;WACP,OAAO;AAGlB,MAAI,KAAK,UAAU,KAAK,QACtB,KAAI;AACF,SAAM,KAAK,OAAO,MAAM;AACxB,QAAK,UAAU;WACR,OAAO;AACd,WAAQ,MAAM,yCAAyC,MAAM;YACrD;AACR,QAAK,SAAS;;;CAKpB,YAAqB;AACnB,SAAO,KAAK;;CAGd,YAAoC;AAClC,SAAO,KAAK;;;AAIhB,MAAM,UAAU,IAAI,oBAAoB;AAExC,MAAa,6BAA6B,SAAiB,YAAqB,SAC9E,QAAQ,MAAM,SAAS,UAAU;AAEnC,MAAa,8BAA6C,QAAQ,MAAM"}
package/dist/start.mjs CHANGED
@@ -29,10 +29,13 @@ const start = async (port, hostname, disableVerbose, motiaFileStorageDir) => {
29
29
  const appConfig = await loadMotiaConfig(baseDir);
30
30
  const redisClient = await instanceRedisMemoryServer(dotMotia);
31
31
  const adapters = {
32
- eventAdapter: appConfig.adapters?.events || new BullMQEventAdapter({ connection: {
33
- host: redisClient.options.socket?.host || "localhost",
34
- port: redisClient.options.socket?.port || 6379
35
- } }),
32
+ eventAdapter: appConfig.adapters?.events || new BullMQEventAdapter({
33
+ connection: {
34
+ host: redisClient.options.socket?.host || "localhost",
35
+ port: redisClient.options.socket?.port || 6379
36
+ },
37
+ prefix: "motia:events"
38
+ }),
36
39
  cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),
37
40
  streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient)
38
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"start.mjs","names":["redisClient: RedisClientType","plugins: MotiaPlugin[]"],"sources":["../src/start.ts"],"sourcesContent":["import { BullMQEventAdapter } from '@motiadev/adapter-bullmq-events'\nimport { RedisCronAdapter } from '@motiadev/adapter-redis-cron'\nimport { RedisStateAdapter } from '@motiadev/adapter-redis-state'\nimport { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'\nimport { createServer, type MotiaPlugin } from '@motiadev/core'\nimport path from 'path'\nimport type { RedisClientType } from 'redis'\nimport { workbenchBase } from './constants'\nimport { generateLockedData, getStepFiles, getStreamFiles } from './generate-locked-data'\nimport { loadMotiaConfig } from './load-motia-config'\nimport { processPlugins } from './plugins/index'\nimport { instanceRedisMemoryServer, stopRedisMemoryServer } from './redis-memory-manager'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { version } from './version'\n\nexport const start = async (\n port: number,\n hostname: string,\n disableVerbose: boolean,\n motiaFileStorageDir?: string,\n): Promise<void> => {\n const baseDir = process.cwd()\n const isVerbose = !disableVerbose\n\n const stepFiles = [...getStepFiles(baseDir), ...getStreamFiles(baseDir)]\n const hasPythonFiles = stepFiles.some((file) => file.endsWith('.py'))\n\n if (hasPythonFiles) {\n console.log('⚙️ Activating Python environment...')\n activatePythonVenv({ baseDir, isVerbose })\n }\n\n const motiaFileStoragePath = motiaFileStorageDir || '.motia'\n\n const dotMotia = path.join(baseDir, motiaFileStoragePath)\n const appConfig = await loadMotiaConfig(baseDir)\n\n const redisClient: RedisClientType = await instanceRedisMemoryServer(dotMotia)\n\n const adapters = {\n eventAdapter:\n appConfig.adapters?.events ||\n new BullMQEventAdapter({\n connection: {\n host: (redisClient.options.socket as { host?: string })?.host || 'localhost',\n port: (redisClient.options.socket as { port?: number })?.port || 6379,\n },\n }),\n cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),\n streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient),\n }\n const lockedData = await generateLockedData({\n projectDir: baseDir,\n streamAdapter: adapters.streamAdapter,\n redisClient,\n streamAuth: appConfig.streamAuth,\n })\n\n const state = appConfig.adapters?.state || new RedisStateAdapter(redisClient)\n\n const config = { isVerbose, isDev: false, version }\n\n const motiaServer = createServer(lockedData, state, config, adapters, appConfig.app)\n const plugins: MotiaPlugin[] = await processPlugins(motiaServer)\n\n if (!process.env.MOTIA_DOCKER_DISABLE_WORKBENCH) {\n const { applyMiddleware } = await import('@motiadev/workbench/middleware')\n await applyMiddleware({\n app: motiaServer.app,\n port,\n workbenchBase,\n plugins: plugins.flatMap((item) => item.workbench),\n })\n }\n\n motiaServer.server.listen(port, hostname)\n console.log('🚀 Server ready and listening on port', port)\n console.log(`🔗 Open http://${hostname}:${port}${workbenchBase} to open workbench 🛠️`)\n\n process.on('SIGTERM', async () => {\n motiaServer.server.close()\n await stopRedisMemoryServer()\n process.exit(0)\n })\n\n process.on('SIGINT', async () => {\n motiaServer.server.close()\n await stopRedisMemoryServer()\n process.exit(0)\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,QAAQ,OACnB,MACA,UACA,gBACA,wBACkB;CAClB,MAAM,UAAU,QAAQ,KAAK;CAC7B,MAAM,YAAY,CAAC;AAKnB,KAHkB,CAAC,GAAG,aAAa,QAAQ,EAAE,GAAG,eAAe,QAAQ,CAAC,CACvC,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC,EAEjD;AAClB,UAAQ,IAAI,sCAAsC;AAClD,qBAAmB;GAAE;GAAS;GAAW,CAAC;;CAG5C,MAAM,uBAAuB,uBAAuB;CAEpD,MAAM,WAAW,KAAK,KAAK,SAAS,qBAAqB;CACzD,MAAM,YAAY,MAAM,gBAAgB,QAAQ;CAEhD,MAAMA,cAA+B,MAAM,0BAA0B,SAAS;CAE9E,MAAM,WAAW;EACf,cACE,UAAU,UAAU,UACpB,IAAI,mBAAmB,EACrB,YAAY;GACV,MAAO,YAAY,QAAQ,QAA8B,QAAQ;GACjE,MAAO,YAAY,QAAQ,QAA8B,QAAQ;GAClE,EACF,CAAC;EACJ,aAAa,UAAU,UAAU,QAAQ,IAAI,iBAAiB,YAAY;EAC1E,eAAe,UAAU,UAAU,WAAW,IAAI,0BAA0B,YAAY;EACzF;CAYD,MAAM,cAAc,aAXD,MAAM,mBAAmB;EAC1C,YAAY;EACZ,eAAe,SAAS;EACxB;EACA,YAAY,UAAU;EACvB,CAAC,EAEY,UAAU,UAAU,SAAS,IAAI,kBAAkB,YAAY,EAE9D;EAAE;EAAW,OAAO;EAAO;EAAS,EAES,UAAU,UAAU,IAAI;CACpF,MAAMC,UAAyB,MAAM,eAAe,YAAY;AAEhE,KAAI,CAAC,QAAQ,IAAI,gCAAgC;EAC/C,MAAM,EAAE,oBAAoB,MAAM,OAAO;AACzC,QAAM,gBAAgB;GACpB,KAAK,YAAY;GACjB;GACA;GACA,SAAS,QAAQ,SAAS,SAAS,KAAK,UAAU;GACnD,CAAC;;AAGJ,aAAY,OAAO,OAAO,MAAM,SAAS;AACzC,SAAQ,IAAI,yCAAyC,KAAK;AAC1D,SAAQ,IAAI,kBAAkB,SAAS,GAAG,OAAO,cAAc,wBAAwB;AAEvF,SAAQ,GAAG,WAAW,YAAY;AAChC,cAAY,OAAO,OAAO;AAC1B,QAAM,uBAAuB;AAC7B,UAAQ,KAAK,EAAE;GACf;AAEF,SAAQ,GAAG,UAAU,YAAY;AAC/B,cAAY,OAAO,OAAO;AAC1B,QAAM,uBAAuB;AAC7B,UAAQ,KAAK,EAAE;GACf"}
1
+ {"version":3,"file":"start.mjs","names":["redisClient: RedisClientType","plugins: MotiaPlugin[]"],"sources":["../src/start.ts"],"sourcesContent":["import { BullMQEventAdapter } from '@motiadev/adapter-bullmq-events'\nimport { RedisCronAdapter } from '@motiadev/adapter-redis-cron'\nimport { RedisStateAdapter } from '@motiadev/adapter-redis-state'\nimport { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'\nimport { createServer, type MotiaPlugin } from '@motiadev/core'\nimport path from 'path'\nimport type { RedisClientType } from 'redis'\nimport { workbenchBase } from './constants'\nimport { generateLockedData, getStepFiles, getStreamFiles } from './generate-locked-data'\nimport { loadMotiaConfig } from './load-motia-config'\nimport { processPlugins } from './plugins/index'\nimport { instanceRedisMemoryServer, stopRedisMemoryServer } from './redis-memory-manager'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { version } from './version'\n\nexport const start = async (\n port: number,\n hostname: string,\n disableVerbose: boolean,\n motiaFileStorageDir?: string,\n): Promise<void> => {\n const baseDir = process.cwd()\n const isVerbose = !disableVerbose\n\n const stepFiles = [...getStepFiles(baseDir), ...getStreamFiles(baseDir)]\n const hasPythonFiles = stepFiles.some((file) => file.endsWith('.py'))\n\n if (hasPythonFiles) {\n console.log('⚙️ Activating Python environment...')\n activatePythonVenv({ baseDir, isVerbose })\n }\n\n const motiaFileStoragePath = motiaFileStorageDir || '.motia'\n\n const dotMotia = path.join(baseDir, motiaFileStoragePath)\n const appConfig = await loadMotiaConfig(baseDir)\n\n const redisClient: RedisClientType = await instanceRedisMemoryServer(dotMotia)\n\n const adapters = {\n eventAdapter:\n appConfig.adapters?.events ||\n new BullMQEventAdapter({\n connection: {\n host: (redisClient.options.socket as { host?: string })?.host || 'localhost',\n port: (redisClient.options.socket as { port?: number })?.port || 6379,\n },\n prefix: 'motia:events',\n }),\n cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),\n streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient),\n }\n const lockedData = await generateLockedData({\n projectDir: baseDir,\n streamAdapter: adapters.streamAdapter,\n redisClient,\n streamAuth: appConfig.streamAuth,\n })\n\n const state = appConfig.adapters?.state || new RedisStateAdapter(redisClient)\n\n const config = { isVerbose, isDev: false, version }\n\n const motiaServer = createServer(lockedData, state, config, adapters, appConfig.app)\n const plugins: MotiaPlugin[] = await processPlugins(motiaServer)\n\n if (!process.env.MOTIA_DOCKER_DISABLE_WORKBENCH) {\n const { applyMiddleware } = await import('@motiadev/workbench/middleware')\n await applyMiddleware({\n app: motiaServer.app,\n port,\n workbenchBase,\n plugins: plugins.flatMap((item) => item.workbench),\n })\n }\n\n motiaServer.server.listen(port, hostname)\n console.log('🚀 Server ready and listening on port', port)\n console.log(`🔗 Open http://${hostname}:${port}${workbenchBase} to open workbench 🛠️`)\n\n process.on('SIGTERM', async () => {\n motiaServer.server.close()\n await stopRedisMemoryServer()\n process.exit(0)\n })\n\n process.on('SIGINT', async () => {\n motiaServer.server.close()\n await stopRedisMemoryServer()\n process.exit(0)\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,QAAQ,OACnB,MACA,UACA,gBACA,wBACkB;CAClB,MAAM,UAAU,QAAQ,KAAK;CAC7B,MAAM,YAAY,CAAC;AAKnB,KAHkB,CAAC,GAAG,aAAa,QAAQ,EAAE,GAAG,eAAe,QAAQ,CAAC,CACvC,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC,EAEjD;AAClB,UAAQ,IAAI,sCAAsC;AAClD,qBAAmB;GAAE;GAAS;GAAW,CAAC;;CAG5C,MAAM,uBAAuB,uBAAuB;CAEpD,MAAM,WAAW,KAAK,KAAK,SAAS,qBAAqB;CACzD,MAAM,YAAY,MAAM,gBAAgB,QAAQ;CAEhD,MAAMA,cAA+B,MAAM,0BAA0B,SAAS;CAE9E,MAAM,WAAW;EACf,cACE,UAAU,UAAU,UACpB,IAAI,mBAAmB;GACrB,YAAY;IACV,MAAO,YAAY,QAAQ,QAA8B,QAAQ;IACjE,MAAO,YAAY,QAAQ,QAA8B,QAAQ;IAClE;GACD,QAAQ;GACT,CAAC;EACJ,aAAa,UAAU,UAAU,QAAQ,IAAI,iBAAiB,YAAY;EAC1E,eAAe,UAAU,UAAU,WAAW,IAAI,0BAA0B,YAAY;EACzF;CAYD,MAAM,cAAc,aAXD,MAAM,mBAAmB;EAC1C,YAAY;EACZ,eAAe,SAAS;EACxB;EACA,YAAY,UAAU;EACvB,CAAC,EAEY,UAAU,UAAU,SAAS,IAAI,kBAAkB,YAAY,EAE9D;EAAE;EAAW,OAAO;EAAO;EAAS,EAES,UAAU,UAAU,IAAI;CACpF,MAAMC,UAAyB,MAAM,eAAe,YAAY;AAEhE,KAAI,CAAC,QAAQ,IAAI,gCAAgC;EAC/C,MAAM,EAAE,oBAAoB,MAAM,OAAO;AACzC,QAAM,gBAAgB;GACpB,KAAK,YAAY;GACjB;GACA;GACA,SAAS,QAAQ,SAAS,SAAS,KAAK,UAAU;GACnD,CAAC;;AAGJ,aAAY,OAAO,OAAO,MAAM,SAAS;AACzC,SAAQ,IAAI,yCAAyC,KAAK;AAC1D,SAAQ,IAAI,kBAAkB,SAAS,GAAG,OAAO,cAAc,wBAAwB;AAEvF,SAAQ,GAAG,WAAW,YAAY;AAChC,cAAY,OAAO,OAAO;AAC1B,QAAM,uBAAuB;AAC7B,UAAQ,KAAK,EAAE;GACf;AAEF,SAAQ,GAAG,UAAU,YAAY;AAC/B,cAAY,OAAO,OAAO;AAC1B,QAAM,uBAAuB;AAC7B,UAAQ,KAAK,EAAE;GACf"}
package/dist/watcher.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { getStepConfig, getStreamConfig } from "@motiadev/core";
1
+ import { getStepConfig, getStreamConfig, invalidate } from "@motiadev/core";
2
2
  import { randomUUID } from "crypto";
3
3
  import chokidar from "chokidar";
4
4
 
@@ -44,6 +44,7 @@ var Watcher = class {
44
44
  this.stepCreateHandler?.(step);
45
45
  }
46
46
  async onStepFileChange(path) {
47
+ if (path.endsWith(".ts")) invalidate(path);
47
48
  const config = await getStepConfig(path, this.dir).catch((err) => {
48
49
  console.error(err);
49
50
  });
@@ -67,6 +68,7 @@ var Watcher = class {
67
68
  if (step && !config) this.stepDeleteHandler?.(step);
68
69
  }
69
70
  async onStepFileDelete(path) {
71
+ if (path.endsWith(".ts")) invalidate(path);
70
72
  const step = this.findStep(path);
71
73
  if (!step) {
72
74
  console.warn(`Step ${path} not found, step skipped`);
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.mjs","names":["dir: string","lockedData: LockedData","step: Step","step","newStep: Step"],"sources":["../src/watcher.ts"],"sourcesContent":["import type { Stream } from '@motiadev/core'\nimport { getStepConfig, getStreamConfig, type LockedData, type Step } from '@motiadev/core'\nimport chokidar, { type FSWatcher } from 'chokidar'\nimport { randomUUID } from 'crypto'\n\ntype StepChangeHandler = (oldStep: Step, newStep: Step) => void\ntype StepCreateHandler = (step: Step) => void\ntype StepDeleteHandler = (step: Step) => void\n\ntype StreamChangeHandler = (oldStream: Stream, newStream: Stream) => void\ntype StreamCreateHandler = (stream: Stream) => void\ntype StreamDeleteHandler = (stream: Stream) => void\n\nexport class Watcher {\n private watcher?: FSWatcher\n private stepChangeHandler?: StepChangeHandler\n private stepCreateHandler?: StepCreateHandler\n private stepDeleteHandler?: StepDeleteHandler\n private streamChangeHandler?: StreamChangeHandler\n private streamCreateHandler?: StreamCreateHandler\n private streamDeleteHandler?: StreamDeleteHandler\n\n constructor(\n private readonly dir: string,\n private lockedData: LockedData,\n ) {}\n\n onStepChange(handler: StepChangeHandler) {\n this.stepChangeHandler = handler\n }\n\n onStepCreate(handler: StepCreateHandler) {\n this.stepCreateHandler = handler\n }\n\n onStepDelete(handler: StepDeleteHandler) {\n this.stepDeleteHandler = handler\n }\n\n onStreamChange(handler: StreamChangeHandler) {\n this.streamChangeHandler = handler\n }\n\n onStreamCreate(handler: StreamCreateHandler) {\n this.streamCreateHandler = handler\n }\n\n onStreamDelete(handler: StreamDeleteHandler) {\n this.streamDeleteHandler = handler\n }\n\n private findStep(path: string): Step | undefined {\n return (\n this.lockedData.activeSteps.find((step) => step.filePath === path) ||\n this.lockedData.devSteps.find((step) => step.filePath === path)\n )\n }\n\n private async onStepFileAdd(path: string): Promise<void> {\n if (!this.stepCreateHandler) {\n console.warn(`No step create handler, step skipped`)\n return\n }\n\n const config = await getStepConfig(path, this.dir).catch((err) => console.error(err))\n\n if (!config) {\n return\n }\n\n const version = `${randomUUID()}:${Math.floor(Date.now() / 1000)}`\n const step: Step = { filePath: path, version, config }\n\n this.stepCreateHandler?.(step)\n }\n\n private async onStepFileChange(path: string): Promise<void> {\n const config = await getStepConfig(path, this.dir).catch((err) => {\n console.error(err)\n })\n\n const step = this.findStep(path)\n\n if (!step && !config) {\n return\n }\n\n // didn't have a step, but now we have a config\n if (!step && config) {\n const version = `${randomUUID()}:${Math.floor(Date.now() / 1000)}`\n const step: Step = { filePath: path, version, config }\n\n this.stepCreateHandler?.(step)\n }\n\n // had a step, and now we have a config\n if (step && config) {\n const newStep: Step = { ...step, config }\n this.stepChangeHandler?.(step, newStep)\n }\n\n // had a step, but no config\n if (step && !config) {\n this.stepDeleteHandler?.(step)\n }\n }\n\n private async onStepFileDelete(path: string): Promise<void> {\n const step = this.findStep(path)\n\n if (!step) {\n console.warn(`Step ${path} not found, step skipped`)\n return\n }\n\n this.stepDeleteHandler?.(step)\n }\n\n private async onStreamFileAdd(path: string): Promise<void> {\n const config = await getStreamConfig(path).catch((err) => console.error(err))\n\n if (!config) {\n return\n }\n\n this.streamCreateHandler?.({ filePath: path, config, factory: null as never })\n }\n\n private async onStreamFileChange(path: string): Promise<void> {\n const stream = this.lockedData.findStream(path)\n const config = await getStreamConfig(path).catch((err) => console.error(err))\n\n if (!stream && config) {\n this.streamCreateHandler?.({ filePath: path, config, factory: null as never })\n } else if (stream && config) {\n this.streamChangeHandler?.(stream, { filePath: path, config, factory: null as never })\n } else if (stream && !config) {\n this.streamDeleteHandler?.(stream)\n }\n }\n\n private async onStreamFileDelete(path: string): Promise<void> {\n const stream = this.lockedData.findStream(path)\n\n if (this.streamDeleteHandler && stream) {\n this.streamDeleteHandler(stream)\n }\n }\n\n private async onFileAdd(path: string): Promise<void> {\n if (this.isStepFile(path)) {\n this.onStepFileAdd(path)\n } else if (this.isStreamFile(path)) {\n this.onStreamFileAdd(path)\n }\n }\n\n private async onFileChange(path: string): Promise<void> {\n if (this.isStepFile(path)) {\n this.onStepFileChange(path)\n } else if (this.isStreamFile(path)) {\n this.onStreamFileChange(path)\n }\n }\n\n private async onFileDelete(path: string): Promise<void> {\n if (this.isStepFile(path)) {\n this.onStepFileDelete(path)\n } else if (this.isStreamFile(path)) {\n this.onStreamFileDelete(path)\n }\n }\n\n init() {\n this.watcher = chokidar\n .watch(this.dir, { persistent: true, ignoreInitial: true })\n .on('add', (path) => this.onFileAdd(path))\n .on('change', (path) => this.onFileChange(path))\n .on('unlink', (path) => this.onFileDelete(path))\n }\n\n private isStepFile(path: string): boolean {\n const isUiNode = /\\.(tsx|jsx)$/.test(path)\n const isDeprecatedPythonStep = /\\.step\\.py$/.test(path)\n\n return /[._]step\\.((ts)|(js)|(rb)|(py))$/.test(path) && !isUiNode && !isDeprecatedPythonStep\n }\n\n private isStreamFile(path: string): boolean {\n const isUiNode = /\\.(tsx|jsx)$/.test(path)\n const isDeprecatedPythonStream = /\\.stream\\.py$/.test(path)\n\n return /[._]stream\\.((ts)|(js)|(rb)|(py))$/.test(path) && !isUiNode && !isDeprecatedPythonStream\n }\n\n async stop(): Promise<void> {\n if (this.watcher) {\n await this.watcher.close()\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"watcher.mjs","names":["dir: string","lockedData: LockedData","step: Step","step","newStep: Step"],"sources":["../src/watcher.ts"],"sourcesContent":["import type { Stream } from '@motiadev/core'\nimport { getStepConfig, getStreamConfig, invalidate, type LockedData, type Step } from '@motiadev/core'\nimport chokidar, { type FSWatcher } from 'chokidar'\nimport { randomUUID } from 'crypto'\n\ntype StepChangeHandler = (oldStep: Step, newStep: Step) => void\ntype StepCreateHandler = (step: Step) => void\ntype StepDeleteHandler = (step: Step) => void\n\ntype StreamChangeHandler = (oldStream: Stream, newStream: Stream) => void\ntype StreamCreateHandler = (stream: Stream) => void\ntype StreamDeleteHandler = (stream: Stream) => void\n\nexport class Watcher {\n private watcher?: FSWatcher\n private stepChangeHandler?: StepChangeHandler\n private stepCreateHandler?: StepCreateHandler\n private stepDeleteHandler?: StepDeleteHandler\n private streamChangeHandler?: StreamChangeHandler\n private streamCreateHandler?: StreamCreateHandler\n private streamDeleteHandler?: StreamDeleteHandler\n\n constructor(\n private readonly dir: string,\n private lockedData: LockedData,\n ) {}\n\n onStepChange(handler: StepChangeHandler) {\n this.stepChangeHandler = handler\n }\n\n onStepCreate(handler: StepCreateHandler) {\n this.stepCreateHandler = handler\n }\n\n onStepDelete(handler: StepDeleteHandler) {\n this.stepDeleteHandler = handler\n }\n\n onStreamChange(handler: StreamChangeHandler) {\n this.streamChangeHandler = handler\n }\n\n onStreamCreate(handler: StreamCreateHandler) {\n this.streamCreateHandler = handler\n }\n\n onStreamDelete(handler: StreamDeleteHandler) {\n this.streamDeleteHandler = handler\n }\n\n private findStep(path: string): Step | undefined {\n return (\n this.lockedData.activeSteps.find((step) => step.filePath === path) ||\n this.lockedData.devSteps.find((step) => step.filePath === path)\n )\n }\n\n private async onStepFileAdd(path: string): Promise<void> {\n if (!this.stepCreateHandler) {\n console.warn(`No step create handler, step skipped`)\n return\n }\n\n const config = await getStepConfig(path, this.dir).catch((err) => console.error(err))\n\n if (!config) {\n return\n }\n\n const version = `${randomUUID()}:${Math.floor(Date.now() / 1000)}`\n const step: Step = { filePath: path, version, config }\n\n this.stepCreateHandler?.(step)\n }\n\n private async onStepFileChange(path: string): Promise<void> {\n if (path.endsWith('.ts')) {\n invalidate(path)\n }\n\n const config = await getStepConfig(path, this.dir).catch((err) => {\n console.error(err)\n })\n\n const step = this.findStep(path)\n\n if (!step && !config) {\n return\n }\n\n // didn't have a step, but now we have a config\n if (!step && config) {\n const version = `${randomUUID()}:${Math.floor(Date.now() / 1000)}`\n const step: Step = { filePath: path, version, config }\n\n this.stepCreateHandler?.(step)\n }\n\n // had a step, and now we have a config\n if (step && config) {\n const newStep: Step = { ...step, config }\n this.stepChangeHandler?.(step, newStep)\n }\n\n // had a step, but no config\n if (step && !config) {\n this.stepDeleteHandler?.(step)\n }\n }\n\n private async onStepFileDelete(path: string): Promise<void> {\n if (path.endsWith('.ts')) {\n invalidate(path)\n }\n\n const step = this.findStep(path)\n\n if (!step) {\n console.warn(`Step ${path} not found, step skipped`)\n return\n }\n\n this.stepDeleteHandler?.(step)\n }\n\n private async onStreamFileAdd(path: string): Promise<void> {\n const config = await getStreamConfig(path).catch((err) => console.error(err))\n\n if (!config) {\n return\n }\n\n this.streamCreateHandler?.({ filePath: path, config, factory: null as never })\n }\n\n private async onStreamFileChange(path: string): Promise<void> {\n const stream = this.lockedData.findStream(path)\n const config = await getStreamConfig(path).catch((err) => console.error(err))\n\n if (!stream && config) {\n this.streamCreateHandler?.({ filePath: path, config, factory: null as never })\n } else if (stream && config) {\n this.streamChangeHandler?.(stream, { filePath: path, config, factory: null as never })\n } else if (stream && !config) {\n this.streamDeleteHandler?.(stream)\n }\n }\n\n private async onStreamFileDelete(path: string): Promise<void> {\n const stream = this.lockedData.findStream(path)\n\n if (this.streamDeleteHandler && stream) {\n this.streamDeleteHandler(stream)\n }\n }\n\n private async onFileAdd(path: string): Promise<void> {\n if (this.isStepFile(path)) {\n this.onStepFileAdd(path)\n } else if (this.isStreamFile(path)) {\n this.onStreamFileAdd(path)\n }\n }\n\n private async onFileChange(path: string): Promise<void> {\n if (this.isStepFile(path)) {\n this.onStepFileChange(path)\n } else if (this.isStreamFile(path)) {\n this.onStreamFileChange(path)\n }\n }\n\n private async onFileDelete(path: string): Promise<void> {\n if (this.isStepFile(path)) {\n this.onStepFileDelete(path)\n } else if (this.isStreamFile(path)) {\n this.onStreamFileDelete(path)\n }\n }\n\n init() {\n this.watcher = chokidar\n .watch(this.dir, { persistent: true, ignoreInitial: true })\n .on('add', (path) => this.onFileAdd(path))\n .on('change', (path) => this.onFileChange(path))\n .on('unlink', (path) => this.onFileDelete(path))\n }\n\n private isStepFile(path: string): boolean {\n const isUiNode = /\\.(tsx|jsx)$/.test(path)\n const isDeprecatedPythonStep = /\\.step\\.py$/.test(path)\n\n return /[._]step\\.((ts)|(js)|(rb)|(py))$/.test(path) && !isUiNode && !isDeprecatedPythonStep\n }\n\n private isStreamFile(path: string): boolean {\n const isUiNode = /\\.(tsx|jsx)$/.test(path)\n const isDeprecatedPythonStream = /\\.stream\\.py$/.test(path)\n\n return /[._]stream\\.((ts)|(js)|(rb)|(py))$/.test(path) && !isUiNode && !isDeprecatedPythonStream\n }\n\n async stop(): Promise<void> {\n if (this.watcher) {\n await this.watcher.close()\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "motia",
3
3
  "description": "Build production-grade backends with a single primitive. APIs, background jobs, Queues, Workflows, and AI agents - unified in one system with built-in State management, Streaming, and Observability.",
4
- "version": "0.14.0-beta.165-198270",
4
+ "version": "0.14.0-beta.165-275091",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
7
7
  "repository": {
@@ -46,13 +46,13 @@
46
46
  "table": "^6.9.0",
47
47
  "ts-node": "^10.9.2",
48
48
  "zod": "^4.1.12",
49
- "@motiadev/adapter-redis-cron": "0.14.0-beta.165-198270",
50
- "@motiadev/adapter-redis-state": "0.14.0-beta.165-198270",
51
- "@motiadev/adapter-redis-streams": "0.14.0-beta.165-198270",
52
- "@motiadev/adapter-bullmq-events": "0.14.0-beta.165-198270",
53
- "@motiadev/core": "0.14.0-beta.165-198270",
54
- "@motiadev/stream-client-node": "0.14.0-beta.165-198270",
55
- "@motiadev/workbench": "0.14.0-beta.165-198270"
49
+ "@motiadev/adapter-bullmq-events": "0.14.0-beta.165-275091",
50
+ "@motiadev/adapter-redis-streams": "0.14.0-beta.165-275091",
51
+ "@motiadev/stream-client-node": "0.14.0-beta.165-275091",
52
+ "@motiadev/core": "0.14.0-beta.165-275091",
53
+ "@motiadev/adapter-redis-state": "0.14.0-beta.165-275091",
54
+ "@motiadev/workbench": "0.14.0-beta.165-275091",
55
+ "@motiadev/adapter-redis-cron": "0.14.0-beta.165-275091"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@amplitude/analytics-types": "^2.9.2",