or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# Dedupe Mixin

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: @open-wc/dedupe-mixin

7

- **Package Type**: npm

8

- **Language**: JavaScript (ES modules)

9

- **Installation**: `npm install @open-wc/dedupe-mixin`

10

11

## Core Imports

12

13

```javascript

14

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

15

```

16

17

For CommonJS (if bundled/transpiled):

18

19

```javascript

20

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

21

```

22

23

## Basic Usage

24

25

```javascript

26

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

27

28

// Create a mixin function

29

const LoggingMixin = (superClass) => class extends superClass {

30

log(message) {

31

console.log(`[${this.constructor.name}] ${message}`);

32

}

33

};

34

35

// Wrap with dedupeMixin to prevent duplicate application

36

const DedupedLoggingMixin = dedupeMixin(LoggingMixin);

37

38

// Create a base class

39

class BaseElement extends HTMLElement {

40

constructor() {

41

super();

42

this.attachShadow({ mode: 'open' });

43

}

44

}

45

46

// Apply the mixin once

47

class ComponentA extends DedupedLoggingMixin(BaseElement) {

48

connectedCallback() {

49

this.log('ComponentA connected');

50

}

51

}

52

53

// Apply the mixin again - it will be deduplicated

54

class ComponentB extends DedupedLoggingMixin(ComponentA) {

55

connectedCallback() {

56

super.connectedCallback();

57

this.log('ComponentB connected');

58

}

59

}

60

61

// Only one LoggingMixin is applied in the inheritance chain

62

const component = new ComponentB();

63

```

64

65

## Capabilities

66

67

### Mixin Deduplication

68

69

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

70

71

```javascript { .api }

72

/**

73

* Apply each mixin in the chain to make sure they are not applied more than once to the final class.

74

* @param {function} mixin - Mixin to be applied

75

* @returns {function} Mixed class factory with mixin applied only once

76

*/

77

function dedupeMixin(mixin);

78

```

79

80

The `dedupeMixin` function:

81

- Takes a mixin function as input

82

- Returns a new function that applies the mixin only if it hasn't been applied before

83

- Uses a WeakMap internally to track applied mixins without memory leaks

84

- Works across complex inheritance hierarchies

85

- Prevents duplicate behavior, performance issues, and unexpected side effects

86

87

**Usage Examples:**

88

89

```javascript

90

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

91

92

// Define a mixin

93

const TimestampMixin = (superClass) => class extends superClass {

94

getTimestamp() {

95

return new Date().toISOString();

96

}

97

};

98

99

// Create deduped version

100

const DedupedTimestampMixin = dedupeMixin(TimestampMixin);

101

102

// Multiple applications - only applies once

103

class Base {}

104

class A extends DedupedTimestampMixin(Base) {}

105

class B extends DedupedTimestampMixin(A) {} // Mixin not applied again

106

107

const instance = new B();

108

console.log(instance.getTimestamp()); // Works correctly

109

```

110

111

```javascript

112

// Complex inheritance with multiple mixins

113

const MixinA = dedupeMixin((superClass) => class extends superClass {

114

featureA() { return 'A'; }

115

});

116

117

const MixinB = dedupeMixin((superClass) => class extends superClass {

118

featureB() { return 'B'; }

119

});

120

121

const MixinC = dedupeMixin((superClass) => class extends superClass {

122

featureC() { return 'C'; }

123

});

124

125

// Compose mixins - each only applied once despite multiple paths

126

const ComposedMixin = (superClass) => MixinA(MixinB(MixinC(superClass)));

127

const AnotherMixin = (superClass) => MixinC(MixinA(MixinB(superClass)));

128

129

class Final extends AnotherMixin(ComposedMixin(Base)) {}

130

// Each mixin (A, B, C) is only applied once despite multiple inheritance paths

131

```

132

133

## Types

134

135

```typescript { .api }

136

/**

137

* Generic constructor type for class constructors

138

*/

139

type Constructor<T> = new (...args: any[]) => T;

140

141

/**

142

* Dedupe mixin function with TypeScript support

143

* @param mixin - A mixin function that extends a constructor

144

* @returns The same mixin function with deduplication behavior

145

*/

146

declare function dedupeMixin<T extends (s: Constructor<any>) => any>(mixin: T): T;

147

```

148

149

The TypeScript definitions provide:

150

- Full type safety with generic type preservation

151

- Proper inference of mixin return types

152

- Constructor type utility for defining mixin signatures

153

- Maintains the original mixin function signature while adding deduplication