6989a98d75
- Arkitektur: docs/auth/passwordless-architecture.md - Backend: iom/quixzoom-auth-service/ (FastAPI + Redis) - Webb: quixzoom-market-pages/se/login/ (QR-kod + polling) - App: iom/quixzoom-app/src/features/auth/ (push + deep links) Flöde: QR-kod → app-godkännande → webb-inloggad
86 lines
2.8 KiB
JavaScript
86 lines
2.8 KiB
JavaScript
export class NodeWebSocket {
|
|
constructor(ws) {
|
|
/** Maps `(event, originalListener)` -> wrapped listener for correct `off()` removal. */
|
|
this._listenerMap = new Map();
|
|
this._ws = ws;
|
|
}
|
|
/** The underlying platform-specific socket. Code that accesses this will not be isomorphic across server and browser environments. */
|
|
get platformSocket() {
|
|
return this._ws;
|
|
}
|
|
get readyState() {
|
|
return this._ws.readyState;
|
|
}
|
|
send(data) {
|
|
this._ws.send(data);
|
|
}
|
|
close(code, reason) {
|
|
this._ws.close(code, reason);
|
|
}
|
|
on(event, listener) {
|
|
const wrapped = this._wrapListener(event, listener);
|
|
this._listenersFor(event).set(listener, wrapped);
|
|
this._ws.on(event, wrapped);
|
|
}
|
|
off(event, listener) {
|
|
const byListener = this._listenerMap.get(event);
|
|
if (!byListener)
|
|
return;
|
|
const wrapped = byListener.get(listener);
|
|
if (wrapped) {
|
|
byListener.delete(listener);
|
|
this._ws.removeListener(event, wrapped);
|
|
}
|
|
}
|
|
once(event, listener) {
|
|
const onceListener = (...args) => {
|
|
this.off(event, listener);
|
|
listener(...args);
|
|
};
|
|
const wrapped = this._wrapListener(event, onceListener);
|
|
this._listenersFor(event).set(listener, wrapped);
|
|
this._ws.on(event, wrapped);
|
|
}
|
|
_listenersFor(event) {
|
|
let map = this._listenerMap.get(event);
|
|
if (!map) {
|
|
map = new Map();
|
|
this._listenerMap.set(event, map);
|
|
}
|
|
return map;
|
|
}
|
|
/**
|
|
* Normalizes `ws` message payloads: text frames become strings,
|
|
* binary frames stay as `Buffer`, and fragmented frames are merged.
|
|
*/
|
|
static _normalizeMessageData(data, isBinary) {
|
|
if (!isBinary) {
|
|
if (Array.isArray(data))
|
|
return Buffer.concat(data).toString();
|
|
if (data instanceof ArrayBuffer)
|
|
return Buffer.from(data).toString();
|
|
return data.toString();
|
|
}
|
|
if (Array.isArray(data))
|
|
return Buffer.concat(data);
|
|
if (data instanceof ArrayBuffer)
|
|
return Buffer.from(data);
|
|
return data;
|
|
}
|
|
_wrapListener(event, listener) {
|
|
switch (event) {
|
|
case 'message':
|
|
return (data, isBinary) => {
|
|
listener(NodeWebSocket._normalizeMessageData(data, isBinary), isBinary);
|
|
};
|
|
case 'close':
|
|
return (code, reason) => {
|
|
listener(code, reason.toString());
|
|
};
|
|
// 'open' and 'error' pass through unchanged
|
|
default:
|
|
return listener;
|
|
}
|
|
}
|
|
}
|
|
//# sourceMappingURL=ws-adapter-node.mjs.map
|