redux-cluster 1.10.0 → 2.0.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/LICENSE +21 -21
- package/README.md +345 -471
- package/dist/cjs/core/backup.d.ts +10 -0
- package/dist/cjs/core/backup.d.ts.map +1 -0
- package/dist/cjs/core/backup.js +166 -0
- package/dist/cjs/core/redux-cluster.d.ts +47 -0
- package/dist/cjs/core/redux-cluster.d.ts.map +1 -0
- package/dist/cjs/core/redux-cluster.js +367 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +43 -0
- package/dist/cjs/network/client.d.ts +23 -0
- package/dist/cjs/network/client.d.ts.map +1 -0
- package/dist/cjs/network/client.js +251 -0
- package/dist/cjs/network/server.d.ts +39 -0
- package/dist/cjs/network/server.d.ts.map +1 -0
- package/dist/cjs/network/server.js +439 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/index.d.ts +125 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +20 -0
- package/dist/cjs/utils/crypto.d.ts +22 -0
- package/dist/cjs/utils/crypto.d.ts.map +1 -0
- package/dist/cjs/utils/crypto.js +404 -0
- package/dist/esm/core/backup.d.ts +10 -0
- package/dist/esm/core/backup.d.ts.map +1 -0
- package/dist/esm/core/backup.js +134 -0
- package/dist/esm/core/redux-cluster.d.ts +47 -0
- package/dist/esm/core/redux-cluster.d.ts.map +1 -0
- package/dist/esm/core/redux-cluster.js +376 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +25 -0
- package/dist/esm/network/client.d.ts +23 -0
- package/dist/esm/network/client.d.ts.map +1 -0
- package/dist/esm/network/client.js +221 -0
- package/dist/esm/network/server.d.ts +39 -0
- package/dist/esm/network/server.d.ts.map +1 -0
- package/dist/esm/network/server.js +408 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/types/index.d.ts +125 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +17 -0
- package/dist/esm/utils/crypto.d.ts +22 -0
- package/dist/esm/utils/crypto.d.ts.map +1 -0
- package/dist/esm/utils/crypto.js +351 -0
- package/package.json +115 -34
- package/index.js +0 -678
- package/test.auto.js +0 -94
- package/test.auto.proc1.js +0 -97
- package/test.auto.proc2.js +0 -85
- package/test.visual.client.highload.js +0 -102
- package/test.visual.client.js +0 -103
- package/test.visual.error.js +0 -45
- package/test.visual.js +0 -97
- package/test.visual.server.highload.js +0 -102
- package/test.visual.server.js +0 -103
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import * as crypto from "crypto";
|
|
2
|
+
import { Transform } from "stream";
|
|
3
|
+
import { SerializationMode } from "../types";
|
|
4
|
+
// Import ObjectStream components - optional dependency
|
|
5
|
+
let Stringifer = null;
|
|
6
|
+
let Parser = null;
|
|
7
|
+
// Initialize ObjectStream if available
|
|
8
|
+
async function initializeObjectStream() {
|
|
9
|
+
try {
|
|
10
|
+
const objectStreamModule = await import("@sergdudko/objectstream");
|
|
11
|
+
Stringifer = objectStreamModule.Stringifer;
|
|
12
|
+
Parser = objectStreamModule.Parser;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// ObjectStream is optional
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Initialize once
|
|
19
|
+
initializeObjectStream();
|
|
20
|
+
// Import ProtoObject - optional dependency
|
|
21
|
+
let protoObjectConstructor = null;
|
|
22
|
+
// Initialize ProtoObject if available
|
|
23
|
+
async function initializeProtoObject() {
|
|
24
|
+
try {
|
|
25
|
+
const protoObjectModule = await import("protoobject");
|
|
26
|
+
protoObjectConstructor = protoObjectModule.ProtoObject ||
|
|
27
|
+
protoObjectModule.default ||
|
|
28
|
+
protoObjectModule;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// ProtoObject is optional
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Initialize once
|
|
35
|
+
initializeProtoObject();
|
|
36
|
+
// Check if ProtoObject is available
|
|
37
|
+
function isProtoObjectAvailable() {
|
|
38
|
+
return protoObjectConstructor !== null;
|
|
39
|
+
}
|
|
40
|
+
// Get ProtoObject class (proper TypeScript way)
|
|
41
|
+
function getProtoObjectClass() {
|
|
42
|
+
return protoObjectConstructor;
|
|
43
|
+
}
|
|
44
|
+
// Generate hash for reducer names
|
|
45
|
+
export function hasher(input) {
|
|
46
|
+
return crypto.createHash("md5").update(input).digest("hex");
|
|
47
|
+
}
|
|
48
|
+
// Create cipher for encryption
|
|
49
|
+
export function createCipher(key) {
|
|
50
|
+
const iv = crypto.randomBytes(16);
|
|
51
|
+
return crypto.createCipheriv("aes-256-ctr", Buffer.from(key), iv);
|
|
52
|
+
}
|
|
53
|
+
// Create decipher for decryption
|
|
54
|
+
export function createDecipher(key, iv) {
|
|
55
|
+
return crypto.createDecipheriv("aes-256-ctr", Buffer.from(key), iv);
|
|
56
|
+
}
|
|
57
|
+
// Encryption function for backup
|
|
58
|
+
export function encrypter(data, password) {
|
|
59
|
+
const key = crypto.scryptSync(password, "salt", 32);
|
|
60
|
+
const iv = crypto.randomBytes(16);
|
|
61
|
+
const cipher = crypto.createCipheriv("aes-256-ctr", key, iv);
|
|
62
|
+
let encrypted = cipher.update(data, "utf8", "hex");
|
|
63
|
+
encrypted += cipher.final("hex");
|
|
64
|
+
return iv.toString("hex") + ":" + encrypted;
|
|
65
|
+
}
|
|
66
|
+
// Decryption function for backup
|
|
67
|
+
export function decrypter(encryptedData, password) {
|
|
68
|
+
const [ivHex, encrypted] = encryptedData.split(":");
|
|
69
|
+
const key = crypto.scryptSync(password, "salt", 32);
|
|
70
|
+
const iv = Buffer.from(ivHex, "hex");
|
|
71
|
+
const decipher = crypto.createDecipheriv("aes-256-ctr", key, iv);
|
|
72
|
+
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
|
73
|
+
decrypted += decipher.final("utf8");
|
|
74
|
+
return decrypted;
|
|
75
|
+
}
|
|
76
|
+
// Utility function for deep cloning objects
|
|
77
|
+
export function deepClone(obj) {
|
|
78
|
+
if (typeof structuredClone === "function") {
|
|
79
|
+
return structuredClone(obj);
|
|
80
|
+
}
|
|
81
|
+
return JSON.parse(JSON.stringify(obj));
|
|
82
|
+
}
|
|
83
|
+
// Universal cloning function based on mode
|
|
84
|
+
export function universalClone(obj, mode, _classRegistry) {
|
|
85
|
+
if (mode === SerializationMode.PROTOOBJECT && isProtoObjectAvailable()) {
|
|
86
|
+
return protoObjectClone(obj);
|
|
87
|
+
}
|
|
88
|
+
return deepClone(obj);
|
|
89
|
+
}
|
|
90
|
+
// ProtoObject cloning function that handles nested ProtoObject instances
|
|
91
|
+
export function protoObjectClone(obj) {
|
|
92
|
+
const ProtoObjectClass = getProtoObjectClass();
|
|
93
|
+
if (!ProtoObjectClass) {
|
|
94
|
+
return deepClone(obj);
|
|
95
|
+
}
|
|
96
|
+
// If it's not a ProtoObject, use regular deep clone
|
|
97
|
+
if (!(obj instanceof ProtoObjectClass)) {
|
|
98
|
+
return deepClone(obj);
|
|
99
|
+
}
|
|
100
|
+
// Create a new ProtoObject with all properties
|
|
101
|
+
const clonedData = {};
|
|
102
|
+
// Copy all enumerable properties
|
|
103
|
+
for (const key of Object.keys(obj)) {
|
|
104
|
+
const value = obj[key];
|
|
105
|
+
if (value instanceof ProtoObjectClass) {
|
|
106
|
+
// Recursively clone nested ProtoObject
|
|
107
|
+
clonedData[key] = protoObjectClone(value);
|
|
108
|
+
}
|
|
109
|
+
else if (Array.isArray(value)) {
|
|
110
|
+
// Clone arrays with potential ProtoObject elements
|
|
111
|
+
clonedData[key] = value.map((item) => item instanceof ProtoObjectClass
|
|
112
|
+
? protoObjectClone(item)
|
|
113
|
+
: deepClone(item));
|
|
114
|
+
}
|
|
115
|
+
else if (value !== null && typeof value === "object") {
|
|
116
|
+
// Clone nested objects
|
|
117
|
+
clonedData[key] = deepClone(value);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// Copy primitive values
|
|
121
|
+
clonedData[key] = value;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return new ProtoObjectClass(clonedData);
|
|
125
|
+
}
|
|
126
|
+
// Universal serialization function
|
|
127
|
+
export function universalSerialize(obj, mode, classRegistry) {
|
|
128
|
+
if (mode === SerializationMode.PROTOOBJECT && isProtoObjectAvailable()) {
|
|
129
|
+
return serializeProtoObject(obj, classRegistry);
|
|
130
|
+
}
|
|
131
|
+
// Default JSON serialization
|
|
132
|
+
return JSON.stringify(obj);
|
|
133
|
+
}
|
|
134
|
+
// Universal deserialization function
|
|
135
|
+
export function universalDeserialize(str, mode, classRegistry) {
|
|
136
|
+
if (mode === SerializationMode.PROTOOBJECT && isProtoObjectAvailable()) {
|
|
137
|
+
return deserializeProtoObject(str, classRegistry);
|
|
138
|
+
}
|
|
139
|
+
// Default JSON deserialization
|
|
140
|
+
return JSON.parse(str);
|
|
141
|
+
}
|
|
142
|
+
// ProtoObject serialization for IPC with class information
|
|
143
|
+
export function serializeProtoObject(obj, classRegistry) {
|
|
144
|
+
const ProtoObjectClass = getProtoObjectClass();
|
|
145
|
+
if (!ProtoObjectClass) {
|
|
146
|
+
return JSON.stringify(obj);
|
|
147
|
+
}
|
|
148
|
+
const serialize = (value) => {
|
|
149
|
+
if (value instanceof ProtoObjectClass) {
|
|
150
|
+
const data = {
|
|
151
|
+
__isProtoObject: true,
|
|
152
|
+
__className: value.constructor.name,
|
|
153
|
+
};
|
|
154
|
+
// Store class information if registry is provided
|
|
155
|
+
if (classRegistry && value.constructor.name !== "ProtoObject") {
|
|
156
|
+
classRegistry.set(value.constructor.name, value.constructor);
|
|
157
|
+
}
|
|
158
|
+
for (const key of Object.keys(value)) {
|
|
159
|
+
data[key] = serialize(value[key]);
|
|
160
|
+
}
|
|
161
|
+
return data;
|
|
162
|
+
}
|
|
163
|
+
else if (Array.isArray(value)) {
|
|
164
|
+
return value.map(serialize);
|
|
165
|
+
}
|
|
166
|
+
else if (value !== null && typeof value === "object") {
|
|
167
|
+
const result = {};
|
|
168
|
+
for (const [key, val] of Object.entries(value)) {
|
|
169
|
+
result[key] = serialize(val);
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
return value;
|
|
174
|
+
};
|
|
175
|
+
return JSON.stringify(serialize(obj));
|
|
176
|
+
}
|
|
177
|
+
// ProtoObject deserialization for IPC with class reconstruction
|
|
178
|
+
export function deserializeProtoObject(str, classRegistry) {
|
|
179
|
+
const ProtoObjectClass = getProtoObjectClass();
|
|
180
|
+
if (!ProtoObjectClass) {
|
|
181
|
+
return JSON.parse(str);
|
|
182
|
+
}
|
|
183
|
+
const deserialize = (value) => {
|
|
184
|
+
if (value && typeof value === "object" && value.__isProtoObject) {
|
|
185
|
+
const className = value.__className;
|
|
186
|
+
const data = {};
|
|
187
|
+
for (const [key, val] of Object.entries(value)) {
|
|
188
|
+
if (key !== "__isProtoObject" && key !== "__className") {
|
|
189
|
+
data[key] = deserialize(val);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Try to use registered class, fallback to ProtoObject
|
|
193
|
+
if (className && classRegistry && classRegistry.has(className)) {
|
|
194
|
+
const ClassConstructor = classRegistry.get(className);
|
|
195
|
+
return new ClassConstructor(data);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
return new ProtoObjectClass(data);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else if (Array.isArray(value)) {
|
|
202
|
+
return value.map(deserialize);
|
|
203
|
+
}
|
|
204
|
+
else if (value !== null && typeof value === "object") {
|
|
205
|
+
const result = {};
|
|
206
|
+
for (const [key, val] of Object.entries(value)) {
|
|
207
|
+
result[key] = deserialize(val);
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
return value;
|
|
212
|
+
};
|
|
213
|
+
return deserialize(JSON.parse(str));
|
|
214
|
+
}
|
|
215
|
+
// Helper function to create a shared class registry
|
|
216
|
+
export function createClassRegistry() {
|
|
217
|
+
return new Map();
|
|
218
|
+
}
|
|
219
|
+
// Stream pipeline functions for buffer->json->class->json->buffer processing
|
|
220
|
+
// Create ObjectStream Parser for JSON parsing (Buffer -> Object)
|
|
221
|
+
export function createObjectStreamParser() {
|
|
222
|
+
if (Parser) {
|
|
223
|
+
return new Parser();
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
// Create ObjectStream Stringifier for JSON serialization (Object -> Buffer)
|
|
228
|
+
export function createObjectStreamStringifier() {
|
|
229
|
+
if (Stringifer) {
|
|
230
|
+
return new Stringifer();
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
// Legacy function for backward compatibility
|
|
235
|
+
export function createObjectStream() {
|
|
236
|
+
return createObjectStreamParser();
|
|
237
|
+
}
|
|
238
|
+
// Create transform stream that converts JSON objects to ProtoObject instances
|
|
239
|
+
export function createDeserializationStream(mode, classRegistry) {
|
|
240
|
+
return new Transform({
|
|
241
|
+
objectMode: true,
|
|
242
|
+
transform(chunk, encoding, callback) {
|
|
243
|
+
try {
|
|
244
|
+
if (mode === SerializationMode.PROTOOBJECT &&
|
|
245
|
+
isProtoObjectAvailable()) {
|
|
246
|
+
const deserialized = deserializeFromObject(chunk, classRegistry);
|
|
247
|
+
callback(null, deserialized);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
callback(null, chunk);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
callback(error instanceof Error ? error : new Error(String(error)));
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
// Create transform stream that converts ProtoObject instances to JSON objects
|
|
260
|
+
export function createSerializationStream(mode, classRegistry) {
|
|
261
|
+
return new Transform({
|
|
262
|
+
objectMode: true,
|
|
263
|
+
transform(chunk, encoding, callback) {
|
|
264
|
+
try {
|
|
265
|
+
if (mode === SerializationMode.PROTOOBJECT &&
|
|
266
|
+
isProtoObjectAvailable()) {
|
|
267
|
+
const serialized = serializeToObject(chunk, classRegistry);
|
|
268
|
+
callback(null, serialized);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
callback(null, chunk);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
callback(error instanceof Error ? error : new Error(String(error)));
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
// Helper functions for object-level serialization/deserialization (without JSON.stringify)
|
|
281
|
+
function serializeToObject(obj, classRegistry) {
|
|
282
|
+
const ProtoObjectClass = getProtoObjectClass();
|
|
283
|
+
if (!ProtoObjectClass) {
|
|
284
|
+
return obj;
|
|
285
|
+
}
|
|
286
|
+
const serialize = (value) => {
|
|
287
|
+
if (value instanceof ProtoObjectClass) {
|
|
288
|
+
const data = {
|
|
289
|
+
__isProtoObject: true,
|
|
290
|
+
__className: value.constructor.name,
|
|
291
|
+
};
|
|
292
|
+
// Store class information if registry is provided
|
|
293
|
+
if (classRegistry && value.constructor.name !== "ProtoObject") {
|
|
294
|
+
classRegistry.set(value.constructor.name, value.constructor);
|
|
295
|
+
}
|
|
296
|
+
for (const key of Object.keys(value)) {
|
|
297
|
+
data[key] = serialize(value[key]);
|
|
298
|
+
}
|
|
299
|
+
return data;
|
|
300
|
+
}
|
|
301
|
+
else if (Array.isArray(value)) {
|
|
302
|
+
return value.map(serialize);
|
|
303
|
+
}
|
|
304
|
+
else if (value !== null && typeof value === "object") {
|
|
305
|
+
const result = {};
|
|
306
|
+
for (const [key, val] of Object.entries(value)) {
|
|
307
|
+
result[key] = serialize(val);
|
|
308
|
+
}
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
return value;
|
|
312
|
+
};
|
|
313
|
+
return serialize(obj);
|
|
314
|
+
}
|
|
315
|
+
function deserializeFromObject(obj, classRegistry) {
|
|
316
|
+
const ProtoObjectClass = getProtoObjectClass();
|
|
317
|
+
if (!ProtoObjectClass) {
|
|
318
|
+
return obj;
|
|
319
|
+
}
|
|
320
|
+
const deserialize = (value) => {
|
|
321
|
+
if (value && typeof value === "object" && value.__isProtoObject) {
|
|
322
|
+
const className = value.__className;
|
|
323
|
+
const data = {};
|
|
324
|
+
for (const [key, val] of Object.entries(value)) {
|
|
325
|
+
if (key !== "__isProtoObject" && key !== "__className") {
|
|
326
|
+
data[key] = deserialize(val);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Try to use registered class, fallback to ProtoObject
|
|
330
|
+
if (className && classRegistry && classRegistry.has(className)) {
|
|
331
|
+
const ClassConstructor = classRegistry.get(className);
|
|
332
|
+
return new ClassConstructor(data);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
return new ProtoObjectClass(data);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else if (Array.isArray(value)) {
|
|
339
|
+
return value.map(deserialize);
|
|
340
|
+
}
|
|
341
|
+
else if (value !== null && typeof value === "object") {
|
|
342
|
+
const result = {};
|
|
343
|
+
for (const [key, val] of Object.entries(value)) {
|
|
344
|
+
result[key] = deserialize(val);
|
|
345
|
+
}
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
return value;
|
|
349
|
+
};
|
|
350
|
+
return deserialize(obj);
|
|
351
|
+
}
|
package/package.json
CHANGED
|
@@ -1,34 +1,115 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "redux-cluster",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "redux-cluster",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "TypeScript cluster module for Redux that synchronizes Redux stores across cluster processes via IPC and TCP sockets",
|
|
6
|
+
"main": "dist/cjs/index.js",
|
|
7
|
+
"module": "dist/esm/index.js",
|
|
8
|
+
"types": "dist/esm/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/esm/index.d.ts",
|
|
13
|
+
"default": "./dist/esm/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/cjs/index.d.ts",
|
|
17
|
+
"default": "./dist/cjs/index.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist/esm/**/*",
|
|
23
|
+
"dist/cjs/**/*",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"funding": [
|
|
28
|
+
{
|
|
29
|
+
"type": "individual",
|
|
30
|
+
"url": "http://dudko.dev/donate"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "buymeacoffee",
|
|
34
|
+
"url": "https://www.buymeacoffee.com/dudko.dev"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "paypal",
|
|
38
|
+
"url": "https://paypal.me/dudkodev"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"type": "patreon",
|
|
42
|
+
"url": "https://patreon.com/dudko_dev"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:pkg",
|
|
47
|
+
"build:esm": "tsc",
|
|
48
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
49
|
+
"build:pkg": "./scripts/create-package-files.sh",
|
|
50
|
+
"build:watch": "tsc --watch",
|
|
51
|
+
"clean": "rm -rf dist",
|
|
52
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
53
|
+
"test": "npm run test:all",
|
|
54
|
+
"test:all": "node --test --import tsx tests/unit.test.ts tests/error.test.ts tests/transport.test.ts",
|
|
55
|
+
"test:unit": "node --test --import tsx tests/unit.test.ts",
|
|
56
|
+
"test:transport": "node --test --import tsx tests/transport.test.ts",
|
|
57
|
+
"test:cluster": "node --test --import tsx tests/cluster.test.ts",
|
|
58
|
+
"test:integration": "node --test --import tsx tests/integration.test.ts",
|
|
59
|
+
"test:error": "node --test --import tsx tests/error.test.ts",
|
|
60
|
+
"test:integration-full": "./integration/run-tests.sh",
|
|
61
|
+
"lint": "eslint src/**/*.ts tests/**/*.ts",
|
|
62
|
+
"lint:fix": "eslint src/**/*.ts tests/**/*.ts --fix",
|
|
63
|
+
"example:basic": "node examples/basic.js",
|
|
64
|
+
"example:server": "node examples/server.js",
|
|
65
|
+
"example:client": "node examples/client.js"
|
|
66
|
+
},
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "git+ssh://git@github.com/siarheidudko/redux-cluster.git"
|
|
70
|
+
},
|
|
71
|
+
"keywords": [
|
|
72
|
+
"redux",
|
|
73
|
+
"cluster",
|
|
74
|
+
"ipc",
|
|
75
|
+
"process",
|
|
76
|
+
"typescript",
|
|
77
|
+
"synchronization",
|
|
78
|
+
"distributed",
|
|
79
|
+
"tcp",
|
|
80
|
+
"socket"
|
|
81
|
+
],
|
|
82
|
+
"author": {
|
|
83
|
+
"name": "Siarhei Dudko",
|
|
84
|
+
"email": "siarhei@dudko.dev",
|
|
85
|
+
"url": "https://dudko.dev"
|
|
86
|
+
},
|
|
87
|
+
"license": "MIT",
|
|
88
|
+
"bugs": {
|
|
89
|
+
"url": "https://github.com/siarheidudko/redux-cluster/issues"
|
|
90
|
+
},
|
|
91
|
+
"homepage": "https://github.com/siarheidudko/redux-cluster#readme",
|
|
92
|
+
"dependencies": {
|
|
93
|
+
"@sergdudko/objectstream": "^3.2.26",
|
|
94
|
+
"protoobject": "^1.1.30",
|
|
95
|
+
"redux": "^5.0.1"
|
|
96
|
+
},
|
|
97
|
+
"devDependencies": {
|
|
98
|
+
"@types/node": "^20.11.17",
|
|
99
|
+
"@typescript-eslint/eslint-plugin": "^8.42.0",
|
|
100
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
101
|
+
"eslint": "^9.35.0",
|
|
102
|
+
"ts-node": "^10.9.2",
|
|
103
|
+
"tsx": "^4.20.5",
|
|
104
|
+
"typescript": "^5.5.4"
|
|
105
|
+
},
|
|
106
|
+
"engines": {
|
|
107
|
+
"node": ">=14.0.0"
|
|
108
|
+
},
|
|
109
|
+
"overrides": {
|
|
110
|
+
"debug": ">=4.3.7"
|
|
111
|
+
},
|
|
112
|
+
"publishConfig": {
|
|
113
|
+
"access": "public"
|
|
114
|
+
}
|
|
115
|
+
}
|