Compare commits

...

2 Commits

Author SHA1 Message Date
Eleanor Mao
cd269b82b3 ts 2024-04-10 16:36:52 +08:00
Eleanor Mao
683f45d187 feat: 2024-04-10 09:30:59 +08:00
6 changed files with 74 additions and 115 deletions

View File

@ -40,6 +40,7 @@
"jest": "^27.4.3", "jest": "^27.4.3",
"jest-resolve": "^27.4.2", "jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0", "jest-watch-typeahead": "^1.0.0",
"js-yaml": "^4.1.0",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"match-sorter": "^6.3.4", "match-sorter": "^6.3.4",
@ -99,6 +100,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@types/js-yaml": "^4.0.9",
"@types/lodash": "^4.17.0", "@types/lodash": "^4.17.0",
"monaco-editor-webpack-plugin": "^7.1.0" "monaco-editor-webpack-plugin": "^7.1.0"
}, },

View File

@ -24,6 +24,7 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<script src="https://cdn-0.plantuml.com/synchro2.min.js"></script>
<title>React App</title> <title>React App</title>
</head> </head>
<body> <body>

30
src/loadYml.ts Normal file
View File

@ -0,0 +1,30 @@
/*
* @Author : Eleanor Mao
* @Date : 2024-04-10 09:14:31
* @LastEditTime : 2024-04-10 09:14:31
*
* Copyright © RingCentral. All rights reserved.
*/
import jsYaml from 'js-yaml';
import { transformDSL } from './transform';
function compress(s: string, pre: string): string {
s = unescape(encodeURIComponent(s));
const arr = [];
for (let i = 0; i < s.length; i++) {
arr.push(s.charCodeAt(i));
}
// @ts-ignore
const compressor = new Zopfli.RawDeflate(arr);
const compressed = compressor.compress();
// @ts-ignore
return "http://www.plantuml.com/plantuml" + pre + encode64_(compressed);
}
export function loadYml(input: string): string {
const definition = jsYaml.load(input);
let outputValue = transformDSL(definition);
return compress(outputValue, '/svg/');
}

View File

@ -1,84 +0,0 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Input Box and Button</title>
<style>
.container {
display: flex;
flex-direction: row;
overflow-x: auto;
align-items: center;
}
.inputBox {
margin-left: 1%;
width: 700px;
height: 800px;
flex-shrink: 0;
}
.submit {
margin-left: 1%;
width: 100px;
height: 50px;
flex-shrink: 0;
}
.outputBox {
margin-left: 1%;
width: 700px;
height: 800px;
flex-shrink: 0;
}
.image {
margin-left: 1%;
flex-shrink: 0;
}
</style>
</head>
<body>
<div class="container">
<textarea id="inputBox" class="inputBox" placeholder="DSL..."></textarea>
<button class="submit" onclick="handleButtonClick()">Submit</button>
<textarea id="outputBox" class="outputBox" placeholder="PlantUML..."></textarea>
<img id="outputImage" class="image" style="display: none" src="" alt="PlantUML Image">
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-yaml/dist/js-yaml.min.js"></script>
<script src="transform.js"></script>
<script async="" src="https://cdn-0.plantuml.com/synchro2.min.js"></script>
<script>
function compress(s, pre) {
//UTF8
s = unescape(encodeURIComponent(s));
var arr = [];
for (var i = 0; i < s.length; i++) {
arr.push(s.charCodeAt(i));
}
var compressor = new Zopfli.RawDeflate(arr);
var compressed = compressor.compress();
return "http://www.plantuml.com/plantuml" + pre + encode64_(compressed);
}
function handleButtonClick() {
const inputValue = document.getElementById('inputBox').value;
const definition = jsyaml.load(inputValue)
let outputValue;
try {
outputValue = transformDSL(definition)
document.getElementById('outputBox').value = outputValue
const imgUrl = compress(outputValue, '/svg/');
document.getElementById('outputImage').src = imgUrl;
document.getElementById('outputImage').style.display = 'block';
} catch (error) {
document.getElementById('outputBox').value = error.message
console.error(error);
}
}
</script>
</body>
</html>

View File

@ -10,39 +10,45 @@ const SCRIPT_NAME = ": Script";
const BOT_NAME = ": Chat"; const BOT_NAME = ": Chat";
const EMAIL_SENDER_NAME = ": EmailSender"; const EMAIL_SENDER_NAME = ": EmailSender";
function isHttp(actions) { interface Action {
actionType: string;
}
interface State {
name: string;
actions: Action[];
eventHandlers: any;
}
function isHttp(actions: Action[]): boolean {
return actions return actions
.map((action) => action.actionType) .some((action) => action.actionType === "HttpRequest");
.some((type) => type == "HttpRequest");
} }
function isScript(actions) { function isScript(actions: Action[]): boolean {
return actions return actions
.map((action) => action.actionType) .some((action) => action.actionType === "Script");
.some((type) => type == "Script");
} }
function isChat(actions) { function isChat(actions: Action[]): boolean {
return actions return actions
.map((action) => action.actionType) .some((action) => action.actionType === 'Chat');
.some((type) => type == "Chat");
} }
function isEmailSender(actions) { function isEmailSender(actions: Action[]): boolean {
return actions return actions
.map((action) => action.actionType) .some((action) => action.actionType === "EmailSender");
.some((type) => type == "EmailSender");
} }
function isEmpty(arr) { function isEmpty(arr: any[]): boolean {
return arr === undefined || arr == null || arr.length == 0; return arr === undefined || arr == null || arr.length === 0;
} }
function isNotBlank(str) { function isNotBlank(str: string): boolean {
return str !== undefined && str !== null && str.trim() !== ""; return str !== undefined && str !== null && str.trim() !== "";
} }
function drawState(eventState, state) { function drawState(eventState: Map<any, any>, state: State): string {
let sb = ""; let sb = "";
const name = state.name; const name = state.name;
const actions = state.actions; const actions = state.actions;
@ -51,10 +57,10 @@ function drawState(eventState, state) {
if (isEmpty(handlers)) { if (isEmpty(handlers)) {
throw Error(`state ${name} handlers must not empty`); throw Error(`state ${name} handlers must not empty`);
} }
let events = new Set() let events = new Set();
for (const handle of handlers) { for (const handle of handlers) {
const stateName = handle.eventType; const stateName = handle.eventType;
events.add(stateName) events.add(stateName);
sb += `state ${stateName} ${EVENT_COLOR} ${EVENT_NAME}\n`; sb += `state ${stateName} ${EVENT_COLOR} ${EVENT_NAME}\n`;
} }
eventState.set(name, events); eventState.set(name, events);
@ -74,14 +80,14 @@ function drawState(eventState, state) {
return sb; return sb;
} }
function append(from, to, description) { function append(from:any, to:any, description:any) {
if (isNotBlank(description)) { if (isNotBlank(description)) {
description = ": " + description; description = ": " + description;
} }
return `${from} ---> ${to}${description}\n`; return `${from} ---> ${to}${description}\n`;
} }
function wrapCond(cond) { function wrapCond(cond:any) {
if (isNotBlank(cond)) { if (isNotBlank(cond)) {
return "(" + cond + ")"; return "(" + cond + ")";
} else { } else {
@ -89,7 +95,7 @@ function wrapCond(cond) {
} }
} }
function drawTransitionCondition(eventCondition, transition) { function drawTransitionCondition(eventCondition:any, transition:any) {
const list = []; const list = [];
if (eventCondition !== undefined && eventCondition !== null) { if (eventCondition !== undefined && eventCondition !== null) {
list.push(eventCondition); list.push(eventCondition);
@ -105,7 +111,7 @@ function drawTransitionCondition(eventCondition, transition) {
return list.join(" && "); return list.join(" && ");
} }
function drawExitCondition(eventCondition, exit) { function drawExitCondition(eventCondition:any, exit:any) {
const list = []; const list = [];
if (eventCondition !== undefined && eventCondition !== null) { if (eventCondition !== undefined && eventCondition !== null) {
list.push(eventCondition); list.push(eventCondition);
@ -116,7 +122,7 @@ function drawExitCondition(eventCondition, exit) {
return list.join(" && "); return list.join(" && ");
} }
function drawStateLine(eventState, state) { function drawStateLine(eventState:any, state:any) {
const handlers = state.eventHandlers; const handlers = state.eventHandlers;
if (isEmpty(handlers)) { if (isEmpty(handlers)) {
return; return;
@ -134,15 +140,15 @@ function drawStateLine(eventState, state) {
const eventCondition = wrapCond(handler.condition); const eventCondition = wrapCond(handler.condition);
const actions = handler.actions; const actions = handler.actions;
for (const action of actions) { for (const action of actions) {
const actionType = action.actionType const actionType = action.actionType;
let targetState = action.targetState let targetState = action.targetState;
if (actionType === "Transition") { if (actionType === "Transition") {
if (eventState.has(targetState)) { if (eventState.has(targetState)) {
let events = eventState.get(targetState) let events = eventState.get(targetState);
if (events.size > 1) { if (events.size > 1) {
continue continue;
} else { } else {
targetState = events.values().next().value targetState = events.values().next().value;
} }
} }
const desc = drawTransitionCondition(eventCondition, action); const desc = drawTransitionCondition(eventCondition, action);
@ -156,7 +162,7 @@ function drawStateLine(eventState, state) {
return sb; return sb;
} }
function transformDSL(definition) { export function transformDSL(definition: any): string {
let sb = ""; let sb = "";
const eventState = new Map(); const eventState = new Map();
const states = definition["states"]; const states = definition["states"];
@ -173,4 +179,3 @@ ${sb}
`; `;
} }
module.exports = { transformDSL };

View File

@ -2343,6 +2343,11 @@
jest-matcher-utils "^27.0.0" jest-matcher-utils "^27.0.0"
pretty-format "^27.0.0" pretty-format "^27.0.0"
"@types/js-yaml@^4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2"
integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==
"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.15" version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"