@musodojo/music-theory-data 20.1.3 → 20.2.0

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
@@ -6,15 +6,14 @@ more.**
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/@musodojo/music-theory-data.svg)](https://www.npmjs.com/package/@musodojo/music-theory-data)
8
8
  [![npm downloads](https://img.shields.io/npm/dw/@musodojo/music-theory-data.svg)](https://www.npmjs.com/package/@musodojo/music-theory-data)
9
-
10
9
  [![JSR score](https://jsr.io/badges/@musodojo/music-theory-data)](https://jsr.io/@musodojo/music-theory-data)
11
10
 
12
11
  ## Community & Support
13
12
 
14
13
  Have a question, a suggestion, or want to report a bug? Get in touch!
15
14
 
16
- - **💬 Discord Server:** Connect with other developers and music
17
- enthusiasts in the [`#music-theory-data` channel.](https://discord.gg/3Tt4SXG5QC)
15
+ - **💬 Discord Server:** Connect with other developers and music enthusiasts in
16
+ the [`#music-theory-data` channel.](https://discord.gg/3Tt4SXG5QC)
18
17
  - **📢 Ask a Question or Share an Idea:** Use
19
18
  [GitHub Discussions](https://github.com/conor-dowdall/music-theory-data/discussions).
20
19
  - **🐞 Report a Bug or Flaw in the Data:** Open a
@@ -47,6 +46,7 @@ intervals, integer notations, and common names.
47
46
 
48
47
  ```ts
49
48
  // src/data/note-collections/diatonic-modes.ts
49
+ // @ts-ignore
50
50
  const ionian: ModalScaleCollection = {
51
51
  category: "scale",
52
52
  rotation: 0,
@@ -87,16 +87,18 @@ const ionian: ModalScaleCollection = {
87
87
  ### Practical Utility Functions
88
88
 
89
89
  Helpers for common tasks like generating note names from a root note and a set
90
- of intervals.
90
+ of intervals. For the full implementation details, refer to the source file.
91
91
 
92
92
  ```ts
93
- // src/utils/note-names.ts
94
93
  export function getNoteNamesFromRootAndIntervals(
94
+ // @ts-ignore
95
95
  rootNote: RootNote,
96
96
  intervals: readonly Interval[],
97
- options: TransformIntervalsOptions = {}
97
+ options: TransformIntervalsOptions = {},
98
98
  ): NoteName[] {
99
- //...
99
+ // This is a simplified representation for documentation purposes.
100
+ // The actual implementation is in src/utils/note-names.ts
101
+ return [];
100
102
  }
101
103
  ```
102
104
 
@@ -142,7 +144,7 @@ import * as music_theory_data from "jsr:@musodojo/music-theory-data";
142
144
  // Get the notes of A Harmonic Minor
143
145
  const notes1 = music_theory_data.getNoteNamesFromRootAndCollectionKey(
144
146
  "A",
145
- "harmonicMinor"
147
+ "harmonicMinor",
146
148
  );
147
149
  console.log(notes1);
148
150
  // ["A", "B", "C", "D", "E", "F", "G♯", "A"]
@@ -150,7 +152,7 @@ console.log(notes1);
150
152
  // Automatically knows whether to use flats or sharps
151
153
  const notes2 = music_theory_data.getNoteNamesFromRootAndCollectionKey(
152
154
  "F",
153
- "ionian"
155
+ "ionian",
154
156
  );
155
157
  console.log(notes2);
156
158
  // ["F", "G", "A", "B♭", "C", "D", "E", "F"];
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@musodojo/music-theory-data",
3
- "version": "20.1.3",
4
- "description": "The musician-friendly TypeScript library for modes, scales, chords, and more.",
3
+ "version": "20.2.0",
4
+ "description": "The musician-friendly TypeScript library for scales, modes, chords, and arpeggios.",
5
5
  "keywords": [
6
6
  "music",
7
- "theory"
7
+ "theory",
8
+ "enharmonic",
9
+ "scale",
10
+ "mode",
11
+ "chord",
12
+ "arpeggio"
8
13
  ],
9
14
  "license": "CC0-1.0",
10
15
  "author": "Conor Dowdall",
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Parses a hex color string and returns its RGB components.
3
+ * Supports 3-digit (#RGB) and 6-digit (#RRGGBB) formats.
4
+ * @param hex The hex color string.
5
+ * @returns An array [r, g, b] or null if the format is invalid.
6
+ */
7
+ export function parseHexColor(hex: string): [number, number, number] | null {
8
+ const hexRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
9
+ const shorthandHexRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
10
+
11
+ // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
12
+ const fullHex = hex.replace(
13
+ shorthandHexRegex,
14
+ (_, r, g, b) => r + r + g + g + b + b,
15
+ );
16
+
17
+ const result = hexRegex.exec(fullHex);
18
+ return result
19
+ ? [
20
+ parseInt(result[1], 16),
21
+ parseInt(result[2], 16),
22
+ parseInt(result[3], 16),
23
+ ]
24
+ : null;
25
+ }
26
+
27
+ /**
28
+ * Calculates whether black or white text has a better contrast ratio against a given background color.
29
+ * @param {string} color - The background color in hex format, e.g. "#E21C48"
30
+ * @returns {'black' | 'white'} - The color that provides better contrast.
31
+ */
32
+ export function getContrastColor(color: string): "black" | "white" {
33
+ // For now, we only support hex colors as that's what's in the library.
34
+ // This can be expanded to support rgb(), hsl(), and color keywords if needed.
35
+ const rgb = parseHexColor(color);
36
+ if (!rgb) {
37
+ return "black"; // Default to black if color parsing fails
38
+ }
39
+
40
+ const [r, g, b] = rgb;
41
+
42
+ // Formula for relative luminance (from WCAG)
43
+ // https://www.w3.org/TR/WCAG20/#relativeluminancedef
44
+ const getLuminance = (c: number) => {
45
+ const sRGB = c / 255;
46
+ return sRGB <= 0.03928
47
+ ? sRGB / 12.92
48
+ : Math.pow((sRGB + 0.055) / 1.055, 2.4);
49
+ };
50
+
51
+ const luminance = 0.2126 * getLuminance(r) +
52
+ 0.7152 * getLuminance(g) +
53
+ 0.0722 * getLuminance(b);
54
+
55
+ // Use a threshold of 0.179 as recommended by WCAG for contrast
56
+ return luminance > 0.179 ? "black" : "white";
57
+ }
package/src/utils/mod.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./colors.ts";
1
2
  export * from "./chords.ts";
2
3
  export * from "./intervals.ts";
3
4
  export * from "./midi-note-sequences.ts";