@sudobility/music_types 0.11.31 → 0.11.33

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 (42) hide show
  1. package/dist/domain/commands/note-commands.d.ts +8 -155
  2. package/dist/domain/commands/note-commands.d.ts.map +1 -1
  3. package/dist/domain/commands/note-commands.js +1 -423
  4. package/dist/domain/commands/note-commands.js.map +1 -1
  5. package/dist/domain/commands/note-marks.d.ts +171 -0
  6. package/dist/domain/commands/note-marks.d.ts.map +1 -0
  7. package/dist/domain/commands/note-marks.js +427 -0
  8. package/dist/domain/commands/note-marks.js.map +1 -0
  9. package/dist/domain/score/fragment.d.ts +3 -7
  10. package/dist/domain/score/fragment.d.ts.map +1 -1
  11. package/dist/domain/score/fragment.js.map +1 -1
  12. package/dist/domain/selection/types.d.ts +2 -2
  13. package/dist/domain/selection/types.d.ts.map +1 -1
  14. package/dist/index.d.ts +7 -5499
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +12 -461
  17. package/dist/index.js.map +1 -1
  18. package/dist/model/api.d.ts +1696 -0
  19. package/dist/model/api.d.ts.map +1 -0
  20. package/dist/model/api.js +125 -0
  21. package/dist/model/api.js.map +1 -0
  22. package/dist/model/generation.d.ts +2178 -0
  23. package/dist/model/generation.d.ts.map +1 -0
  24. package/dist/model/generation.js +142 -0
  25. package/dist/model/generation.js.map +1 -0
  26. package/dist/model/position.d.ts +82 -0
  27. package/dist/model/position.d.ts.map +1 -0
  28. package/dist/model/position.js +24 -0
  29. package/dist/model/position.js.map +1 -0
  30. package/dist/model/schemas.d.ts +1200 -0
  31. package/dist/model/schemas.d.ts.map +1 -0
  32. package/dist/model/schemas.js +200 -0
  33. package/dist/model/schemas.js.map +1 -0
  34. package/dist/model/score.d.ts +462 -0
  35. package/dist/model/score.d.ts.map +1 -0
  36. package/dist/model/score.js +34 -0
  37. package/dist/model/score.js.map +1 -0
  38. package/dist/model/selection-source.d.ts +53 -0
  39. package/dist/model/selection-source.d.ts.map +1 -0
  40. package/dist/model/selection-source.js +2 -0
  41. package/dist/model/selection-source.js.map +1 -0
  42. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/model/generation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The AI generation contracts, and the schemas that validate them.
3
+ *
4
+ * The request and result shapes `music_api` and the app agree on. Both sides
5
+ * import these, which is the whole reason this package exists.
6
+ */
7
+ import { z } from "zod";
8
+ import { clefSchema, keySignatureSchema, measureSchema, scoreSchema, timeSignatureSchema, } from "./schemas.js";
9
+ // ---------------------------------------------------------------------------
10
+ // 6. Zod schemas for the generation contracts
11
+ // ---------------------------------------------------------------------------
12
+ export const midiRangeSchema = z.object({
13
+ lowestMidi: z.number().int().min(0).max(127),
14
+ highestMidi: z.number().int().min(0).max(127),
15
+ });
16
+ export const scoreRangeSchema = z.object({
17
+ startTick: z.number().int().nonnegative(),
18
+ endTick: z.number().int().nonnegative(),
19
+ trackIds: z.array(z.string().min(1)),
20
+ });
21
+ export const scoreFragmentSchema = z.object({
22
+ range: scoreRangeSchema,
23
+ ppq: z.number().int().positive(),
24
+ tracks: z.array(z.object({ trackId: z.string().min(1), measures: z.array(measureSchema) })),
25
+ });
26
+ export const generateScoreRequestTrackSchema = z.object({
27
+ name: z.string(),
28
+ instrumentName: z.string(),
29
+ midiProgram: z.number().int().min(0).max(127),
30
+ clef: clefSchema,
31
+ range: midiRangeSchema.optional(),
32
+ maximumPolyphony: z.number().int().positive().optional(),
33
+ });
34
+ export const generateScoreRequestSchema = z.object({
35
+ prompt: z.string(),
36
+ title: z.string().optional(),
37
+ style: z.string().optional(),
38
+ mood: z.string().optional(),
39
+ durationMeasures: z.number().int().positive(),
40
+ tempo: z.number().positive().optional(),
41
+ timeSignature: timeSignatureSchema.optional(),
42
+ keySignature: keySignatureSchema.optional(),
43
+ tracks: z.array(generateScoreRequestTrackSchema),
44
+ complexity: z.enum(["simple", "moderate", "complex"]).optional(),
45
+ });
46
+ export const generateScoreResultSchema = z.object({
47
+ score: scoreSchema,
48
+ warnings: z.array(z.string()),
49
+ });
50
+ export const regenerationConstraintsSchema = z.object({
51
+ preserveMeasureCount: z.literal(true).optional(),
52
+ preserveTimeSignatures: z.literal(true),
53
+ preserveTempoEvents: z.literal(true),
54
+ preserveBoundaryNotes: z.boolean().optional(),
55
+ preserveHarmony: z.boolean().optional(),
56
+ preserveRhythm: z.boolean().optional(),
57
+ preserveMelody: z.boolean().optional(),
58
+ maximumPolyphony: z.number().int().positive().optional(),
59
+ allowedPitchRangeByTrack: z.record(z.string(), midiRangeSchema).optional(),
60
+ });
61
+ export const regenerateRegionRequestSchema = z.object({
62
+ scoreId: z.string().min(1),
63
+ instruction: z.string(),
64
+ range: scoreRangeSchema,
65
+ precedingContext: scoreFragmentSchema,
66
+ selectedFragment: scoreFragmentSchema,
67
+ followingContext: scoreFragmentSchema,
68
+ constraints: regenerationConstraintsSchema,
69
+ candidateCount: z.number().int().positive(),
70
+ style: z.string().optional(),
71
+ mood: z.string().optional(),
72
+ complexity: z.enum(["simple", "moderate", "complex"]).optional(),
73
+ });
74
+ export const regenerationCandidateSchema = z.object({
75
+ id: z.string().min(1),
76
+ label: z.string(),
77
+ fragment: scoreFragmentSchema,
78
+ });
79
+ export const regenerateRegionResultSchema = z.object({
80
+ candidates: z.array(regenerationCandidateSchema),
81
+ warnings: z.array(z.string()),
82
+ });
83
+ export const projectStatusSchema = z.enum([
84
+ "ready",
85
+ "generating",
86
+ "transcribing",
87
+ ]);
88
+ export const generationJobKindSchema = z.enum([
89
+ "generate-score",
90
+ "generate-track",
91
+ "replace-notes",
92
+ "replace-measures",
93
+ "replace-track",
94
+ ]);
95
+ export const generationJobStatusSchema = z.enum([
96
+ "queued",
97
+ "running",
98
+ "done",
99
+ "failed",
100
+ "cancelled",
101
+ ]);
102
+ export const tokenUsageSchema = z.object({
103
+ promptTokens: z.number().int().nonnegative(),
104
+ completionTokens: z.number().int().nonnegative(),
105
+ model: z.string().min(1),
106
+ });
107
+ export const generationJobSchema = z.object({
108
+ id: z.string().min(1),
109
+ projectId: z.string().min(1),
110
+ kind: generationJobKindSchema,
111
+ status: generationJobStatusSchema,
112
+ createdAt: z.string(),
113
+ finishedAt: z.string().nullable(),
114
+ error: z.string().nullable(),
115
+ usage: tokenUsageSchema.optional(),
116
+ });
117
+ export const createGenerationJobRequestSchema = z.object({
118
+ projectId: z.string().min(1),
119
+ kind: generationJobKindSchema,
120
+ request: z.unknown(),
121
+ });
122
+ /** Parses and validates untrusted JSON as a `GenerateScoreRequest`. Throws `ZodError` on invalid input. */
123
+ export function parseGenerateScoreRequest(json) {
124
+ return generateScoreRequestSchema.parse(json);
125
+ }
126
+ /** Parses and validates untrusted JSON as a `GenerateScoreResult`. Throws `ZodError` on invalid input. */
127
+ export function parseGenerateScoreResult(json) {
128
+ return generateScoreResultSchema.parse(json);
129
+ }
130
+ /** Parses and validates untrusted JSON as a `RegenerateRegionRequest`. Throws `ZodError` on invalid input. */
131
+ export function parseRegenerateRegionRequest(json) {
132
+ return regenerateRegionRequestSchema.parse(json);
133
+ }
134
+ /** Parses and validates untrusted JSON as a `RegenerateRegionResult`. Throws `ZodError` on invalid input. */
135
+ export function parseRegenerateRegionResult(json) {
136
+ return regenerateRegionResultSchema.parse(json);
137
+ }
138
+ /** Parses and validates untrusted JSON as a `RegenerationCandidate`. Throws `ZodError` on invalid input. */
139
+ export function parseRegenerationCandidate(json) {
140
+ return regenerationCandidateSchema.parse(json);
141
+ }
142
+ //# sourceMappingURL=generation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.js","sourceRoot":"","sources":["../../src/model/generation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Where playback is, as one number that everything reads.
3
+ *
4
+ * The editor has three things that follow the music — the caret, the note
5
+ * highlighting, and the piano keyboard — and they used to learn about it
6
+ * separately. The engine published a throttled `positionTick` on one channel
7
+ * and the sounding set on another, and the caret then *re-derived* its own
8
+ * position by dead-reckoning against `performance.now()` from whenever React
9
+ * happened to process the last report. Three consumers, three clocks: under
10
+ * load the caret's anchor was stamped late and drifted against notes that had
11
+ * lit up on the audio clock, so the three visibly disagreed.
12
+ *
13
+ * This is the interface that removes the possibility. One implementation owns
14
+ * the current tick — including the smoothing that keeps a caret gliding
15
+ * between engine reports — and playback *writes* it while everything that
16
+ * follows the music *reads* it. Two views of one number cannot disagree; three
17
+ * derivations of three numbers eventually will.
18
+ *
19
+ * Deliberately not a store slice: the value changes ~30 times a second and
20
+ * routing it through Zustand notifies every subscriber in the app at that rate,
21
+ * which is the cost the playback bus was built to avoid.
22
+ */
23
+ /** Detaches a listener registered with {@link IMusicPosition.subscribe}. */
24
+ export type UnsubscribePosition = () => void;
25
+ /**
26
+ * The playhead, in **score ticks**.
27
+ *
28
+ * Score ticks, not performance ticks: repeats and jumps mean a bar can be
29
+ * played more than once, and every consumer here draws or highlights something
30
+ * on the page, where a bar exists exactly once. The translation happens at the
31
+ * transport boundary so nothing downstream has to know repeats exist.
32
+ */
33
+ export interface IMusicPosition {
34
+ /**
35
+ * The current tick.
36
+ *
37
+ * Read this rather than remembering the last value from `subscribe`: an
38
+ * implementation may smooth between engine reports, in which case this is
39
+ * fresher than the last event and is the number the caret should draw at.
40
+ */
41
+ readonly tick: number;
42
+ /** Whether the transport is advancing, which is when smoothing applies. */
43
+ readonly isPlaying: boolean;
44
+ /**
45
+ * Observe changes.
46
+ *
47
+ * Fires when the underlying position is *reported*, not once per animation
48
+ * frame — a consumer that paints every frame should read {@link tick} in its
49
+ * own loop rather than expect an event per frame.
50
+ */
51
+ subscribe(listener: (tick: number) => void): UnsubscribePosition;
52
+ }
53
+ /**
54
+ * The writable side, held by whatever is driving playback.
55
+ *
56
+ * Split from the read interface so the split is visible in a signature: the
57
+ * transport takes this, and everything that merely follows the music takes
58
+ * {@link IMusicPosition} and cannot move the playhead by accident.
59
+ */
60
+ export interface IMusicPositionSource extends IMusicPosition {
61
+ /**
62
+ * Report an authoritative position, in score ticks.
63
+ *
64
+ * `atSeconds` is the *engine's own* clock reading for this position, not the
65
+ * wall clock at the moment the report is handled. That distinction is the
66
+ * whole point: anchoring on receipt time folds event-loop latency into the
67
+ * playhead, which is what made the caret drift under load.
68
+ */
69
+ report(tick: number, atSeconds?: number): void;
70
+ /** Start or stop smoothing, and set the rate ticks advance at. */
71
+ setPlaying(playing: boolean, ticksPerSecond?: number): void;
72
+ /**
73
+ * How fast ticks are passing right now.
74
+ *
75
+ * Separate from `setPlaying` because it changes *during* playback and must
76
+ * not re-anchor when it does: a score can slow into a fermata or change
77
+ * tempo at a rehearsal mark, and the projection between reports has to use
78
+ * the rate in force at that moment or the playhead glides past the hold.
79
+ */
80
+ setRate(ticksPerSecond: number): void;
81
+ }
82
+ //# sourceMappingURL=position.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../src/model/position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,mBAAmB,CAAC;CAClE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/C,kEAAkE;IAClE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5D;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Where playback is, as one number that everything reads.
3
+ *
4
+ * The editor has three things that follow the music — the caret, the note
5
+ * highlighting, and the piano keyboard — and they used to learn about it
6
+ * separately. The engine published a throttled `positionTick` on one channel
7
+ * and the sounding set on another, and the caret then *re-derived* its own
8
+ * position by dead-reckoning against `performance.now()` from whenever React
9
+ * happened to process the last report. Three consumers, three clocks: under
10
+ * load the caret's anchor was stamped late and drifted against notes that had
11
+ * lit up on the audio clock, so the three visibly disagreed.
12
+ *
13
+ * This is the interface that removes the possibility. One implementation owns
14
+ * the current tick — including the smoothing that keeps a caret gliding
15
+ * between engine reports — and playback *writes* it while everything that
16
+ * follows the music *reads* it. Two views of one number cannot disagree; three
17
+ * derivations of three numbers eventually will.
18
+ *
19
+ * Deliberately not a store slice: the value changes ~30 times a second and
20
+ * routing it through Zustand notifies every subscriber in the app at that rate,
21
+ * which is the cost the playback bus was built to avoid.
22
+ */
23
+ export {};
24
+ //# sourceMappingURL=position.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position.js","sourceRoot":"","sources":["../../src/model/position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}