@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.
- package/.cargo/config.toml +2 -0
- package/.devalang +6 -10
- package/.github/workflows/ci.yml +19 -8
- package/Cargo.toml +18 -2
- package/README.md +80 -33
- package/docs/CHANGELOG.md +56 -0
- package/docs/ROADMAP.md +6 -3
- package/examples/index.deva +52 -35
- package/out-tsc/bin/index.d.ts +2 -0
- package/out-tsc/core/functions/index.d.ts +37 -0
- package/out-tsc/core/functions/index.js +76 -0
- package/out-tsc/core/index.d.ts +6 -0
- package/out-tsc/core/index.js +22 -0
- package/out-tsc/core/types/index.d.ts +4 -0
- package/out-tsc/core/types/index.js +20 -0
- package/out-tsc/core/types/plugin.d.ts +18 -0
- package/out-tsc/core/types/plugin.js +2 -0
- package/out-tsc/core/types/result.d.ts +27 -0
- package/out-tsc/core/types/result.js +2 -0
- package/out-tsc/core/types/statement.d.ts +106 -0
- package/out-tsc/core/types/statement.js +2 -0
- package/out-tsc/core/types/value.d.ts +43 -0
- package/out-tsc/core/types/value.js +2 -0
- package/out-tsc/index.d.ts +7 -0
- package/out-tsc/index.js +41 -2
- package/out-tsc/pkg/devalang_core.d.ts +7 -0
- package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
- package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
- package/out-tsc/scripts/copy-wasm-dts.js +73 -0
- package/out-tsc/scripts/postinstall.d.ts +1 -0
- package/out-tsc/scripts/postinstall.js +33 -23
- package/out-tsc/scripts/version/bump.d.ts +1 -0
- package/out-tsc/scripts/version/fetch.d.ts +1 -0
- package/out-tsc/scripts/version/index.d.ts +1 -0
- package/out-tsc/scripts/version/sync.d.ts +1 -0
- package/package.json +16 -4
- package/project-version.json +3 -3
- package/rust/cli/bank/api.rs +122 -0
- package/rust/cli/bank/commands.rs +275 -0
- package/rust/cli/bank/mod.rs +29 -0
- package/rust/cli/build/commands.rs +97 -0
- package/rust/cli/build/mod.rs +2 -0
- package/rust/cli/build/process.rs +146 -0
- package/rust/cli/{check.rs → check/mod.rs} +18 -31
- package/rust/cli/discover/commands.rs +253 -0
- package/rust/cli/discover/config.rs +111 -0
- package/rust/cli/discover/fs.rs +19 -0
- package/rust/cli/discover/install.rs +103 -0
- package/rust/cli/discover/metadata.rs +48 -0
- package/rust/cli/discover/mod.rs +5 -0
- package/rust/cli/{init.rs → init/commands.rs} +88 -87
- package/rust/cli/init/mod.rs +1 -0
- package/rust/{installer → cli/install}/addon.rs +5 -9
- package/rust/cli/install/bank.rs +53 -0
- package/rust/cli/{install.rs → install/commands.rs} +9 -9
- package/rust/{installer → cli/install}/mod.rs +2 -3
- package/rust/cli/install/plugin.rs +61 -0
- package/rust/cli/{login.rs → login/commands.rs} +8 -11
- package/rust/cli/login/mod.rs +1 -0
- package/rust/cli/mod.rs +2 -3
- package/rust/cli/{driver.rs → parser.rs} +19 -2
- package/rust/cli/play/commands.rs +324 -0
- package/rust/cli/play/io.rs +17 -0
- package/rust/cli/play/mod.rs +5 -0
- package/rust/cli/play/process.rs +150 -0
- package/rust/cli/play/realtime.rs +91 -0
- package/rust/cli/play/utils.rs +23 -0
- package/rust/cli/telemetry/commands.rs +22 -0
- package/rust/cli/telemetry/event_creator.rs +80 -0
- package/rust/cli/telemetry/mod.rs +3 -0
- package/rust/cli/telemetry/send.rs +51 -0
- package/rust/cli/{template.rs → template/commands.rs} +1 -1
- package/rust/cli/template/mod.rs +1 -0
- package/rust/cli/{update.rs → update/commands.rs} +6 -6
- package/rust/cli/update/mod.rs +1 -0
- package/rust/config/driver.rs +57 -72
- package/rust/config/mod.rs +1 -2
- package/rust/config/ops.rs +26 -0
- package/rust/config/settings.rs +60 -50
- package/rust/core/audio/engine/helpers.rs +146 -0
- package/rust/core/audio/engine/mod.rs +7 -0
- package/rust/core/audio/engine/sample.rs +298 -0
- package/rust/core/audio/engine/synth.rs +310 -0
- package/rust/core/audio/evaluator.rs +15 -12
- package/rust/core/audio/interpreter/arrow_call.rs +99 -24
- package/rust/core/audio/interpreter/call.rs +81 -60
- package/rust/core/audio/interpreter/condition.rs +3 -2
- package/rust/core/audio/interpreter/driver.rs +206 -151
- package/rust/core/audio/interpreter/let_.rs +1 -1
- package/rust/core/audio/interpreter/load.rs +2 -1
- package/rust/core/audio/interpreter/loop_.rs +7 -6
- package/rust/core/audio/interpreter/sleep.rs +2 -1
- package/rust/core/audio/interpreter/spawn.rs +45 -57
- package/rust/core/audio/interpreter/tempo.rs +31 -10
- package/rust/core/audio/interpreter/trigger.rs +2 -2
- package/rust/core/audio/loader/trigger.rs +4 -7
- package/rust/core/audio/player.rs +6 -0
- package/rust/core/audio/renderer.rs +5 -7
- package/rust/core/audio/special/env.rs +3 -1
- package/rust/core/audio/special/math.rs +4 -4
- package/rust/core/audio/special/modulator.rs +2 -2
- package/rust/core/builder/mod.rs +9 -3
- package/rust/core/debugger/lexer.rs +1 -1
- package/rust/core/debugger/mod.rs +6 -0
- package/rust/core/debugger/module.rs +4 -4
- package/rust/core/debugger/preprocessor.rs +1 -1
- package/rust/core/debugger/store.rs +2 -2
- package/rust/core/error/mod.rs +189 -0
- package/rust/core/lexer/handler/arrow.rs +1 -1
- package/rust/core/lexer/handler/at.rs +1 -1
- package/rust/core/lexer/handler/brace.rs +2 -2
- package/rust/core/lexer/handler/colon.rs +1 -1
- package/rust/core/lexer/handler/comment.rs +1 -1
- package/rust/core/lexer/handler/dot.rs +1 -1
- package/rust/core/lexer/handler/driver.rs +1 -1
- package/rust/core/lexer/handler/identifier.rs +1 -1
- package/rust/core/lexer/handler/mod.rs +1 -2
- package/rust/core/lexer/handler/number.rs +1 -1
- package/rust/core/lexer/handler/operator.rs +1 -1
- package/rust/core/lexer/handler/parenthesis.rs +2 -2
- package/rust/core/lexer/handler/slash.rs +1 -1
- package/rust/core/lexer/handler/string.rs +1 -1
- package/rust/core/lexer/mod.rs +22 -12
- package/rust/core/lexer/token.rs +90 -97
- package/rust/core/mod.rs +0 -1
- package/rust/core/parser/driver.rs +66 -13
- package/rust/core/parser/handler/arrow_call.rs +28 -8
- package/rust/core/parser/handler/at.rs +55 -21
- package/rust/core/parser/handler/bank.rs +14 -4
- package/rust/core/parser/handler/condition.rs +6 -3
- package/rust/core/parser/handler/dot.rs +2 -1
- package/rust/core/parser/handler/identifier/automate.rs +13 -16
- package/rust/core/parser/handler/identifier/call.rs +4 -4
- package/rust/core/parser/handler/identifier/emit.rs +9 -5
- package/rust/core/parser/handler/identifier/function.rs +20 -7
- package/rust/core/parser/handler/identifier/group.rs +11 -7
- package/rust/core/parser/handler/identifier/let_.rs +24 -9
- package/rust/core/parser/handler/identifier/mod.rs +6 -5
- package/rust/core/parser/handler/identifier/on.rs +16 -7
- package/rust/core/parser/handler/identifier/print.rs +6 -9
- package/rust/core/parser/handler/identifier/sleep.rs +12 -5
- package/rust/core/parser/handler/identifier/spawn.rs +4 -4
- package/rust/core/parser/handler/identifier/synth.rs +79 -9
- package/rust/core/parser/handler/loop_.rs +39 -14
- package/rust/core/parser/handler/tempo.rs +9 -5
- package/rust/core/parser/mod.rs +0 -1
- package/rust/core/parser/statement.rs +6 -137
- package/rust/core/plugin/loader.rs +41 -27
- package/rust/core/plugin/runner.rs +68 -17
- package/rust/core/preprocessor/loader.rs +155 -33
- package/rust/core/preprocessor/processor.rs +2 -2
- package/rust/core/preprocessor/resolver/bank.rs +6 -8
- package/rust/core/preprocessor/resolver/call.rs +20 -24
- package/rust/core/preprocessor/resolver/condition.rs +6 -8
- package/rust/core/preprocessor/resolver/driver.rs +14 -16
- package/rust/core/preprocessor/resolver/function.rs +6 -6
- package/rust/core/preprocessor/resolver/group.rs +6 -8
- package/rust/core/preprocessor/resolver/loop_.rs +8 -10
- package/rust/core/preprocessor/resolver/spawn.rs +19 -23
- package/rust/core/preprocessor/resolver/synth.rs +6 -8
- package/rust/core/preprocessor/resolver/tempo.rs +6 -8
- package/rust/core/preprocessor/resolver/trigger.rs +22 -19
- package/rust/core/preprocessor/resolver/value.rs +99 -4
- package/rust/core/store/export.rs +28 -28
- package/rust/core/store/function.rs +6 -0
- package/rust/core/store/global.rs +7 -1
- package/rust/core/store/import.rs +28 -28
- package/rust/core/store/variable.rs +1 -1
- package/rust/core/utils/mod.rs +0 -1
- package/rust/lib.rs +102 -9
- package/rust/main.rs +156 -45
- package/rust/types/Cargo.toml +8 -0
- package/rust/types/src/addons.rs +55 -0
- package/rust/types/src/ast.rs +198 -0
- package/rust/types/src/config.rs +74 -0
- package/rust/types/src/lib.rs +12 -0
- package/rust/types/src/telemetry.rs +85 -0
- package/rust/utils/Cargo.toml +23 -0
- package/rust/utils/{error.rs → src/error.rs} +186 -200
- package/rust/utils/src/file.rs +94 -0
- package/rust/utils/src/first_usage.rs +97 -0
- package/rust/utils/{mod.rs → src/lib.rs} +1 -1
- package/rust/utils/{logger.rs → src/logger.rs} +17 -12
- package/rust/utils/src/path.rs +88 -0
- package/rust/utils/src/signature.rs +41 -0
- package/rust/utils/{spinner.rs → src/spinner.rs} +3 -5
- package/rust/utils/src/version.rs +27 -0
- package/rust/utils/{watcher.rs → src/watcher.rs} +13 -1
- package/rust/web/api.rs +5 -0
- package/rust/web/cdn.rs +34 -0
- package/templates/minimal/README.md +98 -54
- package/templates/welcome/README.md +98 -54
- package/templates/welcome/src/index.deva +56 -8
- package/templates/welcome/src/variables.deva +2 -4
- package/tests/rust/TODO.md +0 -0
- package/tests/typescript/index.spec.ts +136 -0
- package/tests/typescript/playhead.spec.ts +36 -0
- package/tests/typescript/render_e2e.spec.ts +77 -0
- package/tsconfig.json +1 -1
- package/typescript/core/functions/index.ts +83 -0
- package/typescript/core/index.ts +6 -0
- package/typescript/core/types/index.ts +4 -0
- package/typescript/core/types/plugin.ts +19 -0
- package/typescript/core/types/result.ts +29 -0
- package/typescript/core/types/statement.ts +47 -0
- package/typescript/core/types/value.ts +29 -0
- package/typescript/index.ts +7 -2
- package/typescript/pkg/devalang_core.d.ts +4 -0
- package/typescript/scripts/copy-wasm-dts.ts +41 -0
- package/typescript/scripts/postinstall.ts +45 -32
- package/rust/cli/bank.rs +0 -462
- package/rust/cli/build.rs +0 -252
- package/rust/cli/generator.rs +0 -1
- package/rust/cli/play.rs +0 -1123
- package/rust/cli/telemetry.rs +0 -19
- package/rust/common/api.rs +0 -5
- package/rust/common/cdn.rs +0 -5
- package/rust/config/loader.rs +0 -165
- package/rust/config/stats.rs +0 -257
- package/rust/core/audio/engine.rs +0 -696
- package/rust/core/shared/bank.rs +0 -21
- package/rust/core/shared/duration.rs +0 -9
- package/rust/core/shared/mod.rs +0 -3
- package/rust/core/shared/value.rs +0 -35
- package/rust/core/utils/validation.rs +0 -35
- package/rust/installer/bank.rs +0 -62
- package/rust/installer/plugin.rs +0 -54
- package/rust/installer/utils.rs +0 -56
- package/rust/utils/file.rs +0 -38
- package/rust/utils/first_usage.rs +0 -76
- package/rust/utils/signature.rs +0 -19
- package/rust/utils/telemetry.rs +0 -292
- package/rust/utils/version.rs +0 -15
- /package/rust/{common → web}/mod.rs +0 -0
- /package/rust/{common → web}/sso.rs +0 -0
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
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -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:
|
|
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.
|
|
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
|
-
|
|
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
|
-
>
|
|
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
|
|
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
|
-
- [📦
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
devalang play --watch
|
|
152
|
+
#### **LIVE mode** (repeat the playback + watch mode)
|
|
114
153
|
|
|
115
|
-
|
|
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
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
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
|
|
189
|
+
### [Please refer to the online documentation](https://docs.devalang.com) for detailed information on syntax, features, and usage examples
|
|
146
190
|
|
|
147
|
-
##
|
|
191
|
+
## 📰 What's new
|
|
148
192
|
|
|
149
|
-
-
|
|
150
|
-
-
|
|
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
|
-
- ⏳
|
|
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
|
-
##
|
|
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.
|
package/examples/index.deva
CHANGED
|
@@ -1,43 +1,60 @@
|
|
|
1
|
-
# This file demonstrates general
|
|
1
|
+
# This file demonstrates general use cases of Devalang.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# BPM definition
|
|
4
|
+
bpm 125
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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,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,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);
|