@miniflare/web-sockets
Advanced tools
Comparing version 2.9.0-next.1 to 2.9.0
@@ -36,6 +36,10 @@ import { Dispatcher } from 'undici'; | ||
declare const kClosed: unique symbol; | ||
declare const kClosedIncoming: unique symbol; | ||
declare const kClosedOutgoing: unique symbol; | ||
declare const kCoupled: unique symbol; | ||
declare const kError: unique symbol; | ||
declare const kPair: unique symbol; | ||
@@ -56,7 +60,13 @@ | ||
#private; | ||
static readonly READY_STATE_CONNECTING = 0; | ||
static readonly READY_STATE_OPEN = 1; | ||
static readonly READY_STATE_CLOSING = 2; | ||
static readonly READY_STATE_CLOSED = 3; | ||
[kPair]: WebSocket; | ||
[kAccepted]: boolean; | ||
[kCoupled]: boolean; | ||
[kClosed]: boolean; | ||
[kClosedOutgoing]: boolean; | ||
[kClosedIncoming]: boolean; | ||
protected [kWrapListener]<Type extends keyof WebSocketEventMap>(listener: (event: WebSocketEventMap[Type]) => void): (event: WebSocketEventMap[Type]) => void; | ||
get readyState(): number; | ||
accept(): void; | ||
@@ -67,2 +77,3 @@ send(message: ArrayBuffer | string): void; | ||
[kClose](code?: number, reason?: string): void; | ||
[kError](error?: Error): void; | ||
} | ||
@@ -69,0 +80,0 @@ |
@@ -7,2 +7,3 @@ var __create = Object.create; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); | ||
@@ -25,2 +26,28 @@ var __export = (target, all) => { | ||
}; | ||
var __publicField = (obj, key, value) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
return value; | ||
}; | ||
var __accessCheck = (obj, member, msg) => { | ||
if (!member.has(obj)) | ||
throw TypeError("Cannot " + msg); | ||
}; | ||
var __privateGet = (obj, member, getter) => { | ||
__accessCheck(obj, member, "read from private field"); | ||
return getter ? getter.call(obj) : member.get(obj); | ||
}; | ||
var __privateAdd = (obj, member, value) => { | ||
if (member.has(obj)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
}; | ||
var __privateSet = (obj, member, value, setter) => { | ||
__accessCheck(obj, member, "write to private field"); | ||
setter ? setter.call(obj, value) : member.set(obj, value); | ||
return value; | ||
}; | ||
var __privateMethod = (obj, member, method) => { | ||
__accessCheck(obj, member, "access private method"); | ||
return method; | ||
}; | ||
@@ -81,12 +108,20 @@ // packages/web-sockets/src/index.ts | ||
var kCoupled = Symbol("kCoupled"); | ||
var kClosed = Symbol("kClosed"); | ||
var kClosedOutgoing = Symbol("kClosedOutgoing"); | ||
var kClosedIncoming = Symbol("kClosedIncoming"); | ||
var kSend = Symbol("kSend"); | ||
var kClose = Symbol("kClose"); | ||
var WebSocket = class extends import_shared.InputGatedEventTarget { | ||
#sendQueue = []; | ||
[kPair]; | ||
[kAccepted] = false; | ||
[kCoupled] = false; | ||
[kClosed] = false; | ||
[import_shared.kWrapListener](listener) { | ||
var kError = Symbol("kError"); | ||
var _dispatchQueue, _a, _b, _c, _d, _e, _queuingDispatchToPair, queuingDispatchToPair_fn; | ||
var _WebSocket = class extends import_shared.InputGatedEventTarget { | ||
constructor() { | ||
super(...arguments); | ||
__privateAdd(this, _queuingDispatchToPair); | ||
__privateAdd(this, _dispatchQueue, []); | ||
__publicField(this, _a); | ||
__publicField(this, _b, false); | ||
__publicField(this, _c, false); | ||
__publicField(this, _d, false); | ||
__publicField(this, _e, false); | ||
} | ||
[(_a = kPair, _b = kAccepted, _c = kCoupled, _d = kClosedOutgoing, _e = kClosedIncoming, import_shared.kWrapListener)](listener) { | ||
const wrappedListener = super[import_shared.kWrapListener](listener); | ||
@@ -107,2 +142,10 @@ const addListenerCtx = (0, import_shared.getRequestContext)(); | ||
} | ||
get readyState() { | ||
if (this[kClosedOutgoing] && this[kClosedIncoming]) { | ||
return _WebSocket.READY_STATE_CLOSED; | ||
} else if (this[kClosedOutgoing] || this[kClosedIncoming]) { | ||
return _WebSocket.READY_STATE_CLOSING; | ||
} | ||
return _WebSocket.READY_STATE_OPEN; | ||
} | ||
accept() { | ||
@@ -115,7 +158,6 @@ if (this[kCoupled]) { | ||
this[kAccepted] = true; | ||
const sendQueue = this.#sendQueue; | ||
if (sendQueue) { | ||
for (const event of sendQueue) | ||
if (__privateGet(this, _dispatchQueue) !== void 0) { | ||
for (const event of __privateGet(this, _dispatchQueue)) | ||
this.dispatchEvent(event); | ||
this.#sendQueue = void 0; | ||
__privateSet(this, _dispatchQueue, void 0); | ||
} | ||
@@ -130,19 +172,8 @@ } | ||
[kSend](message) { | ||
if (this[kClosed]) { | ||
if (this[kClosedOutgoing]) { | ||
throw new TypeError("Can't call WebSocket send() after close()."); | ||
} | ||
const event = new MessageEvent("message", { data: message }); | ||
void this.#dispatchMessageEvent(event); | ||
void __privateMethod(this, _queuingDispatchToPair, queuingDispatchToPair_fn).call(this, event); | ||
} | ||
async #dispatchMessageEvent(event) { | ||
await (0, import_shared.waitForOpenOutputGate)(); | ||
const pair = this[kPair]; | ||
if (pair[kAccepted]) { | ||
pair.dispatchEvent(event); | ||
} else { | ||
const sendQueue = pair.#sendQueue; | ||
(0, import_assert.default)(sendQueue !== void 0); | ||
sendQueue.push(event); | ||
} | ||
} | ||
close(code, reason) { | ||
@@ -157,20 +188,37 @@ if (code) { | ||
} | ||
if (!this[kAccepted]) { | ||
throw new TypeError("You must call accept() on this WebSocket before sending messages."); | ||
} | ||
this[kClose](code, reason); | ||
} | ||
[kClose](code, reason) { | ||
if (!this[kAccepted]) { | ||
throw new TypeError("You must call accept() on this WebSocket before sending messages."); | ||
} | ||
if (this[kClosed]) | ||
if (this[kClosedOutgoing]) | ||
throw new TypeError("WebSocket already closed"); | ||
this[kClosed] = true; | ||
this[kPair][kClosed] = true; | ||
void this.#dispatchCloseEvent(code, reason); | ||
this[kClosedOutgoing] = true; | ||
this[kPair][kClosedIncoming] = true; | ||
const event = new CloseEvent("close", { code, reason }); | ||
void __privateMethod(this, _queuingDispatchToPair, queuingDispatchToPair_fn).call(this, event); | ||
} | ||
async #dispatchCloseEvent(code, reason) { | ||
await (0, import_shared.waitForOpenOutputGate)(); | ||
this.dispatchEvent(new CloseEvent("close", { code, reason })); | ||
this[kPair].dispatchEvent(new CloseEvent("close", { code, reason })); | ||
[kError](error) { | ||
const event = new ErrorEvent("error", { error }); | ||
void __privateMethod(this, _queuingDispatchToPair, queuingDispatchToPair_fn).call(this, event); | ||
} | ||
}; | ||
var WebSocket = _WebSocket; | ||
_dispatchQueue = new WeakMap(); | ||
_queuingDispatchToPair = new WeakSet(); | ||
queuingDispatchToPair_fn = async function(event) { | ||
await (0, import_shared.waitForOpenOutputGate)(); | ||
const pair = this[kPair]; | ||
if (pair[kAccepted]) { | ||
pair.dispatchEvent(event); | ||
} else { | ||
(0, import_assert.default)(__privateGet(pair, _dispatchQueue) !== void 0); | ||
__privateGet(pair, _dispatchQueue).push(event); | ||
} | ||
}; | ||
__publicField(WebSocket, "READY_STATE_CONNECTING", 0); | ||
__publicField(WebSocket, "READY_STATE_OPEN", 1); | ||
__publicField(WebSocket, "READY_STATE_CLOSING", 2); | ||
__publicField(WebSocket, "READY_STATE_CLOSED", 3); | ||
var WebSocketPair = function() { | ||
@@ -195,6 +243,14 @@ if (!(this instanceof WebSocketPair)) { | ||
ws.on("message", (message, isBinary) => { | ||
if (!pair[kClosed]) { | ||
if (!pair[kClosedOutgoing]) { | ||
pair[kSend](isBinary ? (0, import_shared2.viewToBuffer)(message) : message.toString()); | ||
} | ||
}); | ||
ws.on("close", (code, reason) => { | ||
if (!pair[kClosedOutgoing]) { | ||
pair[kClose](code, reason.toString()); | ||
} | ||
}); | ||
ws.on("error", (error) => { | ||
pair[kError](error); | ||
}); | ||
pair.addEventListener("message", (e) => { | ||
@@ -204,8 +260,6 @@ ws.send(e.data); | ||
pair.addEventListener("close", (e) => { | ||
if (ws.readyState < import_ws.default.CLOSING) { | ||
if (e.code === 1005) { | ||
ws.close(); | ||
} else { | ||
ws.close(e.code, e.reason); | ||
} | ||
if (e.code === 1005) { | ||
ws.close(); | ||
} else { | ||
ws.close(e.code, e.reason); | ||
} | ||
@@ -220,9 +274,2 @@ }); | ||
pair[kCoupled] = true; | ||
ws.on("close", (code, reason) => { | ||
if (!pair[kClosed]) | ||
pair[kClose](code, reason.toString()); | ||
}); | ||
ws.on("error", (error) => { | ||
pair.dispatchEvent(new ErrorEvent("error", { error })); | ||
}); | ||
} | ||
@@ -309,3 +356,3 @@ | ||
for (const ws of this.#webSockets) { | ||
if (!ws[kClosed]) | ||
if (!ws[kClosedOutgoing]) | ||
ws.close(1012, "Service Restart"); | ||
@@ -312,0 +359,0 @@ } |
{ | ||
"name": "@miniflare/web-sockets", | ||
"version": "2.9.0-next.1", | ||
"version": "2.9.0", | ||
"description": "WebSocket module for Miniflare: a fun, full-featured, fully-local simulator for Cloudflare Workers", | ||
@@ -38,4 +38,4 @@ "keywords": [ | ||
"dependencies": { | ||
"@miniflare/core": "2.9.0-next.1", | ||
"@miniflare/shared": "2.9.0-next.1", | ||
"@miniflare/core": "2.9.0", | ||
"@miniflare/shared": "2.9.0", | ||
"undici": "5.9.1", | ||
@@ -45,5 +45,5 @@ "ws": "^8.2.2" | ||
"devDependencies": { | ||
"@miniflare/shared-test": "2.9.0-next.1", | ||
"@miniflare/shared-test": "2.9.0", | ||
"@types/ws": "^8.2.0" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
23148
442
0
+ Added@miniflare/core@2.9.0(transitive)
+ Added@miniflare/queues@2.9.0(transitive)
+ Added@miniflare/shared@2.9.0(transitive)
+ Added@miniflare/watcher@2.9.0(transitive)
+ Added@types/better-sqlite3@7.6.11(transitive)
+ Added@types/node@22.5.5(transitive)
+ Addedbuiltins@5.1.0(transitive)
+ Addedcross-spawn@7.0.3(transitive)
+ Addedexeca@6.1.0(transitive)
+ Addedget-stream@6.0.1(transitive)
+ Addedhuman-signals@3.0.1(transitive)
+ Addedis-stream@3.0.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedmerge-stream@2.0.0(transitive)
+ Addedmimic-fn@4.0.0(transitive)
+ Addednpm-run-path@5.3.0(transitive)
+ Addednpx-import@1.1.4(transitive)
+ Addedonetime@6.0.0(transitive)
+ Addedparse-package-name@1.0.0(transitive)
+ Addedpath-key@3.1.14.0.0(transitive)
+ Addedsemver@7.6.3(transitive)
+ Addedshebang-command@2.0.0(transitive)
+ Addedshebang-regex@3.0.0(transitive)
+ Addedsignal-exit@3.0.7(transitive)
+ Addedstrip-final-newline@3.0.0(transitive)
+ Addedundici-types@6.19.8(transitive)
+ Addedvalidate-npm-package-name@4.0.0(transitive)
+ Addedwhich@2.0.2(transitive)
- Removed@miniflare/core@2.9.0-next.1(transitive)
- Removed@miniflare/queues@2.9.0-next.1(transitive)
- Removed@miniflare/shared@2.9.0-next.1(transitive)
- Removed@miniflare/watcher@2.9.0-next.1(transitive)
Updated@miniflare/core@2.9.0
Updated@miniflare/shared@2.9.0