├── src
├── data
│ ├── colors.ts
│ └── examples.ts
├── shims-vue.d.ts
├── utils
│ ├── delay.ts
│ ├── formatter.ts
│ └── parser.ts
├── components
│ ├── QueueView.vue
│ ├── StackView.vue
│ ├── TerminalLog.vue
│ ├── Controls.vue
│ ├── CodeEditor.vue
│ ├── HelloWorld.vue
│ └── ExecutionVisualizer.vue
├── composables
│ ├── useAnimator.ts
│ ├── useParser.ts
│ └── useExecutionFlow.ts
├── vite-env.d.ts
├── main.ts
├── App.vue
├── store
│ └── execution.ts
├── assets
│ └── vue.svg
├── views
│ └── HomeView.vue
└── style.css
├── .vscode
└── extensions.json
├── tsconfig.json
├── vite.config.ts
├── .gitignore
├── index.html
├── tsconfig.app.json
├── README.md
├── tsconfig.node.json
├── package.json
└── public
└── vite.svg
/src/data/colors.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/utils/delay.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/data/examples.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/utils/formatter.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/utils/parser.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/QueueView.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/StackView.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/TerminalLog.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/composables/useAnimator.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import { createPinia } from 'pinia'
4 |
5 | import './style.css'
6 |
7 | const app = createApp(App)
8 | app.use(createPinia())
9 | app.mount('#app')
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "types": ["node"],
7 | "baseUrl": ".",
8 | "paths": {
9 | "@/*": ["src/*"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 | import { defineConfig } from 'vite'
3 | import vue from '@vitejs/plugin-vue'
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [vue()],
8 | resolve: {
9 | alias: {
10 | '@': fileURLToPath(new URL('./src', import.meta.url))
11 | }
12 | }
13 | })
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/store/execution.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 | import type { ExecutionStep } from '../composables/useExecutionFlow'
3 |
4 | export const useExecutionStore = defineStore('execution', {
5 | state: () => ({
6 | steps: [] as ExecutionStep[]
7 | }),
8 | actions: {
9 | setSteps(newSteps: ExecutionStep[]) {
10 | this.steps = newSteps
11 | }
12 | }
13 | })
14 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Vue + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/composables/useParser.ts:
--------------------------------------------------------------------------------
1 | import * as esprima from 'esprima'
2 |
3 | export function useParser() {
4 | const parseCodeToAST = (code: string) => {
5 | try {
6 | const ast = esprima.parseScript(code, { loc: true })
7 | return ast
8 | } catch (err) {
9 | console.error('Parsing error:', err)
10 | return null
11 | }
12 | }
13 |
14 | return {
15 | parseCodeToAST
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.dom.json",
3 | "compilerOptions": {
4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
5 |
6 | /* Linting */
7 | "strict": true,
8 | "noUnusedLocals": true,
9 | "noUnusedParameters": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noUncheckedSideEffectImports": true
12 | },
13 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
14 | }
15 |
--------------------------------------------------------------------------------
/src/assets/vue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | <<<<<<< HEAD
2 | # Vue 3 + TypeScript + Vite
3 |
4 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `
12 |
13 |
40 |
--------------------------------------------------------------------------------
/src/components/CodeEditor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
24 |
25 |
41 |
--------------------------------------------------------------------------------
/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | {{ msg }}
11 |
12 |
13 |
14 |
15 | Edit
16 | components/HelloWorld.vue to test HMR
17 |
18 |
19 |
20 |
21 | Check out
22 | create-vue, the official Vue + Vite starter
25 |
26 |
27 | Learn more about IDE Support for Vue in the
28 | Vue Docs Scaling up Guide.
33 |
34 | Click on the Vite and Vue logos to learn more
35 |
36 |
37 |
42 |
--------------------------------------------------------------------------------
/src/views/HomeView.vue:
--------------------------------------------------------------------------------
1 |
29 |
30 |
31 |
JS Execution Visualizer
32 |
33 |
34 |
35 |
36 |
37 |
43 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/composables/useExecutionFlow.ts:
--------------------------------------------------------------------------------
1 | import { Program, CallExpression } from 'estree'
2 |
3 | export interface ExecutionStep {
4 | type: 'callStack' | 'microtask' | 'macrotask' | 'log'
5 | label: string
6 | }
7 |
8 | export function useExecutionFlow() {
9 | const analyzeAST = (ast: Program): ExecutionStep[] => {
10 | const steps: ExecutionStep[] = []
11 |
12 | const walk = (node: any) => {
13 | if (!node) return
14 |
15 | switch (node.type) {
16 | case 'CallExpression': {
17 | const calleeName = node.callee?.name || ''
18 |
19 | if (calleeName === 'console') {
20 | steps.push({ type: 'log', label: 'console.log()' })
21 | } else if (calleeName === 'setTimeout') {
22 | steps.push({ type: 'macrotask', label: 'setTimeout()' })
23 | } else if (calleeName === 'Promise') {
24 | steps.push({ type: 'microtask', label: 'Promise.resolve()' })
25 | } else {
26 | steps.push({ type: 'callStack', label: `${calleeName}()` })
27 | }
28 |
29 | // recurse arguments
30 | node.arguments?.forEach(walk)
31 | break
32 | }
33 |
34 | case 'ExpressionStatement':
35 | case 'VariableDeclaration':
36 | case 'FunctionDeclaration':
37 | case 'BlockStatement':
38 | case 'Program': {
39 | Object.values(node.body || []).forEach(walk)
40 | break
41 | }
42 | }
43 | }
44 |
45 | walk(ast)
46 | return steps
47 | }
48 |
49 | return { analyzeAST }
50 | }
51 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | a {
17 | font-weight: 500;
18 | color: #646cff;
19 | text-decoration: inherit;
20 | }
21 | a:hover {
22 | color: #535bf2;
23 | }
24 |
25 | body {
26 | margin: 0;
27 | display: flex;
28 | place-items: center;
29 | min-width: 320px;
30 | min-height: 100vh;
31 | }
32 |
33 | h1 {
34 | font-size: 3.2em;
35 | line-height: 1.1;
36 | }
37 |
38 | button {
39 | border-radius: 8px;
40 | border: 1px solid transparent;
41 | padding: 0.6em 1.2em;
42 | font-size: 1em;
43 | font-weight: 500;
44 | font-family: inherit;
45 | background-color: #1a1a1a;
46 | cursor: pointer;
47 | transition: border-color 0.25s;
48 | }
49 | button:hover {
50 | border-color: #646cff;
51 | }
52 | button:focus,
53 | button:focus-visible {
54 | outline: 4px auto -webkit-focus-ring-color;
55 | }
56 |
57 | .card {
58 | padding: 2em;
59 | }
60 |
61 | #app {
62 | max-width: 1280px;
63 | margin: 0 auto;
64 | padding: 2rem;
65 | text-align: center;
66 | }
67 |
68 | @media (prefers-color-scheme: light) {
69 | :root {
70 | color: #213547;
71 | background-color: #ffffff;
72 | }
73 | a:hover {
74 | color: #747bff;
75 | }
76 | button {
77 | background-color: #f9f9f9;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/components/ExecutionVisualizer.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
📚 Call Stack
23 |
24 |
25 | {{ item.label }}
26 |
27 |
28 |
29 |
30 |
31 |
🧩 Microtask Queue
32 |
33 |
34 | {{ item.label }}
35 |
36 |
37 |
38 |
39 |
40 |
⏱ Macrotask Queue
41 |
42 |
43 | {{ item.label }}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
84 |
--------------------------------------------------------------------------------