@blac/react 2.0.0-rc-7 → 2.0.0-rc-8

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.es.js CHANGED
@@ -1,167 +1,387 @@
1
- import { useMemo as y, useRef as p, useCallback as I, useSyncExternalStore as C, useEffect as P } from "react";
2
- import { generateUUID as K, Blac as E } from "@blac/core";
3
- const $ = (c, n) => {
4
- var r;
5
- const { id: d, props: w, selector: b } = n ?? {}, s = y(() => K(), []), m = c.isolated ? s : d, i = p(/* @__PURE__ */ new Set()), l = p(/* @__PURE__ */ new Set()), h = I(() => E.getBloc(c, {
6
- id: m,
7
- props: w,
8
- instanceRef: s
9
- }), [c, m, w, s]), u = p(h());
10
- y(() => {
11
- u.current = h();
12
- }, [h]);
13
- const v = y(
14
- () => (e) => {
15
- const t = u.current;
16
- if (!t)
17
- return [];
18
- if (b)
19
- return b(e);
20
- if (t.defaultDependencySelector)
21
- return t.defaultDependencySelector(e);
22
- if (typeof e != "object")
23
- return [[e]];
24
- const a = [];
25
- for (const f of i.current)
26
- f in e && a.push(e[f]);
27
- const S = [];
28
- for (const f of l.current)
29
- if (f in t)
30
- try {
31
- const x = t[f];
32
- switch (typeof x) {
33
- case "function":
34
- continue;
35
- default:
36
- S.push(x);
37
- continue;
1
+ var W = Object.defineProperty;
2
+ var z = (c, e, s) => e in c ? W(c, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : c[e] = s;
3
+ var g = (c, e, s) => z(c, typeof e != "symbol" ? e + "" : e, s);
4
+ import { useMemo as D, useRef as p, useCallback as $, useSyncExternalStore as N, useEffect as O } from "react";
5
+ import { generateUUID as _, Blac as I } from "@blac/core";
6
+ const j = (c, e) => {
7
+ var k, F;
8
+ const { id: s, props: h, selector: f } = e ?? {}, n = D(() => _(), []), o = c.isolated ? n : s, b = p(/* @__PURE__ */ new Set()), B = p(/* @__PURE__ */ new Set()), A = p(!1), K = $(() => I.getBloc(c, {
9
+ id: o,
10
+ props: h,
11
+ instanceRef: n
12
+ }), [c, o, h, n]), v = p(K());
13
+ D(() => {
14
+ v.current = K();
15
+ }, [K]);
16
+ const R = p(void 0), E = p(void 0), M = p(void 0), t = p(void 0);
17
+ t.current !== ((k = v.current) == null ? void 0 : k.uid) && (t.current = (F = v.current) == null ? void 0 : F.uid);
18
+ const l = D(
19
+ () => (u, C) => {
20
+ const d = v.current;
21
+ if (!d)
22
+ return [[], []];
23
+ const S = C ?? R.current;
24
+ let y;
25
+ if (f)
26
+ y = [f(u, S, d), []];
27
+ else if (d.defaultDependencySelector)
28
+ y = [d.defaultDependencySelector(u, S, d), []];
29
+ else if (typeof u != "object")
30
+ y = [[u], []];
31
+ else {
32
+ const m = [], P = [];
33
+ for (const T of b.current)
34
+ T in u && m.push(u[T]);
35
+ for (const T of B.current)
36
+ if (T in d)
37
+ try {
38
+ const w = d[T];
39
+ typeof w != "function" && P.push(w);
40
+ } catch (w) {
41
+ I.instance.log("useBloc Error", w);
38
42
  }
39
- } catch (x) {
40
- E.instance.log("useBloc Error", x);
41
- }
42
- return i.current.size === 0 ? l.current.size > 0 ? [S] : [[]] : [a, S];
43
+ b.current.size === 0 && B.current.size === 0 && (A.current || m.push(u)), y = [m, P];
44
+ }
45
+ return R.current = u, y;
43
46
  },
44
47
  []
45
- ), g = y(() => ({
46
- subscribe: (e) => {
47
- const t = u.current;
48
- if (!t)
48
+ ), a = p(/* @__PURE__ */ new Map()), x = D(() => ({
49
+ subscribe: (u) => {
50
+ const C = v.current;
51
+ if (!C)
49
52
  return () => {
50
53
  };
51
- const a = {
54
+ const d = a.current.get(u);
55
+ if (d)
56
+ return d.unsubscribe;
57
+ const S = {
52
58
  fn: () => {
53
59
  try {
54
- i.current = /* @__PURE__ */ new Set(), l.current = /* @__PURE__ */ new Set(), e(t.state);
55
- } catch (f) {
60
+ !f && !C.defaultDependencySelector && (b.current = /* @__PURE__ */ new Set(), B.current = /* @__PURE__ */ new Set()), u(C.state);
61
+ } catch (P) {
56
62
  console.error({
57
- e: f,
58
- blocInstance: t,
59
- dependencyArray: v
63
+ e: P,
64
+ blocInstance: C,
65
+ dependencyArray: l
60
66
  });
61
67
  }
62
68
  },
63
69
  // Pass the dependency array to control when the subscription is updated
64
- dependencyArray: v,
70
+ dependencyArray: l,
65
71
  // Use the provided id to identify this subscription
66
- id: s
72
+ id: n
67
73
  };
68
- E.activateBloc(t);
69
- const S = t._observer.subscribe(a);
70
- return () => {
71
- S();
74
+ I.activateBloc(C);
75
+ const y = C._observer.subscribe(S), m = () => {
76
+ a.current.delete(u), y();
72
77
  };
78
+ return a.current.set(u, { observer: S, unsubscribe: m }), m;
73
79
  },
74
80
  // Return an immutable snapshot of the current bloc state
75
81
  getSnapshot: () => {
76
- const e = u.current;
77
- return e ? e.state : {};
82
+ const u = v.current;
83
+ if (!u)
84
+ return {};
85
+ const C = u.state, d = l(C, R.current), S = E.current;
86
+ let y = !1;
87
+ if (!S)
88
+ y = !0;
89
+ else if (S.length !== d.length)
90
+ y = !0;
91
+ else
92
+ for (let m = 0; m < d.length; m++) {
93
+ const P = S[m] || [], T = d[m] || [];
94
+ if (P.length !== T.length) {
95
+ y = !0;
96
+ break;
97
+ }
98
+ for (let w = 0; w < T.length; w++)
99
+ if (!Object.is(P[w], T[w])) {
100
+ y = !0;
101
+ break;
102
+ }
103
+ if (y) break;
104
+ }
105
+ return E.current = d, !y && M.current ? M.current : (M.current = C, C);
78
106
  },
79
107
  // Server snapshot mirrors the client snapshot in this implementation
80
108
  getServerSnapshot: () => {
81
- const e = u.current;
82
- return e ? e.state : {};
109
+ const u = v.current;
110
+ return u ? u.state : {};
83
111
  }
84
- }), [(r = u.current) == null ? void 0 : r.uid]);
112
+ }), []);
85
113
  return {
86
- usedKeys: i,
87
- usedClassPropKeys: l,
88
- externalStore: g,
89
- instance: u,
90
- rid: s
114
+ usedKeys: b,
115
+ usedClassPropKeys: B,
116
+ externalStore: x,
117
+ instance: v,
118
+ rid: n,
119
+ hasProxyTracking: A
91
120
  };
92
121
  };
93
- function R(c, n) {
94
- var v, g;
122
+ class U {
123
+ constructor(e = {}) {
124
+ g(this, "stateKeys", /* @__PURE__ */ new Set());
125
+ g(this, "classKeys", /* @__PURE__ */ new Set());
126
+ g(this, "batchedCallbacks", /* @__PURE__ */ new Set());
127
+ g(this, "flushScheduled", !1);
128
+ g(this, "flushTimeoutId");
129
+ g(this, "metrics", {
130
+ stateAccessCount: 0,
131
+ classAccessCount: 0,
132
+ proxyCreationCount: 0,
133
+ batchFlushCount: 0,
134
+ averageResolutionTime: 0,
135
+ memoryUsageKB: 0
136
+ });
137
+ g(this, "resolutionTimes", []);
138
+ g(this, "config");
139
+ g(this, "stateProxyCache", /* @__PURE__ */ new WeakMap());
140
+ g(this, "classProxyCache", /* @__PURE__ */ new WeakMap());
141
+ g(this, "lastStateSnapshot", null);
142
+ g(this, "lastClassSnapshot", null);
143
+ this.config = {
144
+ enableBatching: !0,
145
+ batchTimeout: 0,
146
+ // Use React's scheduler
147
+ enableMetrics: process.env.NODE_ENV === "development",
148
+ maxCacheSize: 1e3,
149
+ enableDeepTracking: !1,
150
+ ...e
151
+ };
152
+ }
153
+ trackStateAccess(e) {
154
+ this.config.enableMetrics && this.metrics.stateAccessCount++, this.stateKeys.add(e), this.config.enableBatching && this.scheduleFlush();
155
+ }
156
+ trackClassAccess(e) {
157
+ this.config.enableMetrics && this.metrics.classAccessCount++, this.classKeys.add(e), this.config.enableBatching && this.scheduleFlush();
158
+ }
159
+ createStateProxy(e, s) {
160
+ const h = this.stateProxyCache.get(e);
161
+ if (h)
162
+ return h;
163
+ const f = this.config.enableMetrics ? performance.now() : 0, n = new Proxy(e, {
164
+ get: (r, i) => {
165
+ typeof i == "string" && (this.trackStateAccess(i), s == null || s(i));
166
+ const o = r[i];
167
+ return this.config.enableDeepTracking && o && typeof o == "object" && !Array.isArray(o) ? this.createStateProxy(o) : o;
168
+ },
169
+ has: (r, i) => i in r,
170
+ ownKeys: (r) => Reflect.ownKeys(r),
171
+ getOwnPropertyDescriptor: (r, i) => Reflect.getOwnPropertyDescriptor(r, i)
172
+ });
173
+ if (this.stateProxyCache.set(e, n), this.config.enableMetrics) {
174
+ this.metrics.proxyCreationCount++;
175
+ const r = performance.now();
176
+ this.resolutionTimes.push(r - f), this.updateAverageResolutionTime();
177
+ }
178
+ return n;
179
+ }
180
+ createClassProxy(e, s) {
181
+ const h = this.classProxyCache.get(e);
182
+ if (h)
183
+ return h;
184
+ const f = this.config.enableMetrics ? performance.now() : 0, n = new Proxy(e, {
185
+ get: (r, i) => {
186
+ const o = r[i];
187
+ return typeof i == "string" && typeof o != "function" && (this.trackClassAccess(i), s == null || s(i)), o;
188
+ }
189
+ });
190
+ if (this.classProxyCache.set(e, n), this.config.enableMetrics) {
191
+ this.metrics.proxyCreationCount++;
192
+ const r = performance.now();
193
+ this.resolutionTimes.push(r - f), this.updateAverageResolutionTime();
194
+ }
195
+ return n;
196
+ }
197
+ getStateKeys() {
198
+ return new Set(this.stateKeys);
199
+ }
200
+ getClassKeys() {
201
+ return new Set(this.classKeys);
202
+ }
203
+ reset() {
204
+ this.stateKeys.clear(), this.classKeys.clear(), this.cancelScheduledFlush();
205
+ }
206
+ subscribe(e) {
207
+ return this.batchedCallbacks.add(e), () => {
208
+ this.batchedCallbacks.delete(e);
209
+ };
210
+ }
211
+ computeDependencyArray(e, s) {
212
+ const h = this.config.enableMetrics ? performance.now() : 0;
213
+ if (typeof e != "object" || e === null)
214
+ return [[e]];
215
+ const f = [];
216
+ for (const r of this.stateKeys)
217
+ r in e && f.push(e[r]);
218
+ const n = [];
219
+ for (const r of this.classKeys)
220
+ if (r in s)
221
+ try {
222
+ const i = s[r];
223
+ typeof i != "function" && n.push(i);
224
+ } catch {
225
+ }
226
+ if (this.config.enableMetrics) {
227
+ const r = performance.now();
228
+ this.resolutionTimes.push(r - h), this.updateAverageResolutionTime();
229
+ }
230
+ return f.length === 0 && n.length === 0 ? [[]] : n.length === 0 ? [f] : f.length === 0 ? [n] : [f, n];
231
+ }
232
+ getMetrics() {
233
+ if (!this.config.enableMetrics)
234
+ return {
235
+ stateAccessCount: 0,
236
+ classAccessCount: 0,
237
+ proxyCreationCount: 0,
238
+ batchFlushCount: 0,
239
+ averageResolutionTime: 0,
240
+ memoryUsageKB: 0
241
+ };
242
+ const e = this.stateKeys.size * 50 + this.classKeys.size * 50 + (this.stateProxyCache instanceof WeakMap ? 100 : 0) + (this.classProxyCache instanceof WeakMap ? 100 : 0);
243
+ return {
244
+ ...this.metrics,
245
+ memoryUsageKB: Math.round(e / 1024)
246
+ };
247
+ }
248
+ clearCaches() {
249
+ this.stateProxyCache = /* @__PURE__ */ new WeakMap(), this.classProxyCache = /* @__PURE__ */ new WeakMap(), this.resolutionTimes = [], this.config.enableMetrics && (this.metrics = {
250
+ stateAccessCount: 0,
251
+ classAccessCount: 0,
252
+ proxyCreationCount: 0,
253
+ batchFlushCount: 0,
254
+ averageResolutionTime: 0,
255
+ memoryUsageKB: 0
256
+ });
257
+ }
258
+ scheduleFlush() {
259
+ this.flushScheduled || (this.flushScheduled = !0, this.config.batchTimeout > 0 ? this.flushTimeoutId = setTimeout(() => {
260
+ this.flushBatchedChanges();
261
+ }, this.config.batchTimeout) : Promise.resolve().then(() => this.flushBatchedChanges()));
262
+ }
263
+ cancelScheduledFlush() {
264
+ this.flushTimeoutId && (clearTimeout(this.flushTimeoutId), this.flushTimeoutId = void 0), this.flushScheduled = !1;
265
+ }
266
+ flushBatchedChanges() {
267
+ if (!this.flushScheduled)
268
+ return;
269
+ this.flushScheduled = !1, this.flushTimeoutId = void 0, this.config.enableMetrics && this.metrics.batchFlushCount++;
270
+ const e = /* @__PURE__ */ new Set([...this.stateKeys, ...this.classKeys]);
271
+ for (const s of this.batchedCallbacks)
272
+ try {
273
+ s(e);
274
+ } catch (h) {
275
+ console.error("Error in dependency change callback:", h);
276
+ }
277
+ }
278
+ updateAverageResolutionTime() {
279
+ if (this.resolutionTimes.length === 0)
280
+ return;
281
+ this.resolutionTimes.length > 100 && (this.resolutionTimes = this.resolutionTimes.slice(-100));
282
+ const e = this.resolutionTimes.reduce((s, h) => s + h, 0);
283
+ this.metrics.averageResolutionTime = e / this.resolutionTimes.length;
284
+ }
285
+ }
286
+ function V(c) {
287
+ return new U(c);
288
+ }
289
+ V();
290
+ function J(c, e) {
291
+ var E, M;
95
292
  const {
96
- externalStore: d,
97
- usedKeys: w,
98
- usedClassPropKeys: b,
99
- instance: s,
100
- rid: B
101
- } = $(c, n), o = C(
102
- d.subscribe,
293
+ externalStore: s,
294
+ usedKeys: h,
295
+ usedClassPropKeys: f,
296
+ instance: n,
297
+ rid: r,
298
+ hasProxyTracking: i
299
+ } = j(c, e), o = N(
300
+ s.subscribe,
103
301
  () => {
104
- const r = d.getSnapshot();
105
- if (r === void 0)
106
- throw new Error(`[useBloc] State snapshot is undefined for bloc ${c.name}. Bloc may not be properly initialized.`);
107
- return r;
302
+ const t = s.getSnapshot();
303
+ if (t === void 0)
304
+ throw new Error(
305
+ `[useBloc] State snapshot is undefined for bloc ${c.name}. Bloc may not be properly initialized.`
306
+ );
307
+ return t;
108
308
  },
109
- d.getServerSnapshot ? () => {
110
- const r = d.getServerSnapshot();
111
- if (r === void 0)
112
- throw new Error(`[useBloc] Server state snapshot is undefined for bloc ${c.name}. Bloc may not be properly initialized.`);
113
- return r;
309
+ s.getServerSnapshot ? () => {
310
+ const t = s.getServerSnapshot();
311
+ if (t === void 0)
312
+ throw new Error(
313
+ `[useBloc] Server state snapshot is undefined for bloc ${c.name}. Bloc may not be properly initialized.`
314
+ );
315
+ return t;
114
316
  } : void 0
115
- ), m = p(/* @__PURE__ */ new WeakMap()), i = p(/* @__PURE__ */ new WeakMap()), l = y(() => {
116
- if (typeof o != "object" || o === null)
317
+ ), b = p(null);
318
+ b.current || (b.current = new U({
319
+ enableBatching: !0,
320
+ enableMetrics: process.env.NODE_ENV === "development",
321
+ enableDeepTracking: !1
322
+ }));
323
+ const B = p(/* @__PURE__ */ new WeakMap()), A = p(/* @__PURE__ */ new WeakMap()), K = D(() => {
324
+ if (e != null && e.selector || (i.current = !0, typeof o != "object" || o === null))
117
325
  return o;
118
- let r = m.current.get(o);
119
- return r || (r = new Proxy(o, {
120
- get(e, t) {
121
- return setTimeout(() => {
122
- w.current.add(t);
123
- }, 0), e[t];
326
+ let t = B.current.get(o);
327
+ return t || (t = new Proxy(o, {
328
+ get(l, a) {
329
+ var k;
330
+ return typeof a == "string" && (h.current.add(a), (k = b.current) == null || k.trackStateAccess(a)), l[a];
124
331
  },
125
- // Handle symbols and non-enumerable properties
126
- has(e, t) {
127
- return t in e;
332
+ has(l, a) {
333
+ return a in l;
128
334
  },
129
- ownKeys(e) {
130
- return Reflect.ownKeys(e);
335
+ ownKeys(l) {
336
+ return Reflect.ownKeys(l);
131
337
  },
132
- getOwnPropertyDescriptor(e, t) {
133
- return Reflect.getOwnPropertyDescriptor(e, t);
338
+ getOwnPropertyDescriptor(l, a) {
339
+ return Reflect.getOwnPropertyDescriptor(l, a);
134
340
  }
135
- }), m.current.set(o, r)), r;
136
- }, [o]), h = y(() => {
137
- if (!s.current)
138
- throw new Error(`[useBloc] Bloc instance is null for ${c.name}. This should never happen - bloc instance must be defined.`);
139
- let r = i.current.get(s.current);
140
- return r || (r = new Proxy(s.current, {
141
- get(e, t) {
142
- if (!e)
143
- throw new Error(`[useBloc] Bloc target is null for ${c.name}. This should never happen - bloc target must be defined.`);
144
- const a = e[t];
145
- return typeof a != "function" && b.current.add(t), a;
341
+ }), B.current.set(o, t)), t;
342
+ }, [o]), v = D(() => {
343
+ if (!n.current)
344
+ throw new Error(
345
+ `[useBloc] Bloc instance is null for ${c.name}. This should never happen - bloc instance must be defined.`
346
+ );
347
+ let t = A.current.get(n.current);
348
+ return t || (t = new Proxy(n.current, {
349
+ get(l, a) {
350
+ var k;
351
+ if (!l)
352
+ throw new Error(
353
+ `[useBloc] Bloc target is null for ${c.name}. This should never happen - bloc target must be defined.`
354
+ );
355
+ const x = l[a];
356
+ return typeof x != "function" && typeof a == "string" && (f.current.add(a), (k = b.current) == null || k.trackClassAccess(a)), x;
146
357
  }
147
- }), i.current.set(s.current, r)), r;
148
- }, [(v = s.current) == null ? void 0 : v.uid]), u = p({});
149
- if (P(() => {
150
- var e;
151
- const r = s.current;
152
- if (r)
153
- return r._addConsumer(B, u.current), (e = n == null ? void 0 : n.onMount) == null || e.call(n, r), () => {
154
- var t;
155
- r && ((t = n == null ? void 0 : n.onUnmount) == null || t.call(n, r), r._removeConsumer(B));
358
+ }), A.current.set(n.current, t)), t;
359
+ }, [(E = n.current) == null ? void 0 : E.uid]), R = p({});
360
+ if (O(() => {
361
+ var l;
362
+ const t = n.current;
363
+ if (t)
364
+ return t._addConsumer(r, R.current), (l = e == null ? void 0 : e.onMount) == null || l.call(e, t), () => {
365
+ var a, x;
366
+ t && ((a = e == null ? void 0 : e.onUnmount) == null || a.call(e, t), t._removeConsumer(r), (x = b.current) == null || x.reset());
156
367
  };
157
- }, [(g = s.current) == null ? void 0 : g.uid, B]), l === void 0)
158
- throw new Error(`[useBloc] State is undefined for ${c.name}. This should never happen - state must be defined.`);
159
- if (!h)
160
- throw new Error(`[useBloc] Instance is null for ${c.name}. This should never happen - instance must be defined.`);
161
- return [l, h];
368
+ }, [(M = n.current) == null ? void 0 : M.uid, r]), O(() => {
369
+ if (process.env.NODE_ENV === "development" && b.current) {
370
+ const t = b.current.getMetrics();
371
+ (t.stateAccessCount > 0 || t.classAccessCount > 0) && console.debug(`[useBloc] ${c.name} Performance Metrics:`, t);
372
+ }
373
+ }), K === void 0)
374
+ throw new Error(
375
+ `[useBloc] State is undefined for ${c.name}. This should never happen - state must be defined.`
376
+ );
377
+ if (!v)
378
+ throw new Error(
379
+ `[useBloc] Instance is null for ${c.name}. This should never happen - instance must be defined.`
380
+ );
381
+ return [K, v];
162
382
  }
163
383
  export {
164
- $ as externalBlocStore,
165
- R as useBloc
384
+ j as externalBlocStore,
385
+ J as useBloc
166
386
  };
167
387
  //# sourceMappingURL=index.es.js.map