assign-gingerly 0.0.42 → 0.0.43

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/README.md CHANGED
@@ -4656,6 +4656,9 @@ When the custom element's `connectedCallback` fires, the feature's `connectedCal
4656
4656
  | `disconnectedCallback` | Feature needs cleanup (remove listeners, abort fetches) |
4657
4657
  | `attributeChangedCallback` | Feature reacts to attribute changes (limited to element's `observedAttributes`) |
4658
4658
  | `adoptedCallback` | Feature reacts to document adoption |
4659
+ | `formDisabledCallback` | Feature reacts to disabled state changes (form-associated elements) |
4660
+ | `formResetCallback` | Feature reacts to form reset (form-associated elements) |
4661
+ | `formStateRestoreCallback` | Feature restores state after navigation/session restore (form-associated elements) |
4659
4662
 
4660
4663
  **Example: Feature that reads computed styles on connect**
4661
4664
 
@@ -4779,6 +4782,18 @@ await customElements.assignFeatures(MyElement, { feature: { spawn: SyncFeature }
4779
4782
  // Both work — await on undefined is a no-op
4780
4783
  ```
4781
4784
 
4785
+ <details>
4786
+ <summary>Catalog of Published Custom Element Features</summary>
4787
+
4788
+ | Package | Description | Source |
4789
+ |---------|-------------|--------|
4790
+ | [truth-sourcer](https://www.npmjs.com/package/truth-sourcer) | Attribute/property binding and truth-sourcing for custom elements | [GitHub](https://github.com/bahrus/truth-sourcer) |
4791
+ | [be-reflective](https://www.npmjs.com/package/be-reflective) | CSS custom state reflection from computed styles | [GitHub](https://github.com/bahrus/be-reflective) |
4792
+ | [face-up](https://www.npmjs.com/package/face-up) | Form Associated Custom Element behavior via ElementInternals | [GitHub](https://github.com/bahrus/face-up) |
4793
+ | [time-ticker](https://www.npmjs.com/package/time-ticker) | Web component that fires events periodically (example of a feature-based component with no code in the class) | [GitHub](https://github.com/bahrus/time-ticker) |
4794
+
4795
+ </details>
4796
+
4782
4797
  ### Roadmap (future phases)
4783
4798
 
4784
4799
  - **Nested features**: Support `?.path?.notation` keys directly in `assignFeatures` (without requiring `PropertyBag`).
package/assignFeatures.js CHANGED
@@ -305,7 +305,10 @@ const VALID_CALLBACKS = new Set([
305
305
  'connectedCallback',
306
306
  'disconnectedCallback',
307
307
  'attributeChangedCallback',
308
- 'adoptedCallback'
308
+ 'adoptedCallback',
309
+ 'formDisabledCallback',
310
+ 'formResetCallback',
311
+ 'formStateRestoreCallback'
309
312
  ]);
310
313
  /**
311
314
  * WeakMap tracking which callbacks have been patched on which constructors,
package/assignFeatures.ts CHANGED
@@ -515,7 +515,10 @@ const VALID_CALLBACKS = new Set([
515
515
  'connectedCallback',
516
516
  'disconnectedCallback',
517
517
  'attributeChangedCallback',
518
- 'adoptedCallback'
518
+ 'adoptedCallback',
519
+ 'formDisabledCallback',
520
+ 'formResetCallback',
521
+ 'formStateRestoreCallback'
519
522
  ]);
520
523
 
521
524
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assign-gingerly",
3
- "version": "0.0.42",
3
+ "version": "0.0.43",
4
4
  "description": "This package provides a utility function for carefully merging one object into another.",
5
5
  "homepage": "https://github.com/bahrus/assign-gingerly#readme",
6
6
  "bugs": {
@@ -179,13 +179,18 @@ export interface AttrConfig<T = unknown, TParserConfig = unknown> {
179
179
  // * Defaults to true (initial read only)
180
180
  // */
181
181
  // initialOnly?: boolean;
182
+
183
+ /**
184
+ * Should make sure it is added to static observedAttribrutes
185
+ */
186
+ sourceOfTruth?: boolean;
182
187
  }
183
188
 
184
189
  export type AttrPatterns<T = any> = {
185
190
  /**
186
191
  * Base prefix for attribute names
187
192
  */
188
- base: string;
193
+ base?: string;
189
194
 
190
195
  /**
191
196
  * Configuration for the base pattern
@@ -241,18 +246,6 @@ export interface IAssignGingerlyOptions {
241
246
  * When the signal is aborted, all event listeners are automatically removed
242
247
  */
243
248
  signal?: AbortSignal;
244
-
245
- /**
246
- * List of property names that should be treated as async methods.
247
- * Works together with withMethods — async methods are awaited before
248
- * continuing the chain.
249
- *
250
- * The path evaluation for keys containing async methods is fire-and-forget:
251
- * assignGingerly remains synchronous and returns immediately.
252
- *
253
- * NOTE: Interaction with @each and @eachTime is not yet implemented.
254
- */
255
- withAsyncMethods?: string[] | Set<string>;
256
249
  }
257
250
 
258
251
  /**
@@ -333,130 +326,3 @@ export interface ElementEnhancement{
333
326
  dispose(registryItem: EnhancementConfig | string | symbol): void;
334
327
  whenResolved(registryItem: EnhancementConfig | string | symbol, mountCtx?: any): Promise<any>;
335
328
  }
336
-
337
- /**
338
- * Context passed to feature spawn constructors
339
- */
340
- export interface FeatureSpawnContext {
341
- /** The feature key (e.g., 'photoTaker') */
342
- key: string;
343
- /** The SupportedFeatureConfig from static supportedFeatures */
344
- optIn: SupportedFeatureConfig;
345
- /** The FeatureConfig from assignFeatures */
346
- injection: FeatureConfig;
347
- /** The features registry reference */
348
- featuresRegistry: FeaturesRegistry;
349
- /** Shared context from the host element (via getSharedContext callback) */
350
- shared?: any;
351
- }
352
-
353
- /**
354
- * Configuration for a supported feature slot declared via static supportedFeatures
355
- */
356
- export interface SupportedFeatureConfig {
357
- /**
358
- * Optional fallback class (or async spawner) to use if no implementation is injected.
359
- */
360
- fallbackSpawn?:
361
- | { new(hostElement: any, ctx: FeatureSpawnContext, initVals?: any): any }
362
- | (() => Promise<{ new(hostElement: any, ctx: FeatureSpawnContext, initVals?: any): any }>);
363
-
364
- /**
365
- * Optional runtime shape validation for the spawned instance.
366
- * Return true if the instance is valid, false to throw.
367
- */
368
- validateShape?: (spawnedInstance: any) => boolean;
369
-
370
- /**
371
- * Optional callback to provide shared context (e.g., ElementInternals, private state)
372
- * to the feature at construction time.
373
- *
374
- * Defined in the class body, this callback has access to #private fields.
375
- * The returned object is passed to the feature constructor as `ctx.shared`.
376
- *
377
- * @param instance - The host element instance
378
- * @returns An object containing shared data for the feature
379
- */
380
- getSharedContext?: (instance: any) => any;
381
- }
382
-
383
- /**
384
- * Class-level configuration for the features system.
385
- * Declared as `static featuresConfig` on the class.
386
- */
387
- export interface FeaturesClassConfig {
388
- /**
389
- * Lifecycle method configuration.
390
- *
391
- * If set to `true`, installs a method named 'whenFeatureReady' on the prototype.
392
- * If set to an object, allows customizing the method name.
393
- *
394
- * The installed method accepts a feature key and returns a Promise that resolves
395
- * with the feature instance once it's ready (useful for async spawners).
396
- * For synchronous spawners, the Promise resolves immediately.
397
- *
398
- * Suggested default name: 'whenFeatureReady'
399
- */
400
- lifecycleKeys?: true | {
401
- /** Method name for awaiting feature readiness. Defaults to 'whenFeatureReady'. */
402
- whenFeatureReady?: string;
403
- };
404
- }
405
-
406
- /**
407
- * Configuration for a feature passed to assignFeatures.
408
- * The feature equivalent of EnhancementConfig.
409
- */
410
- export interface FeatureConfig {
411
- /**
412
- * The class to instantiate for this feature, or an async function that
413
- * resolves to such a class (for lazy-loading).
414
- *
415
- * Synchronous: Constructor receives the host element as its first argument,
416
- * a FeatureSpawnContext as second, and optional initVals as third.
417
- *
418
- * Asynchronous: A function (arrow or async) that returns a Promise resolving
419
- * to a constructor. The getter returns a placeholder object immediately and
420
- * instantiates the real class once the Promise resolves.
421
- */
422
- spawn?:
423
- | { new(hostElement: any, ctx: FeatureSpawnContext, initVals?: any): any }
424
- | (() => Promise<{ new(hostElement: any, ctx: FeatureSpawnContext, initVals?: any): any }>);
425
-
426
- /**
427
- * Attribute patterns for parsing element attributes into initVals.
428
- * Attributes are the "base layer" — programmatic values override them.
429
- * Always unprefixed for features (no enh- prefix).
430
- */
431
- withAttrs?: AttrPatterns<any>;
432
-
433
- /**
434
- * Reserved field for custom configuration data.
435
- * Not interpreted by the library — available to the feature class
436
- * via ctx.injection.customData in the constructor.
437
- */
438
- customData?: any;
439
- }
440
-
441
- export type SupportedFeaturesMap = Record<string, SupportedFeatureConfig>;
442
- export type FeatureConfigsMap = Record<string, FeatureConfig>;
443
-
444
- /**
445
- * Registry for feature configs, keyed by constructor
446
- */
447
- export declare class FeaturesRegistry {
448
- has(ctr: Function): boolean;
449
- get(ctr: Function): Map<string, FeatureConfig> | undefined;
450
- set(ctr: Function, key: string, config: FeatureConfig): void;
451
- hasKey(ctr: Function, key: string): boolean;
452
- }
453
-
454
- /**
455
- * Core assignFeatures function.
456
- * Validates inputs, registers feature configs, and installs lazy getters on the class prototype.
457
- */
458
- export declare function assignFeatures(
459
- ctr: Function,
460
- features: FeatureConfigsMap,
461
- featuresRegistry: FeaturesRegistry
462
- ): Promise<void> | undefined;