Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
589cd39eec | |||
63feebef5c | |||
65037abd9a | |||
97bc339a62 | |||
4e9a6375a5 | |||
3d19dfb800 | |||
d2a7b84292 | |||
9e02bab155 | |||
7352de5a70 | |||
9797d0cb81 | |||
83907fa9db | |||
a367be4e2b | |||
056fa00adc | |||
4759fb2e6f | |||
45f497d9cd | |||
dc61bdebdf | |||
61943055e5 | |||
416fe0f644 | |||
708465d818 | |||
e706fb02d6 | |||
1bf7daa474 | |||
ffc47f8f40 | |||
768aaa84f6 | |||
f3a700eec8 | |||
c853637a9a | |||
9af30d9ef6 | |||
6164714a6b | |||
64ceb98eba | |||
2cbf260900 | |||
cfaaedf602 |
1859
docs/kcl/std.json
1859
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
316
docs/kcl/std.md
316
docs/kcl/std.md
@ -50,6 +50,8 @@
|
||||
* [`sqrt`](#sqrt)
|
||||
* [`startSketchAt`](#startSketchAt)
|
||||
* [`tan`](#tan)
|
||||
* [`tangentalArc`](#tangentalArc)
|
||||
* [`tangentalArcTo`](#tangentalArcTo)
|
||||
* [`tau`](#tau)
|
||||
* [`xLine`](#xLine)
|
||||
* [`xLineTo`](#xLineTo)
|
||||
@ -3234,6 +3236,320 @@ tan(num: number) -> number
|
||||
|
||||
|
||||
|
||||
### tangentalArc
|
||||
|
||||
Draw an arc.
|
||||
|
||||
|
||||
|
||||
```
|
||||
tangentalArc(data: TangentalArcData, sketch_group: SketchGroup) -> SketchGroup
|
||||
```
|
||||
|
||||
#### Arguments
|
||||
|
||||
* `data`: `TangentalArcData` - Data to draw a tangental arc.
|
||||
```
|
||||
{
|
||||
// Offset of the arc, in degrees.
|
||||
offset: number,
|
||||
// Radius of the arc. Not to be confused with Raiders of the Lost Ark.
|
||||
radius: number,
|
||||
} |
|
||||
{
|
||||
// The tag.
|
||||
tag: string,
|
||||
// Where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
to: [number],
|
||||
} |
|
||||
[number]
|
||||
```
|
||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
|
||||
```
|
||||
{
|
||||
// The id of the sketch group.
|
||||
id: uuid,
|
||||
// The position of the sketch group.
|
||||
position: [number],
|
||||
// The rotation of the sketch group.
|
||||
rotation: [number],
|
||||
// The starting path.
|
||||
start: {
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
},
|
||||
// The paths in the sketch group.
|
||||
value: [{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
// The y coordinate.
|
||||
y: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
}],
|
||||
}
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
* `SketchGroup` - A sketch group is a collection of paths.
|
||||
```
|
||||
{
|
||||
// The id of the sketch group.
|
||||
id: uuid,
|
||||
// The position of the sketch group.
|
||||
position: [number],
|
||||
// The rotation of the sketch group.
|
||||
rotation: [number],
|
||||
// The starting path.
|
||||
start: {
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
},
|
||||
// The paths in the sketch group.
|
||||
value: [{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
// The y coordinate.
|
||||
y: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
}],
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### tangentalArcTo
|
||||
|
||||
Draw an arc.
|
||||
|
||||
|
||||
|
||||
```
|
||||
tangentalArcTo(data: TangentalArcToData, sketch_group: SketchGroup) -> SketchGroup
|
||||
```
|
||||
|
||||
#### Arguments
|
||||
|
||||
* `data`: `TangentalArcToData` - Data to draw a tangental arc to a specific point.
|
||||
```
|
||||
{
|
||||
// The tag.
|
||||
tag: string,
|
||||
// Where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
to: [number],
|
||||
} |
|
||||
[number]
|
||||
```
|
||||
* `sketch_group`: `SketchGroup` - A sketch group is a collection of paths.
|
||||
```
|
||||
{
|
||||
// The id of the sketch group.
|
||||
id: uuid,
|
||||
// The position of the sketch group.
|
||||
position: [number],
|
||||
// The rotation of the sketch group.
|
||||
rotation: [number],
|
||||
// The starting path.
|
||||
start: {
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
},
|
||||
// The paths in the sketch group.
|
||||
value: [{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
// The y coordinate.
|
||||
y: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
}],
|
||||
}
|
||||
```
|
||||
|
||||
#### Returns
|
||||
|
||||
* `SketchGroup` - A sketch group is a collection of paths.
|
||||
```
|
||||
{
|
||||
// The id of the sketch group.
|
||||
id: uuid,
|
||||
// The position of the sketch group.
|
||||
position: [number],
|
||||
// The rotation of the sketch group.
|
||||
rotation: [number],
|
||||
// The starting path.
|
||||
start: {
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
},
|
||||
// The paths in the sketch group.
|
||||
value: [{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
// The x coordinate.
|
||||
x: number,
|
||||
// The y coordinate.
|
||||
y: number,
|
||||
} |
|
||||
{
|
||||
// The from point.
|
||||
from: [number],
|
||||
// The name of the path.
|
||||
name: string,
|
||||
// The to point.
|
||||
to: [number],
|
||||
type: string,
|
||||
}],
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### tau
|
||||
|
||||
Return the value of `tau`. The full circle constant (τ). Equal to 2π.
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "untitled-app",
|
||||
"version": "0.9.2",
|
||||
"version": "0.9.4",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.9.0",
|
||||
@ -10,7 +10,7 @@
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@headlessui/react": "^1.7.13",
|
||||
"@headlessui/tailwindcss": "^0.2.0",
|
||||
"@kittycad/lib": "^0.0.39",
|
||||
"@kittycad/lib": "^0.0.40",
|
||||
"@lezer/javascript": "^1.4.7",
|
||||
"@open-rpc/client-js": "^1.8.1",
|
||||
"@react-hook/resize-observer": "^1.2.6",
|
||||
@ -48,7 +48,7 @@
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.4.2",
|
||||
"uuid": "^9.0.0",
|
||||
"vitest": "^0.34.1",
|
||||
"vitest": "^0.34.6",
|
||||
"vscode-jsonrpc": "^8.1.0",
|
||||
"vscode-languageserver-protocol": "^3.17.3",
|
||||
"wasm-pack": "^0.12.1",
|
||||
@ -116,7 +116,7 @@
|
||||
"eslint-plugin-css-modules": "^2.11.0",
|
||||
"happy-dom": "^10.8.0",
|
||||
"husky": "^8.0.3",
|
||||
"postcss": "^8.4.19",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "^2.8.0",
|
||||
"setimmediate": "^1.0.5",
|
||||
"tailwindcss": "^3.2.4",
|
||||
|
122
src-tauri/Cargo.lock
generated
122
src-tauri/Cargo.lock
generated
@ -84,7 +84,7 @@ dependencies = [
|
||||
"tauri-build",
|
||||
"tauri-plugin-fs-extra",
|
||||
"tokio",
|
||||
"toml 0.8.0",
|
||||
"toml 0.8.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1309,7 +1309,21 @@ checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mac",
|
||||
"markup5ever",
|
||||
"markup5ever 0.10.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mac",
|
||||
"markup5ever 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
@ -1644,9 +1658,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad"
|
||||
version = "0.2.26"
|
||||
version = "0.2.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2623ee601ce203476229df3f9d3a14664cb43e3f7455e9ac8ed91aacaa6163d"
|
||||
checksum = "35b2f9302648dbb06fd7121687f9505fc3179eba84111a06d76b246e3158f5dc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1686,7 +1700,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
"html5ever",
|
||||
"html5ever 0.25.2",
|
||||
"matches",
|
||||
"selectors",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kuchikiki"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
"html5ever 0.26.0",
|
||||
"indexmap 1.9.3",
|
||||
"matches",
|
||||
"selectors",
|
||||
]
|
||||
@ -1748,9 +1775,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.18"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -1802,7 +1829,21 @@ checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd"
|
||||
dependencies = [
|
||||
"log",
|
||||
"phf 0.8.0",
|
||||
"phf_codegen",
|
||||
"phf_codegen 0.8.0",
|
||||
"string_cache",
|
||||
"string_cache_codegen",
|
||||
"tendril",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
|
||||
dependencies = [
|
||||
"log",
|
||||
"phf 0.10.1",
|
||||
"phf_codegen 0.10.0",
|
||||
"string_cache",
|
||||
"string_cache_codegen",
|
||||
"tendril",
|
||||
@ -2374,6 +2415,16 @@ dependencies = [
|
||||
"phf_shared 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
|
||||
dependencies = [
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.8.0"
|
||||
@ -3139,7 +3190,7 @@ dependencies = [
|
||||
"log",
|
||||
"matches",
|
||||
"phf 0.8.0",
|
||||
"phf_codegen",
|
||||
"phf_codegen 0.8.0",
|
||||
"precomputed-hash",
|
||||
"servo_arc",
|
||||
"smallvec",
|
||||
@ -3661,9 +3712,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "1.4.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fbe522898e35407a8e60dc3870f7579fea2fc262a6a6072eccdd37ae1e1d91e"
|
||||
checksum = "72aee3277d0a0df01472cc704ab5934a51a1f25348838df17bfb3c5cb727880c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.2",
|
||||
@ -3717,12 +3768,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-build"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d2edd6a259b5591c8efdeb9d5702cb53515b82a6affebd55c7fd6d3a27b7d1b"
|
||||
checksum = "defbfc551bd38ab997e5f8e458f87396d2559d05ce32095076ad6c30f7fc5f9c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_toml",
|
||||
"dirs-next",
|
||||
"heck 0.4.1",
|
||||
"json-patch",
|
||||
"semver",
|
||||
@ -3730,13 +3782,14 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri-utils",
|
||||
"tauri-winres",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-codegen"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54ad2d49fdeab4a08717f5b49a163bdc72efc3b1950b6758245fcde79b645e1a"
|
||||
checksum = "7b3475e55acec0b4a50fb96435f19631fb58cbcd31923e1a213de5c382536bbb"
|
||||
dependencies = [
|
||||
"base64 0.21.2",
|
||||
"brotli",
|
||||
@ -3760,9 +3813,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-macros"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eb12a2454e747896929338d93b0642144bb51e0dddbb36e579035731f0d76b7"
|
||||
checksum = "613740228de92d9196b795ac455091d3a5fbdac2654abb8bb07d010b62ab43af"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
@ -3775,7 +3828,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tauri-plugin-fs-extra"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#b04bde3461066c709d6801cf9ca305cf889a8394"
|
||||
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#9b96996b5a90a6a57d587ce4312975f13a4d8bc2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@ -3786,9 +3839,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "108683199cb18f96d2d4134187bb789964143c845d2d154848dda209191fd769"
|
||||
checksum = "07f8e9e53e00e9f41212c115749e87d5cd2a9eebccafca77a19722eeecd56d43"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http",
|
||||
@ -3807,9 +3860,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7aa256a1407a3a091b5d843eccc1a5042289baf0a43d1179d9f0fcfea37c1b"
|
||||
checksum = "8141d72b6b65f2008911e9ef5b98a68d1e3413b7a1464e8f85eb3673bb19a895"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"gtk",
|
||||
@ -3827,19 +3880,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-utils"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03fc02bb6072bb397e1d473c6f76c953cda48b4a2d0cce605df284aa74a12e84"
|
||||
checksum = "34d55e185904a84a419308d523c2c6891d5e2dbcee740c4997eb42e75a7b0f46"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"ctor",
|
||||
"dunce",
|
||||
"glob",
|
||||
"heck 0.4.1",
|
||||
"html5ever",
|
||||
"html5ever 0.26.0",
|
||||
"infer",
|
||||
"json-patch",
|
||||
"kuchiki",
|
||||
"kuchikiki",
|
||||
"log",
|
||||
"memchr",
|
||||
"phf 0.10.1",
|
||||
"proc-macro2",
|
||||
@ -4024,14 +4078,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c226a7bba6d859b63c92c4b4fe69c5b6b72d0cb897dbc8e6012298e6154cb56e"
|
||||
checksum = "1bc1433177506450fe920e46a4f9812d0c211f5dd556da10e731a0a3dfa151f0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.20.0",
|
||||
"toml_edit 0.20.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4058,9 +4112,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.20.0"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ff63e60a958cefbb518ae1fd6566af80d9d4be430a33f3723dfc47d1d411d95"
|
||||
checksum = "ca676d9ba1a322c1b64eb8045a5ec5c0cfb0c9d08e15e9ff622589ad5221c8fe"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"serde",
|
||||
@ -4855,9 +4909,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.24.3"
|
||||
version = "0.24.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33748f35413c8a98d45f7a08832d848c0c5915501803d1faade5a4ebcd258cea"
|
||||
checksum = "88ef04bdad49eba2e01f06e53688c8413bd6a87b0bc14b72284465cf96e3578e"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"block",
|
||||
@ -4869,7 +4923,7 @@ dependencies = [
|
||||
"gio",
|
||||
"glib",
|
||||
"gtk",
|
||||
"html5ever",
|
||||
"html5ever 0.25.2",
|
||||
"http",
|
||||
"kuchiki",
|
||||
"libc",
|
||||
|
@ -12,18 +12,18 @@ rust-version = "1.60"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.4.0", features = [] }
|
||||
tauri-build = { version = "1.5.0", features = [] }
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
kittycad = "0.2.26"
|
||||
kittycad = "0.2.28"
|
||||
oauth2 = "4.4.2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tauri = { version = "1.4.1", features = [ "os-all", "dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "updater", "devtools"] }
|
||||
tauri = { version = "1.5.0", features = [ "os-all", "dialog-all", "fs-all", "http-request", "path-all", "shell-open", "shell-open-api", "updater", "devtools"] }
|
||||
tauri-plugin-fs-extra = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
|
||||
tokio = { version = "1.32.0", features = ["time"] }
|
||||
toml = "0.8.0"
|
||||
toml = "0.8.1"
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
|
||||
|
@ -8,7 +8,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "kittycad-modeling",
|
||||
"version": "0.9.2"
|
||||
"version": "0.9.4"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
|
@ -23,10 +23,7 @@ type ActionButtonAsLink = BaseActionButtonProps &
|
||||
}
|
||||
|
||||
type ActionButtonAsExternal = BaseActionButtonProps &
|
||||
Omit<
|
||||
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
keyof BaseActionButtonProps
|
||||
> & {
|
||||
Omit<LinkProps, keyof BaseActionButtonProps> & {
|
||||
Element: 'externalLink'
|
||||
}
|
||||
|
||||
@ -69,12 +66,17 @@ export const ActionButton = (props: ActionButtonProps) => {
|
||||
)
|
||||
}
|
||||
case 'externalLink': {
|
||||
const { Element, icon, children, className, ...rest } = props
|
||||
const { Element, to, icon, children, className, ...rest } = props
|
||||
return (
|
||||
<a className={classNames} {...rest}>
|
||||
<Link
|
||||
to={to || paths.INDEX}
|
||||
className={classNames}
|
||||
{...rest}
|
||||
target="_blank"
|
||||
>
|
||||
{icon && <ActionIcon {...icon} />}
|
||||
{children}
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
default: {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { useEffect, useState, useRef } from 'react'
|
||||
import { parser_wasm } from '../lang/abstractSyntaxTree'
|
||||
import { BinaryPart, Value } from '../lang/abstractSyntaxTreeTypes'
|
||||
import { executor } from '../lang/executor'
|
||||
import { parse, BinaryPart, Value, executor } from '../lang/wasm'
|
||||
import {
|
||||
createIdentifier,
|
||||
createLiteral,
|
||||
@ -140,7 +138,7 @@ export function useCalc({
|
||||
useEffect(() => {
|
||||
try {
|
||||
const code = `const __result__ = ${value}\nshow(__result__)`
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const _programMem: any = { root: {}, return: null }
|
||||
availableVarInfo.variables.forEach(({ key, value }) => {
|
||||
_programMem.root[key] = { type: 'userVal', value, __meta: [] }
|
||||
|
@ -6,8 +6,12 @@ import React from 'react'
|
||||
import { useFormik } from 'formik'
|
||||
import { Models } from '@kittycad/lib'
|
||||
import { engineCommandManager } from '../lang/std/engineConnection'
|
||||
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
||||
|
||||
type OutputFormat = Models['OutputFormat_type']
|
||||
type OutputTypeKey = OutputFormat['type']
|
||||
type ExtractStorageTypes<T> = T extends { storage: infer U } ? U : never
|
||||
type StorageUnion = ExtractStorageTypes<OutputFormat>
|
||||
|
||||
interface ExportButtonProps extends React.PropsWithChildren {
|
||||
className?: {
|
||||
@ -19,9 +23,18 @@ interface ExportButtonProps extends React.PropsWithChildren {
|
||||
|
||||
export const ExportButton = ({ children, className }: ExportButtonProps) => {
|
||||
const [modalIsOpen, setIsOpen] = React.useState(false)
|
||||
const {
|
||||
settings: {
|
||||
state: {
|
||||
context: { baseUnit },
|
||||
},
|
||||
},
|
||||
} = useGlobalStateContext()
|
||||
|
||||
const defaultType = 'gltf'
|
||||
const [type, setType] = React.useState(defaultType)
|
||||
const [type, setType] = React.useState<OutputTypeKey>(defaultType)
|
||||
const defaultStorage = 'embedded'
|
||||
const [storage, setStorage] = React.useState<StorageUnion>(defaultStorage)
|
||||
|
||||
function openModal() {
|
||||
setIsOpen(true)
|
||||
@ -34,7 +47,7 @@ export const ExportButton = ({ children, className }: ExportButtonProps) => {
|
||||
// Default to gltf and embedded.
|
||||
const initialValues: OutputFormat = {
|
||||
type: defaultType,
|
||||
storage: 'embedded',
|
||||
storage: defaultStorage,
|
||||
presentation: 'pretty',
|
||||
}
|
||||
const formik = useFormik({
|
||||
@ -62,6 +75,17 @@ export const ExportButton = ({ children, className }: ExportButtonProps) => {
|
||||
},
|
||||
}
|
||||
}
|
||||
if (values.type === 'obj' || values.type === 'stl') {
|
||||
values.units = baseUnit
|
||||
}
|
||||
if (
|
||||
values.type === 'ply' ||
|
||||
values.type === 'stl' ||
|
||||
values.type === 'gltf'
|
||||
) {
|
||||
// Set the storage type.
|
||||
values.storage = storage
|
||||
}
|
||||
engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd: {
|
||||
@ -71,6 +95,7 @@ export const ExportButton = ({ children, className }: ExportButtonProps) => {
|
||||
// in the scene to export. In that case, you'd pass the IDs thru here.
|
||||
entity_ids: [],
|
||||
format: values,
|
||||
source_unit: baseUnit,
|
||||
},
|
||||
cmd_id: uuidv4(),
|
||||
})
|
||||
@ -105,7 +130,17 @@ export const ExportButton = ({ children, className }: ExportButtonProps) => {
|
||||
id="type"
|
||||
name="type"
|
||||
onChange={(e) => {
|
||||
setType(e.target.value)
|
||||
setType(e.target.value as OutputTypeKey)
|
||||
if (e.target.value === 'gltf') {
|
||||
// Set default to embedded.
|
||||
setStorage('embedded')
|
||||
} else if (e.target.value === 'ply') {
|
||||
// Set default to ascii.
|
||||
setStorage('ascii')
|
||||
} else if (e.target.value === 'stl') {
|
||||
// Set default to ascii.
|
||||
setStorage('ascii')
|
||||
}
|
||||
formik.handleChange(e)
|
||||
}}
|
||||
className="bg-chalkboard-20 dark:bg-chalkboard-90 w-full"
|
||||
@ -123,10 +158,10 @@ export const ExportButton = ({ children, className }: ExportButtonProps) => {
|
||||
<select
|
||||
id="storage"
|
||||
name="storage"
|
||||
onChange={formik.handleChange}
|
||||
value={
|
||||
'storage' in formik.values ? formik.values.storage : ''
|
||||
}
|
||||
onChange={(e) => {
|
||||
setStorage(e.target.value as StorageUnion)
|
||||
formik.handleChange(e)
|
||||
}}
|
||||
className="bg-chalkboard-20 dark:bg-chalkboard-90 w-full"
|
||||
>
|
||||
{type === 'gltf' && (
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { processMemory } from './MemoryPanel'
|
||||
import { parser_wasm } from '../lang/abstractSyntaxTree'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
import { initPromise } from '../lang/rust'
|
||||
import { initPromise, parse } from '../lang/wasm'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -26,7 +25,7 @@ describe('processMemory', () => {
|
||||
|> lineTo([2.15, 4.32], %)
|
||||
// |> rx(90, %)
|
||||
show(theExtrude, theSketch)`
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast, {
|
||||
root: {},
|
||||
return: null,
|
||||
|
@ -2,7 +2,7 @@ import ReactJson from 'react-json-view'
|
||||
import { CollapsiblePanel, CollapsiblePanelProps } from './CollapsiblePanel'
|
||||
import { useStore } from '../useStore'
|
||||
import { useMemo } from 'react'
|
||||
import { ProgramMemory, Path, ExtrudeSurface } from '../lang/executor'
|
||||
import { ProgramMemory, Path, ExtrudeSurface } from '../lang/wasm'
|
||||
import { Themes } from '../lib/theme'
|
||||
|
||||
interface MemoryPanelProps extends CollapsiblePanelProps {
|
||||
|
@ -2,6 +2,8 @@ import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import ProjectSidebarMenu from './ProjectSidebarMenu'
|
||||
import { ProjectWithEntryPointMetadata } from '../Router'
|
||||
import { GlobalStateProvider } from './GlobalStateProvider'
|
||||
import CommandBarProvider from './CommandBar'
|
||||
|
||||
const now = new Date()
|
||||
const projectWellFormed = {
|
||||
@ -38,7 +40,11 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
test('Renders the project name', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<ProjectSidebarMenu project={projectWellFormed} />
|
||||
<CommandBarProvider>
|
||||
<GlobalStateProvider>
|
||||
<ProjectSidebarMenu project={projectWellFormed} />
|
||||
</GlobalStateProvider>
|
||||
</CommandBarProvider>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
@ -55,7 +61,11 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
test('Renders app name if given no project', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<ProjectSidebarMenu />
|
||||
<CommandBarProvider>
|
||||
<GlobalStateProvider>
|
||||
<ProjectSidebarMenu />
|
||||
</GlobalStateProvider>
|
||||
</CommandBarProvider>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
@ -69,7 +79,14 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
test('Renders as a link if set to do so', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<ProjectSidebarMenu project={projectWellFormed} renderAsLink={true} />
|
||||
<CommandBarProvider>
|
||||
<GlobalStateProvider>
|
||||
<ProjectSidebarMenu
|
||||
project={projectWellFormed}
|
||||
renderAsLink={true}
|
||||
/>
|
||||
</GlobalStateProvider>
|
||||
</CommandBarProvider>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Fragment, useState } from 'react'
|
||||
import { Value } from '../lang/abstractSyntaxTreeTypes'
|
||||
import { Value } from '../lang/wasm'
|
||||
import {
|
||||
AvailableVars,
|
||||
addToInputHelper,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Fragment, useState } from 'react'
|
||||
import { Value } from '../lang/abstractSyntaxTreeTypes'
|
||||
import { Value } from '../lang/wasm'
|
||||
import {
|
||||
AvailableVars,
|
||||
addToInputHelper,
|
||||
|
@ -20,11 +20,14 @@ import {
|
||||
compareVec2Epsilon,
|
||||
} from 'lang/std/sketch'
|
||||
import { getNodeFromPath } from 'lang/queryAst'
|
||||
import { Program, VariableDeclarator } from 'lang/abstractSyntaxTreeTypes'
|
||||
import { modify_ast_for_sketch } from '../wasm-lib/pkg/wasm_lib'
|
||||
import {
|
||||
Program,
|
||||
VariableDeclarator,
|
||||
rangeTypeFix,
|
||||
modifyAstForSketch,
|
||||
} from 'lang/wasm'
|
||||
import { KCLError } from 'lang/errors'
|
||||
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||
import { rangeTypeFix } from 'lang/abstractSyntaxTree'
|
||||
import { engineCommandManager } from '../lang/std/engineConnection'
|
||||
|
||||
export const Stream = ({ className = '' }) => {
|
||||
@ -249,26 +252,14 @@ export const Stream = ({ className = '' }) => {
|
||||
|
||||
let engineId = guiMode.pathId
|
||||
|
||||
try {
|
||||
const updatedAst: Program = await modify_ast_for_sketch(
|
||||
engineCommandManager,
|
||||
JSON.stringify(ast),
|
||||
variableName,
|
||||
engineId
|
||||
)
|
||||
const updatedAst: Program = await modifyAstForSketch(
|
||||
engineCommandManager,
|
||||
ast,
|
||||
variableName,
|
||||
engineId
|
||||
)
|
||||
|
||||
updateAst(updatedAst, false)
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
updateAst(updatedAst, false)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value, VariableDeclarator } from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value, VariableDeclarator } from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value } from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import {
|
||||
BinaryPart,
|
||||
Value,
|
||||
VariableDeclarator,
|
||||
} from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { BinaryPart, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value } from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value } from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import {
|
||||
BinaryPart,
|
||||
Value,
|
||||
VariableDeclarator,
|
||||
} from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { BinaryPart, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import {
|
||||
BinaryPart,
|
||||
Value,
|
||||
VariableDeclarator,
|
||||
} from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { BinaryPart, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
@ -21,8 +17,6 @@ import { GetInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { createLiteral, createVariableDeclaration } from '../../lang/modifyAst'
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { updateCursors } from '../../lang/util'
|
||||
import { ActionIcon } from 'components/ActionIcon'
|
||||
import { sketchButtonClassnames } from 'Toolbar'
|
||||
|
||||
const getModalInfo = create(GetInfoModal as any)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value } from '../../lang/abstractSyntaxTreeTypes'
|
||||
import { Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { Popover, Transition } from '@headlessui/react'
|
||||
import { ActionButton } from './ActionButton'
|
||||
import { faBars, faGear, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
faBars,
|
||||
faBug,
|
||||
faGear,
|
||||
faSignOutAlt,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import { faGithub } from '@fortawesome/free-brands-svg-icons'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { Fragment, useState } from 'react'
|
||||
@ -137,13 +142,21 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
|
||||
Settings
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="link"
|
||||
Element="externalLink"
|
||||
to="https://github.com/KittyCAD/modeling-app/discussions"
|
||||
icon={{ icon: faGithub }}
|
||||
className="border-transparent dark:border-transparent dark:hover:border-liquid-60"
|
||||
>
|
||||
Request a feature
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://github.com/KittyCAD/modeling-app/issues/new"
|
||||
icon={{ icon: faBug }}
|
||||
className="border-transparent dark:border-transparent dark:hover:border-liquid-60"
|
||||
>
|
||||
Report a bug
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => send('Log out')}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { useLayoutEffect, useEffect, useRef } from 'react'
|
||||
import { _executor } from '../lang/executor'
|
||||
import { _executor } from '../lang/wasm'
|
||||
import { useStore } from '../useStore'
|
||||
import { engineCommandManager } from '../lang/std/engineConnection'
|
||||
import { deferExecution } from 'lib/utils'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
export function useSetupEngineManager(
|
||||
streamRef: React.RefObject<HTMLDivElement>,
|
||||
@ -12,14 +13,14 @@ export function useSetupEngineManager(
|
||||
setMediaStream,
|
||||
setIsStreamReady,
|
||||
setStreamDimensions,
|
||||
executeCode,
|
||||
streamDimensions,
|
||||
executeCode,
|
||||
} = useStore((s) => ({
|
||||
setMediaStream: s.setMediaStream,
|
||||
setIsStreamReady: s.setIsStreamReady,
|
||||
setStreamDimensions: s.setStreamDimensions,
|
||||
executeCode: s.executeCode,
|
||||
streamDimensions: s.streamDimensions,
|
||||
executeCode: s.executeCode,
|
||||
}))
|
||||
|
||||
const streamWidth = streamRef?.current?.offsetWidth
|
||||
@ -40,11 +41,9 @@ export function useSetupEngineManager(
|
||||
setIsStreamReady,
|
||||
width: quadWidth,
|
||||
height: quadHeight,
|
||||
executeCode,
|
||||
token,
|
||||
})
|
||||
engineCommandManager.waitForReady.then(() => {
|
||||
executeCode()
|
||||
})
|
||||
setStreamDimensions({
|
||||
streamWidth: quadWidth,
|
||||
streamHeight: quadHeight,
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { KCLError } from './errors'
|
||||
import { initPromise } from './rust'
|
||||
import { initPromise, parse } from './wasm'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
describe('testing AST', () => {
|
||||
test('5 + 6', () => {
|
||||
const result = parser_wasm('5 +6')
|
||||
const result = parse('5 +6')
|
||||
delete (result as any).nonCodeMeta
|
||||
expect(result.body).toEqual([
|
||||
{
|
||||
@ -37,7 +36,7 @@ describe('testing AST', () => {
|
||||
])
|
||||
})
|
||||
test('const myVar = 5', () => {
|
||||
const { body } = parser_wasm('const myVar = 5')
|
||||
const { body } = parse('const myVar = 5')
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -71,7 +70,7 @@ describe('testing AST', () => {
|
||||
const code = `const myVar = 5
|
||||
const newVar = myVar + 1
|
||||
`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -143,7 +142,7 @@ const newVar = myVar + 1
|
||||
|
||||
describe('testing function declaration', () => {
|
||||
test('fn funcN = () => {}', () => {
|
||||
const { body } = parser_wasm('fn funcN = () => {}')
|
||||
const { body } = parse('fn funcN = () => {}')
|
||||
delete (body[0] as any).declarations[0].init.body.nonCodeMeta
|
||||
expect(body).toEqual([
|
||||
{
|
||||
@ -179,7 +178,7 @@ describe('testing function declaration', () => {
|
||||
])
|
||||
})
|
||||
test('fn funcN = (a, b) => {return a + b}', () => {
|
||||
const { body } = parser_wasm(
|
||||
const { body } = parse(
|
||||
['fn funcN = (a, b) => {', ' return a + b', '}'].join('\n')
|
||||
)
|
||||
delete (body[0] as any).declarations[0].init.body.nonCodeMeta
|
||||
@ -256,7 +255,7 @@ describe('testing function declaration', () => {
|
||||
test('call expression assignment', () => {
|
||||
const code = `fn funcN = (a, b) => { return a + b }
|
||||
const myVar = funcN(1, 2)`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
delete (body[0] as any).declarations[0].init.body.nonCodeMeta
|
||||
expect(body).toEqual([
|
||||
{
|
||||
@ -388,7 +387,7 @@ describe('testing pipe operator special', () => {
|
||||
|> lineTo([1, 1], %)
|
||||
|> rx(45, %)
|
||||
`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
delete (body[0] as any).declarations[0].init.nonCodeMeta
|
||||
expect(body).toEqual([
|
||||
{
|
||||
@ -404,7 +403,7 @@ describe('testing pipe operator special', () => {
|
||||
id: { type: 'Identifier', start: 6, end: 14, name: 'mySketch' },
|
||||
init: {
|
||||
type: 'PipeExpression',
|
||||
start: 15,
|
||||
start: 17,
|
||||
end: 145,
|
||||
body: [
|
||||
{
|
||||
@ -624,7 +623,7 @@ describe('testing pipe operator special', () => {
|
||||
})
|
||||
test('pipe operator with binary expression', () => {
|
||||
let code = `const myVar = 5 + 6 |> myFunc(45, %)`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
delete (body as any)[0].declarations[0].init.nonCodeMeta
|
||||
expect(body).toEqual([
|
||||
{
|
||||
@ -645,7 +644,7 @@ describe('testing pipe operator special', () => {
|
||||
},
|
||||
init: {
|
||||
type: 'PipeExpression',
|
||||
start: 12,
|
||||
start: 14,
|
||||
end: 36,
|
||||
body: [
|
||||
{
|
||||
@ -706,7 +705,7 @@ describe('testing pipe operator special', () => {
|
||||
})
|
||||
test('array expression', () => {
|
||||
let code = `const yo = [1, '2', three, 4 + 5]`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -781,7 +780,7 @@ describe('testing pipe operator special', () => {
|
||||
'const three = 3',
|
||||
"const yo = {aStr: 'str', anum: 2, identifier: three, binExp: 4 + 5}",
|
||||
].join('\n')
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -925,7 +924,7 @@ describe('testing pipe operator special', () => {
|
||||
const code = `const yo = {key: {
|
||||
key2: 'value'
|
||||
}}`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -993,7 +992,7 @@ describe('testing pipe operator special', () => {
|
||||
})
|
||||
test('object expression with array ast', () => {
|
||||
const code = `const yo = {key: [1, '2']}`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -1057,7 +1056,7 @@ describe('testing pipe operator special', () => {
|
||||
})
|
||||
test('object memberExpression simple', () => {
|
||||
const code = `const prop = yo.one.two`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -1112,7 +1111,7 @@ describe('testing pipe operator special', () => {
|
||||
})
|
||||
test('object memberExpression with square braces', () => {
|
||||
const code = `const prop = yo.one["two"]`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -1168,7 +1167,7 @@ describe('testing pipe operator special', () => {
|
||||
})
|
||||
test('object memberExpression with two square braces literal and identifier', () => {
|
||||
const code = `const prop = yo["one"][two]`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body).toEqual([
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
@ -1227,7 +1226,7 @@ describe('testing pipe operator special', () => {
|
||||
describe('nests binary expressions correctly', () => {
|
||||
it('works with the simple case', () => {
|
||||
const code = `const yo = 1 + 2`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body[0]).toEqual({
|
||||
type: 'VariableDeclaration',
|
||||
start: 0,
|
||||
@ -1271,7 +1270,7 @@ describe('nests binary expressions correctly', () => {
|
||||
it('should nest according to precedence with multiply first', () => {
|
||||
// should be binExp { binExp { lit-1 * lit-2 } + lit}
|
||||
const code = `const yo = 1 * 2 + 3`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body[0]).toEqual({
|
||||
type: 'VariableDeclaration',
|
||||
start: 0,
|
||||
@ -1328,7 +1327,7 @@ describe('nests binary expressions correctly', () => {
|
||||
it('should nest according to precedence with sum first', () => {
|
||||
// should be binExp { lit-1 + binExp { lit-2 * lit-3 } }
|
||||
const code = `const yo = 1 + 2 * 3`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect(body[0]).toEqual({
|
||||
type: 'VariableDeclaration',
|
||||
start: 0,
|
||||
@ -1384,7 +1383,7 @@ describe('nests binary expressions correctly', () => {
|
||||
})
|
||||
it('should nest properly with two opperators of equal precedence', () => {
|
||||
const code = `const yo = 1 + 2 - 3`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect((body[0] as any).declarations[0].init).toEqual({
|
||||
type: 'BinaryExpression',
|
||||
start: 11,
|
||||
@ -1421,7 +1420,7 @@ describe('nests binary expressions correctly', () => {
|
||||
})
|
||||
it('should nest properly with two opperators of equal (but higher) precedence', () => {
|
||||
const code = `const yo = 1 * 2 / 3`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
expect((body[0] as any).declarations[0].init).toEqual({
|
||||
type: 'BinaryExpression',
|
||||
start: 11,
|
||||
@ -1458,7 +1457,7 @@ describe('nests binary expressions correctly', () => {
|
||||
})
|
||||
it('should nest properly with longer example', () => {
|
||||
const code = `const yo = 1 + 2 * (3 - 4) / 5 + 6`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
const init = (body[0] as any).declarations[0].init
|
||||
expect(init).toEqual({
|
||||
type: 'BinaryExpression',
|
||||
@ -1520,14 +1519,12 @@ const key = 'c'`
|
||||
value: 'this is a comment',
|
||||
},
|
||||
}
|
||||
const { nonCodeMeta } = parser_wasm(code)
|
||||
const { nonCodeMeta } = parse(code)
|
||||
expect(nonCodeMeta.nonCodeNodes[0]).toEqual(nonCodeMetaInstance)
|
||||
|
||||
// extra whitespace won't change it's position (0) or value (NB the start end would have changed though)
|
||||
const codeWithExtraStartWhitespace = '\n\n\n' + code
|
||||
const { nonCodeMeta: nonCodeMeta2 } = parser_wasm(
|
||||
codeWithExtraStartWhitespace
|
||||
)
|
||||
const { nonCodeMeta: nonCodeMeta2 } = parse(codeWithExtraStartWhitespace)
|
||||
expect(nonCodeMeta2.nonCodeNodes[0].value).toStrictEqual(
|
||||
nonCodeMetaInstance.value
|
||||
)
|
||||
@ -1545,7 +1542,7 @@ const key = 'c'`
|
||||
|> close(%)
|
||||
`
|
||||
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
const indexOfSecondLineToExpression = 2
|
||||
const sketchNonCodeMeta = (body as any)[0].declarations[0].init.nonCodeMeta
|
||||
.nonCodeNodes
|
||||
@ -1569,7 +1566,7 @@ const key = 'c'`
|
||||
' |> rx(90, %)',
|
||||
].join('\n')
|
||||
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
const sketchNonCodeMeta = (body[0] as any).declarations[0].init.nonCodeMeta
|
||||
.nonCodeNodes
|
||||
expect(sketchNonCodeMeta[3]).toEqual({
|
||||
@ -1587,7 +1584,7 @@ const key = 'c'`
|
||||
describe('test UnaryExpression', () => {
|
||||
it('should parse a unary expression in simple var dec situation', () => {
|
||||
const code = `const myVar = -min(4, 100)`
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
const myVarInit = (body?.[0] as any).declarations[0]?.init
|
||||
expect(myVarInit).toEqual({
|
||||
type: 'UnaryExpression',
|
||||
@ -1613,7 +1610,7 @@ describe('test UnaryExpression', () => {
|
||||
describe('testing nested call expressions', () => {
|
||||
it('callExp in a binExp in a callExp', () => {
|
||||
const code = 'const myVar = min(100, 1 + legLen(5, 3))'
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
const myVarInit = (body?.[0] as any).declarations[0]?.init
|
||||
expect(myVarInit).toEqual({
|
||||
type: 'CallExpression',
|
||||
@ -1651,7 +1648,7 @@ describe('testing nested call expressions', () => {
|
||||
describe('should recognise callExpresions in binaryExpressions', () => {
|
||||
const code = "xLineTo(segEndX('seg02', %) + 1, %)"
|
||||
it('should recognise the callExp', () => {
|
||||
const { body } = parser_wasm(code)
|
||||
const { body } = parse(code)
|
||||
const callExpArgs = (body?.[0] as any).expression?.arguments
|
||||
expect(callExpArgs).toEqual([
|
||||
{
|
||||
@ -1690,7 +1687,7 @@ describe('parsing errors', () => {
|
||||
|
||||
let _theError
|
||||
try {
|
||||
const result = expect(parser_wasm(code))
|
||||
const result = expect(parse(code))
|
||||
} catch (e) {
|
||||
_theError = e
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
import { Program } from './abstractSyntaxTreeTypes'
|
||||
import { parse_js } from '../wasm-lib/pkg/wasm_lib'
|
||||
import { initPromise } from './rust'
|
||||
import { Token } from './tokeniser'
|
||||
import { KCLError } from './errors'
|
||||
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||
|
||||
export const rangeTypeFix = (ranges: number[][]): [number, number][] =>
|
||||
ranges.map(([start, end]) => [start, end])
|
||||
|
||||
export const parser_wasm = (code: string): Program => {
|
||||
try {
|
||||
const program: Program = parse_js(code)
|
||||
return program
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
}
|
||||
|
||||
export async function asyncParser(code: string): Promise<Program> {
|
||||
await initPromise
|
||||
try {
|
||||
const program: Program = parse_js(code)
|
||||
return program
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
}
|
||||
|
||||
export function rangeOfToken(token: Token | undefined): [number, number][] {
|
||||
return token === undefined ? [] : [[token.start, token.end]]
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
export type { Program } from '../wasm-lib/kcl/bindings/Program'
|
||||
export type { Value } from '../wasm-lib/kcl/bindings/Value'
|
||||
export type { ObjectExpression } from '../wasm-lib/kcl/bindings/ObjectExpression'
|
||||
export type { MemberExpression } from '../wasm-lib/kcl/bindings/MemberExpression'
|
||||
export type { PipeExpression } from '../wasm-lib/kcl/bindings/PipeExpression'
|
||||
export type { VariableDeclaration } from '../wasm-lib/kcl/bindings/VariableDeclaration'
|
||||
export type { PipeSubstitution } from '../wasm-lib/kcl/bindings/PipeSubstitution'
|
||||
export type { Identifier } from '../wasm-lib/kcl/bindings/Identifier'
|
||||
export type { UnaryExpression } from '../wasm-lib/kcl/bindings/UnaryExpression'
|
||||
export type { BinaryExpression } from '../wasm-lib/kcl/bindings/BinaryExpression'
|
||||
export type { ReturnStatement } from '../wasm-lib/kcl/bindings/ReturnStatement'
|
||||
export type { ExpressionStatement } from '../wasm-lib/kcl/bindings/ExpressionStatement'
|
||||
export type { CallExpression } from '../wasm-lib/kcl/bindings/CallExpression'
|
||||
export type { VariableDeclarator } from '../wasm-lib/kcl/bindings/VariableDeclarator'
|
||||
export type { BinaryPart } from '../wasm-lib/kcl/bindings/BinaryPart'
|
||||
export type { Literal } from '../wasm-lib/kcl/bindings/Literal'
|
||||
export type { ArrayExpression } from '../wasm-lib/kcl/bindings/ArrayExpression'
|
||||
|
||||
export type SyntaxType =
|
||||
| 'Program'
|
||||
| 'ExpressionStatement'
|
||||
| 'BinaryExpression'
|
||||
| 'CallExpression'
|
||||
| 'Identifier'
|
||||
| 'ReturnStatement'
|
||||
| 'VariableDeclaration'
|
||||
| 'VariableDeclarator'
|
||||
| 'MemberExpression'
|
||||
| 'ArrayExpression'
|
||||
| 'ObjectExpression'
|
||||
| 'ObjectProperty'
|
||||
| 'FunctionExpression'
|
||||
| 'PipeExpression'
|
||||
| 'PipeSubstitution'
|
||||
| 'Literal'
|
||||
| 'NonCodeNode'
|
||||
| 'UnaryExpression'
|
@ -1,5 +1,4 @@
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { initPromise } from './rust'
|
||||
import { parse, initPromise } from './wasm'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
@ -13,7 +12,7 @@ const mySketch001 = startSketchAt([0, 0])
|
||||
|> lineTo([0.46, -5.82], %)
|
||||
// |> rx(45, %)
|
||||
show(mySketch001)`
|
||||
const programMemory = await enginelessExecutor(parser_wasm(code))
|
||||
const programMemory = await enginelessExecutor(parse(code))
|
||||
// @ts-ignore
|
||||
const shown = programMemory?.return?.map(
|
||||
// @ts-ignore
|
||||
@ -69,7 +68,7 @@ const mySketch001 = startSketchAt([0, 0])
|
||||
// |> rx(45, %)
|
||||
|> extrude(2, %)
|
||||
show(mySketch001)`
|
||||
const programMemory = await enginelessExecutor(parser_wasm(code))
|
||||
const programMemory = await enginelessExecutor(parse(code))
|
||||
// @ts-ignore
|
||||
const shown = programMemory?.return?.map(
|
||||
// @ts-ignore
|
||||
@ -109,7 +108,7 @@ const sk2 = startSketchAt([0, 0])
|
||||
|
||||
|
||||
show(theExtrude, sk2)`
|
||||
const programMemory = await enginelessExecutor(parser_wasm(code))
|
||||
const programMemory = await enginelessExecutor(parse(code))
|
||||
// @ts-ignore
|
||||
const geos = programMemory?.return?.map(
|
||||
// @ts-ignore
|
||||
|
@ -1,10 +1,7 @@
|
||||
import fs from 'node:fs'
|
||||
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { ProgramMemory, SketchGroup } from './executor'
|
||||
import { initPromise } from './rust'
|
||||
import { parse, ProgramMemory, SketchGroup, initPromise } from './wasm'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
import { vi } from 'vitest'
|
||||
import { KCLError } from './errors'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
@ -403,7 +400,7 @@ async function exe(
|
||||
code: string,
|
||||
programMemory: ProgramMemory = { root: {}, return: null }
|
||||
) {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
|
||||
const result = await enginelessExecutor(ast, programMemory)
|
||||
return result
|
||||
|
@ -1,81 +0,0 @@
|
||||
import { Program } from './abstractSyntaxTreeTypes'
|
||||
import {
|
||||
EngineCommandManager,
|
||||
ArtifactMap,
|
||||
SourceRangeMap,
|
||||
} from './std/engineConnection'
|
||||
import { ProgramReturn } from '../wasm-lib/kcl/bindings/ProgramReturn'
|
||||
import { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
||||
import { execute_wasm } from '../wasm-lib/pkg/wasm_lib'
|
||||
import { KCLError } from './errors'
|
||||
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||
import { rangeTypeFix } from './abstractSyntaxTree'
|
||||
|
||||
export type { SourceRange } from '../wasm-lib/kcl/bindings/SourceRange'
|
||||
export type { Position } from '../wasm-lib/kcl/bindings/Position'
|
||||
export type { Rotation } from '../wasm-lib/kcl/bindings/Rotation'
|
||||
export type { Path } from '../wasm-lib/kcl/bindings/Path'
|
||||
export type { SketchGroup } from '../wasm-lib/kcl/bindings/SketchGroup'
|
||||
export type { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
||||
export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface'
|
||||
|
||||
export type PathToNode = [string | number, string][]
|
||||
|
||||
interface Memory {
|
||||
[key: string]: MemoryItem
|
||||
}
|
||||
|
||||
export interface ProgramMemory {
|
||||
root: Memory
|
||||
return: ProgramReturn | null
|
||||
}
|
||||
|
||||
export const executor = async (
|
||||
node: Program,
|
||||
programMemory: ProgramMemory = { root: {}, return: null },
|
||||
engineCommandManager: EngineCommandManager,
|
||||
// work around while the gemotry is still be stored on the frontend
|
||||
// will be removed when the stream UI is added.
|
||||
tempMapCallback: (a: {
|
||||
artifactMap: ArtifactMap
|
||||
sourceRangeMap: SourceRangeMap
|
||||
}) => void = () => {}
|
||||
): Promise<ProgramMemory> => {
|
||||
engineCommandManager.startNewSession()
|
||||
const _programMemory = await _executor(
|
||||
node,
|
||||
programMemory,
|
||||
engineCommandManager
|
||||
)
|
||||
const { artifactMap, sourceRangeMap } =
|
||||
await engineCommandManager.waitForAllCommands(node, _programMemory)
|
||||
tempMapCallback({ artifactMap, sourceRangeMap })
|
||||
|
||||
engineCommandManager.endSession()
|
||||
return _programMemory
|
||||
}
|
||||
|
||||
export const _executor = async (
|
||||
node: Program,
|
||||
programMemory: ProgramMemory = { root: {}, return: null },
|
||||
engineCommandManager: EngineCommandManager
|
||||
): Promise<ProgramMemory> => {
|
||||
try {
|
||||
const memory: ProgramMemory = await execute_wasm(
|
||||
JSON.stringify(node),
|
||||
JSON.stringify(programMemory),
|
||||
engineCommandManager
|
||||
)
|
||||
return memory
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
import { getNodePathFromSourceRange, getNodeFromPath } from './queryAst'
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { initPromise } from './rust'
|
||||
import { Identifier } from './abstractSyntaxTreeTypes'
|
||||
import { Identifier, parse, initPromise } from './wasm'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -21,7 +19,7 @@ const sk3 = startSketchAt([0, 0])
|
||||
lineToSubstringIndex + subStr.length,
|
||||
]
|
||||
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const nodePath = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const { node } = getNodeFromPath<any>(ast, nodePath)
|
||||
|
||||
@ -46,7 +44,7 @@ const b1 = cube([0,0], 10)`
|
||||
subStrIndex + 'pos'.length,
|
||||
]
|
||||
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const nodePath = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const node = getNodeFromPath<Identifier>(ast, nodePath).node
|
||||
|
||||
@ -80,7 +78,7 @@ const b1 = cube([0,0], 10)`
|
||||
subStrIndex + 'scale'.length,
|
||||
]
|
||||
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const nodePath = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const node = getNodeFromPath<Identifier>(ast, nodePath).node
|
||||
expect(nodePath).toEqual([
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { parse, recast, initPromise } from './wasm'
|
||||
import {
|
||||
createLiteral,
|
||||
createIdentifier,
|
||||
@ -13,8 +13,6 @@ import {
|
||||
giveSketchFnCallTag,
|
||||
moveValueIntoNewVariable,
|
||||
} from './modifyAst'
|
||||
import { recast } from './recast'
|
||||
import { initPromise } from './rust'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
@ -126,7 +124,7 @@ function giveSketchFnCallTagTestHelper(
|
||||
// giveSketchFnCallTag inputs and outputs an ast, which is very verbose for testing
|
||||
// this wrapper changes the input and output to code
|
||||
// making it more of an integration test, but easier to read the test intention is the goal
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const start = code.indexOf(searchStr)
|
||||
const range: [number, number] = [start, start + searchStr.length]
|
||||
const { modifiedAst, tag, isTagExisting } = giveSketchFnCallTag(ast, range)
|
||||
@ -197,7 +195,7 @@ const part001 = startSketchAt([-1.2, 4.83])
|
||||
const yo2 = hmm([identifierGuy + 5])
|
||||
show(part001)`
|
||||
it('should move a binary expression into a new variable', async () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const startIndex = code.indexOf('100 + 100') + 1
|
||||
const { modifiedAst } = moveValueIntoNewVariable(
|
||||
@ -211,7 +209,7 @@ show(part001)`
|
||||
expect(newCode).toContain(`angledLine([newVar, 3.09], %)`)
|
||||
})
|
||||
it('should move a value into a new variable', async () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const startIndex = code.indexOf('2.8') + 1
|
||||
const { modifiedAst } = moveValueIntoNewVariable(
|
||||
@ -225,7 +223,7 @@ show(part001)`
|
||||
expect(newCode).toContain(`line([newVar, 0], %)`)
|
||||
})
|
||||
it('should move a callExpression into a new variable', async () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const startIndex = code.indexOf('def(')
|
||||
const { modifiedAst } = moveValueIntoNewVariable(
|
||||
@ -239,7 +237,7 @@ show(part001)`
|
||||
expect(newCode).toContain(`angledLine([newVar, 3.09], %)`)
|
||||
})
|
||||
it('should move a binary expression with call expression into a new variable', async () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const startIndex = code.indexOf('jkl(') + 1
|
||||
const { modifiedAst } = moveValueIntoNewVariable(
|
||||
@ -253,7 +251,7 @@ show(part001)`
|
||||
expect(newCode).toContain(`angledLine([newVar, 3.09], %)`)
|
||||
})
|
||||
it('should move a identifier into a new variable', async () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const startIndex = code.indexOf('identifierGuy +') + 1
|
||||
const { modifiedAst } = moveValueIntoNewVariable(
|
||||
|
@ -14,14 +14,15 @@ import {
|
||||
ObjectExpression,
|
||||
UnaryExpression,
|
||||
BinaryExpression,
|
||||
} from './abstractSyntaxTreeTypes'
|
||||
PathToNode,
|
||||
ProgramMemory,
|
||||
} from './wasm'
|
||||
import {
|
||||
findAllPreviousVariables,
|
||||
getNodeFromPath,
|
||||
getNodePathFromSourceRange,
|
||||
isNodeSafeToReplace,
|
||||
} from './queryAst'
|
||||
import { PathToNode, ProgramMemory } from './executor'
|
||||
import {
|
||||
addTagForSketchOnFace,
|
||||
getFirstArg,
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { parse, recast, initPromise } from './wasm'
|
||||
import {
|
||||
findAllPreviousVariables,
|
||||
isNodeSafeToReplace,
|
||||
isTypeInValue,
|
||||
getNodePathFromSourceRange,
|
||||
} from './queryAst'
|
||||
import { initPromise } from './rust'
|
||||
import { enginelessExecutor } from '../lib/testHelpers'
|
||||
import {
|
||||
createArrayExpression,
|
||||
@ -13,7 +12,6 @@ import {
|
||||
createLiteral,
|
||||
createPipeSubstitution,
|
||||
} from './modifyAst'
|
||||
import { recast } from './recast'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -36,7 +34,7 @@ const variableBelowShouldNotBeIncluded = 3
|
||||
|
||||
show(part001)`
|
||||
const rangeStart = code.indexOf('// selection-range-7ish-before-this') - 7
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
|
||||
const { variables, bodyPath, insertIndex } = findAllPreviousVariables(
|
||||
@ -70,7 +68,7 @@ const yo = 5 + 6
|
||||
const yo2 = hmm([identifierGuy + 5])
|
||||
show(part001)`
|
||||
it('find a safe binaryExpression', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('100 + 100') + 2
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(true)
|
||||
@ -84,7 +82,7 @@ show(part001)`
|
||||
expect(outCode).toContain(`angledLine([replaceName, 3.09], %)`)
|
||||
})
|
||||
it('find a safe Identifier', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('abc')
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(true)
|
||||
@ -92,7 +90,7 @@ show(part001)`
|
||||
expect(code.slice(result.value.start, result.value.end)).toBe('abc')
|
||||
})
|
||||
it('find a safe CallExpression', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('def')
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(true)
|
||||
@ -106,7 +104,7 @@ show(part001)`
|
||||
expect(outCode).toContain(`angledLine([replaceName, 3.09], %)`)
|
||||
})
|
||||
it('find an UNsafe CallExpression, as it has a PipeSubstitution', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('ghi')
|
||||
const range: [number, number] = [rangeStart, rangeStart]
|
||||
const result = isNodeSafeToReplace(ast, range)
|
||||
@ -115,7 +113,7 @@ show(part001)`
|
||||
expect(code.slice(result.value.start, result.value.end)).toBe('ghi(%)')
|
||||
})
|
||||
it('find an UNsafe Identifier, as it is a callee', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('ine([2.8,')
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(false)
|
||||
@ -125,7 +123,7 @@ show(part001)`
|
||||
)
|
||||
})
|
||||
it("find a safe BinaryExpression that's assigned to a variable", () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('5 + 6') + 1
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(true)
|
||||
@ -139,7 +137,7 @@ show(part001)`
|
||||
expect(outCode).toContain(`const yo = replaceName`)
|
||||
})
|
||||
it('find a safe BinaryExpression that has a CallExpression within', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('jkl') + 1
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(true)
|
||||
@ -155,7 +153,7 @@ show(part001)`
|
||||
expect(outCode).toContain(`angledLine([replaceName, 3.09], %)`)
|
||||
})
|
||||
it('find a safe BinaryExpression within a CallExpression', () => {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const rangeStart = code.indexOf('identifierGuy') + 1
|
||||
const result = isNodeSafeToReplace(ast, [rangeStart, rangeStart])
|
||||
expect(result.isSafe).toBe(true)
|
||||
@ -203,7 +201,7 @@ show(part001)`
|
||||
it('finds the second line when cursor is put at the end', () => {
|
||||
const searchLn = `line([0.94, 2.61], %)`
|
||||
const sourceIndex = code.indexOf(searchLn) + searchLn.length
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const result = getNodePathFromSourceRange(ast, [sourceIndex, sourceIndex])
|
||||
expect(result).toEqual([
|
||||
['body', ''],
|
||||
@ -218,7 +216,7 @@ show(part001)`
|
||||
it('finds the last line when cursor is put at the end', () => {
|
||||
const searchLn = `line([-0.21, -1.4], %)`
|
||||
const sourceIndex = code.indexOf(searchLn) + searchLn.length
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const result = getNodePathFromSourceRange(ast, [sourceIndex, sourceIndex])
|
||||
const expected = [
|
||||
['body', ''],
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { PathToNode, ProgramMemory, SketchGroup, SourceRange } from './executor'
|
||||
import { Selection, ToolTip } from '../useStore'
|
||||
import {
|
||||
BinaryExpression,
|
||||
@ -10,7 +9,11 @@ import {
|
||||
VariableDeclaration,
|
||||
ReturnStatement,
|
||||
ArrayExpression,
|
||||
} from './abstractSyntaxTreeTypes'
|
||||
PathToNode,
|
||||
ProgramMemory,
|
||||
SketchGroup,
|
||||
SourceRange,
|
||||
} from './wasm'
|
||||
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
|
||||
import { getSketchSegmentFromSourceRange } from './std/sketchConstraints'
|
||||
import { getAngle } from '../lib/utils'
|
||||
|
@ -1,8 +1,5 @@
|
||||
import { recast } from './recast'
|
||||
import { parser_wasm } from './abstractSyntaxTree'
|
||||
import { Program } from './abstractSyntaxTreeTypes'
|
||||
import { parse, Program, recast, initPromise } from './wasm'
|
||||
import fs from 'node:fs'
|
||||
import { initPromise } from './rust'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -366,6 +363,6 @@ describe('it recasts binary expression using brackets where needed', () => {
|
||||
// helpers
|
||||
|
||||
function code2ast(code: string): { ast: Program } {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
return { ast }
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { Program } from './abstractSyntaxTreeTypes'
|
||||
import { recast_wasm } from '../wasm-lib/pkg/wasm_lib'
|
||||
|
||||
export const recast = (ast: Program): string => {
|
||||
try {
|
||||
const s: string = recast_wasm(JSON.stringify(ast))
|
||||
return s
|
||||
} catch (e) {
|
||||
// TODO: do something real with the error.
|
||||
console.log('recast error', e)
|
||||
throw e
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import init from '../wasm-lib/pkg/wasm_lib'
|
||||
|
||||
const initialise = async () => {
|
||||
const baseUrl =
|
||||
typeof window === 'undefined'
|
||||
? 'http://127.0.0.1:3000'
|
||||
: window.location.origin.includes('tauri://localhost')
|
||||
? 'tauri://localhost'
|
||||
: window.location.origin.includes('localhost')
|
||||
? 'http://localhost:3000'
|
||||
: window.location.origin && window.location.origin !== 'null'
|
||||
? window.location.origin
|
||||
: 'http://localhost:3000'
|
||||
const fullUrl = baseUrl + '/wasm_lib_bg.wasm'
|
||||
const input = await fetch(fullUrl)
|
||||
const buffer = await input.arrayBuffer()
|
||||
return init(buffer)
|
||||
}
|
||||
|
||||
export const initPromise = initialise()
|
@ -1,4 +1,9 @@
|
||||
import { ProgramMemory, SourceRange } from 'lang/executor'
|
||||
import {
|
||||
ProgramMemory,
|
||||
SourceRange,
|
||||
Program,
|
||||
VariableDeclarator,
|
||||
} from 'lang/wasm'
|
||||
import { Selections } from 'useStore'
|
||||
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_CONNECTION_TIMEOUT_MS } from 'env'
|
||||
import { Models } from '@kittycad/lib'
|
||||
@ -6,7 +11,6 @@ import { exportSave } from 'lib/exportSave'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import * as Sentry from '@sentry/react'
|
||||
import { getNodeFromPath, getNodePathFromSourceRange } from 'lang/queryAst'
|
||||
import { Program, VariableDeclarator } from 'lang/abstractSyntaxTreeTypes'
|
||||
|
||||
let lastMessage = ''
|
||||
|
||||
@ -356,6 +360,11 @@ export class EngineConnection {
|
||||
if (this.shouldTrace()) {
|
||||
iceSpan.resolve?.()
|
||||
}
|
||||
} else if (this.pc?.iceConnectionState === 'failed') {
|
||||
// failed is a terminal state; let's explicitly kill the
|
||||
// connection to the server at this point.
|
||||
console.log('failed to negotiate ice connection; restarting')
|
||||
this.close()
|
||||
}
|
||||
})
|
||||
|
||||
@ -487,9 +496,11 @@ export class EngineConnection {
|
||||
|
||||
this.onDataChannelOpen(this)
|
||||
|
||||
this.onEngineConnectionOpen(this)
|
||||
this.ready = true
|
||||
this.connecting = false
|
||||
// Do this after we set the connection is ready to avoid errors when
|
||||
// we try to send messages before the connection is ready.
|
||||
this.onEngineConnectionOpen(this)
|
||||
})
|
||||
|
||||
this.unreliableDataChannel.addEventListener('close', (event) => {
|
||||
@ -582,6 +593,9 @@ export class EngineCommandManager {
|
||||
outSequence = 1
|
||||
inSequence = 1
|
||||
engineConnection?: EngineConnection
|
||||
// Folks should realize that wait for ready does not get called _everytime_
|
||||
// the connection resets and restarts, it only gets called the first time.
|
||||
// Be careful what you put here.
|
||||
waitForReady: Promise<void> = new Promise(() => {})
|
||||
private resolveReady = () => {}
|
||||
|
||||
@ -605,12 +619,14 @@ export class EngineCommandManager {
|
||||
setIsStreamReady,
|
||||
width,
|
||||
height,
|
||||
executeCode,
|
||||
token,
|
||||
}: {
|
||||
setMediaStream: (stream: MediaStream) => void
|
||||
setIsStreamReady: (isStreamReady: boolean) => void
|
||||
width: number
|
||||
height: number
|
||||
executeCode: (code?: string, force?: boolean) => void
|
||||
token?: string
|
||||
}) {
|
||||
if (width === 0 || height === 0) {
|
||||
@ -633,6 +649,32 @@ export class EngineCommandManager {
|
||||
onEngineConnectionOpen: () => {
|
||||
this.resolveReady()
|
||||
setIsStreamReady(true)
|
||||
|
||||
// Make the axis gizmo.
|
||||
// We do this after the connection opened to avoid a race condition.
|
||||
// Connected opened is the last thing that happens when the stream
|
||||
// is ready.
|
||||
// We also do this here because we want to ensure we create the gizmo
|
||||
// and execute the code everytime the stream is restarted.
|
||||
const gizmoId = uuidv4()
|
||||
this.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd_id: gizmoId,
|
||||
cmd: {
|
||||
type: 'make_axes_gizmo',
|
||||
clobber: false,
|
||||
// If true, axes gizmo will be placed in the corner of the screen.
|
||||
// If false, it will be placed at the origin of the scene.
|
||||
gizmo_mode: true,
|
||||
},
|
||||
})
|
||||
|
||||
// We execute the code here to make sure if the stream was to
|
||||
// restart in a session, we want to make sure to execute the code.
|
||||
// We force it to re-execute the code because we want to make sure
|
||||
// the code is executed everytime the stream is restarted.
|
||||
// We pass undefined for the code so it reads from the current state.
|
||||
executeCode(undefined, true)
|
||||
},
|
||||
onClose: () => {
|
||||
setIsStreamReady(false)
|
||||
@ -729,10 +771,6 @@ export class EngineCommandManager {
|
||||
this.engineConnection?.send(resizeCmd)
|
||||
}
|
||||
handleModelingCommand(message: WebSocketResponse, id: string) {
|
||||
if (this.engineConnection === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (message.type !== 'modeling') {
|
||||
return
|
||||
}
|
||||
@ -900,6 +938,11 @@ export class EngineCommandManager {
|
||||
if (this.engineConnection === undefined) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
if (!this.engineConnection?.isReady()) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
if (
|
||||
command.type === 'modeling_cmd_req' &&
|
||||
command.cmd.type !== lastMessage
|
||||
@ -907,9 +950,6 @@ export class EngineCommandManager {
|
||||
console.log('sending command', command.cmd.type)
|
||||
lastMessage = command.cmd.type
|
||||
}
|
||||
if (!this.engineConnection?.isReady()) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
if (command.type !== 'modeling_cmd_req') return Promise.resolve()
|
||||
const cmd = command.cmd
|
||||
if (
|
||||
|
@ -6,13 +6,9 @@ import {
|
||||
getXComponent,
|
||||
addCloseToPipe,
|
||||
} from './sketch'
|
||||
import { parser_wasm } from '../abstractSyntaxTree'
|
||||
import { parse, recast, initPromise } from '../wasm'
|
||||
import { getNodePathFromSourceRange } from '../queryAst'
|
||||
import { recast } from '../recast'
|
||||
import { enginelessExecutor } from '../../lib/testHelpers'
|
||||
import { initPromise } from '../rust'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
const eachQuad: [number, [number, number]][] = [
|
||||
[-315, [1, 1]],
|
||||
@ -29,6 +25,8 @@ const eachQuad: [number, [number, number]][] = [
|
||||
[675, [1, -1]],
|
||||
]
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
describe('testing getYComponent', () => {
|
||||
it('should return the vertical component of a vector correctly when given angles in each quadrant (and with angles < 0, or > 360)', () => {
|
||||
const expected: [number, number][] = []
|
||||
@ -106,7 +104,7 @@ show(mySketch001)
|
||||
`
|
||||
const code = genCode(lineToChange)
|
||||
const expectedCode = genCode(lineAfterChange)
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const sourceStart = code.indexOf(lineToChange)
|
||||
const { modifiedAst } = changeSketchArguments(
|
||||
@ -144,7 +142,7 @@ const mySketch001 = startSketchAt([0, 0])
|
||||
|> lineTo([-1.59, -1.54], %)
|
||||
|> lineTo([0.46, -5.82], %)
|
||||
show(mySketch001)`
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const sourceStart = code.indexOf(lineToChange)
|
||||
expect(sourceStart).toBe(66)
|
||||
@ -205,7 +203,7 @@ describe('testing addTagForSketchOnFace', () => {
|
||||
show(mySketch001)
|
||||
`
|
||||
const code = genCode(originalLine)
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const sourceStart = code.indexOf(originalLine)
|
||||
const sourceRange: [number, number] = [
|
||||
|
@ -4,9 +4,6 @@ import {
|
||||
SketchGroup,
|
||||
SourceRange,
|
||||
PathToNode,
|
||||
MemoryItem,
|
||||
} from '../executor'
|
||||
import {
|
||||
Program,
|
||||
PipeExpression,
|
||||
CallExpression,
|
||||
@ -14,7 +11,7 @@ import {
|
||||
Value,
|
||||
Literal,
|
||||
VariableDeclaration,
|
||||
} from '../abstractSyntaxTreeTypes'
|
||||
} from '../wasm'
|
||||
import {
|
||||
getNodeFromPath,
|
||||
getNodeFromPathCurry,
|
||||
@ -38,7 +35,6 @@ import {
|
||||
findUniqueName,
|
||||
} from '../modifyAst'
|
||||
import { roundOff, getLength, getAngle } from '../../lib/utils'
|
||||
import { getSketchSegmentFromSourceRange } from './sketchConstraints'
|
||||
import { perpendicularDistance } from 'sketch-helpers'
|
||||
|
||||
export type Coords2d = [number, number]
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { parser_wasm } from '../abstractSyntaxTree'
|
||||
import { SketchGroup } from '../executor'
|
||||
import { parse, SketchGroup, recast, initPromise } from '../wasm'
|
||||
import {
|
||||
ConstraintType,
|
||||
getTransformInfos,
|
||||
transformAstSketchLines,
|
||||
} from './sketchcombos'
|
||||
import { recast } from '../recast'
|
||||
import { initPromise } from '../rust'
|
||||
import { getSketchSegmentFromSourceRange } from './sketchConstraints'
|
||||
import { Selection } from '../../useStore'
|
||||
import { enginelessExecutor } from '../../lib/testHelpers'
|
||||
@ -31,7 +28,7 @@ async function testingSwapSketchFnCall({
|
||||
type: 'default',
|
||||
range: [startIndex, startIndex + callToSwap.length],
|
||||
}
|
||||
const ast = parser_wasm(inputCode)
|
||||
const ast = parse(inputCode)
|
||||
const programMemory = await enginelessExecutor(ast)
|
||||
const selections = {
|
||||
codeBasedSelections: [range],
|
||||
@ -381,7 +378,7 @@ const part001 = startSketchAt([0, 0.04]) // segment-in-start
|
||||
|> xLine(3.54, %)
|
||||
show(part001)`
|
||||
it('normal case works', async () => {
|
||||
const programMemory = await enginelessExecutor(parser_wasm(code))
|
||||
const programMemory = await enginelessExecutor(parse(code))
|
||||
const index = code.indexOf('// normal-segment') - 7
|
||||
const { __geoMeta, ...segment } = getSketchSegmentFromSourceRange(
|
||||
programMemory.root['part001'] as SketchGroup,
|
||||
@ -395,7 +392,7 @@ show(part001)`
|
||||
})
|
||||
})
|
||||
it('verify it works when the segment is in the `start` property', async () => {
|
||||
const programMemory = await enginelessExecutor(parser_wasm(code))
|
||||
const programMemory = await enginelessExecutor(parse(code))
|
||||
const index = code.indexOf('// segment-in-start') - 7
|
||||
const { __geoMeta, ...segment } = getSketchSegmentFromSourceRange(
|
||||
programMemory.root['part001'] as SketchGroup,
|
||||
|
@ -3,8 +3,10 @@ import {
|
||||
Program,
|
||||
VariableDeclarator,
|
||||
CallExpression,
|
||||
} from '../abstractSyntaxTreeTypes'
|
||||
import { SketchGroup, SourceRange, Path } from '../executor'
|
||||
SketchGroup,
|
||||
SourceRange,
|
||||
Path,
|
||||
} from '../wasm'
|
||||
|
||||
export function getSketchSegmentFromSourceRange(
|
||||
sketchGroup: SketchGroup,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { parser_wasm } from '../abstractSyntaxTree'
|
||||
import { Value } from '../abstractSyntaxTreeTypes'
|
||||
import { parse, Value, recast, initPromise } from '../wasm'
|
||||
import {
|
||||
getConstraintType,
|
||||
getTransformInfos,
|
||||
@ -8,10 +7,8 @@ import {
|
||||
ConstraintType,
|
||||
getConstraintLevelFromSourceRange,
|
||||
} from './sketchcombos'
|
||||
import { initPromise } from '../rust'
|
||||
import { Selections, ToolTip } from '../../useStore'
|
||||
import { enginelessExecutor } from '../../lib/testHelpers'
|
||||
import { recast } from '../../lang/recast'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -63,7 +60,7 @@ describe('testing getConstraintType', () => {
|
||||
function getConstraintTypeFromSourceHelper(
|
||||
code: string
|
||||
): ReturnType<typeof getConstraintType> {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const args = (ast.body[0] as any).expression.arguments[0].elements as [
|
||||
Value,
|
||||
Value
|
||||
@ -74,7 +71,7 @@ function getConstraintTypeFromSourceHelper(
|
||||
function getConstraintTypeFromSourceHelper2(
|
||||
code: string
|
||||
): ReturnType<typeof getConstraintType> {
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const arg = (ast.body[0] as any).expression.arguments[0] as Value
|
||||
const fnName = (ast.body[0] as any).expression.callee.name as ToolTip
|
||||
return getConstraintType(arg, fnName)
|
||||
@ -199,7 +196,7 @@ const part001 = startSketchAt([0, 0])
|
||||
show(part001)
|
||||
`
|
||||
it('should transform the ast', async () => {
|
||||
const ast = parser_wasm(inputScript)
|
||||
const ast = parse(inputScript)
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) => ln.includes('//'))
|
||||
@ -286,7 +283,7 @@ const part001 = startSketchAt([0, 0])
|
||||
|> angledLineToY([301, myVar], %) // select for vertical constraint 10
|
||||
show(part001)
|
||||
`
|
||||
const ast = parser_wasm(inputScript)
|
||||
const ast = parse(inputScript)
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) => ln.includes('// select for horizontal constraint'))
|
||||
@ -344,7 +341,7 @@ const part001 = startSketchAt([0, 0])
|
||||
|> yLineTo(myVar, %) // select for vertical constraint 10
|
||||
show(part001)
|
||||
`
|
||||
const ast = parser_wasm(inputScript)
|
||||
const ast = parse(inputScript)
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) => ln.includes('// select for vertical constraint'))
|
||||
@ -435,7 +432,7 @@ async function helperThing(
|
||||
linesOfInterest: string[],
|
||||
constraint: ConstraintType
|
||||
): Promise<string> {
|
||||
const ast = parser_wasm(inputScript)
|
||||
const ast = parse(inputScript)
|
||||
const selectionRanges: Selections['codeBasedSelections'] = inputScript
|
||||
.split('\n')
|
||||
.filter((ln) =>
|
||||
@ -498,7 +495,7 @@ const part001 = startSketchAt([-0.01, -0.05])
|
||||
|> xLine(-3.43 + 0, %) // full
|
||||
|> angledLineOfXLength([243 + 0, 1.2 + 0], %) // full
|
||||
show(part001)`
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const constraintLevels: ReturnType<
|
||||
typeof getConstraintLevelFromSourceRange
|
||||
>[] = ['full', 'partial', 'free']
|
||||
|
@ -6,7 +6,9 @@ import {
|
||||
Value,
|
||||
BinaryPart,
|
||||
VariableDeclarator,
|
||||
} from '../abstractSyntaxTreeTypes'
|
||||
PathToNode,
|
||||
ProgramMemory,
|
||||
} from '../wasm'
|
||||
import {
|
||||
getNodeFromPath,
|
||||
getNodeFromPathCurry,
|
||||
@ -25,10 +27,8 @@ import {
|
||||
giveSketchFnCallTag,
|
||||
} from '../modifyAst'
|
||||
import { createFirstArg, getFirstArg, replaceSketchLine } from './sketch'
|
||||
import { PathToNode, ProgramMemory } from '../executor'
|
||||
import { getSketchSegmentFromSourceRange } from './sketchConstraints'
|
||||
import { getAngle, roundOff, normaliseAngle } from '../../lib/utils'
|
||||
import { MemoryItem } from 'wasm-lib/kcl/bindings/MemoryItem'
|
||||
|
||||
type LineInputsType =
|
||||
| 'xAbsolute'
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { parser_wasm } from '../abstractSyntaxTree'
|
||||
import { parse, initPromise } from '../wasm'
|
||||
import { enginelessExecutor } from '../../lib/testHelpers'
|
||||
import { initPromise } from '../rust'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -17,9 +16,9 @@ describe('testing angledLineThatIntersects', () => {
|
||||
}, %)
|
||||
const intersect = segEndX('yo2', part001)
|
||||
show(part001)`
|
||||
const { root } = await enginelessExecutor(parser_wasm(code('-1')))
|
||||
const { root } = await enginelessExecutor(parse(code('-1')))
|
||||
expect(root.intersect.value).toBe(1 + Math.sqrt(2))
|
||||
const { root: noOffset } = await enginelessExecutor(parser_wasm(code('0')))
|
||||
const { root: noOffset } = await enginelessExecutor(parse(code('0')))
|
||||
expect(noOffset.intersect.value).toBeCloseTo(1)
|
||||
})
|
||||
})
|
||||
|
@ -1,7 +1,12 @@
|
||||
import { ProgramMemory, Path, SourceRange } from '../executor'
|
||||
import { Program, Value } from '../abstractSyntaxTreeTypes'
|
||||
import {
|
||||
ProgramMemory,
|
||||
Path,
|
||||
SourceRange,
|
||||
Program,
|
||||
Value,
|
||||
PathToNode,
|
||||
} from '../wasm'
|
||||
import { ToolTip } from '../../useStore'
|
||||
import { PathToNode } from '../executor'
|
||||
import { EngineCommandManager } from './engineConnection'
|
||||
|
||||
export interface InternalFirstArg {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { lexer, asyncLexer } from './tokeniser'
|
||||
import { initPromise } from './rust'
|
||||
import { lexer, initPromise } from './wasm'
|
||||
|
||||
beforeAll(() => initPromise)
|
||||
|
||||
@ -10,9 +9,9 @@ describe('testing lexer', () => {
|
||||
const code3 = `const yo = 45 /* this is a comment
|
||||
const ya = 6 */
|
||||
const yi=45`
|
||||
expect(await asyncLexer(code)).toEqual(lexer(code))
|
||||
expect(await asyncLexer(code2)).toEqual(lexer(code2))
|
||||
expect(await asyncLexer(code3)).toEqual(lexer(code3))
|
||||
expect(lexer(code)).toEqual(lexer(code))
|
||||
expect(lexer(code2)).toEqual(lexer(code2))
|
||||
expect(lexer(code3)).toEqual(lexer(code3))
|
||||
})
|
||||
it('test lexer', () => {
|
||||
expect(stringSummaryLexer('1 + 2')).toEqual([
|
||||
|
@ -1,28 +0,0 @@
|
||||
import { lexer_js } from '../wasm-lib/pkg/wasm_lib'
|
||||
import { initPromise } from './rust'
|
||||
import { Token } from '../wasm-lib/kcl/bindings/Token'
|
||||
|
||||
export type { Token } from '../wasm-lib/kcl/bindings/Token'
|
||||
|
||||
export async function asyncLexer(str: string): Promise<Token[]> {
|
||||
await initPromise
|
||||
try {
|
||||
const tokens: Token[] = lexer_js(str)
|
||||
return tokens
|
||||
} catch (e) {
|
||||
// TODO: do something real with the error.
|
||||
console.log('lexer error', e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export function lexer(str: string): Token[] {
|
||||
try {
|
||||
const tokens: Token[] = lexer_js(str)
|
||||
return tokens
|
||||
} catch (e) {
|
||||
// TODO: do something real with the error.
|
||||
console.log('lexer error', e)
|
||||
throw e
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import { Selections, StoreState } from '../useStore'
|
||||
import { Program } from './abstractSyntaxTreeTypes'
|
||||
import { PathToNode } from './executor'
|
||||
import { Program, PathToNode } from './wasm'
|
||||
import { getNodeFromPath } from './queryAst'
|
||||
|
||||
export function updateCursors(
|
||||
|
215
src/lang/wasm.ts
Normal file
215
src/lang/wasm.ts
Normal file
@ -0,0 +1,215 @@
|
||||
import init, {
|
||||
parse_wasm,
|
||||
recast_wasm,
|
||||
execute_wasm,
|
||||
lexer_wasm,
|
||||
modify_ast_for_sketch_wasm,
|
||||
} from '../wasm-lib/pkg/wasm_lib'
|
||||
import { KCLError } from './errors'
|
||||
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||
import {
|
||||
EngineCommandManager,
|
||||
ArtifactMap,
|
||||
SourceRangeMap,
|
||||
} from './std/engineConnection'
|
||||
import { ProgramReturn } from '../wasm-lib/kcl/bindings/ProgramReturn'
|
||||
import { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
||||
import type { Program } from '../wasm-lib/kcl/bindings/Program'
|
||||
import type { Token } from '../wasm-lib/kcl/bindings/Token'
|
||||
|
||||
export type { Program } from '../wasm-lib/kcl/bindings/Program'
|
||||
export type { Value } from '../wasm-lib/kcl/bindings/Value'
|
||||
export type { ObjectExpression } from '../wasm-lib/kcl/bindings/ObjectExpression'
|
||||
export type { MemberExpression } from '../wasm-lib/kcl/bindings/MemberExpression'
|
||||
export type { PipeExpression } from '../wasm-lib/kcl/bindings/PipeExpression'
|
||||
export type { VariableDeclaration } from '../wasm-lib/kcl/bindings/VariableDeclaration'
|
||||
export type { PipeSubstitution } from '../wasm-lib/kcl/bindings/PipeSubstitution'
|
||||
export type { Identifier } from '../wasm-lib/kcl/bindings/Identifier'
|
||||
export type { UnaryExpression } from '../wasm-lib/kcl/bindings/UnaryExpression'
|
||||
export type { BinaryExpression } from '../wasm-lib/kcl/bindings/BinaryExpression'
|
||||
export type { ReturnStatement } from '../wasm-lib/kcl/bindings/ReturnStatement'
|
||||
export type { ExpressionStatement } from '../wasm-lib/kcl/bindings/ExpressionStatement'
|
||||
export type { CallExpression } from '../wasm-lib/kcl/bindings/CallExpression'
|
||||
export type { VariableDeclarator } from '../wasm-lib/kcl/bindings/VariableDeclarator'
|
||||
export type { BinaryPart } from '../wasm-lib/kcl/bindings/BinaryPart'
|
||||
export type { Literal } from '../wasm-lib/kcl/bindings/Literal'
|
||||
export type { ArrayExpression } from '../wasm-lib/kcl/bindings/ArrayExpression'
|
||||
|
||||
export type SyntaxType =
|
||||
| 'Program'
|
||||
| 'ExpressionStatement'
|
||||
| 'BinaryExpression'
|
||||
| 'CallExpression'
|
||||
| 'Identifier'
|
||||
| 'ReturnStatement'
|
||||
| 'VariableDeclaration'
|
||||
| 'VariableDeclarator'
|
||||
| 'MemberExpression'
|
||||
| 'ArrayExpression'
|
||||
| 'ObjectExpression'
|
||||
| 'ObjectProperty'
|
||||
| 'FunctionExpression'
|
||||
| 'PipeExpression'
|
||||
| 'PipeSubstitution'
|
||||
| 'Literal'
|
||||
| 'NonCodeNode'
|
||||
| 'UnaryExpression'
|
||||
|
||||
export type { SourceRange } from '../wasm-lib/kcl/bindings/SourceRange'
|
||||
export type { Position } from '../wasm-lib/kcl/bindings/Position'
|
||||
export type { Rotation } from '../wasm-lib/kcl/bindings/Rotation'
|
||||
export type { Path } from '../wasm-lib/kcl/bindings/Path'
|
||||
export type { SketchGroup } from '../wasm-lib/kcl/bindings/SketchGroup'
|
||||
export type { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
||||
export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface'
|
||||
|
||||
// Initialise the wasm module.
|
||||
const initialise = async () => {
|
||||
const baseUrl =
|
||||
typeof window === 'undefined'
|
||||
? 'http://127.0.0.1:3000'
|
||||
: window.location.origin.includes('tauri://localhost')
|
||||
? 'tauri://localhost'
|
||||
: window.location.origin.includes('localhost')
|
||||
? 'http://localhost:3000'
|
||||
: window.location.origin && window.location.origin !== 'null'
|
||||
? window.location.origin
|
||||
: 'http://localhost:3000'
|
||||
const fullUrl = baseUrl + '/wasm_lib_bg.wasm'
|
||||
const input = await fetch(fullUrl)
|
||||
const buffer = await input.arrayBuffer()
|
||||
return init(buffer)
|
||||
}
|
||||
|
||||
export const initPromise = initialise()
|
||||
|
||||
export const rangeTypeFix = (ranges: number[][]): [number, number][] =>
|
||||
ranges.map(([start, end]) => [start, end])
|
||||
|
||||
export const parse = (code: string): Program => {
|
||||
try {
|
||||
const program: Program = parse_wasm(code)
|
||||
return program
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
}
|
||||
|
||||
export type PathToNode = [string | number, string][]
|
||||
|
||||
interface Memory {
|
||||
[key: string]: MemoryItem
|
||||
}
|
||||
|
||||
export interface ProgramMemory {
|
||||
root: Memory
|
||||
return: ProgramReturn | null
|
||||
}
|
||||
|
||||
export const executor = async (
|
||||
node: Program,
|
||||
programMemory: ProgramMemory = { root: {}, return: null },
|
||||
engineCommandManager: EngineCommandManager,
|
||||
// work around while the gemotry is still be stored on the frontend
|
||||
// will be removed when the stream UI is added.
|
||||
tempMapCallback: (a: {
|
||||
artifactMap: ArtifactMap
|
||||
sourceRangeMap: SourceRangeMap
|
||||
}) => void = () => {}
|
||||
): Promise<ProgramMemory> => {
|
||||
engineCommandManager.startNewSession()
|
||||
const _programMemory = await _executor(
|
||||
node,
|
||||
programMemory,
|
||||
engineCommandManager
|
||||
)
|
||||
const { artifactMap, sourceRangeMap } =
|
||||
await engineCommandManager.waitForAllCommands(node, _programMemory)
|
||||
tempMapCallback({ artifactMap, sourceRangeMap })
|
||||
|
||||
engineCommandManager.endSession()
|
||||
return _programMemory
|
||||
}
|
||||
|
||||
export const _executor = async (
|
||||
node: Program,
|
||||
programMemory: ProgramMemory = { root: {}, return: null },
|
||||
engineCommandManager: EngineCommandManager
|
||||
): Promise<ProgramMemory> => {
|
||||
try {
|
||||
const memory: ProgramMemory = await execute_wasm(
|
||||
JSON.stringify(node),
|
||||
JSON.stringify(programMemory),
|
||||
engineCommandManager
|
||||
)
|
||||
return memory
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
}
|
||||
|
||||
export const recast = (ast: Program): string => {
|
||||
try {
|
||||
const s: string = recast_wasm(JSON.stringify(ast))
|
||||
return s
|
||||
} catch (e) {
|
||||
// TODO: do something real with the error.
|
||||
console.log('recast error', e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export function lexer(str: string): Token[] {
|
||||
try {
|
||||
const tokens: Token[] = lexer_wasm(str)
|
||||
return tokens
|
||||
} catch (e) {
|
||||
// TODO: do something real with the error.
|
||||
console.log('lexer error', e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export const modifyAstForSketch = async (
|
||||
engineCommandManager: EngineCommandManager,
|
||||
ast: Program,
|
||||
variableName: string,
|
||||
engineId: string
|
||||
): Promise<Program> => {
|
||||
try {
|
||||
const updatedAst: Program = await modify_ast_for_sketch_wasm(
|
||||
engineCommandManager,
|
||||
JSON.stringify(ast),
|
||||
variableName,
|
||||
engineId
|
||||
)
|
||||
|
||||
return updatedAst
|
||||
} catch (e: any) {
|
||||
const parsed: RustKclError = JSON.parse(e.toString())
|
||||
const kclError = new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
rangeTypeFix(parsed.sourceRanges)
|
||||
)
|
||||
|
||||
console.log(kclError)
|
||||
throw kclError
|
||||
}
|
||||
}
|
@ -1,19 +1,27 @@
|
||||
export const bracket = `// Material: 6061-T6 Aluminum
|
||||
const sigmaAllow = 35000 // psi
|
||||
const width = 9 // inch
|
||||
export const bracket = `const sigmaAllow = 15000 // psi
|
||||
const width = 11 // inch
|
||||
const p = 150 // Force on shelf - lbs
|
||||
const distance = 6 // inches
|
||||
const distance = 12 // inches
|
||||
const FOS = 2
|
||||
const thickness = sqrt(distance * p * FOS * 6 / ( sigmaAllow * width ))
|
||||
const filletR = thickness * 2
|
||||
const shelfMountL = 9
|
||||
const wallMountL = 8
|
||||
|
||||
const leg1 = 5 // inches
|
||||
const leg2 = 8 // inches
|
||||
const thickness = sqrt(distance * p * FOS * 6 / sigmaAllow / width) // inches
|
||||
const bracket = startSketchAt([0, 0])
|
||||
|> line([0, leg1], %)
|
||||
|> line([leg2, 0], %)
|
||||
|> line([0, wallMountL], %)
|
||||
|> tangentalArc({
|
||||
radius: filletR,
|
||||
offset: 90
|
||||
}, %)
|
||||
|> line([-shelfMountL, 0], %)
|
||||
|> line([0, -thickness], %)
|
||||
|> line([-leg2 + thickness, 0], %)
|
||||
|> line([0, -leg1 + thickness], %)
|
||||
|> line([shelfMountL, 0], %)
|
||||
|> tangentalArc({
|
||||
radius: filletR - thickness,
|
||||
offset: -90
|
||||
}, %)
|
||||
|> line([0, -wallMountL], %)
|
||||
|> close(%)
|
||||
|> extrude(width, %)
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { Program } from '../lang/abstractSyntaxTreeTypes'
|
||||
import { ProgramMemory, _executor } from '../lang/executor'
|
||||
import { Program, ProgramMemory, _executor, SourceRange } from '../lang/wasm'
|
||||
import {
|
||||
EngineCommandManager,
|
||||
EngineCommand,
|
||||
} from '../lang/std/engineConnection'
|
||||
import { SourceRange } from 'lang/executor'
|
||||
import { Models } from '@kittycad/lib'
|
||||
|
||||
type WebSocketResponse = Models['OkWebSocketResponseData_type']
|
||||
@ -81,6 +79,7 @@ export async function executor(
|
||||
setMediaStream: () => {},
|
||||
width: 0,
|
||||
height: 0,
|
||||
executeCode: () => {},
|
||||
})
|
||||
await engineCommandManager.waitForReady
|
||||
engineCommandManager.startNewSession()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { isOverlap, roundOff } from './utils'
|
||||
import { SourceRange } from '../lang/executor'
|
||||
import { SourceRange } from '../lang/wasm'
|
||||
|
||||
describe('testing isOverlapping', () => {
|
||||
testBothOrders([0, 3], [3, 10])
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { SourceRange } from '../lang/executor'
|
||||
import { SourceRange } from '../lang/wasm'
|
||||
|
||||
export function isOverlap(a: SourceRange, b: SourceRange) {
|
||||
const [startingRange, secondRange] = a[0] < b[0] ? [a, b] : [b, a]
|
||||
|
@ -2,6 +2,7 @@ import { assign, createMachine } from 'xstate'
|
||||
import { CommandBarMeta } from '../lib/commands'
|
||||
import { Themes, getSystemTheme, setThemeClass } from '../lib/theme'
|
||||
import { CameraSystem, cameraSystems } from 'lib/cameraControls'
|
||||
import { Models } from '@kittycad/lib'
|
||||
|
||||
export const DEFAULT_PROJECT_NAME = 'project-$nnn'
|
||||
|
||||
@ -11,11 +12,11 @@ export enum UnitSystem {
|
||||
}
|
||||
|
||||
export const baseUnits = {
|
||||
imperial: ['in', 'ft'],
|
||||
imperial: ['in', 'ft', 'yd'],
|
||||
metric: ['mm', 'cm', 'm'],
|
||||
} as const
|
||||
|
||||
export type BaseUnit = 'in' | 'ft' | 'mm' | 'cm' | 'm'
|
||||
export type BaseUnit = Models['UnitLength_type']
|
||||
|
||||
export const baseUnitsUnion = Object.values(baseUnits).flatMap((v) => v)
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
import { addLineHighlight, EditorView } from './editor/highlightextension'
|
||||
import { parser_wasm } from './lang/abstractSyntaxTree'
|
||||
import { Program } from './lang/abstractSyntaxTreeTypes'
|
||||
import { getNodeFromPath } from './lang/queryAst'
|
||||
import { enginelessExecutor } from './lib/testHelpers'
|
||||
import {
|
||||
parse,
|
||||
Program,
|
||||
_executor,
|
||||
recast,
|
||||
ProgramMemory,
|
||||
Position,
|
||||
PathToNode,
|
||||
Rotation,
|
||||
SourceRange,
|
||||
} from './lang/executor'
|
||||
import { recast } from './lang/recast'
|
||||
} from './lang/wasm'
|
||||
import { getNodeFromPath } from './lang/queryAst'
|
||||
import { enginelessExecutor } from './lib/testHelpers'
|
||||
import { EditorSelection } from '@codemirror/state'
|
||||
import { EngineCommandManager } from './lang/std/engineConnection'
|
||||
import { KCLError } from './lang/errors'
|
||||
import { deferExecution } from 'lib/utils'
|
||||
import { _executor } from './lang/executor'
|
||||
import { bracket } from 'lib/exampleKcl'
|
||||
import { engineCommandManager } from './lang/std/engineConnection'
|
||||
|
||||
@ -157,7 +157,7 @@ export interface StoreState {
|
||||
code: string
|
||||
setCode: (code: string) => void
|
||||
deferredSetCode: (code: string) => void
|
||||
executeCode: (code?: string) => void
|
||||
executeCode: (code?: string, force?: boolean) => void
|
||||
formatCode: () => void
|
||||
programMemory: ProgramMemory
|
||||
setProgramMemory: (programMemory: ProgramMemory) => void
|
||||
@ -221,11 +221,12 @@ export const useStore = create<StoreState>()(
|
||||
editorView.dispatch({ effects: addLineHighlight.of(selection) })
|
||||
}
|
||||
},
|
||||
executeCode: async (code) => {
|
||||
executeCode: async (code, force) => {
|
||||
const result = await executeCode({
|
||||
code: code || get().code,
|
||||
lastAst: get().ast,
|
||||
engineCommandManager: engineCommandManager,
|
||||
force,
|
||||
})
|
||||
if (!result.isChange) {
|
||||
return
|
||||
@ -366,7 +367,7 @@ export const useStore = create<StoreState>()(
|
||||
{ focusPath, callBack = () => {} } = {}
|
||||
) => {
|
||||
const newCode = recast(ast)
|
||||
const astWithUpdatedSource = parser_wasm(newCode)
|
||||
const astWithUpdatedSource = parse(newCode)
|
||||
callBack(astWithUpdatedSource)
|
||||
|
||||
set({
|
||||
@ -422,7 +423,7 @@ export const useStore = create<StoreState>()(
|
||||
},
|
||||
formatCode: async () => {
|
||||
const code = get().code
|
||||
const ast = parser_wasm(code)
|
||||
const ast = parse(code)
|
||||
const newCode = recast(ast)
|
||||
set({ code: newCode, ast })
|
||||
},
|
||||
@ -511,10 +512,12 @@ async function executeCode({
|
||||
engineCommandManager,
|
||||
code,
|
||||
lastAst,
|
||||
force,
|
||||
}: {
|
||||
code: string
|
||||
lastAst: Program
|
||||
engineCommandManager: EngineCommandManager
|
||||
force?: boolean
|
||||
}): Promise<
|
||||
| {
|
||||
logs: string[]
|
||||
@ -527,7 +530,7 @@ async function executeCode({
|
||||
> {
|
||||
let ast: Program
|
||||
try {
|
||||
ast = parser_wasm(code)
|
||||
ast = parse(code)
|
||||
} catch (e) {
|
||||
let errors: KCLError[] = []
|
||||
let logs: string[] = [JSON.stringify(e)]
|
||||
@ -557,7 +560,7 @@ async function executeCode({
|
||||
}
|
||||
// Check if the ast we have is equal to the ast in the storage.
|
||||
// If it is, we don't need to update the ast.
|
||||
if (JSON.stringify(ast) === JSON.stringify(lastAst))
|
||||
if (JSON.stringify(ast) === JSON.stringify(lastAst) && !force)
|
||||
return { isChange: false }
|
||||
|
||||
const { logs, errors, programMemory } = await executeAst({
|
||||
|
@ -6,10 +6,10 @@
|
||||
serial-integration = { max-threads = 4 }
|
||||
|
||||
[profile.default]
|
||||
slow-timeout = { period = "10s", terminate-after = 1 }
|
||||
slow-timeout = { period = "60s", terminate-after = 1 }
|
||||
|
||||
[profile.ci]
|
||||
slow-timeout = { period = "60s", terminate-after = 10 }
|
||||
slow-timeout = { period = "120s", terminate-after = 10 }
|
||||
|
||||
[[profile.default.overrides]]
|
||||
filter = "test(serial_test_)"
|
||||
|
52
src/wasm-lib/Cargo.lock
generated
52
src/wasm-lib/Cargo.lock
generated
@ -71,9 +71,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.5.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
|
||||
checksum = "f6cd65a4b849ace0b7f6daeebcc1a1d111282227ca745458c61dbf670e52a597"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
@ -109,9 +109,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "2.1.0"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
|
||||
checksum = "0238ca56c96dfa37bdf7c373c8886dd591322500aceeeccdb2216fe06dc2f796"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.48.0",
|
||||
@ -440,9 +440,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.4"
|
||||
version = "4.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136"
|
||||
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@ -450,9 +450,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.4"
|
||||
version = "4.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56"
|
||||
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@ -695,6 +695,20 @@ dependencies = [
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-docs"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c357dec14992ba88803535217ed83d6f6cd80efcb8fa8e3f8a30a9b84fadc1c7"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_tokenstream",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
@ -788,9 +802,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "expectorate"
|
||||
version = "1.0.7"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "710ab6a2d57038a835d66f78d5af3fa5d27c1ec4682f823b9203c48826cb0591"
|
||||
checksum = "de6f19b25bdfa2747ae775f37cd109c31f1272d4e4c83095be0727840aa1d75f"
|
||||
dependencies = [
|
||||
"console",
|
||||
"newline-converter",
|
||||
@ -1376,7 +1390,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.1.31"
|
||||
version = "0.1.32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@ -1385,7 +1399,7 @@ dependencies = [
|
||||
"clap",
|
||||
"criterion",
|
||||
"dashmap",
|
||||
"derive-docs",
|
||||
"derive-docs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"expectorate",
|
||||
"futures",
|
||||
"itertools 0.11.0",
|
||||
@ -1412,9 +1426,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad"
|
||||
version = "0.2.26"
|
||||
version = "0.2.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2623ee601ce203476229df3f9d3a14664cb43e3f7455e9ac8ed91aacaa6163d"
|
||||
checksum = "35b2f9302648dbb06fd7121687f9505fc3179eba84111a06d76b246e3158f5dc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1719,7 +1733,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
[[package]]
|
||||
name = "openapitor"
|
||||
version = "0.0.9"
|
||||
source = "git+https://github.com/KittyCAD/kittycad.rs?branch=main#61a16059b3eaf8793a2a2e1edbc0d770f284fea3"
|
||||
source = "git+https://github.com/KittyCAD/kittycad.rs?branch=main#fa0345c514fcc9ae6cd74ae35c8e5c2800fec34f"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
@ -2945,18 +2959,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.48"
|
||||
version = "1.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
|
||||
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.48"
|
||||
version = "1.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -11,7 +11,7 @@ crate-type = ["cdylib"]
|
||||
bson = { version = "2.7.0", features = ["uuid-1", "chrono"] }
|
||||
gloo-utils = "0.2.0"
|
||||
kcl-lib = { path = "kcl" }
|
||||
kittycad = { version = "0.2.25", default-features = false, features = ["js"] }
|
||||
kittycad = { version = "0.2.27", default-features = false, features = ["js"] }
|
||||
serde_json = "1.0.107"
|
||||
uuid = { version = "1.4.1", features = ["v4", "js", "serde"] }
|
||||
wasm-bindgen = "0.2.87"
|
||||
@ -20,7 +20,7 @@ wasm-bindgen-futures = "0.4.37"
|
||||
[dev-dependencies]
|
||||
anyhow = "1"
|
||||
image = "0.24.7"
|
||||
kittycad = "0.2.25"
|
||||
kittycad = "0.2.27"
|
||||
pretty_assertions = "1.4.0"
|
||||
reqwest = { version = "0.11.20", default-features = false }
|
||||
tokio = { version = "1.32.0", features = ["rt-multi-thread", "macros", "time"] }
|
||||
|
@ -19,6 +19,6 @@ serde_tokenstream = "0.2"
|
||||
syn = { version = "2.0.37", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
expectorate = "1.0.7"
|
||||
expectorate = "1.1.0"
|
||||
openapitor = { git = "https://github.com/KittyCAD/kittycad.rs", branch = "main" }
|
||||
pretty_assertions = "1.4.0"
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language"
|
||||
version = "0.1.31"
|
||||
version = "0.1.32"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
@ -11,17 +11,17 @@ license = "MIT"
|
||||
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
||||
async-recursion = "1.0.5"
|
||||
async-trait = "0.1.73"
|
||||
clap = { version = "4.4.3", features = ["cargo", "derive", "env", "unicode"], optional = true }
|
||||
clap = { version = "4.4.6", features = ["cargo", "derive", "env", "unicode"], optional = true }
|
||||
dashmap = "5.5.3"
|
||||
#derive-docs = { version = "0.1.4" }
|
||||
derive-docs = { path = "../derive-docs" }
|
||||
kittycad = { version = "0.2.25", default-features = false, features = ["js"] }
|
||||
derive-docs = { version = "0.1.4" }
|
||||
#derive-docs = { path = "../derive-docs" }
|
||||
kittycad = { version = "0.2.27", default-features = false, features = ["js"] }
|
||||
lazy_static = "1.4.0"
|
||||
parse-display = "0.8.2"
|
||||
schemars = { version = "0.8", features = ["impl_json_schema", "url", "uuid1"] }
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
thiserror = "1.0.48"
|
||||
thiserror = "1.0.49"
|
||||
ts-rs = { version = "7", package = "ts-rs-json-value", features = ["serde-json-impl", "schemars-impl", "uuid-impl"] }
|
||||
uuid = { version = "1.4.1", features = ["v4", "js", "serde"] }
|
||||
winnow = "0.5.15"
|
||||
@ -52,7 +52,7 @@ debug = true
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5.1"
|
||||
expectorate = "1.0.7"
|
||||
expectorate = "1.1.0"
|
||||
itertools = "0.11.0"
|
||||
pretty_assertions = "1.4.0"
|
||||
tokio = { version = "1.32.0", features = ["rt-multi-thread", "macros", "time"] }
|
||||
|
@ -258,6 +258,23 @@ impl Program {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace a value with the new value, use the source range for matching the exact value.
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
for item in &mut self.body {
|
||||
match item {
|
||||
BodyItem::ExpressionStatement(ref mut expression_statement) => expression_statement
|
||||
.expression
|
||||
.replace_value(source_range, new_value.clone()),
|
||||
BodyItem::VariableDeclaration(ref mut variable_declaration) => {
|
||||
variable_declaration.replace_value(source_range, new_value.clone())
|
||||
}
|
||||
BodyItem::ReturnStatement(ref mut return_statement) => {
|
||||
return_statement.argument.replace_value(source_range, new_value.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the variable declaration with the given name.
|
||||
pub fn get_variable(&self, name: &str) -> Option<&VariableDeclarator> {
|
||||
for item in &self.body {
|
||||
@ -393,6 +410,27 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
if source_range == self.clone().into() {
|
||||
*self = new_value;
|
||||
return;
|
||||
}
|
||||
|
||||
match self {
|
||||
Value::BinaryExpression(ref mut bin_exp) => bin_exp.replace_value(source_range, new_value),
|
||||
Value::ArrayExpression(ref mut array_exp) => array_exp.replace_value(source_range, new_value),
|
||||
Value::ObjectExpression(ref mut obj_exp) => obj_exp.replace_value(source_range, new_value),
|
||||
Value::MemberExpression(_) => {}
|
||||
Value::Literal(_) => {}
|
||||
Value::FunctionExpression(ref mut func_exp) => func_exp.replace_value(source_range, new_value),
|
||||
Value::CallExpression(ref mut call_exp) => call_exp.replace_value(source_range, new_value),
|
||||
Value::Identifier(_) => {}
|
||||
Value::PipeExpression(ref mut pipe_exp) => pipe_exp.replace_value(source_range, new_value),
|
||||
Value::UnaryExpression(ref mut unary_exp) => unary_exp.replace_value(source_range, new_value),
|
||||
Value::PipeSubstitution(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&self) -> usize {
|
||||
match self {
|
||||
Value::Literal(literal) => literal.start(),
|
||||
@ -538,6 +576,23 @@ impl BinaryPart {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
match self {
|
||||
BinaryPart::Literal(_) => {}
|
||||
BinaryPart::Identifier(_) => {}
|
||||
BinaryPart::BinaryExpression(ref mut binary_expression) => {
|
||||
binary_expression.replace_value(source_range, new_value)
|
||||
}
|
||||
BinaryPart::CallExpression(ref mut call_expression) => {
|
||||
call_expression.replace_value(source_range, new_value)
|
||||
}
|
||||
BinaryPart::UnaryExpression(ref mut unary_expression) => {
|
||||
unary_expression.replace_value(source_range, new_value)
|
||||
}
|
||||
BinaryPart::MemberExpression(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
|
||||
match &self {
|
||||
BinaryPart::Literal(literal) => literal.recast(),
|
||||
@ -801,6 +856,12 @@ impl CallExpression {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
for arg in &mut self.arguments {
|
||||
arg.replace_value(source_range, new_value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn recast(&self, options: &FormatOptions, indentation_level: usize, is_in_pipe: bool) -> String {
|
||||
format!(
|
||||
"{}({})",
|
||||
@ -1014,6 +1075,12 @@ impl VariableDeclaration {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
for declaration in &mut self.declarations {
|
||||
declaration.init.replace_value(source_range, new_value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a value that includes the given character position.
|
||||
pub fn get_value_for_position(&self, pos: usize) -> Option<&Value> {
|
||||
for declaration in &self.declarations {
|
||||
@ -1367,6 +1434,12 @@ impl ArrayExpression {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
for element in &mut self.elements {
|
||||
element.replace_value(source_range, new_value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_constraint_level(&self) -> ConstraintLevel {
|
||||
if self.elements.is_empty() {
|
||||
return ConstraintLevel::Ignore {
|
||||
@ -1517,6 +1590,12 @@ impl ObjectExpression {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
for property in &mut self.properties {
|
||||
property.value.replace_value(source_range, new_value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_constraint_level(&self) -> ConstraintLevel {
|
||||
if self.properties.is_empty() {
|
||||
return ConstraintLevel::Ignore {
|
||||
@ -1961,6 +2040,11 @@ impl BinaryExpression {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
self.left.replace_value(source_range, new_value.clone());
|
||||
self.right.replace_value(source_range, new_value);
|
||||
}
|
||||
|
||||
pub fn get_constraint_level(&self) -> ConstraintLevel {
|
||||
let left_constraint_level = self.left.get_constraint_level();
|
||||
let right_constraint_level = self.right.get_constraint_level();
|
||||
@ -2183,6 +2267,10 @@ impl UnaryExpression {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
self.argument.replace_value(source_range, new_value);
|
||||
}
|
||||
|
||||
pub fn get_constraint_level(&self) -> ConstraintLevel {
|
||||
self.argument.get_constraint_level()
|
||||
}
|
||||
@ -2278,6 +2366,12 @@ impl PipeExpression {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
for value in &mut self.body {
|
||||
value.replace_value(source_range, new_value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_constraint_level(&self) -> ConstraintLevel {
|
||||
if self.body.is_empty() {
|
||||
return ConstraintLevel::Ignore {
|
||||
@ -2420,6 +2514,10 @@ impl FunctionExpression {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
|
||||
self.body.replace_value(source_range, new_value);
|
||||
}
|
||||
|
||||
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
|
||||
// We don't want to end with a new line inside nested functions.
|
||||
let mut new_options = options.clone();
|
||||
|
@ -1283,7 +1283,11 @@ impl Parser {
|
||||
let end_token = self.get_token(pipe_body_result.last_index)?;
|
||||
Ok(PipeExpressionResult {
|
||||
expression: PipeExpression {
|
||||
start: current_token.start,
|
||||
start: pipe_body_result
|
||||
.body
|
||||
.first()
|
||||
.map(|v| v.start())
|
||||
.unwrap_or(current_token.start),
|
||||
end: end_token.end,
|
||||
body: pipe_body_result.body,
|
||||
non_code_meta: pipe_body_result.non_code_meta,
|
||||
|
@ -61,6 +61,8 @@ impl StdLib {
|
||||
Box::new(crate::std::sketch::StartSketchAt),
|
||||
Box::new(crate::std::sketch::Close),
|
||||
Box::new(crate::std::sketch::Arc),
|
||||
Box::new(crate::std::sketch::TangentalArc),
|
||||
Box::new(crate::std::sketch::TangentalArcTo),
|
||||
Box::new(crate::std::sketch::BezierCurve),
|
||||
Box::new(crate::std::math::Cos),
|
||||
Box::new(crate::std::math::Sin),
|
||||
|
@ -879,6 +879,214 @@ async fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: Args) ->
|
||||
Ok(new_sketch_group)
|
||||
}
|
||||
|
||||
/// Data to draw a tangental arc.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
pub enum TangentalArcData {
|
||||
RadiusAndOffset {
|
||||
/// Radius of the arc.
|
||||
/// Not to be confused with Raiders of the Lost Ark.
|
||||
radius: f64,
|
||||
/// Offset of the arc, in degrees.
|
||||
offset: f64,
|
||||
},
|
||||
/// A point with a tag.
|
||||
PointWithTag {
|
||||
/// Where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
to: [f64; 2],
|
||||
/// The tag.
|
||||
tag: String,
|
||||
},
|
||||
/// A point where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
Point([f64; 2]),
|
||||
}
|
||||
|
||||
/// Draw a tangental arc.
|
||||
pub async fn tangental_arc(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (TangentalArcData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_tangental_arc(data, sketch_group, args).await?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
}
|
||||
|
||||
/// Draw an arc.
|
||||
#[stdlib {
|
||||
name = "tangentalArc",
|
||||
}]
|
||||
async fn inner_tangental_arc(
|
||||
data: TangentalArcData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
||||
|
||||
let id = uuid::Uuid::new_v4();
|
||||
|
||||
let to = match &data {
|
||||
TangentalArcData::RadiusAndOffset { radius, offset } => {
|
||||
// Calculate the end point from the angle and radius.
|
||||
let end_angle = Angle::from_degrees(*offset);
|
||||
let start_angle = Angle::from_degrees(0.0);
|
||||
let (_, to) = arc_center_and_end(from, start_angle, end_angle, *radius);
|
||||
|
||||
args.send_modeling_cmd(
|
||||
id,
|
||||
ModelingCmd::ExtendPath {
|
||||
path: sketch_group.id,
|
||||
segment: kittycad::types::PathSegment::TangentialArc {
|
||||
radius: *radius,
|
||||
offset: kittycad::types::Angle {
|
||||
unit: kittycad::types::UnitAngle::Degrees,
|
||||
value: *offset,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
to.into()
|
||||
}
|
||||
TangentalArcData::PointWithTag { to, .. } => {
|
||||
args.send_modeling_cmd(
|
||||
id,
|
||||
ModelingCmd::ExtendPath {
|
||||
path: sketch_group.id,
|
||||
segment: kittycad::types::PathSegment::TangentialArcTo {
|
||||
angle_snap_increment: None,
|
||||
to: kittycad::types::Point3D {
|
||||
x: to[0],
|
||||
y: to[1],
|
||||
z: 0.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
*to
|
||||
}
|
||||
TangentalArcData::Point(to) => {
|
||||
args.send_modeling_cmd(
|
||||
id,
|
||||
ModelingCmd::ExtendPath {
|
||||
path: sketch_group.id,
|
||||
segment: kittycad::types::PathSegment::TangentialArcTo {
|
||||
angle_snap_increment: None,
|
||||
to: kittycad::types::Point3D {
|
||||
x: to[0],
|
||||
y: to[1],
|
||||
z: 0.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
*to
|
||||
}
|
||||
};
|
||||
|
||||
let to = [from.x + to[0], from.y + to[1]];
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
to,
|
||||
name: "".to_string(),
|
||||
geo_meta: GeoMeta {
|
||||
id,
|
||||
metadata: args.source_range.into(),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let mut new_sketch_group = sketch_group.clone();
|
||||
new_sketch_group.value.push(current_path);
|
||||
|
||||
Ok(new_sketch_group)
|
||||
}
|
||||
|
||||
/// Data to draw a tangental arc to a specific point.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
pub enum TangentalArcToData {
|
||||
/// A point with a tag.
|
||||
PointWithTag {
|
||||
/// Where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
to: [f64; 2],
|
||||
/// The tag.
|
||||
tag: String,
|
||||
},
|
||||
/// A point where the arc should end. Must lie in the same plane as the current path pen position. Must not be colinear with current path pen position.
|
||||
Point([f64; 2]),
|
||||
}
|
||||
|
||||
/// Draw a tangental arc to a specific point.
|
||||
pub async fn tangental_arc_to(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let (data, sketch_group): (TangentalArcToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||
|
||||
let new_sketch_group = inner_tangental_arc_to(data, sketch_group, args).await?;
|
||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||
}
|
||||
|
||||
/// Draw an arc.
|
||||
#[stdlib {
|
||||
name = "tangentalArcTo",
|
||||
}]
|
||||
async fn inner_tangental_arc_to(
|
||||
data: TangentalArcToData,
|
||||
sketch_group: Box<SketchGroup>,
|
||||
args: Args,
|
||||
) -> Result<Box<SketchGroup>, KclError> {
|
||||
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
||||
let to = match &data {
|
||||
TangentalArcToData::PointWithTag { to, .. } => to,
|
||||
TangentalArcToData::Point(to) => to,
|
||||
};
|
||||
|
||||
let delta = [to[0] - from.x, to[1] - from.y];
|
||||
|
||||
let id = uuid::Uuid::new_v4();
|
||||
|
||||
args.send_modeling_cmd(
|
||||
id,
|
||||
ModelingCmd::ExtendPath {
|
||||
path: sketch_group.id,
|
||||
segment: kittycad::types::PathSegment::TangentialArcTo {
|
||||
angle_snap_increment: None,
|
||||
to: kittycad::types::Point3D {
|
||||
x: delta[0],
|
||||
y: delta[1],
|
||||
z: 0.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
let current_path = Path::ToPoint {
|
||||
base: BasePath {
|
||||
from: from.into(),
|
||||
to: *to,
|
||||
name: if let TangentalArcToData::PointWithTag { tag, .. } = data {
|
||||
tag.to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
geo_meta: GeoMeta {
|
||||
id,
|
||||
metadata: args.source_range.into(),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let mut new_sketch_group = sketch_group.clone();
|
||||
new_sketch_group.value.push(current_path);
|
||||
|
||||
Ok(new_sketch_group)
|
||||
}
|
||||
|
||||
/// Data to draw a bezier curve.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
|
@ -10,6 +10,15 @@ pub struct Angle {
|
||||
degrees: f64,
|
||||
}
|
||||
|
||||
impl From<kittycad::types::Angle> for Angle {
|
||||
fn from(angle: kittycad::types::Angle) -> Self {
|
||||
match angle.unit {
|
||||
kittycad::types::UnitAngle::Degrees => Self::from_degrees(angle.value),
|
||||
kittycad::types::UnitAngle::Radians => Self::from_radians(angle.value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Angle {
|
||||
const ZERO: Self = Self { degrees: 0.0 };
|
||||
/// Make an angle of the given degrees.
|
||||
|
@ -36,7 +36,7 @@ pub async fn execute_wasm(
|
||||
// wasm_bindgen wrapper for execute
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[wasm_bindgen]
|
||||
pub async fn modify_ast_for_sketch(
|
||||
pub async fn modify_ast_for_sketch_wasm(
|
||||
manager: kcl_lib::engine::conn_wasm::EngineCommandManager,
|
||||
program_str: &str,
|
||||
sketch_name: &str,
|
||||
@ -83,13 +83,13 @@ pub fn deserialize_files(data: &[u8]) -> Result<JsValue, JsError> {
|
||||
// wasm_bindgen wrapper for lexer
|
||||
// test for this function and by extension lexer are done in javascript land src/lang/tokeniser.test.ts
|
||||
#[wasm_bindgen]
|
||||
pub fn lexer_js(js: &str) -> Result<JsValue, JsError> {
|
||||
pub fn lexer_wasm(js: &str) -> Result<JsValue, JsError> {
|
||||
let tokens = kcl_lib::token::lexer(js);
|
||||
Ok(JsValue::from_serde(&tokens)?)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn parse_js(js: &str) -> Result<JsValue, String> {
|
||||
pub fn parse_wasm(js: &str) -> Result<JsValue, String> {
|
||||
let tokens = kcl_lib::token::lexer(js);
|
||||
let parser = kcl_lib::parser::Parser::new(tokens);
|
||||
let program = parser.ast().map_err(String::from)?;
|
||||
|
@ -148,6 +148,41 @@ show(bracket)"#;
|
||||
twenty_twenty::assert_image("tests/executor/outputs/parametric.png", &result, 1.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn serial_test_execute_parametric_with_tan_arc_example() {
|
||||
let code = r#"const sigmaAllow = 15000 // psi
|
||||
const width = 11 // inch
|
||||
const p = 150 // Force on shelf - lbs
|
||||
const distance = 12 // inches
|
||||
const FOS = 2
|
||||
const thickness = sqrt(distance * p * FOS * 6 / ( sigmaAllow * width ))
|
||||
const filletR = thickness * 2
|
||||
const shelfMountL = 9
|
||||
const wallMountL = 8
|
||||
|
||||
const bracket = startSketchAt([0, 0])
|
||||
|> line([0, wallMountL], %)
|
||||
|> tangentalArc({
|
||||
radius: filletR,
|
||||
offset: 90
|
||||
}, %)
|
||||
|> line([-shelfMountL, 0], %)
|
||||
|> line([0, -thickness], %)
|
||||
|> line([shelfMountL, 0], %)
|
||||
|> tangentalArc({
|
||||
radius: filletR - thickness,
|
||||
offset: -90
|
||||
}, %)
|
||||
|> line([0, -wallMountL], %)
|
||||
|> close(%)
|
||||
|> extrude(width, %)
|
||||
|
||||
show(bracket)"#;
|
||||
|
||||
let result = execute_and_snapshot(code).await.unwrap();
|
||||
twenty_twenty::assert_image("tests/executor/outputs/parametric_with_tan_arc.png", &result, 1.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn serial_test_execute_engine_error_return() {
|
||||
let code = r#"const part001 = startSketchAt([5.5229, 5.25217])
|
||||
@ -252,3 +287,42 @@ box(-20, -5, 10)"#;
|
||||
let result = execute_and_snapshot(code).await.unwrap();
|
||||
twenty_twenty::assert_image("tests/executor/outputs/negative_args.png", &result, 1.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_basic_tangental_arc() {
|
||||
let code = r#"const boxSketch = startSketchAt([0, 0])
|
||||
|> line([0, 10], %)
|
||||
|> tangentalArc({radius: 5, offset: 90}, %)
|
||||
|> line([5, -15], %)
|
||||
|> extrude(10, %)
|
||||
"#;
|
||||
|
||||
let result = execute_and_snapshot(code).await.unwrap();
|
||||
twenty_twenty::assert_image("tests/executor/outputs/tangental_arc.png", &result, 1.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_basic_tangental_arc_with_point() {
|
||||
let code = r#"const boxSketch = startSketchAt([0, 0])
|
||||
|> line([0, 10], %)
|
||||
|> tangentalArc([-5, 5], %)
|
||||
|> line([5, -15], %)
|
||||
|> extrude(10, %)
|
||||
"#;
|
||||
|
||||
let result = execute_and_snapshot(code).await.unwrap();
|
||||
twenty_twenty::assert_image("tests/executor/outputs/tangental_arc_with_point.png", &result, 1.0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_basic_tangental_arc_to() {
|
||||
let code = r#"const boxSketch = startSketchAt([0, 0])
|
||||
|> line([0, 10], %)
|
||||
|> tangentalArcTo([-5, 15], %)
|
||||
|> line([5, -15], %)
|
||||
|> extrude(10, %)
|
||||
"#;
|
||||
|
||||
let result = execute_and_snapshot(code).await.unwrap();
|
||||
twenty_twenty::assert_image("tests/executor/outputs/tangental_arc_to.png", &result, 1.0);
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 96 KiB |
BIN
src/wasm-lib/tests/executor/outputs/parametric_with_tan_arc.png
Normal file
BIN
src/wasm-lib/tests/executor/outputs/parametric_with_tan_arc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
BIN
src/wasm-lib/tests/executor/outputs/tangental_arc.png
Normal file
BIN
src/wasm-lib/tests/executor/outputs/tangental_arc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
BIN
src/wasm-lib/tests/executor/outputs/tangental_arc_to.png
Normal file
BIN
src/wasm-lib/tests/executor/outputs/tangental_arc_to.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
BIN
src/wasm-lib/tests/executor/outputs/tangental_arc_with_point.png
Normal file
BIN
src/wasm-lib/tests/executor/outputs/tangental_arc_with_point.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
157
yarn.lock
157
yarn.lock
@ -1530,10 +1530,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
|
||||
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
|
||||
|
||||
"@kittycad/lib@^0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-0.0.39.tgz#e548acf5ff7d45a1f1ec9ad2c61ddcfc30d159b7"
|
||||
integrity sha512-cB4wNjsKTMpJUn/kMK3qtkVAqB1csSglqThe+bj02nC1kWTB1XgYxksooc/Gzl1MoK1/n0OPQcbOb7Tojb836A==
|
||||
"@kittycad/lib@^0.0.40":
|
||||
version "0.0.40"
|
||||
resolved "https://registry.yarnpkg.com/@kittycad/lib/-/lib-0.0.40.tgz#0ba00c642e76648fb7cb1337e799b9d24724312d"
|
||||
integrity sha512-R8sQKLWe3lQC7l7cyY49oFgeiMvRh8+bCaaoLiIVYT+YiE9TaS+uwwF1+sR7MiX6YZp/YCBBPFGj4Ci0VHC9Bg==
|
||||
dependencies:
|
||||
node-fetch "3.3.2"
|
||||
openapi-types "^12.0.0"
|
||||
@ -2175,44 +2175,44 @@
|
||||
istanbul-reports "^3.1.5"
|
||||
test-exclude "^6.0.0"
|
||||
|
||||
"@vitest/expect@0.34.1":
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.34.1.tgz#2ba6cb96695f4b4388c6d955423a81afc79b8da0"
|
||||
integrity sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==
|
||||
"@vitest/expect@0.34.6":
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.34.6.tgz#608a7b7a9aa3de0919db99b4cc087340a03ea77e"
|
||||
integrity sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==
|
||||
dependencies:
|
||||
"@vitest/spy" "0.34.1"
|
||||
"@vitest/utils" "0.34.1"
|
||||
chai "^4.3.7"
|
||||
"@vitest/spy" "0.34.6"
|
||||
"@vitest/utils" "0.34.6"
|
||||
chai "^4.3.10"
|
||||
|
||||
"@vitest/runner@0.34.1":
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.34.1.tgz#23c21ba1db8bff610988c72744db590d0fb6c4ba"
|
||||
integrity sha512-YfQMpYzDsYB7yqgmlxZ06NI4LurHWfrH7Wy3Pvf/z/vwUSgq1zLAb1lWcItCzQG+NVox+VvzlKQrYEXb47645g==
|
||||
"@vitest/runner@0.34.6":
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.34.6.tgz#6f43ca241fc96b2edf230db58bcde5b974b8dcaf"
|
||||
integrity sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==
|
||||
dependencies:
|
||||
"@vitest/utils" "0.34.1"
|
||||
"@vitest/utils" "0.34.6"
|
||||
p-limit "^4.0.0"
|
||||
pathe "^1.1.1"
|
||||
|
||||
"@vitest/snapshot@0.34.1":
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.34.1.tgz#814c65f8e714eaf255f47838541004b2a2ba28e6"
|
||||
integrity sha512-0O9LfLU0114OqdF8lENlrLsnn024Tb1CsS9UwG0YMWY2oGTQfPtkW+B/7ieyv0X9R2Oijhi3caB1xgGgEgclSQ==
|
||||
"@vitest/snapshot@0.34.6":
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.34.6.tgz#b4528cf683b60a3e8071cacbcb97d18b9d5e1d8b"
|
||||
integrity sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==
|
||||
dependencies:
|
||||
magic-string "^0.30.1"
|
||||
pathe "^1.1.1"
|
||||
pretty-format "^29.5.0"
|
||||
|
||||
"@vitest/spy@0.34.1":
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.34.1.tgz#2f77234a3d554c5dea664943f2caaab92d304f3c"
|
||||
integrity sha512-UT4WcI3EAPUNO8n6y9QoEqynGGEPmmRxC+cLzneFFXpmacivjHZsNbiKD88KUScv5DCHVDgdBsLD7O7s1enFcQ==
|
||||
"@vitest/spy@0.34.6":
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.34.6.tgz#b5e8642a84aad12896c915bce9b3cc8cdaf821df"
|
||||
integrity sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==
|
||||
dependencies:
|
||||
tinyspy "^2.1.1"
|
||||
|
||||
"@vitest/utils@0.34.1":
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.1.tgz#e5545c6618775fb9a2dae2a80d94fc2f35222233"
|
||||
integrity sha512-/ql9dsFi4iuEbiNcjNHQWXBum7aL8pyhxvfnD9gNtbjR9fUKAjxhj4AA3yfLXg6gJpMGGecvtF8Au2G9y3q47Q==
|
||||
"@vitest/utils@0.34.6":
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.6.tgz#38a0a7eedddb8e7291af09a2409cb8a189516968"
|
||||
integrity sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==
|
||||
dependencies:
|
||||
diff-sequences "^29.4.3"
|
||||
loupe "^2.3.6"
|
||||
@ -2597,18 +2597,18 @@ caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001517:
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001518.tgz#b3ca93904cb4699c01218246c4d77a71dbe97150"
|
||||
integrity sha512-rup09/e3I0BKjncL+FesTayKtPrdwKhUufQFd3riFw1hHg8JmIFoInYfB102cFcY/pPgGmdyl/iy+jgiDi2vdA==
|
||||
|
||||
chai@^4.3.7:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51"
|
||||
integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==
|
||||
chai@^4.3.10:
|
||||
version "4.3.10"
|
||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384"
|
||||
integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==
|
||||
dependencies:
|
||||
assertion-error "^1.1.0"
|
||||
check-error "^1.0.2"
|
||||
deep-eql "^4.1.2"
|
||||
get-func-name "^2.0.0"
|
||||
loupe "^2.3.1"
|
||||
check-error "^1.0.3"
|
||||
deep-eql "^4.1.3"
|
||||
get-func-name "^2.0.2"
|
||||
loupe "^2.3.6"
|
||||
pathval "^1.1.1"
|
||||
type-detect "^4.0.5"
|
||||
type-detect "^4.0.8"
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
@ -2635,10 +2635,12 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
check-error@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||
integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
|
||||
check-error@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694"
|
||||
integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==
|
||||
dependencies:
|
||||
get-func-name "^2.0.2"
|
||||
|
||||
chokidar@^3.5.3:
|
||||
version "3.5.3"
|
||||
@ -2825,7 +2827,7 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
deep-eql@^4.1.2:
|
||||
deep-eql@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d"
|
||||
integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==
|
||||
@ -3550,6 +3552,11 @@ get-func-name@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
|
||||
integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
|
||||
|
||||
get-func-name@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41"
|
||||
integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
|
||||
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82"
|
||||
@ -4271,7 +4278,7 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
loupe@^2.3.1, loupe@^2.3.6:
|
||||
loupe@^2.3.6:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53"
|
||||
integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==
|
||||
@ -4737,10 +4744,10 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
||||
postcss@^8.4.19, postcss@^8.4.23, postcss@^8.4.26:
|
||||
version "8.4.27"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.27.tgz#234d7e4b72e34ba5a92c29636734349e0d9c3057"
|
||||
integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==
|
||||
postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.31:
|
||||
version "8.4.31"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
|
||||
integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
|
||||
dependencies:
|
||||
nanoid "^3.3.6"
|
||||
picocolors "^1.0.0"
|
||||
@ -5063,10 +5070,10 @@ rollup@^2.77.2:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
rollup@^3.25.2:
|
||||
version "3.27.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.27.0.tgz#15bd07e2e1cbfa9255bf6a3f04a432621c2f3550"
|
||||
integrity sha512-aOltLCrYZ0FhJDm7fCqwTjIUEVjWjcydKBV/Zeid6Mn8BWgDCUBBWT5beM5ieForYNo/1ZHuGJdka26kvQ3Gzg==
|
||||
rollup@^3.27.1:
|
||||
version "3.29.4"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
|
||||
integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
@ -5520,7 +5527,7 @@ type-check@^0.4.0, type-check@~0.4.0:
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
|
||||
type-detect@^4.0.0, type-detect@^4.0.5:
|
||||
type-detect@^4.0.0, type-detect@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
||||
@ -5681,17 +5688,17 @@ v8-compile-cache-lib@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
|
||||
|
||||
vite-node@0.34.1:
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.1.tgz#144900ca4bd54cc419c501d671350bcbc07eb1ee"
|
||||
integrity sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==
|
||||
vite-node@0.34.6:
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.6.tgz#34d19795de1498562bf21541a58edcd106328a17"
|
||||
integrity sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==
|
||||
dependencies:
|
||||
cac "^6.7.14"
|
||||
debug "^4.3.4"
|
||||
mlly "^1.4.0"
|
||||
pathe "^1.1.1"
|
||||
picocolors "^1.0.0"
|
||||
vite "^3.0.0 || ^4.0.0"
|
||||
vite "^3.0.0 || ^4.0.0 || ^5.0.0-0"
|
||||
|
||||
vite-plugin-eslint@^1.8.1:
|
||||
version "1.8.1"
|
||||
@ -5711,34 +5718,34 @@ vite-tsconfig-paths@^4.2.0:
|
||||
globrex "^0.1.2"
|
||||
tsconfck "^2.1.0"
|
||||
|
||||
"vite@^3.0.0 || ^4.0.0", vite@^4.4.3:
|
||||
version "4.4.8"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.8.tgz#31e4a438f8748695c68bd57ffd262ba93540fdf7"
|
||||
integrity sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==
|
||||
"vite@^3.0.0 || ^4.0.0 || ^5.0.0-0", "vite@^3.1.0 || ^4.0.0 || ^5.0.0-0", vite@^4.4.3:
|
||||
version "4.4.9"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d"
|
||||
integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
|
||||
dependencies:
|
||||
esbuild "^0.18.10"
|
||||
postcss "^8.4.26"
|
||||
rollup "^3.25.2"
|
||||
postcss "^8.4.27"
|
||||
rollup "^3.27.1"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
vitest@^0.34.1:
|
||||
version "0.34.1"
|
||||
resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.34.1.tgz#3ad7f845e7a9fb0d72ab703cae832a54b8469e1e"
|
||||
integrity sha512-G1PzuBEq9A75XSU88yO5G4vPT20UovbC/2osB2KEuV/FisSIIsw7m5y2xMdB7RsAGHAfg2lPmp2qKr3KWliVlQ==
|
||||
vitest@^0.34.6:
|
||||
version "0.34.6"
|
||||
resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.34.6.tgz#44880feeeef493c04b7f795ed268f24a543250d7"
|
||||
integrity sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==
|
||||
dependencies:
|
||||
"@types/chai" "^4.3.5"
|
||||
"@types/chai-subset" "^1.3.3"
|
||||
"@types/node" "*"
|
||||
"@vitest/expect" "0.34.1"
|
||||
"@vitest/runner" "0.34.1"
|
||||
"@vitest/snapshot" "0.34.1"
|
||||
"@vitest/spy" "0.34.1"
|
||||
"@vitest/utils" "0.34.1"
|
||||
"@vitest/expect" "0.34.6"
|
||||
"@vitest/runner" "0.34.6"
|
||||
"@vitest/snapshot" "0.34.6"
|
||||
"@vitest/spy" "0.34.6"
|
||||
"@vitest/utils" "0.34.6"
|
||||
acorn "^8.9.0"
|
||||
acorn-walk "^8.2.0"
|
||||
cac "^6.7.14"
|
||||
chai "^4.3.7"
|
||||
chai "^4.3.10"
|
||||
debug "^4.3.4"
|
||||
local-pkg "^0.4.3"
|
||||
magic-string "^0.30.1"
|
||||
@ -5748,8 +5755,8 @@ vitest@^0.34.1:
|
||||
strip-literal "^1.0.1"
|
||||
tinybench "^2.5.0"
|
||||
tinypool "^0.7.0"
|
||||
vite "^3.0.0 || ^4.0.0"
|
||||
vite-node "0.34.1"
|
||||
vite "^3.1.0 || ^4.0.0 || ^5.0.0-0"
|
||||
vite-node "0.34.6"
|
||||
why-is-node-running "^2.2.2"
|
||||
|
||||
vscode-jsonrpc@8.1.0, vscode-jsonrpc@^8.1.0:
|
||||
|
Reference in New Issue
Block a user