@libraz/libcantus 1.2.0 → 1.4.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/NOTICE +63 -0
- package/README.md +7 -1
- package/README_ja.md +17 -11
- package/dist/analyze/index.cjs +31 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +161 -13
- package/dist/analyze/index.d.ts +161 -13
- package/dist/analyze/index.js +37 -13
- package/dist/{chunk-NB25P3EH.js → chunk-2G5MCGYU.js} +33 -11
- package/dist/chunk-2G5MCGYU.js.map +1 -0
- package/dist/{chunk-NM7UAMC3.cjs → chunk-3FDBMIPR.cjs} +64 -64
- package/dist/chunk-3FDBMIPR.cjs.map +1 -0
- package/dist/{chunk-HPVSH7SF.cjs → chunk-3MDOEFIQ.cjs} +618 -954
- package/dist/chunk-3MDOEFIQ.cjs.map +1 -0
- package/dist/{chunk-FBH75DAY.js → chunk-5MWRBYAT.js} +560 -159
- package/dist/chunk-5MWRBYAT.js.map +1 -0
- package/dist/{chunk-J7FHVZII.cjs → chunk-6TTBEON3.cjs} +3074 -740
- package/dist/chunk-6TTBEON3.cjs.map +1 -0
- package/dist/{chunk-UMWZ4ZET.js → chunk-7NQ6AL3H.js} +4 -4
- package/dist/chunk-7NQ6AL3H.js.map +1 -0
- package/dist/{chunk-HWHGOVO6.cjs → chunk-E3QO3UET.cjs} +31 -23
- package/dist/chunk-E3QO3UET.cjs.map +1 -0
- package/dist/{chunk-H2KJHBW4.js → chunk-FJFULJZE.js} +2375 -191
- package/dist/chunk-FJFULJZE.js.map +1 -0
- package/dist/{chunk-Q6LFSAKV.js → chunk-FK3DGAIZ.js} +2657 -323
- package/dist/chunk-FK3DGAIZ.js.map +1 -0
- package/dist/chunk-GEDTJHAC.cjs.map +1 -1
- package/dist/{chunk-RFIBF2RR.js → chunk-H7FVMBUC.js} +138 -65
- package/dist/chunk-H7FVMBUC.js.map +1 -0
- package/dist/{chunk-DSMJRXCZ.cjs → chunk-HYSVSFNI.cjs} +931 -530
- package/dist/chunk-HYSVSFNI.cjs.map +1 -0
- package/dist/{chunk-35NBV2FT.cjs → chunk-KMYGRFZ6.cjs} +47 -24
- package/dist/chunk-KMYGRFZ6.cjs.map +1 -0
- package/dist/chunk-LQZQDBCD.cjs +5513 -0
- package/dist/chunk-LQZQDBCD.cjs.map +1 -0
- package/dist/{chunk-PM4XJE2Y.cjs → chunk-P3CPXAJ5.cjs} +76 -54
- package/dist/chunk-P3CPXAJ5.cjs.map +1 -0
- package/dist/{chunk-S5BKZZGM.cjs → chunk-S3QELJUE.cjs} +72 -56
- package/dist/chunk-S3QELJUE.cjs.map +1 -0
- package/dist/{chunk-PUKJP2Z5.js → chunk-TXFWSU5D.js} +31 -8
- package/dist/chunk-TXFWSU5D.js.map +1 -0
- package/dist/{chunk-76ZBTRG2.cjs → chunk-U4EQTDGN.cjs} +258 -218
- package/dist/chunk-U4EQTDGN.cjs.map +1 -0
- package/dist/chunk-UGLFDG7L.cjs.map +1 -1
- package/dist/{chunk-HYJJ2V2I.js → chunk-UTE5A36R.js} +483 -819
- package/dist/chunk-UTE5A36R.js.map +1 -0
- package/dist/{chunk-NFJ4P6ZZ.js → chunk-UZKQISRF.js} +17 -9
- package/dist/chunk-UZKQISRF.js.map +1 -0
- package/dist/{chunk-7KG3RTYS.js → chunk-VL5NXVCN.js} +281 -155
- package/dist/chunk-VL5NXVCN.js.map +1 -0
- package/dist/{chunk-CGBADIO5.cjs → chunk-WOMCXN2W.cjs} +328 -202
- package/dist/chunk-WOMCXN2W.cjs.map +1 -0
- package/dist/{chunk-3R3QVKY5.cjs → chunk-YDGMWH43.cjs} +397 -324
- package/dist/chunk-YDGMWH43.cjs.map +1 -0
- package/dist/{chunk-AGOVW7U6.js → chunk-YYVXRV3V.js} +72 -56
- package/dist/chunk-YYVXRV3V.js.map +1 -0
- package/dist/{chunk-M5RYMAFI.js → chunk-ZLNSH4UL.js} +71 -31
- package/dist/chunk-ZLNSH4UL.js.map +1 -0
- package/dist/{coerce-DRERzdve.d.cts → coerce-CUhHc3Tu.d.ts} +16 -8
- package/dist/{coerce-DP0vYu-x.d.ts → coerce-Ytt2Eiq9.d.cts} +16 -8
- package/dist/core/index.cjs +5 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +9 -8
- package/dist/core/index.d.ts +9 -8
- package/dist/core/index.js +4 -4
- package/dist/generate/index.cjs +20 -8
- package/dist/generate/index.cjs.map +1 -1
- package/dist/generate/index.d.cts +105 -17
- package/dist/generate/index.d.ts +105 -17
- package/dist/generate/index.js +19 -7
- package/dist/{index-CL4b4gUQ.d.ts → index-5VJgKz_Q.d.cts} +6 -2
- package/dist/{index-B9QLziDe.d.cts → index-BLuDesVG.d.ts} +20 -13
- package/dist/{index-BHIUyjhZ.d.ts → index-BV6APVa6.d.cts} +20 -13
- package/dist/{index-BMweUlm5.d.cts → index-Bf0Sv8a9.d.ts} +6 -2
- package/dist/{index-Dw2DP7vm.d.ts → index-BkT21EMv.d.cts} +3 -2
- package/dist/{index-BL5N2Oyz.d.cts → index-C7KCaTRz.d.ts} +3 -2
- package/dist/{index-Cy15oTvh.d.ts → index-C9MYbuKS.d.cts} +7 -3
- package/dist/{index-Cy15oTvh.d.cts → index-C9MYbuKS.d.ts} +7 -3
- package/dist/{index-BNSM-DSk.d.cts → index-DVInzCDS.d.cts} +533 -28
- package/dist/{index-9eoQs2C1.d.ts → index-Dg-SAfhz.d.ts} +6 -4
- package/dist/{index-BJgP97N1.d.ts → index-jgeug9EA.d.ts} +533 -28
- package/dist/{index-cHvbYgJI.d.cts → index-pQihL4z7.d.cts} +6 -4
- package/dist/index.cjs +49 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.js +55 -19
- package/dist/{masks-Cc7-MzzY.d.ts → masks-BnzXnBj0.d.cts} +3 -2
- package/dist/{masks-pADfTOiD.d.cts → masks-tycmkrgs.d.ts} +3 -2
- package/dist/model/index.cjs +12 -12
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +259 -48
- package/dist/model/index.d.ts +259 -48
- package/dist/model/index.js +11 -11
- package/dist/{positional-DJgs6ltD.d.ts → positional-CscpxtlE.d.cts} +3 -2
- package/dist/{positional-DMZer-FM.d.cts → positional-DLnfUgqG.d.ts} +3 -2
- package/dist/{index-BRMbPkHE.d.ts → profile-B4WqcM4H.d.ts} +85 -610
- package/dist/{index-DGCNKAUr.d.cts → profile-BJd1XkPB.d.cts} +85 -610
- package/dist/theory/index.cjs +5 -5
- package/dist/theory/index.cjs.map +1 -1
- package/dist/theory/index.d.cts +18 -14
- package/dist/theory/index.d.ts +18 -14
- package/dist/theory/index.js +4 -4
- package/dist/{index-CJBBiAmU.d.ts → types-7mGFwvMm.d.ts} +1210 -31
- package/dist/{index-BBWNZS0f.d.cts → types-_ofpb2be.d.cts} +1210 -31
- package/package.json +13 -13
- package/dist/chunk-35NBV2FT.cjs.map +0 -1
- package/dist/chunk-3R3QVKY5.cjs.map +0 -1
- package/dist/chunk-76ZBTRG2.cjs.map +0 -1
- package/dist/chunk-7KG3RTYS.js.map +0 -1
- package/dist/chunk-AGOVW7U6.js.map +0 -1
- package/dist/chunk-CGBADIO5.cjs.map +0 -1
- package/dist/chunk-DSMJRXCZ.cjs.map +0 -1
- package/dist/chunk-FBH75DAY.js.map +0 -1
- package/dist/chunk-H2KJHBW4.js.map +0 -1
- package/dist/chunk-HPVSH7SF.cjs.map +0 -1
- package/dist/chunk-HWHGOVO6.cjs.map +0 -1
- package/dist/chunk-HYJJ2V2I.js.map +0 -1
- package/dist/chunk-J7FHVZII.cjs.map +0 -1
- package/dist/chunk-M5RYMAFI.js.map +0 -1
- package/dist/chunk-NB25P3EH.js.map +0 -1
- package/dist/chunk-NFJ4P6ZZ.js.map +0 -1
- package/dist/chunk-NM7UAMC3.cjs.map +0 -1
- package/dist/chunk-PM4XJE2Y.cjs.map +0 -1
- package/dist/chunk-PUKJP2Z5.js.map +0 -1
- package/dist/chunk-Q6LFSAKV.js.map +0 -1
- package/dist/chunk-RFIBF2RR.js.map +0 -1
- package/dist/chunk-S5BKZZGM.cjs.map +0 -1
- package/dist/chunk-SGLEQVJH.cjs +0 -3329
- package/dist/chunk-SGLEQVJH.cjs.map +0 -1
- package/dist/chunk-UMWZ4ZET.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libraz/libcantus",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Pure-TypeScript music theory engine: harmonic analysis, chord and scale vocabulary, voicing, reharmonization, and seeded part generation over MIDI note events.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=22"
|
|
33
33
|
},
|
|
34
|
-
"packageManager": "yarn@4.18.
|
|
34
|
+
"packageManager": "yarn@4.18.1",
|
|
35
35
|
"main": "./dist/index.cjs",
|
|
36
36
|
"module": "./dist/index.js",
|
|
37
37
|
"types": "./dist/index.d.ts",
|
|
@@ -121,7 +121,8 @@
|
|
|
121
121
|
"dist",
|
|
122
122
|
"README.md",
|
|
123
123
|
"README_ja.md",
|
|
124
|
-
"LICENSE"
|
|
124
|
+
"LICENSE",
|
|
125
|
+
"NOTICE"
|
|
125
126
|
],
|
|
126
127
|
"sideEffects": false,
|
|
127
128
|
"scripts": {
|
|
@@ -130,28 +131,27 @@
|
|
|
130
131
|
"lint": "biome check .",
|
|
131
132
|
"lint:fix": "biome check --write .",
|
|
132
133
|
"format": "biome format --write .",
|
|
133
|
-
"examples": "vitest list >/dev/null",
|
|
134
|
-
"typecheck": "tsc --noEmit && tsc -p tsconfig.test.json && yarn examples && tsc -p tsconfig.examples.json",
|
|
134
|
+
"examples": "vitest list -c ../tests/spec/vitest.config.ts >/dev/null",
|
|
135
|
+
"typecheck": "tsc --noEmit && tsc -p tsconfig.test.json && yarn examples && tsc -p ../tests/spec/tsconfig.examples.json",
|
|
135
136
|
"test": "vitest run",
|
|
136
137
|
"test:watch": "vitest",
|
|
137
|
-
"test:coverage": "vitest run --coverage",
|
|
138
|
+
"test:coverage": "vitest run --coverage -c vitest.coverage.config.ts",
|
|
138
139
|
"bench:timeline": "yarn build && node --expose-gc benchmark/timeline-index.mjs",
|
|
139
140
|
"docs": "typedoc",
|
|
140
141
|
"figures": "node scripts/figures/build.mjs",
|
|
141
|
-
"prepare": "[ -d node_modules/typescript ] && tsup || true",
|
|
142
|
+
"prepare": "[ -d node_modules/typescript ] || [ -d ../node_modules/typescript ] && tsup || true",
|
|
142
143
|
"prepublishOnly": "yarn build"
|
|
143
144
|
},
|
|
144
145
|
"devDependencies": {
|
|
145
|
-
"@biomejs/biome": "2.5.14",
|
|
146
146
|
"@libraz/typedoc-theme": "^0.1.1",
|
|
147
|
-
"@types/node": "^26.6.
|
|
148
|
-
"@vitest/coverage-v8": "5.0.
|
|
149
|
-
"tsup": "
|
|
147
|
+
"@types/node": "^26.6.6",
|
|
148
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
149
|
+
"tsup": "9.0.0",
|
|
150
150
|
"typedoc": "0.28.20",
|
|
151
151
|
"typedoc-plugin-extras": "4.0.1",
|
|
152
152
|
"typedoc-plugin-mdn-links": "5.1.1",
|
|
153
153
|
"typescript": "6.0.3",
|
|
154
|
-
"vite": "8.3.
|
|
155
|
-
"vitest": "5.0.
|
|
154
|
+
"vite": "8.3.5",
|
|
155
|
+
"vitest": "5.0.5"
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/libcantus/libcantus/dist/chunk-35NBV2FT.cjs","../src/core/event-index/index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/libcantus/libcantus/dist/chunk-35NBV2FT.cjs","sourcesContent":[null,"import { BEAT_EPS } from '../meter/internal.js';\nimport type { NoteEvent } from '../types.js';\nimport { assertFiniteNumber, assertNoteEvents, assertOptions } from '../validation/index.js';\n\n/**\n * A validated note retaining its position in the caller's original array.\n *\n * @category Core\n */\nexport type IndexedNoteEvent = {\n readonly note: Readonly<NoteEvent>;\n readonly originalIndex: number;\n readonly endBeat: number;\n};\n\n/**\n * Which note wins when several sound from the same onset.\n *\n * `'highest'` and `'lowest'` name a voice, so the answer does not depend on the\n * order the caller happened to store the chord in; `'last'` takes the one\n * latest in the input array. Two notes of the same pitch name no voice apart,\n * so both voice tie-breaks settle a unison on the lower `originalIndex` and\n * name the same note.\n *\n * @category Core\n */\nexport type OnsetTieBreak = 'highest' | 'lowest' | 'last';\n\n/**\n * Binary-searchable, stable-sorted index over note onsets and active spans.\n *\n * @category Core\n */\nexport type NoteEventIndex = {\n notes: readonly IndexedNoteEvent[];\n /**\n * Latest-onset note sounding at `beat`. Simultaneous onsets are resolved by\n * the index's {@link OnsetTieBreak}.\n *\n * @throws If `beat` is not finite.\n */\n at: (beat: number) => IndexedNoteEvent | undefined;\n /**\n * Whether one or more sounding notes attack at `beat`.\n *\n * @throws If `beat` is not finite.\n */\n attacksAt: (beat: number) => boolean;\n /**\n * Unique sounding-note attack beats strictly inside `(startBeat, endBeat)`.\n *\n * @throws If either bound is not finite.\n */\n onsetsBetween: (startBeat: number, endBeat: number) => number[];\n};\n\nfunction upperBound(values: readonly IndexedNoteEvent[], beat: number): number {\n let low = 0;\n let high = values.length;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if ((values[middle]?.note.startBeat ?? Number.POSITIVE_INFINITY) <= beat) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n return low;\n}\n\n/**\n * Copy note events and put them in stable onset order.\n *\n * The order is the one {@link createNoteEventIndex} numbers its notes in, so a\n * pass may read the sequence here and the index there and see the same notes in\n * the same places. What it does not build is the index itself: a caller that\n * only walks the notes in time order would otherwise pay for a segment tree and\n * a wrapper per note that it never queries.\n *\n * The events are copied, so the sequence is the caller's own and two entries\n * that arrived as one shared object stay two.\n *\n * @param events The events to order; already validated by the caller.\n * @returns The copies, earliest onset first, ties in input order.\n */\nexport function sortedNoteEvents(events: readonly NoteEvent[]): NoteEvent[] {\n const sorted = events.map((note) => ({ ...note }));\n // Array sort is stable, so events sharing an onset keep the order they were\n // given in — the tie-break the index spells out as `originalIndex`.\n sorted.sort((a, b) => a.startBeat - b.startBeat);\n return sorted;\n}\n\n/**\n * How an index reads the events it is built from.\n *\n * @category Core\n */\nexport type NoteEventIndexOptions = {\n allowNonPositiveDuration?: boolean;\n tieBreak?: OnsetTieBreak;\n budget?: number;\n /** What the events are, for the validation error message. */\n name?: string;\n};\n\n/**\n * Validate and stable-sort note events once, then expose onset and active-note\n * lookups that cost `O(log n + k)`, where `k` is how many notes share the onset\n * the answer comes from. Non-positive-duration notes may be retained for\n * callers that intentionally filter them later, but never count as sounding.\n *\n * @category Core\n */\nexport function createNoteEventIndex(\n events: readonly NoteEvent[],\n options: NoteEventIndexOptions = {},\n): NoteEventIndex {\n const asked = assertOptions(options, 'options');\n assertNoteEvents(events, asked.name ?? 'note events', asked);\n const tieBreak = asked.tieBreak ?? 'highest';\n // Each wrapper is frozen, not only the array and the note inside it: `endBeat`\n // is what the active-note search is built from, so a host that writes to it\n // would leave the index answering from a span nothing else knows about.\n const notes = Object.freeze(\n events\n .map((note, originalIndex) =>\n Object.freeze({\n note: Object.freeze({ ...note }),\n originalIndex,\n endBeat: note.startBeat + note.durationBeat,\n }),\n )\n .sort((a, b) => a.note.startBeat - b.note.startBeat || a.originalIndex - b.originalIndex),\n );\n // Segment-tree maxima find the latest active onset in logarithmic time even\n // when an early, very long note would defeat a prefix-max backwards scan.\n //\n // It is built on the first `at` query rather than on construction: the onset\n // queries answer from the sorted notes alone, so a caller that never asks\n // which note is sounding would otherwise pay for a structure it never reads.\n let maxEndTree: number[] | undefined;\n let treeSize = 0;\n const endTree = (): number[] => {\n if (maxEndTree !== undefined) {\n return maxEndTree;\n }\n treeSize = 1;\n while (treeSize < notes.length) treeSize *= 2;\n const tree = new Array<number>(treeSize * 2).fill(Number.NEGATIVE_INFINITY);\n for (let index = 0; index < notes.length; index += 1) {\n tree[treeSize + index] = notes[index]?.endBeat ?? Number.NEGATIVE_INFINITY;\n }\n for (let index = treeSize - 1; index > 0; index -= 1) {\n tree[index] = Math.max(\n tree[index * 2] ?? Number.NEGATIVE_INFINITY,\n tree[index * 2 + 1] ?? Number.NEGATIVE_INFINITY,\n );\n }\n maxEndTree = tree;\n return tree;\n };\n const latestActiveIndex = (exclusive: number, beat: number): number => {\n const tree = endTree();\n const find = (node: number, start: number, end: number): number => {\n if (start >= exclusive || (tree[node] ?? Number.NEGATIVE_INFINITY) <= beat + BEAT_EPS) {\n return -1;\n }\n if (end - start === 1) return start < notes.length ? start : -1;\n const mid = Math.floor((start + end) / 2);\n const right = find(node * 2 + 1, mid, end);\n return right >= 0 ? right : find(node * 2, start, mid);\n };\n return find(1, 0, treeSize);\n };\n\n return {\n notes,\n at(beat) {\n // A query beat comes from wherever the host got it — a scrub position, a\n // parsed field — so it is checked like any other entry argument. `NaN`\n // compares false against every bound, which would read as an open window\n // rather than as the missing value it is.\n assertFiniteNumber(beat, 'beat');\n const index = latestActiveIndex(upperBound(notes, beat + BEAT_EPS), beat);\n if (index < 0) return undefined;\n const onset = notes[index]?.note.startBeat;\n let best: IndexedNoteEvent | undefined;\n for (let candidateIndex = index; candidateIndex >= 0; candidateIndex -= 1) {\n const indexed = notes[candidateIndex];\n if (indexed !== undefined && indexed.note.startBeat !== onset) break;\n if (\n indexed === undefined ||\n indexed.note.durationBeat <= 0 ||\n indexed.note.startBeat - BEAT_EPS > beat ||\n beat >= indexed.endBeat - BEAT_EPS\n ) {\n continue;\n }\n if (best === undefined) {\n best = indexed;\n continue;\n }\n if (tieBreak === 'last') continue;\n const difference = indexed.note.pitch - best.note.pitch;\n // Equal pitches name no voice apart, so they are settled on the lower\n // original index rather than on whichever end of the array the scan\n // happens to reach last — otherwise `'highest'` and `'lowest'` would\n // answer a unison differently.\n const wins =\n difference === 0\n ? indexed.originalIndex < best.originalIndex\n : difference > 0 === (tieBreak === 'highest');\n if (wins) {\n best = indexed;\n }\n }\n return best;\n },\n attacksAt(beat) {\n assertFiniteNumber(beat, 'beat');\n // Only a sounding note attacks: a zero-length artefact must not make\n // `attacksAt(b)` true on a beat where `at(b)` finds nothing.\n let index = upperBound(notes, beat + BEAT_EPS) - 1;\n while (index >= 0) {\n const candidate = notes[index];\n if (candidate === undefined || Math.abs(candidate.note.startBeat - beat) >= BEAT_EPS) {\n return false;\n }\n if (candidate.note.durationBeat > 0) {\n return true;\n }\n index -= 1;\n }\n return false;\n },\n onsetsBetween(startBeat, endBeat) {\n assertFiniteNumber(startBeat, 'startBeat');\n assertFiniteNumber(endBeat, 'endBeat');\n const result: number[] = [];\n let index = upperBound(notes, startBeat + BEAT_EPS);\n while (index < notes.length) {\n const indexed = notes[index];\n const onset = indexed?.note.startBeat;\n if (indexed === undefined || onset === undefined || onset >= endBeat - BEAT_EPS) {\n break;\n }\n index += 1;\n if (indexed.note.durationBeat <= 0) {\n continue;\n }\n const previous = result[result.length - 1];\n if (previous === undefined || Math.abs(previous - onset) >= BEAT_EPS) {\n result.push(onset);\n }\n }\n return result;\n },\n };\n}\n"]}
|