# Promise-Based API Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Add Promise-based async/await support to all 10 async convenience methods while maintaining 100% backward compatibility with callback-based API.

**Architecture:** Detect callback parameter in each async method — if no callback provided, wrap the existing implementation in a Promise. If callback exists, use callback mode (existing behavior). This approach requires minimal code changes and zero breaking changes.

**Tech Stack:** Native JavaScript Promises (Node.js 10+), TypeScript for type definitions, existing pako + brotli libraries for compression.

---

## File Structure

| File | Changes | Responsibility |
|------|---------|-----------------|
| `src/zlib.js` | Modify 10 methods | Add callback detection + promise wrapping |
| `index.d.ts` | Create new | TypeScript definitions with callback/promise overloads |
| `test.js` | Add tests | ~35 new test cases covering promise/callback modes |
| `README.md` | Add section | Document promise API with examples |

---

## Task Breakdown

### Task 1: Create TypeScript Definitions File

**Files:**
- Create: `index.d.ts`

- [ ] **Step 1: Create TypeScript definitions skeleton**

Create file `index.d.ts` with type definitions for all exports, classes, and method overloads.

All async methods need overloads for:
1. Promise mode: `(buffer, options?) => Promise<Buffer>`
2. Callback mode: `(buffer, callback) => void` and `(buffer, options, callback) => void`

Include type definitions for:
- ZlibOptions interface (with all compression options)
- BrotliOptions interface
- All constants (Z_OK, Z_BEST_COMPRESSION, BROTLI_*, etc.)
- All 8 stream classes (Gzip, Gunzip, Deflate, Inflate, DeflateRaw, InflateRaw, Unzip)
- All 10 async methods with Promise/callback overloads
- All 9 sync methods
- CRC32 function

Reference: src/zlib.js lines 1-100 for exports structure, src/binding.js for available constants.

- [ ] **Step 2: Verify TypeScript file syntax**

Run: `npx tsc --noEmit index.d.ts`
Expected: No errors (types are valid)

- [ ] **Step 3: Commit TypeScript definitions**

```bash
git add index.d.ts
git commit -m "feat: add TypeScript definitions for promise API"
```

---

### Task 2: Add Promise Tests for Gzip/Gunzip

**Files:**
- Modify: `test.js` (add new test section)

- [ ] **Step 1: Add promise tests for gzip/gunzip**

Add new test section at end of test.js file with:
- Promise mode tests: `await zlib.gzip(data)` returns Buffer
- Promise with options: `await zlib.gzip(data, { level: 9 })` works
- Gunzip promise: decompresses gzip data correctly
- Error handling: promise rejects on invalid input (null, malformed data)
- All tests should use async/await pattern

Test each method individually with descriptive console.log messages.

- [ ] **Step 2: Run tests to verify they fail**

Run: `npm test 2>&1 | grep -A 2 "Promise"`
Expected: Tests fail with "gzip is not returning a promise" or similar

- [ ] **Step 3: Commit test skeleton**

```bash
git add test.js
git commit -m "test: add promise API test cases"
```

---

### Task 3: Implement Promise Wrapper for Gzip/Gunzip

**Files:**
- Modify: `src/zlib.js` (gzip and gunzip methods, around lines 140-198)

- [ ] **Step 1: Update gzip method with promise support**

In `src/zlib.js`, find `exports.gzip` function and replace entire function:

```javascript
exports.gzip = function (buffer, opts, callback) {
  if (typeof opts === 'function') {
    callback = opts;
    opts = {};
  }

  // Return promise if no callback provided
  if (!callback) {
    return new Promise((resolve, reject) => {
      zlibBuffer(new Gzip(opts), buffer, (err, result) => {
        if (err) reject(err);
        else resolve(result);
      });
    });
  }

  // Use callback mode (existing behavior)
  return zlibBuffer(new Gzip(opts), buffer, callback);
};
```

- [ ] **Step 2: Update gunzip method with promise support**

Find `exports.gunzip` and replace entire function with same pattern but using `Gunzip` class instead of `Gzip`.

- [ ] **Step 3: Run tests for gzip/gunzip**

Run: `npm test 2>&1`
Expected: gzip and gunzip promise tests pass

- [ ] **Step 4: Verify callback mode still works**

Run: `npm test 2>&1 | grep -i "callback"`
Expected: Callback tests pass (backward compatibility confirmed)

- [ ] **Step 5: Commit gzip/gunzip implementation**

```bash
git add src/zlib.js
git commit -m "feat: add promise support to gzip/gunzip methods"
```

---

### Task 4: Implement Promise Wrapper for Deflate/Inflate

**Files:**
- Modify: `src/zlib.js` (deflate and inflate methods)

- [ ] **Step 1: Update deflate and inflate methods**

Apply same promise wrapping pattern to `exports.deflate` and `exports.inflate` methods (around lines 128-186).

Each method should:
- Check if callback is provided
- Return Promise if no callback (wrapping in new Promise with resolve/reject)
- Use callback mode if callback provided

- [ ] **Step 2: Run tests**

Run: `npm test 2>&1 | grep -E "(deflate|inflate)" | head -10`
Expected: deflate and inflate promise tests pass

- [ ] **Step 3: Commit deflate/inflate implementation**

```bash
git add src/zlib.js
git commit -m "feat: add promise support to deflate/inflate methods"
```

---

### Task 5: Implement Promise Wrapper for DeflateRaw/InflateRaw

**Files:**
- Modify: `src/zlib.js` (deflateRaw and inflateRaw methods)

- [ ] **Step 1: Update deflateRaw and inflateRaw methods**

Apply same promise wrapping pattern to `exports.deflateRaw` and `exports.inflateRaw` methods.

Follow same structure as previous tasks - detect callback, return promise or use callback mode.

- [ ] **Step 2: Run tests**

Run: `npm test 2>&1`
Expected: All deflateRaw and inflateRaw tests pass

- [ ] **Step 3: Commit deflateRaw/inflateRaw implementation**

```bash
git add src/zlib.js
git commit -m "feat: add promise support to deflateRaw/inflateRaw methods"
```

---

### Task 6: Implement Promise Wrapper for Unzip

**Files:**
- Modify: `src/zlib.js` (unzip method)

- [ ] **Step 1: Update unzip method**

Apply same promise wrapping pattern to `exports.unzip` method.

- [ ] **Step 2: Run tests**

Run: `npm test 2>&1`
Expected: unzip promise tests pass

- [ ] **Step 3: Commit unzip implementation**

```bash
git add src/zlib.js
git commit -m "feat: add promise support to unzip method"
```

---

### Task 7: Implement Promise Wrapper for Brotli Methods

**Files:**
- Modify: `src/zlib.js` (brotliCompress and brotliDecompress methods)

- [ ] **Step 1: Update brotli methods**

Apply promise wrapping pattern to `exports.brotliCompress` and `exports.brotliDecompress` methods.

Note: These use `brotliBuffer` helper function instead of `zlibBuffer`, but same callback detection logic applies.

- [ ] **Step 2: Run tests**

Run: `npm test 2>&1`
Expected: All brotli promise tests pass

- [ ] **Step 3: Commit brotli implementation**

```bash
git add src/zlib.js
git commit -m "feat: add promise support to brotli methods"
```

---

### Task 8: Add Comprehensive Backward Compatibility Tests

**Files:**
- Modify: `test.js` (add more test cases)

- [ ] **Step 1: Add backward compatibility tests**

Add tests to verify:
- Callback with options: `zlib.gzip(data, { level: 9 }, callback)` works
- Callback without options: `zlib.gzip(data, callback)` works
- Promise output matches sync output for same data
- All 10 methods support both promise and callback modes
- Error handling in promises (rejects vs callback error)

Each test should have clear console.log messages for pass/fail.

- [ ] **Step 2: Run full test suite**

Run: `npm test`
Expected: ALL tests pass (original + new promise tests)

- [ ] **Step 3: Commit comprehensive tests**

```bash
git add test.js
git commit -m "test: add comprehensive backward compatibility tests"
```

---

### Task 9: Update README with Promise Examples

**Files:**
- Modify: `README.md`

- [ ] **Step 1: Add new "Promise-Based API" section**

Add new section after "Quick Start" section (around line 94) documenting:
- Promise/async-await syntax
- Examples with `await zlib.gzip(data)`
- Error handling with try/catch
- Options with promises
- All algorithms (gzip, deflate, brotli)

- [ ] **Step 2: Add promise examples to Examples section**

Add new subsection under "## Examples" called "### Compression with Promises" showing:
- async function with compression and decompression
- Promise chaining example
- Error handling patterns
- Working with all algorithm types

- [ ] **Step 3: Verify formatting**

Run: `head -200 README.md | tail -100`
Expected: New promise sections visible and well-formatted

- [ ] **Step 4: Commit README updates**

```bash
git add README.md
git commit -m "docs: add promise API examples and documentation"
```

---

### Task 10: Final Verification and Version Bump

**Files:**
- Modify: `package.json` (version bump)

- [ ] **Step 1: Run full test suite**

Run: `npm test`
Expected: ALL tests pass (original + new promise tests) with no errors

- [ ] **Step 2: Verify TypeScript definitions**

Run: `npx tsc --noEmit index.d.ts 2>&1`
Expected: No type errors

- [ ] **Step 3: Quick regression check**

Run: `node -e "const z = require('./src/zlib.js'); const r = z.gzipSync('test'); console.log(r.length > 0 ? 'OK' : 'FAIL');"`
Expected: Output "OK"

- [ ] **Step 4: Bump version to 2.1.0**

Edit `package.json`, change:
```json
{
  "version": "2.1.0"
}
```

- [ ] **Step 5: Create final commit**

```bash
git add package.json
git commit -m "chore: bump version to 2.1.0 - add promise API support"
```

- [ ] **Step 6: Verify implementation summary**

Run: `git log --oneline HEAD~9..HEAD`
Expected: Shows commits for all 10 tasks

---

## Summary

**Total commits:** 10 (one per task)
**New tests:** ~35
**Modified methods:** 10 async methods updated with promise support
**New file:** 1 (index.d.ts)
**Breaking changes:** None (100% backward compatible)

All changes follow TDD: tests written, implementation added to pass tests, frequent commits.
