Skip to content

Commit

Permalink
add server api for apps
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorS67 committed Jul 27, 2024
1 parent 8e3a5f0 commit 87cc884
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 406 deletions.
7 changes: 7 additions & 0 deletions packages/node/scripts/create-entrypoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ const updateConfig = () => {
updateJSONFile("./package.json", (json) => ({
...json,
exports: Object.assign(
{
".": {
types: "./index.d.ts",
import: "./index.js",
require: "./index.cjs",
},
},
Object.fromEntries(
[...Object.keys(entrypoints)].map((key) => {
let entryPoint = {
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/streaming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export function getProcessorSSEStream(
type: T,
data: ProcessStreamEvents[T]
) {
const event = `event: ${type}\ndata ${JSON.stringify(data)}\n\n`;
const event = `event: ${type}\ndata: ${JSON.stringify(data)}\n\n`;
controller.enqueue(encoder.encode(event));
}

Expand Down
5 changes: 3 additions & 2 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"lint-fix": "eslint --fix \"**/*.{js,jsx,ts,tsx}\""
},
"dependencies": {
"@encrejs/core": "0.0.5",
"@encrejs/core": "0.0.6",
"@encrejs/api": "0.0.1",
"axios": "1.6.2",
"cors": "^2.8.5",
"express": "4.19.2",
Expand All @@ -37,11 +38,11 @@
"@typescript-eslint/typescript-estree": "^5.39.0",
"dotenv": "^16.4.5",
"eslint": "^8.49.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-markdown": "^3.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-unused-imports": "^2.0.0",
Expand Down
11 changes: 10 additions & 1 deletion packages/server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Config {
fileSizeSyncLimitMB: number;
fileSizeLimitMB: number;
};
encreFilePath?: string;
}

const projectRoot: string = path.dirname(fileURLToPath(import.meta.url));
Expand Down Expand Up @@ -50,7 +51,14 @@ if (process.env.ENCRE_CONFIG_PATH) {
let defaultConfig: Omit<Config, 'mode'> = {
port: 5127,
hostname: '::',
webRoot: path.join(projectRoot, '..', 'node_modules', '@encrejs', 'app', 'build'),
webRoot: path.join(
projectRoot,
'..',
'node_modules',
'@encrejs',
'app',
'build'
),
upload: {
fileSizeSyncLimitMB: 20,
fileSizeLimitMB: 20,
Expand Down Expand Up @@ -101,6 +109,7 @@ const finalConfig: Config = {
config.upload!.fileSizeLimitMB,
}
: config.upload,
encreFilePath: process.env.ENCRE_FILE_PATH,
};

export default finalConfig;
50 changes: 50 additions & 0 deletions packages/server/src/controllers/app/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Request, Response, NextFunction } from 'express';
import type { Data, GraphInputs, ProcessOptions } from '@encrejs/api';
import type { ProcessStreamEventFilter } from '@encrejs/api/streaming';
import appService from '../../services/app/index.js';
import config from '../../config.js';

const run = async (req: Request, res: Response, next: NextFunction) => {
try {
const {
userInputs: inputs,
appPath,
context,
filter,
} = req.body as {
userInputs: GraphInputs;
appPath?: string;
context?: Record<string, Data>;
filter?: ProcessStreamEventFilter;
};

const filePath: string =
appPath ?? config.encreFilePath ?? config.projectRoot;
const options: ProcessOptions = { inputs, context };

res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Transfer-Encoding', 'chunked');

for await (const chunk of appService.run(filePath, options, filter)) {
const groups = /event: (?<event>.*)\ndata: (?<data>.*)\n\n/.exec(chunk)!
.groups!;

const eventName = groups.event!;
const data = groups.data!;

const chunkData = {
['#event']: eventName,
...JSON.parse(data),
};

res.write(`data: ${JSON.stringify(chunkData)}\n\n`);
}

res.write('data: [DONE]\n\n');
res.end();
} catch (error) {
next(error);
}
};

export default { run };
8 changes: 8 additions & 0 deletions packages/server/src/routes/app/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express';
import nodesController from '../../controllers/app/index.js';

const router = express.Router();

router.get('/run', nodesController.run);

export default router;
2 changes: 2 additions & 0 deletions packages/server/src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import express from 'express';
import appRouter from './app/index.js';
import nodesRouter from './nodes/index.js';
import registryRouter from './registry/index.js';

const router = express.Router();

router.use('/app', appRouter);
router.use('/nodes', nodesRouter);
router.use('/registry', registryRouter);

Expand Down
65 changes: 65 additions & 0 deletions packages/server/src/services/app/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {
BaseGraph,
createProcessor,
loadGraph,
ProcessOptions,
} from '@encrejs/api';
import { ProcessStreamEventFilter } from '@encrejs/api/streaming';
import { StatusCodes } from 'http-status-codes';

import { InternalError } from '../../exceptions/internal.js';
import { getErrorMessage } from '../../utils/getErrorMessage.js';

async function _getGraph(filePath: string): Promise<BaseGraph> {
try {
const graph = await loadGraph(filePath);

return graph;
} catch (error) {
throw new InternalError(
StatusCodes.INTERNAL_SERVER_ERROR,
`appService.getGraph: ${getErrorMessage(error)}`
);
}
}

function _getProcessor(
graph: BaseGraph,
options?: ProcessOptions
): ReturnType<typeof createProcessor> {
try {
const processor = createProcessor(graph, options);

return processor;
} catch (error) {
throw new InternalError(
StatusCodes.INTERNAL_SERVER_ERROR,
`appService.getProcessor: ${getErrorMessage(error)}`
);
}
}

async function* run(
filePath: string,
options?: ProcessOptions,
filter?: ProcessStreamEventFilter
) {
try {
const graph = await _getGraph(filePath);

const processor = _getProcessor(graph, options);

for await (const chunk of processor.sseStream(filter ?? {})) {
yield chunk;
}
} catch (error) {
throw new InternalError(
StatusCodes.INTERNAL_SERVER_ERROR,
`appService.run: ${getErrorMessage(error)}`
);
}
}

export default {
run,
};
Loading

0 comments on commit 87cc884

Please sign in to comment.