@sudobility/music_types 0.12.1 → 0.13.2

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 (49) hide show
  1. package/CLAUDE.md +20 -0
  2. package/dist/bytes/base64.d.ts +40 -0
  3. package/dist/bytes/base64.d.ts.map +1 -0
  4. package/dist/bytes/base64.js +101 -0
  5. package/dist/bytes/base64.js.map +1 -0
  6. package/dist/bytes/index.d.ts +2 -0
  7. package/dist/bytes/index.d.ts.map +1 -0
  8. package/dist/bytes/index.js +2 -0
  9. package/dist/bytes/index.js.map +1 -0
  10. package/dist/domain/commands/repair-commands.d.ts +10 -0
  11. package/dist/domain/commands/repair-commands.d.ts.map +1 -0
  12. package/dist/domain/commands/repair-commands.js +25 -0
  13. package/dist/domain/commands/repair-commands.js.map +1 -0
  14. package/dist/domain/validation/limits.d.ts +32 -0
  15. package/dist/domain/validation/limits.d.ts.map +1 -0
  16. package/dist/domain/validation/limits.js +32 -0
  17. package/dist/domain/validation/limits.js.map +1 -0
  18. package/dist/domain/validation/repair.d.ts +48 -0
  19. package/dist/domain/validation/repair.d.ts.map +1 -0
  20. package/dist/domain/validation/repair.js +389 -0
  21. package/dist/domain/validation/repair.js.map +1 -0
  22. package/dist/domain/validation/validator.d.ts.map +1 -1
  23. package/dist/domain/validation/validator.js +1 -22
  24. package/dist/domain/validation/validator.js.map +1 -1
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +8 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/model/api.d.ts +16 -0
  30. package/dist/model/api.d.ts.map +1 -1
  31. package/dist/model/api.js +6 -0
  32. package/dist/model/api.js.map +1 -1
  33. package/dist/model/position.d.ts +16 -0
  34. package/dist/model/position.d.ts.map +1 -1
  35. package/dist/platform/playback.d.ts +9 -90
  36. package/dist/platform/playback.d.ts.map +1 -1
  37. package/dist/position/index.d.ts +3 -0
  38. package/dist/position/index.d.ts.map +1 -0
  39. package/dist/position/index.js +3 -0
  40. package/dist/position/index.js.map +1 -0
  41. package/dist/position/music-position.d.ts +69 -0
  42. package/dist/position/music-position.d.ts.map +1 -0
  43. package/dist/position/music-position.js +99 -0
  44. package/dist/position/music-position.js.map +1 -0
  45. package/dist/position/singleton.d.ts +34 -0
  46. package/dist/position/singleton.d.ts.map +1 -0
  47. package/dist/position/singleton.js +33 -0
  48. package/dist/position/singleton.js.map +1 -0
  49. package/package.json +1 -1
@@ -104,12 +104,23 @@ export type Snapshot = {
104
104
  publicId?: string;
105
105
  /** Shown on the Community list. Never the account email. */
106
106
  publisherName?: string;
107
+ /**
108
+ * The title a stranger sees, set when published.
109
+ *
110
+ * Kept apart from `name`, which is the version label this project's own
111
+ * picker draws: "Version 1" is what the tree needs and not what a public
112
+ * page should be called, and renaming for the public must not rewrite the
113
+ * history's labels.
114
+ */
115
+ publicName?: string;
107
116
  createdAt: string;
108
117
  };
109
118
  /** What an anonymous visitor receives. Carries no owner identity, by construction. */
110
119
  export type PublishedSnapshot = {
111
120
  publicId: string;
112
121
  name: string;
122
+ /** The public title. Falls back to `name` for anything published before it existed. */
123
+ publicName: string;
113
124
  publisherName: string;
114
125
  score: Score;
115
126
  createdAt: string;
@@ -473,6 +484,7 @@ export declare const snapshotSummarySchema: z.ZodObject<{
473
484
  createdAt: z.ZodString;
474
485
  publicId: z.ZodOptional<z.ZodString>;
475
486
  publisherName: z.ZodOptional<z.ZodString>;
487
+ publicName: z.ZodOptional<z.ZodString>;
476
488
  }, z.core.$strip>;
477
489
  export declare const snapshotSchema: z.ZodObject<{
478
490
  id: z.ZodString;
@@ -482,6 +494,7 @@ export declare const snapshotSchema: z.ZodObject<{
482
494
  createdAt: z.ZodString;
483
495
  publicId: z.ZodOptional<z.ZodString>;
484
496
  publisherName: z.ZodOptional<z.ZodString>;
497
+ publicName: z.ZodOptional<z.ZodString>;
485
498
  score: z.ZodObject<{
486
499
  id: z.ZodString;
487
500
  version: z.ZodNumber;
@@ -781,6 +794,7 @@ export declare const snapshotSchema: z.ZodObject<{
781
794
  export declare const publishedSnapshotSchema: z.ZodObject<{
782
795
  publicId: z.ZodString;
783
796
  name: z.ZodString;
797
+ publicName: z.ZodString;
784
798
  publisherName: z.ZodString;
785
799
  score: z.ZodObject<{
786
800
  id: z.ZodString;
@@ -1079,10 +1093,12 @@ export declare const communityItemSchema: z.ZodObject<{
1079
1093
  name: z.ZodString;
1080
1094
  createdAt: z.ZodString;
1081
1095
  publicId: z.ZodString;
1096
+ publicName: z.ZodString;
1082
1097
  publisherName: z.ZodString;
1083
1098
  }, z.core.$strip>;
1084
1099
  export declare const publishRequestSchema: z.ZodObject<{
1085
1100
  publisherName: z.ZodString;
1101
+ publicName: z.ZodString;
1086
1102
  }, z.core.$strip>;
1087
1103
  export declare const snapshotCreateRequestSchema: z.ZodObject<{
1088
1104
  name: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAM9C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,uGAAuG;IACvG,MAAM,EAAE,aAAa,CAAC;IACtB,qGAAqG;IACrG,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAE7D;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,IAAI,CAAC;IACT,SAAS,EAAE,IAAI,CAAC;IAChB,wEAAwE;IACxE,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;AAE7D,+EAA+E;AAC/E,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC7B,CAAC;AAMF,eAAO,MAAM,oBAAoB;;;iBAG/B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;iBAM/B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;iBAIlC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAE9B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;iBAUhC,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGzB,CAAC;AAEH,sFAAsF;AACtF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMlC,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB;;;;;iBAE9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;iBAE/B,CAAC;AAEH,eAAO,MAAM,2BAA2B;;iBAEtC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIrC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIrC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,6BAA6B;;iBAExC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;iBAGjC,CAAC;AAMH,eAAO,MAAM,eAAe;;;;;;IAM1B;;;;;OAKG;;IAEH;;;;;OAKG;;IAEH;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,YAAY,GACtB,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEzD,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAE1D;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,YAAY,GAClB,WAAW,CAAC,KAAK,CAAC,CAIpB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"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"}
package/dist/model/api.js CHANGED
@@ -38,6 +38,7 @@ export const snapshotSummarySchema = z.object({
38
38
  // picker badges from, and it is also all a publish response needs to return.
39
39
  publicId: z.string().min(1).optional(),
40
40
  publisherName: z.string().min(1).optional(),
41
+ publicName: z.string().min(1).optional(),
41
42
  });
42
43
  export const snapshotSchema = snapshotSummarySchema.extend({
43
44
  score: scoreSchema,
@@ -47,6 +48,7 @@ export const snapshotSchema = snapshotSummarySchema.extend({
47
48
  export const publishedSnapshotSchema = z.object({
48
49
  publicId: z.string().min(1),
49
50
  name: z.string().min(1),
51
+ publicName: z.string().min(1),
50
52
  publisherName: z.string().min(1),
51
53
  score: scoreSchema,
52
54
  createdAt: z.string().min(1),
@@ -57,6 +59,10 @@ export const communityItemSchema = publishedSnapshotSchema.omit({
57
59
  });
58
60
  export const publishRequestSchema = z.object({
59
61
  publisherName: z.string().min(1).max(80),
62
+ // Required: publishing without a public title would put "Version 1" on a
63
+ // page strangers read. Re-publishing an already-public snapshot is how a
64
+ // title is changed, so this arrives on every publish, not only the first.
65
+ publicName: z.string().min(1).max(200),
60
66
  });
61
67
  export const snapshotCreateRequestSchema = z.object({
62
68
  name: z.string().min(1).max(200),
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/model/api.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,22 @@ export interface IMusicPosition {
39
39
  * fresher than the last event and is the number the caret should draw at.
40
40
  */
41
41
  readonly tick: number;
42
+ /**
43
+ * The last position the transport actually vouched for.
44
+ *
45
+ * Exposed beside {@link tick} deliberately: a smoothed playhead and the
46
+ * report it was projected from are both wanted — a caret glides, while a
47
+ * scrubber, a bar/beat readout or a scroll that follows the music wants the
48
+ * position something corroborated. Keeping the pair on one implementation is
49
+ * what stops them drifting; when the bus kept its own copy of the report and
50
+ * the playhead projected from another, a producer that stopped reporting
51
+ * left the caret gliding the length of the score while everything reading
52
+ * the copy sat at bar one.
53
+ *
54
+ * "Vouched for" rather than "reported": the transport also banks a position
55
+ * when it starts or stops, and that is equally authoritative.
56
+ */
57
+ readonly reportedTick: number;
42
58
  /** Whether the transport is advancing, which is when smoothing applies. */
43
59
  readonly isPlaying: boolean;
44
60
  /**
@@ -1 +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"}
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;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,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"}
@@ -7,7 +7,6 @@
7
7
  * things that import an audio library; everything that depends on playback
8
8
  * depends on this file instead, so the engine stays swappable and mockable.
9
9
  */
10
- import type { ScoreRange } from "../index.js";
11
10
  import type { RenderTrack } from "./audio.js";
12
11
  export type TransportPlaybackState = "stopped" | "playing" | "paused";
13
12
  /**
@@ -24,29 +23,6 @@ export type SoundingNote = {
24
23
  /** Its sounding MIDI pitch, so a keyboard can light a key without resolving the event. */
25
24
  midi: number;
26
25
  };
27
- export type PlaybackObserver = {
28
- onPositionTick(tick: number): void;
29
- /**
30
- * The notes currently sounding, whenever that set changes.
31
- *
32
- * Resolved rather than bare ids. The scheduler already knows each note's
33
- * track and pitch — it scheduled them — and emitting only the id forced every
34
- * consumer to search the whole score to get it back: `playingPitchesForTrack`
35
- * was an O(score) scan per sounding note, twenty times a second.
36
- */
37
- onActiveNotes(notes: SoundingNote[]): void;
38
- onStateChange(state: TransportPlaybackState): void;
39
- /**
40
- * How far along the engine is in becoming able to make a sound.
41
- *
42
- * Optional because not every engine has anything to load. The soundfont
43
- * engine does: tens of megabytes to fetch and several seconds for the synth
44
- * to digest, all on the first press of Play. Without this the transport
45
- * simply looks broken for that whole time — which is exactly how it read
46
- * before there was anywhere to report it.
47
- */
48
- onLoadStateChange?(state: PlaybackLoadState): void;
49
- };
50
26
  /**
51
27
  * The engine's readiness to play, for a progress indicator.
52
28
  *
@@ -77,20 +53,6 @@ export type PlaybackTrack = RenderTrack & {
77
53
  muted: boolean;
78
54
  solo: boolean;
79
55
  };
80
- /**
81
- * A voice to audition, resolved from the GM tables **by the caller**.
82
- *
83
- * The engine cannot resolve it: a percussion voice's program addresses a drum
84
- * kit, and only the GM tables know which kit an arbitrary address falls in.
85
- * Resolving here is what lets the platform layer keep no catalogue of its own.
86
- */
87
- export type AuditionVoice = {
88
- /** The kit's program on a percussion voice, the instrument's own otherwise. */
89
- program: number;
90
- /** The GM catalogue name for `program`. */
91
- name: string;
92
- isPercussion: boolean;
93
- };
94
56
  /** One playback-ready note, in score ticks, carrying the ids playback reports back. */
95
57
  export type PlaybackNote = {
96
58
  tick: number;
@@ -135,6 +97,15 @@ export type PerformanceTimeline = {
135
97
  segments: readonly TimelineSegment[];
136
98
  durationTicks: number;
137
99
  };
100
+ /**
101
+ * The engine contract — `PlaybackEngine`, `PlaybackObserver` and
102
+ * `AuditionVoice` — lives in `@sudobility/music_player`, which is the only
103
+ * thing that implements it.
104
+ *
105
+ * The *plan* stays here, and must: `PlaybackPlan` composes `PerformanceTimeline`,
106
+ * which `performanceTimeline()` in `domain/score/` produces. Moving it would
107
+ * make this package import from music_player.
108
+ */
138
109
  export type PlaybackPlan = {
139
110
  tracks: readonly PlaybackTrack[];
140
111
  notes: readonly PlaybackNote[];
@@ -156,56 +127,4 @@ export type PlaybackLoadState = {
156
127
  status: "failed";
157
128
  message: string;
158
129
  };
159
- export interface PlaybackEngine {
160
- initialize(): Promise<void>;
161
- /** Adopts a plan. The engine is handed music, never a score. */
162
- load(plan: PlaybackPlan): Promise<void>;
163
- play(fromTick?: number): Promise<void>;
164
- pause(): void;
165
- stop(): void;
166
- seek(tick: number): void;
167
- setTempoMultiplier(multiplier: number): void;
168
- setLoop(range: ScoreRange | null): void;
169
- setTrackMute(trackId: string, muted: boolean): void;
170
- setTrackSolo(trackId: string, solo: boolean): void;
171
- /**
172
- * Re-reads every track's volume, pan, mute and solo and pushes them,
173
- * touching nothing that is scheduled.
174
- *
175
- * The mixing counterpart to `load`. Mute and solo had setters; volume and pan
176
- * did not, and a track's volume was only ever read at load time — so once a
177
- * mix change stopped reloading the score (the playback edit lock, see
178
- * `music_lib`'s `score-slice`), moving a fader during playback moved the
179
- * fader and not the sound.
180
- *
181
- * Takes only the tracks, so changing a gain does not rebuild every note —
182
- * which is the whole reason this is separate from `load`. Idempotent, and
183
- * takes them all rather than one property: the caller says "the mix changed,
184
- * here it is" and does not work out which property it was.
185
- */
186
- applyMix(tracks: readonly PlaybackTrack[]): void;
187
- /** Toggles the metronome click. */
188
- setMetronome(enabled: boolean): void;
189
- /** Sets overall output level, 0-1 linear gain. */
190
- setMasterVolume(volume: number): void;
191
- /**
192
- * Sounds `midi` immediately on `program`'s voice and holds it, independent of
193
- * the transport — for auditioning a key while editing.
194
- *
195
- * `voice.isPercussion` mirrors what playback does with a percussion-clef
196
- * track: without it, tapping a note on a drum track auditioned a pitched
197
- * instrument while the same note played back as a drum.
198
- *
199
- * Separate from `play` because the two answer different questions: `play`
200
- * renders the written score along a timeline, this makes a sound *now*, for
201
- * as long as the caller holds it, whether or not a score is even loaded.
202
- * Implementations must not disturb transport state.
203
- */
204
- noteOn(midi: number, voice: AuditionVoice): void;
205
- /** Releases a pitch started by `noteOn`. Silent no-op if it is not sounding. */
206
- noteOff(midi: number): void;
207
- /** Registers (or, with `null`, clears) the single observer receiving position/active-note/state updates. */
208
- setObserver(observer: PlaybackObserver | null): void;
209
- dispose(): void;
210
- }
211
130
  //# sourceMappingURL=playback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/platform/playback.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;;;OAOG;IACH,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC3C,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACnD;;;;;;;;OAQG;IACH,iBAAiB,CAAC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACpD,CAAC;AAEF;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/D;;;;;;;GAOG;AACH,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,KAAK,EAAE,eAAe,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,gEAAgE;IAChE,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;IACxC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACnD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IACjD,mCAAmC;IACnC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,kDAAkD;IAClD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACjD,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,4GAA4G;IAC5G,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;IACrD,OAAO,IAAI,IAAI,CAAC;CACjB"}
1
+ {"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/platform/playback.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAGF;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAGF,uFAAuF;AACvF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/D;;;;;;;GAOG;AACH,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAClC,KAAK,EAAE,eAAe,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./music-position.js";
2
+ export * from "./singleton.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/position/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./music-position.js";
2
+ export * from "./singleton.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/position/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The one place that knows where playback is.
3
+ *
4
+ * **The first stateful singleton service in music_types, and deliberately so.**
5
+ * This package is otherwise model and primitives. The playhead earns the
6
+ * exception because it has exactly one writer — `@sudobility/music_player` —
7
+ * and readers in every other package: the caret, the note highlighting and the
8
+ * piano keyboard. Any other home creates a dependency edge that exists only to
9
+ * reach it. It still obeys the four rules this package keeps: it works on both
10
+ * the frontend and the backend, adds no dependency, contains no hooks and
11
+ * contains no async code.
12
+ *
13
+ * Implements `IMusicPosition` — see that interface for why this exists at all.
14
+ * The short version: the caret, the note highlighting and the piano keyboard
15
+ * used to derive the playhead three different ways and drifted apart under
16
+ * load. Now they read one number.
17
+ *
18
+ * **The smoothing lives here, not in the caret.** That is the load-bearing
19
+ * decision. The engine reports position about thirty times a second, and those
20
+ * reports arrive in clumps because they come off the audio scheduler's
21
+ * lookahead loop rather than a wall clock — driving anything straight off them
22
+ * leaves it stalled on most frames and jumping when it does move. So the
23
+ * playhead is dead-reckoned forward from the last report, and because that
24
+ * happens *inside the single source of truth*, every consumer that asks gets
25
+ * the same smoothed answer at the same instant. When the caret did its own
26
+ * dead-reckoning, it was smoothing a number nobody else was smoothing.
27
+ *
28
+ * The anchor is the engine's own clock reading, not `performance.now()` at the
29
+ * moment the report was handled. Anchoring on receipt folds event-loop latency
30
+ * into the playhead: under load the anchor is stamped late and everything
31
+ * derived from it lags the audio, which is exactly the drift this replaces.
32
+ */
33
+ import type { IMusicPositionSource, UnsubscribePosition } from "../model/position.js";
34
+ export declare class MusicPosition implements IMusicPositionSource {
35
+ private readonly listeners;
36
+ /** The last authoritative report, and the clock reading it belongs to. */
37
+ private anchorTick;
38
+ private anchorSeconds;
39
+ private playing;
40
+ private ticksPerSecond;
41
+ get isPlaying(): boolean;
42
+ /**
43
+ * The playhead now.
44
+ *
45
+ * While stopped this is exactly the last reported tick — a paused caret must
46
+ * not creep. While playing it is the last report projected forward by the
47
+ * time since it was taken, which is what makes motion even however unevenly
48
+ * the reports land.
49
+ */
50
+ get tick(): number;
51
+ /**
52
+ * The last vouched-for position: the last report, or the position banked
53
+ * when the transport last changed state. `tick` projects from exactly this,
54
+ * so the two cannot describe different moments.
55
+ */
56
+ get reportedTick(): number;
57
+ report(tick: number, atSeconds?: number): void;
58
+ /**
59
+ * Update the tick rate without disturbing the anchor.
60
+ *
61
+ * Deliberately not folded into `report`: re-anchoring is `report`'s job and
62
+ * a rate change must not do it, or a tempo change mid-bar would restart the
63
+ * projection from wherever the last report left off.
64
+ */
65
+ setRate(ticksPerSecond: number): void;
66
+ setPlaying(playing: boolean, ticksPerSecond?: number): void;
67
+ subscribe(listener: (tick: number) => void): UnsubscribePosition;
68
+ }
69
+ //# sourceMappingURL=music-position.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"music-position.d.ts","sourceRoot":"","sources":["../../src/position/music-position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AA8B9B,qBAAa,aAAc,YAAW,oBAAoB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAE/D,0EAA0E;IAC1E,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAgB;IAErC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAK;IAE3B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,MAAM,CAcjB;IAED;;;;OAIG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAM9C;;;;;;OAMG;IACH,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAIrC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAY3D,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,mBAAmB;CAIjE"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * How far the playhead may be projected past its last report.
3
+ *
4
+ * Dead reckoning is an interpolation between reports, not a substitute for
5
+ * them. Reports arrive about thirty times a second and in clumps, so the bound
6
+ * has to absorb a clump — but past that, continuing to advance is asserting a
7
+ * position nothing has corroborated.
8
+ *
9
+ * That distinction is not academic: when the engine's own report throttle
10
+ * silenced it, this projected on regardless and the caret glided the length of
11
+ * the score while every consumer of the *reported* tick — the scroll, the
12
+ * bar/beat readout, the scrubber — sat at bar one. One writer, but two
13
+ * behaviours, and they disagreed by the whole piece. Bounded, a stalled
14
+ * producer stops the playhead everywhere at once, which reads as the one fault
15
+ * it is instead of as a caret that works and a page that does not.
16
+ *
17
+ * Half a second is roughly fifteen missed reports: far beyond any clump, far
18
+ * short of anything a reader would call motion.
19
+ */
20
+ const MAX_PROJECTION_SECONDS = 0.5;
21
+ /** Wall-clock seconds, monotonic where the platform offers it. */
22
+ function nowSeconds() {
23
+ return typeof performance !== "undefined"
24
+ ? performance.now() / 1000
25
+ : Date.now() / 1000;
26
+ }
27
+ export class MusicPosition {
28
+ constructor() {
29
+ this.listeners = new Set();
30
+ /** The last authoritative report, and the clock reading it belongs to. */
31
+ this.anchorTick = 0;
32
+ this.anchorSeconds = nowSeconds();
33
+ this.playing = false;
34
+ this.ticksPerSecond = 0;
35
+ }
36
+ get isPlaying() {
37
+ return this.playing;
38
+ }
39
+ /**
40
+ * The playhead now.
41
+ *
42
+ * While stopped this is exactly the last reported tick — a paused caret must
43
+ * not creep. While playing it is the last report projected forward by the
44
+ * time since it was taken, which is what makes motion even however unevenly
45
+ * the reports land.
46
+ */
47
+ get tick() {
48
+ if (!this.playing || this.ticksPerSecond <= 0)
49
+ return this.anchorTick;
50
+ // Capped: see `MAX_PROJECTION_SECONDS`. Past the bound the playhead holds
51
+ // its last corroborated position rather than inventing motion.
52
+ const elapsed = Math.min(nowSeconds() - this.anchorSeconds, MAX_PROJECTION_SECONDS);
53
+ // Never backwards: a report that arrives late would otherwise pull the
54
+ // playhead back a few ticks, which reads as a stutter.
55
+ return Math.max(this.anchorTick, this.anchorTick + elapsed * this.ticksPerSecond);
56
+ }
57
+ /**
58
+ * The last vouched-for position: the last report, or the position banked
59
+ * when the transport last changed state. `tick` projects from exactly this,
60
+ * so the two cannot describe different moments.
61
+ */
62
+ get reportedTick() {
63
+ return this.anchorTick;
64
+ }
65
+ report(tick, atSeconds) {
66
+ this.anchorTick = tick;
67
+ this.anchorSeconds = atSeconds ?? nowSeconds();
68
+ for (const listener of this.listeners)
69
+ listener(tick);
70
+ }
71
+ /**
72
+ * Update the tick rate without disturbing the anchor.
73
+ *
74
+ * Deliberately not folded into `report`: re-anchoring is `report`'s job and
75
+ * a rate change must not do it, or a tempo change mid-bar would restart the
76
+ * projection from wherever the last report left off.
77
+ */
78
+ setRate(ticksPerSecond) {
79
+ this.ticksPerSecond = Math.max(0, ticksPerSecond);
80
+ }
81
+ setPlaying(playing, ticksPerSecond) {
82
+ // Re-anchor on the transition, or the first `tick` read after resuming
83
+ // would project forward from however long the transport sat paused.
84
+ if (playing !== this.playing) {
85
+ this.anchorTick = this.tick;
86
+ this.anchorSeconds = nowSeconds();
87
+ }
88
+ this.playing = playing;
89
+ if (ticksPerSecond !== undefined)
90
+ this.ticksPerSecond = ticksPerSecond;
91
+ for (const listener of this.listeners)
92
+ listener(this.anchorTick);
93
+ }
94
+ subscribe(listener) {
95
+ this.listeners.add(listener);
96
+ return () => this.listeners.delete(listener);
97
+ }
98
+ }
99
+ //# sourceMappingURL=music-position.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"music-position.js","sourceRoot":"","sources":["../../src/position/music-position.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,kEAAkE;AAClE,SAAS,UAAU;IACjB,OAAO,OAAO,WAAW,KAAK,WAAW;QACvC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI;QAC1B,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,OAAO,aAAa;IAA1B;QACmB,cAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;QAE/D,0EAA0E;QAClE,eAAU,GAAG,CAAC,CAAC;QACf,kBAAa,GAAG,UAAU,EAAE,CAAC;QAE7B,YAAO,GAAG,KAAK,CAAC;QAChB,mBAAc,GAAG,CAAC,CAAC;IAwE7B,CAAC;IAtEC,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,IAAI;QACN,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACtE,0EAA0E;QAC1E,+DAA+D;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,UAAU,EAAE,GAAG,IAAI,CAAC,aAAa,EACjC,sBAAsB,CACvB,CAAC;QACF,uEAAuE;QACvE,uDAAuD;QACvD,OAAO,IAAI,CAAC,GAAG,CACb,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC,cAAc,CAChD,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,SAAkB;QACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;QAC/C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,cAAsB;QAC5B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,OAAgB,EAAE,cAAuB;QAClD,uEAAuE;QACvE,oEAAoE;QACpE,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,aAAa,GAAG,UAAU,EAAE,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,cAAc,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACvE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,SAAS,CAAC,QAAgC;QACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The music-position singleton.
3
+ *
4
+ * Same shape as the rest of the family's services (see `@sudobility/di`'s
5
+ * storage and network singletons): initialise once at start-up, read it
6
+ * everywhere, reset it in tests.
7
+ *
8
+ * A singleton because the playhead *is* global to a running transport — there
9
+ * is one piece of music playing, and the whole point of this type is that
10
+ * everything following it reads the same number. Two instances would
11
+ * reintroduce exactly the disagreement it exists to prevent.
12
+ */
13
+ import type { IMusicPosition, IMusicPositionSource } from '../model/position.js';
14
+ /**
15
+ * Creates the singleton if it does not exist.
16
+ *
17
+ * Idempotent, so a second call from a re-mounting composition root does not
18
+ * silently swap the playhead out from under everything subscribed to it.
19
+ */
20
+ export declare function initializeMusicPosition(override?: IMusicPositionSource): IMusicPositionSource;
21
+ /**
22
+ * The writable playhead, for whatever is driving the transport.
23
+ *
24
+ * Auto-initialises rather than throwing: unlike a storage service there is no
25
+ * configuration to get wrong, and a playhead that refuses to exist until
26
+ * somebody remembers a start-up call is a worse failure than one that starts
27
+ * at zero.
28
+ */
29
+ export declare function getMusicPositionSource(): IMusicPositionSource;
30
+ /** The read-only playhead, for anything that follows the music. */
31
+ export declare function getMusicPosition(): IMusicPosition;
32
+ /** Drops the singleton. Tests only — a suite must not inherit the last one's playhead. */
33
+ export declare function resetMusicPosition(): void;
34
+ //# sourceMappingURL=singleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../src/position/singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAK9B;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,oBAAoB,CAGtB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,oBAAoB,CAE7D;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,IAAI,cAAc,CAEjD;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,33 @@
1
+ import { MusicPosition } from './music-position.js';
2
+ let instance = null;
3
+ /**
4
+ * Creates the singleton if it does not exist.
5
+ *
6
+ * Idempotent, so a second call from a re-mounting composition root does not
7
+ * silently swap the playhead out from under everything subscribed to it.
8
+ */
9
+ export function initializeMusicPosition(override) {
10
+ if (!instance)
11
+ instance = override ?? new MusicPosition();
12
+ return instance;
13
+ }
14
+ /**
15
+ * The writable playhead, for whatever is driving the transport.
16
+ *
17
+ * Auto-initialises rather than throwing: unlike a storage service there is no
18
+ * configuration to get wrong, and a playhead that refuses to exist until
19
+ * somebody remembers a start-up call is a worse failure than one that starts
20
+ * at zero.
21
+ */
22
+ export function getMusicPositionSource() {
23
+ return initializeMusicPosition();
24
+ }
25
+ /** The read-only playhead, for anything that follows the music. */
26
+ export function getMusicPosition() {
27
+ return initializeMusicPosition();
28
+ }
29
+ /** Drops the singleton. Tests only — a suite must not inherit the last one's playhead. */
30
+ export function resetMusicPosition() {
31
+ instance = null;
32
+ }
33
+ //# sourceMappingURL=singleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton.js","sourceRoot":"","sources":["../../src/position/singleton.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,IAAI,QAAQ,GAAgC,IAAI,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAA+B;IAE/B,IAAI,CAAC,QAAQ;QAAE,QAAQ,GAAG,QAAQ,IAAI,IAAI,aAAa,EAAE,CAAC;IAC1D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,uBAAuB,EAAE,CAAC;AACnC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,gBAAgB;IAC9B,OAAO,uBAAuB,EAAE,CAAC;AACnC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB;IAChC,QAAQ,GAAG,IAAI,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/music_types",
3
- "version": "0.12.1",
3
+ "version": "0.13.2",
4
4
  "description": "TypeScript types and Zod schemas for the ScoreSmith music API - scores, generation contracts, project payloads",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",