motia 0.8.6-beta.143 → 0.8.6-beta.144-481431
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/dist/cjs/cli.js +2 -0
- package/dist/cjs/constants.js +6 -1
- package/dist/cjs/create/interactive.d.ts +1 -0
- package/dist/cjs/create/interactive.js +21 -5
- package/dist/cjs/create/templates/hello/motia-workbench.json +15 -0
- package/dist/cjs/create/templates/hello/motia.config.ts.txt +9 -0
- package/dist/cjs/create/templates/hello/steps/hello/hello-api.step.ts.txt +46 -0
- package/dist/cjs/create/templates/hello/steps/hello/process-greeting.step.ts.txt +43 -0
- package/dist/cjs/create/templates/hello_js/motia-workbench.json +13 -0
- package/dist/cjs/create/templates/hello_js/motia.config.ts.txt +9 -0
- package/dist/cjs/create/templates/hello_js/steps/hello/hello-api.step.js.txt +47 -0
- package/dist/cjs/create/templates/hello_js/steps/hello/process-greeting.step.js.txt +44 -0
- package/dist/cjs/create/templates/hello_python/motia-workbench.json +13 -0
- package/dist/cjs/create/templates/hello_python/motia.config.ts.txt +9 -0
- package/dist/cjs/create/templates/hello_python/requirements.txt +2 -0
- package/dist/cjs/create/templates/hello_python/steps/hello/hello_api_step.py.txt +74 -0
- package/dist/cjs/create/templates/hello_python/steps/hello/process_greeting_step.py.txt +68 -0
- package/dist/cjs/create/templates/index.js +3 -0
- package/dist/cjs/create/templates/index.ts +3 -0
- package/dist/cjs/create/templates/nodejs/motia.config.ts.txt +1 -1
- package/dist/cjs/create/templates/python/motia.config.ts.txt +1 -1
- package/dist/cjs/dev.js +16 -8
- package/dist/cjs/generate-locked-data.d.ts +2 -3
- package/dist/cjs/generate-locked-data.js +2 -2
- package/dist/cjs/load-motia-config.d.ts +2 -0
- package/dist/cjs/load-motia-config.js +52 -0
- package/dist/cjs/start.js +13 -5
- package/dist/esm/cli.js +2 -0
- package/dist/esm/constants.js +3 -1
- package/dist/esm/create/interactive.d.ts +1 -0
- package/dist/esm/create/interactive.js +21 -5
- package/dist/esm/create/templates/hello/motia-workbench.json +15 -0
- package/dist/esm/create/templates/hello/motia.config.ts.txt +9 -0
- package/dist/esm/create/templates/hello/steps/hello/hello-api.step.ts.txt +46 -0
- package/dist/esm/create/templates/hello/steps/hello/process-greeting.step.ts.txt +43 -0
- package/dist/esm/create/templates/hello_js/motia-workbench.json +13 -0
- package/dist/esm/create/templates/hello_js/motia.config.ts.txt +9 -0
- package/dist/esm/create/templates/hello_js/steps/hello/hello-api.step.js.txt +47 -0
- package/dist/esm/create/templates/hello_js/steps/hello/process-greeting.step.js.txt +44 -0
- package/dist/esm/create/templates/hello_python/motia-workbench.json +13 -0
- package/dist/esm/create/templates/hello_python/motia.config.ts.txt +9 -0
- package/dist/esm/create/templates/hello_python/requirements.txt +2 -0
- package/dist/esm/create/templates/hello_python/steps/hello/hello_api_step.py.txt +74 -0
- package/dist/esm/create/templates/hello_python/steps/hello/process_greeting_step.py.txt +68 -0
- package/dist/esm/create/templates/index.js +3 -0
- package/dist/esm/create/templates/index.ts +3 -0
- package/dist/esm/create/templates/nodejs/motia.config.ts.txt +1 -1
- package/dist/esm/create/templates/python/motia.config.ts.txt +1 -1
- package/dist/esm/dev.js +17 -9
- package/dist/esm/generate-locked-data.d.ts +2 -3
- package/dist/esm/generate-locked-data.js +2 -2
- package/dist/esm/load-motia-config.d.ts +2 -0
- package/dist/esm/load-motia-config.js +15 -0
- package/dist/esm/start.js +14 -6
- package/dist/types/create/interactive.d.ts +1 -0
- package/dist/types/generate-locked-data.d.ts +2 -3
- package/dist/types/load-motia-config.d.ts +2 -0
- package/package.json +4 -4
- /package/dist/cjs/create/templates/nodejs/{steps → tutorial}/petstore/api.step.ts-features.json.txt +0 -0
- /package/dist/cjs/create/templates/nodejs/{steps → tutorial}/petstore/process-food-order.step.ts-features.json.txt +0 -0
- /package/dist/cjs/create/templates/nodejs/{steps → tutorial}/petstore/state-audit-cron.step.ts-features.json.txt +0 -0
- /package/dist/cjs/create/templates/nodejs/{tutorial.tsx.txt → tutorial/tutorial.tsx.txt} +0 -0
- /package/dist/cjs/create/templates/python/{steps → tutorial}/petstore/api_step.py-features.json.txt +0 -0
- /package/dist/cjs/create/templates/python/{steps → tutorial}/petstore/process_food_order_step.py-features.json.txt +0 -0
- /package/dist/cjs/create/templates/python/{steps → tutorial}/petstore/state_audit_cron_step.py-features.json.txt +0 -0
- /package/dist/cjs/create/templates/python/{tutorial.tsx.txt → tutorial/tutorial.tsx.txt} +0 -0
- /package/dist/esm/create/templates/nodejs/{steps → tutorial}/petstore/api.step.ts-features.json.txt +0 -0
- /package/dist/esm/create/templates/nodejs/{steps → tutorial}/petstore/process-food-order.step.ts-features.json.txt +0 -0
- /package/dist/esm/create/templates/nodejs/{steps → tutorial}/petstore/state-audit-cron.step.ts-features.json.txt +0 -0
- /package/dist/esm/create/templates/nodejs/{tutorial.tsx.txt → tutorial/tutorial.tsx.txt} +0 -0
- /package/dist/esm/create/templates/python/{steps → tutorial}/petstore/api_step.py-features.json.txt +0 -0
- /package/dist/esm/create/templates/python/{steps → tutorial}/petstore/process_food_order_step.py-features.json.txt +0 -0
- /package/dist/esm/create/templates/python/{steps → tutorial}/petstore/state_audit_cron_step.py-features.json.txt +0 -0
- /package/dist/esm/create/templates/python/{tutorial.tsx.txt → tutorial/tutorial.tsx.txt} +0 -0
package/dist/cjs/cli.js
CHANGED
|
@@ -24,6 +24,7 @@ commander_1.program
|
|
|
24
24
|
.command('create [name]')
|
|
25
25
|
.description('Create a new motia project')
|
|
26
26
|
.option('-t, --template <template>', 'The template to use for your project')
|
|
27
|
+
.option('-p, --plugin', 'Create a plugin project')
|
|
27
28
|
.option('-i, --interactive', 'Use interactive prompts to create project') // it's default
|
|
28
29
|
.option('-c, --confirm', 'Confirm the project creation', false)
|
|
29
30
|
.action((projectName, options) => {
|
|
@@ -33,6 +34,7 @@ commander_1.program
|
|
|
33
34
|
await createInteractive({
|
|
34
35
|
name: arg.name,
|
|
35
36
|
template: arg.template,
|
|
37
|
+
plugin: !!arg.plugin,
|
|
36
38
|
confirm: !!arg.confirm,
|
|
37
39
|
}, context);
|
|
38
40
|
})(mergedArgs);
|
package/dist/cjs/constants.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.isTutorialDisabled = exports.workbenchBase = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
4
9
|
function getWorkbenchBase() {
|
|
5
10
|
const basePath = process.env.MOTIA_WORKBENCH_BASE;
|
|
6
11
|
if (basePath === '/') {
|
|
@@ -9,4 +14,4 @@ function getWorkbenchBase() {
|
|
|
9
14
|
return basePath && basePath[0] !== '/' ? `/${basePath}` : basePath || '';
|
|
10
15
|
}
|
|
11
16
|
exports.workbenchBase = getWorkbenchBase();
|
|
12
|
-
exports.isTutorialDisabled = process.env.MOTIA_TUTORIAL_DISABLED === 'true';
|
|
17
|
+
exports.isTutorialDisabled = process.env.MOTIA_TUTORIAL_DISABLED === 'true' || !node_fs_1.default.existsSync(node_path_1.default.join(process.cwd(), 'tutorial/tutorial.tsx'));
|
|
@@ -2,6 +2,7 @@ import type { CliContext } from '../cloud/config-utils';
|
|
|
2
2
|
interface CreateInteractiveArgs {
|
|
3
3
|
name?: string;
|
|
4
4
|
template?: string;
|
|
5
|
+
plugin?: boolean;
|
|
5
6
|
confirm?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export declare const createInteractive: (args: CreateInteractiveArgs, context: CliContext) => Promise<void>;
|
|
@@ -8,16 +8,32 @@ const colors_1 = __importDefault(require("colors"));
|
|
|
8
8
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
9
|
const index_1 = require("./index");
|
|
10
10
|
const choices = {
|
|
11
|
-
nodejs: '
|
|
12
|
-
python: '
|
|
13
|
-
|
|
11
|
+
nodejs: 'Tutorial (TypeScript)',
|
|
12
|
+
python: 'Tutorial (Python)',
|
|
13
|
+
'starter-typescript': 'Starter (TypeScript)',
|
|
14
|
+
'starter-javascript': 'Starter (JavaScript)',
|
|
15
|
+
'starter-python': 'Starter (Python)',
|
|
14
16
|
};
|
|
15
17
|
const createInteractive = async (args, context) => {
|
|
16
|
-
context.log('welcome', (message) => message.append(
|
|
18
|
+
context.log('welcome', (message) => message.append(`\n🚀 ${colors_1.default.bold(args.plugin ? 'Welcome to Motia Plugin Creator!' : 'Welcome to Motia Project Creator!')}`));
|
|
17
19
|
const questions = [];
|
|
18
20
|
let name = args.name;
|
|
19
21
|
let template = args.template;
|
|
20
|
-
if (
|
|
22
|
+
if (args.plugin) {
|
|
23
|
+
if (!args.name) {
|
|
24
|
+
context.log('failed', (message) => message
|
|
25
|
+
.tag('failed')
|
|
26
|
+
.append(`Project name is required: ${colors_1.default.bold('motia create --plugin [project-name]')}\n`));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
return (0, index_1.create)({
|
|
30
|
+
projectName: args.name,
|
|
31
|
+
template: 'plugin',
|
|
32
|
+
cursorEnabled: false,
|
|
33
|
+
context,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else if (!args.template) {
|
|
21
37
|
questions.push({
|
|
22
38
|
type: 'list',
|
|
23
39
|
name: 'template',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { config } from '@motiadev/core'
|
|
2
|
+
const statesPlugin = require('@motiadev/plugin-states/plugin')
|
|
3
|
+
const endpointPlugin = require('@motiadev/plugin-endpoint/plugin')
|
|
4
|
+
const logsPlugin = require('@motiadev/plugin-logs/plugin')
|
|
5
|
+
const observabilityPlugin = require('@motiadev/plugin-observability/plugin')
|
|
6
|
+
|
|
7
|
+
export default config({
|
|
8
|
+
plugins: [observabilityPlugin, statesPlugin, endpointPlugin, logsPlugin],
|
|
9
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ApiRouteConfig, Handlers } from 'motia';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const config: ApiRouteConfig = {
|
|
5
|
+
name: 'HelloAPI',
|
|
6
|
+
type: 'api',
|
|
7
|
+
path: '/hello',
|
|
8
|
+
method: 'GET',
|
|
9
|
+
description: 'Receives hello request and emits event for processing',
|
|
10
|
+
emits: ['process-greeting'],
|
|
11
|
+
flows: ['hello-world-flow'],
|
|
12
|
+
responseSchema: {
|
|
13
|
+
200: z.object({
|
|
14
|
+
message: z.string(),
|
|
15
|
+
status: z.string(),
|
|
16
|
+
appName: z.string()
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const handler: Handlers['HelloAPI'] = async (_, { emit, logger }) => {
|
|
22
|
+
const appName = process.env.APP_NAME || 'Motia App';
|
|
23
|
+
const timestamp = new Date().toISOString();
|
|
24
|
+
|
|
25
|
+
logger.info('Hello API endpoint called', { appName, timestamp });
|
|
26
|
+
|
|
27
|
+
// Emit event for background processing
|
|
28
|
+
await emit({
|
|
29
|
+
topic: 'process-greeting',
|
|
30
|
+
data: {
|
|
31
|
+
timestamp,
|
|
32
|
+
appName,
|
|
33
|
+
greetingPrefix: process.env.GREETING_PREFIX || 'Hello',
|
|
34
|
+
requestId: Math.random().toString(36).substring(7)
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
status: 200,
|
|
40
|
+
body: {
|
|
41
|
+
message: 'Hello request received! Check logs for processing.',
|
|
42
|
+
status: 'processing',
|
|
43
|
+
appName
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { EventConfig, Handlers } from 'motia';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
const inputSchema = z.object({
|
|
5
|
+
timestamp: z.string(),
|
|
6
|
+
appName: z.string(),
|
|
7
|
+
greetingPrefix: z.string(),
|
|
8
|
+
requestId: z.string()
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const config: EventConfig = {
|
|
12
|
+
name: 'ProcessGreeting',
|
|
13
|
+
type: 'event',
|
|
14
|
+
description: 'Processes greeting in the background',
|
|
15
|
+
subscribes: ['process-greeting'],
|
|
16
|
+
emits: [],
|
|
17
|
+
flows: ['hello-world-flow'],
|
|
18
|
+
input: inputSchema
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const handler: Handlers['ProcessGreeting'] = async (input, { logger, state }) => {
|
|
22
|
+
const { timestamp, appName, greetingPrefix, requestId } = input;
|
|
23
|
+
|
|
24
|
+
logger.info('Processing greeting', { requestId, appName });
|
|
25
|
+
|
|
26
|
+
const greeting = `${greetingPrefix} ${appName}!`;
|
|
27
|
+
|
|
28
|
+
await new Promise(resolve => setTimeout(resolve, 2000)); // Simulate background processing
|
|
29
|
+
|
|
30
|
+
// Store result in state (demonstrates state usage)
|
|
31
|
+
// Note: The state.set method takes (groupId, key, value)
|
|
32
|
+
await state.set('greetings', requestId, {
|
|
33
|
+
greeting,
|
|
34
|
+
processedAt: new Date().toISOString(),
|
|
35
|
+
originalTimestamp: timestamp
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
logger.info('Greeting processed successfully', {
|
|
39
|
+
requestId,
|
|
40
|
+
greeting,
|
|
41
|
+
storedInState: true
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { config } from '@motiadev/core'
|
|
2
|
+
const statesPlugin = require('@motiadev/plugin-states/plugin')
|
|
3
|
+
const endpointPlugin = require('@motiadev/plugin-endpoint/plugin')
|
|
4
|
+
const logsPlugin = require('@motiadev/plugin-logs/plugin')
|
|
5
|
+
const observabilityPlugin = require('@motiadev/plugin-observability/plugin')
|
|
6
|
+
|
|
7
|
+
export default config({
|
|
8
|
+
plugins: [observabilityPlugin, statesPlugin, endpointPlugin, logsPlugin],
|
|
9
|
+
})
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const { z } = require('zod');
|
|
2
|
+
|
|
3
|
+
const config = {
|
|
4
|
+
name: 'HelloAPI',
|
|
5
|
+
type: 'api',
|
|
6
|
+
path: '/hello',
|
|
7
|
+
method: 'GET',
|
|
8
|
+
description: 'Receives hello request and emits event for processing',
|
|
9
|
+
emits: ['process-greeting'],
|
|
10
|
+
flows: ['hello-world-flow'],
|
|
11
|
+
responseSchema: {
|
|
12
|
+
200: z.object({
|
|
13
|
+
message: z.string(),
|
|
14
|
+
status: z.string(),
|
|
15
|
+
appName: z.string()
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const handler = async (_, { emit, logger }) => {
|
|
21
|
+
const appName = process.env.APP_NAME || 'Motia App';
|
|
22
|
+
const timestamp = new Date().toISOString();
|
|
23
|
+
|
|
24
|
+
logger.info('Hello API endpoint called', { appName, timestamp });
|
|
25
|
+
|
|
26
|
+
// Emit event for background processing
|
|
27
|
+
await emit({
|
|
28
|
+
topic: 'process-greeting',
|
|
29
|
+
data: {
|
|
30
|
+
timestamp,
|
|
31
|
+
appName,
|
|
32
|
+
greetingPrefix: process.env.GREETING_PREFIX || 'Hello',
|
|
33
|
+
requestId: Math.random().toString(36).substring(7)
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
status: 200,
|
|
39
|
+
body: {
|
|
40
|
+
message: 'Hello request received! Check logs for processing.',
|
|
41
|
+
status: 'processing',
|
|
42
|
+
appName
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
module.exports = { config, handler };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const { z } = require('zod');
|
|
2
|
+
|
|
3
|
+
const inputSchema = z.object({
|
|
4
|
+
timestamp: z.string(),
|
|
5
|
+
appName: z.string(),
|
|
6
|
+
greetingPrefix: z.string(),
|
|
7
|
+
requestId: z.string()
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const config = {
|
|
11
|
+
name: 'ProcessGreeting',
|
|
12
|
+
type: 'event',
|
|
13
|
+
description: 'Processes greeting in the background',
|
|
14
|
+
subscribes: ['process-greeting'],
|
|
15
|
+
emits: [],
|
|
16
|
+
flows: ['hello-world-flow'],
|
|
17
|
+
input: inputSchema
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const handler = async (input, { logger, state }) => {
|
|
21
|
+
const { timestamp, appName, greetingPrefix, requestId } = input;
|
|
22
|
+
|
|
23
|
+
logger.info('Processing greeting', { requestId, appName });
|
|
24
|
+
|
|
25
|
+
const greeting = `${greetingPrefix} ${appName}!`;
|
|
26
|
+
|
|
27
|
+
await new Promise(resolve => setTimeout(resolve, 2000)); // Simulate background processing
|
|
28
|
+
|
|
29
|
+
// Store result in state (demonstrates state usage)
|
|
30
|
+
// Note: The state.set method takes (groupId, key, value)
|
|
31
|
+
await state.set('greetings', requestId, {
|
|
32
|
+
greeting,
|
|
33
|
+
processedAt: new Date().toISOString(),
|
|
34
|
+
originalTimestamp: timestamp
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
logger.info('Greeting processed successfully', {
|
|
38
|
+
requestId,
|
|
39
|
+
greeting,
|
|
40
|
+
storedInState: true
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
module.exports = { config, handler };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { config } from '@motiadev/core'
|
|
2
|
+
const statesPlugin = require('@motiadev/plugin-states/plugin')
|
|
3
|
+
const endpointPlugin = require('@motiadev/plugin-endpoint/plugin')
|
|
4
|
+
const logsPlugin = require('@motiadev/plugin-logs/plugin')
|
|
5
|
+
const observabilityPlugin = require('@motiadev/plugin-observability/plugin')
|
|
6
|
+
|
|
7
|
+
export default config({
|
|
8
|
+
plugins: [observabilityPlugin, statesPlugin, endpointPlugin, logsPlugin],
|
|
9
|
+
})
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import random
|
|
3
|
+
import string
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
# Optional: Using Pydantic for validation (remove if not using Pydantic)
|
|
7
|
+
try:
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
class HelloResponse(BaseModel):
|
|
11
|
+
message: str
|
|
12
|
+
status: str
|
|
13
|
+
appName: str
|
|
14
|
+
|
|
15
|
+
# If using Pydantic, we can generate the JSON schema
|
|
16
|
+
response_schema = {
|
|
17
|
+
200: HelloResponse.model_json_schema()
|
|
18
|
+
}
|
|
19
|
+
except ImportError:
|
|
20
|
+
# Without Pydantic, define JSON schema manually
|
|
21
|
+
response_schema = {
|
|
22
|
+
200: {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"properties": {
|
|
25
|
+
"message": {"type": "string"},
|
|
26
|
+
"status": {"type": "string"},
|
|
27
|
+
"appName": {"type": "string"}
|
|
28
|
+
},
|
|
29
|
+
"required": ["message", "status", "appName"]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
config = {
|
|
34
|
+
"name": "HelloAPI",
|
|
35
|
+
"type": "api",
|
|
36
|
+
"path": "/hello",
|
|
37
|
+
"method": "GET",
|
|
38
|
+
"description": "Receives hello request and emits event for processing",
|
|
39
|
+
"emits": ["process-greeting"],
|
|
40
|
+
"flows": ["hello-world-flow"],
|
|
41
|
+
"responseSchema": response_schema
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async def handler(req, context):
|
|
45
|
+
app_name = os.environ.get("APP_NAME", "Motia App")
|
|
46
|
+
timestamp = datetime.utcnow().isoformat()
|
|
47
|
+
|
|
48
|
+
context.logger.info("Hello API endpoint called", {
|
|
49
|
+
"app_name": app_name,
|
|
50
|
+
"timestamp": timestamp
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
# Generate a random request ID
|
|
54
|
+
request_id = ''.join(random.choices(string.ascii_lowercase + string.digits, k=7))
|
|
55
|
+
|
|
56
|
+
# Emit event for background processing
|
|
57
|
+
await context.emit({
|
|
58
|
+
"topic": "process-greeting",
|
|
59
|
+
"data": {
|
|
60
|
+
"timestamp": timestamp,
|
|
61
|
+
"appName": app_name,
|
|
62
|
+
"greetingPrefix": os.environ.get("GREETING_PREFIX", "Hello"),
|
|
63
|
+
"requestId": request_id
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
"status": 200,
|
|
69
|
+
"body": {
|
|
70
|
+
"message": "Hello request received! Check logs for processing.",
|
|
71
|
+
"status": "processing",
|
|
72
|
+
"appName": app_name
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
# Optional: Using Pydantic for validation (remove if not using Pydantic)
|
|
5
|
+
try:
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
class GreetingInput(BaseModel):
|
|
9
|
+
timestamp: str
|
|
10
|
+
appName: str
|
|
11
|
+
greetingPrefix: str
|
|
12
|
+
requestId: str
|
|
13
|
+
|
|
14
|
+
# If using Pydantic, we can generate the JSON schema
|
|
15
|
+
input_schema = GreetingInput.model_json_schema()
|
|
16
|
+
except ImportError:
|
|
17
|
+
# Without Pydantic, define JSON schema manually
|
|
18
|
+
input_schema = {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"timestamp": {"type": "string"},
|
|
22
|
+
"appName": {"type": "string"},
|
|
23
|
+
"greetingPrefix": {"type": "string"},
|
|
24
|
+
"requestId": {"type": "string"}
|
|
25
|
+
},
|
|
26
|
+
"required": ["timestamp", "appName", "greetingPrefix", "requestId"]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
config = {
|
|
30
|
+
"name": "ProcessGreeting",
|
|
31
|
+
"type": "event",
|
|
32
|
+
"description": "Processes greeting in the background",
|
|
33
|
+
"subscribes": ["process-greeting"],
|
|
34
|
+
"emits": [],
|
|
35
|
+
"flows": ["hello-world-flow"],
|
|
36
|
+
"input": input_schema
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async def handler(input_data, context):
|
|
40
|
+
# Extract data from input
|
|
41
|
+
timestamp = input_data.get("timestamp")
|
|
42
|
+
app_name = input_data.get("appName")
|
|
43
|
+
greeting_prefix = input_data.get("greetingPrefix")
|
|
44
|
+
request_id = input_data.get("requestId")
|
|
45
|
+
|
|
46
|
+
context.logger.info("Processing greeting", {
|
|
47
|
+
"request_id": request_id,
|
|
48
|
+
"app_name": app_name
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
greeting = f"{greeting_prefix} {app_name}!"
|
|
52
|
+
|
|
53
|
+
# Simulate background processing
|
|
54
|
+
await asyncio.sleep(2)
|
|
55
|
+
|
|
56
|
+
# Store result in state (demonstrates state usage)
|
|
57
|
+
# Note: The state.set method takes (groupId, key, value)
|
|
58
|
+
await context.state.set("greetings", request_id, {
|
|
59
|
+
"greeting": greeting,
|
|
60
|
+
"processedAt": datetime.utcnow().isoformat(),
|
|
61
|
+
"originalTimestamp": timestamp
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
context.logger.info("Greeting processed successfully", {
|
|
65
|
+
"request_id": request_id,
|
|
66
|
+
"greeting": greeting,
|
|
67
|
+
"stored_in_state": True
|
|
68
|
+
})
|
|
@@ -6,4 +6,7 @@ exports.templates = {
|
|
|
6
6
|
nodejs: (0, generate_1.generateTemplateSteps)('nodejs'),
|
|
7
7
|
python: (0, generate_1.generateTemplateSteps)('python'),
|
|
8
8
|
plugin: (0, generate_1.generatePluginTemplate)('plugin'),
|
|
9
|
+
'starter-typescript': (0, generate_1.generateTemplateSteps)('hello'),
|
|
10
|
+
'starter-javascript': (0, generate_1.generateTemplateSteps)('hello_js'),
|
|
11
|
+
'starter-python': (0, generate_1.generateTemplateSteps)('hello_python'),
|
|
9
12
|
};
|
|
@@ -4,4 +4,7 @@ export const templates: Record<string, Generator> = {
|
|
|
4
4
|
nodejs: generateTemplateSteps('nodejs'),
|
|
5
5
|
python: generateTemplateSteps('python'),
|
|
6
6
|
plugin: generatePluginTemplate('plugin'),
|
|
7
|
+
'starter-typescript': generateTemplateSteps('hello'),
|
|
8
|
+
'starter-javascript': generateTemplateSteps('hello_js'),
|
|
9
|
+
'starter-python': generateTemplateSteps('hello_python'),
|
|
7
10
|
}
|
|
@@ -5,5 +5,5 @@ const logsPlugin = require('@motiadev/plugin-logs/plugin')
|
|
|
5
5
|
const observabilityPlugin = require('@motiadev/plugin-observability/plugin')
|
|
6
6
|
|
|
7
7
|
export default config({
|
|
8
|
-
plugins: [statesPlugin, endpointPlugin, logsPlugin
|
|
8
|
+
plugins: [observabilityPlugin, statesPlugin, endpointPlugin, logsPlugin],
|
|
9
9
|
})
|
|
@@ -5,5 +5,5 @@ const logsPlugin = require('@motiadev/plugin-logs/plugin')
|
|
|
5
5
|
const observabilityPlugin = require('@motiadev/plugin-observability/plugin')
|
|
6
6
|
|
|
7
7
|
export default config({
|
|
8
|
-
plugins: [statesPlugin, endpointPlugin, logsPlugin
|
|
8
|
+
plugins: [observabilityPlugin, statesPlugin, endpointPlugin, logsPlugin],
|
|
9
9
|
})
|
package/dist/cjs/dev.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.dev = void 0;
|
|
7
|
-
// packages/snap/src/dev.ts
|
|
8
7
|
const analytics_node_1 = require("@amplitude/analytics-node");
|
|
9
8
|
const core_1 = require("@motiadev/core");
|
|
10
9
|
const path_1 = __importDefault(require("path"));
|
|
@@ -12,6 +11,7 @@ const endpoints_1 = require("./cloud/endpoints");
|
|
|
12
11
|
const constants_1 = require("./constants");
|
|
13
12
|
const dev_watchers_1 = require("./dev-watchers");
|
|
14
13
|
const generate_locked_data_1 = require("./generate-locked-data");
|
|
14
|
+
const load_motia_config_1 = require("./load-motia-config");
|
|
15
15
|
const plugins_1 = require("./plugins");
|
|
16
16
|
const activate_python_env_1 = require("./utils/activate-python-env");
|
|
17
17
|
const analytics_1 = require("./utils/analytics");
|
|
@@ -40,15 +40,23 @@ const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFileStora
|
|
|
40
40
|
(0, core_1.trackEvent)('python_environment_activated');
|
|
41
41
|
}
|
|
42
42
|
const motiaFileStoragePath = motiaFileStorageDir || '.motia';
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
const appConfig = await (0, load_motia_config_1.loadMotiaConfig)(baseDir);
|
|
44
|
+
const adapters = {
|
|
45
|
+
eventAdapter: appConfig.adapters?.events || new core_1.DefaultQueueEventAdapter(),
|
|
46
|
+
cronAdapter: appConfig.adapters?.cron || new core_1.DefaultCronAdapter(),
|
|
47
|
+
streamAdapter: appConfig.adapters?.streams || new core_1.FileStreamAdapterManager(baseDir, motiaFileStoragePath),
|
|
48
|
+
};
|
|
49
|
+
const lockedData = await (0, generate_locked_data_1.generateLockedData)({
|
|
50
|
+
projectDir: baseDir,
|
|
51
|
+
streamAdapter: adapters.streamAdapter,
|
|
49
52
|
});
|
|
53
|
+
const state = appConfig.adapters?.state ||
|
|
54
|
+
(0, core_1.createStateAdapter)({
|
|
55
|
+
adapter: 'default',
|
|
56
|
+
filePath: path_1.default.join(baseDir, motiaFileStoragePath),
|
|
57
|
+
});
|
|
50
58
|
const config = { isVerbose };
|
|
51
|
-
const motiaServer = (0, core_1.createServer)(lockedData,
|
|
59
|
+
const motiaServer = (0, core_1.createServer)(lockedData, state, config, adapters);
|
|
52
60
|
const watcher = (0, dev_watchers_1.createDevWatchers)(lockedData, motiaServer, motiaServer.motiaEventManager, motiaServer.cronManager);
|
|
53
61
|
const plugins = await (0, plugins_1.processPlugins)(motiaServer);
|
|
54
62
|
// Initialize mermaid generator
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { LockedData, type Step } from '@motiadev/core';
|
|
1
|
+
import { LockedData, type Step, type StreamAdapterManager } from '@motiadev/core';
|
|
2
2
|
export declare const getStepFiles: (projectDir: string) => string[];
|
|
3
3
|
export declare const getStreamFiles: (projectDir: string) => string[];
|
|
4
4
|
export declare const collectFlows: (projectDir: string, lockedData: LockedData) => Promise<Step[]>;
|
|
5
5
|
export declare const generateLockedData: (config: {
|
|
6
6
|
projectDir: string;
|
|
7
|
-
streamAdapter
|
|
7
|
+
streamAdapter: StreamAdapterManager;
|
|
8
8
|
printerType?: "disabled" | "default";
|
|
9
|
-
motiaFileStoragePath?: string;
|
|
10
9
|
}) => Promise<LockedData>;
|
|
@@ -107,13 +107,13 @@ const collectFlows = async (projectDir, lockedData) => {
|
|
|
107
107
|
exports.collectFlows = collectFlows;
|
|
108
108
|
const generateLockedData = async (config) => {
|
|
109
109
|
try {
|
|
110
|
-
const { projectDir, streamAdapter
|
|
110
|
+
const { projectDir, streamAdapter, printerType = 'default' } = config;
|
|
111
111
|
const printer = printerType === 'disabled' ? new printer_1.NoPrinter() : new printer_1.Printer(projectDir);
|
|
112
112
|
/*
|
|
113
113
|
* NOTE: right now for performance and simplicity let's enforce a folder,
|
|
114
114
|
* but we might want to remove this and scan the entire current directory
|
|
115
115
|
*/
|
|
116
|
-
const lockedData = new core_1.LockedData(projectDir, streamAdapter, printer
|
|
116
|
+
const lockedData = new core_1.LockedData(projectDir, streamAdapter, printer);
|
|
117
117
|
await (0, exports.collectFlows)(projectDir, lockedData);
|
|
118
118
|
lockedData.saveTypes();
|
|
119
119
|
return lockedData;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadMotiaConfig = void 0;
|
|
37
|
+
const glob_1 = require("glob");
|
|
38
|
+
const loadMotiaConfig = async (baseDir) => {
|
|
39
|
+
const configFiles = (0, glob_1.globSync)('motia.config.{ts,js}', { absolute: true, cwd: baseDir });
|
|
40
|
+
if (configFiles.length === 0) {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const appConfig = (await Promise.resolve(`${configFiles[0]}`).then(s => __importStar(require(s)))).default;
|
|
45
|
+
return appConfig || {};
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.warn('Failed to load motia.config.ts:', error);
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.loadMotiaConfig = loadMotiaConfig;
|