Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
fffd4a0
build: bump alphaTab to 1.8.0
Danielku15 Dec 2, 2025
9fd7bea
build: allow conditional releases
Danielku15 Dec 2, 2025
dc9c367
build: add webpack publish
Danielku15 Dec 2, 2025
e4c4b76
feat(playground): import alphaTex into editor
Danielku15 Dec 4, 2025
359d1f9
feat(playground): expose alphaTab for fiddling
Danielku15 Dec 4, 2025
da51a07
feat(playground): allow drag&drop on whole page
Danielku15 Dec 5, 2025
660fbf6
fix(monaco): Use pull diagnostics
Danielku15 Dec 3, 2025
f0d2614
fix(lsp): add staff metadata to completions
Danielku15 Dec 5, 2025
7e1c68b
feat(playground): Some convenience features (#2410)
Danielku15 Dec 5, 2025
f034a35
fix: Monaco Diagnostics and staff completions missing (#2413)
Danielku15 Dec 5, 2025
8aa71da
fix(alphatex): only allow swapped values/props for chords (#2409)
Danielku15 Dec 5, 2025
09bb0ab
refactor(renderer): make effect bands part of main renderers (#2414)
Danielku15 Dec 5, 2025
3d31c01
fix(player): grace beats on song start (#2415)
Danielku15 Dec 5, 2025
5c9d3f5
feat: option to extend barlines across staves in system (#2416)
Danielku15 Dec 5, 2025
49c68ed
fix: use innerText when loading alphaTex from dom (#2417)
Danielku15 Dec 6, 2025
aa2c810
feat: Selection API (#2418)
Danielku15 Dec 6, 2025
f965170
build(deps-dev): bump @vscode/test-cli from 0.0.11 to 0.0.12 (#2421)
dependabot[bot] Dec 8, 2025
4b4b519
build(deps-dev): bump tsx from 4.20.6 to 4.21.0 (#2422)
dependabot[bot] Dec 8, 2025
7ca3053
build(deps): bump vscode-textmate from 9.2.1 to 9.3.0 (#2423)
dependabot[bot] Dec 8, 2025
97ff64a
build(deps-dev): bump rimraf from 6.1.0 to 6.1.2 (#2424)
dependabot[bot] Dec 8, 2025
af86866
feat: Multi System Slurs (#2425)
Danielku15 Dec 9, 2025
343f59e
feat(rendering): align 'primary' note heads instead of centering (#2426)
Danielku15 Dec 9, 2025
6cdd778
refactor: Decouple beaming helper (#2427)
Danielku15 Dec 12, 2025
2a0b11c
feat(alphatex): Bar-Wise Voices (#2429)
Danielku15 Dec 14, 2025
db84080
feat: displaced note heads for multiple voices (#2430)
Danielku15 Dec 15, 2025
08e5a9b
build(deps-dev): bump @types/vscode from 1.106.1 to 1.107.0 (#2431)
dependabot[bot] Dec 15, 2025
e529037
build(deps-dev): bump @microsoft/api-extractor from 7.53.3 to 7.55.2 …
dependabot[bot] Dec 15, 2025
c9eeebb
build(deps): bump actions/upload-artifact from 5 to 6 (#2433)
dependabot[bot] Dec 15, 2025
89a6f32
build(deps): bump actions/cache from 4 to 5 (#2434)
dependabot[bot] Dec 15, 2025
3fc7786
feat: in-score chord diagrams (#2435)
Danielku15 Dec 15, 2025
b7dacb7
feat(bundlers): warn if plugins are not used (#2436)
Danielku15 Dec 15, 2025
a1bd11d
fix: numbered notation ties and dash placement (#2438)
Danielku15 Dec 16, 2025
5789b59
feat: hide empty staves (#2443)
Danielku15 Dec 19, 2025
123bff3
feat: smooth cursor scrolling. (#2447)
Danielku15 Dec 20, 2025
758ae89
fix: always apply systemLabelPaddingLeft (#2448)
Danielku15 Dec 20, 2025
07b3546
build(deps): bump vite from 7.2.6 to 7.3.0 (#2450)
dependabot[bot] Dec 22, 2025
bea089e
build(deps): bump serve-static from 2.2.0 to 2.2.1 (#2451)
dependabot[bot] Dec 22, 2025
b85546e
build(deps): bump monaco-editor from 0.54.0 to 0.55.1 (#2452)
dependabot[bot] Dec 22, 2025
719d55b
fix(exporter): no sound in guitar 8 pro RSE (#2456)
L-Sun Dec 24, 2025
604c1c0
feat: add parchment layout (#2459)
Danielku15 Dec 25, 2025
112390e
build(deps-dev): bump @types/node from 24.10.0 to 25.0.3 (#2469)
dependabot[bot] Dec 29, 2025
2e4a6ac
build(deps-dev): bump vite-tsconfig-paths from 5.1.4 to 6.0.3 (#2470)
dependabot[bot] Dec 29, 2025
adca157
build(deps): bump webpack from 5.103.0 to 5.104.1 (#2471)
dependabot[bot] Dec 29, 2025
fd7b573
build(deps-dev): bump chai from 6.2.1 to 6.2.2 (#2473)
dependabot[bot] Jan 5, 2026
05397ad
refactor: new handling of beams and stems (#2475)
Danielku15 Jan 5, 2026
52bfad1
feat: add buzzroll tremolos (#2476)
Danielku15 Jan 5, 2026
d04d3be
feat: new guitar pro instrument set writing (#2477)
Danielku15 Jan 6, 2026
f7c00b0
fix: ensure style element for print dialog (#2480)
Danielku15 Jan 7, 2026
7c32638
feat: advanced font configurations and lyric paddings (#2481)
Danielku15 Jan 8, 2026
28bf384
feat: customize display of bar numbers (#2482)
Danielku15 Jan 8, 2026
962b45b
refactor: use textContent to load alphatex (#2230)
Danielku15 Jan 8, 2026
5ef8ea8
feat: detect bass cleff on Guitar Pro 3-5 files (#2483)
Danielku15 Jan 8, 2026
4443a63
build(deps): bump @fontsource/noto-serif from 5.2.8 to 5.2.9 (#2327)
dependabot[bot] Jan 8, 2026
d9e9aba
fix: prevent endless loops due to invalid bpms (#2484)
Danielku15 Jan 8, 2026
c4cd0c6
chore: update dependencies and fix new linter errors (#2485)
Danielku15 Jan 8, 2026
1edf83d
feat: allow custom beaming rules (#2489)
Danielku15 Jan 9, 2026
2a9e80a
fix: ensure clean beam-stem alignment on subpixel rendering (#2494)
Danielku15 Jan 11, 2026
0fa3828
fix: avoid placeholder reuse on content change (#2495)
Danielku15 Jan 11, 2026
cdf259b
fix: ensure correct note durations for combined duration annotations …
Danielku15 Jan 11, 2026
bc87198
fix: tuplet arcs in numbered notation
Danielku15 Jan 12, 2026
57c6f61
chore: export new public api members
Danielku15 Jan 11, 2026
61a7d47
fix: missing highlight bounds in single staff selection
Danielku15 Jan 12, 2026
6c5b425
fix: typo in package name
Danielku15 Jan 12, 2026
8816833
docs: remove link which breaks in JSON docs
Danielku15 Jan 12, 2026
641098a
chore: export public types
Danielku15 Jan 12, 2026
9526077
chore: Update deps (#2502)
Danielku15 Jan 12, 2026
efb3357
Merge remote-tracking branch 'origin/main' into release/1.8.0
Danielku15 Jan 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- run: npm run build-language-server
- run: npm run build-monaco
id: test
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v6
if: ${{ failure() && steps.test.conclusion == 'failure' }}
with:
name: test-results-web
Expand All @@ -69,7 +69,7 @@ jobs:
- run: npm run build-csharp
- run: npm run test-csharp
id: test
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v6
if: ${{ failure() && steps.test.conclusion == 'failure' }}
with:
name: test-results-csharp
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- run: npm run build-kotlin
- run: npm run test-kotlin
id: test
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v6
if: ${{ failure() && steps.test.conclusion == 'failure' }}
with:
name: test-results-kotlin
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
steps:
- run: touch dummy.txt

- uses: actions/cache@v4
- uses: actions/cache@v5
id: cache
with:
path: dummy.txt
Expand Down
2,620 changes: 409 additions & 2,211 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coderline/alphatab-monorepo",
"version": "1.7.1",
"version": "1.8.0",
"description": "Monorepo for alphaTab and its related packages",
"private": true,
"type": "module",
Expand Down Expand Up @@ -41,7 +41,6 @@
"test-webpack": "npm run test --workspace=packages/webpack",

"build-monaco": "npm run build --workspace=packages/monaco"

},
"devDependencies": {
"concurrently": "^9.2.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/alphatab/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
FORCE_COLOR=1
NODE_OPTIONS=--expose-gc
NODE_OPTIONS=--expose-gc
14 changes: 7 additions & 7 deletions packages/alphatab/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coderline/alphatab",
"version": "1.7.1",
"version": "1.8.0",
"description": "alphaTab is a music notation and guitar tablature rendering library",
"keywords": [
"guitar",
Expand Down Expand Up @@ -58,23 +58,23 @@
"test-accept-reference": "tsx scripts/accept-new-reference-files.ts"
},
"devDependencies": {
"@biomejs/biome": "^2.2.6",
"@biomejs/biome": "^2.3.11",
"@coderline/alphaskia": "^3.4.135",
"@coderline/alphaskia-linux": "^3.4.135",
"@coderline/alphaskia-windows": "^3.4.135",
"@types/chai": "^5.2.3",
"@types/mocha": "^10.0.10",
"@types/node": "^24.10.0",
"@types/node": "^25.0.6",
"assert": "^2.1.0",
"chai": "^6.2.1",
"chai": "^6.2.2",
"chalk": "^5.6.2",
"jest-snapshot": "^30.2.0",
"mocha": "^11.7.5",
"rimraf": "^6.1.0",
"rimraf": "^6.1.2",
"tslib": "^2.8.1",
"tsx": "^4.20.6",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"vite": "^7.2.6",
"vite": "^7.3.1",
"vite-plugin-static-copy": "^3.1.4"
},
"files": [
Expand Down
2 changes: 1 addition & 1 deletion packages/alphatab/scripts/JsonDeclarationEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as ts from 'typescript';
import createEmitter, { generateFile } from './EmitterBase';
import { getTypeWithNullableInfo, type TypeWithNullableInfo } from './TypeSchema';

function createDefaultJsonTypeNode(checker: ts.TypeChecker, type: TypeWithNullableInfo, isNullable: boolean) {
function createDefaultJsonTypeNode(checker: ts.TypeChecker, type: TypeWithNullableInfo, isNullable: boolean): ts.TypeNode {
if (isNullable) {
const notNullable = createDefaultJsonTypeNode(checker, type, false);
return ts.factory.createUnionTypeNode([notNullable, ts.factory.createLiteralTypeNode(ts.factory.createNull())]);
Expand Down
22 changes: 14 additions & 8 deletions packages/alphatab/scripts/Serializer.setProperty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ function generateSetPropertyBody(serializable: TypeSchema, importer: (name: stri
`${mapValueTypeInfo.typeAsString}.fromJson(v)`,
ts.SyntaxKind.CallExpression
);

if(!mapValueTypeInfo.isOptional && !mapValueTypeInfo.isNullable) {
mapValue = ts.factory.createNonNullExpression(mapValue);
}
} else {
itemSerializer = `${mapValueTypeInfo.typeAsString}Serializer`;
importer(itemSerializer, findSerializerModule(mapValueTypeInfo));
Expand All @@ -181,15 +185,17 @@ function generateSetPropertyBody(serializable: TypeSchema, importer: (name: stri
.filter(t => t.tagName.text === 'json_add')
.map(t => t.comment ?? '')[0] as string;

caseStatements.push(
assignField(
ts.factory.createNewExpression(
ts.factory.createIdentifier('Map'),
prop.type.typeArguments!.map(t => t.createTypeNode()),
[]
if(!prop.isReadOnly) {
caseStatements.push(
assignField(
ts.factory.createNewExpression(
ts.factory.createIdentifier('Map'),
prop.type.typeArguments!.map(t => t.createTypeNode()),
[]
)
)
)
);
);
}

caseStatements.push(
ts.factory.createExpressionStatement(
Expand Down
15 changes: 13 additions & 2 deletions packages/alphatab/scripts/Serializer.toJson.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as ts from 'typescript';
import { createNodeFromSource, setMethodBody } from '@coderline/alphatab-transpiler/src/BuilderHelpers';
import * as ts from 'typescript';
import { findSerializerModule } from './Serializer.common';
import type { TypeSchema } from './TypeSchema';

Expand Down Expand Up @@ -30,7 +30,7 @@ function generateToJsonBody(serializable: TypeSchema, importer: (name: string, m
const fieldName = prop.name;
const jsonName = prop.jsonNames.filter(n => n !== '')[0];

if (!jsonName || prop.isReadOnly) {
if (!jsonName || prop.isJsonReadOnly) {
continue;
}

Expand Down Expand Up @@ -153,6 +153,17 @@ function generateToJsonBody(serializable: TypeSchema, importer: (name: string, m
}`,
ts.SyntaxKind.Block
);
} else if(prop.type.typeArguments![1].isArray && prop.type.typeArguments![1].arrayItemType!.isPrimitiveType) {
serializeBlock = createNodeFromSource<ts.Block>(
`{
const m = new Map<string, unknown>();
o.set(${JSON.stringify(jsonName)}, m);
for(const [k, v] of obj.${fieldName}!) {
m.set(k.toString(), v);
}
}`,
ts.SyntaxKind.Block
);
} else {
const itemSerializer = `${prop.type.typeArguments![1].typeAsString}Serializer`;
importer(itemSerializer, findSerializerModule(prop.type.typeArguments![1]));
Expand Down
4 changes: 3 additions & 1 deletion packages/alphatab/scripts/TypeSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export function buildTypeSchema(program: ts.Program, input: ts.ClassDeclaration)
asRaw,
partialNames: !!jsDoc.find(t => t.tagName.text === 'json_partial_names'),
target: jsDoc.find(t => t.tagName.text === 'target')?.comment as string,
isReadOnly: !!jsDoc.find(t => t.tagName.text === 'json_read_only'),
isJsonReadOnly: isReadonly,
isReadOnly: propertyDeclaration.modifiers!.some(m => m.kind == ts.SyntaxKind.ReadonlyKeyword),
name: (member.name as ts.Identifier).text,
jsDocTags: jsDoc,
type: getTypeWithNullableInfo(
Expand Down Expand Up @@ -379,6 +380,7 @@ export interface TypeProperty {
jsonNames: string[];
asRaw: boolean;
target?: string;
isJsonReadOnly: boolean;
isReadOnly: boolean;
}

Expand Down
27 changes: 14 additions & 13 deletions packages/alphatab/scripts/smufl-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,40 @@
import fs from 'node:fs';
import url from 'node:url';
import path from 'node:path';
import { MusicFontSymbol } from '../src/model/MusicFontSymbol';
import { SmuflMetrics } from '../src/SmuflMetrics';
import url from 'node:url';
import { EngravingSettings } from '@coderline/alphatab/EngravingSettings';
import { MusicFontSymbol } from '@coderline/alphatab/model/MusicFontSymbol';
import { SmuflMetadata } from '@coderline/alphatab/SmuflMetadata';

const input = process.argv[2];
const output = process.argv[3];

const metadata = JSON.parse(await fs.promises.readFile(input, 'utf-8'));
const metadata: SmuflMetadata = JSON.parse(await fs.promises.readFile(input, 'utf-8'));

const outputMetadata = {
const outputMetadata:SmuflMetadata = {
engravingDefaults: metadata.engravingDefaults,
glyphBBoxes: {},
glyphsWithAnchors: {}
glyphBBoxes: {} as SmuflMetadata['glyphBBoxes'],
glyphsWithAnchors: {} as SmuflMetadata['glyphsWithAnchors']
};

const alphaTabUsedGlyphs = new Set<string>();
for(const [_,name] of Object.entries(MusicFontSymbol).filter(e => typeof e[1] === "string")) {
alphaTabUsedGlyphs.add(name.toString().toLowerCase());
}

for(const [k,_] of SmuflMetrics.smuflNameToGlyphNameMapping) {
for(const [k,_] of EngravingSettings.smuflNameToGlyphNameMapping) {
alphaTabUsedGlyphs.add(k.toLowerCase());
}

for(const name of Object.keys(metadata.glyphBBoxes)) {
for(const name of Object.keys(metadata.glyphBBoxes!)) {
if(alphaTabUsedGlyphs.has(name.toLowerCase())) {
const alphaTabName = SmuflMetrics.smuflNameToGlyphNameMapping.has(name) ? SmuflMetrics.smuflNameToGlyphNameMapping.get(name)! : name;
outputMetadata.glyphBBoxes[alphaTabName] = metadata.glyphBBoxes[name];
const alphaTabName = EngravingSettings.smuflNameToGlyphNameMapping.has(name) ? EngravingSettings.smuflNameToGlyphNameMapping.get(name)! : name;
outputMetadata.glyphBBoxes![alphaTabName] = metadata.glyphBBoxes![name];
}
}

for(const name of Object.keys(metadata.glyphsWithAnchors)) {
if(alphaTabUsedGlyphs.has(name.toLowerCase())) {
const alphaTabName = SmuflMetrics.smuflNameToGlyphNameMapping.has(name) ? SmuflMetrics.smuflNameToGlyphNameMapping.get(name)! : name;
const alphaTabName = EngravingSettings.smuflNameToGlyphNameMapping.has(name) ? EngravingSettings.smuflNameToGlyphNameMapping.get(name)! : name;
outputMetadata.glyphsWithAnchors[alphaTabName] = metadata.glyphsWithAnchors[name];
}
}
Expand All @@ -44,7 +45,7 @@ await fs.promises.writeFile(output,

if(process.argv[4] === 'true') {
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const smuflMetricsFile = path.resolve(__dirname, '..', 'src', 'SmuflMetrics.ts');
const smuflMetricsFile = path.resolve(__dirname, '..', 'src', 'EngravingSettings.ts');
let source = await fs.promises.readFile(smuflMetricsFile, 'utf-8');
const beginMarker = 'begin bravura_alphatab_metadata';
const endMarker = 'end bravura_alphatab_metadata';
Expand Down
Loading
Loading