iosignal 3.0.1 → 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.
- package/{docs/README.ko.md → README.ko.md} +204 -9
- package/README.md +424 -8
- package/dist/io.js +1 -1
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +1 -1
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +19 -6
- package/examples/react-chat-js/package-lock.json +311 -216
- package/examples/react-chat-js/package.json +6 -6
- package/examples/react-chat-js/src/App.jsx +4 -4
- package/examples/server/package-lock.json +47 -0
- package/examples/svelte-chat-js/.devtools +3 -0
- package/examples/svelte-chat-js/README.md +38 -0
- package/examples/svelte-chat-js/package-lock.json +1505 -0
- package/examples/svelte-chat-js/package.json +22 -0
- package/examples/svelte-chat-js/src/app.css +105 -0
- package/examples/svelte-chat-js/src/app.d.ts +13 -0
- package/examples/svelte-chat-js/src/app.html +12 -0
- package/examples/svelte-chat-js/src/lib/images/github.svg +1 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +1 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
- package/examples/svelte-chat-js/src/lib/shared_io.js +12 -0
- package/examples/svelte-chat-js/src/routes/+layout.svelte +9 -0
- package/examples/svelte-chat-js/src/routes/+page.js +3 -0
- package/examples/svelte-chat-js/src/routes/+page.svelte +162 -0
- package/examples/svelte-chat-js/static/favicon.svg +1 -0
- package/examples/svelte-chat-js/static/global.css +19 -0
- package/examples/svelte-chat-js/static/robots.txt +3 -0
- package/examples/svelte-chat-js/svelte.config.js +15 -0
- package/examples/svelte-chat-js/vite.config.js +6 -0
- package/package.json +1 -1
- package/src/client/IOCore.js +18 -5
- package/src/client/browser/IOWebSocket.js +1 -16
|
@@ -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>
|
|
Binary file
|
|
Binary file
|
|
@@ -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,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;
|
package/package.json
CHANGED
package/src/client/IOCore.js
CHANGED
|
@@ -216,9 +216,22 @@ export class IOCore extends EventEmitter {
|
|
|
216
216
|
|
|
217
217
|
// socket clean
|
|
218
218
|
if (this.socket) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
219
|
+
// For WebSockets, readyState are: 0-CONNECTING, 1-OPEN, 2-CLOSING, 3-CLOSED
|
|
220
|
+
// Calling close() on a CONNECTING socket will cause a browser error.
|
|
221
|
+
if (this.socket.readyState === 0) { // 0 is WebSocket.CONNECTING
|
|
222
|
+
// To avoid the error, we wait for the connection to open, then immediately close it.
|
|
223
|
+
// We also clear other handlers to prevent any other logic from running.
|
|
224
|
+
const socket = this.socket;
|
|
225
|
+
socket.onopen = () => { if(socket) socket.close(); };
|
|
226
|
+
socket.onmessage = null;
|
|
227
|
+
socket.onerror = null;
|
|
228
|
+
socket.onclose = null;
|
|
229
|
+
} else {
|
|
230
|
+
try {
|
|
231
|
+
// For other sockets (like TCP) or other WebSocket states, close directly.
|
|
232
|
+
this.socket.close?.();
|
|
233
|
+
} catch {}
|
|
234
|
+
}
|
|
222
235
|
this.socket = null;
|
|
223
236
|
}
|
|
224
237
|
this.promiseMap.clear();
|
|
@@ -385,8 +398,8 @@ export class IOCore extends EventEmitter {
|
|
|
385
398
|
// console.log( 'ENC_E2E decoded ', decoded )
|
|
386
399
|
msgType = decoded[0]
|
|
387
400
|
// decoded has msg_header only.
|
|
388
|
-
buffer.set(decoded, Boho.MetaSize.ENC_488) // set decoded signal_e2e headaer.
|
|
389
|
-
buffer = buffer.subarray(Boho.MetaSize.ENC_488) // reset offset.
|
|
401
|
+
buffer.set(decoded, Boho.MetaSize.ENC_488) // set decoded signal_e2e headaer.
|
|
402
|
+
buffer = buffer.subarray(Boho.MetaSize.ENC_488) // reset offset.
|
|
390
403
|
// console.log('DECODED MsgType:', IOMsg[ msgType ] )
|
|
391
404
|
} else {
|
|
392
405
|
// console.log('488 DEC_FAIL', buffer)
|
|
@@ -83,22 +83,7 @@ export default class IO extends IOCore {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
* Closes the WebSocket connection and cleans up its event handlers.
|
|
88
|
-
* This is intended for temporary disconnections, and the connection might be re-established by keepAlive.
|
|
89
|
-
*/
|
|
90
|
-
close() {
|
|
91
|
-
if (this.socket) {
|
|
92
|
-
this.socket.onopen = null;
|
|
93
|
-
this.socket.onclose = null;
|
|
94
|
-
this.socket.onmessage = null;
|
|
95
|
-
this.socket.onerror = null;
|
|
96
|
-
if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {
|
|
97
|
-
this.socket.close();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
super.close();
|
|
101
|
-
}
|
|
86
|
+
|
|
102
87
|
|
|
103
88
|
/**
|
|
104
89
|
* Permanently stops the connection and cleans up its specific resources.
|