motia 0.15.4-beta.170-803755 → 0.15.4-beta.170-980856

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.
@@ -1,10 +1,10 @@
1
1
  import { executeCommand } from "../utils/execute-command.mjs";
2
+ import { checkIfDirectoryExists, checkIfFileExists } from "./utils.mjs";
3
+ import { getPackageManager } from "../utils/get-package-manager.mjs";
2
4
  import { version } from "../version.mjs";
3
5
  import { generateTypes } from "../generate-types.mjs";
4
6
  import { pythonInstall } from "../install.mjs";
5
7
  import { pluginDependencies } from "../plugins/plugin-dependencies.mjs";
6
- import { checkIfDirectoryExists, checkIfFileExists } from "./utils.mjs";
7
- import { getPackageManager } from "../utils/get-package-manager.mjs";
8
8
  import { pullRules } from "./pull-rules.mjs";
9
9
  import { setupTemplate } from "./setup-template.mjs";
10
10
  import fs from "fs";
package/dist/dev.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { activatePythonVenv } from "./utils/activate-python-env.mjs";
2
+ import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
2
3
  import { generateLockedData, getStepFiles, getStreamFiles } from "./generate-locked-data.mjs";
3
4
  import { version } from "./version.mjs";
4
5
  import { identifyUser } from "./utils/analytics.mjs";
@@ -9,7 +10,6 @@ import { createDevWatchers } from "./dev-watchers.mjs";
9
10
  import { processPlugins } from "./plugins/process-plugins.mjs";
10
11
  import "./plugins/index.mjs";
11
12
  import { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from "./redis/connection.mjs";
12
- import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
13
13
  import { createMermaidGenerator, createServer, getProjectIdentifier, trackEvent } from "@motiadev/core";
14
14
  import { flush } from "@amplitude/analytics-node";
15
15
  import { BullMQEventAdapter } from "@motiadev/adapter-bullmq-events";
@@ -1 +1 @@
1
- {"version":3,"file":"generate-locked-data.d.mts","names":[],"sources":["../src/generate-locked-data.ts"],"sourcesContent":[],"mappings":";;;;AAyDa,cAAA,YAmFZ,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,UAAA,EAnFkE,UAmFlE,EAAA,GAnF+E,OAmF/E,CAnFuF,IAmFvF,EAAA,CAAA;KAEI,iBAAA,GArF8D;EAAqB,YAAA,EAsFxE,gBAtFwE,CAAA,cAAA,CAAA;EAAR,aAAA,CAAA,EAuF9D,UAvF8D;CAAO;AAqFlF,cAKQ,kBAJG,EAAA,CAAA,MAAA,EAAA;EAIH,UAAA,EAAA,MAAA;EAEK,aAAA,CAAA,EAAA,oBAAA;EACF,WAAA,CAAA,EAAA,eAAA;EAED,WAAA,CAAA,EAAA,UAAA,GAAA,SAAA;EACH,UAAA,CAAA,EADG,iBACH;CAAR,EAAA,GAAA,OAAA,CAAQ,UAAR,CAAA"}
1
+ {"version":3,"file":"generate-locked-data.d.mts","names":[],"sources":["../src/generate-locked-data.ts"],"sourcesContent":[],"mappings":";;;;AA0Da,cAAA,YA0FZ,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,UAAA,EA1FkE,UA0FlE,EAAA,GA1F+E,OA0F/E,CA1FuF,IA0FvF,EAAA,CAAA;KAEI,iBAAA,GA5F8D;EAAqB,YAAA,EA6FxE,gBA7FwE,CAAA,cAAA,CAAA;EAAR,aAAA,CAAA,EA8F9D,UA9F8D;CAAO;AA4FlF,cAKQ,kBAJG,EAAA,CAAA,MAAA,EAAA;EAIH,UAAA,EAAA,MAAA;EAEK,aAAA,CAAA,EAAA,oBAAA;EACF,WAAA,CAAA,EAAA,eAAA;EAED,WAAA,CAAA,EAAA,UAAA,GAAA,SAAA;EACH,UAAA,CAAA,EADG,iBACH;CAAR,EAAA,GAAA,OAAA,CAAQ,UAAR,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { activatePythonVenv } from "./utils/activate-python-env.mjs";
2
2
  import { CompilationError } from "./utils/errors/compilation.error.mjs";
3
3
  import { LockedDataGenerationError } from "./utils/errors/locked-data-generation.error.mjs";
4
+ import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
4
5
  import { LockedData, MemoryStreamAdapterManager, NoPrinter, Printer, getStepConfig, getStreamConfig } from "@motiadev/core";
5
6
  import { randomUUID } from "crypto";
6
7
  import { existsSync } from "fs";
@@ -53,7 +54,12 @@ const collectFlows = async (projectDir, lockedData) => {
53
54
  absolute: true,
54
55
  cwd: srcDir
55
56
  }) : []];
56
- if (stepFiles.some((file) => file.endsWith(".py")) || streamFiles.some((file) => file.endsWith(".py"))) activatePythonVenv({ baseDir: projectDir });
57
+ const hasPythonFiles = stepFiles.some((file) => file.endsWith(".py")) || streamFiles.some((file) => file.endsWith(".py"));
58
+ if (!(await validatePythonEnvironment({
59
+ baseDir: projectDir,
60
+ hasPythonFiles
61
+ })).success) throw new LockedDataGenerationError("Python environment validation failed. Please run the install command to set up your Python environment.");
62
+ if (hasPythonFiles) activatePythonVenv({ baseDir: projectDir });
57
63
  for (const filePath of stepFiles) try {
58
64
  const config = await getStepConfig(filePath, projectDir);
59
65
  if (!config) {
@@ -1 +1 @@
1
- {"version":3,"file":"generate-locked-data.mjs","names":["invalidSteps: Step[]"],"sources":["../src/generate-locked-data.ts"],"sourcesContent":["import {\n getStepConfig,\n getStreamConfig,\n type JsonSchema,\n LockedData,\n MemoryStreamAdapterManager,\n NoPrinter,\n Printer,\n type Step,\n type StreamAdapterManager,\n type StreamAuthConfig,\n} from '@motiadev/core'\nimport { randomUUID } from 'crypto'\nimport { existsSync } from 'fs'\nimport { globSync } from 'glob'\nimport path from 'path'\nimport pc from 'picocolors'\nimport type { RedisClientType } from 'redis'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { CompilationError } from './utils/errors/compilation.error'\nimport { LockedDataGenerationError } from './utils/errors/locked-data-generation.error'\n\nconst version = `${randomUUID()}:${Math.floor(Date.now() / 1000)}`\n\nconst getStepFilesFromDir = (dir: string): string[] => {\n if (!existsSync(dir)) {\n return []\n }\n return [\n ...globSync('**/*.step.{ts,js,rb}', { absolute: true, cwd: dir }),\n ...globSync('**/*_step.{ts,js,py,rb}', { absolute: true, cwd: dir }),\n ]\n}\n\nexport const getStepFiles = (projectDir: string): string[] => {\n const stepsDir = path.join(projectDir, 'steps')\n const srcDir = path.join(projectDir, 'src')\n return [...getStepFilesFromDir(stepsDir), ...getStepFilesFromDir(srcDir)]\n}\n\nconst getStreamFilesFromDir = (dir: string): string[] => {\n if (!existsSync(dir)) {\n return []\n }\n return [\n ...globSync('**/*.stream.{ts,js,rb}', { absolute: true, cwd: dir }),\n ...globSync('**/*_stream.{ts,js,py,rb}', { absolute: true, cwd: dir }),\n ]\n}\n\nexport const getStreamFiles = (projectDir: string): string[] => {\n const stepsDir = path.join(projectDir, 'steps')\n const srcDir = path.join(projectDir, 'src')\n return [...getStreamFilesFromDir(stepsDir), ...getStreamFilesFromDir(srcDir)]\n}\n\n// Helper function to recursively collect flow data\nexport const collectFlows = async (projectDir: string, lockedData: LockedData): Promise<Step[]> => {\n const invalidSteps: Step[] = []\n const stepFiles = getStepFiles(projectDir)\n const streamFiles = getStreamFiles(projectDir)\n const stepsDir = path.join(projectDir, 'steps')\n const srcDir = path.join(projectDir, 'src')\n const deprecatedSteps = [\n ...(existsSync(stepsDir) ? globSync('**/*.step.py', { absolute: true, cwd: stepsDir }) : []),\n ...(existsSync(srcDir) ? globSync('**/*.step.py', { absolute: true, cwd: srcDir }) : []),\n ]\n\n const hasPythonFiles =\n stepFiles.some((file) => file.endsWith('.py')) || streamFiles.some((file) => file.endsWith('.py'))\n\n if (hasPythonFiles) {\n activatePythonVenv({ baseDir: projectDir })\n }\n\n for (const filePath of stepFiles) {\n try {\n const config = await getStepConfig(filePath, projectDir)\n\n if (!config) {\n console.warn(`No config found in step ${filePath}, step skipped`)\n continue\n }\n\n const result = lockedData.createStep({ filePath, version, config }, { disableTypeCreation: true })\n\n if (!result) {\n invalidSteps.push({ filePath, version, config })\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err)\n if (errorMessage.includes('Executable ruby not found') || errorMessage.includes('Executable python not found')) {\n console.warn(pc.yellow(`! [WARNING] Skipping step ${filePath}: ${errorMessage}`))\n continue\n }\n throw new CompilationError(`Error collecting flow ${filePath}`, path.relative(projectDir, filePath), err as Error)\n }\n }\n\n for (const filePath of streamFiles) {\n const config = await getStreamConfig(filePath)\n\n if (!config) {\n console.warn(`No config found in stream ${filePath}, stream skipped`)\n continue\n }\n\n lockedData.createStream({ filePath, config }, { disableTypeCreation: true })\n }\n\n if (deprecatedSteps.length > 0) {\n const warning = pc.yellow('! [WARNING]')\n console.warn(\n pc.yellow(\n [\n '',\n '========================================',\n warning,\n '',\n `Python steps with ${pc.gray('.step.py')} extensions are no longer supported.`,\n `Please rename them to ${pc.gray('_step.py')}.`,\n '',\n pc.bold('Steps:'),\n ...deprecatedSteps.map((step) =>\n pc.reset(\n `- ${pc.cyan(pc.bold(step.replace(projectDir, '')))} rename to ${pc.gray(`${step.replace(projectDir, '').replace('.step.py', '_step.py')}`)}`,\n ),\n ),\n\n '',\n 'Make sure the step names are importable from Python:',\n `- Don't use numbers, dots, dashes, commas, spaces, colons, or special characters`,\n '========================================',\n '',\n ].join('\\n'),\n ),\n )\n }\n\n return invalidSteps\n}\n\ntype StreamAuthOptions = {\n authenticate: StreamAuthConfig['authenticate']\n contextSchema?: JsonSchema\n}\n\nexport const generateLockedData = async (config: {\n projectDir: string\n streamAdapter?: StreamAdapterManager\n redisClient?: RedisClientType\n printerType?: 'disabled' | 'default'\n streamAuth?: StreamAuthOptions\n}): Promise<LockedData> => {\n try {\n const {\n projectDir,\n streamAdapter = new MemoryStreamAdapterManager(),\n printerType = 'default',\n redisClient,\n streamAuth,\n } = config\n const printer = printerType === 'disabled' ? new NoPrinter() : new Printer(projectDir)\n /*\n * NOTE: right now for performance and simplicity let's enforce a folder,\n * but we might want to remove this and scan the entire current directory\n */\n const lockedData = new LockedData(projectDir, streamAdapter, printer, redisClient)\n lockedData.setStreamAuthConfig(streamAuth)\n\n await collectFlows(projectDir, lockedData)\n lockedData.saveTypes()\n\n return lockedData\n } catch (error) {\n console.error(error)\n\n throw new LockedDataGenerationError(\n 'Failed to parse the project, generating locked data step failed',\n error as Error,\n )\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;AAEhE,MAAM,uBAAuB,QAA0B;AACrD,KAAI,CAAC,WAAW,IAAI,CAClB,QAAO,EAAE;AAEX,QAAO,CACL,GAAG,SAAS,wBAAwB;EAAE,UAAU;EAAM,KAAK;EAAK,CAAC,EACjE,GAAG,SAAS,2BAA2B;EAAE,UAAU;EAAM,KAAK;EAAK,CAAC,CACrE;;AAGH,MAAa,gBAAgB,eAAiC;CAC5D,MAAM,WAAW,KAAK,KAAK,YAAY,QAAQ;CAC/C,MAAM,SAAS,KAAK,KAAK,YAAY,MAAM;AAC3C,QAAO,CAAC,GAAG,oBAAoB,SAAS,EAAE,GAAG,oBAAoB,OAAO,CAAC;;AAG3E,MAAM,yBAAyB,QAA0B;AACvD,KAAI,CAAC,WAAW,IAAI,CAClB,QAAO,EAAE;AAEX,QAAO,CACL,GAAG,SAAS,0BAA0B;EAAE,UAAU;EAAM,KAAK;EAAK,CAAC,EACnE,GAAG,SAAS,6BAA6B;EAAE,UAAU;EAAM,KAAK;EAAK,CAAC,CACvE;;AAGH,MAAa,kBAAkB,eAAiC;CAC9D,MAAM,WAAW,KAAK,KAAK,YAAY,QAAQ;CAC/C,MAAM,SAAS,KAAK,KAAK,YAAY,MAAM;AAC3C,QAAO,CAAC,GAAG,sBAAsB,SAAS,EAAE,GAAG,sBAAsB,OAAO,CAAC;;AAI/E,MAAa,eAAe,OAAO,YAAoB,eAA4C;CACjG,MAAMA,eAAuB,EAAE;CAC/B,MAAM,YAAY,aAAa,WAAW;CAC1C,MAAM,cAAc,eAAe,WAAW;CAC9C,MAAM,WAAW,KAAK,KAAK,YAAY,QAAQ;CAC/C,MAAM,SAAS,KAAK,KAAK,YAAY,MAAM;CAC3C,MAAM,kBAAkB,CACtB,GAAI,WAAW,SAAS,GAAG,SAAS,gBAAgB;EAAE,UAAU;EAAM,KAAK;EAAU,CAAC,GAAG,EAAE,EAC3F,GAAI,WAAW,OAAO,GAAG,SAAS,gBAAgB;EAAE,UAAU;EAAM,KAAK;EAAQ,CAAC,GAAG,EAAE,CACxF;AAKD,KAFE,UAAU,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC,IAAI,YAAY,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC,CAGlG,oBAAmB,EAAE,SAAS,YAAY,CAAC;AAG7C,MAAK,MAAM,YAAY,UACrB,KAAI;EACF,MAAM,SAAS,MAAM,cAAc,UAAU,WAAW;AAExD,MAAI,CAAC,QAAQ;AACX,WAAQ,KAAK,2BAA2B,SAAS,gBAAgB;AACjE;;AAKF,MAAI,CAFW,WAAW,WAAW;GAAE;GAAU;GAAS;GAAQ,EAAE,EAAE,qBAAqB,MAAM,CAAC,CAGhG,cAAa,KAAK;GAAE;GAAU;GAAS;GAAQ,CAAC;UAE3C,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AACrE,MAAI,aAAa,SAAS,4BAA4B,IAAI,aAAa,SAAS,8BAA8B,EAAE;AAC9G,WAAQ,KAAK,GAAG,OAAO,6BAA6B,SAAS,IAAI,eAAe,CAAC;AACjF;;AAEF,QAAM,IAAI,iBAAiB,yBAAyB,YAAY,KAAK,SAAS,YAAY,SAAS,EAAE,IAAa;;AAItH,MAAK,MAAM,YAAY,aAAa;EAClC,MAAM,SAAS,MAAM,gBAAgB,SAAS;AAE9C,MAAI,CAAC,QAAQ;AACX,WAAQ,KAAK,6BAA6B,SAAS,kBAAkB;AACrE;;AAGF,aAAW,aAAa;GAAE;GAAU;GAAQ,EAAE,EAAE,qBAAqB,MAAM,CAAC;;AAG9E,KAAI,gBAAgB,SAAS,GAAG;EAC9B,MAAM,UAAU,GAAG,OAAO,cAAc;AACxC,UAAQ,KACN,GAAG,OACD;GACE;GACA;GACA;GACA;GACA,qBAAqB,GAAG,KAAK,WAAW,CAAC;GACzC,yBAAyB,GAAG,KAAK,WAAW,CAAC;GAC7C;GACA,GAAG,KAAK,SAAS;GACjB,GAAG,gBAAgB,KAAK,SACtB,GAAG,MACD,KAAK,GAAG,KAAK,GAAG,KAAK,KAAK,QAAQ,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,GAAG,KAAK,GAAG,KAAK,QAAQ,YAAY,GAAG,CAAC,QAAQ,YAAY,WAAW,GAAG,GAC5I,CACF;GAED;GACA;GACA;GACA;GACA;GACD,CAAC,KAAK,KAAK,CACb,CACF;;AAGH,QAAO;;AAQT,MAAa,qBAAqB,OAAO,WAMd;AACzB,KAAI;EACF,MAAM,EACJ,YACA,gBAAgB,IAAI,4BAA4B,EAChD,cAAc,WACd,aACA,eACE;EAMJ,MAAM,aAAa,IAAI,WAAW,YAAY,eAL9B,gBAAgB,aAAa,IAAI,WAAW,GAAG,IAAI,QAAQ,WAAW,EAKhB,YAAY;AAClF,aAAW,oBAAoB,WAAW;AAE1C,QAAM,aAAa,YAAY,WAAW;AAC1C,aAAW,WAAW;AAEtB,SAAO;UACA,OAAO;AACd,UAAQ,MAAM,MAAM;AAEpB,QAAM,IAAI,0BACR,mEACA,MACD"}
1
+ {"version":3,"file":"generate-locked-data.mjs","names":["invalidSteps: Step[]"],"sources":["../src/generate-locked-data.ts"],"sourcesContent":["import {\n getStepConfig,\n getStreamConfig,\n type JsonSchema,\n LockedData,\n MemoryStreamAdapterManager,\n NoPrinter,\n Printer,\n type Step,\n type StreamAdapterManager,\n type StreamAuthConfig,\n} from '@motiadev/core'\nimport { randomUUID } from 'crypto'\nimport { existsSync } from 'fs'\nimport { globSync } from 'glob'\nimport path from 'path'\nimport pc from 'picocolors'\nimport type { RedisClientType } from 'redis'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { CompilationError } from './utils/errors/compilation.error'\nimport { LockedDataGenerationError } from './utils/errors/locked-data-generation.error'\nimport { validatePythonEnvironment } from './utils/validate-python-environment'\n\nconst version = `${randomUUID()}:${Math.floor(Date.now() / 1000)}`\n\nconst getStepFilesFromDir = (dir: string): string[] => {\n if (!existsSync(dir)) {\n return []\n }\n return [\n ...globSync('**/*.step.{ts,js,rb}', { absolute: true, cwd: dir }),\n ...globSync('**/*_step.{ts,js,py,rb}', { absolute: true, cwd: dir }),\n ]\n}\n\nexport const getStepFiles = (projectDir: string): string[] => {\n const stepsDir = path.join(projectDir, 'steps')\n const srcDir = path.join(projectDir, 'src')\n return [...getStepFilesFromDir(stepsDir), ...getStepFilesFromDir(srcDir)]\n}\n\nconst getStreamFilesFromDir = (dir: string): string[] => {\n if (!existsSync(dir)) {\n return []\n }\n return [\n ...globSync('**/*.stream.{ts,js,rb}', { absolute: true, cwd: dir }),\n ...globSync('**/*_stream.{ts,js,py,rb}', { absolute: true, cwd: dir }),\n ]\n}\n\nexport const getStreamFiles = (projectDir: string): string[] => {\n const stepsDir = path.join(projectDir, 'steps')\n const srcDir = path.join(projectDir, 'src')\n return [...getStreamFilesFromDir(stepsDir), ...getStreamFilesFromDir(srcDir)]\n}\n\n// Helper function to recursively collect flow data\nexport const collectFlows = async (projectDir: string, lockedData: LockedData): Promise<Step[]> => {\n const invalidSteps: Step[] = []\n const stepFiles = getStepFiles(projectDir)\n const streamFiles = getStreamFiles(projectDir)\n const stepsDir = path.join(projectDir, 'steps')\n const srcDir = path.join(projectDir, 'src')\n const deprecatedSteps = [\n ...(existsSync(stepsDir) ? globSync('**/*.step.py', { absolute: true, cwd: stepsDir }) : []),\n ...(existsSync(srcDir) ? globSync('**/*.step.py', { absolute: true, cwd: srcDir }) : []),\n ]\n\n const hasPythonFiles =\n stepFiles.some((file) => file.endsWith('.py')) || streamFiles.some((file) => file.endsWith('.py'))\n\n const pythonValidation = await validatePythonEnvironment({ baseDir: projectDir, hasPythonFiles })\n if (!pythonValidation.success) {\n throw new LockedDataGenerationError(\n 'Python environment validation failed. Please run the install command to set up your Python environment.',\n )\n }\n\n if (hasPythonFiles) {\n activatePythonVenv({ baseDir: projectDir })\n }\n\n for (const filePath of stepFiles) {\n try {\n const config = await getStepConfig(filePath, projectDir)\n\n if (!config) {\n console.warn(`No config found in step ${filePath}, step skipped`)\n continue\n }\n\n const result = lockedData.createStep({ filePath, version, config }, { disableTypeCreation: true })\n\n if (!result) {\n invalidSteps.push({ filePath, version, config })\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err)\n if (errorMessage.includes('Executable ruby not found') || errorMessage.includes('Executable python not found')) {\n console.warn(pc.yellow(`! [WARNING] Skipping step ${filePath}: ${errorMessage}`))\n continue\n }\n throw new CompilationError(`Error collecting flow ${filePath}`, path.relative(projectDir, filePath), err as Error)\n }\n }\n\n for (const filePath of streamFiles) {\n const config = await getStreamConfig(filePath)\n\n if (!config) {\n console.warn(`No config found in stream ${filePath}, stream skipped`)\n continue\n }\n\n lockedData.createStream({ filePath, config }, { disableTypeCreation: true })\n }\n\n if (deprecatedSteps.length > 0) {\n const warning = pc.yellow('! [WARNING]')\n console.warn(\n pc.yellow(\n [\n '',\n '========================================',\n warning,\n '',\n `Python steps with ${pc.gray('.step.py')} extensions are no longer supported.`,\n `Please rename them to ${pc.gray('_step.py')}.`,\n '',\n pc.bold('Steps:'),\n ...deprecatedSteps.map((step) =>\n pc.reset(\n `- ${pc.cyan(pc.bold(step.replace(projectDir, '')))} rename to ${pc.gray(`${step.replace(projectDir, '').replace('.step.py', '_step.py')}`)}`,\n ),\n ),\n\n '',\n 'Make sure the step names are importable from Python:',\n `- Don't use numbers, dots, dashes, commas, spaces, colons, or special characters`,\n '========================================',\n '',\n ].join('\\n'),\n ),\n )\n }\n\n return invalidSteps\n}\n\ntype StreamAuthOptions = {\n authenticate: StreamAuthConfig['authenticate']\n contextSchema?: JsonSchema\n}\n\nexport const generateLockedData = async (config: {\n projectDir: string\n streamAdapter?: StreamAdapterManager\n redisClient?: RedisClientType\n printerType?: 'disabled' | 'default'\n streamAuth?: StreamAuthOptions\n}): Promise<LockedData> => {\n try {\n const {\n projectDir,\n streamAdapter = new MemoryStreamAdapterManager(),\n printerType = 'default',\n redisClient,\n streamAuth,\n } = config\n const printer = printerType === 'disabled' ? new NoPrinter() : new Printer(projectDir)\n /*\n * NOTE: right now for performance and simplicity let's enforce a folder,\n * but we might want to remove this and scan the entire current directory\n */\n const lockedData = new LockedData(projectDir, streamAdapter, printer, redisClient)\n lockedData.setStreamAuthConfig(streamAuth)\n\n await collectFlows(projectDir, lockedData)\n lockedData.saveTypes()\n\n return lockedData\n } catch (error) {\n console.error(error)\n\n throw new LockedDataGenerationError(\n 'Failed to parse the project, generating locked data step failed',\n error as Error,\n )\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { executeCommand } from "../utils/execute-command.mjs";
2
+ import { getPackageManager } from "../utils/get-package-manager.mjs";
2
3
  import { version } from "../version.mjs";
3
4
  import { pluginDependencies } from "./plugin-dependencies.mjs";
4
- import { getPackageManager } from "../utils/get-package-manager.mjs";
5
5
  import fs from "node:fs";
6
6
  import path from "node:path";
7
7
 
package/dist/start.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { activatePythonVenv } from "./utils/activate-python-env.mjs";
2
+ import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
2
3
  import { generateLockedData, getStepFiles, getStreamFiles } from "./generate-locked-data.mjs";
3
4
  import { version } from "./version.mjs";
4
5
  import { loadMotiaConfig } from "./load-motia-config.mjs";
@@ -6,7 +7,6 @@ import { workbenchBase } from "./constants.mjs";
6
7
  import { processPlugins } from "./plugins/process-plugins.mjs";
7
8
  import "./plugins/index.mjs";
8
9
  import { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from "./redis/connection.mjs";
9
- import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
10
10
  import { createServer } from "@motiadev/core";
11
11
  import path from "path";
12
12
  import { BullMQEventAdapter } from "@motiadev/adapter-bullmq-events";
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.15.4-beta.170-803755",
4
+ "version": "0.15.4-beta.170-980856",
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-bullmq-events": "0.15.4-beta.170-803755",
50
- "@motiadev/adapter-redis-cron": "0.15.4-beta.170-803755",
51
- "@motiadev/adapter-redis-state": "0.15.4-beta.170-803755",
52
- "@motiadev/adapter-redis-streams": "0.15.4-beta.170-803755",
53
- "@motiadev/stream-client-node": "0.15.4-beta.170-803755",
54
- "@motiadev/workbench": "0.15.4-beta.170-803755",
55
- "@motiadev/core": "0.15.4-beta.170-803755"
49
+ "@motiadev/adapter-bullmq-events": "0.15.4-beta.170-980856",
50
+ "@motiadev/adapter-redis-cron": "0.15.4-beta.170-980856",
51
+ "@motiadev/adapter-redis-state": "0.15.4-beta.170-980856",
52
+ "@motiadev/adapter-redis-streams": "0.15.4-beta.170-980856",
53
+ "@motiadev/core": "0.15.4-beta.170-980856",
54
+ "@motiadev/stream-client-node": "0.15.4-beta.170-980856",
55
+ "@motiadev/workbench": "0.15.4-beta.170-980856"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@amplitude/analytics-types": "^2.9.2",