# @replit/protocol

JavaScript/TypeScript bindings for the Replit protocol.

## Tree-Shakeable ESM Build

This package now includes a tree-shakeable ES Module build alongside the existing CommonJS build.

### Usage

**Legacy namespace imports (default, fully backward compatible):**
```typescript
import { api } from '@replit/protocol';

// Access types via namespace
const target = api.DeploymentConfig.Target.VM;
const token = api.token.ReplToken.create({ ... });
```

This is the default import and works in all environments without configuration changes.

**Tree-shakeable ESM imports (recommended for new code in Next.js apps):**
```typescript
import { Persistence, ReplToken_WireFormat, Timestamp } from '@replit/protocol/esm';

// Direct access to types
const persistence: Persistence = Persistence.NONE;
const format: ReplToken_WireFormat = ReplToken_WireFormat.PROTOBUF;
```

⚠️ **Note**: ESM imports require adding `@replit/protocol` to `transpilePackages` in `next.config.js`:
```javascript
transpilePackages: ['@replit/protocol', /* other packages */]
```

**CommonJS (Node.js require):**
```typescript
const { api } = require('@replit/protocol');
const { Command } = api;
```

### Bundle Size Impact

The ESM build enables ~80-90% bundle size reduction through tree-shaking:
- **Full bundle**: ~848 KB
- **Single type import**: ~23 KB (96% reduction)

### Key Differences

- **Legacy namespace** (`@replit/protocol`): Uses `api.token.ReplToken`, imports everything
- **ESM direct imports** (`@replit/protocol/esm`): Uses `ReplToken_WireFormat`, tree-shakeable
- ESM uses protobuf-ts with `toBinary()`/`fromBinary()` instead of `encode()`/`decode()`
- ESM uses native `BigInt` instead of Long.js

# Developing
* Change goval/api/types.proto
* In this directory:
  * `pnpm build`
* Change repl-it-web/package.json:
  ```
  "@replit/protocol": "^0.4.9",
  ```
  to
  ```
  "@replit/protocol": "file:../goval/api/npm",
  ```
* Also change repl-it-web/shared/package.json:
  ```
  "@replit/protocol": "^0.4.9",
  ```
  to
  ```
  "@replit/protocol": "file:../../goval/api/npm",
  ```

# Publishing

After your `.proto` changes are merged:
- create a new branch
- cd into `api/npm`
- `pnpm version <new-version> --no-git-tag-version`
- submit a pull request
- merged
- pull latest `main`
- cd into `api/npm`
- `pnpm login` if you're not authed (will need to be in our npm org)
- `pnpm publish`
- it will run a build
- you be asked for 2fa
- package will be published
