Compare commits
17 Commits
franknoiro
...
iterion/en
Author | SHA1 | Date | |
---|---|---|---|
37f1518d59 | |||
cbddb3553d | |||
a24789d944 | |||
dd754c78ab | |||
150f56b47a | |||
f417727a7f | |||
3efdba9cae | |||
0eef6ab7d3 | |||
91d3ba3fce | |||
7165aa1b41 | |||
1a73a640f4 | |||
691a98d345 | |||
18995802f2 | |||
5bb6607452 | |||
e446b71ab6 | |||
05c5a782c2 | |||
cf480bb679 |
@ -297,7 +297,7 @@ jobs:
|
|||||||
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
||||||
|
|
||||||
- name: Upload release files to public bucket
|
- name: Upload release files to public bucket
|
||||||
uses: google-github-actions/upload-cloud-storage@v2.1.3
|
uses: google-github-actions/upload-cloud-storage@v2.2.0
|
||||||
with:
|
with:
|
||||||
path: out
|
path: out
|
||||||
glob: 'Zoo*'
|
glob: 'Zoo*'
|
||||||
@ -305,7 +305,7 @@ jobs:
|
|||||||
destination: ${{ env.BUCKET_DIR }}
|
destination: ${{ env.BUCKET_DIR }}
|
||||||
|
|
||||||
- name: Upload update endpoint to public bucket
|
- name: Upload update endpoint to public bucket
|
||||||
uses: google-github-actions/upload-cloud-storage@v2.1.3
|
uses: google-github-actions/upload-cloud-storage@v2.2.0
|
||||||
with:
|
with:
|
||||||
path: out
|
path: out
|
||||||
glob: 'latest*'
|
glob: 'latest*'
|
||||||
@ -313,7 +313,7 @@ jobs:
|
|||||||
destination: ${{ env.BUCKET_DIR }}
|
destination: ${{ env.BUCKET_DIR }}
|
||||||
|
|
||||||
- name: Upload download endpoint to public bucket
|
- name: Upload download endpoint to public bucket
|
||||||
uses: google-github-actions/upload-cloud-storage@v2.1.3
|
uses: google-github-actions/upload-cloud-storage@v2.2.0
|
||||||
with:
|
with:
|
||||||
path: last_download.json
|
path: last_download.json
|
||||||
destination: ${{ env.BUCKET_DIR }}
|
destination: ${{ env.BUCKET_DIR }}
|
||||||
|
4
.github/workflows/playwright.yml
vendored
4
.github/workflows/playwright.yml
vendored
@ -262,7 +262,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-14]
|
os: [ubuntu-latest, windows-latest, macos-14]
|
||||||
timeout-minutes: 30
|
timeout-minutes: 40
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
needs: check-rust-changes
|
needs: check-rust-changes
|
||||||
steps:
|
steps:
|
||||||
@ -381,7 +381,7 @@ jobs:
|
|||||||
echo "retried=true" >>$GITHUB_OUTPUT
|
echo "retried=true" >>$GITHUB_OUTPUT
|
||||||
echo "run playwright with last failed tests and retry $retry"
|
echo "run playwright with last failed tests and retry $retry"
|
||||||
if [[ "$IS_UBUNTU" == "true" ]]; then
|
if [[ "$IS_UBUNTU" == "true" ]]; then
|
||||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn playwright test --config=playwright.electron.config.ts --grep=@electron || true
|
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn playwright test --config=playwright.electron.config.ts --last-failed --grep=@electron || true
|
||||||
else
|
else
|
||||||
yarn playwright test --config=playwright.electron.config.ts --grep=@electron || true
|
yarn playwright test --config=playwright.electron.config.ts --grep=@electron || true
|
||||||
fi
|
fi
|
||||||
|
8
Makefile
8
Makefile
@ -7,6 +7,14 @@ XSTATE_TYPEGENS := $(wildcard src/machines/*.typegen.ts)
|
|||||||
dev: node_modules public/wasm_lib_bg.wasm $(XSTATE_TYPEGENS)
|
dev: node_modules public/wasm_lib_bg.wasm $(XSTATE_TYPEGENS)
|
||||||
yarn start
|
yarn start
|
||||||
|
|
||||||
|
# I'm sorry this is so specific to my setup you may as well ignore this.
|
||||||
|
# This is so you don't have to deal with electron windows popping up constantly.
|
||||||
|
# It should work for you other Linux users.
|
||||||
|
lee-electron-test:
|
||||||
|
Xephyr -br -ac -noreset -screen 1200x500 :2 &
|
||||||
|
DISPLAY=:2 NODE_ENV=development PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn tron:test -g "when using the file tree"
|
||||||
|
killall Xephyr
|
||||||
|
|
||||||
$(XSTATE_TYPEGENS): $(TS_SRC)
|
$(XSTATE_TYPEGENS): $(TS_SRC)
|
||||||
yarn xstate typegen 'src/**/*.ts?(x)'
|
yarn xstate typegen 'src/**/*.ts?(x)'
|
||||||
|
|
||||||
|
@ -27,9 +27,19 @@ test.describe('Code pane and errors', () => {
|
|||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
// Load the app with the working starter code
|
// Load the app with the working starter code
|
||||||
await page.addInitScript((code) => {
|
await page.addInitScript(() => {
|
||||||
localStorage.setItem('persistCode', code)
|
localStorage.setItem(
|
||||||
}, bracket)
|
'persistCode',
|
||||||
|
`// Extruded Triangle
|
||||||
|
const sketch001 = startSketchOn('XZ')
|
||||||
|
|> startProfileAt([0, 0], %)
|
||||||
|
|> line([10, 0], %)
|
||||||
|
|> line([-5, 10], %)
|
||||||
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|
|> close(%)
|
||||||
|
const extrude001 = extrude(5, sketch001)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
|
@ -43,12 +43,6 @@ test(
|
|||||||
// open the project
|
// open the project
|
||||||
await page.getByText(`bracket`).click()
|
await page.getByText(`bracket`).click()
|
||||||
|
|
||||||
// wait for the project to load
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
// expect zero errors in guter
|
// expect zero errors in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
|
||||||
@ -56,6 +50,12 @@ test(
|
|||||||
const exportButton = page.getByTestId('export-pane-button')
|
const exportButton = page.getByTestId('export-pane-button')
|
||||||
await expect(exportButton).toBeVisible()
|
await expect(exportButton).toBeVisible()
|
||||||
|
|
||||||
|
// Wait for the model to finish loading
|
||||||
|
const modelStateIndicator = page.getByTestId(
|
||||||
|
'model-state-indicator-execution-done'
|
||||||
|
)
|
||||||
|
await expect(modelStateIndicator).toBeVisible({ timeout: 60000 })
|
||||||
|
|
||||||
const gltfOption = page.getByText('glTF')
|
const gltfOption = page.getByText('glTF')
|
||||||
const submitButton = page.getByText('Confirm Export')
|
const submitButton = page.getByText('Confirm Export')
|
||||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
const exportingToastMessage = page.getByText(`Exporting...`)
|
||||||
@ -104,7 +104,7 @@ test(
|
|||||||
},
|
},
|
||||||
{ timeout: 15_000 }
|
{ timeout: 15_000 }
|
||||||
)
|
)
|
||||||
.toBe(477327)
|
.toBe(477481)
|
||||||
|
|
||||||
// clean up output.gltf
|
// clean up output.gltf
|
||||||
await fsp.rm('output.gltf')
|
await fsp.rm('output.gltf')
|
||||||
|
@ -173,10 +173,10 @@ test.describe('Can export from electron app', () => {
|
|||||||
// gray at this pixel means the stream has loaded in the most
|
// gray at this pixel means the stream has loaded in the most
|
||||||
// user way we can verify it (pixel color)
|
// user way we can verify it (pixel color)
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [75, 75, 75]), {
|
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
|
||||||
timeout: 10_000,
|
timeout: 10_000,
|
||||||
})
|
})
|
||||||
.toBeLessThan(10)
|
.toBeLessThan(15)
|
||||||
})
|
})
|
||||||
|
|
||||||
const exportLocations: Array<Paths> = []
|
const exportLocations: Array<Paths> = []
|
||||||
@ -207,7 +207,7 @@ test.describe('Can export from electron app', () => {
|
|||||||
},
|
},
|
||||||
{ timeout: 15_000 }
|
{ timeout: 15_000 }
|
||||||
)
|
)
|
||||||
.toBe(477327)
|
.toBe(477481)
|
||||||
|
|
||||||
// clean up output.gltf
|
// clean up output.gltf
|
||||||
await fsp.rm('output.gltf')
|
await fsp.rm('output.gltf')
|
||||||
@ -495,10 +495,6 @@ test(
|
|||||||
|
|
||||||
await file.click()
|
await file.click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
await expect(u.codeLocator).toContainText(
|
await expect(u.codeLocator).toContainText(
|
||||||
'A mounting bracket for the Focusrite Scarlett Solo audio interface'
|
'A mounting bracket for the Focusrite Scarlett Solo audio interface'
|
||||||
)
|
)
|
||||||
@ -856,10 +852,10 @@ const extrude001 = extrude(200, sketch001)`)
|
|||||||
// gray at this pixel means the stream has loaded in the most
|
// gray at this pixel means the stream has loaded in the most
|
||||||
// user way we can verify it (pixel color)
|
// user way we can verify it (pixel color)
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [132, 132, 132]), {
|
.poll(() => u.getGreatestPixDiff(pointOnModel, [143, 143, 143]), {
|
||||||
timeout: 10_000,
|
timeout: 10_000,
|
||||||
})
|
})
|
||||||
.toBeLessThan(10)
|
.toBeLessThan(15)
|
||||||
|
|
||||||
await expect(async () => {
|
await expect(async () => {
|
||||||
await page.mouse.move(0, 0, { steps: 5 })
|
await page.mouse.move(0, 0, { steps: 5 })
|
||||||
@ -867,8 +863,8 @@ const extrude001 = extrude(200, sketch001)`)
|
|||||||
await page.mouse.click(pointOnModel.x, pointOnModel.y)
|
await page.mouse.click(pointOnModel.x, pointOnModel.y)
|
||||||
// check user can interact with model by checking it turns yellow
|
// check user can interact with model by checking it turns yellow
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [176, 180, 132]))
|
.poll(() => u.getGreatestPixDiff(pointOnModel, [180, 180, 137]))
|
||||||
.toBeLessThan(10)
|
.toBeLessThan(15)
|
||||||
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||||
|
|
||||||
await page.getByTestId('app-logo').click()
|
await page.getByTestId('app-logo').click()
|
||||||
@ -956,10 +952,10 @@ test(
|
|||||||
// gray at this pixel means the stream has loaded in the most
|
// gray at this pixel means the stream has loaded in the most
|
||||||
// user way we can verify it (pixel color)
|
// user way we can verify it (pixel color)
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [75, 75, 75]), {
|
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
|
||||||
timeout: 10_000,
|
timeout: 10_000,
|
||||||
})
|
})
|
||||||
.toBeLessThan(10)
|
.toBeLessThan(15)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
||||||
@ -990,10 +986,10 @@ test(
|
|||||||
// gray at this pixel means the stream has loaded in the most
|
// gray at this pixel means the stream has loaded in the most
|
||||||
// user way we can verify it (pixel color)
|
// user way we can verify it (pixel color)
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [132, 132, 132]), {
|
.poll(() => u.getGreatestPixDiff(pointOnModel, [143, 143, 143]), {
|
||||||
timeout: 10_000,
|
timeout: 10_000,
|
||||||
})
|
})
|
||||||
.toBeLessThan(10)
|
.toBeLessThan(15)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Opening the router-template project should load the stream', async () => {
|
await test.step('Opening the router-template project should load the stream', async () => {
|
||||||
|
@ -358,6 +358,7 @@ const sketch001 = startSketchAt([-0, -0])
|
|||||||
await page.addInitScript(
|
await page.addInitScript(
|
||||||
async ({ code }) => {
|
async ({ code }) => {
|
||||||
localStorage.setItem('persistCode', code)
|
localStorage.setItem('persistCode', code)
|
||||||
|
;(window as any).playwrightSkipFilePicker = true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: bracket,
|
code: bracket,
|
||||||
@ -393,20 +394,22 @@ const sketch001 = startSketchAt([-0, -0])
|
|||||||
await test.step('The second export is blocked', async () => {
|
await test.step('The second export is blocked', async () => {
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
await Promise.all([
|
||||||
await expect(alreadyExportingToastMessage).toBeVisible()
|
expect(exportingToastMessage.first()).toBeVisible(),
|
||||||
|
expect(alreadyExportingToastMessage).toBeVisible(),
|
||||||
await page.waitForTimeout(1000)
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('The first export still succeeds', async () => {
|
await test.step('The first export still succeeds', async () => {
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
await Promise.all([
|
||||||
await expect(errorToastMessage).not.toBeVisible()
|
expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 }),
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
expect(errorToastMessage).not.toBeVisible(),
|
||||||
|
expect(engineErrorToastMessage).not.toBeVisible(),
|
||||||
await expect(successToastMessage).toBeVisible()
|
expect(successToastMessage).toBeVisible({ timeout: 15_000 }),
|
||||||
|
expect(alreadyExportingToastMessage).not.toBeVisible({
|
||||||
await expect(alreadyExportingToastMessage).not.toBeVisible()
|
timeout: 15_000,
|
||||||
|
}),
|
||||||
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -419,10 +422,12 @@ const sketch001 = startSketchAt([-0, -0])
|
|||||||
await expect(exportingToastMessage).toBeVisible()
|
await expect(exportingToastMessage).toBeVisible()
|
||||||
|
|
||||||
// Expect it to succeed.
|
// Expect it to succeed.
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
await Promise.all([
|
||||||
await expect(errorToastMessage).not.toBeVisible()
|
expect(exportingToastMessage).not.toBeVisible(),
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
expect(errorToastMessage).not.toBeVisible(),
|
||||||
await expect(alreadyExportingToastMessage).not.toBeVisible()
|
expect(engineErrorToastMessage).not.toBeVisible(),
|
||||||
|
expect(alreadyExportingToastMessage).not.toBeVisible(),
|
||||||
|
])
|
||||||
|
|
||||||
await expect(successToastMessage).toBeVisible()
|
await expect(successToastMessage).toBeVisible()
|
||||||
})
|
})
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
@ -773,9 +773,9 @@ const extrude001 = extrude(50, sketch001)
|
|||||||
|
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
let noHoverColor: [number, number, number] = [82, 82, 82]
|
let noHoverColor: [number, number, number] = [92, 92, 92]
|
||||||
let hoverColor: [number, number, number] = [116, 116, 116]
|
let hoverColor: [number, number, number] = [127, 127, 127]
|
||||||
let selectColor: [number, number, number] = [144, 148, 97]
|
let selectColor: [number, number, number] = [155, 155, 105]
|
||||||
|
|
||||||
const extrudeWall = { x: 670, y: 275 }
|
const extrudeWall = { x: 670, y: 275 }
|
||||||
const extrudeText = `line([170.36, -121.61], %, $seg01)`
|
const extrudeText = `line([170.36, -121.61], %, $seg01)`
|
||||||
@ -787,7 +787,7 @@ const extrude001 = extrude(50, sketch001)
|
|||||||
|
|
||||||
await expect
|
await expect
|
||||||
.poll(() => u.getGreatestPixDiff(extrudeWall, noHoverColor))
|
.poll(() => u.getGreatestPixDiff(extrudeWall, noHoverColor))
|
||||||
.toBeLessThan(5)
|
.toBeLessThan(15)
|
||||||
await page.mouse.move(nothing.x, nothing.y)
|
await page.mouse.move(nothing.x, nothing.y)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.move(extrudeWall.x, extrudeWall.y)
|
await page.mouse.move(extrudeWall.x, extrudeWall.y)
|
||||||
@ -798,43 +798,43 @@ const extrude001 = extrude(50, sketch001)
|
|||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await expect(
|
await expect(
|
||||||
await u.getGreatestPixDiff(extrudeWall, hoverColor)
|
await u.getGreatestPixDiff(extrudeWall, hoverColor)
|
||||||
).toBeLessThan(6)
|
).toBeLessThan(15)
|
||||||
await page.mouse.click(extrudeWall.x, extrudeWall.y)
|
await page.mouse.click(extrudeWall.x, extrudeWall.y)
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`|> ${extrudeText}`)
|
await expect(page.locator('.cm-activeLine')).toHaveText(`|> ${extrudeText}`)
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await expect(
|
await expect(
|
||||||
await u.getGreatestPixDiff(extrudeWall, selectColor)
|
await u.getGreatestPixDiff(extrudeWall, selectColor)
|
||||||
).toBeLessThan(6)
|
).toBeLessThan(15)
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
// check color stays there, i.e. not overridden (this was a bug previously)
|
// check color stays there, i.e. not overridden (this was a bug previously)
|
||||||
await expect(
|
await expect(
|
||||||
await u.getGreatestPixDiff(extrudeWall, selectColor)
|
await u.getGreatestPixDiff(extrudeWall, selectColor)
|
||||||
).toBeLessThan(6)
|
).toBeLessThan(15)
|
||||||
|
|
||||||
await page.mouse.move(nothing.x, nothing.y)
|
await page.mouse.move(nothing.x, nothing.y)
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
|
await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
|
||||||
|
|
||||||
// because of shading, color is not exact everywhere on the face
|
// because of shading, color is not exact everywhere on the face
|
||||||
noHoverColor = [104, 104, 104]
|
noHoverColor = [115, 115, 115]
|
||||||
hoverColor = [134, 134, 134]
|
hoverColor = [145, 145, 145]
|
||||||
selectColor = [158, 162, 110]
|
selectColor = [168, 168, 120]
|
||||||
|
|
||||||
await expect(await u.getGreatestPixDiff(cap, noHoverColor)).toBeLessThan(6)
|
await expect(await u.getGreatestPixDiff(cap, noHoverColor)).toBeLessThan(15)
|
||||||
await page.mouse.move(cap.x, cap.y)
|
await page.mouse.move(cap.x, cap.y)
|
||||||
await expect(page.getByTestId('hover-highlight').first()).toBeVisible()
|
await expect(page.getByTestId('hover-highlight').first()).toBeVisible()
|
||||||
await expect(page.getByTestId('hover-highlight').first()).toContainText(
|
await expect(page.getByTestId('hover-highlight').first()).toContainText(
|
||||||
removeAfterFirstParenthesis(capText)
|
removeAfterFirstParenthesis(capText)
|
||||||
)
|
)
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await expect(await u.getGreatestPixDiff(cap, hoverColor)).toBeLessThan(6)
|
await expect(await u.getGreatestPixDiff(cap, hoverColor)).toBeLessThan(15)
|
||||||
await page.mouse.click(cap.x, cap.y)
|
await page.mouse.click(cap.x, cap.y)
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`|> ${capText}`)
|
await expect(page.locator('.cm-activeLine')).toHaveText(`|> ${capText}`)
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(6)
|
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(15)
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
// check color stays there, i.e. not overridden (this was a bug previously)
|
// check color stays there, i.e. not overridden (this was a bug previously)
|
||||||
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(6)
|
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(15)
|
||||||
})
|
})
|
||||||
test("Various pipe expressions should and shouldn't allow edit and or extrude", async ({
|
test("Various pipe expressions should and shouldn't allow edit and or extrude", async ({
|
||||||
page,
|
page,
|
||||||
|
@ -233,10 +233,6 @@ test.describe('Testing settings', () => {
|
|||||||
`Project settings override user settings on desktop`,
|
`Project settings override user settings on desktop`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ browser: _ }, testInfo) => {
|
async ({ browser: _ }, testInfo) => {
|
||||||
test.skip(
|
|
||||||
process.platform === 'win32',
|
|
||||||
'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557'
|
|
||||||
)
|
|
||||||
const { electronApp, page } = await setupElectron({
|
const { electronApp, page } = await setupElectron({
|
||||||
testInfo,
|
testInfo,
|
||||||
folderSetupFn: async (dir) => {
|
folderSetupFn: async (dir) => {
|
||||||
@ -276,11 +272,26 @@ test.describe('Testing settings', () => {
|
|||||||
await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor)
|
await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor)
|
||||||
await settingsCloseButton.click()
|
await settingsCloseButton.click()
|
||||||
})
|
})
|
||||||
|
let screenshot = await page.screenshot()
|
||||||
|
await testInfo.attach('screenshot1', {
|
||||||
|
body: screenshot,
|
||||||
|
contentType: 'image/png',
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('Set project theme color', async () => {
|
await test.step('Set project theme color', async () => {
|
||||||
// Open the project
|
// Open the project
|
||||||
await projectLink.click()
|
await projectLink.click()
|
||||||
|
screenshot = await page.screenshot()
|
||||||
|
await testInfo.attach('screenshot2', {
|
||||||
|
body: screenshot,
|
||||||
|
contentType: 'image/png',
|
||||||
|
})
|
||||||
await settingsOpenButton.click()
|
await settingsOpenButton.click()
|
||||||
|
screenshot = await page.screenshot()
|
||||||
|
await testInfo.attach('screenshot3', {
|
||||||
|
body: screenshot,
|
||||||
|
contentType: 'image/png',
|
||||||
|
})
|
||||||
// The project tab should be selected by default within a project
|
// The project tab should be selected by default within a project
|
||||||
await expect(projectSettingsTab).toBeChecked()
|
await expect(projectSettingsTab).toBeChecked()
|
||||||
await themeColorSetting.fill(projectThemeColor)
|
await themeColorSetting.fill(projectThemeColor)
|
||||||
|
@ -47,7 +47,6 @@ nsis:
|
|||||||
oneClick: false
|
oneClick: false
|
||||||
perMachine: true
|
perMachine: true
|
||||||
allowElevation: true
|
allowElevation: true
|
||||||
license: "LICENSE"
|
|
||||||
installerIcon: "assets/icon.ico"
|
installerIcon: "assets/icon.ico"
|
||||||
include: "./installer.nsh"
|
include: "./installer.nsh"
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"decamelize": "^6.0.0",
|
"decamelize": "^6.0.0",
|
||||||
"electron-squirrel-startup": "^1.0.1",
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
"electron-updater": "^6.2.1",
|
"electron-updater": "^6.3.0",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"html2canvas-pro": "^1.5.8",
|
"html2canvas-pro": "^1.5.8",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
|
@ -2,7 +2,7 @@ import { CommandLog } from 'lang/std/engineConnection'
|
|||||||
import { engineCommandManager } from 'lib/singletons'
|
import { engineCommandManager } from 'lib/singletons'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
|
|
||||||
function useEngineCommands(): [CommandLog[], () => void] {
|
export function useEngineCommands(): [CommandLog[], () => void] {
|
||||||
const [engineCommands, setEngineCommands] = useState<CommandLog[]>(
|
const [engineCommands, setEngineCommands] = useState<CommandLog[]>(
|
||||||
engineCommandManager.commandLogs
|
engineCommandManager.commandLogs
|
||||||
)
|
)
|
||||||
|
@ -179,10 +179,7 @@ const FileTreeItem = ({
|
|||||||
codeManager.writeToFile()
|
codeManager.writeToFile()
|
||||||
|
|
||||||
// Prevent seeing the model built one piece at a time when changing files
|
// Prevent seeing the model built one piece at a time when changing files
|
||||||
kclManager.isFirstRender = true
|
kclManager.executeCode(true)
|
||||||
kclManager.executeCode(true).then(() => {
|
|
||||||
kclManager.isFirstRender = false
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
// Let the lsp servers know we closed a file.
|
// Let the lsp servers know we closed a file.
|
||||||
onFileClose(currentFile?.path || null, project?.path || null)
|
onFileClose(currentFile?.path || null, project?.path || null)
|
||||||
|
@ -11,6 +11,8 @@ import {
|
|||||||
|
|
||||||
import { engineCommandManager } from '../lib/singletons'
|
import { engineCommandManager } from '../lib/singletons'
|
||||||
|
|
||||||
|
import { Spinner } from './Spinner'
|
||||||
|
|
||||||
const Loading = ({ children }: React.PropsWithChildren) => {
|
const Loading = ({ children }: React.PropsWithChildren) => {
|
||||||
const [error, setError] = useState<ConnectionError>(ConnectionError.Unset)
|
const [error, setError] = useState<ConnectionError>(ConnectionError.Unset)
|
||||||
|
|
||||||
@ -65,17 +67,7 @@ const Loading = ({ children }: React.PropsWithChildren) => {
|
|||||||
className="body-bg flex flex-col items-center justify-center h-screen"
|
className="body-bg flex flex-col items-center justify-center h-screen"
|
||||||
data-testid="loading"
|
data-testid="loading"
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 10 10" className="w-8 h-8">
|
<Spinner />
|
||||||
<circle
|
|
||||||
cx="5"
|
|
||||||
cy="5"
|
|
||||||
r="4"
|
|
||||||
stroke="var(--primary)"
|
|
||||||
fill="none"
|
|
||||||
strokeDasharray="4, 4"
|
|
||||||
className="animate-spin origin-center"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<p className="text-base mt-4 text-primary">{children || 'Loading'}</p>
|
<p className="text-base mt-4 text-primary">{children || 'Loading'}</p>
|
||||||
<p
|
<p
|
||||||
className={
|
className={
|
||||||
|
@ -11,6 +11,7 @@ import toast from 'react-hot-toast'
|
|||||||
import { CoreDumpManager } from 'lib/coredump'
|
import { CoreDumpManager } from 'lib/coredump'
|
||||||
import openWindow, { openExternalBrowserIfDesktop } from 'lib/openWindow'
|
import openWindow, { openExternalBrowserIfDesktop } from 'lib/openWindow'
|
||||||
import { NetworkMachineIndicator } from './NetworkMachineIndicator'
|
import { NetworkMachineIndicator } from './NetworkMachineIndicator'
|
||||||
|
import { ModelStateIndicator } from './ModelStateIndicator'
|
||||||
|
|
||||||
export function LowerRightControls({
|
export function LowerRightControls({
|
||||||
children,
|
children,
|
||||||
@ -65,6 +66,7 @@ export function LowerRightControls({
|
|||||||
<section className="fixed bottom-2 right-2 flex flex-col items-end gap-3 pointer-events-none">
|
<section className="fixed bottom-2 right-2 flex flex-col items-end gap-3 pointer-events-none">
|
||||||
{children}
|
{children}
|
||||||
<menu className="flex items-center justify-end gap-3 pointer-events-auto">
|
<menu className="flex items-center justify-end gap-3 pointer-events-auto">
|
||||||
|
{!location.pathname.startsWith(PATHS.HOME) && <ModelStateIndicator />}
|
||||||
<a
|
<a
|
||||||
onClick={openExternalBrowserIfDesktop(
|
onClick={openExternalBrowserIfDesktop(
|
||||||
`https://github.com/KittyCAD/modeling-app/releases/tag/v${APP_VERSION}`
|
`https://github.com/KittyCAD/modeling-app/releases/tag/v${APP_VERSION}`
|
||||||
|
39
src/components/ModelStateIndicator.tsx
Normal file
39
src/components/ModelStateIndicator.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { useEngineCommands } from './EngineCommands'
|
||||||
|
import { Spinner } from './Spinner'
|
||||||
|
import { CustomIcon } from './CustomIcon'
|
||||||
|
|
||||||
|
export const ModelStateIndicator = () => {
|
||||||
|
const [commands] = useEngineCommands()
|
||||||
|
|
||||||
|
const lastCommandType = commands[commands.length - 1]?.type
|
||||||
|
|
||||||
|
let className = 'w-6 h-6 '
|
||||||
|
let icon = <Spinner className={className} />
|
||||||
|
let dataTestId = 'model-state-indicator'
|
||||||
|
|
||||||
|
if (lastCommandType === 'receive-reliable') {
|
||||||
|
className +=
|
||||||
|
'bg-chalkboard-20 dark:bg-chalkboard-80 !group-disabled:bg-chalkboard-30 !dark:group-disabled:bg-chalkboard-80 rounded-sm bg-succeed-10/30 dark:bg-succeed'
|
||||||
|
icon = (
|
||||||
|
<CustomIcon
|
||||||
|
data-testid={dataTestId + '-receive-reliable'}
|
||||||
|
name="checkmark"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
} else if (lastCommandType === 'execution-done') {
|
||||||
|
className +=
|
||||||
|
'border-6 border border-solid border-chalkboard-60 dark:border-chalkboard-80 bg-chalkboard-20 dark:bg-chalkboard-80 !group-disabled:bg-chalkboard-30 !dark:group-disabled:bg-chalkboard-80 rounded-sm bg-succeed-10/30 dark:bg-succeed'
|
||||||
|
icon = (
|
||||||
|
<CustomIcon
|
||||||
|
data-testid={dataTestId + '-execution-done'}
|
||||||
|
name="checkmark"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={className} data-testid="model-state-indicator">
|
||||||
|
{icon}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -66,7 +66,6 @@ import {
|
|||||||
hasExtrudableGeometry,
|
hasExtrudableGeometry,
|
||||||
isSingleCursorInPipe,
|
isSingleCursorInPipe,
|
||||||
} from 'lang/queryAst'
|
} from 'lang/queryAst'
|
||||||
import { TEST } from 'env'
|
|
||||||
import { exportFromEngine } from 'lib/exportFromEngine'
|
import { exportFromEngine } from 'lib/exportFromEngine'
|
||||||
import { Models } from '@kittycad/lib/dist/types/src'
|
import { Models } from '@kittycad/lib/dist/types/src'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
@ -161,9 +160,7 @@ export const ModelingMachineProvider = ({
|
|||||||
|
|
||||||
store.videoElement?.pause()
|
store.videoElement?.pause()
|
||||||
|
|
||||||
kclManager.isFirstRender = true
|
|
||||||
kclManager.executeCode().then(() => {
|
kclManager.executeCode().then(() => {
|
||||||
kclManager.isFirstRender = false
|
|
||||||
if (engineCommandManager.engineConnection?.idleMode) return
|
if (engineCommandManager.engineConnection?.idleMode) return
|
||||||
|
|
||||||
store.videoElement?.play().catch((e) => {
|
store.videoElement?.play().catch((e) => {
|
||||||
@ -363,7 +360,7 @@ export const ModelingMachineProvider = ({
|
|||||||
return {}
|
return {}
|
||||||
}),
|
}),
|
||||||
Make: async (_, event) => {
|
Make: async (_, event) => {
|
||||||
if (event.type !== 'Make' || TEST) return
|
if (event.type !== 'Make') return
|
||||||
// Check if we already have an export intent.
|
// Check if we already have an export intent.
|
||||||
if (engineCommandManager.exportIntent) {
|
if (engineCommandManager.exportIntent) {
|
||||||
toast.error('Already exporting')
|
toast.error('Already exporting')
|
||||||
@ -407,7 +404,7 @@ export const ModelingMachineProvider = ({
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
'Engine export': async (_, event) => {
|
'Engine export': async (_, event) => {
|
||||||
if (event.type !== 'Export' || TEST) return
|
if (event.type !== 'Export') return
|
||||||
if (engineCommandManager.exportIntent) {
|
if (engineCommandManager.exportIntent) {
|
||||||
toast.error('Already exporting')
|
toast.error('Already exporting')
|
||||||
return
|
return
|
||||||
|
@ -193,10 +193,7 @@ export const SettingsAuthProviderBase = ({
|
|||||||
resetSettingsIncludesUnitChange
|
resetSettingsIncludesUnitChange
|
||||||
) {
|
) {
|
||||||
// Unit changes requires a re-exec of code
|
// Unit changes requires a re-exec of code
|
||||||
kclManager.isFirstRender = true
|
kclManager.executeCode(true)
|
||||||
kclManager.executeCode(true).then(() => {
|
|
||||||
kclManager.isFirstRender = false
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
// For any future logging we'd like to do
|
// For any future logging we'd like to do
|
||||||
// console.log(
|
// console.log(
|
||||||
|
17
src/components/Spinner.tsx
Normal file
17
src/components/Spinner.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { SVGProps } from 'react'
|
||||||
|
|
||||||
|
export const Spinner = (props: SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg viewBox="0 0 10 10" className={'w-8 h-8'} {...props}>
|
||||||
|
<circle
|
||||||
|
cx="5"
|
||||||
|
cy="5"
|
||||||
|
r="4"
|
||||||
|
stroke="var(--primary)"
|
||||||
|
fill="none"
|
||||||
|
strokeDasharray="4, 4"
|
||||||
|
className="animate-spin origin-center"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
@ -54,12 +54,10 @@ export const Stream = () => {
|
|||||||
* central place, we can move this code there.
|
* central place, we can move this code there.
|
||||||
*/
|
*/
|
||||||
async function executeCodeAndPlayStream() {
|
async function executeCodeAndPlayStream() {
|
||||||
kclManager.isFirstRender = true
|
|
||||||
kclManager.executeCode(true).then(() => {
|
kclManager.executeCode(true).then(() => {
|
||||||
videoRef.current?.play().catch((e) => {
|
videoRef.current?.play().catch((e) => {
|
||||||
console.warn('Video playing was prevented', e, videoRef.current)
|
console.warn('Video playing was prevented', e, videoRef.current)
|
||||||
})
|
})
|
||||||
kclManager.isFirstRender = false
|
|
||||||
setStreamState(StreamState.Playing)
|
setStreamState(StreamState.Playing)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -219,7 +217,7 @@ export const Stream = () => {
|
|||||||
* Play the vid
|
* Play the vid
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!kclManager.isFirstRender) {
|
if (!kclManager.isExecuting) {
|
||||||
setTimeout(() =>
|
setTimeout(() =>
|
||||||
// execute in the next event loop
|
// execute in the next event loop
|
||||||
videoRef.current?.play().catch((e) => {
|
videoRef.current?.play().catch((e) => {
|
||||||
@ -227,7 +225,7 @@ export const Stream = () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, [kclManager.isFirstRender])
|
}, [kclManager.isExecuting])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@ -382,15 +380,15 @@ export const Stream = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(!isNetworkOkay || isLoading || kclManager.isFirstRender) && (
|
{(!isNetworkOkay || isLoading) && (
|
||||||
<div className="text-center absolute inset-0">
|
<div className="text-center absolute inset-0">
|
||||||
<Loading>
|
<Loading>
|
||||||
{!isNetworkOkay && !isLoading && !kclManager.isFirstRender ? (
|
{!isNetworkOkay && !isLoading ? (
|
||||||
<span data-testid="loading-stream">Stream disconnected...</span>
|
<span data-testid="loading-stream">Stream disconnected...</span>
|
||||||
) : !isLoading && kclManager.isFirstRender ? (
|
|
||||||
<span data-testid="loading-stream">Building scene...</span>
|
|
||||||
) : (
|
) : (
|
||||||
|
!isLoading && (
|
||||||
<span data-testid="loading-stream">Loading stream...</span>
|
<span data-testid="loading-stream">Loading stream...</span>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</Loading>
|
</Loading>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,8 +60,6 @@ export class KclManager {
|
|||||||
private _wasmInitFailedCallback: (arg: boolean) => void = () => {}
|
private _wasmInitFailedCallback: (arg: boolean) => void = () => {}
|
||||||
private _executeCallback: () => void = () => {}
|
private _executeCallback: () => void = () => {}
|
||||||
|
|
||||||
isFirstRender = true
|
|
||||||
|
|
||||||
get ast() {
|
get ast() {
|
||||||
return this._ast
|
return this._ast
|
||||||
}
|
}
|
||||||
|
@ -95,8 +95,6 @@ export const wasmUrl = () => {
|
|||||||
document.location.pathname.split('/').slice(0, -1).join('/') +
|
document.location.pathname.split('/').slice(0, -1).join('/') +
|
||||||
'/wasm_lib_bg.wasm'
|
'/wasm_lib_bg.wasm'
|
||||||
|
|
||||||
console.log(`Full URL for WASM: ${fullUrl}`)
|
|
||||||
|
|
||||||
return fullUrl
|
return fullUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ const bracket = startSketchOn('XY')
|
|||||||
|> extrude(width, %)
|
|> extrude(width, %)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius: filletR,
|
radius: filletR,
|
||||||
tags: [getPreviousAdjacentEdge(innerEdge)]
|
tags: [getNextAdjacentEdge(innerEdge)]
|
||||||
}, %)
|
}, %)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius: filletR + thickness,
|
radius: filletR + thickness,
|
||||||
tags: [getPreviousAdjacentEdge(outerEdge)]
|
tags: [getNextAdjacentEdge(outerEdge)]
|
||||||
}, %)`
|
}, %)`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +81,6 @@ export class MachineManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._machines = await window.electron.listMachines()
|
this._machines = await window.electron.listMachines()
|
||||||
console.log('Machines:', this._machines)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateMachineApiIp(): Promise<void> {
|
private async updateMachineApiIp(): Promise<void> {
|
||||||
|
@ -16,7 +16,6 @@ window.tearDown = engineCommandManager.tearDown
|
|||||||
|
|
||||||
// This needs to be after codeManager is created.
|
// This needs to be after codeManager is created.
|
||||||
export const kclManager = new KclManager(engineCommandManager)
|
export const kclManager = new KclManager(engineCommandManager)
|
||||||
kclManager.isFirstRender = true
|
|
||||||
engineCommandManager.kclManager = kclManager
|
engineCommandManager.kclManager = kclManager
|
||||||
|
|
||||||
engineCommandManager.getAstCb = () => kclManager.ast
|
engineCommandManager.getAstCb = () => kclManager.ast
|
||||||
|
@ -107,10 +107,7 @@ function OnboardingWarningWeb(props: OnboardingResetWarningProps) {
|
|||||||
codeManager.updateCodeStateEditor(bracket)
|
codeManager.updateCodeStateEditor(bracket)
|
||||||
await codeManager.writeToFile()
|
await codeManager.writeToFile()
|
||||||
|
|
||||||
kclManager.isFirstRender = true
|
await kclManager.executeCode(true)
|
||||||
await kclManager.executeCode(true).then(() => {
|
|
||||||
kclManager.isFirstRender = false
|
|
||||||
})
|
|
||||||
props.setShouldShowWarning(false)
|
props.setShouldShowWarning(false)
|
||||||
}}
|
}}
|
||||||
nextText="Overwrite code and continue"
|
nextText="Overwrite code and continue"
|
||||||
|
@ -13,10 +13,7 @@ export default function Sketching() {
|
|||||||
async function clearEditor() {
|
async function clearEditor() {
|
||||||
// We do want to update both the state and editor here.
|
// We do want to update both the state and editor here.
|
||||||
codeManager.updateCodeStateEditor('')
|
codeManager.updateCodeStateEditor('')
|
||||||
kclManager.isFirstRender = true
|
await kclManager.executeCode(true)
|
||||||
await kclManager.executeCode(true).then(() => {
|
|
||||||
kclManager.isFirstRender = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearEditor()
|
clearEditor()
|
||||||
|
@ -82,10 +82,7 @@ export function useDemoCode() {
|
|||||||
if (!editorManager.editorView || codeManager.code === bracket) return
|
if (!editorManager.editorView || codeManager.code === bracket) return
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
codeManager.updateCodeStateEditor(bracket)
|
codeManager.updateCodeStateEditor(bracket)
|
||||||
kclManager.isFirstRender = true
|
await kclManager.executeCode(true)
|
||||||
await kclManager.executeCode(true).then(() => {
|
|
||||||
kclManager.isFirstRender = false
|
|
||||||
})
|
|
||||||
await codeManager.writeToFile()
|
await codeManager.writeToFile()
|
||||||
})
|
})
|
||||||
}, [editorManager.editorView])
|
}, [editorManager.editorView])
|
||||||
|
6
src/wasm-lib/Cargo.lock
generated
6
src/wasm-lib/Cargo.lock
generated
@ -672,7 +672,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive-docs"
|
name = "derive-docs"
|
||||||
version = "0.1.25"
|
version = "0.1.26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -1345,7 +1345,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.2.11"
|
version = "0.2.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx",
|
"approx",
|
||||||
@ -1417,7 +1417,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "derive-docs"
|
name = "derive-docs"
|
||||||
description = "A tool for generating documentation from Rust derive macros"
|
description = "A tool for generating documentation from Rust derive macros"
|
||||||
version = "0.1.25"
|
version = "0.1.26"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
description = "A test server for KCL"
|
description = "A test server for KCL"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language implementation and tools"
|
description = "KittyCAD Language implementation and tools"
|
||||||
version = "0.2.11"
|
version = "0.2.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
@ -20,7 +20,7 @@ clap = { version = "4.5.16", default-features = false, optional = true, features
|
|||||||
convert_case = "0.6.0"
|
convert_case = "0.6.0"
|
||||||
dashmap = "6.0.1"
|
dashmap = "6.0.1"
|
||||||
databake = { version = "0.1.8", features = ["derive"] }
|
databake = { version = "0.1.8", features = ["derive"] }
|
||||||
derive-docs = { version = "0.1.24", path = "../derive-docs" }
|
derive-docs = { version = "0.1.26", path = "../derive-docs" }
|
||||||
form_urlencoded = "1.2.1"
|
form_urlencoded = "1.2.1"
|
||||||
futures = { version = "0.3.30" }
|
futures = { version = "0.3.30" }
|
||||||
git_rev = "0.1.0"
|
git_rev = "0.1.0"
|
||||||
|
@ -55,10 +55,10 @@ const bracketBody = bs
|
|||||||
|> fillet({
|
|> fillet({
|
||||||
radius: radius,
|
radius: radius,
|
||||||
tags: [
|
tags: [
|
||||||
getNextAdjacentEdge(bs.tags.edge7),
|
getPreviousAdjacentEdge(bs.tags.edge7),
|
||||||
getNextAdjacentEdge(bs.tags.edge2),
|
getPreviousAdjacentEdge(bs.tags.edge2),
|
||||||
getNextAdjacentEdge(bs.tags.edge3),
|
getPreviousAdjacentEdge(bs.tags.edge3),
|
||||||
getNextAdjacentEdge(bs.tags.edge6)
|
getPreviousAdjacentEdge(bs.tags.edge6)
|
||||||
]
|
]
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
|
18
yarn.lock
18
yarn.lock
@ -3668,6 +3668,14 @@ builder-util-runtime@9.2.4:
|
|||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
sax "^1.2.4"
|
sax "^1.2.4"
|
||||||
|
|
||||||
|
builder-util-runtime@9.2.5:
|
||||||
|
version "9.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.5.tgz#0afdffa0adb5c84c14926c7dd2cf3c6e96e9be83"
|
||||||
|
integrity sha512-HjIDfhvqx/8B3TDN4GbABQcgpewTU4LMRTQPkVpKYV3lsuxEJoIfvg09GyWTNmfVNSUAYf+fbTN//JX4TH20pg==
|
||||||
|
dependencies:
|
||||||
|
debug "^4.3.4"
|
||||||
|
sax "^1.2.4"
|
||||||
|
|
||||||
builder-util@24.13.1:
|
builder-util@24.13.1:
|
||||||
version "24.13.1"
|
version "24.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.13.1.tgz#4a4c4f9466b016b85c6990a0ea15aa14edec6816"
|
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.13.1.tgz#4a4c4f9466b016b85c6990a0ea15aa14edec6816"
|
||||||
@ -4613,12 +4621,12 @@ electron-to-chromium@^1.5.4:
|
|||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6"
|
||||||
integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==
|
integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==
|
||||||
|
|
||||||
electron-updater@^6.2.1:
|
electron-updater@^6.3.0:
|
||||||
version "6.2.1"
|
version "6.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.2.1.tgz#1c9adb9ba2a21a5dc50a8c434c45360d5e9fe6c9"
|
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.3.0.tgz#13a5c3c3f0b2b114fe33181e24a8270096734b3e"
|
||||||
integrity sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==
|
integrity sha512-3Xlezhk+dKaSQrOnkQNqCGiuGSSUPO9BV9TQZ4Iig6AyTJ4FzJONE5gFFc382sY53Sh9dwJfzKsA3DxRHt2btw==
|
||||||
dependencies:
|
dependencies:
|
||||||
builder-util-runtime "9.2.4"
|
builder-util-runtime "9.2.5"
|
||||||
fs-extra "^10.1.0"
|
fs-extra "^10.1.0"
|
||||||
js-yaml "^4.1.0"
|
js-yaml "^4.1.0"
|
||||||
lazy-val "^1.0.5"
|
lazy-val "^1.0.5"
|
||||||
|
Reference in New Issue
Block a user