or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-open-wc--dedupe-mixin

Dedupe JavaScript Class Mixins

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@open-wc/dedupe-mixin@2.0.x

To install, run

npx @tessl/cli install tessl/npm-open-wc--dedupe-mixin@2.0.0

index.mddocs/

Dedupe Mixin

Dedupe Mixin provides a utility function for automatically deduplicating JavaScript class mixins to prevent duplicate application of the same mixin in an inheritance chain. It uses a WeakMap to track which mixins have been applied to which classes, ensuring that each mixin is only applied once even when multiple inheritance paths attempt to apply the same mixin.

Package Information

  • Package Name: @open-wc/dedupe-mixin
  • Package Type: npm
  • Language: JavaScript (ES modules)
  • Installation: npm install @open-wc/dedupe-mixin

Core Imports

import { dedupeMixin } from '@open-wc/dedupe-mixin';

For CommonJS (if bundled/transpiled):

const { dedupeMixin } = require('@open-wc/dedupe-mixin');

Basic Usage

import { dedupeMixin } from '@open-wc/dedupe-mixin';

// Create a mixin function
const LoggingMixin = (superClass) => class extends superClass {
  log(message) {
    console.log(`[${this.constructor.name}] ${message}`);
  }
};

// Wrap with dedupeMixin to prevent duplicate application
const DedupedLoggingMixin = dedupeMixin(LoggingMixin);

// Create a base class
class BaseElement extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }
}

// Apply the mixin once
class ComponentA extends DedupedLoggingMixin(BaseElement) {
  connectedCallback() {
    this.log('ComponentA connected');
  }
}

// Apply the mixin again - it will be deduplicated
class ComponentB extends DedupedLoggingMixin(ComponentA) {
  connectedCallback() {
    super.connectedCallback();
    this.log('ComponentB connected');
  }
}

// Only one LoggingMixin is applied in the inheritance chain
const component = new ComponentB();

Capabilities

Mixin Deduplication

Wraps a mixin function to ensure it is only applied once in any inheritance chain.

/**
 * Apply each mixin in the chain to make sure they are not applied more than once to the final class.
 * @param {function} mixin - Mixin to be applied
 * @returns {function} Mixed class factory with mixin applied only once
 */
function dedupeMixin(mixin);

The dedupeMixin function:

  • Takes a mixin function as input
  • Returns a new function that applies the mixin only if it hasn't been applied before
  • Uses a WeakMap internally to track applied mixins without memory leaks
  • Works across complex inheritance hierarchies
  • Prevents duplicate behavior, performance issues, and unexpected side effects

Usage Examples:

import { dedupeMixin } from '@open-wc/dedupe-mixin';

// Define a mixin
const TimestampMixin = (superClass) => class extends superClass {
  getTimestamp() {
    return new Date().toISOString();
  }
};

// Create deduped version
const DedupedTimestampMixin = dedupeMixin(TimestampMixin);

// Multiple applications - only applies once
class Base {}
class A extends DedupedTimestampMixin(Base) {}
class B extends DedupedTimestampMixin(A) {} // Mixin not applied again

const instance = new B();
console.log(instance.getTimestamp()); // Works correctly
// Complex inheritance with multiple mixins
const MixinA = dedupeMixin((superClass) => class extends superClass {
  featureA() { return 'A'; }
});

const MixinB = dedupeMixin((superClass) => class extends superClass {
  featureB() { return 'B'; }
});

const MixinC = dedupeMixin((superClass) => class extends superClass {
  featureC() { return 'C'; }
});

// Compose mixins - each only applied once despite multiple paths
const ComposedMixin = (superClass) => MixinA(MixinB(MixinC(superClass)));
const AnotherMixin = (superClass) => MixinC(MixinA(MixinB(superClass)));

class Final extends AnotherMixin(ComposedMixin(Base)) {}
// Each mixin (A, B, C) is only applied once despite multiple inheritance paths

Types

/**
 * Generic constructor type for class constructors
 */
type Constructor<T> = new (...args: any[]) => T;

/**
 * Dedupe mixin function with TypeScript support
 * @param mixin - A mixin function that extends a constructor
 * @returns The same mixin function with deduplication behavior
 */
declare function dedupeMixin<T extends (s: Constructor<any>) => any>(mixin: T): T;

The TypeScript definitions provide:

  • Full type safety with generic type preservation
  • Proper inference of mixin return types
  • Constructor type utility for defining mixin signatures
  • Maintains the original mixin function signature while adding deduplication