redux-cluster-ws 2.0.0 ā 2.0.2
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/package.json +8 -3
- package/FUNDING.yml +0 -7
- package/eslint.config.js +0 -143
- package/examples/browser-example.cjs +0 -350
- package/examples/browser.html +0 -255
- package/examples/client.cjs +0 -155
- package/examples/cross-library-browser.html +0 -655
- package/examples/cross-library-client.cjs +0 -190
- package/examples/cross-library-server.cjs +0 -213
- package/examples/server.cjs +0 -96
package/examples/browser.html
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Redux-Cluster-WS Browser Example</title>
|
|
7
|
-
<style>
|
|
8
|
-
body {
|
|
9
|
-
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
|
10
|
-
max-width: 800px;
|
|
11
|
-
margin: 0 auto;
|
|
12
|
-
padding: 20px;
|
|
13
|
-
background-color: #f5f5f5;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.container {
|
|
17
|
-
background: white;
|
|
18
|
-
padding: 30px;
|
|
19
|
-
border-radius: 10px;
|
|
20
|
-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
h1 {
|
|
24
|
-
color: #333;
|
|
25
|
-
text-align: center;
|
|
26
|
-
margin-bottom: 30px;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.status {
|
|
30
|
-
padding: 15px;
|
|
31
|
-
border-radius: 5px;
|
|
32
|
-
margin-bottom: 20px;
|
|
33
|
-
font-weight: bold;
|
|
34
|
-
text-align: center;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.connected {
|
|
38
|
-
background-color: #d4edda;
|
|
39
|
-
color: #155724;
|
|
40
|
-
border: 1px solid #c3e6cb;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.disconnected {
|
|
44
|
-
background-color: #f8d7da;
|
|
45
|
-
color: #721c24;
|
|
46
|
-
border: 1px solid #f5c6cb;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.connecting {
|
|
50
|
-
background-color: #fff3cd;
|
|
51
|
-
color: #856404;
|
|
52
|
-
border: 1px solid #ffeaa7;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.counter-display {
|
|
56
|
-
text-align: center;
|
|
57
|
-
margin: 30px 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.counter-value {
|
|
61
|
-
font-size: 48px;
|
|
62
|
-
font-weight: bold;
|
|
63
|
-
color: #007bff;
|
|
64
|
-
margin: 20px 0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.last-update {
|
|
68
|
-
color: #666;
|
|
69
|
-
font-size: 14px;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.controls {
|
|
73
|
-
display: flex;
|
|
74
|
-
gap: 10px;
|
|
75
|
-
justify-content: center;
|
|
76
|
-
margin: 30px 0;
|
|
77
|
-
flex-wrap: wrap;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
button {
|
|
81
|
-
background-color: #007bff;
|
|
82
|
-
color: white;
|
|
83
|
-
border: none;
|
|
84
|
-
padding: 12px 24px;
|
|
85
|
-
border-radius: 5px;
|
|
86
|
-
cursor: pointer;
|
|
87
|
-
font-size: 16px;
|
|
88
|
-
min-width: 120px;
|
|
89
|
-
transition: background-color 0.3s;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
button:hover:not(:disabled) {
|
|
93
|
-
background-color: #0056b3;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
button:disabled {
|
|
97
|
-
background-color: #6c757d;
|
|
98
|
-
cursor: not-allowed;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.increment {
|
|
102
|
-
background-color: #28a745;
|
|
103
|
-
}
|
|
104
|
-
.increment:hover:not(:disabled) {
|
|
105
|
-
background-color: #218838;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.decrement {
|
|
109
|
-
background-color: #dc3545;
|
|
110
|
-
}
|
|
111
|
-
.decrement:hover:not(:disabled) {
|
|
112
|
-
background-color: #c82333;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.reset {
|
|
116
|
-
background-color: #ffc107;
|
|
117
|
-
color: #212529;
|
|
118
|
-
}
|
|
119
|
-
.reset:hover:not(:disabled) {
|
|
120
|
-
background-color: #e0a800;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.connection-form {
|
|
124
|
-
background-color: #f8f9fa;
|
|
125
|
-
padding: 20px;
|
|
126
|
-
border-radius: 5px;
|
|
127
|
-
margin-bottom: 20px;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.form-group {
|
|
131
|
-
margin-bottom: 15px;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
label {
|
|
135
|
-
display: block;
|
|
136
|
-
margin-bottom: 5px;
|
|
137
|
-
font-weight: bold;
|
|
138
|
-
color: #333;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
input {
|
|
142
|
-
width: 100%;
|
|
143
|
-
padding: 8px 12px;
|
|
144
|
-
border: 1px solid #ddd;
|
|
145
|
-
border-radius: 4px;
|
|
146
|
-
font-size: 14px;
|
|
147
|
-
box-sizing: border-box;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.log {
|
|
151
|
-
background-color: #f8f9fa;
|
|
152
|
-
border: 1px solid #dee2e6;
|
|
153
|
-
border-radius: 5px;
|
|
154
|
-
padding: 15px;
|
|
155
|
-
margin-top: 20px;
|
|
156
|
-
max-height: 200px;
|
|
157
|
-
overflow-y: auto;
|
|
158
|
-
font-family: "Courier New", monospace;
|
|
159
|
-
font-size: 12px;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.log-entry {
|
|
163
|
-
margin-bottom: 5px;
|
|
164
|
-
padding: 2px 0;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.log-info {
|
|
168
|
-
color: #17a2b8;
|
|
169
|
-
}
|
|
170
|
-
.log-success {
|
|
171
|
-
color: #28a745;
|
|
172
|
-
}
|
|
173
|
-
.log-warning {
|
|
174
|
-
color: #ffc107;
|
|
175
|
-
}
|
|
176
|
-
.log-error {
|
|
177
|
-
color: #dc3545;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
@media (max-width: 600px) {
|
|
181
|
-
.controls {
|
|
182
|
-
flex-direction: column;
|
|
183
|
-
align-items: center;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
button {
|
|
187
|
-
width: 100%;
|
|
188
|
-
max-width: 300px;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
</style>
|
|
192
|
-
</head>
|
|
193
|
-
<body>
|
|
194
|
-
<div class="container">
|
|
195
|
-
<h1>š Redux-Cluster-WS Browser Example</h1>
|
|
196
|
-
|
|
197
|
-
<div id="status" class="status disconnected">Disconnected</div>
|
|
198
|
-
|
|
199
|
-
<div class="connection-form">
|
|
200
|
-
<h3>Connection Settings</h3>
|
|
201
|
-
<div class="form-group">
|
|
202
|
-
<label for="host">Server Host:</label>
|
|
203
|
-
<input
|
|
204
|
-
type="text"
|
|
205
|
-
id="host"
|
|
206
|
-
value="ws://localhost"
|
|
207
|
-
placeholder="ws://localhost"
|
|
208
|
-
/>
|
|
209
|
-
</div>
|
|
210
|
-
<div class="form-group">
|
|
211
|
-
<label for="port">Port:</label>
|
|
212
|
-
<input type="number" id="port" value="8080" placeholder="8080" />
|
|
213
|
-
</div>
|
|
214
|
-
<div class="form-group">
|
|
215
|
-
<label for="login">Login:</label>
|
|
216
|
-
<input type="text" id="login" value="demo" placeholder="demo" />
|
|
217
|
-
</div>
|
|
218
|
-
<div class="form-group">
|
|
219
|
-
<label for="password">Password:</label>
|
|
220
|
-
<input
|
|
221
|
-
type="password"
|
|
222
|
-
id="password"
|
|
223
|
-
value="demo"
|
|
224
|
-
placeholder="demo"
|
|
225
|
-
/>
|
|
226
|
-
</div>
|
|
227
|
-
<button onclick="toggleConnection()" id="connectBtn">Connect</button>
|
|
228
|
-
</div>
|
|
229
|
-
|
|
230
|
-
<div class="counter-display">
|
|
231
|
-
<h2>Counter Value</h2>
|
|
232
|
-
<div class="counter-value" id="counterValue">0</div>
|
|
233
|
-
<div class="last-update" id="lastUpdate">Never updated</div>
|
|
234
|
-
</div>
|
|
235
|
-
|
|
236
|
-
<div class="controls">
|
|
237
|
-
<button class="increment" onclick="increment()" id="incBtn" disabled>
|
|
238
|
-
ā Increment
|
|
239
|
-
</button>
|
|
240
|
-
<button class="decrement" onclick="decrement()" id="decBtn" disabled>
|
|
241
|
-
ā Decrement
|
|
242
|
-
</button>
|
|
243
|
-
<button class="reset" onclick="reset()" id="resetBtn" disabled>
|
|
244
|
-
š Reset
|
|
245
|
-
</button>
|
|
246
|
-
</div>
|
|
247
|
-
|
|
248
|
-
<div class="log" id="log">
|
|
249
|
-
<div class="log-entry log-info">Ready to connect...</div>
|
|
250
|
-
</div>
|
|
251
|
-
</div>
|
|
252
|
-
|
|
253
|
-
<script src="browser-example.js"></script>
|
|
254
|
-
</body>
|
|
255
|
-
</html>
|
package/examples/client.cjs
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Basic Redux-Cluster-WS Client Example
|
|
5
|
-
*
|
|
6
|
-
* This example demonstrates how to create a WebSocket client
|
|
7
|
-
* that connects to a Redux-Cluster-WS server and synchronizes state.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const { createStore } = require("redux-cluster");
|
|
11
|
-
const { client } = require("../dist/cjs/index.js");
|
|
12
|
-
const readline = require("readline");
|
|
13
|
-
|
|
14
|
-
// Same reducer as server (must be identical for proper synchronization)
|
|
15
|
-
function counterReducer(state = { count: 0, lastUpdate: null }, action) {
|
|
16
|
-
switch (action.type) {
|
|
17
|
-
case "INCREMENT":
|
|
18
|
-
return {
|
|
19
|
-
count: state.count + 1,
|
|
20
|
-
lastUpdate: new Date().toISOString(),
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
case "DECREMENT":
|
|
24
|
-
return {
|
|
25
|
-
count: state.count - 1,
|
|
26
|
-
lastUpdate: new Date().toISOString(),
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
case "RESET":
|
|
30
|
-
return {
|
|
31
|
-
count: 0,
|
|
32
|
-
lastUpdate: new Date().toISOString(),
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
default:
|
|
36
|
-
return state;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
console.log("š Starting Redux-Cluster-WS Client Example...");
|
|
41
|
-
|
|
42
|
-
// Create Redux store
|
|
43
|
-
const store = createStore(counterReducer);
|
|
44
|
-
|
|
45
|
-
// Add WebSocket client capability
|
|
46
|
-
client(store);
|
|
47
|
-
|
|
48
|
-
// Subscribe to state changes
|
|
49
|
-
store.subscribe(() => {
|
|
50
|
-
const state = store.getState();
|
|
51
|
-
console.log(
|
|
52
|
-
`\\nš State synchronized: count=${state.count}, lastUpdate=${state.lastUpdate}`
|
|
53
|
-
);
|
|
54
|
-
showMenu();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Connect to server
|
|
58
|
-
console.log("š Connecting to server...");
|
|
59
|
-
|
|
60
|
-
store.createWSClient({
|
|
61
|
-
host: "ws://localhost",
|
|
62
|
-
port: 8088,
|
|
63
|
-
login: "demo",
|
|
64
|
-
password: "demo",
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Setup interactive menu
|
|
68
|
-
const rl = readline.createInterface({
|
|
69
|
-
input: process.stdin,
|
|
70
|
-
output: process.stdout,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
function showMenu() {
|
|
74
|
-
if (store.connected) {
|
|
75
|
-
console.log("\\nš® Available actions:");
|
|
76
|
-
console.log(" [1] Increment counter");
|
|
77
|
-
console.log(" [2] Decrement counter");
|
|
78
|
-
console.log(" [3] Reset counter");
|
|
79
|
-
console.log(" [4] Show current state");
|
|
80
|
-
console.log(" [q] Quit");
|
|
81
|
-
console.log("");
|
|
82
|
-
process.stdout.write("Choose action: ");
|
|
83
|
-
} else {
|
|
84
|
-
console.log("\\nā³ Waiting for connection...");
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
rl.on("line", (input) => {
|
|
89
|
-
const choice = input.trim().toLowerCase();
|
|
90
|
-
|
|
91
|
-
if (!store.connected) {
|
|
92
|
-
console.log("ā Not connected to server yet. Please wait...");
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
switch (choice) {
|
|
97
|
-
case "1":
|
|
98
|
-
console.log("ā Sending INCREMENT action...");
|
|
99
|
-
store.dispatch({ type: "INCREMENT" });
|
|
100
|
-
break;
|
|
101
|
-
|
|
102
|
-
case "2":
|
|
103
|
-
console.log("ā Sending DECREMENT action...");
|
|
104
|
-
store.dispatch({ type: "DECREMENT" });
|
|
105
|
-
break;
|
|
106
|
-
|
|
107
|
-
case "3":
|
|
108
|
-
console.log("š Sending RESET action...");
|
|
109
|
-
store.dispatch({ type: "RESET" });
|
|
110
|
-
break;
|
|
111
|
-
|
|
112
|
-
case "4":
|
|
113
|
-
const state = store.getState();
|
|
114
|
-
console.log("\\nš Current state:");
|
|
115
|
-
console.log(JSON.stringify(state, null, 2));
|
|
116
|
-
showMenu();
|
|
117
|
-
break;
|
|
118
|
-
|
|
119
|
-
case "q":
|
|
120
|
-
case "quit":
|
|
121
|
-
case "exit":
|
|
122
|
-
console.log("\\nš Goodbye!");
|
|
123
|
-
process.exit(0);
|
|
124
|
-
break;
|
|
125
|
-
|
|
126
|
-
default:
|
|
127
|
-
console.log("ā Invalid choice. Please try again.");
|
|
128
|
-
showMenu();
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Handle connection events
|
|
134
|
-
setTimeout(() => {
|
|
135
|
-
if (store.connected) {
|
|
136
|
-
console.log("ā
Connected to server!");
|
|
137
|
-
const state = store.getState();
|
|
138
|
-
console.log(`š Initial state: count=${state.count}`);
|
|
139
|
-
showMenu();
|
|
140
|
-
} else {
|
|
141
|
-
console.log("ā Failed to connect to server.");
|
|
142
|
-
console.log("š” Make sure the server is running on ws://localhost:8080");
|
|
143
|
-
console.log("š” Run: node examples/server.js");
|
|
144
|
-
process.exit(1);
|
|
145
|
-
}
|
|
146
|
-
}, 2000);
|
|
147
|
-
|
|
148
|
-
// Handle graceful shutdown
|
|
149
|
-
process.on("SIGINT", () => {
|
|
150
|
-
console.log("\\nš Shutting down client...");
|
|
151
|
-
rl.close();
|
|
152
|
-
process.exit(0);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
console.log("ā³ Connecting... (this may take a moment)");
|