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.
Files changed (57) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +345 -471
  3. package/dist/cjs/core/backup.d.ts +10 -0
  4. package/dist/cjs/core/backup.d.ts.map +1 -0
  5. package/dist/cjs/core/backup.js +166 -0
  6. package/dist/cjs/core/redux-cluster.d.ts +47 -0
  7. package/dist/cjs/core/redux-cluster.d.ts.map +1 -0
  8. package/dist/cjs/core/redux-cluster.js +367 -0
  9. package/dist/cjs/index.d.ts +22 -0
  10. package/dist/cjs/index.d.ts.map +1 -0
  11. package/dist/cjs/index.js +43 -0
  12. package/dist/cjs/network/client.d.ts +23 -0
  13. package/dist/cjs/network/client.d.ts.map +1 -0
  14. package/dist/cjs/network/client.js +251 -0
  15. package/dist/cjs/network/server.d.ts +39 -0
  16. package/dist/cjs/network/server.d.ts.map +1 -0
  17. package/dist/cjs/network/server.js +439 -0
  18. package/dist/cjs/package.json +1 -0
  19. package/dist/cjs/types/index.d.ts +125 -0
  20. package/dist/cjs/types/index.d.ts.map +1 -0
  21. package/dist/cjs/types/index.js +20 -0
  22. package/dist/cjs/utils/crypto.d.ts +22 -0
  23. package/dist/cjs/utils/crypto.d.ts.map +1 -0
  24. package/dist/cjs/utils/crypto.js +404 -0
  25. package/dist/esm/core/backup.d.ts +10 -0
  26. package/dist/esm/core/backup.d.ts.map +1 -0
  27. package/dist/esm/core/backup.js +134 -0
  28. package/dist/esm/core/redux-cluster.d.ts +47 -0
  29. package/dist/esm/core/redux-cluster.d.ts.map +1 -0
  30. package/dist/esm/core/redux-cluster.js +376 -0
  31. package/dist/esm/index.d.ts +22 -0
  32. package/dist/esm/index.d.ts.map +1 -0
  33. package/dist/esm/index.js +25 -0
  34. package/dist/esm/network/client.d.ts +23 -0
  35. package/dist/esm/network/client.d.ts.map +1 -0
  36. package/dist/esm/network/client.js +221 -0
  37. package/dist/esm/network/server.d.ts +39 -0
  38. package/dist/esm/network/server.d.ts.map +1 -0
  39. package/dist/esm/network/server.js +408 -0
  40. package/dist/esm/package.json +1 -0
  41. package/dist/esm/types/index.d.ts +125 -0
  42. package/dist/esm/types/index.d.ts.map +1 -0
  43. package/dist/esm/types/index.js +17 -0
  44. package/dist/esm/utils/crypto.d.ts +22 -0
  45. package/dist/esm/utils/crypto.d.ts.map +1 -0
  46. package/dist/esm/utils/crypto.js +351 -0
  47. package/package.json +115 -34
  48. package/index.js +0 -678
  49. package/test.auto.js +0 -94
  50. package/test.auto.proc1.js +0 -97
  51. package/test.auto.proc2.js +0 -85
  52. package/test.visual.client.highload.js +0 -102
  53. package/test.visual.client.js +0 -103
  54. package/test.visual.error.js +0 -45
  55. package/test.visual.js +0 -97
  56. package/test.visual.server.highload.js +0 -102
  57. package/test.visual.server.js +0 -103
@@ -0,0 +1,404 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.hasher = hasher;
37
+ exports.createCipher = createCipher;
38
+ exports.createDecipher = createDecipher;
39
+ exports.encrypter = encrypter;
40
+ exports.decrypter = decrypter;
41
+ exports.deepClone = deepClone;
42
+ exports.universalClone = universalClone;
43
+ exports.protoObjectClone = protoObjectClone;
44
+ exports.universalSerialize = universalSerialize;
45
+ exports.universalDeserialize = universalDeserialize;
46
+ exports.serializeProtoObject = serializeProtoObject;
47
+ exports.deserializeProtoObject = deserializeProtoObject;
48
+ exports.createClassRegistry = createClassRegistry;
49
+ exports.createObjectStreamParser = createObjectStreamParser;
50
+ exports.createObjectStreamStringifier = createObjectStreamStringifier;
51
+ exports.createObjectStream = createObjectStream;
52
+ exports.createDeserializationStream = createDeserializationStream;
53
+ exports.createSerializationStream = createSerializationStream;
54
+ const crypto = __importStar(require("crypto"));
55
+ const stream_1 = require("stream");
56
+ const types_1 = require("../types");
57
+ // Import ObjectStream components - optional dependency
58
+ let Stringifer = null;
59
+ let Parser = null;
60
+ // Initialize ObjectStream if available
61
+ async function initializeObjectStream() {
62
+ try {
63
+ const objectStreamModule = await Promise.resolve().then(() => __importStar(require("@sergdudko/objectstream")));
64
+ Stringifer = objectStreamModule.Stringifer;
65
+ Parser = objectStreamModule.Parser;
66
+ }
67
+ catch {
68
+ // ObjectStream is optional
69
+ }
70
+ }
71
+ // Initialize once
72
+ initializeObjectStream();
73
+ // Import ProtoObject - optional dependency
74
+ let protoObjectConstructor = null;
75
+ // Initialize ProtoObject if available
76
+ async function initializeProtoObject() {
77
+ try {
78
+ const protoObjectModule = await Promise.resolve().then(() => __importStar(require("protoobject")));
79
+ protoObjectConstructor = protoObjectModule.ProtoObject ||
80
+ protoObjectModule.default ||
81
+ protoObjectModule;
82
+ }
83
+ catch {
84
+ // ProtoObject is optional
85
+ }
86
+ }
87
+ // Initialize once
88
+ initializeProtoObject();
89
+ // Check if ProtoObject is available
90
+ function isProtoObjectAvailable() {
91
+ return protoObjectConstructor !== null;
92
+ }
93
+ // Get ProtoObject class (proper TypeScript way)
94
+ function getProtoObjectClass() {
95
+ return protoObjectConstructor;
96
+ }
97
+ // Generate hash for reducer names
98
+ function hasher(input) {
99
+ return crypto.createHash("md5").update(input).digest("hex");
100
+ }
101
+ // Create cipher for encryption
102
+ function createCipher(key) {
103
+ const iv = crypto.randomBytes(16);
104
+ return crypto.createCipheriv("aes-256-ctr", Buffer.from(key), iv);
105
+ }
106
+ // Create decipher for decryption
107
+ function createDecipher(key, iv) {
108
+ return crypto.createDecipheriv("aes-256-ctr", Buffer.from(key), iv);
109
+ }
110
+ // Encryption function for backup
111
+ function encrypter(data, password) {
112
+ const key = crypto.scryptSync(password, "salt", 32);
113
+ const iv = crypto.randomBytes(16);
114
+ const cipher = crypto.createCipheriv("aes-256-ctr", key, iv);
115
+ let encrypted = cipher.update(data, "utf8", "hex");
116
+ encrypted += cipher.final("hex");
117
+ return iv.toString("hex") + ":" + encrypted;
118
+ }
119
+ // Decryption function for backup
120
+ function decrypter(encryptedData, password) {
121
+ const [ivHex, encrypted] = encryptedData.split(":");
122
+ const key = crypto.scryptSync(password, "salt", 32);
123
+ const iv = Buffer.from(ivHex, "hex");
124
+ const decipher = crypto.createDecipheriv("aes-256-ctr", key, iv);
125
+ let decrypted = decipher.update(encrypted, "hex", "utf8");
126
+ decrypted += decipher.final("utf8");
127
+ return decrypted;
128
+ }
129
+ // Utility function for deep cloning objects
130
+ function deepClone(obj) {
131
+ if (typeof structuredClone === "function") {
132
+ return structuredClone(obj);
133
+ }
134
+ return JSON.parse(JSON.stringify(obj));
135
+ }
136
+ // Universal cloning function based on mode
137
+ function universalClone(obj, mode, _classRegistry) {
138
+ if (mode === types_1.SerializationMode.PROTOOBJECT && isProtoObjectAvailable()) {
139
+ return protoObjectClone(obj);
140
+ }
141
+ return deepClone(obj);
142
+ }
143
+ // ProtoObject cloning function that handles nested ProtoObject instances
144
+ function protoObjectClone(obj) {
145
+ const ProtoObjectClass = getProtoObjectClass();
146
+ if (!ProtoObjectClass) {
147
+ return deepClone(obj);
148
+ }
149
+ // If it's not a ProtoObject, use regular deep clone
150
+ if (!(obj instanceof ProtoObjectClass)) {
151
+ return deepClone(obj);
152
+ }
153
+ // Create a new ProtoObject with all properties
154
+ const clonedData = {};
155
+ // Copy all enumerable properties
156
+ for (const key of Object.keys(obj)) {
157
+ const value = obj[key];
158
+ if (value instanceof ProtoObjectClass) {
159
+ // Recursively clone nested ProtoObject
160
+ clonedData[key] = protoObjectClone(value);
161
+ }
162
+ else if (Array.isArray(value)) {
163
+ // Clone arrays with potential ProtoObject elements
164
+ clonedData[key] = value.map((item) => item instanceof ProtoObjectClass
165
+ ? protoObjectClone(item)
166
+ : deepClone(item));
167
+ }
168
+ else if (value !== null && typeof value === "object") {
169
+ // Clone nested objects
170
+ clonedData[key] = deepClone(value);
171
+ }
172
+ else {
173
+ // Copy primitive values
174
+ clonedData[key] = value;
175
+ }
176
+ }
177
+ return new ProtoObjectClass(clonedData);
178
+ }
179
+ // Universal serialization function
180
+ function universalSerialize(obj, mode, classRegistry) {
181
+ if (mode === types_1.SerializationMode.PROTOOBJECT && isProtoObjectAvailable()) {
182
+ return serializeProtoObject(obj, classRegistry);
183
+ }
184
+ // Default JSON serialization
185
+ return JSON.stringify(obj);
186
+ }
187
+ // Universal deserialization function
188
+ function universalDeserialize(str, mode, classRegistry) {
189
+ if (mode === types_1.SerializationMode.PROTOOBJECT && isProtoObjectAvailable()) {
190
+ return deserializeProtoObject(str, classRegistry);
191
+ }
192
+ // Default JSON deserialization
193
+ return JSON.parse(str);
194
+ }
195
+ // ProtoObject serialization for IPC with class information
196
+ function serializeProtoObject(obj, classRegistry) {
197
+ const ProtoObjectClass = getProtoObjectClass();
198
+ if (!ProtoObjectClass) {
199
+ return JSON.stringify(obj);
200
+ }
201
+ const serialize = (value) => {
202
+ if (value instanceof ProtoObjectClass) {
203
+ const data = {
204
+ __isProtoObject: true,
205
+ __className: value.constructor.name,
206
+ };
207
+ // Store class information if registry is provided
208
+ if (classRegistry && value.constructor.name !== "ProtoObject") {
209
+ classRegistry.set(value.constructor.name, value.constructor);
210
+ }
211
+ for (const key of Object.keys(value)) {
212
+ data[key] = serialize(value[key]);
213
+ }
214
+ return data;
215
+ }
216
+ else if (Array.isArray(value)) {
217
+ return value.map(serialize);
218
+ }
219
+ else if (value !== null && typeof value === "object") {
220
+ const result = {};
221
+ for (const [key, val] of Object.entries(value)) {
222
+ result[key] = serialize(val);
223
+ }
224
+ return result;
225
+ }
226
+ return value;
227
+ };
228
+ return JSON.stringify(serialize(obj));
229
+ }
230
+ // ProtoObject deserialization for IPC with class reconstruction
231
+ function deserializeProtoObject(str, classRegistry) {
232
+ const ProtoObjectClass = getProtoObjectClass();
233
+ if (!ProtoObjectClass) {
234
+ return JSON.parse(str);
235
+ }
236
+ const deserialize = (value) => {
237
+ if (value && typeof value === "object" && value.__isProtoObject) {
238
+ const className = value.__className;
239
+ const data = {};
240
+ for (const [key, val] of Object.entries(value)) {
241
+ if (key !== "__isProtoObject" && key !== "__className") {
242
+ data[key] = deserialize(val);
243
+ }
244
+ }
245
+ // Try to use registered class, fallback to ProtoObject
246
+ if (className && classRegistry && classRegistry.has(className)) {
247
+ const ClassConstructor = classRegistry.get(className);
248
+ return new ClassConstructor(data);
249
+ }
250
+ else {
251
+ return new ProtoObjectClass(data);
252
+ }
253
+ }
254
+ else if (Array.isArray(value)) {
255
+ return value.map(deserialize);
256
+ }
257
+ else if (value !== null && typeof value === "object") {
258
+ const result = {};
259
+ for (const [key, val] of Object.entries(value)) {
260
+ result[key] = deserialize(val);
261
+ }
262
+ return result;
263
+ }
264
+ return value;
265
+ };
266
+ return deserialize(JSON.parse(str));
267
+ }
268
+ // Helper function to create a shared class registry
269
+ function createClassRegistry() {
270
+ return new Map();
271
+ }
272
+ // Stream pipeline functions for buffer->json->class->json->buffer processing
273
+ // Create ObjectStream Parser for JSON parsing (Buffer -> Object)
274
+ function createObjectStreamParser() {
275
+ if (Parser) {
276
+ return new Parser();
277
+ }
278
+ return null;
279
+ }
280
+ // Create ObjectStream Stringifier for JSON serialization (Object -> Buffer)
281
+ function createObjectStreamStringifier() {
282
+ if (Stringifer) {
283
+ return new Stringifer();
284
+ }
285
+ return null;
286
+ }
287
+ // Legacy function for backward compatibility
288
+ function createObjectStream() {
289
+ return createObjectStreamParser();
290
+ }
291
+ // Create transform stream that converts JSON objects to ProtoObject instances
292
+ function createDeserializationStream(mode, classRegistry) {
293
+ return new stream_1.Transform({
294
+ objectMode: true,
295
+ transform(chunk, encoding, callback) {
296
+ try {
297
+ if (mode === types_1.SerializationMode.PROTOOBJECT &&
298
+ isProtoObjectAvailable()) {
299
+ const deserialized = deserializeFromObject(chunk, classRegistry);
300
+ callback(null, deserialized);
301
+ }
302
+ else {
303
+ callback(null, chunk);
304
+ }
305
+ }
306
+ catch (error) {
307
+ callback(error instanceof Error ? error : new Error(String(error)));
308
+ }
309
+ },
310
+ });
311
+ }
312
+ // Create transform stream that converts ProtoObject instances to JSON objects
313
+ function createSerializationStream(mode, classRegistry) {
314
+ return new stream_1.Transform({
315
+ objectMode: true,
316
+ transform(chunk, encoding, callback) {
317
+ try {
318
+ if (mode === types_1.SerializationMode.PROTOOBJECT &&
319
+ isProtoObjectAvailable()) {
320
+ const serialized = serializeToObject(chunk, classRegistry);
321
+ callback(null, serialized);
322
+ }
323
+ else {
324
+ callback(null, chunk);
325
+ }
326
+ }
327
+ catch (error) {
328
+ callback(error instanceof Error ? error : new Error(String(error)));
329
+ }
330
+ },
331
+ });
332
+ }
333
+ // Helper functions for object-level serialization/deserialization (without JSON.stringify)
334
+ function serializeToObject(obj, classRegistry) {
335
+ const ProtoObjectClass = getProtoObjectClass();
336
+ if (!ProtoObjectClass) {
337
+ return obj;
338
+ }
339
+ const serialize = (value) => {
340
+ if (value instanceof ProtoObjectClass) {
341
+ const data = {
342
+ __isProtoObject: true,
343
+ __className: value.constructor.name,
344
+ };
345
+ // Store class information if registry is provided
346
+ if (classRegistry && value.constructor.name !== "ProtoObject") {
347
+ classRegistry.set(value.constructor.name, value.constructor);
348
+ }
349
+ for (const key of Object.keys(value)) {
350
+ data[key] = serialize(value[key]);
351
+ }
352
+ return data;
353
+ }
354
+ else if (Array.isArray(value)) {
355
+ return value.map(serialize);
356
+ }
357
+ else if (value !== null && typeof value === "object") {
358
+ const result = {};
359
+ for (const [key, val] of Object.entries(value)) {
360
+ result[key] = serialize(val);
361
+ }
362
+ return result;
363
+ }
364
+ return value;
365
+ };
366
+ return serialize(obj);
367
+ }
368
+ function deserializeFromObject(obj, classRegistry) {
369
+ const ProtoObjectClass = getProtoObjectClass();
370
+ if (!ProtoObjectClass) {
371
+ return obj;
372
+ }
373
+ const deserialize = (value) => {
374
+ if (value && typeof value === "object" && value.__isProtoObject) {
375
+ const className = value.__className;
376
+ const data = {};
377
+ for (const [key, val] of Object.entries(value)) {
378
+ if (key !== "__isProtoObject" && key !== "__className") {
379
+ data[key] = deserialize(val);
380
+ }
381
+ }
382
+ // Try to use registered class, fallback to ProtoObject
383
+ if (className && classRegistry && classRegistry.has(className)) {
384
+ const ClassConstructor = classRegistry.get(className);
385
+ return new ClassConstructor(data);
386
+ }
387
+ else {
388
+ return new ProtoObjectClass(data);
389
+ }
390
+ }
391
+ else if (Array.isArray(value)) {
392
+ return value.map(deserialize);
393
+ }
394
+ else if (value !== null && typeof value === "object") {
395
+ const result = {};
396
+ for (const [key, val] of Object.entries(value)) {
397
+ result[key] = deserialize(val);
398
+ }
399
+ return result;
400
+ }
401
+ return value;
402
+ };
403
+ return deserialize(obj);
404
+ }
@@ -0,0 +1,10 @@
1
+ import { BackupSettings, ReduxClusterStore } from "../types";
2
+ export declare class BackupManager<S = any> {
3
+ private store;
4
+ private settings;
5
+ private createBackupInstance?;
6
+ constructor(store: ReduxClusterStore<S>, settings: BackupSettings);
7
+ initialize(): Promise<boolean>;
8
+ private loadBackup;
9
+ }
10
+ //# sourceMappingURL=backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../../src/core/backup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAe,MAAM,UAAU,CAAC;AAG1E,qBAAa,aAAa,CAAC,CAAC,GAAG,GAAG;IAI9B,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAJlB,OAAO,CAAC,oBAAoB,CAAC,CAAoB;gBAGvC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC3B,QAAQ,EAAE,cAAc;IAGrB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;YAiB7B,UAAU;CA+CzB"}
@@ -0,0 +1,134 @@
1
+ import * as fs from "fs";
2
+ import { MessageType } from "../types";
3
+ import { encrypter, decrypter } from "../utils/crypto";
4
+ export class BackupManager {
5
+ store;
6
+ settings;
7
+ createBackupInstance;
8
+ constructor(store, settings) {
9
+ this.store = store;
10
+ this.settings = settings;
11
+ }
12
+ async initialize() {
13
+ try {
14
+ await this.loadBackup();
15
+ this.createBackupInstance = new BackupInstance(this.store, this.settings);
16
+ return true;
17
+ }
18
+ catch (err) {
19
+ if (err.message.toLowerCase().includes("no such file or directory")) {
20
+ this.createBackupInstance = new BackupInstance(this.store, this.settings);
21
+ return true;
22
+ }
23
+ throw err;
24
+ }
25
+ }
26
+ async loadBackup() {
27
+ return new Promise((resolve, reject) => {
28
+ fs.readFile(this.settings.path, (err, data) => {
29
+ if (err) {
30
+ reject(new Error(`ReduxCluster.backup load error: ${err.message}`));
31
+ return;
32
+ }
33
+ try {
34
+ let content = data.toString();
35
+ // Decrypt if key is provided
36
+ if (this.settings.key) {
37
+ content = decrypter(content, this.settings.key);
38
+ }
39
+ const state = JSON.parse(content);
40
+ // Restore state using internal method
41
+ if ("_internalSync" in this.store &&
42
+ typeof this.store._internalSync === "function") {
43
+ this.store._internalSync(state);
44
+ }
45
+ else {
46
+ // Fallback: use dispatchNEW if available, otherwise skip restore
47
+ if ("dispatchNEW" in this.store &&
48
+ typeof this.store.dispatchNEW === "function") {
49
+ this.store.dispatchNEW({
50
+ type: MessageType.SYNC,
51
+ payload: state,
52
+ _internal: true,
53
+ });
54
+ }
55
+ }
56
+ setTimeout(() => resolve(), 500);
57
+ }
58
+ catch (parseErr) {
59
+ reject(new Error(`ReduxCluster.backup decoding error: ${parseErr.message}`));
60
+ }
61
+ });
62
+ });
63
+ }
64
+ }
65
+ class BackupInstance {
66
+ store;
67
+ settings;
68
+ count = 0;
69
+ allowed = true;
70
+ unsubscribe = null;
71
+ constructor(store, settings) {
72
+ this.store = store;
73
+ this.settings = settings;
74
+ this.unsubscribe = this.store.subscribe(() => {
75
+ this.handleStateChange();
76
+ });
77
+ }
78
+ handleStateChange() {
79
+ if (typeof this.settings.timeout === "number") {
80
+ // Priority setting - timeout based backup
81
+ if (this.allowed) {
82
+ this.allowed = false;
83
+ setTimeout(() => {
84
+ this.write(true);
85
+ }, this.settings.timeout * 1000);
86
+ }
87
+ }
88
+ else if (typeof this.settings.count === "number") {
89
+ // Count based backup
90
+ this.count++;
91
+ if (this.count >= this.settings.count) {
92
+ this.count = 0;
93
+ this.write();
94
+ }
95
+ }
96
+ }
97
+ write(restart = false, callback) {
98
+ if (this.allowed || restart) {
99
+ try {
100
+ let content = JSON.stringify(this.store.getState());
101
+ // Encrypt if key is provided
102
+ if (this.settings.key) {
103
+ content = encrypter(content, this.settings.key);
104
+ }
105
+ this.writeToFile(content, callback);
106
+ }
107
+ catch (err) {
108
+ this.store.stderr(`ReduxCluster.backup write error: ${err.message}`);
109
+ this.allowed = false;
110
+ setTimeout(() => this.write(true, callback), 1000);
111
+ }
112
+ }
113
+ }
114
+ writeToFile(content, callback) {
115
+ try {
116
+ fs.writeFileSync(this.settings.path, content);
117
+ this.allowed = true;
118
+ if (callback) {
119
+ callback(true);
120
+ }
121
+ }
122
+ catch (err) {
123
+ this.store.stderr(`ReduxCluster.backup write error: ${err.message}`);
124
+ this.allowed = false;
125
+ setTimeout(() => this.write(true, callback), 1000);
126
+ }
127
+ }
128
+ dispose() {
129
+ if (this.unsubscribe) {
130
+ this.unsubscribe();
131
+ this.unsubscribe = null;
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,47 @@
1
+ import { Store, Reducer, Action } from "redux";
2
+ import { ReduxClusterStore, SyncMode, Role, ClusterMessage, ServerSettings, ClientSettings, BackupSettings, ErrorHandler, ReduxClusterConfig } from "../types";
3
+ import { ClusterServer } from "../network/server";
4
+ import { ClusterClient } from "../network/client";
5
+ export declare class ReduxCluster<S = any, A extends Action = Action> implements ReduxClusterStore<S, A> {
6
+ readonly dispatch: Store<S, A>["dispatch"];
7
+ readonly getState: Store<S, A>["getState"];
8
+ readonly subscribe: Store<S, A>["subscribe"];
9
+ readonly replaceReducer: Store<S, A>["replaceReducer"];
10
+ readonly [Symbol.observable]: Store<S, A>[typeof Symbol.observable];
11
+ readonly RCHash: string;
12
+ readonly version: string;
13
+ readonly homepage: string;
14
+ readonly role: Role[];
15
+ connected: boolean;
16
+ mode: SyncMode;
17
+ resync: number;
18
+ stderr: ErrorHandler;
19
+ readonly config: ReduxClusterConfig;
20
+ private readonly altReducer;
21
+ private readonly defaultState;
22
+ private readonly store;
23
+ private readonly allsock;
24
+ private counter?;
25
+ private dispatchNEW?;
26
+ private unsubscribe?;
27
+ private classRegistry;
28
+ constructor(reducer: Reducer<S, A>, config?: ReduxClusterConfig);
29
+ private internalSync;
30
+ _internalSync(payload: S): void;
31
+ private createNewReducer;
32
+ private updateCounter;
33
+ private sendActionsToNodes;
34
+ private initializeClusterRole;
35
+ private initializeMaster;
36
+ private initializeWorker;
37
+ private handleMasterMessage;
38
+ private handleWorkerMessage;
39
+ sendtoall(message?: ClusterMessage): void;
40
+ sendtoallsock(message?: ClusterMessage): void;
41
+ createServer(settings?: ServerSettings): ClusterServer;
42
+ createClient(settings?: ClientSettings): ClusterClient;
43
+ backup(settings: BackupSettings): Promise<boolean>;
44
+ registerClass(name: string, classConstructor: any): void;
45
+ getRegisteredClasses(): string[];
46
+ }
47
+ //# sourceMappingURL=redux-cluster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redux-cluster.d.ts","sourceRoot":"","sources":["../../../src/core/redux-cluster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAW5D,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,IAAI,EACJ,cAAc,EAEd,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,kBAAkB,EAEnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMlD,qBAAa,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,CAC1D,YAAW,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC;IAGlC,SAAgB,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClD,SAAgB,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClD,SAAgB,SAAS,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACpD,SAAgB,cAAc,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC9D,SAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC;IAG3E,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,IAAI,EAAE,IAAI,EAAE,CAAM;IAC3B,SAAS,UAAS;IAClB,IAAI,EAAE,QAAQ,CAAY;IAC1B,MAAM,SAAQ;IACd,MAAM,EAAE,YAAY,CAAiB;IAC5C,SAAgB,MAAM,EAAE,kBAAkB,CAAC;IAE3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAI;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,WAAW,CAAC,CAA0B;IAC9C,OAAO,CAAC,WAAW,CAAC,CAAa;IACjC,OAAO,CAAC,aAAa,CAAyB;gBAElC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAE,kBAAuB;IA4EnE,OAAO,CAAC,YAAY;IASb,aAAa,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI;IAItC,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,gBAAgB;IAiCxB,OAAO,CAAC,mBAAmB;IAwD3B,OAAO,CAAC,mBAAmB;IAoCpB,SAAS,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;IA6BzC,aAAa,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;IAW7C,YAAY,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa;IAetD,YAAY,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa;IAetD,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,GAAG,IAAI;IASxD,oBAAoB,IAAI,MAAM,EAAE;CAMxC"}