@devaloop/devalang 0.0.1-alpha.9 → 0.0.1-beta.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 (322) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +6 -1
  3. package/.github/workflows/ci.yml +103 -0
  4. package/Cargo.toml +81 -48
  5. package/README.md +137 -154
  6. package/docs/CHANGELOG.md +428 -1
  7. package/docs/CONTRIBUTING.md +101 -0
  8. package/docs/ROADMAP.md +14 -7
  9. package/docs/TODO.md +16 -15
  10. package/examples/automation.deva +42 -0
  11. package/examples/bank.deva +7 -0
  12. package/examples/bus.deva +10 -0
  13. package/examples/duration.deva +9 -0
  14. package/examples/effect.deva +2 -0
  15. package/examples/events.deva +12 -0
  16. package/examples/filter.deva +11 -0
  17. package/examples/function.deva +15 -0
  18. package/examples/index.deva +57 -12
  19. package/examples/lfo.deva +9 -0
  20. package/examples/loop.deva +5 -12
  21. package/examples/pattern.deva +8 -0
  22. package/examples/plugin.deva +16 -0
  23. package/examples/synth.deva +11 -1
  24. package/examples/synth_types.deva +17 -0
  25. package/examples/variables.deva +1 -1
  26. package/out-tsc/bin/index.d.ts +2 -0
  27. package/out-tsc/bin/index.js +51 -7
  28. package/out-tsc/core/functions/index.d.ts +42 -0
  29. package/out-tsc/core/functions/index.js +87 -0
  30. package/out-tsc/core/index.d.ts +6 -0
  31. package/out-tsc/core/index.js +22 -0
  32. package/out-tsc/core/types/index.d.ts +4 -0
  33. package/out-tsc/core/types/index.js +20 -0
  34. package/out-tsc/core/types/plugin.d.ts +18 -0
  35. package/out-tsc/core/types/plugin.js +2 -0
  36. package/out-tsc/core/types/result.d.ts +27 -0
  37. package/out-tsc/core/types/result.js +2 -0
  38. package/out-tsc/core/types/statement.d.ts +106 -0
  39. package/out-tsc/core/types/statement.js +2 -0
  40. package/out-tsc/core/types/value.d.ts +43 -0
  41. package/out-tsc/core/types/value.js +2 -0
  42. package/out-tsc/index.d.ts +7 -0
  43. package/out-tsc/index.js +42 -1
  44. package/out-tsc/pkg/devalang_core.d.ts +15 -0
  45. package/out-tsc/pkg/devalang_core.js +65 -0
  46. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +34 -0
  47. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  48. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  49. package/out-tsc/scripts/postinstall.d.ts +1 -0
  50. package/out-tsc/scripts/postinstall.js +83 -0
  51. package/out-tsc/scripts/version/bump.d.ts +1 -0
  52. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  53. package/out-tsc/scripts/version/index.d.ts +1 -0
  54. package/out-tsc/scripts/version/sync.d.ts +1 -0
  55. package/package.json +28 -7
  56. package/project-version.json +4 -4
  57. package/rust/cli/bank/api.rs +122 -0
  58. package/rust/cli/bank/commands.rs +306 -0
  59. package/rust/cli/bank/mod.rs +29 -0
  60. package/rust/cli/build/commands.rs +153 -0
  61. package/rust/cli/build/mod.rs +2 -0
  62. package/rust/cli/build/process.rs +165 -0
  63. package/rust/cli/check/mod.rs +208 -0
  64. package/rust/cli/discover/commands.rs +253 -0
  65. package/rust/cli/discover/config.rs +111 -0
  66. package/rust/cli/discover/fs.rs +19 -0
  67. package/rust/cli/discover/install.rs +103 -0
  68. package/rust/cli/discover/metadata.rs +48 -0
  69. package/rust/cli/discover/mod.rs +5 -0
  70. package/rust/cli/{init.rs → init/commands.rs} +32 -23
  71. package/rust/cli/init/mod.rs +1 -0
  72. package/rust/cli/install/addon.rs +118 -0
  73. package/rust/cli/install/bank.rs +72 -0
  74. package/rust/cli/install/commands.rs +35 -0
  75. package/rust/cli/install/mod.rs +4 -0
  76. package/rust/cli/install/plugin.rs +80 -0
  77. package/rust/cli/login/commands.rs +124 -0
  78. package/rust/cli/login/mod.rs +1 -0
  79. package/rust/cli/mod.rs +9 -202
  80. package/rust/cli/parser.rs +359 -0
  81. package/rust/cli/play/commands.rs +375 -0
  82. package/rust/cli/play/io.rs +17 -0
  83. package/rust/cli/play/mod.rs +5 -0
  84. package/rust/cli/play/process.rs +159 -0
  85. package/rust/cli/play/realtime.rs +91 -0
  86. package/rust/cli/play/utils.rs +23 -0
  87. package/rust/cli/telemetry/commands.rs +22 -0
  88. package/rust/cli/telemetry/event_creator.rs +80 -0
  89. package/rust/cli/telemetry/mod.rs +3 -0
  90. package/rust/cli/telemetry/send.rs +51 -0
  91. package/rust/cli/{template.rs → template/commands.rs} +17 -5
  92. package/rust/cli/template/mod.rs +1 -0
  93. package/rust/cli/update/commands.rs +6 -0
  94. package/rust/cli/update/mod.rs +1 -0
  95. package/rust/config/driver.rs +112 -0
  96. package/rust/config/mod.rs +3 -16
  97. package/rust/config/ops.rs +26 -0
  98. package/rust/config/settings.rs +101 -0
  99. package/rust/core/audio/engine/driver.rs +220 -0
  100. package/rust/core/audio/engine/export.rs +169 -0
  101. package/rust/core/audio/engine/helpers.rs +178 -0
  102. package/rust/core/audio/engine/mod.rs +56 -0
  103. package/rust/core/audio/engine/notes/dsp.rs +85 -0
  104. package/rust/core/audio/engine/notes/mod.rs +44 -0
  105. package/rust/core/audio/engine/notes/params.rs +294 -0
  106. package/rust/core/audio/engine/sample/insert.rs +199 -0
  107. package/rust/core/audio/engine/sample/mod.rs +40 -0
  108. package/rust/core/audio/engine/sample/padding.rs +170 -0
  109. package/rust/core/audio/evaluator/condition.rs +61 -0
  110. package/rust/core/audio/evaluator/mod.rs +9 -0
  111. package/rust/core/audio/evaluator/numeric.rs +152 -0
  112. package/rust/core/audio/evaluator/rhs.rs +16 -0
  113. package/rust/core/audio/evaluator/string_expr.rs +94 -0
  114. package/rust/core/audio/interpreter/driver.rs +574 -216
  115. package/rust/core/audio/interpreter/mod.rs +2 -12
  116. package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +175 -0
  117. package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +384 -0
  118. package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +2 -0
  119. package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +316 -0
  120. package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +3 -0
  121. package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +192 -0
  122. package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +24 -0
  123. package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +116 -0
  124. package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +97 -0
  125. package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +100 -0
  126. package/rust/core/audio/interpreter/statements/automate.rs +16 -0
  127. package/rust/core/audio/interpreter/statements/call.rs +295 -0
  128. package/rust/core/audio/interpreter/{condition.rs → statements/condition.rs} +72 -69
  129. package/rust/core/audio/interpreter/statements/function.rs +24 -0
  130. package/rust/core/audio/interpreter/statements/let_.rs +36 -0
  131. package/rust/core/audio/interpreter/statements/load.rs +17 -0
  132. package/rust/core/audio/interpreter/statements/loop_.rs +115 -0
  133. package/rust/core/audio/interpreter/statements/mod.rs +12 -0
  134. package/rust/core/audio/interpreter/statements/sleep.rs +28 -0
  135. package/rust/core/audio/interpreter/statements/spawn.rs +253 -0
  136. package/rust/core/audio/interpreter/statements/tempo.rs +40 -0
  137. package/rust/core/audio/interpreter/statements/trigger.rs +239 -0
  138. package/rust/core/audio/loader/mod.rs +1 -1
  139. package/rust/core/audio/loader/trigger.rs +98 -52
  140. package/rust/core/audio/mod.rs +2 -2
  141. package/rust/core/audio/player.rs +28 -12
  142. package/rust/core/audio/special/easing.rs +189 -0
  143. package/rust/core/audio/special/env.rs +45 -0
  144. package/rust/core/audio/special/math.rs +134 -0
  145. package/rust/core/audio/special/mod.rs +9 -0
  146. package/rust/core/audio/special/modulator.rs +143 -0
  147. package/rust/core/builder/mod.rs +129 -80
  148. package/rust/core/debugger/lexer.rs +4 -4
  149. package/rust/core/debugger/logs.rs +52 -0
  150. package/rust/core/debugger/mod.rs +11 -2
  151. package/rust/core/debugger/preprocessor.rs +4 -4
  152. package/rust/core/debugger/store.rs +38 -25
  153. package/rust/core/error/mod.rs +221 -12
  154. package/rust/core/lexer/driver.rs +59 -0
  155. package/rust/core/lexer/handler/arrow.rs +62 -11
  156. package/rust/core/lexer/handler/at.rs +5 -5
  157. package/rust/core/lexer/handler/brace.rs +11 -11
  158. package/rust/core/lexer/handler/colon.rs +5 -5
  159. package/rust/core/lexer/handler/comment.rs +3 -3
  160. package/rust/core/lexer/handler/dot.rs +6 -6
  161. package/rust/core/lexer/handler/driver.rs +143 -32
  162. package/rust/core/lexer/handler/identifier.rs +11 -5
  163. package/rust/core/lexer/handler/indent.rs +18 -4
  164. package/rust/core/lexer/handler/mod.rs +6 -5
  165. package/rust/core/lexer/handler/newline.rs +3 -3
  166. package/rust/core/lexer/handler/number.rs +5 -5
  167. package/rust/core/lexer/handler/operator.rs +5 -3
  168. package/rust/core/lexer/handler/parenthesis.rs +41 -0
  169. package/rust/core/lexer/handler/slash.rs +21 -0
  170. package/rust/core/lexer/handler/string.rs +3 -3
  171. package/rust/core/lexer/mod.rs +1 -49
  172. package/rust/core/lexer/token.rs +17 -12
  173. package/rust/core/mod.rs +9 -10
  174. package/rust/core/parser/driver/block.rs +111 -0
  175. package/rust/core/parser/driver/cursor.rs +82 -0
  176. package/rust/core/parser/driver/driver_impl.rs +139 -0
  177. package/rust/core/parser/driver/mod.rs +6 -0
  178. package/rust/core/parser/driver/parse_array.rs +120 -0
  179. package/rust/core/parser/driver/parse_map.rs +223 -0
  180. package/rust/core/parser/driver/parser.rs +160 -0
  181. package/rust/core/parser/handler/arrow_call.rs +277 -126
  182. package/rust/core/parser/handler/at.rs +142 -25
  183. package/rust/core/parser/handler/bank.rs +83 -20
  184. package/rust/core/parser/handler/condition.rs +14 -5
  185. package/rust/core/parser/handler/dot.rs +111 -75
  186. package/rust/core/parser/handler/identifier/automate.rs +254 -0
  187. package/rust/core/parser/handler/identifier/call.rs +74 -24
  188. package/rust/core/parser/handler/identifier/emit.rs +70 -0
  189. package/rust/core/parser/handler/identifier/function.rs +113 -0
  190. package/rust/core/parser/handler/identifier/group.rs +28 -14
  191. package/rust/core/parser/handler/identifier/let_.rs +61 -21
  192. package/rust/core/parser/handler/identifier/mod.rs +24 -20
  193. package/rust/core/parser/handler/identifier/on.rs +107 -0
  194. package/rust/core/parser/handler/identifier/print.rs +49 -0
  195. package/rust/core/parser/handler/identifier/sleep.rs +77 -14
  196. package/rust/core/parser/handler/identifier/spawn.rs +81 -31
  197. package/rust/core/parser/handler/identifier/synth.rs +102 -32
  198. package/rust/core/parser/handler/loop_.rs +144 -22
  199. package/rust/core/parser/handler/mod.rs +6 -5
  200. package/rust/core/parser/handler/pattern.rs +74 -0
  201. package/rust/core/parser/handler/tempo.rs +67 -9
  202. package/rust/core/parser/mod.rs +3 -4
  203. package/rust/core/parser/statement.rs +6 -92
  204. package/rust/core/plugin/loader.rs +137 -0
  205. package/rust/core/plugin/mod.rs +2 -0
  206. package/rust/core/plugin/runner/mod.rs +11 -0
  207. package/rust/core/plugin/runner/non_wasm.rs +297 -0
  208. package/rust/core/plugin/runner/wasm32.rs +43 -0
  209. package/rust/core/preprocessor/loader/inject.rs +278 -0
  210. package/rust/core/preprocessor/loader/loader_helpers.rs +110 -0
  211. package/rust/core/preprocessor/loader/mod.rs +235 -0
  212. package/rust/core/preprocessor/mod.rs +4 -4
  213. package/rust/core/preprocessor/module.rs +55 -50
  214. package/rust/core/preprocessor/processor/handlers.rs +107 -0
  215. package/rust/core/preprocessor/processor/mod.rs +1 -0
  216. package/rust/core/preprocessor/resolver/bank.rs +14 -12
  217. package/rust/core/preprocessor/resolver/call.rs +106 -105
  218. package/rust/core/preprocessor/resolver/condition.rs +13 -10
  219. package/rust/core/preprocessor/resolver/driver.rs +145 -48
  220. package/rust/core/preprocessor/resolver/function.rs +69 -0
  221. package/rust/core/preprocessor/resolver/group.rs +122 -61
  222. package/rust/core/preprocessor/resolver/let_.rs +13 -12
  223. package/rust/core/preprocessor/resolver/loop_.rs +240 -13
  224. package/rust/core/preprocessor/resolver/mod.rs +8 -6
  225. package/rust/core/preprocessor/resolver/pattern.rs +83 -0
  226. package/rust/core/preprocessor/resolver/spawn.rs +83 -42
  227. package/rust/core/preprocessor/resolver/synth.rs +15 -11
  228. package/rust/core/preprocessor/resolver/tempo.rs +13 -14
  229. package/rust/core/preprocessor/resolver/trigger.rs +32 -28
  230. package/rust/core/preprocessor/resolver/value.rs +111 -13
  231. package/rust/core/store/global.rs +57 -39
  232. package/rust/core/store/mod.rs +0 -3
  233. package/rust/lib.rs +323 -117
  234. package/rust/main.rs +388 -65
  235. package/rust/types/Cargo.toml +11 -0
  236. package/rust/types/src/addons.rs +55 -0
  237. package/rust/types/src/ast.rs +202 -0
  238. package/rust/types/src/config.rs +84 -0
  239. package/rust/types/src/lib.rs +15 -0
  240. package/rust/types/src/plugin.rs +20 -0
  241. package/rust/types/src/store.rs +139 -0
  242. package/rust/types/src/telemetry.rs +85 -0
  243. package/rust/utils/Cargo.toml +26 -0
  244. package/rust/utils/src/error.rs +186 -0
  245. package/rust/utils/src/file.rs +94 -0
  246. package/rust/utils/src/first_usage.rs +97 -0
  247. package/rust/utils/{mod.rs → src/lib.rs} +6 -3
  248. package/rust/utils/{logger.rs → src/logger.rs} +94 -17
  249. package/rust/utils/src/path.rs +129 -0
  250. package/rust/utils/src/signature.rs +41 -0
  251. package/rust/utils/{spinner.rs → src/spinner.rs} +7 -8
  252. package/rust/utils/src/version.rs +27 -0
  253. package/rust/utils/{watcher.rs → src/watcher.rs} +17 -4
  254. package/rust/web/api.rs +5 -0
  255. package/rust/web/cdn.rs +34 -0
  256. package/rust/web/mod.rs +3 -0
  257. package/rust/web/sso.rs +5 -0
  258. package/templates/minimal/README.md +143 -127
  259. package/templates/welcome/README.md +143 -127
  260. package/templates/welcome/src/index.deva +56 -8
  261. package/templates/welcome/src/variables.deva +2 -4
  262. package/tests/integration.rs +21 -0
  263. package/tests/rust/cli_check_build.rs +21 -0
  264. package/tests/rust/cli_help.rs +12 -0
  265. package/tests/rust/cli_template_list.rs +10 -0
  266. package/tests/rust/cli_version.rs +11 -0
  267. package/tests/typescript/index.spec.ts +136 -0
  268. package/tests/typescript/playhead.spec.ts +36 -0
  269. package/tests/typescript/render_e2e.spec.ts +77 -0
  270. package/tsconfig.json +12 -10
  271. package/typescript/bin/index.ts +19 -5
  272. package/typescript/core/functions/index.ts +94 -0
  273. package/typescript/core/index.ts +6 -0
  274. package/typescript/core/types/index.ts +4 -0
  275. package/typescript/core/types/plugin.ts +19 -0
  276. package/typescript/core/types/result.ts +29 -0
  277. package/typescript/core/types/statement.ts +47 -0
  278. package/typescript/core/types/value.ts +29 -0
  279. package/typescript/index.ts +8 -1
  280. package/typescript/pkg/devalang_core.d.ts +4 -0
  281. package/typescript/pkg/devalang_core.ts +65 -0
  282. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  283. package/typescript/scripts/postinstall.ts +85 -0
  284. package/typescript/scripts/version/bump.ts +0 -1
  285. package/typescript/scripts/version/index.ts +0 -1
  286. package/docs/COMMANDS.md +0 -85
  287. package/docs/CONFIG.md +0 -30
  288. package/docs/SYNTAX.md +0 -210
  289. package/out-tsc/bin/devalang.exe +0 -0
  290. package/out-tsc/scripts/postbuild.js +0 -11
  291. package/rust/cli/build.rs +0 -137
  292. package/rust/cli/check.rs +0 -117
  293. package/rust/cli/play.rs +0 -193
  294. package/rust/config/loader.rs +0 -13
  295. package/rust/core/audio/engine.rs +0 -203
  296. package/rust/core/audio/evaluator.rs +0 -31
  297. package/rust/core/audio/interpreter/arrow_call.rs +0 -129
  298. package/rust/core/audio/interpreter/call.rs +0 -64
  299. package/rust/core/audio/interpreter/let_.rs +0 -19
  300. package/rust/core/audio/interpreter/load.rs +0 -18
  301. package/rust/core/audio/interpreter/loop_.rs +0 -67
  302. package/rust/core/audio/interpreter/sleep.rs +0 -36
  303. package/rust/core/audio/interpreter/spawn.rs +0 -66
  304. package/rust/core/audio/interpreter/tempo.rs +0 -16
  305. package/rust/core/audio/interpreter/trigger.rs +0 -69
  306. package/rust/core/audio/renderer.rs +0 -54
  307. package/rust/core/parser/driver.rs +0 -331
  308. package/rust/core/preprocessor/loader.rs +0 -193
  309. package/rust/core/preprocessor/processor.rs +0 -76
  310. package/rust/core/shared/duration.rs +0 -8
  311. package/rust/core/shared/mod.rs +0 -2
  312. package/rust/core/shared/value.rs +0 -18
  313. package/rust/core/store/export.rs +0 -28
  314. package/rust/core/store/import.rs +0 -28
  315. package/rust/core/store/variable.rs +0 -28
  316. package/rust/core/utils/mod.rs +0 -2
  317. package/rust/core/utils/path.rs +0 -31
  318. package/rust/core/utils/validation.rs +0 -37
  319. package/rust/utils/file.rs +0 -35
  320. package/rust/utils/signature.rs +0 -17
  321. package/rust/utils/version.rs +0 -15
  322. package/typescript/scripts/postbuild.ts +0 -8
@@ -0,0 +1,77 @@
1
+ import { expect } from "chai";
2
+ import * as fs from "fs";
3
+ import * as os from "os";
4
+ import * as path from "path";
5
+
6
+ const core: any = require("../../out-tsc");
7
+
8
+ describe("devalang debug_render and render_audio E2E", () => {
9
+ let origCwd: string;
10
+ let tmpDir: string | null = null;
11
+
12
+ before(function () {
13
+ origCwd = process.cwd();
14
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "devalang-e2e-"));
15
+ fs.writeFileSync(
16
+ path.join(tmpDir, ".devalang"),
17
+ 'name = "devalang-test"\n'
18
+ );
19
+ fs.mkdirSync(path.join(tmpDir, ".deva"), { recursive: true });
20
+ process.chdir(tmpDir as string);
21
+ });
22
+
23
+ after(function () {
24
+ if (tmpDir) {
25
+ try {
26
+ process.chdir(origCwd);
27
+ fs.rmSync(tmpDir, { recursive: true, force: true });
28
+ } catch (e) {
29
+ // ignore
30
+ }
31
+ }
32
+ });
33
+
34
+ it("debug_render should return diagnostics including note_count and global_vars", function () {
35
+ const dbg = core.pkg && core.pkg.debug_render;
36
+ if (typeof dbg !== "function") {
37
+ // skip if wasm binding missing
38
+ // eslint-disable-next-line no-invalid-this
39
+ this.skip();
40
+ }
41
+
42
+ const sampleProgram = `# sample program\nbpm 120\n\ngroup myLead:\n let mySynth = synth sine\n mySynth -> note(C4, { duration: 400 })\n mySynth -> note(G4, { duration: 400 })\ncall myLead\n`;
43
+
44
+ const out = dbg(sampleProgram);
45
+ expect(out).to.be.an("object");
46
+ expect(out).to.have.property("samples_len");
47
+ expect(out).to.have.property("any_nonzero");
48
+ expect(out).to.have.property("note_count");
49
+ expect(out).to.have.property("global_vars");
50
+
51
+ // Basic assertions: at least one non-zero sample or note_count > 0
52
+ expect(out.note_count).to.be.at.least(0);
53
+ expect(out.global_vars).to.include("myLead");
54
+ });
55
+
56
+ it("render_audio should return a Float32Array and not be completely silent", function () {
57
+ const render = (core.pkg && core.pkg.render_audio) || core.render_audio;
58
+ if (typeof render !== "function") {
59
+ // eslint-disable-next-line no-invalid-this
60
+ this.skip();
61
+ }
62
+
63
+ const sampleProgram = `# sample program\nbpm 120\n\ngroup myLead:\n let mySynth = synth sine\n mySynth -> note(C4, { duration: 400 })\n mySynth -> note(G4, { duration: 400 })\ncall myLead\n`;
64
+
65
+ const arr = render(sampleProgram);
66
+ // If wasm returns JS typed array wrapper, check constructor name
67
+ expect(arr.constructor && arr.constructor.name).to.match(
68
+ /Float32Array|Float64Array|ArrayBuffer|Uint8Array/
69
+ );
70
+
71
+ // Convert to plain array if needed
72
+ const samples: number[] = Array.from(arr as any);
73
+ // Expect either note_count > 0 indirectly via nonzero samples
74
+ const anyNonZero = samples.some((s) => s !== 0);
75
+ expect(anyNonZero).to.be.true;
76
+ });
77
+ });
package/tsconfig.json CHANGED
@@ -11,7 +11,7 @@
11
11
  // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12
12
 
13
13
  /* Language and Environment */
14
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
14
+ "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
15
15
  // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16
16
  // "jsx": "preserve", /* Specify what JSX code is generated. */
17
17
  // "libReplacement": true, /* Enable lib replacement. */
@@ -26,8 +26,8 @@
26
26
  // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
27
27
 
28
28
  /* Modules */
29
- "module": "commonjs", /* Specify what module code is generated. */
30
- "rootDir": "./typescript", /* Specify the root folder within your source files. */
29
+ "module": "commonjs" /* Specify what module code is generated. */,
30
+ "rootDir": "./typescript" /* Specify the root folder within your source files. */,
31
31
  // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
32
32
  // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
33
33
  // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
@@ -52,14 +52,14 @@
52
52
  // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
53
53
 
54
54
  /* Emit */
55
- // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
55
+ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
56
56
  // "declarationMap": true, /* Create sourcemaps for d.ts files. */
57
57
  // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
58
58
  // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
59
59
  // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
60
60
  // "noEmit": true, /* Disable emitting files from a compilation. */
61
61
  // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
62
- "outDir": "./out-tsc", /* Specify an output folder for all emitted files. */
62
+ "outDir": "./out-tsc" /* Specify an output folder for all emitted files. */,
63
63
  // "removeComments": true, /* Disable emitting comments. */
64
64
  // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
65
65
  // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
@@ -80,12 +80,12 @@
80
80
  // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
81
81
  // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
82
82
  // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
83
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
83
+ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
84
84
  // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
85
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
85
+ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
86
86
 
87
87
  /* Type Checking */
88
- "strict": true, /* Enable all strict type-checking options. */
88
+ "strict": true /* Enable all strict type-checking options. */,
89
89
  // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
90
90
  // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
91
91
  // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
@@ -108,6 +108,8 @@
108
108
 
109
109
  /* Completeness */
110
110
  // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
111
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
112
- }
111
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
112
+ },
113
+ "include": ["typescript/**/*.ts"],
114
+ "exclude": ["node_modules", "out-tsc", "target", "dist", "**/*.spec.ts"]
113
115
  }
@@ -1,14 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawn } from "child_process";
4
- import path from "path";
4
+ import * as path from "path";
5
5
 
6
- const binaryPath = path.join(__dirname, "devalang.exe");
6
+ let binaryName: string;
7
7
 
8
- const subCommand = process.argv[2] || "help";
8
+ switch (process.platform) {
9
+ case "win32":
10
+ binaryName = "devalang-x86_64-pc-windows-msvc.exe";
11
+ break;
12
+ case "darwin":
13
+ binaryName = "devalang-x86_64-apple-darwin";
14
+ break;
15
+ case "linux":
16
+ binaryName = "devalang-x86_64-unknown-linux-gnu";
17
+ break;
18
+ default:
19
+ console.error(`Unsupported platform: ${process.platform}`);
20
+ process.exit(1);
21
+ }
22
+
23
+ const binaryPath = path.join(__dirname, binaryName);
9
24
 
10
25
  const args = process.argv.slice(2);
11
26
  const child = spawn(binaryPath, args, { stdio: "inherit" });
12
27
 
13
-
14
- child.on("exit", (code) => process.exit(code));
28
+ child.on("exit", (code) => process.exit(code ?? 1));
@@ -0,0 +1,94 @@
1
+ import { ParseResult } from "../types/result";
2
+ import { DebugResult } from "../types/result";
3
+
4
+ let wasmPkg: any = undefined;
5
+ try {
6
+ // prefer runtime pkg generated by wasm-pack when available
7
+ // require at runtime so the package can be used even if wasm hasn't been built
8
+ // (this keeps tests and consumers robust).
9
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
10
+ wasmPkg = require("../../pkg/devalang_core");
11
+ } catch (_e) {
12
+ wasmPkg = undefined;
13
+ }
14
+
15
+ /**
16
+ * Parses the user code.
17
+ * @param entry_path The entry path for the code.
18
+ * @param source The source code to parse.
19
+ * @returns ParseResult | any
20
+ */
21
+ export function parse(entry_path: string, source: string): ParseResult | any {
22
+ if (wasmPkg && typeof wasmPkg.parse === "function") {
23
+ return wasmPkg.parse(entry_path, source);
24
+ }
25
+
26
+ throw new Error(
27
+ "WASM binding 'parse' not available. Build the wasm package or use the JS runtime."
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Renders the debug information for the user code.
33
+ * @param user_code The user-provided code to render debug information for.
34
+ * @returns DebugResult | any
35
+ */
36
+ export function debug_render(user_code: string): DebugResult | any {
37
+ if (wasmPkg && typeof wasmPkg.debug_render === "function") {
38
+ return wasmPkg.debug_render(user_code);
39
+ }
40
+
41
+ throw new Error(
42
+ "WASM binding 'debug_render' not available. Build the wasm package or use the JS runtime."
43
+ );
44
+ }
45
+
46
+ /**
47
+ * Renders audio from the user code.
48
+ * @param user_code The user-provided code to render audio from.
49
+ * @returns Float32Array
50
+ */
51
+ export function render_audio(user_code: string): Float32Array {
52
+ if (wasmPkg && typeof wasmPkg.render_audio === "function") {
53
+ return wasmPkg.render_audio(user_code);
54
+ }
55
+
56
+ // Fallback: indicate missing wasm with an empty buffer rather than breaking consumers.
57
+ return new Float32Array(0);
58
+ }
59
+
60
+ /**
61
+ * Register a JS callback to receive playhead events { time, line, column } during playback.
62
+ * The callback will be called with a single object argument.
63
+ * @param cb The callback function to register.
64
+ * @returns void
65
+ */
66
+ export function register_playhead_callback(cb: (ev: { time: number; line: number; column: number }) => void) {
67
+ if (wasmPkg && typeof wasmPkg.register_playhead_callback === "function") {
68
+ return wasmPkg.register_playhead_callback(cb);
69
+ }
70
+ // no-op fallback
71
+ return;
72
+ }
73
+
74
+ /**
75
+ * Collects playhead events that have been recorded during playback.
76
+ * @returns Array of playhead events { time, line, column }.
77
+ */
78
+ export function collect_playhead_events() {
79
+ if (wasmPkg && typeof wasmPkg.collect_playhead_events === "function") {
80
+ return wasmPkg.collect_playhead_events();
81
+ }
82
+ return [];
83
+ }
84
+
85
+ /**
86
+ * Unregisters the JS callback for playhead events.
87
+ * @returns void
88
+ */
89
+ export function unregister_playhead_callback() {
90
+ if (wasmPkg && typeof wasmPkg.unregister_playhead_callback === "function") {
91
+ return wasmPkg.unregister_playhead_callback();
92
+ }
93
+ return;
94
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core functionality for the Devalang language.
3
+ * This module exports all the core types and functions used in the language.
4
+ */
5
+ export * from "./types/index";
6
+ export * from "./functions/index";
@@ -0,0 +1,4 @@
1
+ export * from "./result";
2
+ export * from "./statement";
3
+ export * from "./value";
4
+ export * from "./plugin";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Represents a plugin export.
3
+ */
4
+ export interface PluginExport {
5
+ name: string;
6
+ kind: string;
7
+ default?: any;
8
+ }
9
+
10
+ /**
11
+ * Represents a plugin.
12
+ */
13
+ export interface PluginInfo {
14
+ author: string;
15
+ name: string;
16
+ version?: string;
17
+ description?: string;
18
+ exports: PluginExport[];
19
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Represents an error that occurred during parsing.
3
+ */
4
+ export interface ErrorResult {
5
+ message: string;
6
+ line: number;
7
+ column: number;
8
+ }
9
+
10
+ /**
11
+ * Represents the result of parsing user code.
12
+ */
13
+ export interface ParseResult {
14
+ ok: boolean;
15
+ ast: string;
16
+ errors: ErrorResult[];
17
+ }
18
+
19
+ /**
20
+ * Represents the result of debugging user code.
21
+ */
22
+ export interface DebugResult {
23
+ samples_len: number;
24
+ any_nonzero: boolean;
25
+ ast: string;
26
+ note_count: number;
27
+ global_vars: string[];
28
+ statements_count: number;
29
+ }
@@ -0,0 +1,47 @@
1
+ import { Value, Duration } from "./value";
2
+
3
+ /**
4
+ * Represents a statement kind in the code.
5
+ */
6
+ export type StatementKind =
7
+ | { kind: "Tempo" }
8
+ | { kind: "Bank"; alias?: string }
9
+ | { kind: "Print" }
10
+ | { kind: "Load"; source: string; alias: string }
11
+ | { kind: "Use"; name: string; alias?: string }
12
+ | { kind: "Let"; name: string }
13
+ | { kind: "Automate"; target: string }
14
+ | { kind: "ArrowCall"; target: string; method: string; args: Value[] }
15
+ | { kind: "Function"; name: string; parameters: string[]; body: Statement[] }
16
+ | { kind: "Synth" }
17
+ | { kind: "Trigger"; entity: string; duration: Duration; effects?: Value }
18
+ | { kind: "Sleep" }
19
+ | { kind: "Call"; name: string; args: Value[] }
20
+ | { kind: "Spawn"; name: string; args: Value[] }
21
+ | { kind: "Loop" }
22
+ | { kind: "Group" }
23
+ | { kind: "Include"; path: string }
24
+ | { kind: "Export"; names: string[]; source: string }
25
+ | { kind: "Import"; names: string[]; source: string }
26
+ | { kind: "If" }
27
+ | { kind: "Else" }
28
+ | { kind: "ElseIf" }
29
+ | { kind: "Comment" }
30
+ | { kind: "Indent" }
31
+ | { kind: "Dedent" }
32
+ | { kind: "NewLine" }
33
+ | { kind: "On"; event: string; args?: Value[]; body: Statement[] }
34
+ | { kind: "Emit"; event: string; payload?: Value }
35
+ | { kind: "Unknown" }
36
+ | { kind: "Error"; message: string };
37
+
38
+ /**
39
+ * Represents a statement in the code.
40
+ */
41
+ export interface Statement {
42
+ kind: StatementKind;
43
+ value: Value;
44
+ indent: number;
45
+ line: number;
46
+ column: number;
47
+ }
@@ -0,0 +1,29 @@
1
+ import { Statement } from "./statement";
2
+
3
+ /**
4
+ * Represents a duration in the code.
5
+ */
6
+ export type Duration =
7
+ | { Number: number }
8
+ | { Identifier: string }
9
+ | { Beat: string }
10
+ | { Auto: null };
11
+
12
+ /**
13
+ * Represents a value in the code.
14
+ */
15
+ export type Value =
16
+ | { Boolean: boolean }
17
+ | { Number: number }
18
+ | { Duration: Duration }
19
+ | { Identifier: string }
20
+ | { String: string }
21
+ | { Array: Value[] }
22
+ | { Map: Record<string, Value> }
23
+ | { Block: Statement[] }
24
+ | { Sample: string }
25
+ | { Beat: string }
26
+ | { Statement: Statement }
27
+ | { StatementKind: any }
28
+ | { Unknown: null }
29
+ | null;
@@ -1 +1,8 @@
1
- // This file is part of the Devalang project
1
+ /**
2
+ * Public TypeScript definitions for Devalang.
3
+ * ————————————————————————————————————————
4
+ * Used to provide TypeScript types for the Devalang WASM package.
5
+ */
6
+
7
+ export * as pkg from "./pkg/devalang_core";
8
+ export * as core from "./core/index";
@@ -0,0 +1,4 @@
1
+ /**
2
+ * This module exports all the core types and functions used in the WASM package.
3
+ */
4
+ export * from "../../pkg/devalang_core";
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Shim TypeScript source that re-exports the runtime wasm-pack package when
3
+ * available, or provides safe stubs when not present. Compiles to
4
+ * out-tsc/pkg/devalang_core.js so compiled code can require("./pkg/devalang_core").
5
+ */
6
+ let runtimePkg: any;
7
+ try {
8
+ // prefer runtime pkg generated by wasm-pack when available
9
+ // require at runtime so the package can be used even if wasm hasn't been built
10
+ // (this keeps tests and consumers robust).
11
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
12
+ runtimePkg = require("../../pkg/devalang_core");
13
+ } catch (e) {
14
+ runtimePkg = undefined;
15
+ }
16
+
17
+ export function parse(...args: any[]) {
18
+ if (runtimePkg && typeof runtimePkg.parse === "function")
19
+ return runtimePkg.parse(...args);
20
+ throw new Error("WASM package not built: pkg/devalang_core not found");
21
+ }
22
+
23
+ export function debug_render(...args: any[]) {
24
+ if (runtimePkg && typeof runtimePkg.debug_render === "function")
25
+ return runtimePkg.debug_render(...args);
26
+ throw new Error("WASM package not built: pkg/devalang_core not found");
27
+ }
28
+
29
+ export function render_audio(...args: any[]) {
30
+ if (runtimePkg && typeof runtimePkg.render_audio === "function")
31
+ return runtimePkg.render_audio(...args);
32
+ return new Float32Array(0);
33
+ }
34
+
35
+ export function register_playhead_callback(cb?: any) {
36
+ if (runtimePkg && typeof runtimePkg.register_playhead_callback === "function")
37
+ return runtimePkg.register_playhead_callback(cb);
38
+ return;
39
+ }
40
+
41
+ export function collect_playhead_events() {
42
+ if (runtimePkg && typeof runtimePkg.collect_playhead_events === "function") {
43
+ return runtimePkg.collect_playhead_events();
44
+ }
45
+ return [];
46
+ }
47
+
48
+ export function unregister_playhead_callback() {
49
+ if (
50
+ runtimePkg &&
51
+ typeof runtimePkg.unregister_playhead_callback === "function"
52
+ )
53
+ return runtimePkg.unregister_playhead_callback();
54
+ return;
55
+ }
56
+
57
+ const pkg = {
58
+ parse,
59
+ debug_render,
60
+ render_audio,
61
+ register_playhead_callback,
62
+ collect_playhead_events,
63
+ unregister_playhead_callback,
64
+ };
65
+ export default pkg;
@@ -0,0 +1,41 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ // Copies .d.ts files from pkg/ (wasm-pack output) into out-tsc/pkg/
5
+ const ROOT = path.resolve(__dirname, '..', '..');
6
+ const PKG_DIR = path.join(ROOT, 'pkg');
7
+ const OUT_DIR = path.join(ROOT, 'out-tsc', 'pkg');
8
+
9
+ function ensureDir(p: string): void {
10
+ if (!fs.existsSync(p)) fs.mkdirSync(p, { recursive: true });
11
+ }
12
+
13
+ function copyDir(src: string, dest: string): void {
14
+ ensureDir(dest);
15
+ const items = fs.readdirSync(src, { withFileTypes: true });
16
+ for (const item of items) {
17
+ const srcPath = path.join(src, item.name);
18
+ const destPath = path.join(dest, item.name);
19
+ if (item.isDirectory()) {
20
+ copyDir(srcPath, destPath);
21
+ } else if (item.isFile() && item.name.endsWith('.d.ts')) {
22
+ fs.copyFileSync(srcPath, destPath);
23
+ console.log('copied', srcPath, '->', destPath);
24
+ }
25
+ }
26
+ }
27
+
28
+ function main(): number {
29
+ if (!fs.existsSync(PKG_DIR)) {
30
+ console.error('pkg directory not found at', PKG_DIR);
31
+ return 1;
32
+ }
33
+
34
+ ensureDir(OUT_DIR);
35
+ copyDir(PKG_DIR, OUT_DIR);
36
+ console.log('done');
37
+ return 0;
38
+ }
39
+
40
+ const exitCode = main();
41
+ if (exitCode !== 0) process.exit(exitCode);
@@ -0,0 +1,85 @@
1
+ import { createWriteStream, mkdirSync } from "fs";
2
+ import { join } from "path";
3
+ import { https } from "follow-redirects";
4
+ import fs from "fs";
5
+ import path from "path";
6
+
7
+ const projectVersionPath = path.join(__dirname, "../../project-version.json");
8
+ let versionString = "";
9
+ try {
10
+ if (!fs.existsSync(projectVersionPath)) {
11
+ console.warn(`⚠️ project-version.json not found at ${projectVersionPath}. Skipping postinstall binary download.`);
12
+ } else {
13
+ const version = fs.readFileSync(projectVersionPath, "utf-8").trim();
14
+ try {
15
+ versionString = JSON.parse(version).version;
16
+ } catch (e: any) {
17
+ console.warn(`⚠️ Failed to parse project-version.json: ${e.message}. Skipping binary download.`);
18
+ versionString = "";
19
+ }
20
+ }
21
+ } catch (e: any) {
22
+ console.warn(`⚠️ Could not read project-version.json: ${e.message}. Skipping binary download.`);
23
+ versionString = "";
24
+ }
25
+
26
+ const platform = process.platform;
27
+
28
+ let binaryName: string = "";
29
+
30
+ switch (platform) {
31
+ case "win32":
32
+ binaryName = "devalang-x86_64-pc-windows-msvc.exe";
33
+ break;
34
+ case "darwin":
35
+ binaryName = "devalang-x86_64-apple-darwin";
36
+ break;
37
+ case "linux":
38
+ binaryName = "devalang-x86_64-unknown-linux-gnu";
39
+ break;
40
+ }
41
+
42
+ if (binaryName !== "" && versionString) {
43
+ const destDir = join(__dirname, "..", "..", "out-tsc", "bin");
44
+ const dest = join(destDir, binaryName);
45
+ const url = `https://github.com/devaloop-labs/devalang/releases/download/v${versionString}/${binaryName}`;
46
+
47
+ mkdirSync(destDir, { recursive: true });
48
+
49
+ console.log(`⬇️ Downloading ${binaryName} from ${url}`);
50
+
51
+ const req = https.get(url, (res: any) => {
52
+ if (res.statusCode === 404) {
53
+ console.warn(`⚠️ Asset not found (HTTP 404). Skipping binary download.`);
54
+ res.resume();
55
+ return;
56
+ }
57
+
58
+ if (res.statusCode !== 200) {
59
+ console.warn(`⚠️ Failed (HTTP ${res.statusCode}). Skipping binary download.`);
60
+ res.resume();
61
+ return;
62
+ }
63
+
64
+ const file = createWriteStream(dest, { mode: 0o755 });
65
+ res.pipe(file);
66
+ file.on("finish", () => {
67
+ file.close();
68
+ console.log(`✅ Downloaded ${binaryName} to ${dest}`);
69
+ });
70
+ });
71
+
72
+ req.setTimeout(30000, () => {
73
+ console.warn(`⚠️ Download timed out after 30s. Skipping binary download for ${binaryName}.`);
74
+ try {
75
+ req.destroy();
76
+ } catch (e) {}
77
+ });
78
+
79
+ req.on("error", (err: any) => {
80
+ // Network or other errors should not fail CI; log and continue
81
+ console.warn(`⚠️ Error downloading binary: ${err.message}. Skipping binary download.`);
82
+ });
83
+ } else {
84
+ console.warn(`⚠️ Unsupported platform: ${platform}. Skipping binary download.`);
85
+ }
@@ -1,5 +1,4 @@
1
1
  import fs from "fs";
2
- import path from "path";
3
2
 
4
3
  export const bumpVersion = async (bumpType: string, projectVersionPath: string) => {
5
4
  const versionData = JSON.parse(fs.readFileSync(projectVersionPath, "utf-8"));
@@ -1,5 +1,4 @@
1
1
  import path from "path";
2
- import fs from "fs";
3
2
 
4
3
  import { bumpVersion } from "./bump";
5
4
  import { syncVersion } from "./sync";