mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-19 00:02:28 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e99db8ba79 |
+1
-2
@@ -11,5 +11,4 @@ CaddyfileRemoteMalo
|
||||
.dev-docker-wrapper*
|
||||
backend/.minio-data
|
||||
.aider*
|
||||
!.aiderignore
|
||||
rust-client/Cargo.toml
|
||||
!.aiderignore
|
||||
@@ -1,31 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [1.501.3](https://github.com/windmill-labs/windmill/compare/v1.501.2...v1.501.3) (2025-06-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **backend:** return correct content-type for openapi spec ([#6045](https://github.com/windmill-labs/windmill/issues/6045)) ([44457c7](https://github.com/windmill-labs/windmill/commit/44457c72cf75c969de97c39bb23f57acad268e10))
|
||||
* **frontend:** load all flow jobs on page load ([#6029](https://github.com/windmill-labs/windmill/issues/6029)) ([dc5e764](https://github.com/windmill-labs/windmill/commit/dc5e764d9db9251dc356094d6ac47c45fdf72c74))
|
||||
* ignore type only imports when computing ts lockfiles ([900c8ed](https://github.com/windmill-labs/windmill/commit/900c8edd7b35802e23a1359029da8ddbfb783753))
|
||||
* improve ordering of forms for non complete ordering + array schema fix ([18ee03a](https://github.com/windmill-labs/windmill/commit/18ee03a32371885f5e608cb306b5ccbccc31dac5))
|
||||
* missing static_asset_config from api call ([#6058](https://github.com/windmill-labs/windmill/issues/6058)) ([395f1ff](https://github.com/windmill-labs/windmill/commit/395f1ff8ba05020d72d1d8b34bd6bb32517b7aec))
|
||||
|
||||
## [1.501.2](https://github.com/windmill-labs/windmill/compare/v1.501.1...v1.501.2) (2025-06-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* improve schema form handling of inconsistent order and properties ([3daf79f](https://github.com/windmill-labs/windmill/commit/3daf79ffbc45ca32ff443e5521a67d62528665db))
|
||||
|
||||
## [1.501.1](https://github.com/windmill-labs/windmill/compare/v1.501.0...v1.501.1) (2025-06-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* optimize jobs list run incremental refresh performance ([1bdd00a](https://github.com/windmill-labs/windmill/commit/1bdd00a3e4a94ecb23efb9614c341c64a67ac389))
|
||||
* pwsh skip already installed modules outside of cache ([#6037](https://github.com/windmill-labs/windmill/issues/6037)) ([29f6fab](https://github.com/windmill-labs/windmill/commit/29f6fab60c6f8cf251182a56c09bac7692868bae))
|
||||
|
||||
## [1.501.0](https://github.com/windmill-labs/windmill/compare/v1.500.3...v1.501.0) (2025-06-24)
|
||||
|
||||
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "CREATE INDEX CONCURRENTLY idx_audit_recent_login_activities \nON audit (timestamp, username) \nWHERE operation IN ('users.login', 'oauth.login', 'users.token.refresh');",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "222e29b89d10f3840d4e9b9ab63207df3cbab63c83d4a6374e72a11893841653"
|
||||
}
|
||||
Generated
+45
-96
@@ -1639,9 +1639,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
version = "3.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
@@ -2364,9 +2364,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.4"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
@@ -4502,15 +4502,6 @@ dependencies = [
|
||||
"dirs-sys 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||
dependencies = [
|
||||
"dirs-sys 0.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
@@ -4528,7 +4519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users 0.4.6",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -4540,22 +4531,10 @@ checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users 0.4.6",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users 0.5.0",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
@@ -4563,7 +4542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users 0.4.6",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -6170,26 +6149,19 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||
|
||||
[[package]]
|
||||
name = "hf-hub"
|
||||
version = "0.4.3"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "629d8f3bbeda9d148036d6b0de0a3ab947abd08ce90626327fc3547a49d59d97"
|
||||
checksum = "2b780635574b3d92f036890d8373433d6f9fc7abb320ee42a5c25897fc8ed732"
|
||||
dependencies = [
|
||||
"dirs 6.0.0",
|
||||
"futures",
|
||||
"http 1.3.1",
|
||||
"dirs 5.0.1",
|
||||
"indicatif",
|
||||
"libc",
|
||||
"log",
|
||||
"native-tls",
|
||||
"num_cpus",
|
||||
"rand 0.9.0",
|
||||
"reqwest 0.12.20",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"thiserror 1.0.69",
|
||||
"ureq",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7294,9 +7266,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.4"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"libc",
|
||||
@@ -10131,17 +10103,6 @@ dependencies = [
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
||||
dependencies = [
|
||||
"getrandom 0.2.16",
|
||||
"libredox",
|
||||
"thiserror 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast"
|
||||
version = "1.0.24"
|
||||
@@ -10450,7 +10411,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rmcp"
|
||||
version = "0.1.5"
|
||||
source = "git+https://github.com/modelcontextprotocol/rust-sdk#e6effb327883d0a8a91f5efbb527194747eee57b"
|
||||
source = "git+https://github.com/modelcontextprotocol/rust-sdk#893969ac7780897bbb804d41fb98347553386f33"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
@@ -10479,7 +10440,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rmcp-macros"
|
||||
version = "0.1.5"
|
||||
source = "git+https://github.com/modelcontextprotocol/rust-sdk#e6effb327883d0a8a91f5efbb527194747eee57b"
|
||||
source = "git+https://github.com/modelcontextprotocol/rust-sdk#893969ac7780897bbb804d41fb98347553386f33"
|
||||
dependencies = [
|
||||
"darling 0.20.11",
|
||||
"proc-macro2",
|
||||
@@ -11638,17 +11599,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socks"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sourcemap"
|
||||
version = "8.0.1"
|
||||
@@ -14076,7 +14026,6 @@ dependencies = [
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"socks",
|
||||
"url",
|
||||
"webpki-roots 0.26.11",
|
||||
]
|
||||
@@ -14616,7 +14565,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -14668,7 +14617,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -14779,7 +14728,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
@@ -14794,7 +14743,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
@@ -14807,7 +14756,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -14821,7 +14770,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -14898,7 +14847,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -14912,7 +14861,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -14935,7 +14884,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
@@ -14947,7 +14896,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -14956,7 +14905,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -14968,7 +14917,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-csharp"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -14980,7 +14929,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -14992,7 +14941,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15004,7 +14953,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-java"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15016,7 +14965,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-nu"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"nu-parser",
|
||||
@@ -15027,7 +14976,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -15038,7 +14987,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -15049,7 +14998,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15072,7 +15021,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -15089,7 +15038,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15101,7 +15050,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15119,7 +15068,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wasm"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.16",
|
||||
@@ -15143,7 +15092,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15153,7 +15102,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15186,7 +15135,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
@@ -15196,7 +15145,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15832,9 +15781,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.5.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909"
|
||||
checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rustix 1.0.7",
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -32,7 +32,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -329,7 +329,7 @@ jsonwebtoken = "8.3.0"
|
||||
pem = "3.0.1"
|
||||
nix = { version = "0.27.1", features = ["process", "signal"] }
|
||||
tinyvector = { git = "https://github.com/windmill-labs/tinyvector", rev = "20823b94c20f2b9093f318badd24026cf54dcc85" }
|
||||
hf-hub = "0.4.3"
|
||||
hf-hub = "0.3.2"
|
||||
tokenizers = "0.14.1"
|
||||
candle-core = "0.9.1"
|
||||
candle-transformers = "0.9.1"
|
||||
|
||||
@@ -29,36 +29,12 @@ use wasm_bindgen::prelude::*;
|
||||
|
||||
struct ImportsFinder {
|
||||
imports: HashSet<String>,
|
||||
skip_type_only: bool,
|
||||
}
|
||||
|
||||
impl Visit for ImportsFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_import_decl(&mut self, n: &swc_ecma_ast::ImportDecl) {
|
||||
if self.skip_type_only {
|
||||
if n.type_only {
|
||||
return;
|
||||
}
|
||||
if n.specifiers.len() > 0 {
|
||||
let mut is_type_only = true;
|
||||
|
||||
for specifier in n.specifiers.iter() {
|
||||
match specifier {
|
||||
swc_ecma_ast::ImportSpecifier::Named(
|
||||
swc_ecma_ast::ImportNamedSpecifier { is_type_only, .. },
|
||||
) if *is_type_only => (),
|
||||
_ => {
|
||||
is_type_only = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_type_only {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref s) = n.src.raw {
|
||||
let s = s.to_string();
|
||||
if s.starts_with("'") && s.ends_with("'") {
|
||||
@@ -70,7 +46,7 @@ impl Visit for ImportsFinder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_expr_for_imports(code: &str, skip_type_only: bool) -> anyhow::Result<Vec<String>> {
|
||||
pub fn parse_expr_for_imports(code: &str) -> anyhow::Result<Vec<String>> {
|
||||
let cm: Lrc<SourceMap> = Default::default();
|
||||
let fm = cm.new_source_file(FileName::Custom("main.d.ts".into()).into(), code.into());
|
||||
let mut tss = TsSyntax::default();
|
||||
@@ -96,7 +72,7 @@ pub fn parse_expr_for_imports(code: &str, skip_type_only: bool) -> anyhow::Resul
|
||||
anyhow::anyhow!("Error while parsing code, it is invalid TypeScript: {err_s}, {e:?}")
|
||||
})?;
|
||||
|
||||
let mut visitor = ImportsFinder { imports: HashSet::new(), skip_type_only };
|
||||
let mut visitor = ImportsFinder { imports: HashSet::new() };
|
||||
visitor.visit_module(&expr);
|
||||
|
||||
let mut imports: Vec<_> = visitor.imports.into_iter().collect();
|
||||
@@ -342,7 +318,7 @@ lazy_static::lazy_static! {
|
||||
}
|
||||
|
||||
pub fn remove_pinned_imports(code: &str) -> anyhow::Result<String> {
|
||||
let mut imports = parse_expr_for_imports(code, false)?;
|
||||
let mut imports = parse_expr_for_imports(code)?;
|
||||
imports.sort_by_key(|f| 0 - (f.len() as i32));
|
||||
let mut content = code.to_string();
|
||||
for import in imports {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
mod tests {
|
||||
use windmill_parser_ts::parse_expr_for_imports;
|
||||
|
||||
#[test]
|
||||
fn test_imports() {
|
||||
let code = r#"
|
||||
import { foo } from "bar";
|
||||
import type { foo } from "bar2";
|
||||
import { type foo, bar } from "bar3";
|
||||
import { bar, type foo } from "bar7";
|
||||
|
||||
import { type foo, type bar } from "bar4";
|
||||
import * as foo from "bar5";
|
||||
import foo from "bar6";
|
||||
"#;
|
||||
let imports = parse_expr_for_imports(code, true).unwrap();
|
||||
assert_eq!(imports, vec!["bar", "bar3", "bar5", "bar6", "bar7"]);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ pub fn parse_outputs(code: &str) -> String {
|
||||
#[cfg(feature = "ts-parser")]
|
||||
#[wasm_bindgen]
|
||||
pub fn parse_ts_imports(code: &str) -> String {
|
||||
let parsed = parse_expr_for_imports(code, false);
|
||||
let parsed = parse_expr_for_imports(code);
|
||||
let r = if let Ok(parsed) = parsed {
|
||||
json!({ "imports": parsed })
|
||||
} else {
|
||||
|
||||
@@ -339,7 +339,7 @@ fn test_parse_imports() -> anyhow::Result<()> {
|
||||
import { bar } from \"bar/foo/d\";
|
||||
import { bar as baroof } from \"bar\";
|
||||
";
|
||||
let mut l = parse_expr_for_imports(code, false)?;
|
||||
let mut l = parse_expr_for_imports(code)?;
|
||||
l.sort();
|
||||
assert_eq!(
|
||||
l,
|
||||
@@ -360,7 +360,7 @@ fn test_parse_imports_dts() -> anyhow::Result<()> {
|
||||
let code = "
|
||||
export type foo = number
|
||||
";
|
||||
let mut l = parse_expr_for_imports(code, false)?;
|
||||
let mut l = parse_expr_for_imports(code)?;
|
||||
l.sort();
|
||||
assert_eq!(l, vec![] as Vec<String>);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.501.3
|
||||
version: 1.501.0
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
|
||||
@@ -812,16 +812,6 @@ async fn fix_job_completed_index(db: &DB) -> Result<(), Error> {
|
||||
.execute(db)
|
||||
.await?;
|
||||
});
|
||||
|
||||
run_windmill_migration!("audit_recent_login_activities", db, |tx| {
|
||||
sqlx::query!(
|
||||
"CREATE INDEX CONCURRENTLY idx_audit_recent_login_activities
|
||||
ON audit (timestamp, username)
|
||||
WHERE operation IN ('users.login', 'oauth.login', 'users.token.refresh');"
|
||||
)
|
||||
.execute(db)
|
||||
.await?;
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ use candle_nn::VarBuilder;
|
||||
#[cfg(feature = "embedding")]
|
||||
use candle_transformers::models::bert::{BertModel, Config, DTYPE};
|
||||
#[cfg(feature = "embedding")]
|
||||
use hf_hub::api::tokio::Api;
|
||||
use hf_hub::{api::sync::Api, Cache, Repo};
|
||||
#[cfg(feature = "embedding")]
|
||||
use serde::Deserialize;
|
||||
#[cfg(feature = "embedding")]
|
||||
@@ -158,22 +158,63 @@ pub struct ModelInstance {
|
||||
#[cfg(feature = "embedding")]
|
||||
impl ModelInstance {
|
||||
pub async fn load_model_files() -> Result<(PathBuf, PathBuf, PathBuf)> {
|
||||
let api = Api::new()?;
|
||||
let repo_api = api.model("thenlper/gte-small".to_string());
|
||||
let repo = Repo::model("thenlper/gte-small".to_string());
|
||||
|
||||
let (config_filename, tokenizer_filename, weights_filename) =
|
||||
(
|
||||
repo_api
|
||||
.get("config.json")
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to get config.json from hugging face: {}", e))?,
|
||||
repo_api.get("tokenizer.json").await.map_err(|e| {
|
||||
anyhow!("Failed to get tokenizer.json from hugging face: {}", e)
|
||||
})?,
|
||||
repo_api.get("model.safetensors").await.map_err(|e| {
|
||||
anyhow!("Failed to get model.safetensors from hugging face: {}", e)
|
||||
})?,
|
||||
);
|
||||
let cache = Cache::default().repo(repo.clone());
|
||||
|
||||
let api = Api::new()?;
|
||||
let api = api.repo(repo);
|
||||
|
||||
let (config_filename, tokenizer_filename, weights_filename) = (
|
||||
cache
|
||||
.get("config.json")
|
||||
.or_else(|| {
|
||||
api.get("config.json")
|
||||
.or_else(|e| {
|
||||
tracing::error!("Failed to get config.json from hugging face: {}", e);
|
||||
return Err(e);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.ok_or(Error::msg("could not get config.json"))?,
|
||||
cache
|
||||
.get("tokenizer.json")
|
||||
.or_else(|| {
|
||||
api.get("tokenizer.json")
|
||||
.or_else(|e| {
|
||||
tracing::error!(
|
||||
"Failed to get tokenizer.json from hugging face: {}",
|
||||
e
|
||||
);
|
||||
return Err(e);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.ok_or(Error::msg("could not get tokenizer.json"))?,
|
||||
cache
|
||||
.get("model.safetensors")
|
||||
.and_then(|p| {
|
||||
tracing::info!("Found embedding model in cache");
|
||||
Some(p)
|
||||
})
|
||||
.or_else(|| {
|
||||
tracing::info!("Downloading embedding model...");
|
||||
api.get("model.safetensors")
|
||||
.or_else(|e| {
|
||||
tracing::error!(
|
||||
"Failed to get model.safetensors from hugging face: {}",
|
||||
e
|
||||
);
|
||||
return Err(e);
|
||||
})
|
||||
.ok()
|
||||
.and_then(|p| {
|
||||
tracing::info!("Downloaded embedding model");
|
||||
Some(p)
|
||||
})
|
||||
})
|
||||
.ok_or(Error::msg("could not get model.safetensors"))?,
|
||||
);
|
||||
|
||||
Ok((config_filename, tokenizer_filename, weights_filename))
|
||||
}
|
||||
|
||||
@@ -5875,7 +5875,6 @@ pub fn filter_list_completed_query(
|
||||
sqlb.and_where_le("started_at", "?".bind(&dt.to_rfc3339()));
|
||||
}
|
||||
if let Some(dt) = &lq.created_or_started_after {
|
||||
sqlb.and_where_ge("created_at", "?".bind(&dt.to_rfc3339()));
|
||||
sqlb.and_where_ge("started_at", "?".bind(&dt.to_rfc3339()));
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,8 @@ use anyhow::Context;
|
||||
use argon2::Argon2;
|
||||
use axum::extract::DefaultBodyLimit;
|
||||
use axum::{middleware::from_extractor, routing::get, routing::post, Extension, Router};
|
||||
use axum::response::Response;
|
||||
use axum::http::HeaderValue;
|
||||
use axum::body::Body;
|
||||
use db::DB;
|
||||
use http::HeaderValue;
|
||||
use reqwest::Client;
|
||||
#[cfg(feature = "oauth2")]
|
||||
use std::collections::HashMap;
|
||||
@@ -238,7 +236,6 @@ lazy_static::lazy_static! {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Compliance with cloud events spec.
|
||||
pub async fn add_webhook_allowed_origin(
|
||||
req: axum::extract::Request,
|
||||
@@ -261,7 +258,6 @@ pub async fn add_webhook_allowed_origin(
|
||||
next.run(req).await
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "tantivy"))]
|
||||
type IndexReader = ();
|
||||
|
||||
@@ -894,18 +890,12 @@ async fn ee_license() -> String {
|
||||
}
|
||||
}
|
||||
|
||||
async fn openapi() -> Response {
|
||||
Response::builder()
|
||||
.header("content-type", "application/yaml")
|
||||
.body(Body::from(include_str!("../openapi-deref.yaml")))
|
||||
.unwrap()
|
||||
async fn openapi() -> &'static str {
|
||||
include_str!("../openapi-deref.yaml")
|
||||
}
|
||||
|
||||
async fn openapi_json() -> Response {
|
||||
Response::builder()
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(include_str!("../openapi-deref.json")))
|
||||
.unwrap()
|
||||
async fn openapi_json() -> &'static str {
|
||||
include_str!("../openapi-deref.json")
|
||||
}
|
||||
|
||||
pub async fn migrate_db(db: &DB) -> anyhow::Result<Option<JoinHandle<()>>> {
|
||||
|
||||
@@ -10,8 +10,6 @@ use axum::{body::Body, extract::OriginalUri, http::Response, response::IntoRespo
|
||||
|
||||
#[cfg(feature = "static_frontend")]
|
||||
use axum::http::header;
|
||||
#[cfg(feature = "static_frontend")]
|
||||
use http::HeaderValue;
|
||||
|
||||
use hyper::Uri;
|
||||
#[cfg(feature = "static_frontend")]
|
||||
@@ -19,12 +17,6 @@ use mime_guess::mime;
|
||||
#[cfg(feature = "static_frontend")]
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
// Content Security Policy configuration
|
||||
#[cfg(feature = "static_frontend")]
|
||||
lazy_static::lazy_static! {
|
||||
static ref CSP_POLICY: String = std::env::var("CSP_POLICY").unwrap_or_default();
|
||||
}
|
||||
|
||||
// static_handler is a handler that serves static files from the
|
||||
pub async fn static_handler(OriginalUri(original_uri): OriginalUri) -> StaticFile {
|
||||
StaticFile(original_uri)
|
||||
@@ -59,13 +51,6 @@ fn serve_path(path: &str) -> Response<Body> {
|
||||
let mut res = Response::builder()
|
||||
.header(header::CONTENT_TYPE, mime.as_ref())
|
||||
.header(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||
|
||||
// Add Content-Security-Policy header for static assets when policy is set
|
||||
if !CSP_POLICY.is_empty() {
|
||||
if let Ok(header_value) = HeaderValue::try_from(CSP_POLICY.as_str()) {
|
||||
res = res.header("Content-Security-Policy", header_value);
|
||||
}
|
||||
}
|
||||
if mime.as_ref() == mime::APPLICATION_JAVASCRIPT
|
||||
|| mime.as_ref() == mime::TEXT_JAVASCRIPT
|
||||
|| path.ends_with(".wasm")
|
||||
|
||||
@@ -510,23 +510,6 @@ fn raw_to_string(x: &str) -> String {
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
const POWERSHELL_INSTALL_CODE: &str = r#"
|
||||
$availableModules = Get-Module -ListAvailable
|
||||
$path = '{path}'
|
||||
|
||||
$moduleNames = @({modules})
|
||||
|
||||
foreach ($module in $moduleNames) {
|
||||
if (-not ($availableModules | Where-Object { $_.Name -eq $module })) {
|
||||
Write-Host "Installing module $module..."
|
||||
Save-Module -Name $module -Path $path -Force
|
||||
} else {
|
||||
Write-Host "Module $module already installed"
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all)]
|
||||
pub async fn handle_powershell_job(
|
||||
mem_peak: &mut i32,
|
||||
@@ -590,34 +573,27 @@ pub async fn handle_powershell_job(
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let mut modules_to_install: Vec<String> = Vec::new();
|
||||
let mut install_string: String = String::new();
|
||||
let mut logs1 = String::new();
|
||||
for line in content.lines() {
|
||||
for cap in RE_POWERSHELL_IMPORTS.captures_iter(line) {
|
||||
let module = cap.get(1).unwrap().as_str();
|
||||
if !installed_modules.contains(&module.to_lowercase()) {
|
||||
modules_to_install.push(module.to_string());
|
||||
logs1.push_str(&format!("\n{} not found in cache", module.to_string()));
|
||||
// instead of using Install-Module, we use Save-Module so that we can specify the installation path
|
||||
install_string.push_str(&format!(
|
||||
"Save-Module -Path {} -Force {};",
|
||||
POWERSHELL_CACHE_DIR, module
|
||||
));
|
||||
} else {
|
||||
logs1.push_str(&format!("\n{} found in cache", module.to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !logs1.is_empty() {
|
||||
if !install_string.is_empty() {
|
||||
logs1.push_str("\n\nInstalling modules...");
|
||||
append_logs(&job.id, &job.workspace_id, logs1, db).await;
|
||||
}
|
||||
|
||||
if !modules_to_install.is_empty() {
|
||||
let install_string = POWERSHELL_INSTALL_CODE
|
||||
.replace("{path}", POWERSHELL_CACHE_DIR)
|
||||
.replace(
|
||||
"{modules}",
|
||||
&modules_to_install
|
||||
.iter()
|
||||
.map(|x| format!("'{x}'"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
);
|
||||
let child = Command::new(POWERSHELL_PATH.as_str())
|
||||
.args(&["-Command", &install_string])
|
||||
.stdout(Stdio::piped())
|
||||
|
||||
@@ -66,10 +66,10 @@ lazy_static::lazy_static! {
|
||||
lazy_static::lazy_static! {
|
||||
static ref PIPTAR_UPLOAD_CHANNEL: tokio::sync::mpsc::UnboundedSender<PiptarUploadTask> = {
|
||||
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
|
||||
// Spawn background task to handle uploads sequentially
|
||||
tokio::spawn(handle_piptar_uploads(rx));
|
||||
|
||||
|
||||
tx
|
||||
};
|
||||
}
|
||||
@@ -85,7 +85,7 @@ struct PiptarUploadTask {
|
||||
async fn handle_piptar_uploads(mut rx: tokio::sync::mpsc::UnboundedReceiver<PiptarUploadTask>) {
|
||||
use crate::global_cache::build_tar_and_push;
|
||||
use windmill_common::s3_helpers::get_object_store;
|
||||
|
||||
|
||||
while let Some(task) = rx.recv().await {
|
||||
if let Some(os) = get_object_store().await {
|
||||
match build_tar_and_push(os, task.venv_path.clone(), task.cache_dir, None, false).await {
|
||||
@@ -324,7 +324,6 @@ pub async fn uv_pip_compile(
|
||||
child_cmd
|
||||
.env("SystemRoot", SYSTEM_ROOT.as_str())
|
||||
.env("USERPROFILE", crate::USERPROFILE_ENV.as_str())
|
||||
.env("HOME", crate::USERPROFILE_ENV.as_str())
|
||||
.env(
|
||||
"LOCALAPPDATA",
|
||||
std::env::var("LOCALAPPDATA")
|
||||
@@ -333,29 +332,6 @@ pub async fn uv_pip_compile(
|
||||
.env(
|
||||
"TMP",
|
||||
std::env::var("TMP").unwrap_or_else(|_| String::from("/tmp")),
|
||||
)
|
||||
.env(
|
||||
"APPDATA",
|
||||
std::env::var("APPDATA")
|
||||
.unwrap_or_else(|_| format!("{}\\AppData\\Roaming", crate::USERPROFILE_ENV.as_str())),
|
||||
)
|
||||
.env(
|
||||
"ComSpec",
|
||||
std::env::var("ComSpec").unwrap_or_else(|_| String::from("C:\\Windows\\System32\\cmd.exe")),
|
||||
)
|
||||
.env(
|
||||
"PATHEXT",
|
||||
std::env::var("PATHEXT").unwrap_or_else(|_|
|
||||
String::from(".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL")
|
||||
),
|
||||
)
|
||||
.env(
|
||||
"ProgramData",
|
||||
std::env::var("ProgramData").unwrap_or_else(|_| String::from("C:\\ProgramData")),
|
||||
)
|
||||
.env(
|
||||
"ProgramFiles",
|
||||
std::env::var("ProgramFiles").unwrap_or_else(|_| String::from("C:\\Program Files")),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -626,7 +602,7 @@ pub async fn handle_python_job(
|
||||
if v == '<function call>':
|
||||
del pre_args[k]
|
||||
kwargs = inner_script.preprocessor(**pre_args)
|
||||
kwrags_json = res_to_json(kwargs)
|
||||
kwrags_json = res_to_json(kwargs)
|
||||
with open("args.json", 'w') as f:
|
||||
f.write(kwrags_json)"#
|
||||
)
|
||||
@@ -702,7 +678,7 @@ except BaseException as e:
|
||||
tb = traceback.format_tb(exc_traceback)
|
||||
with open(result_json, 'w') as f:
|
||||
err = {{ "message": str(e), "name": e.__class__.__name__, "stack": '\n'.join(tb[1:]) }}
|
||||
extra = e.__dict__
|
||||
extra = e.__dict__
|
||||
if extra and len(extra) > 0:
|
||||
err['extra'] = extra
|
||||
flow_node_id = os.environ.get('WM_FLOW_STEP_ID')
|
||||
@@ -1441,7 +1417,6 @@ async fn spawn_uv_install(
|
||||
.envs(PROXY_ENVS.clone())
|
||||
.env("SystemRoot", SYSTEM_ROOT.as_str())
|
||||
.env("USERPROFILE", crate::USERPROFILE_ENV.as_str())
|
||||
.env("HOME", HOME_ENV.as_str())
|
||||
.env(
|
||||
"TMP",
|
||||
std::env::var("TMP").unwrap_or_else(|_| String::from("/tmp")),
|
||||
@@ -1451,29 +1426,6 @@ async fn spawn_uv_install(
|
||||
std::env::var("LOCALAPPDATA")
|
||||
.unwrap_or_else(|_| format!("{}\\AppData\\Local", HOME_ENV.as_str())),
|
||||
)
|
||||
.env(
|
||||
"APPDATA",
|
||||
std::env::var("APPDATA")
|
||||
.unwrap_or_else(|_| format!("{}\\AppData\\Roaming", crate::USERPROFILE_ENV.as_str())),
|
||||
)
|
||||
.env(
|
||||
"ComSpec",
|
||||
std::env::var("ComSpec").unwrap_or_else(|_| String::from("C:\\Windows\\System32\\cmd.exe")),
|
||||
)
|
||||
.env(
|
||||
"PATHEXT",
|
||||
std::env::var("PATHEXT").unwrap_or_else(|_|
|
||||
String::from(".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL")
|
||||
),
|
||||
)
|
||||
.env(
|
||||
"ProgramData",
|
||||
std::env::var("ProgramData").unwrap_or_else(|_| String::from("C:\\ProgramData")),
|
||||
)
|
||||
.env(
|
||||
"ProgramFiles",
|
||||
std::env::var("ProgramFiles").unwrap_or_else(|_| String::from("C:\\Program Files")),
|
||||
)
|
||||
.args(&command_args[1..])
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
@@ -1858,7 +1810,7 @@ pub async fn handle_python_reqs(
|
||||
|
||||
// Create a file to indicate that installation was successfull
|
||||
let valid_path = venv_p.clone() + "/.valid.windmill";
|
||||
// This is atomic operation, meaning, that it either completes and wheel is valid,
|
||||
// This is atomic operation, meaning, that it either completes and wheel is valid,
|
||||
// or it does not and wheel is invalid and will be reinstalled next run
|
||||
if let Err(e) = File::create(&valid_path).await{
|
||||
tracing::error!(
|
||||
@@ -1990,7 +1942,7 @@ pub async fn handle_python_reqs(
|
||||
venv_path: venv_p.clone(),
|
||||
cache_dir: py_version.to_cache_dir_top_level(false),
|
||||
};
|
||||
|
||||
|
||||
if let Err(e) = PIPTAR_UPLOAD_CHANNEL.send(upload_task) {
|
||||
tracing::warn!("Failed to queue piptar upload for {venv_p}: {e}");
|
||||
} else {
|
||||
@@ -2009,7 +1961,7 @@ pub async fn handle_python_reqs(
|
||||
pids.lock().await.get_mut(i).and_then(|e| e.take());
|
||||
// Create a file to indicate that installation was successfull
|
||||
let valid_path = venv_p.clone() + "/.valid.windmill";
|
||||
// This is atomic operation, meaning, that it either completes and wheel is valid,
|
||||
// This is atomic operation, meaning, that it either completes and wheel is valid,
|
||||
// or it does not and wheel is invalid and will be reinstalled next run
|
||||
if let Err(e) = File::create(&valid_path).await{
|
||||
tracing::error!(
|
||||
|
||||
@@ -188,7 +188,7 @@ fn try_normalize(path: &Path) -> Option<PathBuf> {
|
||||
|
||||
fn parse_ts_relative_imports(raw_code: &str, script_path: &str) -> error::Result<Vec<String>> {
|
||||
let mut relative_imports = vec![];
|
||||
let r = parse_expr_for_imports(raw_code, true)?;
|
||||
let r = parse_expr_for_imports(raw_code)?;
|
||||
for import in r {
|
||||
let import = import.trim_end_matches(".ts");
|
||||
if import.starts_with("/") {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { sleep } from "https://deno.land/x/sleep@v1.2.1/mod.ts";
|
||||
import * as windmill from "https://deno.land/x/windmill@v1.174.0/mod.ts";
|
||||
import * as api from "https://deno.land/x/windmill@v1.174.0/windmill-api/index.ts";
|
||||
|
||||
export const VERSION = "v1.501.3";
|
||||
export const VERSION = "v1.501.0";
|
||||
|
||||
export async function login(email: string, password: string): Promise<string> {
|
||||
return await windmill.UserService.login({
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ export {
|
||||
// }
|
||||
// });
|
||||
|
||||
export const VERSION = "1.501.3";
|
||||
export const VERSION = "1.501.0";
|
||||
|
||||
const command = new Command()
|
||||
.name("wmill")
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.501.3",
|
||||
"version": "1.501.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-components",
|
||||
"version": "1.501.3",
|
||||
"version": "1.501.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.501.3",
|
||||
"version": "1.501.0",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
setInputCat as computeInputCat,
|
||||
debounce,
|
||||
emptyString,
|
||||
getSchemaFromProperties,
|
||||
clone
|
||||
getSchemaFromProperties
|
||||
} from '$lib/utils'
|
||||
import { DollarSign, Pipette, Plus, X, Check, Loader2 } from 'lucide-svelte'
|
||||
import { createEventDispatcher, onDestroy, onMount, tick, untrack } from 'svelte'
|
||||
@@ -245,7 +244,7 @@
|
||||
nvalue = undefined
|
||||
}
|
||||
if ((value == undefined || value == null) && !ignoreValueUndefined) {
|
||||
nvalue = clone(defaultValue)
|
||||
nvalue = structuredClone($state.snapshot(defaultValue))
|
||||
if (defaultValue === undefined || defaultValue === null) {
|
||||
if (inputCat === 'string') {
|
||||
nvalue = nullable ? null : ''
|
||||
@@ -297,7 +296,7 @@
|
||||
lastValue = value
|
||||
}
|
||||
|
||||
let oldDefaultValue = clone(defaultValue)
|
||||
let oldDefaultValue = structuredClone($state.snapshot(defaultValue))
|
||||
function handleDefaultValueChange() {
|
||||
if (
|
||||
deepEqual(value, oldDefaultValue) &&
|
||||
@@ -306,7 +305,7 @@
|
||||
) {
|
||||
value = defaultValue
|
||||
}
|
||||
oldDefaultValue = clone(defaultValue)
|
||||
oldDefaultValue = structuredClone($state.snapshot(defaultValue))
|
||||
}
|
||||
|
||||
function isObjectCat(inputCat?: string) {
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
import Alert from './common/alert/Alert.svelte'
|
||||
import EditableSchemaDrawer from './schema/EditableSchemaDrawer.svelte'
|
||||
import type { SchemaProperty } from '$lib/common'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import { tick } from 'svelte'
|
||||
|
||||
interface Props {
|
||||
canEditResourceType?: boolean
|
||||
@@ -50,6 +48,20 @@
|
||||
? 'bytes'
|
||||
: 'string'
|
||||
)
|
||||
|
||||
let schema = $state({
|
||||
properties: itemsType?.properties || {},
|
||||
order: Object.keys(itemsType?.properties || {}),
|
||||
required: Object.values(itemsType?.properties || {}).map((p) => p.required)
|
||||
})
|
||||
|
||||
function updateItemsType() {
|
||||
itemsType = {
|
||||
...itemsType,
|
||||
properties: schema.properties,
|
||||
type: 'object'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if canEditResourceType || originalType == 'string[]' || originalType == 'object[]'}
|
||||
@@ -168,40 +180,10 @@
|
||||
{/if}
|
||||
|
||||
{#if selected === 'object'}
|
||||
<Toggle
|
||||
bind:checked={
|
||||
() => {
|
||||
return itemsType?.properties != undefined
|
||||
},
|
||||
async (v) => {
|
||||
await tick()
|
||||
if (v) {
|
||||
itemsType = { type: 'object', properties: {} }
|
||||
} else {
|
||||
itemsType = { type: 'object', properties: undefined }
|
||||
}
|
||||
}
|
||||
}
|
||||
options={{ left: 'JSON', right: 'Custom Object' }}
|
||||
<EditableSchemaDrawer
|
||||
bind:schema
|
||||
on:change={() => {
|
||||
updateItemsType()
|
||||
}}
|
||||
/>
|
||||
{#if itemsType?.properties != undefined}
|
||||
<EditableSchemaDrawer
|
||||
bind:schema={
|
||||
() => {
|
||||
return {
|
||||
properties: itemsType?.properties || {},
|
||||
order: Object.keys(itemsType?.properties || {}),
|
||||
required: Object.values(itemsType?.properties || {}).map((p) => p.required)
|
||||
}
|
||||
},
|
||||
(schema) => {
|
||||
itemsType = {
|
||||
...itemsType,
|
||||
properties: schema.properties,
|
||||
type: 'object'
|
||||
}
|
||||
}
|
||||
}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
orderedJsonStringify,
|
||||
orderedYamlStringify,
|
||||
replaceFalseWithUndefined,
|
||||
type Value,
|
||||
clone
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
import type { Script } from '$lib/gen'
|
||||
|
||||
@@ -69,7 +68,7 @@
|
||||
}
|
||||
|
||||
function prepareDiff(data: Value) {
|
||||
const metadata = clone(cleanValueProperties(replaceFalseWithUndefined(data)))
|
||||
const metadata = structuredClone(cleanValueProperties(replaceFalseWithUndefined(data)))
|
||||
const content = metadata['content']
|
||||
if (metadata['content'] !== undefined) {
|
||||
metadata['content'] = 'check content diff'
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
import Tooltip from './Tooltip.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { readFieldsRecursively, clone} from '$lib/utils'
|
||||
import { readFieldsRecursively } from '$lib/utils'
|
||||
|
||||
interface Props {
|
||||
value?: any
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
let { value = $bindable(), helperScript, entrypoint, args: _args, name }: Props = $props()
|
||||
|
||||
let args = $state(clone(_args))
|
||||
let args = $state(structuredClone($state.snapshot(_args)))
|
||||
$effect(() => {
|
||||
readFieldsRecursively(_args, { excludeField: [name] })
|
||||
untrack(() => !deepEqual(args, _args) && (args = $state.snapshot(_args)))
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import Label from './Label.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import { emptyString, clone} from '$lib/utils'
|
||||
import { emptyString } from '$lib/utils'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
import SchemaFormDnd from './schema/SchemaFormDND.svelte'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
@@ -114,7 +114,7 @@
|
||||
Object.keys(schema?.properties ?? {}).forEach((key) => {
|
||||
if (schema?.properties[key].default != undefined && args?.[key] == undefined) {
|
||||
let value = schema?.properties[key].default
|
||||
nargs[key] = value === 'object' ? clone(value) : value
|
||||
nargs[key] = value === 'object' ? structuredClone($state.snapshot(value)) : value
|
||||
}
|
||||
})
|
||||
args = nargs
|
||||
|
||||
@@ -155,7 +155,6 @@
|
||||
import { writable } from 'svelte/store'
|
||||
import { formatResourceTypes } from './copilot/chat/script/core'
|
||||
import FakeMonacoPlaceHolder from './FakeMonacoPlaceHolder.svelte'
|
||||
import { editorPositionMap } from '$lib/utils'
|
||||
// import EditorTheme from './EditorTheme.svelte'
|
||||
|
||||
let divEl: HTMLDivElement | null = null
|
||||
@@ -189,7 +188,6 @@
|
||||
export let extraLib: string | undefined = undefined
|
||||
export let changeTimeout: number = 500
|
||||
export let loadAsync = false
|
||||
export let key: string | undefined = undefined
|
||||
|
||||
let lang = scriptLangToEditorLang(scriptLang)
|
||||
$: lang = scriptLangToEditorLang(scriptLang)
|
||||
@@ -1279,10 +1277,6 @@
|
||||
tabSize: lang == 'python' ? 4 : 2,
|
||||
folding
|
||||
})
|
||||
if (key && editorPositionMap?.[key]) {
|
||||
editor.setPosition(editorPositionMap[key])
|
||||
editor.revealPositionInCenterIfOutsideViewport(editorPositionMap[key])
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading monaco:', e)
|
||||
return
|
||||
@@ -1312,10 +1306,6 @@
|
||||
dispatch('blur')
|
||||
})
|
||||
|
||||
editor?.onDidChangeCursorPosition((event) => {
|
||||
if (key) editorPositionMap[key] = event.position
|
||||
})
|
||||
|
||||
editor?.onDidFocusEditorText(() => {
|
||||
dispatch('focus')
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
readFieldsRecursively,
|
||||
replaceFalseWithUndefined,
|
||||
type StateStore,
|
||||
type Value,
|
||||
clone
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { Drawer } from '$lib/components/common'
|
||||
@@ -76,11 +75,6 @@
|
||||
import { Triggers } from './triggers/triggers.svelte'
|
||||
import { TestSteps } from './flows/testSteps.svelte'
|
||||
import { aiChatManager } from './copilot/chat/AIChatManager.svelte'
|
||||
import {
|
||||
setStepHistoryLoaderContext,
|
||||
StepHistoryLoader,
|
||||
type stepState
|
||||
} from './stepHistoryLoader.svelte'
|
||||
|
||||
interface Props {
|
||||
initialPath?: string
|
||||
@@ -102,11 +96,6 @@
|
||||
draftTriggersFromUrl?: Trigger[] | undefined
|
||||
selectedTriggerIndexFromUrl?: number | undefined
|
||||
children?: import('svelte').Snippet
|
||||
loadedFromHistoryFromUrl?: {
|
||||
flowJobInitial: boolean | undefined
|
||||
stepsState: Record<string, stepState>
|
||||
}
|
||||
noInitial?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -128,9 +117,7 @@
|
||||
setSavedraftCb = undefined,
|
||||
draftTriggersFromUrl = undefined,
|
||||
selectedTriggerIndexFromUrl = undefined,
|
||||
children,
|
||||
loadedFromHistoryFromUrl,
|
||||
noInitial = false
|
||||
children
|
||||
}: Props = $props()
|
||||
|
||||
let initialPathStore = writable(initialPath)
|
||||
@@ -186,7 +173,7 @@
|
||||
savedValue: savedFlow,
|
||||
modifiedValue: {
|
||||
...flowStore.val,
|
||||
draft_triggers: clone(triggersState.getDraftTriggersSnapshot())
|
||||
draft_triggers: structuredClone(triggersState.getDraftTriggersSnapshot())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +238,7 @@
|
||||
|
||||
if (savedFlow) {
|
||||
const draftOrDeployed = cleanValueProperties(savedFlow.draft || savedFlow)
|
||||
const currentDraftTriggers = clone(triggersState.getDraftTriggersSnapshot())
|
||||
const currentDraftTriggers = structuredClone(triggersState.getDraftTriggersSnapshot())
|
||||
const current = cleanValueProperties(
|
||||
$state.snapshot({
|
||||
...flowStore.val,
|
||||
@@ -330,15 +317,15 @@
|
||||
savedFlow = {
|
||||
...(newFlow || savedFlow?.draft_only
|
||||
? {
|
||||
...clone(flowStore.val),
|
||||
...structuredClone($state.snapshot(flowStore.val)),
|
||||
path: $pathStore,
|
||||
draft_only: true
|
||||
}
|
||||
: savedFlow),
|
||||
draft: {
|
||||
...clone(flowStore.val),
|
||||
...structuredClone($state.snapshot(flowStore.val)),
|
||||
path: $pathStore,
|
||||
draft_triggers: clone(triggersState.getDraftTriggersSnapshot())
|
||||
draft_triggers: structuredClone(triggersState.getDraftTriggersSnapshot())
|
||||
}
|
||||
} as FlowWithDraftAndDraftTriggers
|
||||
|
||||
@@ -520,7 +507,7 @@
|
||||
draft_triggers: Trigger[]
|
||||
}
|
||||
savedFlow = {
|
||||
...clone(newSavedFlow),
|
||||
...structuredClone($state.snapshot(newSavedFlow)),
|
||||
path: $pathStore
|
||||
} as Flow
|
||||
setDraftTriggers([])
|
||||
@@ -546,11 +533,7 @@
|
||||
path: $pathStore,
|
||||
selectedId: $selectedIdStore,
|
||||
draft_triggers: triggersState.getDraftTriggersSnapshot(),
|
||||
selected_trigger: triggersState.getSelectedTriggerSnapshot(),
|
||||
loadedFromHistory: {
|
||||
flowJobInitial: stepHistoryLoader.flowJobInitial,
|
||||
stepsState: stepHistoryLoader.stepStates
|
||||
}
|
||||
selected_trigger: triggersState.getSelectedTriggerSnapshot()
|
||||
})
|
||||
)
|
||||
} catch (err) {
|
||||
@@ -850,40 +833,6 @@
|
||||
const hasAiDiff = aiChatManager.flowAiChatHelpers?.hasDiff() ?? false
|
||||
customUi && untrack(() => onCustomUiChange(customUi, hasAiDiff))
|
||||
})
|
||||
|
||||
export async function loadFlowState() {
|
||||
await stepHistoryLoader.loadIndividualStepsStates(
|
||||
flowStore.val as Flow,
|
||||
flowStateStore,
|
||||
$workspaceStore!,
|
||||
$initialPathStore,
|
||||
$pathStore
|
||||
)
|
||||
}
|
||||
|
||||
let stepHistoryLoader = new StepHistoryLoader(
|
||||
loadedFromHistoryFromUrl?.stepsState ?? {},
|
||||
loadedFromHistoryFromUrl?.flowJobInitial,
|
||||
saveSessionDraft,
|
||||
noInitial
|
||||
)
|
||||
setStepHistoryLoaderContext(stepHistoryLoader)
|
||||
|
||||
export function setLoadedFromHistory(
|
||||
loadedFromHistoryUrl:
|
||||
| {
|
||||
flowJobInitial: boolean | undefined
|
||||
stepsState: Record<string, stepState>
|
||||
}
|
||||
| undefined
|
||||
) {
|
||||
if (!loadedFromHistoryUrl) {
|
||||
return
|
||||
}
|
||||
|
||||
stepHistoryLoader.setFlowJobInitial(loadedFromHistoryUrl.flowJobInitial)
|
||||
stepHistoryLoader.stepStates = loadedFromHistoryUrl.stepsState
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={onKeyDown} />
|
||||
@@ -1043,7 +992,7 @@
|
||||
|
||||
await syncWithDeployed()
|
||||
|
||||
const currentDraftTriggers = clone(
|
||||
const currentDraftTriggers = structuredClone(
|
||||
triggersState.getDraftTriggersSnapshot()
|
||||
)
|
||||
|
||||
@@ -1144,9 +1093,6 @@
|
||||
}}
|
||||
{forceTestTab}
|
||||
{highlightArg}
|
||||
onRunPreview={() => {
|
||||
flowPreviewButtons?.openPreview(true)
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<CenteredPage>Loading...</CenteredPage>
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
import Toggle from './Toggle.svelte'
|
||||
import JsonInputs from './JsonInputs.svelte'
|
||||
import FlowHistoryJobPicker from './FlowHistoryJobPicker.svelte'
|
||||
import { NEVER_TESTED_THIS_FAR } from './flows/models'
|
||||
import { writable, type Writable } from 'svelte/store'
|
||||
import type { DurationStatus, GraphModuleState } from './graph'
|
||||
import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte'
|
||||
import { aiChatManager } from './copilot/chat/AIChatManager.svelte'
|
||||
import { stateSnapshot } from '$lib/svelte5Utils.svelte'
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
export let jobId: string | undefined = undefined
|
||||
export let job: Job | undefined = undefined
|
||||
export let initial: boolean = false
|
||||
|
||||
export let selectedJobStep: string | undefined = undefined
|
||||
export let selectedJobStepIsTopLevel: boolean | undefined = undefined
|
||||
@@ -70,8 +71,6 @@
|
||||
} = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let stepHistoryLoader = getStepHistoryLoaderContext()
|
||||
|
||||
let renderCount: number = 0
|
||||
let schemaFormWithArgPicker: SchemaFormWithArgPicker | undefined = undefined
|
||||
let currentJobId: string | undefined = undefined
|
||||
@@ -97,8 +96,8 @@
|
||||
args: Record<string, any>,
|
||||
restartedFrom: RestartedFrom | undefined
|
||||
) {
|
||||
if (stepHistoryLoader?.flowJobInitial) {
|
||||
stepHistoryLoader?.setFlowJobInitial(false)
|
||||
if (initial) {
|
||||
initial = false
|
||||
}
|
||||
try {
|
||||
lastPreviewFlow = JSON.stringify(flowStore.val)
|
||||
@@ -187,6 +186,44 @@
|
||||
|
||||
$: selectedJobStep !== undefined && onSelectedJobStepChange()
|
||||
|
||||
async function loadIndividualStepsStates() {
|
||||
// console.log('loadIndividualStepsStates')
|
||||
dfs(flowStore.val.value.modules, async (module) => {
|
||||
// console.log('module', $flowStateStore[module.id], module.id)
|
||||
const prev = $flowStateStore[module.id]?.previewResult
|
||||
if (prev && prev != NEVER_TESTED_THIS_FAR) {
|
||||
return
|
||||
}
|
||||
const previousJobId = await JobService.listJobs({
|
||||
workspace: $workspaceStore!,
|
||||
scriptPathExact:
|
||||
`path` in module.value
|
||||
? module.value.path
|
||||
: ($initialPathStore == '' ? $pathStore : $initialPathStore) + '/' + module.id,
|
||||
jobKinds: ['preview', 'script', 'flowpreview', 'flow', 'flowscript'].join(','),
|
||||
page: 1,
|
||||
perPage: 1
|
||||
})
|
||||
// console.log('previousJobId', previousJobId, module.id)
|
||||
|
||||
if (previousJobId.length > 0) {
|
||||
const getJobResult = await JobService.getCompletedJobResultMaybe({
|
||||
workspace: $workspaceStore!,
|
||||
id: previousJobId[0].id
|
||||
})
|
||||
if ('result' in getJobResult) {
|
||||
$flowStateStore[module.id] = {
|
||||
...($flowStateStore[module.id] ?? {}),
|
||||
previewResult: getJobResult.result,
|
||||
previewJobId: previousJobId[0].id,
|
||||
previewWorkspaceId: previousJobId[0].workspace_id,
|
||||
previewSuccess: getJobResult.success
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let scrollableDiv: HTMLDivElement | undefined = undefined
|
||||
function handleScroll() {
|
||||
scrollTop = scrollableDiv?.scrollTop ?? 0
|
||||
@@ -449,15 +486,16 @@
|
||||
>
|
||||
<FlowHistoryJobPicker
|
||||
selectInitial={jobId == undefined}
|
||||
on:nohistory={() => {
|
||||
loadIndividualStepsStates()
|
||||
}}
|
||||
on:select={(e) => {
|
||||
if (!currentJobId) {
|
||||
currentJobId = jobId
|
||||
}
|
||||
const detail = e.detail
|
||||
initial = detail.initial
|
||||
jobId = detail.jobId
|
||||
if (detail.initial && stepHistoryLoader?.flowJobInitial === undefined) {
|
||||
stepHistoryLoader?.setFlowJobInitial(detail.initial)
|
||||
}
|
||||
}}
|
||||
on:unselect={() => {
|
||||
jobId = currentJobId
|
||||
@@ -467,12 +505,12 @@
|
||||
/>
|
||||
</div>
|
||||
{#if jobId}
|
||||
{#if stepHistoryLoader?.flowJobInitial}
|
||||
{#if initial}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
on:click={() => {
|
||||
stepHistoryLoader?.setFlowJobInitial(false)
|
||||
initial = false
|
||||
}}
|
||||
class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 rounded bg-gray-500/40 absolute top-0 left-0 w-full z-50"
|
||||
>
|
||||
@@ -494,6 +532,12 @@
|
||||
on:done={() => {
|
||||
$executionCount = $executionCount + 1
|
||||
}}
|
||||
on:jobsLoaded={() => {
|
||||
if (initial) {
|
||||
console.log('loading initial steps after initial job loaded')
|
||||
loadIndividualStepsStates()
|
||||
}
|
||||
}}
|
||||
bind:selectedJobStep
|
||||
bind:rightColumnSelect
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import { type RunnableType, type Job } from '$lib/gen/index.js'
|
||||
import { sendUserToast } from '$lib/utils.js'
|
||||
import RunningJobSchemaPicker from '$lib/components/schema/RunningJobSchemaPicker.svelte'
|
||||
@@ -49,7 +48,7 @@
|
||||
dispatch('select', { args: fullPayload, jobId: data.id })
|
||||
} else {
|
||||
dispatch('select', {
|
||||
args: clone(data.payloadData),
|
||||
args: structuredClone($state.snapshot(data.payloadData)),
|
||||
jobId: data.id
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import type ItemPicker from './ItemPicker.svelte'
|
||||
import type { InputTransform } from '$lib/gen'
|
||||
import TemplateEditor from './TemplateEditor.svelte'
|
||||
import { setInputCat as computeInputCat, isCodeInjection, clone} from '$lib/utils'
|
||||
import { setInputCat as computeInputCat, isCodeInjection } from '$lib/utils'
|
||||
import { FunctionSquare, InfoIcon } from 'lucide-svelte'
|
||||
import { getResourceTypes } from './resourceTypesStore'
|
||||
import type { FlowCopilotContext } from './copilot/flow'
|
||||
@@ -280,7 +280,7 @@
|
||||
function onArgChange() {
|
||||
const newArg = { arg, propertyType, inputCat }
|
||||
if (!deepEqual(newArg, prevArg)) {
|
||||
prevArg = clone(newArg)
|
||||
prevArg = structuredClone($state.snapshot(newArg))
|
||||
updateStaticInput(inputCat, propertyType, arg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
disableMock?: boolean
|
||||
disableHistory?: boolean
|
||||
onUpdateMock?: (mock: { enabled: boolean; return_value?: unknown }) => void
|
||||
loadingHistory?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -39,8 +38,7 @@
|
||||
testIsLoading = false,
|
||||
disableMock = false,
|
||||
disableHistory = false,
|
||||
onUpdateMock,
|
||||
loadingHistory = false
|
||||
onUpdateMock
|
||||
}: Props = $props()
|
||||
|
||||
const { testSteps } = getContext<FlowEditorContext>('FlowEditorContext')
|
||||
@@ -84,7 +82,7 @@
|
||||
mock={mod.mock}
|
||||
bind:forceJson
|
||||
bind:selectedJob
|
||||
isLoading={(testIsLoading && !scriptProgress) || fetchingLastJob || loadingHistory}
|
||||
isLoading={(testIsLoading && !scriptProgress) || fetchingLastJob}
|
||||
bind:preview
|
||||
path={`path` in mod.value ? mod.value.path : ''}
|
||||
{loopStatus}
|
||||
@@ -114,9 +112,7 @@
|
||||
duration={selectedJob?.['duration_ms']}
|
||||
mem={selectedJob?.['mem_peak']}
|
||||
content={selectedJob?.logs}
|
||||
isLoading={(testIsLoading && selectedJob?.['running'] == false) ||
|
||||
fetchingLastJob ||
|
||||
loadingHistory}
|
||||
isLoading={(testIsLoading && selectedJob?.['running'] == false) || fetchingLastJob}
|
||||
tag={selectedJob?.tag}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import type { FlowEditorContext } from './flows/types'
|
||||
import TestJobLoader from './TestJobLoader.svelte'
|
||||
import { getStepHistoryLoaderContext } from './stepHistoryLoader.svelte'
|
||||
|
||||
interface Props {
|
||||
mod: FlowModule
|
||||
@@ -38,7 +37,6 @@
|
||||
|
||||
let testJobLoader: TestJobLoader | undefined = $state(undefined)
|
||||
let jobProgressReset: () => void = () => {}
|
||||
let stepHistoryLoader = getStepHistoryLoaderContext()
|
||||
|
||||
export function runTestWithStepArgs() {
|
||||
runTest(testSteps.getStepArgs(mod.id)?.value)
|
||||
@@ -94,7 +92,6 @@
|
||||
$flowStateStore[mod.id].previewWorkspaceId = testJob.workspace_id
|
||||
$flowStateStore = $flowStateStore
|
||||
}
|
||||
stepHistoryLoader?.resetInitial(mod.id)
|
||||
}
|
||||
testJob = undefined
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import { Button } from '$lib/components/common'
|
||||
import { InputService, type Input, type RunnableType } from '$lib/gen/index.js'
|
||||
import { userStore, workspaceStore } from '$lib/stores.js'
|
||||
@@ -138,7 +137,7 @@
|
||||
const fullPayload = await input.getFullPayload?.()
|
||||
dispatch('select', fullPayload)
|
||||
} else {
|
||||
selectedArgs = clone($state.snapshot(input.payloadData) ?? {})
|
||||
selectedArgs = structuredClone($state.snapshot(input.payloadData) ?? {})
|
||||
dispatch('select', selectedArgs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import SavedInputsPicker from '$lib/components/SavedInputsPicker.svelte'
|
||||
import { createEventDispatcher, tick } from 'svelte'
|
||||
import HistoricInputs from '$lib/components/HistoricInputs.svelte'
|
||||
@@ -163,7 +162,7 @@
|
||||
{/if}
|
||||
<Button
|
||||
on:click={async () => {
|
||||
appliedSearchArgs = clone(searchArgs)
|
||||
appliedSearchArgs = structuredClone($state.snapshot(searchArgs))
|
||||
await tick()
|
||||
historicInputs?.refresh(true)
|
||||
}}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { Schema } from '$lib/common'
|
||||
import { VariableService, type Script } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { allTrue, computeShow, clone } from '$lib/utils'
|
||||
import { allTrue, computeShow } from '$lib/utils'
|
||||
import { Button } from './common'
|
||||
import ItemPicker from './ItemPicker.svelte'
|
||||
import VariableEditor from './VariableEditor.svelte'
|
||||
@@ -119,12 +119,12 @@
|
||||
let inputCheck: { [id: string]: boolean } = $state({})
|
||||
|
||||
export function setDefaults() {
|
||||
const nargs = clone(defaultValues)
|
||||
const nargs = structuredClone($state.snapshot(defaultValues))
|
||||
|
||||
Object.keys(schema?.properties ?? {}).forEach((key) => {
|
||||
if (schema?.properties[key].default != undefined && args && args[key] == undefined) {
|
||||
let value = schema?.properties[key].default
|
||||
nargs[key] = value === 'object' ? clone(value) : value
|
||||
nargs[key] = value === 'object' ? structuredClone($state.snapshot(value)) : value
|
||||
}
|
||||
})
|
||||
args = nargs
|
||||
@@ -163,19 +163,19 @@
|
||||
if (!deepEqual(schema?.order, lkeys) || !deepEqual(keys, lkeys)) {
|
||||
if (schema?.order && Array.isArray(schema.order)) {
|
||||
const n = {}
|
||||
|
||||
;(schema.order as string[]).forEach((x) => {
|
||||
if (schema.properties && schema.properties[x] != undefined) {
|
||||
n[x] = schema.properties[x]
|
||||
}
|
||||
})
|
||||
|
||||
Object.keys(schema.properties ?? {})
|
||||
.filter((x) => !schema.order?.includes(x))
|
||||
.forEach((x) => {
|
||||
n[x] = schema.properties[x]
|
||||
})
|
||||
if (!deepEqual(schema.properties, n) || !deepEqual(schema.properties, Object.keys(n))) {
|
||||
schema.properties = n
|
||||
}
|
||||
schema.properties = n
|
||||
}
|
||||
let nkeys = Object.keys(schema.properties ?? {})
|
||||
|
||||
@@ -221,10 +221,20 @@
|
||||
args = {}
|
||||
}
|
||||
})
|
||||
|
||||
$effect.pre(() => {
|
||||
schema.order
|
||||
Object.keys(schema.properties ?? {})
|
||||
const newKeys = [
|
||||
...new Set(
|
||||
(Array.isArray(schema?.order)
|
||||
? schema?.order
|
||||
: Object.keys(schema?.properties ?? {})) as string[]
|
||||
)
|
||||
]
|
||||
|
||||
if (!deepEqual(keys, newKeys)) {
|
||||
keys = newKeys
|
||||
}
|
||||
})
|
||||
$effect.pre(() => {
|
||||
schema && (untrack(() => reorder()), (hidden = {}))
|
||||
})
|
||||
$effect.pre(() => {
|
||||
@@ -259,8 +269,7 @@
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
<!-- {JSON.stringify(schema.order)} -->
|
||||
<!-- {JSON.stringify(schema)} -->
|
||||
|
||||
<div
|
||||
class="w-full {className} {flexWrap ? 'flex flex-row flex-wrap gap-x-6 ' : ''} {nestedClasses}"
|
||||
use:dragHandleZone={dndConfig ?? { items: [], dragDisabled: true }}
|
||||
@@ -294,7 +303,7 @@
|
||||
pattern={formerProperty?.pattern}
|
||||
valid={inputCheck[argName]}
|
||||
defaultValue={defaultValues?.[argName] ??
|
||||
clone(formerProperty?.default)}
|
||||
structuredClone($state.snapshot(formerProperty?.default))}
|
||||
enum_={dynamicEnums?.[argName] ?? formerProperty?.enum}
|
||||
format={formerProperty?.format}
|
||||
contentEncoding={formerProperty?.contentEncoding}
|
||||
@@ -365,7 +374,7 @@
|
||||
pattern={schema.properties[argName].pattern}
|
||||
bind:valid={inputCheck[argName]}
|
||||
defaultValue={defaultValues?.[argName] ??
|
||||
clone(schema.properties[argName].default)}
|
||||
structuredClone($state.snapshot(schema.properties[argName].default))}
|
||||
enum_={dynamicEnums?.[argName] ?? schema.properties[argName].enum}
|
||||
format={schema.properties[argName].format}
|
||||
contentEncoding={schema.properties[argName].contentEncoding}
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
generateRandomString,
|
||||
orderedJsonStringify,
|
||||
replaceFalseWithUndefined,
|
||||
type Value,
|
||||
clone
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
import Path from './Path.svelte'
|
||||
import ScriptEditor from './ScriptEditor.svelte'
|
||||
@@ -144,7 +143,7 @@
|
||||
savedValue: savedScript,
|
||||
modifiedValue: {
|
||||
...script,
|
||||
draft_triggers: clone(triggersState.getDraftTriggersSnapshot())
|
||||
draft_triggers: structuredClone(triggersState.getDraftTriggersSnapshot())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,7 +336,7 @@
|
||||
'#' +
|
||||
encodeState({
|
||||
...script,
|
||||
draft_triggers: clone(triggersState.getDraftTriggersSnapshot())
|
||||
draft_triggers: structuredClone(triggersState.getDraftTriggersSnapshot())
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -563,8 +562,8 @@
|
||||
)
|
||||
}
|
||||
|
||||
const { draft_triggers: _, ...newScript } = clone(script)
|
||||
savedScript = clone(newScript) as NewScriptWithDraft
|
||||
const { draft_triggers: _, ...newScript } = structuredClone($state.snapshot(script))
|
||||
savedScript = structuredClone($state.snapshot(newScript)) as NewScriptWithDraft
|
||||
setDraftTriggers([])
|
||||
|
||||
if (!disableHistoryChange) {
|
||||
@@ -590,7 +589,7 @@
|
||||
|
||||
if (savedScript) {
|
||||
const draftOrDeployed = cleanValueProperties(savedScript.draft || savedScript)
|
||||
const currentTriggers = clone(triggersState.getDraftTriggersSnapshot())
|
||||
const currentTriggers = structuredClone(triggersState.getDraftTriggersSnapshot())
|
||||
const current = cleanValueProperties({ ...script, draft_triggers: currentTriggers })
|
||||
if (!forceSave && orderedJsonStringify(draftOrDeployed) === orderedJsonStringify(current)) {
|
||||
sendUserToast('No changes detected, ignoring', false, [
|
||||
@@ -695,7 +694,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
const clonedScript = clone(script)
|
||||
const clonedScript = structuredClone($state.snapshot(script))
|
||||
savedScript = {
|
||||
...(initialPath == '' || savedScript?.draft_only
|
||||
? { ...clonedScript, draft_only: true }
|
||||
@@ -755,7 +754,7 @@
|
||||
}
|
||||
await syncWithDeployed()
|
||||
|
||||
const currentDraftTriggers = clone(
|
||||
const currentDraftTriggers = structuredClone(
|
||||
triggersState.getDraftTriggersSnapshot()
|
||||
)
|
||||
|
||||
@@ -1126,7 +1125,7 @@
|
||||
>
|
||||
<LanguageIcon {lang} />
|
||||
<span class="ml-2 py-2 truncate">{label}</span>
|
||||
{#if lang === 'nu'}
|
||||
{#if lang === 'ansible' || lang === 'nu'}
|
||||
<span class="text-tertiary !text-xs"> BETA </span>
|
||||
{/if}
|
||||
</Button>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy'
|
||||
|
||||
import TableCustom from './TableCustom.svelte'
|
||||
|
||||
import { GroupService, UserService, GranularAclService } from '$lib/gen'
|
||||
@@ -40,9 +42,7 @@
|
||||
let ownerKind: 'user' | 'group' = $state('user')
|
||||
let owner: string = $state('')
|
||||
|
||||
let newOwner: string = $derived.by(
|
||||
() => owner && [ownerKind === 'group' ? 'g' : 'u', owner].join('/')
|
||||
)
|
||||
let newOwner: string = $state('')
|
||||
let write: boolean = false
|
||||
let acls: [string, boolean][] = $state([])
|
||||
let groups: String[] = $state([])
|
||||
@@ -50,6 +50,10 @@
|
||||
|
||||
let drawer: Drawer | undefined = $state()
|
||||
|
||||
run(() => {
|
||||
newOwner = [ownerKind === 'group' ? 'g' : 'u', owner].join('/')
|
||||
})
|
||||
|
||||
let own = $state(false)
|
||||
export async function openDrawer(newPath: string, kind_l: Kind) {
|
||||
path = newPath
|
||||
@@ -141,9 +145,7 @@
|
||||
bind:value={owner}
|
||||
/>
|
||||
{/key}
|
||||
<Button size="sm" disabled={!newOwner} on:click={() => addAcl(newOwner, write)}
|
||||
>Add permission</Button
|
||||
>
|
||||
<Button size="sm" on:click={() => addAcl(newOwner, write)}>Add permission</Button>
|
||||
</div>
|
||||
{/if}
|
||||
<TableCustom>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
languages,
|
||||
type IRange,
|
||||
type IDisposable,
|
||||
type IPosition
|
||||
Position
|
||||
} from 'monaco-editor'
|
||||
|
||||
languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
@@ -79,7 +79,6 @@
|
||||
import { vimMode } from '$lib/stores'
|
||||
import { initVim } from './monaco_keybindings'
|
||||
import FakeMonacoPlaceHolder from './FakeMonacoPlaceHolder.svelte'
|
||||
import { editorPositionMap } from '$lib/utils'
|
||||
// import { createConfiguredEditor } from 'vscode/monaco'
|
||||
// import type { IStandaloneCodeEditor } from 'vscode/vscode/vs/editor/standalone/browser/standaloneCodeEditor'
|
||||
|
||||
@@ -116,8 +115,7 @@
|
||||
allowVim = false,
|
||||
tailwindClasses = [],
|
||||
class: className = '',
|
||||
loadAsync = false,
|
||||
key
|
||||
loadAsync = false
|
||||
}: {
|
||||
lang: string
|
||||
code?: string
|
||||
@@ -140,8 +138,6 @@
|
||||
tailwindClasses?: string[]
|
||||
class?: string
|
||||
loadAsync?: boolean
|
||||
initialCursorPos?: IPosition
|
||||
key?: string
|
||||
} = $props()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -240,6 +236,13 @@
|
||||
suggestion = value
|
||||
}
|
||||
|
||||
export function setCursorPosition(position: Position): void {
|
||||
if (editor) {
|
||||
editor.setPosition(position)
|
||||
editor.revealPositionInCenterIfOutsideViewport(position)
|
||||
}
|
||||
}
|
||||
|
||||
let disableTabCond: meditor.IContextKey<boolean> | undefined
|
||||
|
||||
$effect(() => {
|
||||
@@ -385,10 +388,6 @@
|
||||
snippetsPreventQuickSuggestions: disableSuggestions
|
||||
}
|
||||
})
|
||||
if (key && editorPositionMap?.[key]) {
|
||||
editor.setPosition(editorPositionMap[key])
|
||||
editor.revealPositionInCenterIfOutsideViewport(editorPositionMap[key])
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading monaco:', e)
|
||||
return
|
||||
@@ -404,7 +403,7 @@
|
||||
}, 200)
|
||||
})
|
||||
editor.onDidChangeCursorPosition((event) => {
|
||||
if (key) editorPositionMap[key] = event.position
|
||||
dispatch('cursorPositionChange', { position: event.position })
|
||||
})
|
||||
|
||||
editor.onDidFocusEditorText(() => {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import ResolveStyle from '../helpers/ResolveStyle.svelte'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { computeWorkspaceS3FileInputPolicy } from '../../editor/appUtilsS3'
|
||||
import { defaultIfEmptyString, clone} from '$lib/utils'
|
||||
import { defaultIfEmptyString } from '$lib/utils'
|
||||
import { userStore } from '$lib/stores'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
let previousDefault = $state(resolvedConfig.defaultValues)
|
||||
|
||||
function onDefaultChange() {
|
||||
previousDefault = clone(resolvedConfig.defaultValues)
|
||||
previousDefault = structuredClone($state.snapshot(resolvedConfig.defaultValues))
|
||||
args = previousDefault ?? {}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { GridApi, createGrid, type IDatasource } from 'ag-grid-community'
|
||||
import { sendUserToast, clone} from '$lib/utils'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { createEventDispatcher, getContext, mount, unmount } from 'svelte'
|
||||
import type { AppViewerContext, ComponentCustomCSS, ContextPanelContext } from '../../../types'
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
function refreshActions(actions: TableAction[]) {
|
||||
if (!deepEqual(actions, lastActions)) {
|
||||
lastActions = clone(actions)
|
||||
lastActions = structuredClone(stateSnapshot(actions))
|
||||
updateOptions()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { GridApi, createGrid } from 'ag-grid-community'
|
||||
import { isObject, sendUserToast, clone} from '$lib/utils'
|
||||
import { isObject, sendUserToast } from '$lib/utils'
|
||||
import { getContext, mount, onDestroy, unmount } from 'svelte'
|
||||
import type { AppInput } from '../../../inputType'
|
||||
import type {
|
||||
@@ -206,7 +206,7 @@
|
||||
|
||||
function refreshActions(actions: TableAction[]) {
|
||||
if (!deepEqual(actions, lastActions)) {
|
||||
lastActions = clone(actions)
|
||||
lastActions = structuredClone(stateSnapshot(actions))
|
||||
updateOptions()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
const debounceEval = async (s?: string) => {
|
||||
let args = s == 'exprChanged' ? { file: { name: 'example.png' } } : undefined
|
||||
let nvalue = await evalExpr(input as EvalAppInput, args)
|
||||
|
||||
if (field) {
|
||||
editorContext?.evalPreview.update((x) => {
|
||||
x[`${id}.${field}`] = nvalue
|
||||
@@ -136,6 +137,7 @@
|
||||
if (!onDemandOnly) {
|
||||
let nhash = typeof nvalue != 'object' ? nvalue : sum(nvalue)
|
||||
if (lastExprHash != nhash) {
|
||||
// console.log('eval changed', field, nvalue)
|
||||
value = nvalue
|
||||
lastExprHash = nhash
|
||||
}
|
||||
@@ -166,8 +168,6 @@
|
||||
await debounceTemplate()
|
||||
} else if (input?.type == 'eval') {
|
||||
value = await evalExpr(input as EvalAppInput)
|
||||
let nhash = typeof value != 'object' ? value : sum(value)
|
||||
lastExprHash = nhash
|
||||
} else if (input?.type == 'evalv2') {
|
||||
// console.log('evalv2', onDemandOnly, field)
|
||||
if (onDemandOnly && exportValueFunction) {
|
||||
@@ -347,6 +347,7 @@
|
||||
) &&
|
||||
untrack(() => debounceTemplate())
|
||||
})
|
||||
let stateId = $derived($worldStore?.stateId)
|
||||
$effect(() => {
|
||||
input?.type == 'static' && input.value
|
||||
input && $worldStore && untrack(() => debounce(handleConnection))
|
||||
@@ -355,25 +356,17 @@
|
||||
input &&
|
||||
input.type == 'template' &&
|
||||
isCodeInjection(input.eval) &&
|
||||
$stateId &&
|
||||
$stateStore &&
|
||||
untrack(() => debounce(debounceTemplate))
|
||||
})
|
||||
$effect.pre(() => {
|
||||
input && input.type == 'eval' && $stateStore && untrack(() => debounce2(debounceEval))
|
||||
input &&
|
||||
input.type == 'eval' &&
|
||||
$stateId &&
|
||||
$stateStore &&
|
||||
untrack(() => debounce2(debounceEval))
|
||||
})
|
||||
|
||||
if (input?.type == 'eval') {
|
||||
$worldStore?.stateId.subscribe((x) => {
|
||||
debounce2(debounceEval)
|
||||
})
|
||||
}
|
||||
|
||||
if (input?.type == 'template') {
|
||||
$worldStore?.stateId.subscribe((x) => {
|
||||
debounce2(debounceTemplate)
|
||||
})
|
||||
}
|
||||
|
||||
$effect.pre(() => {
|
||||
input?.type == 'evalv2' && input.expr && untrack(() => debounceEval('exprChanged'))
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import { createBubbler, stopPropagation } from 'svelte/legacy'
|
||||
|
||||
const bubble = createBubbler()
|
||||
@@ -134,7 +133,7 @@
|
||||
tabs
|
||||
)
|
||||
) {
|
||||
lastTabs = clone(tabs)
|
||||
lastTabs = structuredClone($state.snapshot(tabs))
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
allIdsInPath: writable([]),
|
||||
darkMode,
|
||||
cssEditorOpen,
|
||||
globalCssEditorSavedPosition: { val: undefined },
|
||||
previewTheme,
|
||||
debuggingComponents: writable({}),
|
||||
replaceStateFn: replaceStateFn,
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
cleanValueProperties,
|
||||
orderedJsonStringify,
|
||||
type Value,
|
||||
replaceFalseWithUndefined,
|
||||
clone
|
||||
replaceFalseWithUndefined
|
||||
} from '../../../utils'
|
||||
import type { AppInput, Runnable } from '../inputType'
|
||||
import type { App, AppEditorContext, AppViewerContext } from '../types'
|
||||
@@ -393,7 +392,7 @@
|
||||
})
|
||||
savedApp = {
|
||||
summary: $summary,
|
||||
value: clone($app),
|
||||
value: structuredClone($state.snapshot($app)),
|
||||
path: path,
|
||||
policy: policy,
|
||||
custom_path: customPath
|
||||
@@ -489,7 +488,7 @@
|
||||
})
|
||||
savedApp = {
|
||||
summary: $summary,
|
||||
value: clone($app),
|
||||
value: structuredClone($state.snapshot($app)),
|
||||
path: npath,
|
||||
policy,
|
||||
custom_path: customPath
|
||||
@@ -573,13 +572,13 @@
|
||||
})
|
||||
savedApp = {
|
||||
summary: $summary,
|
||||
value: clone($app),
|
||||
value: structuredClone($state.snapshot($app)),
|
||||
path: newEditedPath,
|
||||
policy,
|
||||
draft_only: true,
|
||||
draft: {
|
||||
summary: $summary,
|
||||
value: clone($app),
|
||||
value: structuredClone($state.snapshot($app)),
|
||||
path: newEditedPath,
|
||||
policy,
|
||||
custom_path: customPath
|
||||
@@ -661,7 +660,7 @@
|
||||
...(savedApp?.draft_only
|
||||
? {
|
||||
summary: $summary,
|
||||
value: clone($app),
|
||||
value: structuredClone($state.snapshot($app)),
|
||||
path: savedApp.draft_only ? newEditedPath || path : path,
|
||||
policy,
|
||||
draft_only: true,
|
||||
@@ -670,7 +669,7 @@
|
||||
: savedApp),
|
||||
draft: {
|
||||
summary: $summary,
|
||||
value: clone($app),
|
||||
value: structuredClone($state.snapshot($app)),
|
||||
path: newEditedPath || path,
|
||||
policy,
|
||||
custom_path: customPath
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
} from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { base } from '$lib/base'
|
||||
import { emptyString, formatCron, sendUserToast, tryEvery, clone} from '$lib/utils'
|
||||
import { emptyString, formatCron, sendUserToast, tryEvery } from '$lib/utils'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
@@ -127,7 +127,7 @@
|
||||
)
|
||||
: {}
|
||||
setTimeout(() => {
|
||||
args = clone(nargs)
|
||||
args = structuredClone($state.snapshot(nargs))
|
||||
})
|
||||
|
||||
customPath =
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import { Code, Copy, MoveLeft, MoveRight, Paintbrush2 } from 'lucide-svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { slide } from 'svelte/transition'
|
||||
@@ -54,10 +53,10 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
let isQuickMenuOpen = $state(false)
|
||||
|
||||
let prevValue = clone(value)
|
||||
let prevValue = structuredClone($state.snapshot(value))
|
||||
$effect(() => {
|
||||
if (deepEqual(prevValue, value)) return
|
||||
prevValue = clone(value)
|
||||
prevValue = structuredClone($state.snapshot(value))
|
||||
dispatch('change', value)
|
||||
})
|
||||
|
||||
|
||||
@@ -13,13 +13,22 @@
|
||||
import { resolveTheme } from './themeUtils'
|
||||
import ThemeCodePreview from './ThemeCodePreview.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
const { app, appPath } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const { app, globalCssEditorSavedPosition } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let cssEditor: SimpleEditor | undefined = $state(undefined)
|
||||
let alertHeight: number | undefined = $state(undefined)
|
||||
let themeViewer: any = $state(undefined)
|
||||
let selectedTab: 'css' | 'theme' = $state('css')
|
||||
|
||||
$effect(() => {
|
||||
if (!cssEditor) return
|
||||
setTimeout(() => {
|
||||
if (globalCssEditorSavedPosition.val)
|
||||
cssEditor?.setCursorPosition(globalCssEditorSavedPosition.val)
|
||||
}, 0)
|
||||
})
|
||||
|
||||
function insertSelector(selector: string) {
|
||||
if ($app?.theme?.type === 'path') {
|
||||
sendUserToast(
|
||||
@@ -79,7 +88,9 @@
|
||||
small
|
||||
automaticLayout
|
||||
bind:this={cssEditor}
|
||||
key={`app-global-css-editor-${$workspaceStore}-${$appPath}`}
|
||||
on:cursorPositionChange={(e) => {
|
||||
globalCssEditorSavedPosition.val = e.detail.position
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<ThemeCodePreview theme={$app.theme}>
|
||||
|
||||
+1
-3
@@ -23,7 +23,7 @@
|
||||
import DiffEditor from '$lib/components/DiffEditor.svelte'
|
||||
import CacheTtlPopup from './CacheTtlPopup.svelte'
|
||||
import EditorSettings from '$lib/components/EditorSettings.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore } from '$lib/stores'
|
||||
|
||||
const {
|
||||
runnableComponents,
|
||||
@@ -387,7 +387,6 @@
|
||||
}
|
||||
$app = $app
|
||||
}}
|
||||
key={`app-inline-${$workspaceStore}-${$appPath}-${id}`}
|
||||
args={Object.entries(fields).reduce((acc, [key, obj]) => {
|
||||
acc[key] = obj.type === 'static' ? obj.value : undefined
|
||||
return acc
|
||||
@@ -416,7 +415,6 @@
|
||||
inferSuggestions(e.detail.code)
|
||||
$app = $app
|
||||
}}
|
||||
key={`app-inline-${$workspaceStore}-${$appPath}-${id}`}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import type {
|
||||
} from './inputType'
|
||||
import type { World } from './rx'
|
||||
import type { FilledItem } from './svelte-grid/types'
|
||||
import type { Position } from 'monaco-editor'
|
||||
|
||||
export type HorizontalAlignment = 'left' | 'center' | 'right'
|
||||
export type VerticalAlignment = 'top' | 'center' | 'bottom'
|
||||
@@ -277,6 +278,7 @@ export type AppViewerContext = {
|
||||
allIdsInPath: Writable<string[]>
|
||||
darkMode: Writable<boolean>
|
||||
cssEditorOpen: Writable<boolean>
|
||||
globalCssEditorSavedPosition: { val: Position | undefined } // Not reactive
|
||||
previewTheme: Writable<string | undefined>
|
||||
debuggingComponents: Writable<Record<string, number>>
|
||||
replaceStateFn?: ((url: string) => void) | undefined
|
||||
|
||||
@@ -145,14 +145,8 @@ export function createAppFromScript(path: string, schema: Record<string, any> |
|
||||
value: false
|
||||
},
|
||||
disabled: {
|
||||
type: 'evalv2',
|
||||
expr: '!c.valid',
|
||||
connections: [
|
||||
{
|
||||
componentId: 'c',
|
||||
id: 'valid'
|
||||
}
|
||||
]
|
||||
type: 'eval',
|
||||
expr: '!c.valid'
|
||||
},
|
||||
beforeIcon: {
|
||||
type: 'static',
|
||||
@@ -711,14 +705,8 @@ export function createAppFromFlow(path: string, schema: Record<string, any> | un
|
||||
value: false
|
||||
},
|
||||
disabled: {
|
||||
type: 'evalv2',
|
||||
expr: '!c.valid',
|
||||
connections: [
|
||||
{
|
||||
componentId: 'c',
|
||||
id: 'valid'
|
||||
}
|
||||
]
|
||||
type: 'eval',
|
||||
expr: '!c.valid'
|
||||
},
|
||||
beforeIcon: {
|
||||
type: 'static',
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
onEditInput?: ((moduleId: string, key: string) => void) | undefined
|
||||
forceTestTab?: Record<string, boolean>
|
||||
highlightArg?: Record<string, string | undefined>
|
||||
onRunPreview?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -53,8 +52,7 @@
|
||||
onTestUpTo = undefined,
|
||||
onEditInput = undefined,
|
||||
forceTestTab,
|
||||
highlightArg,
|
||||
onRunPreview = () => {}
|
||||
highlightArg
|
||||
}: Props = $props()
|
||||
|
||||
let flowModuleSchemaMap: FlowModuleSchemaMap | undefined = $state()
|
||||
@@ -130,7 +128,6 @@
|
||||
{onDeployTrigger}
|
||||
{forceTestTab}
|
||||
{highlightArg}
|
||||
{onRunPreview}
|
||||
/>
|
||||
{/if}
|
||||
</Pane>
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
onDeployTrigger?: (trigger: Trigger) => void
|
||||
forceTestTab?: Record<string, boolean>
|
||||
highlightArg?: Record<string, string | undefined>
|
||||
onRunPreview?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -38,8 +37,7 @@
|
||||
savedFlow = undefined,
|
||||
onDeployTrigger = () => {},
|
||||
forceTestTab,
|
||||
highlightArg,
|
||||
onRunPreview
|
||||
highlightArg
|
||||
}: Props = $props()
|
||||
|
||||
const {
|
||||
@@ -84,7 +82,6 @@
|
||||
showCaptureHint.set(true)
|
||||
}}
|
||||
on:applyArgs
|
||||
{onRunPreview}
|
||||
/>
|
||||
{:else if $selectedId === 'Result'}
|
||||
<p class="p-4 text-secondary">The result of the flow will be the result of the last node.</p>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { getContext, tick, untrack } from 'svelte'
|
||||
import FlowCard from '../common/FlowCard.svelte'
|
||||
import type { FlowEditorContext } from '../types'
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import JsonInputs from '$lib/components/JsonInputs.svelte'
|
||||
import { convert } from '@redocly/json-to-json-schema'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
@@ -26,6 +27,7 @@
|
||||
Check
|
||||
} from 'lucide-svelte'
|
||||
import CaptureIcon from '$lib/components/triggers/CaptureIcon.svelte'
|
||||
import FlowPreviewContent from '$lib/components/FlowPreviewContent.svelte'
|
||||
import FlowInputEditor from './FlowInputEditor.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import CaptureButton from '$lib/components/triggers/CaptureButton.svelte'
|
||||
@@ -40,16 +42,15 @@
|
||||
} from '$lib/components/schema/schemaUtils.svelte'
|
||||
import SideBarTab from '$lib/components/meltComponents/SideBarTab.svelte'
|
||||
import CaptureTable from '$lib/components/triggers/CaptureTable.svelte'
|
||||
import { isObjectTooBig, clone } from '$lib/utils'
|
||||
import { isObjectTooBig } from '$lib/utils'
|
||||
import { refreshStateStore } from '$lib/svelte5Utils.svelte'
|
||||
|
||||
interface Props {
|
||||
noEditor: boolean
|
||||
disabled: boolean
|
||||
onRunPreview?: () => void
|
||||
}
|
||||
|
||||
let { noEditor, disabled, onRunPreview }: Props = $props()
|
||||
let { noEditor, disabled }: Props = $props()
|
||||
|
||||
const {
|
||||
flowStore,
|
||||
@@ -75,6 +76,7 @@
|
||||
let runDisabled: boolean = $state(false)
|
||||
let editableSchemaForm: EditableSchemaForm | undefined = $state(undefined)
|
||||
let savedPreviewArgs: Record<string, any> | undefined = $state(undefined)
|
||||
let preventEscape = $state(false)
|
||||
let isValid = $state(true)
|
||||
|
||||
function updateEditPanelSize(size: number | undefined) {
|
||||
@@ -170,7 +172,7 @@
|
||||
}
|
||||
|
||||
function schemaFromPayload(payloadData: any) {
|
||||
const payload = clone(payloadData)
|
||||
const payload = structuredClone($state.snapshot(payloadData))
|
||||
const parsed = JSON.parse(JSON.stringify(payload))
|
||||
|
||||
if (!parsed) {
|
||||
@@ -191,6 +193,9 @@
|
||||
return { required: [], properties: {}, ...convert(parsed) }
|
||||
}
|
||||
|
||||
let flowPreviewContent: FlowPreviewContent | undefined = $state()
|
||||
let previewOpen = $state(false)
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {
|
||||
runPreview()
|
||||
@@ -204,9 +209,10 @@
|
||||
|
||||
function runPreview() {
|
||||
if (previewArguments) {
|
||||
previewArgs.val = clone(previewArguments)
|
||||
previewArgs.val = structuredClone($state.snapshot(previewArguments))
|
||||
}
|
||||
onRunPreview?.()
|
||||
previewOpen = true
|
||||
flowPreviewContent?.test()
|
||||
}
|
||||
|
||||
function updatePreviewSchemaAndArgs(payload: any) {
|
||||
@@ -221,7 +227,7 @@
|
||||
updatePreviewSchema(undefined)
|
||||
return
|
||||
}
|
||||
payloadData = clone(payload)
|
||||
payloadData = structuredClone($state.snapshot(payload))
|
||||
selectedSchema = schemaFromPayload(payloadData)
|
||||
updatePreviewSchema(selectedSchema)
|
||||
updatePreviewArguments(payloadData)
|
||||
@@ -247,7 +253,7 @@
|
||||
async function applySchemaAndArgs() {
|
||||
flowStore.val.schema = applyDiff(flowStore.val.schema, diff)
|
||||
if (previewArguments) {
|
||||
savedPreviewArgs = clone(previewArguments)
|
||||
savedPreviewArgs = structuredClone($state.snapshot(previewArguments))
|
||||
}
|
||||
updatePreviewSchemaAndArgs(undefined)
|
||||
if ($flowInputEditorState) {
|
||||
@@ -260,8 +266,8 @@
|
||||
previewArguments = savedPreviewArgs
|
||||
return
|
||||
}
|
||||
savedPreviewArgs = clone(previewArguments)
|
||||
previewArguments = clone(payloadData)
|
||||
savedPreviewArgs = structuredClone($state.snapshot(previewArguments))
|
||||
previewArguments = structuredClone($state.snapshot(payloadData))
|
||||
}
|
||||
|
||||
let tabButtonWidth = 0
|
||||
@@ -353,6 +359,18 @@
|
||||
<!-- Add svelte:window to listen for keyboard events -->
|
||||
<svelte:window onkeydown={handleKeydown} />
|
||||
|
||||
<Drawer bind:open={previewOpen} alwaysOpen size="75%" {preventEscape}>
|
||||
<FlowPreviewContent
|
||||
bind:this={flowPreviewContent}
|
||||
open={previewOpen}
|
||||
previewMode="whole"
|
||||
on:close={() => {
|
||||
previewOpen = false
|
||||
}}
|
||||
bind:preventEscape
|
||||
/>
|
||||
</Drawer>
|
||||
|
||||
<FlowCard {noEditor} title="Flow Input">
|
||||
{#if !disabled}
|
||||
<div class="py-2 px-4 h-full">
|
||||
@@ -398,7 +416,7 @@
|
||||
on:change={() => {
|
||||
previewArguments = previewArguments
|
||||
if (!previewSchema) {
|
||||
savedPreviewArgs = clone(previewArguments)
|
||||
savedPreviewArgs = structuredClone($state.snapshot(previewArguments))
|
||||
}
|
||||
refreshStateStore(flowStore)
|
||||
}}
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
import ModulePreviewResultViewer from '$lib/components/ModulePreviewResultViewer.svelte'
|
||||
import { aiChatManager } from '$lib/components/copilot/chat/AIChatManager.svelte'
|
||||
import { refreshStateStore } from '$lib/svelte5Utils.svelte'
|
||||
import { getStepHistoryLoaderContext } from '$lib/components/stepHistoryLoader.svelte'
|
||||
|
||||
const {
|
||||
selectedId,
|
||||
@@ -187,7 +186,6 @@
|
||||
let forceReload = $state(0)
|
||||
let editorPanelSize = $state(noEditor ? 0 : flowModule.value.type == 'script' ? 30 : 50)
|
||||
let editorSettingsPanelSize = $state(100 - untrack(() => editorPanelSize))
|
||||
let stepHistoryLoader = getStepHistoryLoaderContext()
|
||||
|
||||
function onSelectedIdChange() {
|
||||
if (!$flowStateStore?.[$selectedId]?.schema && flowModule) {
|
||||
@@ -449,7 +447,6 @@
|
||||
},
|
||||
{}
|
||||
)}
|
||||
key={`flow-inline-${$workspaceStore}-${$pathStore}-${flowModule.id}`}
|
||||
/>
|
||||
<DiffEditor
|
||||
open={false}
|
||||
@@ -822,23 +819,7 @@
|
||||
</div>
|
||||
</Pane>
|
||||
{#if selected === 'test'}
|
||||
<Pane minSize={20} class="relative">
|
||||
{#if stepHistoryLoader?.stepStates[flowModule.id]?.initial && !flowModule.mock?.enabled}
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
onclick={() => {
|
||||
stepHistoryLoader?.resetInitial(flowModule.id)
|
||||
}}
|
||||
class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 bg-gray-500/40 absolute top-0 left-0 w-full z-50"
|
||||
>
|
||||
<div class="text-center text-primary text-sm py-2 pt-20"
|
||||
><span class="font-bold border p-2 bg-surface-secondary rounded-md"
|
||||
>Run loaded from history</span
|
||||
></div
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
<Pane minSize={20}>
|
||||
<ModulePreviewResultViewer
|
||||
lang={flowModule.value['language'] ?? 'deno'}
|
||||
{editor}
|
||||
@@ -858,7 +839,6 @@
|
||||
{testIsLoading}
|
||||
disableMock={preprocessorModule || failureModule}
|
||||
disableHistory={failureModule}
|
||||
loadingHistory={stepHistoryLoader?.stepStates[flowModule.id]?.loadingJobs}
|
||||
/>
|
||||
</Pane>
|
||||
{/if}
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
cleanValueProperties,
|
||||
emptySchema,
|
||||
orderedJsonStringify,
|
||||
sendUserToast,
|
||||
clone
|
||||
sendUserToast
|
||||
} from '$lib/utils'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { fade } from 'svelte/transition'
|
||||
@@ -29,7 +28,7 @@
|
||||
workspace: $workspaceStore!,
|
||||
hash
|
||||
})
|
||||
savedScript = clone(script)
|
||||
savedScript = structuredClone($state.snapshot(script))
|
||||
callback = cb
|
||||
}
|
||||
|
||||
@@ -101,7 +100,7 @@
|
||||
lock: undefined
|
||||
}
|
||||
})
|
||||
savedScript = clone(script)
|
||||
savedScript = structuredClone($state.snapshot(script))
|
||||
callback?.()
|
||||
} catch (error) {
|
||||
sendUserToast(`Impossible to save the script: ${error.body}`, true)
|
||||
@@ -247,7 +246,7 @@
|
||||
button: {
|
||||
text: 'Restore to saved',
|
||||
onClick: () => {
|
||||
script = clone(savedScript)
|
||||
script = structuredClone($state.snapshot(savedScript))
|
||||
diffDrawer?.closeDrawer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function copyFirstStepSchema(
|
||||
const firstModuleId = flowStore.val.value.modules[0]?.id
|
||||
|
||||
if (flowState[firstModuleId] && firstModuleId) {
|
||||
flowStore.val.schema = clone(flowState[firstModuleId].schema)
|
||||
flowStore.val.schema = structuredClone($state.snapshot(flowState[firstModuleId].schema))
|
||||
const v = flowStore.val.value.modules[0].value
|
||||
if (v.type == 'rawscript' || v.type == 'script') {
|
||||
Object.keys(v.input_transforms ?? {}).forEach((key) => {
|
||||
@@ -47,7 +47,7 @@ export async function getFirstStepSchema(flowState: FlowState, flow: OpenFlow) {
|
||||
throw new Error('no first step found')
|
||||
}
|
||||
|
||||
const schema = clone(flowState[firstModuleId].schema)
|
||||
const schema = structuredClone(flowState[firstModuleId].schema)
|
||||
const v = flow.value.modules[0].value
|
||||
|
||||
if (v.type !== 'rawscript' && v.type !== 'script') {
|
||||
|
||||
@@ -23,7 +23,7 @@ export async function copyFirstStepSchema(flowState: FlowState, flowStore: Writa
|
||||
const firstModuleId = flow.value.modules[0]?.id
|
||||
|
||||
if (flowState[firstModuleId] && firstModuleId) {
|
||||
flow.schema = clone(flowState[firstModuleId].schema)
|
||||
flow.schema = structuredClone(stateSnapshot(flowState[firstModuleId].schema))
|
||||
const v = flow.value.modules[0].value
|
||||
if (v.type == 'rawscript' || v.type == 'script') {
|
||||
Object.keys(v.input_transforms ?? {}).forEach((key) => {
|
||||
@@ -50,7 +50,7 @@ export async function getFirstStepSchema(flowState: FlowState, flowStore: StateS
|
||||
throw new Error('no first step found')
|
||||
}
|
||||
|
||||
const schema = clone(flowState[firstModuleId].schema)
|
||||
const schema = structuredClone(stateSnapshot(flowState[firstModuleId].schema))
|
||||
const v = flow.value.modules[0].value
|
||||
|
||||
if (v.type !== 'rawscript' && v.type !== 'script') {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import FlowPreviewContent from '$lib/components/FlowPreviewContent.svelte'
|
||||
import type { Job } from '$lib/gen'
|
||||
import { createEventDispatcher, tick } from 'svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import { getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from '../types'
|
||||
@@ -26,7 +26,6 @@
|
||||
export async function openPreview(test: boolean = false) {
|
||||
if (!previewOpen) {
|
||||
previewOpen = true
|
||||
await tick()
|
||||
flowPreviewContent?.refresh()
|
||||
if (!test) return
|
||||
}
|
||||
@@ -39,6 +38,7 @@
|
||||
let jobId: string | undefined = $state(undefined)
|
||||
let job: Job | undefined = $state(undefined)
|
||||
let preventEscape = $state(false)
|
||||
let initial = $state(false)
|
||||
let selectedJobStep: string | undefined = $state(undefined)
|
||||
let selectedJobStepIsTopLevel: boolean | undefined = $state(undefined)
|
||||
let selectedJobStepType: 'single' | 'forloop' | 'branchall' = $state('single')
|
||||
@@ -120,6 +120,7 @@
|
||||
bind:previewMode
|
||||
bind:job
|
||||
bind:jobId
|
||||
bind:initial
|
||||
bind:selectedJobStep
|
||||
bind:selectedJobStepIsTopLevel
|
||||
bind:selectedJobStepType
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
} from '$lib/components/copilot/chat/flow/ModuleAcceptReject.svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import ModuleTest from '$lib/components/ModuleTest.svelte'
|
||||
import { getStepHistoryLoaderContext } from '$lib/components/stepHistoryLoader.svelte'
|
||||
|
||||
interface Props {
|
||||
selected?: boolean
|
||||
@@ -140,8 +139,6 @@
|
||||
|
||||
let flowStateStore = $derived(flowEditorContext?.flowStateStore)
|
||||
|
||||
let stepHistoryLoader = getStepHistoryLoaderContext()
|
||||
|
||||
function updateConnectingData(
|
||||
id: string | undefined,
|
||||
pickableIds: Record<string, any> | undefined,
|
||||
@@ -452,9 +449,7 @@
|
||||
bind:derivedHistoryOpen={historyOpen}
|
||||
historyOffset={{ mainAxis: 12, crossAxis: -9 }}
|
||||
clazz="p-1"
|
||||
isLoading={testIsLoading ||
|
||||
(id ? stepHistoryLoader?.stepStates[id]?.loadingJobs : false)}
|
||||
initial={id ? stepHistoryLoader?.stepStates[id]?.initial : undefined}
|
||||
isLoading={testIsLoading}
|
||||
/>
|
||||
{/snippet}
|
||||
</OutputPicker>
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
import { dfsByModule } from '../previousResults'
|
||||
import type { InlineScript, InsertKind } from '$lib/components/graph/graphBuilder.svelte'
|
||||
import { refreshStateStore } from '$lib/svelte5Utils.svelte'
|
||||
import { getStepHistoryLoaderContext } from '$lib/components/stepHistoryLoader.svelte'
|
||||
|
||||
interface Props {
|
||||
sidebarSize?: number | undefined
|
||||
@@ -240,18 +239,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
let stepHistoryLoader = getStepHistoryLoaderContext()
|
||||
|
||||
async function loadLastJob(path: string, moduleId: string) {
|
||||
if (!path) {
|
||||
return
|
||||
}
|
||||
if (stepHistoryLoader) {
|
||||
stepHistoryLoader.stepStates[moduleId] = {
|
||||
initial: true,
|
||||
loadingJobs: true
|
||||
}
|
||||
}
|
||||
const previousJobId = await JobService.listJobs({
|
||||
workspace: $workspaceStore!,
|
||||
scriptPathExact: path,
|
||||
@@ -272,9 +263,6 @@
|
||||
previewWorkspaceId: previousJobId[0].workspace_id,
|
||||
previewSuccess: getJobResult.success
|
||||
}
|
||||
if (stepHistoryLoader) {
|
||||
stepHistoryLoader.stepStates[moduleId].loadingJobs = false
|
||||
}
|
||||
}
|
||||
$flowStateStore = $flowStateStore
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
bottomBarOpen?: boolean
|
||||
loopStatus?: { type: 'inside' | 'self'; flow: 'forloopflow' | 'whileloopflow' } | undefined
|
||||
onEditInput?: (moduleId: string, key: string) => void
|
||||
initial?: boolean
|
||||
onResetInitial?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -186,7 +184,7 @@
|
||||
}}
|
||||
bind:this={popover}
|
||||
allowFullScreen
|
||||
contentClasses="overflow-hidden resize relative"
|
||||
contentClasses="overflow-hidden resize"
|
||||
contentStyle={`width: calc(${MIN_WIDTH}px); min-width: calc(${MIN_WIDTH}px); height: calc(${MIN_HEIGHT}px); min-height: calc(${MIN_HEIGHT}px); `}
|
||||
extraProps={{ 'data-prop-picker': true }}
|
||||
closeOnOtherPopoverOpen
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { Pin, History, Pen, Check, X, Loader2, Pencil } from 'lucide-svelte'
|
||||
import ObjectViewer from '$lib/components/propertyPicker/ObjectViewer.svelte'
|
||||
@@ -29,7 +28,6 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import DisplayResultControlBar from '$lib/components/DisplayResultControlBar.svelte'
|
||||
import { base } from '$lib/base'
|
||||
import { fade } from 'svelte/transition'
|
||||
|
||||
interface Props {
|
||||
prefix?: string
|
||||
@@ -66,8 +64,6 @@
|
||||
onUpdateMock?: (mock: { enabled: boolean; return_value?: unknown }) => void
|
||||
onEditInput?: (moduleId: string, key: string) => void
|
||||
selectionId?: string
|
||||
initial?: boolean
|
||||
onResetInitial?: () => void
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -99,8 +95,7 @@
|
||||
onSelect,
|
||||
onUpdateMock,
|
||||
onEditInput,
|
||||
selectionId,
|
||||
initial
|
||||
selectionId
|
||||
}: Props = $props()
|
||||
|
||||
type SelectedJob =
|
||||
@@ -196,7 +191,7 @@
|
||||
})
|
||||
} else if (selectedJob && 'result' in selectedJob) {
|
||||
// Pin the job
|
||||
let mockValue: any = clone(selectedJob.result)
|
||||
let mockValue: any = structuredClone($state.snapshot(selectedJob.result))
|
||||
if (selectedJob.result === 'never tested this far') {
|
||||
mockValue = { example: 'value' }
|
||||
}
|
||||
@@ -257,8 +252,6 @@
|
||||
|
||||
let popoverHeight = $derived(customHeight ?? (clientHeight > 0 ? clientHeight : 0))
|
||||
|
||||
const isLoadingAndNotMock = $derived(isLoading && !mock?.enabled)
|
||||
|
||||
const copilot_fix_render = $derived(copilot_fix)
|
||||
</script>
|
||||
|
||||
@@ -360,7 +353,7 @@
|
||||
{/snippet}
|
||||
</Popover>
|
||||
{/if}
|
||||
{#if !isLoadingAndNotMock || mock?.enabled}
|
||||
{#if !isLoading}
|
||||
<div
|
||||
class={twMerge(
|
||||
'w-grow min-w-0 flex gap-1 items-center h-[27px] rounded-md group',
|
||||
@@ -420,7 +413,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !disableMock && !isLoadingAndNotMock}
|
||||
{#if !disableMock && !isLoading}
|
||||
<Tooltip disablePopup={mock?.enabled}>
|
||||
<Button
|
||||
color="light"
|
||||
@@ -585,7 +578,7 @@
|
||||
hoveringResult = false
|
||||
}}
|
||||
>
|
||||
{#if isLoadingAndNotMock}
|
||||
{#if isLoading}
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<Loader2 class="animate-spin" />
|
||||
</div>
|
||||
@@ -616,7 +609,7 @@
|
||||
if (mock?.enabled) {
|
||||
const newMock = {
|
||||
enabled: true,
|
||||
return_value: clone(detail)
|
||||
return_value: structuredClone($state.snapshot(detail))
|
||||
}
|
||||
tmpMock = newMock
|
||||
}
|
||||
@@ -707,13 +700,6 @@
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if initial && !mock?.enabled}
|
||||
<span
|
||||
in:fade
|
||||
class="-mb-1 -mt-0.5 w-full text-right pr-4 dark:text-gray-500 text-gray-400 font-normal text-2xs py-0"
|
||||
>Run loaded from history</span
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#snippet editKey(key: string)}
|
||||
|
||||
@@ -3,7 +3,8 @@ import type { ScheduleTrigger } from '../triggers'
|
||||
import type { Writable } from 'svelte/store'
|
||||
import { writable } from 'svelte/store'
|
||||
import { get } from 'svelte/store'
|
||||
import { sendUserToast, clone} from '$lib/utils'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { stateSnapshot } from '$lib/svelte5Utils.svelte'
|
||||
|
||||
// Load the schedule of a flow given its path and the workspace
|
||||
export async function loadSchedule(path: string, workspace: string): Promise<ScheduleTrigger> {
|
||||
@@ -45,7 +46,7 @@ export async function loadSchedules(
|
||||
if (!path || path == '') {
|
||||
schedules.set([])
|
||||
primarySchedule.update((ps) => (ps === undefined ? false : ps))
|
||||
initialPrimarySchedule.set(clone(get(primarySchedule)))
|
||||
initialPrimarySchedule.set(structuredClone(stateSnapshot(get(primarySchedule))))
|
||||
return
|
||||
}
|
||||
try {
|
||||
@@ -73,7 +74,7 @@ export async function loadSchedules(
|
||||
: false
|
||||
}
|
||||
primarySchedule.update((ps) => (ps === undefined || forceRefresh ? remotePrimarySchedule : ps))
|
||||
initialPrimarySchedule.set(clone(remotePrimarySchedule))
|
||||
initialPrimarySchedule.set(structuredClone(stateSnapshot(remotePrimarySchedule)))
|
||||
|
||||
triggersCount.update((tc) => {
|
||||
const primary = get(primarySchedule)
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
type PickableProperties
|
||||
} from './previousResults'
|
||||
import { evalValue, type ModuleArgs } from './utils'
|
||||
import { clone } from '$lib/utils'
|
||||
|
||||
export class TestSteps {
|
||||
#stepsEvaluated = $state<Record<string, ModuleArgs>>({})
|
||||
@@ -103,7 +102,7 @@ export class TestSteps {
|
||||
|
||||
const argSnapshot = $state.snapshot(evalValue(argName, modules[0], pickableProperties, false))
|
||||
this.#stepsEvaluated[moduleId].value[argName] = argSnapshot
|
||||
this.#steps[moduleId].value[argName] = clone(argSnapshot)
|
||||
this.#steps[moduleId].value[argName] = structuredClone(argSnapshot)
|
||||
}
|
||||
|
||||
initializeFromSchema(
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
import { Expand } from 'lucide-svelte'
|
||||
import Toggle from '../Toggle.svelte'
|
||||
import DataflowEdge from './renderers/edges/DataflowEdge.svelte'
|
||||
import { encodeState, clone} from '$lib/utils'
|
||||
import { encodeState } from '$lib/utils'
|
||||
import BranchOneStart from './renderers/nodes/BranchOneStart.svelte'
|
||||
import NoBranchNode from './renderers/nodes/NoBranchNode.svelte'
|
||||
import HiddenBaseEdge from './renderers/edges/HiddenBaseEdge.svelte'
|
||||
@@ -310,12 +310,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
let lastModules = clone(modules)
|
||||
let lastModules = structuredClone($state.snapshot(modules))
|
||||
let moduleCounter = $state(0)
|
||||
function onModulesChange2(modules) {
|
||||
if (!deepEqual(modules, lastModules)) {
|
||||
console.log('modules changed', modules)
|
||||
lastModules = clone(modules)
|
||||
lastModules = structuredClone($state.snapshot(modules))
|
||||
moduleCounter++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { clone } from '$lib/utils'
|
||||
import { Alert, Badge, Drawer, DrawerContent } from '$lib/components/common'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
|
||||
@@ -49,6 +48,7 @@
|
||||
import { collectStaticFields, hash, type TriggerableV2 } from '../apps/editor/commonAppUtils'
|
||||
import type { SavedAndModifiedValue } from '../common/confirmationModal/unsavedTypes'
|
||||
import DropdownV2 from '../DropdownV2.svelte'
|
||||
import { stateSnapshot } from '$lib/svelte5Utils.svelte'
|
||||
|
||||
// async function hash(message) {
|
||||
// try {
|
||||
@@ -205,7 +205,7 @@
|
||||
})
|
||||
savedApp = {
|
||||
summary: summary,
|
||||
value: clone(app),
|
||||
value: structuredClone(stateSnapshot(app)),
|
||||
path: path,
|
||||
policy: policy,
|
||||
custom_path: customPath
|
||||
@@ -310,7 +310,7 @@
|
||||
})
|
||||
savedApp = {
|
||||
summary: summary,
|
||||
value: clone(app),
|
||||
value: structuredClone(stateSnapshot(app)),
|
||||
path: npath,
|
||||
policy,
|
||||
custom_path: customPath
|
||||
@@ -402,13 +402,13 @@
|
||||
})
|
||||
savedApp = {
|
||||
summary: summary,
|
||||
value: clone(app),
|
||||
value: structuredClone(stateSnapshot(app)),
|
||||
path: newEditedPath,
|
||||
policy,
|
||||
draft_only: true,
|
||||
draft: {
|
||||
summary: summary,
|
||||
value: clone(app),
|
||||
value: structuredClone(stateSnapshot(app)),
|
||||
path: newEditedPath,
|
||||
policy,
|
||||
custom_path: customPath
|
||||
@@ -500,7 +500,7 @@
|
||||
...(savedApp?.draft_only
|
||||
? {
|
||||
summary: summary,
|
||||
value: clone(app),
|
||||
value: structuredClone(stateSnapshot(app)),
|
||||
path: savedApp.draft_only ? newEditedPath || path : path,
|
||||
policy,
|
||||
draft_only: true,
|
||||
@@ -509,7 +509,7 @@
|
||||
: savedApp),
|
||||
draft: {
|
||||
summary: summary,
|
||||
value: clone(app),
|
||||
value: structuredClone(stateSnapshot(app)),
|
||||
path: newEditedPath || path,
|
||||
policy,
|
||||
custom_path: customPath
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import AddProperty from './AddProperty.svelte'
|
||||
import { dragHandle, dragHandleZone } from '@windmill-labs/svelte-dnd-action'
|
||||
import { flip } from 'svelte/animate'
|
||||
import { emptyString, clone} from '$lib/utils'
|
||||
import { emptyString } from '$lib/utils'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { createEventDispatcher, tick } from 'svelte'
|
||||
import Label from '../Label.svelte'
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
let { schema = $bindable(), parentId = undefined, jsonView = $bindable(false) }: Props = $props()
|
||||
|
||||
// let schema = $state(clone(schema))
|
||||
// let schema = $state(structuredClone($state.snapshot(schema)))
|
||||
|
||||
let schemaString: string = $state(JSON.stringify(schema, null, '\t'))
|
||||
let editor: SimpleEditor | undefined = $state(undefined)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy'
|
||||
|
||||
import autosize from '$lib/autosize'
|
||||
import { shouldDisplayPlaceholder, clone} from '$lib/utils'
|
||||
import { shouldDisplayPlaceholder } from '$lib/utils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import ArrayTypeNarrowing from '../ArrayTypeNarrowing.svelte'
|
||||
import Label from '../Label.svelte'
|
||||
@@ -118,7 +120,7 @@
|
||||
order
|
||||
})
|
||||
|
||||
let initialExtra: any = clone({
|
||||
let initialExtra: any = structuredClone({
|
||||
order: undefined,
|
||||
properties: undefined,
|
||||
...$state.snapshot(extra)
|
||||
@@ -138,7 +140,7 @@
|
||||
return
|
||||
}
|
||||
if (!deepEqual(extra, initialExtra)) {
|
||||
initialExtra = clone(extra)
|
||||
initialExtra = structuredClone($state.snapshot(extra))
|
||||
console.debug('property content updated')
|
||||
dispatchIfMounted('change')
|
||||
}
|
||||
@@ -158,10 +160,10 @@
|
||||
;[oneOf]
|
||||
untrack(() => updateOneOfSchemas(oneOf))
|
||||
})
|
||||
$effect(() => {
|
||||
run(() => {
|
||||
extra && mounted && untrack(() => onContentChange())
|
||||
})
|
||||
$effect(() => {
|
||||
run(() => {
|
||||
;(properties || order) && untrack(() => updateSchema())
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { clone } from '$lib/utils'
|
||||
export type SchemaDiff = {
|
||||
diff: 'same' | 'added' | 'removed' | 'modified' | Record<string, SchemaDiff>
|
||||
fullSchema: { [key: string]: any } | undefined
|
||||
@@ -134,7 +133,7 @@ export function schemaFromDiff(
|
||||
if (!schema) {
|
||||
return undefined
|
||||
}
|
||||
const newSchema = clone(schema)
|
||||
const newSchema = structuredClone($state.snapshot(schema))
|
||||
Object.keys(diff).forEach((key) => {
|
||||
const diffValue = diff[key].diff
|
||||
if (diffValue === 'added' || diffValue === 'modified') {
|
||||
@@ -180,7 +179,7 @@ export function setNestedProperty(
|
||||
return curr[field][key]
|
||||
}, obj)
|
||||
if (lastKey && value) {
|
||||
const newValue = clone(value)
|
||||
const newValue = structuredClone($state.snapshot(value))
|
||||
target[field][lastKey] = newValue
|
||||
return
|
||||
} else if (lastKey && !value) {
|
||||
@@ -200,7 +199,7 @@ export function applyDiff(
|
||||
return
|
||||
}
|
||||
|
||||
let newSchema = clone(schema)
|
||||
let newSchema = structuredClone($state.snapshot(schema))
|
||||
|
||||
Object.keys(diff).forEach((key) => {
|
||||
const diffValue = diff[key].diff
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<script lang="ts" generics="Item extends { label?: string; value: any; subtitle?: string }">
|
||||
<script lang="ts" generics="Item extends { label?: string; value: any; }">
|
||||
import { clickOutside } from '$lib/utils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import CloseButton from '../common/CloseButton.svelte'
|
||||
|
||||
@@ -138,9 +138,6 @@
|
||||
}}
|
||||
>
|
||||
{item.label || '\xa0'}
|
||||
{#if item.subtitle}
|
||||
<div class="text-xs text-tertiary">{item.subtitle}</div>
|
||||
{/if}
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
|
||||
@@ -43,7 +43,6 @@ export type ProcessedItem<T> = {
|
||||
__is_create?: true
|
||||
label: string
|
||||
value: T
|
||||
subtitle?: string
|
||||
}
|
||||
|
||||
export function getLabel<T>(item: { label?: string; value: T } | undefined): string {
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
import { type Writable, get } from 'svelte/store'
|
||||
import type { FlowState } from './flows/flowState'
|
||||
import { NEVER_TESTED_THIS_FAR } from './flows/models'
|
||||
import { JobService, type Flow, type FlowModule } from '$lib/gen'
|
||||
import { dfs } from './flows/dfs'
|
||||
import { getContext, setContext } from 'svelte'
|
||||
import pLimit from 'p-limit'
|
||||
|
||||
export type stepState = {
|
||||
initial?: boolean
|
||||
loadingJobs?: boolean
|
||||
}
|
||||
|
||||
const STEP_HISTORY_LOADER_CONTEXT_KEY = 'stepHistoryLoader'
|
||||
|
||||
export class StepHistoryLoader {
|
||||
#stepStates = $state<Record<string, stepState>>({})
|
||||
#flowJobInitial = $state<boolean | undefined>(undefined)
|
||||
#saveCb = $state<(() => void) | undefined>(undefined)
|
||||
#noInitial = $state<boolean>(false)
|
||||
|
||||
get stepStates() {
|
||||
return this.#stepStates
|
||||
}
|
||||
|
||||
set stepStates(value: Record<string, stepState>) {
|
||||
this.#stepStates = value
|
||||
}
|
||||
|
||||
get flowJobInitial(): boolean | undefined {
|
||||
return this.#flowJobInitial
|
||||
}
|
||||
|
||||
setFlowJobInitial(value: boolean | undefined) {
|
||||
if (this.#noInitial) {
|
||||
return
|
||||
}
|
||||
this.#flowJobInitial = value
|
||||
if (value === false) {
|
||||
// Set all step initials to false
|
||||
Object.keys(this.#stepStates).forEach((stepId) => {
|
||||
this.#stepStates[stepId].initial = false
|
||||
})
|
||||
}
|
||||
this.#saveCb?.()
|
||||
}
|
||||
|
||||
constructor(
|
||||
stepStates: Record<string, stepState>,
|
||||
flowJobInitial?: boolean,
|
||||
saveCb?: () => void,
|
||||
noInitial?: boolean
|
||||
) {
|
||||
this.#stepStates = stepStates
|
||||
this.#flowJobInitial = flowJobInitial
|
||||
this.#saveCb = saveCb
|
||||
this.#noInitial = noInitial ?? false
|
||||
}
|
||||
|
||||
resetInitial(stepId: string | undefined) {
|
||||
if (!stepId) {
|
||||
return
|
||||
}
|
||||
if (stepId in this.#stepStates && this.#stepStates[stepId]) {
|
||||
this.#stepStates[stepId].initial = false
|
||||
}
|
||||
|
||||
// Check if all initial states are false
|
||||
const allInitialFalse = Object.values(this.#stepStates).every((state) => !state.initial)
|
||||
if (allInitialFalse) {
|
||||
this.#flowJobInitial = false
|
||||
}
|
||||
|
||||
this.#saveCb?.()
|
||||
}
|
||||
|
||||
async loadIndividualStepsStates(
|
||||
flow: Flow,
|
||||
flowStateStore: Writable<FlowState>,
|
||||
workspaceId: string,
|
||||
initialPath: string,
|
||||
path: string
|
||||
): Promise<void> {
|
||||
// Collect all modules that need loading
|
||||
const modulesToLoad: FlowModule[] = []
|
||||
dfs(flow.value.modules, (module) => {
|
||||
const prev = get(flowStateStore)[module.id]?.previewResult
|
||||
if (!prev || prev === NEVER_TESTED_THIS_FAR) {
|
||||
modulesToLoad.push(module)
|
||||
// Initialize step state if it doesn't exist
|
||||
if (!this.#stepStates[module.id]) {
|
||||
this.#stepStates[module.id] = {
|
||||
initial: this.#noInitial ? false : undefined,
|
||||
loadingJobs: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Load all modules in parallel and wait for completion
|
||||
const limit = pLimit(5)
|
||||
const loadPromises = modulesToLoad.map((module) =>
|
||||
limit(async () => {
|
||||
try {
|
||||
this.#stepStates[module.id].loadingJobs = true
|
||||
|
||||
const scriptPath =
|
||||
`path` in module.value
|
||||
? module.value.path
|
||||
: (initialPath === '' ? path : initialPath) + '/' + module.id
|
||||
|
||||
const previousJobId = await JobService.listJobs({
|
||||
workspace: workspaceId,
|
||||
scriptPathExact: scriptPath,
|
||||
jobKinds: ['preview', 'script', 'flowpreview', 'flow', 'flowscript'].join(','),
|
||||
page: 1,
|
||||
perPage: 1
|
||||
})
|
||||
|
||||
if (previousJobId.length === 0) {
|
||||
this.#stepStates[module.id].loadingJobs = false
|
||||
return
|
||||
}
|
||||
|
||||
const getJobResult = await JobService.getCompletedJobResultMaybe({
|
||||
workspace: workspaceId,
|
||||
id: previousJobId[0].id
|
||||
})
|
||||
|
||||
if ('result' in getJobResult) {
|
||||
flowStateStore.update((state) => ({
|
||||
...state,
|
||||
[module.id]: {
|
||||
...(state[module.id] ?? {}),
|
||||
previewResult: getJobResult.result,
|
||||
previewJobId: previousJobId[0].id,
|
||||
previewWorkspaceId: previousJobId[0].workspace_id,
|
||||
previewSuccess: getJobResult.success
|
||||
}
|
||||
}))
|
||||
this.#stepStates[module.id].initial =
|
||||
this.#stepStates[module.id].initial !== undefined
|
||||
? this.#stepStates[module.id].initial
|
||||
: true
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to load history for module ${module.id}:`, error)
|
||||
this.#stepStates[module.id] = {
|
||||
initial: false,
|
||||
loadingJobs: false
|
||||
}
|
||||
} finally {
|
||||
// Ensure loading state is always cleaned up
|
||||
this.#stepStates[module.id].loadingJobs = false
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Wait for all loading operations to complete
|
||||
await Promise.all(loadPromises)
|
||||
}
|
||||
}
|
||||
|
||||
export function getStepHistoryLoaderContext() {
|
||||
return getContext<StepHistoryLoader>(STEP_HISTORY_LOADER_CONTEXT_KEY)
|
||||
}
|
||||
|
||||
export function setStepHistoryLoaderContext(stepHistoryLoader: StepHistoryLoader) {
|
||||
setContext<StepHistoryLoader>(STEP_HISTORY_LOADER_CONTEXT_KEY, stepHistoryLoader)
|
||||
}
|
||||
@@ -27,8 +27,9 @@
|
||||
import { Popover } from '$lib/components/meltComponents'
|
||||
import { CaptureService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { isObject, sendUserToast, clone, formatDateShort } from '$lib/utils'
|
||||
import { isObject, sendUserToast } from '$lib/utils'
|
||||
import { triggerIconMap } from './utils'
|
||||
import { formatDateShort } from '$lib/utils'
|
||||
import DisplayResult from '$lib/components/DisplayResult.svelte'
|
||||
import DisplayResultControlBar from '$lib/components/DisplayResultControlBar.svelte'
|
||||
import { base } from '$lib/base'
|
||||
@@ -431,7 +432,7 @@
|
||||
|
||||
dispatch('applyArgs', {
|
||||
kind: testKind,
|
||||
args: { ...clone(payloadData), ...trigger_extra }
|
||||
args: { ...structuredClone($state.snapshot(payloadData)), ...trigger_extra }
|
||||
})
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import { type CaptureTriggerKind } from '$lib/gen'
|
||||
import CaptureButton from '$lib/components/triggers/CaptureButton.svelte'
|
||||
import InfiniteList from '../InfiniteList.svelte'
|
||||
import { isObject, sendUserToast, clone} from '$lib/utils'
|
||||
import { isObject, sendUserToast } from '$lib/utils'
|
||||
import SchemaPickerRow from '$lib/components/schema/SchemaPickerRow.svelte'
|
||||
import type { Capture } from '$lib/gen'
|
||||
import { AwsIcon, MqttIcon } from '../icons'
|
||||
@@ -161,7 +161,7 @@
|
||||
} else {
|
||||
const payloadData = await getPayload(capture)
|
||||
selected = capture.id
|
||||
dispatch('select', clone(payloadData))
|
||||
dispatch('select', structuredClone($state.snapshot(payloadData)))
|
||||
dispatch('selectCapture', capture)
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,7 @@
|
||||
testKind === 'preprocessor' ? fullCapture.preprocessor_args : fullCapture.main_args
|
||||
}
|
||||
} else {
|
||||
payloadData = clone(capture.payloadData)
|
||||
payloadData = structuredClone($state.snapshot(capture.payloadData))
|
||||
}
|
||||
return payloadData
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import {
|
||||
@@ -106,7 +106,7 @@
|
||||
} finally {
|
||||
drawerLoading = false
|
||||
if (!defaultValues) {
|
||||
initialConfig = clone(getGcpConfig())
|
||||
initialConfig = structuredClone($state.snapshot(getGcpConfig()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import ScriptPicker from '$lib/components/ScriptPicker.svelte'
|
||||
import { HttpTriggerService, VariableService, type AuthenticationMethod } from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2, Pipette, Plus } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -183,7 +183,7 @@
|
||||
} finally {
|
||||
if (!defaultConfig) {
|
||||
// If the route is loaded from the backend, we to set the initial config
|
||||
initialConfig = clone(getRouteConfig())
|
||||
initialConfig = structuredClone($state.snapshot(getRouteConfig()))
|
||||
}
|
||||
clearTimeout(loader)
|
||||
drawerLoading = false
|
||||
|
||||
@@ -51,7 +51,6 @@ export async function saveHttpRouteFromCfg(
|
||||
route_path: isAdmin || !edit ? routeCfg.route_path : undefined,
|
||||
http_method: routeCfg.http_method,
|
||||
is_static_website: routeCfg.is_static_website,
|
||||
static_asset_config: routeCfg.static_asset_config,
|
||||
workspaced_route: routeCfg.workspaced_route,
|
||||
authentication_resource_path: routeCfg.authentication_resource_path,
|
||||
wrap_body: routeCfg.wrap_body,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import ScriptPicker from '$lib/components/ScriptPicker.svelte'
|
||||
import { KafkaTriggerService } from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -119,7 +119,7 @@
|
||||
sendUserToast(`Could not load Kafka trigger: ${err}`, true)
|
||||
} finally {
|
||||
if (!defaultConfig) {
|
||||
initialConfig = clone(getSaveCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getSaveCfg()))
|
||||
}
|
||||
clearTimeout(loadingTimeout)
|
||||
drawerLoading = false
|
||||
@@ -221,7 +221,7 @@
|
||||
return {
|
||||
kafka_resource_path: kafkaResourcePath,
|
||||
group_id: kafkaCfg.group_id,
|
||||
topics: clone(kafkaCfg.topics),
|
||||
topics: structuredClone($state.snapshot(kafkaCfg.topics)),
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import Required from '$lib/components/Required.svelte'
|
||||
import ScriptPicker from '$lib/components/ScriptPicker.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -114,7 +114,7 @@
|
||||
sendUserToast(`Could not load mqtt trigger: ${err.body}`, true)
|
||||
} finally {
|
||||
if (!defaultConfig) {
|
||||
initialConfig = clone(getSaveCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getSaveCfg()))
|
||||
}
|
||||
clearTimeout(loadingTimeout)
|
||||
drawerLoading = false
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import ScriptPicker from '$lib/components/ScriptPicker.svelte'
|
||||
import { NatsTriggerService } from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -112,7 +112,7 @@
|
||||
drawerLoading = false
|
||||
showLoading = false
|
||||
if (!defaultConfig) {
|
||||
initialConfig = clone(getSaveCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getSaveCfg()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import ScriptPicker from '$lib/components/ScriptPicker.svelte'
|
||||
import { PostgresTriggerService, type Language, type Relations } from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, emptyStringTrimmed, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, emptyStringTrimmed, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -210,7 +210,7 @@
|
||||
sendUserToast(`Could not load postgres trigger: ${err.body}`, true)
|
||||
} finally {
|
||||
if (!defaultConfig) {
|
||||
initialConfig = clone(getSaveCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getSaveCfg()))
|
||||
}
|
||||
clearTimeout(loadingTimeout)
|
||||
drawerLoading = false
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
type Schedule
|
||||
} from '$lib/gen'
|
||||
import { enterpriseLicense, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, formatCron, sendUserToast, cronV1toV2, clone } from '$lib/utils'
|
||||
import { canWrite, emptyString, formatCron, sendUserToast, cronV1toV2 } from '$lib/utils'
|
||||
import { base } from '$lib/base'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { List, Loader2, Save, AlertTriangle } from 'lucide-svelte'
|
||||
@@ -132,7 +132,7 @@
|
||||
edit = true
|
||||
} finally {
|
||||
if (!defaultCfg) {
|
||||
initialConfig = clone(getScheduleCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getScheduleCfg()))
|
||||
}
|
||||
clearTimeout(loadingTimeout)
|
||||
drawerLoading = false
|
||||
@@ -608,21 +608,21 @@
|
||||
}
|
||||
|
||||
function getScheduleCfg(): Record<string, any> {
|
||||
let errorHadlerExtraArgsDerived = clone(errorHandlerExtraArgs)
|
||||
let errorHadlerExtraArgsDerived = structuredClone($state.snapshot(errorHandlerExtraArgs))
|
||||
if (errorHandlerPath !== undefined && isSlackHandler('error', errorHandlerPath)) {
|
||||
errorHadlerExtraArgsDerived['slack'] = '$res:f/slack_bot/bot_token'
|
||||
} else {
|
||||
errorHadlerExtraArgsDerived['slack'] = undefined
|
||||
}
|
||||
|
||||
let recoveryHandlerExtraArgsDerived = clone(recoveryHandlerExtraArgs)
|
||||
let recoveryHandlerExtraArgsDerived = structuredClone($state.snapshot(recoveryHandlerExtraArgs))
|
||||
if (recoveryHandlerPath !== undefined && isSlackHandler('recovery', recoveryHandlerPath)) {
|
||||
recoveryHandlerExtraArgsDerived['slack'] = '$res:f/slack_bot/bot_token'
|
||||
} else {
|
||||
recoveryHandlerExtraArgsDerived['slack'] = undefined
|
||||
}
|
||||
|
||||
let successHandlerExtraArgsDerived = clone(successHandlerExtraArgs)
|
||||
let successHandlerExtraArgsDerived = structuredClone($state.snapshot(successHandlerExtraArgs))
|
||||
if (successHandlerPath !== undefined && isSlackHandler('success', successHandlerPath)) {
|
||||
successHandlerExtraArgsDerived['slack'] = '$res:f/slack_bot/bot_token'
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import { SqsTriggerService, type AwsAuthResourceType } from '$lib/gen'
|
||||
@@ -136,7 +136,7 @@
|
||||
dirtyPath = false
|
||||
enabled = defaultValues?.enabled ?? false
|
||||
} finally {
|
||||
initialConfig = clone(getSaveCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getSaveCfg()))
|
||||
clearTimeout(loadingTimeout)
|
||||
drawerLoading = false
|
||||
showLoading = false
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
type WebsocketTriggerInitialMessage
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { canWrite, emptySchema, emptyString, sendUserToast, clone} from '$lib/utils'
|
||||
import { canWrite, emptySchema, emptyString, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2, X, Plus } from 'lucide-svelte'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
@@ -139,7 +139,7 @@
|
||||
sendUserToast(`Could not load websocket trigger: ${err}`, true)
|
||||
} finally {
|
||||
if (!defaultConfig) {
|
||||
initialConfig = clone(getSaveCfg())
|
||||
initialConfig = structuredClone($state.snapshot(getSaveCfg()))
|
||||
}
|
||||
clearTimeout(loadingTimeout)
|
||||
drawerLoading = false
|
||||
|
||||
@@ -1023,7 +1023,7 @@ export type Value = {
|
||||
}
|
||||
|
||||
export function replaceFalseWithUndefined(obj: any) {
|
||||
return replaceFalseWithUndefinedRec(clone(obj))
|
||||
return replaceFalseWithUndefinedRec(structuredClone(stateSnapshot(obj)))
|
||||
}
|
||||
|
||||
function replaceFalseWithUndefinedRec(obj: any) {
|
||||
@@ -1052,7 +1052,7 @@ export function cleanValueProperties(obj: Value) {
|
||||
let newObj: any = {}
|
||||
for (const key of Object.keys(obj)) {
|
||||
if (key !== 'parent_hash' && key !== 'draft' && key !== 'draft_only') {
|
||||
newObj[key] = clone(obj[key])
|
||||
newObj[key] = structuredClone(stateSnapshot(obj[key]))
|
||||
}
|
||||
}
|
||||
return newObj
|
||||
@@ -1372,7 +1372,6 @@ import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type { Snippet } from 'svelte'
|
||||
import { OpenAPIV2, type OpenAPI, type OpenAPIV3, type OpenAPIV3_1 } from 'openapi-types'
|
||||
import type { IPosition } from 'monaco-editor'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
@@ -1431,11 +1430,3 @@ export function scroll_into_view_if_needed_polyfill(elem: Element, centerIfNeede
|
||||
|
||||
return observer // return for testing
|
||||
}
|
||||
|
||||
export function clone<T>(t: T): T {
|
||||
if (typeof t === 'function') throw new Error('Cannot clone a function')
|
||||
if (typeof t === 'object') return stateSnapshot(t) as T
|
||||
return t
|
||||
}
|
||||
|
||||
export const editorPositionMap: Record<string, IPosition> = {}
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
} from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { page } from '$app/stores'
|
||||
import { cleanValueProperties, decodeState, type Value, clone} from '$lib/utils'
|
||||
import { cleanValueProperties, decodeState, type Value } from '$lib/utils'
|
||||
import { afterNavigate, replaceState } from '$app/navigation'
|
||||
import { goto } from '$lib/navigation'
|
||||
import { sendUserToast, type ToastAction } from '$lib/toast'
|
||||
import DiffDrawer from '$lib/components/DiffDrawer.svelte'
|
||||
import type { App } from '$lib/components/apps/types'
|
||||
import UnsavedConfirmationModal from '$lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte'
|
||||
import { stateSnapshot } from '$lib/svelte5Utils.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
|
||||
let app = $state(
|
||||
@@ -52,7 +53,7 @@
|
||||
path,
|
||||
workspace: $workspaceStore!
|
||||
})
|
||||
const app_w_draft_: AppWithLastVersionWDraft = clone(app_w_draft)
|
||||
const app_w_draft_: AppWithLastVersionWDraft = structuredClone(stateSnapshot(app_w_draft))
|
||||
savedApp = {
|
||||
summary: app_w_draft_.summary,
|
||||
value: app_w_draft_.value as App,
|
||||
@@ -200,7 +201,7 @@
|
||||
function onRestore(ev: any) {
|
||||
sendUserToast('App restored from previous deployment')
|
||||
app = ev.detail
|
||||
const app_ = clone(app!)
|
||||
const app_ = structuredClone(stateSnapshot(app!))
|
||||
savedApp = {
|
||||
summary: app_.summary,
|
||||
value: app_.value as App,
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
import { AppService, DraftService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { page } from '$app/stores'
|
||||
import { cleanValueProperties, decodeState, type Value, clone} from '$lib/utils'
|
||||
import { cleanValueProperties, decodeState, type Value } from '$lib/utils'
|
||||
import { afterNavigate, replaceState } from '$app/navigation'
|
||||
import { goto } from '$lib/navigation'
|
||||
import { sendUserToast, type ToastAction } from '$lib/toast'
|
||||
import DiffDrawer from '$lib/components/DiffDrawer.svelte'
|
||||
import type { HiddenRunnable } from '$lib/components/apps/types'
|
||||
import RawAppEditor from '$lib/components/raw_apps/RawAppEditor.svelte'
|
||||
import { stateSnapshot } from '$lib/svelte5Utils.svelte'
|
||||
|
||||
let files: Record<string, string> | undefined = undefined
|
||||
let runnables = {}
|
||||
@@ -62,7 +63,7 @@
|
||||
path,
|
||||
workspace: $workspaceStore!
|
||||
})
|
||||
const app_w_draft_ = clone(app_w_draft)
|
||||
const app_w_draft_ = structuredClone(stateSnapshot(app_w_draft))
|
||||
savedApp = {
|
||||
summary: app_w_draft_.summary,
|
||||
value: app_w_draft_.value as any,
|
||||
@@ -190,9 +191,9 @@
|
||||
extractRawApp(prev)
|
||||
savedApp = {
|
||||
summary: prev.summary,
|
||||
value: clone(prev.value),
|
||||
value: structuredClone(stateSnapshot(prev.value)),
|
||||
path: prev.path,
|
||||
policy: clone(policy),
|
||||
policy: structuredClone(stateSnapshot(policy)),
|
||||
custom_path: prev.custom_path
|
||||
}
|
||||
redraw++
|
||||
|
||||
@@ -153,7 +153,6 @@
|
||||
}
|
||||
}
|
||||
await initFlow(flow, flowStore, flowStateStore)
|
||||
flowBuilder?.loadFlowState()
|
||||
loading = false
|
||||
}
|
||||
|
||||
@@ -183,7 +182,6 @@
|
||||
{loading}
|
||||
{draftTriggersFromUrl}
|
||||
{selectedTriggerIndexFromUrl}
|
||||
noInitial
|
||||
>
|
||||
<UnsavedConfirmationModal
|
||||
getInitialAndModifiedValues={flowBuilder?.getInitialAndModifiedValues}
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
decodeState,
|
||||
emptySchema,
|
||||
orderedJsonStringify,
|
||||
type StateStore,
|
||||
clone
|
||||
type StateStore
|
||||
} from '$lib/utils'
|
||||
import { initFlow } from '$lib/components/flows/flowStore.svelte'
|
||||
import { goto } from '$lib/navigation'
|
||||
@@ -23,7 +22,6 @@
|
||||
import type { ScheduleTrigger } from '$lib/components/triggers'
|
||||
import type { Trigger } from '$lib/components/triggers/utils'
|
||||
import { untrack } from 'svelte'
|
||||
import type { stepState } from '$lib/components/stepHistoryLoader.svelte'
|
||||
|
||||
let version: undefined | number = $state(undefined)
|
||||
let nodraft = $page.url.searchParams.get('nodraft')
|
||||
@@ -75,9 +73,6 @@
|
||||
|
||||
let draftTriggersFromUrl: Trigger[] | undefined = $state(undefined)
|
||||
let selectedTriggerIndexFromUrl: number | undefined = $state(undefined)
|
||||
let loadedFromHistoryFromUrl:
|
||||
| { flowJobInitial: boolean | undefined; stepsState: Record<string, stepState> }
|
||||
| undefined = $state(undefined)
|
||||
|
||||
let flowBuilder: FlowBuilder | undefined = $state(undefined)
|
||||
|
||||
@@ -111,10 +106,8 @@
|
||||
flow = stateLoadedFromUrl.flow
|
||||
draftTriggersFromUrl = stateLoadedFromUrl.draft_triggers
|
||||
selectedTriggerIndexFromUrl = stateLoadedFromUrl.selected_trigger
|
||||
loadedFromHistoryFromUrl = stateLoadedFromUrl.loadedFromHistory
|
||||
flowBuilder?.setDraftTriggers(draftTriggersFromUrl)
|
||||
flowBuilder?.setSelectedTriggerIndex(selectedTriggerIndexFromUrl)
|
||||
flowBuilder?.setLoadedFromHistory(loadedFromHistoryFromUrl)
|
||||
const selectedId = stateLoadedFromUrl?.selectedId ?? 'settings-metadata'
|
||||
const reloadAction = () => {
|
||||
stateLoadedFromUrl = undefined
|
||||
@@ -159,10 +152,10 @@
|
||||
path: $page.params.path
|
||||
})
|
||||
savedFlow = {
|
||||
...clone(flowWithDraft),
|
||||
...structuredClone($state.snapshot(flowWithDraft)),
|
||||
draft: flowWithDraft.draft
|
||||
? {
|
||||
...clone(flowWithDraft.draft),
|
||||
...structuredClone($state.snapshot(flowWithDraft.draft)),
|
||||
path: flowWithDraft.draft.path ?? flowWithDraft.path // backward compatibility for old drafts missing path
|
||||
}
|
||||
: undefined
|
||||
@@ -219,7 +212,6 @@
|
||||
await initFlow(flow, flowStore, flowStateStore)
|
||||
loading = false
|
||||
selectedId = stateLoadedFromUrl?.selectedId ?? $page.url.searchParams.get('selected')
|
||||
flowBuilder?.loadFlowState()
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
@@ -291,7 +283,6 @@
|
||||
{draftTriggersFromUrl}
|
||||
{selectedTriggerIndexFromUrl}
|
||||
{version}
|
||||
{loadedFromHistoryFromUrl}
|
||||
>
|
||||
<UnsavedConfirmationModal
|
||||
{diffDrawer}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { page } from '$app/stores'
|
||||
import { initialArgsStore, workspaceStore } from '$lib/stores'
|
||||
import ScriptBuilder from '$lib/components/ScriptBuilder.svelte'
|
||||
import { decodeState, cleanValueProperties, orderedJsonStringify, clone} from '$lib/utils'
|
||||
import { decodeState, cleanValueProperties, orderedJsonStringify } from '$lib/utils'
|
||||
import { goto } from '$lib/navigation'
|
||||
import { replaceState } from '$app/navigation'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
@@ -87,14 +87,14 @@
|
||||
workspace: $workspaceStore!,
|
||||
hash
|
||||
})
|
||||
savedScript = clone(scriptByHash) as NewScriptWithDraft
|
||||
savedScript = structuredClone($state.snapshot(scriptByHash)) as NewScriptWithDraft
|
||||
script = { ...scriptByHash, parent_hash: hash, lock: undefined }
|
||||
} else {
|
||||
const scriptWithDraft = await ScriptService.getScriptByPathWithDraft({
|
||||
workspace: $workspaceStore!,
|
||||
path: $page.params.path
|
||||
})
|
||||
savedScript = clone(scriptWithDraft)
|
||||
savedScript = structuredClone($state.snapshot(scriptWithDraft))
|
||||
if (scriptWithDraft.draft != undefined) {
|
||||
script = scriptWithDraft.draft
|
||||
scriptBuilder?.setDraftTriggers(script.draft_triggers)
|
||||
|
||||
@@ -18,11 +18,8 @@
|
||||
return
|
||||
}
|
||||
|
||||
if (rd?.startsWith('https://') || rd?.startsWith('http://')) {
|
||||
window.location.href = rd
|
||||
} else {
|
||||
goto(rd ?? '/user/login')
|
||||
}
|
||||
console.log('logout 4', rd)
|
||||
goto(rd ?? '/user/login')
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wmill = ">=1.501.3"
|
||||
wmill_pg = ">=1.501.3"
|
||||
wmill = ">=1.501.0"
|
||||
wmill_pg = ">=1.501.0"
|
||||
sendgrid = "*"
|
||||
mysql-connector-python = "*"
|
||||
pymongo = "*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.501.3
|
||||
version: 1.501.0
|
||||
title: OpenFlow Spec
|
||||
contact:
|
||||
name: Ruben Fiszel
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RootModule = 'WindmillClient.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.501.3'
|
||||
ModuleVersion = '1.501.0'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
description = "A client library for accessing Windmill server wrapping the Windmill client API"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill-pg"
|
||||
version = "1.501.3"
|
||||
version = "1.501.0"
|
||||
description = "An extension client for the wmill client library focused on pg"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user