@viamrobotics/test-widgets 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,65 +1,46 @@
1
- # Svelte library
2
-
3
- Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
4
-
5
- Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
-
7
- ## Creating a project
8
-
9
- If you're seeing this, you've probably already done this step. Congrats!
10
-
11
- ```sh
12
- # create a new project in the current directory
13
- npx sv create
14
-
15
- # create a new project in my-app
16
- npx sv create my-app
17
- ```
18
-
19
- To recreate this project with the same configuration:
20
-
21
- ```sh
22
- # recreate this project
23
- pnpm dlx sv@0.12.8 create --template library --types ts --add prettier eslint vitest="usages:unit,component" playwright tailwindcss="plugins:none" sveltekit-adapter="adapter:static" devtools-json mcp="ide:claude-code+setup:remote" --install pnpm my-app
24
- ```
25
-
26
- ## Developing
27
-
28
- Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
29
-
30
- ```sh
31
- npm run dev
32
-
33
- # or start the server and open the app in a new browser tab
34
- npm run dev -- --open
35
- ```
36
-
37
- Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
38
-
39
- ## Building
40
-
41
- To build your library:
42
-
43
- ```sh
44
- npm pack
45
- ```
46
-
47
- To create a production version of your showcase app:
48
-
49
- ```sh
50
- npm run build
51
- ```
52
-
53
- You can preview the production build with `npm run preview`.
54
-
55
- > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
56
-
57
- ## Publishing
58
-
59
- Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
60
-
61
- To publish your library to [npm](https://www.npmjs.com):
62
-
63
- ```sh
64
- npm publish
1
+ # @viamrobotics/test-widgets
2
+
3
+ A library of Svelte components for interacting with Viam-powered machines. Each widget provides a test interface for a specific resource type -- arms, bases, cameras, motors, sensors, and more -- allowing users to send commands, view live data, and control hardware directly from the browser.
4
+
5
+ Also includes reusable building blocks for visualizations, such as maps (MapLibre), SLAM mapping, 3D point clouds (Three.js), etc.
6
+
7
+ ## Playground
8
+
9
+ The playground (`pnpm dev`) can be used to develop the test-cards against prod robots with prod modules.
10
+
11
+ This is useful if you need to validate the sdk against specific behavior of modules or need to replicate a bug from another robot (why replicate locally when you could just develop directly against the robot with the bug?).
12
+
13
+ To setup your playground, create a `.env.local` in the test-cards directory with the following format (no need to create two robots):
14
+
15
+ ```json
16
+ VITE_PLAYGROUND_ROBOTS='
17
+ {
18
+ "some prod robot": {
19
+ "host": "fleet-rover-01-main.ve4ba7w5qr.viam.cloud",
20
+ "partId": "<PART-ID>",
21
+ "apiKeyId": "<API-KEY-ID>",
22
+ "apiKeyValue": "<API-KEY-VALUE>",
23
+ "signalingAddress": "https://app.viam.com:443"
24
+ },
25
+ "some staging robot name": {
26
+ "host": "fleet-rover-02-main.ytobojb44p.viamstg.cloud",
27
+ "partId": "<PART-ID>",
28
+ "apiKeyId": "<API-KEY-ID>",
29
+ "apiKeyValue": "<API-KEY-VALUE>",
30
+ "signalingAddress": "https://app.viam.dev:443"
31
+ },
32
+ "local-machine (no fqdn)": {
33
+ "host": "localhost:8080",
34
+ "serviceHost": "http://localhost:8080",
35
+ "partId": "local-machine (no fqdn)",
36
+ "signalingAddress": ""
37
+ },
38
+ "local-machine (fqdn)": {
39
+ "host": "something-unique",
40
+ "serviceHost": "http://localhost:8080",
41
+ "partId": "local-machine (fqdn)",
42
+ "signalingAddress": ""
43
+ }
44
+ }
45
+ '
65
46
  ```
@@ -1,9 +1,8 @@
1
1
  <script lang="ts">
2
- import type { ResizeDetail } from '@svelte-put/resize'
3
2
  import type { QueryObserverResult } from '@tanstack/svelte-query'
4
3
  import type { Snippet } from 'svelte'
5
4
 
6
- import { resize } from '@svelte-put/resize'
5
+ import { useResizeObserver } from 'runed'
7
6
 
8
7
  import ContentRect from './content-rect.svelte'
9
8
  import ErrorDisplay from './error.svelte'
@@ -17,10 +16,15 @@
17
16
 
18
17
  const { queries, contentCx = '', children }: Props = $props()
19
18
 
20
- let contentRect = $state<DOMRect>()
21
- const handleResize = (event: CustomEvent<ResizeDetail>) => {
22
- contentRect = event.detail.entry.contentRect
23
- }
19
+ let el = $state.raw<HTMLDivElement>()
20
+ let contentRect = $state.raw<DOMRect>()
21
+
22
+ useResizeObserver(
23
+ () => el,
24
+ ([entry]) => {
25
+ contentRect = entry.contentRect
26
+ }
27
+ )
24
28
 
25
29
  let errors = $state.raw<Error[]>([])
26
30
  let data = $state.raw<unknown[]>([])
@@ -65,8 +69,7 @@
65
69
  {:else}
66
70
  <div
67
71
  class="w-full"
68
- use:resize
69
- onresized={handleResize}
72
+ bind:this={el}
70
73
  >
71
74
  {@render children?.({ data })}
72
75
  </div>
@@ -2,7 +2,6 @@
2
2
  import { Button, Label, Switch, ToggleButtons } from '@viamrobotics/prime-core'
3
3
  import { CameraClient } from '@viamrobotics/sdk'
4
4
  import { createResourceClient, createResourceQuery } from '@viamrobotics/svelte-sdk'
5
- import { writable } from 'svelte/store'
6
5
 
7
6
  import { useAddImageToDataset } from '../../../add-image-to-dataset'
8
7
  import ConnectionStatus from '../../connection-status.svelte'
@@ -30,7 +29,7 @@
30
29
  () => resourceName,
31
30
  'camera'
32
31
  )
33
- const isShowingPip = writable(false)
32
+ const isShowingPip = $state(false)
34
33
  let isShowingPointcloud = $state(false)
35
34
 
36
35
  const { addImageToDataset } = useAddImageToDataset()
@@ -47,7 +46,7 @@
47
46
  const imageQuery = createResourceQuery(client, 'getImages', () => ({
48
47
  enabled: refetchInterval.current !== RefetchIntervals.LIVE,
49
48
  refetchInterval: refetchInterval.current,
50
- refetchIntervalInBackground: $isShowingPip,
49
+ refetchIntervalInBackground: isShowingPip,
51
50
  }))
52
51
 
53
52
  const pointcloudQuery = createResourceQuery(client, 'getPointCloud', () => ({
@@ -1,12 +1,10 @@
1
1
  <script lang="ts">
2
- import type { ResizeDetail } from '@svelte-put/resize'
3
-
4
2
  import * as Sentry from '@sentry/svelte'
5
- import { resize } from '@svelte-put/resize'
6
3
  import { createMutation, type QueryObserverResult } from '@tanstack/svelte-query'
7
4
  import { Button, Label, Select } from '@viamrobotics/prime-core'
8
5
  import { CameraClient, type RobotClient, streamApi, StreamClient } from '@viamrobotics/sdk'
9
6
  import { useRobotClient } from '@viamrobotics/svelte-sdk'
7
+ import { useResizeObserver } from 'runed'
10
8
  import { untrack } from 'svelte'
11
9
 
12
10
  import { assertExists } from '../../../assert'
@@ -228,9 +226,12 @@
228
226
  })
229
227
 
230
228
  let contentRect = $state.raw<DOMRect>()
231
- const handleResize = (event: CustomEvent<ResizeDetail>) => {
232
- contentRect = event.detail.entry.contentRect
233
- }
229
+ useResizeObserver(
230
+ () => videoElement,
231
+ ([entry]) => {
232
+ contentRect = entry.contentRect
233
+ }
234
+ )
234
235
 
235
236
  let hoverTooltipOpen = $state(false)
236
237
  let mouseHoverImagePosition = $state({ pctX: 0, pctY: 0, absX: 0, absY: 0 })
@@ -340,8 +341,6 @@
340
341
  controls={false}
341
342
  playsinline
342
343
  aria-label={`${resourceName} stream`}
343
- use:resize
344
- onresized={handleResize}
345
344
  >
346
345
  </video>
347
346
  </div>
@@ -1,6 +1,4 @@
1
1
  <script lang="ts">
2
- import type { Writable } from 'svelte/store'
3
-
4
2
  import { Button } from '@viamrobotics/prime-core'
5
3
  import { onMount } from 'svelte'
6
4
 
@@ -9,19 +7,20 @@
9
7
  interface Props {
10
8
  resourceName: string
11
9
  mediaStream: MediaStream | null
12
- isShowingPip: Writable<boolean>
10
+ isShowingPip: boolean
13
11
  }
14
12
 
15
- const { resourceName, mediaStream, isShowingPip }: Props = $props()
13
+ let { resourceName, mediaStream, isShowingPip = $bindable(false) }: Props = $props()
16
14
 
17
15
  let videoElement = $state.raw<HTMLVideoElement>()
18
16
  let lastErr = $state.raw<Error>()
19
17
 
20
18
  const onEnter = () => {
21
- $isShowingPip = true
19
+ isShowingPip = true
22
20
  }
21
+
23
22
  const onLeave = () => {
24
- $isShowingPip = false
23
+ isShowingPip = false
25
24
  }
26
25
 
27
26
  onMount(() => {
@@ -31,7 +30,7 @@
31
30
  return () => {
32
31
  videoElement?.removeEventListener('enterpictureinpicture', onEnter)
33
32
  videoElement?.removeEventListener('leavepictureinpicture', onLeave)
34
- if ($isShowingPip) {
33
+ if (isShowingPip) {
35
34
  document.exitPictureInPicture()
36
35
  }
37
36
  }
@@ -47,7 +46,7 @@
47
46
  lastErr = undefined
48
47
 
49
48
  try {
50
- await ($isShowingPip
49
+ await (isShowingPip
51
50
  ? document.exitPictureInPicture()
52
51
  : videoElement?.requestPictureInPicture())
53
52
  } catch (error) {
@@ -1,9 +1,8 @@
1
- import type { Writable } from 'svelte/store';
2
1
  interface Props {
3
2
  resourceName: string;
4
3
  mediaStream: MediaStream | null;
5
- isShowingPip: Writable<boolean>;
4
+ isShowingPip: boolean;
6
5
  }
7
- declare const PictureInPictureButton: import("svelte").Component<Props, {}, "">;
6
+ declare const PictureInPictureButton: import("svelte").Component<Props, {}, "isShowingPip">;
8
7
  type PictureInPictureButton = ReturnType<typeof PictureInPictureButton>;
9
8
  export default PictureInPictureButton;
@@ -69,7 +69,6 @@
69
69
  </script>
70
70
 
71
71
  <Container
72
- name="Detection {detection.id}"
73
72
  positionType="absolute"
74
73
  positionLeft={factoredxMin}
75
74
  positionTop={factoredyMin}
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
2
  import type { cameraApi, Classification, Detection } from '@viamrobotics/sdk'
3
3
 
4
- import { resize } from '@svelte-put/resize'
5
4
  import { Canvas } from '@threlte/core'
6
5
  import { Progress } from '@viamrobotics/prime-core'
6
+ import { useResizeObserver } from 'runed'
7
7
  import { provideFontFamilies } from 'threlte-uikit'
8
8
 
9
9
  import { useMeasureFps } from '../../../fps.svelte'
@@ -69,6 +69,13 @@
69
69
  let container = $state<HTMLElement>()
70
70
  let size = $state<Size>()
71
71
 
72
+ useResizeObserver(
73
+ () => container,
74
+ () => {
75
+ setSize()
76
+ }
77
+ )
78
+
72
79
  const setSize = () => {
73
80
  if (container) {
74
81
  size = getImageSize(img, container)
@@ -94,8 +101,6 @@
94
101
  <div
95
102
  class="flex h-full min-h-0 w-full min-w-0 gap-2 py-2 pl-2"
96
103
  bind:this={container}
97
- use:resize
98
- onresize={setSize}
99
104
  >
100
105
  {#if !size}
101
106
  <div class="grid w-full place-content-center">
@@ -134,7 +134,10 @@
134
134
  </Select>
135
135
  </Label>
136
136
  </div>
137
- <Label position="top">
137
+ <Label
138
+ cx="w-fit"
139
+ position="top"
140
+ >
138
141
  Is remote?
139
142
  <Switch
140
143
  slot="input"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viamrobotics/test-widgets",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "files": [
@@ -27,76 +27,86 @@
27
27
  "url": "git+https://github.com/viamrobotics/test-widgets.git"
28
28
  },
29
29
  "peerDependencies": {
30
- "svelte": "^5.0.0"
30
+ "@sentry/svelte": ">=8",
31
+ "@threlte/core": ">=8",
32
+ "@threlte/extras": ">=9",
33
+ "@viamrobotics/prime-core": ">=0.1",
34
+ "@viamrobotics/prime-editor": ">=0.0.2",
35
+ "@viamrobotics/sdk": ">=0.68",
36
+ "@viamrobotics/svelte-sdk": ">=1.1",
37
+ "lodash-es": ">=4",
38
+ "runed": ">=0.28",
39
+ "svelte": ">=5",
40
+ "three": ">=0.178",
41
+ "threlte-uikit": ">=2"
31
42
  },
32
43
  "devDependencies": {
33
44
  "@changesets/cli": "^2.30.0",
34
- "@eslint/compat": "^2.0.3",
45
+ "@eslint/compat": "^2.0.5",
35
46
  "@eslint/js": "^10.0.1",
36
47
  "@fontsource-variable/public-sans": "^5.2.7",
37
48
  "@fontsource-variable/roboto-mono": "^5.2.8",
38
49
  "@fontsource-variable/space-grotesk": "^5.2.10",
39
50
  "@playwright/test": "^1.59.1",
40
- "@sentry/svelte": "^10.47.0",
41
- "@svelte-put/resize": "^4.0.0",
51
+ "@sentry/svelte": "^10.48.0",
42
52
  "@sveltejs/adapter-static": "^3.0.10",
43
- "@sveltejs/kit": "^2.55.0",
53
+ "@sveltejs/kit": "^2.57.1",
44
54
  "@sveltejs/package": "^2.5.7",
45
55
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
46
56
  "@tailwindcss/postcss": "^4.2.2",
47
57
  "@tailwindcss/vite": "^4.2.2",
48
- "@tanstack/svelte-query": "^6.1.12",
49
- "@tanstack/svelte-query-devtools": "^6.1.12",
58
+ "@tanstack/svelte-query": "^6.1.16",
59
+ "@tanstack/svelte-query-devtools": "^6.1.16",
50
60
  "@testing-library/dom": "^10.4.1",
51
61
  "@testing-library/jest-dom": "^6.9.1",
52
62
  "@testing-library/svelte": "^5.3.1",
53
63
  "@testing-library/user-event": "^14.6.1",
54
- "@threlte/core": "^8.5.5",
55
- "@threlte/extras": "^9.14.2",
56
- "@threlte/test": "^1.0.0",
64
+ "@threlte/core": "^8.5.9",
65
+ "@threlte/extras": "^9.14.6",
66
+ "@threlte/test": "^2.0.2",
57
67
  "@types/lodash-es": "^4.17.12",
58
68
  "@types/node": "^25",
59
69
  "@types/three": "^0.183.1",
60
- "@viamrobotics/motion-tools": "^1.16.0",
70
+ "@viamrobotics/motion-tools": "^1.18.1",
61
71
  "@viamrobotics/prime-core": "^0.1.16",
62
72
  "@viamrobotics/prime-editor": "^0.0.2",
63
- "@viamrobotics/sdk": "^0.68.1",
64
- "@viamrobotics/svelte-sdk": "^1.1.5",
73
+ "@viamrobotics/sdk": "^0.68.2",
74
+ "@viamrobotics/svelte-sdk": "^1.1.6",
65
75
  "@viamrobotics/tailwind-config": "^1.0.0",
66
76
  "@viamrobotics/three": "^0.0.9",
67
- "@vitest/browser": "^4.1.2",
68
- "@vitest/browser-playwright": "^4.1.2",
69
- "@vitest/coverage-v8": "^4.1.2",
70
- "eslint": "^10.1.0",
77
+ "@vitest/browser": "^4.1.4",
78
+ "@vitest/browser-playwright": "^4.1.4",
79
+ "@vitest/coverage-v8": "^4.1.4",
80
+ "eslint": "^10.2.0",
71
81
  "eslint-config-prettier": "^10.1.8",
72
82
  "eslint-plugin-perfectionist": "^5.8.0",
73
- "eslint-plugin-svelte": "^3.16.0",
83
+ "eslint-plugin-svelte": "^3.17.0",
74
84
  "eslint-plugin-unicorn": "^64.0.0",
75
- "globals": "^17.4.0",
85
+ "globals": "^17.5.0",
76
86
  "lodash-es": "^4.18.1",
77
- "maplibre-gl": "^5.21.1",
87
+ "maplibre-gl": "^5.23.0",
78
88
  "mock-match-media": "^1.0.3",
79
89
  "playwright": "^1.59.1",
80
- "prettier": "^3.8.1",
90
+ "prettier": "^3.8.3",
81
91
  "prettier-plugin-svelte": "^3.5.1",
82
92
  "prettier-plugin-tailwindcss": "^0.7.2",
83
93
  "publint": "^0.3.18",
84
94
  "runed": "^0.37.1",
85
- "svelte": "^5.55.1",
95
+ "svelte": "^5.55.4",
86
96
  "svelte-check": "^4.4.6",
87
97
  "svelte-splitpanes": "^8.0.12",
88
98
  "tailwind-merge": "^3.5.0",
89
99
  "tailwindcss": "^4.2.2",
90
100
  "three": "^0.183.2",
91
- "threlte-uikit": "^1.2.1",
101
+ "threlte-uikit": "^2.0.0",
92
102
  "type-fest": "^5.5.0",
93
103
  "typescript": "^6.0.2",
94
- "typescript-eslint": "^8.58.0",
95
- "vite": "^8.0.3",
104
+ "typescript-eslint": "^8.58.2",
105
+ "vite": "^8.0.8",
96
106
  "vite-plugin-devtools-json": "^1.0.0",
97
- "vite-plugin-glsl": "^1.5.6",
98
- "vitest": "^4.1.2",
99
- "vitest-browser-svelte": "^2.1.0"
107
+ "vite-plugin-glsl": "^1.6.0",
108
+ "vitest": "^4.1.4",
109
+ "vitest-browser-svelte": "^2.1.1"
100
110
  },
101
111
  "engines": {
102
112
  "node": ">=22.12.0"