@blac/core 2.0.0-rc.14 → 2.0.0-rc.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -833,7 +833,9 @@ var StateContainerRegistry = class {
833
833
  */
834
834
  on(event, listener) {
835
835
  if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
836
- this.listeners.get(event).add(listener);
836
+ const instance = this.listeners.get(event);
837
+ if (!instance) throw new Error(`${BLAC_ERROR_PREFIX} Failed to register listener for event '${event}'`);
838
+ instance.add(listener);
837
839
  return () => {
838
840
  this.listeners.get(event)?.delete(listener);
839
841
  };
@@ -880,12 +882,12 @@ function getPluginManager() {
880
882
  *
881
883
  * @example
882
884
  * ```ts
883
- * class CounterBloc extends StateContainer<number> {
885
+ * class CounterBloc extends StateContainer<{ count: number }> {
884
886
  * constructor() {
885
- * super(0);
887
+ * super({ count: 0 });
886
888
  * }
887
889
  * increment() {
888
- * this.emit(this.state + 1);
890
+ * this.emit({ count: this.state.count + 1 });
889
891
  * }
890
892
  * }
891
893
  * ```
@@ -1235,33 +1237,70 @@ var Cubit = class extends StateContainer {
1235
1237
  //#endregion
1236
1238
  //#region src/core/Vertex.ts
1237
1239
  /**
1238
- * Event-driven state container that processes events to update state.
1239
- * Use with event handlers registered via the on() method.
1240
+ * Event-driven state container using discriminated union events.
1241
+ * Extends StateContainer with event-based state transitions and
1242
+ * compile-time exhaustive checking for event handlers.
1240
1243
  *
1241
- * @template S - State type
1242
- * @template E - Event type (extends BaseEvent)
1244
+ * @template S - State type (must be an object)
1245
+ * @template E - Event union type (discriminated by 'type' property)
1243
1246
  * @template P - Props type (optional)
1247
+ *
1248
+ * @example
1249
+ * ```typescript
1250
+ * type CounterEvent =
1251
+ * | { type: 'increment'; amount: number }
1252
+ * | { type: 'decrement' }
1253
+ * | { type: 'reset' };
1254
+ *
1255
+ * class CounterVertex extends Vertex<{ count: number }, CounterEvent> {
1256
+ * constructor() {
1257
+ * super({ count: 0 });
1258
+ * this.createHandlers({
1259
+ * increment: (event, emit) => {
1260
+ * emit({ count: this.state.count + event.amount });
1261
+ * },
1262
+ * decrement: (_, emit) => {
1263
+ * emit({ count: this.state.count - 1 });
1264
+ * },
1265
+ * reset: (_, emit) => {
1266
+ * emit({ count: 0 });
1267
+ * },
1268
+ * });
1269
+ * }
1270
+ *
1271
+ * increment = (amount = 1) => this.add({ type: 'increment', amount });
1272
+ * }
1273
+ * ```
1244
1274
  */
1245
1275
  var Vertex = class extends StateContainer {
1246
1276
  constructor(initialState) {
1247
1277
  super(initialState);
1248
- this.eventHandlers = /* @__PURE__ */ new Map();
1278
+ this.handlers = /* @__PURE__ */ new Map();
1249
1279
  this.isProcessing = false;
1250
1280
  this.eventQueue = [];
1251
- this.on = (EventClass, handler) => {
1252
- const className = EventClass.name;
1253
- const registrations = this.eventHandlers.get(className) || [];
1254
- registrations.push({
1255
- eventClass: EventClass,
1256
- handler
1257
- });
1258
- this.eventHandlers.set(className, registrations);
1259
- };
1260
1281
  this.add = (event) => {
1261
- StateContainer._registry.emit("eventAdded", this, event);
1262
- this.processEvent(event);
1282
+ const enrichedEvent = this.enrichEvent(event);
1283
+ StateContainer._registry.emit("eventAdded", this, enrichedEvent);
1284
+ this.processEvent(enrichedEvent);
1285
+ };
1286
+ }
1287
+ /**
1288
+ * Register all event handlers with exhaustive type checking.
1289
+ * TypeScript will error if any event type from the union is missing.
1290
+ *
1291
+ * @param handlers - Map of event type to handler function
1292
+ */
1293
+ createHandlers(handlers) {
1294
+ for (const [eventType, handler] of Object.entries(handlers)) this.handlers.set(eventType, handler);
1295
+ }
1296
+ /** @internal */
1297
+ enrichEvent(event) {
1298
+ return {
1299
+ ...event,
1300
+ timestamp: Date.now()
1263
1301
  };
1264
1302
  }
1303
+ /** @internal */
1265
1304
  processEvent(event) {
1266
1305
  if (this.isProcessing) {
1267
1306
  this.eventQueue.push(event);
@@ -1278,26 +1317,27 @@ var Vertex = class extends StateContainer {
1278
1317
  this.isProcessing = false;
1279
1318
  }
1280
1319
  }
1320
+ /** @internal */
1281
1321
  handleEvent(event) {
1282
- const className = event.constructor.name;
1283
- const registrations = this.eventHandlers.get(className);
1284
- if (!registrations || registrations.length === 0) {
1285
- if (this.debug) console.warn(`No handler registered for event: ${className}`);
1322
+ const handler = this.handlers.get(event.type);
1323
+ if (!handler) {
1324
+ if (this.debug) console.warn(`No handler registered for event type: ${event.type}`);
1286
1325
  return;
1287
1326
  }
1288
1327
  const emitFn = (state) => {
1289
1328
  this.emit(state);
1290
1329
  };
1291
- for (const registration of registrations) try {
1292
- registration.handler(event, emitFn);
1330
+ try {
1331
+ handler(event, emitFn);
1293
1332
  } catch (error$1) {
1294
- if (this.debug) console.error(`Error handling event ${className}:`, error$1);
1333
+ if (this.debug) console.error(`Error handling event ${event.type}:`, error$1);
1295
1334
  this.onEventError(event, error$1);
1296
1335
  }
1297
1336
  }
1298
1337
  /**
1299
- * Handle errors that occur during event processing.
1300
- * Override this method to implement custom error handling.
1338
+ * Called when an error occurs during event processing.
1339
+ * Override to implement custom error handling.
1340
+ *
1301
1341
  * @param _event - The event that caused the error
1302
1342
  * @param _error - The error that occurred
1303
1343
  */
@@ -2035,6 +2075,67 @@ function configureLogger(opts) {
2035
2075
  defaultLogger = createLogger(currentConfig);
2036
2076
  }
2037
2077
 
2078
+ //#endregion
2079
+ //#region src/config.ts
2080
+ const defaultConfig = {
2081
+ devMode: process.env.NODE_ENV !== "production",
2082
+ logger: {
2083
+ enabled: false,
2084
+ level: LogLevel.INFO
2085
+ }
2086
+ };
2087
+ let globalConfig = { ...defaultConfig };
2088
+ /**
2089
+ * Configure global defaults for @blac/core.
2090
+ *
2091
+ * @example
2092
+ * ```ts
2093
+ * import { configureBlac, LogLevel } from '@blac/core';
2094
+ *
2095
+ * configureBlac({
2096
+ * devMode: true,
2097
+ * logger: {
2098
+ * enabled: true,
2099
+ * level: LogLevel.DEBUG
2100
+ * }
2101
+ * });
2102
+ * ```
2103
+ *
2104
+ * @param config - Partial configuration to merge with defaults
2105
+ */
2106
+ function configureBlac(config) {
2107
+ globalConfig = {
2108
+ ...globalConfig,
2109
+ ...config,
2110
+ logger: {
2111
+ ...globalConfig.logger,
2112
+ ...config.logger
2113
+ }
2114
+ };
2115
+ if (config.logger) configureLogger(config.logger);
2116
+ }
2117
+ /**
2118
+ * Get the current global configuration.
2119
+ * @internal
2120
+ */
2121
+ function getBlacConfig() {
2122
+ return globalConfig;
2123
+ }
2124
+ /**
2125
+ * Check if development mode is enabled.
2126
+ */
2127
+ function isDevMode() {
2128
+ return globalConfig.devMode;
2129
+ }
2130
+ /**
2131
+ * Reset configuration to defaults (useful for testing).
2132
+ * @internal
2133
+ */
2134
+ function resetBlacConfig() {
2135
+ globalConfig = { ...defaultConfig };
2136
+ configureLogger(defaultConfig.logger);
2137
+ }
2138
+
2038
2139
  //#endregion
2039
2140
  //#region src/decorators/blac.ts
2040
2141
  /**
@@ -2069,5 +2170,5 @@ function blac(options) {
2069
2170
  }
2070
2171
 
2071
2172
  //#endregion
2072
- export { BLAC_DEFAULTS, BLAC_ERROR_PREFIX, BLAC_ID_PATTERNS, BLAC_STATIC_PROPS, Cubit, ExternalDependencyManager, LogLevel, PluginManager, StateContainer, StateContainerRegistry, Vertex, __resetIdCounters, blac, captureTrackedPaths, clearActiveTracker, clearExternalDependencies, commitTrackedGetters, configureLogger, createArrayProxy, createAutoTrackSnapshot, createAutoTrackSubscribe, createBlocProxy, createGetterTracker, createIdGenerator, createLogger, createManualDepsSnapshot, createManualDepsSubscribe, createNoTrackSnapshot, createNoTrackSubscribe, createPluginManager, createProxy, createProxyForTarget, createProxyInternal, createProxyTrackerState, createTrackerState, debug, disableGetterTracking, error, generateId, generateIsolatedKey, generateSimpleId, getActiveTracker, getDescriptor, getGetterExecutionContext, getPluginManager, getStaticProp, getValueAtPath, globalRegistry, hasChanges, hasGetterChanges, hasInitHook, hasTrackedData, info, initAutoTrackState, initManualDepsState, initNoTrackState, invalidateRenderCache, isExcludedFromDevTools, isGetter, isIsolatedClass, isIsolatedKey, isKeepAliveClass, isProxyable, parsePath, resetGetterTracker, setActiveTracker, shallowEqual, startProxyTracking, startTracking, stopProxyTracking, warn };
2173
+ export { BLAC_DEFAULTS, BLAC_ERROR_PREFIX, BLAC_ID_PATTERNS, BLAC_STATIC_PROPS, Cubit, ExternalDependencyManager, LogLevel, PluginManager, StateContainer, StateContainerRegistry, Vertex, __resetIdCounters, blac, captureTrackedPaths, clearActiveTracker, clearExternalDependencies, commitTrackedGetters, configureBlac, configureLogger, createArrayProxy, createAutoTrackSnapshot, createAutoTrackSubscribe, createBlocProxy, createGetterTracker, createIdGenerator, createLogger, createManualDepsSnapshot, createManualDepsSubscribe, createNoTrackSnapshot, createNoTrackSubscribe, createPluginManager, createProxy, createProxyForTarget, createProxyInternal, createProxyTrackerState, createTrackerState, debug, disableGetterTracking, error, generateId, generateIsolatedKey, generateSimpleId, getActiveTracker, getBlacConfig, getDescriptor, getGetterExecutionContext, getPluginManager, getStaticProp, getValueAtPath, globalRegistry, hasChanges, hasGetterChanges, hasInitHook, hasTrackedData, info, initAutoTrackState, initManualDepsState, initNoTrackState, invalidateRenderCache, isDevMode, isExcludedFromDevTools, isGetter, isIsolatedClass, isIsolatedKey, isKeepAliveClass, isProxyable, parsePath, resetBlacConfig, resetGetterTracker, setActiveTracker, shallowEqual, startProxyTracking, startTracking, stopProxyTracking, warn };
2073
2174
  //# sourceMappingURL=index.js.map