@blac/core 2.0.0-rc-13 → 2.0.0-rc-16

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 (54) hide show
  1. package/package.json +10 -15
  2. package/src/Blac.ts +38 -71
  3. package/src/Bloc.ts +8 -9
  4. package/src/BlocBase.ts +246 -540
  5. package/src/Cubit.ts +1 -16
  6. package/src/__tests__/Blac.config.test.ts +10 -17
  7. package/src/__tests__/Bloc.event.test.ts +27 -52
  8. package/src/__tests__/BlocBase.subscription.test.ts +349 -0
  9. package/src/__tests__/Cubit.test.ts +39 -50
  10. package/src/__tests__/memory-leaks.test.ts +383 -0
  11. package/src/__tests__/plugins.test.ts +107 -97
  12. package/src/adapter/BlacAdapter.ts +347 -207
  13. package/src/adapter/ProxyFactory.ts +196 -255
  14. package/src/adapter/__tests__/BlacAdapter.test.ts +71 -77
  15. package/src/adapter/__tests__/ProxyFactory.test.ts +1 -1
  16. package/src/adapter/index.ts +0 -1
  17. package/src/errors/BlacError.ts +69 -0
  18. package/src/errors/ErrorManager.ts +101 -0
  19. package/src/errors/handleError.ts +114 -0
  20. package/src/errors/index.ts +13 -0
  21. package/src/events.ts +7 -1
  22. package/src/index.ts +7 -1
  23. package/src/lifecycle/BlocLifecycle.ts +156 -0
  24. package/src/lifecycle/index.ts +1 -0
  25. package/src/plugins/BlocPluginRegistry.ts +71 -51
  26. package/src/plugins/SystemPluginRegistry.ts +63 -13
  27. package/src/plugins/__tests__/BlocPluginRegistry.test.ts +450 -0
  28. package/src/plugins/__tests__/SystemPluginRegistry.test.ts +404 -0
  29. package/src/plugins/types.ts +32 -3
  30. package/src/subscription/README.md +132 -0
  31. package/src/subscription/SubscriptionManager.ts +395 -0
  32. package/src/subscription/__tests__/SubscriptionManager.test.ts +355 -0
  33. package/src/subscription/index.ts +2 -0
  34. package/src/subscription/types.ts +90 -0
  35. package/src/testing.ts +31 -37
  36. package/src/types.ts +4 -21
  37. package/src/utils/BatchingManager.ts +59 -0
  38. package/src/utils/RerenderLogger.ts +265 -0
  39. package/src/utils/__tests__/generateInstanceId.test.ts +104 -0
  40. package/src/utils/__tests__/shallowEqual.test.ts +171 -0
  41. package/src/utils/__tests__/uuid.test.ts +144 -0
  42. package/src/utils/generateInstanceId.ts +54 -0
  43. package/src/utils/shallowEqual.ts +1 -1
  44. package/README.md +0 -329
  45. package/dist/index.cjs.js +0 -11
  46. package/dist/index.cjs.js.map +0 -1
  47. package/dist/index.d.ts +0 -1078
  48. package/dist/index.es.js +0 -1992
  49. package/dist/index.es.js.map +0 -1
  50. package/src/BlacObserver.ts +0 -189
  51. package/src/__tests__/BlocBase.lifecycle.test.ts +0 -441
  52. package/src/__tests__/props.test.ts +0 -256
  53. package/src/adapter/ConsumerTracker.ts +0 -241
  54. package/src/adapter/__tests__/ConsumerTracker.test.ts +0 -562
package/dist/index.es.js DELETED
@@ -1,1992 +0,0 @@
1
- var R = Object.defineProperty;
2
- var O = (c, e, t) => e in c ? R(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
3
- var i = (c, e, t) => O(c, typeof e != "symbol" ? e + "" : e, t);
4
- class H {
5
- /**
6
- * Creates a new BlacObservable instance
7
- * @param bloc - The Bloc instance to observe
8
- */
9
- constructor(e) {
10
- /** The Bloc instance this observable is associated with */
11
- i(this, "bloc");
12
- i(this, "_observers", /* @__PURE__ */ new Set());
13
- this.bloc = e;
14
- }
15
- /**
16
- * Gets the number of active observers
17
- * @returns The number of observers currently subscribed
18
- */
19
- get size() {
20
- return this._observers.size;
21
- }
22
- /**
23
- * Gets the set of all observers
24
- * @returns The Set of all BlacObserver instances
25
- */
26
- get observers() {
27
- return this._observers;
28
- }
29
- /**
30
- * Subscribes an observer to state changes
31
- * @param observer - The observer to subscribe
32
- * @returns A function that can be called to unsubscribe the observer
33
- */
34
- subscribe(e) {
35
- const t = this.bloc._disposalState;
36
- return t === y.DISPOSED || t === y.DISPOSING ? (u.log(
37
- "BlacObservable.subscribe: Cannot subscribe to disposed/disposing bloc.",
38
- this.bloc,
39
- e
40
- ), () => {
41
- }) : (u.log(
42
- "BlacObservable.subscribe: Subscribing observer.",
43
- this.bloc,
44
- e
45
- ), this._observers.add(e), t === y.DISPOSAL_REQUESTED && (u.log(
46
- "BlacObservable.subscribe: Cancelling disposal due to new subscription.",
47
- this.bloc
48
- ), this.bloc._atomicStateTransition(
49
- y.DISPOSAL_REQUESTED,
50
- y.ACTIVE
51
- )), () => {
52
- u.log(
53
- "BlacObservable.subscribe: Unsubscribing observer.",
54
- this.bloc,
55
- e
56
- ), this.unsubscribe(e);
57
- });
58
- }
59
- /**
60
- * Unsubscribes an observer from state changes
61
- * @param observer - The observer to unsubscribe
62
- */
63
- unsubscribe(e) {
64
- this._observers.delete(e), this.size === 0 && (u.log("BlacObservable.unsubscribe: No observers left.", this.bloc), this.bloc._consumers.size === 0 && !this.bloc._keepAlive && this.bloc._disposalState === y.ACTIVE && (u.log(
65
- `[${this.bloc._name}:${this.bloc._id}] No observers or consumers left. Scheduling disposal.`
66
- ), this.bloc._scheduleDisposal()));
67
- }
68
- /**
69
- * Notifies all observers of a state change
70
- * @param newState - The new state value
71
- * @param oldState - The previous state value
72
- * @param action - Optional action that triggered the state change
73
- */
74
- notify(e, t, s) {
75
- this._observers.forEach((r) => {
76
- let n = !1;
77
- if (r.dependencyArray) {
78
- const o = r.lastState, a = r.dependencyArray(
79
- e,
80
- t,
81
- this.bloc
82
- );
83
- if (!o)
84
- n = !0;
85
- else if (o.length !== a.length)
86
- n = !0;
87
- else
88
- for (let l = 0; l < a.length; l++)
89
- if (!Object.is(o[l], a[l])) {
90
- n = !0;
91
- break;
92
- }
93
- r.lastState = a;
94
- } else
95
- n = !0;
96
- n && r.fn(e, t, s);
97
- }), u.instance.plugins.notifyStateChanged(this.bloc, t, e);
98
- }
99
- /**
100
- * Clears the observer set
101
- */
102
- clear() {
103
- this._observers.clear();
104
- }
105
- }
106
- function $() {
107
- return typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
108
- const e = Math.random() * 16 | 0;
109
- return (c === "x" ? e : e & 3 | 8).toString(16);
110
- });
111
- }
112
- class V {
113
- constructor() {
114
- i(this, "plugins", /* @__PURE__ */ new Map());
115
- i(this, "executionOrder", []);
116
- i(this, "attached", !1);
117
- }
118
- /**
119
- * Add a bloc plugin
120
- */
121
- add(e) {
122
- if (this.plugins.has(e.name))
123
- throw new Error(`Plugin '${e.name}' is already registered`);
124
- e.capabilities && this.validateCapabilities(e), this.plugins.set(e.name, e), this.executionOrder.push(e.name);
125
- }
126
- /**
127
- * Remove a bloc plugin
128
- */
129
- remove(e) {
130
- const t = this.plugins.get(e);
131
- if (!t) return !1;
132
- if (this.attached && t.onDetach)
133
- try {
134
- t.onDetach();
135
- } catch (s) {
136
- console.error(`Plugin '${e}' error in onDetach:`, s);
137
- }
138
- return this.plugins.delete(e), this.executionOrder = this.executionOrder.filter((s) => s !== e), !0;
139
- }
140
- /**
141
- * Get a plugin by name
142
- */
143
- get(e) {
144
- return this.plugins.get(e);
145
- }
146
- /**
147
- * Get all plugins in execution order
148
- */
149
- getAll() {
150
- return this.executionOrder.map((e) => this.plugins.get(e));
151
- }
152
- /**
153
- * Clear all plugins
154
- */
155
- clear() {
156
- if (this.attached) {
157
- for (const e of this.getAll())
158
- if (e.onDetach)
159
- try {
160
- e.onDetach();
161
- } catch (t) {
162
- console.error(`Plugin '${e.name}' error in onDetach:`, t);
163
- }
164
- }
165
- this.plugins.clear(), this.executionOrder = [], this.attached = !1;
166
- }
167
- /**
168
- * Attach all plugins to a bloc
169
- */
170
- attach(e) {
171
- if (this.attached)
172
- throw new Error("Plugins are already attached");
173
- for (const t of this.getAll())
174
- if (t.onAttach)
175
- try {
176
- t.onAttach(e);
177
- } catch (s) {
178
- console.error(`Plugin '${t.name}' error in onAttach:`, s), this.remove(t.name);
179
- }
180
- this.attached = !0;
181
- }
182
- /**
183
- * Transform state through all plugins
184
- */
185
- transformState(e, t) {
186
- let s = t;
187
- for (const r of this.getAll())
188
- if (r.transformState && this.canTransformState(r))
189
- try {
190
- s = r.transformState(e, s);
191
- } catch (n) {
192
- console.error(`Plugin '${r.name}' error in transformState:`, n);
193
- }
194
- return s;
195
- }
196
- /**
197
- * Transform event through all plugins
198
- */
199
- transformEvent(e) {
200
- let t = e;
201
- for (const s of this.getAll()) {
202
- if (t === null) break;
203
- if (s.transformEvent && this.canInterceptEvents(s))
204
- try {
205
- t = s.transformEvent(t);
206
- } catch (r) {
207
- console.error(`Plugin '${s.name}' error in transformEvent:`, r);
208
- }
209
- }
210
- return t;
211
- }
212
- /**
213
- * Notify plugins of state change
214
- */
215
- notifyStateChange(e, t) {
216
- for (const s of this.getAll())
217
- if (s.onStateChange && this.canReadState(s))
218
- try {
219
- s.onStateChange(e, t);
220
- } catch (r) {
221
- console.error(`Plugin '${s.name}' error in onStateChange:`, r);
222
- }
223
- }
224
- /**
225
- * Notify plugins of event
226
- */
227
- notifyEvent(e) {
228
- for (const t of this.getAll())
229
- if (t.onEvent && this.canReadState(t))
230
- try {
231
- t.onEvent(e);
232
- } catch (s) {
233
- console.error(`Plugin '${t.name}' error in onEvent:`, s);
234
- }
235
- }
236
- /**
237
- * Notify plugins of error
238
- */
239
- notifyError(e, t) {
240
- for (const s of this.getAll())
241
- if (s.onError)
242
- try {
243
- s.onError(e, t);
244
- } catch (r) {
245
- console.error(`Plugin '${s.name}' error in onError:`, r);
246
- }
247
- }
248
- validateCapabilities(e) {
249
- const t = e.capabilities;
250
- if (t.transformState && !t.readState)
251
- throw new Error(`Plugin '${e.name}': transformState requires readState capability`);
252
- if (t.interceptEvents && !t.readState)
253
- throw new Error(`Plugin '${e.name}': interceptEvents requires readState capability`);
254
- }
255
- canReadState(e) {
256
- return !e.capabilities || e.capabilities.readState !== !1;
257
- }
258
- canTransformState(e) {
259
- return !e.capabilities || e.capabilities.transformState === !0;
260
- }
261
- canInterceptEvents(e) {
262
- return !e.capabilities || e.capabilities.interceptEvents === !0;
263
- }
264
- }
265
- var y = /* @__PURE__ */ ((c) => (c.ACTIVE = "active", c.DISPOSAL_REQUESTED = "disposal_requested", c.DISPOSING = "disposing", c.DISPOSED = "disposed", c))(y || {});
266
- class k {
267
- /**
268
- * Creates a new BlocBase instance with the given initial state.
269
- * Sets up the observer, registers with the Blac manager, and initializes addons.
270
- *
271
- * @param initialState The initial state value for this Bloc
272
- */
273
- constructor(e) {
274
- i(this, "uid", $());
275
- /**
276
- * Defines how dependencies are selected from the state for efficient updates.
277
- * When provided, observers will only be notified when selected dependencies change.
278
- */
279
- i(this, "defaultDependencySelector");
280
- /**
281
- * @internal
282
- * Indicates if this specific Bloc instance is isolated from others of the same type.
283
- */
284
- i(this, "_isolated", !1);
285
- /**
286
- * @internal
287
- * Observable responsible for managing state listeners and notifying consumers.
288
- */
289
- i(this, "_observer");
290
- /**
291
- * The unique identifier for this Bloc instance.
292
- * Defaults to the class name, but can be customized.
293
- */
294
- i(this, "_id");
295
- /**
296
- * @internal
297
- * Reference string used internally for tracking and debugging.
298
- */
299
- i(this, "_instanceRef");
300
- /**
301
- * @internal
302
- * Indicates if this specific Bloc instance should be kept alive when no consumers are present.
303
- */
304
- i(this, "_keepAlive", !1);
305
- /**
306
- * @readonly
307
- * Timestamp when this Bloc instance was created, useful for debugging and performance tracking.
308
- */
309
- i(this, "_createdAt", Date.now());
310
- /**
311
- * @internal
312
- * Atomic disposal state to prevent race conditions
313
- */
314
- i(this, "_disposalState", "active");
315
- /**
316
- * @internal
317
- * Timestamp when disposal was requested (for React Strict Mode grace period)
318
- */
319
- i(this, "_disposalRequestTime", 0);
320
- /**
321
- * @internal
322
- * The current state of the Bloc.
323
- */
324
- i(this, "_state");
325
- /**
326
- * @internal
327
- * The previous state of the Bloc, maintained for comparison and history.
328
- */
329
- i(this, "_oldState");
330
- /**
331
- * Props passed during Bloc instance creation.
332
- * Can be used to configure or parameterize the Bloc's behavior.
333
- */
334
- i(this, "props", null);
335
- /**
336
- * @internal
337
- * Flag to prevent batching race conditions
338
- */
339
- i(this, "_batchingLock", !1);
340
- /**
341
- * @internal
342
- * Pending batched updates
343
- */
344
- i(this, "_pendingUpdates", []);
345
- /**
346
- * @internal
347
- * Map of consumer IDs to their WeakRef objects for proper cleanup
348
- */
349
- i(this, "_consumerRefs", /* @__PURE__ */ new Map());
350
- /**
351
- * Plugin registry for this bloc instance
352
- */
353
- i(this, "_plugins");
354
- /**
355
- * @internal
356
- * Validates that all consumer references are still alive
357
- * Removes dead consumers automatically
358
- */
359
- i(this, "_validateConsumers", () => {
360
- const e = [];
361
- for (const [t, s] of this._consumerRefs)
362
- s.deref() === void 0 && e.push(t);
363
- for (const t of e)
364
- this._consumers.delete(t), this._consumerRefs.delete(t);
365
- this._consumers.size === 0 && !this._keepAlive && this._disposalState === "active" && this._scheduleDisposal();
366
- });
367
- /**
368
- * @internal
369
- * Updates the Bloc instance's ID to a new value.
370
- * Only updates if the new ID is defined and different from the current one.
371
- *
372
- * @param id The new ID to assign to this Bloc instance
373
- */
374
- i(this, "_updateId", (e) => {
375
- const t = this._id;
376
- !e || e === t || (this._id = e);
377
- });
378
- /**
379
- * @internal
380
- * Optional function to be called when the Bloc is disposed.
381
- */
382
- i(this, "onDispose");
383
- /**
384
- * @internal
385
- * Set of consumer IDs currently listening to this Bloc's state changes.
386
- */
387
- i(this, "_consumers", /* @__PURE__ */ new Set());
388
- /**
389
- * @internal
390
- * Registers a new consumer to this Bloc instance.
391
- * Notifies the Blac manager that a consumer has been added.
392
- *
393
- * @param consumerId The unique ID of the consumer being added
394
- * @param consumerRef Optional reference to the consumer object for cleanup validation
395
- */
396
- i(this, "_addConsumer", (e, t) => {
397
- var s;
398
- return this._disposalState !== "active" ? !1 : (this._consumers.has(e) || (this._consumers.add(e), t && this._consumerRefs.set(e, new WeakRef(t)), (s = globalThis.Blac) == null || s.log(
399
- `[${this._name}:${this._id}] Consumer added. Total consumers: ${this._consumers.size}`
400
- )), !0);
401
- });
402
- /**
403
- * @internal
404
- * Unregisters a consumer from this Bloc instance.
405
- * Notifies the Blac manager that a consumer has been removed.
406
- *
407
- * @param consumerId The unique ID of the consumer being removed
408
- */
409
- i(this, "_removeConsumer", (e) => {
410
- var t, s;
411
- this._consumers.has(e) && (this._consumers.delete(e), this._consumerRefs.delete(e), (t = globalThis.Blac) == null || t.log(
412
- `[${this._name}:${this._id}] Consumer removed. Remaining consumers: ${this._consumers.size}, keepAlive: ${this._keepAlive}`
413
- ), this._consumers.size === 0 && !this._keepAlive && this._disposalState === "active" && ((s = globalThis.Blac) == null || s.log(
414
- `[${this._name}:${this._id}] No consumers left and not keep-alive. Scheduling disposal.`
415
- ), this._scheduleDisposal()));
416
- });
417
- /**
418
- * @internal
419
- * Handler function for disposal (can be set by Blac manager)
420
- */
421
- i(this, "_disposalHandler");
422
- i(this, "lastUpdate", Date.now());
423
- /**
424
- * @internal
425
- * Flag to indicate if batching is enabled for this bloc
426
- */
427
- i(this, "_batchingEnabled", !1);
428
- /**
429
- * @internal
430
- * Updates the state and notifies all observers of the change.
431
- *
432
- * @param newState The new state to be set
433
- * @param oldState The previous state for comparison
434
- * @param action Optional metadata about what caused the state change
435
- */
436
- i(this, "_pushState", (e, t, s) => {
437
- if (e === void 0 || s !== void 0 && typeof s != "object" && typeof s != "function")
438
- return;
439
- let r = e;
440
- try {
441
- r = this._plugins.transformState(t, e);
442
- } catch (n) {
443
- this._plugins.notifyError(n, {
444
- phase: "state-change",
445
- operation: "transformState"
446
- });
447
- }
448
- if (this._batchingEnabled) {
449
- this._pendingUpdates.push({ newState: r, oldState: t, action: s }), this._oldState = t, this._state = r;
450
- return;
451
- }
452
- this._oldState = t, this._state = r;
453
- try {
454
- this._plugins.notifyStateChange(t, r);
455
- } catch (n) {
456
- console.error("Error notifying bloc plugins of state change:", n);
457
- }
458
- this._observer.notify(r, t, s), this.lastUpdate = Date.now();
459
- });
460
- /**
461
- * Enables batching for multiple state updates
462
- * @param batchFn Function to execute with batching enabled
463
- */
464
- i(this, "batch", (e) => {
465
- if (this._batchingLock)
466
- return e();
467
- this._batchingLock = !0, this._batchingEnabled = !0, this._pendingUpdates = [];
468
- try {
469
- const t = e();
470
- if (this._pendingUpdates.length > 0) {
471
- const s = this._pendingUpdates[this._pendingUpdates.length - 1];
472
- this._observer.notify(
473
- s.newState,
474
- s.oldState,
475
- s.action
476
- ), this.lastUpdate = Date.now();
477
- }
478
- return t;
479
- } finally {
480
- this._batchingEnabled = !1, this._batchingLock = !1, this._pendingUpdates = [];
481
- }
482
- });
483
- this._state = e, this._observer = new H(this), this._id = this.constructor.name;
484
- const t = this.constructor;
485
- if (this._keepAlive = typeof t.keepAlive == "boolean" ? t.keepAlive : !1, this._isolated = typeof t.isolated == "boolean" ? t.isolated : !1, this._plugins = new V(), t.plugins && Array.isArray(t.plugins))
486
- for (const s of t.plugins)
487
- this.addPlugin(s);
488
- }
489
- get isIsolated() {
490
- return this._isolated;
491
- }
492
- get isKeepAlive() {
493
- return this._keepAlive;
494
- }
495
- /**
496
- * Returns the current state of the Bloc.
497
- * Use this getter to access the state in a read-only manner.
498
- * Returns the state even during transitional lifecycle states for React compatibility.
499
- */
500
- get state() {
501
- return this._disposalState === "disposed" ? this._state : this._state;
502
- }
503
- /**
504
- * Returns whether this Bloc instance has been disposed.
505
- * @returns true if the bloc is in DISPOSED state
506
- */
507
- get isDisposed() {
508
- return this._disposalState === "disposed";
509
- }
510
- /**
511
- * @internal
512
- * Returns the name of the Bloc class for identification and debugging.
513
- */
514
- get _name() {
515
- return this.constructor.name;
516
- }
517
- /**
518
- * @internal
519
- * Performs atomic state transition using compare-and-swap semantics
520
- * @param expectedState The expected current state
521
- * @param newState The desired new state
522
- * @returns Result indicating success/failure and state information
523
- */
524
- _atomicStateTransition(e, t) {
525
- var s, r, n, o;
526
- if (this._disposalState === e) {
527
- const a = this._disposalState;
528
- return this._disposalState = t, (s = globalThis.Blac) != null && s.enableLog && ((r = globalThis.Blac) == null || r.log(
529
- `[${this._name}:${this._id}] State transition: ${a} -> ${t} (SUCCESS)`
530
- )), {
531
- success: !0,
532
- currentState: t,
533
- previousState: a
534
- };
535
- }
536
- return (n = globalThis.Blac) != null && n.enableLog && ((o = globalThis.Blac) == null || o.log(
537
- `[${this._name}:${this._id}] State transition failed: expected ${e}, current ${this._disposalState}`
538
- )), {
539
- success: !1,
540
- currentState: this._disposalState,
541
- previousState: e
542
- };
543
- }
544
- /**
545
- * @internal
546
- * Cleans up resources and removes this Bloc from the system.
547
- * Notifies the Blac manager and clears all observers.
548
- */
549
- _dispose() {
550
- var t;
551
- let e = this._atomicStateTransition(
552
- "active",
553
- "disposing"
554
- /* DISPOSING */
555
- );
556
- if (e.success || (e = this._atomicStateTransition(
557
- "disposal_requested",
558
- "disposing"
559
- /* DISPOSING */
560
- )), !e.success)
561
- return !1;
562
- try {
563
- return this._consumers.clear(), this._consumerRefs.clear(), this._observer.clear(), (t = this.onDispose) == null || t.call(this), this._atomicStateTransition(
564
- "disposing",
565
- "disposed"
566
- /* DISPOSED */
567
- ).success;
568
- } catch (s) {
569
- throw this._disposalState = "active", s;
570
- }
571
- }
572
- /**
573
- * @internal
574
- * Sets the disposal handler for this bloc
575
- */
576
- _setDisposalHandler(e) {
577
- this._disposalHandler = e;
578
- }
579
- /**
580
- * @internal
581
- * Schedules disposal of this bloc instance if it has no consumers
582
- * Uses atomic state transitions to prevent race conditions
583
- */
584
- _scheduleDisposal() {
585
- if (!this._atomicStateTransition(
586
- "active",
587
- "disposal_requested"
588
- /* DISPOSAL_REQUESTED */
589
- ).success)
590
- return;
591
- if (!(this._consumers.size === 0 && !this._keepAlive)) {
592
- this._atomicStateTransition(
593
- "disposal_requested",
594
- "active"
595
- /* ACTIVE */
596
- );
597
- return;
598
- }
599
- this._disposalRequestTime = Date.now(), queueMicrotask(() => {
600
- this._consumers.size === 0 && !this._keepAlive && this._observer.size === 0 && this._disposalState === "disposal_requested" ? this._disposalHandler ? this._disposalHandler(this) : this._dispose() : this._atomicStateTransition(
601
- "disposal_requested",
602
- "active"
603
- /* ACTIVE */
604
- );
605
- });
606
- }
607
- /**
608
- * Notify observers of a state change
609
- * @internal Used by plugins for state hydration
610
- * @param newState The new state
611
- * @param oldState The old state
612
- */
613
- _notifyObservers(e, t) {
614
- this._observer.notify(e, t);
615
- }
616
- /**
617
- * Add a plugin to this bloc instance
618
- */
619
- addPlugin(e) {
620
- if (this._plugins.add(e), this._disposalState === "active")
621
- try {
622
- e.onAttach && e.onAttach(this);
623
- } catch (t) {
624
- throw console.error(`Failed to attach plugin '${e.name}':`, t), this._plugins.remove(e.name), t;
625
- }
626
- }
627
- /**
628
- * Remove a plugin from this bloc instance
629
- */
630
- removePlugin(e) {
631
- return this._plugins.remove(e);
632
- }
633
- /**
634
- * Get a plugin by name
635
- */
636
- getPlugin(e) {
637
- return this._plugins.get(e);
638
- }
639
- /**
640
- * Get all plugins
641
- */
642
- getPlugins() {
643
- return this._plugins.getAll();
644
- }
645
- /**
646
- * @internal
647
- * Activate plugins when bloc becomes active
648
- */
649
- _activatePlugins() {
650
- if (this._disposalState === "active")
651
- try {
652
- this._plugins.attach(this);
653
- } catch (e) {
654
- console.error(`Failed to activate plugins for ${this._name}:`, e);
655
- }
656
- }
657
- }
658
- /**
659
- * When true, every consumer will receive its own unique instance of this Bloc.
660
- * Use this when state should not be shared between components.
661
- * @default false
662
- */
663
- i(k, "isolated", !1), /**
664
- * When true, the Bloc instance persists even when there are no active consumers.
665
- * Useful for maintaining state between component unmount/remount cycles.
666
- * @default false
667
- */
668
- i(k, "keepAlive", !1);
669
- class U {
670
- constructor() {
671
- i(this, "plugins", /* @__PURE__ */ new Map());
672
- i(this, "metrics", /* @__PURE__ */ new Map());
673
- i(this, "executionOrder", []);
674
- }
675
- /**
676
- * Add a system plugin
677
- */
678
- add(e) {
679
- if (this.plugins.has(e.name))
680
- throw new Error(`Plugin '${e.name}' is already registered`);
681
- this.plugins.set(e.name, e), this.executionOrder.push(e.name), this.initializeMetrics(e.name);
682
- }
683
- /**
684
- * Remove a system plugin
685
- */
686
- remove(e) {
687
- return this.plugins.get(e) ? (this.plugins.delete(e), this.metrics.delete(e), this.executionOrder = this.executionOrder.filter((s) => s !== e), !0) : !1;
688
- }
689
- /**
690
- * Get a plugin by name
691
- */
692
- get(e) {
693
- return this.plugins.get(e);
694
- }
695
- /**
696
- * Get all plugins in execution order
697
- */
698
- getAll() {
699
- return this.executionOrder.map((e) => this.plugins.get(e));
700
- }
701
- /**
702
- * Clear all plugins
703
- */
704
- clear() {
705
- this.plugins.clear(), this.metrics.clear(), this.executionOrder = [];
706
- }
707
- /**
708
- * Execute a hook on all plugins
709
- */
710
- executeHook(e, t, s) {
711
- for (const r of this.executionOrder) {
712
- const n = this.plugins.get(r), o = n[e];
713
- if (typeof o != "function") continue;
714
- const a = performance.now();
715
- try {
716
- o.apply(n, t), this.recordSuccess(r, e, a);
717
- } catch (l) {
718
- this.recordError(r, e, l), s ? s(l, n) : console.error(`Plugin '${r}' error in hook '${e}':`, l);
719
- }
720
- }
721
- }
722
- /**
723
- * Bootstrap all plugins
724
- */
725
- bootstrap() {
726
- this.executeHook("beforeBootstrap", []), this.executeHook("afterBootstrap", []);
727
- }
728
- /**
729
- * Shutdown all plugins
730
- */
731
- shutdown() {
732
- this.executeHook("beforeShutdown", []), this.executeHook("afterShutdown", []);
733
- }
734
- /**
735
- * Notify plugins of bloc creation
736
- */
737
- notifyBlocCreated(e) {
738
- this.executeHook("onBlocCreated", [e]);
739
- }
740
- /**
741
- * Notify plugins of bloc disposal
742
- */
743
- notifyBlocDisposed(e) {
744
- this.executeHook("onBlocDisposed", [e]);
745
- }
746
- /**
747
- * Notify plugins of state change
748
- */
749
- notifyStateChanged(e, t, s) {
750
- this.executeHook("onStateChanged", [e, t, s]);
751
- }
752
- /**
753
- * Notify plugins of event addition
754
- */
755
- notifyEventAdded(e, t) {
756
- this.executeHook("onEventAdded", [e, t]);
757
- }
758
- /**
759
- * Notify plugins of errors
760
- */
761
- notifyError(e, t, s) {
762
- this.executeHook("onError", [e, t, s], (r, n) => {
763
- console.error(`Plugin '${n.name}' error handler failed:`, r);
764
- });
765
- }
766
- /**
767
- * Get metrics for a plugin
768
- */
769
- getMetrics(e) {
770
- return this.metrics.get(e);
771
- }
772
- initializeMetrics(e) {
773
- this.metrics.set(e, /* @__PURE__ */ new Map());
774
- }
775
- recordSuccess(e, t, s) {
776
- const r = this.metrics.get(e), n = r.get(t) || {
777
- executionTime: 0,
778
- executionCount: 0,
779
- errorCount: 0
780
- }, o = performance.now() - s;
781
- r.set(t, {
782
- ...n,
783
- executionTime: n.executionTime + o,
784
- executionCount: n.executionCount + 1,
785
- lastExecutionTime: o
786
- });
787
- }
788
- recordError(e, t, s) {
789
- const r = this.metrics.get(e), n = r.get(t) || {
790
- executionTime: 0,
791
- executionCount: 0,
792
- errorCount: 0
793
- };
794
- r.set(t, {
795
- ...n,
796
- errorCount: n.errorCount + 1,
797
- lastError: s
798
- });
799
- }
800
- }
801
- const _ = class _ {
802
- getInstance() {
803
- return _._instance || (_._instance = new u({
804
- __unsafe_ignore_singleton: !0
805
- })), _._instance;
806
- }
807
- setInstance(e) {
808
- _._instance = e;
809
- }
810
- resetInstance() {
811
- const e = _._instance;
812
- if (_._instance = new u({
813
- __unsafe_ignore_singleton: !0
814
- }), e)
815
- for (const t of e.keepAliveBlocs)
816
- _._instance.keepAliveBlocs.add(t), _._instance.uidRegistry.set(t.uid, t);
817
- }
818
- };
819
- i(_, "_instance");
820
- let E = _, S = new E();
821
- function W(c) {
822
- S = c;
823
- }
824
- const h = class h {
825
- /**
826
- * Creates a new Blac instance.
827
- * @param options - Configuration options including singleton control
828
- */
829
- constructor(e = {}) {
830
- /** Timestamp when the instance was created */
831
- i(this, "createdAt", Date.now());
832
- /** Map storing all registered bloc instances by their class name and ID */
833
- i(this, "blocInstanceMap", /* @__PURE__ */ new Map());
834
- /** Map storing isolated bloc instances grouped by their constructor */
835
- // Using BlocConstructor<BlocBase<unknown>> would break type inference when storing
836
- // different bloc types in the same map. The 'any' allows proper polymorphic storage
837
- // while maintaining type safety at usage sites through the BlocConstructor constraint.
838
- i(this, "isolatedBlocMap", /* @__PURE__ */ new Map());
839
- /** Map for O(1) lookup of isolated blocs by UID */
840
- i(this, "isolatedBlocIndex", /* @__PURE__ */ new Map());
841
- /** Map tracking UIDs to prevent memory leaks */
842
- i(this, "uidRegistry", /* @__PURE__ */ new Map());
843
- /** Set of keep-alive blocs for controlled cleanup */
844
- i(this, "keepAliveBlocs", /* @__PURE__ */ new Set());
845
- /** Flag to control whether changes should be posted to document */
846
- i(this, "postChangesToDocument", !1);
847
- /** System plugin registry */
848
- i(this, "plugins", new U());
849
- /**
850
- * Logs messages to console when logging is enabled
851
- * @param args - Arguments to log
852
- */
853
- i(this, "log", (...e) => {
854
- h.logSpy && h.logSpy(e), h.enableLog && h.logLevel, h.enableLog && h.logLevel;
855
- });
856
- /**
857
- * Logs a warning message
858
- * @param message - Warning message
859
- * @param args - Additional arguments
860
- */
861
- i(this, "warn", (e, ...t) => {
862
- h.enableLog;
863
- });
864
- /**
865
- * Logs an error message
866
- * @param message - Error message
867
- * @param args - Additional arguments
868
- */
869
- i(this, "error", (e, ...t) => {
870
- h.enableLog;
871
- });
872
- /**
873
- * Resets the Blac instance to a new one, disposing non-keepAlive blocs
874
- * from the old instance.
875
- */
876
- i(this, "resetInstance", () => {
877
- this.log("Reset Blac instance");
878
- const e = new Map(this.blocInstanceMap), t = new Map(this.isolatedBlocMap);
879
- e.forEach((s) => {
880
- !s._keepAlive && s._disposalState === y.ACTIVE && this.disposeBloc(s);
881
- }), t.forEach((s) => {
882
- s.forEach((r) => {
883
- !r._keepAlive && r._disposalState === y.ACTIVE && this.disposeBloc(r);
884
- });
885
- }), this.blocInstanceMap.clear(), this.isolatedBlocMap.clear(), this.isolatedBlocIndex.clear(), S.resetInstance();
886
- });
887
- /**
888
- * Disposes of a bloc instance by removing it from the appropriate registry
889
- * @param bloc - The bloc instance to dispose
890
- */
891
- i(this, "disposeBloc", (e) => {
892
- const t = e._disposalState;
893
- if (![
894
- y.ACTIVE,
895
- y.DISPOSAL_REQUESTED
896
- ].includes(t)) {
897
- this.log(
898
- `[${e._name}:${String(e._id)}] disposeBloc called on bloc in invalid state: ${t}`
899
- );
900
- return;
901
- }
902
- const r = e.constructor, n = this.createBlocInstanceMapKey(e._name, e._id);
903
- this.log(
904
- `[${e._name}:${String(e._id)}] disposeBloc called. Isolated: ${String(r.isolated)}`
905
- ), e._dispose(), this.plugins.notifyBlocDisposed(e), r.isolated ? (this.unregisterIsolatedBlocInstance(e), this.blocInstanceMap.delete(n)) : this.unregisterBlocInstance(e), this.log("dispatched bloc", e);
906
- });
907
- i(this, "activateBloc", (e) => {
908
- if (e._disposalState !== y.ACTIVE) {
909
- this.log(
910
- `[${e._name}:${String(e._id)}] activateBloc called on disposed bloc. Ignoring.`
911
- );
912
- return;
913
- }
914
- const t = e.constructor;
915
- (e.isIsolated ? this.findIsolatedBlocInstance(t, e._id) : this.findRegisteredBlocInstance(t, e._id)) || (this.log(
916
- `[${e._name}:${String(e._id)}] activateBloc called. Isolated: ${String(e.isIsolated)}`
917
- ), e.isIsolated ? this.registerIsolatedBlocInstance(e) : this.registerBlocInstance(e));
918
- });
919
- /**
920
- * Gets or creates a bloc instance based on the provided class and options.
921
- * If a bloc with the given ID exists, it will be returned. Otherwise, a new instance will be created.
922
- *
923
- * @param blocClass - The bloc class to get or create
924
- * @param options - Options including:
925
- * - id: The instance ID (defaults to class name if not provided)
926
- * - props: Properties to pass to the bloc constructor
927
- * - instanceRef: Optional reference string for the instance
928
- * @returns The bloc instance
929
- */
930
- i(this, "getBloc", (e, t = {}) => {
931
- const { id: s, forceNewInstance: r } = t, n = e, o = s ?? e.name;
932
- if (this.log(`[${e.name}:${String(o)}] (getBloc) Called:`, {
933
- options: t,
934
- base: n
935
- }), !r)
936
- if (n.isolated) {
937
- const l = this.findIsolatedBlocInstance(
938
- e,
939
- t.instanceRef ?? o
940
- );
941
- if (l)
942
- return l;
943
- if (t.throwIfNotFound)
944
- throw new Error(`Isolated bloc ${e.name} not found`);
945
- } else {
946
- const l = this.findRegisteredBlocInstance(
947
- e,
948
- o
949
- );
950
- if (l)
951
- return l;
952
- if (t.throwIfNotFound)
953
- throw new Error(`Registered bloc ${e.name} not found`);
954
- }
955
- const a = this.createNewBlocInstance(e, o, t);
956
- if (this.log(
957
- `[${e.name}:${String(o)}] (getBloc) No existing instance found. Creating new one.`,
958
- t,
959
- a
960
- ), !a)
961
- throw new Error(
962
- `[getBloc] Failed to create bloc instance for ${e.name}. This should never happen.`
963
- );
964
- return a;
965
- });
966
- /**
967
- * Gets a bloc instance or throws an error if it doesn't exist
968
- * @param blocClass - The bloc class to get
969
- * @param options - Options including:
970
- * - id: The instance ID (defaults to class name if not provided)
971
- * - props: Properties to pass to the bloc constructor
972
- * - instanceRef: Optional reference string for the instance
973
- */
974
- i(this, "getBlocOrThrow", (e, t = {}) => {
975
- const s = e.isolated, r = t.id || e.name, n = s ? this.findIsolatedBlocInstance(e, r) : this.findRegisteredBlocInstance(e, r);
976
- if (n)
977
- return n;
978
- throw new Error(`Bloc ${e.name} not found`);
979
- });
980
- /**
981
- * Gets all instances of a specific bloc class
982
- * @param blocClass - The bloc class to search for
983
- * @param options - Options including:
984
- * - searchIsolated: Whether to search in isolated blocs (defaults to bloc's isolated property)
985
- * @returns Array of matching bloc instances
986
- */
987
- i(this, "getAllBlocs", (e, t = {}) => {
988
- const s = [];
989
- if (this.blocInstanceMap.forEach((r) => {
990
- r.constructor === e && s.push(r);
991
- }), t.searchIsolated !== !1) {
992
- const r = this.isolatedBlocMap.get(e);
993
- r && s.push(...r.map((n) => n));
994
- }
995
- return s;
996
- });
997
- /**
998
- * Disposes all keep-alive blocs of a specific type
999
- * @param blocClass - The bloc class to dispose
1000
- */
1001
- i(this, "disposeKeepAliveBlocs", (e) => {
1002
- const t = [];
1003
- for (const s of this.keepAliveBlocs)
1004
- (!e || s.constructor === e) && t.push(s);
1005
- t.forEach((s) => s._dispose());
1006
- });
1007
- /**
1008
- * Disposes all blocs matching a pattern
1009
- * @param predicate - Function to test each bloc for disposal
1010
- */
1011
- i(this, "disposeBlocs", (e) => {
1012
- const t = [];
1013
- for (const s of this.blocInstanceMap.values())
1014
- e(s) && t.push(s);
1015
- for (const s of this.isolatedBlocMap.values())
1016
- for (const r of s)
1017
- e(r) && t.push(r);
1018
- t.forEach((s) => s._dispose());
1019
- });
1020
- /**
1021
- * Gets memory usage statistics for debugging
1022
- */
1023
- i(this, "getMemoryStats", () => ({
1024
- totalBlocs: this.uidRegistry.size,
1025
- registeredBlocs: this.blocInstanceMap.size,
1026
- isolatedBlocs: Array.from(this.isolatedBlocMap.values()).reduce(
1027
- (e, t) => e + t.length,
1028
- 0
1029
- ),
1030
- keepAliveBlocs: this.keepAliveBlocs.size,
1031
- isolatedBlocTypes: this.isolatedBlocMap.size
1032
- }));
1033
- /**
1034
- * Validates consumer references and cleans up orphaned consumers
1035
- */
1036
- i(this, "validateConsumers", () => {
1037
- for (const e of this.uidRegistry.values())
1038
- e._validateConsumers(), e._consumers.size === 0 && !e._keepAlive && e._disposalState === y.ACTIVE && setTimeout(() => {
1039
- e._consumers.size === 0 && !e._keepAlive && e._disposalState === y.ACTIVE && this.disposeBloc(e);
1040
- }, 1e3);
1041
- });
1042
- const { __unsafe_ignore_singleton: t = !1 } = e;
1043
- if (!t)
1044
- return h.instance;
1045
- S.setInstance(this), this.plugins.bootstrap();
1046
- }
1047
- static get instance() {
1048
- return S.getInstance();
1049
- }
1050
- static get getAllBlocs() {
1051
- return h.instance.getAllBlocs;
1052
- }
1053
- /** Get current configuration */
1054
- static get config() {
1055
- return { ...this._config };
1056
- }
1057
- /**
1058
- * Set or update Blac configuration
1059
- * @param config - Partial configuration to merge with existing config
1060
- * @throws Error if configuration is invalid
1061
- */
1062
- static setConfig(e) {
1063
- if (e.proxyDependencyTracking !== void 0 && typeof e.proxyDependencyTracking != "boolean")
1064
- throw new Error("BlacConfig.proxyDependencyTracking must be a boolean");
1065
- if (e.exposeBlacInstance !== void 0 && typeof e.exposeBlacInstance != "boolean")
1066
- throw new Error("BlacConfig.exposeBlacInstance must be a boolean");
1067
- this._config = {
1068
- ...this._config,
1069
- ...e
1070
- }, this.enableLog && this.instance.log("Blac config updated:", this._config);
1071
- }
1072
- static get log() {
1073
- return h.instance.log;
1074
- }
1075
- /**
1076
- * Gets the current Blac instance
1077
- * @returns The Blac instance
1078
- */
1079
- static getInstance() {
1080
- return S.getInstance();
1081
- }
1082
- static get warn() {
1083
- return h.instance.warn;
1084
- }
1085
- static get error() {
1086
- return h.instance.error;
1087
- }
1088
- static get disposeBloc() {
1089
- return h.instance.disposeBloc;
1090
- }
1091
- /**
1092
- * Creates a unique key for a bloc instance in the map based on the bloc class name and instance ID
1093
- * @param blocClassName - The name of the bloc class
1094
- * @param id - The instance ID
1095
- * @returns A unique key string in the format "className:id"
1096
- */
1097
- createBlocInstanceMapKey(e, t) {
1098
- return `${e}:${String(t)}`;
1099
- }
1100
- /**
1101
- * Unregister a bloc instance from the main registry
1102
- * @param bloc - The bloc instance to unregister
1103
- */
1104
- unregisterBlocInstance(e) {
1105
- const t = this.createBlocInstanceMapKey(e._name, e._id);
1106
- this.blocInstanceMap.delete(t), this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e);
1107
- }
1108
- /**
1109
- * Registers a bloc instance in the main registry
1110
- * @param bloc - The bloc instance to register
1111
- */
1112
- registerBlocInstance(e) {
1113
- const t = this.createBlocInstanceMapKey(e._name, e._id);
1114
- this.blocInstanceMap.set(t, e), this.uidRegistry.set(e.uid, e), e._keepAlive && this.keepAliveBlocs.add(e);
1115
- }
1116
- /**
1117
- * Finds a registered bloc instance by its class and ID
1118
- * @param blocClass - The bloc class to search for
1119
- * @param id - The instance ID
1120
- * @returns The found bloc instance or undefined if not found
1121
- */
1122
- findRegisteredBlocInstance(e, t) {
1123
- if (e.isolated) return;
1124
- const r = this.createBlocInstanceMapKey(e.name, t);
1125
- return this.blocInstanceMap.get(r);
1126
- }
1127
- /**
1128
- * Registers an isolated bloc instance in the isolated registry
1129
- * @param bloc - The isolated bloc instance to register
1130
- */
1131
- registerIsolatedBlocInstance(e) {
1132
- const t = e.constructor, s = this.isolatedBlocMap.get(t);
1133
- s ? s.push(e) : this.isolatedBlocMap.set(t, [e]), this.isolatedBlocIndex.set(e.uid, e), this.uidRegistry.set(e.uid, e), e._keepAlive && this.keepAliveBlocs.add(e);
1134
- }
1135
- /**
1136
- * Unregister an isolated bloc instance from the isolated registry
1137
- * @param bloc - The isolated bloc instance to unregister
1138
- */
1139
- unregisterIsolatedBlocInstance(e) {
1140
- const t = e.constructor, s = this.isolatedBlocMap.get(t);
1141
- let r = !1;
1142
- if (s) {
1143
- const o = s.findIndex((a) => a.uid === e.uid);
1144
- o !== -1 && (s.splice(o, 1), r = !0), s.length === 0 && this.isolatedBlocMap.delete(t);
1145
- }
1146
- const n = this.isolatedBlocIndex.delete(e.uid);
1147
- this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e), r !== n && this.warn(
1148
- `[Blac] Inconsistent state detected during isolated bloc cleanup for ${e._name}:${e.uid}. Map removal: ${r}, Index removal: ${n}`
1149
- );
1150
- }
1151
- /**
1152
- * Finds an isolated bloc instance by its class and ID (O(n) lookup)
1153
- */
1154
- findIsolatedBlocInstance(e, t) {
1155
- if (!e.isolated) return;
1156
- const r = this.isolatedBlocMap.get(e);
1157
- return r ? r.find((o) => o._id === t) : void 0;
1158
- }
1159
- /**
1160
- * Finds an isolated bloc instance by UID (O(1) lookup)
1161
- */
1162
- findIsolatedBlocInstanceByUid(e) {
1163
- return this.isolatedBlocIndex.get(e);
1164
- }
1165
- /**
1166
- * Creates a new bloc instance and registers it in the appropriate registry
1167
- * @param blocClass - The bloc class to instantiate
1168
- * @param id - The instance ID
1169
- * @param props - Properties to pass to the bloc constructor
1170
- * @param instanceRef - Optional reference string for the instance
1171
- * @returns The newly created bloc instance
1172
- */
1173
- createNewBlocInstance(e, t, s = {}) {
1174
- const { props: r, instanceRef: n } = s, o = new e(r);
1175
- return o._instanceRef = n, o.props = r || null, o._updateId(t), o._setDisposalHandler((a) => this.disposeBloc(a)), o.isIsolated ? this.registerIsolatedBlocInstance(o) : this.registerBlocInstance(o), o._activatePlugins(), this.plugins.notifyBlocCreated(o), o;
1176
- }
1177
- static get activateBloc() {
1178
- return h.instance.activateBloc;
1179
- }
1180
- static get getBloc() {
1181
- return h.instance.getBloc;
1182
- }
1183
- static get getBlocOrThrow() {
1184
- return h.instance.getBlocOrThrow;
1185
- }
1186
- static get disposeKeepAliveBlocs() {
1187
- return h.instance.disposeKeepAliveBlocs;
1188
- }
1189
- static get disposeBlocs() {
1190
- return h.instance.disposeBlocs;
1191
- }
1192
- static get getMemoryStats() {
1193
- return h.instance.getMemoryStats;
1194
- }
1195
- static get validateConsumers() {
1196
- return h.instance.validateConsumers;
1197
- }
1198
- /**
1199
- * Bootstrap the Blac instance and all plugins
1200
- */
1201
- bootstrap() {
1202
- this.plugins.bootstrap();
1203
- }
1204
- /**
1205
- * Shutdown the Blac instance and all plugins
1206
- */
1207
- shutdown() {
1208
- this.plugins.shutdown();
1209
- for (const e of this.blocInstanceMap.values())
1210
- e._keepAlive || this.disposeBloc(e);
1211
- for (const e of this.isolatedBlocMap.values())
1212
- for (const t of e)
1213
- t._keepAlive || this.disposeBloc(t);
1214
- }
1215
- };
1216
- /** Private static configuration */
1217
- i(h, "_config", {
1218
- exposeBlacInstance: !1,
1219
- proxyDependencyTracking: !0
1220
- }), /** Flag to enable/disable logging */
1221
- i(h, "enableLog", !1), i(h, "logLevel", "warn"), i(h, "logSpy", null), i(h, "resetInstance", () => {
1222
- S.resetInstance();
1223
- });
1224
- let u = h;
1225
- class j extends k {
1226
- constructor() {
1227
- super(...arguments);
1228
- i(this, "eventHandlers", /* @__PURE__ */ new Map());
1229
- /**
1230
- * @internal
1231
- * Event queue to ensure sequential processing of async events
1232
- */
1233
- i(this, "_eventQueue", []);
1234
- /**
1235
- * @internal
1236
- * Flag indicating if an event is currently being processed
1237
- */
1238
- i(this, "_isProcessingEvent", !1);
1239
- /**
1240
- * Dispatches an action/event to the Bloc.
1241
- * Events are queued and processed sequentially to prevent race conditions.
1242
- * @param action The action/event instance to be processed.
1243
- */
1244
- i(this, "add", async (t) => {
1245
- let s = t;
1246
- try {
1247
- s = this._plugins.transformEvent(t);
1248
- } catch (r) {
1249
- console.error("Error transforming event:", r);
1250
- }
1251
- if (s !== null) {
1252
- try {
1253
- this._plugins.notifyEvent(s);
1254
- } catch (r) {
1255
- console.error("Error notifying plugins of event:", r);
1256
- }
1257
- u.instance.plugins.notifyEventAdded(this, s), this._eventQueue.push(s), this._isProcessingEvent || await this._processEventQueue();
1258
- }
1259
- });
1260
- }
1261
- /**
1262
- * Registers an event handler for a specific event type.
1263
- * This method is typically called in the constructor of a derived Bloc class.
1264
- * @param eventConstructor The constructor of the event to handle (e.g., LoadDataEvent).
1265
- * @param handler A function that processes the event and can emit new states.
1266
- * The 'event' parameter in the handler will be typed to the specific eventConstructor.
1267
- */
1268
- on(t, s) {
1269
- this.eventHandlers.has(t) && u.warn(
1270
- `[Bloc ${this._name}:${String(this._id)}] Handler for event '${t.name}' already registered. It will be overwritten.`
1271
- ), this.eventHandlers.set(
1272
- t,
1273
- s
1274
- );
1275
- }
1276
- /**
1277
- * @internal
1278
- * Processes events from the queue sequentially
1279
- */
1280
- async _processEventQueue() {
1281
- if (!this._isProcessingEvent) {
1282
- this._isProcessingEvent = !0;
1283
- try {
1284
- for (; this._eventQueue.length > 0; ) {
1285
- const t = this._eventQueue.shift();
1286
- await this._processEvent(t);
1287
- }
1288
- } finally {
1289
- this._isProcessingEvent = !1;
1290
- }
1291
- }
1292
- }
1293
- /**
1294
- * @internal
1295
- * Processes a single event
1296
- */
1297
- async _processEvent(t) {
1298
- const s = t.constructor, r = this.eventHandlers.get(s);
1299
- if (r) {
1300
- const n = (o) => {
1301
- const a = this.state;
1302
- this._pushState(o, a, t);
1303
- };
1304
- try {
1305
- await r(t, n);
1306
- } catch (o) {
1307
- const a = t.constructor.name || "UnnamedConstructor", l = {
1308
- blocName: this._name,
1309
- blocId: String(this._id),
1310
- eventType: a,
1311
- currentState: this.state,
1312
- action: t,
1313
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1314
- };
1315
- if (u.error(
1316
- `[Bloc ${this._name}:${String(this._id)}] Error in event handler for '${a}':`,
1317
- o,
1318
- "Context:",
1319
- l
1320
- ), o instanceof Error)
1321
- try {
1322
- this._plugins.notifyError(o, {
1323
- phase: "event-processing",
1324
- operation: "handler",
1325
- metadata: { event: t }
1326
- }), u.instance.plugins.notifyError(o, this, {
1327
- phase: "event-processing",
1328
- operation: "handler",
1329
- metadata: { event: t }
1330
- });
1331
- } catch (d) {
1332
- console.error("Error notifying plugins:", d);
1333
- }
1334
- if (o instanceof Error && o.name === "CriticalError")
1335
- throw o;
1336
- }
1337
- } else {
1338
- const n = t.constructor.name || "UnnamedConstructor";
1339
- u.warn(
1340
- `[Bloc ${this._name}:${String(this._id)}] No handler registered for action type: '${n}'.`,
1341
- "Registered handlers:",
1342
- Array.from(this.eventHandlers.keys()).map((o) => o.name),
1343
- "Action was:",
1344
- t
1345
- );
1346
- }
1347
- }
1348
- }
1349
- class z extends k {
1350
- /**
1351
- * @internal
1352
- * Protected method for useBloc to call
1353
- */
1354
- _updateProps(e) {
1355
- var s;
1356
- const t = this.props;
1357
- this.props = e, (s = this.onPropsChanged) == null || s.call(this, t, e);
1358
- }
1359
- /**
1360
- * Updates the current state and notifies all observers of the change.
1361
- * If the new state is identical to the current state (using Object.is),
1362
- * no update will occur.
1363
- * @param state - The new state to set
1364
- */
1365
- emit(e) {
1366
- if (Object.is(e, this.state))
1367
- return;
1368
- const t = this.state, s = e;
1369
- this._pushState(s, t);
1370
- }
1371
- /**
1372
- * Partially updates the current state by merging it with the provided state patch.
1373
- * This method is only applicable when the state is an object type.
1374
- *
1375
- * @param statePatch - A partial state object containing only the properties to update
1376
- * @param ignoreChangeCheck - If true, skips checking if the state has actually changed
1377
- * @throws {TypeError} If the state is not an object type
1378
- */
1379
- patch(e, t = !1) {
1380
- if (typeof this.state != "object" || this.state === null) {
1381
- u.warn(
1382
- "Cubit.patch: was called on a cubit where the state is not an object. This is a no-op."
1383
- );
1384
- return;
1385
- }
1386
- let s = !1;
1387
- if (t)
1388
- s = !0;
1389
- else
1390
- for (const r in e)
1391
- if (Object.prototype.hasOwnProperty.call(e, r)) {
1392
- const o = this.state[r];
1393
- if (!Object.is(e[r], o)) {
1394
- s = !0;
1395
- break;
1396
- }
1397
- }
1398
- s && this.emit({
1399
- ...this.state,
1400
- ...e
1401
- });
1402
- }
1403
- }
1404
- class L {
1405
- constructor(e) {
1406
- this.props = e;
1407
- }
1408
- }
1409
- function N(c, e) {
1410
- if (Object.is(c, e))
1411
- return !0;
1412
- if (typeof c != "object" || c === null || typeof e != "object" || e === null)
1413
- return !1;
1414
- const t = Object.keys(c), s = Object.keys(e);
1415
- if (t.length !== s.length)
1416
- return !1;
1417
- for (let r = 0; r < t.length; r++) {
1418
- const n = t[r];
1419
- if (!Object.prototype.hasOwnProperty.call(e, n) || !Object.is(c[n], e[n]))
1420
- return !1;
1421
- }
1422
- return !0;
1423
- }
1424
- class q {
1425
- /**
1426
- * Sets up a clean test environment
1427
- */
1428
- static setUp() {
1429
- this.originalInstance = u.instance, u.resetInstance(), u.enableLog = !1;
1430
- }
1431
- /**
1432
- * Tears down the test environment and restores original state
1433
- */
1434
- static tearDown() {
1435
- u.resetInstance();
1436
- }
1437
- /**
1438
- * Creates a test bloc with automatic cleanup
1439
- */
1440
- static createBloc(e, ...t) {
1441
- const s = new e(...t);
1442
- return u.activateBloc(s), s;
1443
- }
1444
- /**
1445
- * Waits for a bloc to emit a specific state
1446
- */
1447
- static async waitForState(e, t, s = 5e3) {
1448
- return new Promise((r, n) => {
1449
- const o = setTimeout(() => {
1450
- n(
1451
- new Error(
1452
- `Timeout waiting for state matching predicate after ${s}ms`
1453
- )
1454
- );
1455
- }, s), a = e._observer.subscribe({
1456
- id: `test-waiter-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
1457
- fn: (l) => {
1458
- t(l) && (clearTimeout(o), a(), r(l));
1459
- }
1460
- });
1461
- t(e.state) && (clearTimeout(o), a(), r(e.state));
1462
- });
1463
- }
1464
- /**
1465
- * Expects a bloc to emit specific states in order
1466
- */
1467
- static async expectStates(e, t, s = 5e3) {
1468
- const r = [];
1469
- return new Promise((n, o) => {
1470
- const a = setTimeout(() => {
1471
- o(
1472
- new Error(
1473
- `Timeout waiting for states. Expected: ${JSON.stringify(t)}, Received: ${JSON.stringify(r)}`
1474
- )
1475
- );
1476
- }, s), l = e._observer.subscribe({
1477
- id: `test-expecter-${crypto.randomUUID()}`,
1478
- fn: (d) => {
1479
- if (r.push(d), r.length === t.length) {
1480
- clearTimeout(a), l();
1481
- for (let f = 0; f < t.length; f++) {
1482
- const m = t[f], v = r[f];
1483
- if (JSON.stringify(m) !== JSON.stringify(v)) {
1484
- o(
1485
- new Error(
1486
- `State mismatch at index ${f}. Expected: ${JSON.stringify(m)}, Received: ${JSON.stringify(v)}`
1487
- )
1488
- );
1489
- return;
1490
- }
1491
- }
1492
- n();
1493
- }
1494
- }
1495
- });
1496
- });
1497
- }
1498
- }
1499
- i(q, "originalInstance");
1500
- class F extends j {
1501
- constructor(t) {
1502
- super(t);
1503
- i(this, "mockHandlers", /* @__PURE__ */ new Map());
1504
- }
1505
- /**
1506
- * Mock an event handler for testing
1507
- */
1508
- mockEventHandler(t, s) {
1509
- this.on(t, s);
1510
- }
1511
- /**
1512
- * Get the number of registered handlers
1513
- */
1514
- getHandlerCount() {
1515
- return this.eventHandlers.size;
1516
- }
1517
- /**
1518
- * Check if a handler is registered for an event type
1519
- */
1520
- hasHandler(t) {
1521
- return this.eventHandlers.has(t);
1522
- }
1523
- }
1524
- class G extends z {
1525
- constructor(t) {
1526
- super(t);
1527
- i(this, "stateHistory", []);
1528
- this.stateHistory.push(t);
1529
- }
1530
- /**
1531
- * Override emit to track state history
1532
- */
1533
- emit(t) {
1534
- this.stateHistory.push(t), super.emit(t);
1535
- }
1536
- /**
1537
- * Get the history of all states
1538
- */
1539
- getStateHistory() {
1540
- return [...this.stateHistory];
1541
- }
1542
- /**
1543
- * Clear state history
1544
- */
1545
- clearStateHistory() {
1546
- this.stateHistory = [this.state];
1547
- }
1548
- }
1549
- class J {
1550
- constructor() {
1551
- i(this, "initialStats");
1552
- this.initialStats = u.getMemoryStats();
1553
- }
1554
- /**
1555
- * Check for memory leaks and return a report
1556
- */
1557
- checkForLeaks() {
1558
- const e = u.getMemoryStats(), t = e.registeredBlocs > this.initialStats.registeredBlocs || e.isolatedBlocs > this.initialStats.isolatedBlocs || e.keepAliveBlocs > this.initialStats.keepAliveBlocs, s = `
1559
- Memory Leak Detection Report:
1560
- - Initial registered blocs: ${this.initialStats.registeredBlocs}
1561
- - Current registered blocs: ${e.registeredBlocs}
1562
- - Initial isolated blocs: ${this.initialStats.isolatedBlocs}
1563
- - Current isolated blocs: ${e.isolatedBlocs}
1564
- - Initial keep-alive blocs: ${this.initialStats.keepAliveBlocs}
1565
- - Current keep-alive blocs: ${e.keepAliveBlocs}
1566
- - Potential leaks detected: ${t ? "YES" : "NO"}
1567
- `.trim();
1568
- return {
1569
- hasLeaks: t,
1570
- report: s,
1571
- stats: e
1572
- };
1573
- }
1574
- }
1575
- class K {
1576
- constructor() {
1577
- i(this, "consumers", /* @__PURE__ */ new WeakMap());
1578
- i(this, "registrationCount", 0);
1579
- i(this, "activeConsumers", 0);
1580
- }
1581
- register(e, t) {
1582
- this.registrationCount++, this.consumers.get(e) || this.activeConsumers++, this.consumers.set(e, {
1583
- id: t,
1584
- lastNotified: Date.now(),
1585
- hasRendered: !1,
1586
- stateAccesses: /* @__PURE__ */ new Set(),
1587
- classAccesses: /* @__PURE__ */ new Set(),
1588
- stateValues: /* @__PURE__ */ new Map(),
1589
- classValues: /* @__PURE__ */ new Map(),
1590
- accessCount: 0,
1591
- lastAccessTime: 0,
1592
- firstAccessTime: 0
1593
- });
1594
- }
1595
- unregister(e) {
1596
- e && this.consumers.get(e) && (this.consumers.delete(e), this.activeConsumers = Math.max(0, this.activeConsumers - 1));
1597
- }
1598
- trackAccess(e, t, s, r) {
1599
- const n = this.consumers.get(e);
1600
- if (!n) return;
1601
- const o = Date.now();
1602
- n.firstAccessTime || (n.firstAccessTime = o), n.accessCount++, n.lastAccessTime = o, t === "state" ? (n.stateAccesses.add(s), r !== void 0 && n.stateValues.set(s, { value: r, lastAccessTime: o })) : (n.classAccesses.add(s), r !== void 0 && n.classValues.set(s, { value: r, lastAccessTime: o }));
1603
- }
1604
- resetTracking(e) {
1605
- const t = this.consumers.get(e);
1606
- t && (t.stateAccesses.clear(), t.classAccesses.clear(), t.stateValues.clear(), t.classValues.clear(), t.accessCount = 0, t.firstAccessTime = 0);
1607
- }
1608
- getDependencies(e) {
1609
- const t = this.consumers.get(e);
1610
- return t ? {
1611
- statePaths: Array.from(t.stateAccesses),
1612
- classPaths: Array.from(t.classAccesses)
1613
- } : null;
1614
- }
1615
- hasValuesChanged(e, t, s) {
1616
- const r = this.consumers.get(e);
1617
- if (!r) return !0;
1618
- let n = !1;
1619
- const o = Date.now();
1620
- if (r.stateValues.size === 0 && r.classValues.size === 0 && (r.stateAccesses.size > 0 || r.classAccesses.size > 0))
1621
- return !0;
1622
- for (const [a, l] of r.stateValues)
1623
- try {
1624
- const d = this.getValueAtPath(t, a);
1625
- d !== l.value && (r.stateValues.set(a, {
1626
- value: d,
1627
- lastAccessTime: o
1628
- }), n = !0);
1629
- } catch {
1630
- n = !0;
1631
- }
1632
- for (const [a, l] of r.classValues)
1633
- try {
1634
- const d = this.getValueAtPath(s, a);
1635
- d !== l.value && (r.classValues.set(a, {
1636
- value: d,
1637
- lastAccessTime: o
1638
- }), n = !0);
1639
- } catch {
1640
- n = !0;
1641
- }
1642
- return n;
1643
- }
1644
- shouldNotifyConsumer(e, t) {
1645
- const s = this.consumers.get(e);
1646
- if (!s) return !1;
1647
- for (const r of t) {
1648
- if (s.stateAccesses.has(r) || s.classAccesses.has(r)) return !0;
1649
- for (const n of s.stateAccesses)
1650
- if (r.startsWith(n + ".") || n.startsWith(r + "."))
1651
- return !0;
1652
- }
1653
- return !1;
1654
- }
1655
- updateLastNotified(e) {
1656
- const t = this.consumers.get(e);
1657
- t && (t.lastNotified = Date.now());
1658
- }
1659
- getConsumerInfo(e) {
1660
- return this.consumers.get(e);
1661
- }
1662
- setHasRendered(e, t) {
1663
- const s = this.consumers.get(e);
1664
- s && (s.hasRendered = t);
1665
- }
1666
- hasConsumer(e) {
1667
- return this.consumers.has(e);
1668
- }
1669
- getStats() {
1670
- return {
1671
- totalRegistrations: this.registrationCount,
1672
- activeConsumers: this.activeConsumers
1673
- };
1674
- }
1675
- getValueAtPath(e, t) {
1676
- const s = t.split(".");
1677
- let r = e;
1678
- for (const n of s) {
1679
- if (r == null) return;
1680
- r = r[n];
1681
- }
1682
- return r;
1683
- }
1684
- }
1685
- const x = /* @__PURE__ */ new WeakMap();
1686
- let p = {
1687
- stateProxiesCreated: 0,
1688
- classProxiesCreated: 0,
1689
- cacheHits: 0,
1690
- cacheMisses: 0,
1691
- propertyAccesses: 0,
1692
- nestedProxiesCreated: 0,
1693
- totalProxiesCreated: 0,
1694
- createdAt: Date.now()
1695
- };
1696
- class I {
1697
- static createStateProxy(e) {
1698
- const { target: t, consumerRef: s, consumerTracker: r, path: n = "" } = e;
1699
- if (!s || !r || typeof t != "object" || t === null)
1700
- return t;
1701
- let o = x.get(t);
1702
- o || (o = /* @__PURE__ */ new WeakMap(), x.set(t, o));
1703
- const a = o.get(s);
1704
- if (a)
1705
- return p.cacheHits++, a;
1706
- p.cacheMisses++;
1707
- const l = {
1708
- get(f, m) {
1709
- if (typeof m == "symbol" || m === "constructor")
1710
- return Reflect.get(f, m);
1711
- const v = n ? `${n}.${m}` : m;
1712
- p.propertyAccesses++;
1713
- const g = Reflect.get(f, m), B = g && typeof g === "object" && g !== null ? void 0 : g;
1714
- if (r.trackAccess(s, "state", v, B), g && typeof g == "object" && g !== null) {
1715
- const w = Object.getPrototypeOf(g) === Object.prototype, T = Array.isArray(g);
1716
- if (w || T)
1717
- return p.nestedProxiesCreated++, I.createStateProxy({
1718
- target: g,
1719
- consumerRef: s,
1720
- consumerTracker: r,
1721
- path: v
1722
- });
1723
- }
1724
- return g;
1725
- },
1726
- has(f, m) {
1727
- return m in f;
1728
- },
1729
- ownKeys(f) {
1730
- return Reflect.ownKeys(f);
1731
- },
1732
- getOwnPropertyDescriptor(f, m) {
1733
- return Reflect.getOwnPropertyDescriptor(f, m);
1734
- },
1735
- set() {
1736
- return !1;
1737
- },
1738
- deleteProperty() {
1739
- return !1;
1740
- }
1741
- }, d = new Proxy(t, l);
1742
- return o.set(s, d), p.stateProxiesCreated++, p.totalProxiesCreated++, d;
1743
- }
1744
- static createClassProxy(e) {
1745
- const { target: t, consumerRef: s, consumerTracker: r } = e;
1746
- if (!s || !r)
1747
- return t;
1748
- let n = x.get(t);
1749
- n || (n = /* @__PURE__ */ new WeakMap(), x.set(t, n));
1750
- const o = n.get(s);
1751
- if (o)
1752
- return p.cacheHits++, o;
1753
- p.cacheMisses++;
1754
- const a = {
1755
- get(d, f) {
1756
- const m = Reflect.get(d, f);
1757
- let v = !1, g = d;
1758
- const A = /* @__PURE__ */ new WeakSet(), P = 10;
1759
- let B = 0;
1760
- for (; g && !v && B < P && !A.has(g); ) {
1761
- A.add(g);
1762
- try {
1763
- const C = Object.getOwnPropertyDescriptor(
1764
- g,
1765
- f
1766
- );
1767
- if (C && C.get) {
1768
- v = !0;
1769
- break;
1770
- }
1771
- g = Object.getPrototypeOf(g), B++;
1772
- } catch {
1773
- break;
1774
- }
1775
- }
1776
- if (!v)
1777
- return m;
1778
- p.propertyAccesses++;
1779
- const w = m, M = w !== null && typeof w != "object" ? w : void 0;
1780
- return r.trackAccess(
1781
- s,
1782
- "class",
1783
- String(f),
1784
- M
1785
- ), m;
1786
- },
1787
- has(d, f) {
1788
- return f in d;
1789
- },
1790
- ownKeys(d) {
1791
- return Reflect.ownKeys(d);
1792
- },
1793
- getOwnPropertyDescriptor(d, f) {
1794
- return Reflect.getOwnPropertyDescriptor(d, f);
1795
- }
1796
- }, l = new Proxy(t, a);
1797
- return n.set(s, l), p.classProxiesCreated++, p.totalProxiesCreated++, l;
1798
- }
1799
- static getProxyState(e) {
1800
- return I.createStateProxy({
1801
- target: e.state,
1802
- consumerRef: e.consumerRef,
1803
- consumerTracker: e.consumerTracker
1804
- });
1805
- }
1806
- static getProxyBlocInstance(e) {
1807
- return I.createClassProxy({
1808
- target: e.blocInstance,
1809
- consumerRef: e.consumerRef,
1810
- consumerTracker: e.consumerTracker
1811
- });
1812
- }
1813
- static getStats() {
1814
- const e = Date.now() - p.createdAt;
1815
- return {
1816
- ...p,
1817
- totalProxies: p.stateProxiesCreated + p.classProxiesCreated,
1818
- cacheEfficiency: p.cacheHits + p.cacheMisses > 0 ? `${(p.cacheHits / (p.cacheHits + p.cacheMisses) * 100).toFixed(1)}%` : "N/A",
1819
- lifetime: `${e}ms`,
1820
- proxiesPerSecond: e > 0 ? (p.totalProxiesCreated / (e / 1e3)).toFixed(2) : "N/A"
1821
- };
1822
- }
1823
- static resetStats() {
1824
- p = {
1825
- stateProxiesCreated: 0,
1826
- classProxiesCreated: 0,
1827
- cacheHits: 0,
1828
- cacheMisses: 0,
1829
- propertyAccesses: 0,
1830
- nestedProxiesCreated: 0,
1831
- totalProxiesCreated: 0,
1832
- createdAt: Date.now()
1833
- };
1834
- }
1835
- }
1836
- const b = class b {
1837
- constructor(e, t) {
1838
- i(this, "id", `consumer-${$()}`);
1839
- i(this, "blocConstructor");
1840
- i(this, "componentRef", { current: {} });
1841
- i(this, "blocInstance");
1842
- // Core components
1843
- i(this, "consumerTracker");
1844
- i(this, "lastProps");
1845
- i(this, "unmountTime", 0);
1846
- i(this, "mountTime", 0);
1847
- // Dependency tracking
1848
- i(this, "dependencyValues");
1849
- i(this, "isUsingDependencies", !1);
1850
- // Lifecycle state
1851
- i(this, "hasMounted", !1);
1852
- i(this, "mountCount", 0);
1853
- i(this, "options");
1854
- i(this, "createStateProxy", (e) => I.createStateProxy({
1855
- target: e.target,
1856
- consumerRef: this.componentRef.current,
1857
- consumerTracker: this
1858
- }));
1859
- i(this, "createClassProxy", (e) => I.createClassProxy({
1860
- target: e.target,
1861
- consumerRef: this.componentRef.current,
1862
- consumerTracker: this
1863
- }));
1864
- i(this, "createSubscription", (e) => this.blocInstance._observer.subscribe({
1865
- id: this.id,
1866
- fn: (s, r) => {
1867
- var n;
1868
- if (this.isUsingDependencies && ((n = this.options) != null && n.dependencies)) {
1869
- const o = this.options.dependencies(this.blocInstance);
1870
- if (!this.hasDependencyValuesChanged(
1871
- this.dependencyValues,
1872
- o
1873
- ))
1874
- return;
1875
- this.dependencyValues = o;
1876
- } else if (u.config.proxyDependencyTracking) {
1877
- const o = this.consumerTracker.getConsumerInfo(
1878
- this.componentRef.current
1879
- );
1880
- if (o && o.hasRendered && !this.consumerTracker.hasValuesChanged(
1881
- this.componentRef.current,
1882
- s,
1883
- this.blocInstance
1884
- ))
1885
- return;
1886
- } else {
1887
- e.onChange();
1888
- return;
1889
- }
1890
- e.onChange();
1891
- }
1892
- }));
1893
- i(this, "mount", () => {
1894
- var e, t;
1895
- if (this.isUsingDependencies && ((e = this.options) != null && e.dependencies) && (this.dependencyValues = this.options.dependencies(this.blocInstance)), this.mountCount++, this.blocInstance._addConsumer(this.id, this.componentRef.current), !this.hasMounted && (this.hasMounted = !0, this.mountTime = Date.now(), (t = this.options) != null && t.onMount))
1896
- try {
1897
- this.options.onMount(this.blocInstance);
1898
- } catch (s) {
1899
- throw s;
1900
- }
1901
- });
1902
- i(this, "unmount", () => {
1903
- var e;
1904
- if (this.unmountTime = Date.now(), this.consumerTracker.unregister(this.componentRef.current), this.blocInstance._removeConsumer(this.id), b.propsOwners.get(this.blocInstance) === this.id && b.propsOwners.delete(this.blocInstance), (e = this.options) != null && e.onUnmount)
1905
- try {
1906
- this.options.onUnmount(this.blocInstance);
1907
- } catch {
1908
- }
1909
- });
1910
- i(this, "getProxyState", (e) => this.isUsingDependencies || !u.config.proxyDependencyTracking ? e : I.getProxyState({
1911
- state: e,
1912
- consumerRef: this.componentRef.current,
1913
- consumerTracker: this
1914
- }));
1915
- i(this, "getProxyBlocInstance", () => this.isUsingDependencies || !u.config.proxyDependencyTracking ? this.blocInstance : I.getProxyBlocInstance({
1916
- blocInstance: this.blocInstance,
1917
- consumerRef: this.componentRef.current,
1918
- consumerTracker: this
1919
- }));
1920
- this.options = t, this.blocConstructor = e.blocConstructor, this.componentRef = e.componentRef, this.isUsingDependencies = !!(t != null && t.dependencies), this.consumerTracker = new K(), this.blocInstance = this.updateBlocInstance(), this.consumerTracker.register(e.componentRef.current, this.id), this.isUsingDependencies && (t != null && t.dependencies) && (this.dependencyValues = t.dependencies(this.blocInstance)), (t == null ? void 0 : t.props) !== void 0 && this.updateProps(t.props);
1921
- }
1922
- trackAccess(e, t, s, r) {
1923
- this.consumerTracker.trackAccess(e, t, s, r);
1924
- }
1925
- getConsumerDependencies(e) {
1926
- return this.consumerTracker.getDependencies(e);
1927
- }
1928
- shouldNotifyConsumer(e, t) {
1929
- const s = this.consumerTracker.getConsumerInfo(e);
1930
- return !s || !s.hasRendered ? !0 : this.consumerTracker.shouldNotifyConsumer(e, t);
1931
- }
1932
- updateLastNotified(e) {
1933
- this.consumerTracker.updateLastNotified(e), this.consumerTracker.setHasRendered(e, !0);
1934
- }
1935
- resetConsumerTracking() {
1936
- this.consumerTracker.resetTracking(this.componentRef.current);
1937
- }
1938
- updateBlocInstance() {
1939
- var e, t;
1940
- return this.blocInstance = u.instance.getBloc(this.blocConstructor, {
1941
- props: (e = this.options) == null ? void 0 : e.props,
1942
- id: (t = this.options) == null ? void 0 : t.id,
1943
- instanceRef: this.id
1944
- }), this.blocInstance;
1945
- }
1946
- // Expose calledOnMount for backward compatibility
1947
- get calledOnMount() {
1948
- return this.hasMounted;
1949
- }
1950
- updateProps(e) {
1951
- const t = this.blocInstance;
1952
- if (b.propsOwners.has(t) || b.propsOwners.set(t, this.id), b.propsOwners.get(t) !== this.id) {
1953
- u.warn(
1954
- `[BlacAdapter] Attempted to set props on ${t.constructor.name} from non-owner adapter`
1955
- );
1956
- return;
1957
- }
1958
- t._disposalState === y.DISPOSED || t._disposalState === y.DISPOSING || N(this.lastProps, e) || ("add" in t && typeof t.add == "function" ? t.add(new L(e)) : "_updateProps" in t && typeof t._updateProps == "function" && t._updateProps(e), this.lastProps = e);
1959
- }
1960
- hasDependencyValuesChanged(e, t) {
1961
- if (!e || e.length !== t.length) return !0;
1962
- for (let s = 0; s < e.length; s++)
1963
- if (!Object.is(e[s], t[s]))
1964
- return !0;
1965
- return !1;
1966
- }
1967
- };
1968
- // Props ownership tracking
1969
- i(b, "propsOwners", /* @__PURE__ */ new WeakMap());
1970
- let D = b;
1971
- export {
1972
- u as Blac,
1973
- D as BlacAdapter,
1974
- H as BlacObservable,
1975
- j as Bloc,
1976
- k as BlocBase,
1977
- y as BlocLifecycleState,
1978
- V as BlocPluginRegistry,
1979
- q as BlocTest,
1980
- K as ConsumerTracker,
1981
- z as Cubit,
1982
- J as MemoryLeakDetector,
1983
- F as MockBloc,
1984
- G as MockCubit,
1985
- L as PropsUpdated,
1986
- I as ProxyFactory,
1987
- U as SystemPluginRegistry,
1988
- $ as generateUUID,
1989
- W as setBlacInstanceManager,
1990
- N as shallowEqual
1991
- };
1992
- //# sourceMappingURL=index.es.js.map