From fef26c8421185ac51152197b3a1116b742b46b11 Mon Sep 17 00:00:00 2001 From: rahim Date: Mon, 9 Feb 2026 16:57:39 +1100 Subject: [PATCH] feat(sandbox): add private sandbox package for internal testing (#478) --- commitlint.config.js | 1 + packages/sandbox/.gitignore | 2 + packages/sandbox/package.json | 30 +++++++++ packages/sandbox/setup.ts | 26 ++++++++ packages/sandbox/src/index.html | 17 +++++ packages/sandbox/templates/core/index.html | 13 ++++ packages/sandbox/templates/core/main.ts | 3 + packages/sandbox/templates/html/index.html | 13 ++++ packages/sandbox/templates/html/main.ts | 18 ++++++ packages/sandbox/templates/react/index.html | 13 ++++ packages/sandbox/templates/react/main.tsx | 21 +++++++ packages/sandbox/templates/styles.css | 1 + packages/sandbox/tsconfig.json | 10 +++ packages/sandbox/vite.config.ts | 27 ++++++++ pnpm-lock.yaml | 69 ++++++++++++++++++++- 15 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 packages/sandbox/.gitignore create mode 100644 packages/sandbox/package.json create mode 100644 packages/sandbox/setup.ts create mode 100644 packages/sandbox/src/index.html create mode 100644 packages/sandbox/templates/core/index.html create mode 100644 packages/sandbox/templates/core/main.ts create mode 100644 packages/sandbox/templates/html/index.html create mode 100644 packages/sandbox/templates/html/main.ts create mode 100644 packages/sandbox/templates/react/index.html create mode 100644 packages/sandbox/templates/react/main.tsx create mode 100644 packages/sandbox/templates/styles.css create mode 100644 packages/sandbox/tsconfig.json create mode 100644 packages/sandbox/vite.config.ts diff --git a/commitlint.config.js b/commitlint.config.js index f5e52474..5300bb12 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -27,6 +27,7 @@ export default { 'react', 'rfc', 'root', + 'sandbox', 'site', 'store', 'test', diff --git a/packages/sandbox/.gitignore b/packages/sandbox/.gitignore new file mode 100644 index 00000000..c16e81c1 --- /dev/null +++ b/packages/sandbox/.gitignore @@ -0,0 +1,2 @@ +src/* +!src/index.html diff --git a/packages/sandbox/package.json b/packages/sandbox/package.json new file mode 100644 index 00000000..bc6d7c8d --- /dev/null +++ b/packages/sandbox/package.json @@ -0,0 +1,30 @@ +{ + "name": "@videojs/sandbox", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx setup.ts && vite", + "build": "tsx setup.ts && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@videojs/core": "workspace:*", + "@videojs/html": "workspace:*", + "@videojs/react": "workspace:*", + "@videojs/store": "workspace:*", + "@videojs/utils": "workspace:*" + }, + "devDependencies": { + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "@tailwindcss/vite": "^4.1.17", + "@vitejs/plugin-react": "^4.0.0", + "tailwindcss": "^4.1.17", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "tsx": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^6.0.0" + } +} diff --git a/packages/sandbox/setup.ts b/packages/sandbox/setup.ts new file mode 100644 index 00000000..5e687e09 --- /dev/null +++ b/packages/sandbox/setup.ts @@ -0,0 +1,26 @@ +import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs'; +import { resolve } from 'node:path'; + +const root = import.meta.dirname; +const templatesDir = resolve(root, 'templates'); +const srcDir = resolve(root, 'src'); + +function mirror(dir: string) { + for (const entry of readdirSync(dir)) { + const templatePath = resolve(dir, entry); + const targetPath = resolve(srcDir, templatePath.slice(templatesDir.length + 1)); + + if (statSync(templatePath).isDirectory()) { + mkdirSync(targetPath, { recursive: true }); + mirror(templatePath); + continue; + } + + if (!existsSync(targetPath)) { + copyFileSync(templatePath, targetPath); + console.log(`Created ${targetPath.slice(root.length + 1)}`); + } + } +} + +mirror(templatesDir); diff --git a/packages/sandbox/src/index.html b/packages/sandbox/src/index.html new file mode 100644 index 00000000..3d44cbce --- /dev/null +++ b/packages/sandbox/src/index.html @@ -0,0 +1,17 @@ + + + + + + Sandbox + + + +

Sandbox

+ + + diff --git a/packages/sandbox/templates/core/index.html b/packages/sandbox/templates/core/index.html new file mode 100644 index 00000000..b90c8272 --- /dev/null +++ b/packages/sandbox/templates/core/index.html @@ -0,0 +1,13 @@ + + + + + + Sandbox — Core + + + +
+ + + diff --git a/packages/sandbox/templates/core/main.ts b/packages/sandbox/templates/core/main.ts new file mode 100644 index 00000000..df3154ac --- /dev/null +++ b/packages/sandbox/templates/core/main.ts @@ -0,0 +1,3 @@ +// http://localhost:5173/core/ + +// import { } from '@videojs/core'; diff --git a/packages/sandbox/templates/html/index.html b/packages/sandbox/templates/html/index.html new file mode 100644 index 00000000..89b2c294 --- /dev/null +++ b/packages/sandbox/templates/html/index.html @@ -0,0 +1,13 @@ + + + + + + Sandbox — HTML + + + +
+ + + diff --git a/packages/sandbox/templates/html/main.ts b/packages/sandbox/templates/html/main.ts new file mode 100644 index 00000000..9fae361c --- /dev/null +++ b/packages/sandbox/templates/html/main.ts @@ -0,0 +1,18 @@ +// HTML sandbox — Web player (DOM/Browser) +// http://localhost:5173/html/ + +import { createPlayer, features, MediaElement } from '@videojs/html'; + +const { PlayerElement } = createPlayer({ + features: features.video, +}); + +customElements.define('video-player', PlayerElement); + +const html = String.raw; + +document.getElementById('root')!.innerHTML = html` + + + +`; diff --git a/packages/sandbox/templates/react/index.html b/packages/sandbox/templates/react/index.html new file mode 100644 index 00000000..72bb6f58 --- /dev/null +++ b/packages/sandbox/templates/react/index.html @@ -0,0 +1,13 @@ + + + + + + Sandbox — React + + + +
+ + + diff --git a/packages/sandbox/templates/react/main.tsx b/packages/sandbox/templates/react/main.tsx new file mode 100644 index 00000000..7e67d936 --- /dev/null +++ b/packages/sandbox/templates/react/main.tsx @@ -0,0 +1,21 @@ +// React sandbox — React player +// http://localhost:5173/react/ + +import { Container, createPlayer, features, Video } from '@videojs/react'; +import { createRoot } from 'react-dom/client'; + +const { Provider } = createPlayer({ + features: features.video, +}); + +function App() { + return ( + + + + + ); +} + +createRoot(document.getElementById('root')!).render(); diff --git a/packages/sandbox/templates/styles.css b/packages/sandbox/templates/styles.css new file mode 100644 index 00000000..f1d8c73c --- /dev/null +++ b/packages/sandbox/templates/styles.css @@ -0,0 +1 @@ +@import "tailwindcss"; diff --git a/packages/sandbox/tsconfig.json b/packages/sandbox/tsconfig.json new file mode 100644 index 00000000..221e6c92 --- /dev/null +++ b/packages/sandbox/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": false, + "noEmit": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/packages/sandbox/vite.config.ts b/packages/sandbox/vite.config.ts new file mode 100644 index 00000000..2e7b2fcd --- /dev/null +++ b/packages/sandbox/vite.config.ts @@ -0,0 +1,27 @@ +import { resolve } from 'node:path'; +import tailwindcss from '@tailwindcss/vite'; +import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + root: 'src', + plugins: [tailwindcss(), react()], + resolve: { + dedupe: ['react', 'react-dom'], + }, + optimizeDeps: { + exclude: ['@videojs/core', '@videojs/html', '@videojs/react', '@videojs/store', '@videojs/utils'], + }, + build: { + outDir: resolve(__dirname, 'dist'), + emptyOutDir: true, + rollupOptions: { + input: { + main: resolve(__dirname, 'src/index.html'), + core: resolve(__dirname, 'src/core/index.html'), + html: resolve(__dirname, 'src/html/index.html'), + react: resolve(__dirname, 'src/react/index.html'), + }, + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65e9b524..e720c7b4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -261,6 +261,55 @@ importers: specifier: ^3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.3)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + packages/sandbox: + dependencies: + '@videojs/core': + specifier: workspace:* + version: link:../core + '@videojs/html': + specifier: workspace:* + version: link:../html + '@videojs/react': + specifier: workspace:* + version: link:../react + '@videojs/store': + specifier: workspace:* + version: link:../store + '@videojs/utils': + specifier: workspace:* + version: link:../utils + devDependencies: + '@tailwindcss/vite': + specifier: ^4.1.17 + version: 4.1.18(vite@6.4.1(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@types/react': + specifier: ^18.0.0 + version: 18.3.27 + '@types/react-dom': + specifier: ^18.0.0 + version: 18.3.7(@types/react@18.3.27) + '@vitejs/plugin-react': + specifier: ^4.0.0 + version: 4.7.0(vite@6.4.1(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + react: + specifier: ^18.0.0 + version: 18.3.1 + react-dom: + specifier: ^18.0.0 + version: 18.3.1(react@18.3.1) + tailwindcss: + specifier: ^4.1.17 + version: 4.1.18 + tsx: + specifier: ^4.0.0 + version: 4.21.0 + typescript: + specifier: ^5.0.0 + version: 5.9.3 + vite: + specifier: ^6.0.0 + version: 6.4.1(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + packages/store: dependencies: '@videojs/utils': @@ -2646,6 +2695,11 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -8934,6 +8988,13 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 + '@tailwindcss/vite@4.1.18(vite@6.4.1(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@tailwindcss/node': 4.1.18 + '@tailwindcss/oxide': 4.1.18 + tailwindcss: 4.1.18 + vite: 6.4.1(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + '@tailwindcss/vite@4.1.18(vite@7.2.7(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@tailwindcss/node': 4.1.18 @@ -9101,6 +9162,10 @@ snapshots: '@types/prop-types@15.7.15': {} + '@types/react-dom@18.3.7(@types/react@18.3.27)': + dependencies: + '@types/react': 18.3.27 + '@types/react-dom@19.2.3(@types/react@19.2.7)': dependencies: '@types/react': 19.2.7 @@ -9313,7 +9378,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.3)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.3)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) '@vitest/utils@3.2.4': dependencies: @@ -13328,7 +13393,7 @@ snapshots: debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.2.7(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@22.19.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti