motia 0.8.2-beta.140-930160 → 0.8.2-beta.140-709523
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/cloud/build/builders/archiver.d.ts +1 -2
- package/dist/cjs/cloud/build/builders/archiver.js +14 -25
- package/dist/cjs/cloud/build/builders/include-static-files.js +1 -2
- package/dist/cjs/cloud/build/builders/node/index.js +4 -4
- package/dist/cjs/dev.js +13 -8
- package/dist/cjs/generate-plugins.js +18 -20
- package/dist/cjs/load-motia-config.d.ts +2 -0
- package/dist/cjs/load-motia-config.js +52 -0
- package/dist/cjs/start.js +10 -4
- package/dist/esm/cloud/build/builders/archiver.d.ts +1 -2
- package/dist/esm/cloud/build/builders/archiver.js +14 -25
- package/dist/esm/cloud/build/builders/include-static-files.js +1 -2
- package/dist/esm/cloud/build/builders/node/index.js +4 -4
- package/dist/esm/dev.js +14 -9
- package/dist/esm/generate-plugins.js +18 -20
- package/dist/esm/load-motia-config.d.ts +2 -0
- package/dist/esm/load-motia-config.js +15 -0
- package/dist/esm/start.js +11 -5
- package/dist/types/cloud/build/builders/archiver.d.ts +1 -2
- package/dist/types/load-motia-config.d.ts +2 -0
- package/package.json +4 -4
|
@@ -9,7 +9,6 @@ export declare class Archiver {
|
|
|
9
9
|
private uncompressedSize;
|
|
10
10
|
constructor(filePath: string);
|
|
11
11
|
appendDirectory(sourcePath: string, targetPath: string): void;
|
|
12
|
-
|
|
13
|
-
append(stream: fs.ReadStream | string | Buffer, filePath: string): void;
|
|
12
|
+
append(stream: fs.ReadStream | string, filePath: string): void;
|
|
14
13
|
finalize(): Promise<ArchiveResult>;
|
|
15
14
|
}
|
|
@@ -16,50 +16,39 @@ class Archiver {
|
|
|
16
16
|
}
|
|
17
17
|
appendDirectory(sourcePath, targetPath) {
|
|
18
18
|
try {
|
|
19
|
-
const
|
|
20
|
-
if (!stat.isDirectory()) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
this.uncompressedSize += this.calculateDirectorySize(sourcePath);
|
|
24
|
-
this.archive.directory(sourcePath, targetPath === '/' ? false : targetPath);
|
|
25
|
-
}
|
|
26
|
-
catch (_error) { }
|
|
27
|
-
}
|
|
28
|
-
calculateDirectorySize(dirPath) {
|
|
29
|
-
let totalSize = 0;
|
|
30
|
-
try {
|
|
31
|
-
const items = fs_1.default.readdirSync(dirPath);
|
|
19
|
+
const items = fs_1.default.readdirSync(sourcePath);
|
|
32
20
|
for (const item of items) {
|
|
33
|
-
const fullPath = path_1.default.join(
|
|
21
|
+
const fullPath = path_1.default.join(sourcePath, item);
|
|
34
22
|
try {
|
|
35
23
|
const stat = fs_1.default.statSync(fullPath);
|
|
36
24
|
if (stat.isDirectory()) {
|
|
37
|
-
|
|
25
|
+
this.appendDirectory(fullPath, path_1.default.join(targetPath, item));
|
|
38
26
|
}
|
|
39
27
|
else {
|
|
40
|
-
|
|
28
|
+
this.append(fs_1.default.createReadStream(fullPath), targetPath ? path_1.default.join(targetPath, item) : item);
|
|
41
29
|
}
|
|
42
30
|
}
|
|
43
|
-
catch (_error) {
|
|
31
|
+
catch (_error) {
|
|
32
|
+
// Ignore individual file errors
|
|
33
|
+
}
|
|
44
34
|
}
|
|
45
35
|
}
|
|
46
|
-
catch (_error) {
|
|
47
|
-
|
|
36
|
+
catch (_error) {
|
|
37
|
+
// Ignore directory read errors
|
|
38
|
+
}
|
|
48
39
|
}
|
|
49
40
|
append(stream, filePath) {
|
|
41
|
+
// Track uncompressed size
|
|
50
42
|
if (typeof stream === 'string') {
|
|
43
|
+
// String content
|
|
51
44
|
this.uncompressedSize += Buffer.byteLength(stream, 'utf8');
|
|
52
|
-
this.archive.append(stream, { name: filePath });
|
|
53
|
-
}
|
|
54
|
-
else if (Buffer.isBuffer(stream)) {
|
|
55
|
-
this.uncompressedSize += stream.length;
|
|
56
|
-
this.archive.append(stream, { name: filePath });
|
|
57
45
|
}
|
|
58
46
|
else {
|
|
47
|
+
// ReadStream - get file stats
|
|
59
48
|
const stats = fs_1.default.statSync(stream.path);
|
|
60
49
|
this.uncompressedSize += stats.size;
|
|
61
|
-
this.archive.append(stream, { name: filePath });
|
|
62
50
|
}
|
|
51
|
+
this.archive.append(stream, { name: filePath });
|
|
63
52
|
}
|
|
64
53
|
async finalize() {
|
|
65
54
|
return new Promise((resolve, reject) => {
|
|
@@ -18,8 +18,7 @@ const includeStaticFiles = (steps, builder, archive) => {
|
|
|
18
18
|
const matches = (0, glob_1.globSync)(file, { cwd: path_1.default.dirname(step.filePath), absolute: true });
|
|
19
19
|
matches.forEach((filePath) => {
|
|
20
20
|
const relativeFilePath = path_1.default.relative(builder.projectDir, filePath);
|
|
21
|
-
|
|
22
|
-
archive.append(content, relativeFilePath);
|
|
21
|
+
archive.append(fs_1.default.createReadStream(filePath), relativeFilePath);
|
|
23
22
|
});
|
|
24
23
|
});
|
|
25
24
|
}
|
|
@@ -94,8 +94,8 @@ class NodeBuilder {
|
|
|
94
94
|
const archiver = new archiver_1.Archiver(path_1.default.join(constants_1.distDir, zipName));
|
|
95
95
|
const routerJs = path_1.default.join(constants_1.distDir, 'router.js');
|
|
96
96
|
const routerMap = path_1.default.join(constants_1.distDir, 'router.js.map');
|
|
97
|
-
archiver.append(fs_1.default.
|
|
98
|
-
archiver.append(fs_1.default.
|
|
97
|
+
archiver.append(fs_1.default.createReadStream(routerJs), 'router.js');
|
|
98
|
+
archiver.append(fs_1.default.createReadStream(routerMap), 'router.js.map');
|
|
99
99
|
(0, include_static_files_1.includeStaticFiles)(steps, this.builder, archiver);
|
|
100
100
|
const { compressedSize, uncompressedSize } = await archiver.finalize();
|
|
101
101
|
fs_1.default.unlinkSync(tsRouter);
|
|
@@ -123,8 +123,8 @@ class NodeBuilder {
|
|
|
123
123
|
};
|
|
124
124
|
await esbuild.build(userConfig ? { ...defaultConfig, ...userConfig } : defaultConfig);
|
|
125
125
|
const archiver = new archiver_1.Archiver(path_1.default.join(constants_1.distDir, bundlePath));
|
|
126
|
-
archiver.append(fs_1.default.
|
|
127
|
-
archiver.append(fs_1.default.
|
|
126
|
+
archiver.append(fs_1.default.createReadStream(outputJsFile), entrypointPath);
|
|
127
|
+
archiver.append(fs_1.default.createReadStream(outputMapFile), entrypointMapPath);
|
|
128
128
|
(0, include_static_files_1.includeStaticFiles)([step], this.builder, archiver);
|
|
129
129
|
const { compressedSize, uncompressedSize } = await archiver.finalize();
|
|
130
130
|
fs_1.default.unlinkSync(outputJsFile);
|
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"));
|
|
@@ -13,6 +12,7 @@ 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");
|
|
15
14
|
const generate_plugins_1 = require("./generate-plugins");
|
|
15
|
+
const load_motia_config_1 = require("./load-motia-config");
|
|
16
16
|
const activate_python_env_1 = require("./utils/activate-python-env");
|
|
17
17
|
const analytics_1 = require("./utils/analytics");
|
|
18
18
|
const version_1 = require("./version");
|
|
@@ -41,14 +41,19 @@ const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFileStora
|
|
|
41
41
|
}
|
|
42
42
|
const motiaFileStoragePath = motiaFileStorageDir || '.motia';
|
|
43
43
|
const lockedData = await (0, generate_locked_data_1.generateLockedData)({ projectDir: baseDir, motiaFileStoragePath });
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
const appConfig = await (0, load_motia_config_1.loadMotiaConfig)(baseDir);
|
|
45
|
+
const state = appConfig.adapters?.state ||
|
|
46
|
+
(0, core_1.createStateAdapter)({
|
|
47
|
+
adapter: 'default',
|
|
48
|
+
filePath: path_1.default.join(baseDir, motiaFileStoragePath),
|
|
49
|
+
});
|
|
50
50
|
const config = { isVerbose };
|
|
51
|
-
const
|
|
51
|
+
const adapters = {
|
|
52
|
+
eventAdapter: appConfig.adapters?.events || new core_1.DefaultQueueEventAdapter(),
|
|
53
|
+
cronAdapter: appConfig.adapters?.cron || new core_1.DefaultCronAdapter(),
|
|
54
|
+
streamAdapterFactory: appConfig.adapters?.streams ? () => appConfig.adapters.streams : undefined,
|
|
55
|
+
};
|
|
56
|
+
const motiaServer = (0, core_1.createServer)(lockedData, state, config, adapters);
|
|
52
57
|
const watcher = (0, dev_watchers_1.createDevWatchers)(lockedData, motiaServer, motiaServer.motiaEventManager, motiaServer.cronManager);
|
|
53
58
|
const plugins = await (0, generate_plugins_1.processPlugins)(motiaServer);
|
|
54
59
|
// Initialize mermaid generator
|
|
@@ -42,17 +42,17 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
42
42
|
const node_path_1 = __importDefault(require("node:path"));
|
|
43
43
|
const core_1 = require("@motiadev/core");
|
|
44
44
|
const glob_1 = require("glob");
|
|
45
|
-
const collectPluginSteps = async (dirname, stepPatterns, projectRoot
|
|
45
|
+
const collectPluginSteps = async (dirname, stepPatterns, projectRoot) => {
|
|
46
46
|
const pluginSteps = [];
|
|
47
47
|
if (!node_fs_1.default.existsSync(dirname)) {
|
|
48
|
-
|
|
48
|
+
console.warn(`[Plugin] Directory not found: ${dirname}`);
|
|
49
49
|
return pluginSteps;
|
|
50
50
|
}
|
|
51
51
|
for (const pattern of stepPatterns) {
|
|
52
52
|
try {
|
|
53
53
|
const stepFiles = (0, glob_1.globSync)(pattern, { absolute: true, cwd: dirname });
|
|
54
54
|
if (stepFiles.length === 0) {
|
|
55
|
-
|
|
55
|
+
console.log(`[Plugin] No files found matching pattern: ${pattern} in ${dirname}`);
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
58
|
for (const filePath of stepFiles) {
|
|
@@ -62,36 +62,35 @@ const collectPluginSteps = async (dirname, stepPatterns, projectRoot, printer) =
|
|
|
62
62
|
pluginSteps.push({ filePath, config });
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
|
|
65
|
+
console.warn(`[Plugin] No config found in step ${filePath}, step skipped`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
catch (error) {
|
|
69
|
-
|
|
69
|
+
console.error(`[Plugin] Error loading step ${filePath}:`, error);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
catch (error) {
|
|
74
|
-
|
|
74
|
+
console.error(`[Plugin] Error processing pattern ${pattern}:`, error);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
return pluginSteps;
|
|
78
78
|
};
|
|
79
|
-
const loadConfig = async (baseDir
|
|
79
|
+
const loadConfig = async (baseDir) => {
|
|
80
80
|
const configFiles = (0, glob_1.globSync)('motia.config.{ts,js}', { absolute: true, cwd: baseDir });
|
|
81
81
|
if (configFiles.length === 0) {
|
|
82
82
|
const templatePath = node_path_1.default.join(__dirname, 'create/templates/nodejs/motia.config.ts.txt');
|
|
83
83
|
const templateContent = node_fs_1.default.readFileSync(templatePath, 'utf-8');
|
|
84
84
|
const configPath = node_path_1.default.join(baseDir, 'motia.config.ts');
|
|
85
85
|
node_fs_1.default.writeFileSync(configPath, templateContent);
|
|
86
|
-
|
|
86
|
+
console.log('Created motia.config.ts with default plugins');
|
|
87
87
|
return (await Promise.resolve(`${configPath}`).then(s => __importStar(require(s)))).default;
|
|
88
88
|
}
|
|
89
89
|
return (await Promise.resolve(`${configFiles[0]}`).then(s => __importStar(require(s)))).default;
|
|
90
90
|
};
|
|
91
91
|
const createPluginContext = (motiaServer) => {
|
|
92
|
-
const { motia, addRoute, removeRoute
|
|
92
|
+
const { motia, addRoute, removeRoute } = motiaServer;
|
|
93
93
|
return {
|
|
94
|
-
printer,
|
|
95
94
|
tracerFactory: motia.tracerFactory,
|
|
96
95
|
state: motia.stateAdapter,
|
|
97
96
|
lockedData: motia.lockedData,
|
|
@@ -118,12 +117,12 @@ const createPluginContext = (motiaServer) => {
|
|
|
118
117
|
};
|
|
119
118
|
};
|
|
120
119
|
const processSteps = async (motiaServer, plugins, baseDir) => {
|
|
121
|
-
const { motia, addRoute
|
|
120
|
+
const { motia, addRoute } = motiaServer;
|
|
122
121
|
for (const plugin of plugins) {
|
|
123
122
|
if (plugin.dirname && plugin.steps) {
|
|
124
|
-
|
|
123
|
+
console.log(`[Plugin] Loading steps from ${plugin.dirname}`);
|
|
125
124
|
try {
|
|
126
|
-
const pluginSteps = await collectPluginSteps(plugin.dirname, plugin.steps, baseDir
|
|
125
|
+
const pluginSteps = await collectPluginSteps(plugin.dirname, plugin.steps, baseDir);
|
|
127
126
|
const version = `plugin_${(0, node_crypto_1.randomUUID)()}:${Math.floor(Date.now() / 1000)}`;
|
|
128
127
|
for (const { filePath, config } of pluginSteps) {
|
|
129
128
|
try {
|
|
@@ -135,27 +134,26 @@ const processSteps = async (motiaServer, plugins, baseDir) => {
|
|
|
135
134
|
}
|
|
136
135
|
}
|
|
137
136
|
else {
|
|
138
|
-
|
|
137
|
+
console.warn(`[Plugin] Failed to register step: ${config.name} from ${filePath}`);
|
|
139
138
|
}
|
|
140
139
|
}
|
|
141
140
|
catch (error) {
|
|
142
|
-
|
|
141
|
+
console.error(`[Plugin] Error registering step ${filePath}:`, error);
|
|
143
142
|
}
|
|
144
143
|
}
|
|
145
144
|
}
|
|
146
145
|
catch (error) {
|
|
147
|
-
|
|
146
|
+
console.error(`[Plugin] Error loading steps from ${plugin.dirname}:`, error);
|
|
148
147
|
}
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
};
|
|
152
151
|
const processPlugins = async (motiaServer) => {
|
|
153
|
-
const
|
|
154
|
-
const baseDir = motia.lockedData.baseDir;
|
|
152
|
+
const baseDir = motiaServer.motia.lockedData.baseDir;
|
|
155
153
|
const context = createPluginContext(motiaServer);
|
|
156
|
-
const appConfig = await loadConfig(baseDir
|
|
154
|
+
const appConfig = await loadConfig(baseDir);
|
|
157
155
|
if (!appConfig?.plugins) {
|
|
158
|
-
|
|
156
|
+
console.warn('No plugins found in motia.config.ts');
|
|
159
157
|
return [];
|
|
160
158
|
}
|
|
161
159
|
const plugins = appConfig.plugins?.flatMap((item) => item(context)) || [];
|
|
@@ -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;
|
package/dist/cjs/start.js
CHANGED
|
@@ -9,6 +9,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const constants_1 = require("./constants");
|
|
10
10
|
const generate_locked_data_1 = require("./generate-locked-data");
|
|
11
11
|
const generate_plugins_1 = require("./generate-plugins");
|
|
12
|
+
const load_motia_config_1 = require("./load-motia-config");
|
|
12
13
|
const activate_python_env_1 = require("./utils/activate-python-env");
|
|
13
14
|
const version_1 = require("./version");
|
|
14
15
|
require('ts-node').register({
|
|
@@ -27,11 +28,16 @@ const start = async (port, hostname, disableVerbose, motiaFileStorageDir) => {
|
|
|
27
28
|
const motiaFileStoragePath = motiaFileStorageDir || '.motia';
|
|
28
29
|
const dotMotia = path_1.default.join(baseDir, motiaFileStoragePath);
|
|
29
30
|
const lockedData = await (0, generate_locked_data_1.generateLockedData)({ projectDir: baseDir, motiaFileStoragePath });
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
31
|
+
const appConfig = await (0, load_motia_config_1.loadMotiaConfig)(baseDir);
|
|
32
|
+
const state = appConfig.adapters?.state || (0, core_1.createStateAdapter)({ adapter: 'default', filePath: dotMotia });
|
|
33
|
+
const eventAdapter = appConfig.adapters?.events || new core_1.DefaultQueueEventAdapter();
|
|
33
34
|
const config = { isVerbose, isDev: false, version: version_1.version };
|
|
34
|
-
const
|
|
35
|
+
const adapters = {
|
|
36
|
+
eventAdapter,
|
|
37
|
+
cronAdapter: appConfig.adapters?.cron || new core_1.DefaultCronAdapter(),
|
|
38
|
+
streamAdapterFactory: appConfig.adapters?.streams ? () => appConfig.adapters.streams : undefined,
|
|
39
|
+
};
|
|
40
|
+
const motiaServer = (0, core_1.createServer)(lockedData, state, config, adapters);
|
|
35
41
|
const plugins = await (0, generate_plugins_1.processPlugins)(motiaServer);
|
|
36
42
|
if (!process.env.MOTIA_DOCKER_DISABLE_WORKBENCH) {
|
|
37
43
|
const { applyMiddleware } = require('@motiadev/workbench/dist/middleware');
|
|
@@ -9,7 +9,6 @@ export declare class Archiver {
|
|
|
9
9
|
private uncompressedSize;
|
|
10
10
|
constructor(filePath: string);
|
|
11
11
|
appendDirectory(sourcePath: string, targetPath: string): void;
|
|
12
|
-
|
|
13
|
-
append(stream: fs.ReadStream | string | Buffer, filePath: string): void;
|
|
12
|
+
append(stream: fs.ReadStream | string, filePath: string): void;
|
|
14
13
|
finalize(): Promise<ArchiveResult>;
|
|
15
14
|
}
|
|
@@ -10,50 +10,39 @@ export class Archiver {
|
|
|
10
10
|
}
|
|
11
11
|
appendDirectory(sourcePath, targetPath) {
|
|
12
12
|
try {
|
|
13
|
-
const
|
|
14
|
-
if (!stat.isDirectory()) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
this.uncompressedSize += this.calculateDirectorySize(sourcePath);
|
|
18
|
-
this.archive.directory(sourcePath, targetPath === '/' ? false : targetPath);
|
|
19
|
-
}
|
|
20
|
-
catch (_error) { }
|
|
21
|
-
}
|
|
22
|
-
calculateDirectorySize(dirPath) {
|
|
23
|
-
let totalSize = 0;
|
|
24
|
-
try {
|
|
25
|
-
const items = fs.readdirSync(dirPath);
|
|
13
|
+
const items = fs.readdirSync(sourcePath);
|
|
26
14
|
for (const item of items) {
|
|
27
|
-
const fullPath = path.join(
|
|
15
|
+
const fullPath = path.join(sourcePath, item);
|
|
28
16
|
try {
|
|
29
17
|
const stat = fs.statSync(fullPath);
|
|
30
18
|
if (stat.isDirectory()) {
|
|
31
|
-
|
|
19
|
+
this.appendDirectory(fullPath, path.join(targetPath, item));
|
|
32
20
|
}
|
|
33
21
|
else {
|
|
34
|
-
|
|
22
|
+
this.append(fs.createReadStream(fullPath), targetPath ? path.join(targetPath, item) : item);
|
|
35
23
|
}
|
|
36
24
|
}
|
|
37
|
-
catch (_error) {
|
|
25
|
+
catch (_error) {
|
|
26
|
+
// Ignore individual file errors
|
|
27
|
+
}
|
|
38
28
|
}
|
|
39
29
|
}
|
|
40
|
-
catch (_error) {
|
|
41
|
-
|
|
30
|
+
catch (_error) {
|
|
31
|
+
// Ignore directory read errors
|
|
32
|
+
}
|
|
42
33
|
}
|
|
43
34
|
append(stream, filePath) {
|
|
35
|
+
// Track uncompressed size
|
|
44
36
|
if (typeof stream === 'string') {
|
|
37
|
+
// String content
|
|
45
38
|
this.uncompressedSize += Buffer.byteLength(stream, 'utf8');
|
|
46
|
-
this.archive.append(stream, { name: filePath });
|
|
47
|
-
}
|
|
48
|
-
else if (Buffer.isBuffer(stream)) {
|
|
49
|
-
this.uncompressedSize += stream.length;
|
|
50
|
-
this.archive.append(stream, { name: filePath });
|
|
51
39
|
}
|
|
52
40
|
else {
|
|
41
|
+
// ReadStream - get file stats
|
|
53
42
|
const stats = fs.statSync(stream.path);
|
|
54
43
|
this.uncompressedSize += stats.size;
|
|
55
|
-
this.archive.append(stream, { name: filePath });
|
|
56
44
|
}
|
|
45
|
+
this.archive.append(stream, { name: filePath });
|
|
57
46
|
}
|
|
58
47
|
async finalize() {
|
|
59
48
|
return new Promise((resolve, reject) => {
|
|
@@ -12,8 +12,7 @@ export const includeStaticFiles = (steps, builder, archive) => {
|
|
|
12
12
|
const matches = globSync(file, { cwd: path.dirname(step.filePath), absolute: true });
|
|
13
13
|
matches.forEach((filePath) => {
|
|
14
14
|
const relativeFilePath = path.relative(builder.projectDir, filePath);
|
|
15
|
-
|
|
16
|
-
archive.append(content, relativeFilePath);
|
|
15
|
+
archive.append(fs.createReadStream(filePath), relativeFilePath);
|
|
17
16
|
});
|
|
18
17
|
});
|
|
19
18
|
}
|
|
@@ -55,8 +55,8 @@ export class NodeBuilder {
|
|
|
55
55
|
const archiver = new Archiver(path.join(distDir, zipName));
|
|
56
56
|
const routerJs = path.join(distDir, 'router.js');
|
|
57
57
|
const routerMap = path.join(distDir, 'router.js.map');
|
|
58
|
-
archiver.append(fs.
|
|
59
|
-
archiver.append(fs.
|
|
58
|
+
archiver.append(fs.createReadStream(routerJs), 'router.js');
|
|
59
|
+
archiver.append(fs.createReadStream(routerMap), 'router.js.map');
|
|
60
60
|
includeStaticFiles(steps, this.builder, archiver);
|
|
61
61
|
const { compressedSize, uncompressedSize } = await archiver.finalize();
|
|
62
62
|
fs.unlinkSync(tsRouter);
|
|
@@ -84,8 +84,8 @@ export class NodeBuilder {
|
|
|
84
84
|
};
|
|
85
85
|
await esbuild.build(userConfig ? { ...defaultConfig, ...userConfig } : defaultConfig);
|
|
86
86
|
const archiver = new Archiver(path.join(distDir, bundlePath));
|
|
87
|
-
archiver.append(fs.
|
|
88
|
-
archiver.append(fs.
|
|
87
|
+
archiver.append(fs.createReadStream(outputJsFile), entrypointPath);
|
|
88
|
+
archiver.append(fs.createReadStream(outputMapFile), entrypointMapPath);
|
|
89
89
|
includeStaticFiles([step], this.builder, archiver);
|
|
90
90
|
const { compressedSize, uncompressedSize } = await archiver.finalize();
|
|
91
91
|
fs.unlinkSync(outputJsFile);
|
package/dist/esm/dev.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// packages/snap/src/dev.ts
|
|
2
1
|
import { flush } from '@amplitude/analytics-node';
|
|
3
|
-
import {
|
|
2
|
+
import { createMermaidGenerator, createServer, createStateAdapter, DefaultCronAdapter, DefaultQueueEventAdapter, getProjectIdentifier, trackEvent, } from '@motiadev/core';
|
|
4
3
|
import path from 'path';
|
|
5
4
|
import { deployEndpoints } from './cloud/endpoints';
|
|
6
5
|
import { isTutorialDisabled, workbenchBase } from './constants';
|
|
7
6
|
import { createDevWatchers } from './dev-watchers';
|
|
8
7
|
import { generateLockedData, getStepFiles } from './generate-locked-data';
|
|
9
8
|
import { processPlugins } from './generate-plugins';
|
|
9
|
+
import { loadMotiaConfig } from './load-motia-config';
|
|
10
10
|
import { activatePythonVenv } from './utils/activate-python-env';
|
|
11
11
|
import { identifyUser } from './utils/analytics';
|
|
12
12
|
import { version } from './version';
|
|
@@ -35,14 +35,19 @@ export const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFi
|
|
|
35
35
|
}
|
|
36
36
|
const motiaFileStoragePath = motiaFileStorageDir || '.motia';
|
|
37
37
|
const lockedData = await generateLockedData({ projectDir: baseDir, motiaFileStoragePath });
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
const appConfig = await loadMotiaConfig(baseDir);
|
|
39
|
+
const state = appConfig.adapters?.state ||
|
|
40
|
+
createStateAdapter({
|
|
41
|
+
adapter: 'default',
|
|
42
|
+
filePath: path.join(baseDir, motiaFileStoragePath),
|
|
43
|
+
});
|
|
44
44
|
const config = { isVerbose };
|
|
45
|
-
const
|
|
45
|
+
const adapters = {
|
|
46
|
+
eventAdapter: appConfig.adapters?.events || new DefaultQueueEventAdapter(),
|
|
47
|
+
cronAdapter: appConfig.adapters?.cron || new DefaultCronAdapter(),
|
|
48
|
+
streamAdapterFactory: appConfig.adapters?.streams ? () => appConfig.adapters.streams : undefined,
|
|
49
|
+
};
|
|
50
|
+
const motiaServer = createServer(lockedData, state, config, adapters);
|
|
46
51
|
const watcher = createDevWatchers(lockedData, motiaServer, motiaServer.motiaEventManager, motiaServer.cronManager);
|
|
47
52
|
const plugins = await processPlugins(motiaServer);
|
|
48
53
|
// Initialize mermaid generator
|
|
@@ -3,17 +3,17 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { getStepConfig, PLUGIN_FLOW_ID, } from '@motiadev/core';
|
|
5
5
|
import { globSync } from 'glob';
|
|
6
|
-
const collectPluginSteps = async (dirname, stepPatterns, projectRoot
|
|
6
|
+
const collectPluginSteps = async (dirname, stepPatterns, projectRoot) => {
|
|
7
7
|
const pluginSteps = [];
|
|
8
8
|
if (!fs.existsSync(dirname)) {
|
|
9
|
-
|
|
9
|
+
console.warn(`[Plugin] Directory not found: ${dirname}`);
|
|
10
10
|
return pluginSteps;
|
|
11
11
|
}
|
|
12
12
|
for (const pattern of stepPatterns) {
|
|
13
13
|
try {
|
|
14
14
|
const stepFiles = globSync(pattern, { absolute: true, cwd: dirname });
|
|
15
15
|
if (stepFiles.length === 0) {
|
|
16
|
-
|
|
16
|
+
console.log(`[Plugin] No files found matching pattern: ${pattern} in ${dirname}`);
|
|
17
17
|
continue;
|
|
18
18
|
}
|
|
19
19
|
for (const filePath of stepFiles) {
|
|
@@ -23,36 +23,35 @@ const collectPluginSteps = async (dirname, stepPatterns, projectRoot, printer) =
|
|
|
23
23
|
pluginSteps.push({ filePath, config });
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
-
|
|
26
|
+
console.warn(`[Plugin] No config found in step ${filePath}, step skipped`);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
catch (error) {
|
|
30
|
-
|
|
30
|
+
console.error(`[Plugin] Error loading step ${filePath}:`, error);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
catch (error) {
|
|
35
|
-
|
|
35
|
+
console.error(`[Plugin] Error processing pattern ${pattern}:`, error);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
return pluginSteps;
|
|
39
39
|
};
|
|
40
|
-
const loadConfig = async (baseDir
|
|
40
|
+
const loadConfig = async (baseDir) => {
|
|
41
41
|
const configFiles = globSync('motia.config.{ts,js}', { absolute: true, cwd: baseDir });
|
|
42
42
|
if (configFiles.length === 0) {
|
|
43
43
|
const templatePath = path.join(__dirname, 'create/templates/nodejs/motia.config.ts.txt');
|
|
44
44
|
const templateContent = fs.readFileSync(templatePath, 'utf-8');
|
|
45
45
|
const configPath = path.join(baseDir, 'motia.config.ts');
|
|
46
46
|
fs.writeFileSync(configPath, templateContent);
|
|
47
|
-
|
|
47
|
+
console.log('Created motia.config.ts with default plugins');
|
|
48
48
|
return (await import(configPath)).default;
|
|
49
49
|
}
|
|
50
50
|
return (await import(configFiles[0])).default;
|
|
51
51
|
};
|
|
52
52
|
const createPluginContext = (motiaServer) => {
|
|
53
|
-
const { motia, addRoute, removeRoute
|
|
53
|
+
const { motia, addRoute, removeRoute } = motiaServer;
|
|
54
54
|
return {
|
|
55
|
-
printer,
|
|
56
55
|
tracerFactory: motia.tracerFactory,
|
|
57
56
|
state: motia.stateAdapter,
|
|
58
57
|
lockedData: motia.lockedData,
|
|
@@ -79,12 +78,12 @@ const createPluginContext = (motiaServer) => {
|
|
|
79
78
|
};
|
|
80
79
|
};
|
|
81
80
|
const processSteps = async (motiaServer, plugins, baseDir) => {
|
|
82
|
-
const { motia, addRoute
|
|
81
|
+
const { motia, addRoute } = motiaServer;
|
|
83
82
|
for (const plugin of plugins) {
|
|
84
83
|
if (plugin.dirname && plugin.steps) {
|
|
85
|
-
|
|
84
|
+
console.log(`[Plugin] Loading steps from ${plugin.dirname}`);
|
|
86
85
|
try {
|
|
87
|
-
const pluginSteps = await collectPluginSteps(plugin.dirname, plugin.steps, baseDir
|
|
86
|
+
const pluginSteps = await collectPluginSteps(plugin.dirname, plugin.steps, baseDir);
|
|
88
87
|
const version = `plugin_${randomUUID()}:${Math.floor(Date.now() / 1000)}`;
|
|
89
88
|
for (const { filePath, config } of pluginSteps) {
|
|
90
89
|
try {
|
|
@@ -96,27 +95,26 @@ const processSteps = async (motiaServer, plugins, baseDir) => {
|
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
97
|
else {
|
|
99
|
-
|
|
98
|
+
console.warn(`[Plugin] Failed to register step: ${config.name} from ${filePath}`);
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
101
|
catch (error) {
|
|
103
|
-
|
|
102
|
+
console.error(`[Plugin] Error registering step ${filePath}:`, error);
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
catch (error) {
|
|
108
|
-
|
|
107
|
+
console.error(`[Plugin] Error loading steps from ${plugin.dirname}:`, error);
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
111
|
};
|
|
113
112
|
export const processPlugins = async (motiaServer) => {
|
|
114
|
-
const
|
|
115
|
-
const baseDir = motia.lockedData.baseDir;
|
|
113
|
+
const baseDir = motiaServer.motia.lockedData.baseDir;
|
|
116
114
|
const context = createPluginContext(motiaServer);
|
|
117
|
-
const appConfig = await loadConfig(baseDir
|
|
115
|
+
const appConfig = await loadConfig(baseDir);
|
|
118
116
|
if (!appConfig?.plugins) {
|
|
119
|
-
|
|
117
|
+
console.warn('No plugins found in motia.config.ts');
|
|
120
118
|
return [];
|
|
121
119
|
}
|
|
122
120
|
const plugins = appConfig.plugins?.flatMap((item) => item(context)) || [];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { globSync } from 'glob';
|
|
2
|
+
export const loadMotiaConfig = async (baseDir) => {
|
|
3
|
+
const configFiles = globSync('motia.config.{ts,js}', { absolute: true, cwd: baseDir });
|
|
4
|
+
if (configFiles.length === 0) {
|
|
5
|
+
return {};
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
const appConfig = (await import(configFiles[0])).default;
|
|
9
|
+
return appConfig || {};
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
console.warn('Failed to load motia.config.ts:', error);
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
};
|
package/dist/esm/start.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createServer, createStateAdapter, DefaultCronAdapter, DefaultQueueEventAdapter, } from '@motiadev/core';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { workbenchBase } from './constants';
|
|
4
4
|
import { generateLockedData, getStepFiles } from './generate-locked-data';
|
|
5
5
|
import { processPlugins } from './generate-plugins';
|
|
6
|
+
import { loadMotiaConfig } from './load-motia-config';
|
|
6
7
|
import { activatePythonVenv } from './utils/activate-python-env';
|
|
7
8
|
import { version } from './version';
|
|
8
9
|
require('ts-node').register({
|
|
@@ -21,11 +22,16 @@ export const start = async (port, hostname, disableVerbose, motiaFileStorageDir)
|
|
|
21
22
|
const motiaFileStoragePath = motiaFileStorageDir || '.motia';
|
|
22
23
|
const dotMotia = path.join(baseDir, motiaFileStoragePath);
|
|
23
24
|
const lockedData = await generateLockedData({ projectDir: baseDir, motiaFileStoragePath });
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
25
|
+
const appConfig = await loadMotiaConfig(baseDir);
|
|
26
|
+
const state = appConfig.adapters?.state || createStateAdapter({ adapter: 'default', filePath: dotMotia });
|
|
27
|
+
const eventAdapter = appConfig.adapters?.events || new DefaultQueueEventAdapter();
|
|
27
28
|
const config = { isVerbose, isDev: false, version };
|
|
28
|
-
const
|
|
29
|
+
const adapters = {
|
|
30
|
+
eventAdapter,
|
|
31
|
+
cronAdapter: appConfig.adapters?.cron || new DefaultCronAdapter(),
|
|
32
|
+
streamAdapterFactory: appConfig.adapters?.streams ? () => appConfig.adapters.streams : undefined,
|
|
33
|
+
};
|
|
34
|
+
const motiaServer = createServer(lockedData, state, config, adapters);
|
|
29
35
|
const plugins = await processPlugins(motiaServer);
|
|
30
36
|
if (!process.env.MOTIA_DOCKER_DISABLE_WORKBENCH) {
|
|
31
37
|
const { applyMiddleware } = require('@motiadev/workbench/dist/middleware');
|
|
@@ -9,7 +9,6 @@ export declare class Archiver {
|
|
|
9
9
|
private uncompressedSize;
|
|
10
10
|
constructor(filePath: string);
|
|
11
11
|
appendDirectory(sourcePath: string, targetPath: string): void;
|
|
12
|
-
|
|
13
|
-
append(stream: fs.ReadStream | string | Buffer, filePath: string): void;
|
|
12
|
+
append(stream: fs.ReadStream | string, filePath: string): void;
|
|
14
13
|
finalize(): Promise<ArchiveResult>;
|
|
15
14
|
}
|
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.2-beta.140-
|
|
4
|
+
"version": "0.8.2-beta.140-709523",
|
|
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/
|
|
50
|
-
"@motiadev/workbench": "0.8.2-beta.140-
|
|
51
|
-
"@motiadev/
|
|
49
|
+
"@motiadev/core": "0.8.2-beta.140-709523",
|
|
50
|
+
"@motiadev/workbench": "0.8.2-beta.140-709523",
|
|
51
|
+
"@motiadev/stream-client-node": "0.8.2-beta.140-709523"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@amplitude/analytics-types": "^2.9.2",
|