@blac/core 2.0.0-rc-13 → 2.0.0-rc-14
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/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +522 -297
- package/dist/index.es.js +1833 -1550
- package/dist/index.es.js.map +1 -1
- package/package.json +6 -7
- package/src/Blac.ts +38 -71
- package/src/Bloc.ts +8 -9
- package/src/BlocBase.ts +246 -540
- package/src/Cubit.ts +1 -16
- package/src/__tests__/Blac.config.test.ts +10 -17
- package/src/__tests__/Bloc.event.test.ts +27 -52
- package/src/__tests__/BlocBase.subscription.test.ts +349 -0
- package/src/__tests__/Cubit.test.ts +39 -50
- package/src/__tests__/memory-leaks.test.ts +383 -0
- package/src/__tests__/plugins.test.ts +107 -97
- package/src/adapter/BlacAdapter.ts +347 -207
- package/src/adapter/ProxyFactory.ts +196 -255
- package/src/adapter/__tests__/BlacAdapter.test.ts +71 -77
- package/src/adapter/__tests__/ProxyFactory.test.ts +1 -1
- package/src/adapter/index.ts +0 -1
- package/src/errors/BlacError.ts +69 -0
- package/src/errors/ErrorManager.ts +101 -0
- package/src/errors/handleError.ts +114 -0
- package/src/errors/index.ts +13 -0
- package/src/events.ts +7 -1
- package/src/index.ts +7 -1
- package/src/lifecycle/BlocLifecycle.ts +156 -0
- package/src/lifecycle/index.ts +1 -0
- package/src/plugins/BlocPluginRegistry.ts +71 -51
- package/src/plugins/SystemPluginRegistry.ts +63 -13
- package/src/plugins/__tests__/BlocPluginRegistry.test.ts +450 -0
- package/src/plugins/__tests__/SystemPluginRegistry.test.ts +404 -0
- package/src/plugins/types.ts +32 -3
- package/src/subscription/README.md +132 -0
- package/src/subscription/SubscriptionManager.ts +395 -0
- package/src/subscription/__tests__/SubscriptionManager.test.ts +355 -0
- package/src/subscription/index.ts +2 -0
- package/src/subscription/types.ts +90 -0
- package/src/testing.ts +31 -37
- package/src/types.ts +4 -21
- package/src/utils/BatchingManager.ts +59 -0
- package/src/utils/RerenderLogger.ts +265 -0
- package/src/utils/__tests__/generateInstanceId.test.ts +104 -0
- package/src/utils/__tests__/shallowEqual.test.ts +171 -0
- package/src/utils/__tests__/uuid.test.ts +144 -0
- package/src/utils/generateInstanceId.ts +54 -0
- package/src/utils/shallowEqual.ts +1 -1
- package/README.md +0 -329
- package/src/BlacObserver.ts +0 -189
- package/src/__tests__/BlocBase.lifecycle.test.ts +0 -441
- package/src/__tests__/props.test.ts +0 -256
- package/src/adapter/ConsumerTracker.ts +0 -241
- package/src/adapter/__tests__/ConsumerTracker.test.ts +0 -562
package/dist/index.es.js
CHANGED
|
@@ -1,141 +1,107 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
i(this, "_observers", /* @__PURE__ */ new Set());
|
|
13
|
-
this.bloc = e;
|
|
1
|
+
var u = /* @__PURE__ */ ((r) => (r.ACTIVE = "active", r.DISPOSAL_REQUESTED = "disposal_requested", r.DISPOSING = "disposing", r.DISPOSED = "disposed", r))(u || {});
|
|
2
|
+
class B {
|
|
3
|
+
disposalState = "active";
|
|
4
|
+
disposalLock = !1;
|
|
5
|
+
disposalTimer;
|
|
6
|
+
disposalHandler;
|
|
7
|
+
get currentState() {
|
|
8
|
+
return this.disposalState;
|
|
9
|
+
}
|
|
10
|
+
get isDisposed() {
|
|
11
|
+
return this.disposalState === "disposed";
|
|
14
12
|
}
|
|
15
13
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @returns The number of observers currently subscribed
|
|
14
|
+
* Atomic state transition for disposal
|
|
18
15
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
atomicStateTransition(e, t) {
|
|
17
|
+
if (this.disposalLock)
|
|
18
|
+
return {
|
|
19
|
+
success: !1,
|
|
20
|
+
currentState: this.disposalState,
|
|
21
|
+
previousState: this.disposalState
|
|
22
|
+
};
|
|
23
|
+
this.disposalLock = !0;
|
|
24
|
+
try {
|
|
25
|
+
if (this.disposalState !== e)
|
|
26
|
+
return {
|
|
27
|
+
success: !1,
|
|
28
|
+
currentState: this.disposalState,
|
|
29
|
+
previousState: this.disposalState
|
|
30
|
+
};
|
|
31
|
+
const s = this.disposalState;
|
|
32
|
+
return this.disposalState = t, {
|
|
33
|
+
success: !0,
|
|
34
|
+
currentState: t,
|
|
35
|
+
previousState: s
|
|
36
|
+
};
|
|
37
|
+
} finally {
|
|
38
|
+
this.disposalLock = !1;
|
|
39
|
+
}
|
|
21
40
|
}
|
|
22
41
|
/**
|
|
23
|
-
*
|
|
24
|
-
* @returns The Set of all BlacObserver instances
|
|
42
|
+
* Schedule disposal after a delay
|
|
25
43
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
44
|
+
scheduleDisposal(e, t, s) {
|
|
45
|
+
this.disposalTimer && (clearTimeout(this.disposalTimer), this.disposalTimer = void 0), this.atomicStateTransition(
|
|
46
|
+
"active",
|
|
47
|
+
"disposal_requested"
|
|
48
|
+
/* DISPOSAL_REQUESTED */
|
|
49
|
+
).success && (this.disposalTimer = setTimeout(() => {
|
|
50
|
+
t() && this.disposalState === "disposal_requested" ? s() : this.atomicStateTransition(
|
|
51
|
+
"disposal_requested",
|
|
52
|
+
"active"
|
|
53
|
+
/* ACTIVE */
|
|
54
|
+
);
|
|
55
|
+
}, e));
|
|
28
56
|
}
|
|
29
57
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param observer - The observer to subscribe
|
|
32
|
-
* @returns A function that can be called to unsubscribe the observer
|
|
58
|
+
* Cancel disposal if in disposal requested state
|
|
33
59
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
});
|
|
60
|
+
cancelDisposal() {
|
|
61
|
+
return this.disposalState === "disposal_requested" ? (this.disposalTimer && (clearTimeout(this.disposalTimer), this.disposalTimer = void 0), this.atomicStateTransition(
|
|
62
|
+
"disposal_requested",
|
|
63
|
+
"active"
|
|
64
|
+
/* ACTIVE */
|
|
65
|
+
).success) : !1;
|
|
58
66
|
}
|
|
59
67
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @param observer - The observer to unsubscribe
|
|
68
|
+
* Set disposal handler
|
|
62
69
|
*/
|
|
63
|
-
|
|
64
|
-
this.
|
|
65
|
-
`[${this.bloc._name}:${this.bloc._id}] No observers or consumers left. Scheduling disposal.`
|
|
66
|
-
), this.bloc._scheduleDisposal()));
|
|
70
|
+
setDisposalHandler(e) {
|
|
71
|
+
this.disposalHandler = e;
|
|
67
72
|
}
|
|
68
73
|
/**
|
|
69
|
-
*
|
|
70
|
-
* @param newState - The new state value
|
|
71
|
-
* @param oldState - The previous state value
|
|
72
|
-
* @param action - Optional action that triggered the state change
|
|
74
|
+
* Get disposal handler
|
|
73
75
|
*/
|
|
74
|
-
|
|
75
|
-
this.
|
|
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);
|
|
76
|
+
getDisposalHandler() {
|
|
77
|
+
return this.disposalHandler;
|
|
98
78
|
}
|
|
99
79
|
/**
|
|
100
|
-
*
|
|
80
|
+
* Clear disposal timer
|
|
101
81
|
*/
|
|
102
|
-
|
|
103
|
-
this.
|
|
82
|
+
clearDisposalTimer() {
|
|
83
|
+
this.disposalTimer && (clearTimeout(this.disposalTimer), this.disposalTimer = void 0);
|
|
104
84
|
}
|
|
105
85
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
class V {
|
|
113
|
-
constructor() {
|
|
114
|
-
i(this, "plugins", /* @__PURE__ */ new Map());
|
|
115
|
-
i(this, "executionOrder", []);
|
|
116
|
-
i(this, "attached", !1);
|
|
117
|
-
}
|
|
86
|
+
class T {
|
|
87
|
+
plugins = /* @__PURE__ */ new Map();
|
|
88
|
+
metrics = /* @__PURE__ */ new Map();
|
|
89
|
+
executionOrder = [];
|
|
118
90
|
/**
|
|
119
|
-
* Add a
|
|
91
|
+
* Add a system plugin
|
|
120
92
|
*/
|
|
121
93
|
add(e) {
|
|
122
94
|
if (this.plugins.has(e.name))
|
|
123
95
|
throw new Error(`Plugin '${e.name}' is already registered`);
|
|
124
|
-
|
|
96
|
+
this.plugins.set(e.name, e), this.executionOrder.push(e.name), this.initializeMetrics(e.name);
|
|
125
97
|
}
|
|
126
98
|
/**
|
|
127
|
-
* Remove a
|
|
99
|
+
* Remove a system plugin
|
|
128
100
|
*/
|
|
129
101
|
remove(e) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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;
|
|
102
|
+
return this.plugins.get(e) ? (this.plugins.delete(e), this.metrics.delete(e), this.executionOrder = this.executionOrder.filter(
|
|
103
|
+
(s) => s !== e
|
|
104
|
+
), !0) : !1;
|
|
139
105
|
}
|
|
140
106
|
/**
|
|
141
107
|
* Get a plugin by name
|
|
@@ -153,1111 +119,1353 @@ class V {
|
|
|
153
119
|
* Clear all plugins
|
|
154
120
|
*/
|
|
155
121
|
clear() {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
122
|
+
this.plugins.clear(), this.metrics.clear(), this.executionOrder = [];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Execute a hook on all plugins
|
|
126
|
+
*/
|
|
127
|
+
executeHook(e, t, s) {
|
|
128
|
+
for (const i of this.executionOrder) {
|
|
129
|
+
const n = this.plugins.get(i), a = n[e];
|
|
130
|
+
if (typeof a != "function") continue;
|
|
131
|
+
const c = performance.now();
|
|
132
|
+
try {
|
|
133
|
+
a.apply(n, t), this.recordSuccess(i, e, c);
|
|
134
|
+
} catch (l) {
|
|
135
|
+
this.recordError(i, e, l), s ? s(l, n) : console.error(
|
|
136
|
+
`Plugin '${i}' error in hook '${e}':`,
|
|
137
|
+
l
|
|
138
|
+
);
|
|
139
|
+
}
|
|
164
140
|
}
|
|
165
|
-
this.plugins.clear(), this.executionOrder = [], this.attached = !1;
|
|
166
141
|
}
|
|
167
142
|
/**
|
|
168
|
-
*
|
|
143
|
+
* Bootstrap all plugins
|
|
169
144
|
*/
|
|
170
|
-
|
|
171
|
-
|
|
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;
|
|
145
|
+
bootstrap() {
|
|
146
|
+
this.executeHook("beforeBootstrap", []), this.executeHook("afterBootstrap", []);
|
|
181
147
|
}
|
|
182
148
|
/**
|
|
183
|
-
*
|
|
149
|
+
* Shutdown all plugins
|
|
184
150
|
*/
|
|
185
|
-
|
|
186
|
-
|
|
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;
|
|
151
|
+
shutdown() {
|
|
152
|
+
this.executeHook("beforeShutdown", []), this.executeHook("afterShutdown", []);
|
|
195
153
|
}
|
|
196
154
|
/**
|
|
197
|
-
*
|
|
155
|
+
* Notify plugins of bloc creation
|
|
198
156
|
*/
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
console.error(`Plugin '${s.name}' error in transformEvent:`, r);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return t;
|
|
157
|
+
notifyBlocCreated(e) {
|
|
158
|
+
this.executeHook("onBlocCreated", [e]);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Notify plugins of bloc disposal
|
|
162
|
+
*/
|
|
163
|
+
notifyBlocDisposed(e) {
|
|
164
|
+
this.executeHook("onBlocDisposed", [e]);
|
|
211
165
|
}
|
|
212
166
|
/**
|
|
213
167
|
* Notify plugins of state change
|
|
214
168
|
*/
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
}
|
|
169
|
+
notifyStateChanged(e, t, s) {
|
|
170
|
+
this.executeHook("onStateChanged", [e, t, s]);
|
|
223
171
|
}
|
|
224
172
|
/**
|
|
225
|
-
* Notify plugins of event
|
|
173
|
+
* Notify plugins of event addition
|
|
226
174
|
*/
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
}
|
|
175
|
+
notifyEventAdded(e, t) {
|
|
176
|
+
this.executeHook("onEventAdded", [e, t]);
|
|
235
177
|
}
|
|
236
178
|
/**
|
|
237
|
-
* Notify plugins of
|
|
179
|
+
* Notify plugins of errors
|
|
238
180
|
*/
|
|
239
|
-
notifyError(e, t) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
s.onError(e, t);
|
|
244
|
-
} catch (r) {
|
|
245
|
-
console.error(`Plugin '${s.name}' error in onError:`, r);
|
|
246
|
-
}
|
|
181
|
+
notifyError(e, t, s) {
|
|
182
|
+
this.executeHook("onError", [e, t, s], (i, n) => {
|
|
183
|
+
console.error(`Plugin '${n.name}' error handler failed:`, i);
|
|
184
|
+
});
|
|
247
185
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
throw new Error(`Plugin '${e.name}': interceptEvents requires readState capability`);
|
|
186
|
+
/**
|
|
187
|
+
* Notify plugins of adapter lifecycle events
|
|
188
|
+
*/
|
|
189
|
+
notifyAdapterCreated(e, t) {
|
|
190
|
+
this.executeHook("onAdapterCreated", [e, t]);
|
|
254
191
|
}
|
|
255
|
-
|
|
256
|
-
|
|
192
|
+
notifyAdapterMount(e, t) {
|
|
193
|
+
this.executeHook("onAdapterMount", [e, t]);
|
|
257
194
|
}
|
|
258
|
-
|
|
259
|
-
|
|
195
|
+
notifyAdapterUnmount(e, t) {
|
|
196
|
+
this.executeHook("onAdapterUnmount", [e, t]);
|
|
260
197
|
}
|
|
261
|
-
|
|
262
|
-
|
|
198
|
+
notifyAdapterRender(e, t) {
|
|
199
|
+
this.executeHook("onAdapterRender", [e, t]);
|
|
200
|
+
}
|
|
201
|
+
notifyAdapterDisposed(e, t) {
|
|
202
|
+
this.executeHook("onAdapterDisposed", [e, t]);
|
|
263
203
|
}
|
|
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
204
|
/**
|
|
268
|
-
*
|
|
269
|
-
* Sets up the observer, registers with the Blac manager, and initializes addons.
|
|
270
|
-
*
|
|
271
|
-
* @param initialState The initial state value for this Bloc
|
|
205
|
+
* Get metrics for a plugin
|
|
272
206
|
*/
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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();
|
|
207
|
+
getMetrics(e) {
|
|
208
|
+
return this.metrics.get(e);
|
|
209
|
+
}
|
|
210
|
+
initializeMetrics(e) {
|
|
211
|
+
this.metrics.set(e, /* @__PURE__ */ new Map());
|
|
212
|
+
}
|
|
213
|
+
recordSuccess(e, t, s) {
|
|
214
|
+
const i = this.metrics.get(e), n = i.get(t) || {
|
|
215
|
+
executionTime: 0,
|
|
216
|
+
executionCount: 0,
|
|
217
|
+
errorCount: 0
|
|
218
|
+
}, a = performance.now() - s;
|
|
219
|
+
i.set(t, {
|
|
220
|
+
...n,
|
|
221
|
+
executionTime: n.executionTime + a,
|
|
222
|
+
executionCount: n.executionCount + 1,
|
|
223
|
+
lastExecutionTime: a
|
|
459
224
|
});
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
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
|
-
}
|
|
225
|
+
}
|
|
226
|
+
recordError(e, t, s) {
|
|
227
|
+
const i = this.metrics.get(e), n = i.get(t) || {
|
|
228
|
+
executionTime: 0,
|
|
229
|
+
executionCount: 0,
|
|
230
|
+
errorCount: 0
|
|
231
|
+
};
|
|
232
|
+
i.set(t, {
|
|
233
|
+
...n,
|
|
234
|
+
errorCount: n.errorCount + 1,
|
|
235
|
+
lastError: s
|
|
482
236
|
});
|
|
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
237
|
}
|
|
489
|
-
|
|
490
|
-
|
|
238
|
+
}
|
|
239
|
+
var v = /* @__PURE__ */ ((r) => (r.LIFECYCLE = "LIFECYCLE", r.STATE = "STATE", r.PLUGIN = "PLUGIN", r.VALIDATION = "VALIDATION", r.DISPOSAL = "DISPOSAL", r.CONSUMER = "CONSUMER", r))(v || {}), y = /* @__PURE__ */ ((r) => (r.FATAL = "FATAL", r.ERROR = "ERROR", r.WARNING = "WARNING", r.INFO = "INFO", r))(y || {});
|
|
240
|
+
class m extends Error {
|
|
241
|
+
constructor(e, t, s, i, n) {
|
|
242
|
+
super(e), this.category = t, this.severity = s, this.context = i, this.cause = n, this.name = "BlacError", Object.setPrototypeOf(this, m.prototype);
|
|
491
243
|
}
|
|
492
|
-
|
|
493
|
-
|
|
244
|
+
toString() {
|
|
245
|
+
const e = this.context ? ` [${Object.entries(this.context).filter(([t, s]) => s !== void 0).map(([t, s]) => `${t}: ${s}`).join(", ")}]` : "";
|
|
246
|
+
return `${this.name} [${this.severity}/${this.category}]: ${this.message}${e}`;
|
|
494
247
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
return this._disposalState === "disposed" ? this._state : this._state;
|
|
248
|
+
}
|
|
249
|
+
const P = {
|
|
250
|
+
shouldPropagate: (r) => r.severity === "FATAL",
|
|
251
|
+
shouldLog: (r) => r.severity !== "INFO",
|
|
252
|
+
handle: (r) => {
|
|
253
|
+
P.shouldLog(r) && console.error(r.toString(), r.cause);
|
|
502
254
|
}
|
|
255
|
+
};
|
|
256
|
+
class f {
|
|
257
|
+
static instance;
|
|
258
|
+
handlers = /* @__PURE__ */ new Set();
|
|
259
|
+
strategy = P;
|
|
503
260
|
/**
|
|
504
|
-
*
|
|
505
|
-
* @returns true if the bloc is in DISPOSED state
|
|
261
|
+
* Get the singleton instance of ErrorManager
|
|
506
262
|
*/
|
|
507
|
-
|
|
508
|
-
return
|
|
263
|
+
static getInstance() {
|
|
264
|
+
return f.instance || (f.instance = new f()), f.instance;
|
|
509
265
|
}
|
|
510
266
|
/**
|
|
511
|
-
*
|
|
512
|
-
* Returns the name of the Bloc class for identification and debugging.
|
|
267
|
+
* Set a custom error handling strategy
|
|
513
268
|
*/
|
|
514
|
-
|
|
515
|
-
|
|
269
|
+
setStrategy(e) {
|
|
270
|
+
this.strategy = e;
|
|
516
271
|
}
|
|
517
272
|
/**
|
|
518
|
-
*
|
|
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
|
|
273
|
+
* Add a custom error handler that will be called for all errors
|
|
523
274
|
*/
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
};
|
|
275
|
+
addHandler(e) {
|
|
276
|
+
this.handlers.add(e);
|
|
543
277
|
}
|
|
544
278
|
/**
|
|
545
|
-
*
|
|
546
|
-
* Cleans up resources and removes this Bloc from the system.
|
|
547
|
-
* Notifies the Blac manager and clears all observers.
|
|
279
|
+
* Remove a previously added error handler
|
|
548
280
|
*/
|
|
549
|
-
|
|
550
|
-
|
|
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
|
-
}
|
|
281
|
+
removeHandler(e) {
|
|
282
|
+
this.handlers.delete(e);
|
|
571
283
|
}
|
|
572
284
|
/**
|
|
573
|
-
*
|
|
574
|
-
* Sets the disposal handler for this bloc
|
|
285
|
+
* Process an error through all handlers and apply the configured strategy
|
|
575
286
|
*/
|
|
576
|
-
|
|
577
|
-
this.
|
|
287
|
+
handle(e) {
|
|
288
|
+
if (this.handlers.forEach((t) => {
|
|
289
|
+
try {
|
|
290
|
+
t(e);
|
|
291
|
+
} catch (s) {
|
|
292
|
+
console.error("Error in error handler:", s);
|
|
293
|
+
}
|
|
294
|
+
}), this.strategy.handle(e), this.strategy.shouldPropagate(e))
|
|
295
|
+
throw e;
|
|
578
296
|
}
|
|
579
297
|
/**
|
|
580
|
-
*
|
|
581
|
-
* Schedules disposal of this bloc instance if it has no consumers
|
|
582
|
-
* Uses atomic state transitions to prevent race conditions
|
|
298
|
+
* Convenience method for wrapping operations with error handling
|
|
583
299
|
*/
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
return;
|
|
591
|
-
if (!(this._consumers.size === 0 && !this._keepAlive)) {
|
|
592
|
-
this._atomicStateTransition(
|
|
593
|
-
"disposal_requested",
|
|
594
|
-
"active"
|
|
595
|
-
/* ACTIVE */
|
|
596
|
-
);
|
|
300
|
+
wrap(e, t) {
|
|
301
|
+
try {
|
|
302
|
+
return e();
|
|
303
|
+
} catch (s) {
|
|
304
|
+
const i = t(s);
|
|
305
|
+
this.handle(i);
|
|
597
306
|
return;
|
|
598
307
|
}
|
|
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
308
|
}
|
|
607
309
|
/**
|
|
608
|
-
*
|
|
609
|
-
* @internal Used by plugins for state hydration
|
|
610
|
-
* @param newState The new state
|
|
611
|
-
* @param oldState The old state
|
|
310
|
+
* Async version of wrap
|
|
612
311
|
*/
|
|
613
|
-
|
|
614
|
-
|
|
312
|
+
async wrapAsync(e, t) {
|
|
313
|
+
try {
|
|
314
|
+
return await e();
|
|
315
|
+
} catch (s) {
|
|
316
|
+
const i = t(s);
|
|
317
|
+
this.handle(i);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
615
320
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
321
|
+
}
|
|
322
|
+
class g {
|
|
323
|
+
static _instance;
|
|
324
|
+
getInstance() {
|
|
325
|
+
return g._instance || (g._instance = new o({
|
|
326
|
+
__unsafe_ignore_singleton: !0
|
|
327
|
+
})), g._instance;
|
|
328
|
+
}
|
|
329
|
+
setInstance(e) {
|
|
330
|
+
g._instance = e;
|
|
331
|
+
}
|
|
332
|
+
resetInstance() {
|
|
333
|
+
const e = g._instance;
|
|
334
|
+
if (g._instance = new o({
|
|
335
|
+
__unsafe_ignore_singleton: !0
|
|
336
|
+
}), e)
|
|
337
|
+
for (const t of e.keepAliveBlocs)
|
|
338
|
+
g._instance.keepAliveBlocs.add(t), g._instance.uidRegistry.set(t.uid, t);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
let b = new g();
|
|
342
|
+
function H(r) {
|
|
343
|
+
b = r;
|
|
344
|
+
}
|
|
345
|
+
class o {
|
|
346
|
+
static get instance() {
|
|
347
|
+
return b.getInstance();
|
|
348
|
+
}
|
|
349
|
+
/** Timestamp when the instance was created */
|
|
350
|
+
createdAt = Date.now();
|
|
351
|
+
errorManager = f.getInstance();
|
|
352
|
+
static get getAllBlocs() {
|
|
353
|
+
return o.instance.getAllBlocs;
|
|
354
|
+
}
|
|
355
|
+
/** Private static configuration */
|
|
356
|
+
static _config = {
|
|
357
|
+
proxyDependencyTracking: !0
|
|
358
|
+
};
|
|
359
|
+
/** Get current configuration */
|
|
360
|
+
static get config() {
|
|
361
|
+
return { ...this._config };
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Set or update Blac configuration
|
|
365
|
+
* @param config - Partial configuration to merge with existing config
|
|
366
|
+
* @throws Error if configuration is invalid
|
|
367
|
+
*/
|
|
368
|
+
static setConfig(e) {
|
|
369
|
+
if (e.proxyDependencyTracking !== void 0 && typeof e.proxyDependencyTracking != "boolean") {
|
|
370
|
+
const t = new m(
|
|
371
|
+
"BlacConfig.proxyDependencyTracking must be a boolean",
|
|
372
|
+
v.VALIDATION,
|
|
373
|
+
y.FATAL
|
|
374
|
+
);
|
|
375
|
+
this.instance.errorManager.handle(t);
|
|
376
|
+
}
|
|
377
|
+
this._config = {
|
|
378
|
+
...this._config,
|
|
379
|
+
...e
|
|
380
|
+
}, this.enableLog && this.instance.log("Blac config updated:", this._config);
|
|
381
|
+
}
|
|
382
|
+
/** Map storing all registered bloc instances by their class name and ID */
|
|
383
|
+
blocInstanceMap = /* @__PURE__ */ new Map();
|
|
384
|
+
/** Map storing isolated bloc instances grouped by their constructor */
|
|
385
|
+
// Using BlocConstructor<BlocBase<unknown>> would break type inference when storing
|
|
386
|
+
// different bloc types in the same map. The 'any' allows proper polymorphic storage
|
|
387
|
+
// while maintaining type safety at usage sites through the BlocConstructor constraint.
|
|
388
|
+
isolatedBlocMap = /* @__PURE__ */ new Map();
|
|
389
|
+
/** Map for O(1) lookup of isolated blocs by UID */
|
|
390
|
+
isolatedBlocIndex = /* @__PURE__ */ new Map();
|
|
391
|
+
/** Map tracking UIDs to prevent memory leaks */
|
|
392
|
+
uidRegistry = /* @__PURE__ */ new Map();
|
|
393
|
+
/** Set of keep-alive blocs for controlled cleanup */
|
|
394
|
+
keepAliveBlocs = /* @__PURE__ */ new Set();
|
|
395
|
+
/** Flag to control whether changes should be posted to document */
|
|
396
|
+
postChangesToDocument = !1;
|
|
397
|
+
/** System plugin registry */
|
|
398
|
+
plugins = new T();
|
|
399
|
+
/**
|
|
400
|
+
* Creates a new Blac instance.
|
|
401
|
+
* @param options - Configuration options including singleton control
|
|
402
|
+
*/
|
|
403
|
+
constructor(e = {}) {
|
|
404
|
+
const { __unsafe_ignore_singleton: t = !1 } = e;
|
|
405
|
+
if (!t)
|
|
406
|
+
return o.instance;
|
|
407
|
+
b.setInstance(this), this.plugins.bootstrap();
|
|
408
|
+
}
|
|
409
|
+
/** Flag to enable/disable logging */
|
|
410
|
+
static enableLog = !1;
|
|
411
|
+
static logLevel = "warn";
|
|
412
|
+
static logSpy = null;
|
|
413
|
+
/**
|
|
414
|
+
* Logs messages to console when logging is enabled
|
|
415
|
+
* @param args - Arguments to log
|
|
416
|
+
*/
|
|
417
|
+
log = (...e) => {
|
|
418
|
+
o.logSpy && o.logSpy(e), o.enableLog && o.logLevel, o.enableLog && o.logLevel;
|
|
419
|
+
};
|
|
420
|
+
static get log() {
|
|
421
|
+
return o.instance.log;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Gets the current Blac instance
|
|
425
|
+
* @returns The Blac instance
|
|
426
|
+
*/
|
|
427
|
+
static getInstance() {
|
|
428
|
+
return b.getInstance();
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Logs a warning message
|
|
432
|
+
* @param message - Warning message
|
|
433
|
+
* @param args - Additional arguments
|
|
434
|
+
*/
|
|
435
|
+
warn = (e, ...t) => {
|
|
436
|
+
console.warn(e, ...t);
|
|
437
|
+
};
|
|
438
|
+
static get warn() {
|
|
439
|
+
return o.instance.warn;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Logs an error message
|
|
443
|
+
* @param message - Error message
|
|
444
|
+
* @param args - Additional arguments
|
|
445
|
+
*/
|
|
446
|
+
error = (e, ...t) => {
|
|
447
|
+
o.enableLog && console.error(e, ...t);
|
|
448
|
+
};
|
|
449
|
+
static get error() {
|
|
450
|
+
return o.instance.error;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Resets the Blac instance to a new one, disposing non-keepAlive blocs
|
|
454
|
+
* from the old instance.
|
|
455
|
+
*/
|
|
456
|
+
resetInstance = () => {
|
|
457
|
+
this.log("Reset Blac instance");
|
|
458
|
+
const e = new Map(this.blocInstanceMap), t = new Map(this.isolatedBlocMap);
|
|
459
|
+
e.forEach((s) => {
|
|
460
|
+
!s._keepAlive && s._disposalState === u.ACTIVE && this.disposeBloc(s);
|
|
461
|
+
}), t.forEach((s) => {
|
|
462
|
+
s.forEach((i) => {
|
|
463
|
+
!i._keepAlive && i._disposalState === u.ACTIVE && this.disposeBloc(i);
|
|
464
|
+
});
|
|
465
|
+
}), this.blocInstanceMap.clear(), this.isolatedBlocMap.clear(), this.isolatedBlocIndex.clear(), b.resetInstance();
|
|
466
|
+
};
|
|
467
|
+
static resetInstance = () => {
|
|
468
|
+
b.resetInstance();
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* Disposes of a bloc instance by removing it from the appropriate registry
|
|
472
|
+
* @param bloc - The bloc instance to dispose
|
|
473
|
+
*/
|
|
474
|
+
disposeBloc = (e) => {
|
|
475
|
+
const t = e._disposalState;
|
|
476
|
+
if (![
|
|
477
|
+
u.ACTIVE,
|
|
478
|
+
u.DISPOSAL_REQUESTED
|
|
479
|
+
].includes(t)) {
|
|
480
|
+
this.log(
|
|
481
|
+
`[${e._name}:${String(e._id)}] disposeBloc called on bloc in invalid state: ${t}`
|
|
482
|
+
);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const i = e.constructor, n = this.createBlocInstanceMapKey(e._name, e._id);
|
|
486
|
+
this.log(
|
|
487
|
+
`[${e._name}:${String(e._id)}] disposeBloc called. Isolated: ${String(i.isolated)}`
|
|
488
|
+
), e.dispose(), this.plugins.notifyBlocDisposed(e), i.isolated ? (this.unregisterIsolatedBlocInstance(e), this.blocInstanceMap.delete(n)) : this.unregisterBlocInstance(e), this.log("dispatched bloc", e);
|
|
489
|
+
};
|
|
490
|
+
static get disposeBloc() {
|
|
491
|
+
return o.instance.disposeBloc;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Creates a unique key for a bloc instance in the map based on the bloc class name and instance ID
|
|
495
|
+
* @param blocClassName - The name of the bloc class
|
|
496
|
+
* @param id - The instance ID
|
|
497
|
+
* @returns A unique key string in the format "className:id"
|
|
498
|
+
*/
|
|
499
|
+
createBlocInstanceMapKey(e, t) {
|
|
500
|
+
return `${e}:${String(t)}`;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Unregister a bloc instance from the main registry
|
|
504
|
+
* @param bloc - The bloc instance to unregister
|
|
505
|
+
*/
|
|
506
|
+
unregisterBlocInstance(e) {
|
|
507
|
+
const t = this.createBlocInstanceMapKey(e._name, e._id);
|
|
508
|
+
this.blocInstanceMap.delete(t), this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Registers a bloc instance in the main registry
|
|
512
|
+
* @param bloc - The bloc instance to register
|
|
513
|
+
*/
|
|
514
|
+
registerBlocInstance(e) {
|
|
515
|
+
const t = this.createBlocInstanceMapKey(e._name, e._id);
|
|
516
|
+
this.blocInstanceMap.set(t, e), this.uidRegistry.set(e.uid, e), e._keepAlive && this.keepAliveBlocs.add(e);
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Finds a registered bloc instance by its class and ID
|
|
520
|
+
* @param blocClass - The bloc class to search for
|
|
521
|
+
* @param id - The instance ID
|
|
522
|
+
* @returns The found bloc instance or undefined if not found
|
|
523
|
+
*/
|
|
524
|
+
findRegisteredBlocInstance(e, t) {
|
|
525
|
+
if (e.isolated) return;
|
|
526
|
+
const i = this.createBlocInstanceMapKey(e.name, t), n = this.blocInstanceMap.get(i);
|
|
527
|
+
if (!(n && n.isDisposed))
|
|
528
|
+
return n;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Registers an isolated bloc instance in the isolated registry
|
|
532
|
+
* @param bloc - The isolated bloc instance to register
|
|
533
|
+
*/
|
|
534
|
+
registerIsolatedBlocInstance(e) {
|
|
535
|
+
const t = e.constructor, s = this.isolatedBlocMap.get(t);
|
|
536
|
+
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);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Unregister an isolated bloc instance from the isolated registry
|
|
540
|
+
* @param bloc - The isolated bloc instance to unregister
|
|
541
|
+
*/
|
|
542
|
+
unregisterIsolatedBlocInstance(e) {
|
|
543
|
+
const t = e.constructor, s = this.isolatedBlocMap.get(t);
|
|
544
|
+
let i = !1;
|
|
545
|
+
if (s) {
|
|
546
|
+
const a = s.findIndex((c) => c.uid === e.uid);
|
|
547
|
+
a !== -1 && (s.splice(a, 1), i = !0), s.length === 0 && this.isolatedBlocMap.delete(t);
|
|
548
|
+
}
|
|
549
|
+
const n = this.isolatedBlocIndex.delete(e.uid);
|
|
550
|
+
this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e), i !== n && this.warn(
|
|
551
|
+
`[Blac] Inconsistent state detected during isolated bloc cleanup for ${e._name}:${e.uid}. Map removal: ${i}, Index removal: ${n}`
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Finds an isolated bloc instance by its class and ID (O(n) lookup)
|
|
556
|
+
*/
|
|
557
|
+
findIsolatedBlocInstance(e, t) {
|
|
558
|
+
if (!e.isolated) return;
|
|
559
|
+
const i = this.isolatedBlocMap.get(e);
|
|
560
|
+
return i ? i.find((a) => a._id === t && !a.isDisposed) : void 0;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Finds an isolated bloc instance by UID (O(1) lookup)
|
|
564
|
+
*/
|
|
565
|
+
findIsolatedBlocInstanceByUid(e) {
|
|
566
|
+
return this.isolatedBlocIndex.get(e);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Creates a new bloc instance and registers it in the appropriate registry
|
|
570
|
+
* @param blocClass - The bloc class to instantiate
|
|
571
|
+
* @param id - The instance ID
|
|
572
|
+
* @param props - Properties to pass to the bloc constructor
|
|
573
|
+
* @param instanceRef - Optional reference string for the instance
|
|
574
|
+
* @returns The newly created bloc instance
|
|
575
|
+
*/
|
|
576
|
+
createNewBlocInstance(e, t, s = {}) {
|
|
577
|
+
const { constructorParams: i, instanceRef: n } = s, a = new e(i);
|
|
578
|
+
return a.blacInstance = this, a._instanceRef = n, a._id = t, a.setDisposalHandler((c) => this.disposeBloc(c)), a.isIsolated ? this.registerIsolatedBlocInstance(a) : this.registerBlocInstance(a), this.plugins.notifyBlocCreated(a), a;
|
|
579
|
+
}
|
|
580
|
+
activateBloc = (e) => {
|
|
581
|
+
if (e._disposalState !== u.ACTIVE) {
|
|
582
|
+
this.log(
|
|
583
|
+
`[${e._name}:${String(e._id)}] activateBloc called on disposed bloc. Ignoring.`
|
|
584
|
+
);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
const t = e.constructor;
|
|
588
|
+
(e.isIsolated ? this.findIsolatedBlocInstance(t, e._id) : this.findRegisteredBlocInstance(t, e._id)) || (this.log(
|
|
589
|
+
`[${e._name}:${String(e._id)}] activateBloc called. Isolated: ${String(e.isIsolated)}`
|
|
590
|
+
), e.isIsolated ? this.registerIsolatedBlocInstance(e) : this.registerBlocInstance(e));
|
|
591
|
+
};
|
|
592
|
+
static get activateBloc() {
|
|
593
|
+
return o.instance.activateBloc;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Gets or creates a bloc instance based on the provided class and options.
|
|
597
|
+
* If a bloc with the given ID exists, it will be returned. Otherwise, a new instance will be created.
|
|
598
|
+
*
|
|
599
|
+
* @param blocClass - The bloc class to get or create
|
|
600
|
+
* @param options - Options including:
|
|
601
|
+
* - id: The instance ID (defaults to class name if not provided)
|
|
602
|
+
* - props: Properties to pass to the bloc constructor
|
|
603
|
+
* - instanceRef: Optional reference string for the instance
|
|
604
|
+
* @returns The bloc instance
|
|
605
|
+
*/
|
|
606
|
+
getBloc = (e, t = {}) => {
|
|
607
|
+
const { id: s, forceNewInstance: i } = t, n = e, a = s ?? e.name;
|
|
608
|
+
if (this.log(`[${e.name}:${String(a)}] (getBloc) Called:`, {
|
|
609
|
+
options: t,
|
|
610
|
+
base: n
|
|
611
|
+
}), !i)
|
|
612
|
+
if (n.isolated) {
|
|
613
|
+
const l = this.findIsolatedBlocInstance(
|
|
614
|
+
e,
|
|
615
|
+
t.instanceRef ?? a
|
|
616
|
+
);
|
|
617
|
+
if (l)
|
|
618
|
+
return l;
|
|
619
|
+
if (t.throwIfNotFound)
|
|
620
|
+
throw new Error(`Isolated bloc ${e.name} not found`);
|
|
621
|
+
} else {
|
|
622
|
+
const l = this.findRegisteredBlocInstance(
|
|
623
|
+
e,
|
|
624
|
+
a
|
|
625
|
+
);
|
|
626
|
+
if (l)
|
|
627
|
+
return l;
|
|
628
|
+
if (t.throwIfNotFound)
|
|
629
|
+
throw new Error(`Registered bloc ${e.name} not found`);
|
|
625
630
|
}
|
|
631
|
+
const c = this.createNewBlocInstance(e, a, t);
|
|
632
|
+
if (this.log(
|
|
633
|
+
`[${e.name}:${String(a)}] (getBloc) No existing instance found. Creating new one.`,
|
|
634
|
+
t,
|
|
635
|
+
c
|
|
636
|
+
), !c)
|
|
637
|
+
throw new Error(
|
|
638
|
+
`[getBloc] Failed to create bloc instance for ${e.name}. This should never happen.`
|
|
639
|
+
);
|
|
640
|
+
return c;
|
|
641
|
+
};
|
|
642
|
+
static get getBloc() {
|
|
643
|
+
return o.instance.getBloc;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Gets all instances of a specific bloc class
|
|
647
|
+
* @param blocClass - The bloc class to search for
|
|
648
|
+
* @param options - Options including:
|
|
649
|
+
* - searchIsolated: Whether to search in isolated blocs (defaults to bloc's isolated property)
|
|
650
|
+
* @returns Array of matching bloc instances
|
|
651
|
+
*/
|
|
652
|
+
getAllBlocs = (e, t = {}) => {
|
|
653
|
+
const s = [];
|
|
654
|
+
if (this.blocInstanceMap.forEach((i) => {
|
|
655
|
+
i.constructor === e && s.push(i);
|
|
656
|
+
}), t.searchIsolated !== !1) {
|
|
657
|
+
const i = this.isolatedBlocMap.get(e);
|
|
658
|
+
i && s.push(...i.map((n) => n));
|
|
659
|
+
}
|
|
660
|
+
return s;
|
|
661
|
+
};
|
|
662
|
+
/**
|
|
663
|
+
* Disposes all keep-alive blocs of a specific type
|
|
664
|
+
* @param blocClass - The bloc class to dispose
|
|
665
|
+
*/
|
|
666
|
+
disposeKeepAliveBlocs = (e) => {
|
|
667
|
+
const t = [];
|
|
668
|
+
for (const s of this.keepAliveBlocs)
|
|
669
|
+
(!e || s.constructor === e) && t.push(s);
|
|
670
|
+
t.forEach((s) => s.dispose());
|
|
671
|
+
};
|
|
672
|
+
static get disposeKeepAliveBlocs() {
|
|
673
|
+
return o.instance.disposeKeepAliveBlocs;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Disposes all blocs matching a pattern
|
|
677
|
+
* @param predicate - Function to test each bloc for disposal
|
|
678
|
+
*/
|
|
679
|
+
disposeBlocs = (e) => {
|
|
680
|
+
const t = [];
|
|
681
|
+
for (const s of this.blocInstanceMap.values())
|
|
682
|
+
e(s) && t.push(s);
|
|
683
|
+
for (const s of this.isolatedBlocMap.values())
|
|
684
|
+
for (const i of s)
|
|
685
|
+
e(i) && t.push(i);
|
|
686
|
+
t.forEach((s) => s.dispose());
|
|
687
|
+
};
|
|
688
|
+
static get disposeBlocs() {
|
|
689
|
+
return o.instance.disposeBlocs;
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Gets memory usage statistics for debugging
|
|
693
|
+
*/
|
|
694
|
+
getMemoryStats = () => ({
|
|
695
|
+
totalBlocs: this.uidRegistry.size,
|
|
696
|
+
registeredBlocs: this.blocInstanceMap.size,
|
|
697
|
+
isolatedBlocs: Array.from(this.isolatedBlocMap.values()).reduce(
|
|
698
|
+
(e, t) => e + t.length,
|
|
699
|
+
0
|
|
700
|
+
),
|
|
701
|
+
keepAliveBlocs: this.keepAliveBlocs.size,
|
|
702
|
+
isolatedBlocTypes: this.isolatedBlocMap.size
|
|
703
|
+
});
|
|
704
|
+
static get getMemoryStats() {
|
|
705
|
+
return o.instance.getMemoryStats;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Validates subscription references and cleans up orphaned blocs
|
|
709
|
+
*/
|
|
710
|
+
validateConsumers = () => {
|
|
711
|
+
for (const e of this.uidRegistry.values())
|
|
712
|
+
e.subscriptionCount === 0 && !e._keepAlive && e._disposalState === u.ACTIVE && setTimeout(() => {
|
|
713
|
+
e.subscriptionCount === 0 && !e._keepAlive && e._disposalState === u.ACTIVE && this.disposeBloc(e);
|
|
714
|
+
}, 1e3);
|
|
715
|
+
};
|
|
716
|
+
static get validateConsumers() {
|
|
717
|
+
return o.instance.validateConsumers;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Bootstrap the Blac instance and all plugins
|
|
721
|
+
*/
|
|
722
|
+
bootstrap() {
|
|
723
|
+
this.plugins.bootstrap();
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Shutdown the Blac instance and all plugins
|
|
727
|
+
*/
|
|
728
|
+
shutdown() {
|
|
729
|
+
this.plugins.shutdown();
|
|
730
|
+
for (const e of this.blocInstanceMap.values())
|
|
731
|
+
e._keepAlive || this.disposeBloc(e);
|
|
732
|
+
for (const e of this.isolatedBlocMap.values())
|
|
733
|
+
for (const t of e)
|
|
734
|
+
t._keepAlive || this.disposeBloc(t);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
function A() {
|
|
738
|
+
return typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(r) {
|
|
739
|
+
const e = Math.random() * 16 | 0;
|
|
740
|
+
return (r === "x" ? e : e & 3 | 8).toString(16);
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
const x = {
|
|
744
|
+
fatal: (r, e, t, s) => {
|
|
745
|
+
const i = new m(
|
|
746
|
+
r,
|
|
747
|
+
e,
|
|
748
|
+
y.FATAL,
|
|
749
|
+
t,
|
|
750
|
+
s
|
|
751
|
+
);
|
|
752
|
+
throw f.getInstance().handle(i), i;
|
|
753
|
+
},
|
|
754
|
+
error: (r, e, t, s) => {
|
|
755
|
+
const i = new m(
|
|
756
|
+
r,
|
|
757
|
+
e,
|
|
758
|
+
y.ERROR,
|
|
759
|
+
t,
|
|
760
|
+
s
|
|
761
|
+
);
|
|
762
|
+
f.getInstance().handle(i);
|
|
763
|
+
},
|
|
764
|
+
warn: (r, e, t, s) => {
|
|
765
|
+
const i = new m(
|
|
766
|
+
r,
|
|
767
|
+
e,
|
|
768
|
+
y.WARNING,
|
|
769
|
+
t,
|
|
770
|
+
s
|
|
771
|
+
);
|
|
772
|
+
f.getInstance().handle(i);
|
|
773
|
+
},
|
|
774
|
+
info: (r, e, t) => {
|
|
775
|
+
const s = new m(r, e, y.INFO, t);
|
|
776
|
+
f.getInstance().handle(s);
|
|
777
|
+
},
|
|
778
|
+
/**
|
|
779
|
+
* Wraps a function to catch and handle errors
|
|
780
|
+
*/
|
|
781
|
+
wrap: (r, e, t, s = y.ERROR) => {
|
|
782
|
+
try {
|
|
783
|
+
return r();
|
|
784
|
+
} catch (i) {
|
|
785
|
+
const n = i instanceof Error ? i.message : String(i), a = new m(n, e, s, t, i);
|
|
786
|
+
f.getInstance().handle(a);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
/**
|
|
791
|
+
* Wraps an async function to catch and handle errors
|
|
792
|
+
*/
|
|
793
|
+
wrapAsync: async (r, e, t, s = y.ERROR) => {
|
|
794
|
+
try {
|
|
795
|
+
return await r();
|
|
796
|
+
} catch (i) {
|
|
797
|
+
const n = i instanceof Error ? i.message : String(i), a = new m(n, e, s, t, i);
|
|
798
|
+
f.getInstance().handle(a);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
class w {
|
|
804
|
+
plugins = /* @__PURE__ */ new Map();
|
|
805
|
+
executionOrder = [];
|
|
806
|
+
attached = !1;
|
|
807
|
+
/**
|
|
808
|
+
* Add a bloc plugin
|
|
809
|
+
*/
|
|
810
|
+
add(e) {
|
|
811
|
+
if (this.plugins.has(e.name))
|
|
812
|
+
throw new Error(`Plugin '${e.name}' is already registered`);
|
|
813
|
+
e.capabilities && this.validateCapabilities(e), this.plugins.set(e.name, e), this.executionOrder.push(e.name);
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Remove a bloc plugin
|
|
817
|
+
*/
|
|
818
|
+
remove(e) {
|
|
819
|
+
const t = this.plugins.get(e);
|
|
820
|
+
return t ? (this.attached && t.onDetach && x.wrap(() => t.onDetach(), v.PLUGIN, {
|
|
821
|
+
pluginName: e,
|
|
822
|
+
operation: "onDetach"
|
|
823
|
+
}), this.plugins.delete(e), this.executionOrder = this.executionOrder.filter(
|
|
824
|
+
(s) => s !== e
|
|
825
|
+
), !0) : !1;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Get a plugin by name
|
|
829
|
+
*/
|
|
830
|
+
get(e) {
|
|
831
|
+
return this.plugins.get(e);
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Get all plugins in execution order
|
|
835
|
+
*/
|
|
836
|
+
getAll() {
|
|
837
|
+
return this.executionOrder.map((e) => this.plugins.get(e));
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Clear all plugins
|
|
841
|
+
*/
|
|
842
|
+
clear() {
|
|
843
|
+
if (this.attached)
|
|
844
|
+
for (const e of this.getAll())
|
|
845
|
+
e.onDetach && x.wrap(() => e.onDetach(), v.PLUGIN, {
|
|
846
|
+
pluginName: e.name,
|
|
847
|
+
operation: "onDetach"
|
|
848
|
+
});
|
|
849
|
+
this.plugins.clear(), this.executionOrder = [], this.attached = !1;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Attach all plugins to a bloc
|
|
853
|
+
*/
|
|
854
|
+
attach(e) {
|
|
855
|
+
if (this.attached)
|
|
856
|
+
throw new Error("Plugins are already attached");
|
|
857
|
+
for (const t of this.getAll())
|
|
858
|
+
if (t.onAttach)
|
|
859
|
+
try {
|
|
860
|
+
t.onAttach(e);
|
|
861
|
+
} catch (s) {
|
|
862
|
+
console.error(`Plugin '${t.name}' error in onAttach:`, s), this.remove(t.name);
|
|
863
|
+
}
|
|
864
|
+
this.attached = !0;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Transform state through all plugins
|
|
868
|
+
*/
|
|
869
|
+
transformState(e, t) {
|
|
870
|
+
let s = t;
|
|
871
|
+
for (const i of this.getAll())
|
|
872
|
+
if (i.transformState && this.canTransformState(i))
|
|
873
|
+
try {
|
|
874
|
+
s = i.transformState(
|
|
875
|
+
e,
|
|
876
|
+
s
|
|
877
|
+
);
|
|
878
|
+
} catch (n) {
|
|
879
|
+
console.error(
|
|
880
|
+
`Plugin '${i.name}' error in transformState:`,
|
|
881
|
+
n
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
return s;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Transform event through all plugins
|
|
888
|
+
*/
|
|
889
|
+
transformEvent(e) {
|
|
890
|
+
let t = e;
|
|
891
|
+
for (const s of this.getAll()) {
|
|
892
|
+
if (t === null) break;
|
|
893
|
+
if (s.transformEvent && this.canInterceptEvents(s))
|
|
894
|
+
try {
|
|
895
|
+
t = s.transformEvent(t);
|
|
896
|
+
} catch (i) {
|
|
897
|
+
console.error(
|
|
898
|
+
`Plugin '${s.name}' error in transformEvent:`,
|
|
899
|
+
i
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return t;
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Notify plugins of state change
|
|
907
|
+
*/
|
|
908
|
+
notifyStateChange(e, t) {
|
|
909
|
+
for (const s of this.getAll())
|
|
910
|
+
if (s.onStateChange && this.canReadState(s))
|
|
911
|
+
try {
|
|
912
|
+
s.onStateChange(e, t);
|
|
913
|
+
} catch (i) {
|
|
914
|
+
console.error(
|
|
915
|
+
`Plugin '${s.name}' error in onStateChange:`,
|
|
916
|
+
i
|
|
917
|
+
);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Notify plugins of event
|
|
922
|
+
*/
|
|
923
|
+
notifyEvent(e) {
|
|
924
|
+
for (const t of this.getAll())
|
|
925
|
+
if (t.onEvent && this.canReadState(t))
|
|
926
|
+
try {
|
|
927
|
+
t.onEvent(e);
|
|
928
|
+
} catch (s) {
|
|
929
|
+
console.error(`Plugin '${t.name}' error in onEvent:`, s);
|
|
930
|
+
}
|
|
626
931
|
}
|
|
627
932
|
/**
|
|
628
|
-
*
|
|
933
|
+
* Notify plugins of error
|
|
629
934
|
*/
|
|
630
|
-
|
|
631
|
-
|
|
935
|
+
notifyError(e, t) {
|
|
936
|
+
for (const s of this.getAll())
|
|
937
|
+
if (s.onError)
|
|
938
|
+
try {
|
|
939
|
+
s.onError(e, t);
|
|
940
|
+
} catch (i) {
|
|
941
|
+
console.error(`Plugin '${s.name}' error in onError:`, i);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
validateCapabilities(e) {
|
|
945
|
+
const t = e.capabilities;
|
|
946
|
+
if (t.transformState && !t.readState)
|
|
947
|
+
throw new Error(
|
|
948
|
+
`Plugin '${e.name}': transformState requires readState capability`
|
|
949
|
+
);
|
|
950
|
+
if (t.interceptEvents && !t.readState)
|
|
951
|
+
throw new Error(
|
|
952
|
+
`Plugin '${e.name}': interceptEvents requires readState capability`
|
|
953
|
+
);
|
|
954
|
+
}
|
|
955
|
+
canReadState(e) {
|
|
956
|
+
return !e.capabilities || e.capabilities.readState !== !1;
|
|
957
|
+
}
|
|
958
|
+
canTransformState(e) {
|
|
959
|
+
return !e.capabilities || e.capabilities.transformState === !0;
|
|
960
|
+
}
|
|
961
|
+
canInterceptEvents(e) {
|
|
962
|
+
return !e.capabilities || e.capabilities.interceptEvents === !0;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
class E {
|
|
966
|
+
constructor(e) {
|
|
967
|
+
this.bloc = e;
|
|
632
968
|
}
|
|
969
|
+
subscriptions = /* @__PURE__ */ new Map();
|
|
970
|
+
pathToSubscriptions = /* @__PURE__ */ new Map();
|
|
971
|
+
weakRefCleanupScheduled = !1;
|
|
972
|
+
totalNotifications = 0;
|
|
633
973
|
/**
|
|
634
|
-
*
|
|
974
|
+
* Subscribe to state changes
|
|
635
975
|
*/
|
|
636
|
-
|
|
637
|
-
|
|
976
|
+
subscribe(e) {
|
|
977
|
+
const t = `${e.type}-${A()}`, s = {
|
|
978
|
+
id: t,
|
|
979
|
+
type: e.type,
|
|
980
|
+
selector: e.selector,
|
|
981
|
+
equalityFn: e.equalityFn || Object.is,
|
|
982
|
+
notify: e.notify,
|
|
983
|
+
priority: e.priority ?? 0,
|
|
984
|
+
weakRef: e.weakRef,
|
|
985
|
+
dependencies: /* @__PURE__ */ new Set(),
|
|
986
|
+
metadata: {
|
|
987
|
+
lastNotified: Date.now(),
|
|
988
|
+
hasRendered: !1,
|
|
989
|
+
accessCount: 0,
|
|
990
|
+
firstAccessTime: Date.now()
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
if (s.selector)
|
|
994
|
+
try {
|
|
995
|
+
s.lastValue = s.selector(
|
|
996
|
+
this.bloc.state,
|
|
997
|
+
this.bloc
|
|
998
|
+
);
|
|
999
|
+
} catch (i) {
|
|
1000
|
+
o.error(`SubscriptionManager: Error in selector for ${t}:`, i);
|
|
1001
|
+
}
|
|
1002
|
+
return this.subscriptions.set(t, s), o.log(
|
|
1003
|
+
`[${this.bloc._name}:${this.bloc._id}] Subscription added: ${t}. Total: ${this.subscriptions.size}`
|
|
1004
|
+
), this.bloc._cancelDisposalIfRequested(), () => this.unsubscribe(t);
|
|
638
1005
|
}
|
|
639
1006
|
/**
|
|
640
|
-
*
|
|
1007
|
+
* Unsubscribe by ID
|
|
641
1008
|
*/
|
|
642
|
-
|
|
643
|
-
|
|
1009
|
+
unsubscribe(e) {
|
|
1010
|
+
const t = this.subscriptions.get(e);
|
|
1011
|
+
if (t) {
|
|
1012
|
+
if (t.dependencies)
|
|
1013
|
+
for (const s of t.dependencies) {
|
|
1014
|
+
const i = this.pathToSubscriptions.get(s);
|
|
1015
|
+
i && (i.delete(e), i.size === 0 && this.pathToSubscriptions.delete(s));
|
|
1016
|
+
}
|
|
1017
|
+
this.subscriptions.delete(e), o.log(
|
|
1018
|
+
`[${this.bloc._name}:${this.bloc._id}] Subscription removed: ${e}. Remaining: ${this.subscriptions.size}`
|
|
1019
|
+
), this.bloc.checkDisposal();
|
|
1020
|
+
}
|
|
644
1021
|
}
|
|
645
1022
|
/**
|
|
646
|
-
*
|
|
647
|
-
* Activate plugins when bloc becomes active
|
|
1023
|
+
* Notify all subscriptions of state change
|
|
648
1024
|
*/
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
1025
|
+
notify(e, t, s) {
|
|
1026
|
+
this.cleanupDeadReferences();
|
|
1027
|
+
const i = Array.from(this.subscriptions.values()).sort(
|
|
1028
|
+
(n, a) => (a.priority ?? 0) - (n.priority ?? 0)
|
|
1029
|
+
);
|
|
1030
|
+
for (const n of i) {
|
|
1031
|
+
if (n.weakRef && !n.weakRef.deref()) {
|
|
1032
|
+
this.scheduleWeakRefCleanup();
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
let a = !1, c, l;
|
|
1036
|
+
if (n.selector)
|
|
1037
|
+
try {
|
|
1038
|
+
c = n.selector(e, this.bloc), l = n.lastValue, a = !(n.equalityFn || Object.is)(l, c), a && (n.lastValue = c);
|
|
1039
|
+
} catch (h) {
|
|
1040
|
+
o.error(
|
|
1041
|
+
`SubscriptionManager: Error in selector for ${n.id}:`,
|
|
1042
|
+
h
|
|
1043
|
+
);
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
if (n.dependencies && n.dependencies.size > 0) {
|
|
1048
|
+
const h = this.getChangedPaths(t, e);
|
|
1049
|
+
a = this.shouldNotifyForPaths(
|
|
1050
|
+
n.id,
|
|
1051
|
+
h
|
|
1052
|
+
), o.config.logLevel === "debug" && (o.log(
|
|
1053
|
+
`[SubscriptionManager] Subscription ${n.id} dependencies:`,
|
|
1054
|
+
Array.from(n.dependencies)
|
|
1055
|
+
), o.log(
|
|
1056
|
+
"[SubscriptionManager] Changed paths:",
|
|
1057
|
+
Array.from(h)
|
|
1058
|
+
), o.log("[SubscriptionManager] Should notify:", a));
|
|
1059
|
+
} else
|
|
1060
|
+
a = !0;
|
|
1061
|
+
c = e, l = t;
|
|
655
1062
|
}
|
|
1063
|
+
if (a)
|
|
1064
|
+
try {
|
|
1065
|
+
n.notify(c, l, s), this.totalNotifications++, n.metadata && (n.metadata.lastNotified = Date.now(), n.metadata.hasRendered = !0);
|
|
1066
|
+
} catch (h) {
|
|
1067
|
+
o.error(
|
|
1068
|
+
`SubscriptionManager: Error in notify for ${n.id}:`,
|
|
1069
|
+
h
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
656
1073
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
i(
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
i
|
|
672
|
-
|
|
673
|
-
|
|
1074
|
+
/**
|
|
1075
|
+
* Track a path access for a subscription
|
|
1076
|
+
*/
|
|
1077
|
+
trackAccess(e, t, s) {
|
|
1078
|
+
const i = this.subscriptions.get(e);
|
|
1079
|
+
if (!i) return;
|
|
1080
|
+
i.dependencies || (i.dependencies = /* @__PURE__ */ new Set()), i.dependencies.add(t);
|
|
1081
|
+
let n = this.pathToSubscriptions.get(t);
|
|
1082
|
+
n || (n = /* @__PURE__ */ new Set(), this.pathToSubscriptions.set(t, n)), n.add(e), i.metadata && (i.metadata.accessCount = (i.metadata.accessCount || 0) + 1, i.metadata.lastAccessTime = Date.now());
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Get the paths that changed between two states
|
|
1086
|
+
*/
|
|
1087
|
+
getChangedPaths(e, t, s = "") {
|
|
1088
|
+
const i = /* @__PURE__ */ new Set();
|
|
1089
|
+
if (e === t) return i;
|
|
1090
|
+
if (typeof e != "object" || typeof t != "object" || e === null || t === null)
|
|
1091
|
+
return s && i.add(s), i;
|
|
1092
|
+
const n = /* @__PURE__ */ new Set([
|
|
1093
|
+
...Object.keys(e),
|
|
1094
|
+
...Object.keys(t)
|
|
1095
|
+
]);
|
|
1096
|
+
for (const a of n) {
|
|
1097
|
+
const c = s ? `${s}.${a}` : a, l = e[a], h = t[a];
|
|
1098
|
+
l !== h && (i.add(c), typeof l == "object" && typeof h == "object" && l !== null && h !== null && this.getChangedPaths(
|
|
1099
|
+
l,
|
|
1100
|
+
h,
|
|
1101
|
+
c
|
|
1102
|
+
).forEach((S) => i.add(S)));
|
|
1103
|
+
}
|
|
1104
|
+
return i;
|
|
674
1105
|
}
|
|
675
1106
|
/**
|
|
676
|
-
*
|
|
1107
|
+
* Check if a subscription should be notified based on changed paths
|
|
677
1108
|
*/
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1109
|
+
shouldNotifyForPaths(e, t) {
|
|
1110
|
+
const s = this.subscriptions.get(e);
|
|
1111
|
+
if (!s || !s.dependencies) return !0;
|
|
1112
|
+
for (const i of s.dependencies) {
|
|
1113
|
+
if (i.startsWith("_class.")) {
|
|
1114
|
+
if (t.size > 0)
|
|
1115
|
+
return !0;
|
|
1116
|
+
continue;
|
|
1117
|
+
}
|
|
1118
|
+
if (t.has(i)) return !0;
|
|
1119
|
+
for (const n of t)
|
|
1120
|
+
if (n.startsWith(i + ".") || i.startsWith(n + "."))
|
|
1121
|
+
return !0;
|
|
1122
|
+
}
|
|
1123
|
+
return !1;
|
|
682
1124
|
}
|
|
683
1125
|
/**
|
|
684
|
-
*
|
|
1126
|
+
* Get statistics about subscriptions
|
|
685
1127
|
*/
|
|
686
|
-
|
|
687
|
-
|
|
1128
|
+
getStats() {
|
|
1129
|
+
let e = 0, t = 0;
|
|
1130
|
+
for (const s of this.subscriptions.values())
|
|
1131
|
+
s.type === "consumer" ? e++ : t++;
|
|
1132
|
+
return {
|
|
1133
|
+
activeSubscriptions: this.subscriptions.size,
|
|
1134
|
+
consumerCount: e,
|
|
1135
|
+
observerCount: t,
|
|
1136
|
+
totalNotifications: this.totalNotifications,
|
|
1137
|
+
trackedDependencies: this.pathToSubscriptions.size
|
|
1138
|
+
};
|
|
688
1139
|
}
|
|
689
1140
|
/**
|
|
690
|
-
*
|
|
1141
|
+
* Clear all subscriptions
|
|
691
1142
|
*/
|
|
692
|
-
|
|
693
|
-
|
|
1143
|
+
clear() {
|
|
1144
|
+
this.subscriptions.clear(), this.pathToSubscriptions.clear();
|
|
694
1145
|
}
|
|
695
1146
|
/**
|
|
696
|
-
* Get
|
|
1147
|
+
* Get subscription by ID
|
|
697
1148
|
*/
|
|
698
|
-
|
|
699
|
-
return this.
|
|
1149
|
+
getSubscription(e) {
|
|
1150
|
+
return this.subscriptions.get(e);
|
|
700
1151
|
}
|
|
701
1152
|
/**
|
|
702
|
-
*
|
|
1153
|
+
* Check if there are any active subscriptions
|
|
703
1154
|
*/
|
|
704
|
-
|
|
705
|
-
|
|
1155
|
+
get hasSubscriptions() {
|
|
1156
|
+
return this.subscriptions.size > 0;
|
|
706
1157
|
}
|
|
707
1158
|
/**
|
|
708
|
-
*
|
|
1159
|
+
* Get count of active subscriptions
|
|
709
1160
|
*/
|
|
710
|
-
|
|
711
|
-
|
|
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
|
-
}
|
|
1161
|
+
get size() {
|
|
1162
|
+
return this.subscriptions.size;
|
|
721
1163
|
}
|
|
722
1164
|
/**
|
|
723
|
-
*
|
|
1165
|
+
* Clean up subscriptions with dead weak references
|
|
724
1166
|
*/
|
|
725
|
-
|
|
726
|
-
this.
|
|
1167
|
+
cleanupDeadReferences() {
|
|
1168
|
+
if (!this.weakRefCleanupScheduled) return;
|
|
1169
|
+
const e = [];
|
|
1170
|
+
for (const [t, s] of this.subscriptions)
|
|
1171
|
+
s.weakRef && !s.weakRef.deref() && e.push(t);
|
|
1172
|
+
for (const t of e)
|
|
1173
|
+
this.unsubscribe(t);
|
|
1174
|
+
this.weakRefCleanupScheduled = !1;
|
|
727
1175
|
}
|
|
728
1176
|
/**
|
|
729
|
-
*
|
|
1177
|
+
* Schedule weak reference cleanup for next tick
|
|
730
1178
|
*/
|
|
731
|
-
|
|
732
|
-
this.
|
|
1179
|
+
scheduleWeakRefCleanup() {
|
|
1180
|
+
this.weakRefCleanupScheduled || (this.weakRefCleanupScheduled = !0, queueMicrotask(() => this.cleanupDeadReferences()));
|
|
733
1181
|
}
|
|
1182
|
+
}
|
|
1183
|
+
class D {
|
|
1184
|
+
pendingUpdates = [];
|
|
1185
|
+
isBatching = !1;
|
|
734
1186
|
/**
|
|
735
|
-
*
|
|
1187
|
+
* Execute a callback with batched updates
|
|
736
1188
|
*/
|
|
737
|
-
|
|
738
|
-
this.
|
|
1189
|
+
batchUpdates(e, t) {
|
|
1190
|
+
if (this.isBatching) {
|
|
1191
|
+
e();
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
this.isBatching = !0, this.pendingUpdates = [];
|
|
1195
|
+
try {
|
|
1196
|
+
if (e(), this.pendingUpdates.length > 0) {
|
|
1197
|
+
const s = this.pendingUpdates[this.pendingUpdates.length - 1];
|
|
1198
|
+
t(s);
|
|
1199
|
+
}
|
|
1200
|
+
} finally {
|
|
1201
|
+
this.isBatching = !1, this.pendingUpdates = [];
|
|
1202
|
+
}
|
|
739
1203
|
}
|
|
740
1204
|
/**
|
|
741
|
-
*
|
|
1205
|
+
* Add an update to the batch
|
|
742
1206
|
*/
|
|
743
|
-
|
|
744
|
-
this.
|
|
1207
|
+
addUpdate(e) {
|
|
1208
|
+
this.isBatching && this.pendingUpdates.push(e);
|
|
745
1209
|
}
|
|
746
1210
|
/**
|
|
747
|
-
*
|
|
1211
|
+
* Check if currently batching
|
|
748
1212
|
*/
|
|
749
|
-
|
|
750
|
-
this.
|
|
1213
|
+
get isCurrentlyBatching() {
|
|
1214
|
+
return this.isBatching;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
class C {
|
|
1218
|
+
uid = A();
|
|
1219
|
+
blacInstance;
|
|
1220
|
+
static isolated = !1;
|
|
1221
|
+
get isIsolated() {
|
|
1222
|
+
return this._isolated;
|
|
1223
|
+
}
|
|
1224
|
+
static keepAlive = !1;
|
|
1225
|
+
get isKeepAlive() {
|
|
1226
|
+
return this._keepAlive;
|
|
751
1227
|
}
|
|
1228
|
+
_isolated = !1;
|
|
1229
|
+
_id;
|
|
1230
|
+
_instanceRef;
|
|
1231
|
+
_name;
|
|
752
1232
|
/**
|
|
753
|
-
*
|
|
1233
|
+
* Unified subscription manager for all state notifications
|
|
754
1234
|
*/
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1235
|
+
_subscriptionManager;
|
|
1236
|
+
_state;
|
|
1237
|
+
_lifecycleManager = new B();
|
|
1238
|
+
_batchingManager = new D();
|
|
1239
|
+
_keepAlive = !1;
|
|
1240
|
+
lastUpdate;
|
|
1241
|
+
_plugins = new w();
|
|
1242
|
+
onDispose;
|
|
758
1243
|
/**
|
|
759
|
-
*
|
|
1244
|
+
* Creates a new BlocBase instance with unified subscription management
|
|
760
1245
|
*/
|
|
761
|
-
|
|
762
|
-
this.
|
|
763
|
-
|
|
764
|
-
|
|
1246
|
+
constructor(e) {
|
|
1247
|
+
this._state = e, this._id = this.constructor.name, this._name = this.constructor.name, this._subscriptionManager = new E(this);
|
|
1248
|
+
const t = this.constructor;
|
|
1249
|
+
if (this._keepAlive = typeof t.keepAlive == "boolean" ? t.keepAlive : !1, this._isolated = typeof t.isolated == "boolean" ? t.isolated : !1, this._plugins = new w(), t.plugins && Array.isArray(t.plugins))
|
|
1250
|
+
for (const s of t.plugins)
|
|
1251
|
+
this._plugins.add(s);
|
|
1252
|
+
this._plugins.attach(this);
|
|
765
1253
|
}
|
|
766
1254
|
/**
|
|
767
|
-
*
|
|
1255
|
+
* Returns the current state
|
|
768
1256
|
*/
|
|
769
|
-
|
|
770
|
-
return this.
|
|
771
|
-
}
|
|
772
|
-
initializeMetrics(e) {
|
|
773
|
-
this.metrics.set(e, /* @__PURE__ */ new Map());
|
|
1257
|
+
get state() {
|
|
1258
|
+
return this._lifecycleManager.isDisposed ? this._state : this._state;
|
|
774
1259
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
...n,
|
|
783
|
-
executionTime: n.executionTime + o,
|
|
784
|
-
executionCount: n.executionCount + 1,
|
|
785
|
-
lastExecutionTime: o
|
|
1260
|
+
/**
|
|
1261
|
+
* Subscribe to all state changes
|
|
1262
|
+
*/
|
|
1263
|
+
subscribe(e) {
|
|
1264
|
+
return this._subscriptionManager.subscribe({
|
|
1265
|
+
type: "observer",
|
|
1266
|
+
notify: (t) => e(t)
|
|
786
1267
|
});
|
|
787
1268
|
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
lastError: s
|
|
1269
|
+
/**
|
|
1270
|
+
* Subscribe with a selector for optimized updates
|
|
1271
|
+
*/
|
|
1272
|
+
subscribeWithSelector(e, t, s) {
|
|
1273
|
+
return this._subscriptionManager.subscribe({
|
|
1274
|
+
type: "consumer",
|
|
1275
|
+
selector: e,
|
|
1276
|
+
equalityFn: s,
|
|
1277
|
+
notify: (i) => t(i)
|
|
798
1278
|
});
|
|
799
1279
|
}
|
|
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
1280
|
/**
|
|
826
|
-
*
|
|
827
|
-
* @param options - Configuration options including singleton control
|
|
1281
|
+
* Subscribe with React component reference for automatic cleanup
|
|
828
1282
|
*/
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
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());
|
|
1283
|
+
subscribeComponent(e, t) {
|
|
1284
|
+
return this._subscriptionManager.subscribe({
|
|
1285
|
+
type: "consumer",
|
|
1286
|
+
weakRef: e,
|
|
1287
|
+
notify: t
|
|
1019
1288
|
});
|
|
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
1289
|
}
|
|
1057
1290
|
/**
|
|
1058
|
-
*
|
|
1059
|
-
* @param config - Partial configuration to merge with existing config
|
|
1060
|
-
* @throws Error if configuration is invalid
|
|
1291
|
+
* Get current subscription count
|
|
1061
1292
|
*/
|
|
1062
|
-
|
|
1063
|
-
|
|
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;
|
|
1293
|
+
get subscriptionCount() {
|
|
1294
|
+
return this._subscriptionManager.size;
|
|
1074
1295
|
}
|
|
1075
1296
|
/**
|
|
1076
|
-
*
|
|
1077
|
-
* @returns The Blac instance
|
|
1297
|
+
* Track property access for a subscription
|
|
1078
1298
|
*/
|
|
1079
|
-
|
|
1080
|
-
|
|
1299
|
+
trackAccess(e, t, s) {
|
|
1300
|
+
this._subscriptionManager.trackAccess(e, t, s);
|
|
1081
1301
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1302
|
+
/**
|
|
1303
|
+
* Emit a new state
|
|
1304
|
+
*/
|
|
1305
|
+
emit(e, t) {
|
|
1306
|
+
this._pushState(e, this._state, t);
|
|
1084
1307
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1308
|
+
/**
|
|
1309
|
+
* Internal state push method used by Bloc
|
|
1310
|
+
*/
|
|
1311
|
+
_pushState(e, t, s) {
|
|
1312
|
+
if (this._lifecycleManager.currentState !== u.ACTIVE) {
|
|
1313
|
+
this.blacInstance?.error(
|
|
1314
|
+
`[${this._name}:${this._id}] Attempted state update on ${this._lifecycleManager.currentState} bloc. Update ignored.`
|
|
1315
|
+
);
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
if (e === void 0)
|
|
1319
|
+
return;
|
|
1320
|
+
this._state = e;
|
|
1321
|
+
const i = this._plugins.transformState(
|
|
1322
|
+
t,
|
|
1323
|
+
e
|
|
1324
|
+
);
|
|
1325
|
+
if (this._state = i, this._plugins.notifyStateChange(t, i), this.blacInstance?.plugins.notifyStateChanged(
|
|
1326
|
+
this,
|
|
1327
|
+
t,
|
|
1328
|
+
i
|
|
1329
|
+
), this._batchingManager.isCurrentlyBatching) {
|
|
1330
|
+
this._batchingManager.addUpdate({
|
|
1331
|
+
newState: i,
|
|
1332
|
+
oldState: t,
|
|
1333
|
+
action: s
|
|
1334
|
+
});
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
this._subscriptionManager.notify(i, t, s), this.lastUpdate = Date.now();
|
|
1338
|
+
}
|
|
1339
|
+
_batchUpdates(e) {
|
|
1340
|
+
this._batchingManager.batchUpdates(e, (t) => {
|
|
1341
|
+
this._subscriptionManager.notify(
|
|
1342
|
+
t.newState,
|
|
1343
|
+
t.oldState,
|
|
1344
|
+
t.action
|
|
1345
|
+
);
|
|
1346
|
+
});
|
|
1087
1347
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1348
|
+
/**
|
|
1349
|
+
* Add a plugin
|
|
1350
|
+
*/
|
|
1351
|
+
addPlugin(e) {
|
|
1352
|
+
if (this._plugins.add(e), this._plugins.attached && e.onAttach)
|
|
1353
|
+
try {
|
|
1354
|
+
e.onAttach(this);
|
|
1355
|
+
} catch (t) {
|
|
1356
|
+
console.error(`Plugin '${e.name}' error in onAttach:`, t);
|
|
1357
|
+
}
|
|
1090
1358
|
}
|
|
1091
1359
|
/**
|
|
1092
|
-
*
|
|
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"
|
|
1360
|
+
* Remove a plugin
|
|
1096
1361
|
*/
|
|
1097
|
-
|
|
1098
|
-
|
|
1362
|
+
removePlugin(e) {
|
|
1363
|
+
this._plugins.remove(e.name);
|
|
1099
1364
|
}
|
|
1100
1365
|
/**
|
|
1101
|
-
*
|
|
1102
|
-
* @param bloc - The bloc instance to unregister
|
|
1366
|
+
* Get all plugins
|
|
1103
1367
|
*/
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
this.blocInstanceMap.delete(t), this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e);
|
|
1368
|
+
get plugins() {
|
|
1369
|
+
return this._plugins.getAll();
|
|
1107
1370
|
}
|
|
1108
1371
|
/**
|
|
1109
|
-
*
|
|
1110
|
-
* @param bloc - The bloc instance to register
|
|
1372
|
+
* Disposal management
|
|
1111
1373
|
*/
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
this.blocInstanceMap.set(t, e), this.uidRegistry.set(e.uid, e), e._keepAlive && this.keepAliveBlocs.add(e);
|
|
1374
|
+
get isDisposed() {
|
|
1375
|
+
return this._lifecycleManager.isDisposed;
|
|
1115
1376
|
}
|
|
1116
1377
|
/**
|
|
1117
|
-
*
|
|
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
|
|
1378
|
+
* Atomic state transition for disposal
|
|
1121
1379
|
*/
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1380
|
+
_atomicStateTransition(e, t) {
|
|
1381
|
+
return this._lifecycleManager.atomicStateTransition(
|
|
1382
|
+
e,
|
|
1383
|
+
t
|
|
1384
|
+
);
|
|
1126
1385
|
}
|
|
1127
1386
|
/**
|
|
1128
|
-
*
|
|
1129
|
-
* @param bloc - The isolated bloc instance to register
|
|
1387
|
+
* Dispose the bloc and clean up resources
|
|
1130
1388
|
*/
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1389
|
+
async dispose() {
|
|
1390
|
+
if (!this._lifecycleManager.atomicStateTransition(
|
|
1391
|
+
u.ACTIVE,
|
|
1392
|
+
u.DISPOSING
|
|
1393
|
+
).success)
|
|
1394
|
+
if (this._lifecycleManager.currentState === u.DISPOSAL_REQUESTED)
|
|
1395
|
+
this._lifecycleManager.atomicStateTransition(
|
|
1396
|
+
u.DISPOSAL_REQUESTED,
|
|
1397
|
+
u.DISPOSING
|
|
1398
|
+
);
|
|
1399
|
+
else
|
|
1400
|
+
return;
|
|
1401
|
+
try {
|
|
1402
|
+
this._subscriptionManager.clear(), this.onDispose && this.onDispose();
|
|
1403
|
+
for (const s of this._plugins.getAll())
|
|
1404
|
+
try {
|
|
1405
|
+
"onDispose" in s && typeof s.onDispose == "function" && s.onDispose(this);
|
|
1406
|
+
} catch (i) {
|
|
1407
|
+
console.error("Plugin disposal error:", i);
|
|
1408
|
+
}
|
|
1409
|
+
const t = this._lifecycleManager.getDisposalHandler();
|
|
1410
|
+
t && t(this);
|
|
1411
|
+
} finally {
|
|
1412
|
+
this._lifecycleManager.atomicStateTransition(
|
|
1413
|
+
u.DISPOSING,
|
|
1414
|
+
u.DISPOSED
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1134
1417
|
}
|
|
1135
1418
|
/**
|
|
1136
|
-
*
|
|
1137
|
-
* @param bloc - The isolated bloc instance to unregister
|
|
1419
|
+
* Schedule disposal when no subscriptions remain
|
|
1138
1420
|
*/
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
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}`
|
|
1421
|
+
_scheduleDisposal() {
|
|
1422
|
+
this._subscriptionManager.size === 0 && !this._keepAlive && this._lifecycleManager.scheduleDisposal(
|
|
1423
|
+
16,
|
|
1424
|
+
() => this._subscriptionManager.size === 0 && !this._keepAlive,
|
|
1425
|
+
() => this.dispose()
|
|
1149
1426
|
);
|
|
1150
1427
|
}
|
|
1151
1428
|
/**
|
|
1152
|
-
*
|
|
1429
|
+
* Set disposal handler
|
|
1153
1430
|
*/
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1431
|
+
setDisposalHandler(e) {
|
|
1432
|
+
this._lifecycleManager.setDisposalHandler(
|
|
1433
|
+
e
|
|
1434
|
+
);
|
|
1158
1435
|
}
|
|
1159
1436
|
/**
|
|
1160
|
-
*
|
|
1437
|
+
* Check if disposal should be scheduled (called by subscription manager)
|
|
1161
1438
|
*/
|
|
1162
|
-
|
|
1163
|
-
|
|
1439
|
+
checkDisposal() {
|
|
1440
|
+
this._subscriptionManager.size === 0 && !this._keepAlive && this._lifecycleManager.currentState === u.ACTIVE && this._scheduleDisposal();
|
|
1164
1441
|
}
|
|
1165
1442
|
/**
|
|
1166
|
-
*
|
|
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
|
|
1443
|
+
* Cancel disposal if bloc is in disposal_requested state
|
|
1172
1444
|
*/
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
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;
|
|
1445
|
+
_cancelDisposalIfRequested() {
|
|
1446
|
+
this.blacInstance?.log(
|
|
1447
|
+
`[${this._name}:${this._id}] _cancelDisposalIfRequested called. Current state: ${this._lifecycleManager.currentState}`
|
|
1448
|
+
), this._lifecycleManager.cancelDisposal() ? this.blacInstance?.log(
|
|
1449
|
+
`[${this._name}:${this._id}] Disposal cancelled - new subscription added`
|
|
1450
|
+
) : this._lifecycleManager.currentState === u.DISPOSAL_REQUESTED ? this.blacInstance?.warn(
|
|
1451
|
+
`[${this._name}:${this._id}] Failed to cancel disposal. Current state: ${this._lifecycleManager.currentState}`
|
|
1452
|
+
) : this._lifecycleManager.isDisposed && this.blacInstance?.error(
|
|
1453
|
+
`[${this._name}:${this._id}] Cannot cancel disposal - bloc is already disposed`
|
|
1454
|
+
);
|
|
1197
1455
|
}
|
|
1456
|
+
}
|
|
1457
|
+
class R extends C {
|
|
1458
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
1198
1459
|
/**
|
|
1199
|
-
*
|
|
1460
|
+
* @internal
|
|
1461
|
+
* Event queue to ensure sequential processing of async events
|
|
1200
1462
|
*/
|
|
1201
|
-
|
|
1202
|
-
this.plugins.bootstrap();
|
|
1203
|
-
}
|
|
1463
|
+
_eventQueue = [];
|
|
1204
1464
|
/**
|
|
1205
|
-
*
|
|
1465
|
+
* @internal
|
|
1466
|
+
* Flag indicating if an event is currently being processed
|
|
1206
1467
|
*/
|
|
1207
|
-
|
|
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
|
-
}
|
|
1468
|
+
_isProcessingEvent = !1;
|
|
1261
1469
|
/**
|
|
1262
1470
|
* Registers an event handler for a specific event type.
|
|
1263
1471
|
* This method is typically called in the constructor of a derived Bloc class.
|
|
@@ -1265,14 +1473,35 @@ class j extends k {
|
|
|
1265
1473
|
* @param handler A function that processes the event and can emit new states.
|
|
1266
1474
|
* The 'event' parameter in the handler will be typed to the specific eventConstructor.
|
|
1267
1475
|
*/
|
|
1268
|
-
on(
|
|
1269
|
-
this.eventHandlers.has(
|
|
1270
|
-
`[Bloc ${this._name}:${String(this._id)}] Handler for event '${
|
|
1476
|
+
on(e, t) {
|
|
1477
|
+
this.eventHandlers.has(e) && o.warn(
|
|
1478
|
+
`[Bloc ${this._name}:${String(this._id)}] Handler for event '${e.name}' already registered. It will be overwritten.`
|
|
1271
1479
|
), this.eventHandlers.set(
|
|
1272
|
-
|
|
1273
|
-
|
|
1480
|
+
e,
|
|
1481
|
+
t
|
|
1274
1482
|
);
|
|
1275
1483
|
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Dispatches an action/event to the Bloc.
|
|
1486
|
+
* Events are queued and processed sequentially to prevent race conditions.
|
|
1487
|
+
* @param action The action/event instance to be processed.
|
|
1488
|
+
*/
|
|
1489
|
+
add = async (e) => {
|
|
1490
|
+
let t = e;
|
|
1491
|
+
try {
|
|
1492
|
+
t = this._plugins.transformEvent(e);
|
|
1493
|
+
} catch (s) {
|
|
1494
|
+
console.error("Error transforming event:", s);
|
|
1495
|
+
}
|
|
1496
|
+
if (t !== null) {
|
|
1497
|
+
try {
|
|
1498
|
+
this._plugins.notifyEvent(t);
|
|
1499
|
+
} catch (s) {
|
|
1500
|
+
console.error("Error notifying plugins of event:", s);
|
|
1501
|
+
}
|
|
1502
|
+
o.instance.plugins.notifyEventAdded(this, t), this._eventQueue.push(t), this._isProcessingEvent || await this._processEventQueue();
|
|
1503
|
+
}
|
|
1504
|
+
};
|
|
1276
1505
|
/**
|
|
1277
1506
|
* @internal
|
|
1278
1507
|
* Processes events from the queue sequentially
|
|
@@ -1282,8 +1511,8 @@ class j extends k {
|
|
|
1282
1511
|
this._isProcessingEvent = !0;
|
|
1283
1512
|
try {
|
|
1284
1513
|
for (; this._eventQueue.length > 0; ) {
|
|
1285
|
-
const
|
|
1286
|
-
await this._processEvent(
|
|
1514
|
+
const e = this._eventQueue.shift();
|
|
1515
|
+
await this._processEvent(e);
|
|
1287
1516
|
}
|
|
1288
1517
|
} finally {
|
|
1289
1518
|
this._isProcessingEvent = !1;
|
|
@@ -1294,68 +1523,59 @@ class j extends k {
|
|
|
1294
1523
|
* @internal
|
|
1295
1524
|
* Processes a single event
|
|
1296
1525
|
*/
|
|
1297
|
-
async _processEvent(
|
|
1298
|
-
const
|
|
1299
|
-
if (
|
|
1300
|
-
const
|
|
1526
|
+
async _processEvent(e) {
|
|
1527
|
+
const t = e.constructor, s = this.eventHandlers.get(t);
|
|
1528
|
+
if (s) {
|
|
1529
|
+
const i = (n) => {
|
|
1301
1530
|
const a = this.state;
|
|
1302
|
-
this._pushState(
|
|
1531
|
+
this._pushState(n, a, e);
|
|
1303
1532
|
};
|
|
1304
1533
|
try {
|
|
1305
|
-
await
|
|
1306
|
-
} catch (
|
|
1307
|
-
const a =
|
|
1534
|
+
await s(e, i);
|
|
1535
|
+
} catch (n) {
|
|
1536
|
+
const a = e.constructor.name || "UnnamedConstructor", c = {
|
|
1308
1537
|
blocName: this._name,
|
|
1309
1538
|
blocId: String(this._id),
|
|
1310
1539
|
eventType: a,
|
|
1311
1540
|
currentState: this.state,
|
|
1312
|
-
action:
|
|
1541
|
+
action: e,
|
|
1313
1542
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1314
1543
|
};
|
|
1315
|
-
if (
|
|
1544
|
+
if (o.error(
|
|
1316
1545
|
`[Bloc ${this._name}:${String(this._id)}] Error in event handler for '${a}':`,
|
|
1317
|
-
|
|
1546
|
+
n,
|
|
1318
1547
|
"Context:",
|
|
1319
|
-
|
|
1320
|
-
),
|
|
1548
|
+
c
|
|
1549
|
+
), n instanceof Error)
|
|
1321
1550
|
try {
|
|
1322
|
-
this._plugins.notifyError(
|
|
1551
|
+
this._plugins.notifyError(n, {
|
|
1323
1552
|
phase: "event-processing",
|
|
1324
1553
|
operation: "handler",
|
|
1325
|
-
metadata: { event:
|
|
1326
|
-
}),
|
|
1554
|
+
metadata: { event: e }
|
|
1555
|
+
}), o.instance.plugins.notifyError(n, this, {
|
|
1327
1556
|
phase: "event-processing",
|
|
1328
1557
|
operation: "handler",
|
|
1329
|
-
metadata: { event:
|
|
1558
|
+
metadata: { event: e }
|
|
1330
1559
|
});
|
|
1331
|
-
} catch (
|
|
1332
|
-
console.error("Error notifying plugins:",
|
|
1560
|
+
} catch (l) {
|
|
1561
|
+
console.error("Error notifying plugins:", l);
|
|
1333
1562
|
}
|
|
1334
|
-
if (
|
|
1335
|
-
throw
|
|
1563
|
+
if (n instanceof Error && n.name === "CriticalError")
|
|
1564
|
+
throw n;
|
|
1336
1565
|
}
|
|
1337
1566
|
} else {
|
|
1338
|
-
const
|
|
1339
|
-
|
|
1340
|
-
`[Bloc ${this._name}:${String(this._id)}] No handler registered for action type: '${
|
|
1567
|
+
const i = e.constructor.name || "UnnamedConstructor";
|
|
1568
|
+
o.warn(
|
|
1569
|
+
`[Bloc ${this._name}:${String(this._id)}] No handler registered for action type: '${i}'.`,
|
|
1341
1570
|
"Registered handlers:",
|
|
1342
|
-
Array.from(this.eventHandlers.keys()).map((
|
|
1571
|
+
Array.from(this.eventHandlers.keys()).map((n) => n.name),
|
|
1343
1572
|
"Action was:",
|
|
1344
|
-
|
|
1573
|
+
e
|
|
1345
1574
|
);
|
|
1346
1575
|
}
|
|
1347
1576
|
}
|
|
1348
1577
|
}
|
|
1349
|
-
class
|
|
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
|
-
}
|
|
1578
|
+
class O extends C {
|
|
1359
1579
|
/**
|
|
1360
1580
|
* Updates the current state and notifies all observers of the change.
|
|
1361
1581
|
* If the new state is identical to the current state (using Object.is),
|
|
@@ -1378,7 +1598,7 @@ class z extends k {
|
|
|
1378
1598
|
*/
|
|
1379
1599
|
patch(e, t = !1) {
|
|
1380
1600
|
if (typeof this.state != "object" || this.state === null) {
|
|
1381
|
-
|
|
1601
|
+
o.warn(
|
|
1382
1602
|
"Cubit.patch: was called on a cubit where the state is not an object. This is a no-op."
|
|
1383
1603
|
);
|
|
1384
1604
|
return;
|
|
@@ -1387,10 +1607,10 @@ class z extends k {
|
|
|
1387
1607
|
if (t)
|
|
1388
1608
|
s = !0;
|
|
1389
1609
|
else
|
|
1390
|
-
for (const
|
|
1391
|
-
if (Object.prototype.hasOwnProperty.call(e,
|
|
1392
|
-
const
|
|
1393
|
-
if (!Object.is(e[
|
|
1610
|
+
for (const i in e)
|
|
1611
|
+
if (Object.prototype.hasOwnProperty.call(e, i)) {
|
|
1612
|
+
const a = this.state[i];
|
|
1613
|
+
if (!Object.is(e[i], a)) {
|
|
1394
1614
|
s = !0;
|
|
1395
1615
|
break;
|
|
1396
1616
|
}
|
|
@@ -1406,107 +1626,232 @@ class L {
|
|
|
1406
1626
|
this.props = e;
|
|
1407
1627
|
}
|
|
1408
1628
|
}
|
|
1409
|
-
function
|
|
1410
|
-
if (Object.is(
|
|
1629
|
+
function V(r, e) {
|
|
1630
|
+
if (Object.is(r, e))
|
|
1411
1631
|
return !0;
|
|
1412
|
-
if (typeof
|
|
1632
|
+
if (typeof r != "object" || r === null || typeof e != "object" || e === null)
|
|
1413
1633
|
return !1;
|
|
1414
|
-
const t = Object.keys(
|
|
1634
|
+
const t = Object.keys(r), s = Object.keys(e);
|
|
1415
1635
|
if (t.length !== s.length)
|
|
1416
1636
|
return !1;
|
|
1417
|
-
for (let
|
|
1418
|
-
const n = t[
|
|
1419
|
-
if (!Object.prototype.hasOwnProperty.call(e, n) || !Object.is(
|
|
1637
|
+
for (let i = 0; i < t.length; i++) {
|
|
1638
|
+
const n = t[i];
|
|
1639
|
+
if (!Object.prototype.hasOwnProperty.call(e, n) || !Object.is(r[n], e[n]))
|
|
1420
1640
|
return !1;
|
|
1421
1641
|
}
|
|
1422
1642
|
return !0;
|
|
1423
1643
|
}
|
|
1424
|
-
|
|
1644
|
+
function N(r) {
|
|
1645
|
+
if (!r || typeof r != "object")
|
|
1646
|
+
return;
|
|
1647
|
+
const e = [];
|
|
1648
|
+
for (const [s, i] of Object.entries(r)) {
|
|
1649
|
+
const n = typeof i;
|
|
1650
|
+
(n === "string" || n === "number" || n === "boolean" || i === null || i === void 0) && e.push([s, i]);
|
|
1651
|
+
}
|
|
1652
|
+
if (e.length === 0)
|
|
1653
|
+
return;
|
|
1654
|
+
e.sort(([s], [i]) => s.localeCompare(i));
|
|
1655
|
+
const t = [];
|
|
1656
|
+
for (const [s, i] of e)
|
|
1657
|
+
i === null ? t.push(`${s}:null`) : i === void 0 ? t.push(`${s}:undefined`) : t.push(`${s}:${String(i)}`);
|
|
1658
|
+
return t.join("|");
|
|
1659
|
+
}
|
|
1660
|
+
class F {
|
|
1661
|
+
static componentRenderCounts = /* @__PURE__ */ new Map();
|
|
1662
|
+
static lastRenderTimestamps = /* @__PURE__ */ new Map();
|
|
1663
|
+
static groupedLogs = /* @__PURE__ */ new Map();
|
|
1664
|
+
static groupTimeouts = /* @__PURE__ */ new Map();
|
|
1665
|
+
/**
|
|
1666
|
+
* Log a component rerender with detailed information
|
|
1667
|
+
*/
|
|
1668
|
+
static logRerender(e) {
|
|
1669
|
+
const t = o._config?.rerenderLogging;
|
|
1670
|
+
if (!t) return;
|
|
1671
|
+
const s = this.parseConfig(t);
|
|
1672
|
+
if (!s.enabled || s.filter && !s.filter({
|
|
1673
|
+
componentName: e.componentName,
|
|
1674
|
+
blocName: e.blocName
|
|
1675
|
+
}))
|
|
1676
|
+
return;
|
|
1677
|
+
const i = `${e.componentName}-${e.blocId}`, n = this.componentRenderCounts.get(i) || 0;
|
|
1678
|
+
this.componentRenderCounts.set(i, n + 1), e.renderCount = n + 1;
|
|
1679
|
+
const a = this.lastRenderTimestamps.get(i);
|
|
1680
|
+
a && (e.duration = e.timestamp - a), this.lastRenderTimestamps.set(i, e.timestamp), s.includeStackTrace && s.level === "detailed" && (e.stackTrace = new Error().stack), s.groupRerenders ? this.logGrouped(e, s) : this.logImmediate(e, s);
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Parse the logging configuration
|
|
1684
|
+
*/
|
|
1685
|
+
static parseConfig(e) {
|
|
1686
|
+
return e === !0 ? { enabled: !0, level: "normal" } : typeof e == "string" ? {
|
|
1687
|
+
enabled: !0,
|
|
1688
|
+
level: e === "minimal" ? "minimal" : "detailed"
|
|
1689
|
+
} : {
|
|
1690
|
+
enabled: e.enabled,
|
|
1691
|
+
level: e.level || "normal",
|
|
1692
|
+
filter: e.filter,
|
|
1693
|
+
includeStackTrace: e.includeStackTrace,
|
|
1694
|
+
groupRerenders: e.groupRerenders
|
|
1695
|
+
};
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* Log immediately without grouping
|
|
1699
|
+
*/
|
|
1700
|
+
static logImmediate(e, t) {
|
|
1701
|
+
const s = this.formatMessage(e, t.level);
|
|
1702
|
+
t.level === "detailed" ? (console.group(s.header), s.details && console.log(s.details), s.values && console.table(s.values), e.stackTrace && console.log("Stack trace:", e.stackTrace), console.groupEnd()) : console.log(s.header, s.details || "");
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Log with grouping (batch multiple rerenders)
|
|
1706
|
+
*/
|
|
1707
|
+
static logGrouped(e, t) {
|
|
1708
|
+
const s = `${e.componentName}-${e.blocId}`, i = this.groupTimeouts.get(s);
|
|
1709
|
+
i && clearTimeout(i);
|
|
1710
|
+
const n = this.groupedLogs.get(s) || [];
|
|
1711
|
+
n.push(e), this.groupedLogs.set(s, n);
|
|
1712
|
+
const a = setTimeout(() => {
|
|
1713
|
+
const c = this.groupedLogs.get(s) || [];
|
|
1714
|
+
this.groupedLogs.delete(s), this.groupTimeouts.delete(s), c.length === 1 ? this.logImmediate(c[0], t) : (console.group(
|
|
1715
|
+
`🔄 ${e.componentName} rendered ${c.length} times (${e.blocName})`
|
|
1716
|
+
), c.forEach((l, h) => {
|
|
1717
|
+
const p = this.formatMessage(l, t.level);
|
|
1718
|
+
console.log(` ${h + 1}. ${p.details || p.header}`);
|
|
1719
|
+
}), console.groupEnd());
|
|
1720
|
+
}, 50);
|
|
1721
|
+
this.groupTimeouts.set(s, a);
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Format the log message based on level
|
|
1725
|
+
*/
|
|
1726
|
+
static formatMessage(e, t) {
|
|
1727
|
+
const s = this.getReasonEmoji(e.reason.type);
|
|
1728
|
+
if (t === "minimal")
|
|
1729
|
+
return {
|
|
1730
|
+
header: `${s} ${e.componentName} #${e.renderCount}`,
|
|
1731
|
+
details: null,
|
|
1732
|
+
values: null
|
|
1733
|
+
};
|
|
1734
|
+
const i = `${s} ${e.componentName} rerender #${e.renderCount} (${e.blocName})`;
|
|
1735
|
+
let n = `Reason: ${e.reason.description || e.reason.type}`;
|
|
1736
|
+
e.duration !== void 0 && (n += ` | Time since last: ${e.duration}ms`), t === "normal" && e.reason.changedPaths && e.reason.changedPaths.length > 0 && (n += ` | Changed: ${e.reason.changedPaths.join(", ")}`);
|
|
1737
|
+
let a = null;
|
|
1738
|
+
return t === "detailed" && e.reason.changedPaths && e.reason.changedPaths.length > 0 && (a = {}, e.reason.changedPaths.forEach((c) => {
|
|
1739
|
+
a[c] = {
|
|
1740
|
+
old: e.reason.oldValues?.[c],
|
|
1741
|
+
new: e.reason.newValues?.[c]
|
|
1742
|
+
};
|
|
1743
|
+
}), Object.keys(a).length === 0 && (a = null)), { header: i, details: n, values: a };
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* Get emoji for reason type
|
|
1747
|
+
*/
|
|
1748
|
+
static getReasonEmoji(e) {
|
|
1749
|
+
switch (e) {
|
|
1750
|
+
case "state-change":
|
|
1751
|
+
return "📊";
|
|
1752
|
+
case "dependency-change":
|
|
1753
|
+
return "🔗";
|
|
1754
|
+
case "mount":
|
|
1755
|
+
return "🚀";
|
|
1756
|
+
case "props-change":
|
|
1757
|
+
return "📦";
|
|
1758
|
+
default:
|
|
1759
|
+
return "🔄";
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Clear all tracking data
|
|
1764
|
+
*/
|
|
1765
|
+
static clear() {
|
|
1766
|
+
this.componentRenderCounts.clear(), this.lastRenderTimestamps.clear(), this.groupedLogs.clear(), this.groupTimeouts.forEach((e) => clearTimeout(e)), this.groupTimeouts.clear();
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Get render count for a component
|
|
1770
|
+
*/
|
|
1771
|
+
static getRenderCount(e, t) {
|
|
1772
|
+
return this.componentRenderCounts.get(`${e}-${t}`) || 0;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
class j {
|
|
1776
|
+
static originalInstance;
|
|
1425
1777
|
/**
|
|
1426
1778
|
* Sets up a clean test environment
|
|
1427
1779
|
*/
|
|
1428
1780
|
static setUp() {
|
|
1429
|
-
this.originalInstance =
|
|
1781
|
+
this.originalInstance = o.instance, o.resetInstance(), o.enableLog = !1;
|
|
1430
1782
|
}
|
|
1431
1783
|
/**
|
|
1432
1784
|
* Tears down the test environment and restores original state
|
|
1433
1785
|
*/
|
|
1434
1786
|
static tearDown() {
|
|
1435
|
-
|
|
1787
|
+
o.resetInstance();
|
|
1436
1788
|
}
|
|
1437
1789
|
/**
|
|
1438
1790
|
* Creates a test bloc with automatic cleanup
|
|
1439
1791
|
*/
|
|
1440
1792
|
static createBloc(e, ...t) {
|
|
1441
1793
|
const s = new e(...t);
|
|
1442
|
-
return
|
|
1794
|
+
return o.activateBloc(s), s;
|
|
1443
1795
|
}
|
|
1444
1796
|
/**
|
|
1445
1797
|
* Waits for a bloc to emit a specific state
|
|
1446
1798
|
*/
|
|
1447
1799
|
static async waitForState(e, t, s = 5e3) {
|
|
1448
|
-
return new Promise((
|
|
1449
|
-
const
|
|
1800
|
+
return new Promise((i, n) => {
|
|
1801
|
+
const a = setTimeout(() => {
|
|
1450
1802
|
n(
|
|
1451
1803
|
new Error(
|
|
1452
1804
|
`Timeout waiting for state matching predicate after ${s}ms`
|
|
1453
1805
|
)
|
|
1454
1806
|
);
|
|
1455
|
-
}, s),
|
|
1456
|
-
|
|
1457
|
-
fn: (l) => {
|
|
1458
|
-
t(l) && (clearTimeout(o), a(), r(l));
|
|
1459
|
-
}
|
|
1807
|
+
}, s), c = e.subscribe((l) => {
|
|
1808
|
+
t(l) && (clearTimeout(a), c(), i(l));
|
|
1460
1809
|
});
|
|
1461
|
-
t(e.state) && (clearTimeout(
|
|
1810
|
+
t(e.state) && (clearTimeout(a), c(), i(e.state));
|
|
1462
1811
|
});
|
|
1463
1812
|
}
|
|
1464
1813
|
/**
|
|
1465
1814
|
* Expects a bloc to emit specific states in order
|
|
1466
1815
|
*/
|
|
1467
1816
|
static async expectStates(e, t, s = 5e3) {
|
|
1468
|
-
const
|
|
1469
|
-
return new Promise((n,
|
|
1470
|
-
const
|
|
1471
|
-
|
|
1817
|
+
const i = [];
|
|
1818
|
+
return new Promise((n, a) => {
|
|
1819
|
+
const c = setTimeout(() => {
|
|
1820
|
+
a(
|
|
1472
1821
|
new Error(
|
|
1473
|
-
`Timeout waiting for states. Expected: ${JSON.stringify(t)}, Received: ${JSON.stringify(
|
|
1822
|
+
`Timeout waiting for states. Expected: ${JSON.stringify(t)}, Received: ${JSON.stringify(i)}`
|
|
1474
1823
|
)
|
|
1475
1824
|
);
|
|
1476
|
-
}, s), l = e.
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
);
|
|
1489
|
-
return;
|
|
1490
|
-
}
|
|
1825
|
+
}, s), l = e.subscribe((h) => {
|
|
1826
|
+
if (i.push(h), i.length === t.length) {
|
|
1827
|
+
clearTimeout(c), l();
|
|
1828
|
+
for (let p = 0; p < t.length; p++) {
|
|
1829
|
+
const S = t[p], k = i[p];
|
|
1830
|
+
if (JSON.stringify(S) !== JSON.stringify(k)) {
|
|
1831
|
+
a(
|
|
1832
|
+
new Error(
|
|
1833
|
+
`State mismatch at index ${p}. Expected: ${JSON.stringify(S)}, Received: ${JSON.stringify(k)}`
|
|
1834
|
+
)
|
|
1835
|
+
);
|
|
1836
|
+
return;
|
|
1491
1837
|
}
|
|
1492
|
-
n();
|
|
1493
1838
|
}
|
|
1839
|
+
n();
|
|
1494
1840
|
}
|
|
1495
1841
|
});
|
|
1496
1842
|
});
|
|
1497
1843
|
}
|
|
1498
1844
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
constructor(
|
|
1502
|
-
super(
|
|
1503
|
-
i(this, "mockHandlers", /* @__PURE__ */ new Map());
|
|
1845
|
+
class z extends R {
|
|
1846
|
+
mockHandlers = /* @__PURE__ */ new Map();
|
|
1847
|
+
constructor(e) {
|
|
1848
|
+
super(e);
|
|
1504
1849
|
}
|
|
1505
1850
|
/**
|
|
1506
1851
|
* Mock an event handler for testing
|
|
1507
1852
|
*/
|
|
1508
|
-
mockEventHandler(
|
|
1509
|
-
this.on(
|
|
1853
|
+
mockEventHandler(e, t) {
|
|
1854
|
+
this.on(e, t);
|
|
1510
1855
|
}
|
|
1511
1856
|
/**
|
|
1512
1857
|
* Get the number of registered handlers
|
|
@@ -1517,21 +1862,20 @@ class F extends j {
|
|
|
1517
1862
|
/**
|
|
1518
1863
|
* Check if a handler is registered for an event type
|
|
1519
1864
|
*/
|
|
1520
|
-
hasHandler(
|
|
1521
|
-
return this.eventHandlers.has(
|
|
1865
|
+
hasHandler(e) {
|
|
1866
|
+
return this.eventHandlers.has(e);
|
|
1522
1867
|
}
|
|
1523
1868
|
}
|
|
1524
|
-
class
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
this.stateHistory.push(t);
|
|
1869
|
+
class q extends O {
|
|
1870
|
+
stateHistory = [];
|
|
1871
|
+
constructor(e) {
|
|
1872
|
+
super(e), this.stateHistory.push(e);
|
|
1529
1873
|
}
|
|
1530
1874
|
/**
|
|
1531
1875
|
* Override emit to track state history
|
|
1532
1876
|
*/
|
|
1533
|
-
emit(
|
|
1534
|
-
this.stateHistory.push(
|
|
1877
|
+
emit(e) {
|
|
1878
|
+
this.stateHistory.push(e), super.emit(e);
|
|
1535
1879
|
}
|
|
1536
1880
|
/**
|
|
1537
1881
|
* Get the history of all states
|
|
@@ -1546,16 +1890,16 @@ class G extends z {
|
|
|
1546
1890
|
this.stateHistory = [this.state];
|
|
1547
1891
|
}
|
|
1548
1892
|
}
|
|
1549
|
-
class
|
|
1893
|
+
class W {
|
|
1894
|
+
initialStats;
|
|
1550
1895
|
constructor() {
|
|
1551
|
-
|
|
1552
|
-
this.initialStats = u.getMemoryStats();
|
|
1896
|
+
this.initialStats = o.getMemoryStats();
|
|
1553
1897
|
}
|
|
1554
1898
|
/**
|
|
1555
1899
|
* Check for memory leaks and return a report
|
|
1556
1900
|
*/
|
|
1557
1901
|
checkForLeaks() {
|
|
1558
|
-
const e =
|
|
1902
|
+
const e = o.getMemoryStats(), t = e.registeredBlocs > this.initialStats.registeredBlocs || e.isolatedBlocs > this.initialStats.isolatedBlocs || e.keepAliveBlocs > this.initialStats.keepAliveBlocs, s = `
|
|
1559
1903
|
Memory Leak Detection Report:
|
|
1560
1904
|
- Initial registered blocs: ${this.initialStats.registeredBlocs}
|
|
1561
1905
|
- Current registered blocs: ${e.registeredBlocs}
|
|
@@ -1572,421 +1916,360 @@ Memory Leak Detection Report:
|
|
|
1572
1916
|
};
|
|
1573
1917
|
}
|
|
1574
1918
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1919
|
+
const I = /* @__PURE__ */ new WeakMap(), d = {
|
|
1920
|
+
stateProxiesCreated: 0,
|
|
1921
|
+
classProxiesCreated: 0,
|
|
1922
|
+
cacheHits: 0,
|
|
1923
|
+
cacheMisses: 0,
|
|
1924
|
+
totalProxiesCreated: 0
|
|
1925
|
+
}, _ = (r, e, t, s = "") => {
|
|
1926
|
+
if (!e || !t || typeof r != "object" || r === null)
|
|
1927
|
+
return r;
|
|
1928
|
+
if (!s) {
|
|
1929
|
+
let n = I.get(r);
|
|
1930
|
+
n || (n = /* @__PURE__ */ new WeakMap(), I.set(r, n));
|
|
1931
|
+
const a = n.get(e);
|
|
1932
|
+
if (a)
|
|
1933
|
+
return d.cacheHits++, a;
|
|
1934
|
+
d.cacheMisses++;
|
|
1935
|
+
}
|
|
1936
|
+
const i = new Proxy(r, {
|
|
1937
|
+
get(n, a) {
|
|
1938
|
+
if (typeof a == "symbol" || a === "constructor")
|
|
1939
|
+
return Reflect.get(n, a);
|
|
1940
|
+
const c = s ? `${s}.${a}` : a, l = Reflect.get(n, a), h = l && typeof l == "object";
|
|
1941
|
+
return t.trackAccess(
|
|
1942
|
+
e,
|
|
1943
|
+
"state",
|
|
1944
|
+
c,
|
|
1945
|
+
h ? void 0 : l
|
|
1946
|
+
), h && (Array.isArray(l) || Object.getPrototypeOf(l) === Object.prototype) ? _(l, e, t, c) : l;
|
|
1947
|
+
},
|
|
1948
|
+
set: () => !1,
|
|
1949
|
+
// State should be immutable
|
|
1950
|
+
deleteProperty: () => !1
|
|
1951
|
+
// State properties should not be deleted
|
|
1952
|
+
});
|
|
1953
|
+
return s || (I.get(r).set(e, i), d.stateProxiesCreated++, d.totalProxiesCreated++), i;
|
|
1954
|
+
}, M = (r, e, t) => {
|
|
1955
|
+
if (!e || !t)
|
|
1956
|
+
return r;
|
|
1957
|
+
let s = I.get(r);
|
|
1958
|
+
s || (s = /* @__PURE__ */ new WeakMap(), I.set(r, s));
|
|
1959
|
+
const i = s.get(e);
|
|
1960
|
+
if (i)
|
|
1961
|
+
return d.cacheHits++, i;
|
|
1962
|
+
d.cacheMisses++;
|
|
1963
|
+
const n = new Proxy(r, {
|
|
1964
|
+
get(a, c) {
|
|
1965
|
+
const l = Reflect.get(a, c);
|
|
1966
|
+
if (U(a, c)?.get) {
|
|
1967
|
+
const p = l !== null && typeof l != "object";
|
|
1968
|
+
t.trackAccess(
|
|
1969
|
+
e,
|
|
1970
|
+
"class",
|
|
1971
|
+
String(c),
|
|
1972
|
+
p ? l : void 0
|
|
1973
|
+
);
|
|
1974
|
+
}
|
|
1975
|
+
return l;
|
|
1976
|
+
}
|
|
1977
|
+
});
|
|
1978
|
+
return s.set(e, n), d.classProxiesCreated++, d.totalProxiesCreated++, n;
|
|
1979
|
+
}, U = (r, e, t = 10) => {
|
|
1980
|
+
let s = r, i = 0;
|
|
1981
|
+
for (; s && i < t; ) {
|
|
1982
|
+
const n = Object.getOwnPropertyDescriptor(s, e);
|
|
1983
|
+
if (n) return n;
|
|
1984
|
+
s = Object.getPrototypeOf(s), i++;
|
|
1985
|
+
}
|
|
1986
|
+
}, $ = {
|
|
1987
|
+
createStateProxy: (r) => _(
|
|
1988
|
+
r.target,
|
|
1989
|
+
r.consumerRef,
|
|
1990
|
+
r.consumerTracker,
|
|
1991
|
+
r.path
|
|
1992
|
+
),
|
|
1993
|
+
createClassProxy: (r) => M(
|
|
1994
|
+
r.target,
|
|
1995
|
+
r.consumerRef,
|
|
1996
|
+
r.consumerTracker
|
|
1997
|
+
),
|
|
1998
|
+
getProxyState: (r) => _(
|
|
1999
|
+
r.state,
|
|
2000
|
+
r.consumerRef,
|
|
2001
|
+
r.consumerTracker
|
|
2002
|
+
),
|
|
2003
|
+
getProxyBlocInstance: (r) => M(
|
|
2004
|
+
r.blocInstance,
|
|
2005
|
+
r.consumerRef,
|
|
2006
|
+
r.consumerTracker
|
|
2007
|
+
),
|
|
2008
|
+
// Compatibility functions that return expected structure
|
|
2009
|
+
getStats: () => ({
|
|
2010
|
+
...d,
|
|
2011
|
+
propertyAccesses: 0,
|
|
2012
|
+
nestedProxiesCreated: 0,
|
|
2013
|
+
cacheEfficiency: d.cacheHits + d.cacheMisses > 0 ? `${(d.cacheHits / (d.cacheHits + d.cacheMisses) * 100).toFixed(1)}%` : "N/A",
|
|
2014
|
+
lifetime: "0ms",
|
|
2015
|
+
proxiesPerSecond: "N/A"
|
|
2016
|
+
}),
|
|
2017
|
+
resetStats: () => {
|
|
2018
|
+
d.stateProxiesCreated = 0, d.classProxiesCreated = 0, d.cacheHits = 0, d.cacheMisses = 0, d.totalProxiesCreated = 0;
|
|
1580
2019
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
2020
|
+
};
|
|
2021
|
+
class G {
|
|
2022
|
+
id = `adapter-${A()}`;
|
|
2023
|
+
blocConstructor;
|
|
2024
|
+
componentRef = { current: {} };
|
|
2025
|
+
blocInstance;
|
|
2026
|
+
unmountTime = 0;
|
|
2027
|
+
mountTime = 0;
|
|
2028
|
+
// Subscription management
|
|
2029
|
+
subscriptionId;
|
|
2030
|
+
unsubscribe;
|
|
2031
|
+
// Dependency tracking
|
|
2032
|
+
dependencyValues;
|
|
2033
|
+
isUsingDependencies = !1;
|
|
2034
|
+
trackedPaths = /* @__PURE__ */ new Set();
|
|
2035
|
+
pendingTrackedPaths = /* @__PURE__ */ new Set();
|
|
2036
|
+
// Paths tracked before subscription exists
|
|
2037
|
+
// Proxy caching
|
|
2038
|
+
cachedStateProxy;
|
|
2039
|
+
cachedBlocProxy;
|
|
2040
|
+
lastProxiedState;
|
|
2041
|
+
// Lifecycle state
|
|
2042
|
+
hasMounted = !1;
|
|
2043
|
+
mountCount = 0;
|
|
2044
|
+
// Rerender tracking
|
|
2045
|
+
lastState;
|
|
2046
|
+
lastDependencyValues;
|
|
2047
|
+
componentName;
|
|
2048
|
+
renderCount = 0;
|
|
2049
|
+
lastDependenciesFn;
|
|
2050
|
+
options;
|
|
2051
|
+
constructor(e, t) {
|
|
2052
|
+
this.options = t, this.blocConstructor = e.blocConstructor, this.componentRef = e.componentRef, this.isUsingDependencies = !!t?.dependencies, this.updateBlocInstance(), this.isUsingDependencies && t?.dependencies && (this.dependencyValues = t.dependencies(this.blocInstance));
|
|
2053
|
+
const s = this.getAdapterMetadata();
|
|
2054
|
+
o.getInstance().plugins.notifyAdapterCreated(this, s);
|
|
1594
2055
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
2056
|
+
trackAccess(e, t, s, i) {
|
|
2057
|
+
const n = t === "class" ? `_class.${s}` : s;
|
|
2058
|
+
this.trackedPaths.add(n), this.subscriptionId ? this.blocInstance.trackAccess(this.subscriptionId, n, i) : (this.pendingTrackedPaths.add(n), o.config.logLevel === "debug" && o.log(`[BlacAdapter] trackAccess storing pending path: ${s}`));
|
|
2059
|
+
}
|
|
2060
|
+
updateBlocInstance() {
|
|
2061
|
+
let e = this.options?.instanceId;
|
|
2062
|
+
if (!e && this.options?.staticProps) {
|
|
2063
|
+
const t = N(this.options.staticProps);
|
|
2064
|
+
t && (e = t);
|
|
2065
|
+
}
|
|
2066
|
+
return this.blocInstance = o.instance.getBloc(this.blocConstructor, {
|
|
2067
|
+
constructorParams: this.options?.staticProps,
|
|
2068
|
+
id: e,
|
|
2069
|
+
instanceRef: this.id
|
|
2070
|
+
}), this.blocInstance;
|
|
2071
|
+
}
|
|
2072
|
+
createSubscription = (e) => {
|
|
2073
|
+
if (this.isUsingDependencies && this.options?.dependencies)
|
|
2074
|
+
this.unsubscribe = this.blocInstance.subscribeWithSelector(
|
|
2075
|
+
(t) => this.options.dependencies(this.blocInstance),
|
|
2076
|
+
(t) => {
|
|
2077
|
+
this.hasDependencyValuesChanged(
|
|
2078
|
+
this.dependencyValues,
|
|
2079
|
+
t
|
|
2080
|
+
) && (this.dependencyValues = t, e.onChange());
|
|
2081
|
+
}
|
|
2082
|
+
);
|
|
2083
|
+
else {
|
|
2084
|
+
const t = new WeakRef(this.componentRef.current);
|
|
2085
|
+
this.unsubscribe = this.blocInstance.subscribeComponent(
|
|
2086
|
+
t,
|
|
2087
|
+
e.onChange
|
|
2088
|
+
);
|
|
2089
|
+
const s = this.blocInstance._subscriptionManager.subscriptions;
|
|
2090
|
+
if (this.subscriptionId = Array.from(s.keys()).pop(), this.subscriptionId && this.pendingTrackedPaths.size > 0) {
|
|
2091
|
+
for (const i of this.pendingTrackedPaths)
|
|
2092
|
+
this.blocInstance.trackAccess(this.subscriptionId, i);
|
|
2093
|
+
this.pendingTrackedPaths.clear();
|
|
1631
2094
|
}
|
|
1632
|
-
|
|
2095
|
+
}
|
|
2096
|
+
return () => {
|
|
2097
|
+
this.unsubscribe && (this.unsubscribe(), this.unsubscribe = void 0, this.subscriptionId = void 0);
|
|
2098
|
+
};
|
|
2099
|
+
};
|
|
2100
|
+
hasDependencyValuesChanged = (e, t) => {
|
|
2101
|
+
if (!e || e.length !== t.length) return !0;
|
|
2102
|
+
for (let s = 0; s < e.length; s++)
|
|
2103
|
+
if (!Object.is(e[s], t[s]))
|
|
2104
|
+
return !0;
|
|
2105
|
+
return !1;
|
|
2106
|
+
};
|
|
2107
|
+
getStateProxy = () => {
|
|
2108
|
+
if (this.isUsingDependencies || !o.config.proxyDependencyTracking)
|
|
2109
|
+
return this.blocInstance.state;
|
|
2110
|
+
const e = this.blocInstance.state;
|
|
2111
|
+
return this.cachedStateProxy && this.lastProxiedState === e ? this.cachedStateProxy : (this.lastProxiedState = e, this.cachedStateProxy = this.createStateProxy({ target: e }), this.cachedStateProxy);
|
|
2112
|
+
};
|
|
2113
|
+
getBlocProxy = () => this.isUsingDependencies || !o.config.proxyDependencyTracking ? this.blocInstance : this.cachedBlocProxy ? this.cachedBlocProxy : (this.cachedBlocProxy = this.createClassProxy({ target: this.blocInstance }), this.cachedBlocProxy);
|
|
2114
|
+
createStateProxy = (e) => $.createStateProxy({
|
|
2115
|
+
target: e.target,
|
|
2116
|
+
consumerRef: this.componentRef.current,
|
|
2117
|
+
consumerTracker: this
|
|
2118
|
+
});
|
|
2119
|
+
createClassProxy = (e) => $.createClassProxy({
|
|
2120
|
+
target: e.target,
|
|
2121
|
+
consumerRef: this.componentRef.current,
|
|
2122
|
+
consumerTracker: this
|
|
2123
|
+
});
|
|
2124
|
+
// Lifecycle methods
|
|
2125
|
+
mount = () => {
|
|
2126
|
+
this.hasMounted = !0, this.mountCount++, this.mountTime = Date.now(), this.options?.onMount && this.options.onMount(this.blocInstance), this.isUsingDependencies && this.options?.dependencies && (this.dependencyValues = this.options.dependencies(this.blocInstance));
|
|
2127
|
+
const e = this.getAdapterMetadata();
|
|
2128
|
+
o.getInstance().plugins.notifyAdapterMount(this, e);
|
|
2129
|
+
};
|
|
2130
|
+
unmount = () => {
|
|
2131
|
+
if (this.unmountTime = Date.now(), this.unsubscribe && (this.unsubscribe(), this.unsubscribe = void 0, this.subscriptionId = void 0), this.options?.onUnmount)
|
|
1633
2132
|
try {
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
lastAccessTime: o
|
|
1638
|
-
}), n = !0);
|
|
1639
|
-
} catch {
|
|
1640
|
-
n = !0;
|
|
2133
|
+
this.options.onUnmount(this.blocInstance);
|
|
2134
|
+
} catch (t) {
|
|
2135
|
+
console.error("Error in onUnmount hook:", t);
|
|
1641
2136
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
if (r.startsWith(n + ".") || n.startsWith(r + "."))
|
|
1651
|
-
return !0;
|
|
2137
|
+
const e = this.getAdapterMetadata();
|
|
2138
|
+
o.getInstance().plugins.notifyAdapterUnmount(this, e);
|
|
2139
|
+
};
|
|
2140
|
+
// Reset tracking for next render
|
|
2141
|
+
resetTracking() {
|
|
2142
|
+
if (this.trackedPaths.clear(), this.pendingTrackedPaths.clear(), this.subscriptionId) {
|
|
2143
|
+
const e = this.blocInstance._subscriptionManager.subscriptions.get(this.subscriptionId);
|
|
2144
|
+
e && e.dependencies && e.dependencies.clear();
|
|
1652
2145
|
}
|
|
1653
|
-
return !1;
|
|
1654
|
-
}
|
|
1655
|
-
updateLastNotified(e) {
|
|
1656
|
-
const t = this.consumers.get(e);
|
|
1657
|
-
t && (t.lastNotified = Date.now());
|
|
1658
2146
|
}
|
|
1659
|
-
|
|
1660
|
-
|
|
2147
|
+
// Set component name for rerender logging
|
|
2148
|
+
setComponentName(e) {
|
|
2149
|
+
this.componentName = e;
|
|
1661
2150
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
2151
|
+
// Notify plugins about render
|
|
2152
|
+
notifyRender() {
|
|
2153
|
+
this.renderCount++, this.isUsingDependencies && this.options?.dependencies && (this.lastDependencyValues = this.dependencyValues, this.dependencyValues = this.options.dependencies(this.blocInstance));
|
|
2154
|
+
const e = this.getAdapterMetadata();
|
|
2155
|
+
o.getInstance().plugins.notifyAdapterRender(this, e);
|
|
1665
2156
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
}
|
|
1669
|
-
getStats() {
|
|
2157
|
+
// Get adapter metadata for plugins
|
|
2158
|
+
getAdapterMetadata() {
|
|
1670
2159
|
return {
|
|
1671
|
-
|
|
1672
|
-
|
|
2160
|
+
componentName: this.componentName,
|
|
2161
|
+
blocInstance: this.blocInstance,
|
|
2162
|
+
renderCount: this.renderCount,
|
|
2163
|
+
trackedPaths: Array.from(this.trackedPaths),
|
|
2164
|
+
isUsingDependencies: this.isUsingDependencies,
|
|
2165
|
+
lastState: this.lastState,
|
|
2166
|
+
lastDependencyValues: this.lastDependencyValues,
|
|
2167
|
+
currentDependencyValues: this.dependencyValues
|
|
1673
2168
|
};
|
|
1674
2169
|
}
|
|
2170
|
+
// Get value at a dot-notated path
|
|
1675
2171
|
getValueAtPath(e, t) {
|
|
1676
2172
|
const s = t.split(".");
|
|
1677
|
-
let
|
|
2173
|
+
let i = e;
|
|
1678
2174
|
for (const n of s) {
|
|
1679
|
-
if (
|
|
1680
|
-
|
|
2175
|
+
if (i == null) return;
|
|
2176
|
+
i = i[n];
|
|
1681
2177
|
}
|
|
1682
|
-
return
|
|
2178
|
+
return i;
|
|
2179
|
+
}
|
|
2180
|
+
// Get paths that changed between states
|
|
2181
|
+
getStateChangedPaths(e, t) {
|
|
2182
|
+
const s = [];
|
|
2183
|
+
if (this.trackedPaths.size > 0)
|
|
2184
|
+
for (const i of this.trackedPaths) {
|
|
2185
|
+
if (i.startsWith("_class.")) continue;
|
|
2186
|
+
const n = this.getValueAtPath(e, i), a = this.getValueAtPath(t, i);
|
|
2187
|
+
Object.is(n, a) || s.push(i);
|
|
2188
|
+
}
|
|
2189
|
+
else if (e !== t) {
|
|
2190
|
+
const i = this.getDeepChangedPaths(e, t);
|
|
2191
|
+
if (i.length > 0)
|
|
2192
|
+
return i;
|
|
2193
|
+
s.push("(entire state)");
|
|
2194
|
+
}
|
|
2195
|
+
return s;
|
|
1683
2196
|
}
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
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;
|
|
2197
|
+
// Deep comparison to find all changed paths
|
|
2198
|
+
getDeepChangedPaths(e, t, s = "") {
|
|
2199
|
+
const i = [];
|
|
2200
|
+
if (e === t) return i;
|
|
2201
|
+
if (e == null || t == null)
|
|
2202
|
+
return i.push(s || "(root)"), i;
|
|
2203
|
+
if (typeof e != "object" || typeof t != "object")
|
|
2204
|
+
return e !== t && i.push(s || "(root)"), i;
|
|
2205
|
+
if (Array.isArray(e) || Array.isArray(t)) {
|
|
2206
|
+
if (!Array.isArray(e) || !Array.isArray(t) || e.length !== t.length)
|
|
2207
|
+
return i.push(s || "(root)"), i;
|
|
2208
|
+
for (let a = 0; a < e.length; a++) {
|
|
2209
|
+
const c = s ? `${s}[${a}]` : `[${a}]`;
|
|
2210
|
+
i.push(
|
|
2211
|
+
...this.getDeepChangedPaths(e[a], t[a], c)
|
|
2212
|
+
);
|
|
1740
2213
|
}
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
for (; g && !v && B < P && !A.has(g); ) {
|
|
1761
|
-
A.add(g);
|
|
1762
|
-
try {
|
|
1763
|
-
const C = Object.getOwnPropertyDescriptor(
|
|
1764
|
-
g,
|
|
1765
|
-
f
|
|
2214
|
+
return i;
|
|
2215
|
+
}
|
|
2216
|
+
const n = /* @__PURE__ */ new Set([...Object.keys(e), ...Object.keys(t)]);
|
|
2217
|
+
for (const a of n) {
|
|
2218
|
+
const c = s ? `${s}.${a}` : a;
|
|
2219
|
+
if (!(a in e))
|
|
2220
|
+
i.push(`${c} (added)`);
|
|
2221
|
+
else if (!(a in t))
|
|
2222
|
+
i.push(`${c} (removed)`);
|
|
2223
|
+
else {
|
|
2224
|
+
const l = e[a], h = t[a];
|
|
2225
|
+
if (!Object.is(l, h))
|
|
2226
|
+
if (typeof l != "object" || typeof h != "object" || l === null || h === null)
|
|
2227
|
+
i.push(c);
|
|
2228
|
+
else {
|
|
2229
|
+
const p = this.getDeepChangedPaths(
|
|
2230
|
+
l,
|
|
2231
|
+
h,
|
|
2232
|
+
c
|
|
1766
2233
|
);
|
|
1767
|
-
|
|
1768
|
-
v = !0;
|
|
1769
|
-
break;
|
|
1770
|
-
}
|
|
1771
|
-
g = Object.getPrototypeOf(g), B++;
|
|
1772
|
-
} catch {
|
|
1773
|
-
break;
|
|
2234
|
+
p.length > 0 ? i.push(...p) : i.push(c);
|
|
1774
2235
|
}
|
|
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
2236
|
}
|
|
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
2237
|
}
|
|
1958
|
-
|
|
2238
|
+
return i;
|
|
1959
2239
|
}
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
for (let s = 0; s < e.length; s++)
|
|
1963
|
-
if (!Object.is(e[s], t[s]))
|
|
1964
|
-
return !0;
|
|
1965
|
-
return !1;
|
|
2240
|
+
// Get last rerender reason
|
|
2241
|
+
getLastRerenderReason() {
|
|
1966
2242
|
}
|
|
1967
|
-
}
|
|
1968
|
-
// Props ownership tracking
|
|
1969
|
-
i(b, "propsOwners", /* @__PURE__ */ new WeakMap());
|
|
1970
|
-
let D = b;
|
|
2243
|
+
}
|
|
1971
2244
|
export {
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
2245
|
+
o as Blac,
|
|
2246
|
+
G as BlacAdapter,
|
|
2247
|
+
m as BlacError,
|
|
2248
|
+
R as Bloc,
|
|
2249
|
+
C as BlocBase,
|
|
2250
|
+
B as BlocLifecycleManager,
|
|
2251
|
+
u as BlocLifecycleState,
|
|
2252
|
+
w as BlocPluginRegistry,
|
|
2253
|
+
j as BlocTest,
|
|
2254
|
+
O as Cubit,
|
|
2255
|
+
P as DefaultErrorStrategy,
|
|
2256
|
+
v as ErrorCategory,
|
|
2257
|
+
f as ErrorManager,
|
|
2258
|
+
y as ErrorSeverity,
|
|
2259
|
+
W as MemoryLeakDetector,
|
|
2260
|
+
z as MockBloc,
|
|
2261
|
+
q as MockCubit,
|
|
1985
2262
|
L as PropsUpdated,
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2263
|
+
$ as ProxyFactory,
|
|
2264
|
+
F as RerenderLogger,
|
|
2265
|
+
E as SubscriptionManager,
|
|
2266
|
+
T as SystemPluginRegistry,
|
|
2267
|
+
M as createBlocProxy,
|
|
2268
|
+
_ as createStateProxy,
|
|
2269
|
+
N as generateInstanceIdFromProps,
|
|
2270
|
+
A as generateUUID,
|
|
2271
|
+
x as handleError,
|
|
2272
|
+
H as setBlacInstanceManager,
|
|
2273
|
+
V as shallowEqual
|
|
1991
2274
|
};
|
|
1992
2275
|
//# sourceMappingURL=index.es.js.map
|