Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default {
testEnvironment: 'node',
testMatch: ['**/*.test.(ts|tsx)'],
transform: {
'^.+.tsx?$': ['ts-jest', {}],
},
};
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
"prepare": "husky",
"commit": "cz",
"e2e": "playwright test",
"e2e:ui": "playwright test --ui"
"e2e:ui": "playwright test --ui",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"dependencies": {
"@commitlint/cli": "^19.4.0",
Expand All @@ -25,8 +28,11 @@
"@eslint/js": "^9.9.1",
"@mui/icons-material": "^6.0.1",
"@mui/material": "^5.16.7",
"@types/eslint-scope": "^3.7.7",
"ace-builds": "^1.36.0",
"acorn": "^8.12.1",
"acorn-walk": "^8.3.4",
"eslint-scope": "^8.2.0",
"globals": "^15.9.0",
"react": "^18.3.1",
"react-ace": "^12.0.0",
Expand All @@ -38,6 +44,7 @@
"@playwright/test": "^1.48.2",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@types/jest": "^29.5.14",
"@types/node": "^22.9.0",
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.0",
Expand All @@ -52,9 +59,11 @@
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.11",
"husky": "^9.1.5",
"jest": "^29.7.0",
"lint-staged": "^15.2.9",
"prettier": "^3.3.3",
"semantic-release": "^24.1.0",
"ts-jest": "^29.2.5",
"typescript": "^5.5.4",
"vite": "^5.4.2"
},
Expand Down
6 changes: 3 additions & 3 deletions src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { StyledBox } from './Modal.styled.ts';

function InfoModal({
children,
isOpen,
isOpened,
onClose,
}: PropsWithChildren<{ isOpen: boolean; onClose: () => void }>) {
}: PropsWithChildren<{ isOpened: boolean; onClose: () => void }>) {
return (
<Modal
open={isOpen}
open={isOpened}
onClose={onClose}
sx={{
'&.MuiModal-root': {
Expand Down
2 changes: 1 addition & 1 deletion src/emotion.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ declare module '@emotion/react' {
disabled: string;
enabled: string;
};
task: {
macrotask: {
disabled: string;
enabled: string;
};
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/Home.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import TasksQueueBase from './sections/TasksQueue/TasksQueue.tsx';
import MicroTasksQueueBase from './sections/MicroTasksQueue/MicroTasksQueue.tsx';
import InfoBase from './sections/Info/Info.tsx';
import ConfiguratorBase from './sections/Configurator/Configurator.tsx';
import EventLoopBase from './sections/EventLoop/EventLoop.tsx';
import EventLoopBase from './sections/Wheel/Wheel.tsx';

export const Layout = styled.div`
flex: 1;
Expand Down
16 changes: 0 additions & 16 deletions src/pages/home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
import * as Styled from './Home.styled.ts';
import { useEventLoopAnimation } from '../../store/store.ts';
import { isMobile } from '../../utils/isMobile.ts';
import { useEffect } from 'react';
import { EVENT_LOOP_ID } from '../../utils/constants.ts';

export default function Home() {
const status = useEventLoopAnimation((state) => state.status);

useEffect(() => {
const eventLoopTitleDomNode = document.getElementById(EVENT_LOOP_ID);
if (isMobile() && status === 'running' && eventLoopTitleDomNode) {
eventLoopTitleDomNode.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
}
}, [status]);

return (
<Styled.Layout>
<Styled.Info />
Expand Down
44 changes: 44 additions & 0 deletions src/pages/home/sections/Callstack/Callstack.modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as Styled from './Callstack.styled.ts';
import InfoModal from 'components/Modal/Modal.tsx';

function CallStackModal({
isOpened,
toggle,
}: {
isOpened: boolean;
toggle: () => void;
}) {
return (
<InfoModal isOpened={isOpened} onClose={toggle}>
<h2>Call stack</h2>
<Styled.CloseIcon onClick={toggle} />
<p>
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.
</p>
<ul>
<li>
When a script calls a function, the interpreter adds it to the call
stack and then starts carrying out the function.
</li>
<li>
Any functions that are called by that function are added to the call
stack further up, and run where their calls are reached.
</li>
<li>
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.
</li>
<li>
If the stack takes up more space than it was assigned, a "stack
overflow" error is thrown.
</li>
</ul>
</InfoModal>
);
}

export default CallStackModal;
2 changes: 1 addition & 1 deletion src/pages/home/sections/Callstack/Callstack.styled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from '@emotion/styled';
import { css } from '@emotion/react';
import InfoClosed from '../../../../components/CloseIcon/InfoIcon.tsx';
import InfoClosed from 'components/CloseIcon/InfoIcon.tsx';

export const Callstack = styled.div`
flex: 1;
Expand Down
50 changes: 11 additions & 39 deletions src/pages/home/sections/Callstack/Callstack.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,26 @@
import { useEventLists } from '../../../../store/store.ts';
import * as Styled from './Callstack.styled.ts';
import InfoIcon from '../../../../components/InfoIcon/InfoIcon.tsx';
import InfoModal from '../../../../components/Modal/Modal.tsx';
import useBoolean from '../../../../utils/useBoolean.tsx';
import InfoIcon from 'components/InfoIcon/InfoIcon.tsx';
import useBoolean from 'utils/hooks/useBoolean.ts';
import { Zoom } from '@mui/material';
import { List } from '../../Home.styled.ts';
import CallStackModal from './Callstack.modal.tsx';
import { useQueueManagerStore } from 'store/store.ts';

function CallStack({ className }: { className?: string }) {
const tasks = useEventLists((state) => state.callstack);
const [open, setOpen, setClose] = useBoolean(false);
const tasks = useQueueManagerStore((state) => state.callstack);
const [isOpened, toggle] = useBoolean(false);

return (
<List className={className}>
<span>CallStack</span>
<Styled.Callstack>
<InfoIcon onClick={setOpen} />
{tasks.map(({ display: stack }) => (
<Zoom in key={stack}>
<Styled.CallstackElement>{stack}</Styled.CallstackElement>
<InfoIcon onClick={toggle} />
{tasks.map((task) => (
<Zoom in key={task}>
<Styled.CallstackElement>{task}</Styled.CallstackElement>
</Zoom>
))}
<InfoModal isOpen={open} onClose={setClose}>
<h2>Call stack</h2>
<Styled.CloseIcon onClick={setClose} />
<p>
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.
</p>
<ul>
<li>
When a script calls a function, the interpreter adds it to the
call stack and then starts carrying out the function.
</li>
<li>
Any functions that are called by that function are added to the
call stack further up, and run where their calls are reached.
</li>
<li>
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.
</li>
<li>
If the stack takes up more space than it was assigned, a "stack
overflow" error is thrown.
</li>
</ul>
</InfoModal>
<CallStackModal isOpened={isOpened} toggle={toggle} />
</Styled.Callstack>
</List>
);
Expand Down
34 changes: 15 additions & 19 deletions src/pages/home/sections/Configurator/Configurator.data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ foo1();`,
},
{
title: 'microtasks',
code: `console.log(1);
setTimeout(() => console.log(2), 0);
queueMicrotask(() => console.log(3));
code: `console.log(1);
setTimeout(() => console.log(2), 0);
queueMicrotask(() => console.log(3));
Promise.resolve().then(() => {
console.log(4);
});
setTimeout(() => console.log(5), 500);
});
setTimeout(() => console.log(5), 500);
console.log(6);`,
},
{
title: 'requestAnimationFrame',
code: `console.log(1);
queueMicrotask(() => console.log(2));
requestAnimationFrame(() => console.log(3));
requestAnimationFrame(() => console.log(4));
code: `console.log(1);
queueMicrotask(() => console.log(2));
requestAnimationFrame(() => console.log(3));
requestAnimationFrame(() => console.log(4));
console.log(5);`,
},
{
Expand All @@ -60,24 +60,20 @@ function foo3() {
setTimeout(() => {
foo4();
console.log('foo3:1');
}, 0);
queueMicrotask(() => console.log('foo3:2'));
}, 0);
queueMicrotask(() => console.log('foo3:2'));
Promise.resolve().then(() => {
console.log('foo3:3')
});
setTimeout(() => console.log('foo3:4'), 500);
});
setTimeout(() => console.log('foo3:4'), 500);
console.log('foo3:5');
}
function foo4() {
console.log('foo4');
}
function foo5(param1) {
console.log(param1);
}

console.log('global');
setTimeout(() => console.log('global:1'), 500);
foo1();
foo5('foo5:1');`,
setTimeout(() => console.log('global:1'), 500);
foo1();`,
},
];
2 changes: 0 additions & 2 deletions src/pages/home/sections/Configurator/Configurator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/theme-solarized_dark';
import * as Styled from './Configurator.styled.ts';
import { BaseLayoutElement } from '../../Home.styled.ts';
import Controls from './Controls/Controls.tsx';
Expand Down
Loading
Loading