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-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
"js-yaml": "^4.1.0",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"match-sorter": "^6.3.4",
@ -99,6 +100,7 @@
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@types/js-yaml": "^4.0.9",
"@types/lodash": "^4.17.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.
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>
</head>
<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 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
.map((action) => action.actionType)
.some((type) => type == "HttpRequest");
.some((action) => action.actionType === "HttpRequest");
}
function isScript(actions) {
function isScript(actions: Action[]): boolean {
return actions
.map((action) => action.actionType)
.some((type) => type == "Script");
.some((action) => action.actionType === "Script");
}
function isChat(actions) {
function isChat(actions: Action[]): boolean {
return actions
.map((action) => action.actionType)
.some((type) => type == "Chat");
.some((action) => action.actionType === 'Chat');
}
function isEmailSender(actions) {
function isEmailSender(actions: Action[]): boolean {
return actions
.map((action) => action.actionType)
.some((type) => type == "EmailSender");
.some((action) => action.actionType === "EmailSender");
}
function isEmpty(arr) {
return arr === undefined || arr == null || arr.length == 0;
function isEmpty(arr: any[]): boolean {
return arr === undefined || arr == null || arr.length === 0;
}
function isNotBlank(str) {
function isNotBlank(str: string): boolean {
return str !== undefined && str !== null && str.trim() !== "";
}
function drawState(eventState, state) {
function drawState(eventState: Map<any, any>, state: State): string {
let sb = "";
const name = state.name;
const actions = state.actions;
@ -51,10 +57,10 @@ function drawState(eventState, state) {
if (isEmpty(handlers)) {
throw Error(`state ${name} handlers must not empty`);
}
let events = new Set()
let events = new Set();
for (const handle of handlers) {
const stateName = handle.eventType;
events.add(stateName)
events.add(stateName);
sb += `state ${stateName} ${EVENT_COLOR} ${EVENT_NAME}\n`;
}
eventState.set(name, events);
@ -74,14 +80,14 @@ function drawState(eventState, state) {
return sb;
}
function append(from, to, description) {
function append(from:any, to:any, description:any) {
if (isNotBlank(description)) {
description = ": " + description;
}
return `${from} ---> ${to}${description}\n`;
}
function wrapCond(cond) {
function wrapCond(cond:any) {
if (isNotBlank(cond)) {
return "(" + cond + ")";
} else {
@ -89,7 +95,7 @@ function wrapCond(cond) {
}
}
function drawTransitionCondition(eventCondition, transition) {
function drawTransitionCondition(eventCondition:any, transition:any) {
const list = [];
if (eventCondition !== undefined && eventCondition !== null) {
list.push(eventCondition);
@ -105,7 +111,7 @@ function drawTransitionCondition(eventCondition, transition) {
return list.join(" && ");
}
function drawExitCondition(eventCondition, exit) {
function drawExitCondition(eventCondition:any, exit:any) {
const list = [];
if (eventCondition !== undefined && eventCondition !== null) {
list.push(eventCondition);
@ -116,7 +122,7 @@ function drawExitCondition(eventCondition, exit) {
return list.join(" && ");
}
function drawStateLine(eventState, state) {
function drawStateLine(eventState:any, state:any) {
const handlers = state.eventHandlers;
if (isEmpty(handlers)) {
return;
@ -134,15 +140,15 @@ function drawStateLine(eventState, state) {
const eventCondition = wrapCond(handler.condition);
const actions = handler.actions;
for (const action of actions) {
const actionType = action.actionType
let targetState = action.targetState
const actionType = action.actionType;
let targetState = action.targetState;
if (actionType === "Transition") {
if (eventState.has(targetState)) {
let events = eventState.get(targetState)
let events = eventState.get(targetState);
if (events.size > 1) {
continue
continue;
} else {
targetState = events.values().next().value
targetState = events.values().next().value;
}
}
const desc = drawTransitionCondition(eventCondition, action);
@ -156,7 +162,7 @@ function drawStateLine(eventState, state) {
return sb;
}
function transformDSL(definition) {
export function transformDSL(definition: any): string {
let sb = "";
const eventState = new Map();
const states = definition["states"];
@ -173,4 +179,3 @@ ${sb}
`;
}
module.exports = { transformDSL };

View File

@ -2343,6 +2343,11 @@
jest-matcher-utils "^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":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"