diff --git a/packages/sdk/test-app/.eslintrc.cjs b/packages/sdk/test-app/.eslintrc.cjs new file mode 100644 index 0000000..d6c9537 --- /dev/null +++ b/packages/sdk/test-app/.eslintrc.cjs @@ -0,0 +1,18 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, +} diff --git a/packages/sdk/test-app/.gitignore b/packages/sdk/test-app/.gitignore index 4d29575..a547bf3 100644 --- a/packages/sdk/test-app/.gitignore +++ b/packages/sdk/test-app/.gitignore @@ -1,23 +1,24 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - +# 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? diff --git a/packages/sdk/test-app/README.md b/packages/sdk/test-app/README.md index ee39472..e1cdc89 100644 --- a/packages/sdk/test-app/README.md +++ b/packages/sdk/test-app/README.md @@ -1 +1,30 @@ -# Testing the typescript SDK in React +# 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/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default { + // other rules... + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + project: ['./tsconfig.json', './tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: __dirname, + }, +} +``` + +- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` +- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list diff --git a/packages/sdk/test-app/index.html b/packages/sdk/test-app/index.html new file mode 100644 index 0000000..e4b78ea --- /dev/null +++ b/packages/sdk/test-app/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/packages/sdk/test-app/package.json b/packages/sdk/test-app/package.json index 5592813..3eb638a 100644 --- a/packages/sdk/test-app/package.json +++ b/packages/sdk/test-app/package.json @@ -1,44 +1,24 @@ { - "name": "test-app", - "version": "0.1.0", + "name": "test-app-vite", "private": true, - "dependencies": { - "@clockworklabs/spacetimedb-sdk": "workspace:*", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.18.23", - "@types/react": "^18.0.31", - "@types/react-dom": "^18.0.11", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-scripts": "5.0.1", - "typescript": "^4.9.5", - "web-vitals": "^2.1.4" - }, + "version": "0.0.0", + "type": "module", "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1", + "@clockworklabs/spacetimedb-sdk": "workspace:*" }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.2.2", + "vite": "^5.3.4" } } diff --git a/packages/sdk/test-app/public/favicon.ico b/packages/sdk/test-app/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/packages/sdk/test-app/public/favicon.ico and /dev/null differ diff --git a/packages/sdk/test-app/public/index.html b/packages/sdk/test-app/public/index.html deleted file mode 100644 index aa069f2..0000000 --- a/packages/sdk/test-app/public/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - React App - - - -
- - - diff --git a/packages/sdk/test-app/public/logo192.png b/packages/sdk/test-app/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/packages/sdk/test-app/public/logo192.png and /dev/null differ diff --git a/packages/sdk/test-app/public/logo512.png b/packages/sdk/test-app/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/packages/sdk/test-app/public/logo512.png and /dev/null differ diff --git a/packages/sdk/test-app/public/manifest.json b/packages/sdk/test-app/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/packages/sdk/test-app/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/packages/sdk/test-app/public/robots.txt b/packages/sdk/test-app/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/packages/sdk/test-app/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/packages/sdk/test-app/src/App.css b/packages/sdk/test-app/src/App.css index 74b5e05..b9d355d 100644 --- a/packages/sdk/test-app/src/App.css +++ b/packages/sdk/test-app/src/App.css @@ -1,34 +1,24 @@ -.App { +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; text-align: center; } -.App-logo { - height: 40vmin; - pointer-events: none; +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; } - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); } - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); } -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { +@keyframes logo-spin { from { transform: rotate(0deg); } @@ -36,3 +26,17 @@ transform: rotate(360deg); } } + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/packages/sdk/test-app/src/App.tsx b/packages/sdk/test-app/src/App.tsx index b3393ee..44e98d9 100644 --- a/packages/sdk/test-app/src/App.tsx +++ b/packages/sdk/test-app/src/App.tsx @@ -1,15 +1,21 @@ -import React, { useEffect, useState } from "react"; import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; +import { useEffect, useState } from "react"; import "./App.css"; function App() { const [client] = useState( - new SpacetimeDBClient("localhost:3000", "goldbreezycanid", { - identity: - "49f2d472cabfbc7ded52ac1f93316750dc8ea162aac97cc52a340aed221b7ff3", - token: - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJoZXhfaWRlbnRpdHkiOiI0OWYyZDQ3MmNhYmZiYzdkZWQ1MmFjMWY5MzMxNjc1MGRjOGVhMTYyYWFjOTdjYzUyYTM0MGFlZDIyMWI3ZmYzIiwiaWF0IjoxNjgwMTkwNDc5fQ.KPz0DjrWb6I5c51wa71FGTgWz0Nh6CiNycM0ynmDDNkGjRxsci5cmiEjHQdYKyIeaG9MizSVPGlaDJ2Z7uctcg", - }) + new SpacetimeDBClient( + "localhost:3000", + "goldbreezycanid", + // @ts-ignore + // TODO: WHy are these not according to the types? + { + identity: + "49f2d472cabfbc7ded52ac1f93316750dc8ea162aac97cc52a340aed221b7ff3", + token: + "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJoZXhfaWRlbnRpdHkiOiI0OWYyZDQ3MmNhYmZiYzdkZWQ1MmFjMWY5MzMxNjc1MGRjOGVhMTYyYWFjOTdjYzUyYTM0MGFlZDIyMWI3ZmYzIiwiaWF0IjoxNjgwMTkwNDc5fQ.KPz0DjrWb6I5c51wa71FGTgWz0Nh6CiNycM0ynmDDNkGjRxsci5cmiEjHQdYKyIeaG9MizSVPGlaDJ2Z7uctcg", + } + ) ); useEffect(() => { diff --git a/packages/sdk/test-app/src/index.css b/packages/sdk/test-app/src/index.css index 4a1df4d..6119ad9 100644 --- a/packages/sdk/test-app/src/index.css +++ b/packages/sdk/test-app/src/index.css @@ -1,13 +1,68 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; +:root { + font-family: Inter, 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; } -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; +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; + } } diff --git a/packages/sdk/test-app/src/index.tsx b/packages/sdk/test-app/src/index.tsx deleted file mode 100644 index 368510c..0000000 --- a/packages/sdk/test-app/src/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import ReactDOM from "react-dom/client"; -import "./index.css"; -import App from "./App"; - -const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement -); -root.render(); diff --git a/packages/sdk/test-app/src/main.tsx b/packages/sdk/test-app/src/main.tsx new file mode 100644 index 0000000..3d7150d --- /dev/null +++ b/packages/sdk/test-app/src/main.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.tsx' +import './index.css' + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/packages/sdk/test-app/src/react-app-env.d.ts b/packages/sdk/test-app/src/react-app-env.d.ts deleted file mode 100644 index 6431bc5..0000000 --- a/packages/sdk/test-app/src/react-app-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/packages/sdk/test-app/src/vite-env.d.ts b/packages/sdk/test-app/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/packages/sdk/test-app/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/sdk/test-app/tsconfig.app.json b/packages/sdk/test-app/tsconfig.app.json new file mode 100644 index 0000000..d739292 --- /dev/null +++ b/packages/sdk/test-app/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/packages/sdk/test-app/tsconfig.json b/packages/sdk/test-app/tsconfig.json index 9d379a3..ea9d0cd 100644 --- a/packages/sdk/test-app/tsconfig.json +++ b/packages/sdk/test-app/tsconfig.json @@ -1,20 +1,11 @@ { - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" - }, - "include": ["src"] + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.node.json" + } + ] } diff --git a/packages/sdk/test-app/tsconfig.node.json b/packages/sdk/test-app/tsconfig.node.json new file mode 100644 index 0000000..3afdd6e --- /dev/null +++ b/packages/sdk/test-app/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true, + "noEmit": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/sdk/test-app/vite.config.ts b/packages/sdk/test-app/vite.config.ts new file mode 100644 index 0000000..5a33944 --- /dev/null +++ b/packages/sdk/test-app/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 27f429d..9ed04e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,67 @@ importers: '@clockworklabs/spacetimedb-sdk': specifier: workspace:* version: link:../../../packages/sdk + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@types/react': + specifier: ^18.3.3 + version: 18.3.3 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.3.1 + version: 4.3.1(vite@5.3.4(terser@5.31.2)) + typescript: + specifier: ^5.2.2 + version: 5.5.3 + vite: + specifier: ^5.3.4 + version: 5.3.4(terser@5.31.2) + + packages/sdk: + dependencies: + brotli: + specifier: 1.3.3 + version: 1.3.3 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + events: + specifier: ^3.3.0 + version: 3.3.0 + isomorphic-ws: + specifier: ^5.0.0 + version: 5.0.0(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + long: + specifier: ^5.2.3 + version: 5.2.3 + websocket: + specifier: ^1.0.34 + version: 1.0.35 + ws: + specifier: ^8.13.0 + version: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + devDependencies: + '@types/brotli': + specifier: 1.3.3 + version: 1.3.3 + '@types/websocket': + specifier: ^1.0.5 + version: 1.0.10 + + packages/sdk/test-app: + dependencies: + '@clockworklabs/spacetimedb-sdk': + specifier: workspace:* + version: link:.. '@testing-library/jest-dom': - specifier: ^5.17.0 + specifier: ^5.16.5 version: 5.17.0 '@testing-library/react': specifier: ^13.4.0 @@ -42,13 +101,13 @@ importers: specifier: ^27.5.2 version: 27.5.2 '@types/node': - specifier: ^16.18.38 + specifier: ^16.18.23 version: 16.18.101 '@types/react': - specifier: ^18.2.15 + specifier: ^18.0.31 version: 18.3.3 '@types/react-dom': - specifier: ^18.2.7 + specifier: ^18.0.11 version: 18.3.0 react: specifier: ^18.2.0 @@ -66,11 +125,11 @@ importers: specifier: ^2.1.4 version: 2.1.4 - examples/quickstart/client-vite: + packages/sdk/test-app-vite: dependencies: '@clockworklabs/spacetimedb-sdk': specifier: workspace:* - version: link:../../../packages/sdk + version: link:.. react: specifier: ^18.3.1 version: 18.3.1 @@ -94,37 +153,6 @@ importers: specifier: ^5.3.4 version: 5.3.4(terser@5.31.2) - packages/sdk: - dependencies: - brotli: - specifier: 1.3.3 - version: 1.3.3 - buffer: - specifier: ^6.0.3 - version: 6.0.3 - events: - specifier: ^3.3.0 - version: 3.3.0 - isomorphic-ws: - specifier: ^5.0.0 - version: 5.0.0(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - long: - specifier: ^5.2.3 - version: 5.2.3 - websocket: - specifier: ^1.0.34 - version: 1.0.35 - ws: - specifier: ^8.13.0 - version: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - devDependencies: - '@types/brotli': - specifier: 1.3.3 - version: 1.3.3 - '@types/websocket': - specifier: ^1.0.5 - version: 1.0.10 - packages: '@adobe/css-tools@4.4.0': @@ -4077,10 +4105,6 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - mime-db@1.53.0: - resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==} - engines: {node: '>= 0.6'} - mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} @@ -8728,7 +8752,7 @@ snapshots: compressible@2.0.18: dependencies: - mime-db: 1.53.0 + mime-db: 1.52.0 compression@1.7.4: dependencies: @@ -8971,7 +8995,7 @@ snapshots: debug@3.2.7: dependencies: - ms: 2.1.3 + ms: 2.1.2 debug@4.3.5: dependencies: @@ -10961,8 +10985,6 @@ snapshots: mime-db@1.52.0: {} - mime-db@1.53.0: {} - mime-types@2.1.35: dependencies: mime-db: 1.52.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7f60d48..b931775 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,5 @@ packages: - "packages/*" - "examples/**" - - "tests/**/*" + - "packages/sdk/test-app" + - "packages/sdk/test-app-vite"