Skip to content
Open
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
27 changes: 27 additions & 0 deletions .github/workflows/deploy-playground-react.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Deploy React Playground

on:
push:
branches:
- main
workflow_dispatch:

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
- run: bun install --frozen-lockfile
# Ensure comlink-worker-pool (dependency for the react hook) and the react hook itself are built
- run: bun run -F comlink-worker-pool build
- run: bun run -F comlink-worker-pool-react build
# Build the React playground
- run: bun run -F @comlink-worker-pool/playground-react build
- name: Deploy React Playground to GitHub Pages
id: deployment-react-playground # Changed ID as requested
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./packages/playground-react/dist # Updated publish_dir
repository: natanelia/comlink-plus # This should ideally be dynamic or checked if it's correct
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"playground:lint": "bun run -F comlink-worker-pool-playground lint",
"playground:build": "bun run -F comlink-worker-pool-playground build",
"playground:dev": "bun run -F comlink-worker-pool-playground dev",
"dev:react-playground": "bun --filter @comlink-worker-pool/playground-react dev",
"lint": "bun run -F comlink-worker-pool-react -F comlink-worker-pool lint",
"build": "bun run -F comlink-worker-pool-react -F comlink-worker-pool build",
"build:watch": "bun run -F comlink-worker-pool-react -F comlink-worker-pool build",
Expand Down
3 changes: 3 additions & 0 deletions packages/playground-react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Playground React

This package is a playground for React components.
12 changes: 12 additions & 0 deletions packages/playground-react/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Comlink Worker Pool React Playground</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
30 changes: 30 additions & 0 deletions packages/playground-react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@comlink-worker-pool/playground-react",
"private": true,
"scripts": {
"dev": "vite",
"dev:react": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "biome check ."
},
"dependencies": {
"react": "^19.1.0",
"react-dom": "^19.1.0",
"comlink": "^4.4.2",
"comlink-worker-pool": "workspace:packages/comlink-worker-pool",
"comlink-worker-pool-react": "*"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.4",
"@types/bun": "^1.2.10",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@vitejs/plugin-react": "^4.4.1",
"autoprefixer": "^10.4.21",
"oxlint": "^0.16.6",
"postcss": "^8.5.3",
"tailwindcss": "^4.1.4",
"vite": "^6.3.2"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as Comlink from "comlink";
import { WorkerPool, type WorkerPoolStats } from "comlink-worker-pool";
import { useWorkerPool } from "comlink-worker-pool-react";
import type { WorkerPoolStats } from "comlink-worker-pool";
import { useEffect, useRef, useState } from "react";
import "./index.css";

Expand All @@ -15,36 +16,18 @@ type WorkerApi = {
const proxyFactory = (worker: Worker) => Comlink.wrap<WorkerApi>(worker);

function App() {
const [pool, setPool] = useState<WorkerPool<WorkerApi> | null>(null);
const [inputNumber, setInputNumber] = useState(40);
const [taskCount, setTaskCount] = useState(10);
const [inputText, setInputText] = useState("");
const [reverseText, setReverseText] = useState("");
const [logs, setLogs] = useState<{ key: string; text: string }[]>([]);
const logsListRef = useRef<HTMLUListElement>(null);

useEffect(() => {
const size = navigator.hardwareConcurrency || 4;
const p = new WorkerPool<WorkerApi>({
size,
workerFactory,
proxyFactory,
onUpdateStats: setStats,
workerIdleTimeoutMs: 1000,
});
setPool(p);
setStats(p.getStats());
return () => {
p.terminateAll();
};
}, []);

const [stats, setStats] = useState<WorkerPoolStats>({
size: 0,
available: 0,
queue: 0,
workers: 0,
idleWorkers: 0,
const { pool, stats, setStats } = useWorkerPool<WorkerApi>({
size: navigator.hardwareConcurrency || 4,
workerFactory,
proxyFactory,
workerIdleTimeoutMs: 1000,
});

// Utility to format log messages
Expand Down Expand Up @@ -138,31 +121,31 @@ function App() {
<div className="flex flex-col items-center min-w-[70px]">
<span className="text-xs text-organic-300">Workers</span>
<span className="text-xl font-bold text-organic-300">
{stats.size}
{stats?.size ?? 0}
</span>
</div>
<div className="flex flex-col items-center min-w-[70px]">
<span className="text-xs text-organic-300">Available</span>
<span className="text-xl font-bold text-organic-300">
{stats.available}
{stats?.available ?? 0}
</span>
</div>
<div className="flex flex-col items-center min-w-[70px]">
<span className="text-xs text-organic-300">Queue</span>
<span className="text-xl font-bold text-organic-300">
{stats.queue}
{stats?.queue ?? 0}
</span>
</div>
<div className="flex flex-col items-center min-w-[70px]">
<span className="text-xs text-organic-300">Active Workers</span>
<span className="text-lg font-bold text-organic-300">
{stats.workers}
{stats?.workers ?? 0}
</span>
</div>
<div className="flex flex-col items-center min-w-[70px]">
<span className="text-xs text-organic-300">Idle Workers</span>
<span className="text-lg font-bold text-organic-300">
{stats.idleWorkers}
{stats?.idleWorkers ?? 0}
</span>
</div>
</div>
Expand Down
38 changes: 38 additions & 0 deletions packages/playground-react/src/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as Comlink from "comlink";

// CPU-intensive Fibonacci
function fib(n: number): number {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}

// simulate variable workload
function sleep(ms: number) {
return new Promise((res) => setTimeout(res, ms));
}

export async function fibAsync(n: number): Promise<number> {
if (typeof n !== "number") throw new Error("Input must be a number");
return fib(n);
}

// Example API methods for proxified callbacks
export async function countWords(text: string): Promise<number> {
// Simulate processing delay
const delay = Math.floor(Math.random() * 800) + 200;
await sleep(delay);
if (typeof text !== "string") throw new Error("Input must be a string");
return text.trim().split(/\s+/).filter(Boolean).length;
}

export async function reverseString(text: string): Promise<string> {
const delay = Math.floor(Math.random() * 800) + 200;
await sleep(delay);
if (typeof text !== "string") throw new Error("Input must be a string");
return text.split("").reverse().join("");
}

const api = { fibAsync, countWords, reverseString };
export type WorkerApi = typeof api;

Comlink.expose(api);
22 changes: 22 additions & 0 deletions packages/playground-react/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"types": ["bun-types"],
"outDir": "dist",
"declaration": true,
"declarationDir": "dist/types",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react-jsx",
"allowJs": true,
"checkJs": false,
"resolveJsonModule": true,
"isolatedModules": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
15 changes: 15 additions & 0 deletions packages/playground-react/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
base: '/comlink-plus/',
build: {
outDir: "./dist",
emptyOutDir: true,
},
server: {
open: true,
port: 5174,
},
plugins: [react()],
});
86 changes: 77 additions & 9 deletions packages/playground/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Comlink Worker Pool Playground</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<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>Comlink Worker Pool - Vanilla JS Playground</title>
<script type="module" src="/src/main.js"></script>
<style>
body { font-family: sans-serif; margin: 20px; background-color: #f0f0f0; }
.container { max-width: 800px; margin: auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
h1 { text-align: center; color: #333; }
.controls, .stats, .logs { margin-bottom: 20px; padding: 15px; border: 1px solid #ddd; border-radius: 4px; }
.controls h2, .stats h2, .logs h2 { margin-top: 0; color: #555; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="number"], input[type="text"] { width: calc(100% - 22px); padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; }
button { padding: 10px 15px; margin-right: 10px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
button:hover { background-color: #0056b3; }
#logsContainer { max-height: 300px; overflow-y: auto; background-color: #f9f9f9; padding: 10px; border: 1px solid #eee; }
.log-entry { margin-bottom: 5px; font-family: monospace; font-size: 0.9em; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 10px; }
.stat-item { background-color: #e9ecef; padding: 10px; border-radius: 4px; text-align: center; }
.stat-item .label { font-size: 0.8em; color: #666; }
.stat-item .value { font-size: 1.2em; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>Comlink Worker Pool - Vanilla JS Playground</h1>

<div class="controls">
<h2>Controls</h2>
<div>
<label for="taskCount">Tasks (parallel for all actions):</label>
<input type="number" id="taskCount" value="10" min="1" max="100">
</div>
</div>

<div class="stats">
<h2>Worker Pool Stats</h2>
<div class="stats-grid">
<div class="stat-item"><span class="label">Pool Size</span><div id="statSize" class="value">0</div></div>
<div class="stat-item"><span class="label">Available</span><div id="statAvailable" class="value">0</div></div>
<div class="stat-item"><span class="label">Queue</span><div id="statQueue" class="value">0</div></div>
<div class="stat-item"><span class="label">Active Workers</span><div id="statWorkers" class="value">0</div></div>
<div class="stat-item"><span class="label">Idle Workers</span><div id="statIdleWorkers" class="value">0</div></div>
</div>
</div>

<div class="controls">
<h2>Fibonacci Calculator</h2>
<label for="fibInput">Number (n):</label>
<input type="number" id="fibInput" value="40" min="1" max="100">
<button id="runFib">Calculate Fib (n)</button>
</div>

<div class="controls">
<h2>Word Counter</h2>
<label for="wordCountInput">Input Text:</label>
<input type="text" id="wordCountInput" placeholder="Type a sentence or paragraph...">
<button id="runCountWords">Count Words</button>
</div>

<div class="controls">
<h2>String Reverser</h2>
<label for="reverseStringInput">Input Text:</label>
<input type="text" id="reverseStringInput" placeholder="Type text to reverse...">
<button id="runReverseString">Reverse String</button>
</div>

<div class="logs">
<div style="display: flex; justify-content: space-between; align-items: center;">
<h2>Logs</h2>
<button id="clearLogs">Clear Logs</button>
</div>
<div id="logsContainer"></div>
</div>
</div>
</body>
</html>
5 changes: 0 additions & 5 deletions packages/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,12 @@
"lint": "biome check ."
},
"dependencies": {
"react": "^19.1.0",
"react-dom": "^19.1.0",
"comlink": "^4.4.2",
"comlink-worker-pool": "workspace:packages/comlink-worker-pool"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.4",
"@types/bun": "^1.2.10",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@vitejs/plugin-react": "^4.4.1",
"autoprefixer": "^10.4.21",
"oxlint": "^0.16.6",
"postcss": "^8.5.3",
Expand Down
Loading
Loading