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
57 changes: 57 additions & 0 deletions examples/comparisons/01-basic-await-comparison.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env node
/**
* Basic Await Pattern: Node.js vs Bun.js Comparison
*
* This example demonstrates the classic await pattern working
* identically in both Node.js and Bun.js runtimes.
*/

import { $ } from '../../src/$.mjs';

// Runtime detection
const runtime = typeof globalThis.Bun !== 'undefined' ? 'Bun' : 'Node.js';
console.log(`πŸš€ Running with ${runtime}`);
console.log('=' .repeat(50));

async function basicAwaitComparison() {
try {
console.log('1️⃣ Basic Command Execution:');
const result1 = await $`echo "Hello from ${runtime}!"`;
console.log(` Output: ${result1.stdout.trim()}`);
console.log(` Exit Code: ${result1.code}`);

console.log('\n2️⃣ File System Operations (Built-in Commands):');
const result2 = await $`mkdir -p temp-${runtime.toLowerCase()}`;
console.log(` Directory created: ${result2.code === 0 ? 'βœ…' : '❌'}`);

const result3 = await $`ls -la temp-${runtime.toLowerCase()}`;
console.log(` Directory listing: ${result3.code === 0 ? 'βœ…' : '❌'}`);

console.log('\n3️⃣ Pipeline Operations:');
const result4 = await $`echo "1\n2\n3" | wc -l`;
console.log(` Line count: ${result4.stdout.trim()}`);

console.log('\n4️⃣ Built-in Command Chains:');
const result5 = await $`seq 1 3 | cat`;
console.log(` Sequence: ${result5.stdout.trim().replace(/\n/g, ', ')}`);

console.log('\n5️⃣ Error Handling:');
try {
await $`sh -c 'exit 42'`;
} catch (error) {
console.log(` Caught error with code: ${error.code} βœ…`);
}

// Cleanup
await $`rm -rf temp-${runtime.toLowerCase()}`;

console.log('\n' + '=' .repeat(50));
console.log(`βœ… All basic await patterns work perfectly in ${runtime}!`);

} catch (error) {
console.error(`❌ Error in ${runtime}:`, error.message);
process.exit(1);
}
}

basicAwaitComparison();
77 changes: 77 additions & 0 deletions examples/comparisons/02-async-iteration-comparison.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env node
/**
* Async Iteration Pattern: Node.js vs Bun.js Comparison
*
* This example demonstrates real-time streaming with async iteration
* working identically in both Node.js and Bun.js runtimes.
*/

import { $ } from '../../src/$.mjs';

// Runtime detection
const runtime = typeof globalThis.Bun !== 'undefined' ? 'Bun' : 'Node.js';
console.log(`πŸš€ Running with ${runtime}`);
console.log('=' .repeat(50));

async function asyncIterationComparison() {
try {
console.log('1️⃣ Real-time Streaming with Built-in Commands:');
let chunkCount = 0;

for await (const chunk of $`seq 1 5`.stream()) {
if (chunk.type === 'stdout') {
chunkCount++;
console.log(` Chunk ${chunkCount}: ${chunk.data.toString().trim()}`);
}
}

console.log('\n2️⃣ Streaming with System Commands:');
let eventCount = 0;

// Use a command that produces output with delays
for await (const chunk of $`sh -c 'for i in A B C; do echo "Event $i"; sleep 0.1; done'`.stream()) {
if (chunk.type === 'stdout') {
eventCount++;
console.log(` ${runtime} Event ${eventCount}: ${chunk.data.toString().trim()}`);
}
}

console.log('\n3️⃣ Pipeline Streaming:');
let pipelineEvents = 0;

for await (const chunk of $`echo -e "red\ngreen\nblue" | cat`.stream()) {
if (chunk.type === 'stdout') {
pipelineEvents++;
console.log(` Pipeline ${pipelineEvents}: ${chunk.data.toString().trim()}`);
}
}

console.log('\n4️⃣ Mixed Streaming (stdout + stderr):');
let mixedCount = 0;

for await (const chunk of $`sh -c 'echo "stdout message"; echo "stderr message" >&2'`.stream()) {
mixedCount++;
console.log(` ${chunk.type.toUpperCase()}: ${chunk.data.toString().trim()}`);
}

console.log('\n5️⃣ Large Output Streaming:');
let largeCount = 0;

for await (const chunk of $`seq 1 10`.stream()) {
if (chunk.type === 'stdout') {
largeCount++;
}
}
console.log(` Processed ${largeCount} chunks from large output`);

console.log('\n' + '=' .repeat(50));
console.log(`βœ… All async iteration patterns work perfectly in ${runtime}!`);
console.log(` Total chunks processed: ${chunkCount + eventCount + pipelineEvents + mixedCount + largeCount}`);

} catch (error) {
console.error(`❌ Error in ${runtime}:`, error.message);
process.exit(1);
}
}

asyncIterationComparison();
101 changes: 101 additions & 0 deletions examples/comparisons/03-eventemitter-comparison.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env node
/**
* EventEmitter Pattern: Node.js vs Bun.js Comparison
*
* This example demonstrates event-driven command execution
* working identically in both Node.js and Bun.js runtimes.
*/

import { $ } from '../../src/$.mjs';

// Runtime detection
const runtime = typeof globalThis.Bun !== 'undefined' ? 'Bun' : 'Node.js';
console.log(`πŸš€ Running with ${runtime}`);
console.log('=' .repeat(50));

async function eventEmitterComparison() {
try {
console.log('1️⃣ Basic Event Handling:');

const cmd1 = $`echo "Testing events in ${runtime}"`
.on('data', (chunk) => {
console.log(` πŸ“₯ Data: ${chunk.data.toString().trim()}`);
})
.on('end', (result) => {
console.log(` 🏁 End: Exit code ${result.code}`);
});

await cmd1;

console.log('\n2️⃣ Multiple Event Listeners:');

let dataEvents = 0;
let stderrEvents = 0;

const cmd2 = $`sh -c 'echo "stdout"; echo "stderr" >&2; echo "more stdout"'`
.on('data', (chunk) => {
dataEvents++;
console.log(` πŸ“¨ ${chunk.type}: ${chunk.data.toString().trim()}`);
})
.on('stderr', (chunk) => {
stderrEvents++;
console.log(` 🚨 Stderr: ${chunk.toString().trim()}`);
})
.on('exit', (code) => {
console.log(` πŸšͺ Exit: Code ${code}`);
});

await cmd2;
console.log(` Events captured: ${dataEvents} data, ${stderrEvents} stderr`);

console.log('\n3️⃣ Pipeline Event Handling:');

let pipelineEvents = 0;

const cmd3 = $`seq 1 3 | cat`
.on('data', (chunk) => {
if (chunk.type === 'stdout') {
pipelineEvents++;
console.log(` πŸ”— Pipeline: ${chunk.data.toString().trim()}`);
}
});

await cmd3;
console.log(` Pipeline events: ${pipelineEvents}`);

console.log('\n4️⃣ Error Event Handling:');

try {
const cmd4 = $`sh -c 'echo "before error"; exit 1; echo "after error"'`
.on('data', (chunk) => {
console.log(` πŸ“ Before error: ${chunk.data.toString().trim()}`);
})
.on('error', (error) => {
console.log(` ⚠️ Error event: ${error.message}`);
});

await cmd4;
} catch (error) {
console.log(` βœ… Caught error: Code ${error.code}`);
}

console.log('\n5️⃣ Mixed Pattern (Events + Await):');

const mixedCmd = $`echo "Mixed pattern works in ${runtime}"`
.on('data', (chunk) => {
console.log(` πŸ”„ Real-time: ${chunk.data.toString().trim()}`);
});

const result = await mixedCmd;
console.log(` πŸ“Š Final result: ${result.stdout.trim()}`);

console.log('\n' + '=' .repeat(50));
console.log(`βœ… All EventEmitter patterns work perfectly in ${runtime}!`);

} catch (error) {
console.error(`❌ Error in ${runtime}:`, error.message);
process.exit(1);
}
}

eventEmitterComparison();
101 changes: 101 additions & 0 deletions examples/comparisons/04-streaming-stdin-comparison.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env node
/**
* Streaming STDIN Control: Node.js vs Bun.js Comparison
*
* This example demonstrates real-time stdin control and streaming interfaces
* working identically in both Node.js and Bun.js runtimes.
*/

import { $ } from '../../src/$.mjs';

// Runtime detection
const runtime = typeof globalThis.Bun !== 'undefined' ? 'Bun' : 'Node.js';
console.log(`πŸš€ Running with ${runtime}`);
console.log('=' .repeat(50));

async function streamingStdinComparison() {
try {
console.log('1️⃣ Basic STDIN Control:');

const catCmd = $`cat`;

// Start the command
catCmd.start();

// Wait a moment for process to spawn
await new Promise(resolve => setTimeout(resolve, 50));

// Access stdin stream
const stdin = await catCmd.streams.stdin;
if (stdin) {
stdin.write(`Hello from ${runtime}!\n`);
stdin.write('Multiple lines work perfectly!\n');
stdin.end();
}

const result = await catCmd;
console.log(` Output: ${result.stdout.trim()}`);

console.log('\n2️⃣ Interactive Command Control:');

const grepCmd = $`grep "important"`;
const grepStdin = await grepCmd.streams.stdin;

if (grepStdin) {
grepStdin.write('ignore this line\n');
grepStdin.write('important message here\n');
grepStdin.write('skip this too\n');
grepStdin.write('another important note\n');
grepStdin.end();
}

const grepResult = await grepCmd;
console.log(` Filtered output:\n${grepResult.stdout}`);

console.log('\n3️⃣ Sort Command with STDIN:');

const sortCmd = $`sort -r`;
const sortStdin = await sortCmd.streams.stdin;

if (sortStdin) {
sortStdin.write('zebra\n');
sortStdin.write('apple\n');
sortStdin.write('banana\n');
sortStdin.end();
}

const sortResult = await sortCmd;
console.log(` Sorted (reverse): ${sortResult.stdout.trim()}`);

console.log('\n4️⃣ Pipeline with STDIN:');

const pipelineCmd = $`cat | wc -l`;
const pipelineStdin = await pipelineCmd.streams.stdin;

if (pipelineStdin) {
pipelineStdin.write('line 1\n');
pipelineStdin.write('line 2\n');
pipelineStdin.write('line 3\n');
pipelineStdin.end();
}

const pipelineResult = await pipelineCmd;
console.log(` Line count: ${pipelineResult.stdout.trim()}`);

console.log('\n5️⃣ Options-based STDIN:');

const optionsCmd = $({ stdin: `Data from ${runtime} options\nSecond line\n` })`cat`;
const optionsResult = await optionsCmd;
console.log(` Options STDIN:\n${optionsResult.stdout}`);

console.log('\n' + '=' .repeat(50));
console.log(`βœ… All streaming STDIN patterns work perfectly in ${runtime}!`);

} catch (error) {
console.error(`❌ Error in ${runtime}:`, error.message);
console.error(error.stack);
process.exit(1);
}
}

streamingStdinComparison();
Loading