diff --git a/.github/workflows/ci-typescript.yaml b/.github/workflows/ci-typescript.yaml index 1c174753..c2cae32c 100644 --- a/.github/workflows/ci-typescript.yaml +++ b/.github/workflows/ci-typescript.yaml @@ -37,19 +37,29 @@ jobs: pnpm install - name: Generate - run: | - mkdir -p ./out/ && - protoc protobuf_definitions/*.proto \ - --plugin=./node_modules/.bin/protoc-gen-ts_proto \ - --proto_path=protobuf_definitions \ - --ts_proto_out=./out \ - --ts_proto_opt=outputIndex=true \ - --ts_proto_opt=globalThisPolyfill=true \ - --ts_proto_opt=useExactTypes=false + run: pnpm run generate - name: Compile run: pnpm run build + - name: Verify package entrypoints + run: | + SMOKE=$(mktemp -d) + TARBALL=$(pnpm pack --pack-destination "$SMOKE" | tail -1) + cd "$SMOKE" + npm init -y > /dev/null + npm install "$TARBALL" > /dev/null + node --input-type=module -e " + import { blueye } from '@blueyerobotics/protocol-definitions'; + if (!blueye.protocol.GetBatteryReq) throw new Error('missing expected export'); + console.log('ESM import OK'); + " + node --input-type=commonjs -e " + const { blueye } = require('@blueyerobotics/protocol-definitions'); + if (!blueye.protocol.GetBatteryReq) throw new Error('missing expected export'); + console.log('CJS require OK'); + " + - name: Publish to npm run: | cp README.npm.md README.md diff --git a/.gitignore b/.gitignore index a4b51f5d..afc52765 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,9 @@ bin obj out +# typescript outputs +dist + # Other build build_imx diff --git a/CLAUDE.md b/CLAUDE.md index 3f3ae27d..0440ca9d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,17 +22,19 @@ cmake --install build --prefix /usr/local ### TypeScript ``` pnpm install -# Generate TypeScript from proto files: -mkdir -p ./out/ && protoc protobuf_definitions/*.proto \ - --plugin=./node_modules/.bin/protoc-gen-ts_proto \ - --proto_path=protobuf_definitions \ - --ts_proto_out=./out \ - --ts_proto_opt=outputIndex=true \ - --ts_proto_opt=globalThisPolyfill=true \ - --ts_proto_opt=useExactTypes=false -# Compile TypeScript: -pnpm run build +pnpm run generate # generate TypeScript from proto files into ./out (requires protoc) +pnpm run build # compile ./out into ./dist ``` +The protoc flags live in the `generate` script in `package.json`; CI runs the same +script, so keep changes in one place. `--ts_proto_opt=importSuffix=.js` is required — +the package compiles as ESM with `moduleResolution: NodeNext`, which needs explicit +file extensions on relative imports. + +The npm package ships ES modules only — `"type": "module"` plus an `exports` map, +with no separate CommonJS build. The `.` entry uses a `default` condition rather +than `import`, so `require()` still resolves on Node.js 22.12+ via `require(esm)`; +an `import` condition would match ESM callers only and fail everything else with +`ERR_PACKAGE_PATH_NOT_EXPORTED`. The `./dist/*` subpath keeps deep imports working. ### C#/.NET ``` diff --git a/README.npm.md b/README.npm.md index 95bd9896..efb261c5 100644 --- a/README.npm.md +++ b/README.npm.md @@ -2,12 +2,46 @@ TypeScript protobuf definitions for Blueye Robotics protocols generated using [ts-proto](https://github.com/stephenh/ts-proto). +## Protocol version + +This package implements **version 3** of the Blueye communication protocol, used by +drones running Blunux 3.0 and newer. Older drones use the separate +[legacy protocol](https://github.com/BluEye-Robotics/blueye.legacyprotocol). + +The npm version above tracks releases of *this package* — packaging, module format +and generated API surface — and is independent of the protocol version. A major +version bump here does not indicate a new protocol generation. + ## Installation ```bash npm install @blueyerobotics/protocol-definitions ``` +## Module format + +This package ships ES modules only — there is no separate CommonJS build. Both +`import` and `require()` work on current Node.js releases. + +```ts +import { blueye } from "@blueyerobotics/protocol-definitions"; +``` + +`require()` is supported on Node.js 22.12+ (or 20.19+), which can load an ES +module from CommonJS: + +```js +const { blueye } = require("@blueyerobotics/protocol-definitions"); +``` + +On older Node.js versions `require()` fails with `ERR_REQUIRE_ESM` — use `import` +or a dynamic `await import()` instead. + +The package root is the supported entry point. Individual generated modules stay +reachable under `./dist/` (for example +`@blueyerobotics/protocol-definitions/dist/telemetry.js`) if you want to import a +single protocol file to keep bundles small. + ## Usage ```ts diff --git a/package.json b/package.json index aa763b88..73988db1 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,26 @@ { "name": "@blueyerobotics/protocol-definitions", - "version": "3.2.0", + "version": "4.0.0", "license": "LGPL-3.0-only", "description": "TypeScript definitions for Blueye Robotics protocols", "repository": { "type": "git", "url": "https://github.com/BluEye-Robotics/ProtocolDefinitions.git" }, - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/*": "./dist/*" + }, + "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { + "generate": "rm -rf out && mkdir -p out && protoc protobuf_definitions/*.proto --plugin=./node_modules/.bin/protoc-gen-ts_proto --proto_path=protobuf_definitions --ts_proto_out=./out --ts_proto_opt=outputIndex=true --ts_proto_opt=globalThisPolyfill=true --ts_proto_opt=useExactTypes=false --ts_proto_opt=esModuleInterop=true --ts_proto_opt=importSuffix=.js", "build": "tsc" }, "dependencies": { diff --git a/tsconfig.json b/tsconfig.json index fc30754e..54339cbc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { - "target": "ES2020", - "module": "CommonJS", + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", "declaration": true, "outDir": "dist", "strict": true,