@devaloop/devalang 0.0.1-alpha.9 → 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 (271) 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 -154
  6. package/docs/CHANGELOG.md +386 -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/duration.deva +9 -0
  13. package/examples/events.deva +12 -0
  14. package/examples/function.deva +15 -0
  15. package/examples/index.deva +57 -12
  16. package/examples/loop.deva +5 -12
  17. package/examples/pattern.deva +8 -0
  18. package/examples/plugin.deva +16 -0
  19. package/examples/variables.deva +1 -1
  20. package/out-tsc/bin/index.d.ts +2 -0
  21. package/out-tsc/bin/index.js +51 -7
  22. package/out-tsc/core/functions/index.d.ts +37 -0
  23. package/out-tsc/core/functions/index.js +76 -0
  24. package/out-tsc/core/index.d.ts +6 -0
  25. package/out-tsc/core/index.js +22 -0
  26. package/out-tsc/core/types/index.d.ts +4 -0
  27. package/out-tsc/core/types/index.js +20 -0
  28. package/out-tsc/core/types/plugin.d.ts +18 -0
  29. package/out-tsc/core/types/plugin.js +2 -0
  30. package/out-tsc/core/types/result.d.ts +27 -0
  31. package/out-tsc/core/types/result.js +2 -0
  32. package/out-tsc/core/types/statement.d.ts +106 -0
  33. package/out-tsc/core/types/statement.js +2 -0
  34. package/out-tsc/core/types/value.d.ts +43 -0
  35. package/out-tsc/core/types/value.js +2 -0
  36. package/out-tsc/index.d.ts +7 -0
  37. package/out-tsc/index.js +42 -1
  38. package/out-tsc/pkg/devalang_core.d.ts +13 -0
  39. package/out-tsc/pkg/devalang_core.js +50 -0
  40. package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +33 -0
  41. package/out-tsc/scripts/copy-wasm-dts.d.ts +1 -0
  42. package/out-tsc/scripts/copy-wasm-dts.js +73 -0
  43. package/out-tsc/scripts/postinstall.d.ts +1 -0
  44. package/out-tsc/scripts/postinstall.js +83 -0
  45. package/out-tsc/scripts/version/bump.d.ts +1 -0
  46. package/out-tsc/scripts/version/fetch.d.ts +1 -0
  47. package/out-tsc/scripts/version/index.d.ts +1 -0
  48. package/out-tsc/scripts/version/sync.d.ts +1 -0
  49. package/package.json +28 -7
  50. package/project-version.json +4 -4
  51. package/rust/cli/bank/api.rs +122 -0
  52. package/rust/cli/bank/commands.rs +275 -0
  53. package/rust/cli/bank/mod.rs +29 -0
  54. package/rust/cli/build/commands.rs +103 -0
  55. package/rust/cli/build/mod.rs +2 -0
  56. package/rust/cli/build/process.rs +146 -0
  57. package/rust/cli/check/mod.rs +208 -0
  58. package/rust/cli/discover/commands.rs +253 -0
  59. package/rust/cli/discover/config.rs +111 -0
  60. package/rust/cli/discover/fs.rs +19 -0
  61. package/rust/cli/discover/install.rs +103 -0
  62. package/rust/cli/discover/metadata.rs +48 -0
  63. package/rust/cli/discover/mod.rs +5 -0
  64. package/rust/cli/{init.rs → init/commands.rs} +32 -23
  65. package/rust/cli/init/mod.rs +1 -0
  66. package/rust/cli/install/addon.rs +118 -0
  67. package/rust/cli/install/bank.rs +53 -0
  68. package/rust/cli/install/commands.rs +35 -0
  69. package/rust/cli/install/mod.rs +4 -0
  70. package/rust/cli/install/plugin.rs +61 -0
  71. package/rust/cli/login/commands.rs +124 -0
  72. package/rust/cli/login/mod.rs +1 -0
  73. package/rust/cli/mod.rs +12 -205
  74. package/rust/cli/parser.rs +314 -0
  75. package/rust/cli/play/commands.rs +324 -0
  76. package/rust/cli/play/io.rs +17 -0
  77. package/rust/cli/play/mod.rs +5 -0
  78. package/rust/cli/play/process.rs +150 -0
  79. package/rust/cli/play/realtime.rs +91 -0
  80. package/rust/cli/play/utils.rs +23 -0
  81. package/rust/cli/telemetry/commands.rs +22 -0
  82. package/rust/cli/telemetry/event_creator.rs +80 -0
  83. package/rust/cli/telemetry/mod.rs +3 -0
  84. package/rust/cli/telemetry/send.rs +51 -0
  85. package/rust/cli/{template.rs → template/commands.rs} +69 -57
  86. package/rust/cli/template/mod.rs +1 -0
  87. package/rust/cli/update/commands.rs +6 -0
  88. package/rust/cli/update/mod.rs +1 -0
  89. package/rust/config/driver.rs +103 -0
  90. package/rust/config/mod.rs +3 -16
  91. package/rust/config/ops.rs +26 -0
  92. package/rust/config/settings.rs +101 -0
  93. package/rust/core/audio/engine/helpers.rs +170 -0
  94. package/rust/core/audio/engine/mod.rs +7 -0
  95. package/rust/core/audio/engine/sample.rs +366 -0
  96. package/rust/core/audio/engine/synth.rs +325 -0
  97. package/rust/core/audio/evaluator.rs +310 -31
  98. package/rust/core/audio/interpreter/arrow_call.rs +311 -129
  99. package/rust/core/audio/interpreter/automate.rs +18 -0
  100. package/rust/core/audio/interpreter/call.rs +294 -64
  101. package/rust/core/audio/interpreter/condition.rs +71 -69
  102. package/rust/core/audio/interpreter/driver.rs +542 -216
  103. package/rust/core/audio/interpreter/function.rs +26 -0
  104. package/rust/core/audio/interpreter/let_.rs +38 -19
  105. package/rust/core/audio/interpreter/load.rs +19 -18
  106. package/rust/core/audio/interpreter/loop_.rs +114 -67
  107. package/rust/core/audio/interpreter/mod.rs +14 -12
  108. package/rust/core/audio/interpreter/sleep.rs +28 -36
  109. package/rust/core/audio/interpreter/spawn.rs +252 -66
  110. package/rust/core/audio/interpreter/tempo.rs +40 -16
  111. package/rust/core/audio/interpreter/trigger.rs +239 -69
  112. package/rust/core/audio/loader/mod.rs +1 -1
  113. package/rust/core/audio/loader/trigger.rs +97 -52
  114. package/rust/core/audio/mod.rs +7 -6
  115. package/rust/core/audio/player.rs +70 -54
  116. package/rust/core/audio/renderer.rs +54 -54
  117. package/rust/core/audio/special/easing.rs +189 -0
  118. package/rust/core/audio/special/env.rs +45 -0
  119. package/rust/core/audio/special/math.rs +134 -0
  120. package/rust/core/audio/special/mod.rs +9 -0
  121. package/rust/core/audio/special/modulator.rs +143 -0
  122. package/rust/core/builder/mod.rs +86 -80
  123. package/rust/core/debugger/lexer.rs +27 -27
  124. package/rust/core/debugger/mod.rs +30 -21
  125. package/rust/core/debugger/module.rs +55 -0
  126. package/rust/core/debugger/preprocessor.rs +27 -27
  127. package/rust/core/debugger/store.rs +40 -25
  128. package/rust/core/error/mod.rs +269 -60
  129. package/rust/core/lexer/driver.rs +61 -0
  130. package/rust/core/lexer/handler/arrow.rs +82 -31
  131. package/rust/core/lexer/handler/at.rs +21 -21
  132. package/rust/core/lexer/handler/brace.rs +41 -41
  133. package/rust/core/lexer/handler/colon.rs +21 -21
  134. package/rust/core/lexer/handler/comment.rs +30 -30
  135. package/rust/core/lexer/handler/dot.rs +21 -21
  136. package/rust/core/lexer/handler/driver.rs +337 -226
  137. package/rust/core/lexer/handler/identifier.rs +47 -41
  138. package/rust/core/lexer/handler/indent.rs +66 -52
  139. package/rust/core/lexer/handler/mod.rs +15 -14
  140. package/rust/core/lexer/handler/newline.rs +23 -23
  141. package/rust/core/lexer/handler/number.rs +31 -31
  142. package/rust/core/lexer/handler/operator.rs +46 -44
  143. package/rust/core/lexer/handler/parenthesis.rs +41 -0
  144. package/rust/core/lexer/handler/slash.rs +21 -0
  145. package/rust/core/lexer/handler/string.rs +63 -63
  146. package/rust/core/lexer/mod.rs +3 -51
  147. package/rust/core/lexer/token.rs +17 -12
  148. package/rust/core/mod.rs +10 -10
  149. package/rust/core/parser/driver.rs +584 -331
  150. package/rust/core/parser/handler/arrow_call.rs +253 -126
  151. package/rust/core/parser/handler/at.rs +279 -162
  152. package/rust/core/parser/handler/bank.rs +104 -41
  153. package/rust/core/parser/handler/condition.rs +83 -74
  154. package/rust/core/parser/handler/dot.rs +148 -112
  155. package/rust/core/parser/handler/identifier/automate.rs +254 -0
  156. package/rust/core/parser/handler/identifier/call.rs +91 -41
  157. package/rust/core/parser/handler/identifier/emit.rs +70 -0
  158. package/rust/core/parser/handler/identifier/function.rs +113 -0
  159. package/rust/core/parser/handler/identifier/group.rs +89 -75
  160. package/rust/core/parser/handler/identifier/let_.rs +173 -133
  161. package/rust/core/parser/handler/identifier/mod.rs +55 -51
  162. package/rust/core/parser/handler/identifier/on.rs +107 -0
  163. package/rust/core/parser/handler/identifier/print.rs +49 -0
  164. package/rust/core/parser/handler/identifier/sleep.rs +43 -33
  165. package/rust/core/parser/handler/identifier/spawn.rs +91 -41
  166. package/rust/core/parser/handler/identifier/synth.rs +135 -65
  167. package/rust/core/parser/handler/loop_.rs +194 -72
  168. package/rust/core/parser/handler/mod.rs +9 -8
  169. package/rust/core/parser/handler/pattern.rs +74 -0
  170. package/rust/core/parser/handler/tempo.rs +57 -47
  171. package/rust/core/parser/mod.rs +3 -4
  172. package/rust/core/parser/statement.rs +11 -96
  173. package/rust/core/plugin/loader.rs +137 -0
  174. package/rust/core/plugin/mod.rs +2 -0
  175. package/rust/core/plugin/runner.rs +347 -0
  176. package/rust/core/preprocessor/loader.rs +637 -193
  177. package/rust/core/preprocessor/mod.rs +4 -4
  178. package/rust/core/preprocessor/module.rs +60 -50
  179. package/rust/core/preprocessor/processor.rs +114 -76
  180. package/rust/core/preprocessor/resolver/bank.rs +49 -47
  181. package/rust/core/preprocessor/resolver/call.rs +124 -123
  182. package/rust/core/preprocessor/resolver/condition.rs +95 -92
  183. package/rust/core/preprocessor/resolver/driver.rs +324 -227
  184. package/rust/core/preprocessor/resolver/function.rs +69 -0
  185. package/rust/core/preprocessor/resolver/group.rs +94 -61
  186. package/rust/core/preprocessor/resolver/let_.rs +32 -31
  187. package/rust/core/preprocessor/resolver/loop_.rs +318 -91
  188. package/rust/core/preprocessor/resolver/mod.rs +16 -14
  189. package/rust/core/preprocessor/resolver/pattern.rs +83 -0
  190. package/rust/core/preprocessor/resolver/spawn.rs +99 -58
  191. package/rust/core/preprocessor/resolver/synth.rs +54 -50
  192. package/rust/core/preprocessor/resolver/tempo.rs +48 -49
  193. package/rust/core/preprocessor/resolver/trigger.rs +116 -112
  194. package/rust/core/preprocessor/resolver/value.rs +176 -78
  195. package/rust/core/store/export.rs +28 -28
  196. package/rust/core/store/function.rs +40 -0
  197. package/rust/core/store/global.rs +61 -39
  198. package/rust/core/store/import.rs +28 -28
  199. package/rust/core/store/mod.rs +5 -4
  200. package/rust/core/store/variable.rs +51 -28
  201. package/rust/core/utils/mod.rs +1 -2
  202. package/rust/core/utils/path.rs +37 -31
  203. package/rust/lib.rs +308 -117
  204. package/rust/main.rs +364 -65
  205. package/rust/types/Cargo.toml +11 -0
  206. package/rust/types/src/addons.rs +55 -0
  207. package/rust/types/src/ast.rs +202 -0
  208. package/rust/types/src/config.rs +74 -0
  209. package/rust/types/src/lib.rs +12 -0
  210. package/rust/types/src/telemetry.rs +85 -0
  211. package/rust/utils/Cargo.toml +26 -0
  212. package/rust/utils/src/error.rs +186 -0
  213. package/rust/utils/src/file.rs +94 -0
  214. package/rust/utils/src/first_usage.rs +97 -0
  215. package/rust/utils/{mod.rs → src/lib.rs} +9 -6
  216. package/rust/utils/{logger.rs → src/logger.rs} +200 -123
  217. package/rust/utils/src/path.rs +88 -0
  218. package/rust/utils/src/signature.rs +41 -0
  219. package/rust/utils/{spinner.rs → src/spinner.rs} +20 -21
  220. package/rust/utils/src/version.rs +27 -0
  221. package/rust/utils/{watcher.rs → src/watcher.rs} +46 -33
  222. package/rust/web/api.rs +5 -0
  223. package/rust/web/cdn.rs +34 -0
  224. package/rust/web/mod.rs +3 -0
  225. package/rust/web/sso.rs +5 -0
  226. package/templates/minimal/README.md +143 -127
  227. package/templates/welcome/README.md +143 -127
  228. package/templates/welcome/src/index.deva +56 -8
  229. package/templates/welcome/src/variables.deva +2 -4
  230. package/tests/integration.rs +21 -0
  231. package/tests/rust/cli_check_build.rs +21 -0
  232. package/tests/rust/cli_help.rs +12 -0
  233. package/tests/rust/cli_template_list.rs +10 -0
  234. package/tests/rust/cli_version.rs +11 -0
  235. package/tests/typescript/index.spec.ts +136 -0
  236. package/tests/typescript/playhead.spec.ts +36 -0
  237. package/tests/typescript/render_e2e.spec.ts +77 -0
  238. package/tsconfig.json +12 -10
  239. package/typescript/bin/index.ts +19 -5
  240. package/typescript/core/functions/index.ts +83 -0
  241. package/typescript/core/index.ts +6 -0
  242. package/typescript/core/types/index.ts +4 -0
  243. package/typescript/core/types/plugin.ts +19 -0
  244. package/typescript/core/types/result.ts +29 -0
  245. package/typescript/core/types/statement.ts +47 -0
  246. package/typescript/core/types/value.ts +29 -0
  247. package/typescript/index.ts +8 -1
  248. package/typescript/pkg/devalang_core.d.ts +4 -0
  249. package/typescript/pkg/devalang_core.ts +49 -0
  250. package/typescript/scripts/copy-wasm-dts.ts +41 -0
  251. package/typescript/scripts/postinstall.ts +85 -0
  252. package/typescript/scripts/version/bump.ts +0 -1
  253. package/typescript/scripts/version/index.ts +0 -1
  254. package/docs/COMMANDS.md +0 -85
  255. package/docs/CONFIG.md +0 -30
  256. package/docs/SYNTAX.md +0 -210
  257. package/out-tsc/bin/devalang.exe +0 -0
  258. package/out-tsc/scripts/postbuild.js +0 -11
  259. package/rust/cli/build.rs +0 -137
  260. package/rust/cli/check.rs +0 -117
  261. package/rust/cli/play.rs +0 -193
  262. package/rust/config/loader.rs +0 -13
  263. package/rust/core/audio/engine.rs +0 -203
  264. package/rust/core/shared/duration.rs +0 -8
  265. package/rust/core/shared/mod.rs +0 -2
  266. package/rust/core/shared/value.rs +0 -18
  267. package/rust/core/utils/validation.rs +0 -37
  268. package/rust/utils/file.rs +0 -35
  269. package/rust/utils/signature.rs +0 -17
  270. package/rust/utils/version.rs +0 -15
  271. 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
+ }