@effectionx/websocket 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -0
- package/esm/mod.d.ts +2 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +1 -0
- package/esm/package.json +3 -0
- package/esm/websocket.d.ts +90 -0
- package/esm/websocket.d.ts.map +1 -0
- package/esm/websocket.js +60 -0
- package/package.json +29 -0
- package/script/mod.d.ts +2 -0
- package/script/mod.d.ts.map +1 -0
- package/script/mod.js +17 -0
- package/script/package.json +3 -0
- package/script/websocket.d.ts +90 -0
- package/script/websocket.d.ts.map +1 -0
- package/script/websocket.js +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# WebSocket
|
|
2
|
+
|
|
3
|
+
A streamlined [WebSocket][websocket] client for Effection programs that
|
|
4
|
+
transforms the event-based WebSocket API into a clean, resource-oriented stream.
|
|
5
|
+
|
|
6
|
+
## Why Use this API?
|
|
7
|
+
|
|
8
|
+
Traditional WebSocket API require managing multiple event handlers (`open`,
|
|
9
|
+
`close`, `error`, `message`) which can become complex and error-prone.
|
|
10
|
+
|
|
11
|
+
This package simplifies WebSocket usage by:
|
|
12
|
+
|
|
13
|
+
- Providing a clean stream-based interface
|
|
14
|
+
- Handling connection state management automatically
|
|
15
|
+
- Implementing proper error handling
|
|
16
|
+
- Ensuring resource cleanup
|
|
17
|
+
|
|
18
|
+
## Basic Usage
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { each, main } from "effection";
|
|
22
|
+
import { useWebSocket } from "@effectionx/websocket";
|
|
23
|
+
|
|
24
|
+
await main(function* () {
|
|
25
|
+
// Connection is guaranteed to be open when this returns
|
|
26
|
+
let socket = yield* useWebSocket("ws://websocket.example.org");
|
|
27
|
+
|
|
28
|
+
// Send messages to the server
|
|
29
|
+
socket.send("Hello World");
|
|
30
|
+
|
|
31
|
+
// Receive messages using a simple iterator
|
|
32
|
+
for (let message of yield* each(socket)) {
|
|
33
|
+
console.log("Message from server", message);
|
|
34
|
+
yield* each.next();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **Ready-to-use Connections**: `useWebSocket()` returns only after the
|
|
42
|
+
connection is established
|
|
43
|
+
- **Automatic Error Handling**: Socket errors are properly propagated to your
|
|
44
|
+
error boundary
|
|
45
|
+
- **Stream-based API**: Messages are delivered through a simple stream interface
|
|
46
|
+
- **Clean Resource Management**: Connections are properly cleaned up when the
|
|
47
|
+
operation completes
|
|
48
|
+
|
|
49
|
+
## Advanced Usage
|
|
50
|
+
|
|
51
|
+
### Custom WebSocket Implementations
|
|
52
|
+
|
|
53
|
+
For environments without native WebSocket support (like Node.js < 21), you can
|
|
54
|
+
provide your own WebSocket implementation:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { createWebSocket } from "my-websocket-client";
|
|
58
|
+
import { each, main } from "effection";
|
|
59
|
+
import { useWebSocket } from "@effectionx/websocket";
|
|
60
|
+
|
|
61
|
+
await main(function* () {
|
|
62
|
+
let socket = yield* useWebSocket(() =>
|
|
63
|
+
createWebSocket("ws://websocket.example.org")
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
for (let message of yield* each(socket)) {
|
|
67
|
+
console.log("Message from server", message);
|
|
68
|
+
yield* each.next();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
[websocket]: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
package/esm/mod.d.ts
ADDED
package/esm/mod.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
package/esm/mod.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./websocket.js";
|
package/esm/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Operation, Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Handle to a
|
|
4
|
+
* [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object
|
|
5
|
+
* that can be consumed as an Effection stream. It has all the same properties as
|
|
6
|
+
* the underlying `WebSocket` apart from the event handlers. Instead, the resource
|
|
7
|
+
* itself is a subscribale stream. When the socket is closed, the stream will
|
|
8
|
+
* complete with a [`CloseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent)
|
|
9
|
+
*
|
|
10
|
+
* A WebSocketResource does not have an explicit close method. Rather, the underlying
|
|
11
|
+
* socket will be automatically closed when the resource passes out of scope.
|
|
12
|
+
*/
|
|
13
|
+
export interface WebSocketResource<T> extends Stream<MessageEvent<T>, CloseEvent> {
|
|
14
|
+
/**
|
|
15
|
+
* the type of data that this websocket accepts
|
|
16
|
+
*/
|
|
17
|
+
readonly binaryType: BinaryType;
|
|
18
|
+
readonly bufferedAmmount: number;
|
|
19
|
+
readonly extensions: string;
|
|
20
|
+
readonly protocol: string;
|
|
21
|
+
readonly readyState: number;
|
|
22
|
+
readonly url: string;
|
|
23
|
+
send(data: WebSocketData): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
|
|
27
|
+
* resource using the native
|
|
28
|
+
* [WebSocket constructor](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket)
|
|
29
|
+
* available on the current platform.
|
|
30
|
+
*
|
|
31
|
+
* The resource will not be returned until a connection has been
|
|
32
|
+
* succesffuly established with the server and the
|
|
33
|
+
* [`open`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/open_event)
|
|
34
|
+
* has been received. Once initialized, it will crash if it receives
|
|
35
|
+
* an [`error`]() event at any time.
|
|
36
|
+
*
|
|
37
|
+
* Once created, the websocket resource can be use to consume events from the server:
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* let socket = yield* useWebSocket("ws://websocket.example.org");
|
|
41
|
+
*
|
|
42
|
+
* for (let event of yield* each(socket)) {
|
|
43
|
+
* console.log('event data: ', event.data);
|
|
44
|
+
* yield* each.next();
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @param url - The URL of the target WebSocket server to connect to. The URL must use one of the following schemes: ws, wss, http, or https, and cannot include a URL fragment. If a relative URL is provided, it is relative to the base URL of the calling script. For more detail, see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket#url
|
|
49
|
+
*
|
|
50
|
+
* @param prototol - A single string or an array of strings representing the sub-protocol(s) that the client would like to use, in order of preference. If it is omitted, an empty array is used by default, i.e. []. For more details, see
|
|
51
|
+
*
|
|
52
|
+
* @returns an operation yielding a {@link WebSocketResource}
|
|
53
|
+
*/
|
|
54
|
+
export declare function useWebSocket<T>(url: string, protocols?: string): Operation<WebSocketResource<T>>;
|
|
55
|
+
/**
|
|
56
|
+
* Create a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
|
|
57
|
+
* resource, but delegate the creation of the underlying websocket to a function
|
|
58
|
+
* of your choice. This is necessary on platforms that do not have a global
|
|
59
|
+
* `WebSocket` constructor such as NodeJS \<= 20.
|
|
60
|
+
*
|
|
61
|
+
* The resource will not be returned until a connection has been
|
|
62
|
+
* succesffuly established with the server and the
|
|
63
|
+
* [`open`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/open_event)
|
|
64
|
+
* has been received. Once initialized, it will crash if it receives
|
|
65
|
+
* an [`error`]() event at any time.
|
|
66
|
+
*
|
|
67
|
+
* Once created, the websocket resource can be use to consume events from the server:
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* import * as ws from 'ws';
|
|
71
|
+
*
|
|
72
|
+
* function* example() {
|
|
73
|
+
* let socket = yield* useWebSocket(() => new ws.WebSocket("ws://websocket.example.org"));
|
|
74
|
+
*
|
|
75
|
+
* for (let event of yield* each(socket)) {
|
|
76
|
+
* console.log('event data: ', event.data);
|
|
77
|
+
* yield* each.next();
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* ```
|
|
82
|
+
* @param create - a function that will construct the underlying [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object that this resource wil use
|
|
83
|
+
* @returns an operation yielding a {@link WebSocketResource}
|
|
84
|
+
*/
|
|
85
|
+
export declare function useWebSocket<T>(create: () => WebSocket): Operation<WebSocketResource<T>>;
|
|
86
|
+
/**
|
|
87
|
+
* @ignore
|
|
88
|
+
*/
|
|
89
|
+
export type WebSocketData = Parameters<WebSocket["send"]>[0];
|
|
90
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,CAClC,SAAQ,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;IAC3C;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,GACjB,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,MAAM,SAAS,GACtB,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAsEnC;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
package/esm/websocket.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createSignal, once, race, resource, spawn, withResolvers, } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* @ignore the catch-all version that supports both forms above.
|
|
4
|
+
*/
|
|
5
|
+
export function useWebSocket(url, protocols) {
|
|
6
|
+
return resource(function* (provide) {
|
|
7
|
+
let socket = typeof url === "string"
|
|
8
|
+
? new WebSocket(url, protocols)
|
|
9
|
+
: url();
|
|
10
|
+
let messages = createSignal();
|
|
11
|
+
let { operation: closed, resolve: close } = withResolvers();
|
|
12
|
+
yield* spawn(function* () {
|
|
13
|
+
throw yield* once(socket, "error");
|
|
14
|
+
});
|
|
15
|
+
yield* once(socket, "open");
|
|
16
|
+
yield* spawn(function* () {
|
|
17
|
+
let subscription = yield* messages;
|
|
18
|
+
let next = yield* subscription.next();
|
|
19
|
+
while (!next.done) {
|
|
20
|
+
next = yield* subscription.next();
|
|
21
|
+
}
|
|
22
|
+
close(next.value);
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
socket.addEventListener("message", messages.send);
|
|
26
|
+
socket.addEventListener("close", messages.close);
|
|
27
|
+
yield* race([
|
|
28
|
+
closed,
|
|
29
|
+
provide({
|
|
30
|
+
get binaryType() {
|
|
31
|
+
return socket.binaryType;
|
|
32
|
+
},
|
|
33
|
+
get bufferedAmmount() {
|
|
34
|
+
return socket.bufferedAmount;
|
|
35
|
+
},
|
|
36
|
+
get extensions() {
|
|
37
|
+
return socket.extensions;
|
|
38
|
+
},
|
|
39
|
+
get protocol() {
|
|
40
|
+
return socket.protocol;
|
|
41
|
+
},
|
|
42
|
+
get readyState() {
|
|
43
|
+
return socket.readyState;
|
|
44
|
+
},
|
|
45
|
+
get url() {
|
|
46
|
+
return socket.url;
|
|
47
|
+
},
|
|
48
|
+
send: (data) => socket.send(data),
|
|
49
|
+
[Symbol.iterator]: messages[Symbol.iterator],
|
|
50
|
+
}),
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
socket.close(1000, "released");
|
|
55
|
+
yield* closed;
|
|
56
|
+
socket.removeEventListener("message", messages.send);
|
|
57
|
+
socket.removeEventListener("close", messages.close);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@effectionx/websocket",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"author": "engineering@frontside.com",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/thefrontside/effectionx.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/thefrontside/effectionx/issues"
|
|
12
|
+
},
|
|
13
|
+
"main": "./script/mod.js",
|
|
14
|
+
"module": "./esm/mod.js",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./esm/mod.js",
|
|
18
|
+
"require": "./script/mod.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">= 16"
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"effection": "4.0.0-alpha.6"
|
|
27
|
+
},
|
|
28
|
+
"_generatedBy": "dnt@dev"
|
|
29
|
+
}
|
package/script/mod.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
package/script/mod.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./websocket.js"), exports);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Operation, Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Handle to a
|
|
4
|
+
* [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object
|
|
5
|
+
* that can be consumed as an Effection stream. It has all the same properties as
|
|
6
|
+
* the underlying `WebSocket` apart from the event handlers. Instead, the resource
|
|
7
|
+
* itself is a subscribale stream. When the socket is closed, the stream will
|
|
8
|
+
* complete with a [`CloseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent)
|
|
9
|
+
*
|
|
10
|
+
* A WebSocketResource does not have an explicit close method. Rather, the underlying
|
|
11
|
+
* socket will be automatically closed when the resource passes out of scope.
|
|
12
|
+
*/
|
|
13
|
+
export interface WebSocketResource<T> extends Stream<MessageEvent<T>, CloseEvent> {
|
|
14
|
+
/**
|
|
15
|
+
* the type of data that this websocket accepts
|
|
16
|
+
*/
|
|
17
|
+
readonly binaryType: BinaryType;
|
|
18
|
+
readonly bufferedAmmount: number;
|
|
19
|
+
readonly extensions: string;
|
|
20
|
+
readonly protocol: string;
|
|
21
|
+
readonly readyState: number;
|
|
22
|
+
readonly url: string;
|
|
23
|
+
send(data: WebSocketData): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
|
|
27
|
+
* resource using the native
|
|
28
|
+
* [WebSocket constructor](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket)
|
|
29
|
+
* available on the current platform.
|
|
30
|
+
*
|
|
31
|
+
* The resource will not be returned until a connection has been
|
|
32
|
+
* succesffuly established with the server and the
|
|
33
|
+
* [`open`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/open_event)
|
|
34
|
+
* has been received. Once initialized, it will crash if it receives
|
|
35
|
+
* an [`error`]() event at any time.
|
|
36
|
+
*
|
|
37
|
+
* Once created, the websocket resource can be use to consume events from the server:
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* let socket = yield* useWebSocket("ws://websocket.example.org");
|
|
41
|
+
*
|
|
42
|
+
* for (let event of yield* each(socket)) {
|
|
43
|
+
* console.log('event data: ', event.data);
|
|
44
|
+
* yield* each.next();
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @param url - The URL of the target WebSocket server to connect to. The URL must use one of the following schemes: ws, wss, http, or https, and cannot include a URL fragment. If a relative URL is provided, it is relative to the base URL of the calling script. For more detail, see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket#url
|
|
49
|
+
*
|
|
50
|
+
* @param prototol - A single string or an array of strings representing the sub-protocol(s) that the client would like to use, in order of preference. If it is omitted, an empty array is used by default, i.e. []. For more details, see
|
|
51
|
+
*
|
|
52
|
+
* @returns an operation yielding a {@link WebSocketResource}
|
|
53
|
+
*/
|
|
54
|
+
export declare function useWebSocket<T>(url: string, protocols?: string): Operation<WebSocketResource<T>>;
|
|
55
|
+
/**
|
|
56
|
+
* Create a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
|
|
57
|
+
* resource, but delegate the creation of the underlying websocket to a function
|
|
58
|
+
* of your choice. This is necessary on platforms that do not have a global
|
|
59
|
+
* `WebSocket` constructor such as NodeJS \<= 20.
|
|
60
|
+
*
|
|
61
|
+
* The resource will not be returned until a connection has been
|
|
62
|
+
* succesffuly established with the server and the
|
|
63
|
+
* [`open`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/open_event)
|
|
64
|
+
* has been received. Once initialized, it will crash if it receives
|
|
65
|
+
* an [`error`]() event at any time.
|
|
66
|
+
*
|
|
67
|
+
* Once created, the websocket resource can be use to consume events from the server:
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* import * as ws from 'ws';
|
|
71
|
+
*
|
|
72
|
+
* function* example() {
|
|
73
|
+
* let socket = yield* useWebSocket(() => new ws.WebSocket("ws://websocket.example.org"));
|
|
74
|
+
*
|
|
75
|
+
* for (let event of yield* each(socket)) {
|
|
76
|
+
* console.log('event data: ', event.data);
|
|
77
|
+
* yield* each.next();
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* ```
|
|
82
|
+
* @param create - a function that will construct the underlying [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object that this resource wil use
|
|
83
|
+
* @returns an operation yielding a {@link WebSocketResource}
|
|
84
|
+
*/
|
|
85
|
+
export declare function useWebSocket<T>(create: () => WebSocket): Operation<WebSocketResource<T>>;
|
|
86
|
+
/**
|
|
87
|
+
* @ignore
|
|
88
|
+
*/
|
|
89
|
+
export type WebSocketData = Parameters<WebSocket["send"]>[0];
|
|
90
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,CAClC,SAAQ,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;IAC3C;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,GACjB,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,MAAM,SAAS,GACtB,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAsEnC;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useWebSocket = useWebSocket;
|
|
4
|
+
const effection_1 = require("effection");
|
|
5
|
+
/**
|
|
6
|
+
* @ignore the catch-all version that supports both forms above.
|
|
7
|
+
*/
|
|
8
|
+
function useWebSocket(url, protocols) {
|
|
9
|
+
return (0, effection_1.resource)(function* (provide) {
|
|
10
|
+
let socket = typeof url === "string"
|
|
11
|
+
? new WebSocket(url, protocols)
|
|
12
|
+
: url();
|
|
13
|
+
let messages = (0, effection_1.createSignal)();
|
|
14
|
+
let { operation: closed, resolve: close } = (0, effection_1.withResolvers)();
|
|
15
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
16
|
+
throw yield* (0, effection_1.once)(socket, "error");
|
|
17
|
+
});
|
|
18
|
+
yield* (0, effection_1.once)(socket, "open");
|
|
19
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
20
|
+
let subscription = yield* messages;
|
|
21
|
+
let next = yield* subscription.next();
|
|
22
|
+
while (!next.done) {
|
|
23
|
+
next = yield* subscription.next();
|
|
24
|
+
}
|
|
25
|
+
close(next.value);
|
|
26
|
+
});
|
|
27
|
+
try {
|
|
28
|
+
socket.addEventListener("message", messages.send);
|
|
29
|
+
socket.addEventListener("close", messages.close);
|
|
30
|
+
yield* (0, effection_1.race)([
|
|
31
|
+
closed,
|
|
32
|
+
provide({
|
|
33
|
+
get binaryType() {
|
|
34
|
+
return socket.binaryType;
|
|
35
|
+
},
|
|
36
|
+
get bufferedAmmount() {
|
|
37
|
+
return socket.bufferedAmount;
|
|
38
|
+
},
|
|
39
|
+
get extensions() {
|
|
40
|
+
return socket.extensions;
|
|
41
|
+
},
|
|
42
|
+
get protocol() {
|
|
43
|
+
return socket.protocol;
|
|
44
|
+
},
|
|
45
|
+
get readyState() {
|
|
46
|
+
return socket.readyState;
|
|
47
|
+
},
|
|
48
|
+
get url() {
|
|
49
|
+
return socket.url;
|
|
50
|
+
},
|
|
51
|
+
send: (data) => socket.send(data),
|
|
52
|
+
[Symbol.iterator]: messages[Symbol.iterator],
|
|
53
|
+
}),
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
socket.close(1000, "released");
|
|
58
|
+
yield* closed;
|
|
59
|
+
socket.removeEventListener("message", messages.send);
|
|
60
|
+
socket.removeEventListener("close", messages.close);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|