Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,5 @@ docs/dist
src/api-version.ts

*.DS_Store

playwright-report/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this since I was running the playwright tests locally.

20 changes: 10 additions & 10 deletions Node.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Node & Viam's TypeScript SDK
# Node.js & Viam's TypeScript SDK
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the official name "Node.js" for consistency across the documentation.


This document contains detailed instructions on including Viam in your Node project. For a runnable example, see the [examples directory](/examples/node/).
This document contains detailed instructions on including Viam in your Node.js project. For a runnable example, see the [examples directory](/examples/node/).

## Requirements

This document assumes you already have Node installed. If not, follow the [instructions](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs) provided by Node.
This document assumes you already have Node.js >= version 20 installed. If not, follow the [instructions](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs) provided by Node.js.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --env-file flag was introduced in v20, so calling this out just in case some folks are running v18 which is still under long term support.


### Dependencies

Expand All @@ -19,25 +19,25 @@ You can use either Yarn or NPM to install the dependencies. This document will u

### Polyfills

Using the SDK with Node also requires the use of some polyfills. In your application's entrypoint (`main.ts`, `index.ts`, or something similar), you will need to register those polyfills:
Using the SDK with Node.js also requires the use of some polyfills. In your application's entrypoint (`main.ts`, `index.ts`, or something similar), you will need to register those polyfills:

```ts
// main.ts

import wrtc = require('node-datachannel/polyfill');
const wrtc = require('node-datachannel/polyfill');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node.js supports two module formats: CommonJS (require) and ESM (import). While they can be mixed together in some programs, the expected syntax for each format is different. If we wanted to use ESM import statements it would look a little like reversed Python:

import wrtc from 'node-datachannel/polyfill';

However after updating the example code to use ESM, it appears the Viam TypeScript SDK does not have an ESM compatible module export for Node.js at the moment. So I've updated the example code to use CommonJS for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file works fine for me in Node 20 mod your API key secret fix

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import wrtc = require('node-datachannel/polyfill') works in Node 20? That's quite odd since it doesn't work in the REPL:

image

Could tsc be transpiling the code to be valid?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes tsc or tsx would transpile to js since node can't run typescript.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe eslint/the community in general prefers ESM style imports in TS? At least i often see lint errors when i do const foo = require('bar')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node 22 can run TypeScript with the experimental type stripping flag and would fail with the example code as is. I think we should have valid JS in the examples, even if tsc papers over the syntax errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe eslint/the community in general prefers ESM style imports in TS? At least i often see lint errors when i do const foo = require('bar')

Yes, ESM is the official standard and should be used when possible. However, the current build output of the TS SDK cannot be imported as ESM in Node.js:

image

(The above example in the REPL is using the dynamic ESM import syntax but the same error applies when running main.ts with static ESM imports)

for (const key in wrtc) {
(global as any)[key] = (wrtc as any)[key];
}
```

### Transport

Communicating with your Viam machine in Node requires the use of a custom transport. In your app's entrypoint, you will also need to register the custom transport:
Communicating with your Viam machine in Node.js requires the use of a custom transport. In your app's entrypoint, you will also need to register the custom transport:

```ts
// main.ts

import connectNode = require('@connectrpc/connect-node');
const connectNode = require('@connectrpc/connect-node');
globalThis.VIAM = {
GRPC_TRANSPORT_FACTORY: (opts: any) =>
connectNode.createGrpcTransport({ httpVersion: '2', ...opts }),
Expand All @@ -51,9 +51,9 @@ To use the SDK, you can use similar instructions to those found on the [document
```ts
// main.ts

import VIAM = require('@viamrobotics/sdk');
import wrtc = require('node-datachannel/polyfill');
import connectNode = require('@connectrpc/connect-node');
const VIAM = require('@viamrobotics/sdk');
const wrtc = require('node-datachannel/polyfill');
const connectNode = require('@connectrpc/connect-node');
globalThis.VIAM = {
GRPC_TRANSPORT_FACTORY: (opts: any) =>
connectNode.createGrpcTransport({ httpVersion: '2', ...opts }),
Expand Down
8 changes: 4 additions & 4 deletions e2e/tests/connect-and-status.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ test('check resource names and multiple statuses', async ({ page }) => {
const resourceNames = page
.getByTestId('resource-names')
.getByTestId('resource-name');
await expect(resourceNames).toHaveCount(4);
await expect(resourceNames).toHaveCount(3);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why the number of builtin resources is only 1 now, maybe something changed in the server implementation. It appears to be unrelated to my changes.

await expect(resourceNames.getByText('base1')).toHaveCount(1);
await expect(resourceNames.getByText('servo1')).toHaveCount(1);
await expect(resourceNames.getByText('builtin')).toHaveCount(2);
await expect(resourceNames.getByText('builtin')).toHaveCount(1);

// 3 status iterations * 4 resource names (see main.ts for loop)
// 3 status iterations * 3 resource names (see main.ts for loop)
const statuses = page.getByTestId('statuses').getByTestId('status');
await expect(statuses).toHaveCount(12);
await expect(statuses).toHaveCount(9);
});
24 changes: 12 additions & 12 deletions examples/node/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Viam SDK Quickstart - Node
# Viam SDK Quickstart - Node.js

This example demonstrates how to connect to a machine using Node.js.

## Usage

You must have a `.env` file in this directory with the following connection info which can be easily found in the TypeScript code sample for your machine.
You must have a `.env` file in this directory with the following connection info which can be easily found in the TypeScript code sample for your machine. Use the `authEntity` value from the Code Sample as the `API_KEY_ID` and the `payload` value as the `API_KEY`.

```
HOST="<HOST>"
Expand Down Expand Up @@ -42,18 +42,18 @@ The `main.ts` file was updated to include the following polyfills and updates:
- WebRTC Polyfills:

```js
import wrtc = require('node-datachannel/polyfill');
for (const key in wrtc) {
(global as any)[key] = (wrtc as any)[key];
}
const wrtc = require('node-datachannel/polyfill');
for (const key in wrtc) {
(global as any)[key] = (wrtc as any)[key];
}
```

- GRPC connection configuration
```js
import VIAM = require('@viamrobotics/sdk');
globalThis.VIAM = {
// @ts-ignore
GRPC_TRANSPORT_FACTORY: (opts: any) =>
connectNode.createGrpcTransport({ httpVersion: '2', ...opts }),
};
const VIAM = require('@viamrobotics/sdk');
globalThis.VIAM = {
// @ts-ignore
GRPC_TRANSPORT_FACTORY: (opts: any) =>
connectNode.createGrpcTransport({ httpVersion: '2', ...opts }),
};
```
Loading