updates to frontend-react
This commit is contained in:
24
Web/WebSocket/websocket/apps/frontend-react/.gitignore
vendored
Normal file
24
Web/WebSocket/websocket/apps/frontend-react/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
2
Web/WebSocket/websocket/apps/frontend-react/.npmrc
Normal file
2
Web/WebSocket/websocket/apps/frontend-react/.npmrc
Normal file
@@ -0,0 +1,2 @@
|
||||
save-exact=true
|
||||
package-lock=false
|
||||
1
Web/WebSocket/websocket/apps/frontend-react/.nvmrc
Normal file
1
Web/WebSocket/websocket/apps/frontend-react/.nvmrc
Normal file
@@ -0,0 +1 @@
|
||||
24
|
||||
12
Web/WebSocket/websocket/apps/frontend-react/.prettierrc
Normal file
12
Web/WebSocket/websocket/apps/frontend-react/.prettierrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSameLine": true,
|
||||
"bracketSpacing": false,
|
||||
"printWidth": 160,
|
||||
"semi": true,
|
||||
"singleAttributePerLine": false,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "none",
|
||||
"useTabs": false
|
||||
}
|
||||
73
Web/WebSocket/websocket/apps/frontend-react/README.md
Normal file
73
Web/WebSocket/websocket/apps/frontend-react/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# React + TypeScript + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||
|
||||
## React Compiler
|
||||
|
||||
The React Compiler is currently not compatible with SWC. See [this issue](https://github.com/vitejs/vite-plugin-react/issues/428) for tracking the progress.
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
|
||||
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
||||
|
||||
```js
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
extends: [
|
||||
// Other configs...
|
||||
|
||||
// Remove tseslint.configs.recommended and replace with this
|
||||
tseslint.configs.recommendedTypeChecked,
|
||||
// Alternatively, use this for stricter rules
|
||||
tseslint.configs.strictTypeChecked,
|
||||
// Optionally, add this for stylistic rules
|
||||
tseslint.configs.stylisticTypeChecked
|
||||
|
||||
// Other configs...
|
||||
],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||
tsconfigRootDir: import.meta.dirname
|
||||
}
|
||||
// other options...
|
||||
}
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
||||
|
||||
```js
|
||||
// eslint.config.js
|
||||
import reactX from 'eslint-plugin-react-x';
|
||||
import reactDom from 'eslint-plugin-react-dom';
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
extends: [
|
||||
// Other configs...
|
||||
// Enable lint rules for React
|
||||
reactX.configs['recommended-typescript'],
|
||||
// Enable lint rules for React DOM
|
||||
reactDom.configs.recommended
|
||||
],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||
tsconfigRootDir: import.meta.dirname
|
||||
}
|
||||
// other options...
|
||||
}
|
||||
}
|
||||
]);
|
||||
```
|
||||
18
Web/WebSocket/websocket/apps/frontend-react/eslint.config.js
Normal file
18
Web/WebSocket/websocket/apps/frontend-react/eslint.config.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import js from '@eslint/js';
|
||||
import globals from 'globals';
|
||||
import reactHooks from 'eslint-plugin-react-hooks';
|
||||
import reactRefresh from 'eslint-plugin-react-refresh';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import {defineConfig, globalIgnores} from 'eslint/config';
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
extends: [js.configs.recommended, tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser
|
||||
}
|
||||
}
|
||||
]);
|
||||
13
Web/WebSocket/websocket/apps/frontend-react/index.html
Normal file
13
Web/WebSocket/websocket/apps/frontend-react/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>frontend-react</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
36
Web/WebSocket/websocket/apps/frontend-react/package.json
Normal file
36
Web/WebSocket/websocket/apps/frontend-react/package.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "frontend-react",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "2.9.0",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-redux": "9.2.0",
|
||||
"styled-components": "6.1.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@techniker-me/websocket-shared-types": "*",
|
||||
"@types/react": "^19.1.13",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"@vitejs/plugin-react-swc": "^4.1.0",
|
||||
"babel-plugin-styled-components": "2.1.4",
|
||||
"babel-plugin-transform-amd-to-commonjs": "1.6.0",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"globals": "^16.4.0",
|
||||
"typescript": "~5.8.3",
|
||||
"typescript-eslint": "^8.44.0",
|
||||
"vite": "^7.1.7",
|
||||
"vite-plugin-babel": "1.3.2"
|
||||
}
|
||||
}
|
||||
10
Web/WebSocket/websocket/apps/frontend-react/src/App.tsx
Normal file
10
Web/WebSocket/websocket/apps/frontend-react/src/App.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import {LoginView} from './views';
|
||||
|
||||
export default function App() {
|
||||
console.log('APP')
|
||||
return (
|
||||
<>
|
||||
<LoginView />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface ILoginFormProps {
|
||||
onSubmit: (username: string, secret: string) => void;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { useState } from 'react';
|
||||
import ILoginFormPops from './ILoginFormProps';
|
||||
import { Input } from './Styled';
|
||||
|
||||
export function LoginForm({ onSubmit }: ILoginFormProps) {
|
||||
const [username, setUsername] = useState<string>('');
|
||||
const [secret, setSecret] = useState<string>('');
|
||||
|
||||
// The submit handler now correctly uses 'event'
|
||||
const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
onSubmit(username, secret);
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleFormSubmit}>
|
||||
{/*
|
||||
- The 'placeholder' prop is now lowercase.
|
||||
- The 'onChange' handler correctly destructures {target}.
|
||||
*/}
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
autoComplete="username"
|
||||
value={username}
|
||||
onChange={({ target }) => setUsername(target.value)}
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
autoComplete="current-password"
|
||||
value={secret}
|
||||
onChange={({ target }) => setSecret(target.value)}
|
||||
/>
|
||||
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const Input = styled.input`
|
||||
width: 100%;
|
||||
heght: 1.3rem;
|
||||
backgroundColor: blue
|
||||
`
|
||||
|
||||
export const Button = styled.button`
|
||||
width: fit-content;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
background-color: #a7c42;
|
||||
|
||||
`
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './ILoginFormProps';
|
||||
export * from './LoginForm';
|
||||
@@ -0,0 +1 @@
|
||||
export * from './LoginForm';
|
||||
68
Web/WebSocket/websocket/apps/frontend-react/src/index.css
Normal file
68
Web/WebSocket/websocket/apps/frontend-react/src/index.css
Normal file
@@ -0,0 +1,68 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
13
Web/WebSocket/websocket/apps/frontend-react/src/main.tsx
Normal file
13
Web/WebSocket/websocket/apps/frontend-react/src/main.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import {Provider} from 'react-redux';
|
||||
import store from './store';
|
||||
import App from './App.tsx';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<Provider store={store}>
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
</Provider>
|
||||
);
|
||||
@@ -0,0 +1,18 @@
|
||||
import {configureStore} from '@reduxjs/toolkit';
|
||||
import {userSlice} from './slices';
|
||||
|
||||
// Configure the main store
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
// Add the reducer from your slice to the store
|
||||
user: userSlice.reducer
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
||||
|
||||
// Type definition for the root state, can be used with useSelector hook
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
|
||||
// Type definition for dispatch, can be used with useDispatch hook
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
@@ -0,0 +1,40 @@
|
||||
import {createSlice, configureStore, PayloadAction} from '@reduxjs/toolkit';
|
||||
|
||||
interface IUserState {
|
||||
id: string | null;
|
||||
name: string | null;
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
const initialState: IUserState = {
|
||||
id: null,
|
||||
name: null,
|
||||
isLoading: false,
|
||||
error: null
|
||||
};
|
||||
|
||||
export const userSlice = createSlice({
|
||||
name: 'user', // A name for this slice, used in action types
|
||||
initialState,
|
||||
reducers: {
|
||||
// The key here becomes part of the action type: 'user/setUserLoading'
|
||||
setUserLoading(state, action: PayloadAction<boolean>) {
|
||||
// Redux Toolkit uses Immer, so you can "mutate" the state directly.
|
||||
// Immer handles the immutable update behind the scenes.
|
||||
state.isLoading = action.payload;
|
||||
},
|
||||
userFetchSuccess(state, action: PayloadAction<{id: string; name: string}>) {
|
||||
state.isLoading = false;
|
||||
state.id = action.payload.id;
|
||||
state.name = action.payload.name;
|
||||
state.error = null;
|
||||
},
|
||||
userFetchError(state, action: PayloadAction<string>) {
|
||||
state.isLoading = false;
|
||||
state.error = action.payload;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const {setUserLoading, userFetchSuccess, userFetchError} = userSlice.actions;
|
||||
@@ -0,0 +1 @@
|
||||
export * from './User.slice';
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
import {LoginForm} from '../../components';
|
||||
|
||||
export function LoginView() {
|
||||
const handleLoginSubmit = (username: string, secret: string) => {
|
||||
console.log('handling login submit username [%o] secret [%o]', username, secret)
|
||||
};
|
||||
|
||||
console.log('LoginView...')
|
||||
|
||||
return <>
|
||||
<LoginForm onSubmit={handleLoginSubmit} />
|
||||
</>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './LoginView';
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"types": ["vite/client"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [{"path": "./tsconfig.app.json"}, {"path": "./tsconfig.node.json"}]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2023",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"types": [],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
95
Web/WebSocket/websocket/apps/frontend-react/vite.config.ts
Normal file
95
Web/WebSocket/websocket/apps/frontend-react/vite.config.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import type {UserConfig} from 'vite';
|
||||
|
||||
import path from 'node:path';
|
||||
import {defineConfig} from 'vite';
|
||||
import VitePluginReact from '@vitejs/plugin-react-swc';
|
||||
import ViteBabelPlugin from 'vite-plugin-babel';
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig(({mode}) => {
|
||||
const isProductionMode = mode === 'production';
|
||||
|
||||
// optional: const modeDependentEnvironmentVariables = loadEnv(mode, process.cwd()); // https://vite.dev/config/#using-environment-variables-in-config
|
||||
return {
|
||||
define: {},
|
||||
root: path.resolve(process.cwd()),
|
||||
publicDir: 'public',
|
||||
cacheDir: 'node_modules/.vite', // default is `node_modules/.vite` <-- https://vite.dev/config/shared-options.html#cachedir
|
||||
base: '/',
|
||||
mode,
|
||||
resolve: {
|
||||
alias: {
|
||||
assets: path.resolve(process.cwd(), 'src/assets'),
|
||||
components: path.resolve(process.cwd(), 'src/components'),
|
||||
services: path.resolve(process.cwd(), 'src/services'),
|
||||
store: path.resolve(process.cwd(), 'src/store'),
|
||||
styles: path.resolve(process.cwd(), 'src/styles'),
|
||||
themes: path.resolve(process.cwd(), 'src/themes'),
|
||||
utils: path.resolve(process.cwd(), 'src/utils'),
|
||||
views: path.resolve(process.cwd(), 'src/views')
|
||||
},
|
||||
dedupe: [],
|
||||
conditions: ['module', 'browser', 'development|production'], // default is `['module', 'browser', 'development|production']`
|
||||
mainFields: ['browser', 'module'], // default is `['browser', 'module', 'jsnext:main', 'jsnext']`
|
||||
extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],
|
||||
preserveSymlinks: false // default is false
|
||||
},
|
||||
css: {
|
||||
modules: undefined, // default is `undefined`
|
||||
// postcss: {},
|
||||
devSourcemap: true, // default is `false` **experimental Vite feature**
|
||||
transformer: 'postcss' // default is `postcss` **experimental Vite feature**
|
||||
},
|
||||
json: {
|
||||
stringify: true // default is 'auto' // https://vite.dev/config/shared-options.html#json-stringify
|
||||
},
|
||||
esbuild: {
|
||||
jsxFactory: 'h',
|
||||
jsxFragment: 'Fragment',
|
||||
jsxInject: `import React from 'react'`
|
||||
},
|
||||
logLevel: 'debug', // default is `info`
|
||||
clearScreen: false, // default is `true`
|
||||
envDir: '.',
|
||||
appType: 'spa',
|
||||
server: {
|
||||
host: 'localhost',
|
||||
allowedHosts: ['localhost', '.phenixrts.com'],
|
||||
port: 5173,
|
||||
open: true,
|
||||
hmr: true,
|
||||
fs: {
|
||||
strict: true,
|
||||
deny: ['.env', '.env.*', '*.{crt,pem}', '**/.git/**'] // default is `['.env', '.env.*', '*.{crt,pem}', '**/.git/**']`
|
||||
}
|
||||
},
|
||||
build: {
|
||||
target: ['es2020', 'chrome80', 'firefox78', 'safari14'],
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets',
|
||||
assetsInlineLimit: 4096, // default is `4096` ~ 4KiB
|
||||
cssCodeSplit: true,
|
||||
minify: isProductionMode,
|
||||
cssMinify: isProductionMode,
|
||||
sourcemap: !isProductionMode,
|
||||
manifest: false, // default is `false`<-- https://vite.dev/config/build-options.html#build-manifest ,
|
||||
ssrManifest: false,
|
||||
ssr: false,
|
||||
emitAssets: false,
|
||||
terserOptions: {},
|
||||
emptyOutDir: true,
|
||||
copyPublicDir: true,
|
||||
reportCompressedSize: true,
|
||||
chunkSizeWarningLimit: 500,
|
||||
watch: null
|
||||
},
|
||||
plugins: [
|
||||
VitePluginReact(),
|
||||
ViteBabelPlugin({
|
||||
babelConfig: {
|
||||
plugins: ['transform-amd-to-commonjs', 'babel-plugin-styled-components']
|
||||
}
|
||||
})
|
||||
]
|
||||
} satisfies UserConfig;
|
||||
});
|
||||
1128
Web/WebSocket/websocket/bun.lock
Normal file
1128
Web/WebSocket/websocket/bun.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,16 +11,16 @@
|
||||
"build:types": "npm run build -w @techniker-me/websocket-shared-types",
|
||||
"dev": "npm run dev --workspaces --if-present",
|
||||
"dev:server": "npm run dev -w @techniker-me/websocket-server",
|
||||
"dev:frontend": "npm run dev -w @techniker-me/websocket-frontend",
|
||||
"dev:all": "concurrently \"npm run dev:server\" \"npm run dev:frontend\"",
|
||||
"dev:frontend:vanilla": "npm run dev -w @techniker-me/websocket-frontend",
|
||||
"clean": "npm run clean --workspaces --if-present",
|
||||
"lint": "npm run lint --workspaces --if-present",
|
||||
"typecheck": "npm run typecheck --workspaces --if-present",
|
||||
"start": "npm run build:types && npm run dev:all"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "5.9.2",
|
||||
"concurrently": "8.2.2"
|
||||
"concurrently": "8.2.2",
|
||||
"prettier": "3.6.2",
|
||||
"typescript": "5.9.2"
|
||||
},
|
||||
"author": "Alexander Zinn"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "~5.8.3"
|
||||
"typescript": "~5.9.2"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
@@ -39,3 +39,5 @@ export interface ExtendedWebSocket {
|
||||
isOpen(): boolean;
|
||||
isClosed(): boolean;
|
||||
}
|
||||
|
||||
export type Nullable<T> = T | null;
|
||||
|
||||
Reference in New Issue
Block a user