Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Socket

ASecurity

How to use @owlmeans/socket — the transport-agnostic Connection model shared by client-socket and server-socket, its message types (call/request/event/auth/system), the type guards, and the socket error classes. Auto-invoked when importing socket types, message constants or the connection model.

3 stars
0 votes
0 copies
0 views
Added 9/22/2026
businesstypescriptgo

Works with

terminalcli

Security Analysis

A100/100

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add owlmeans/common --skill socket --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Socket?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Socket
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/owlmeans-socket-common/badge)](https://www.skillsdirectory.com/skills/owlmeans-socket-common)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: socket
description: How to use @owlmeans/socket — the transport-agnostic Connection model shared by client-socket and server-socket, its message types (call/request/event/auth/system), the type guards, and the socket error classes. Auto-invoked when importing socket types, message constants or the connection model.
user-invocable: false
---
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->

# @owlmeans/socket

**Layer:** Core
**Install:** `"@owlmeans/socket": "^0.1.18-rc.26"` in `dependencies`

Contracts and one implementation-free connection model. It knows nothing about WebSockets: the
browser side is `@owlmeans/client-socket`, the Fastify side `@owlmeans/server-socket`, and each
supplies the members the model leaves abstract — `send`, `close`, `authenticate` and `prepare` —
that make it concrete. Both halves of an application therefore speak the same frames.

## Key Exports

| Export | Description |
|--------|-------------|
| `createBasicConnection()` | The connection model — everything below the wire. A carrier assigns `send` / `close` / `authenticate` / `prepare` and feeds bytes to `receive` |
| `Connection` | What a handler is handed: the messaging verbs, `stage`, `getListeners` |
| `Message<T>` | The frame — `{ type, payload, id?, sender?, recipient?, dt?, rawData? }` |
| `CallMessage<T>` / `EventMessage<T>` / `AuthMessage<T>` | The three frames that add a field: `method` + `timeout`, `event`, `stage` |
| `MessageType` | `Call` `Result` `Error` `Request` `Response` `Event` `Message` `Auth` `System` |
| `isMessage` / `isEventMessage` / `isCallMessage` / `isAuthMessage` | Type guards — `isMessage(msg, true)` excludes system frames, `isEventMessage(msg, true)` keeps only them |
| `ConnectionListener` / `CallHendler` / `RequestHandler` / `CallResolver` | The callback shapes |
| `SocketSystemEvent` | The `event` values a `MessageType.System` frame carries — see below |
| `SOCKET_HEARTBEAT_TIMEOUT_CODE` | `4000` — the close code `client-socket`'s carrier uses when it force-closes a socket that has gone silent |
| `SocketError` and subclasses | `SocketInitializationError`, `SocketConnectionError`, `SocketUnauthorized`, `SocketUnsupported`, `SocketTimeout`, `SocketMessageError`, `SocketMessageMalformed` — all registered with `ResilientError` |
| `CALL_TIMEOUT` | 60 000 ms, the fallback when neither the message nor `connection.defaultCallTimeout` says |

## The four ways to say something

Pick by who is expected to answer and how often — they are separate registries, and a handler
bound to one never sees the others.

| Verb | Answered by | Shape |
|---|---|---|
| `notify(event, payload)` | `observe(event, handler)` | Fire-and-forget, fanned out to every observer of that event name |
| `call(method, ...args)` | `perform(method, handler)` | One RPC, resolved with the handler's return value or rejected with its error |
| `request(payload, observer?)` | `acknowledge(handler)`, answered with `reply(id, payload)` | An open question — acknowledgers run in turn until one takes it |
| `enqueue(payload, id?)` | `consume(filter?)` | A mailbox the far side drains on its own schedule; `enqueued()` is its depth |

```typescript
import { MessageType } from '@owlmeans/socket'
import type { Connection, EventMessage } from '@owlmeans/socket'

connection.observe<Progress>('job-event', async message => render(message.payload))
await connection.notify('job-event', { id, progress: 0.5 })

connection.perform<Report, [string]>('report', async id => await build(id))
const report = await connection.call<Report, [string]>('report', id)
```

A `call` carries an id and a timeout, and the model arms the timer on both sides: the caller
rejects with `SocketTimeout` when the answer does not arrive, and the performer stops sending one
once it has elapsed. `timeout: 0` disables it. A performer that throws is answered with a
`MessageType.Error` frame carrying the marshalled error, so the caller's `call` rejects with the
original class rather than with a string.

## Frames a listener sees

`listen(listener)` receives EVERY inbound frame after the model has routed it — the escape hatch
for what the verbs above do not cover. It also receives the frames a carrier synthesises, which is
how a handler learns the connection is gone:

```typescript
connection.listen(async message => {
  if (typeof message !== 'object') {
    return
  }
  const msg = message as EventMessage<void>
  if (msg.type === MessageType.System && msg.event === 'close') {
    await cleanUp()
  }
})
```

Both carriers emit exactly that frame — `MessageType.System`, `event: 'close'`, payload
`{ code }` — when the socket closes for good. Nothing else reports a TERMINAL disconnect, so any
subscription a handler opened is released there.

**`SocketSystemEvent`** is the full vocabulary a `MessageType.System` frame's `event` can carry —
`client-socket`'s reconnecting carrier is what emits the other four:

| Event | Meaning |
|---|---|
| `close` | The connection is gone for good — see above |
| `disconnected` | The socket dropped and a retry IS scheduled (client-socket only) — `{ code }` |
| `reconnecting` | Before each retry attempt (client-socket only) — `{ attempt, delay }` |
| `reconnected` | A retry succeeded, same `Connection` model (client-socket only) — `{ attempts }` |
| `lost` | The retry budget elapsed with no success, immediately followed by `close` (client-socket only) |

`close` is the only one of the five a plain carrier with no retry logic (like `server-socket`, or
`client-socket` itself with `reconnect: false`) will ever emit — a listener written against `close`
alone, before reconnect support existed, still sees exactly the frame it always did once a
reconnecting carrier's retries give up.

## What the model expects of a carrier

- `receive(raw)` takes the raw string. It only parses text that starts with `{` or `[`; anything
  else is dropped without reaching a listener. The carriers' own heartbeat IS JSON
  (`{ type: 'ping' }`), so it is parsed: it matches no `MessageType` and routes nowhere, yet it
  still reaches every `listen` listener — a listener has to recognise the frames it wants.
- A frame with no `type` is read as `MessageType.Message` and a frame with no `payload` is treated
  as its own payload, so a plain JSON body from a foreign client still arrives as a message.
- `prepare(message, isRequest?)` is the carrier's hook for stamping a frame — timestamps,
  `sender` / `recipient`. It runs on every outbound frame and on every inbound one.
- `send`, `close` and `authenticate` throw `SyntaxError` until a carrier assigns them, so one that
  forgets a member fails loudly rather than dropping frames. `prepare` is the exception: it is
  optional on the interface and simply absent until assigned, and the model calls it defensively —
  a carrier that omits it stamps nothing.

## Authentication

`auth(stage, payload)` sends an `AuthMessage` and waits. The far side's `authenticate` answers with
the next stage and its payload, or throws — a rejection travels back as an `AuthMessage` with a
null stage and is rebuilt by the initiator. `connection.stage` holds the current
`AuthenticationStage` throughout. Only the server carrier implements a real sequence; see the
`server-socket` skill.

Raw inbound data is parsed and structurally checked before dispatch. A server connection may accept
only authentication frames until its carrier marks it authenticated; an unknown call returns a
typed socket error, and listener failures are isolated and logged so an EventEmitter never receives
an unhandled rejected promise. Keep sensitive actions behind the carrier's authentication stage.

## Depends On

- `@owlmeans/error` — `ResilientError`, which every socket error registers with
- `@owlmeans/auth` — `AuthenticationStage`, the vocabulary the auth frames carry
- `@owlmeans/basic-ids` — `uuid` for call and request ids

## Related

- `client-socket` — the browser carrier and `useWs`
- `server-socket` — the Fastify carrier, guard enforcement and `connection(protocol, callback)`

Attribution

owlmeansowlmeans
View sourceMore from owlmeans →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Solution Architect

Designs system architecture, component specifications, and technical integration strategy. Use when: designing solutions, system architecture, technology stack, or integration approaches.

192 votes

Akorchak:Venture Assessment

Generate a comprehensive VC investment assessment report for a company

72 votes

Stock Analysis

Analyze stocks and cryptocurrencies using Yahoo Finance data. Supports portfolio management (create, add, remove assets), crypto analysis (Top 20 by market cap), and periodic performance reports (daily/weekly/monthly/quarterly/yearly). 8 analysis dimensions for stocks, 3 for crypto. Use for stock analysis, portfolio tracking, earnings reactions, or crypto monitoring.

6511 votes

Just Fucking Cancel

Find and cancel unwanted subscriptions by analyzing bank transactions. Detects recurring charges, calculates annual waste, and helps you cancel with direct URLs and browser automation. Use when: 'cancel subscriptions', 'audit subscriptions', 'find recurring charges', 'what am I paying for', 'save money', 'subscription cleanup', 'stop wasting money'. Supports CSV import (Apple Card, Chase, Amex, Citi, Bank of America, Capital One, Mint, Copilot) OR Plaid API for automatic transaction pull. Out...

6511 votes

Telegram Compose

Compose rich, readable Telegram messages using HTML formatting via direct Telegram API. Use when: (1) Sending any Telegram message beyond a simple one-line reply, (2) Creating structured messages with sections, lists, or status updates, (3) Need formatting unavailable via Clawdbot's Markdown conversion (underline, spoilers, expandable blockquotes, user mentions by ID), (4) Sending alerts, reports, summaries, or notifications to Telegram, (5) Want professional, scannable message formatting wit...

6511 votes
View all in business →