motia 0.8.6-beta.143 → 0.8.6-beta.144-824340
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/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/types/create/interactive.d.ts +1 -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/esm/cli.js
CHANGED
|
@@ -22,6 +22,7 @@ program
|
|
|
22
22
|
.command('create [name]')
|
|
23
23
|
.description('Create a new motia project')
|
|
24
24
|
.option('-t, --template <template>', 'The template to use for your project')
|
|
25
|
+
.option('-p, --plugin', 'Create a plugin project')
|
|
25
26
|
.option('-i, --interactive', 'Use interactive prompts to create project') // it's default
|
|
26
27
|
.option('-c, --confirm', 'Confirm the project creation', false)
|
|
27
28
|
.action((projectName, options) => {
|
|
@@ -31,6 +32,7 @@ program
|
|
|
31
32
|
await createInteractive({
|
|
32
33
|
name: arg.name,
|
|
33
34
|
template: arg.template,
|
|
35
|
+
plugin: !!arg.plugin,
|
|
34
36
|
confirm: !!arg.confirm,
|
|
35
37
|
}, context);
|
|
36
38
|
})(mergedArgs);
|
package/dist/esm/constants.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
function getWorkbenchBase() {
|
|
2
4
|
const basePath = process.env.MOTIA_WORKBENCH_BASE;
|
|
3
5
|
if (basePath === '/') {
|
|
@@ -6,4 +8,4 @@ function getWorkbenchBase() {
|
|
|
6
8
|
return basePath && basePath[0] !== '/' ? `/${basePath}` : basePath || '';
|
|
7
9
|
}
|
|
8
10
|
export const workbenchBase = getWorkbenchBase();
|
|
9
|
-
export const isTutorialDisabled = process.env.MOTIA_TUTORIAL_DISABLED === 'true';
|
|
11
|
+
export const isTutorialDisabled = process.env.MOTIA_TUTORIAL_DISABLED === 'true' || !fs.existsSync(path.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>;
|
|
@@ -2,16 +2,32 @@ import colors from 'colors';
|
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
3
|
import { create } from './index';
|
|
4
4
|
const choices = {
|
|
5
|
-
nodejs: '
|
|
6
|
-
python: '
|
|
7
|
-
|
|
5
|
+
nodejs: 'Tutorial (TypeScript)',
|
|
6
|
+
python: 'Tutorial (Python)',
|
|
7
|
+
'starter-typescript': 'Starter (TypeScript)',
|
|
8
|
+
'starter-javascript': 'Starter (JavaScript)',
|
|
9
|
+
'starter-python': 'Starter (Python)',
|
|
8
10
|
};
|
|
9
11
|
export const createInteractive = async (args, context) => {
|
|
10
|
-
context.log('welcome', (message) => message.append(
|
|
12
|
+
context.log('welcome', (message) => message.append(`\n🚀 ${colors.bold(args.plugin ? 'Welcome to Motia Plugin Creator!' : 'Welcome to Motia Project Creator!')}`));
|
|
11
13
|
const questions = [];
|
|
12
14
|
let name = args.name;
|
|
13
15
|
let template = args.template;
|
|
14
|
-
if (
|
|
16
|
+
if (args.plugin) {
|
|
17
|
+
if (!args.name) {
|
|
18
|
+
context.log('failed', (message) => message
|
|
19
|
+
.tag('failed')
|
|
20
|
+
.append(`Project name is required: ${colors.bold('motia create --plugin [project-name]')}\n`));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
return create({
|
|
24
|
+
projectName: args.name,
|
|
25
|
+
template: 'plugin',
|
|
26
|
+
cursorEnabled: false,
|
|
27
|
+
context,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (!args.template) {
|
|
15
31
|
questions.push({
|
|
16
32
|
type: 'list',
|
|
17
33
|
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
|
+
})
|
|
@@ -3,4 +3,7 @@ export const templates = {
|
|
|
3
3
|
nodejs: generateTemplateSteps('nodejs'),
|
|
4
4
|
python: generateTemplateSteps('python'),
|
|
5
5
|
plugin: generatePluginTemplate('plugin'),
|
|
6
|
+
'starter-typescript': generateTemplateSteps('hello'),
|
|
7
|
+
'starter-javascript': generateTemplateSteps('hello_js'),
|
|
8
|
+
'starter-python': generateTemplateSteps('hello_python'),
|
|
6
9
|
};
|
|
@@ -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
|
})
|
|
@@ -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>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "motia",
|
|
3
3
|
"description": "A Modern Unified Backend Framework for APIs, Events and Agents",
|
|
4
|
-
"version": "0.8.6-beta.
|
|
4
|
+
"version": "0.8.6-beta.144-824340",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"python-ast": "^0.1.0",
|
|
47
47
|
"table": "^6.9.0",
|
|
48
48
|
"ts-node": "^10.9.2",
|
|
49
|
-
"@motiadev/core": "0.8.6-beta.
|
|
50
|
-
"@motiadev/stream-client-node": "0.8.6-beta.
|
|
51
|
-
"@motiadev/workbench": "0.8.6-beta.
|
|
49
|
+
"@motiadev/core": "0.8.6-beta.144-824340",
|
|
50
|
+
"@motiadev/stream-client-node": "0.8.6-beta.144-824340",
|
|
51
|
+
"@motiadev/workbench": "0.8.6-beta.144-824340"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@amplitude/analytics-types": "^2.9.2",
|
/package/dist/cjs/create/templates/nodejs/{steps → tutorial}/petstore/api.step.ts-features.json.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/cjs/create/templates/python/{steps → tutorial}/petstore/api_step.py-features.json.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/esm/create/templates/nodejs/{steps → tutorial}/petstore/api.step.ts-features.json.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/esm/create/templates/python/{steps → tutorial}/petstore/api_step.py-features.json.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|