@asaidimu/utils-store 2.0.2 → 2.0.4

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/index.js CHANGED
@@ -1,1298 +1 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJS = (cb, mod) => function __require() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
- };
11
- var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
14
- };
15
- var __copyProps = (to, from, except, desc) => {
16
- if (from && typeof from === "object" || typeof from === "function") {
17
- for (let key of __getOwnPropNames(from))
18
- if (!__hasOwnProp.call(to, key) && key !== except)
19
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
- }
21
- return to;
22
- };
23
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
- // If the importer is in node compatibility mode or this is not an ESM
25
- // file that has been converted to a CommonJS file using a Babel-
26
- // compatible transform (i.e. "__esModule" has not been set), then set
27
- // "default" to the CommonJS "module.exports" for node compatibility.
28
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
- mod
30
- ));
31
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
-
33
- // node_modules/@asaidimu/events/index.js
34
- var require_events = __commonJS({
35
- "node_modules/@asaidimu/events/index.js"(exports2, module2) {
36
- "use strict";
37
- var __defProp2 = Object.defineProperty;
38
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
39
- var __getOwnPropNames2 = Object.getOwnPropertyNames;
40
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
41
- var __export2 = (target, all) => {
42
- for (var name in all)
43
- __defProp2(target, name, { get: all[name], enumerable: true });
44
- };
45
- var __copyProps2 = (to, from, except, desc) => {
46
- if (from && typeof from === "object" || typeof from === "function") {
47
- for (let key of __getOwnPropNames2(from))
48
- if (!__hasOwnProp2.call(to, key) && key !== except)
49
- __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
50
- }
51
- return to;
52
- };
53
- var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
54
- var events_exports = {};
55
- __export2(events_exports, {
56
- createEventBus: () => createEventBus6
57
- });
58
- module2.exports = __toCommonJS2(events_exports);
59
- var createEventBus6 = (options = {
60
- async: false,
61
- batchSize: 1e3,
62
- batchDelay: 16,
63
- errorHandler: (error) => console.error("EventBus Error:", error),
64
- crossTab: false,
65
- channelName: "event-bus-channel"
66
- // Unique channel name
67
- }) => {
68
- const subscribers = /* @__PURE__ */ new Map();
69
- let eventQueue = [];
70
- let totalEvents = 0;
71
- let totalDuration = 0;
72
- const eventCounts = /* @__PURE__ */ new Map();
73
- const cachedArrays = /* @__PURE__ */ new Map();
74
- let broadcastChannel = null;
75
- if (options.crossTab && typeof BroadcastChannel !== "undefined") {
76
- broadcastChannel = new BroadcastChannel(options.channelName);
77
- } else if (options.crossTab) {
78
- console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");
79
- }
80
- const updateMetrics = (eventName, duration) => {
81
- totalEvents++;
82
- totalDuration += duration;
83
- eventCounts.set(
84
- eventName,
85
- (eventCounts.get(eventName) || 0) + 1
86
- );
87
- };
88
- const processBatch = () => {
89
- const batchToProcess = eventQueue;
90
- eventQueue = [];
91
- batchToProcess.forEach(({ name, payload }) => {
92
- const start = performance.now();
93
- try {
94
- const callbacks = cachedArrays.get(name) || [];
95
- callbacks.forEach((callback) => callback(payload));
96
- } catch (error) {
97
- options.errorHandler({
98
- ...error,
99
- eventName: name,
100
- payload
101
- });
102
- }
103
- updateMetrics(name, performance.now() - start);
104
- });
105
- };
106
- const debouncedProcess = /* @__PURE__ */ (() => {
107
- let timeoutId;
108
- return () => {
109
- clearTimeout(timeoutId);
110
- timeoutId = setTimeout(processBatch, options.batchDelay);
111
- };
112
- })();
113
- const updateCachedArray = (eventName) => {
114
- const callbackSet = subscribers.get(eventName);
115
- if (callbackSet) {
116
- cachedArrays.set(eventName, Array.from(callbackSet));
117
- } else {
118
- cachedArrays.delete(eventName);
119
- }
120
- };
121
- if (broadcastChannel) {
122
- broadcastChannel.onmessage = (event) => {
123
- const { name, payload } = event.data;
124
- const callbacks = cachedArrays.get(name) || [];
125
- callbacks.forEach((callback) => callback(payload));
126
- };
127
- }
128
- return {
129
- subscribe: (eventName, callback) => {
130
- if (!subscribers.has(eventName)) {
131
- subscribers.set(eventName, /* @__PURE__ */ new Set());
132
- }
133
- const callbacks = subscribers.get(eventName);
134
- callbacks.add(callback);
135
- updateCachedArray(eventName);
136
- return () => {
137
- callbacks.delete(callback);
138
- if (callbacks.size === 0) {
139
- subscribers.delete(eventName);
140
- cachedArrays.delete(eventName);
141
- } else {
142
- updateCachedArray(eventName);
143
- }
144
- };
145
- },
146
- emit: ({ name, payload }) => {
147
- if (options.async) {
148
- eventQueue.push({ name, payload });
149
- if (eventQueue.length >= options.batchSize) {
150
- processBatch();
151
- } else {
152
- debouncedProcess();
153
- }
154
- if (broadcastChannel) {
155
- broadcastChannel.postMessage({ name, payload });
156
- }
157
- return;
158
- }
159
- const start = performance.now();
160
- try {
161
- const callbacks = cachedArrays.get(name) || [];
162
- callbacks.forEach((callback) => callback(payload));
163
- if (broadcastChannel) {
164
- broadcastChannel.postMessage({ name, payload });
165
- }
166
- } catch (error) {
167
- options.errorHandler({
168
- ...error,
169
- eventName: name,
170
- payload
171
- });
172
- }
173
- updateMetrics(name, performance.now() - start);
174
- },
175
- getMetrics: () => ({
176
- totalEvents,
177
- activeSubscriptions: Array.from(subscribers.values()).reduce((acc, set) => acc + set.size, 0),
178
- eventCounts,
179
- averageEmitDuration: totalEvents > 0 ? totalDuration / totalEvents : 0
180
- }),
181
- clear: () => {
182
- subscribers.clear();
183
- cachedArrays.clear();
184
- eventQueue = [];
185
- totalEvents = 0;
186
- totalDuration = 0;
187
- eventCounts.clear();
188
- if (broadcastChannel) {
189
- broadcastChannel.close();
190
- broadcastChannel = null;
191
- }
192
- }
193
- };
194
- };
195
- }
196
- });
197
-
198
- // src/store/index.ts
199
- var store_exports = {};
200
- __export(store_exports, {
201
- DELETE_SYMBOL: () => DELETE_SYMBOL,
202
- ReactiveDataStore: () => ReactiveDataStore,
203
- StoreObserver: () => StoreObserver
204
- });
205
- module.exports = __toCommonJS(store_exports);
206
-
207
- // src/store/store.ts
208
- var import_events5 = __toESM(require_events());
209
-
210
- // node_modules/uuid/dist/esm/stringify.js
211
- var byteToHex = [];
212
- for (let i = 0; i < 256; ++i) {
213
- byteToHex.push((i + 256).toString(16).slice(1));
214
- }
215
- function unsafeStringify(arr, offset = 0) {
216
- return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
217
- }
218
-
219
- // node_modules/uuid/dist/esm/rng.js
220
- var import_crypto = require("crypto");
221
- var rnds8Pool = new Uint8Array(256);
222
- var poolPtr = rnds8Pool.length;
223
- function rng() {
224
- if (poolPtr > rnds8Pool.length - 16) {
225
- (0, import_crypto.randomFillSync)(rnds8Pool);
226
- poolPtr = 0;
227
- }
228
- return rnds8Pool.slice(poolPtr, poolPtr += 16);
229
- }
230
-
231
- // node_modules/uuid/dist/esm/native.js
232
- var import_crypto2 = require("crypto");
233
- var native_default = { randomUUID: import_crypto2.randomUUID };
234
-
235
- // node_modules/uuid/dist/esm/v4.js
236
- function v4(options, buf, offset) {
237
- if (native_default.randomUUID && !buf && !options) {
238
- return native_default.randomUUID();
239
- }
240
- options = options || {};
241
- const rnds = options.random ?? options.rng?.() ?? rng();
242
- if (rnds.length < 16) {
243
- throw new Error("Random bytes length must be >= 16");
244
- }
245
- rnds[6] = rnds[6] & 15 | 64;
246
- rnds[8] = rnds[8] & 63 | 128;
247
- if (buf) {
248
- offset = offset || 0;
249
- if (offset < 0 || offset + 16 > buf.length) {
250
- throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
251
- }
252
- for (let i = 0; i < 16; ++i) {
253
- buf[offset + i] = rnds[i];
254
- }
255
- return buf;
256
- }
257
- return unsafeStringify(rnds);
258
- }
259
- var v4_default = v4;
260
-
261
- // src/store/types.ts
262
- var DELETE_SYMBOL = Symbol.for("delete");
263
-
264
- // src/store/merge.ts
265
- var shallowClone = (obj) => {
266
- if (Array.isArray(obj)) {
267
- return [...obj];
268
- }
269
- return { ...obj };
270
- };
271
- function createMerge(options) {
272
- const deleteSymbol = options?.deleteMarker || DELETE_SYMBOL;
273
- function mergeFn(original, changes) {
274
- if (typeof original !== "object" || original === null) {
275
- if (typeof changes === "object" && changes !== null) {
276
- return cleanObject(changes);
277
- }
278
- return changes === deleteSymbol ? {} : changes;
279
- }
280
- if (typeof changes !== "object" || changes === null) {
281
- return original;
282
- }
283
- const result = shallowClone(original);
284
- const stack = [
285
- { target: result, source: changes }
286
- ];
287
- while (stack.length > 0) {
288
- const { target, source } = stack.pop();
289
- for (const key of Object.keys(source)) {
290
- if (!Object.prototype.hasOwnProperty.call(source, key)) {
291
- continue;
292
- }
293
- const sourceValue = source[key];
294
- if (sourceValue === deleteSymbol) {
295
- delete target[key];
296
- continue;
297
- }
298
- if (Array.isArray(sourceValue)) {
299
- target[key] = sourceValue.map(
300
- (item) => typeof item === "object" && item !== null && !Array.isArray(item) ? cleanObject(item) : item === deleteSymbol ? void 0 : item
301
- );
302
- continue;
303
- }
304
- if (typeof sourceValue === "object" && sourceValue !== null) {
305
- target[key] = shallowClone(
306
- key in target && typeof target[key] === "object" && target[key] !== null ? target[key] : {}
307
- );
308
- stack.push({
309
- target: target[key],
310
- source: sourceValue
311
- });
312
- } else {
313
- target[key] = sourceValue;
314
- }
315
- }
316
- }
317
- return result;
318
- function cleanObject(obj) {
319
- if (obj === null || obj === void 0) {
320
- return obj;
321
- }
322
- if (Array.isArray(obj)) {
323
- return obj.filter((item) => item !== deleteSymbol).map(
324
- (item) => typeof item === "object" && item !== null && !Array.isArray(item) ? cleanObject(item) : item === deleteSymbol ? void 0 : item
325
- );
326
- }
327
- if (typeof obj === "object") {
328
- const result2 = {};
329
- for (const [key, value] of Object.entries(obj)) {
330
- if (value === deleteSymbol) {
331
- continue;
332
- }
333
- if (typeof value === "object" && value !== null) {
334
- const cleanedValue = cleanObject(value);
335
- if (cleanedValue !== void 0) {
336
- result2[key] = cleanedValue;
337
- }
338
- } else {
339
- result2[key] = value;
340
- }
341
- }
342
- return result2;
343
- }
344
- return obj === deleteSymbol ? void 0 : obj;
345
- }
346
- }
347
- return mergeFn;
348
- }
349
- var merge = createMerge();
350
-
351
- // src/store/diff.ts
352
- function createDiff(options) {
353
- const deleteSymbol = options?.deleteMarker || DELETE_SYMBOL;
354
- function diffFn(original, partial) {
355
- const changedPaths = /* @__PURE__ */ new Set();
356
- const orig = original || {};
357
- const part = partial || {};
358
- const add = (s) => changedPaths.add(s);
359
- function addPath(path) {
360
- if (!path)
361
- return;
362
- const parts = path.split(".");
363
- add(path);
364
- for (let i = parts.length - 1; i > 0; i--) {
365
- const parentPath = parts.slice(0, i).join(".");
366
- if (changedPaths.has(parentPath))
367
- break;
368
- add(parentPath);
369
- }
370
- }
371
- const stack = [
372
- { path: "", orig, part }
373
- ];
374
- while (stack.length > 0) {
375
- const { path, orig: orig2, part: part2 } = stack.pop();
376
- if (part2 === null || part2 === void 0)
377
- continue;
378
- if (Array.isArray(part2)) {
379
- if (!Array.isArray(orig2) || JSON.stringify(orig2) !== JSON.stringify(part2)) {
380
- addPath(path);
381
- }
382
- } else if (typeof part2 === "object") {
383
- const keys = Object.keys(part2);
384
- for (let i = 0; i < keys.length; i++) {
385
- const key = keys[i];
386
- const newPath = path ? `${path}.${key}` : key;
387
- const partValue = part2[key];
388
- if (partValue === deleteSymbol || orig2 === null || orig2 === void 0) {
389
- addPath(newPath);
390
- continue;
391
- }
392
- const origValue = orig2[key];
393
- if (typeof partValue === "object" && partValue !== null) {
394
- stack.push({ path: newPath, orig: origValue, part: partValue });
395
- } else if (origValue !== partValue) {
396
- addPath(newPath);
397
- }
398
- }
399
- }
400
- }
401
- return Array.from(changedPaths);
402
- }
403
- return diffFn;
404
- }
405
- function createDerivePaths(options) {
406
- const deleteSymbol = options?.deleteMarker || DELETE_SYMBOL;
407
- function derivePathsFn(changes) {
408
- const paths = /* @__PURE__ */ new Set();
409
- function extractPaths(obj, currentPath = "") {
410
- if (obj === null || obj === void 0)
411
- return;
412
- if (typeof obj === "object" && !Array.isArray(obj)) {
413
- const keys = Object.keys(obj);
414
- for (let i = 0; i < keys.length; i++) {
415
- const key = keys[i];
416
- const newPath = currentPath ? `${currentPath}.${key}` : key;
417
- paths.add(newPath);
418
- if (typeof obj[key] === "object" && obj[key] !== null && obj[key] !== deleteSymbol) {
419
- extractPaths(obj[key], newPath);
420
- }
421
- }
422
- } else if (currentPath) {
423
- paths.add(currentPath);
424
- }
425
- }
426
- extractPaths(changes);
427
- const result = Array.from(paths);
428
- const parentPaths = /* @__PURE__ */ new Set();
429
- for (const path of result) {
430
- const parts = path.split(".");
431
- for (let i = 1; i < parts.length; i++) {
432
- const parentPath = parts.slice(0, i).join(".");
433
- if (parentPaths.has(parentPath))
434
- break;
435
- parentPaths.add(parentPath);
436
- }
437
- }
438
- return [...result, ...parentPaths];
439
- }
440
- return derivePathsFn;
441
- }
442
- var diff = createDiff();
443
- var derivePaths = createDerivePaths();
444
-
445
- // src/store/state.ts
446
- var CoreStateManager = class {
447
- constructor(initialData, updateBus, diff3) {
448
- this.updateBus = updateBus;
449
- this.diff = diff3;
450
- this.cache = structuredClone(initialData);
451
- }
452
- cache;
453
- get(clone) {
454
- if (clone) {
455
- return structuredClone(this.cache);
456
- }
457
- return this.cache;
458
- }
459
- applyChanges(newState) {
460
- const changedPaths = this.diff(this.get(true), newState);
461
- if (changedPaths.length > 0) {
462
- this.cache = structuredClone(newState);
463
- this.notifyListeners(changedPaths);
464
- }
465
- return changedPaths;
466
- }
467
- notifyListeners(changedPaths) {
468
- changedPaths.forEach(
469
- (changed) => this.updateBus.emit({
470
- name: "update",
471
- payload: changed
472
- })
473
- );
474
- }
475
- };
476
-
477
- // src/store/middleware.ts
478
- var import_events = __toESM(require_events());
479
- var MiddlewareEngine = class {
480
- constructor(eventBus, executionState, merge2) {
481
- this.eventBus = eventBus;
482
- this.executionState = executionState;
483
- this.merge = merge2;
484
- }
485
- middleware = [];
486
- blockingMiddleware = [];
487
- async executeBlocking(currentState, partialUpdate) {
488
- for (const { fn, name, id } of this.blockingMiddleware) {
489
- const execInfo = {
490
- id,
491
- name,
492
- startTime: performance.now()
493
- };
494
- this.executionState.runningMiddleware = {
495
- id,
496
- name,
497
- startTime: performance.now()
498
- };
499
- this.emitMiddlewareLifecycle("start", { id, name, type: "blocking" });
500
- try {
501
- const result = await Promise.resolve(fn(currentState, partialUpdate));
502
- execInfo.endTime = performance.now();
503
- execInfo.duration = execInfo.endTime - execInfo.startTime;
504
- if (result === false) {
505
- execInfo.blocked = true;
506
- this.emitMiddlewareLifecycle("blocked", { id, name, duration: execInfo.duration });
507
- this.eventBus.emit({ name: "middleware:executed", payload: execInfo });
508
- return { blocked: true };
509
- }
510
- this.emitMiddlewareLifecycle("complete", { id, name, type: "blocking", duration: execInfo.duration });
511
- this.eventBus.emit({ name: "middleware:executed", payload: { ...execInfo, blocked: false } });
512
- } catch (error) {
513
- execInfo.endTime = performance.now();
514
- execInfo.duration = execInfo.endTime - execInfo.startTime;
515
- execInfo.error = error instanceof Error ? error : new Error(String(error));
516
- execInfo.blocked = true;
517
- this.emitMiddlewareError(id, name, execInfo.error, execInfo.duration);
518
- this.eventBus.emit({ name: "middleware:executed", payload: execInfo });
519
- return { blocked: true, error: execInfo.error };
520
- } finally {
521
- this.executionState.runningMiddleware = null;
522
- }
523
- }
524
- return { blocked: false };
525
- }
526
- async executeTransform(initialState, partialUpdate) {
527
- let currentState = initialState;
528
- let changes = partialUpdate;
529
- for (const { fn, name, id } of this.middleware) {
530
- const execInfo = {
531
- id,
532
- name,
533
- startTime: performance.now()
534
- };
535
- this.executionState.runningMiddleware = {
536
- id,
537
- name,
538
- startTime: performance.now()
539
- };
540
- this.emitMiddlewareLifecycle("start", { id, name, type: "transform" });
541
- try {
542
- const middlewareResult = await Promise.resolve(fn(currentState, partialUpdate));
543
- execInfo.endTime = performance.now();
544
- execInfo.duration = execInfo.endTime - execInfo.startTime;
545
- execInfo.blocked = false;
546
- if (middlewareResult && typeof middlewareResult === "object") {
547
- currentState = this.merge(currentState, middlewareResult);
548
- changes = this.merge(changes, middlewareResult);
549
- }
550
- this.eventBus.emit({ name: "middleware:executed", payload: execInfo });
551
- this.emitMiddlewareLifecycle("complete", { id, name, type: "transform", duration: execInfo.duration });
552
- } catch (e) {
553
- execInfo.endTime = performance.now();
554
- execInfo.duration = execInfo.endTime - execInfo.startTime;
555
- execInfo.error = e instanceof Error ? e : new Error(String(e));
556
- execInfo.blocked = false;
557
- this.eventBus.emit({ name: "middleware:executed", payload: execInfo });
558
- this.emitMiddlewareError(id, name, execInfo.error, execInfo.duration);
559
- console.error(`Middleware ${name} error:`, e);
560
- } finally {
561
- this.executionState.runningMiddleware = null;
562
- }
563
- }
564
- return changes;
565
- }
566
- addMiddleware(middleware, name = "unnamed-middleware") {
567
- const id = this.generateId();
568
- this.middleware.push({ fn: middleware, name, id });
569
- this.updateExecutionState();
570
- return id;
571
- }
572
- addBlockingMiddleware(middleware, name = "unnamed-blocking-middleware") {
573
- const id = this.generateId();
574
- this.blockingMiddleware.push({ fn: middleware, name, id });
575
- this.updateExecutionState();
576
- return id;
577
- }
578
- removeMiddleware(id) {
579
- const initialLength = this.middleware.length + this.blockingMiddleware.length;
580
- this.middleware = this.middleware.filter((m) => m.id !== id);
581
- this.blockingMiddleware = this.blockingMiddleware.filter((m) => m.id !== id);
582
- this.updateExecutionState();
583
- return this.middleware.length + this.blockingMiddleware.length < initialLength;
584
- }
585
- updateExecutionState() {
586
- this.executionState.middlewares = [
587
- ...this.middleware.map((m) => m.name),
588
- ...this.blockingMiddleware.map((m) => m.name)
589
- ];
590
- }
591
- emitMiddlewareLifecycle(phase, data) {
592
- this.eventBus.emit({
593
- name: `middleware:${phase}`,
594
- payload: { ...data, timestamp: Date.now() }
595
- });
596
- }
597
- emitMiddlewareError(id, name, error, duration) {
598
- this.eventBus.emit({
599
- name: "middleware:error",
600
- payload: { id, name, error, duration, timestamp: Date.now() }
601
- });
602
- }
603
- generateId() {
604
- return crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
605
- }
606
- };
607
-
608
- // src/store/persistence.ts
609
- var import_events2 = __toESM(require_events());
610
- var PersistenceHandler = class {
611
- constructor(eventBus, coreState, instanceID) {
612
- this.eventBus = eventBus;
613
- this.coreState = coreState;
614
- this.instanceID = instanceID;
615
- }
616
- persistence;
617
- instanceID;
618
- persistenceReady = false;
619
- async initialize(persistence) {
620
- if (persistence) {
621
- await this.setPersistence(persistence);
622
- } else {
623
- this.setPersistenceReady();
624
- }
625
- }
626
- isReady() {
627
- return this.persistenceReady;
628
- }
629
- async handleStateChange(changedPaths, state) {
630
- if (!this.persistence || changedPaths.length === 0)
631
- return;
632
- try {
633
- const success = await this.persistence.set(this.instanceID, state);
634
- if (!success) {
635
- this.eventBus.emit({
636
- name: "update:complete",
637
- payload: { persistence: false, timestamp: Date.now() }
638
- });
639
- }
640
- } catch (error) {
641
- this.eventBus.emit({
642
- name: "update:complete",
643
- payload: { persistence: false, error, timestamp: Date.now() }
644
- });
645
- }
646
- }
647
- setPersistenceReady() {
648
- this.persistenceReady = true;
649
- this.eventBus.emit({
650
- name: "persistence:ready",
651
- payload: { timestamp: Date.now() }
652
- });
653
- }
654
- async setPersistence(persistence) {
655
- this.persistence = persistence;
656
- try {
657
- const persistedState = await this.persistence.get();
658
- if (persistedState) {
659
- this.coreState.applyChanges(persistedState);
660
- }
661
- } catch (error) {
662
- console.error("Failed to initialize persistence:", error);
663
- } finally {
664
- this.setPersistenceReady();
665
- }
666
- this.persistence.subscribe(this.instanceID, async (state) => {
667
- const changedPaths = this.coreState.applyChanges(state);
668
- if (changedPaths.length > 0) {
669
- this.eventBus.emit({
670
- name: "update:complete",
671
- payload: {
672
- changedPaths,
673
- source: "external",
674
- timestamp: Date.now()
675
- }
676
- });
677
- }
678
- });
679
- }
680
- };
681
-
682
- // src/store/transactions.ts
683
- var import_events3 = __toESM(require_events());
684
- var TransactionManager = class {
685
- constructor(eventBus, coreState, executionState) {
686
- this.eventBus = eventBus;
687
- this.coreState = coreState;
688
- this.executionState = executionState;
689
- }
690
- async execute(operation) {
691
- const snapshot = this.coreState.get(true);
692
- this.executionState.transactionActive = true;
693
- this.eventBus.emit({
694
- name: "transaction:start",
695
- payload: { timestamp: Date.now() }
696
- });
697
- try {
698
- const result = await Promise.resolve(operation());
699
- this.eventBus.emit({
700
- name: "transaction:complete",
701
- payload: { timestamp: Date.now() }
702
- });
703
- this.executionState.transactionActive = false;
704
- return result;
705
- } catch (error) {
706
- this.coreState.applyChanges(snapshot);
707
- this.eventBus.emit({
708
- name: "transaction:error",
709
- payload: {
710
- error: error instanceof Error ? error : new Error(String(error)),
711
- timestamp: Date.now()
712
- }
713
- });
714
- this.executionState.transactionActive = false;
715
- throw error;
716
- }
717
- }
718
- };
719
-
720
- // src/store/metrics.ts
721
- var import_events4 = __toESM(require_events());
722
- var MetricsCollector = class {
723
- updateCount = 0;
724
- listenerExecutions = 0;
725
- averageUpdateTime = 0;
726
- largestUpdateSize = 0;
727
- mostActiveListenerPaths = [];
728
- updateTimes = [];
729
- constructor(eventBus) {
730
- this.setupEventListeners(eventBus);
731
- }
732
- getMetrics() {
733
- return {
734
- updateCount: this.updateCount,
735
- listenerExecutions: this.listenerExecutions,
736
- averageUpdateTime: this.averageUpdateTime,
737
- largestUpdateSize: this.largestUpdateSize,
738
- mostActiveListenerPaths: [...this.mostActiveListenerPaths]
739
- };
740
- }
741
- setupEventListeners(eventBus) {
742
- eventBus.subscribe("update:complete", (data) => {
743
- if (data.duration) {
744
- this.updateTimes.push(data.duration);
745
- if (this.updateTimes.length > 100)
746
- this.updateTimes.shift();
747
- this.averageUpdateTime = this.updateTimes.reduce((a, b) => a + b, 0) / this.updateTimes.length;
748
- }
749
- if (data.changedPaths?.length) {
750
- this.updateCount++;
751
- this.largestUpdateSize = Math.max(this.largestUpdateSize, data.changedPaths.length);
752
- }
753
- });
754
- }
755
- };
756
-
757
- // src/store/store.ts
758
- var ReactiveDataStore = class {
759
- coreState;
760
- middlewareEngine;
761
- persistenceHandler;
762
- transactionManager;
763
- metricsCollector;
764
- pendingUpdates = [];
765
- isUpdating = false;
766
- updateBus = (0, import_events5.createEventBus)();
767
- eventBus = (0, import_events5.createEventBus)();
768
- executionState;
769
- instanceID = v4_default();
770
- merge;
771
- diff;
772
- constructor(initialData, persistence, deleteMarker = DELETE_SYMBOL) {
773
- this.executionState = {
774
- executing: false,
775
- changes: null,
776
- pendingChanges: [],
777
- middlewares: [],
778
- runningMiddleware: null,
779
- transactionActive: false
780
- };
781
- this.merge = createMerge({ deleteMarker });
782
- this.diff = createDiff({ deleteMarker });
783
- this.coreState = new CoreStateManager(initialData, this.updateBus, this.diff);
784
- this.middlewareEngine = new MiddlewareEngine(this.eventBus, this.executionState, this.merge);
785
- this.persistenceHandler = new PersistenceHandler(this.eventBus, this.coreState, this.instanceID);
786
- this.transactionManager = new TransactionManager(this.eventBus, this.coreState, this.executionState);
787
- this.metricsCollector = new MetricsCollector(this.eventBus);
788
- this.persistenceHandler.initialize(persistence);
789
- }
790
- isReady() {
791
- return this.persistenceHandler.isReady();
792
- }
793
- state() {
794
- return this.executionState;
795
- }
796
- get(clone) {
797
- return this.coreState.get(clone);
798
- }
799
- async set(update) {
800
- if (this.isUpdating) {
801
- this.pendingUpdates.push(update);
802
- this.executionState.pendingChanges = [...this.pendingUpdates];
803
- return;
804
- }
805
- this.isUpdating = true;
806
- this.executionState.executing = true;
807
- const startTime = performance.now();
808
- this.eventBus.emit({
809
- name: "update:start",
810
- payload: { timestamp: startTime }
811
- });
812
- try {
813
- let partialState = update;
814
- if (typeof update === "function") {
815
- const result = update(this.get(true));
816
- partialState = result instanceof Promise ? await result : result;
817
- }
818
- const blockingResult = await this.middlewareEngine.executeBlocking(this.get(), partialState);
819
- if (blockingResult.blocked) {
820
- this.eventBus.emit({
821
- name: "update:complete",
822
- payload: {
823
- blocked: true,
824
- error: blockingResult.error,
825
- timestamp: Date.now()
826
- }
827
- });
828
- return;
829
- }
830
- const merged = this.merge(this.get(true), partialState);
831
- const processed = await this.middlewareEngine.executeTransform(merged, partialState);
832
- const finalState = this.merge(this.get(true), processed);
833
- const changedPaths = this.coreState.applyChanges(finalState);
834
- await this.persistenceHandler.handleStateChange(changedPaths, this.get());
835
- const endTime = performance.now();
836
- this.eventBus.emit({
837
- name: "update:complete",
838
- payload: {
839
- changedPaths,
840
- duration: endTime - startTime,
841
- timestamp: Date.now()
842
- }
843
- });
844
- } catch (error) {
845
- this.eventBus.emit({
846
- name: "update:complete",
847
- payload: {
848
- blocked: true,
849
- error,
850
- timestamp: Date.now()
851
- }
852
- });
853
- throw error;
854
- } finally {
855
- this.isUpdating = false;
856
- this.executionState.executing = false;
857
- this.executionState.changes = null;
858
- this.executionState.runningMiddleware = null;
859
- if (this.pendingUpdates.length > 0) {
860
- const nextUpdate = this.pendingUpdates.shift();
861
- this.executionState.pendingChanges = [...this.pendingUpdates];
862
- if (nextUpdate) {
863
- return this.set(nextUpdate);
864
- }
865
- }
866
- }
867
- }
868
- subscribe(path, callback) {
869
- const all = Array.isArray(path) ? path : [path];
870
- return this.updateBus.subscribe("update", (changed) => {
871
- if (all.includes(changed) || path === "") {
872
- callback(this.get(true));
873
- this.metricsCollector.listenerExecutions++;
874
- }
875
- });
876
- }
877
- id() {
878
- return this.instanceID;
879
- }
880
- async transaction(operation) {
881
- return this.transactionManager.execute(operation);
882
- }
883
- use(props) {
884
- if (props.block) {
885
- return this.middlewareEngine.addBlockingMiddleware(
886
- props.action,
887
- props.name
888
- );
889
- }
890
- return this.middlewareEngine.addMiddleware(props.action, props.name);
891
- }
892
- unuse(id) {
893
- return this.middlewareEngine.removeMiddleware(id);
894
- }
895
- /** @deprecated WILL BE REMOVED*/
896
- metrics() {
897
- return this.metricsCollector.getMetrics();
898
- }
899
- onStoreEvent(event, listener) {
900
- return this.eventBus.subscribe(event, listener);
901
- }
902
- };
903
-
904
- // src/store/observability.ts
905
- var diff2 = createDiff();
906
- var StoreObserver = class {
907
- store;
908
- eventHistory = [];
909
- maxEvents;
910
- enableConsoleLogging;
911
- logEvents;
912
- performanceThresholds;
913
- unsubscribers = [];
914
- stateHistory = [];
915
- maxStateHistory = 20;
916
- activeTransactionCount = 0;
917
- activeBatches = /* @__PURE__ */ new Set();
918
- middlewareExecutions = [];
919
- /**
920
- * Creates a new StoreObservability instance
921
- * @param store The ReactiveDataStore to observe
922
- * @param options Configuration options
923
- */
924
- constructor(store, options = {}) {
925
- this.store = store;
926
- this.maxEvents = options.maxEvents ?? 500;
927
- this.maxStateHistory = options.maxStateHistory ?? 20;
928
- this.enableConsoleLogging = options.enableConsoleLogging ?? false;
929
- this.logEvents = {
930
- updates: options.logEvents?.updates ?? true,
931
- middleware: options.logEvents?.middleware ?? true,
932
- transactions: options.logEvents?.transactions ?? true
933
- };
934
- this.performanceThresholds = {
935
- updateTime: options.performanceThresholds?.updateTime ?? 50,
936
- middlewareTime: options.performanceThresholds?.middlewareTime ?? 20
937
- };
938
- this.recordStateSnapshot();
939
- this.setupEventListeners();
940
- }
941
- /**
942
- * Sets up all event listeners
943
- */
944
- setupEventListeners() {
945
- const events = [
946
- "update:start",
947
- "update:complete",
948
- "middleware:start",
949
- "middleware:complete",
950
- "middleware:error",
951
- "middleware:blocked",
952
- "transaction:start",
953
- "transaction:complete",
954
- "transaction:error",
955
- "middleware:executed"
956
- ];
957
- this.unsubscribers.push(
958
- this.store.subscribe("", () => {
959
- this.recordStateSnapshot();
960
- })
961
- );
962
- for (const event of events) {
963
- const shouldLog = event.startsWith("update") && this.logEvents.updates || event.startsWith("middleware") && this.logEvents.middleware || event.startsWith("transaction") && this.logEvents.transactions;
964
- this.unsubscribers.push(
965
- this.store.onStoreEvent(event, (data) => {
966
- if (event === "middleware:executed") {
967
- this.middlewareExecutions.push(data);
968
- } else if (event === "transaction:start") {
969
- this.activeTransactionCount++;
970
- } else if (event === "transaction:complete" || event === "transaction:error") {
971
- this.activeTransactionCount = Math.max(
972
- 0,
973
- this.activeTransactionCount - 1
974
- );
975
- }
976
- if (data.batchId) {
977
- if (event.endsWith("start")) {
978
- this.activeBatches.add(data.batchId);
979
- } else if (event.endsWith("complete") || event.endsWith("error")) {
980
- this.activeBatches.delete(data.batchId);
981
- }
982
- }
983
- this.recordEvent(event, data);
984
- if (this.enableConsoleLogging && shouldLog) {
985
- this.logEventToConsole(event, data);
986
- }
987
- this.checkPerformance(event, data);
988
- })
989
- );
990
- }
991
- }
992
- /**
993
- * Records a state snapshot
994
- */
995
- recordStateSnapshot() {
996
- const currentState = structuredClone(this.store.get());
997
- if (this.stateHistory.length > 0 && diff2(currentState, this.stateHistory[0]).length === 0)
998
- return;
999
- this.stateHistory.unshift(currentState);
1000
- if (this.stateHistory.length > this.maxStateHistory) {
1001
- this.stateHistory.pop();
1002
- }
1003
- }
1004
- /**
1005
- * Records an event to the history
1006
- * @param type Event type
1007
- * @param data Event data
1008
- */
1009
- recordEvent(type, data) {
1010
- const event = {
1011
- type,
1012
- timestamp: Date.now(),
1013
- data: structuredClone(data)
1014
- };
1015
- this.eventHistory.unshift(event);
1016
- if (this.eventHistory.length > this.maxEvents) {
1017
- this.eventHistory.pop();
1018
- }
1019
- }
1020
- /**
1021
- * Logs an event to the console with appropriate formatting
1022
- * @param type Event type
1023
- * @param data Event data
1024
- */
1025
- logEventToConsole(type, data) {
1026
- const timestamp = new Date(data.timestamp || Date.now()).toISOString().split("T")[1].replace("Z", "");
1027
- if (type === "update:start") {
1028
- console.group(
1029
- `%c\u26A1 Store Update Started [${timestamp}]`,
1030
- "color: #4a6da7"
1031
- );
1032
- } else if (type === "update:complete") {
1033
- if (data.blocked) {
1034
- console.warn(
1035
- `%c\u270B Update Blocked [${timestamp}]`,
1036
- "color: #bf8c0a",
1037
- data.error
1038
- );
1039
- } else {
1040
- const changedPaths = data.changedPaths || [];
1041
- if (changedPaths.length > 0) {
1042
- console.log(
1043
- `%c\u2705 Update Complete [${timestamp}] - ${changedPaths.length} paths changed in ${data.duration?.toFixed(2)}ms`,
1044
- "color: #2a9d8f",
1045
- changedPaths
1046
- );
1047
- }
1048
- }
1049
- console.groupEnd();
1050
- } else if (type === "middleware:start") {
1051
- console.debug(
1052
- `%c\u25C0 Middleware "${data.name}" started [${timestamp}] (${data.type})`,
1053
- "color: #8c8c8c"
1054
- );
1055
- } else if (type === "middleware:complete") {
1056
- console.debug(
1057
- `%c\u25B6 Middleware "${data.name}" completed [${timestamp}] in ${data.duration?.toFixed(2)}ms`,
1058
- "color: #7c9c7c"
1059
- );
1060
- } else if (type === "middleware:error") {
1061
- console.error(
1062
- `%c\u274C Middleware "${data.name}" error [${timestamp}]:`,
1063
- "color: #e63946",
1064
- data.error
1065
- );
1066
- } else if (type === "middleware:blocked") {
1067
- console.warn(
1068
- `%c\u{1F6D1} Middleware "${data.name}" blocked update [${timestamp}]`,
1069
- "color: #e76f51"
1070
- );
1071
- } else if (type === "transaction:start") {
1072
- console.group(
1073
- `%c\u{1F4E6} Transaction Started [${timestamp}]`,
1074
- "color: #6d597a"
1075
- );
1076
- } else if (type === "transaction:complete") {
1077
- console.log(`%c\u{1F4E6} Transaction Complete [${timestamp}]`, "color: #355070");
1078
- console.groupEnd();
1079
- } else if (type === "transaction:error") {
1080
- console.error(
1081
- `%c\u{1F4E6} Transaction Error [${timestamp}]:`,
1082
- "color: #e56b6f",
1083
- data.error
1084
- );
1085
- console.groupEnd();
1086
- }
1087
- }
1088
- /**
1089
- * Checks for performance issues in the events
1090
- * @param type Event type
1091
- * @param data Event data
1092
- */
1093
- checkPerformance(type, data) {
1094
- if (!this.enableConsoleLogging)
1095
- return;
1096
- if (type === "update:complete" && !data.blocked && data.duration > this.performanceThresholds.updateTime) {
1097
- console.warn(
1098
- `%c\u26A0\uFE0F Slow update detected [${data.duration.toFixed(2)}ms]`,
1099
- "color: #ff9f1c",
1100
- {
1101
- changedPaths: data.changedPaths,
1102
- threshold: this.performanceThresholds.updateTime
1103
- }
1104
- );
1105
- }
1106
- if (type === "middleware:complete" && data.duration > this.performanceThresholds.middlewareTime) {
1107
- console.warn(
1108
- `%c\u26A0\uFE0F Slow middleware "${data.name}" [${data.duration.toFixed(2)}ms]`,
1109
- "color: #ff9f1c",
1110
- {
1111
- threshold: this.performanceThresholds.middlewareTime
1112
- }
1113
- );
1114
- }
1115
- }
1116
- /**
1117
- * Returns the event history
1118
- * @returns Array of debug events
1119
- */
1120
- getEventHistory() {
1121
- return structuredClone(this.eventHistory);
1122
- }
1123
- /**
1124
- * Returns the state history
1125
- * @returns Array of state snapshots
1126
- */
1127
- getStateHistory() {
1128
- return structuredClone(this.stateHistory);
1129
- }
1130
- /**
1131
- * Returns middleware execution history from the state
1132
- * @returns Array of middleware executions
1133
- */
1134
- getMiddlewareExecutions() {
1135
- return this.middlewareExecutions;
1136
- }
1137
- /**
1138
- * Returns state performance metrics
1139
- * @returns Store metrics object
1140
- */
1141
- getPerformanceMetrics() {
1142
- return this.store.metrics();
1143
- }
1144
- /**
1145
- * Returns current transaction status
1146
- * @returns Object with transaction status information
1147
- */
1148
- getTransactionStatus() {
1149
- return {
1150
- activeTransactions: this.activeTransactionCount,
1151
- activeBatches: Array.from(this.activeBatches)
1152
- };
1153
- }
1154
- /**
1155
- * Creates a middleware that logs all updates
1156
- * @param options Options for the logging middleware
1157
- * @returns A middleware function
1158
- */
1159
- createLoggingMiddleware(options = {}) {
1160
- const { logLevel = "debug", logUpdates = true } = options;
1161
- return (_, update) => {
1162
- if (logUpdates) {
1163
- const logMethod = console[logLevel] || console.log;
1164
- logMethod("State Update:", update);
1165
- }
1166
- return update;
1167
- };
1168
- }
1169
- /**
1170
- * Creates a middleware that validates updates against a schema
1171
- * @param validator Function that validates updates
1172
- * @returns A blocking middleware function
1173
- */
1174
- createValidationMiddleware(validator) {
1175
- return (state, update) => {
1176
- const result = validator(state, update);
1177
- if (typeof result === "boolean") {
1178
- return result;
1179
- }
1180
- if (!result.valid && result.reason) {
1181
- console.warn("Validation failed:", result.reason);
1182
- }
1183
- return result.valid;
1184
- };
1185
- }
1186
- /**
1187
- * Clears all event and state history
1188
- */
1189
- clearHistory() {
1190
- this.eventHistory = [];
1191
- if (this.stateHistory.length > 0) {
1192
- const currentState = this.stateHistory[0];
1193
- this.stateHistory = [currentState];
1194
- }
1195
- }
1196
- /**
1197
- * Returns a simplified view of recent state changes
1198
- * @param limit Maximum number of state changes to compare
1199
- * @returns Array of state difference objects
1200
- */
1201
- getRecentChanges(limit = 5) {
1202
- const changes = [];
1203
- const historyLimit = Math.min(limit, this.stateHistory.length - 1);
1204
- for (let i = 0; i < historyLimit; i++) {
1205
- const newState = this.stateHistory[i];
1206
- const oldState = this.stateHistory[i + 1];
1207
- const changedPaths = diff2(oldState, newState);
1208
- const from = {};
1209
- const to = {};
1210
- for (const path of changedPaths) {
1211
- const pathParts = path.split(".");
1212
- const getNestedValue = (obj, parts) => {
1213
- return parts.reduce(
1214
- (o, key) => o && o[key] !== void 0 ? o[key] : void 0,
1215
- obj
1216
- );
1217
- };
1218
- const setNestedValue = (obj, parts, value) => {
1219
- const lastIndex = parts.length - 1;
1220
- const lastKey = parts[lastIndex];
1221
- const restParts = parts.slice(0, lastIndex);
1222
- const target = restParts.reduce((o, key) => {
1223
- o[key] = o[key] ?? {};
1224
- return o[key];
1225
- }, obj);
1226
- target[lastKey] = value;
1227
- };
1228
- const oldValue = getNestedValue(oldState, pathParts);
1229
- const newValue = getNestedValue(newState, pathParts);
1230
- setNestedValue(from, pathParts, oldValue);
1231
- setNestedValue(to, pathParts, newValue);
1232
- }
1233
- let updateTimestamp = Date.now();
1234
- for (const event of this.eventHistory) {
1235
- if (event.type === "update:complete" && event.data.changedPaths?.length > 0) {
1236
- updateTimestamp = event.timestamp;
1237
- break;
1238
- }
1239
- }
1240
- if (changedPaths.length === 0)
1241
- continue;
1242
- changes.push({
1243
- timestamp: updateTimestamp,
1244
- changedPaths,
1245
- from,
1246
- to
1247
- });
1248
- }
1249
- return changes;
1250
- }
1251
- /**
1252
- * Creates a time-travel debug middleware that lets you undo/redo state changes
1253
- * @returns An object with undo/redo methods and state info
1254
- */
1255
- createTimeTravel() {
1256
- let currentIndex = 0;
1257
- let future = [];
1258
- return {
1259
- canUndo: () => currentIndex < this.stateHistory.length - 1,
1260
- canRedo: () => future.length > 0,
1261
- undo: async () => {
1262
- if (currentIndex < this.stateHistory.length - 1) {
1263
- const nextIndex = currentIndex + 1;
1264
- const previousState = this.stateHistory[nextIndex];
1265
- future.unshift(this.stateHistory[currentIndex]);
1266
- currentIndex = nextIndex;
1267
- await this.store.set(previousState);
1268
- }
1269
- },
1270
- redo: async () => {
1271
- if (future.length > 0) {
1272
- const nextState = future.shift();
1273
- currentIndex = Math.max(0, currentIndex - 1);
1274
- await this.store.set(nextState);
1275
- }
1276
- },
1277
- getHistoryLength: () => this.stateHistory.length,
1278
- clear: () => {
1279
- future = [];
1280
- currentIndex = 0;
1281
- }
1282
- };
1283
- }
1284
- /**
1285
- * Disconnects all event listeners and cleans up resources
1286
- */
1287
- disconnect() {
1288
- this.unsubscribers.forEach((unsubscribe) => unsubscribe());
1289
- this.unsubscribers = [];
1290
- this.clearHistory();
1291
- }
1292
- };
1293
- // Annotate the CommonJS export names for ESM import in node:
1294
- 0 && (module.exports = {
1295
- DELETE_SYMBOL,
1296
- ReactiveDataStore,
1297
- StoreObserver
1298
- });
1
+ "use strict";var e,t,r=require("uuid"),s=Object.create,a=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,d=(e,t,r)=>(r=null!=e?s(o(e)):{},((e,t,r,s)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of n(t))c.call(e,o)||o===r||a(e,o,{get:()=>t[o],enumerable:!(s=i(t,o))||s.enumerable});return e})(e&&e.__esModule?r:a(r,"default",{value:e,enumerable:!0}),e)),l=(e={"node_modules/@asaidimu/events/index.js"(e,t){var r,s=Object.defineProperty,a=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,o={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(o,{createEventBus:()=>c}),t.exports=(r=o,((e,t,r,o)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))n.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(o=a(t,c))||o.enumerable});return e})(s({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],s=0,a=0;const i=new Map,n=new Map;let o=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?o=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{s++,a+=t,i.set(e,(i.get(e)||0)+1)},d=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const s=performance.now();try{(n.get(t)||[]).forEach((e=>e(r)))}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-s)}))},l=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(d,e.batchDelay)}})(),h=e=>{const r=t.get(e);r?n.set(e,Array.from(r)):n.delete(e)};return o&&(o.onmessage=e=>{const{name:t,payload:r}=e.data;(n.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const s=t.get(e);return s.add(r),h(e),()=>{s.delete(r),0===s.size?(t.delete(e),n.delete(e)):h(e)}},emit:({name:t,payload:s})=>{if(e.async)return r.push({name:t,payload:s}),r.length>=e.batchSize?d():l(),void(o&&o.postMessage({name:t,payload:s}));const a=performance.now();try{(n.get(t)||[]).forEach((e=>e(s))),o&&o.postMessage({name:t,payload:s})}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-a)},getMetrics:()=>({totalEvents:s,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:i,averageEmitDuration:s>0?a/s:0}),clear:()=>{t.clear(),n.clear(),r=[],s=0,a=0,i.clear(),o&&(o.close(),o=null)}}}}},function(){return t||(0,e[n(e)[0]])((t={exports:{}}).exports,t),t.exports}),h=d(l()),u=Symbol.for("delete"),m=e=>Array.isArray(e)?[...e]:{...e};function p(e){const t=e?.deleteMarker||u;return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?i(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const s=m(e),a=[{target:s,source:r}];for(;a.length>0;){const{target:e,source:r}=a.pop();for(const s of Object.keys(r)){if(!Object.prototype.hasOwnProperty.call(r,s))continue;const n=r[s];n!==t?Array.isArray(n)?e[s]=n.map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e===t?void 0:e:i(e))):"object"==typeof n&&null!==n?(e[s]=m(s in e&&"object"==typeof e[s]&&null!==e[s]?e[s]:{}),a.push({target:e[s],source:n})):e[s]=n:delete e[s]}}return s;function i(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e===t?void 0:e:i(e)));if("object"==typeof e){const r={};for(const[s,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=i(a);void 0!==e&&(r[s]=e)}else r[s]=a;return r}return e===t?void 0:e}}}function g(e){const t=e?.deleteMarker||u;return function(e,r){const s=new Set,a=e=>s.add(e);function i(e){if(!e)return;const t=e.split(".");a(e);for(let e=t.length-1;e>0;e--){const r=t.slice(0,e).join(".");if(s.has(r))break;a(r)}}const n=[{path:"",orig:e||{},part:r||{}}];for(;n.length>0;){const{path:e,orig:r,part:s}=n.pop();if(null!=s)if(Array.isArray(s))Array.isArray(r)&&JSON.stringify(r)===JSON.stringify(s)||i(e);else if("object"==typeof s){const a=Object.keys(s);for(let o=0;o<a.length;o++){const c=a[o],d=e?`${e}.${c}`:c,l=s[c];if(l===t||null==r){i(d);continue}const h=r[c];"object"==typeof l&&null!==l?n.push({path:d,orig:h,part:l}):h!==l&&i(d)}}}return Array.from(s)}}p(),g();var f=class{constructor(e,t,r){this.updateBus=t,this.diff=r,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e){const t=this.diff(this.get(!0),e);return t.length>0&&(this.cache=structuredClone(e),this.notifyListeners(t)),t}notifyListeners(e){e.forEach((e=>this.updateBus.emit({name:"update",payload:e})))}};d(l());var y=class{constructor(e,t,r){this.eventBus=e,this.executionState=t,this.merge=r}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:r,name:s,id:a}of this.blockingMiddleware){const i={id:a,name:s,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:s,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:s,type:"blocking"});try{const n=await Promise.resolve(r(e,t));if(i.endTime=performance.now(),i.duration=i.endTime-i.startTime,!1===n)return i.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:a,name:s,duration:i.duration}),this.eventBus.emit({name:"middleware:executed",payload:i}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:a,name:s,type:"blocking",duration:i.duration}),this.eventBus.emit({name:"middleware:executed",payload:{...i,blocked:!1}})}catch(e){return i.endTime=performance.now(),i.duration=i.endTime-i.startTime,i.error=e instanceof Error?e:new Error(String(e)),i.blocked=!0,this.emitMiddlewareError(a,s,i.error,i.duration),this.eventBus.emit({name:"middleware:executed",payload:i}),{blocked:!0,error:i.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let r=e,s=t;for(const{fn:e,name:a,id:i}of this.middleware){const n={id:i,name:a,startTime:performance.now()};this.executionState.runningMiddleware={id:i,name:a,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:i,name:a,type:"transform"});try{const o=await Promise.resolve(e(r,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(r=this.merge(r,o),s=this.merge(s,o)),this.eventBus.emit({name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:i,name:a,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.eventBus.emit({name:"middleware:executed",payload:n}),this.emitMiddlewareError(i,a,n.error,n.duration),console.error(`Middleware ${a} error:`,e)}finally{this.executionState.runningMiddleware=null}}return s}addMiddleware(e,t="unnamed-middleware"){const r=this.generateId();return this.middleware.push({fn:e,name:t,id:r}),this.updateExecutionState(),r}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const r=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:r}),this.updateExecutionState(),r}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.eventBus.emit({name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,r,s){this.eventBus.emit({name:"middleware:error",payload:{id:e,name:t,error:r,duration:s,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}};d(l());var w=class{constructor(e,t,r){this.eventBus=e,this.coreState=t,this.instanceID=r}persistence;instanceID;persistenceReady=!1;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}async handleStateChange(e,t){if(this.persistence&&0!==e.length)try{await this.persistence.set(this.instanceID,t)||this.eventBus.emit({name:"update:complete",payload:{persistence:!1,timestamp:Date.now()}})}catch(e){this.eventBus.emit({name:"update:complete",payload:{persistence:!1,error:e,timestamp:Date.now()}})}}setPersistenceReady(){this.persistenceReady=!0,this.eventBus.emit({name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e)}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.eventBus.emit({name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}};d(l());var v=class{constructor(e,t,r){this.eventBus=e,this.coreState=t,this.executionState=r}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.eventBus.emit({name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.eventBus.emit({name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t),this.eventBus.emit({name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}};d(l());var b=class{updateCount=0;listenerExecutions=0;averageUpdateTime=0;largestUpdateSize=0;mostActiveListenerPaths=[];updateTimes=[];constructor(e){this.setupEventListeners(e)}getMetrics(){return{updateCount:this.updateCount,listenerExecutions:this.listenerExecutions,averageUpdateTime:this.averageUpdateTime,largestUpdateSize:this.largestUpdateSize,mostActiveListenerPaths:[...this.mostActiveListenerPaths]}}setupEventListeners(e){e.subscribe("update:complete",(e=>{e.duration&&(this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift(),this.averageUpdateTime=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length),e.changedPaths?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.changedPaths.length))}))}},S=g();exports.DELETE_SYMBOL=u,exports.ReactiveDataStore=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;pendingUpdates=[];isUpdating=!1;updateBus=(0,h.createEventBus)();eventBus=(0,h.createEventBus)();executionState;instanceID=r.v4();merge;diff;constructor(e,t,r=u){this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=p({deleteMarker:r}),this.diff=g({deleteMarker:r}),this.coreState=new f(e,this.updateBus,this.diff),this.middlewareEngine=new y(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new w(this.eventBus,this.coreState,this.instanceID),this.transactionManager=new v(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new b(this.eventBus),this.persistenceHandler.initialize(t)}isReady(){return this.persistenceHandler.isReady()}state(){return this.executionState}get(e){return this.coreState.get(e)}async set(e){if(this.isUpdating)return this.pendingUpdates.push(e),void(this.executionState.pendingChanges=[...this.pendingUpdates]);this.isUpdating=!0,this.executionState.executing=!0;const t=performance.now();this.eventBus.emit({name:"update:start",payload:{timestamp:t}});try{let r=e;if("function"==typeof e){const t=e(this.get(!0));r=t instanceof Promise?await t:t}const s=await this.middlewareEngine.executeBlocking(this.get(),r);if(s.blocked)return void this.eventBus.emit({name:"update:complete",payload:{blocked:!0,error:s.error,timestamp:Date.now()}});const a=this.merge(this.get(!0),r),i=await this.middlewareEngine.executeTransform(a,r),n=this.merge(this.get(!0),i),o=this.coreState.applyChanges(n);await this.persistenceHandler.handleStateChange(o,this.get());const c=performance.now();this.eventBus.emit({name:"update:complete",payload:{changedPaths:o,duration:c-t,timestamp:Date.now()}})}catch(e){throw this.eventBus.emit({name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now()}}),e}finally{if(this.isUpdating=!1,this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.pendingUpdates.length>0){const e=this.pendingUpdates.shift();if(this.executionState.pendingChanges=[...this.pendingUpdates],e)return this.set(e)}}}subscribe(e,t){const r=Array.isArray(e)?e:[e];return this.updateBus.subscribe("update",(s=>{(r.includes(s)||""===e)&&(t(this.get(!0)),this.metricsCollector.listenerExecutions++)}))}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){return e.block?this.middlewareEngine.addBlockingMiddleware(e.action,e.name):this.middlewareEngine.addMiddleware(e.action,e.name)}unuse(e){return this.middlewareEngine.removeMiddleware(e)}metrics(){return this.metricsCollector.getMetrics()}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}},exports.StoreObserver=class{store;eventHistory=[];maxEvents;enableConsoleLogging;logEvents;performanceThresholds;unsubscribers=[];stateHistory=[];maxStateHistory=20;activeTransactionCount=0;activeBatches=new Set;middlewareExecutions=[];constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot(),this.setupEventListeners()}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed"];this.unsubscribers.push(this.store.subscribe("",(()=>{this.recordStateSnapshot()})));for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions;this.unsubscribers.push(this.store.onStoreEvent(t,(r=>{"middleware:executed"===t?this.middlewareExecutions.push(r):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),r.batchId&&(t.endsWith("start")?this.activeBatches.add(r.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(r.batchId)),this.recordEvent(t,r),this.enableConsoleLogging&&e&&this.logEventToConsole(t,r),this.checkPerformance(t,r)})))}}recordStateSnapshot(){const e=structuredClone(this.store.get());this.stateHistory.length>0&&0===S(e,this.stateHistory[0]).length||(this.stateHistory.unshift(e),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop())}recordEvent(e,t){const r={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(r),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}logEventToConsole(e,t){const r=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)console.group(`%c⚡ Store Update Started [${r}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)console.warn(`%c✋ Update Blocked [${r}]`,"color: #bf8c0a",t.error);else{const e=t.changedPaths||[];e.length>0&&console.log(`%c✅ Update Complete [${r}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f",e)}console.groupEnd()}else"middleware:start"===e?console.debug(`%c◀ Middleware "${t.name}" started [${r}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?console.debug(`%c▶ Middleware "${t.name}" completed [${r}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?console.error(`%c❌ Middleware "${t.name}" error [${r}]:`,"color: #e63946",t.error):"middleware:blocked"===e?console.warn(`%c🛑 Middleware "${t.name}" blocked update [${r}]`,"color: #e76f51"):"transaction:start"===e?console.group(`%c📦 Transaction Started [${r}]`,"color: #6d597a"):"transaction:complete"===e?(console.log(`%c📦 Transaction Complete [${r}]`,"color: #355070"),console.groupEnd()):"transaction:error"===e&&(console.error(`%c📦 Transaction Error [${r}]:`,"color: #e56b6f",t.error),console.groupEnd())}checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&console.warn(`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{changedPaths:t.changedPaths,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&console.warn(`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getPerformanceMetrics(){return this.store.metrics()}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:r=!0}=e;return(e,s)=>{if(r){(console[t]||console.log)("State Update:",s)}return s}}createValidationMiddleware(e){return(t,r)=>{const s=e(t,r);return"boolean"==typeof s?s:(!s.valid&&s.reason&&console.warn("Validation failed:",s.reason),s.valid)}}clearHistory(){if(this.eventHistory=[],this.stateHistory.length>0){const e=this.stateHistory[0];this.stateHistory=[e]}}getRecentChanges(e=5){const t=[],r=Math.min(e,this.stateHistory.length-1);for(let e=0;e<r;e++){const r=this.stateHistory[e],s=this.stateHistory[e+1],a=S(s,r),i={},n={};for(const e of a){const t=e.split("."),a=(e,t)=>t.reduce(((e,t)=>e&&void 0!==e[t]?e[t]:void 0),e),o=(e,t,r)=>{const s=t.length-1,a=t[s];t.slice(0,s).reduce(((e,t)=>(e[t]=e[t]??{},e[t])),e)[a]=r},c=a(s,t),d=a(r,t);o(i,t,c),o(n,t,d)}let o=Date.now();for(const e of this.eventHistory)if("update:complete"===e.type&&e.data.changedPaths?.length>0){o=e.timestamp;break}0!==a.length&&t.push({timestamp:o,changedPaths:a,from:i,to:n})}return t}createTimeTravel(){let e=0,t=[];return{canUndo:()=>e<this.stateHistory.length-1,canRedo:()=>t.length>0,undo:async()=>{if(e<this.stateHistory.length-1){const r=e+1,s=this.stateHistory[r];t.unshift(this.stateHistory[e]),e=r,await this.store.set(s)}},redo:async()=>{if(t.length>0){const r=t.shift();e=Math.max(0,e-1),await this.store.set(r)}},getHistoryLength:()=>this.stateHistory.length,clear:()=>{t=[],e=0}}}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.clearHistory()}},exports.author="https://github.com/asaidimu";