iosignal 3.0.0 → 3.1.0

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.
Files changed (57) hide show
  1. package/README.ko.md +566 -0
  2. package/README.md +561 -2
  3. package/dist/io.d.ts +481 -0
  4. package/dist/io.js +3 -3
  5. package/dist/io.js.map +1 -1
  6. package/dist/io.min.js +3 -3
  7. package/dist/io.min.js.map +1 -1
  8. package/dist/iosignal.js +558 -104
  9. package/dist/types/client/IOCore.d.ts +408 -0
  10. package/dist/types/client/browser/IOWebSocket.d.ts +75 -0
  11. package/dist/types/common/constants.d.ts +169 -0
  12. package/dist/types/common/payload.d.ts +6 -0
  13. package/dist/types/common/quotaTable.d.ts +47 -0
  14. package/examples/react-chat-js/dist/assets/index-Cy4qaVcJ.js +56 -0
  15. package/examples/react-chat-js/dist/assets/index-NETrjYhz.css +1 -0
  16. package/examples/react-chat-js/dist/index.html +14 -0
  17. package/examples/react-chat-js/index.html +13 -0
  18. package/examples/react-chat-js/package-lock.json +1723 -0
  19. package/examples/react-chat-js/package.json +20 -0
  20. package/examples/react-chat-js/src/App.css +61 -0
  21. package/examples/react-chat-js/src/App.jsx +125 -0
  22. package/examples/react-chat-js/src/index.css +13 -0
  23. package/examples/react-chat-js/src/main.jsx +13 -0
  24. package/examples/react-chat-js/src/shared_io.js +12 -0
  25. package/examples/react-chat-js/vite.config.js +7 -0
  26. package/examples/server/index.js +12 -0
  27. package/examples/server/package-lock.json +47 -0
  28. package/examples/server/package.json +12 -0
  29. package/examples/svelte-chat-js/.devtools +3 -0
  30. package/examples/svelte-chat-js/README.md +38 -0
  31. package/examples/svelte-chat-js/package-lock.json +1505 -0
  32. package/examples/svelte-chat-js/package.json +22 -0
  33. package/examples/svelte-chat-js/src/app.css +105 -0
  34. package/examples/svelte-chat-js/src/app.d.ts +13 -0
  35. package/examples/svelte-chat-js/src/app.html +12 -0
  36. package/examples/svelte-chat-js/src/lib/images/github.svg +1 -0
  37. package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +1 -0
  38. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
  39. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
  40. package/examples/svelte-chat-js/src/lib/shared_io.js +12 -0
  41. package/examples/svelte-chat-js/src/routes/+layout.svelte +9 -0
  42. package/examples/svelte-chat-js/src/routes/+page.js +3 -0
  43. package/examples/svelte-chat-js/src/routes/+page.svelte +162 -0
  44. package/examples/svelte-chat-js/static/favicon.svg +1 -0
  45. package/examples/svelte-chat-js/static/global.css +19 -0
  46. package/examples/svelte-chat-js/static/robots.txt +3 -0
  47. package/examples/svelte-chat-js/svelte.config.js +15 -0
  48. package/examples/svelte-chat-js/vite.config.js +6 -0
  49. package/package.json +9 -3
  50. package/rollup.config.js +11 -4
  51. package/src/client/IOCongSocket.js +20 -9
  52. package/src/client/IOCore.js +437 -79
  53. package/src/client/IOWS.js +12 -15
  54. package/src/client/browser/IOWebSocket.js +101 -17
  55. package/src/common/constants.js +91 -1
  56. package/tsconfig.json +24 -0
  57. package/docs/README.kr.md +0 -230
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "svelte-chat-js",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "preview": "vite preview",
10
+ "prepare": "svelte-kit sync || echo ''"
11
+ },
12
+ "devDependencies": {
13
+ "@sveltejs/adapter-auto": "^6.0.0",
14
+ "@sveltejs/kit": "^2.22.0",
15
+ "@sveltejs/vite-plugin-svelte": "^6.0.0",
16
+ "svelte": "^5.0.0",
17
+ "vite": "^7.0.4"
18
+ },
19
+ "dependencies": {
20
+ "iosignal": "file:../.."
21
+ }
22
+ }
@@ -0,0 +1,105 @@
1
+ @import '@fontsource/fira-mono';
2
+
3
+ :root {
4
+ --font-body:
5
+ Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
6
+ 'Open Sans', 'Helvetica Neue', sans-serif;
7
+ --font-mono: 'Fira Mono', monospace;
8
+ --color-bg-0: rgb(202, 216, 228);
9
+ --color-bg-1: hsl(209, 36%, 86%);
10
+ --color-bg-2: hsl(224, 44%, 95%);
11
+ --color-theme-1: #ff3e00;
12
+ --color-theme-2: #4075a6;
13
+ --color-text: rgba(0, 0, 0, 0.7);
14
+ --column-width: 42rem;
15
+ --column-margin-top: 4rem;
16
+ font-family: var(--font-body);
17
+ color: var(--color-text);
18
+ }
19
+
20
+ body {
21
+ min-height: 100vh;
22
+ margin: 0;
23
+ background-attachment: fixed;
24
+ background-color: var(--color-bg-1);
25
+ background-size: 100vw 100vh;
26
+ background-image:
27
+ radial-gradient(50% 50% at 50% 50%, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0) 100%),
28
+ linear-gradient(180deg, var(--color-bg-0) 0%, var(--color-bg-1) 15%, var(--color-bg-2) 50%);
29
+ }
30
+
31
+ h1,
32
+ h2,
33
+ p {
34
+ font-weight: 400;
35
+ }
36
+
37
+ p {
38
+ line-height: 1.5;
39
+ }
40
+
41
+ a {
42
+ color: var(--color-theme-1);
43
+ text-decoration: none;
44
+ }
45
+
46
+ a:hover {
47
+ text-decoration: underline;
48
+ }
49
+
50
+ h1 {
51
+ font-size: 2rem;
52
+ text-align: center;
53
+ }
54
+
55
+ h2 {
56
+ font-size: 1rem;
57
+ }
58
+
59
+ pre {
60
+ font-size: 16px;
61
+ font-family: var(--font-mono);
62
+ background-color: rgba(255, 255, 255, 0.45);
63
+ border-radius: 3px;
64
+ box-shadow: 2px 2px 6px rgb(255 255 255 / 25%);
65
+ padding: 0.5em;
66
+ overflow-x: auto;
67
+ color: var(--color-text);
68
+ }
69
+
70
+ .text-column {
71
+ display: flex;
72
+ max-width: 48rem;
73
+ flex: 0.6;
74
+ flex-direction: column;
75
+ justify-content: center;
76
+ margin: 0 auto;
77
+ }
78
+
79
+ input,
80
+ button {
81
+ font-size: inherit;
82
+ font-family: inherit;
83
+ }
84
+
85
+ button:focus:not(:focus-visible) {
86
+ outline: none;
87
+ }
88
+
89
+ @media (min-width: 720px) {
90
+ h1 {
91
+ font-size: 2.4rem;
92
+ }
93
+ }
94
+
95
+ .visually-hidden {
96
+ border: 0;
97
+ clip: rect(0 0 0 0);
98
+ height: auto;
99
+ margin: 0;
100
+ overflow: hidden;
101
+ padding: 0;
102
+ position: absolute;
103
+ width: 1px;
104
+ white-space: nowrap;
105
+ }
@@ -0,0 +1,13 @@
1
+ // See https://svelte.dev/docs/kit/types#app.d.ts
2
+ // for information about these interfaces
3
+ declare global {
4
+ namespace App {
5
+ // interface Error {}
6
+ // interface Locals {}
7
+ // interface PageData {}
8
+ // interface PageState {}
9
+ // interface Platform {}
10
+ }
11
+ }
12
+
13
+ export {};
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="%sveltekit.assets%/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ %sveltekit.head%
8
+ </head>
9
+ <body data-sveltekit-preload-data="hover">
10
+ <div style="display: contents">%sveltekit.body%</div>
11
+ </body>
12
+ </html>
@@ -0,0 +1 @@
1
+ <svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/></svg>
@@ -0,0 +1,12 @@
1
+ import IO from 'iosignal/io.js'
2
+
3
+
4
+ const url = 'ws://localhost:7777';
5
+ const io = new IO(url);
6
+ const channel = 'chat';
7
+
8
+
9
+ console.log('IO instance created:', io);
10
+
11
+ export { io, channel};
12
+
@@ -0,0 +1,9 @@
1
+ <script>
2
+ let { children } = $props();
3
+ </script>
4
+
5
+ <svelte:head>
6
+ <link rel="stylesheet" href="/global.css" />
7
+ </svelte:head>
8
+
9
+ {@render children()}
@@ -0,0 +1,3 @@
1
+ // since there's no dynamic data here, we can prerender
2
+ // it so that it gets served as a static asset in production
3
+ export const prerender = true;
@@ -0,0 +1,162 @@
1
+ <script>
2
+ import { dev, browser } from "$app/environment";
3
+ import IO from "iosignal/io.js";
4
+
5
+ // const url = 'ws://192.168.0.15:7777';
6
+ const url = "ws://localhost:7777";
7
+ const channel_tag = "channel#topic";
8
+
9
+ let messages = $state([]);
10
+ let input = $state("Hello, World!");
11
+ let ioState = $state(null);
12
+ let cid = $state(null);
13
+ let counts = $state({ instances: 0, websockets: 0 });
14
+ let io = null;
15
+ let messagesEnd;
16
+
17
+ const scrollToBottom = () => {
18
+ messagesEnd?.scrollIntoView({ behavior: "smooth" });
19
+ };
20
+
21
+ if (browser) {
22
+ io = new IO(url);
23
+ if (dev)
24
+ console.log("new io:", IO.version, IO.instanceCount, IO.webSocketCount);
25
+
26
+ counts = { instances: IO.instanceCount, websockets: IO.webSocketCount };
27
+
28
+ const handleReady = () => {
29
+ console.log("ready cid:", io.cid);
30
+ cid = io.cid;
31
+ io.subscribe(channel_tag);
32
+ };
33
+
34
+ const handleChange = (state) => {
35
+ ioState = state;
36
+ counts = { instances: IO.instanceCount, websockets: IO.webSocketCount };
37
+ };
38
+
39
+ const handleChannelMessage = (msgObj, tag) => {
40
+ console.log("Received message in App:", msgObj, tag);
41
+ messages = [...messages, `${msgObj.cid} : ${msgObj.text}`];
42
+ scrollToBottom();
43
+ };
44
+
45
+ const handleError = (error) => {
46
+ console.error("IO Error in App:", error);
47
+ ioState = `Error: ${error.message}`;
48
+ };
49
+
50
+ io.on("ready", handleReady);
51
+ io.on("change", handleChange);
52
+ io.on(channel_tag, handleChannelMessage);
53
+ io.on("error", handleError);
54
+
55
+ $effect(() => {
56
+ return () => {
57
+ io.destroy();
58
+ io = null;
59
+ };
60
+ });
61
+ }
62
+
63
+ const sendMessage = () => {
64
+ if (input.trim()) {
65
+ // console.log('Sending message:', input);
66
+ const msgObj = { text: input, cid: io.cid };
67
+ // console.log('Sending message object:', msgObj);
68
+ io.signal(channel_tag, msgObj);
69
+ input = "date" + Date.now();
70
+ }
71
+ };
72
+
73
+ let ioStateStyle = $derived(
74
+ `color: ${ioState === "ready" ? "green" : "red"}; font-weight: bold;`,
75
+ );
76
+ </script>
77
+
78
+ <div class="App">
79
+ <h1>Svelte 5 Chat Example</h1>
80
+ <div>URL: {url}</div>
81
+ <div>Channel: {channel_tag}</div>
82
+ <div>IO State: <span style={ioStateStyle}>{ioState}</span></div>
83
+ <div>Client ID: {cid}</div>
84
+ <div>IO Instances: {counts.instances}</div>
85
+ <div>WebSockets Created: {counts.websockets}</div>
86
+ <div class="messages">
87
+ {#each messages as msg, index (index)}
88
+ <div>{msg}</div>
89
+ {/each}
90
+ <div bind:this={messagesEnd}></div>
91
+ </div>
92
+ <div class="input-area">
93
+ <input
94
+ type="text"
95
+ bind:value={input}
96
+ onkeyup={(e) => e.key === "Enter" && sendMessage()}
97
+ disabled={ioState !== "ready"}
98
+ />
99
+ <button onclick={sendMessage} disabled={ioState !== "ready"}> Send </button>
100
+ </div>
101
+ </div>
102
+
103
+ <style>
104
+ .App {
105
+ height: 100%;
106
+ margin: 0;
107
+ display: flex;
108
+ flex-direction: column;
109
+ padding: 20px;
110
+ box-sizing: border-box;
111
+ }
112
+
113
+ h1 {
114
+ margin-top: 0;
115
+ color: #333;
116
+ }
117
+
118
+ .messages {
119
+ flex-grow: 1;
120
+ border: 1px solid #ccc;
121
+ padding: 10px;
122
+ overflow-y: auto;
123
+ margin-bottom: 10px;
124
+ display: flex;
125
+ flex-direction: column;
126
+ justify-content: flex-end;
127
+ }
128
+
129
+ .messages div {
130
+ background-color: #f0f0f0;
131
+ padding: 8px;
132
+ margin-bottom: 5px;
133
+ border-radius: 5px;
134
+ text-align: left;
135
+ }
136
+
137
+ .input-area {
138
+ display: flex;
139
+ gap: 10px;
140
+ margin-top: auto;
141
+ }
142
+
143
+ .input-area input {
144
+ flex-grow: 1;
145
+ padding: 10px;
146
+ border: 1px solid #ccc;
147
+ border-radius: 5px;
148
+ }
149
+
150
+ .input-area button {
151
+ padding: 10px 15px;
152
+ background-color: #007bff;
153
+ color: white;
154
+ border: none;
155
+ border-radius: 5px;
156
+ cursor: pointer;
157
+ }
158
+
159
+ .input-area button:hover {
160
+ background-color: #0056b3;
161
+ }
162
+ </style>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116" style="fill:#ff3e00"/><path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328" style="fill:#fff"/></svg>
@@ -0,0 +1,19 @@
1
+ html, body, #root, .App {
2
+ height: 100%;
3
+ margin: 0;
4
+ display: flex;
5
+ flex-direction: column;
6
+ }
7
+
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
10
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
11
+ sans-serif;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ code {
17
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
18
+ monospace;
19
+ }
@@ -0,0 +1,3 @@
1
+ # allow crawling everything by default
2
+ User-agent: *
3
+ Disallow:
@@ -0,0 +1,15 @@
1
+ import adapter from '@sveltejs/adapter-auto';
2
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3
+
4
+ /** @type {import('@sveltejs/kit').Config} */
5
+ const config = {
6
+ compilerOptions: {
7
+ runes: true
8
+ },
9
+ kit: {
10
+ adapter: adapter()
11
+ },
12
+ preprocess: vitePreprocess()
13
+ };
14
+
15
+ export default config;
@@ -0,0 +1,6 @@
1
+ import { sveltekit } from '@sveltejs/kit/vite';
2
+ import { defineConfig } from 'vite';
3
+
4
+ export default defineConfig({
5
+ plugins: [sveltekit()]
6
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iosignal",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "iosignal",
5
5
  "type": "module",
6
6
  "exports": {
@@ -12,11 +12,13 @@
12
12
  "./io.js": "./dist/io.js",
13
13
  "./browser": "./dist/io.js"
14
14
  },
15
+ "types": "./dist/types/src/client/browser/IOWebSocket.d.ts",
15
16
  "browser": "./dist/io.min.js",
16
17
  "jsdelivr": "./dist/io.min.js",
17
18
  "unpkg": "./dist/io.min.js",
18
19
  "scripts": {
19
- "build": "rollup -c",
20
+ "build": "rollup -c && npm run build:types",
21
+ "build:types": "tsc --project tsconfig.json",
20
22
  "start": "node ./test-browser/server.js"
21
23
  },
22
24
  "engines": {
@@ -31,8 +33,12 @@
31
33
  "@rollup/plugin-commonjs": "^28.0.0",
32
34
  "@rollup/plugin-json": "^6.1.0",
33
35
  "@rollup/plugin-node-resolve": "^15.3.0",
36
+ "@rollup/plugin-replace": "^6.0.1",
34
37
  "@rollup/plugin-terser": "^0.4.4",
35
- "rollup": "^4.36.0"
38
+ "@types/node": "^24.1.0",
39
+ "rollup": "^4.36.0",
40
+ "rollup-plugin-dts": "^6.2.1",
41
+ "typescript": "^5.8.3"
36
42
  },
37
43
  "dependencies": {
38
44
  "boho": "^1.1.1",
package/rollup.config.js CHANGED
@@ -2,9 +2,10 @@ import resolve from '@rollup/plugin-node-resolve'
2
2
  import commonjs from '@rollup/plugin-commonjs'
3
3
  import json from '@rollup/plugin-json'
4
4
  import terser from '@rollup/plugin-terser'
5
+ import dts from 'rollup-plugin-dts'
5
6
 
6
7
  export default [
7
- {
8
+ {
8
9
  input: './src/client/browser/IOWebSocket.js',
9
10
  output: [
10
11
  {
@@ -23,12 +24,18 @@ export default [
23
24
  resolve({
24
25
  preferBuiltins: false
25
26
  }),
26
- json(),
27
- commonjs()
28
- ,terser()
27
+ commonjs(),
28
+ json(),
29
+ terser()
29
30
  ]
30
31
  },
31
32
  {
33
+ input: './src/client/browser/IOWebSocket.js',
34
+ output: { file: './dist/io.d.ts', format: 'es' },
35
+ plugins: [dts()]
36
+ }
37
+
38
+ ,{
32
39
  input: './index.js',
33
40
  output: [
34
41
  { file: './dist/iosignal.js', format: 'es' }
@@ -1,4 +1,5 @@
1
1
  import { IOCore } from "./IOCore.js"
2
+ import { STATES } from "../common/constants.js";
2
3
  import { pack, CongRx } from './CongPacket.js'
3
4
  import net from 'net'
4
5
 
@@ -9,20 +10,30 @@ export class IOCongSocket extends IOCore {
9
10
  if (url) this.open();
10
11
  }
11
12
 
13
+ /**
14
+ * Closes TCP socket and cleans resources.
15
+ */
12
16
  close() {
13
- this.socket?.end();
14
- this.socket = null;
17
+ if (this.socket) {
18
+ if (this.congRx) {
19
+ this.socket.unpipe(this.congRx);
20
+ this.congRx.destroy(); // Use destroy() for complete stream cleanup
21
+ this.congRx = null;
22
+ }
23
+ this.socket.removeAllListeners();
24
+ if (!this.socket.destroyed) {
25
+ this.socket.destroy(); // destroy() is sufficient for forceful closing
26
+ }
27
+ }
28
+ super.close();
15
29
  }
16
30
 
17
- stop() {
18
- this.close()
19
- clearInterval(this.connectionCheckerIntervalID);
20
- this.connectionCheckerIntervalID = null
21
- }
31
+
22
32
 
23
33
  keepAlive() {
24
- let state = this.socket?.readyState;
25
- if (!this.socket || !(state === 'open' || state === 'opening')) {
34
+ if (!this.autoReconnect) return;
35
+ // Reconnect only if the socket is fully destroyed and the state is closed.
36
+ if ((!this.socket || this.socket.destroyed) && this.state === STATES.CLOSED) {
26
37
  this.open();
27
38
  }
28
39
  }