@devaloop/devalang 0.0.1-alpha.8 → 0.0.1-beta.1

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 (277) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.devalang +10 -4
  3. package/.github/workflows/ci.yml +103 -0
  4. package/Cargo.toml +80 -48
  5. package/README.md +135 -158
  6. package/docs/CHANGELOG.md +413 -1
  7. package/docs/CONTRIBUTING.md +101 -0
  8. package/docs/ROADMAP.md +10 -7
  9. package/docs/TODO.md +21 -9
  10. package/examples/automation.deva +42 -0
  11. package/examples/bank.deva +7 -0
  12. package/examples/condition.deva +8 -12
  13. package/examples/duration.deva +9 -0
  14. package/examples/events.deva +12 -0
  15. package/examples/function.deva +15 -0
  16. package/examples/group.deva +3 -3
  17. package/examples/index.deva +57 -10
  18. package/examples/loop.deva +7 -12
  19. package/examples/pattern.deva +8 -0
  20. package/examples/plugin.deva +16 -0
  21. package/examples/synth.deva +14 -0
  22. package/examples/variables.deva +2 -2
  23. package/out-tsc/bin/index.d.ts +2 -0
  24. package/out-tsc/bin/index.js +51 -7
  25. package/out-tsc/core/functions/index.d.ts +37 -0
  26. package/out-tsc/core/functions/index.js +76 -0
  27. package/out-tsc/core/index.d.ts +6 -0
  28. package/out-tsc/core/index.js +22 -0
  29. package/out-tsc/core/types/index.d.ts +4 -0
  30. package/out-tsc/core/types/index.js +20 -0
  31. package/out-tsc/core/types/plugin.d.ts +18 -0
  32. package/out-tsc/core/types/plugin.js +2 -0
  33. package/out-tsc/core/types/result.d.ts +27 -0
  34. package/out-tsc/core/types/result.js +2 -0
  35. package/out-tsc/core/types/statement.d.ts +106 -0
  36. package/out-tsc/core/types/statement.js +2 -0
  37. package/out-tsc/core/types/value.d.ts +43 -0
  38. package/out-tsc/core/types/value.js +2 -0
  39. package/out-tsc/index.d.ts +7 -0
  40. package/out-tsc/index.js +42 -1
  41. package/out-tsc/pkg/devalang_core.d.ts +13 -0
  42. package/out-tsc/pkg/devalang_core.js +50 -0
  43. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  44. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  45. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  46. package/out-tsc/scripts/postinstall.d.ts +1 -0
  47. package/out-tsc/scripts/postinstall.js +83 -0
  48. package/out-tsc/scripts/version/bump.d.ts +1 -0
  49. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  50. package/out-tsc/scripts/version/fetch.js +1 -5
  51. package/out-tsc/scripts/version/index.d.ts +1 -0
  52. package/out-tsc/scripts/version/sync.d.ts +1 -0
  53. package/package.json +28 -7
  54. package/project-version.json +4 -4
  55. package/rust/cli/bank/api.rs +122 -0
  56. package/rust/cli/bank/commands.rs +275 -0
  57. package/rust/cli/bank/mod.rs +29 -0
  58. package/rust/cli/build/commands.rs +103 -0
  59. package/rust/cli/build/mod.rs +2 -0
  60. package/rust/cli/build/process.rs +146 -0
  61. package/rust/cli/check/mod.rs +208 -0
  62. package/rust/cli/discover/commands.rs +253 -0
  63. package/rust/cli/discover/config.rs +111 -0
  64. package/rust/cli/discover/fs.rs +19 -0
  65. package/rust/cli/discover/install.rs +103 -0
  66. package/rust/cli/discover/metadata.rs +48 -0
  67. package/rust/cli/discover/mod.rs +5 -0
  68. package/rust/cli/{init.rs → init/commands.rs} +32 -23
  69. package/rust/cli/init/mod.rs +1 -0
  70. package/rust/cli/install/addon.rs +118 -0
  71. package/rust/cli/install/bank.rs +53 -0
  72. package/rust/cli/install/commands.rs +35 -0
  73. package/rust/cli/install/mod.rs +4 -0
  74. package/rust/cli/install/plugin.rs +61 -0
  75. package/rust/cli/login/commands.rs +124 -0
  76. package/rust/cli/login/mod.rs +1 -0
  77. package/rust/cli/mod.rs +12 -205
  78. package/rust/cli/parser.rs +314 -0
  79. package/rust/cli/play/commands.rs +324 -0
  80. package/rust/cli/play/io.rs +17 -0
  81. package/rust/cli/play/mod.rs +5 -0
  82. package/rust/cli/play/process.rs +150 -0
  83. package/rust/cli/play/realtime.rs +91 -0
  84. package/rust/cli/play/utils.rs +23 -0
  85. package/rust/cli/telemetry/commands.rs +22 -0
  86. package/rust/cli/telemetry/event_creator.rs +80 -0
  87. package/rust/cli/telemetry/mod.rs +3 -0
  88. package/rust/cli/telemetry/send.rs +51 -0
  89. package/rust/cli/{template.rs → template/commands.rs} +69 -57
  90. package/rust/cli/template/mod.rs +1 -0
  91. package/rust/cli/update/commands.rs +6 -0
  92. package/rust/cli/update/mod.rs +1 -0
  93. package/rust/config/driver.rs +103 -0
  94. package/rust/config/mod.rs +3 -16
  95. package/rust/config/ops.rs +26 -0
  96. package/rust/config/settings.rs +101 -0
  97. package/rust/core/audio/engine/helpers.rs +170 -0
  98. package/rust/core/audio/engine/mod.rs +7 -0
  99. package/rust/core/audio/engine/sample.rs +366 -0
  100. package/rust/core/audio/engine/synth.rs +325 -0
  101. package/rust/core/audio/evaluator.rs +310 -31
  102. package/rust/core/audio/interpreter/arrow_call.rs +311 -0
  103. package/rust/core/audio/interpreter/automate.rs +18 -0
  104. package/rust/core/audio/interpreter/call.rs +294 -42
  105. package/rust/core/audio/interpreter/condition.rs +71 -65
  106. package/rust/core/audio/interpreter/driver.rs +542 -204
  107. package/rust/core/audio/interpreter/function.rs +26 -0
  108. package/rust/core/audio/interpreter/let_.rs +38 -19
  109. package/rust/core/audio/interpreter/load.rs +19 -18
  110. package/rust/core/audio/interpreter/loop_.rs +114 -59
  111. package/rust/core/audio/interpreter/mod.rs +14 -11
  112. package/rust/core/audio/interpreter/sleep.rs +28 -36
  113. package/rust/core/audio/interpreter/spawn.rs +252 -65
  114. package/rust/core/audio/interpreter/tempo.rs +40 -16
  115. package/rust/core/audio/interpreter/trigger.rs +239 -69
  116. package/rust/core/audio/loader/mod.rs +1 -1
  117. package/rust/core/audio/loader/trigger.rs +97 -52
  118. package/rust/core/audio/mod.rs +7 -6
  119. package/rust/core/audio/player.rs +70 -54
  120. package/rust/core/audio/renderer.rs +54 -57
  121. package/rust/core/audio/special/easing.rs +189 -0
  122. package/rust/core/audio/special/env.rs +45 -0
  123. package/rust/core/audio/special/math.rs +134 -0
  124. package/rust/core/audio/special/mod.rs +9 -0
  125. package/rust/core/audio/special/modulator.rs +143 -0
  126. package/rust/core/builder/mod.rs +86 -80
  127. package/rust/core/debugger/lexer.rs +27 -27
  128. package/rust/core/debugger/mod.rs +30 -21
  129. package/rust/core/debugger/module.rs +55 -0
  130. package/rust/core/debugger/preprocessor.rs +27 -27
  131. package/rust/core/debugger/store.rs +40 -25
  132. package/rust/core/error/mod.rs +269 -60
  133. package/rust/core/lexer/driver.rs +61 -0
  134. package/rust/core/lexer/handler/arrow.rs +82 -0
  135. package/rust/core/lexer/handler/at.rs +21 -21
  136. package/rust/core/lexer/handler/brace.rs +41 -41
  137. package/rust/core/lexer/handler/colon.rs +21 -21
  138. package/rust/core/lexer/handler/comment.rs +30 -30
  139. package/rust/core/lexer/handler/dot.rs +21 -21
  140. package/rust/core/lexer/handler/driver.rs +337 -215
  141. package/rust/core/lexer/handler/identifier.rs +47 -40
  142. package/rust/core/lexer/handler/indent.rs +66 -52
  143. package/rust/core/lexer/handler/mod.rs +15 -13
  144. package/rust/core/lexer/handler/newline.rs +23 -23
  145. package/rust/core/lexer/handler/number.rs +31 -31
  146. package/rust/core/lexer/handler/operator.rs +46 -44
  147. package/rust/core/lexer/handler/parenthesis.rs +41 -0
  148. package/rust/core/lexer/handler/slash.rs +21 -0
  149. package/rust/core/lexer/handler/string.rs +63 -63
  150. package/rust/core/lexer/mod.rs +3 -30
  151. package/rust/core/lexer/token.rs +21 -12
  152. package/rust/core/mod.rs +10 -10
  153. package/rust/core/parser/driver.rs +584 -312
  154. package/rust/core/parser/handler/arrow_call.rs +253 -0
  155. package/rust/core/parser/handler/at.rs +279 -162
  156. package/rust/core/parser/handler/bank.rs +104 -41
  157. package/rust/core/parser/handler/condition.rs +83 -74
  158. package/rust/core/parser/handler/dot.rs +148 -112
  159. package/rust/core/parser/handler/identifier/automate.rs +254 -0
  160. package/rust/core/parser/handler/identifier/call.rs +91 -0
  161. package/rust/core/parser/handler/identifier/emit.rs +70 -0
  162. package/rust/core/parser/handler/identifier/function.rs +113 -0
  163. package/rust/core/parser/handler/identifier/group.rs +89 -0
  164. package/rust/core/parser/handler/identifier/let_.rs +173 -0
  165. package/rust/core/parser/handler/identifier/mod.rs +55 -0
  166. package/rust/core/parser/handler/identifier/on.rs +107 -0
  167. package/rust/core/parser/handler/identifier/print.rs +49 -0
  168. package/rust/core/parser/handler/identifier/sleep.rs +43 -0
  169. package/rust/core/parser/handler/identifier/spawn.rs +91 -0
  170. package/rust/core/parser/handler/identifier/synth.rs +135 -0
  171. package/rust/core/parser/handler/loop_.rs +194 -66
  172. package/rust/core/parser/handler/mod.rs +9 -7
  173. package/rust/core/parser/handler/pattern.rs +74 -0
  174. package/rust/core/parser/handler/tempo.rs +57 -47
  175. package/rust/core/parser/mod.rs +3 -4
  176. package/rust/core/parser/statement.rs +11 -88
  177. package/rust/core/plugin/loader.rs +137 -0
  178. package/rust/core/plugin/mod.rs +2 -0
  179. package/rust/core/plugin/runner.rs +347 -0
  180. package/rust/core/preprocessor/loader.rs +637 -179
  181. package/rust/core/preprocessor/mod.rs +4 -4
  182. package/rust/core/preprocessor/module.rs +60 -53
  183. package/rust/core/preprocessor/processor.rs +114 -67
  184. package/rust/core/preprocessor/resolver/bank.rs +49 -47
  185. package/rust/core/preprocessor/resolver/call.rs +124 -53
  186. package/rust/core/preprocessor/resolver/condition.rs +95 -66
  187. package/rust/core/preprocessor/resolver/driver.rs +324 -182
  188. package/rust/core/preprocessor/resolver/function.rs +69 -0
  189. package/rust/core/preprocessor/resolver/group.rs +94 -118
  190. package/rust/core/preprocessor/resolver/let_.rs +32 -0
  191. package/rust/core/preprocessor/resolver/loop_.rs +318 -145
  192. package/rust/core/preprocessor/resolver/mod.rs +16 -10
  193. package/rust/core/preprocessor/resolver/pattern.rs +83 -0
  194. package/rust/core/preprocessor/resolver/spawn.rs +99 -53
  195. package/rust/core/preprocessor/resolver/synth.rs +54 -0
  196. package/rust/core/preprocessor/resolver/tempo.rs +48 -49
  197. package/rust/core/preprocessor/resolver/trigger.rs +116 -111
  198. package/rust/core/preprocessor/resolver/value.rs +176 -0
  199. package/rust/core/store/export.rs +28 -28
  200. package/rust/core/store/function.rs +40 -0
  201. package/rust/core/store/global.rs +61 -39
  202. package/rust/core/store/import.rs +28 -28
  203. package/rust/core/store/mod.rs +5 -4
  204. package/rust/core/store/variable.rs +51 -28
  205. package/rust/core/utils/mod.rs +1 -2
  206. package/rust/core/utils/path.rs +37 -46
  207. package/rust/lib.rs +308 -117
  208. package/rust/main.rs +364 -65
  209. package/rust/types/Cargo.toml +11 -0
  210. package/rust/types/src/addons.rs +55 -0
  211. package/rust/types/src/ast.rs +202 -0
  212. package/rust/types/src/config.rs +74 -0
  213. package/rust/types/src/lib.rs +12 -0
  214. package/rust/types/src/telemetry.rs +85 -0
  215. package/rust/utils/Cargo.toml +26 -0
  216. package/rust/utils/src/error.rs +186 -0
  217. package/rust/utils/src/file.rs +94 -0
  218. package/rust/utils/src/first_usage.rs +97 -0
  219. package/rust/utils/{mod.rs → src/lib.rs} +9 -6
  220. package/rust/utils/{logger.rs → src/logger.rs} +200 -123
  221. package/rust/utils/src/path.rs +88 -0
  222. package/rust/utils/src/signature.rs +41 -0
  223. package/rust/utils/{spinner.rs → src/spinner.rs} +20 -21
  224. package/rust/utils/src/version.rs +27 -0
  225. package/rust/utils/{watcher.rs → src/watcher.rs} +46 -33
  226. package/rust/web/api.rs +5 -0
  227. package/rust/web/cdn.rs +34 -0
  228. package/rust/web/mod.rs +3 -0
  229. package/rust/web/sso.rs +5 -0
  230. package/templates/minimal/README.md +143 -127
  231. package/templates/welcome/README.md +143 -127
  232. package/templates/welcome/src/index.deva +56 -8
  233. package/templates/welcome/src/variables.deva +2 -4
  234. package/tests/integration.rs +21 -0
  235. package/tests/rust/cli_check_build.rs +21 -0
  236. package/tests/rust/cli_help.rs +12 -0
  237. package/tests/rust/cli_template_list.rs +10 -0
  238. package/tests/rust/cli_version.rs +11 -0
  239. package/tests/typescript/index.spec.ts +136 -0
  240. package/tests/typescript/playhead.spec.ts +36 -0
  241. package/tests/typescript/render_e2e.spec.ts +77 -0
  242. package/tsconfig.json +12 -10
  243. package/typescript/bin/index.ts +19 -5
  244. package/typescript/core/functions/index.ts +83 -0
  245. package/typescript/core/index.ts +6 -0
  246. package/typescript/core/types/index.ts +4 -0
  247. package/typescript/core/types/plugin.ts +19 -0
  248. package/typescript/core/types/result.ts +29 -0
  249. package/typescript/core/types/statement.ts +47 -0
  250. package/typescript/core/types/value.ts +29 -0
  251. package/typescript/index.ts +8 -1
  252. package/typescript/pkg/devalang_core.d.ts +4 -0
  253. package/typescript/pkg/devalang_core.ts +49 -0
  254. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  255. package/typescript/scripts/postinstall.ts +85 -0
  256. package/typescript/scripts/version/bump.ts +0 -1
  257. package/typescript/scripts/version/fetch.ts +1 -6
  258. package/typescript/scripts/version/index.ts +0 -1
  259. package/docs/COMMANDS.md +0 -85
  260. package/docs/CONFIG.md +0 -30
  261. package/docs/SYNTAX.md +0 -210
  262. package/out-tsc/bin/devalang.exe +0 -0
  263. package/out-tsc/scripts/postbuild.js +0 -11
  264. package/rust/cli/build.rs +0 -137
  265. package/rust/cli/check.rs +0 -117
  266. package/rust/cli/play.rs +0 -193
  267. package/rust/config/loader.rs +0 -13
  268. package/rust/core/audio/engine.rs +0 -126
  269. package/rust/core/parser/handler/identifier.rs +0 -262
  270. package/rust/core/shared/duration.rs +0 -8
  271. package/rust/core/shared/mod.rs +0 -2
  272. package/rust/core/shared/value.rs +0 -18
  273. package/rust/core/utils/validation.rs +0 -35
  274. package/rust/utils/file.rs +0 -35
  275. package/rust/utils/signature.rs +0 -17
  276. package/rust/utils/version.rs +0 -15
  277. package/typescript/scripts/postbuild.ts +0 -8
package/rust/main.rs CHANGED
@@ -1,65 +1,364 @@
1
- #![cfg(feature = "cli")]
2
-
3
- pub mod core;
4
- pub mod cli;
5
- pub mod utils;
6
- pub mod config;
7
-
8
- use std::io;
9
- use cli::{ Cli };
10
- use clap::Parser;
11
- use crate::{
12
- cli::{
13
- build::handle_build_command,
14
- check::handle_check_command,
15
- init::handle_init_command,
16
- play::handle_play_command,
17
- template::{ handle_template_info_command, handle_template_list_command },
18
- Commands,
19
- TemplateCommand,
20
- },
21
- config::{ loader::load_config, Config },
22
- };
23
-
24
- fn main() -> io::Result<()> {
25
- let cli: Cli = Cli::parse();
26
- let mut config: Option<Config> = None;
27
-
28
- if !cli.no_config {
29
- config = load_config(None);
30
- } else {
31
- println!("No configuration file loaded. Running with arguments only.");
32
- }
33
-
34
- match cli.command {
35
- Commands::Init { name, template } => {
36
- handle_init_command(name, template);
37
- }
38
-
39
- Commands::Template { command } =>
40
- match command {
41
- TemplateCommand::List => {
42
- handle_template_list_command();
43
- }
44
- TemplateCommand::Info { name } => {
45
- handle_template_info_command(name);
46
- }
47
- }
48
-
49
- Commands::Check { entry, output, watch, compilation_mode, debug } => {
50
- handle_check_command(config, entry, output, watch);
51
- }
52
-
53
- Commands::Build { entry, output, watch, compilation_mode, debug, compress } => {
54
- handle_build_command(config, entry, output, watch);
55
- }
56
-
57
- Commands::Play { entry, output, watch, repeat } => {
58
- handle_play_command(config, entry, output, watch, repeat);
59
- }
60
-
61
- _ => {}
62
- }
63
-
64
- Ok(())
65
- }
1
+ #![cfg(feature = "cli")]
2
+
3
+ pub mod cli;
4
+ pub mod config;
5
+ pub mod core;
6
+ pub mod web;
7
+ pub use devalang_utils as utils;
8
+ use devalang_utils::path::ensure_deva_dir;
9
+
10
+ use crate::cli::telemetry::send::send_telemetry_event;
11
+ use crate::config::settings::ensure_user_config_file_exists;
12
+ use crate::config::settings::write_user_config_file;
13
+ use crate::{
14
+ cli::{
15
+ bank::{
16
+ handle_bank_available_command, handle_bank_info_command, handle_bank_list_command,
17
+ handle_remove_bank_command, handle_update_bank_command,
18
+ },
19
+ build::commands::handle_build_command,
20
+ check::handle_check_command,
21
+ discover::commands::handle_discover_command,
22
+ init::commands::handle_init_command,
23
+ install::commands::handle_install_command,
24
+ login::commands::handle_login_command,
25
+ parser::{BankCommand, Cli, Commands, InstallCommand, TelemetryCommand, TemplateCommand},
26
+ play::commands::handle_play_command,
27
+ telemetry::{
28
+ commands::{handle_telemetry_disable_command, handle_telemetry_enable_command},
29
+ event_creator::{TelemetryEventCreator, TelemetryEventExt},
30
+ },
31
+ template::commands::{handle_template_info_command, handle_template_list_command},
32
+ update::commands::handle_update_command,
33
+ },
34
+ config::driver::ProjectConfig,
35
+ utils::first_usage::check_is_first_usage,
36
+ };
37
+ use clap::CommandFactory;
38
+ use clap::FromArgMatches;
39
+ use devalang_types::{AddonType, TelemetryErrorLevel};
40
+ use std::io;
41
+
42
+ #[tokio::main]
43
+ async fn main() -> io::Result<()> {
44
+ let version = devalang_utils::version::get_version();
45
+ let signature = devalang_utils::signature::get_signature(&version);
46
+
47
+ let version_static: &'static str = Box::leak(format!("v{}", version).into_boxed_str());
48
+ let signature_static: &'static str = Box::leak(signature.into_boxed_str());
49
+
50
+ let mut cmd = Cli::command();
51
+ cmd = cmd.version(version_static).before_help(signature_static);
52
+
53
+ let raw_args: Vec<String> = std::env::args().collect();
54
+ if raw_args.iter().any(|a| a == "--version" || a == "-V") {
55
+ println!("{}", signature_static);
56
+ return Ok(());
57
+ }
58
+
59
+ let matches = cmd.get_matches();
60
+ let cli: Cli = Cli::from_arg_matches(&matches).expect("failed to parse cli args");
61
+ let mut config: Option<ProjectConfig> = None;
62
+
63
+ let telemetry_event_creator = TelemetryEventCreator::new();
64
+ let mut event = telemetry_event_creator.get_base_event();
65
+
66
+ let mut had_error: bool = false;
67
+ let mut last_error_message: Option<String> = None;
68
+ let mut exit_code: Option<i32> = None;
69
+
70
+ let _ = ensure_deva_dir();
71
+
72
+ if check_is_first_usage() == true {
73
+ write_user_config_file();
74
+ } else {
75
+ ensure_user_config_file_exists();
76
+ }
77
+
78
+ let duration = std::time::Instant::now();
79
+
80
+ if !cli.no_config {
81
+ config = config::ops::load_config(None);
82
+ } else {
83
+ println!("No configuration file loaded. Running with arguments only.");
84
+ }
85
+
86
+ match cli.command {
87
+ Commands::Init { name, template } => {
88
+ handle_init_command(name, template);
89
+ }
90
+
91
+ Commands::Template { command } => match command {
92
+ TemplateCommand::List => {
93
+ handle_template_list_command();
94
+ }
95
+ TemplateCommand::Info { name } => {
96
+ handle_template_info_command(name);
97
+ }
98
+ },
99
+
100
+ Commands::Check {
101
+ entry,
102
+ output,
103
+ watch,
104
+ debug,
105
+ } => {
106
+ if let Err(err) = handle_check_command(config, entry, output, watch, debug) {
107
+ let logger = devalang_utils::logger::Logger::new();
108
+ logger.log_message(
109
+ devalang_utils::logger::LogLevel::Error,
110
+ &format!("❌ Check failed: {}", err),
111
+ );
112
+ had_error = true;
113
+ last_error_message = Some(format!("check failed: {}", err));
114
+ exit_code = Some(1);
115
+ }
116
+ }
117
+
118
+ Commands::Build {
119
+ entry,
120
+ output,
121
+ watch,
122
+ debug,
123
+ compress,
124
+ } => {
125
+ if let Err(err) = handle_build_command(config, entry, output, watch, debug, compress) {
126
+ let logger = devalang_utils::logger::Logger::new();
127
+ logger.log_message(
128
+ devalang_utils::logger::LogLevel::Error,
129
+ &format!("❌ Build failed: {}", err),
130
+ );
131
+ had_error = true;
132
+ last_error_message = Some(format!("build failed: {}", err));
133
+ exit_code = Some(1);
134
+ }
135
+ }
136
+
137
+ Commands::Play {
138
+ entry,
139
+ output,
140
+ watch,
141
+ repeat,
142
+ debug,
143
+ } => {
144
+ if let Err(err) = handle_play_command(config, entry, output, watch, repeat, debug) {
145
+ let logger = devalang_utils::logger::Logger::new();
146
+ logger.log_message(
147
+ devalang_utils::logger::LogLevel::Error,
148
+ &format!("❌ Play failed: {}", err),
149
+ );
150
+ had_error = true;
151
+ last_error_message = Some(format!("play failed: {}", err));
152
+ exit_code = Some(1);
153
+ }
154
+ }
155
+
156
+ Commands::Install { command } => match command {
157
+ InstallCommand::Template { name } => {
158
+ if let Err(err) = handle_install_command(name, AddonType::Template).await {
159
+ let logger = devalang_utils::logger::Logger::new();
160
+ logger.log_message(
161
+ devalang_utils::logger::LogLevel::Error,
162
+ &format!("❌ Failed to install template: {}", err),
163
+ );
164
+ had_error = true;
165
+ last_error_message = Some(format!("install template failed: {}", err));
166
+ exit_code = Some(1);
167
+ }
168
+ }
169
+ InstallCommand::Bank { name } => {
170
+ if let Err(err) = handle_install_command(name, AddonType::Bank).await {
171
+ let logger = devalang_utils::logger::Logger::new();
172
+ logger.log_message(
173
+ devalang_utils::logger::LogLevel::Error,
174
+ &format!("❌ Failed to install bank: {}", err),
175
+ );
176
+ had_error = true;
177
+ last_error_message = Some(format!("install bank failed: {}", err));
178
+ exit_code = Some(1);
179
+ }
180
+ }
181
+ InstallCommand::Plugin { name } => {
182
+ if let Err(err) = handle_install_command(name, AddonType::Plugin).await {
183
+ let logger = devalang_utils::logger::Logger::new();
184
+ logger.log_message(
185
+ devalang_utils::logger::LogLevel::Error,
186
+ &format!("❌ Failed to install plugin: {}", err),
187
+ );
188
+ had_error = true;
189
+ last_error_message = Some(format!("install plugin failed: {}", err));
190
+ exit_code = Some(1);
191
+ }
192
+ }
193
+ InstallCommand::Preset { name } => {
194
+ if let Err(err) = handle_install_command(name, AddonType::Preset).await {
195
+ let logger = devalang_utils::logger::Logger::new();
196
+ logger.log_message(
197
+ devalang_utils::logger::LogLevel::Error,
198
+ &format!("❌ Failed to install preset: {}", err),
199
+ );
200
+ had_error = true;
201
+ last_error_message = Some(format!("install preset failed: {}", err));
202
+ exit_code = Some(1);
203
+ }
204
+ }
205
+ },
206
+
207
+ Commands::Bank { command } => match command {
208
+ BankCommand::List => {
209
+ if let Err(err) = handle_bank_list_command().await {
210
+ let logger = devalang_utils::logger::Logger::new();
211
+ logger.log_message(
212
+ devalang_utils::logger::LogLevel::Error,
213
+ &format!("❌ Failed to list local banks: {}", err),
214
+ );
215
+ had_error = true;
216
+ last_error_message = Some(format!("bank list failed: {}", err));
217
+ exit_code = Some(1);
218
+ }
219
+ }
220
+
221
+ BankCommand::Available => {
222
+ if let Err(err) = handle_bank_available_command().await {
223
+ let logger = devalang_utils::logger::Logger::new();
224
+ logger.log_message(
225
+ devalang_utils::logger::LogLevel::Error,
226
+ &format!("❌ Failed to list available banks: {}", err),
227
+ );
228
+ had_error = true;
229
+ last_error_message = Some(format!("bank available failed: {}", err));
230
+ exit_code = Some(1);
231
+ }
232
+ }
233
+
234
+ BankCommand::Info { name } => {
235
+ if let Err(err) = handle_bank_info_command(name).await {
236
+ let logger = devalang_utils::logger::Logger::new();
237
+ logger.log_message(
238
+ devalang_utils::logger::LogLevel::Error,
239
+ &format!("❌ Failed to get bank info: {}", err),
240
+ );
241
+ had_error = true;
242
+ last_error_message = Some(format!("bank info failed: {}", err));
243
+ exit_code = Some(1);
244
+ }
245
+ }
246
+
247
+ BankCommand::Remove { name } => {
248
+ if let Err(err) = handle_remove_bank_command(name).await {
249
+ let logger = devalang_utils::logger::Logger::new();
250
+ logger.log_message(
251
+ devalang_utils::logger::LogLevel::Error,
252
+ &format!("❌ Failed to remove bank: {}", err),
253
+ );
254
+ had_error = true;
255
+ last_error_message = Some(format!("bank remove failed: {}", err));
256
+ exit_code = Some(1);
257
+ }
258
+ }
259
+
260
+ BankCommand::Update { name } => {
261
+ if let Err(err) = handle_update_bank_command(name).await {
262
+ let logger = devalang_utils::logger::Logger::new();
263
+ logger.log_message(
264
+ devalang_utils::logger::LogLevel::Error,
265
+ &format!("❌ Failed to update bank: {}", err),
266
+ );
267
+ had_error = true;
268
+ last_error_message = Some(format!("bank update failed: {}", err));
269
+ exit_code = Some(1);
270
+ }
271
+ }
272
+ },
273
+
274
+ Commands::Update { only } => {
275
+ if let Err(err) = handle_update_command(only).await {
276
+ let logger = devalang_utils::logger::Logger::new();
277
+ logger.log_message(
278
+ devalang_utils::logger::LogLevel::Error,
279
+ &format!("❌ Update failed: {}", err),
280
+ );
281
+ had_error = true;
282
+ last_error_message = Some(format!("update failed: {}", err));
283
+ exit_code = Some(1);
284
+ }
285
+ }
286
+
287
+ Commands::Telemetry { command } => match command {
288
+ TelemetryCommand::Enable { .. } => {
289
+ if let Err(err) = handle_telemetry_enable_command().await {
290
+ let logger = devalang_utils::logger::Logger::new();
291
+ logger.log_message(
292
+ devalang_utils::logger::LogLevel::Error,
293
+ &format!("❌ Failed to enable telemetry: {}", err),
294
+ );
295
+ had_error = true;
296
+ last_error_message = Some(format!("telemetry enable failed: {}", err));
297
+ exit_code = Some(1);
298
+ }
299
+ }
300
+ TelemetryCommand::Disable { .. } => {
301
+ if let Err(err) = handle_telemetry_disable_command().await {
302
+ let logger = devalang_utils::logger::Logger::new();
303
+ logger.log_message(
304
+ devalang_utils::logger::LogLevel::Error,
305
+ &format!("❌ Failed to disable telemetry: {}", err),
306
+ );
307
+ had_error = true;
308
+ last_error_message = Some(format!("telemetry disable failed: {}", err));
309
+ exit_code = Some(1);
310
+ }
311
+ }
312
+ },
313
+
314
+ Commands::Discover {} => {
315
+ if let Err(err) = handle_discover_command().await {
316
+ let logger = devalang_utils::logger::Logger::new();
317
+ logger.log_message(
318
+ devalang_utils::logger::LogLevel::Error,
319
+ &format!("❌ Failed to discover: {}", err),
320
+ );
321
+ had_error = true;
322
+ last_error_message = Some(format!("discover failed: {}", err));
323
+ exit_code = Some(1);
324
+ }
325
+ }
326
+
327
+ Commands::Login { .. } => {
328
+ if let Err(err) = handle_login_command().await {
329
+ let logger = devalang_utils::logger::Logger::new();
330
+ logger.log_message(
331
+ devalang_utils::logger::LogLevel::Error,
332
+ &format!("❌ Login failed: {}", err),
333
+ );
334
+ had_error = true;
335
+ last_error_message = Some(format!("login failed: {}", err));
336
+ exit_code = Some(1);
337
+ }
338
+ }
339
+
340
+ Commands::Logout { .. } => {
341
+ let logger = devalang_utils::logger::Logger::new();
342
+ logger.log_message(
343
+ devalang_utils::logger::LogLevel::Error,
344
+ "❌ Logout command is not implemented yet.",
345
+ );
346
+ had_error = true;
347
+ last_error_message = Some("logout not implemented".to_string());
348
+ exit_code = Some(1);
349
+ }
350
+ }
351
+
352
+ // SECTION Telemetry
353
+ event.set_timestamp(chrono::Utc::now().to_string());
354
+ event.set_duration(duration.elapsed().as_millis() as u64);
355
+ event.set_success(!had_error);
356
+
357
+ if had_error {
358
+ event.set_error(TelemetryErrorLevel::Critical, last_error_message, exit_code);
359
+ }
360
+
361
+ let _ = send_telemetry_event(&event).await;
362
+
363
+ Ok(())
364
+ }
@@ -0,0 +1,11 @@
1
+ [package]
2
+ name = "devalang_types"
3
+ version = "0.0.2"
4
+ description = "Types and traits for Devalang"
5
+ license = "MIT"
6
+ authors = ["Devaloop <contact@devaloop.com>"]
7
+ edition = "2024"
8
+
9
+ [dependencies]
10
+ serde = { version = "1.0", features = ["derive"] }
11
+ toml = "0.8"
@@ -0,0 +1,55 @@
1
+ use serde::Deserialize;
2
+
3
+ #[derive(Debug, Clone)]
4
+ pub struct DiscoveredAddon {
5
+ pub path: std::path::PathBuf,
6
+ pub name: String,
7
+ pub extension: String,
8
+ pub addon_type: String,
9
+ }
10
+
11
+ #[derive(Debug, Clone)]
12
+ pub struct AddonWithMetadata {
13
+ pub name: String,
14
+ pub path: String,
15
+ pub addon_type: String,
16
+ pub metadata: AddonMetadata,
17
+ }
18
+
19
+ #[derive(Debug, Clone)]
20
+ pub struct AddonMetadata {
21
+ pub name: String,
22
+ pub author: String,
23
+ pub version: String,
24
+ pub description: String,
25
+ pub access: String,
26
+ }
27
+
28
+ #[derive(Debug, Clone)]
29
+ pub enum AddonType {
30
+ Bank,
31
+ Plugin,
32
+ Preset,
33
+ Template,
34
+ }
35
+
36
+ #[derive(Debug, Deserialize)]
37
+ pub struct BankInfo {
38
+ pub name: String,
39
+ pub version: String,
40
+ pub description: String,
41
+ pub author: String,
42
+ }
43
+
44
+ #[derive(Debug, Deserialize)]
45
+ pub struct BankFile {
46
+ pub bank: BankInfo,
47
+ pub triggers: Option<Vec<BankTrigger>>,
48
+ pub audio_path: Option<String>,
49
+ }
50
+
51
+ #[derive(Debug, Deserialize)]
52
+ pub struct BankTrigger {
53
+ pub name: String,
54
+ pub path: String,
55
+ }
@@ -0,0 +1,202 @@
1
+ use serde::{Deserialize, Serialize};
2
+ use std::collections::HashMap;
3
+
4
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5
+ pub enum Duration {
6
+ Number(f32),
7
+ Identifier(String),
8
+ Beat(String),
9
+ Auto,
10
+ }
11
+
12
+ #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
13
+ pub enum Severity {
14
+ Warning,
15
+ Critical,
16
+ }
17
+
18
+ #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
19
+ pub struct StackFrame {
20
+ pub module: Option<String>,
21
+ pub context: Option<String>,
22
+ pub line: usize,
23
+ pub column: usize,
24
+ }
25
+
26
+ #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
27
+ pub struct ErrorResult {
28
+ pub message: String,
29
+ pub line: usize,
30
+ pub column: usize,
31
+ pub severity: Severity,
32
+ pub stack: Vec<StackFrame>,
33
+ }
34
+
35
+ #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
36
+ pub enum StatementKind {
37
+ // ───── Core Instructions ─────
38
+ Tempo,
39
+ Bank {
40
+ alias: Option<String>,
41
+ },
42
+ Print,
43
+ Load {
44
+ source: String,
45
+ alias: String,
46
+ },
47
+ Use {
48
+ name: String,
49
+ alias: Option<String>,
50
+ },
51
+ Let {
52
+ name: String,
53
+ },
54
+ Automate {
55
+ target: String,
56
+ },
57
+ ArrowCall {
58
+ target: String,
59
+ method: String,
60
+ args: Vec<Value>,
61
+ },
62
+ Function {
63
+ name: String,
64
+ parameters: Vec<String>,
65
+ body: Vec<Statement>,
66
+ },
67
+
68
+ // ───── Instruments ─────
69
+ Synth,
70
+
71
+ // ───── Playback / Scheduling ─────
72
+ Trigger {
73
+ entity: String,
74
+ duration: Duration,
75
+ effects: Option<Value>,
76
+ },
77
+ Sleep,
78
+ Call {
79
+ name: String,
80
+ args: Vec<Value>,
81
+ },
82
+ Spawn {
83
+ name: String,
84
+ args: Vec<Value>,
85
+ },
86
+ Loop,
87
+
88
+ // ───── Structure & Logic ─────
89
+ Group,
90
+ Pattern {
91
+ name: String,
92
+ target: Option<String>,
93
+ },
94
+
95
+ // ───── Module System ─────
96
+ Include(String),
97
+ Export {
98
+ names: Vec<String>,
99
+ source: String,
100
+ },
101
+ Import {
102
+ names: Vec<String>,
103
+ source: String,
104
+ },
105
+
106
+ // ───── Conditions ─────
107
+ If,
108
+ Else,
109
+ ElseIf,
110
+
111
+ // ───── Internal / Utility ─────
112
+ Comment,
113
+ Indent,
114
+ Dedent,
115
+ NewLine,
116
+
117
+ // ───── Events / Live coding ─────
118
+ On {
119
+ event: String,
120
+ args: Option<Vec<Value>>,
121
+ body: Vec<Statement>,
122
+ },
123
+ Emit {
124
+ event: String,
125
+ payload: Option<Value>,
126
+ },
127
+
128
+ // ───── Error Handling ─────
129
+ Unknown,
130
+ Error {
131
+ message: String,
132
+ },
133
+ }
134
+
135
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
136
+ pub enum Value {
137
+ Boolean(bool),
138
+ Number(f32),
139
+ Duration(Duration),
140
+ Identifier(String),
141
+ String(String),
142
+ Array(Vec<Value>),
143
+ Map(HashMap<String, Value>),
144
+ Block(Vec<Statement>),
145
+ Sample(String),
146
+ Beat(String),
147
+ Statement(Box<Statement>),
148
+ StatementKind(Box<StatementKind>),
149
+ Unknown,
150
+ Null,
151
+ }
152
+
153
+ impl Value {
154
+ pub fn get(&self, key: &str) -> Option<&Value> {
155
+ if let Value::Map(map) = self {
156
+ map.get(key)
157
+ } else {
158
+ None
159
+ }
160
+ }
161
+ }
162
+
163
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
164
+ pub struct Statement {
165
+ pub kind: StatementKind,
166
+ pub value: Value,
167
+ pub indent: usize,
168
+ pub line: usize,
169
+ pub column: usize,
170
+ }
171
+
172
+ impl Statement {
173
+ pub fn unknown() -> Self {
174
+ Statement {
175
+ kind: StatementKind::Unknown,
176
+ value: Value::Null,
177
+ indent: 0,
178
+ line: 0,
179
+ column: 0,
180
+ }
181
+ }
182
+
183
+ pub fn unknown_with_pos(indent: usize, line: usize, column: usize) -> Self {
184
+ Statement {
185
+ kind: StatementKind::Unknown,
186
+ value: Value::Null,
187
+ indent,
188
+ line,
189
+ column,
190
+ }
191
+ }
192
+
193
+ pub fn error_with_pos(indent: usize, line: usize, column: usize, message: String) -> Self {
194
+ Statement {
195
+ kind: StatementKind::Error { message },
196
+ value: Value::Null,
197
+ indent,
198
+ line,
199
+ column,
200
+ }
201
+ }
202
+ }