@devaloop/devalang 0.0.1-alpha.16-hotfix.1 → 0.0.1-alpha.17

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 (235) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +6 -10
  3. package/.github/workflows/ci.yml +19 -8
  4. package/Cargo.toml +18 -2
  5. package/README.md +80 -33
  6. package/docs/CHANGELOG.md +56 -0
  7. package/docs/ROADMAP.md +6 -3
  8. package/examples/index.deva +52 -35
  9. package/out-tsc/bin/index.d.ts +2 -0
  10. package/out-tsc/core/functions/index.d.ts +37 -0
  11. package/out-tsc/core/functions/index.js +76 -0
  12. package/out-tsc/core/index.d.ts +6 -0
  13. package/out-tsc/core/index.js +22 -0
  14. package/out-tsc/core/types/index.d.ts +4 -0
  15. package/out-tsc/core/types/index.js +20 -0
  16. package/out-tsc/core/types/plugin.d.ts +18 -0
  17. package/out-tsc/core/types/plugin.js +2 -0
  18. package/out-tsc/core/types/result.d.ts +27 -0
  19. package/out-tsc/core/types/result.js +2 -0
  20. package/out-tsc/core/types/statement.d.ts +106 -0
  21. package/out-tsc/core/types/statement.js +2 -0
  22. package/out-tsc/core/types/value.d.ts +43 -0
  23. package/out-tsc/core/types/value.js +2 -0
  24. package/out-tsc/index.d.ts +7 -0
  25. package/out-tsc/index.js +41 -2
  26. package/out-tsc/pkg/devalang_core.d.ts +7 -0
  27. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  28. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  29. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  30. package/out-tsc/scripts/postinstall.d.ts +1 -0
  31. package/out-tsc/scripts/postinstall.js +33 -23
  32. package/out-tsc/scripts/version/bump.d.ts +1 -0
  33. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  34. package/out-tsc/scripts/version/index.d.ts +1 -0
  35. package/out-tsc/scripts/version/sync.d.ts +1 -0
  36. package/package.json +16 -4
  37. package/project-version.json +3 -3
  38. package/rust/cli/bank/api.rs +122 -0
  39. package/rust/cli/bank/commands.rs +275 -0
  40. package/rust/cli/bank/mod.rs +29 -0
  41. package/rust/cli/build/commands.rs +97 -0
  42. package/rust/cli/build/mod.rs +2 -0
  43. package/rust/cli/build/process.rs +146 -0
  44. package/rust/cli/{check.rs → check/mod.rs} +18 -31
  45. package/rust/cli/discover/commands.rs +253 -0
  46. package/rust/cli/discover/config.rs +111 -0
  47. package/rust/cli/discover/fs.rs +19 -0
  48. package/rust/cli/discover/install.rs +103 -0
  49. package/rust/cli/discover/metadata.rs +48 -0
  50. package/rust/cli/discover/mod.rs +5 -0
  51. package/rust/cli/{init.rs → init/commands.rs} +88 -87
  52. package/rust/cli/init/mod.rs +1 -0
  53. package/rust/{installer → cli/install}/addon.rs +5 -9
  54. package/rust/cli/install/bank.rs +53 -0
  55. package/rust/cli/{install.rs → install/commands.rs} +9 -9
  56. package/rust/{installer → cli/install}/mod.rs +2 -3
  57. package/rust/cli/install/plugin.rs +61 -0
  58. package/rust/cli/{login.rs → login/commands.rs} +8 -11
  59. package/rust/cli/login/mod.rs +1 -0
  60. package/rust/cli/mod.rs +2 -3
  61. package/rust/cli/{driver.rs → parser.rs} +19 -2
  62. package/rust/cli/play/commands.rs +324 -0
  63. package/rust/cli/play/io.rs +17 -0
  64. package/rust/cli/play/mod.rs +5 -0
  65. package/rust/cli/play/process.rs +150 -0
  66. package/rust/cli/play/realtime.rs +91 -0
  67. package/rust/cli/play/utils.rs +23 -0
  68. package/rust/cli/telemetry/commands.rs +22 -0
  69. package/rust/cli/telemetry/event_creator.rs +80 -0
  70. package/rust/cli/telemetry/mod.rs +3 -0
  71. package/rust/cli/telemetry/send.rs +51 -0
  72. package/rust/cli/{template.rs → template/commands.rs} +1 -1
  73. package/rust/cli/template/mod.rs +1 -0
  74. package/rust/cli/{update.rs → update/commands.rs} +6 -6
  75. package/rust/cli/update/mod.rs +1 -0
  76. package/rust/config/driver.rs +57 -72
  77. package/rust/config/mod.rs +1 -2
  78. package/rust/config/ops.rs +26 -0
  79. package/rust/config/settings.rs +60 -50
  80. package/rust/core/audio/engine/helpers.rs +146 -0
  81. package/rust/core/audio/engine/mod.rs +7 -0
  82. package/rust/core/audio/engine/sample.rs +298 -0
  83. package/rust/core/audio/engine/synth.rs +310 -0
  84. package/rust/core/audio/evaluator.rs +15 -12
  85. package/rust/core/audio/interpreter/arrow_call.rs +99 -24
  86. package/rust/core/audio/interpreter/call.rs +81 -60
  87. package/rust/core/audio/interpreter/condition.rs +3 -2
  88. package/rust/core/audio/interpreter/driver.rs +206 -151
  89. package/rust/core/audio/interpreter/let_.rs +1 -1
  90. package/rust/core/audio/interpreter/load.rs +2 -1
  91. package/rust/core/audio/interpreter/loop_.rs +7 -6
  92. package/rust/core/audio/interpreter/sleep.rs +2 -1
  93. package/rust/core/audio/interpreter/spawn.rs +45 -57
  94. package/rust/core/audio/interpreter/tempo.rs +31 -10
  95. package/rust/core/audio/interpreter/trigger.rs +2 -2
  96. package/rust/core/audio/loader/trigger.rs +4 -7
  97. package/rust/core/audio/player.rs +6 -0
  98. package/rust/core/audio/renderer.rs +5 -7
  99. package/rust/core/audio/special/env.rs +3 -1
  100. package/rust/core/audio/special/math.rs +4 -4
  101. package/rust/core/audio/special/modulator.rs +2 -2
  102. package/rust/core/builder/mod.rs +9 -3
  103. package/rust/core/debugger/lexer.rs +1 -1
  104. package/rust/core/debugger/mod.rs +6 -0
  105. package/rust/core/debugger/module.rs +4 -4
  106. package/rust/core/debugger/preprocessor.rs +1 -1
  107. package/rust/core/debugger/store.rs +2 -2
  108. package/rust/core/error/mod.rs +189 -0
  109. package/rust/core/lexer/handler/arrow.rs +1 -1
  110. package/rust/core/lexer/handler/at.rs +1 -1
  111. package/rust/core/lexer/handler/brace.rs +2 -2
  112. package/rust/core/lexer/handler/colon.rs +1 -1
  113. package/rust/core/lexer/handler/comment.rs +1 -1
  114. package/rust/core/lexer/handler/dot.rs +1 -1
  115. package/rust/core/lexer/handler/driver.rs +1 -1
  116. package/rust/core/lexer/handler/identifier.rs +1 -1
  117. package/rust/core/lexer/handler/mod.rs +1 -2
  118. package/rust/core/lexer/handler/number.rs +1 -1
  119. package/rust/core/lexer/handler/operator.rs +1 -1
  120. package/rust/core/lexer/handler/parenthesis.rs +2 -2
  121. package/rust/core/lexer/handler/slash.rs +1 -1
  122. package/rust/core/lexer/handler/string.rs +1 -1
  123. package/rust/core/lexer/mod.rs +22 -12
  124. package/rust/core/lexer/token.rs +90 -97
  125. package/rust/core/mod.rs +0 -1
  126. package/rust/core/parser/driver.rs +66 -13
  127. package/rust/core/parser/handler/arrow_call.rs +28 -8
  128. package/rust/core/parser/handler/at.rs +55 -21
  129. package/rust/core/parser/handler/bank.rs +14 -4
  130. package/rust/core/parser/handler/condition.rs +6 -3
  131. package/rust/core/parser/handler/dot.rs +2 -1
  132. package/rust/core/parser/handler/identifier/automate.rs +13 -16
  133. package/rust/core/parser/handler/identifier/call.rs +4 -4
  134. package/rust/core/parser/handler/identifier/emit.rs +9 -5
  135. package/rust/core/parser/handler/identifier/function.rs +20 -7
  136. package/rust/core/parser/handler/identifier/group.rs +11 -7
  137. package/rust/core/parser/handler/identifier/let_.rs +24 -9
  138. package/rust/core/parser/handler/identifier/mod.rs +6 -5
  139. package/rust/core/parser/handler/identifier/on.rs +16 -7
  140. package/rust/core/parser/handler/identifier/print.rs +6 -9
  141. package/rust/core/parser/handler/identifier/sleep.rs +12 -5
  142. package/rust/core/parser/handler/identifier/spawn.rs +4 -4
  143. package/rust/core/parser/handler/identifier/synth.rs +79 -9
  144. package/rust/core/parser/handler/loop_.rs +39 -14
  145. package/rust/core/parser/handler/tempo.rs +9 -5
  146. package/rust/core/parser/mod.rs +0 -1
  147. package/rust/core/parser/statement.rs +6 -137
  148. package/rust/core/plugin/loader.rs +41 -27
  149. package/rust/core/plugin/runner.rs +68 -17
  150. package/rust/core/preprocessor/loader.rs +155 -33
  151. package/rust/core/preprocessor/processor.rs +2 -2
  152. package/rust/core/preprocessor/resolver/bank.rs +6 -8
  153. package/rust/core/preprocessor/resolver/call.rs +20 -24
  154. package/rust/core/preprocessor/resolver/condition.rs +6 -8
  155. package/rust/core/preprocessor/resolver/driver.rs +14 -16
  156. package/rust/core/preprocessor/resolver/function.rs +6 -6
  157. package/rust/core/preprocessor/resolver/group.rs +6 -8
  158. package/rust/core/preprocessor/resolver/loop_.rs +8 -10
  159. package/rust/core/preprocessor/resolver/spawn.rs +19 -23
  160. package/rust/core/preprocessor/resolver/synth.rs +6 -8
  161. package/rust/core/preprocessor/resolver/tempo.rs +6 -8
  162. package/rust/core/preprocessor/resolver/trigger.rs +22 -19
  163. package/rust/core/preprocessor/resolver/value.rs +99 -4
  164. package/rust/core/store/export.rs +28 -28
  165. package/rust/core/store/function.rs +6 -0
  166. package/rust/core/store/global.rs +7 -1
  167. package/rust/core/store/import.rs +28 -28
  168. package/rust/core/store/variable.rs +1 -1
  169. package/rust/core/utils/mod.rs +0 -1
  170. package/rust/lib.rs +102 -9
  171. package/rust/main.rs +156 -45
  172. package/rust/types/Cargo.toml +8 -0
  173. package/rust/types/src/addons.rs +55 -0
  174. package/rust/types/src/ast.rs +198 -0
  175. package/rust/types/src/config.rs +74 -0
  176. package/rust/types/src/lib.rs +12 -0
  177. package/rust/types/src/telemetry.rs +85 -0
  178. package/rust/utils/Cargo.toml +23 -0
  179. package/rust/utils/{error.rs → src/error.rs} +186 -200
  180. package/rust/utils/src/file.rs +94 -0
  181. package/rust/utils/src/first_usage.rs +97 -0
  182. package/rust/utils/{mod.rs → src/lib.rs} +1 -1
  183. package/rust/utils/{logger.rs → src/logger.rs} +17 -12
  184. package/rust/utils/src/path.rs +88 -0
  185. package/rust/utils/src/signature.rs +41 -0
  186. package/rust/utils/{spinner.rs → src/spinner.rs} +3 -5
  187. package/rust/utils/src/version.rs +27 -0
  188. package/rust/utils/{watcher.rs → src/watcher.rs} +13 -1
  189. package/rust/web/api.rs +5 -0
  190. package/rust/web/cdn.rs +34 -0
  191. package/templates/minimal/README.md +98 -54
  192. package/templates/welcome/README.md +98 -54
  193. package/templates/welcome/src/index.deva +56 -8
  194. package/templates/welcome/src/variables.deva +2 -4
  195. package/tests/rust/TODO.md +0 -0
  196. package/tests/typescript/index.spec.ts +136 -0
  197. package/tests/typescript/playhead.spec.ts +36 -0
  198. package/tests/typescript/render_e2e.spec.ts +77 -0
  199. package/tsconfig.json +1 -1
  200. package/typescript/core/functions/index.ts +83 -0
  201. package/typescript/core/index.ts +6 -0
  202. package/typescript/core/types/index.ts +4 -0
  203. package/typescript/core/types/plugin.ts +19 -0
  204. package/typescript/core/types/result.ts +29 -0
  205. package/typescript/core/types/statement.ts +47 -0
  206. package/typescript/core/types/value.ts +29 -0
  207. package/typescript/index.ts +7 -2
  208. package/typescript/pkg/devalang_core.d.ts +4 -0
  209. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  210. package/typescript/scripts/postinstall.ts +45 -32
  211. package/rust/cli/bank.rs +0 -462
  212. package/rust/cli/build.rs +0 -252
  213. package/rust/cli/generator.rs +0 -1
  214. package/rust/cli/play.rs +0 -1123
  215. package/rust/cli/telemetry.rs +0 -19
  216. package/rust/common/api.rs +0 -5
  217. package/rust/common/cdn.rs +0 -5
  218. package/rust/config/loader.rs +0 -165
  219. package/rust/config/stats.rs +0 -257
  220. package/rust/core/audio/engine.rs +0 -696
  221. package/rust/core/shared/bank.rs +0 -21
  222. package/rust/core/shared/duration.rs +0 -9
  223. package/rust/core/shared/mod.rs +0 -3
  224. package/rust/core/shared/value.rs +0 -35
  225. package/rust/core/utils/validation.rs +0 -35
  226. package/rust/installer/bank.rs +0 -62
  227. package/rust/installer/plugin.rs +0 -54
  228. package/rust/installer/utils.rs +0 -56
  229. package/rust/utils/file.rs +0 -38
  230. package/rust/utils/first_usage.rs +0 -76
  231. package/rust/utils/signature.rs +0 -19
  232. package/rust/utils/telemetry.rs +0 -292
  233. package/rust/utils/version.rs +0 -15
  234. /package/rust/{common → web}/mod.rs +0 -0
  235. /package/rust/{common → web}/sso.rs +0 -0
@@ -0,0 +1,2 @@
1
+ [target.wasm32-unknown-unknown]
2
+ rustflags = ["--cfg", "getrandom_backend=\"wasm_js\""]
package/.devalang CHANGED
@@ -1,10 +1,6 @@
1
- [defaults]
2
- entry = "./examples"
3
- output = "./output"
4
- watch = false
5
- debug = true
6
- compress = true
7
-
8
- [[banks]]
9
- path = "devalang://bank/devaloop.808"
10
- version = "0.0.2"
1
+ [defaults]
2
+ entry = "./examples"
3
+ output = "./output"
4
+ watch = false
5
+ debug = true
6
+ compress = true
@@ -1,12 +1,12 @@
1
1
  name: CI & Release
2
2
 
3
+ permissions:
4
+ contents: write
5
+
3
6
  on:
4
7
  push:
5
- branches:
6
- - main
7
8
  tags:
8
9
  - "v*"
9
- pull_request:
10
10
 
11
11
  jobs:
12
12
  build:
@@ -77,16 +77,27 @@ jobs:
77
77
  Copy-Item "target\${{ matrix.target }}\release\devalang${{ matrix.bin_ext }}" "out-tsc\bin\devalang-${{ matrix.target }}${{ matrix.bin_ext }}" -Force
78
78
 
79
79
  - name: Upload artifact (CI)
80
- if: startsWith(github.ref, 'refs/heads/')
81
80
  uses: actions/upload-artifact@v4
82
81
  with:
83
82
  name: devalang-${{ matrix.target }}
84
83
  path: out-tsc/bin/*
85
84
 
85
+ release:
86
+ name: Create GitHub Release
87
+ runs-on: ubuntu-latest
88
+ needs: build
89
+ steps:
90
+ - name: Download all build artifacts
91
+ uses: actions/download-artifact@v4
92
+ with:
93
+ path: dist
94
+ pattern: devalang-*
95
+ merge-multiple: true
96
+
97
+ - name: List files
98
+ run: ls -la dist
99
+
86
100
  - name: Upload to GitHub Release
87
- if: startsWith(github.ref, 'refs/tags/')
88
101
  uses: softprops/action-gh-release@v2
89
102
  with:
90
- files: out-tsc/bin/*
91
- env:
92
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
103
+ files: dist/*
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "devalang"
3
- version = "0.0.1-alpha.16-hotfix.1"
3
+ version = "0.0.1-alpha.17"
4
4
  authors = ["Devaloop <contact@devaloop.com>"]
5
5
  description = "Write music like code. Devalang is a domain-specific language (DSL) for sound designers and music hackers. Compose, automate, and control sound — in plain text."
6
6
  license = "MIT"
@@ -30,6 +30,7 @@ default = ["cli"]
30
30
  cli = ["crossterm", "indicatif", "inquire", "zip", "reqwest", "flate2", "tokio"]
31
31
 
32
32
  [dependencies]
33
+ devalang_types = { path = "rust/types" }
33
34
  clap = { version = "4.5", features = ["derive"] }
34
35
  serde = { version = "1.0", features = ["derive"] }
35
36
  serde_json = "1.0"
@@ -47,6 +48,7 @@ crossterm = { version = "0.27", optional = true }
47
48
  indicatif = { version = "0.17", optional = true }
48
49
  inquire = { version = "0.7.5", optional = true }
49
50
  js-sys = "0.3"
51
+ getrandom = { version = "0.3", features = ["wasm_js"] }
50
52
  reqwest = { version = "0.12.22", optional = true, features = ["json"] }
51
53
  flate2 = { version = "1.0", optional = true }
52
54
  tokio = { version = "1", features = ["full"], optional = true }
@@ -57,4 +59,18 @@ tiny_http = "0.9.0"
57
59
  dirs = "5"
58
60
  urlencoding = "2.1"
59
61
  uuid = { version = "1.18.0", features = ["v4"] }
60
- wasmtime = "19"
62
+ console_error_panic_hook = "0.1.7"
63
+
64
+ # For wasm32, enable wasm-friendly randomness backends and avoid
65
+ # pulling in native-only CLI dependencies.
66
+ [target.'cfg(target_arch = "wasm32")'.dependencies]
67
+ getrandom = { version = "0.3", features = ["wasm_js"] }
68
+ uuid = { version = "1.18.0", features = ["v4", "js", "rng-getrandom"] }
69
+ # Keep a lightweight linkage to the utils crate for wasm builds without
70
+ # enabling native CLI features.
71
+ devalang_utils = { path = "rust/utils", default-features = false }
72
+
73
+ # devalang_utils with CLI and wasmtime are only needed for native targets.
74
+ [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
75
+ devalang_utils = { path = "rust/utils", features = ["cli"] }
76
+ wasmtime = "19"
package/README.md CHANGED
@@ -28,11 +28,13 @@ Whether you're building a track, shaping textures, or performing live, Devalang
28
28
 
29
29
  From studio sketches to live sets, Devalang gives you rhythmic control — with the elegance of code.
30
30
 
31
- > 🚧 Alpha Notice 🚧
31
+ > **🚧 Notice 🚧**
32
32
  >
33
- > Includes synthesis, playback, and rendering features, but is still in early development.
33
+ > Includes synthesis, playback, and rendering features, but is still in early development, and breaking changes may occur.
34
34
  >
35
- > NEW: Devalang is available for **Windows**, **Linux**, and **macOS**.
35
+ > **NEW**: [Devaforge is now available for creating addons](https://github.com/devaloop-labs/devaforge).
36
+ >
37
+ > **NEW**: Now available for Windows, Linux, and macOS.
36
38
 
37
39
  ## 📚 Quick Access
38
40
 
@@ -43,31 +45,54 @@ From studio sketches to live sets, Devalang gives you rhythmic control — with
43
45
  - [📜 Changelog](./docs/CHANGELOG.md)
44
46
  - [💡 Examples](./examples/)
45
47
  - [🌐 Project Website](https://devalang.com)
46
- - [📦 Devalang CLI on npm](https://www.npmjs.com/package/@devaloop/devalang)
48
+ - [📦 Devaforge on npm](https://www.npmjs.com/package/@devaloop/devaforge)
49
+ - [📦 Devalang on npm](https://www.npmjs.com/package/@devaloop/devalang)
47
50
 
48
51
  ## ⏱️ Try it now !
49
52
 
50
53
  ### Try Devalang in your browser
51
54
 
52
- > Have a look at the [Playground](https://playground.devalang.com) to try Devalang directly in your browser
55
+ > [Have a look at the Playground to try Devalang directly in your browser](https://playground.devalang.com)
56
+
57
+ ### Try Devalang in your terminal
53
58
 
54
- ### Try Devalang CLI
59
+ #### With Node.js
55
60
 
56
61
  ```bash
57
- # Install Devalang CLI globally
58
62
  npm install -g @devaloop/devalang@latest
63
+ ```
59
64
 
60
- # Create a new Devalang project
65
+ #### With Rust
66
+
67
+ ```bash
68
+ cargo install devalang
69
+ ```
70
+
71
+ #### Initialize a new project
72
+
73
+ ```bash
61
74
  devalang init --name my-project --template minimal
62
- cd my-project
63
75
  ```
64
76
 
77
+ #### Write your first script
78
+
65
79
  Create a new Devalang file `src/index.deva` in the project directory:
66
80
 
67
81
  ```deva
68
82
  # src/index.deva
69
83
 
84
+ # BPM definition
85
+ bpm 125
86
+
87
+ # Bank picking (make sure you installed it)
88
+ bank devaloop.808 as my808Bank
89
+
70
90
  group myGroup:
91
+ # Rhythmic (each beat playing a kick)
92
+ on beat:
93
+ .my808Bank.kick 1/4
94
+
95
+ # Synth definition with ADSR
71
96
  let myLead = synth sine {
72
97
  attack: 0,
73
98
  decay: 100,
@@ -75,12 +100,27 @@ group myGroup:
75
100
  release: 100
76
101
  }
77
102
 
103
+ # Global automation
78
104
  automate myLead:
105
+ param volume {
106
+ 0% = 0.0
107
+ 100% = 0.5
108
+ }
79
109
  param pitch {
80
110
  0% = -12.0
81
111
  100% = 12.0
82
112
  }
83
113
 
114
+ # Notes in a loop with condition
115
+ for i in [1, 2, 3]:
116
+ if i == 3:
117
+ myLead -> note(C5, { duration: 200 })
118
+ print "Playing note C5 for " + i
119
+
120
+ # Pause runtime for 500ms
121
+ sleep 500
122
+
123
+ # Note with automation
84
124
  myLead -> note(C4, {
85
125
  duration: 400,
86
126
  velocity: 0.8,
@@ -92,27 +132,26 @@ group myGroup:
92
132
  }
93
133
  })
94
134
 
135
+ # Notes with params
95
136
  myLead -> note(E4, { duration: 400 })
96
137
  myLead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
97
138
  myLead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
98
139
 
99
- for i in [1, 2, 3]:
100
- myLead -> note(C5, { duration: 200 })
101
- print "Playing note C5 for " + i
102
-
140
+ # Calling the group to play it
103
141
  call myGroup
104
142
  ```
105
143
 
106
144
  ### And the best part ? You can play it directly from the command line:
107
145
 
146
+ #### Play the script once
147
+
108
148
  ```bash
109
- # Play the Devalang file
110
149
  devalang play
150
+ ```
111
151
 
112
- # Play the Devalang file with watch mode
113
- devalang play --watch
152
+ #### **LIVE mode** (repeat the playback + watch mode)
114
153
 
115
- # LIVE mode (repeat the playback + watch mode)
154
+ ```bash
116
155
  devalang play --repeat
117
156
  ```
118
157
 
@@ -122,7 +161,7 @@ devalang play --repeat
122
161
 
123
162
  ## ❓ Why Devalang ?
124
163
 
125
- - 🎹 Prototype audio ideas without opening a DAW, even VSCode
164
+ - 🎹 Prototype audio ideas without opening a DAW, even VSCode with our Playground
126
165
  - 💻 Integrate sound into code-based workflows
127
166
  - 🎛️ Control audio parameters through readable syntax
128
167
  - 🧪 Build musical logic with variables and conditions
@@ -130,31 +169,39 @@ devalang play --repeat
130
169
 
131
170
  ## 🚀 Features
132
171
 
133
- - 🎵 **Audio Engine**: Integrated audio playback and rendering
134
- - 🧩 **Module system** for importing and exporting variables between files
135
- - 📦 **Addon manager** for managing external banks, plugins and more
136
- - 📜 **Structured AST** generation for debugging and future compilation
137
- - 🔢 **Basic data types**: strings, numbers, booleans, maps, arrays
138
- - 👁️ **Watch mode** for `build`, `check` and `play` commands
139
- - 📂 **Project templates** for quick setup
140
- - 🎛️ **Custom samples**: easily load and trigger your own audio files
141
- - 🔄 **Looping and grouping**: create complex patterns with ease
172
+ - **Fast Build & Hot Reload** optimized build process for quicker iteration.
173
+ - 🎵 **Audio Engine & Real-time runner** low-latency playback, render-to-file, and a realtime runner used by `devalang play` for live feedback.
174
+ - ▶️ **Live mode (watch + repeat)** edit and hear changes instantly with `devalang play --repeat` and watch mode.
175
+ - 🧩 **Language primitives** synths, notes, ADSR, maps, arrays, loops, conditionals and functions for expressive musical logic.
176
+ - 🎛️ **Per-note automation & modulators** `automate` maps, `$mod.*`, `$easing.*` and `$math.*` helpers for envelopes and LFOs.
177
+ - 🧩 **Module system & structured AST** — import/export variables, stable AST output for debugging and tooling.
178
+ - 🧰 **Plugins & Addons (WASM-ready)** install plugins/banks, `@use` directive, and WASM plugin integration so plugins can render or process audio at runtime.
179
+ - 📦 **Addon manager & Devaforge** — CLI commands to discover/install banks, plugins and templates; `devaforge` helps create addons.
180
+ - ⚙️ **CLI tooling** `build`, `check`, `play`, `install`, `init`, `discover`, `telemetry` and more with consistent flags (`--watch`, `--debug`, `--compress`).
181
+ - 📂 **Project templates & examples** — quick-start templates and many example projects in `examples/`.
182
+ - 🧑‍💻 **TypeScript API & WASM distribution** — Node-friendly package with TypeScript bindings and a WASM build for browser/Node usage.
183
+ - 🧰 **Editor & formatting support** — VSCode extension and Prettier plugin to edit Devalang with syntax and formatting support.
184
+ - 🎵 **Custom samples & banks** — drop samples into `.deva` and reference them from code; banks of sounds for fast composition.
185
+ - 🔄 **Looping, grouping & scheduling** — precise beat-tied scheduling primitives for complex rhythmic patterns.
142
186
 
143
187
  ## 📄 Documentation
144
188
 
145
- ### Please refer to the [online documentation](https://docs.devalang.com) for detailed information on syntax, features, and usage examples
189
+ ### [Please refer to the online documentation](https://docs.devalang.com) for detailed information on syntax, features, and usage examples
146
190
 
147
- ## 🧯 Known issues
191
+ ## 📰 What's new
148
192
 
149
- - No smart modules yet, all groups, variables, and samples must be explicitly imported where used
150
- - No support yet for cross-platform builds (Linux, macOS)
193
+ - **Devaforge**: Introduced a new system for creating and managing addons, including a CLI for addon generation.
194
+ - **Documentation updates**: Improved documentation for clarity and completeness.
195
+ - **Discovering addons**: Introduced a new command to detect addons.
196
+ - **Public TypeScript API**: Added a public TypeScript API for easier integration.
197
+ - **Improved error messages**: Enhanced error messages for better debugging.
198
+ - **Bug fixes**: Various bug fixes and stability improvements.
151
199
 
152
200
  ## 🧪 Roadmap Highlights
153
201
 
154
202
  For more info, see [docs/ROADMAP.md](./docs/ROADMAP.md)
155
203
 
156
- - ⏳ Other statements (e.g `pattern`, ...)
157
- - ⏳ Addon generator
204
+ - ⏳ Smart modules
158
205
 
159
206
  ## 🛡️ License
160
207
 
package/docs/CHANGELOG.md CHANGED
@@ -4,6 +4,62 @@
4
4
 
5
5
  # Changelog
6
6
 
7
+ ## Version 0.0.1-alpha.17 (2025-08-31)
8
+
9
+ ### ✨ Addons
10
+
11
+ - Discovering addons: use the CLI to discover plugins or banks : place compiled addons (.devabank, .devaplugin) anywhere into your `.deva` folder, then run:
12
+
13
+ ```bash
14
+ devalang discover
15
+ ```
16
+
17
+ - Installing external addons: use the CLI to install addons:
18
+
19
+ ```bash
20
+ devalang install <plugin | bank> user.myPlugin
21
+ ```
22
+
23
+ - Plugin usage: you can now reference installed plugins directly from Devalang source
24
+ using the `@use` directive and an optional alias. Examples:
25
+
26
+ - `@use user.myPlugin` — exposes the plugin under its default name
27
+ - `@use user.myPlugin as myAlias` — expose the plugin as `myAlias` for shorter calls
28
+
29
+ ### 🧩 Packaging & TypeScript
30
+
31
+ - Improved packaging and postinstall logic for the TypeScript/WASM distribution; the
32
+ Node package now avoids hard-failing when optional native binaries are not available.
33
+ - `out-tsc` postinstall now performs guarded downloads and better logging to help consumers diagnose installation issues on CI or constrained environments.
34
+
35
+ ### 🧠 Architecture & Refactor
36
+
37
+ - Introduced a shared `devalang_types` crate to centralize project types and config structures — this simplifies cross-crate typing between the CLI, core, utils and WASM artifacts.
38
+ - Split utilities into a reusable `devalang_utils` crate (logger, watcher, spinner, file helpers, telemetry) and moved several helpers (path resolution, file copying, safe archive extraction) to that crate.
39
+ - Modularized CLI features, clean separation between build/process, realtime runner, IO helpers and stats collection.
40
+
41
+ ### 🐛 Bug fixes & stability
42
+
43
+ - Multiple robustness fixes across the parser, preprocessor and audio engine:
44
+ - dotted identifiers and synth/provider resolution improvements,
45
+ - safer path resolution for `.deva` resources (banks, plugins, presets),
46
+ - improved error collection and logging with annotated stacks for better debug output.
47
+ - Audio runtime: better BPM/duration estimation and loop handling in the realtime runner to avoid premature termination of periodic handlers while loops execute.
48
+
49
+ ### 🧪 Tests & CI
50
+
51
+ - Added test scaffolding and types to centralize cross-crate tests (test harness and lightweight types prepared in `devalang_types`); this enables adding unit tests incrementally without duplicating type definitions. (Full test coverage is ongoing.)
52
+
53
+ ## Version 0.0.1-alpha.16-hotfix.2 (2025-08-29)
54
+
55
+ ### 🌎 Ecosystem
56
+
57
+ - Published `@devaloop/devaforge` on npm. A tool for creating and managing Devalang addons.
58
+
59
+ ### 🔎 Telemetry
60
+
61
+ - Patched first usage and user configuration.
62
+
7
63
  ## Version 0.0.1-alpha.16-hotfix.1 (2025-08-29)
8
64
 
9
65
  ### 🌎 Ecosystem
package/docs/ROADMAP.md CHANGED
@@ -23,9 +23,12 @@ Devalang is a work in progress. Here’s what we’re planning next:
23
23
  - ✅ **WASM support**: Compile Devalang to WebAssembly for use in web applications and other environments.
24
24
  - ✅ **VSCode extension**: Create a VSCode extension for syntax highlighting and code completion.
25
25
 
26
- ## Upcoming
26
+ ## In Progress
27
27
 
28
28
  - ⏳ **Addon generator**: Implement addon generation for creating reusable plugins, banks and presets.
29
+ - ⏳ **Testing**: Expand test coverage for all features.
30
+
31
+ ## Planned
32
+
29
33
  - ⏳ **Smart modules**: Let Devalang detect and use groups, samples, and variables without needing to import them manually.
30
- - ⏳ **Other statements**: Implement `pattern`, and other control structures.
31
- - ⏳ **Testing**: Expand test coverage for all features.
34
+ - ⏳ **Other statements**: Implement `pattern`, and other control structures.
@@ -1,43 +1,60 @@
1
- # This file demonstrates general uses of Devalang.
1
+ # This file demonstrates general use cases of Devalang.
2
2
 
3
- bpm 120
3
+ # BPM definition
4
+ bpm 125
4
5
 
5
- group main:
6
- let lead = synth sine {
6
+ # Bank picking (make sure you have installed it)
7
+ bank devaloop.808 as my808Bank
8
+
9
+ group myGroup:
10
+ # Rhythmic (each beat playing a kick)
11
+ on beat:
12
+ .my808Bank.kick 1/4
13
+
14
+ # Synth definition with ADSR
15
+ let myLead = synth sine {
7
16
  attack: 0,
8
17
  decay: 100,
9
18
  sustain: 100,
10
19
  release: 100
11
20
  }
12
21
 
13
- # Global automation for this synth (applies to subsequent notes)
14
- automate lead:
15
- param volume {
16
- 0% = 0.0
17
- 100% = 1.0
18
- }
19
- param pan {
20
- 0% = -1.0
21
- 100% = 1.0
22
- }
23
- param pitch {
24
- 0% = -12.0
25
- 100% = 12.0
26
- }
27
-
28
- # Notes (per-note automation can override globals)
29
- lead -> note(C4, {
30
- duration: 400,
31
- velocity: 0.8,
32
- automate: {
33
- pan: {
34
- 0%: -1.0
35
- 100%: 0.0
36
- }
37
- }
38
- })
39
- lead -> note(E4, { duration: 400 })
40
- lead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
41
- lead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
42
-
43
- call main
22
+ # Global automation
23
+ automate myLead:
24
+ param volume {
25
+ 0% = 0.0
26
+ 100% = 0.5
27
+ }
28
+ param pitch {
29
+ 0% = -12.0
30
+ 100% = 12.0
31
+ }
32
+
33
+ # Notes in a loop with condition
34
+ for i in [1, 2, 3]:
35
+ if i == 3:
36
+ myLead -> note(C5, { duration: 200 })
37
+ print "Playing note C5 for " + i
38
+
39
+ # Pause runtime for 500ms
40
+ sleep 500
41
+
42
+ # Note with automation
43
+ myLead -> note(C4, {
44
+ duration: 400,
45
+ velocity: 0.8,
46
+ automate: {
47
+ pan: {
48
+ 0%: -1.0,
49
+ 100%: 0.0
50
+ }
51
+ }
52
+ })
53
+
54
+ # Notes with params
55
+ myLead -> note(E4, { duration: 400 })
56
+ myLead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
57
+ myLead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
58
+
59
+ # Calling the group to play it
60
+ call myGroup
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,37 @@
1
+ import { ParseResult } from "../types/result";
2
+ import { DebugResult } from "../types/result";
3
+ /**
4
+ * Parses the user code.
5
+ * @param entry_path The entry path for the code.
6
+ * @param source The source code to parse.
7
+ * @returns ParseResult | any
8
+ */
9
+ export declare function parse(entry_path: string, source: string): ParseResult | any;
10
+ /**
11
+ * Renders the debug information for the user code.
12
+ * @param user_code The user-provided code to render debug information for.
13
+ * @returns DebugResult | any
14
+ */
15
+ export declare function debug_render(user_code: string): DebugResult | any;
16
+ /**
17
+ * Renders audio from the user code.
18
+ * @param user_code The user-provided code to render audio from.
19
+ * @returns Float32Array
20
+ */
21
+ export declare function render_audio(user_code: string): Float32Array;
22
+ /**
23
+ * Register a JS callback to receive playhead events { time, line, column } during playback.
24
+ * The callback will be called with a single object argument.
25
+ * @param cb The callback function to register.
26
+ * @returns void
27
+ */
28
+ export declare function register_playhead_callback(cb: (ev: {
29
+ time: number;
30
+ line: number;
31
+ column: number;
32
+ }) => void): any;
33
+ /**
34
+ * Unregisters the JS callback for playhead events.
35
+ * @returns void
36
+ */
37
+ export declare function unregister_playhead_callback(): any;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parse = parse;
4
+ exports.debug_render = debug_render;
5
+ exports.render_audio = render_audio;
6
+ exports.register_playhead_callback = register_playhead_callback;
7
+ exports.unregister_playhead_callback = unregister_playhead_callback;
8
+ let wasmPkg = undefined;
9
+ try {
10
+ // prefer runtime pkg generated by wasm-pack when available
11
+ // require at runtime so the package can be used even if wasm hasn't been built
12
+ // (this keeps tests and consumers robust).
13
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
14
+ wasmPkg = require("../../pkg/devalang_core");
15
+ }
16
+ catch (_e) {
17
+ wasmPkg = undefined;
18
+ }
19
+ /**
20
+ * Parses the user code.
21
+ * @param entry_path The entry path for the code.
22
+ * @param source The source code to parse.
23
+ * @returns ParseResult | any
24
+ */
25
+ function parse(entry_path, source) {
26
+ if (wasmPkg && typeof wasmPkg.parse === "function") {
27
+ return wasmPkg.parse(entry_path, source);
28
+ }
29
+ throw new Error("WASM binding 'parse' not available. Build the wasm package or use the JS runtime.");
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
+ function debug_render(user_code) {
37
+ if (wasmPkg && typeof wasmPkg.debug_render === "function") {
38
+ return wasmPkg.debug_render(user_code);
39
+ }
40
+ throw new Error("WASM binding 'debug_render' not available. Build the wasm package or use the JS runtime.");
41
+ }
42
+ /**
43
+ * Renders audio from the user code.
44
+ * @param user_code The user-provided code to render audio from.
45
+ * @returns Float32Array
46
+ */
47
+ function render_audio(user_code) {
48
+ if (wasmPkg && typeof wasmPkg.render_audio === "function") {
49
+ return wasmPkg.render_audio(user_code);
50
+ }
51
+ // Fallback: indicate missing wasm with an empty buffer rather than breaking consumers.
52
+ return new Float32Array(0);
53
+ }
54
+ /**
55
+ * Register a JS callback to receive playhead events { time, line, column } during playback.
56
+ * The callback will be called with a single object argument.
57
+ * @param cb The callback function to register.
58
+ * @returns void
59
+ */
60
+ function register_playhead_callback(cb) {
61
+ if (wasmPkg && typeof wasmPkg.register_playhead_callback === "function") {
62
+ return wasmPkg.register_playhead_callback(cb);
63
+ }
64
+ // no-op fallback
65
+ return;
66
+ }
67
+ /**
68
+ * Unregisters the JS callback for playhead events.
69
+ * @returns void
70
+ */
71
+ function unregister_playhead_callback() {
72
+ if (wasmPkg && typeof wasmPkg.unregister_playhead_callback === "function") {
73
+ return wasmPkg.unregister_playhead_callback();
74
+ }
75
+ return;
76
+ }
@@ -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,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * Core functionality for the Devalang language.
19
+ * This module exports all the core types and functions used in the language.
20
+ */
21
+ __exportStar(require("./types/index"), exports);
22
+ __exportStar(require("./functions/index"), exports);
@@ -0,0 +1,4 @@
1
+ export * from "./result";
2
+ export * from "./statement";
3
+ export * from "./value";
4
+ export * from "./plugin";