@scorelabs/core 1.0.5 → 1.0.9

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.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/dist/importers/MusicXMLParser.d.ts +2 -1
  3. package/dist/importers/MusicXMLParser.js +102 -29
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +2 -2
  6. package/dist/models/Instrument.d.ts +8 -19
  7. package/dist/models/Instrument.js +77 -23
  8. package/dist/models/Measure.d.ts +3 -1
  9. package/dist/models/Measure.js +7 -1
  10. package/dist/models/Note.d.ts +1 -1
  11. package/dist/models/Note.js +1 -1
  12. package/dist/models/NoteSet.d.ts +40 -38
  13. package/dist/models/NoteSet.js +5 -2
  14. package/dist/models/Part.d.ts +2 -2
  15. package/dist/models/Part.js +1 -1
  16. package/dist/models/Pitch.js +4 -0
  17. package/dist/models/PreMeasure.d.ts +24 -0
  18. package/dist/models/PreMeasure.js +30 -0
  19. package/dist/models/Score.d.ts +18 -3
  20. package/dist/models/Score.js +196 -8
  21. package/dist/models/Staff.d.ts +2 -2
  22. package/dist/models/index.d.ts +1 -0
  23. package/dist/models/index.js +1 -0
  24. package/dist/models/types.d.ts +2 -213
  25. package/dist/models/types.js +2 -213
  26. package/dist/types/Accidental.d.ts +7 -0
  27. package/dist/types/Accidental.js +8 -0
  28. package/dist/types/Arpeggio.d.ts +5 -0
  29. package/dist/types/Arpeggio.js +6 -0
  30. package/dist/types/Articulation.d.ts +10 -0
  31. package/dist/types/Articulation.js +11 -0
  32. package/dist/types/BarlineStyle.d.ts +9 -0
  33. package/dist/types/BarlineStyle.js +10 -0
  34. package/dist/types/Bowing.d.ts +4 -0
  35. package/dist/types/Bowing.js +5 -0
  36. package/dist/types/Clef.d.ts +10 -0
  37. package/dist/types/Clef.js +11 -0
  38. package/dist/types/Duration.d.ts +20 -0
  39. package/dist/types/Duration.js +60 -0
  40. package/dist/types/Dynamic.d.ts +12 -0
  41. package/dist/types/Dynamic.js +13 -0
  42. package/dist/types/Fretboard.d.ts +19 -0
  43. package/dist/types/Fretboard.js +1 -0
  44. package/dist/types/Genre.d.ts +27 -0
  45. package/dist/types/Genre.js +28 -0
  46. package/dist/types/Glissando.d.ts +8 -0
  47. package/dist/types/Glissando.js +5 -0
  48. package/dist/types/Hairpin.d.ts +10 -0
  49. package/dist/types/Hairpin.js +11 -0
  50. package/dist/types/InstrumentPreset.d.ts +11 -0
  51. package/dist/types/InstrumentPreset.js +12 -0
  52. package/dist/types/InstrumentType.d.ts +8 -0
  53. package/dist/types/InstrumentType.js +9 -0
  54. package/dist/types/KeySignature.d.ts +3 -0
  55. package/dist/types/KeySignature.js +1 -0
  56. package/dist/types/Lyric.d.ts +11 -0
  57. package/dist/types/Lyric.js +7 -0
  58. package/dist/types/NoteheadShape.d.ts +8 -0
  59. package/dist/types/NoteheadShape.js +9 -0
  60. package/dist/types/Ornament.d.ts +8 -0
  61. package/dist/types/Ornament.js +9 -0
  62. package/dist/types/Ottava.d.ts +10 -0
  63. package/dist/types/Ottava.js +7 -0
  64. package/dist/types/Pedal.d.ts +4 -0
  65. package/dist/types/Pedal.js +1 -0
  66. package/dist/types/Repeat.d.ts +8 -0
  67. package/dist/types/Repeat.js +1 -0
  68. package/dist/types/Slur.d.ts +4 -0
  69. package/dist/types/Slur.js +1 -0
  70. package/dist/types/StemDirection.d.ts +4 -0
  71. package/dist/types/StemDirection.js +5 -0
  72. package/dist/types/Tempo.d.ts +8 -0
  73. package/dist/types/Tempo.js +1 -0
  74. package/dist/types/TimeSignature.d.ts +6 -0
  75. package/dist/types/TimeSignature.js +3 -0
  76. package/dist/types/Tuplet.d.ts +5 -0
  77. package/dist/types/Tuplet.js +1 -0
  78. package/dist/types/index.d.ts +26 -0
  79. package/dist/types/index.js +26 -0
  80. package/package.json +5 -4
  81. package/dist/utils/tier.d.ts +0 -36
  82. package/dist/utils/tier.js +0 -112
@@ -0,0 +1,9 @@
1
+ export var NoteheadShape;
2
+ (function (NoteheadShape) {
3
+ NoteheadShape["Normal"] = "normal";
4
+ NoteheadShape["Cross"] = "cross";
5
+ NoteheadShape["Diamond"] = "diamond";
6
+ NoteheadShape["Slash"] = "slash";
7
+ NoteheadShape["Triangle"] = "triangle";
8
+ NoteheadShape["Square"] = "square";
9
+ })(NoteheadShape || (NoteheadShape = {}));
@@ -0,0 +1,8 @@
1
+ export declare enum Ornament {
2
+ Trill = "trill",
3
+ Mordent = "mordent",
4
+ InvertedMordent = "inverted-mordent",
5
+ Turn = "turn",
6
+ InvertedTurn = "inverted-turn",
7
+ Tremolo = "tremolo"
8
+ }
@@ -0,0 +1,9 @@
1
+ export var Ornament;
2
+ (function (Ornament) {
3
+ Ornament["Trill"] = "trill";
4
+ Ornament["Mordent"] = "mordent";
5
+ Ornament["InvertedMordent"] = "inverted-mordent";
6
+ Ornament["Turn"] = "turn";
7
+ Ornament["InvertedTurn"] = "inverted-turn";
8
+ Ornament["Tremolo"] = "tremolo";
9
+ })(Ornament || (Ornament = {}));
@@ -0,0 +1,10 @@
1
+ export declare enum OttavaType {
2
+ OttavaAlta = "8va",
3
+ OttavaBassa = "8vb",
4
+ QuindicesimaAlta = "15ma",
5
+ QuindicesimaBassa = "15mb"
6
+ }
7
+ export interface Ottava {
8
+ type: OttavaType;
9
+ placement: 'start' | 'stop';
10
+ }
@@ -0,0 +1,7 @@
1
+ export var OttavaType;
2
+ (function (OttavaType) {
3
+ OttavaType["OttavaAlta"] = "8va";
4
+ OttavaType["OttavaBassa"] = "8vb";
5
+ OttavaType["QuindicesimaAlta"] = "15ma";
6
+ OttavaType["QuindicesimaBassa"] = "15mb";
7
+ })(OttavaType || (OttavaType = {}));
@@ -0,0 +1,4 @@
1
+ export interface Pedal {
2
+ type: 'sustain' | 'una-corda';
3
+ placement: 'start' | 'stop';
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface Repeat {
2
+ type: 'start' | 'end';
3
+ times?: number;
4
+ }
5
+ export interface Volta {
6
+ type: 'start' | 'stop' | 'both';
7
+ numbers: number[];
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export interface Slur {
2
+ placement: 'start' | 'stop';
3
+ direction?: 'up' | 'down';
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export declare enum StemDirection {
2
+ Up = "up",
3
+ Down = "down"
4
+ }
@@ -0,0 +1,5 @@
1
+ export var StemDirection;
2
+ (function (StemDirection) {
3
+ StemDirection["Up"] = "up";
4
+ StemDirection["Down"] = "down";
5
+ })(StemDirection || (StemDirection = {}));
@@ -0,0 +1,8 @@
1
+ import { Duration } from './Duration.js';
2
+ export interface Tempo {
3
+ bpm: number;
4
+ duration: Duration;
5
+ isDotted: boolean;
6
+ text?: string;
7
+ gradual?: 'ritardando' | 'accelerando';
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export interface TimeSignature {
2
+ beats: number;
3
+ beatType: number;
4
+ symbol?: 'common' | 'cut' | 'normal';
5
+ }
6
+ export declare function isSymbolicTimeSignature(timeSignature: TimeSignature): boolean;
@@ -0,0 +1,3 @@
1
+ export function isSymbolicTimeSignature(timeSignature) {
2
+ return timeSignature.symbol === 'common' || timeSignature.symbol === 'cut';
3
+ }
@@ -0,0 +1,5 @@
1
+ export interface Tuplet {
2
+ actual: number;
3
+ normal: number;
4
+ type: 'start' | 'stop' | 'middle';
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ export * from './InstrumentPreset.js';
2
+ export * from './InstrumentType.js';
3
+ export * from './StemDirection.js';
4
+ export * from './Clef.js';
5
+ export * from './Duration.js';
6
+ export * from './Accidental.js';
7
+ export * from './Articulation.js';
8
+ export * from './Dynamic.js';
9
+ export * from './Genre.js';
10
+ export * from './BarlineStyle.js';
11
+ export * from './Lyric.js';
12
+ export * from './Bowing.js';
13
+ export * from './NoteheadShape.js';
14
+ export * from './Ornament.js';
15
+ export * from './Fretboard.js';
16
+ export * from './TimeSignature.js';
17
+ export * from './KeySignature.js';
18
+ export * from './Tempo.js';
19
+ export * from './Hairpin.js';
20
+ export * from './Ottava.js';
21
+ export * from './Arpeggio.js';
22
+ export * from './Glissando.js';
23
+ export * from './Pedal.js';
24
+ export * from './Slur.js';
25
+ export * from './Tuplet.js';
26
+ export * from './Repeat.js';
@@ -0,0 +1,26 @@
1
+ export * from './InstrumentPreset.js';
2
+ export * from './InstrumentType.js';
3
+ export * from './StemDirection.js';
4
+ export * from './Clef.js';
5
+ export * from './Duration.js';
6
+ export * from './Accidental.js';
7
+ export * from './Articulation.js';
8
+ export * from './Dynamic.js';
9
+ export * from './Genre.js';
10
+ export * from './BarlineStyle.js';
11
+ export * from './Lyric.js';
12
+ export * from './Bowing.js';
13
+ export * from './NoteheadShape.js';
14
+ export * from './Ornament.js';
15
+ export * from './Fretboard.js';
16
+ export * from './TimeSignature.js';
17
+ export * from './KeySignature.js';
18
+ export * from './Tempo.js';
19
+ export * from './Hairpin.js';
20
+ export * from './Ottava.js';
21
+ export * from './Arpeggio.js';
22
+ export * from './Glissando.js';
23
+ export * from './Pedal.js';
24
+ export * from './Slur.js';
25
+ export * from './Tuplet.js';
26
+ export * from './Repeat.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scorelabs/core",
3
- "version": "1.0.5",
3
+ "version": "1.0.9",
4
4
  "description": "Core logic and models for ScoreLabs music notation",
5
5
  "type": "module",
6
6
  "files": [
@@ -11,8 +11,8 @@
11
11
  "types": "./dist/index.d.ts",
12
12
  "exports": {
13
13
  ".": {
14
- "import": "./dist/index.js",
15
- "types": "./dist/index.d.ts"
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
16
  }
17
17
  },
18
18
  "scripts": {
@@ -23,7 +23,8 @@
23
23
  "release:minor": "npm version minor && npm publish --access public",
24
24
  "release:major": "npm version major && npm publish --access public",
25
25
  "release": "npm run release:patch",
26
- "test": "vitest"
26
+ "test": "vitest",
27
+ "lint": "eslint ."
27
28
  },
28
29
  "dependencies": {
29
30
  "jszip": "^3.10.1"
@@ -1,36 +0,0 @@
1
- export declare const TOKEN_MODULUS = 17;
2
- export declare const EXPECTED_REMAINDER = 2;
3
- export declare const EXPIRATION_MS: number;
4
- export type UserTier = 'free' | 'premium';
5
- /**
6
- * Obfuscates the user's tier into a numeric token for the viewer.
7
- * The viewer expects token % 17 === 2 for premium access.
8
- */
9
- export declare function generateObfuscatedToken(tier: UserTier): number;
10
- /**
11
- * Packs token and timestamp into an obfuscated string.
12
- */
13
- export declare function packToken(token: number, timestamp: number, salt: string): string;
14
- /**
15
- * Unpacks the token string and validates the signature.
16
- */
17
- export declare function unpackToken(packed: string, salt: string): {
18
- token: number;
19
- timestamp: number;
20
- } | null;
21
- /**
22
- * Returns the effective numeric token, checking for expiration.
23
- */
24
- export declare function getEffectiveToken(user: any): number;
25
- /**
26
- * Returns the effective tier from the obfuscated token
27
- */
28
- export declare function getTierFromUser(user: any): UserTier;
29
- /**
30
- * Returns true only if the user has a valid, non-expired premium token.
31
- */
32
- export declare function isUserPremium(user: any): boolean;
33
- /**
34
- * Returns true only if the user has a valid, non-expired free token.
35
- */
36
- export declare function isUserFree(user: any): boolean;
@@ -1,112 +0,0 @@
1
- export const TOKEN_MODULUS = 17;
2
- export const EXPECTED_REMAINDER = 2;
3
- export const EXPIRATION_MS = 24 * 60 * 60 * 1000;
4
- /**
5
- * Obfuscates the user's tier into a numeric token for the viewer.
6
- * The viewer expects token % 17 === 2 for premium access.
7
- */
8
- export function generateObfuscatedToken(tier) {
9
- const isPremium = tier === 'premium';
10
- let base = Math.floor(Math.random() * 8999) + 1000;
11
- if (isPremium) {
12
- // Ensure token % 17 === 2
13
- return base - (base % TOKEN_MODULUS) + EXPECTED_REMAINDER;
14
- }
15
- else {
16
- // Ensure token % 17 !== 2
17
- const result = base;
18
- return result % TOKEN_MODULUS === EXPECTED_REMAINDER ? result + 1 : result;
19
- }
20
- }
21
- /**
22
- * Packs token and timestamp into an obfuscated string.
23
- */
24
- export function packToken(token, timestamp, salt) {
25
- // Use a more robust numeric salt
26
- const saltNum = salt
27
- .split('')
28
- .reduce((acc, char, i) => acc + char.charCodeAt(0) * (i + 1), 0);
29
- // Pack components
30
- const tHex = token.toString(16);
31
- // Obfuscate time using XOR with salt and token
32
- const timeKey = (saltNum ^ token) % 1000000;
33
- const oTime = (BigInt(timestamp) ^ BigInt(timeKey)).toString(16);
34
- // Create a signature that binds token, time and salt
35
- const sigPayload = `${token}:${timestamp}:${salt}`;
36
- let sig = 0;
37
- for (let i = 0; i < sigPayload.length; i++) {
38
- sig = (sig << 5) - sig + sigPayload.charCodeAt(i);
39
- sig |= 0; // Convert to 32bit integer
40
- }
41
- const sHex = Math.abs(sig).toString(16);
42
- return `${tHex}-${oTime}-${sHex}`;
43
- }
44
- /**
45
- * Unpacks the token string and validates the signature.
46
- */
47
- export function unpackToken(packed, salt) {
48
- try {
49
- const [tHex, oTime, sHex] = packed.split('-');
50
- if (!tHex || !oTime || !sHex)
51
- return null;
52
- const token = parseInt(tHex, 16);
53
- const saltNum = salt
54
- .split('')
55
- .reduce((acc, char, i) => acc + char.charCodeAt(0) * (i + 1), 0);
56
- const timeKey = (saltNum ^ token) % 1000000;
57
- const timestamp = Number(BigInt(parseInt(oTime, 16)) ^ BigInt(timeKey));
58
- // Validate signature
59
- const sigPayload = `${token}:${timestamp}:${salt}`;
60
- let sig = 0;
61
- for (let i = 0; i < sigPayload.length; i++) {
62
- sig = (sig << 5) - sig + sigPayload.charCodeAt(i);
63
- sig |= 0;
64
- }
65
- const expectedSig = Math.abs(sig).toString(16);
66
- if (sHex !== expectedSig)
67
- return null;
68
- return { token, timestamp };
69
- }
70
- catch (e) {
71
- return null;
72
- }
73
- }
74
- /**
75
- * Returns the effective numeric token, checking for expiration.
76
- */
77
- export function getEffectiveToken(user) {
78
- if (!user)
79
- return 0;
80
- const accessToken = user.accessToken || user.access_token;
81
- if (!accessToken) {
82
- return 0;
83
- }
84
- const salt = (user.uuid || user.id || 'default-salt').toString();
85
- const unpacked = unpackToken(accessToken, salt);
86
- if (!unpacked)
87
- return 0;
88
- const now = Date.now();
89
- if (now - unpacked.timestamp >= EXPIRATION_MS || now < unpacked.timestamp) {
90
- return 0; // Expired
91
- }
92
- return unpacked.token;
93
- }
94
- /**
95
- * Returns the effective tier from the obfuscated token
96
- */
97
- export function getTierFromUser(user) {
98
- const token = getEffectiveToken(user);
99
- return token % TOKEN_MODULUS === EXPECTED_REMAINDER ? 'premium' : 'free';
100
- }
101
- /**
102
- * Returns true only if the user has a valid, non-expired premium token.
103
- */
104
- export function isUserPremium(user) {
105
- return getTierFromUser(user) === 'premium';
106
- }
107
- /**
108
- * Returns true only if the user has a valid, non-expired free token.
109
- */
110
- export function isUserFree(user) {
111
- return getTierFromUser(user) === 'free';
112
- }