CodeSampleX

Beispiel

ws 8.21.3: Distinguish ws package EventEmitter API and Buffer payloads from native WHATWG EventTarget WebSocket and string payloads in Node

Verifiziertes Beispiel für npm ws 8.21.3: Distinguish ws package EventEmitter API and Buffer payloads from native WHATWG EventTarget WebSocket and string…

sha256:1a1d36a350a9eb2dcd345ed3b5163cee5cc2ec75783de4b1c90f8d313b012ee7

Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen. Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen. MIT-0

Ausführungsbelege

Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.

Beleggrundlage
Signierter Vertrag bestanden
Verifizierungsbelege
3
Signaturschlüssel, die es gebaut haben
3
Deklarierte Umgebung node linux x64 node node npm

Umgebungen der Verifizierungsläufe

Umgebung Contract Stufen Lauf
node 22 · linux alpine/x64 · docker ed25519:ac1544ece1e22594 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-14
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-09-07

Fall

HOW
Ziel
Distinguish ws package EventEmitter API and Buffer payloads from native WHATWG EventTarget WebSocket and string payloads in Node
Pakete
Symbole
  • WebSocket
  • WebSocket.prototype.on
  • WebSocket.prototype.ping
  • WebSocket.prototype.binaryType
  • WebSocketServer
Umgebung
node
Erstellt
2026-08-14T22:43:45Z

Contract

  1. assert ws inherits from EventEmitter with .on() and .ping() while native WebSocket is an EventTarget without .on() or .ping()
  2. assert WebSocketServer exists in ws but not on globalThis
  3. assert ws defaults binaryType to nodebuffer while native WebSocket defaults to blob and rejects nodebuffer
  4. assert ws .on('message') yields a Buffer directly (data.data is undefined) while native onmessage yields MessageEvent with string event.data
  5. assert ws .on('close') yields Buffer reason while native onclose yields string event.reason

Dateien

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • test/contract.mjs

Quellartefakt herunterladen (tar.gz)

Quelltext

NOTES.md
A naive model assumes `ws` and native `WebSocket` share the same API, writing `socket.on('message', (event) => process(event.data))` or calling `socket.ping()` on native instances.
This fails loudly with `TypeError: socket.on is not a function` on native `WebSocket`, or fails silently in `ws` where `event.data` evaluates to `undefined` because `data` is passed directly as a `Buffer`.
csx.json
{"case":{"caseId":"case:sha256:34f392705de3fb799e763847855644ef9f32f03bf99bda08eb93e12aceb03d62","constraints":{"runtime":"node"},"contract":["assert ws inherits from EventEmitter with .on() and .ping() while native WebSocket is an EventTarget without .on() or .ping()","assert WebSocketServer exists in ws but not on globalThis","assert ws defaults binaryType to nodebuffer while native WebSocket defaults to blob and rejects nodebuffer","assert ws .on('message') yields a Buffer directly (data.data is undefined) while native onmessage yields MessageEvent with string event.data","assert ws .on('close') yields Buffer reason while native onclose yields string event.reason"],"goal":"Distinguish ws package EventEmitter API and Buffer payloads from native WHATWG EventTarget WebSocket and string payloads in Node","kind":"HOW","packages":["pkg:npm/ws@8.21.3"],"schemaVersion":1,"symbols":["WebSocket","WebSocket.prototype.on","WebSocket.prototype.ping","WebSocket.prototype.binaryType","WebSocketServer"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/ws@8.21.3"],"schemaVersion":1,"symbols":["WebSocket","WebSocket.prototype.on","WebSocket.prototype.ping","WebSocket.prototype.binaryType","WebSocketServer"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "sample",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample",
      "version": "1.0.0",
      "dependencies": {
        "ws": "8.21.3"
      }
    },
    "node_modules/ws": {
      "version": "8.21.3",
      "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
      "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
      "license": "MIT",
      "engines": {
        "node": ">=10.0.0"
      },
      "peerDependencies": {
        "bufferutil": "^4.0.1",
        "utf-8-validate": ">=5.0.2"
      },
      "peerDependenciesMeta": {
        "bufferutil": {
          "optional": true
        },
        "utf-8-validate": {
          "optional": true
        }
      }
    }
  }
}
package.json
{
  "name": "sample",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "test": "node test/contract.mjs"
  },
  "dependencies": {
    "ws": "8.21.3"
  }
}
test/contract.mjs
import assert from 'node:assert/strict';
import { EventEmitter } from 'node:events';
import http from 'node:http';
import ws, { WebSocket, WebSocketServer } from 'ws';

// --- 1. Prototype & Class API Disagreements ---

// ws WebSocket inherits from EventEmitter; globalThis.WebSocket inherits from EventTarget
assert.equal(WebSocket.prototype instanceof EventEmitter, true);
assert.equal(typeof WebSocket.prototype.on, 'function');
assert.equal(typeof WebSocket.prototype.ping, 'function');

assert.equal(globalThis.WebSocket.prototype instanceof EventEmitter, false);
assert.equal(globalThis.WebSocket.prototype instanceof EventTarget, true);
assert.equal(typeof globalThis.WebSocket.prototype.on, 'undefined');
assert.equal(typeof globalThis.WebSocket.prototype.ping, 'undefined');

// WebSocketServer exists on the ws package, but not as a global
assert.equal(typeof WebSocketServer, 'function');
assert.equal(typeof globalThis.WebSocketServer, 'undefined');

// --- 2. Default binaryType Disagreements ---

const dummyWs = new WebSocket('ws://127.0.0.1:1');
dummyWs.on('error', () => {});
assert.equal(dummyWs.binaryType, 'nodebuffer');
dummyWs.close();

const dummyNative = new globalThis.WebSocket('ws://127.0.0.1:1');
dummyNative.onerror = () => {};
assert.equal(dummyNative.binaryType, 'blob');
// WHATWG specification ignores 'nodebuffer'; binaryType remains 'blob'
dummyNative.binaryType = 'nodebuffer';
assert.equal(dummyNative.binaryType, 'blob');
dummyNative.close();

// --- 3. Runtime Event Signature & Payload Disagreements ---

const server = http.createServer();
const wss = new WebSocketServer({ server });

wss.on('connection', (socket) => {
  socket.on('message', (data) => {
    socket.send('ack:' + data.toString());
    socket.close(1000, 'server_closed');
  });
});

await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
const port = server.address().port;
const url = `ws://127.0.0.1:${port}`;

// ws client: .on('message') delivers Buffer directly; .on('close') delivers Buffer reason
await new Promise((resolve, reject) => {
  const client = new WebSocket(url);
  client.on('error', reject);
  client.on('open', () => client.send('hello_ws'));
  client.on('message', (data, isBinary) => {
    // ws delivers (data: Buffer, isBinary: boolean); data.data is undefined
    assert.equal(Buffer.isBuffer(data), true);
    assert.equal(data.data, undefined);
    assert.equal(isBinary, false);
    assert.equal(data.toString('utf8'), 'ack:hello_ws');
  });
  client.on('close', (code, reason) => {
    // ws delivers reason as a Buffer, NOT a string
    assert.equal(code, 1000);
    assert.equal(Buffer.isBuffer(reason), true);
    assert.notEqual(typeof reason, 'string');
    assert.equal(reason.toString('utf8'), 'server_closed');
    resolve();
  });
});

// native WebSocket client: onmessage receives MessageEvent; onclose receives CloseEvent
await new Promise((resolve, reject) => {
  const nativeClient = new globalThis.WebSocket(url);
  nativeClient.onerror = reject;
  nativeClient.onopen = () => nativeClient.send('hello_native');
  nativeClient.onmessage = (event) => {
    // native delivers MessageEvent; payload is at event.data as string
    assert.equal(Buffer.isBuffer(event), false);
    assert.equal(typeof event.data, 'string');
    assert.equal(event.data, 'ack:hello_native');
  };
  nativeClient.onclose = (event) => {
    // native event.reason is a primitive string, NOT a Buffer
    assert.equal(event.code, 1000);
    assert.equal(typeof event.reason, 'string');
    assert.equal(Buffer.isBuffer(event.reason), false);
    assert.equal(event.reason, 'server_closed');
    resolve();
  };
});

await new Promise((resolve) => server.close(resolve));

Ursprungs-Seeder

anonymous