reflex-sync 1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrei
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # REFLEX
2
+
3
+ Transparent reactive state synchronization for distributed Node.js environments.
4
+
5
+ ## ⚙️ Configuration Reference
6
+
7
+ ```typescript
8
+ interface ReflexOptions {
9
+ mode: 'master' | 'client';
10
+ host?: string; // Remote address (required for client)
11
+ port: number; // Port for TCP/TLS tunnel
12
+ key: string; // Shared secret for HMAC handshake
13
+ secure?: boolean; // Enable TLS 1.3 encryption
14
+ tls?: { // Standard Node.js TLS options
15
+ cert?: string;
16
+ key?: string;
17
+ ca?: string;
18
+ rejectUnauthorized?: boolean;
19
+ };
20
+ limits?: {
21
+ maxClients?: number; // Maximum inbound connections
22
+ maxPayloadSize?: number; // Inbound packet size cap (default 1MB)
23
+ opsPerSecond?: number; // Sliding-window update threshold (default 500)
24
+ };
25
+ }
26
+ ```
27
+
28
+ ## 🛠️ API Reference
29
+
30
+ ### `reflex.boot(): Promise<void>`
31
+ Initializes the instance. On `master`, starts the TCP/TLS listener. On `client`, initiates the handshake and state hydration.
32
+
33
+ ### `reflex.state: T`
34
+ A reactive `Proxy` representing the synchronized state. Changes made to this object are automatically propagated across the network using path-based delta updates. Supports deep nesting and property deletion.
35
+
36
+ ### 📡 Events
37
+
38
+ | Event | Origin | Payload | Description |
39
+ |-------|--------|---------|-------------|
40
+ | `ready` | Master | `string` | Listener is active and awaiting connections. |
41
+ | `synced` | Client | `void` | Initial state hydration from master is complete. |
42
+ | `update` | Any | `Packet` | Fired when a property change is received from the network. |
43
+ | `clientConnect` | Master | `string` | Fired when a client successfully authenticates (returns IP). |
44
+ | `error` | Any | `Error` | Fired on connection drops or socket failures. |
45
+ | `warn` | Any | `string` | Fired for non-fatal security violations (Rate limits, Over-sized payloads). |
46
+
47
+ ## 🕹️ Examples
48
+
49
+ ### Synchronization Patterns
50
+
51
+ ```typescript
52
+ // Master: Authoritative Node
53
+ const bot = new Reflex({ mode: 'master', port: 8080, key: 'secret' }, { stats: { uptime: 0 } });
54
+ await bot.boot();
55
+
56
+ // Client: Remote Dashboard
57
+ const web = new Reflex({ mode: 'client', host: 'bot.server.com', port: 8080, key: 'secret' });
58
+ await web.boot();
59
+
60
+ // Cross-application reaction
61
+ web.on('update', (pkg) => {
62
+ if (pkg.p.includes('uptime')) renderUI(pkg.v);
63
+ });
64
+ ```
65
+
66
+ ## 🔐 Protocol Implementation Details
67
+
68
+ ### Conflict Resolution
69
+ Reflex implements a **Last Write Wins (LWW)** strategy using UTC timestamps (`ts`) generated at the point of origin. Updates arriving at a node with a timestamp older than the current property metadata are discarded to prevent out-of-order state transitions.
70
+
71
+ ### Security Handshake
72
+ 1. Client initiates TCP/TLS connection.
73
+ 2. Client sends `AUTH` packet with the `key`.
74
+ 3. Master validates the `key`.
75
+ 4. Master transmits the full current state and metadata mapping (`SYNC`).
76
+ 5. Connection is promoted to the active sync set.
77
+
78
+ ---
79
+
80
+ MIT © 2026 Andrei
@@ -0,0 +1,61 @@
1
+ import { EventEmitter } from 'node:events';
2
+
3
+ /**
4
+ * @copyright 2026 Andrei
5
+ * @license MIT
6
+ * @package REFLEX
7
+ */
8
+ type Operation = 'SET' | 'DELETE' | 'AUTH' | 'SYNC' | 'PONG' | 'PING';
9
+ interface Packet {
10
+ t: Operation;
11
+ p?: string[];
12
+ v?: any;
13
+ ts?: number;
14
+ m?: Record<string, number>;
15
+ k?: string;
16
+ s?: string;
17
+ }
18
+ interface ReflexOptions {
19
+ host?: string;
20
+ port: number;
21
+ key: string;
22
+ mode: 'master' | 'client';
23
+ secure?: boolean;
24
+ tls?: {
25
+ cert?: string;
26
+ key?: string;
27
+ ca?: string;
28
+ rejectUnauthorized?: boolean;
29
+ };
30
+ limits?: {
31
+ maxClients?: number;
32
+ maxPayloadSize?: number;
33
+ opsPerSecond?: number;
34
+ };
35
+ }
36
+
37
+ /**
38
+ * @copyright 2026 Andrei
39
+ */
40
+
41
+ declare class Reflex<T extends object> extends EventEmitter {
42
+ private opts;
43
+ private _state;
44
+ private _proxy;
45
+ private _server;
46
+ private _socket;
47
+ private _clients;
48
+ private readonly _auth;
49
+ private _timestamps;
50
+ constructor(opts: ReflexOptions, initial?: T);
51
+ get state(): T;
52
+ boot(): Promise<void>;
53
+ private _serve;
54
+ private _join;
55
+ private _handleInbound;
56
+ private _process;
57
+ private _propagate;
58
+ private _transmit;
59
+ }
60
+
61
+ export { type Operation, type Packet, Reflex, type ReflexOptions };
package/dist/index.js ADDED
@@ -0,0 +1,256 @@
1
+ // src/core/Reflex.ts
2
+ import net from "net";
3
+ import tls from "tls";
4
+ import { EventEmitter } from "events";
5
+
6
+ // src/security/Authenticator.ts
7
+ import crypto from "crypto";
8
+ var Authenticator = class {
9
+ static ALGORITHM = "sha256";
10
+ clientOps = /* @__PURE__ */ new Map();
11
+ lastReset = Date.now();
12
+ /**
13
+ * @params {string} key
14
+ * @params {string} salt
15
+ * @returns {string} HMAC signature
16
+ */
17
+ static sign(key, salt) {
18
+ return crypto.createHmac(this.ALGORITHM, key).update(salt).digest("hex");
19
+ }
20
+ /**
21
+ * @params {string} challenge
22
+ * @params {string} signature
23
+ * @params {string} key
24
+ * @returns {boolean} Valid/Invalid
25
+ */
26
+ static verify(challenge, signature, key) {
27
+ const expected = this.sign(key, challenge);
28
+ return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
29
+ }
30
+ /**
31
+ * @params {string} id
32
+ * @params {number} limit
33
+ * @returns {boolean} Within limit/Exceeded
34
+ */
35
+ rateLimit(id, limit) {
36
+ const now = Date.now();
37
+ if (now - this.lastReset > 1e3) {
38
+ this.clientOps.clear();
39
+ this.lastReset = now;
40
+ }
41
+ const count = (this.clientOps.get(id) || 0) + 1;
42
+ if (count > limit) return false;
43
+ this.clientOps.set(id, count);
44
+ return true;
45
+ }
46
+ };
47
+
48
+ // src/state/ProxyManager.ts
49
+ var ProxyManager = class {
50
+ _onChange;
51
+ /**
52
+ * @params {(path: string[], value: any) => void} listener
53
+ */
54
+ constructor(listener) {
55
+ this._onChange = listener;
56
+ }
57
+ /**
58
+ * @params {T} source
59
+ * @params {string[]} path
60
+ * @returns {T} Observability Proxy
61
+ */
62
+ observe(source, path = []) {
63
+ const self = this;
64
+ return new Proxy(source, {
65
+ set(target, prop, value) {
66
+ const fullPath = [...path, String(prop)];
67
+ if (target[prop] === value) return true;
68
+ target[prop] = value;
69
+ self._onChange(fullPath, value);
70
+ return true;
71
+ },
72
+ get(target, prop) {
73
+ const value = target[prop];
74
+ if (typeof value === "object" && value !== null) {
75
+ return self.observe(value, [...path, String(prop)]);
76
+ }
77
+ return value;
78
+ },
79
+ deleteProperty(target, prop) {
80
+ delete target[prop];
81
+ self._onChange([...path, String(prop)], void 0);
82
+ return true;
83
+ }
84
+ });
85
+ }
86
+ /**
87
+ * @params {any} root
88
+ * @params {string[]} path
89
+ * @params {any} value
90
+ */
91
+ patch(root, path, value) {
92
+ const last = path.pop();
93
+ if (!last) return;
94
+ let target = root;
95
+ for (const segment of path) {
96
+ if (!target[segment]) target[segment] = {};
97
+ target = target[segment];
98
+ }
99
+ if (value === void 0) {
100
+ delete target[last];
101
+ } else {
102
+ target[last] = value;
103
+ }
104
+ }
105
+ };
106
+
107
+ // src/core/Reflex.ts
108
+ var Reflex = class extends EventEmitter {
109
+ constructor(opts, initial = {}) {
110
+ super();
111
+ this.opts = opts;
112
+ this._auth = new Authenticator();
113
+ this._proxy = new ProxyManager((p, v) => this._propagate(p, v));
114
+ this._state = this._proxy.observe(initial);
115
+ }
116
+ _state;
117
+ _proxy;
118
+ _server = null;
119
+ _socket = null;
120
+ _clients = /* @__PURE__ */ new Set();
121
+ _auth;
122
+ _timestamps = /* @__PURE__ */ new Map();
123
+ get state() {
124
+ return this._state;
125
+ }
126
+ async boot() {
127
+ if (this.opts.mode === "master") {
128
+ return this._serve();
129
+ } else {
130
+ return this._join();
131
+ }
132
+ }
133
+ async _serve() {
134
+ const handler = (s) => this._handleInbound(s);
135
+ if (this.opts.secure && this.opts.tls) {
136
+ this._server = tls.createServer(this.opts.tls, handler);
137
+ } else {
138
+ this._server = net.createServer(handler);
139
+ }
140
+ return new Promise((r) => {
141
+ this._server?.listen(this.opts.port, this.opts.host || "0.0.0.0", () => {
142
+ this.emit("ready", `REFLEX Master initialized on ${this.opts.port}`);
143
+ r();
144
+ });
145
+ });
146
+ }
147
+ async _join() {
148
+ return new Promise((resolve) => {
149
+ const connect = () => {
150
+ const port = this.opts.port;
151
+ const host = this.opts.host || "localhost";
152
+ if (this.opts.secure) {
153
+ this._socket = tls.connect({ port, host, ...this.opts.tls }, () => {
154
+ this._transmit({ t: "AUTH", k: this.opts.key });
155
+ resolve();
156
+ });
157
+ } else {
158
+ this._socket = net.connect({ port, host }, () => {
159
+ this._transmit({ t: "AUTH", k: this.opts.key });
160
+ resolve();
161
+ });
162
+ }
163
+ this._socket.on("data", (d) => this._process(d));
164
+ this._socket.on("error", (e) => {
165
+ this.emit("error", e);
166
+ setTimeout(connect, 5e3);
167
+ });
168
+ };
169
+ connect();
170
+ });
171
+ }
172
+ _handleInbound(s) {
173
+ let verified = false;
174
+ const remote = s.remoteAddress || "unknown";
175
+ const heartbeat = setInterval(() => {
176
+ if (s.writable) s.write(JSON.stringify({ t: "PING" }));
177
+ }, 3e4);
178
+ s.on("data", (d) => {
179
+ if (d.length > (this.opts.limits?.maxPayloadSize || 1024 * 1024)) {
180
+ this.emit("warn", `Payload too large from ${remote}`);
181
+ return s.destroy();
182
+ }
183
+ try {
184
+ const pkg = JSON.parse(d.toString());
185
+ if (pkg.t === "AUTH" && pkg.k === this.opts.key) {
186
+ verified = true;
187
+ this._clients.add(s);
188
+ s.write(JSON.stringify({ t: "SYNC", v: this.state, m: Object.fromEntries(this._timestamps) }));
189
+ this.emit("clientConnect", remote);
190
+ } else if (verified) {
191
+ if (pkg.t === "PONG") return;
192
+ if (!this._auth.rateLimit(remote, this.opts.limits?.opsPerSecond || 500)) return;
193
+ this._process(d, s);
194
+ } else {
195
+ s.destroy();
196
+ }
197
+ } catch (e) {
198
+ s.destroy();
199
+ }
200
+ });
201
+ s.on("close", () => {
202
+ clearInterval(heartbeat);
203
+ this._clients.delete(s);
204
+ });
205
+ }
206
+ _process(d, source) {
207
+ try {
208
+ const pkg = JSON.parse(d.toString());
209
+ if (pkg.t === "PING") return this._transmit({ t: "PONG" });
210
+ if (pkg.t === "SYNC" && this.opts.mode === "client") {
211
+ Object.assign(this.state, pkg.v);
212
+ if (pkg.m) this._timestamps = new Map(Object.entries(pkg.m));
213
+ this.emit("synced");
214
+ } else if (pkg.t === "SET") {
215
+ const key = pkg.p.join(".");
216
+ const last = this._timestamps.get(key) || 0;
217
+ if (pkg.ts && pkg.ts < last) return;
218
+ this._timestamps.set(key, pkg.ts || Date.now());
219
+ this._proxy.patch(this.state, pkg.p, pkg.v);
220
+ if (this.opts.mode === "master") {
221
+ const raw = d.toString();
222
+ this._clients.forEach((c) => {
223
+ if (c !== source) c.write(raw);
224
+ });
225
+ }
226
+ this.emit("update", pkg);
227
+ }
228
+ } catch (e) {
229
+ }
230
+ }
231
+ _propagate(p, v) {
232
+ const ts = Date.now();
233
+ this._timestamps.set(p.join("."), ts);
234
+ this._transmit({ t: "SET", p, v, ts });
235
+ }
236
+ _transmit(pkg) {
237
+ const raw = JSON.stringify(pkg);
238
+ if (this.opts.mode === "master") {
239
+ this._clients.forEach((c) => c.write(raw));
240
+ } else if (this._socket && !this._socket.destroyed) {
241
+ this._socket.write(raw);
242
+ }
243
+ }
244
+ };
245
+ export {
246
+ Reflex
247
+ };
248
+ /**
249
+ * @copyright 2026 Andrei
250
+ * @license MIT
251
+ */
252
+ /**
253
+ * @copyright 2026 Andrei
254
+ * @license MIT
255
+ * @package REFLEX
256
+ */
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "reflex-sync",
3
+ "version": "1.0.0",
4
+ "description": "High-performance, secure, real-time reactive state synchronization across processes and servers.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format esm --dts --clean",
16
+ "dev": "tsup src/index.ts --format esm --watch --dts",
17
+ "test": "node --test tests/*.test.js"
18
+ },
19
+ "keywords": [
20
+ "state",
21
+ "sync",
22
+ "reactive",
23
+ "ipc",
24
+ "tls",
25
+ "proxy",
26
+ "reflex"
27
+ ],
28
+ "author": "Andrei",
29
+ "license": "MIT",
30
+ "devDependencies": {
31
+ "tsup": "^8.0.2",
32
+ "typescript": "^5.3.3",
33
+ "@types/node": "^20.11.24"
34
+ },
35
+ "dependencies": {
36
+ "zod": "^3.22.4"
37
+ }
38
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @copyright 2026 Andrei
3
+ */
4
+
5
+ import net from 'node:net';
6
+ import tls from 'node:tls';
7
+ import { EventEmitter } from 'node:events';
8
+ import { ReflexOptions, Packet } from '../types/index.js';
9
+ import { Authenticator } from '../security/Authenticator.js';
10
+ import { ProxyManager } from '../state/ProxyManager.js';
11
+
12
+ export class Reflex<T extends object> extends EventEmitter {
13
+ private _state: T;
14
+ private _proxy: ProxyManager;
15
+ private _server: net.Server | tls.Server | null = null;
16
+ private _socket: net.Socket | tls.TLSSocket | null = null;
17
+ private _clients: Set<net.Socket | tls.TLSSocket> = new Set();
18
+ private readonly _auth: Authenticator;
19
+ private _timestamps: Map<string, number> = new Map();
20
+
21
+ constructor(private opts: ReflexOptions, initial: T = {} as T) {
22
+ super();
23
+ this._auth = new Authenticator();
24
+ this._proxy = new ProxyManager((p, v) => this._propagate(p, v));
25
+ this._state = this._proxy.observe(initial);
26
+ }
27
+
28
+ public get state(): T {
29
+ return this._state;
30
+ }
31
+
32
+ public async boot(): Promise<void> {
33
+ if (this.opts.mode === 'master') {
34
+ return this._serve();
35
+ } else {
36
+ return this._join();
37
+ }
38
+ }
39
+
40
+ private async _serve(): Promise<void> {
41
+ const handler = (s: net.Socket | tls.TLSSocket) => this._handleInbound(s);
42
+
43
+ if (this.opts.secure && this.opts.tls) {
44
+ this._server = tls.createServer(this.opts.tls, handler);
45
+ } else {
46
+ this._server = net.createServer(handler);
47
+ }
48
+
49
+ return new Promise((r) => {
50
+ this._server?.listen(this.opts.port, this.opts.host || '0.0.0.0', () => {
51
+ this.emit('ready', `REFLEX Master initialized on ${this.opts.port}`);
52
+ r();
53
+ });
54
+ });
55
+ }
56
+
57
+ private async _join(): Promise<void> {
58
+ return new Promise((resolve) => {
59
+ const connect = () => {
60
+ const port = this.opts.port;
61
+ const host = this.opts.host || 'localhost';
62
+
63
+ if (this.opts.secure) {
64
+ this._socket = tls.connect({ port, host, ...this.opts.tls }, () => {
65
+ this._transmit({ t: 'AUTH', k: this.opts.key });
66
+ resolve();
67
+ });
68
+ } else {
69
+ this._socket = net.connect({ port, host }, () => {
70
+ this._transmit({ t: 'AUTH', k: this.opts.key });
71
+ resolve();
72
+ });
73
+ }
74
+
75
+ this._socket.on('data', (d: Buffer) => this._process(d));
76
+ this._socket.on('error', (e: Error) => {
77
+ this.emit('error', e);
78
+ setTimeout(connect, 5000);
79
+ });
80
+ };
81
+ connect();
82
+ });
83
+ }
84
+
85
+ private _handleInbound(s: net.Socket | tls.TLSSocket): void {
86
+ let verified = false;
87
+ const remote = s.remoteAddress || 'unknown';
88
+
89
+ const heartbeat = setInterval(() => {
90
+ if (s.writable) s.write(JSON.stringify({ t: 'PING' }));
91
+ }, 30000);
92
+
93
+ s.on('data', (d: Buffer) => {
94
+ if (d.length > (this.opts.limits?.maxPayloadSize || 1024 * 1024)) {
95
+ this.emit('warn', `Payload too large from ${remote}`);
96
+ return s.destroy();
97
+ }
98
+
99
+ try {
100
+ const pkg: Packet = JSON.parse(d.toString());
101
+
102
+ if (pkg.t === 'AUTH' && pkg.k === this.opts.key) {
103
+ verified = true;
104
+ this._clients.add(s);
105
+ s.write(JSON.stringify({ t: 'SYNC', v: this.state, m: Object.fromEntries(this._timestamps) }));
106
+ this.emit('clientConnect', remote);
107
+ } else if (verified) {
108
+ if (pkg.t === 'PONG') return;
109
+ if (!this._auth.rateLimit(remote, this.opts.limits?.opsPerSecond || 500)) return;
110
+ this._process(d, s);
111
+ } else {
112
+ s.destroy();
113
+ }
114
+ } catch (e) { s.destroy(); }
115
+ });
116
+
117
+ s.on('close', () => {
118
+ clearInterval(heartbeat);
119
+ this._clients.delete(s);
120
+ });
121
+ }
122
+
123
+ private _process(d: Buffer, source?: net.Socket | tls.TLSSocket): void {
124
+ try {
125
+ const pkg: Packet = JSON.parse(d.toString());
126
+ if (pkg.t === 'PING') return this._transmit({ t: 'PONG' });
127
+
128
+ if (pkg.t === 'SYNC' && this.opts.mode === 'client') {
129
+ Object.assign(this.state, pkg.v);
130
+ if (pkg.m) this._timestamps = new Map(Object.entries(pkg.m));
131
+ this.emit('synced');
132
+ } else if (pkg.t === 'SET') {
133
+ const key = pkg.p!.join('.');
134
+ const last = this._timestamps.get(key) || 0;
135
+
136
+ if (pkg.ts && pkg.ts < last) return; // Conflict resolution: LWW
137
+
138
+ this._timestamps.set(key, pkg.ts || Date.now());
139
+ this._proxy.patch(this.state, pkg.p!, pkg.v);
140
+
141
+ if (this.opts.mode === 'master') {
142
+ const raw = d.toString();
143
+ this._clients.forEach(c => { if (c !== source) c.write(raw); });
144
+ }
145
+ this.emit('update', pkg);
146
+ }
147
+ } catch (e) {}
148
+ }
149
+
150
+ private _propagate(p: string[], v: any): void {
151
+ const ts = Date.now();
152
+ this._timestamps.set(p.join('.'), ts);
153
+ this._transmit({ t: 'SET', p, v, ts });
154
+ }
155
+
156
+ private _transmit(pkg: Packet): void {
157
+ const raw = JSON.stringify(pkg);
158
+ if (this.opts.mode === 'master') {
159
+ this._clients.forEach(c => c.write(raw));
160
+ } else if (this._socket && !this._socket.destroyed) {
161
+ this._socket.write(raw);
162
+ }
163
+ }
164
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @copyright 2026 Andrei
3
+ * @license MIT
4
+ */
5
+
6
+ export * from './core/Reflex.js';
7
+ export * from './types/index.js';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @copyright 2026 Andrei
3
+ * @license MIT
4
+ */
5
+
6
+ import crypto from 'node:crypto';
7
+
8
+ export class Authenticator {
9
+ private static readonly ALGORITHM = 'sha256';
10
+ private clientOps: Map<string, number> = new Map();
11
+ private lastReset = Date.now();
12
+
13
+ /**
14
+ * @params {string} key
15
+ * @params {string} salt
16
+ * @returns {string} HMAC signature
17
+ */
18
+ public static sign(key: string, salt: string): string {
19
+ return crypto
20
+ .createHmac(this.ALGORITHM, key)
21
+ .update(salt)
22
+ .digest('hex');
23
+ }
24
+
25
+ /**
26
+ * @params {string} challenge
27
+ * @params {string} signature
28
+ * @params {string} key
29
+ * @returns {boolean} Valid/Invalid
30
+ */
31
+ public static verify(challenge: string, signature: string, key: string): boolean {
32
+ const expected = this.sign(key, challenge);
33
+ return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
34
+ }
35
+
36
+ /**
37
+ * @params {string} id
38
+ * @params {number} limit
39
+ * @returns {boolean} Within limit/Exceeded
40
+ */
41
+ public rateLimit(id: string, limit: number): boolean {
42
+ const now = Date.now();
43
+ if (now - this.lastReset > 1000) {
44
+ this.clientOps.clear();
45
+ this.lastReset = now;
46
+ }
47
+
48
+ const count = (this.clientOps.get(id) || 0) + 1;
49
+ if (count > limit) return false;
50
+
51
+ this.clientOps.set(id, count);
52
+ return true;
53
+ }
54
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @copyright 2026 Andrei
3
+ */
4
+
5
+ export class ProxyManager {
6
+ private _onChange: (path: string[], value: any) => void;
7
+
8
+ /**
9
+ * @params {(path: string[], value: any) => void} listener
10
+ */
11
+ constructor(listener: (path: string[], value: any) => void) {
12
+ this._onChange = listener;
13
+ }
14
+
15
+ /**
16
+ * @params {T} source
17
+ * @params {string[]} path
18
+ * @returns {T} Observability Proxy
19
+ */
20
+ public observe<T extends object>(source: T, path: string[] = []): T {
21
+ const self = this;
22
+ return new Proxy(source, {
23
+ set(target: any, prop: string | symbol, value: any): boolean {
24
+ const fullPath = [...path, String(prop)];
25
+
26
+ // Prevent recursive triggers if same value
27
+ if (target[prop] === value) return true;
28
+
29
+ target[prop] = value;
30
+ self._onChange(fullPath, value);
31
+ return true;
32
+ },
33
+ get(target: any, prop: string | symbol): any {
34
+ const value = target[prop];
35
+ if (typeof value === 'object' && value !== null) {
36
+ return self.observe(value, [...path, String(prop)]);
37
+ }
38
+ return value;
39
+ },
40
+ deleteProperty(target: any, prop: string | symbol): boolean {
41
+ delete target[prop];
42
+ self._onChange([...path, String(prop)], undefined);
43
+ return true;
44
+ }
45
+ });
46
+ }
47
+
48
+ /**
49
+ * @params {any} root
50
+ * @params {string[]} path
51
+ * @params {any} value
52
+ */
53
+ public patch(root: any, path: string[], value: any): void {
54
+ const last = path.pop();
55
+ if (!last) return;
56
+
57
+ let target = root;
58
+ for (const segment of path) {
59
+ if (!target[segment]) target[segment] = {};
60
+ target = target[segment];
61
+ }
62
+
63
+ if (value === undefined) {
64
+ delete target[last];
65
+ } else {
66
+ target[last] = value;
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @copyright 2026 Andrei
3
+ * @license MIT
4
+ * @package REFLEX
5
+ */
6
+
7
+ export type Operation = 'SET' | 'DELETE' | 'AUTH' | 'SYNC' | 'PONG' | 'PING';
8
+
9
+ export interface Packet {
10
+ t: Operation;
11
+ p?: string[]; // Path
12
+ v?: any; // Value
13
+ ts?: number; // Timestamp (Conflict Resolution)
14
+ m?: Record<string, number>; // Full Metadata Sync
15
+ k?: string; // Key/Handshake
16
+ s?: string; // Salt/Signature
17
+ }
18
+
19
+ export interface ReflexOptions {
20
+ host?: string;
21
+ port: number;
22
+ key: string;
23
+ mode: 'master' | 'client';
24
+ secure?: boolean;
25
+ tls?: {
26
+ cert?: string;
27
+ key?: string;
28
+ ca?: string;
29
+ rejectUnauthorized?: boolean;
30
+ };
31
+ limits?: {
32
+ maxClients?: number;
33
+ maxPayloadSize?: number; // In bytes
34
+ opsPerSecond?: number;
35
+ };
36
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "node",
6
+ "strict": true,
7
+ "declaration": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "outDir": "./dist"
12
+ },
13
+ "include": ["src/**/*"],
14
+ "exclude": ["node_modules", "dist"]
15
+ }