diff --git a/CHANGELOG.md b/CHANGELOG.md index 185de91..e069840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,8 @@ ## [1.9.3](https://github.com/vault-developer/event-loop-explorer/compare/v1.9.2...v1.9.3) (2024-11-22) - ### Bug Fixes -* update isMobile function ([ed15f5e](https://github.com/vault-developer/event-loop-explorer/commit/ed15f5e9a34b3c183317c20f1a0fbea9b159e3e8)) +- update isMobile function ([ed15f5e](https://github.com/vault-developer/event-loop-explorer/commit/ed15f5e9a34b3c183317c20f1a0fbea9b159e3e8)) ## [1.9.2](https://github.com/vault-developer/event-loop-explorer/compare/v1.9.1...v1.9.2) (2024-10-30) diff --git a/src/App.tsx b/src/App.tsx index 110dfc9..d444fe2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,66 +1,10 @@ -import * as Styled from './App.styled.ts'; -import CallStack from './components/Callstack/Callstack.tsx'; -import Console from './components/Console/Console.tsx'; -import Editor from './components/Editor/Editor.tsx'; -import EventLoop from './components/EventLoop/EventLoop.tsx'; -import MicroTasksQueue from './components/MicroTasksQueue/MicroTasksQueue.tsx'; -import RequestAnimationFrameQueue from './components/RenderCallbacksQueue/RequestAnimationFrameQueue.tsx'; -import TasksQueue from './components/TasksQueue/TasksQueue.tsx'; -import WebApiQueue from './components/WebApiQueue/WebApiQueue.tsx'; import StylesProvider from './providers/StylesProvider.tsx'; +import Home from './pages/home/Home.tsx'; function App() { return ( - - -

Event Loop Explorer

-

- If you enjoy this project, please ⭐ it on{' '} - - GitHub - - ! -

-
- - - - - Web api - - - - RequestAnimationFrame callbacks - - - - CallStack - - - - Console - - - - Tasks Queue - - - - Microtasks Queue - - - -

Event Loop

- - - -
-
+
); } diff --git a/src/components/Callstack/Callstack.tsx b/src/components/Callstack/Callstack.tsx deleted file mode 100644 index e2aec2d..0000000 --- a/src/components/Callstack/Callstack.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { useEventLists } from '../../store/store.ts'; -import * as Styled from './Callstack.styled.ts'; -import InfoIcon from '../InfoIcon/InfoIcon.tsx'; -import InfoModal from '../Modal/Modal.tsx'; -import useBoolean from '../../utils/useBoolean.tsx'; -import { Zoom } from '@mui/material'; - -function CallStack() { - const tasks = useEventLists((state) => state.callstack); - const [open, setOpen, setClose] = useBoolean(false); - - return ( - - - {tasks.map(({ display: stack }) => ( - - {stack} - - ))} - -

Call stack

- -

- A call stack is a mechanism for an interpreter to keep track of its - place in a script that calls multiple functions — what function is - currently being run and what functions are called from within that - function, etc. -

-
    -
  • - When a script calls a function, the interpreter adds it to the call - stack and then starts carrying out the function. -
  • -
  • - Any functions that are called by that function are added to the call - stack further up, and run where their calls are reached. -
  • -
  • - When the current function is finished, the interpreter takes it off - the stack and resumes execution where it left off in the last code - listing. -
  • -
  • - If the stack takes up more space than it was assigned, a "stack - overflow" error is thrown. -
  • -
-
-
- ); -} - -export default CallStack; diff --git a/src/components/Console/Console.tsx b/src/components/Console/Console.tsx deleted file mode 100644 index 320333f..0000000 --- a/src/components/Console/Console.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useEventLists } from '../../store/store.ts'; -import * as Styled from './Console.styled.ts'; -import { Zoom } from '@mui/material'; - -function Console() { - const tasks = useEventLists((state) => state.console); - - return ( - - {tasks.map((log, i) => ( - - {log} - - ))} - - ); -} - -export default Console; diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx deleted file mode 100644 index 6c319ea..0000000 --- a/src/components/Editor/Editor.tsx +++ /dev/null @@ -1,215 +0,0 @@ -import PauseIcon from '@mui/icons-material/Pause'; -import PlayArrowIcon from '@mui/icons-material/PlayArrow'; -import StopIcon from '@mui/icons-material/Stop'; -import { - FormControl, - InputLabel, - MenuItem, - Select, - SelectChangeEvent, - Slider, -} from '@mui/material'; -import 'ace-builds/src-noconflict/mode-javascript'; -import 'ace-builds/src-noconflict/theme-solarized_dark'; -import { useEffect, useRef, useState } from 'react'; -import AceEditor from 'react-ace'; -import { - useEditor, - useEventLists, - useEventLoopAnimation, - useSpeedFactor, -} from '../../store/store.ts'; -import { isMobile } from '../../utils/isMobile.ts'; -import { parse } from '../../utils/parse.ts'; -import { codeExamples } from './Editor.data.tsx'; -import * as Styled from './Editor.styled.ts'; - -const codeByTitle = codeExamples.reduce( - (acc, { title, code }) => { - acc[title] = code; - return acc; - }, - {} as Record -); - -function EditorComponent() { - const [text, setText] = useState(codeExamples[3].code); - const eventListsStateSet = useEventLists((state) => state.set); - const eventListsStateClear = useEventLists((state) => state.clear); - const clearAnimationState = useEventLoopAnimation((state) => state.clear); - const setAnimationState = useEventLoopAnimation((state) => state.setState); - const status = useEventLoopAnimation((state) => state.status); - const [example, setExample] = useState(codeExamples[3].title); - const speedFactorState = useSpeedFactor((state) => state); - const setEditorRef = useEditor((state) => state.setRef); - const setSourceCode = useEditor((state) => state.setSource); - const clearEditor = useEditor((state) => state.clearEditor); - const editorRef = useRef(null); - - const onSelect = (e: SelectChangeEvent) => { - const example = e.target.value; - const code = codeByTitle[example]; - setText(code); - setExample(example); - }; - - const onStop = () => { - clearAnimationState(); - eventListsStateClear(); - clearEditor(); - }; - - const onPause = () => { - setAnimationState('paused', 'status'); - }; - - const onResume = () => { - setAnimationState('running', 'status'); - }; - - const onRun = () => { - clearAnimationState(); - eventListsStateClear(); - const script = parse(text); - setSourceCode(text); - eventListsStateSet({ - list: 'task_queue', - type: 'push', - value: script, - }); - setAnimationState('running', 'status'); - }; - - const onSpeedChange = (_: Event, value: number | number[]) => { - const num = Array.isArray(value) ? value[0] : value; - const res = num >= 0 ? num + 1 : 1 / (1 - num); - speedFactorState.setSpeed(res); - }; - - const speed = - speedFactorState.speed >= 1 - ? speedFactorState.speed - 1 - : 1 - 1 / speedFactorState.speed; - - useEffect(() => { - if (editorRef.current) { - setEditorRef(editorRef); - } - }, []); - - useEffect(() => { - if ( - isMobile() && - status === 'running' && - document.getElementById('eventLoop') - ) { - document.getElementById('eventLoop')?.scrollIntoView({ - behavior: 'smooth', - block: 'start', - }); - } - }, [status]); - - return ( - - - {status === 'disabled' && ( - <> - - - example: - - - - - - run - - - )} - {status !== 'disabled' && ( - <> - -
- speed: {Math.round(speedFactorState.speed * 100)}% -
- -
- - - - stop - - - {status === 'paused' && ( - - - resume - - )} - - {status === 'running' && ( - - - pause - - )} - - - )} -
- - - -
- ); -} - -export default EditorComponent; diff --git a/src/components/EventLoop/EventLoop.tsx b/src/components/EventLoop/EventLoop.tsx deleted file mode 100644 index 1498377..0000000 --- a/src/components/EventLoop/EventLoop.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import Pointer from './Pointer/Pointer.tsx'; -import { useEventLoopAnimation } from '../../store/store.ts'; -import CircleLabels from './CircleLabels/CircleLabels.tsx'; -import { events } from './EventLoop.data.ts'; -import * as Styled from './EventLoop.styled.ts'; -import { useTheme } from '@emotion/react'; -import InfoIcon from '../InfoIcon/InfoIcon.tsx'; -import InfoModal from '../Modal/Modal.tsx'; -import useBoolean from '../../utils/useBoolean.tsx'; - -function EventLoop() { - const animation = useEventLoopAnimation((state) => state); - const theme = useTheme(); - const [open, setOpen, setClose] = useBoolean(false); - - return ( - <> - - - - {events.map(({ degree, type }) => { - const enabled = animation[type] ? 'enabled' : 'disabled'; - const background = theme.custom.colors.wheel[type][enabled]; - return ( - - ); - })} - - - - - -

Event Loop

- -

- The event loop is a fundamental concept in browser that manages the - execution of code, handling of events, and updating of the user - interface. -

-

- The event loop continuously checks for and processes events and queued - tasks in a specific order: -

-
    -
  1. Execute all synchronous code in the call stack
  2. -
  3. - Check the microtask queue (e.g., Promise callbacks) and execute all - tasks. -
  4. -
  5. - Check the macrotask queue (e.g., setTimeout, DOM events) and execute - one task. -
  6. -
  7. Update the rendering if necessary.
  8. -
  9. Repeat the process.
  10. -
-
- - ); -} - -export default EventLoop; diff --git a/src/components/MicroTasksQueue/MicroTasksQueue.tsx b/src/components/MicroTasksQueue/MicroTasksQueue.tsx deleted file mode 100644 index 43541ea..0000000 --- a/src/components/MicroTasksQueue/MicroTasksQueue.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useEventLists } from '../../store/store.ts'; -import * as Styled from './MicroTasksQueue.styled.ts'; -import InfoIcon from '../InfoIcon/InfoIcon.tsx'; -import InfoModal from '../Modal/Modal.tsx'; -import useBoolean from '../../utils/useBoolean.tsx'; -import { Zoom } from '@mui/material'; - -function MicroTasksQueue() { - const tasks = useEventLists((state) => state.microtask_queue); - const [open, setOpen, setClose] = useBoolean(false); - - return ( - - - {tasks.map((task) => { - const serialized = task.serialize(); - const key = serialized + task.node.start; - return ( - - {serialized} - - ); - })} - -

Microtasks

- -

- A microtask is a short function which is executed after the function - or program which created it exits and only if the JavaScript execution - stack is empty, but before returning control to the event loop being - used by the user agent to drive the script's execution environment. -

-

Events that can trigger new microtasks:

-
    -
  • Promise resolution (.then(), .catch(), .finally())
  • -
  • Occurrence of observed DOM changes
  • -
  • queueMicrotask() method
  • -
-
-
- ); -} - -export default MicroTasksQueue; diff --git a/src/components/RenderCallbacksQueue/RequestAnimationFrameQueue.tsx b/src/components/RenderCallbacksQueue/RequestAnimationFrameQueue.tsx deleted file mode 100644 index ab82175..0000000 --- a/src/components/RenderCallbacksQueue/RequestAnimationFrameQueue.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useEventLists } from '../../store/store.ts'; -import * as Styled from './RequestAnimationFrameQueue.styled.ts'; -import InfoIcon from '../InfoIcon/InfoIcon.tsx'; -import InfoModal from '../Modal/Modal.tsx'; -import useBoolean from '../../utils/useBoolean.tsx'; -import { Zoom } from '@mui/material'; - -function RequestAnimationFrameQueue() { - const callbacks = useEventLists((state) => state.render_callbacks); - const [open, setOpen, setClose] = useBoolean(false); - - return ( - - - {callbacks.map((callback) => { - const serialized = callback.serialize(); - const key = serialized + callback.node.start; - return ( - - {serialized} - - ); - })} - -

RequestAnimationFrame

- -

- The window.requestAnimationFrame() method tells the browser you wish - to perform an animation. It requests the browser to call a - user-supplied callback function before the next repaint. -

-

- The frequency of calls to the callback function will generally match - the display refresh rate. The most common refresh rate is 60hz, (60 - cycles/frames per second), though 75hz, 120hz, and 144hz are also - widely used. -

-

- requestAnimationFrame() calls are paused in most browsers when running - in background tabs or hidden iframes, in order to improve performance - and battery life. -

-
-
- ); -} - -export default RequestAnimationFrameQueue; diff --git a/src/components/TasksQueue/TasksQueue.tsx b/src/components/TasksQueue/TasksQueue.tsx deleted file mode 100644 index fdde009..0000000 --- a/src/components/TasksQueue/TasksQueue.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { useEventLists } from '../../store/store.ts'; -import * as Styled from './TasksQueue.styled.ts'; -import InfoIcon from '../InfoIcon/InfoIcon.tsx'; -import InfoModal from '../Modal/Modal.tsx'; -import useBoolean from '../../utils/useBoolean.tsx'; -import { Zoom } from '@mui/material'; - -function TasksQueue() { - const tasks = useEventLists((state) => state.task_queue); - const [open, setOpen, setClose] = useBoolean(false); - - return ( - - - {tasks.map((task) => { - const serialized = task.serialize(); - const key = serialized + task.node.start; - return ( - - {serialized} - - ); - })} - -

Tasks

- -

- A task is anything which is scheduled to be run by the standard - mechanisms such as initially starting to run a program, an event being - dispatched asynchronously, or an interval or timeout being fired. - These all get scheduled on the task queue. -

-

- For example, tasks get added to the task queue when: -

-
    -
  • - A new JavaScript program or subprogram is executed (such as from a - console, or by running the code in a {'