@devaloop/devalang 0.0.1-alpha.16-hotfix.3 → 0.0.1-alpha.18

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 (239) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +10 -10
  3. package/.github/workflows/ci.yml +0 -1
  4. package/Cargo.toml +18 -2
  5. package/README.md +82 -34
  6. package/docs/CHANGELOG.md +91 -0
  7. package/docs/ROADMAP.md +7 -4
  8. package/docs/TODO.md +1 -1
  9. package/examples/index.deva +55 -35
  10. package/examples/pattern.deva +5 -5
  11. package/out-tsc/bin/index.d.ts +2 -0
  12. package/out-tsc/core/functions/index.d.ts +37 -0
  13. package/out-tsc/core/functions/index.js +76 -0
  14. package/out-tsc/core/index.d.ts +6 -0
  15. package/out-tsc/core/index.js +22 -0
  16. package/out-tsc/core/types/index.d.ts +4 -0
  17. package/out-tsc/core/types/index.js +20 -0
  18. package/out-tsc/core/types/plugin.d.ts +18 -0
  19. package/out-tsc/core/types/plugin.js +2 -0
  20. package/out-tsc/core/types/result.d.ts +27 -0
  21. package/out-tsc/core/types/result.js +2 -0
  22. package/out-tsc/core/types/statement.d.ts +106 -0
  23. package/out-tsc/core/types/statement.js +2 -0
  24. package/out-tsc/core/types/value.d.ts +43 -0
  25. package/out-tsc/core/types/value.js +2 -0
  26. package/out-tsc/index.d.ts +7 -0
  27. package/out-tsc/index.js +41 -2
  28. package/out-tsc/pkg/devalang_core.d.ts +7 -0
  29. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  30. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  31. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  32. package/out-tsc/scripts/postinstall.d.ts +1 -0
  33. package/out-tsc/scripts/postinstall.js +33 -23
  34. package/out-tsc/scripts/version/bump.d.ts +1 -0
  35. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  36. package/out-tsc/scripts/version/index.d.ts +1 -0
  37. package/out-tsc/scripts/version/sync.d.ts +1 -0
  38. package/package.json +16 -4
  39. package/project-version.json +3 -3
  40. package/rust/cli/bank/api.rs +122 -0
  41. package/rust/cli/bank/commands.rs +275 -0
  42. package/rust/cli/bank/mod.rs +29 -0
  43. package/rust/cli/build/commands.rs +107 -0
  44. package/rust/cli/build/mod.rs +2 -0
  45. package/rust/cli/build/process.rs +146 -0
  46. package/rust/cli/{check.rs → check/mod.rs} +18 -31
  47. package/rust/cli/discover/commands.rs +253 -0
  48. package/rust/cli/discover/config.rs +111 -0
  49. package/rust/cli/discover/fs.rs +19 -0
  50. package/rust/cli/discover/install.rs +103 -0
  51. package/rust/cli/discover/metadata.rs +48 -0
  52. package/rust/cli/discover/mod.rs +5 -0
  53. package/rust/cli/{init.rs → init/commands.rs} +88 -87
  54. package/rust/cli/init/mod.rs +1 -0
  55. package/rust/cli/install/addon.rs +126 -0
  56. package/rust/cli/install/bank.rs +53 -0
  57. package/rust/cli/{install.rs → install/commands.rs} +9 -9
  58. package/rust/{installer → cli/install}/mod.rs +2 -3
  59. package/rust/cli/install/plugin.rs +61 -0
  60. package/rust/cli/{login.rs → login/commands.rs} +8 -11
  61. package/rust/cli/login/mod.rs +1 -0
  62. package/rust/cli/mod.rs +2 -2
  63. package/rust/cli/{driver.rs → parser.rs} +7 -2
  64. package/rust/cli/play/commands.rs +324 -0
  65. package/rust/cli/play/io.rs +17 -0
  66. package/rust/cli/play/mod.rs +5 -0
  67. package/rust/cli/play/process.rs +150 -0
  68. package/rust/cli/play/realtime.rs +91 -0
  69. package/rust/cli/play/utils.rs +23 -0
  70. package/rust/cli/{telemetry.rs → telemetry/commands.rs} +4 -4
  71. package/rust/cli/telemetry/event_creator.rs +80 -0
  72. package/rust/cli/telemetry/mod.rs +3 -0
  73. package/rust/cli/telemetry/send.rs +51 -0
  74. package/rust/cli/{template.rs → template/commands.rs} +1 -1
  75. package/rust/cli/template/mod.rs +1 -0
  76. package/rust/cli/{update.rs → update/commands.rs} +6 -6
  77. package/rust/cli/update/mod.rs +1 -0
  78. package/rust/config/driver.rs +57 -72
  79. package/rust/config/mod.rs +1 -2
  80. package/rust/config/ops.rs +26 -0
  81. package/rust/config/settings.rs +40 -42
  82. package/rust/core/audio/engine/helpers.rs +158 -0
  83. package/rust/core/audio/engine/mod.rs +7 -0
  84. package/rust/core/audio/engine/sample.rs +359 -0
  85. package/rust/core/audio/engine/synth.rs +325 -0
  86. package/rust/core/audio/evaluator.rs +68 -27
  87. package/rust/core/audio/interpreter/arrow_call.rs +113 -33
  88. package/rust/core/audio/interpreter/call.rs +232 -56
  89. package/rust/core/audio/interpreter/condition.rs +3 -2
  90. package/rust/core/audio/interpreter/driver.rs +206 -151
  91. package/rust/core/audio/interpreter/let_.rs +1 -1
  92. package/rust/core/audio/interpreter/load.rs +2 -1
  93. package/rust/core/audio/interpreter/loop_.rs +7 -6
  94. package/rust/core/audio/interpreter/sleep.rs +2 -1
  95. package/rust/core/audio/interpreter/spawn.rs +186 -54
  96. package/rust/core/audio/interpreter/tempo.rs +31 -10
  97. package/rust/core/audio/interpreter/trigger.rs +2 -2
  98. package/rust/core/audio/loader/trigger.rs +4 -7
  99. package/rust/core/audio/player.rs +6 -0
  100. package/rust/core/audio/renderer.rs +5 -7
  101. package/rust/core/audio/special/env.rs +3 -1
  102. package/rust/core/audio/special/math.rs +26 -6
  103. package/rust/core/audio/special/modulator.rs +2 -2
  104. package/rust/core/builder/mod.rs +9 -3
  105. package/rust/core/debugger/lexer.rs +1 -1
  106. package/rust/core/debugger/mod.rs +6 -0
  107. package/rust/core/debugger/module.rs +4 -4
  108. package/rust/core/debugger/preprocessor.rs +1 -1
  109. package/rust/core/debugger/store.rs +2 -2
  110. package/rust/core/error/mod.rs +189 -0
  111. package/rust/core/lexer/driver.rs +61 -0
  112. package/rust/core/lexer/handler/arrow.rs +1 -1
  113. package/rust/core/lexer/handler/at.rs +1 -1
  114. package/rust/core/lexer/handler/brace.rs +2 -2
  115. package/rust/core/lexer/handler/colon.rs +1 -1
  116. package/rust/core/lexer/handler/comment.rs +1 -1
  117. package/rust/core/lexer/handler/dot.rs +1 -1
  118. package/rust/core/lexer/handler/driver.rs +1 -1
  119. package/rust/core/lexer/handler/identifier.rs +4 -3
  120. package/rust/core/lexer/handler/mod.rs +1 -2
  121. package/rust/core/lexer/handler/number.rs +1 -1
  122. package/rust/core/lexer/handler/operator.rs +1 -1
  123. package/rust/core/lexer/handler/parenthesis.rs +2 -2
  124. package/rust/core/lexer/handler/slash.rs +1 -1
  125. package/rust/core/lexer/handler/string.rs +1 -1
  126. package/rust/core/lexer/mod.rs +1 -52
  127. package/rust/core/lexer/token.rs +91 -97
  128. package/rust/core/mod.rs +0 -1
  129. package/rust/core/parser/driver.rs +78 -22
  130. package/rust/core/parser/handler/arrow_call.rs +28 -8
  131. package/rust/core/parser/handler/at.rs +55 -21
  132. package/rust/core/parser/handler/bank.rs +14 -4
  133. package/rust/core/parser/handler/condition.rs +6 -3
  134. package/rust/core/parser/handler/dot.rs +5 -3
  135. package/rust/core/parser/handler/identifier/automate.rs +13 -16
  136. package/rust/core/parser/handler/identifier/call.rs +4 -4
  137. package/rust/core/parser/handler/identifier/emit.rs +9 -5
  138. package/rust/core/parser/handler/identifier/function.rs +20 -7
  139. package/rust/core/parser/handler/identifier/group.rs +11 -7
  140. package/rust/core/parser/handler/identifier/let_.rs +24 -9
  141. package/rust/core/parser/handler/identifier/mod.rs +6 -5
  142. package/rust/core/parser/handler/identifier/on.rs +16 -7
  143. package/rust/core/parser/handler/identifier/print.rs +6 -9
  144. package/rust/core/parser/handler/identifier/sleep.rs +12 -5
  145. package/rust/core/parser/handler/identifier/spawn.rs +4 -4
  146. package/rust/core/parser/handler/identifier/synth.rs +79 -9
  147. package/rust/core/parser/handler/loop_.rs +38 -13
  148. package/rust/core/parser/handler/mod.rs +1 -0
  149. package/rust/core/parser/handler/pattern.rs +74 -0
  150. package/rust/core/parser/handler/tempo.rs +9 -5
  151. package/rust/core/parser/mod.rs +0 -1
  152. package/rust/core/parser/statement.rs +6 -137
  153. package/rust/core/plugin/loader.rs +41 -27
  154. package/rust/core/plugin/runner.rs +68 -17
  155. package/rust/core/preprocessor/loader.rs +181 -99
  156. package/rust/core/preprocessor/processor.rs +9 -9
  157. package/rust/core/preprocessor/resolver/bank.rs +6 -8
  158. package/rust/core/preprocessor/resolver/call.rs +47 -23
  159. package/rust/core/preprocessor/resolver/condition.rs +6 -8
  160. package/rust/core/preprocessor/resolver/driver.rs +28 -28
  161. package/rust/core/preprocessor/resolver/function.rs +6 -6
  162. package/rust/core/preprocessor/resolver/group.rs +6 -8
  163. package/rust/core/preprocessor/resolver/loop_.rs +8 -10
  164. package/rust/core/preprocessor/resolver/mod.rs +1 -0
  165. package/rust/core/preprocessor/resolver/pattern.rs +75 -0
  166. package/rust/core/preprocessor/resolver/spawn.rs +45 -22
  167. package/rust/core/preprocessor/resolver/synth.rs +6 -8
  168. package/rust/core/preprocessor/resolver/tempo.rs +6 -8
  169. package/rust/core/preprocessor/resolver/trigger.rs +22 -19
  170. package/rust/core/preprocessor/resolver/value.rs +99 -4
  171. package/rust/core/store/export.rs +28 -28
  172. package/rust/core/store/function.rs +6 -0
  173. package/rust/core/store/global.rs +7 -1
  174. package/rust/core/store/import.rs +28 -28
  175. package/rust/core/store/variable.rs +16 -2
  176. package/rust/core/utils/mod.rs +0 -1
  177. package/rust/lib.rs +102 -9
  178. package/rust/main.rs +159 -45
  179. package/rust/types/Cargo.toml +11 -0
  180. package/rust/types/src/addons.rs +55 -0
  181. package/rust/types/src/ast.rs +202 -0
  182. package/rust/types/src/config.rs +74 -0
  183. package/rust/types/src/lib.rs +12 -0
  184. package/rust/types/src/telemetry.rs +85 -0
  185. package/rust/utils/Cargo.toml +26 -0
  186. package/rust/utils/{error.rs → src/error.rs} +186 -200
  187. package/rust/utils/src/file.rs +94 -0
  188. package/rust/utils/src/first_usage.rs +97 -0
  189. package/rust/utils/{mod.rs → src/lib.rs} +1 -1
  190. package/rust/utils/{logger.rs → src/logger.rs} +17 -12
  191. package/rust/utils/src/path.rs +88 -0
  192. package/rust/utils/src/signature.rs +41 -0
  193. package/rust/utils/{spinner.rs → src/spinner.rs} +3 -5
  194. package/rust/utils/src/version.rs +27 -0
  195. package/rust/utils/{watcher.rs → src/watcher.rs} +13 -1
  196. package/rust/web/cdn.rs +34 -0
  197. package/templates/minimal/README.md +98 -54
  198. package/templates/welcome/README.md +98 -54
  199. package/templates/welcome/src/index.deva +56 -8
  200. package/templates/welcome/src/variables.deva +2 -4
  201. package/tests/rust/TODO.md +0 -0
  202. package/tests/typescript/index.spec.ts +136 -0
  203. package/tests/typescript/playhead.spec.ts +36 -0
  204. package/tests/typescript/render_e2e.spec.ts +77 -0
  205. package/tsconfig.json +1 -1
  206. package/typescript/core/functions/index.ts +83 -0
  207. package/typescript/core/index.ts +6 -0
  208. package/typescript/core/types/index.ts +4 -0
  209. package/typescript/core/types/plugin.ts +19 -0
  210. package/typescript/core/types/result.ts +29 -0
  211. package/typescript/core/types/statement.ts +47 -0
  212. package/typescript/core/types/value.ts +29 -0
  213. package/typescript/index.ts +7 -2
  214. package/typescript/pkg/devalang_core.d.ts +4 -0
  215. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  216. package/rust/cli/bank.rs +0 -462
  217. package/rust/cli/build.rs +0 -252
  218. package/rust/cli/play.rs +0 -1123
  219. package/rust/common/cdn.rs +0 -5
  220. package/rust/config/loader.rs +0 -165
  221. package/rust/config/stats.rs +0 -257
  222. package/rust/core/audio/engine.rs +0 -696
  223. package/rust/core/shared/bank.rs +0 -21
  224. package/rust/core/shared/duration.rs +0 -9
  225. package/rust/core/shared/mod.rs +0 -3
  226. package/rust/core/shared/value.rs +0 -35
  227. package/rust/core/utils/validation.rs +0 -35
  228. package/rust/installer/addon.rs +0 -84
  229. package/rust/installer/bank.rs +0 -62
  230. package/rust/installer/plugin.rs +0 -54
  231. package/rust/installer/utils.rs +0 -56
  232. package/rust/utils/file.rs +0 -38
  233. package/rust/utils/first_usage.rs +0 -83
  234. package/rust/utils/signature.rs +0 -19
  235. package/rust/utils/telemetry.rs +0 -292
  236. package/rust/utils/version.rs +0 -15
  237. /package/rust/{common → web}/api.rs +0 -0
  238. /package/rust/{common → web}/mod.rs +0 -0
  239. /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,10 @@
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
7
+
8
+ [[banks]]
9
+ path = "devalang://bank/devaloop.808"
10
+ version = "0.0.1"
@@ -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.18"
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", version = "0.0.1" }
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, version = "0.0.1" }
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"], version = "0.0.1" }
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,50 @@ 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've installed it)
88
+ bank devaloop.808 as my808Bank
89
+
90
+ # Pattern literal without options
91
+ pattern kickPattern with my808Bank.kick = "x--- x--- x--- x---"
92
+
72
93
  group myGroup:
94
+ # Rhythmic (each beat playing a kick)
95
+ # on beat:
96
+ # .my808Bank.kick 1/4
97
+
98
+ # Synth definition with ADSR
73
99
  let myLead = synth sine {
74
100
  attack: 0,
75
101
  decay: 100,
@@ -77,12 +103,27 @@ group myGroup:
77
103
  release: 100
78
104
  }
79
105
 
106
+ # Global automation
80
107
  automate myLead:
108
+ param volume {
109
+ 0% = 0.0
110
+ 100% = 0.5
111
+ }
81
112
  param pitch {
82
113
  0% = -12.0
83
114
  100% = 12.0
84
115
  }
85
116
 
117
+ # Notes in a loop with condition
118
+ for i in [1, 2, 3]:
119
+ if i == 3:
120
+ myLead -> note(C5, { duration: 200 })
121
+ print "Playing note C5 for " + i
122
+
123
+ # Pause runtime for 500ms
124
+ sleep 500
125
+
126
+ # Note with automation
86
127
  myLead -> note(C4, {
87
128
  duration: 400,
88
129
  velocity: 0.8,
@@ -94,27 +135,26 @@ group myGroup:
94
135
  }
95
136
  })
96
137
 
97
- myLead -> note(E4, { duration: 400 })
138
+ # Notes with params
98
139
  myLead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
99
140
  myLead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
100
141
 
101
- for i in [1, 2, 3]:
102
- myLead -> note(C5, { duration: 200 })
103
- print "Playing note C5 for " + i
104
-
105
- call myGroup
142
+ # Spawning the group & the pattern to play them in parallel
143
+ spawn myGroup
144
+ spawn kickPattern
106
145
  ```
107
146
 
108
147
  ### And the best part ? You can play it directly from the command line:
109
148
 
149
+ #### Play the script once
150
+
110
151
  ```bash
111
- # Play the Devalang file
112
152
  devalang play
153
+ ```
113
154
 
114
- # Play the Devalang file with watch mode
115
- devalang play --watch
155
+ #### **LIVE mode** (repeat the playback + watch mode)
116
156
 
117
- # LIVE mode (repeat the playback + watch mode)
157
+ ```bash
118
158
  devalang play --repeat
119
159
  ```
120
160
 
@@ -124,7 +164,7 @@ devalang play --repeat
124
164
 
125
165
  ## ❓ Why Devalang ?
126
166
 
127
- - 🎹 Prototype audio ideas without opening a DAW, even VSCode
167
+ - 🎹 Prototype audio ideas without opening a DAW, even VSCode with our Playground
128
168
  - 💻 Integrate sound into code-based workflows
129
169
  - 🎛️ Control audio parameters through readable syntax
130
170
  - 🧪 Build musical logic with variables and conditions
@@ -132,31 +172,39 @@ devalang play --repeat
132
172
 
133
173
  ## 🚀 Features
134
174
 
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
175
+ - **Fast Build & Hot Reload** optimized build process for quicker iteration.
176
+ - 🎵 **Audio Engine & Real-time runner** low-latency playback, render-to-file, and a realtime runner used by `devalang play` for live feedback.
177
+ - ▶️ **Live mode (watch + repeat)** edit and hear changes instantly with `devalang play --repeat` and watch mode.
178
+ - 🧩 **Language primitives** synths, notes, ADSR, maps, arrays, loops, conditionals and functions for expressive musical logic.
179
+ - 🎛️ **Per-note automation & modulators** `automate` maps, `$mod.*`, `$easing.*` and `$math.*` helpers for envelopes and LFOs.
180
+ - 🧩 **Module system & structured AST** — import/export variables, stable AST output for debugging and tooling.
181
+ - 🧰 **Plugins & Addons (WASM-ready)** install plugins/banks, `@use` directive, and WASM plugin integration so plugins can render or process audio at runtime.
182
+ - 📦 **Addon manager & Devaforge** — CLI commands to discover/install banks, plugins and templates; `devaforge` helps create addons.
183
+ - ⚙️ **CLI tooling** `build`, `check`, `play`, `install`, `init`, `discover`, `telemetry` and more with consistent flags (`--watch`, `--debug`, `--compress`).
184
+ - 📂 **Project templates & examples** — quick-start templates and many example projects in `examples/`.
185
+ - 🧑‍💻 **TypeScript API & WASM distribution** — Node-friendly package with TypeScript bindings and a WASM build for browser/Node usage.
186
+ - 🧰 **Editor & formatting support** — VSCode extension and Prettier plugin to edit Devalang with syntax and formatting support.
187
+ - 🎵 **Custom samples & banks** — drop samples into `.deva` and reference them from code; banks of sounds for fast composition.
188
+ - 🔄 **Looping, grouping & scheduling** — precise beat-tied scheduling primitives for complex rhythmic patterns.
144
189
 
145
190
  ## 📄 Documentation
146
191
 
147
- ### Please refer to the [online documentation](https://docs.devalang.com) for detailed information on syntax, features, and usage examples
192
+ ### [Please refer to the online documentation](https://docs.devalang.com) for detailed information on syntax, features, and usage examples
148
193
 
149
- ## 🧯 Known issues
194
+ ## 📰 What's new
150
195
 
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)
196
+ - **Devaforge**: Introduced a new system for creating and managing addons, including a CLI for addon generation.
197
+ - **Documentation updates**: Improved documentation for clarity and completeness.
198
+ - **Discovering addons**: Introduced a new command to detect addons.
199
+ - **Public TypeScript API**: Added a public TypeScript API for easier integration.
200
+ - **Improved error messages**: Enhanced error messages for better debugging.
201
+ - **Bug fixes**: Various bug fixes and stability improvements.
153
202
 
154
203
  ## 🧪 Roadmap Highlights
155
204
 
156
205
  For more info, see [docs/ROADMAP.md](./docs/ROADMAP.md)
157
206
 
158
- - ⏳ Other statements (e.g `pattern`, ...)
159
- - ⏳ Addon generator
207
+ - ⏳ Smart modules
160
208
 
161
209
  ## 🛡️ License
162
210
 
package/docs/CHANGELOG.md CHANGED
@@ -4,6 +4,97 @@
4
4
 
5
5
  # Changelog
6
6
 
7
+ ## Version 0.0.1-alpha.18 (2025-09-02)
8
+
9
+ ### ✨ Language Features
10
+
11
+ - New `pattern` statement to define rhythmic patterns with an optional target entity.
12
+ - Example: `pattern kickPattern with my808.kick = "x--- x--- x--- x---"`
13
+ - Patterns can be invoked with `call` or `spawn` just like functions or groups.
14
+
15
+ ### 🧠 Core Engine
16
+
17
+ - Pattern playback: schedules steps across one bar (4 beats), computing per-step duration and triggering the target on non-rest characters.
18
+ - ADSR envelope: improved interpolation at segment boundaries to avoid clicks and handle 0/1-sample edge cases.
19
+ - Sample engine: robust stereo-to-mono mixdown with RMS-preserving scaling; applies a tiny automatic fade (~1 ms) when samples start/end abruptly to reduce clicks.
20
+
21
+ ### 🧩 Parser & Lexer
22
+
23
+ - Added `Pattern` token and parser handler; supports `pattern <name> [with <bank.trigger>] = "..."`.
24
+ - Introduced a dedicated lexer driver (`rust/core/lexer/driver.rs`) to separate file resolution from tokenization.
25
+ - Map/array parsing now logs structured errors via the shared logger instead of printing to stdout.
26
+
27
+ ### 🔁 Preprocessor & Resolution
28
+
29
+ - Pattern resolver stores definitions in the variable table, enabling later `call`/`spawn` usage.
30
+ - Variable lookup now walks parent scopes, fixing missed resolutions for outer-scope identifiers.
31
+
32
+ ### 🛠️ CLI & Telemetry
33
+
34
+ - `build`: non-watch mode now executes and surfaces errors correctly.
35
+ - `install`: requires authentication and reports API/JSON errors with clear messages.
36
+ - Telemetry: generates a stable UUID when missing; consistently records CLI version, OS, and args.
37
+ - Ensures the `.deva` directory exists at startup.
38
+
39
+ ### 📚 Examples
40
+
41
+ - Added `examples/pattern.deva`; updated `examples/index.deva` to demonstrate `pattern` and `spawn`.
42
+
43
+ ### 📦 Packaging
44
+
45
+ - Added crate metadata (description, license, authors) and pinned internal versions for `devalang_types` and `devalang_utils`.
46
+
47
+ ### 🐛 Fixes & Stability
48
+
49
+ - Safer `$math` parsing with diagnostics for malformed calls and argument evaluation failures.
50
+ - Minor parser fixes (loop body collection, clearer error messages) and logging cleanups across modules.
51
+
52
+ ## Version 0.0.1-alpha.17 (2025-08-30)
53
+
54
+ ### ✨ Addons
55
+
56
+ - Discovering addons: use the CLI to discover plugins or banks : place compiled addons (.devabank, .devaplugin) anywhere into your `.deva` folder, then run:
57
+
58
+ ```bash
59
+ devalang discover
60
+ ```
61
+
62
+ - Installing external addons: use the CLI to install addons:
63
+
64
+ ```bash
65
+ devalang install <plugin | bank> user.myPlugin
66
+ ```
67
+
68
+ - Plugin usage: you can now reference installed plugins directly from Devalang source
69
+ using the `@use` directive and an optional alias. Examples:
70
+
71
+ - `@use user.myPlugin` — exposes the plugin under its default name
72
+ - `@use user.myPlugin as myAlias` — expose the plugin as `myAlias` for shorter calls
73
+
74
+ ### 🧩 Packaging & TypeScript
75
+
76
+ - Improved packaging and postinstall logic for the TypeScript/WASM distribution; the
77
+ Node package now avoids hard-failing when optional native binaries are not available.
78
+ - `out-tsc` postinstall now performs guarded downloads and better logging to help consumers diagnose installation issues on CI or constrained environments.
79
+
80
+ ### 🧠 Architecture & Refactor
81
+
82
+ - 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.
83
+ - 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.
84
+ - Modularized CLI features, clean separation between build/process, realtime runner, IO helpers and stats collection.
85
+
86
+ ### 🐛 Bug fixes & stability
87
+
88
+ - Multiple robustness fixes across the parser, preprocessor and audio engine:
89
+ - dotted identifiers and synth/provider resolution improvements,
90
+ - safer path resolution for `.deva` resources (banks, plugins, presets),
91
+ - improved error collection and logging with annotated stacks for better debug output.
92
+ - Audio runtime: better BPM/duration estimation and loop handling in the realtime runner to avoid premature termination of periodic handlers while loops execute.
93
+
94
+ ### 🧪 Tests & CI
95
+
96
+ - 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.)
97
+
7
98
  ## Version 0.0.1-alpha.16-hotfix.2 (2025-08-29)
8
99
 
9
100
  ### 🌎 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.
package/docs/TODO.md CHANGED
@@ -73,7 +73,7 @@ This is a list of tasks and features to be implemented in Devalang. Note that th
73
73
 
74
74
  ## Addon generator
75
75
 
76
- - [ ] Implement addon generator
76
+ - [x] Implement addon generator
77
77
  - [ ] Create example addons
78
78
 
79
79
  ## Other TODOs
@@ -1,43 +1,63 @@
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've installed it)
7
+ bank devaloop.808 as my808Bank
8
+
9
+ # Pattern literal without options
10
+ pattern kickPattern with my808Bank.kick = "x--- x--- x--- x---"
11
+
12
+ group myGroup:
13
+ # Rhythmic (each beat playing a kick)
14
+ # on beat:
15
+ # .my808Bank.kick 1/4
16
+
17
+ # Synth definition with ADSR
18
+ let myLead = synth sine {
7
19
  attack: 0,
8
20
  decay: 100,
9
21
  sustain: 100,
10
22
  release: 100
11
23
  }
12
24
 
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
25
+ # Global automation
26
+ automate myLead:
27
+ param volume {
28
+ 0% = 0.0
29
+ 100% = 0.5
30
+ }
31
+ param pitch {
32
+ 0% = -12.0
33
+ 100% = 12.0
34
+ }
35
+
36
+ # Notes in a loop with condition
37
+ for i in [1, 2, 3]:
38
+ if i == 3:
39
+ myLead -> note(C5, { duration: 200 })
40
+ print "Playing note C5 for " + i
41
+
42
+ # Pause runtime for 500ms
43
+ sleep 500
44
+
45
+ # Note with automation
46
+ myLead -> note(C4, {
47
+ duration: 400,
48
+ velocity: 0.8,
49
+ automate: {
50
+ pan: {
51
+ 0%: -1.0,
52
+ 100%: 0.0
53
+ }
54
+ }
55
+ })
56
+
57
+ # Notes with params
58
+ myLead -> note(G4, { duration: 600, glide: true, target_freq: 659.25 })
59
+ myLead -> note(B3, { duration: 400, slide: true, target_amp: 0.3 })
60
+
61
+ # Spawning the group & the pattern to play them in parallel
62
+ spawn myGroup
63
+ spawn kickPattern
@@ -1,8 +1,8 @@
1
- # TODO planned for future release
1
+ # This file demonstrates the usage of patterns in Devaloop
2
2
 
3
- # bank devaloop.808 as 808
3
+ bank devaloop.808 as my808
4
4
 
5
- # # Pattern literal without options
6
- # pattern kickPattern with 808.kick = "x--- x--- x--- x---"
5
+ # Pattern literal without options
6
+ pattern kickPattern with my808.kick = "x--- x--- x--- x---"
7
7
 
8
- # call kickPattern
8
+ call kickPattern
@@ -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";