Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit exports so that types match code #122

Merged
merged 6 commits into from
Jun 6, 2023
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
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ If any entity institutes patent litigation - including cross-claim or countercla
**3. Source of Contribution.**

Your contribution is either your original creation, based upon previous work that, to the best of your knowledge, is covered under an appropriate open source license and you have the right under that license to submit that work with modifications, whether created in whole or in part by you, or you have clearly identified the source of the contribution and any license or other restriction (like related patents, trademarks, and license agreements) of which you are personally aware.

## Releasing a new version

1. Update [HISTORY.md](./HISTORY.md) with the changes since the last release.
2. Run `yarn version` to pick the new version.
3. Create a new pull request with these changes.
4. After the pull request has been merged to `main` run `yarn publish`. Pick the same version as above.
5. Create a [Github release](https://github.com/cruise-automation/rosbag.js/releases/new) for the version.
9 changes: 9 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# 4.0.1

* Add explicit exports so that types match code.
* Export `OpenBag` type.

# 4.0.0

* Convert to Typescript

# 2.5.0

* Added MessageWriter functionality, and deprecated passing the unparsed message definitions direction to MessageReader.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rosbag",
"version": "4.0.0",
"version": "4.0.1",
"license": "Apache-2.0",
"repository": "cruise-automation/rosbag.js",
"dependencies": {
Expand Down
26 changes: 17 additions & 9 deletions src/bag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ export type ReadOptions = {
freeze?: boolean;
};

/**
* Represents a bag that has been opened, which guarantees certain properties are available.
*/
// eslint-disable-next-line no-use-before-define
export interface OpenBag extends Bag {
header: BagHeader;
connections: Record<number, Connection>;
chunkInfos: ChunkInfo[];
}

/**
* The high level rosbag interface.
*
Expand All @@ -46,7 +56,7 @@ export default class Bag {
this.reader = bagReader;
}

static open = (_file: File | string): Promise<Bag> =>
static open = (_file: File | string): Promise<OpenBag> =>
Promise.reject(
new Error(
"This method should have been overridden based on the environment. Make sure you are correctly importing the node or web version of Bag."
Expand All @@ -62,9 +72,11 @@ export default class Bag {

/**
* If the bag is manually created with the constructor, you must call `await open()` on the bag.
* Generally this is called for you if you're using `const bag = await Bag.open()`
* Generally this is called for you if you're using `const bag = await Bag.open()`.
*
* Returns `this` with the type of `OpenBag`.
*/
async open() {
async open(): Promise<OpenBag> {
this.header = await this.reader.readHeaderAsync();
const { connectionCount, chunkCount, indexPosition } = this.header;

Expand All @@ -89,6 +101,8 @@ export default class Bag {
.map((x) => x.endTime)
.reduce((prev, current) => (TimeUtil.compare(prev, current) > 0 ? prev : current));
}

return this as OpenBag;
}

async readMessages(opts: ReadOptions, callback: (msg: ReadResult<unknown>) => void) {
Expand Down Expand Up @@ -149,9 +163,3 @@ export default class Bag {
}
}
}

interface OpenBag extends Bag {
header: BagHeader;
connections: Record<number, Connection>;
chunkInfos: ChunkInfo[];
}
21 changes: 21 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as TypeExports from ".";
import * as NodeExports from "./node";
import * as WebExports from "./web";

describe("exports", () => {
it("matches web and node exports", () => {
// Remove exports that are implemented differently between Node and Web.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { open: _typeOpen, ...TypeSharedExports } = TypeExports;
const { open: nodeOpen, Reader: NodeReader, ...NodeSharedExports } = NodeExports;
const { open: webOpen, Reader: WebReader, ...WebSharedExports } = WebExports;

expect(nodeOpen).toEqual(expect.any(Function));
expect(NodeReader).toEqual(expect.any(Function));
expect(webOpen).toEqual(expect.any(Function));
expect(WebReader).toEqual(expect.any(Function));

expect(NodeSharedExports).toEqual(TypeSharedExports);
expect(WebSharedExports).toEqual(TypeSharedExports);
});
});
36 changes: 29 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,35 @@
// found in the LICENSE file in the root directory of this source tree.
// You may not use this file except in compliance with the License.

import BagReader from "./BagReader";
import { MessageReader } from "./MessageReader";
import { MessageWriter } from "./MessageWriter";
import * as TimeUtil from "./TimeUtil";
import Bag, { OpenBag } from "./bag";
import { extractFields, extractTime } from "./fields";
import { parseMessageDefinition, rosPrimitiveTypes } from "./parseMessageDefinition";
import { Filelike } from "./types";

export * from "./bag";
export * from "./BagReader";
export * from "./MessageReader";
export * from "./MessageWriter";
export * from "./parseMessageDefinition";
const { open } = Bag;

export declare class Reader implements Filelike {
read(): void;
size(): number;
}

// These exports must match node/index.ts and web/index.ts
export * from "./types";
export * from "./fields";
export { TimeUtil };
export {
TimeUtil,
Bag,
OpenBag,
BagReader,
MessageReader,
MessageWriter,
open,
parseMessageDefinition,
rosPrimitiveTypes,
extractFields,
extractTime,
};
export default Bag;
8 changes: 5 additions & 3 deletions src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
extractTime,
} from "../index";
import type { Callback } from "../types";
import Bag from "../bag";
import Bag, { OpenBag } from "../bag";
import BagReader from "../BagReader";

// reader using nodejs fs api
Expand Down Expand Up @@ -78,7 +78,7 @@ export class Reader {
}
}

const open = async (filename: File | string) => {
const open = async (filename: File | string): Promise<OpenBag> => {
if (typeof filename !== "string") {
throw new Error(
"Expected filename to be a string. Make sure you are correctly importing the node or web version of Bag."
Expand All @@ -87,14 +87,16 @@ const open = async (filename: File | string) => {

const bag = new Bag(new BagReader(new Reader(filename)));
await bag.open();
return bag;
return bag as OpenBag;
};

Bag.open = open;

// These exports must match ../index.ts
export * from "../types";
export {
TimeUtil,
Bag,
BagReader,
MessageReader,
MessageWriter,
Expand Down
8 changes: 5 additions & 3 deletions src/web/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
extractTime,
} from "../index";
import type { Callback } from "../types";
import Bag from "../bag";
import Bag, { OpenBag } from "../bag";
import BagReader from "../BagReader";

// browser reader for Blob|File objects
Expand Down Expand Up @@ -54,7 +54,7 @@ export class Reader {
}
}

const open = async (file: File | string) => {
const open = async (file: File | string): Promise<OpenBag> => {
if (!(file instanceof Blob)) {
throw new Error(
"Expected file to be a File or Blob. Make sure you are correctly importing the node or web version of Bag."
Expand All @@ -63,14 +63,16 @@ const open = async (file: File | string) => {

const bag = new Bag(new BagReader(new Reader(file)));
await bag.open();
return bag;
return bag as OpenBag;
};

Bag.open = open;

// These exports must match ../index.ts
export * from "../types";
export {
TimeUtil,
Bag,
BagReader,
MessageReader,
MessageWriter,
Expand Down