@devaloop/devalang 0.0.1-alpha.16-hotfix.3 → 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 (232) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +6 -10
  3. package/.github/workflows/ci.yml +0 -1
  4. package/Cargo.toml +18 -2
  5. package/README.md +77 -32
  6. package/docs/CHANGELOG.md +46 -0
  7. package/docs/ROADMAP.md +7 -4
  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 -2
  61. package/rust/cli/{driver.rs → parser.rs} +7 -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.rs → telemetry/commands.rs} +4 -4
  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 +40 -42
  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/rust/cli/bank.rs +0 -462
  211. package/rust/cli/build.rs +0 -252
  212. package/rust/cli/play.rs +0 -1123
  213. package/rust/common/api.rs +0 -5
  214. package/rust/common/cdn.rs +0 -5
  215. package/rust/config/loader.rs +0 -165
  216. package/rust/config/stats.rs +0 -257
  217. package/rust/core/audio/engine.rs +0 -696
  218. package/rust/core/shared/bank.rs +0 -21
  219. package/rust/core/shared/duration.rs +0 -9
  220. package/rust/core/shared/mod.rs +0 -3
  221. package/rust/core/shared/value.rs +0 -35
  222. package/rust/core/utils/validation.rs +0 -35
  223. package/rust/installer/bank.rs +0 -62
  224. package/rust/installer/plugin.rs +0 -54
  225. package/rust/installer/utils.rs +0 -56
  226. package/rust/utils/file.rs +0 -38
  227. package/rust/utils/first_usage.rs +0 -83
  228. package/rust/utils/signature.rs +0 -19
  229. package/rust/utils/telemetry.rs +0 -292
  230. package/rust/utils/version.rs +0 -15
  231. /package/rust/{common → web}/mod.rs +0 -0
  232. /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
@@ -85,7 +85,6 @@ jobs:
85
85
  release:
86
86
  name: Create GitHub Release
87
87
  runs-on: ubuntu-latest
88
- if: startsWith(github.ref, 'refs/tags/')
89
88
  needs: build
90
89
  steps:
91
90
  - name: Download all build artifacts
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "devalang"
3
- version = "0.0.1-alpha.16-hotfix.3"
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,13 +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: [Devaforge is now available for creating addons](https://github.com/devaloop-labs/devaforge).
35
+ > **NEW**: [Devaforge is now available for creating addons](https://github.com/devaloop-labs/devaforge).
36
36
  >
37
- > NEW: Devalang is now available for **Windows**, **Linux**, and **macOS**.
37
+ > **NEW**: Now available for Windows, Linux, and macOS.
38
38
 
39
39
  ## 📚 Quick Access
40
40
 
@@ -52,24 +52,47 @@ From studio sketches to live sets, Devalang gives you rhythmic control — with
52
52
 
53
53
  ### Try Devalang in your browser
54
54
 
55
- > 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
56
 
57
- ### Try Devalang CLI
57
+ ### Try Devalang in your terminal
58
+
59
+ #### With Node.js
58
60
 
59
61
  ```bash
60
- # Install Devalang CLI globally
61
62
  npm install -g @devaloop/devalang@latest
63
+ ```
64
+
65
+ #### With Rust
66
+
67
+ ```bash
68
+ cargo install devalang
69
+ ```
62
70
 
63
- # Create a new Devalang project
71
+ #### Initialize a new project
72
+
73
+ ```bash
64
74
  devalang init --name my-project --template minimal
65
75
  ```
66
76
 
77
+ #### Write your first script
78
+
67
79
  Create a new Devalang file `src/index.deva` in the project directory:
68
80
 
69
81
  ```deva
70
82
  # src/index.deva
71
83
 
84
+ # BPM definition
85
+ bpm 125
86
+
87
+ # Bank picking (make sure you installed it)
88
+ bank devaloop.808 as my808Bank
89
+
72
90
  group myGroup:
91
+ # Rhythmic (each beat playing a kick)
92
+ on beat:
93
+ .my808Bank.kick 1/4
94
+
95
+ # Synth definition with ADSR
73
96
  let myLead = synth sine {
74
97
  attack: 0,
75
98
  decay: 100,
@@ -77,12 +100,27 @@ group myGroup:
77
100
  release: 100
78
101
  }
79
102
 
103
+ # Global automation
80
104
  automate myLead:
105
+ param volume {
106
+ 0% = 0.0
107
+ 100% = 0.5
108
+ }
81
109
  param pitch {
82
110
  0% = -12.0
83
111
  100% = 12.0
84
112
  }
85
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
86
124
  myLead -> note(C4, {
87
125
  duration: 400,
88
126
  velocity: 0.8,
@@ -94,27 +132,26 @@ group myGroup:
94
132
  }
95
133
  })
96
134
 
135
+ # Notes with params
97
136
  myLead -> note(E4, { duration: 400 })
98
137
  myLead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
99
138
  myLead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
100
139
 
101
- for i in [1, 2, 3]:
102
- myLead -> note(C5, { duration: 200 })
103
- print "Playing note C5 for " + i
104
-
140
+ # Calling the group to play it
105
141
  call myGroup
106
142
  ```
107
143
 
108
144
  ### And the best part ? You can play it directly from the command line:
109
145
 
146
+ #### Play the script once
147
+
110
148
  ```bash
111
- # Play the Devalang file
112
149
  devalang play
150
+ ```
113
151
 
114
- # Play the Devalang file with watch mode
115
- devalang play --watch
152
+ #### **LIVE mode** (repeat the playback + watch mode)
116
153
 
117
- # LIVE mode (repeat the playback + watch mode)
154
+ ```bash
118
155
  devalang play --repeat
119
156
  ```
120
157
 
@@ -124,7 +161,7 @@ devalang play --repeat
124
161
 
125
162
  ## ❓ Why Devalang ?
126
163
 
127
- - 🎹 Prototype audio ideas without opening a DAW, even VSCode
164
+ - 🎹 Prototype audio ideas without opening a DAW, even VSCode with our Playground
128
165
  - 💻 Integrate sound into code-based workflows
129
166
  - 🎛️ Control audio parameters through readable syntax
130
167
  - 🧪 Build musical logic with variables and conditions
@@ -132,31 +169,39 @@ devalang play --repeat
132
169
 
133
170
  ## 🚀 Features
134
171
 
135
- - 🎵 **Audio Engine**: Integrated audio playback and rendering
136
- - 🧩 **Module system** for importing and exporting variables between files
137
- - 📦 **Addon manager** for managing external banks, plugins and more
138
- - 📜 **Structured AST** generation for debugging and future compilation
139
- - 🔢 **Basic data types**: strings, numbers, booleans, maps, arrays
140
- - 👁️ **Watch mode** for `build`, `check` and `play` commands
141
- - 📂 **Project templates** for quick setup
142
- - 🎛️ **Custom samples**: easily load and trigger your own audio files
143
- - 🔄 **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.
144
186
 
145
187
  ## 📄 Documentation
146
188
 
147
- ### 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
148
190
 
149
- ## 🧯 Known issues
191
+ ## 📰 What's new
150
192
 
151
- - No smart modules yet, all groups, variables, and samples must be explicitly imported where used
152
- - 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.
153
199
 
154
200
  ## 🧪 Roadmap Highlights
155
201
 
156
202
  For more info, see [docs/ROADMAP.md](./docs/ROADMAP.md)
157
203
 
158
- - ⏳ Other statements (e.g `pattern`, ...)
159
- - ⏳ Addon generator
204
+ - ⏳ Smart modules
160
205
 
161
206
  ## 🛡️ License
162
207
 
package/docs/CHANGELOG.md CHANGED
@@ -4,6 +4,52 @@
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
+
7
53
  ## Version 0.0.1-alpha.16-hotfix.2 (2025-08-29)
8
54
 
9
55
  ### 🌎 Ecosystem
package/docs/ROADMAP.md CHANGED
@@ -22,10 +22,13 @@ Devalang is a work in progress. Here’s what we’re planning next:
22
22
  - ✅ **Sample loading**: Add `@load` assignment to load samples (.mp3, .wav) for use as values.
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
- - ✅ **Addon generator**: Implement addon generation for creating reusable plugins, banks and presets.
26
25
 
27
- ## Upcoming
26
+ ## In Progress
27
+
28
+ - ⏳ **Addon generator**: Implement addon generation for creating reusable plugins, banks and presets.
29
+ - ⏳ **Testing**: Expand test coverage for all features.
30
+
31
+ ## Planned
28
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";
@@ -0,0 +1,20 @@
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
+ __exportStar(require("./result"), exports);
18
+ __exportStar(require("./statement"), exports);
19
+ __exportStar(require("./value"), exports);
20
+ __exportStar(require("./plugin"), exports);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Represents a plugin export.
3
+ */
4
+ export interface PluginExport {
5
+ name: string;
6
+ kind: string;
7
+ default?: any;
8
+ }
9
+ /**
10
+ * Represents a plugin.
11
+ */
12
+ export interface PluginInfo {
13
+ author: string;
14
+ name: string;
15
+ version?: string;
16
+ description?: string;
17
+ exports: PluginExport[];
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,27 @@
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
+ * Represents the result of parsing user code.
11
+ */
12
+ export interface ParseResult {
13
+ ok: boolean;
14
+ ast: string;
15
+ errors: ErrorResult[];
16
+ }
17
+ /**
18
+ * Represents the result of debugging user code.
19
+ */
20
+ export interface DebugResult {
21
+ samples_len: number;
22
+ any_nonzero: boolean;
23
+ ast: string;
24
+ note_count: number;
25
+ global_vars: string[];
26
+ statements_count: number;
27
+ }