npm package: @piplfy/widget
Description: Piplfy Widget — native WebSocket bridge for Node.js applications
Latest version: 0.0.2

# Piplfy Widget

Native WebSocket bridge that runs as a sidecar process alongside your Node.js application. Handles real-time communication with the Piplfy platform through an embedded Rust binary — no native compilation required on install.

## Install

```bash
npm install piplfy-widget
```

The correct binary for your OS and architecture is installed automatically. No extra steps needed.

### Supported platforms

| Platform | Architecture | Package |
| -------- | ------------ | ------- |
| Linux | x64 | `piplfy-widget-linux-x64` |
| Windows | x64 | `piplfy-widget-win32-x64` |

> macOS and ARM support coming soon.

## Quick start

```javascript
import { startPwidget } from "piplfy-widget";

const widget = await startPwidget({
  onLog: (line) => console.log("[pwidget]", line),
});

// The binary is now running and listening for WebSocket connections.
// When you're done:
widget.kill();
```

## API

### `startPwidget(options?)`

Starts the native binary as a child process. Returns a Promise that resolves once the process is ready (emits `"listening on"` to stdout).

**Options:**

| Parameter | Type | Default | Description |
| --------- | ---- | ------- | ----------- |
| `timeout` | `number` | `5000` | Max milliseconds to wait for startup before rejecting |
| `env` | `Record<string, string>` | `{}` | Extra environment variables passed to the binary |
| `onLog` | `(data: string) => void` | — | Called on every stdout/stderr chunk |
| `onExit` | `(code: number \| null) => void` | — | Called when the process exits |

**Returns:** `Promise<{ kill: () => void, process: ChildProcess }>`

```javascript
const widget = await startPwidget({
  timeout: 8000,
  env: {
    PORT: "9090",
    PWIDGET_SECRET: process.env.PWIDGET_SECRET,
  },
  onLog: (line) => console.log("[pwidget]", line),
  onExit: (code) => {
    if (code !== 0) console.error("pwidget crashed with code", code);
  },
});
```

### `resolveBinaryPath()`

Returns the absolute path to the native binary for the current platform. Useful if you want to manage the process yourself.

```javascript
import { resolveBinaryPath } from "piplfy-widget";

const binaryPath = resolveBinaryPath();
// => "/path/to/node_modules/piplfy-widget-linux-x64/bin/pwidget"
```

## CLI

You can also run the binary directly from the command line:

```bash
npx piplfy-widget
```

## Zod schemas

The package exports Zod validation schemas that match the data structures expected by the binary. Zod is an optional peer dependency — if you don't use the schemas, you don't need to install it.

```bash
npm install zod
```

```javascript
import { userContextSchema } from "piplfy-widget/schemas";

const result = userContextSchema.safeParse(payload);

if (!result.success) {
  console.error(result.error.issues);
  return;
}

// result.data is fully typed
console.log(result.data.email);
console.log(result.data.organization.domain);
```

The `userContextSchema` validates the following shape:

```typescript
{
  id: string
  username: string | null
  email: string              // validated as email
  profile: {
    firstname: string
    lastname: string | null
    phone: string | null
  }
  organization: {
    name: string
    domain: string
    public_domain: string | null
    description: string | null
    country_id: string | null  // validated as UUID
    sector_id: string | null   // validated as UUID
    size_id: string | null     // validated as UUID
    target_countries: string[] | null
    target_sectors: string[] | null
    target_sizes: string[] | null
    target_tags: string[] | null
    logo_url: string | null    // validated as URL
  }
}
```

## Usage with Express

A common pattern is to proxy WebSocket connections from your Express server to the native binary:

```javascript
import express from "express";
import http from "http";
import httpProxy from "http-proxy";
import { startPwidget } from "piplfy-widget";

const app = express();
const server = http.createServer(app);

const proxy = httpProxy.createProxyServer({
  target: "http://localhost:8080",
  ws: true,
});

await startPwidget({
  env: { PORT: "8080" },
  onLog: (line) => console.log("[pwidget]", line),
  onExit: (code) => {
    console.error("pwidget exited unexpectedly:", code);
    process.exit(1);
  },
});

app.get("/health", (req, res) => res.json({ status: "ok" }));

server.on("upgrade", (req, socket, head) => {
  if (req.url === "/ws") {
    proxy.ws(req, socket, head);
  } else {
    socket.destroy();
  }
});

server.listen(3000, () => {
  console.log("Server listening on :3000");
});
```

## Troubleshooting

**`piplfy-widget: plataforma "X" no soportada`** — Your OS/arch combination doesn't have a prebuilt binary yet. See the supported platforms table above.

**`pwidget failed to start within 5000ms`** — The binary didn't emit `"listening on"` in time. Try increasing the `timeout` option or check the logs with `onLog`.

**`no se encontró el paquete "piplfy-widget-..."`** — The platform-specific package didn't install. Run `npm install` again, or install it explicitly: `npm install piplfy-widget-linux-x64`.

## License

MIT