@beatbax/engine 0.1.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.
Files changed (174) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/audio/bufferedRenderer.d.ts +32 -0
  3. package/dist/audio/bufferedRenderer.d.ts.map +1 -0
  4. package/dist/audio/bufferedRenderer.js +309 -0
  5. package/dist/audio/bufferedRenderer.js.map +1 -0
  6. package/dist/audio/pcmRenderer.d.ts +25 -0
  7. package/dist/audio/pcmRenderer.d.ts.map +1 -0
  8. package/dist/audio/pcmRenderer.js +1288 -0
  9. package/dist/audio/pcmRenderer.js.map +1 -0
  10. package/dist/audio/playback.d.ts +57 -0
  11. package/dist/audio/playback.d.ts.map +1 -0
  12. package/dist/audio/playback.js +794 -0
  13. package/dist/audio/playback.js.map +1 -0
  14. package/dist/chips/gameboy/apu.d.ts +9 -0
  15. package/dist/chips/gameboy/apu.d.ts.map +1 -0
  16. package/dist/chips/gameboy/apu.js +27 -0
  17. package/dist/chips/gameboy/apu.js.map +1 -0
  18. package/dist/chips/gameboy/noise.d.ts +6 -0
  19. package/dist/chips/gameboy/noise.d.ts.map +1 -0
  20. package/dist/chips/gameboy/noise.js +155 -0
  21. package/dist/chips/gameboy/noise.js.map +1 -0
  22. package/dist/chips/gameboy/packet.d.ts +3 -0
  23. package/dist/chips/gameboy/packet.d.ts.map +1 -0
  24. package/dist/chips/gameboy/packet.js +3 -0
  25. package/dist/chips/gameboy/packet.js.map +1 -0
  26. package/dist/chips/gameboy/periodTables.d.ts +16 -0
  27. package/dist/chips/gameboy/periodTables.d.ts.map +1 -0
  28. package/dist/chips/gameboy/periodTables.js +29 -0
  29. package/dist/chips/gameboy/periodTables.js.map +1 -0
  30. package/dist/chips/gameboy/pulse.d.ts +12 -0
  31. package/dist/chips/gameboy/pulse.d.ts.map +1 -0
  32. package/dist/chips/gameboy/pulse.js +275 -0
  33. package/dist/chips/gameboy/pulse.js.map +1 -0
  34. package/dist/chips/gameboy/wave.d.ts +8 -0
  35. package/dist/chips/gameboy/wave.d.ts.map +1 -0
  36. package/dist/chips/gameboy/wave.js +146 -0
  37. package/dist/chips/gameboy/wave.js.map +1 -0
  38. package/dist/effects/index.d.ts +7 -0
  39. package/dist/effects/index.d.ts.map +1 -0
  40. package/dist/effects/index.js +1028 -0
  41. package/dist/effects/index.js.map +1 -0
  42. package/dist/effects/types.d.ts +8 -0
  43. package/dist/effects/types.d.ts.map +1 -0
  44. package/dist/effects/types.js +2 -0
  45. package/dist/effects/types.js.map +1 -0
  46. package/dist/expand/refExpander.d.ts +14 -0
  47. package/dist/expand/refExpander.d.ts.map +1 -0
  48. package/dist/expand/refExpander.js +130 -0
  49. package/dist/expand/refExpander.js.map +1 -0
  50. package/dist/export/index.d.ts +5 -0
  51. package/dist/export/index.d.ts.map +1 -0
  52. package/dist/export/index.js +5 -0
  53. package/dist/export/index.js.map +1 -0
  54. package/dist/export/jsonExport.d.ts +9 -0
  55. package/dist/export/jsonExport.d.ts.map +1 -0
  56. package/dist/export/jsonExport.js +184 -0
  57. package/dist/export/jsonExport.js.map +1 -0
  58. package/dist/export/midiExport.d.ts +9 -0
  59. package/dist/export/midiExport.d.ts.map +1 -0
  60. package/dist/export/midiExport.js +390 -0
  61. package/dist/export/midiExport.js.map +1 -0
  62. package/dist/export/ugeWriter.d.ts +33 -0
  63. package/dist/export/ugeWriter.d.ts.map +1 -0
  64. package/dist/export/ugeWriter.js +1997 -0
  65. package/dist/export/ugeWriter.js.map +1 -0
  66. package/dist/export/wavWriter.d.ts +24 -0
  67. package/dist/export/wavWriter.d.ts.map +1 -0
  68. package/dist/export/wavWriter.js +126 -0
  69. package/dist/export/wavWriter.js.map +1 -0
  70. package/dist/import/index.d.ts +5 -0
  71. package/dist/import/index.d.ts.map +1 -0
  72. package/dist/import/index.js +8 -0
  73. package/dist/import/index.js.map +1 -0
  74. package/dist/import/remoteCache.d.ts +60 -0
  75. package/dist/import/remoteCache.d.ts.map +1 -0
  76. package/dist/import/remoteCache.js +194 -0
  77. package/dist/import/remoteCache.js.map +1 -0
  78. package/dist/import/uge/uge.reader.d.ts +27 -0
  79. package/dist/import/uge/uge.reader.d.ts.map +1 -0
  80. package/dist/import/uge/uge.reader.js +545 -0
  81. package/dist/import/uge/uge.reader.js.map +1 -0
  82. package/dist/import/urlUtils.d.ts +50 -0
  83. package/dist/import/urlUtils.d.ts.map +1 -0
  84. package/dist/import/urlUtils.js +87 -0
  85. package/dist/import/urlUtils.js.map +1 -0
  86. package/dist/index.d.ts +18 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +318 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/instruments/instrumentState.d.ts +15 -0
  91. package/dist/instruments/instrumentState.d.ts.map +1 -0
  92. package/dist/instruments/instrumentState.js +24 -0
  93. package/dist/instruments/instrumentState.js.map +1 -0
  94. package/dist/parser/ast.d.ts +22 -0
  95. package/dist/parser/ast.d.ts.map +1 -0
  96. package/dist/parser/ast.js +5 -0
  97. package/dist/parser/ast.js.map +1 -0
  98. package/dist/parser/index.d.ts +14 -0
  99. package/dist/parser/index.d.ts.map +1 -0
  100. package/dist/parser/index.js +10 -0
  101. package/dist/parser/index.js.map +1 -0
  102. package/dist/parser/peggy/generated/parser.d.ts +8 -0
  103. package/dist/parser/peggy/generated/parser.d.ts.map +1 -0
  104. package/dist/parser/peggy/generated/parser.js +6269 -0
  105. package/dist/parser/peggy/generated/parser.js.map +1 -0
  106. package/dist/parser/peggy/index.d.ts +3 -0
  107. package/dist/parser/peggy/index.d.ts.map +1 -0
  108. package/dist/parser/peggy/index.js +555 -0
  109. package/dist/parser/peggy/index.js.map +1 -0
  110. package/dist/parser/structured.d.ts +16 -0
  111. package/dist/parser/structured.d.ts.map +1 -0
  112. package/dist/parser/structured.js +232 -0
  113. package/dist/parser/structured.js.map +1 -0
  114. package/dist/parser/tokenizer.d.ts +12 -0
  115. package/dist/parser/tokenizer.d.ts.map +1 -0
  116. package/dist/parser/tokenizer.js +14 -0
  117. package/dist/parser/tokenizer.js.map +1 -0
  118. package/dist/patterns/expand.d.ts +32 -0
  119. package/dist/patterns/expand.d.ts.map +1 -0
  120. package/dist/patterns/expand.js +184 -0
  121. package/dist/patterns/expand.js.map +1 -0
  122. package/dist/patterns/index.d.ts +2 -0
  123. package/dist/patterns/index.d.ts.map +1 -0
  124. package/dist/patterns/index.js +2 -0
  125. package/dist/patterns/index.js.map +1 -0
  126. package/dist/scheduler/index.d.ts +6 -0
  127. package/dist/scheduler/index.d.ts.map +1 -0
  128. package/dist/scheduler/index.js +9 -0
  129. package/dist/scheduler/index.js.map +1 -0
  130. package/dist/scheduler/tickScheduler.d.ts +27 -0
  131. package/dist/scheduler/tickScheduler.d.ts.map +1 -0
  132. package/dist/scheduler/tickScheduler.js +74 -0
  133. package/dist/scheduler/tickScheduler.js.map +1 -0
  134. package/dist/sequences/expand.d.ts +14 -0
  135. package/dist/sequences/expand.d.ts.map +1 -0
  136. package/dist/sequences/expand.js +137 -0
  137. package/dist/sequences/expand.js.map +1 -0
  138. package/dist/song/importResolver.browser.d.ts +29 -0
  139. package/dist/song/importResolver.browser.d.ts.map +1 -0
  140. package/dist/song/importResolver.browser.js +168 -0
  141. package/dist/song/importResolver.browser.js.map +1 -0
  142. package/dist/song/importResolver.d.ts +40 -0
  143. package/dist/song/importResolver.d.ts.map +1 -0
  144. package/dist/song/importResolver.js +445 -0
  145. package/dist/song/importResolver.js.map +1 -0
  146. package/dist/song/index.browser.d.ts +9 -0
  147. package/dist/song/index.browser.d.ts.map +1 -0
  148. package/dist/song/index.browser.js +7 -0
  149. package/dist/song/index.browser.js.map +1 -0
  150. package/dist/song/index.d.ts +8 -0
  151. package/dist/song/index.d.ts.map +1 -0
  152. package/dist/song/index.js +6 -0
  153. package/dist/song/index.js.map +1 -0
  154. package/dist/song/resolver.browser.d.ts +50 -0
  155. package/dist/song/resolver.browser.d.ts.map +1 -0
  156. package/dist/song/resolver.browser.js +536 -0
  157. package/dist/song/resolver.browser.js.map +1 -0
  158. package/dist/song/resolver.d.ts +20 -0
  159. package/dist/song/resolver.d.ts.map +1 -0
  160. package/dist/song/resolver.js +540 -0
  161. package/dist/song/resolver.js.map +1 -0
  162. package/dist/song/songModel.d.ts +34 -0
  163. package/dist/song/songModel.d.ts.map +1 -0
  164. package/dist/song/songModel.js +2 -0
  165. package/dist/song/songModel.js.map +1 -0
  166. package/dist/tests/refExpander.test.d.ts +2 -0
  167. package/dist/tests/refExpander.test.d.ts.map +1 -0
  168. package/dist/tests/refExpander.test.js +37 -0
  169. package/dist/tests/refExpander.test.js.map +1 -0
  170. package/dist/util/diag.d.ts +16 -0
  171. package/dist/util/diag.d.ts.map +1 -0
  172. package/dist/util/diag.js +29 -0
  173. package/dist/util/diag.js.map +1 -0
  174. package/package.json +84 -0
@@ -0,0 +1,445 @@
1
+ /**
2
+ * Import resolution for .ins files.
3
+ * Handles loading, caching, cycle detection, and merging of instrument definitions.
4
+ * Supports both local file imports and remote HTTP(S) imports.
5
+ */
6
+ import { parse } from '../parser/index.js';
7
+ import * as path from 'path';
8
+ import * as fs from 'fs';
9
+ import { isRemoteImport, isLocalImport, extractLocalPath } from '../import/urlUtils.js';
10
+ import { RemoteInstrumentCache } from '../import/remoteCache.js';
11
+ /**
12
+ * Validate an import path for security vulnerabilities.
13
+ * Rejects paths with:
14
+ * - Parent directory traversal (..) segments (for local paths)
15
+ * - Absolute paths (unless explicitly allowed, for local paths)
16
+ * - Missing local: prefix for file imports
17
+ * Remote URLs (http://, https://, github:) are allowed and validated separately.
18
+ * @throws Error if the path is invalid
19
+ */
20
+ function validateImportPath(importSource, allowAbsolutePaths = false) {
21
+ // Remote imports are handled separately
22
+ if (isRemoteImport(importSource)) {
23
+ return;
24
+ }
25
+ // Local imports must have local: prefix
26
+ if (!isLocalImport(importSource)) {
27
+ throw new Error(`Invalid import path "${importSource}": local file imports must use "local:" prefix. ` +
28
+ `Use "local:${importSource}" instead. Remote imports should use "https://" or "github:" prefix.`);
29
+ }
30
+ // Extract the actual path from local: prefix
31
+ const actualPath = extractLocalPath(importSource);
32
+ // Normalize path separators for consistent checking
33
+ const normalized = actualPath.replace(/\\/g, '/');
34
+ // Check for parent directory traversal (..) as a path segment
35
+ // This regex matches ".." when it's:
36
+ // - At the start followed by / or end: ^\.\.(/|$)
37
+ // - Preceded by / and followed by / or end: /\.\.(/|$)
38
+ // This allows filenames containing ".." like "file..txt" but blocks path traversal
39
+ if (/(^|\/)\.\.($|\/)/.test(normalized)) {
40
+ throw new Error(`Invalid import path "${importSource}": path traversal using ".." is not allowed for security reasons`);
41
+ }
42
+ // Check for absolute paths
43
+ if (!allowAbsolutePaths) {
44
+ // Check for Unix-style absolute paths
45
+ if (normalized.startsWith('/')) {
46
+ throw new Error(`Invalid import path "${importSource}": absolute paths are not allowed for security reasons`);
47
+ }
48
+ // Check for Windows-style absolute paths (C:, D:, etc.)
49
+ if (/^[a-zA-Z]:/.test(normalized)) {
50
+ throw new Error(`Invalid import path "${importSource}": absolute paths are not allowed for security reasons`);
51
+ }
52
+ }
53
+ }
54
+ /**
55
+ * Validate that a resolved path is within allowed directories.
56
+ * Ensures the resolved path is under the base directory or one of the search paths.
57
+ */
58
+ function validateResolvedPath(resolvedPath, allowedDirs, importSource, pathLib) {
59
+ if (allowedDirs.length === 0) {
60
+ return; // No restrictions if no allowed directories specified
61
+ }
62
+ const normalizedResolved = pathLib.normalize(resolvedPath);
63
+ for (const allowedDir of allowedDirs) {
64
+ const normalizedAllowed = pathLib.normalize(allowedDir);
65
+ const relative = pathLib.relative(normalizedAllowed, normalizedResolved);
66
+ // If relative path doesn't start with .., it's within the allowed directory
67
+ if (!relative.startsWith('..') && !pathLib.isAbsolute(relative)) {
68
+ return; // Valid - within allowed directory
69
+ }
70
+ }
71
+ throw new Error(`Security violation: import path "${importSource}" resolves to "${resolvedPath}" ` +
72
+ `which is outside the allowed directories`);
73
+ }
74
+ /**
75
+ * Resolve a relative import path to an absolute path.
76
+ */
77
+ function resolveImportPath(importSource, baseFilePath, searchPaths = [], options = {}) {
78
+ const fileExists = options.fileExists;
79
+ // Validate import path for security vulnerabilities
80
+ validateImportPath(importSource, options.allowAbsolutePaths || false);
81
+ // Extract the actual file path from local: prefix
82
+ const actualPath = extractLocalPath(importSource);
83
+ const checkExists = fileExists || ((p) => {
84
+ try {
85
+ return fs.existsSync(p);
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ });
91
+ // Use posix paths when a custom fileExists is provided (testing mode)
92
+ const pathLib = fileExists ? path.posix : path;
93
+ // Build list of allowed directories for validation
94
+ const allowedDirs = [];
95
+ if (baseFilePath) {
96
+ const baseDir = pathLib.dirname(baseFilePath);
97
+ // Normalize to absolute path for proper validation
98
+ const absoluteBaseDir = pathLib.isAbsolute(baseDir) ? baseDir : pathLib.resolve(baseDir);
99
+ allowedDirs.push(absoluteBaseDir);
100
+ }
101
+ // Also normalize search paths to absolute
102
+ for (const searchPath of searchPaths) {
103
+ const absoluteSearchPath = pathLib.isAbsolute(searchPath) ? searchPath : pathLib.resolve(searchPath);
104
+ allowedDirs.push(absoluteSearchPath);
105
+ }
106
+ // If we have a base file path, try resolving relative to it first
107
+ if (baseFilePath) {
108
+ const baseDir = pathLib.dirname(baseFilePath);
109
+ const resolved = pathLib.resolve(baseDir, actualPath);
110
+ // Validate that resolved path is within allowed directories
111
+ validateResolvedPath(resolved, allowedDirs, importSource, pathLib);
112
+ if (checkExists(resolved)) {
113
+ return resolved;
114
+ }
115
+ }
116
+ // Try search paths
117
+ for (const searchPath of searchPaths) {
118
+ const resolved = pathLib.resolve(searchPath, actualPath);
119
+ // Validate that resolved path is within allowed directories
120
+ validateResolvedPath(resolved, allowedDirs, importSource, pathLib);
121
+ if (checkExists(resolved)) {
122
+ return resolved;
123
+ }
124
+ }
125
+ return null;
126
+ }
127
+ /**
128
+ * Validate that an AST contains only allowed node types for .ins files.
129
+ */
130
+ function validateInsFile(ast, filePath) {
131
+ // .ins files should only contain instrument definitions and imports
132
+ // Check for disallowed nodes
133
+ const disallowed = [];
134
+ // Playback/structure directives
135
+ if (Object.keys(ast.pats || {}).length > 0)
136
+ disallowed.push('patterns');
137
+ if (Object.keys(ast.seqs || {}).length > 0)
138
+ disallowed.push('sequences');
139
+ if ((ast.channels || []).length > 0)
140
+ disallowed.push('channels');
141
+ if (ast.arranges && Object.keys(ast.arranges).length > 0)
142
+ disallowed.push('arranges');
143
+ if (ast.play !== undefined)
144
+ disallowed.push('play');
145
+ // Top-level scalar directives (should not be in .ins files)
146
+ if (ast.chip !== undefined)
147
+ disallowed.push('chip');
148
+ if (ast.bpm !== undefined)
149
+ disallowed.push('bpm');
150
+ if (ast.volume !== undefined)
151
+ disallowed.push('volume');
152
+ // Metadata
153
+ if (ast.metadata !== undefined && Object.keys(ast.metadata).length > 0) {
154
+ disallowed.push('metadata');
155
+ }
156
+ // Effect definitions
157
+ if (ast.effects && Object.keys(ast.effects).length > 0)
158
+ disallowed.push('effects');
159
+ // Pattern events and structured patterns
160
+ if (ast.patternEvents && Object.keys(ast.patternEvents).length > 0) {
161
+ disallowed.push('patternEvents');
162
+ }
163
+ if (ast.sequenceItems && Object.keys(ast.sequenceItems).length > 0) {
164
+ disallowed.push('sequenceItems');
165
+ }
166
+ // Check for any other non-standard properties that might be added
167
+ const allowedKeys = new Set([
168
+ 'insts', 'imports', 'pats', 'seqs', 'channels', 'arranges', 'play',
169
+ 'chip', 'bpm', 'volume', 'metadata', 'effects', 'patternEvents', 'sequenceItems'
170
+ ]);
171
+ for (const key of Object.keys(ast)) {
172
+ if (!allowedKeys.has(key) && key !== 'insts' && key !== 'imports') {
173
+ disallowed.push(`unknown property '${key}'`);
174
+ }
175
+ }
176
+ if (disallowed.length > 0) {
177
+ throw new Error(`Invalid .ins file "${filePath}": .ins files may only contain "inst" and "import" declarations. ` +
178
+ `Found: ${disallowed.join(', ')}`);
179
+ }
180
+ }
181
+ /**
182
+ * Load and parse an import file (local or remote).
183
+ */
184
+ async function loadImportFile(importSource, ctx) {
185
+ // Handle remote imports
186
+ if (isRemoteImport(importSource)) {
187
+ return await loadRemoteImportFile(importSource, ctx);
188
+ }
189
+ // Check if this is a local import in browser context
190
+ if (isLocalImport(importSource) && typeof window !== 'undefined') {
191
+ throw new Error(`Local imports are not supported in the browser for security reasons. ` +
192
+ `Import "${importSource}" cannot be loaded. ` +
193
+ `Use remote imports (https:// or github:) instead, or run in CLI for local file access.`);
194
+ }
195
+ // Resolve local file path
196
+ const absolutePath = resolveImportPath(importSource, ctx.options.baseFilePath, ctx.options.searchPaths || [], ctx.options);
197
+ if (!absolutePath) {
198
+ throw new Error(`Import file not found: "${importSource}"` +
199
+ (ctx.options.baseFilePath ? ` (imported from "${ctx.options.baseFilePath}")` : ''));
200
+ }
201
+ // Check cache first
202
+ if (ctx.cache[absolutePath]) {
203
+ return ctx.cache[absolutePath];
204
+ }
205
+ // Check for import cycles
206
+ if (ctx.importStack.includes(absolutePath)) {
207
+ const cycle = [...ctx.importStack, absolutePath].join(' -> ');
208
+ throw new Error(`Import cycle detected: ${cycle}`);
209
+ }
210
+ // Read file
211
+ let source;
212
+ try {
213
+ if (ctx.options.readFile) {
214
+ source = ctx.options.readFile(absolutePath);
215
+ }
216
+ else {
217
+ source = fs.readFileSync(absolutePath, 'utf-8');
218
+ }
219
+ }
220
+ catch (err) {
221
+ throw new Error(`Failed to read import file "${absolutePath}": ${err}`);
222
+ }
223
+ // Parse file
224
+ let ast;
225
+ try {
226
+ ast = parse(source);
227
+ }
228
+ catch (err) {
229
+ throw new Error(`Failed to parse import file "${absolutePath}": ${err}`);
230
+ }
231
+ // Validate that this is a valid .ins file
232
+ validateInsFile(ast, absolutePath);
233
+ // Add to import stack for cycle detection
234
+ ctx.importStack.push(absolutePath);
235
+ // Recursively process imports in this file
236
+ // Create a new context with updated baseFilePath so nested imports resolve relative to this .ins file
237
+ const nestedCtx = {
238
+ ...ctx,
239
+ options: { ...ctx.options, baseFilePath: absolutePath }
240
+ };
241
+ const mergedInsts = await processImports(ast, absolutePath, nestedCtx);
242
+ // Merge this file's instruments (they override imported ones - last-win)
243
+ const finalInsts = mergeInstruments(mergedInsts, ast.insts || {}, absolutePath, ctx);
244
+ // Remove from import stack
245
+ ctx.importStack.pop();
246
+ // Cache the result
247
+ ctx.cache[absolutePath] = finalInsts;
248
+ return finalInsts;
249
+ }
250
+ /**
251
+ * Load and parse a remote import file.
252
+ */
253
+ async function loadRemoteImportFile(url, ctx) {
254
+ // Check for import cycles (use URL as identifier)
255
+ if (ctx.importStack.includes(url)) {
256
+ const cycle = [...ctx.importStack, url].join(' -> ');
257
+ throw new Error(`Import cycle detected: ${cycle}`);
258
+ }
259
+ // Get or create remote cache
260
+ if (!ctx.remoteCache) {
261
+ ctx.remoteCache = new RemoteInstrumentCache(ctx.options.remoteOptions);
262
+ }
263
+ // Add to import stack
264
+ ctx.importStack.push(url);
265
+ try {
266
+ // Fetch from remote cache (handles caching internally)
267
+ const instruments = await ctx.remoteCache.fetch(url);
268
+ // Note: Remote .ins files cannot have nested imports for security reasons
269
+ // The RemoteInstrumentCache already validates that the file only contains instruments
270
+ return instruments;
271
+ }
272
+ finally {
273
+ // Remove from import stack
274
+ ctx.importStack.pop();
275
+ }
276
+ }
277
+ /**
278
+ * Merge instrument maps with last-win semantics.
279
+ */
280
+ function mergeInstruments(base, override, sourcePath, ctx) {
281
+ const result = { ...base };
282
+ for (const [name, inst] of Object.entries(override)) {
283
+ if (result[name] !== undefined) {
284
+ const message = `Instrument "${name}" from "${sourcePath}" overrides previously defined instrument`;
285
+ if (ctx.options.strictMode) {
286
+ throw new Error(message);
287
+ }
288
+ else if (ctx.options.onWarn) {
289
+ ctx.options.onWarn(message);
290
+ }
291
+ }
292
+ result[name] = inst;
293
+ }
294
+ return result;
295
+ }
296
+ /**
297
+ * Process all imports in an AST and return merged instruments.
298
+ */
299
+ async function processImports(ast, baseFilePath, ctx) {
300
+ let mergedInsts = {};
301
+ if (!ast.imports || ast.imports.length === 0) {
302
+ return mergedInsts;
303
+ }
304
+ for (const imp of ast.imports) {
305
+ const importedInsts = await loadImportFile(imp.source, ctx);
306
+ // Merge imported instruments (later imports override earlier ones)
307
+ mergedInsts = mergeInstruments(mergedInsts, importedInsts, imp.source, ctx);
308
+ }
309
+ return mergedInsts;
310
+ }
311
+ /**
312
+ * Resolve all imports in an AST and merge them into the instrument table.
313
+ * Returns a new AST with merged instruments.
314
+ * Supports both local file imports and remote HTTP(S) imports.
315
+ */
316
+ export async function resolveImports(ast, options = {}) {
317
+ const ctx = {
318
+ importStack: [],
319
+ cache: {},
320
+ options,
321
+ remoteCache: options.remoteCache,
322
+ };
323
+ // Process imports
324
+ const importedInsts = await processImports(ast, options.baseFilePath, ctx);
325
+ // Merge imported instruments with local instruments (local overrides imported)
326
+ const finalInsts = mergeInstruments(importedInsts, ast.insts || {}, options.baseFilePath || '<main>', ctx);
327
+ // Return new AST with merged instruments and cleared imports
328
+ // (imports are already resolved, so we don't want to resolve them again)
329
+ return {
330
+ ...ast,
331
+ insts: finalInsts,
332
+ imports: [], // Clear imports to prevent double-resolution
333
+ };
334
+ }
335
+ /**
336
+ * Synchronous wrapper for resolveImports for backward compatibility.
337
+ * Does not support remote imports - throws an error if remote imports are encountered.
338
+ * @deprecated Use resolveImports (async) instead
339
+ */
340
+ export function resolveImportsSync(ast, options = {}) {
341
+ // Check if AST contains remote imports
342
+ if (ast.imports && ast.imports.some(imp => isRemoteImport(imp.source))) {
343
+ throw new Error('Remote imports require async resolution. Use resolveImports() instead of resolveImportsSync().');
344
+ }
345
+ // Use a synchronous implementation for local imports only
346
+ const ctx = {
347
+ importStack: [],
348
+ cache: {},
349
+ options,
350
+ };
351
+ // Process imports synchronously
352
+ const importedInsts = processImportsSync(ast, options.baseFilePath, ctx);
353
+ // Merge imported instruments with local instruments
354
+ const finalInsts = mergeInstruments(importedInsts, ast.insts || {}, options.baseFilePath || '<main>', ctx);
355
+ return {
356
+ ...ast,
357
+ insts: finalInsts,
358
+ };
359
+ }
360
+ /**
361
+ * Synchronous version of processImports (local files only).
362
+ */
363
+ function processImportsSync(ast, baseFilePath, ctx) {
364
+ let mergedInsts = {};
365
+ if (!ast.imports || ast.imports.length === 0) {
366
+ return mergedInsts;
367
+ }
368
+ for (const imp of ast.imports) {
369
+ if (isRemoteImport(imp.source)) {
370
+ throw new Error(`Remote import "${imp.source}" requires async resolution. Use resolveImports() instead.`);
371
+ }
372
+ const importedInsts = loadImportFileSync(imp.source, ctx);
373
+ mergedInsts = mergeInstruments(mergedInsts, importedInsts, imp.source, ctx);
374
+ }
375
+ return mergedInsts;
376
+ }
377
+ /**
378
+ * Synchronous version of loadImportFile (local files only).
379
+ */
380
+ function loadImportFileSync(importSource, ctx) {
381
+ if (isRemoteImport(importSource)) {
382
+ throw new Error(`Remote import "${importSource}" requires async resolution.`);
383
+ }
384
+ // Check if this is a local import in browser context
385
+ if (isLocalImport(importSource) && typeof window !== 'undefined') {
386
+ throw new Error(`Local imports are not supported in the browser for security reasons. ` +
387
+ `Import "${importSource}" cannot be loaded. ` +
388
+ `Use remote imports (https:// or github:) instead, or run in CLI for local file access.`);
389
+ }
390
+ // Resolve local file path
391
+ const absolutePath = resolveImportPath(importSource, ctx.options.baseFilePath, ctx.options.searchPaths || [], ctx.options);
392
+ if (!absolutePath) {
393
+ throw new Error(`Import file not found: "${importSource}"` +
394
+ (ctx.options.baseFilePath ? ` (imported from "${ctx.options.baseFilePath}")` : ''));
395
+ }
396
+ // Check cache first
397
+ if (ctx.cache[absolutePath]) {
398
+ return ctx.cache[absolutePath];
399
+ }
400
+ // Check for import cycles
401
+ if (ctx.importStack.includes(absolutePath)) {
402
+ const cycle = [...ctx.importStack, absolutePath].join(' -> ');
403
+ throw new Error(`Import cycle detected: ${cycle}`);
404
+ }
405
+ // Read file
406
+ let source;
407
+ try {
408
+ if (ctx.options.readFile) {
409
+ source = ctx.options.readFile(absolutePath);
410
+ }
411
+ else {
412
+ source = fs.readFileSync(absolutePath, 'utf-8');
413
+ }
414
+ }
415
+ catch (err) {
416
+ throw new Error(`Failed to read import file "${absolutePath}": ${err}`);
417
+ }
418
+ // Parse file
419
+ let ast;
420
+ try {
421
+ ast = parse(source);
422
+ }
423
+ catch (err) {
424
+ throw new Error(`Failed to parse import file "${absolutePath}": ${err}`);
425
+ }
426
+ // Validate that this is a valid .ins file
427
+ validateInsFile(ast, absolutePath);
428
+ // Add to import stack for cycle detection
429
+ ctx.importStack.push(absolutePath);
430
+ // Recursively process imports in this file
431
+ // Create a new context with updated baseFilePath so nested imports resolve relative to this .ins file
432
+ const nestedCtx = {
433
+ ...ctx,
434
+ options: { ...ctx.options, baseFilePath: absolutePath }
435
+ };
436
+ const mergedInsts = processImportsSync(ast, absolutePath, nestedCtx);
437
+ // Merge this file's instruments (they override imported ones - last-win)
438
+ const finalInsts = mergeInstruments(mergedInsts, ast.insts || {}, absolutePath, ctx);
439
+ // Remove from import stack
440
+ ctx.importStack.pop();
441
+ // Cache the result
442
+ ctx.cache[absolutePath] = finalInsts;
443
+ return finalInsts;
444
+ }
445
+ //# sourceMappingURL=importResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importResolver.js","sourceRoot":"","sources":["../../src/song/importResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Song module exports (Browser version)
3
+ * Uses browser-safe import resolver that doesn't depend on Node.js built-ins
4
+ */
5
+ export { resolveSong, resolveSongAsync, isPanEmpty, parseEffectParams, parseEffectsInline } from './resolver.browser.js';
6
+ export { resolveImports, resolveImportsSync } from './importResolver.browser.js';
7
+ export type { ImportResolverOptions } from './importResolver.browser.js';
8
+ export type { SongModel, ChannelModel, ChannelEvent } from './songModel.js';
9
+ //# sourceMappingURL=index.browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../src/song/index.browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACzH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjF,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Song module exports (Browser version)
3
+ * Uses browser-safe import resolver that doesn't depend on Node.js built-ins
4
+ */
5
+ export { resolveSong, resolveSongAsync, isPanEmpty, parseEffectParams, parseEffectsInline } from './resolver.browser.js';
6
+ export { resolveImports, resolveImportsSync } from './importResolver.browser.js';
7
+ //# sourceMappingURL=index.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../src/song/index.browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACzH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Song module exports
3
+ */
4
+ export { resolveSong, resolveSongAsync, isPanEmpty, parseEffectParams, parseEffectsInline } from './resolver.js';
5
+ export { resolveImports, resolveImportsSync } from './importResolver.js';
6
+ export type { ImportResolverOptions } from './importResolver.js';
7
+ export type { SongModel, ChannelModel, ChannelEvent } from './songModel.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/song/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzE,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Song module exports
3
+ */
4
+ export { resolveSong, resolveSongAsync, isPanEmpty, parseEffectParams, parseEffectsInline } from './resolver.js';
5
+ export { resolveImports, resolveImportsSync } from './importResolver.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/song/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { AST } from '../parser/ast.js';
2
+ import { SongModel } from './songModel.js';
3
+ export declare function isPanEmpty(pan: any): boolean;
4
+ export declare function parseEffectParams(paramsStr: string | undefined): Array<string | number>;
5
+ export declare function parseEffectsInline(str: string): {
6
+ effects: {
7
+ type: string;
8
+ params: Array<string | number>;
9
+ paramsStr?: string;
10
+ }[];
11
+ pan: any;
12
+ };
13
+ /**
14
+ * Resolve an AST into a SongModel (ISM), expanding sequences and resolving
15
+ * instrument overrides according to the language expansion pipeline.
16
+ *
17
+ * Note: This function does not support remote imports in the browser.
18
+ * Use resolveSongAsync() instead for remote imports.
19
+ */
20
+ export declare function resolveSong(ast: AST, opts?: {
21
+ filename?: string;
22
+ searchPaths?: string[];
23
+ strictInstruments?: boolean;
24
+ onWarn?: (d: {
25
+ component: string;
26
+ message: string;
27
+ file?: string;
28
+ loc?: any;
29
+ }) => void;
30
+ }): SongModel;
31
+ /**
32
+ * Async version of resolveSong that supports remote imports.
33
+ * Use this when your AST may contain remote imports (http://, https://, github:).
34
+ */
35
+ export declare function resolveSongAsync(ast: AST, opts?: {
36
+ filename?: string;
37
+ searchPaths?: string[];
38
+ strictInstruments?: boolean;
39
+ onWarn?: (d: {
40
+ component: string;
41
+ message: string;
42
+ file?: string;
43
+ loc?: any;
44
+ }) => void;
45
+ }): Promise<SongModel>;
46
+ declare const _default: {
47
+ resolveSong: typeof resolveSong;
48
+ };
49
+ export default _default;
50
+ //# sourceMappingURL=resolver.browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.browser.d.ts","sourceRoot":"","sources":["../../src/song/resolver.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAgB,MAAM,kBAAkB,CAAC;AAIrD,OAAO,EAAE,SAAS,EAAoD,MAAM,gBAAgB,CAAC;AA4B7F,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAS5C;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAOvF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM;;cAGf,MAAM;gBAAU,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;oBAAc,MAAM;;;EAkDxF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAA;CAAE,GAAG,SAAS,CAsB1N;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAc9O;;;;AAgZD,wBAA+B"}