@mintjamsinc/ichigojs 0.1.2 → 0.1.3

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.
@@ -7169,6 +7169,10 @@
7169
7169
  * The change tracker, if any.
7170
7170
  */
7171
7171
  #onChange;
7172
+ /**
7173
+ * The logger instance.
7174
+ */
7175
+ #logger;
7172
7176
  /**
7173
7177
  * The set of changed identifiers.
7174
7178
  */
@@ -7184,6 +7188,10 @@
7184
7188
  constructor(args = {}) {
7185
7189
  this.#parent = args.parent;
7186
7190
  this.#onChange = args.onChange;
7191
+ this.#logger = args.vApplication?.logManager.getLogger('VBindings');
7192
+ if (this.#logger?.isDebugEnabled) {
7193
+ this.#logger.debug(`VBindings created. Parent: ${this.#parent ? 'yes' : 'no'}`);
7194
+ }
7187
7195
  this.#local = new Proxy({}, {
7188
7196
  get: (obj, key) => {
7189
7197
  if (Reflect.has(obj, key)) {
@@ -7208,6 +7216,7 @@
7208
7216
  let path = '';
7209
7217
  for (const part of changedPath?.split('.') || []) {
7210
7218
  path = path ? `${path}.${part}` : part;
7219
+ this.#logger?.debug(`Binding changed: ${path}`);
7211
7220
  this.#changes.add(path);
7212
7221
  }
7213
7222
  this.#onChange?.(changedPath);
@@ -7218,15 +7227,22 @@
7218
7227
  // Detect changes
7219
7228
  let hasChanged = oldValue !== newValue;
7220
7229
  // Special handling for arrays: check length changes even if same object reference
7221
- if (!hasChanged && Array.isArray(newValue)) {
7230
+ if (Array.isArray(newValue)) {
7222
7231
  const cachedLength = this.#lengthCache.get(key);
7223
7232
  const currentLength = newValue.length;
7224
- if (cachedLength !== undefined && cachedLength !== currentLength) {
7233
+ if (!hasChanged && cachedLength !== undefined && cachedLength !== currentLength) {
7225
7234
  hasChanged = true;
7226
7235
  }
7227
7236
  this.#lengthCache.set(key, currentLength);
7228
7237
  }
7229
7238
  if (hasChanged) {
7239
+ if (this.#logger?.isDebugEnabled) {
7240
+ const oldValueString = typeof oldValue === 'string' ? `"${oldValue}"` : JSON.stringify(oldValue) || 'undefined';
7241
+ const newValueString = typeof newValue === 'string' ? `"${newValue}"` : JSON.stringify(newValue) || 'undefined';
7242
+ const oldValuePreview = oldValueString.length > 100 ? `${oldValueString.substring(0, 100)}...` : oldValueString;
7243
+ const newValuePreview = newValueString.length > 100 ? `${newValueString.substring(0, 100)}...` : newValueString;
7244
+ this.#logger.debug(`Binding set on ${target === obj ? 'local' : 'parent'}: ${key}: ${oldValuePreview} -> ${newValuePreview}`);
7245
+ }
7230
7246
  this.#changes.add(key);
7231
7247
  this.#onChange?.(key);
7232
7248
  }
@@ -7234,6 +7250,7 @@
7234
7250
  },
7235
7251
  deleteProperty: (obj, key) => {
7236
7252
  const result = Reflect.deleteProperty(obj, key);
7253
+ this.#logger?.debug(`Binding deleted: ${key}`);
7237
7254
  this.#changes.add(key);
7238
7255
  this.#onChange?.(key);
7239
7256
  return result;
@@ -8947,10 +8964,13 @@
8947
8964
  }
8948
8965
  // .number modifier: convert to number
8949
8966
  if (this.#modifiers.has('number')) {
8950
- const parsed = Number(result);
8951
- // Only convert if it's a valid number
8952
- if (!isNaN(parsed)) {
8953
- result = parsed;
8967
+ // Skip conversion if the value is empty string
8968
+ if (result !== '') {
8969
+ const parsed = Number(result);
8970
+ // Only convert if it's a valid number
8971
+ if (!isNaN(parsed)) {
8972
+ result = parsed;
8973
+ }
8954
8974
  }
8955
8975
  }
8956
8976
  return result;
@@ -9478,49 +9498,105 @@
9478
9498
  })(LogLevel || (LogLevel = {}));
9479
9499
 
9480
9500
  // Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
9501
+ /**
9502
+ * A simple logger class for virtual applications.
9503
+ */
9481
9504
  class VLogger {
9505
+ /** The name of the logger. */
9482
9506
  #name;
9507
+ /** The log manager instance. */
9483
9508
  #logManager;
9484
9509
  constructor(name, logManager) {
9485
9510
  this.#name = name;
9486
9511
  this.#logManager = logManager;
9487
9512
  }
9513
+ /**
9514
+ * Indicates whether the debug level is enabled.
9515
+ */
9516
+ get isDebugEnabled() {
9517
+ return [LogLevel.DEBUG].includes(this.#logManager.logLevel);
9518
+ }
9519
+ /**
9520
+ * Indicates whether the info level is enabled.
9521
+ */
9522
+ get isInfoEnabled() {
9523
+ return [LogLevel.DEBUG, LogLevel.INFO].includes(this.#logManager.logLevel);
9524
+ }
9525
+ /**
9526
+ * Indicates whether the warn level is enabled.
9527
+ */
9528
+ get isWarnEnabled() {
9529
+ return [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN].includes(this.#logManager.logLevel);
9530
+ }
9531
+ /**
9532
+ * Logs a debug message.
9533
+ * @param message The message to log.
9534
+ */
9488
9535
  debug(message) {
9489
- if (![LogLevel.DEBUG].includes(this.#logManager.logLevel)) {
9536
+ if (!this.isDebugEnabled) {
9490
9537
  return;
9491
9538
  }
9492
9539
  console.debug(`[${this.#name}] ${LogLevel.DEBUG}: ${message}`);
9493
9540
  }
9541
+ /**
9542
+ * Logs an info message.
9543
+ * @param message The message to log.
9544
+ */
9494
9545
  info(message) {
9495
- if (![LogLevel.DEBUG, LogLevel.INFO].includes(this.#logManager.logLevel)) {
9546
+ if (!this.isInfoEnabled) {
9496
9547
  return;
9497
9548
  }
9498
9549
  console.info(`[${this.#name}] ${LogLevel.INFO}: ${message}`);
9499
9550
  }
9551
+ /**
9552
+ * Logs a warn message.
9553
+ * @param message The message to log.
9554
+ */
9500
9555
  warn(message) {
9501
- if (![LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN].includes(this.#logManager.logLevel)) {
9556
+ if (!this.isWarnEnabled) {
9502
9557
  return;
9503
9558
  }
9504
9559
  console.warn(`[${this.#name}] ${LogLevel.WARN}: ${message}`);
9505
9560
  }
9561
+ /**
9562
+ * Logs an error message.
9563
+ * @param message The message to log.
9564
+ */
9506
9565
  error(message) {
9507
9566
  console.error(`[${this.#name}] ${LogLevel.ERROR}: ${message}`);
9508
9567
  }
9509
9568
  }
9510
9569
 
9511
9570
  // Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
9571
+ /**
9572
+ * Manages loggers and their log levels.
9573
+ */
9512
9574
  class VLogManager {
9575
+ /** The current log level. */
9513
9576
  #logLevel;
9577
+ /** A map of logger instances by name. */
9514
9578
  #loggers = new Map();
9515
9579
  constructor(logLevel = LogLevel.INFO) {
9516
9580
  this.#logLevel = logLevel;
9517
9581
  }
9582
+ /**
9583
+ * Sets the log level for all loggers.
9584
+ * @param level The log level to set.
9585
+ */
9518
9586
  set logLevel(level) {
9519
9587
  this.#logLevel = level;
9520
9588
  }
9589
+ /**
9590
+ * Gets the current log level.
9591
+ */
9521
9592
  get logLevel() {
9522
9593
  return this.#logLevel;
9523
9594
  }
9595
+ /**
9596
+ * Gets a logger by name, creating it if it doesn't exist.
9597
+ * @param name The name of the logger.
9598
+ * @returns The logger instance.
9599
+ */
9524
9600
  getLogger(name) {
9525
9601
  if (this.#loggers.has(name)) {
9526
9602
  return this.#loggers.get(name);
@@ -9692,7 +9768,8 @@
9692
9768
  this.#bindings = new VBindings({
9693
9769
  onChange: (identifier) => {
9694
9770
  this.#scheduleUpdate();
9695
- }
9771
+ },
9772
+ vApplication: this
9696
9773
  });
9697
9774
  // Inject utility methods into bindings
9698
9775
  this.#bindings.set('$nextTick', (callback) => this.#nextTick(callback));
@@ -9796,13 +9873,7 @@
9796
9873
  // Track if the computed value actually changed
9797
9874
  if (oldValue !== newValue) {
9798
9875
  this.#bindings?.set(key, newValue);
9799
- this.#bindings?.changes.forEach(id => {
9800
- allChanges.add(id);
9801
- const idx = id.indexOf('[');
9802
- if (idx !== -1) {
9803
- allChanges.add(id.substring(0, idx));
9804
- }
9805
- });
9876
+ allChanges.add(key);
9806
9877
  }
9807
9878
  }
9808
9879
  catch (error) {