@yam8d/m8-sdk 0.2.0 → 0.3.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.
@@ -0,0 +1,112 @@
1
+ /**
2
+ * viewContext.ts
3
+ *
4
+ * Derives semantic meaning from raw M8State by mapping cursor position and
5
+ * currentLine content to typed, labelled fields using the m8-view-context.json schema.
6
+ *
7
+ * The five grid views (song, chain, phrase, table, groove) are fully supported.
8
+ * Parameter views (inst, mixer, project, …) return a minimal context with viewName only.
9
+ */
10
+ import type { M8State } from './types';
11
+ export type M8FieldType = 'chainRef' | 'phraseRef' | 'note' | 'velocity' | 'instrumentRef' | 'fxCommand' | 'fxValue' | 'transpose' | 'ticks' | 'volume' | 'ppq' | 'instrumentName' | 'eqSlot' | 'rowIndex';
12
+ /**
13
+ * A single parsed field value extracted from the currentLine.
14
+ */
15
+ export interface M8ParsedField {
16
+ /** Column key as defined in the schema (e.g. 'fx1cmd', 'note', 'track3'). */
17
+ key: string;
18
+ /** Human-readable label (e.g. 'FX1 Command', 'Note (N)'). */
19
+ label: string;
20
+ /** Semantic type of this field. */
21
+ type: M8FieldType;
22
+ /** Raw text extracted from currentLine (trimmed). */
23
+ rawValue: string;
24
+ /**
25
+ * Parsed integer (from hex) when the field holds a numeric value.
26
+ * `null` for empty cells ('--', '---') and text-only types (note name, fxCommand).
27
+ */
28
+ hexValue: number | null;
29
+ /** True when the cell is empty/unused ('--', '---', '---00'). */
30
+ isEmpty: boolean;
31
+ /** Extra view-specific metadata (e.g. { trackIndex: 2 } for song view track columns). */
32
+ meta?: Record<string, unknown>;
33
+ }
34
+ /**
35
+ * All fields parsed from the current row (line at cursorPos.y).
36
+ */
37
+ export interface M8ParsedRow {
38
+ /** Row index (hex-parsed) derived from the leftmost chars of currentLine. null if not parseable. */
39
+ rowIndex: number | null;
40
+ /** Schema key for the row index field (e.g. 'songRow', 'step', 'chainPos'). */
41
+ rowKey: string;
42
+ /** Map of column key → parsed field for every column in this view. */
43
+ fields: Record<string, M8ParsedField>;
44
+ }
45
+ /**
46
+ * The field currently under the cursor, plus row context.
47
+ */
48
+ export interface M8ActiveField extends M8ParsedField {
49
+ /** Repetition of the view name for convenience. */
50
+ viewName: string;
51
+ /** Row index of the line containing this field (null if not parseable). */
52
+ rowIndex: number | null;
53
+ }
54
+ /**
55
+ * Full semantic context for the current M8State.
56
+ */
57
+ export interface M8SemanticContext {
58
+ /** M8 view name (lowercased), e.g. 'song', 'phrase'. */
59
+ viewName: string;
60
+ /** Human-readable view title from schema ('Song View', 'Phrase View', …). */
61
+ viewTitle: string | null;
62
+ /** View description from the schema. */
63
+ viewDescription: string | null;
64
+ /**
65
+ * The numeric ID of the current view item, parsed from the screen title.
66
+ * e.g. 'F2' from ' CHAIN F2*', '03' from ' PHRASE 03'.
67
+ * null for views that have no item number (song, instrument pool).
68
+ */
69
+ viewId: string | null;
70
+ /** True when the title carries a '*' suffix, indicating unsaved changes. */
71
+ isUnsaved: boolean;
72
+ /** Whether this view is a structured grid (song/chain/phrase/table/groove). */
73
+ isGridView: boolean;
74
+ /** All fields on the line at cursorPos.y (null for non-grid views or missing line). */
75
+ row: M8ParsedRow | null;
76
+ /** The specific field under the cursor (null when cursor is out of any column range). */
77
+ activeField: M8ActiveField | null;
78
+ }
79
+ /**
80
+ * Look up the description of a 3-character FX command name.
81
+ * Returns undefined if the command is unknown.
82
+ */
83
+ export declare function lookupFxCommand(cmd: string): {
84
+ description: string;
85
+ } | undefined;
86
+ /**
87
+ * Derives a full semantic context from the current M8State.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * const ctx = getSemanticContext(state)
92
+ * if (ctx?.activeField?.type === 'chainRef') {
93
+ * const track = ctx.activeField.meta?.trackIndex // 1–8
94
+ * const chainNum = ctx.activeField.hexValue // 0–255 or null if empty
95
+ * const songRow = ctx.row?.rowIndex
96
+ * }
97
+ * ```
98
+ */
99
+ export declare function getSemanticContext(state: M8State): M8SemanticContext | null;
100
+ /**
101
+ * Returns a short human-readable description of what the cursor is currently on.
102
+ *
103
+ * @example
104
+ * "Track 3 — Chain 0A — Song Row 02"
105
+ * "Note A#4 — Step 7 (Phrase)"
106
+ * "FX1 Command: KIL (Kill Note) — Step 0"
107
+ */
108
+ export declare function describeContext(ctx: M8SemanticContext): string;
109
+ /**
110
+ * Formats a parsed field value as a human-readable string.
111
+ */
112
+ export declare function formatFieldValue(field: M8ParsedField): string;