@blac/core 2.0.0-rc-8 → 2.0.0-rc-11
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/README.md +27 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +224 -14
- package/dist/index.es.js +1122 -556
- package/dist/index.es.js.map +1 -1
- package/package.json +5 -4
- package/src/Blac.ts +109 -47
- package/src/BlacObserver.ts +58 -24
- package/src/Bloc.ts +120 -160
- package/src/BlocBase.ts +266 -90
- package/src/Cubit.ts +15 -1
- package/src/__tests__/Blac.config.test.ts +86 -0
- package/src/__tests__/Bloc.event.test.ts +419 -0
- package/src/__tests__/BlocBase.lifecycle.test.ts +441 -0
- package/src/__tests__/Cubit.test.ts +473 -0
- package/src/__tests__/props.test.ts +256 -0
- package/src/adapter/BlacAdapter.ts +327 -0
- package/src/adapter/ConsumerTracker.ts +241 -0
- package/src/adapter/ProxyFactory.ts +308 -0
- package/src/adapter/__tests__/BlacAdapter.test.ts +561 -0
- package/src/adapter/__tests__/ConsumerTracker.test.ts +562 -0
- package/src/adapter/__tests__/ProxyFactory.test.ts +655 -0
- package/src/adapter/index.ts +3 -0
- package/src/events.ts +3 -0
- package/src/index.ts +4 -1
- package/src/testing.ts +60 -47
- package/src/types.ts +12 -13
- package/src/utils/shallowEqual.ts +40 -0
- package/src/utils/uuid.ts +4 -4
- package/src/BlacEvent.ts +0 -5
package/dist/index.es.js
CHANGED
|
@@ -1,385 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var i = (
|
|
4
|
-
|
|
5
|
-
getInstance() {
|
|
6
|
-
return u._instance || (u._instance = new l({
|
|
7
|
-
__unsafe_ignore_singleton: !0
|
|
8
|
-
})), u._instance;
|
|
9
|
-
}
|
|
10
|
-
setInstance(e) {
|
|
11
|
-
u._instance = e;
|
|
12
|
-
}
|
|
13
|
-
resetInstance() {
|
|
14
|
-
const e = u._instance;
|
|
15
|
-
if (u._instance = new l({
|
|
16
|
-
__unsafe_ignore_singleton: !0
|
|
17
|
-
}), e)
|
|
18
|
-
for (const t of e.keepAliveBlocs)
|
|
19
|
-
u._instance.keepAliveBlocs.add(t), u._instance.uidRegistry.set(t.uid, t);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
i(u, "_instance");
|
|
23
|
-
let B = u, g = new B();
|
|
24
|
-
function A(d) {
|
|
25
|
-
g = d;
|
|
26
|
-
}
|
|
27
|
-
const r = class r {
|
|
28
|
-
/**
|
|
29
|
-
* Creates a new Blac instance.
|
|
30
|
-
* @param options - Configuration options including singleton control
|
|
31
|
-
*/
|
|
32
|
-
constructor(e = {}) {
|
|
33
|
-
/** Timestamp when the instance was created */
|
|
34
|
-
i(this, "createdAt", Date.now());
|
|
35
|
-
/** Map storing all registered bloc instances by their class name and ID */
|
|
36
|
-
i(this, "blocInstanceMap", /* @__PURE__ */ new Map());
|
|
37
|
-
/** Map storing isolated bloc instances grouped by their constructor */
|
|
38
|
-
// TODO: BlocConstructor<any> is required here for type inference to work correctly.
|
|
39
|
-
// Using BlocConstructor<BlocBase<unknown>> would break type inference when storing
|
|
40
|
-
// different bloc types in the same map. The 'any' allows proper polymorphic storage
|
|
41
|
-
// while maintaining type safety at usage sites through the BlocConstructor constraint.
|
|
42
|
-
i(this, "isolatedBlocMap", /* @__PURE__ */ new Map());
|
|
43
|
-
/** Map for O(1) lookup of isolated blocs by UID */
|
|
44
|
-
i(this, "isolatedBlocIndex", /* @__PURE__ */ new Map());
|
|
45
|
-
/** Map tracking UIDs to prevent memory leaks */
|
|
46
|
-
i(this, "uidRegistry", /* @__PURE__ */ new Map());
|
|
47
|
-
/** Set of keep-alive blocs for controlled cleanup */
|
|
48
|
-
i(this, "keepAliveBlocs", /* @__PURE__ */ new Set());
|
|
49
|
-
/** Flag to control whether changes should be posted to document */
|
|
50
|
-
i(this, "postChangesToDocument", !1);
|
|
51
|
-
/**
|
|
52
|
-
* Logs messages to console when logging is enabled
|
|
53
|
-
* @param args - Arguments to log
|
|
54
|
-
*/
|
|
55
|
-
i(this, "log", (...e) => {
|
|
56
|
-
r.enableLog && r.logLevel === "warn" && console.warn(`☢️ [Blac ${this.createdAt.toString()}]`, ...e), r.enableLog && r.logLevel === "log" && console.log(`☢️ [Blac ${this.createdAt.toString()}]`, ...e);
|
|
57
|
-
});
|
|
58
|
-
/**
|
|
59
|
-
* Logs a warning message
|
|
60
|
-
* @param message - Warning message
|
|
61
|
-
* @param args - Additional arguments
|
|
62
|
-
*/
|
|
63
|
-
i(this, "warn", (e, ...t) => {
|
|
64
|
-
r.enableLog && console.warn(
|
|
65
|
-
`🚨 [Blac ${String(r.instance.createdAt)}]`,
|
|
66
|
-
e,
|
|
67
|
-
...t
|
|
68
|
-
);
|
|
69
|
-
});
|
|
70
|
-
/**
|
|
71
|
-
* Logs an error message
|
|
72
|
-
* @param message - Error message
|
|
73
|
-
* @param args - Additional arguments
|
|
74
|
-
*/
|
|
75
|
-
i(this, "error", (e, ...t) => {
|
|
76
|
-
r.enableLog && console.error(
|
|
77
|
-
`🚨 [Blac ${String(r.instance.createdAt)}]`,
|
|
78
|
-
e,
|
|
79
|
-
...t
|
|
80
|
-
);
|
|
81
|
-
});
|
|
82
|
-
/**
|
|
83
|
-
* Resets the Blac instance to a new one, disposing non-keepAlive blocs
|
|
84
|
-
* from the old instance.
|
|
85
|
-
*/
|
|
86
|
-
i(this, "resetInstance", () => {
|
|
87
|
-
this.log("Reset Blac instance");
|
|
88
|
-
const e = new Map(this.blocInstanceMap), t = new Map(this.isolatedBlocMap);
|
|
89
|
-
e.forEach((s) => {
|
|
90
|
-
!s._keepAlive && s._disposalState === "active" && this.disposeBloc(s);
|
|
91
|
-
}), t.forEach((s) => {
|
|
92
|
-
s.forEach((n) => {
|
|
93
|
-
!n._keepAlive && n._disposalState === "active" && this.disposeBloc(n);
|
|
94
|
-
});
|
|
95
|
-
}), this.blocInstanceMap.clear(), this.isolatedBlocMap.clear(), this.isolatedBlocIndex.clear(), g.resetInstance();
|
|
96
|
-
});
|
|
97
|
-
/**
|
|
98
|
-
* Disposes of a bloc instance by removing it from the appropriate registry
|
|
99
|
-
* @param bloc - The bloc instance to dispose
|
|
100
|
-
*/
|
|
101
|
-
i(this, "disposeBloc", (e) => {
|
|
102
|
-
if (e._disposalState !== "active") {
|
|
103
|
-
this.log(
|
|
104
|
-
`[${e._name}:${String(e._id)}] disposeBloc called on already disposed bloc`
|
|
105
|
-
);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const t = e.constructor, s = this.createBlocInstanceMapKey(e._name, e._id);
|
|
109
|
-
this.log(
|
|
110
|
-
`[${e._name}:${String(e._id)}] disposeBloc called. Isolated: ${String(t.isolated)}`
|
|
111
|
-
), e._dispose(), t.isolated ? (this.unregisterIsolatedBlocInstance(e), this.blocInstanceMap.delete(s)) : this.unregisterBlocInstance(e), this.log("dispatched bloc", e);
|
|
112
|
-
});
|
|
113
|
-
i(this, "activateBloc", (e) => {
|
|
114
|
-
if (e._disposalState !== "active") {
|
|
115
|
-
this.log(
|
|
116
|
-
`[${e._name}:${String(e._id)}] activateBloc called on disposed bloc. Ignoring.`
|
|
117
|
-
);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
const t = e.constructor;
|
|
121
|
-
(e.isIsolated ? this.findIsolatedBlocInstance(t, e._id) : this.findRegisteredBlocInstance(t, e._id)) || (this.log(
|
|
122
|
-
`[${e._name}:${String(e._id)}] activateBloc called. Isolated: ${String(e.isIsolated)}`
|
|
123
|
-
), e.isIsolated ? this.registerIsolatedBlocInstance(e) : this.registerBlocInstance(e));
|
|
124
|
-
});
|
|
125
|
-
/**
|
|
126
|
-
* Gets or creates a bloc instance based on the provided class and options.
|
|
127
|
-
* If a bloc with the given ID exists, it will be returned. Otherwise, a new instance will be created.
|
|
128
|
-
*
|
|
129
|
-
* @param blocClass - The bloc class to get or create
|
|
130
|
-
* @param options - Options including:
|
|
131
|
-
* - id: The instance ID (defaults to class name if not provided)
|
|
132
|
-
* - props: Properties to pass to the bloc constructor
|
|
133
|
-
* - instanceRef: Optional reference string for the instance
|
|
134
|
-
* @returns The bloc instance
|
|
135
|
-
*/
|
|
136
|
-
i(this, "getBloc", (e, t = {}) => {
|
|
137
|
-
const { id: s } = t, n = e, o = s ?? e.name;
|
|
138
|
-
if (n.isolated) {
|
|
139
|
-
const c = this.findIsolatedBlocInstance(e, o);
|
|
140
|
-
if (c)
|
|
141
|
-
return c;
|
|
142
|
-
if (t.throwIfNotFound)
|
|
143
|
-
throw new Error(`Isolated bloc ${e.name} not found`);
|
|
144
|
-
} else {
|
|
145
|
-
const c = this.findRegisteredBlocInstance(e, o);
|
|
146
|
-
if (c)
|
|
147
|
-
return c;
|
|
148
|
-
if (t.throwIfNotFound)
|
|
149
|
-
throw new Error(`Registered bloc ${e.name} not found`);
|
|
150
|
-
}
|
|
151
|
-
const a = this.createNewBlocInstance(e, o, t);
|
|
152
|
-
if (this.log(
|
|
153
|
-
`[${e.name}:${String(o)}] (getBloc) No existing instance found. Creating new one.`,
|
|
154
|
-
t,
|
|
155
|
-
a
|
|
156
|
-
), !a)
|
|
157
|
-
throw new Error(
|
|
158
|
-
`[getBloc] Failed to create bloc instance for ${e.name}. This should never happen.`
|
|
159
|
-
);
|
|
160
|
-
return a;
|
|
161
|
-
});
|
|
162
|
-
/**
|
|
163
|
-
* Gets a bloc instance or throws an error if it doesn't exist
|
|
164
|
-
* @param blocClass - The bloc class to get
|
|
165
|
-
* @param options - Options including:
|
|
166
|
-
* - id: The instance ID (defaults to class name if not provided)
|
|
167
|
-
* - props: Properties to pass to the bloc constructor
|
|
168
|
-
* - instanceRef: Optional reference string for the instance
|
|
169
|
-
*/
|
|
170
|
-
i(this, "getBlocOrThrow", (e, t = {}) => {
|
|
171
|
-
const s = e.isolated, n = t.id || e.name, o = s ? this.findIsolatedBlocInstance(e, n) : this.findRegisteredBlocInstance(e, n);
|
|
172
|
-
if (o)
|
|
173
|
-
return o;
|
|
174
|
-
throw new Error(`Bloc ${e.name} not found`);
|
|
175
|
-
});
|
|
176
|
-
/**
|
|
177
|
-
* Gets all instances of a specific bloc class
|
|
178
|
-
* @param blocClass - The bloc class to search for
|
|
179
|
-
* @param options - Options including:
|
|
180
|
-
* - searchIsolated: Whether to search in isolated blocs (defaults to bloc's isolated property)
|
|
181
|
-
* @returns Array of matching bloc instances
|
|
182
|
-
*/
|
|
183
|
-
i(this, "getAllBlocs", (e, t = {}) => {
|
|
184
|
-
const s = [];
|
|
185
|
-
if (this.blocInstanceMap.forEach((n) => {
|
|
186
|
-
n.constructor === e && s.push(n);
|
|
187
|
-
}), t.searchIsolated !== !1) {
|
|
188
|
-
const n = this.isolatedBlocMap.get(e);
|
|
189
|
-
n && s.push(...n.map((o) => o));
|
|
190
|
-
}
|
|
191
|
-
return s;
|
|
192
|
-
});
|
|
193
|
-
/**
|
|
194
|
-
* Disposes all keep-alive blocs of a specific type
|
|
195
|
-
* @param blocClass - The bloc class to dispose
|
|
196
|
-
*/
|
|
197
|
-
i(this, "disposeKeepAliveBlocs", (e) => {
|
|
198
|
-
const t = [];
|
|
199
|
-
for (const s of this.keepAliveBlocs)
|
|
200
|
-
(!e || s.constructor === e) && t.push(s);
|
|
201
|
-
t.forEach((s) => s._dispose());
|
|
202
|
-
});
|
|
203
|
-
/**
|
|
204
|
-
* Disposes all blocs matching a pattern
|
|
205
|
-
* @param predicate - Function to test each bloc for disposal
|
|
206
|
-
*/
|
|
207
|
-
i(this, "disposeBlocs", (e) => {
|
|
208
|
-
const t = [];
|
|
209
|
-
for (const s of this.blocInstanceMap.values())
|
|
210
|
-
e(s) && t.push(s);
|
|
211
|
-
for (const s of this.isolatedBlocMap.values())
|
|
212
|
-
for (const n of s)
|
|
213
|
-
e(n) && t.push(n);
|
|
214
|
-
t.forEach((s) => s._dispose());
|
|
215
|
-
});
|
|
216
|
-
/**
|
|
217
|
-
* Gets memory usage statistics for debugging
|
|
218
|
-
*/
|
|
219
|
-
i(this, "getMemoryStats", () => ({
|
|
220
|
-
totalBlocs: this.uidRegistry.size,
|
|
221
|
-
registeredBlocs: this.blocInstanceMap.size,
|
|
222
|
-
isolatedBlocs: Array.from(this.isolatedBlocMap.values()).reduce(
|
|
223
|
-
(e, t) => e + t.length,
|
|
224
|
-
0
|
|
225
|
-
),
|
|
226
|
-
keepAliveBlocs: this.keepAliveBlocs.size,
|
|
227
|
-
isolatedBlocTypes: this.isolatedBlocMap.size
|
|
228
|
-
}));
|
|
229
|
-
/**
|
|
230
|
-
* Validates consumer references and cleans up orphaned consumers
|
|
231
|
-
*/
|
|
232
|
-
i(this, "validateConsumers", () => {
|
|
233
|
-
for (const e of this.uidRegistry.values())
|
|
234
|
-
e._validateConsumers(), e._consumers.size === 0 && !e._keepAlive && e._disposalState === "active" && setTimeout(() => {
|
|
235
|
-
e._consumers.size === 0 && !e._keepAlive && e._disposalState === "active" && this.disposeBloc(e);
|
|
236
|
-
}, 1e3);
|
|
237
|
-
});
|
|
238
|
-
const { __unsafe_ignore_singleton: t = !1 } = e;
|
|
239
|
-
if (!t)
|
|
240
|
-
return r.instance;
|
|
241
|
-
g.setInstance(this);
|
|
242
|
-
}
|
|
243
|
-
/** @deprecated Use getInstance() instead */
|
|
244
|
-
static get instance() {
|
|
245
|
-
return g.getInstance();
|
|
246
|
-
}
|
|
247
|
-
static get getAllBlocs() {
|
|
248
|
-
return r.instance.getAllBlocs;
|
|
249
|
-
}
|
|
250
|
-
static get log() {
|
|
251
|
-
return r.instance.log;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Gets the current Blac instance
|
|
255
|
-
* @returns The Blac instance
|
|
256
|
-
*/
|
|
257
|
-
static getInstance() {
|
|
258
|
-
return g.getInstance();
|
|
259
|
-
}
|
|
260
|
-
static get warn() {
|
|
261
|
-
return r.instance.warn;
|
|
262
|
-
}
|
|
263
|
-
static get error() {
|
|
264
|
-
return r.instance.error;
|
|
265
|
-
}
|
|
266
|
-
static get disposeBloc() {
|
|
267
|
-
return r.instance.disposeBloc;
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Creates a unique key for a bloc instance in the map based on the bloc class name and instance ID
|
|
271
|
-
* @param blocClassName - The name of the bloc class
|
|
272
|
-
* @param id - The instance ID
|
|
273
|
-
* @returns A unique key string in the format "className:id"
|
|
274
|
-
*/
|
|
275
|
-
createBlocInstanceMapKey(e, t) {
|
|
276
|
-
return `${e}:${String(t)}`;
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Unregister a bloc instance from the main registry
|
|
280
|
-
* @param bloc - The bloc instance to unregister
|
|
281
|
-
*/
|
|
282
|
-
unregisterBlocInstance(e) {
|
|
283
|
-
const t = this.createBlocInstanceMapKey(e._name, e._id);
|
|
284
|
-
this.blocInstanceMap.delete(t), this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e);
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Registers a bloc instance in the main registry
|
|
288
|
-
* @param bloc - The bloc instance to register
|
|
289
|
-
*/
|
|
290
|
-
registerBlocInstance(e) {
|
|
291
|
-
const t = this.createBlocInstanceMapKey(e._name, e._id);
|
|
292
|
-
this.blocInstanceMap.set(t, e), this.uidRegistry.set(e.uid, e), e._keepAlive && this.keepAliveBlocs.add(e);
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Finds a registered bloc instance by its class and ID
|
|
296
|
-
* @param blocClass - The bloc class to search for
|
|
297
|
-
* @param id - The instance ID
|
|
298
|
-
* @returns The found bloc instance or undefined if not found
|
|
299
|
-
*/
|
|
300
|
-
findRegisteredBlocInstance(e, t) {
|
|
301
|
-
if (e.isolated) return;
|
|
302
|
-
const n = this.createBlocInstanceMapKey(e.name, t);
|
|
303
|
-
return this.blocInstanceMap.get(n);
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Registers an isolated bloc instance in the isolated registry
|
|
307
|
-
* @param bloc - The isolated bloc instance to register
|
|
308
|
-
*/
|
|
309
|
-
registerIsolatedBlocInstance(e) {
|
|
310
|
-
const t = e.constructor, s = this.isolatedBlocMap.get(t);
|
|
311
|
-
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);
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Unregister an isolated bloc instance from the isolated registry
|
|
315
|
-
* @param bloc - The isolated bloc instance to unregister
|
|
316
|
-
*/
|
|
317
|
-
unregisterIsolatedBlocInstance(e) {
|
|
318
|
-
const t = e.constructor, s = this.isolatedBlocMap.get(t);
|
|
319
|
-
let n = !1;
|
|
320
|
-
if (s) {
|
|
321
|
-
const a = s.findIndex((c) => c.uid === e.uid);
|
|
322
|
-
a !== -1 && (s.splice(a, 1), n = !0), s.length === 0 && this.isolatedBlocMap.delete(t);
|
|
323
|
-
}
|
|
324
|
-
const o = this.isolatedBlocIndex.delete(e.uid);
|
|
325
|
-
this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e), n !== o && this.warn(
|
|
326
|
-
`[Blac] Inconsistent state detected during isolated bloc cleanup for ${e._name}:${e.uid}. Map removal: ${n}, Index removal: ${o}`
|
|
327
|
-
);
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Finds an isolated bloc instance by its class and ID (O(n) lookup)
|
|
331
|
-
*/
|
|
332
|
-
findIsolatedBlocInstance(e, t) {
|
|
333
|
-
if (!e.isolated) return;
|
|
334
|
-
const n = this.isolatedBlocMap.get(e);
|
|
335
|
-
return n ? n.find((a) => a._id === t) : void 0;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Finds an isolated bloc instance by UID (O(1) lookup)
|
|
339
|
-
*/
|
|
340
|
-
findIsolatedBlocInstanceByUid(e) {
|
|
341
|
-
return this.isolatedBlocIndex.get(e);
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Creates a new bloc instance and registers it in the appropriate registry
|
|
345
|
-
* @param blocClass - The bloc class to instantiate
|
|
346
|
-
* @param id - The instance ID
|
|
347
|
-
* @param props - Properties to pass to the bloc constructor
|
|
348
|
-
* @param instanceRef - Optional reference string for the instance
|
|
349
|
-
* @returns The newly created bloc instance
|
|
350
|
-
*/
|
|
351
|
-
createNewBlocInstance(e, t, s = {}) {
|
|
352
|
-
const { props: n, instanceRef: o } = s, a = new e(n);
|
|
353
|
-
return a._instanceRef = o, a.props = n || null, a._updateId(t), a._setDisposalHandler((c) => this.disposeBloc(c)), a.isIsolated ? (this.registerIsolatedBlocInstance(a), a) : (this.registerBlocInstance(a), a);
|
|
354
|
-
}
|
|
355
|
-
static get activateBloc() {
|
|
356
|
-
return r.instance.activateBloc;
|
|
357
|
-
}
|
|
358
|
-
static get getBloc() {
|
|
359
|
-
return r.instance.getBloc;
|
|
360
|
-
}
|
|
361
|
-
static get getBlocOrThrow() {
|
|
362
|
-
return r.instance.getBlocOrThrow;
|
|
363
|
-
}
|
|
364
|
-
static get disposeKeepAliveBlocs() {
|
|
365
|
-
return r.instance.disposeKeepAliveBlocs;
|
|
366
|
-
}
|
|
367
|
-
static get disposeBlocs() {
|
|
368
|
-
return r.instance.disposeBlocs;
|
|
369
|
-
}
|
|
370
|
-
static get getMemoryStats() {
|
|
371
|
-
return r.instance.getMemoryStats;
|
|
372
|
-
}
|
|
373
|
-
static get validateConsumers() {
|
|
374
|
-
return r.instance.validateConsumers;
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
/** Flag to enable/disable logging */
|
|
378
|
-
i(r, "enableLog", !1), i(r, "logLevel", "warn"), i(r, "resetInstance", () => {
|
|
379
|
-
g.resetInstance();
|
|
380
|
-
});
|
|
381
|
-
let l = r;
|
|
382
|
-
class w {
|
|
1
|
+
var E = Object.defineProperty;
|
|
2
|
+
var O = (c, e, t) => e in c ? E(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
|
|
3
|
+
var i = (c, e, t) => O(c, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
class V {
|
|
383
5
|
/**
|
|
384
6
|
* Creates a new BlacObservable instance
|
|
385
7
|
* @param bloc - The Bloc instance to observe
|
|
@@ -410,16 +32,38 @@ class w {
|
|
|
410
32
|
* @returns A function that can be called to unsubscribe the observer
|
|
411
33
|
*/
|
|
412
34
|
subscribe(e) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
35
|
+
const t = this.bloc._disposalState;
|
|
36
|
+
return t === _.DISPOSED || t === _.DISPOSING ? (d.log(
|
|
37
|
+
"BlacObservable.subscribe: Cannot subscribe to disposed/disposing bloc.",
|
|
38
|
+
this.bloc,
|
|
39
|
+
e
|
|
40
|
+
), () => {
|
|
41
|
+
}) : (d.log(
|
|
42
|
+
"BlacObservable.subscribe: Subscribing observer.",
|
|
43
|
+
this.bloc,
|
|
44
|
+
e
|
|
45
|
+
), this._observers.add(e), t === _.DISPOSAL_REQUESTED && (d.log(
|
|
46
|
+
"BlacObservable.subscribe: Cancelling disposal due to new subscription.",
|
|
47
|
+
this.bloc
|
|
48
|
+
), this.bloc._atomicStateTransition(
|
|
49
|
+
_.DISPOSAL_REQUESTED,
|
|
50
|
+
_.ACTIVE
|
|
51
|
+
)), () => {
|
|
52
|
+
d.log(
|
|
53
|
+
"BlacObservable.subscribe: Unsubscribing observer.",
|
|
54
|
+
this.bloc,
|
|
55
|
+
e
|
|
56
|
+
), this.unsubscribe(e);
|
|
57
|
+
});
|
|
416
58
|
}
|
|
417
59
|
/**
|
|
418
60
|
* Unsubscribes an observer from state changes
|
|
419
61
|
* @param observer - The observer to unsubscribe
|
|
420
62
|
*/
|
|
421
63
|
unsubscribe(e) {
|
|
422
|
-
this._observers.delete(e), this.size === 0 && (
|
|
64
|
+
this._observers.delete(e), this.size === 0 && (d.log("BlacObservable.unsubscribe: No observers left.", this.bloc), this.bloc._consumers.size === 0 && !this.bloc._keepAlive && this.bloc._disposalState === _.ACTIVE && (d.log(
|
|
65
|
+
`[${this.bloc._name}:${this.bloc._id}] No observers or consumers left. Scheduling disposal.`
|
|
66
|
+
), this.bloc._scheduleDisposal()));
|
|
423
67
|
}
|
|
424
68
|
/**
|
|
425
69
|
* Notifies all observers of a state change
|
|
@@ -429,31 +73,27 @@ class w {
|
|
|
429
73
|
*/
|
|
430
74
|
notify(e, t, s) {
|
|
431
75
|
this._observers.forEach((n) => {
|
|
432
|
-
let
|
|
76
|
+
let r = !1;
|
|
433
77
|
if (n.dependencyArray) {
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
78
|
+
const o = n.lastState, a = n.dependencyArray(
|
|
79
|
+
e,
|
|
80
|
+
t,
|
|
81
|
+
this.bloc
|
|
82
|
+
);
|
|
83
|
+
if (!o)
|
|
84
|
+
r = !0;
|
|
85
|
+
else if (o.length !== a.length)
|
|
86
|
+
r = !0;
|
|
439
87
|
else
|
|
440
|
-
for (let
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
o = !0;
|
|
88
|
+
for (let u = 0; u < a.length; u++)
|
|
89
|
+
if (!Object.is(o[u], a[u])) {
|
|
90
|
+
r = !0;
|
|
444
91
|
break;
|
|
445
92
|
}
|
|
446
|
-
|
|
447
|
-
if (!Object.is(_[f], p[f])) {
|
|
448
|
-
o = !0;
|
|
449
|
-
break;
|
|
450
|
-
}
|
|
451
|
-
if (o) break;
|
|
452
|
-
}
|
|
453
|
-
n.lastState = c;
|
|
93
|
+
n.lastState = a;
|
|
454
94
|
} else
|
|
455
|
-
|
|
456
|
-
|
|
95
|
+
r = !0;
|
|
96
|
+
r && n.fn(e, t, s);
|
|
457
97
|
});
|
|
458
98
|
}
|
|
459
99
|
/**
|
|
@@ -463,21 +103,22 @@ class w {
|
|
|
463
103
|
this._observers.clear();
|
|
464
104
|
}
|
|
465
105
|
}
|
|
466
|
-
function
|
|
467
|
-
return typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(
|
|
106
|
+
function $() {
|
|
107
|
+
return typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
468
108
|
const e = Math.random() * 16 | 0;
|
|
469
|
-
return (
|
|
109
|
+
return (c === "x" ? e : e & 3 | 8).toString(16);
|
|
470
110
|
});
|
|
471
111
|
}
|
|
472
|
-
|
|
112
|
+
var _ = /* @__PURE__ */ ((c) => (c.ACTIVE = "active", c.DISPOSAL_REQUESTED = "disposal_requested", c.DISPOSING = "disposing", c.DISPOSED = "disposed", c))(_ || {});
|
|
113
|
+
class x {
|
|
473
114
|
/**
|
|
474
115
|
* Creates a new BlocBase instance with the given initial state.
|
|
475
116
|
* Sets up the observer, registers with the Blac manager, and initializes addons.
|
|
476
|
-
*
|
|
117
|
+
*
|
|
477
118
|
* @param initialState The initial state value for this Bloc
|
|
478
119
|
*/
|
|
479
120
|
constructor(e) {
|
|
480
|
-
i(this, "uid",
|
|
121
|
+
i(this, "uid", $());
|
|
481
122
|
/**
|
|
482
123
|
* Defines how dependencies are selected from the state for efficient updates.
|
|
483
124
|
* When provided, observers will only be notified when selected dependencies change.
|
|
@@ -515,9 +156,14 @@ class v {
|
|
|
515
156
|
i(this, "_createdAt", Date.now());
|
|
516
157
|
/**
|
|
517
158
|
* @internal
|
|
518
|
-
*
|
|
159
|
+
* Atomic disposal state to prevent race conditions
|
|
519
160
|
*/
|
|
520
161
|
i(this, "_disposalState", "active");
|
|
162
|
+
/**
|
|
163
|
+
* @internal
|
|
164
|
+
* Timestamp when disposal was requested (for React Strict Mode grace period)
|
|
165
|
+
*/
|
|
166
|
+
i(this, "_disposalRequestTime", 0);
|
|
521
167
|
/**
|
|
522
168
|
* @internal
|
|
523
169
|
* The current state of the Bloc.
|
|
@@ -565,7 +211,7 @@ class v {
|
|
|
565
211
|
* @internal
|
|
566
212
|
* Updates the Bloc instance's ID to a new value.
|
|
567
213
|
* Only updates if the new ID is defined and different from the current one.
|
|
568
|
-
*
|
|
214
|
+
*
|
|
569
215
|
* @param id The new ID to assign to this Bloc instance
|
|
570
216
|
*/
|
|
571
217
|
i(this, "_updateId", (e) => {
|
|
@@ -586,24 +232,30 @@ class v {
|
|
|
586
232
|
* @internal
|
|
587
233
|
* Registers a new consumer to this Bloc instance.
|
|
588
234
|
* Notifies the Blac manager that a consumer has been added.
|
|
589
|
-
*
|
|
235
|
+
*
|
|
590
236
|
* @param consumerId The unique ID of the consumer being added
|
|
591
237
|
* @param consumerRef Optional reference to the consumer object for cleanup validation
|
|
592
238
|
*/
|
|
593
239
|
i(this, "_addConsumer", (e, t) => {
|
|
594
240
|
var s;
|
|
595
|
-
this._disposalState
|
|
241
|
+
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(
|
|
242
|
+
`[${this._name}:${this._id}] Consumer added. Total consumers: ${this._consumers.size}`
|
|
243
|
+
)), !0);
|
|
596
244
|
});
|
|
597
245
|
/**
|
|
598
246
|
* @internal
|
|
599
247
|
* Unregisters a consumer from this Bloc instance.
|
|
600
248
|
* Notifies the Blac manager that a consumer has been removed.
|
|
601
|
-
*
|
|
249
|
+
*
|
|
602
250
|
* @param consumerId The unique ID of the consumer being removed
|
|
603
251
|
*/
|
|
604
252
|
i(this, "_removeConsumer", (e) => {
|
|
605
253
|
var t, s;
|
|
606
|
-
this._consumers.has(e) && (this._consumers.delete(e), this._consumerRefs.delete(e), (t = globalThis.Blac) == null || t.log(
|
|
254
|
+
this._consumers.has(e) && (this._consumers.delete(e), this._consumerRefs.delete(e), (t = globalThis.Blac) == null || t.log(
|
|
255
|
+
`[${this._name}:${this._id}] Consumer removed. Remaining consumers: ${this._consumers.size}, keepAlive: ${this._keepAlive}`
|
|
256
|
+
), this._consumers.size === 0 && !this._keepAlive && this._disposalState === "active" && ((s = globalThis.Blac) == null || s.log(
|
|
257
|
+
`[${this._name}:${this._id}] No consumers left and not keep-alive. Scheduling disposal.`
|
|
258
|
+
), this._scheduleDisposal()));
|
|
607
259
|
});
|
|
608
260
|
/**
|
|
609
261
|
* @internal
|
|
@@ -619,110 +271,585 @@ class v {
|
|
|
619
271
|
/**
|
|
620
272
|
* @internal
|
|
621
273
|
* Updates the state and notifies all observers of the change.
|
|
622
|
-
*
|
|
274
|
+
*
|
|
623
275
|
* @param newState The new state to be set
|
|
624
276
|
* @param oldState The previous state for comparison
|
|
625
277
|
* @param action Optional metadata about what caused the state change
|
|
626
278
|
*/
|
|
627
279
|
i(this, "_pushState", (e, t, s) => {
|
|
628
|
-
if (e
|
|
629
|
-
|
|
630
|
-
|
|
280
|
+
if (e !== void 0 && !(s !== void 0 && typeof s != "object" && typeof s != "function")) {
|
|
281
|
+
if (this._batchingEnabled) {
|
|
282
|
+
this._pendingUpdates.push({ newState: e, oldState: t, action: s }), this._oldState = t, this._state = e;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
this._oldState = t, this._state = e, this._observer.notify(e, t, s), this.lastUpdate = Date.now();
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
/**
|
|
289
|
+
* Enables batching for multiple state updates
|
|
290
|
+
* @param batchFn Function to execute with batching enabled
|
|
291
|
+
*/
|
|
292
|
+
i(this, "batch", (e) => {
|
|
293
|
+
if (this._batchingLock)
|
|
294
|
+
return e();
|
|
295
|
+
this._batchingLock = !0, this._batchingEnabled = !0, this._pendingUpdates = [];
|
|
296
|
+
try {
|
|
297
|
+
const t = e();
|
|
298
|
+
if (this._pendingUpdates.length > 0) {
|
|
299
|
+
const s = this._pendingUpdates[this._pendingUpdates.length - 1];
|
|
300
|
+
this._observer.notify(
|
|
301
|
+
s.newState,
|
|
302
|
+
s.oldState,
|
|
303
|
+
s.action
|
|
304
|
+
), this.lastUpdate = Date.now();
|
|
305
|
+
}
|
|
306
|
+
return t;
|
|
307
|
+
} finally {
|
|
308
|
+
this._batchingEnabled = !1, this._batchingLock = !1, this._pendingUpdates = [];
|
|
631
309
|
}
|
|
632
|
-
|
|
633
|
-
|
|
310
|
+
});
|
|
311
|
+
this._state = e, this._observer = new V(this), this._id = this.constructor.name;
|
|
312
|
+
const t = this.constructor;
|
|
313
|
+
this._keepAlive = typeof t.keepAlive == "boolean" ? t.keepAlive : !1, this._isolated = typeof t.isolated == "boolean" ? t.isolated : !1;
|
|
314
|
+
}
|
|
315
|
+
get isIsolated() {
|
|
316
|
+
return this._isolated;
|
|
317
|
+
}
|
|
318
|
+
get isKeepAlive() {
|
|
319
|
+
return this._keepAlive;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Returns the current state of the Bloc.
|
|
323
|
+
* Use this getter to access the state in a read-only manner.
|
|
324
|
+
* Returns the state even during transitional lifecycle states for React compatibility.
|
|
325
|
+
*/
|
|
326
|
+
get state() {
|
|
327
|
+
return this._disposalState === "disposed" ? this._state : this._state;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Returns whether this Bloc instance has been disposed.
|
|
331
|
+
* @returns true if the bloc is in DISPOSED state
|
|
332
|
+
*/
|
|
333
|
+
get isDisposed() {
|
|
334
|
+
return this._disposalState === "disposed";
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* @internal
|
|
338
|
+
* Returns the name of the Bloc class for identification and debugging.
|
|
339
|
+
*/
|
|
340
|
+
get _name() {
|
|
341
|
+
return this.constructor.name;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* @internal
|
|
345
|
+
* Performs atomic state transition using compare-and-swap semantics
|
|
346
|
+
* @param expectedState The expected current state
|
|
347
|
+
* @param newState The desired new state
|
|
348
|
+
* @returns Result indicating success/failure and state information
|
|
349
|
+
*/
|
|
350
|
+
_atomicStateTransition(e, t) {
|
|
351
|
+
var s, n, r, o;
|
|
352
|
+
if (this._disposalState === e) {
|
|
353
|
+
const a = this._disposalState;
|
|
354
|
+
return this._disposalState = t, (s = globalThis.Blac) != null && s.enableLog && ((n = globalThis.Blac) == null || n.log(
|
|
355
|
+
`[${this._name}:${this._id}] State transition: ${a} -> ${t} (SUCCESS)`
|
|
356
|
+
)), {
|
|
357
|
+
success: !0,
|
|
358
|
+
currentState: t,
|
|
359
|
+
previousState: a
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
return (r = globalThis.Blac) != null && r.enableLog && ((o = globalThis.Blac) == null || o.log(
|
|
363
|
+
`[${this._name}:${this._id}] State transition failed: expected ${e}, current ${this._disposalState}`
|
|
364
|
+
)), {
|
|
365
|
+
success: !1,
|
|
366
|
+
currentState: this._disposalState,
|
|
367
|
+
previousState: e
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* @internal
|
|
372
|
+
* Cleans up resources and removes this Bloc from the system.
|
|
373
|
+
* Notifies the Blac manager and clears all observers.
|
|
374
|
+
*/
|
|
375
|
+
_dispose() {
|
|
376
|
+
var t;
|
|
377
|
+
let e = this._atomicStateTransition(
|
|
378
|
+
"active",
|
|
379
|
+
"disposing"
|
|
380
|
+
/* DISPOSING */
|
|
381
|
+
);
|
|
382
|
+
if (e.success || (e = this._atomicStateTransition(
|
|
383
|
+
"disposal_requested",
|
|
384
|
+
"disposing"
|
|
385
|
+
/* DISPOSING */
|
|
386
|
+
)), !e.success)
|
|
387
|
+
return !1;
|
|
388
|
+
try {
|
|
389
|
+
return this._consumers.clear(), this._consumerRefs.clear(), this._observer.clear(), (t = this.onDispose) == null || t.call(this), this._atomicStateTransition(
|
|
390
|
+
"disposing",
|
|
391
|
+
"disposed"
|
|
392
|
+
/* DISPOSED */
|
|
393
|
+
).success;
|
|
394
|
+
} catch (s) {
|
|
395
|
+
throw this._disposalState = "active", s;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* @internal
|
|
400
|
+
* Sets the disposal handler for this bloc
|
|
401
|
+
*/
|
|
402
|
+
_setDisposalHandler(e) {
|
|
403
|
+
this._disposalHandler = e;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* @internal
|
|
407
|
+
* Schedules disposal of this bloc instance if it has no consumers
|
|
408
|
+
* Uses atomic state transitions to prevent race conditions
|
|
409
|
+
*/
|
|
410
|
+
_scheduleDisposal() {
|
|
411
|
+
if (!this._atomicStateTransition(
|
|
412
|
+
"active",
|
|
413
|
+
"disposal_requested"
|
|
414
|
+
/* DISPOSAL_REQUESTED */
|
|
415
|
+
).success)
|
|
416
|
+
return;
|
|
417
|
+
if (!(this._consumers.size === 0 && !this._keepAlive)) {
|
|
418
|
+
this._atomicStateTransition(
|
|
419
|
+
"disposal_requested",
|
|
420
|
+
"active"
|
|
421
|
+
/* ACTIVE */
|
|
422
|
+
);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
this._disposalRequestTime = Date.now(), queueMicrotask(() => {
|
|
426
|
+
this._consumers.size === 0 && !this._keepAlive && this._observer.size === 0 && this._disposalState === "disposal_requested" ? this._disposalHandler ? this._disposalHandler(this) : this._dispose() : this._atomicStateTransition(
|
|
427
|
+
"disposal_requested",
|
|
428
|
+
"active"
|
|
429
|
+
/* ACTIVE */
|
|
430
|
+
);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* When true, every consumer will receive its own unique instance of this Bloc.
|
|
436
|
+
* Use this when state should not be shared between components.
|
|
437
|
+
* @default false
|
|
438
|
+
*/
|
|
439
|
+
i(x, "isolated", !1), /**
|
|
440
|
+
* When true, the Bloc instance persists even when there are no active consumers.
|
|
441
|
+
* Useful for maintaining state between component unmount/remount cycles.
|
|
442
|
+
* @default false
|
|
443
|
+
*/
|
|
444
|
+
i(x, "keepAlive", !1);
|
|
445
|
+
const y = class y {
|
|
446
|
+
getInstance() {
|
|
447
|
+
return y._instance || (y._instance = new d({
|
|
448
|
+
__unsafe_ignore_singleton: !0
|
|
449
|
+
})), y._instance;
|
|
450
|
+
}
|
|
451
|
+
setInstance(e) {
|
|
452
|
+
y._instance = e;
|
|
453
|
+
}
|
|
454
|
+
resetInstance() {
|
|
455
|
+
const e = y._instance;
|
|
456
|
+
if (y._instance = new d({
|
|
457
|
+
__unsafe_ignore_singleton: !0
|
|
458
|
+
}), e)
|
|
459
|
+
for (const t of e.keepAliveBlocs)
|
|
460
|
+
y._instance.keepAliveBlocs.add(t), y._instance.uidRegistry.set(t.uid, t);
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
i(y, "_instance");
|
|
464
|
+
let C = y, S = new C();
|
|
465
|
+
function q(c) {
|
|
466
|
+
S = c;
|
|
467
|
+
}
|
|
468
|
+
const l = class l {
|
|
469
|
+
/**
|
|
470
|
+
* Creates a new Blac instance.
|
|
471
|
+
* @param options - Configuration options including singleton control
|
|
472
|
+
*/
|
|
473
|
+
constructor(e = {}) {
|
|
474
|
+
/** Timestamp when the instance was created */
|
|
475
|
+
i(this, "createdAt", Date.now());
|
|
476
|
+
/** Map storing all registered bloc instances by their class name and ID */
|
|
477
|
+
i(this, "blocInstanceMap", /* @__PURE__ */ new Map());
|
|
478
|
+
/** Map storing isolated bloc instances grouped by their constructor */
|
|
479
|
+
// Using BlocConstructor<BlocBase<unknown>> would break type inference when storing
|
|
480
|
+
// different bloc types in the same map. The 'any' allows proper polymorphic storage
|
|
481
|
+
// while maintaining type safety at usage sites through the BlocConstructor constraint.
|
|
482
|
+
i(this, "isolatedBlocMap", /* @__PURE__ */ new Map());
|
|
483
|
+
/** Map for O(1) lookup of isolated blocs by UID */
|
|
484
|
+
i(this, "isolatedBlocIndex", /* @__PURE__ */ new Map());
|
|
485
|
+
/** Map tracking UIDs to prevent memory leaks */
|
|
486
|
+
i(this, "uidRegistry", /* @__PURE__ */ new Map());
|
|
487
|
+
/** Set of keep-alive blocs for controlled cleanup */
|
|
488
|
+
i(this, "keepAliveBlocs", /* @__PURE__ */ new Set());
|
|
489
|
+
/** Flag to control whether changes should be posted to document */
|
|
490
|
+
i(this, "postChangesToDocument", !1);
|
|
491
|
+
/**
|
|
492
|
+
* Logs messages to console when logging is enabled
|
|
493
|
+
* @param args - Arguments to log
|
|
494
|
+
*/
|
|
495
|
+
i(this, "log", (...e) => {
|
|
496
|
+
l.logSpy && l.logSpy(e), l.enableLog && l.logLevel, l.enableLog && l.logLevel;
|
|
497
|
+
});
|
|
498
|
+
/**
|
|
499
|
+
* Logs a warning message
|
|
500
|
+
* @param message - Warning message
|
|
501
|
+
* @param args - Additional arguments
|
|
502
|
+
*/
|
|
503
|
+
i(this, "warn", (e, ...t) => {
|
|
504
|
+
l.enableLog;
|
|
505
|
+
});
|
|
506
|
+
/**
|
|
507
|
+
* Logs an error message
|
|
508
|
+
* @param message - Error message
|
|
509
|
+
* @param args - Additional arguments
|
|
510
|
+
*/
|
|
511
|
+
i(this, "error", (e, ...t) => {
|
|
512
|
+
l.enableLog;
|
|
513
|
+
});
|
|
514
|
+
/**
|
|
515
|
+
* Resets the Blac instance to a new one, disposing non-keepAlive blocs
|
|
516
|
+
* from the old instance.
|
|
517
|
+
*/
|
|
518
|
+
i(this, "resetInstance", () => {
|
|
519
|
+
this.log("Reset Blac instance");
|
|
520
|
+
const e = new Map(this.blocInstanceMap), t = new Map(this.isolatedBlocMap);
|
|
521
|
+
e.forEach((s) => {
|
|
522
|
+
!s._keepAlive && s._disposalState === _.ACTIVE && this.disposeBloc(s);
|
|
523
|
+
}), t.forEach((s) => {
|
|
524
|
+
s.forEach((n) => {
|
|
525
|
+
!n._keepAlive && n._disposalState === _.ACTIVE && this.disposeBloc(n);
|
|
526
|
+
});
|
|
527
|
+
}), this.blocInstanceMap.clear(), this.isolatedBlocMap.clear(), this.isolatedBlocIndex.clear(), S.resetInstance();
|
|
528
|
+
});
|
|
529
|
+
/**
|
|
530
|
+
* Disposes of a bloc instance by removing it from the appropriate registry
|
|
531
|
+
* @param bloc - The bloc instance to dispose
|
|
532
|
+
*/
|
|
533
|
+
i(this, "disposeBloc", (e) => {
|
|
534
|
+
const t = e._disposalState;
|
|
535
|
+
if (![
|
|
536
|
+
_.ACTIVE,
|
|
537
|
+
_.DISPOSAL_REQUESTED
|
|
538
|
+
].includes(t)) {
|
|
539
|
+
this.log(
|
|
540
|
+
`[${e._name}:${String(e._id)}] disposeBloc called on bloc in invalid state: ${t}`
|
|
541
|
+
);
|
|
634
542
|
return;
|
|
635
543
|
}
|
|
636
|
-
|
|
637
|
-
|
|
544
|
+
const n = e.constructor, r = this.createBlocInstanceMapKey(e._name, e._id);
|
|
545
|
+
this.log(
|
|
546
|
+
`[${e._name}:${String(e._id)}] disposeBloc called. Isolated: ${String(n.isolated)}`
|
|
547
|
+
), e._dispose(), n.isolated ? (this.unregisterIsolatedBlocInstance(e), this.blocInstanceMap.delete(r)) : this.unregisterBlocInstance(e), this.log("dispatched bloc", e);
|
|
548
|
+
});
|
|
549
|
+
i(this, "activateBloc", (e) => {
|
|
550
|
+
if (e._disposalState !== _.ACTIVE) {
|
|
551
|
+
this.log(
|
|
552
|
+
`[${e._name}:${String(e._id)}] activateBloc called on disposed bloc. Ignoring.`
|
|
553
|
+
);
|
|
638
554
|
return;
|
|
639
555
|
}
|
|
640
|
-
|
|
556
|
+
const t = e.constructor;
|
|
557
|
+
(e.isIsolated ? this.findIsolatedBlocInstance(t, e._id) : this.findRegisteredBlocInstance(t, e._id)) || (this.log(
|
|
558
|
+
`[${e._name}:${String(e._id)}] activateBloc called. Isolated: ${String(e.isIsolated)}`
|
|
559
|
+
), e.isIsolated ? this.registerIsolatedBlocInstance(e) : this.registerBlocInstance(e));
|
|
560
|
+
});
|
|
561
|
+
/**
|
|
562
|
+
* Gets or creates a bloc instance based on the provided class and options.
|
|
563
|
+
* If a bloc with the given ID exists, it will be returned. Otherwise, a new instance will be created.
|
|
564
|
+
*
|
|
565
|
+
* @param blocClass - The bloc class to get or create
|
|
566
|
+
* @param options - Options including:
|
|
567
|
+
* - id: The instance ID (defaults to class name if not provided)
|
|
568
|
+
* - props: Properties to pass to the bloc constructor
|
|
569
|
+
* - instanceRef: Optional reference string for the instance
|
|
570
|
+
* @returns The bloc instance
|
|
571
|
+
*/
|
|
572
|
+
i(this, "getBloc", (e, t = {}) => {
|
|
573
|
+
const { id: s, forceNewInstance: n } = t, r = e, o = s ?? e.name;
|
|
574
|
+
if (this.log(`[${e.name}:${String(o)}] (getBloc) Called:`, {
|
|
575
|
+
options: t,
|
|
576
|
+
base: r
|
|
577
|
+
}), !n)
|
|
578
|
+
if (r.isolated) {
|
|
579
|
+
const u = this.findIsolatedBlocInstance(
|
|
580
|
+
e,
|
|
581
|
+
t.instanceRef ?? o
|
|
582
|
+
);
|
|
583
|
+
if (u)
|
|
584
|
+
return u;
|
|
585
|
+
if (t.throwIfNotFound)
|
|
586
|
+
throw new Error(`Isolated bloc ${e.name} not found`);
|
|
587
|
+
} else {
|
|
588
|
+
const u = this.findRegisteredBlocInstance(
|
|
589
|
+
e,
|
|
590
|
+
o
|
|
591
|
+
);
|
|
592
|
+
if (u)
|
|
593
|
+
return u;
|
|
594
|
+
if (t.throwIfNotFound)
|
|
595
|
+
throw new Error(`Registered bloc ${e.name} not found`);
|
|
596
|
+
}
|
|
597
|
+
const a = this.createNewBlocInstance(e, o, t);
|
|
598
|
+
if (this.log(
|
|
599
|
+
`[${e.name}:${String(o)}] (getBloc) No existing instance found. Creating new one.`,
|
|
600
|
+
t,
|
|
601
|
+
a
|
|
602
|
+
), !a)
|
|
603
|
+
throw new Error(
|
|
604
|
+
`[getBloc] Failed to create bloc instance for ${e.name}. This should never happen.`
|
|
605
|
+
);
|
|
606
|
+
return a;
|
|
607
|
+
});
|
|
608
|
+
/**
|
|
609
|
+
* Gets a bloc instance or throws an error if it doesn't exist
|
|
610
|
+
* @param blocClass - The bloc class to get
|
|
611
|
+
* @param options - Options including:
|
|
612
|
+
* - id: The instance ID (defaults to class name if not provided)
|
|
613
|
+
* - props: Properties to pass to the bloc constructor
|
|
614
|
+
* - instanceRef: Optional reference string for the instance
|
|
615
|
+
*/
|
|
616
|
+
i(this, "getBlocOrThrow", (e, t = {}) => {
|
|
617
|
+
const s = e.isolated, n = t.id || e.name, r = s ? this.findIsolatedBlocInstance(e, n) : this.findRegisteredBlocInstance(e, n);
|
|
618
|
+
if (r)
|
|
619
|
+
return r;
|
|
620
|
+
throw new Error(`Bloc ${e.name} not found`);
|
|
621
|
+
});
|
|
622
|
+
/**
|
|
623
|
+
* Gets all instances of a specific bloc class
|
|
624
|
+
* @param blocClass - The bloc class to search for
|
|
625
|
+
* @param options - Options including:
|
|
626
|
+
* - searchIsolated: Whether to search in isolated blocs (defaults to bloc's isolated property)
|
|
627
|
+
* @returns Array of matching bloc instances
|
|
628
|
+
*/
|
|
629
|
+
i(this, "getAllBlocs", (e, t = {}) => {
|
|
630
|
+
const s = [];
|
|
631
|
+
if (this.blocInstanceMap.forEach((n) => {
|
|
632
|
+
n.constructor === e && s.push(n);
|
|
633
|
+
}), t.searchIsolated !== !1) {
|
|
634
|
+
const n = this.isolatedBlocMap.get(e);
|
|
635
|
+
n && s.push(...n.map((r) => r));
|
|
636
|
+
}
|
|
637
|
+
return s;
|
|
638
|
+
});
|
|
639
|
+
/**
|
|
640
|
+
* Disposes all keep-alive blocs of a specific type
|
|
641
|
+
* @param blocClass - The bloc class to dispose
|
|
642
|
+
*/
|
|
643
|
+
i(this, "disposeKeepAliveBlocs", (e) => {
|
|
644
|
+
const t = [];
|
|
645
|
+
for (const s of this.keepAliveBlocs)
|
|
646
|
+
(!e || s.constructor === e) && t.push(s);
|
|
647
|
+
t.forEach((s) => s._dispose());
|
|
648
|
+
});
|
|
649
|
+
/**
|
|
650
|
+
* Disposes all blocs matching a pattern
|
|
651
|
+
* @param predicate - Function to test each bloc for disposal
|
|
652
|
+
*/
|
|
653
|
+
i(this, "disposeBlocs", (e) => {
|
|
654
|
+
const t = [];
|
|
655
|
+
for (const s of this.blocInstanceMap.values())
|
|
656
|
+
e(s) && t.push(s);
|
|
657
|
+
for (const s of this.isolatedBlocMap.values())
|
|
658
|
+
for (const n of s)
|
|
659
|
+
e(n) && t.push(n);
|
|
660
|
+
t.forEach((s) => s._dispose());
|
|
641
661
|
});
|
|
642
662
|
/**
|
|
643
|
-
*
|
|
644
|
-
* @param batchFn Function to execute with batching enabled
|
|
663
|
+
* Gets memory usage statistics for debugging
|
|
645
664
|
*/
|
|
646
|
-
i(this, "
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
665
|
+
i(this, "getMemoryStats", () => ({
|
|
666
|
+
totalBlocs: this.uidRegistry.size,
|
|
667
|
+
registeredBlocs: this.blocInstanceMap.size,
|
|
668
|
+
isolatedBlocs: Array.from(this.isolatedBlocMap.values()).reduce(
|
|
669
|
+
(e, t) => e + t.length,
|
|
670
|
+
0
|
|
671
|
+
),
|
|
672
|
+
keepAliveBlocs: this.keepAliveBlocs.size,
|
|
673
|
+
isolatedBlocTypes: this.isolatedBlocMap.size
|
|
674
|
+
}));
|
|
675
|
+
/**
|
|
676
|
+
* Validates consumer references and cleans up orphaned consumers
|
|
677
|
+
*/
|
|
678
|
+
i(this, "validateConsumers", () => {
|
|
679
|
+
for (const e of this.uidRegistry.values())
|
|
680
|
+
e._validateConsumers(), e._consumers.size === 0 && !e._keepAlive && e._disposalState === _.ACTIVE && setTimeout(() => {
|
|
681
|
+
e._consumers.size === 0 && !e._keepAlive && e._disposalState === _.ACTIVE && this.disposeBloc(e);
|
|
682
|
+
}, 1e3);
|
|
660
683
|
});
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
684
|
+
const { __unsafe_ignore_singleton: t = !1 } = e;
|
|
685
|
+
if (!t)
|
|
686
|
+
return l.instance;
|
|
687
|
+
S.setInstance(this);
|
|
664
688
|
}
|
|
665
|
-
get
|
|
666
|
-
return
|
|
689
|
+
static get instance() {
|
|
690
|
+
return S.getInstance();
|
|
667
691
|
}
|
|
668
|
-
get
|
|
669
|
-
return
|
|
692
|
+
static get getAllBlocs() {
|
|
693
|
+
return l.instance.getAllBlocs;
|
|
694
|
+
}
|
|
695
|
+
/** Get current configuration */
|
|
696
|
+
static get config() {
|
|
697
|
+
return { ...this._config };
|
|
670
698
|
}
|
|
671
699
|
/**
|
|
672
|
-
*
|
|
673
|
-
*
|
|
700
|
+
* Set or update Blac configuration
|
|
701
|
+
* @param config - Partial configuration to merge with existing config
|
|
702
|
+
* @throws Error if configuration is invalid
|
|
674
703
|
*/
|
|
675
|
-
|
|
676
|
-
|
|
704
|
+
static setConfig(e) {
|
|
705
|
+
if (e.proxyDependencyTracking !== void 0 && typeof e.proxyDependencyTracking != "boolean")
|
|
706
|
+
throw new Error("BlacConfig.proxyDependencyTracking must be a boolean");
|
|
707
|
+
if (e.exposeBlacInstance !== void 0 && typeof e.exposeBlacInstance != "boolean")
|
|
708
|
+
throw new Error("BlacConfig.exposeBlacInstance must be a boolean");
|
|
709
|
+
this._config = {
|
|
710
|
+
...this._config,
|
|
711
|
+
...e
|
|
712
|
+
}, this.enableLog && this.instance.log("Blac config updated:", this._config);
|
|
713
|
+
}
|
|
714
|
+
static get log() {
|
|
715
|
+
return l.instance.log;
|
|
677
716
|
}
|
|
678
717
|
/**
|
|
679
|
-
*
|
|
680
|
-
*
|
|
718
|
+
* Gets the current Blac instance
|
|
719
|
+
* @returns The Blac instance
|
|
681
720
|
*/
|
|
682
|
-
|
|
683
|
-
return
|
|
721
|
+
static getInstance() {
|
|
722
|
+
return S.getInstance();
|
|
723
|
+
}
|
|
724
|
+
static get warn() {
|
|
725
|
+
return l.instance.warn;
|
|
726
|
+
}
|
|
727
|
+
static get error() {
|
|
728
|
+
return l.instance.error;
|
|
729
|
+
}
|
|
730
|
+
static get disposeBloc() {
|
|
731
|
+
return l.instance.disposeBloc;
|
|
684
732
|
}
|
|
685
733
|
/**
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
734
|
+
* Creates a unique key for a bloc instance in the map based on the bloc class name and instance ID
|
|
735
|
+
* @param blocClassName - The name of the bloc class
|
|
736
|
+
* @param id - The instance ID
|
|
737
|
+
* @returns A unique key string in the format "className:id"
|
|
689
738
|
*/
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
this._disposalState === "active" && (this._disposalState = "disposing", this._consumers.clear(), this._consumerRefs.clear(), this._observer.clear(), (e = this.onDispose) == null || e.call(this), this._disposalState = "disposed");
|
|
739
|
+
createBlocInstanceMapKey(e, t) {
|
|
740
|
+
return `${e}:${String(t)}`;
|
|
693
741
|
}
|
|
694
742
|
/**
|
|
695
|
-
*
|
|
696
|
-
*
|
|
743
|
+
* Unregister a bloc instance from the main registry
|
|
744
|
+
* @param bloc - The bloc instance to unregister
|
|
697
745
|
*/
|
|
698
|
-
|
|
699
|
-
|
|
746
|
+
unregisterBlocInstance(e) {
|
|
747
|
+
const t = this.createBlocInstanceMapKey(e._name, e._id);
|
|
748
|
+
this.blocInstanceMap.delete(t), this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e);
|
|
700
749
|
}
|
|
701
750
|
/**
|
|
702
|
-
*
|
|
703
|
-
*
|
|
751
|
+
* Registers a bloc instance in the main registry
|
|
752
|
+
* @param bloc - The bloc instance to register
|
|
704
753
|
*/
|
|
705
|
-
|
|
706
|
-
|
|
754
|
+
registerBlocInstance(e) {
|
|
755
|
+
const t = this.createBlocInstanceMapKey(e._name, e._id);
|
|
756
|
+
this.blocInstanceMap.set(t, e), this.uidRegistry.set(e.uid, e), e._keepAlive && this.keepAliveBlocs.add(e);
|
|
707
757
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
758
|
+
/**
|
|
759
|
+
* Finds a registered bloc instance by its class and ID
|
|
760
|
+
* @param blocClass - The bloc class to search for
|
|
761
|
+
* @param id - The instance ID
|
|
762
|
+
* @returns The found bloc instance or undefined if not found
|
|
763
|
+
*/
|
|
764
|
+
findRegisteredBlocInstance(e, t) {
|
|
765
|
+
if (e.isolated) return;
|
|
766
|
+
const n = this.createBlocInstanceMapKey(e.name, t);
|
|
767
|
+
return this.blocInstanceMap.get(n);
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Registers an isolated bloc instance in the isolated registry
|
|
771
|
+
* @param bloc - The isolated bloc instance to register
|
|
772
|
+
*/
|
|
773
|
+
registerIsolatedBlocInstance(e) {
|
|
774
|
+
const t = e.constructor, s = this.isolatedBlocMap.get(t);
|
|
775
|
+
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);
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Unregister an isolated bloc instance from the isolated registry
|
|
779
|
+
* @param bloc - The isolated bloc instance to unregister
|
|
780
|
+
*/
|
|
781
|
+
unregisterIsolatedBlocInstance(e) {
|
|
782
|
+
const t = e.constructor, s = this.isolatedBlocMap.get(t);
|
|
783
|
+
let n = !1;
|
|
784
|
+
if (s) {
|
|
785
|
+
const o = s.findIndex((a) => a.uid === e.uid);
|
|
786
|
+
o !== -1 && (s.splice(o, 1), n = !0), s.length === 0 && this.isolatedBlocMap.delete(t);
|
|
787
|
+
}
|
|
788
|
+
const r = this.isolatedBlocIndex.delete(e.uid);
|
|
789
|
+
this.uidRegistry.delete(e.uid), this.keepAliveBlocs.delete(e), n !== r && this.warn(
|
|
790
|
+
`[Blac] Inconsistent state detected during isolated bloc cleanup for ${e._name}:${e.uid}. Map removal: ${n}, Index removal: ${r}`
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Finds an isolated bloc instance by its class and ID (O(n) lookup)
|
|
795
|
+
*/
|
|
796
|
+
findIsolatedBlocInstance(e, t) {
|
|
797
|
+
if (!e.isolated) return;
|
|
798
|
+
const n = this.isolatedBlocMap.get(e);
|
|
799
|
+
return n ? n.find((o) => o._id === t) : void 0;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Finds an isolated bloc instance by UID (O(1) lookup)
|
|
803
|
+
*/
|
|
804
|
+
findIsolatedBlocInstanceByUid(e) {
|
|
805
|
+
return this.isolatedBlocIndex.get(e);
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Creates a new bloc instance and registers it in the appropriate registry
|
|
809
|
+
* @param blocClass - The bloc class to instantiate
|
|
810
|
+
* @param id - The instance ID
|
|
811
|
+
* @param props - Properties to pass to the bloc constructor
|
|
812
|
+
* @param instanceRef - Optional reference string for the instance
|
|
813
|
+
* @returns The newly created bloc instance
|
|
814
|
+
*/
|
|
815
|
+
createNewBlocInstance(e, t, s = {}) {
|
|
816
|
+
const { props: n, instanceRef: r } = s, o = new e(n);
|
|
817
|
+
return o._instanceRef = r, o.props = n || null, o._updateId(t), o._setDisposalHandler((a) => this.disposeBloc(a)), o.isIsolated ? (this.registerIsolatedBlocInstance(o), o) : (this.registerBlocInstance(o), o);
|
|
818
|
+
}
|
|
819
|
+
static get activateBloc() {
|
|
820
|
+
return l.instance.activateBloc;
|
|
821
|
+
}
|
|
822
|
+
static get getBloc() {
|
|
823
|
+
return l.instance.getBloc;
|
|
824
|
+
}
|
|
825
|
+
static get getBlocOrThrow() {
|
|
826
|
+
return l.instance.getBlocOrThrow;
|
|
827
|
+
}
|
|
828
|
+
static get disposeKeepAliveBlocs() {
|
|
829
|
+
return l.instance.disposeKeepAliveBlocs;
|
|
830
|
+
}
|
|
831
|
+
static get disposeBlocs() {
|
|
832
|
+
return l.instance.disposeBlocs;
|
|
833
|
+
}
|
|
834
|
+
static get getMemoryStats() {
|
|
835
|
+
return l.instance.getMemoryStats;
|
|
836
|
+
}
|
|
837
|
+
static get validateConsumers() {
|
|
838
|
+
return l.instance.validateConsumers;
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
/** Private static configuration */
|
|
842
|
+
i(l, "_config", {
|
|
843
|
+
exposeBlacInstance: !1,
|
|
844
|
+
proxyDependencyTracking: !0
|
|
845
|
+
}), /** Flag to enable/disable logging */
|
|
846
|
+
i(l, "enableLog", !1), i(l, "logLevel", "warn"), i(l, "logSpy", null), i(l, "resetInstance", () => {
|
|
847
|
+
S.resetInstance();
|
|
848
|
+
});
|
|
849
|
+
let d = l;
|
|
850
|
+
class U extends x {
|
|
721
851
|
constructor() {
|
|
722
852
|
super(...arguments);
|
|
723
|
-
// Stores handlers: Map<EventConstructor (subtype of A), HandlerFunction>
|
|
724
|
-
// The handler's event parameter will be correctly typed to the specific EventConstructor
|
|
725
|
-
// by the 'on' method's signature.
|
|
726
853
|
i(this, "eventHandlers", /* @__PURE__ */ new Map());
|
|
727
854
|
/**
|
|
728
855
|
* @internal
|
|
@@ -751,7 +878,7 @@ class S extends v {
|
|
|
751
878
|
* The 'event' parameter in the handler will be typed to the specific eventConstructor.
|
|
752
879
|
*/
|
|
753
880
|
on(t, s) {
|
|
754
|
-
this.eventHandlers.has(t) &&
|
|
881
|
+
this.eventHandlers.has(t) && d.warn(
|
|
755
882
|
`[Bloc ${this._name}:${String(this._id)}] Handler for event '${t.name}' already registered. It will be overwritten.`
|
|
756
883
|
), this.eventHandlers.set(
|
|
757
884
|
t,
|
|
@@ -782,42 +909,51 @@ class S extends v {
|
|
|
782
909
|
async _processEvent(t) {
|
|
783
910
|
const s = t.constructor, n = this.eventHandlers.get(s);
|
|
784
911
|
if (n) {
|
|
785
|
-
const
|
|
786
|
-
const
|
|
787
|
-
this._pushState(
|
|
912
|
+
const r = (o) => {
|
|
913
|
+
const a = this.state;
|
|
914
|
+
this._pushState(o, a, t);
|
|
788
915
|
};
|
|
789
916
|
try {
|
|
790
|
-
await n(t,
|
|
791
|
-
} catch (
|
|
792
|
-
const
|
|
917
|
+
await n(t, r);
|
|
918
|
+
} catch (o) {
|
|
919
|
+
const a = t.constructor.name || "UnnamedConstructor", u = {
|
|
793
920
|
blocName: this._name,
|
|
794
921
|
blocId: String(this._id),
|
|
795
|
-
eventType:
|
|
922
|
+
eventType: a,
|
|
796
923
|
currentState: this.state,
|
|
797
924
|
action: t,
|
|
798
925
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
799
926
|
};
|
|
800
|
-
if (
|
|
801
|
-
`[Bloc ${this._name}:${String(this._id)}] Error in event handler for '${
|
|
802
|
-
|
|
927
|
+
if (d.error(
|
|
928
|
+
`[Bloc ${this._name}:${String(this._id)}] Error in event handler for '${a}':`,
|
|
929
|
+
o,
|
|
803
930
|
"Context:",
|
|
804
|
-
|
|
805
|
-
),
|
|
806
|
-
throw
|
|
931
|
+
u
|
|
932
|
+
), o instanceof Error && o.name === "CriticalError")
|
|
933
|
+
throw o;
|
|
807
934
|
}
|
|
808
935
|
} else {
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
`[Bloc ${this._name}:${String(this._id)}] No handler registered for action type: '${
|
|
936
|
+
const r = t.constructor.name || "UnnamedConstructor";
|
|
937
|
+
d.warn(
|
|
938
|
+
`[Bloc ${this._name}:${String(this._id)}] No handler registered for action type: '${r}'.`,
|
|
812
939
|
"Registered handlers:",
|
|
813
|
-
Array.from(this.eventHandlers.keys()).map((
|
|
940
|
+
Array.from(this.eventHandlers.keys()).map((o) => o.name),
|
|
814
941
|
"Action was:",
|
|
815
942
|
t
|
|
816
943
|
);
|
|
817
944
|
}
|
|
818
945
|
}
|
|
819
946
|
}
|
|
820
|
-
class
|
|
947
|
+
class H extends x {
|
|
948
|
+
/**
|
|
949
|
+
* @internal
|
|
950
|
+
* Protected method for useBloc to call
|
|
951
|
+
*/
|
|
952
|
+
_updateProps(e) {
|
|
953
|
+
var s;
|
|
954
|
+
const t = this.props;
|
|
955
|
+
this.props = e, (s = this.onPropsChanged) == null || s.call(this, t, e);
|
|
956
|
+
}
|
|
821
957
|
/**
|
|
822
958
|
* Updates the current state and notifies all observers of the change.
|
|
823
959
|
* If the new state is identical to the current state (using Object.is),
|
|
@@ -833,14 +969,14 @@ class k extends v {
|
|
|
833
969
|
/**
|
|
834
970
|
* Partially updates the current state by merging it with the provided state patch.
|
|
835
971
|
* This method is only applicable when the state is an object type.
|
|
836
|
-
*
|
|
972
|
+
*
|
|
837
973
|
* @param statePatch - A partial state object containing only the properties to update
|
|
838
974
|
* @param ignoreChangeCheck - If true, skips checking if the state has actually changed
|
|
839
975
|
* @throws {TypeError} If the state is not an object type
|
|
840
976
|
*/
|
|
841
977
|
patch(e, t = !1) {
|
|
842
978
|
if (typeof this.state != "object" || this.state === null) {
|
|
843
|
-
|
|
979
|
+
d.warn(
|
|
844
980
|
"Cubit.patch: was called on a cubit where the state is not an object. This is a no-op."
|
|
845
981
|
);
|
|
846
982
|
return;
|
|
@@ -851,8 +987,8 @@ class k extends v {
|
|
|
851
987
|
else
|
|
852
988
|
for (const n in e)
|
|
853
989
|
if (Object.prototype.hasOwnProperty.call(e, n)) {
|
|
854
|
-
const
|
|
855
|
-
if (!Object.is(e[n],
|
|
990
|
+
const o = this.state[n];
|
|
991
|
+
if (!Object.is(e[n], o)) {
|
|
856
992
|
s = !0;
|
|
857
993
|
break;
|
|
858
994
|
}
|
|
@@ -863,40 +999,64 @@ class k extends v {
|
|
|
863
999
|
});
|
|
864
1000
|
}
|
|
865
1001
|
}
|
|
866
|
-
class
|
|
1002
|
+
class N {
|
|
1003
|
+
constructor(e) {
|
|
1004
|
+
this.props = e;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
function j(c, e) {
|
|
1008
|
+
if (Object.is(c, e))
|
|
1009
|
+
return !0;
|
|
1010
|
+
if (typeof c != "object" || c === null || typeof e != "object" || e === null)
|
|
1011
|
+
return !1;
|
|
1012
|
+
const t = Object.keys(c), s = Object.keys(e);
|
|
1013
|
+
if (t.length !== s.length)
|
|
1014
|
+
return !1;
|
|
1015
|
+
for (let n = 0; n < t.length; n++) {
|
|
1016
|
+
const r = t[n];
|
|
1017
|
+
if (!Object.prototype.hasOwnProperty.call(e, r) || !Object.is(c[r], e[r]))
|
|
1018
|
+
return !1;
|
|
1019
|
+
}
|
|
1020
|
+
return !0;
|
|
1021
|
+
}
|
|
1022
|
+
class L {
|
|
867
1023
|
/**
|
|
868
1024
|
* Sets up a clean test environment
|
|
869
1025
|
*/
|
|
870
1026
|
static setUp() {
|
|
871
|
-
this.originalInstance =
|
|
1027
|
+
this.originalInstance = d.instance, d.resetInstance(), d.enableLog = !1;
|
|
872
1028
|
}
|
|
873
1029
|
/**
|
|
874
1030
|
* Tears down the test environment and restores original state
|
|
875
1031
|
*/
|
|
876
1032
|
static tearDown() {
|
|
877
|
-
|
|
1033
|
+
d.resetInstance();
|
|
878
1034
|
}
|
|
879
1035
|
/**
|
|
880
1036
|
* Creates a test bloc with automatic cleanup
|
|
881
1037
|
*/
|
|
882
1038
|
static createBloc(e, ...t) {
|
|
883
1039
|
const s = new e(...t);
|
|
884
|
-
return
|
|
1040
|
+
return d.activateBloc(s), s;
|
|
885
1041
|
}
|
|
886
1042
|
/**
|
|
887
1043
|
* Waits for a bloc to emit a specific state
|
|
888
1044
|
*/
|
|
889
1045
|
static async waitForState(e, t, s = 5e3) {
|
|
890
|
-
return new Promise((n,
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1046
|
+
return new Promise((n, r) => {
|
|
1047
|
+
const o = setTimeout(() => {
|
|
1048
|
+
r(
|
|
1049
|
+
new Error(
|
|
1050
|
+
`Timeout waiting for state matching predicate after ${s}ms`
|
|
1051
|
+
)
|
|
1052
|
+
);
|
|
1053
|
+
}, s), a = e._observer.subscribe({
|
|
1054
|
+
id: `test-waiter-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
1055
|
+
fn: (u) => {
|
|
1056
|
+
t(u) && (clearTimeout(o), a(), n(u));
|
|
897
1057
|
}
|
|
898
1058
|
});
|
|
899
|
-
t(e.state) && (clearTimeout(
|
|
1059
|
+
t(e.state) && (clearTimeout(o), a(), n(e.state));
|
|
900
1060
|
});
|
|
901
1061
|
}
|
|
902
1062
|
/**
|
|
@@ -904,34 +1064,38 @@ class $ {
|
|
|
904
1064
|
*/
|
|
905
1065
|
static async expectStates(e, t, s = 5e3) {
|
|
906
1066
|
const n = [];
|
|
907
|
-
return new Promise((
|
|
908
|
-
const
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1067
|
+
return new Promise((r, o) => {
|
|
1068
|
+
const a = setTimeout(() => {
|
|
1069
|
+
o(
|
|
1070
|
+
new Error(
|
|
1071
|
+
`Timeout waiting for states. Expected: ${JSON.stringify(t)}, Received: ${JSON.stringify(n)}`
|
|
1072
|
+
)
|
|
1073
|
+
);
|
|
1074
|
+
}, s), u = e._observer.subscribe({
|
|
913
1075
|
id: `test-expecter-${crypto.randomUUID()}`,
|
|
914
|
-
fn: (
|
|
915
|
-
if (n.push(
|
|
916
|
-
clearTimeout(
|
|
917
|
-
for (let
|
|
918
|
-
const
|
|
919
|
-
if (JSON.stringify(
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1076
|
+
fn: (p) => {
|
|
1077
|
+
if (n.push(p), n.length === t.length) {
|
|
1078
|
+
clearTimeout(a), u();
|
|
1079
|
+
for (let h = 0; h < t.length; h++) {
|
|
1080
|
+
const m = t[h], I = n[h];
|
|
1081
|
+
if (JSON.stringify(m) !== JSON.stringify(I)) {
|
|
1082
|
+
o(
|
|
1083
|
+
new Error(
|
|
1084
|
+
`State mismatch at index ${h}. Expected: ${JSON.stringify(m)}, Received: ${JSON.stringify(I)}`
|
|
1085
|
+
)
|
|
1086
|
+
);
|
|
923
1087
|
return;
|
|
924
1088
|
}
|
|
925
1089
|
}
|
|
926
|
-
|
|
1090
|
+
r();
|
|
927
1091
|
}
|
|
928
1092
|
}
|
|
929
1093
|
});
|
|
930
1094
|
});
|
|
931
1095
|
}
|
|
932
1096
|
}
|
|
933
|
-
i(
|
|
934
|
-
class
|
|
1097
|
+
i(L, "originalInstance");
|
|
1098
|
+
class Q extends U {
|
|
935
1099
|
constructor(t) {
|
|
936
1100
|
super(t);
|
|
937
1101
|
i(this, "mockHandlers", /* @__PURE__ */ new Map());
|
|
@@ -955,7 +1119,7 @@ class M extends S {
|
|
|
955
1119
|
return this.eventHandlers.has(t);
|
|
956
1120
|
}
|
|
957
1121
|
}
|
|
958
|
-
class
|
|
1122
|
+
class W extends H {
|
|
959
1123
|
constructor(t) {
|
|
960
1124
|
super(t);
|
|
961
1125
|
i(this, "stateHistory", []);
|
|
@@ -980,16 +1144,16 @@ class E extends k {
|
|
|
980
1144
|
this.stateHistory = [this.state];
|
|
981
1145
|
}
|
|
982
1146
|
}
|
|
983
|
-
class
|
|
1147
|
+
class F {
|
|
984
1148
|
constructor() {
|
|
985
1149
|
i(this, "initialStats");
|
|
986
|
-
this.initialStats =
|
|
1150
|
+
this.initialStats = d.getMemoryStats();
|
|
987
1151
|
}
|
|
988
1152
|
/**
|
|
989
1153
|
* Check for memory leaks and return a report
|
|
990
1154
|
*/
|
|
991
1155
|
checkForLeaks() {
|
|
992
|
-
const e =
|
|
1156
|
+
const e = d.getMemoryStats(), t = e.registeredBlocs > this.initialStats.registeredBlocs || e.isolatedBlocs > this.initialStats.isolatedBlocs || e.keepAliveBlocs > this.initialStats.keepAliveBlocs, s = `
|
|
993
1157
|
Memory Leak Detection Report:
|
|
994
1158
|
- Initial registered blocs: ${this.initialStats.registeredBlocs}
|
|
995
1159
|
- Current registered blocs: ${e.registeredBlocs}
|
|
@@ -1006,17 +1170,419 @@ Memory Leak Detection Report:
|
|
|
1006
1170
|
};
|
|
1007
1171
|
}
|
|
1008
1172
|
}
|
|
1173
|
+
class z {
|
|
1174
|
+
constructor() {
|
|
1175
|
+
i(this, "consumers", /* @__PURE__ */ new WeakMap());
|
|
1176
|
+
i(this, "registrationCount", 0);
|
|
1177
|
+
i(this, "activeConsumers", 0);
|
|
1178
|
+
}
|
|
1179
|
+
register(e, t) {
|
|
1180
|
+
this.registrationCount++, this.consumers.get(e) || this.activeConsumers++, this.consumers.set(e, {
|
|
1181
|
+
id: t,
|
|
1182
|
+
lastNotified: Date.now(),
|
|
1183
|
+
hasRendered: !1,
|
|
1184
|
+
stateAccesses: /* @__PURE__ */ new Set(),
|
|
1185
|
+
classAccesses: /* @__PURE__ */ new Set(),
|
|
1186
|
+
stateValues: /* @__PURE__ */ new Map(),
|
|
1187
|
+
classValues: /* @__PURE__ */ new Map(),
|
|
1188
|
+
accessCount: 0,
|
|
1189
|
+
lastAccessTime: 0,
|
|
1190
|
+
firstAccessTime: 0
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
unregister(e) {
|
|
1194
|
+
e && this.consumers.get(e) && (this.consumers.delete(e), this.activeConsumers = Math.max(0, this.activeConsumers - 1));
|
|
1195
|
+
}
|
|
1196
|
+
trackAccess(e, t, s, n) {
|
|
1197
|
+
const r = this.consumers.get(e);
|
|
1198
|
+
if (!r) return;
|
|
1199
|
+
const o = Date.now();
|
|
1200
|
+
r.firstAccessTime || (r.firstAccessTime = o), r.accessCount++, r.lastAccessTime = o, t === "state" ? (r.stateAccesses.add(s), n !== void 0 && r.stateValues.set(s, { value: n, lastAccessTime: o })) : (r.classAccesses.add(s), n !== void 0 && r.classValues.set(s, { value: n, lastAccessTime: o }));
|
|
1201
|
+
}
|
|
1202
|
+
resetTracking(e) {
|
|
1203
|
+
const t = this.consumers.get(e);
|
|
1204
|
+
t && (t.stateAccesses.clear(), t.classAccesses.clear(), t.stateValues.clear(), t.classValues.clear(), t.accessCount = 0, t.firstAccessTime = 0);
|
|
1205
|
+
}
|
|
1206
|
+
getDependencies(e) {
|
|
1207
|
+
const t = this.consumers.get(e);
|
|
1208
|
+
return t ? {
|
|
1209
|
+
statePaths: Array.from(t.stateAccesses),
|
|
1210
|
+
classPaths: Array.from(t.classAccesses)
|
|
1211
|
+
} : null;
|
|
1212
|
+
}
|
|
1213
|
+
hasValuesChanged(e, t, s) {
|
|
1214
|
+
const n = this.consumers.get(e);
|
|
1215
|
+
if (!n) return !0;
|
|
1216
|
+
let r = !1;
|
|
1217
|
+
const o = Date.now();
|
|
1218
|
+
if (n.stateValues.size === 0 && n.classValues.size === 0 && (n.stateAccesses.size > 0 || n.classAccesses.size > 0))
|
|
1219
|
+
return !0;
|
|
1220
|
+
for (const [a, u] of n.stateValues)
|
|
1221
|
+
try {
|
|
1222
|
+
const p = this.getValueAtPath(t, a);
|
|
1223
|
+
p !== u.value && (n.stateValues.set(a, {
|
|
1224
|
+
value: p,
|
|
1225
|
+
lastAccessTime: o
|
|
1226
|
+
}), r = !0);
|
|
1227
|
+
} catch {
|
|
1228
|
+
r = !0;
|
|
1229
|
+
}
|
|
1230
|
+
for (const [a, u] of n.classValues)
|
|
1231
|
+
try {
|
|
1232
|
+
const p = this.getValueAtPath(s, a);
|
|
1233
|
+
p !== u.value && (n.classValues.set(a, {
|
|
1234
|
+
value: p,
|
|
1235
|
+
lastAccessTime: o
|
|
1236
|
+
}), r = !0);
|
|
1237
|
+
} catch {
|
|
1238
|
+
r = !0;
|
|
1239
|
+
}
|
|
1240
|
+
return r;
|
|
1241
|
+
}
|
|
1242
|
+
shouldNotifyConsumer(e, t) {
|
|
1243
|
+
const s = this.consumers.get(e);
|
|
1244
|
+
if (!s) return !1;
|
|
1245
|
+
for (const n of t) {
|
|
1246
|
+
if (s.stateAccesses.has(n) || s.classAccesses.has(n)) return !0;
|
|
1247
|
+
for (const r of s.stateAccesses)
|
|
1248
|
+
if (n.startsWith(r + ".") || r.startsWith(n + "."))
|
|
1249
|
+
return !0;
|
|
1250
|
+
}
|
|
1251
|
+
return !1;
|
|
1252
|
+
}
|
|
1253
|
+
updateLastNotified(e) {
|
|
1254
|
+
const t = this.consumers.get(e);
|
|
1255
|
+
t && (t.lastNotified = Date.now());
|
|
1256
|
+
}
|
|
1257
|
+
getConsumerInfo(e) {
|
|
1258
|
+
return this.consumers.get(e);
|
|
1259
|
+
}
|
|
1260
|
+
setHasRendered(e, t) {
|
|
1261
|
+
const s = this.consumers.get(e);
|
|
1262
|
+
s && (s.hasRendered = t);
|
|
1263
|
+
}
|
|
1264
|
+
hasConsumer(e) {
|
|
1265
|
+
return this.consumers.has(e);
|
|
1266
|
+
}
|
|
1267
|
+
getStats() {
|
|
1268
|
+
return {
|
|
1269
|
+
totalRegistrations: this.registrationCount,
|
|
1270
|
+
activeConsumers: this.activeConsumers
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
getValueAtPath(e, t) {
|
|
1274
|
+
const s = t.split(".");
|
|
1275
|
+
let n = e;
|
|
1276
|
+
for (const r of s) {
|
|
1277
|
+
if (n == null) return;
|
|
1278
|
+
n = n[r];
|
|
1279
|
+
}
|
|
1280
|
+
return n;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
const k = /* @__PURE__ */ new WeakMap();
|
|
1284
|
+
let f = {
|
|
1285
|
+
stateProxiesCreated: 0,
|
|
1286
|
+
classProxiesCreated: 0,
|
|
1287
|
+
cacheHits: 0,
|
|
1288
|
+
cacheMisses: 0,
|
|
1289
|
+
propertyAccesses: 0,
|
|
1290
|
+
nestedProxiesCreated: 0,
|
|
1291
|
+
totalProxiesCreated: 0,
|
|
1292
|
+
createdAt: Date.now()
|
|
1293
|
+
};
|
|
1294
|
+
class b {
|
|
1295
|
+
static createStateProxy(e) {
|
|
1296
|
+
const { target: t, consumerRef: s, consumerTracker: n, path: r = "" } = e;
|
|
1297
|
+
if (!s || !n || typeof t != "object" || t === null)
|
|
1298
|
+
return t;
|
|
1299
|
+
let o = k.get(t);
|
|
1300
|
+
o || (o = /* @__PURE__ */ new WeakMap(), k.set(t, o));
|
|
1301
|
+
const a = o.get(s);
|
|
1302
|
+
if (a)
|
|
1303
|
+
return f.cacheHits++, a;
|
|
1304
|
+
f.cacheMisses++;
|
|
1305
|
+
const u = {
|
|
1306
|
+
get(h, m) {
|
|
1307
|
+
if (typeof m == "symbol" || m === "constructor")
|
|
1308
|
+
return Reflect.get(h, m);
|
|
1309
|
+
const I = r ? `${r}.${m}` : m;
|
|
1310
|
+
f.propertyAccesses++;
|
|
1311
|
+
const g = Reflect.get(h, m), w = g && typeof g === "object" && g !== null ? void 0 : g;
|
|
1312
|
+
if (n.trackAccess(s, "state", I, w), g && typeof g == "object" && g !== null) {
|
|
1313
|
+
const B = Object.getPrototypeOf(g) === Object.prototype, P = Array.isArray(g);
|
|
1314
|
+
if (B || P)
|
|
1315
|
+
return f.nestedProxiesCreated++, b.createStateProxy({
|
|
1316
|
+
target: g,
|
|
1317
|
+
consumerRef: s,
|
|
1318
|
+
consumerTracker: n,
|
|
1319
|
+
path: I
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
return g;
|
|
1323
|
+
},
|
|
1324
|
+
has(h, m) {
|
|
1325
|
+
return m in h;
|
|
1326
|
+
},
|
|
1327
|
+
ownKeys(h) {
|
|
1328
|
+
return Reflect.ownKeys(h);
|
|
1329
|
+
},
|
|
1330
|
+
getOwnPropertyDescriptor(h, m) {
|
|
1331
|
+
return Reflect.getOwnPropertyDescriptor(h, m);
|
|
1332
|
+
},
|
|
1333
|
+
set() {
|
|
1334
|
+
return !1;
|
|
1335
|
+
},
|
|
1336
|
+
deleteProperty() {
|
|
1337
|
+
return !1;
|
|
1338
|
+
}
|
|
1339
|
+
}, p = new Proxy(t, u);
|
|
1340
|
+
return o.set(s, p), f.stateProxiesCreated++, f.totalProxiesCreated++, p;
|
|
1341
|
+
}
|
|
1342
|
+
static createClassProxy(e) {
|
|
1343
|
+
const { target: t, consumerRef: s, consumerTracker: n } = e;
|
|
1344
|
+
if (!s || !n)
|
|
1345
|
+
return t;
|
|
1346
|
+
let r = k.get(t);
|
|
1347
|
+
r || (r = /* @__PURE__ */ new WeakMap(), k.set(t, r));
|
|
1348
|
+
const o = r.get(s);
|
|
1349
|
+
if (o)
|
|
1350
|
+
return f.cacheHits++, o;
|
|
1351
|
+
f.cacheMisses++;
|
|
1352
|
+
const a = {
|
|
1353
|
+
get(p, h) {
|
|
1354
|
+
const m = Reflect.get(p, h);
|
|
1355
|
+
let I = !1, g = p;
|
|
1356
|
+
const A = /* @__PURE__ */ new WeakSet(), D = 10;
|
|
1357
|
+
let w = 0;
|
|
1358
|
+
for (; g && !I && w < D && !A.has(g); ) {
|
|
1359
|
+
A.add(g);
|
|
1360
|
+
try {
|
|
1361
|
+
const T = Object.getOwnPropertyDescriptor(
|
|
1362
|
+
g,
|
|
1363
|
+
h
|
|
1364
|
+
);
|
|
1365
|
+
if (T && T.get) {
|
|
1366
|
+
I = !0;
|
|
1367
|
+
break;
|
|
1368
|
+
}
|
|
1369
|
+
g = Object.getPrototypeOf(g), w++;
|
|
1370
|
+
} catch {
|
|
1371
|
+
break;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
if (!I)
|
|
1375
|
+
return m;
|
|
1376
|
+
f.propertyAccesses++;
|
|
1377
|
+
const B = m, M = B !== null && typeof B != "object" ? B : void 0;
|
|
1378
|
+
return n.trackAccess(
|
|
1379
|
+
s,
|
|
1380
|
+
"class",
|
|
1381
|
+
String(h),
|
|
1382
|
+
M
|
|
1383
|
+
), m;
|
|
1384
|
+
},
|
|
1385
|
+
has(p, h) {
|
|
1386
|
+
return h in p;
|
|
1387
|
+
},
|
|
1388
|
+
ownKeys(p) {
|
|
1389
|
+
return Reflect.ownKeys(p);
|
|
1390
|
+
},
|
|
1391
|
+
getOwnPropertyDescriptor(p, h) {
|
|
1392
|
+
return Reflect.getOwnPropertyDescriptor(p, h);
|
|
1393
|
+
}
|
|
1394
|
+
}, u = new Proxy(t, a);
|
|
1395
|
+
return r.set(s, u), f.classProxiesCreated++, f.totalProxiesCreated++, u;
|
|
1396
|
+
}
|
|
1397
|
+
static getProxyState(e) {
|
|
1398
|
+
return b.createStateProxy({
|
|
1399
|
+
target: e.state,
|
|
1400
|
+
consumerRef: e.consumerRef,
|
|
1401
|
+
consumerTracker: e.consumerTracker
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
static getProxyBlocInstance(e) {
|
|
1405
|
+
return b.createClassProxy({
|
|
1406
|
+
target: e.blocInstance,
|
|
1407
|
+
consumerRef: e.consumerRef,
|
|
1408
|
+
consumerTracker: e.consumerTracker
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
static getStats() {
|
|
1412
|
+
const e = Date.now() - f.createdAt;
|
|
1413
|
+
return {
|
|
1414
|
+
...f,
|
|
1415
|
+
totalProxies: f.stateProxiesCreated + f.classProxiesCreated,
|
|
1416
|
+
cacheEfficiency: f.cacheHits + f.cacheMisses > 0 ? `${(f.cacheHits / (f.cacheHits + f.cacheMisses) * 100).toFixed(1)}%` : "N/A",
|
|
1417
|
+
lifetime: `${e}ms`,
|
|
1418
|
+
proxiesPerSecond: e > 0 ? (f.totalProxiesCreated / (e / 1e3)).toFixed(2) : "N/A"
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
static resetStats() {
|
|
1422
|
+
f = {
|
|
1423
|
+
stateProxiesCreated: 0,
|
|
1424
|
+
classProxiesCreated: 0,
|
|
1425
|
+
cacheHits: 0,
|
|
1426
|
+
cacheMisses: 0,
|
|
1427
|
+
propertyAccesses: 0,
|
|
1428
|
+
nestedProxiesCreated: 0,
|
|
1429
|
+
totalProxiesCreated: 0,
|
|
1430
|
+
createdAt: Date.now()
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
const v = class v {
|
|
1435
|
+
constructor(e, t) {
|
|
1436
|
+
i(this, "id", `consumer-${$()}`);
|
|
1437
|
+
i(this, "blocConstructor");
|
|
1438
|
+
i(this, "componentRef", { current: {} });
|
|
1439
|
+
i(this, "blocInstance");
|
|
1440
|
+
// Core components
|
|
1441
|
+
i(this, "consumerTracker");
|
|
1442
|
+
i(this, "lastProps");
|
|
1443
|
+
i(this, "unmountTime", 0);
|
|
1444
|
+
i(this, "mountTime", 0);
|
|
1445
|
+
// Dependency tracking
|
|
1446
|
+
i(this, "dependencyValues");
|
|
1447
|
+
i(this, "isUsingDependencies", !1);
|
|
1448
|
+
// Lifecycle state
|
|
1449
|
+
i(this, "hasMounted", !1);
|
|
1450
|
+
i(this, "mountCount", 0);
|
|
1451
|
+
i(this, "options");
|
|
1452
|
+
i(this, "createStateProxy", (e) => b.createStateProxy({
|
|
1453
|
+
target: e.target,
|
|
1454
|
+
consumerRef: this.componentRef.current,
|
|
1455
|
+
consumerTracker: this
|
|
1456
|
+
}));
|
|
1457
|
+
i(this, "createClassProxy", (e) => b.createClassProxy({
|
|
1458
|
+
target: e.target,
|
|
1459
|
+
consumerRef: this.componentRef.current,
|
|
1460
|
+
consumerTracker: this
|
|
1461
|
+
}));
|
|
1462
|
+
i(this, "createSubscription", (e) => this.blocInstance._observer.subscribe({
|
|
1463
|
+
id: this.id,
|
|
1464
|
+
fn: (s, n) => {
|
|
1465
|
+
var r;
|
|
1466
|
+
if (this.isUsingDependencies && ((r = this.options) != null && r.dependencies)) {
|
|
1467
|
+
const o = this.options.dependencies(this.blocInstance);
|
|
1468
|
+
if (!this.hasDependencyValuesChanged(
|
|
1469
|
+
this.dependencyValues,
|
|
1470
|
+
o
|
|
1471
|
+
))
|
|
1472
|
+
return;
|
|
1473
|
+
this.dependencyValues = o;
|
|
1474
|
+
} else if (d.config.proxyDependencyTracking) {
|
|
1475
|
+
const o = this.consumerTracker.getConsumerInfo(
|
|
1476
|
+
this.componentRef.current
|
|
1477
|
+
);
|
|
1478
|
+
if (o && o.hasRendered && !this.consumerTracker.hasValuesChanged(
|
|
1479
|
+
this.componentRef.current,
|
|
1480
|
+
s,
|
|
1481
|
+
this.blocInstance
|
|
1482
|
+
))
|
|
1483
|
+
return;
|
|
1484
|
+
} else {
|
|
1485
|
+
e.onChange();
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
e.onChange();
|
|
1489
|
+
}
|
|
1490
|
+
}));
|
|
1491
|
+
i(this, "mount", () => {
|
|
1492
|
+
var e, t;
|
|
1493
|
+
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))
|
|
1494
|
+
try {
|
|
1495
|
+
this.options.onMount(this.blocInstance);
|
|
1496
|
+
} catch (s) {
|
|
1497
|
+
throw s;
|
|
1498
|
+
}
|
|
1499
|
+
});
|
|
1500
|
+
i(this, "unmount", () => {
|
|
1501
|
+
var e;
|
|
1502
|
+
if (this.unmountTime = Date.now(), this.consumerTracker.unregister(this.componentRef.current), this.blocInstance._removeConsumer(this.id), v.propsOwners.get(this.blocInstance) === this.id && v.propsOwners.delete(this.blocInstance), (e = this.options) != null && e.onUnmount)
|
|
1503
|
+
try {
|
|
1504
|
+
this.options.onUnmount(this.blocInstance);
|
|
1505
|
+
} catch {
|
|
1506
|
+
}
|
|
1507
|
+
});
|
|
1508
|
+
i(this, "getProxyState", (e) => this.isUsingDependencies || !d.config.proxyDependencyTracking ? e : b.getProxyState({
|
|
1509
|
+
state: e,
|
|
1510
|
+
consumerRef: this.componentRef.current,
|
|
1511
|
+
consumerTracker: this
|
|
1512
|
+
}));
|
|
1513
|
+
i(this, "getProxyBlocInstance", () => this.isUsingDependencies || !d.config.proxyDependencyTracking ? this.blocInstance : b.getProxyBlocInstance({
|
|
1514
|
+
blocInstance: this.blocInstance,
|
|
1515
|
+
consumerRef: this.componentRef.current,
|
|
1516
|
+
consumerTracker: this
|
|
1517
|
+
}));
|
|
1518
|
+
this.options = t, this.blocConstructor = e.blocConstructor, this.componentRef = e.componentRef, this.isUsingDependencies = !!(t != null && t.dependencies), this.consumerTracker = new z(), 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);
|
|
1519
|
+
}
|
|
1520
|
+
trackAccess(e, t, s, n) {
|
|
1521
|
+
this.consumerTracker.trackAccess(e, t, s, n);
|
|
1522
|
+
}
|
|
1523
|
+
getConsumerDependencies(e) {
|
|
1524
|
+
return this.consumerTracker.getDependencies(e);
|
|
1525
|
+
}
|
|
1526
|
+
shouldNotifyConsumer(e, t) {
|
|
1527
|
+
const s = this.consumerTracker.getConsumerInfo(e);
|
|
1528
|
+
return !s || !s.hasRendered ? !0 : this.consumerTracker.shouldNotifyConsumer(e, t);
|
|
1529
|
+
}
|
|
1530
|
+
updateLastNotified(e) {
|
|
1531
|
+
this.consumerTracker.updateLastNotified(e), this.consumerTracker.setHasRendered(e, !0);
|
|
1532
|
+
}
|
|
1533
|
+
resetConsumerTracking() {
|
|
1534
|
+
this.consumerTracker.resetTracking(this.componentRef.current);
|
|
1535
|
+
}
|
|
1536
|
+
updateBlocInstance() {
|
|
1537
|
+
var e, t;
|
|
1538
|
+
return this.blocInstance = d.instance.getBloc(this.blocConstructor, {
|
|
1539
|
+
props: (e = this.options) == null ? void 0 : e.props,
|
|
1540
|
+
id: (t = this.options) == null ? void 0 : t.id,
|
|
1541
|
+
instanceRef: this.id
|
|
1542
|
+
}), this.blocInstance;
|
|
1543
|
+
}
|
|
1544
|
+
// Expose calledOnMount for backward compatibility
|
|
1545
|
+
get calledOnMount() {
|
|
1546
|
+
return this.hasMounted;
|
|
1547
|
+
}
|
|
1548
|
+
updateProps(e) {
|
|
1549
|
+
const t = this.blocInstance;
|
|
1550
|
+
if (v.propsOwners.has(t) || v.propsOwners.set(t, this.id), v.propsOwners.get(t) !== this.id) {
|
|
1551
|
+
d.warn(
|
|
1552
|
+
`[BlacAdapter] Attempted to set props on ${t.constructor.name} from non-owner adapter`
|
|
1553
|
+
);
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
t._disposalState === _.DISPOSED || t._disposalState === _.DISPOSING || j(this.lastProps, e) || ("add" in t && typeof t.add == "function" ? t.add(new N(e)) : "_updateProps" in t && typeof t._updateProps == "function" && t._updateProps(e), this.lastProps = e);
|
|
1557
|
+
}
|
|
1558
|
+
hasDependencyValuesChanged(e, t) {
|
|
1559
|
+
if (!e || e.length !== t.length) return !0;
|
|
1560
|
+
for (let s = 0; s < e.length; s++)
|
|
1561
|
+
if (!Object.is(e[s], t[s]))
|
|
1562
|
+
return !0;
|
|
1563
|
+
return !1;
|
|
1564
|
+
}
|
|
1565
|
+
};
|
|
1566
|
+
// Props ownership tracking
|
|
1567
|
+
i(v, "propsOwners", /* @__PURE__ */ new WeakMap());
|
|
1568
|
+
let R = v;
|
|
1009
1569
|
export {
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1570
|
+
d as Blac,
|
|
1571
|
+
R as BlacAdapter,
|
|
1572
|
+
V as BlacObservable,
|
|
1573
|
+
U as Bloc,
|
|
1574
|
+
x as BlocBase,
|
|
1575
|
+
_ as BlocLifecycleState,
|
|
1576
|
+
L as BlocTest,
|
|
1577
|
+
z as ConsumerTracker,
|
|
1578
|
+
H as Cubit,
|
|
1579
|
+
F as MemoryLeakDetector,
|
|
1580
|
+
Q as MockBloc,
|
|
1581
|
+
W as MockCubit,
|
|
1582
|
+
N as PropsUpdated,
|
|
1583
|
+
b as ProxyFactory,
|
|
1584
|
+
$ as generateUUID,
|
|
1585
|
+
q as setBlacInstanceManager,
|
|
1586
|
+
j as shallowEqual
|
|
1021
1587
|
};
|
|
1022
1588
|
//# sourceMappingURL=index.es.js.map
|