@blac/core 2.0.0-rc.8 → 2.0.0-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/core/StateContainer.d.ts +6 -1
  2. package/dist/index.cjs +114 -286
  3. package/dist/index.d.cts +0 -1
  4. package/dist/index.d.ts +0 -1
  5. package/dist/index.js +115 -284
  6. package/package.json +2 -3
  7. package/dist/adapter/framework-adapter.d.ts.map +0 -1
  8. package/dist/adapter/index.d.ts.map +0 -1
  9. package/dist/constants.d.ts.map +0 -1
  10. package/dist/core/Cubit.d.ts.map +0 -1
  11. package/dist/core/StateContainer.d.ts.map +0 -1
  12. package/dist/core/StateContainerRegistry.d.ts.map +0 -1
  13. package/dist/core/Vertex.d.ts.map +0 -1
  14. package/dist/index.cjs.map +0 -1
  15. package/dist/index.d.ts.map +0 -1
  16. package/dist/index.js.map +0 -1
  17. package/dist/logging/Logger.d.ts.map +0 -1
  18. package/dist/plugin/BlacPlugin.d.ts.map +0 -1
  19. package/dist/plugin/PluginManager.d.ts.map +0 -1
  20. package/dist/proxy/ProxyTracker.d.ts +0 -71
  21. package/dist/proxy/ProxyTracker.d.ts.map +0 -1
  22. package/dist/registry/index.d.ts.map +0 -1
  23. package/dist/test-utils/index.d.ts.map +0 -1
  24. package/dist/tracking/dependency-tracker.d.ts.map +0 -1
  25. package/dist/tracking/getter-tracker.d.ts.map +0 -1
  26. package/dist/tracking/index.d.ts.map +0 -1
  27. package/dist/tracking/path-utils.d.ts.map +0 -1
  28. package/dist/tracking/proxy-tracker.d.ts.map +0 -1
  29. package/dist/types/branded.d.ts.map +0 -1
  30. package/dist/types/events.d.ts.map +0 -1
  31. package/dist/types/utilities.d.ts.map +0 -1
  32. package/dist/utils/equality.d.ts.map +0 -1
  33. package/dist/utils/idGenerator.d.ts.map +0 -1
  34. package/dist/utils/immutable.d.ts.map +0 -1
  35. package/dist/utils/stack-trace.d.ts.map +0 -1
  36. package/dist/utils/static-props.d.ts.map +0 -1
@@ -146,7 +146,7 @@ export declare abstract class StateContainer<S> {
146
146
  * Create a new StateContainer
147
147
  */
148
148
  constructor(initialState: S);
149
- initiConfig(config: StateContainerConfig): void;
149
+ initConfig(config: StateContainerConfig): void;
150
150
  /**
151
151
  * Get the current state
152
152
  */
@@ -168,6 +168,11 @@ export declare abstract class StateContainer<S> {
168
168
  * Emit a new state (with change detection)
169
169
  */
170
170
  protected emit(newState: S): void;
171
+ /**
172
+ * Enable stack trace capture in development
173
+ * Defaults to true, but can be disabled to improve performance
174
+ */
175
+ static enableStackTrace: boolean;
171
176
  /**
172
177
  * Capture stack trace for debugging
173
178
  * Can be overridden to disable in production
package/dist/index.cjs CHANGED
@@ -398,6 +398,9 @@ function createBlocProxy(bloc) {
398
398
  const value = getDescriptor(target, prop).get.call(target);
399
399
  tracker.trackedValues.set(prop, value);
400
400
  return value;
401
+ } catch (error$1) {
402
+ tracker.currentlyAccessing.delete(prop);
403
+ throw error$1;
401
404
  } finally {
402
405
  getterExecutionContext.tracker = prevContext.tracker;
403
406
  getterExecutionContext.currentBloc = prevContext.currentBloc;
@@ -545,7 +548,7 @@ var StateContainerRegistry = class {
545
548
  const config = { instanceId: instanceKey };
546
549
  if (isolated) {
547
550
  const instance$1 = new Type(constructorArgs);
548
- instance$1.initiConfig(config);
551
+ instance$1.initConfig(config);
549
552
  this.registerType(Type);
550
553
  return instance$1;
551
554
  }
@@ -556,7 +559,7 @@ var StateContainerRegistry = class {
556
559
  return entry.instance;
557
560
  }
558
561
  const instance = new Type(constructorArgs);
559
- instance.initiConfig(config);
562
+ instance.initConfig(config);
560
563
  instances.set(instanceKey, {
561
564
  instance,
562
565
  refCount: 1
@@ -613,7 +616,7 @@ var StateContainerRegistry = class {
613
616
  if (!entry) {
614
617
  const instance = new Type(constructorArgs);
615
618
  const config = { instanceId: instanceKey };
616
- instance.initiConfig(config);
619
+ instance.initConfig(config);
617
620
  entry = {
618
621
  instance,
619
622
  refCount: 1
@@ -919,7 +922,7 @@ var StateContainer = class StateContainer {
919
922
  this.lastUpdateTimestamp = Date.now();
920
923
  this._state = initialState;
921
924
  }
922
- initiConfig(config) {
925
+ initConfig(config) {
923
926
  this.config = { ...config };
924
927
  this.name = this.config.name || this.constructor.name;
925
928
  this.debug = this.config.debug ?? false;
@@ -977,12 +980,15 @@ var StateContainer = class StateContainer {
977
980
  StateContainer._registry.emit("stateChanged", this, previousState, newState, stackTrace);
978
981
  this.lastUpdateTimestamp = Date.now();
979
982
  }
983
+ static {
984
+ this.enableStackTrace = true;
985
+ }
980
986
  /**
981
987
  * Capture stack trace for debugging
982
988
  * Can be overridden to disable in production
983
989
  */
984
990
  captureStackTrace() {
985
- if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return "";
991
+ if (!StateContainer.enableStackTrace || typeof process !== "undefined" && process.env?.NODE_ENV === "production") return "";
986
992
  try {
987
993
  const relevantLines = ((/* @__PURE__ */ new Error()).stack || "").split("\n").slice(1);
988
994
  const formattedLines = [];
@@ -1360,6 +1366,13 @@ function hasInitHook(plugin) {
1360
1366
  //#endregion
1361
1367
  //#region src/tracking/proxy-tracker.ts
1362
1368
  /**
1369
+ * Functional proxy tracker for automatic dependency tracking
1370
+ *
1371
+ * This module provides a functional approach to proxy-based dependency tracking.
1372
+ * Unlike the class-based ProxyTracker, this uses a state object pattern that's
1373
+ * easier to integrate with functional programming patterns and framework hooks.
1374
+ */
1375
+ /**
1363
1376
  * Check if a value can be proxied
1364
1377
  *
1365
1378
  * Returns true for plain objects and arrays only.
@@ -1687,284 +1700,6 @@ function hasTrackedData(tracker) {
1687
1700
  return tracker.proxyTrackerState.trackedPaths.size > 0 || tracker.pathCache.size > 0 || tracker.previousRenderPaths.size > 0;
1688
1701
  }
1689
1702
 
1690
- //#endregion
1691
- //#region src/logging/Logger.ts
1692
- let LogLevel = /* @__PURE__ */ function(LogLevel$1) {
1693
- LogLevel$1[LogLevel$1["ERROR"] = 0] = "ERROR";
1694
- LogLevel$1[LogLevel$1["WARN"] = 1] = "WARN";
1695
- LogLevel$1[LogLevel$1["INFO"] = 2] = "INFO";
1696
- LogLevel$1[LogLevel$1["DEBUG"] = 3] = "DEBUG";
1697
- return LogLevel$1;
1698
- }({});
1699
- /**
1700
- * Creates a logger instance with given configuration
1701
- *
1702
- * @param config - Logger configuration
1703
- * @returns Logger instance with debug, info, warn, error, and configure methods
1704
- *
1705
- * @example
1706
- * ```ts
1707
- * const logger = createLogger({
1708
- * enabled: true,
1709
- * level: LogLevel.DEBUG,
1710
- * output: (entry) => console.log(JSON.stringify(entry))
1711
- * });
1712
- * logger.debug('MyComponent', 'Rendering', { props: { foo: 'bar' } });
1713
- * ```
1714
- */
1715
- function createLogger(config) {
1716
- const shouldLog = (level) => {
1717
- return config.enabled && config.level >= level;
1718
- };
1719
- const log = (level, context, message, data) => {
1720
- try {
1721
- const entry = {
1722
- level,
1723
- context,
1724
- message,
1725
- timestamp: Date.now(),
1726
- ...data !== void 0 && { data: serialize(data) }
1727
- };
1728
- config.output(entry);
1729
- } catch (e) {
1730
- console.error("[BlacLogger] Error logging:", e);
1731
- }
1732
- };
1733
- const serialize = (data) => {
1734
- try {
1735
- return JSON.parse(JSON.stringify(data));
1736
- } catch {
1737
- return String(data);
1738
- }
1739
- };
1740
- return {
1741
- debug: (context, message, data) => {
1742
- if (shouldLog(LogLevel.DEBUG)) log("DEBUG", context, message, data);
1743
- },
1744
- info: (context, message, data) => {
1745
- if (shouldLog(LogLevel.INFO)) log("INFO", context, message, data);
1746
- },
1747
- warn: (context, message, data) => {
1748
- if (shouldLog(LogLevel.WARN)) log("WARN", context, message, data);
1749
- },
1750
- error: (context, message, data) => {
1751
- if (shouldLog(LogLevel.ERROR)) log("ERROR", context, message, data);
1752
- },
1753
- configure: (opts) => {
1754
- Object.assign(config, opts);
1755
- }
1756
- };
1757
- }
1758
- let currentConfig = {
1759
- enabled: false,
1760
- level: LogLevel.INFO,
1761
- output: (entry) => console.log(JSON.stringify(entry))
1762
- };
1763
- let defaultLogger = createLogger(currentConfig);
1764
- const debug = (context, message, data) => defaultLogger.debug(context, message, data);
1765
- const info = (context, message, data) => defaultLogger.info(context, message, data);
1766
- const warn = (context, message, data) => defaultLogger.warn(context, message, data);
1767
- const error = (context, message, data) => defaultLogger.error(context, message, data);
1768
- /**
1769
- * Configuration function that recreates the default logger
1770
- *
1771
- * @param opts - Partial logger configuration
1772
- *
1773
- * @example
1774
- * ```ts
1775
- * configureLogger({ enabled: true, level: LogLevel.DEBUG });
1776
- * ```
1777
- */
1778
- function configureLogger(opts) {
1779
- currentConfig = {
1780
- ...currentConfig,
1781
- ...opts
1782
- };
1783
- defaultLogger = createLogger(currentConfig);
1784
- }
1785
-
1786
- //#endregion
1787
- //#region src/proxy/ProxyTracker.ts
1788
- /**
1789
- * ProxyTracker - Automatic dependency tracking through Proxies
1790
- *
1791
- * Tracks property access on state objects to automatically determine
1792
- * which parts of the state a component depends on.
1793
- */
1794
- /**
1795
- * Check if a value is an object that can be proxied
1796
- */
1797
- function isProxyable$1(value) {
1798
- return value !== null && typeof value === "object" && !(value instanceof Date) && !(value instanceof RegExp) && !(value instanceof Map) && !(value instanceof Set) && !(value instanceof WeakMap) && !(value instanceof WeakSet) && !(value instanceof Promise);
1799
- }
1800
- /**
1801
- * Tracks property access on state objects
1802
- */
1803
- var ProxyTracker = class {
1804
- constructor() {
1805
- this.trackedPaths = /* @__PURE__ */ new Set();
1806
- this.isTracking = false;
1807
- this.proxyCache = /* @__PURE__ */ new WeakMap();
1808
- this.maxDepth = 10;
1809
- }
1810
- /**
1811
- * Create a proxy that tracks property access
1812
- */
1813
- createProxy(target, path = "", depth = 0) {
1814
- if (!this.isTracking || !isProxyable$1(target)) return target;
1815
- if (depth >= this.maxDepth) return target;
1816
- if (this.proxyCache.has(target)) return this.proxyCache.get(target);
1817
- if (Array.isArray(target)) return this.createArrayProxy(target, path, depth);
1818
- const proxy = new Proxy(target, {
1819
- get: (obj, prop) => {
1820
- const value = Reflect.get(obj, prop);
1821
- if (typeof value === "function") return value.bind(obj);
1822
- const fullPath = path ? `${path}.${String(prop)}` : String(prop);
1823
- if (isProxyable$1(value)) return this.createProxy(value, fullPath, depth + 1);
1824
- if (typeof prop === "string" && this.isTracking) {
1825
- if (!prop.startsWith("_") && !prop.startsWith("$$")) {
1826
- this.trackedPaths.add(fullPath);
1827
- debug("ProxyTracker", "Tracked property access", {
1828
- path: fullPath,
1829
- valueType: typeof value
1830
- });
1831
- }
1832
- }
1833
- return value;
1834
- },
1835
- has: (obj, prop) => {
1836
- if (typeof prop === "string" && this.isTracking) {
1837
- const fullPath = path ? `${path}.${prop}` : prop;
1838
- this.trackedPaths.add(fullPath);
1839
- debug("ProxyTracker", "Tracked \"in\" operator access", { path: fullPath });
1840
- }
1841
- return Reflect.has(obj, prop);
1842
- },
1843
- ownKeys: (obj) => {
1844
- if (this.isTracking && path) {
1845
- this.trackedPaths.add(path);
1846
- debug("ProxyTracker", "Tracked object keys iteration", { path });
1847
- }
1848
- return Reflect.ownKeys(obj);
1849
- }
1850
- });
1851
- this.proxyCache.set(target, proxy);
1852
- return proxy;
1853
- }
1854
- /**
1855
- * Create a proxy for arrays with special handling
1856
- */
1857
- createArrayProxy(target, path, depth = 0) {
1858
- const proxy = new Proxy(target, { get: (arr, prop) => {
1859
- const value = Reflect.get(arr, prop);
1860
- if (typeof value === "function") {
1861
- if (this.isTracking && path && typeof prop === "string") {
1862
- this.trackedPaths.add(path);
1863
- debug("ProxyTracker", "Tracked array method access", {
1864
- path,
1865
- method: String(prop)
1866
- });
1867
- }
1868
- return value.bind(arr);
1869
- }
1870
- let fullPath;
1871
- if (prop === "length") fullPath = path ? `${path}.length` : "length";
1872
- else if (typeof prop === "string") {
1873
- const index = Number(prop);
1874
- if (!isNaN(index) && index >= 0) fullPath = path ? `${path}[${index}]` : `[${index}]`;
1875
- else fullPath = path ? `${path}.${prop}` : prop;
1876
- } else return value;
1877
- if (isProxyable$1(value)) return this.createProxy(value, fullPath, depth + 1);
1878
- if (this.isTracking) {
1879
- this.trackedPaths.add(fullPath);
1880
- debug("ProxyTracker", "Tracked array property access", {
1881
- path: fullPath,
1882
- valueType: typeof value
1883
- });
1884
- }
1885
- return value;
1886
- } });
1887
- this.proxyCache.set(target, proxy);
1888
- return proxy;
1889
- }
1890
- /**
1891
- * Start tracking property access
1892
- */
1893
- startTracking() {
1894
- this.isTracking = true;
1895
- this.trackedPaths.clear();
1896
- debug("ProxyTracker", "Started tracking");
1897
- }
1898
- /**
1899
- * Stop tracking and return tracked paths
1900
- */
1901
- stopTracking() {
1902
- this.isTracking = false;
1903
- debug("ProxyTracker", "Stopped tracking", {
1904
- pathCount: this.trackedPaths.size,
1905
- paths: Array.from(this.trackedPaths)
1906
- });
1907
- return new Set(this.trackedPaths);
1908
- }
1909
- /**
1910
- * Get currently tracked paths
1911
- */
1912
- getTrackedPaths() {
1913
- return new Set(this.trackedPaths);
1914
- }
1915
- /**
1916
- * Check if currently tracking
1917
- */
1918
- isCurrentlyTracking() {
1919
- return this.isTracking;
1920
- }
1921
- /**
1922
- * Clear proxy cache (useful for memory management)
1923
- */
1924
- clearCache() {
1925
- this.proxyCache = /* @__PURE__ */ new WeakMap();
1926
- }
1927
- /**
1928
- * Set maximum tracking depth
1929
- */
1930
- setMaxDepth(depth) {
1931
- this.maxDepth = Math.max(1, depth);
1932
- }
1933
- /**
1934
- * Add a path manually (useful for forcing dependencies)
1935
- */
1936
- addPath(path) {
1937
- this.trackedPaths.add(path);
1938
- }
1939
- /**
1940
- * Remove a path manually
1941
- */
1942
- removePath(path) {
1943
- this.trackedPaths.delete(path);
1944
- }
1945
- /**
1946
- * Clear all tracked paths
1947
- */
1948
- clearPaths() {
1949
- this.trackedPaths.clear();
1950
- }
1951
- };
1952
- /**
1953
- * Global proxy tracker instance for convenience
1954
- */
1955
- const globalProxyTracker = new ProxyTracker();
1956
- /**
1957
- * Utility function to track property access in a callback
1958
- */
1959
- function trackAccess(state, callback) {
1960
- const tracker = new ProxyTracker();
1961
- tracker.startTracking();
1962
- return {
1963
- result: callback(tracker.createProxy(state)),
1964
- trackedPaths: tracker.stopTracking()
1965
- };
1966
- }
1967
-
1968
1703
  //#endregion
1969
1704
  //#region src/adapter/framework-adapter.ts
1970
1705
  /**
@@ -2135,6 +1870,102 @@ function disableGetterTracking(adapterState, rawInstance) {
2135
1870
  }
2136
1871
  }
2137
1872
 
1873
+ //#endregion
1874
+ //#region src/logging/Logger.ts
1875
+ let LogLevel = /* @__PURE__ */ function(LogLevel$1) {
1876
+ LogLevel$1[LogLevel$1["ERROR"] = 0] = "ERROR";
1877
+ LogLevel$1[LogLevel$1["WARN"] = 1] = "WARN";
1878
+ LogLevel$1[LogLevel$1["INFO"] = 2] = "INFO";
1879
+ LogLevel$1[LogLevel$1["DEBUG"] = 3] = "DEBUG";
1880
+ return LogLevel$1;
1881
+ }({});
1882
+ /**
1883
+ * Creates a logger instance with given configuration
1884
+ *
1885
+ * @param config - Logger configuration
1886
+ * @returns Logger instance with debug, info, warn, error, and configure methods
1887
+ *
1888
+ * @example
1889
+ * ```ts
1890
+ * const logger = createLogger({
1891
+ * enabled: true,
1892
+ * level: LogLevel.DEBUG,
1893
+ * output: (entry) => console.log(JSON.stringify(entry))
1894
+ * });
1895
+ * logger.debug('MyComponent', 'Rendering', { props: { foo: 'bar' } });
1896
+ * ```
1897
+ */
1898
+ function createLogger(config) {
1899
+ const shouldLog = (level) => {
1900
+ return config.enabled && config.level >= level;
1901
+ };
1902
+ const log = (level, context, message, data) => {
1903
+ try {
1904
+ const entry = {
1905
+ level,
1906
+ context,
1907
+ message,
1908
+ timestamp: Date.now(),
1909
+ ...data !== void 0 && { data: serialize(data) }
1910
+ };
1911
+ config.output(entry);
1912
+ } catch (e) {
1913
+ console.error("[BlacLogger] Error logging:", e);
1914
+ }
1915
+ };
1916
+ const serialize = (data) => {
1917
+ try {
1918
+ return JSON.parse(JSON.stringify(data));
1919
+ } catch {
1920
+ return String(data);
1921
+ }
1922
+ };
1923
+ return {
1924
+ debug: (context, message, data) => {
1925
+ if (shouldLog(LogLevel.DEBUG)) log("DEBUG", context, message, data);
1926
+ },
1927
+ info: (context, message, data) => {
1928
+ if (shouldLog(LogLevel.INFO)) log("INFO", context, message, data);
1929
+ },
1930
+ warn: (context, message, data) => {
1931
+ if (shouldLog(LogLevel.WARN)) log("WARN", context, message, data);
1932
+ },
1933
+ error: (context, message, data) => {
1934
+ if (shouldLog(LogLevel.ERROR)) log("ERROR", context, message, data);
1935
+ },
1936
+ configure: (opts) => {
1937
+ Object.assign(config, opts);
1938
+ }
1939
+ };
1940
+ }
1941
+ let currentConfig = {
1942
+ enabled: false,
1943
+ level: LogLevel.INFO,
1944
+ output: (entry) => console.log(JSON.stringify(entry))
1945
+ };
1946
+ let defaultLogger = createLogger(currentConfig);
1947
+ const debug = (context, message, data) => defaultLogger.debug(context, message, data);
1948
+ const info = (context, message, data) => defaultLogger.info(context, message, data);
1949
+ const warn = (context, message, data) => defaultLogger.warn(context, message, data);
1950
+ const error = (context, message, data) => defaultLogger.error(context, message, data);
1951
+ /**
1952
+ * Configuration function that recreates the default logger
1953
+ *
1954
+ * @param opts - Partial logger configuration
1955
+ *
1956
+ * @example
1957
+ * ```ts
1958
+ * configureLogger({ enabled: true, level: LogLevel.DEBUG });
1959
+ * ```
1960
+ */
1961
+ function configureLogger(opts) {
1962
+ currentConfig = {
1963
+ ...currentConfig,
1964
+ ...opts
1965
+ };
1966
+ defaultLogger = createLogger(currentConfig);
1967
+ }
1968
+
2138
1969
  //#endregion
2139
1970
  exports.AuthVertex = AuthVertex;
2140
1971
  exports.BLAC_DEFAULTS = BLAC_DEFAULTS;
@@ -2151,7 +1982,6 @@ exports.LogLevel = LogLevel;
2151
1982
  exports.LoginEvent = LoginEvent;
2152
1983
  exports.LogoutEvent = LogoutEvent;
2153
1984
  exports.PluginManager = PluginManager;
2154
- exports.ProxyTracker = ProxyTracker;
2155
1985
  exports.ResetEvent = ResetEvent;
2156
1986
  exports.StateContainer = StateContainer;
2157
1987
  exports.StateContainerRegistry = StateContainerRegistry;
@@ -2192,7 +2022,6 @@ exports.getGetterExecutionContext = getGetterExecutionContext;
2192
2022
  exports.getPluginManager = getPluginManager;
2193
2023
  exports.getStaticProp = getStaticProp;
2194
2024
  exports.getValueAtPath = getValueAtPath;
2195
- exports.globalProxyTracker = globalProxyTracker;
2196
2025
  exports.globalRegistry = globalRegistry;
2197
2026
  exports.hasChanges = hasChanges;
2198
2027
  exports.hasGetterChanges = hasGetterChanges;
@@ -2216,6 +2045,5 @@ exports.shallowEqual = shallowEqual;
2216
2045
  exports.startProxyTracking = startProxyTracking;
2217
2046
  exports.startTracking = startTracking;
2218
2047
  exports.stopProxyTracking = stopProxyTracking;
2219
- exports.trackAccess = trackAccess;
2220
2048
  exports.warn = warn;
2221
2049
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -8,7 +8,6 @@ export type { BlacPlugin, BlacPluginWithInit, PluginContext, PluginConfig, Insta
8
8
  export { PluginManager, createPluginManager } from './plugin/PluginManager';
9
9
  export { hasInitHook } from './plugin/BlacPlugin';
10
10
  export * from './tracking';
11
- export * from './proxy/ProxyTracker';
12
11
  export * from './adapter';
13
12
  export type { Brand, BrandedId, InstanceId } from './types/branded';
14
13
  export type { BaseEvent } from './types/events';
package/dist/index.d.ts CHANGED
@@ -8,7 +8,6 @@ export type { BlacPlugin, BlacPluginWithInit, PluginContext, PluginConfig, Insta
8
8
  export { PluginManager, createPluginManager } from './plugin/PluginManager';
9
9
  export { hasInitHook } from './plugin/BlacPlugin';
10
10
  export * from './tracking';
11
- export * from './proxy/ProxyTracker';
12
11
  export * from './adapter';
13
12
  export type { Brand, BrandedId, InstanceId } from './types/branded';
14
13
  export type { BaseEvent } from './types/events';