snice 3.10.1 → 3.10.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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v3.10.0
2
+ * snice v3.10.2
3
3
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1493,10 +1493,12 @@ var Snice = (function (exports) {
1493
1493
  * ConditionalIfPart handles <if> conditional rendering
1494
1494
  * Removes/inserts DOM nodes based on condition
1495
1495
  */
1496
+ // Sentinel value to distinguish "not yet set" from undefined
1497
+ const NOT_SET = Symbol('not-set');
1496
1498
  class ConditionalIfPart extends Part {
1497
1499
  constructor(ifElement) {
1498
1500
  super();
1499
- this.value = undefined;
1501
+ this.value = NOT_SET;
1500
1502
  this.fragment = null;
1501
1503
  this.ifElement = ifElement;
1502
1504
  this.ifElement.style.display = 'contents';
@@ -1538,7 +1540,7 @@ var Snice = (function (exports) {
1538
1540
  class ConditionalCasePart extends Part {
1539
1541
  constructor(caseElement) {
1540
1542
  super();
1541
- this.value = undefined;
1543
+ this.value = NOT_SET;
1542
1544
  this.childrenMap = new Map();
1543
1545
  this.fragments = new Map();
1544
1546
  this.defaultChild = null;
@@ -3013,17 +3015,19 @@ var Snice = (function (exports) {
3013
3015
  }
3014
3016
  }
3015
3017
  }
3016
- // Apply any properties that were set before element was connected
3017
- // BUT only if they don't have an HTML attribute (don't override HTML attributes)
3018
+ // Clear pre-init values for properties that have HTML attributes
3019
+ // This prevents field initializers from overwriting HTML attributes later
3018
3020
  if (this[PRE_INIT_PROPERTY_VALUES]) {
3019
- for (const [propName, propValue] of this[PRE_INIT_PROPERTY_VALUES]) {
3020
- // Remove from map first so getter doesn't return it during setter call
3021
- this[PRE_INIT_PROPERTY_VALUES].delete(propName);
3022
- // Only apply pre-init value if NO HTML attribute exists
3023
- // This prevents field initializers from overwriting HTML attributes
3021
+ for (const [propName, propValue] of Array.from(this[PRE_INIT_PROPERTY_VALUES].entries())) {
3024
3022
  const propOptions = properties?.get(propName);
3025
3023
  const attributeName = typeof propOptions?.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
3026
- if (!this.hasAttribute(attributeName)) {
3024
+ if (this.hasAttribute(attributeName)) {
3025
+ // Attribute exists - remove from PRE_INIT to prevent overwriting
3026
+ this[PRE_INIT_PROPERTY_VALUES].delete(propName);
3027
+ }
3028
+ else {
3029
+ // No attribute - apply the pre-init value
3030
+ this[PRE_INIT_PROPERTY_VALUES].delete(propName);
3027
3031
  this[propName] = propValue;
3028
3032
  }
3029
3033
  }
@@ -3283,16 +3287,18 @@ var Snice = (function (exports) {
3283
3287
  context.metadata[PROPERTIES].set(propertyKey, options || {});
3284
3288
  // Return a field initializer function for new decorators
3285
3289
  return function (initialValue) {
3290
+ // Ensure constructor[PROPERTIES] exists
3291
+ const constructor = this.constructor;
3292
+ if (!constructor[PROPERTIES]) {
3293
+ constructor[PROPERTIES] = new Map();
3294
+ }
3286
3295
  // Detect type from initial value if not explicitly provided
3287
3296
  const finalOptions = { ...options };
3288
3297
  if (!finalOptions.type && initialValue !== undefined) {
3289
3298
  finalOptions.type = detectType(initialValue);
3290
- // Update the metadata with the detected type
3291
- const constructor = this.constructor;
3292
- if (constructor[PROPERTIES]) {
3293
- constructor[PROPERTIES].set(propertyKey, finalOptions);
3294
- }
3295
3299
  }
3300
+ // Always store property options on constructor for runtime access
3301
+ constructor[PROPERTIES].set(propertyKey, finalOptions);
3296
3302
  // Set up the property descriptor on first access
3297
3303
  if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
3298
3304
  const descriptor = {
@@ -3321,8 +3327,9 @@ var Snice = (function (exports) {
3321
3327
  // Get old value by calling the getter (which reads from attribute)
3322
3328
  const oldValue = this[propertyKey];
3323
3329
  // Check if value actually changed
3324
- if (oldValue === newValue)
3330
+ if (oldValue === newValue) {
3325
3331
  return;
3332
+ }
3326
3333
  // Don't reflect to DOM until connectedCallback has started
3327
3334
  // This prevents field initializers from overwriting HTML attributes
3328
3335
  if (!this[PROPERTIES_INITIALIZED]) {