@foxglove/rosbag2-web
Version:
ROS2 (Robot Operating System) bag reader and writer for the browser
193 lines • 8.94 kB
JavaScript
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a, _SqliteSqljs_file, _SqliteSqljs_data, _SqliteSqljs_context, _SqliteSqljs_SqlInitialization;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqliteSqljs = void 0;
const rosbag2_1 = require("@foxglove/rosbag2");
const rostime_1 = require("@foxglove/rostime");
const sql_js_1 = __importDefault(require("@foxglove/sql.js"));
class SqliteSqljs {
static async Initialize(config) {
if (__classPrivateFieldGet(_a, _a, "f", _SqliteSqljs_SqlInitialization)) {
return await __classPrivateFieldGet(_a, _a, "f", _SqliteSqljs_SqlInitialization);
}
__classPrivateFieldSet(_a, _a, (0, sql_js_1.default)(config), "f", _SqliteSqljs_SqlInitialization);
return await __classPrivateFieldGet(_a, _a, "f", _SqliteSqljs_SqlInitialization);
}
constructor(data) {
_SqliteSqljs_file.set(this, void 0);
_SqliteSqljs_data.set(this, void 0);
_SqliteSqljs_context.set(this, void 0);
if (data instanceof File) {
__classPrivateFieldSet(this, _SqliteSqljs_file, data, "f");
}
else if (data instanceof Uint8Array) {
__classPrivateFieldSet(this, _SqliteSqljs_data, data, "f");
}
}
async open() {
const SQL = await _a.Initialize();
let db;
if (__classPrivateFieldGet(this, _SqliteSqljs_file, "f")) {
db = new SQL.Database({ file: __classPrivateFieldGet(this, _SqliteSqljs_file, "f") });
}
else if (__classPrivateFieldGet(this, _SqliteSqljs_data, "f")) {
db = new SQL.Database({ data: __classPrivateFieldGet(this, _SqliteSqljs_data, "f") });
}
else {
db = new SQL.Database();
}
// Retrieve all of the topics
const idToTopic = new Map();
const topicNameToId = new Map();
const topicRows = (db.exec("select * from topics")[0]?.values ?? []);
for (const row of topicRows) {
const [id, name, type, serializationFormat, qosProfilesStr] = row;
const offeredQosProfiles = (0, rosbag2_1.parseQosProfiles)(qosProfilesStr ?? "[]");
const topic = { name, type, serializationFormat, offeredQosProfiles };
const bigintId = BigInt(id);
idToTopic.set(bigintId, topic);
topicNameToId.set(name, bigintId);
}
__classPrivateFieldSet(this, _SqliteSqljs_context, { db, idToTopic, topicNameToId }, "f");
}
async close() {
if (__classPrivateFieldGet(this, _SqliteSqljs_context, "f") != undefined) {
__classPrivateFieldGet(this, _SqliteSqljs_context, "f").db.close();
__classPrivateFieldSet(this, _SqliteSqljs_context, undefined, "f");
}
}
async readTopics() {
if (__classPrivateFieldGet(this, _SqliteSqljs_context, "f") == undefined) {
throw new Error(`Call open() before reading topics`);
}
return Array.from(__classPrivateFieldGet(this, _SqliteSqljs_context, "f").idToTopic.values());
}
readMessages(opts = {}) {
if (__classPrivateFieldGet(this, _SqliteSqljs_context, "f") == undefined) {
throw new Error(`Call open() before reading messages`);
}
const db = __classPrivateFieldGet(this, _SqliteSqljs_context, "f").db;
const topicNameToId = __classPrivateFieldGet(this, _SqliteSqljs_context, "f").topicNameToId;
// Build a SQL query and bind parameters
let args = [];
let query = `select topic_id,cast(timestamp as TEXT) as timestamp,data from messages`;
if (opts.startTime != undefined) {
query += ` where timestamp >= cast(? as INTEGER)`;
args.push((0, rostime_1.toNanoSec)(opts.startTime).toString());
}
if (opts.endTime != undefined) {
if (args.length === 0) {
query += ` where timestamp < cast(? as INTEGER)`;
}
else {
query += ` and timestamp < cast(? as INTEGER)`;
}
args.push((0, rostime_1.toNanoSec)(opts.endTime).toString());
}
if (opts.topics != undefined) {
// Map topics to topic_ids
const topicIds = [];
for (const topicName of opts.topics) {
const topicId = topicNameToId.get(topicName);
if (topicId != undefined) {
topicIds.push(Number(topicId));
}
}
if (topicIds.length === 0) {
if (args.length === 0) {
query += ` where topic_id = NULL`;
}
else {
query += ` and topic_id = NULL`;
}
}
else if (topicIds.length === 1) {
if (args.length === 0) {
query += ` where topic_id = ?`;
}
else {
query += ` and topic_id = ?`;
}
args.push(topicIds[0]);
}
else {
if (args.length === 0) {
query += ` where topic_id in (${topicIds.map(() => "?").join(",")})`;
}
else {
query += ` and topic_id in (${topicIds.map(() => "?").join(",")})`;
}
args = args.concat(topicIds);
}
}
const statement = db.prepare(query, args);
const dbIterator = new SqlJsMessageRowIterator(statement);
return new rosbag2_1.RawMessageIterator(dbIterator, __classPrivateFieldGet(this, _SqliteSqljs_context, "f").idToTopic);
}
async timeRange() {
if (__classPrivateFieldGet(this, _SqliteSqljs_context, "f") == undefined) {
throw new Error(`Call open() before retrieving the time range`);
}
const db = __classPrivateFieldGet(this, _SqliteSqljs_context, "f").db;
const res = db.exec("select cast(min(timestamp) as TEXT), cast(max(timestamp) as TEXT) from messages")[0]?.values[0] ?? ["0", "0"];
const [minNsec, maxNsec] = res;
return [(0, rostime_1.fromNanoSec)(BigInt(minNsec ?? 0n)), (0, rostime_1.fromNanoSec)(BigInt(maxNsec ?? 0n))];
}
async messageCounts() {
if (__classPrivateFieldGet(this, _SqliteSqljs_context, "f") == undefined) {
throw new Error(`Call open() before retrieving message counts`);
}
const db = __classPrivateFieldGet(this, _SqliteSqljs_context, "f").db;
const rows = db.exec(`
select topics.name,count(*)
from messages
inner join topics on messages.topic_id = topics.id
group by topics.id`)[0]?.values ?? [];
const counts = new Map();
for (const [topicName, count] of rows) {
counts.set(topicName, count);
}
return counts;
}
}
exports.SqliteSqljs = SqliteSqljs;
_a = SqliteSqljs, _SqliteSqljs_file = new WeakMap(), _SqliteSqljs_data = new WeakMap(), _SqliteSqljs_context = new WeakMap();
_SqliteSqljs_SqlInitialization = { value: void 0 };
class SqlJsMessageRowIterator {
constructor(statement) {
this.statement = statement;
}
[Symbol.iterator]() {
return this;
}
next() {
if (!this.statement.step()) {
return { value: undefined, done: true };
}
const [topic_id, timestamp, data] = this.statement.get();
return {
value: { topic_id: BigInt(topic_id), timestamp: BigInt(timestamp), data },
done: false,
};
}
return() {
this.statement.freemem();
this.statement.free();
return { value: undefined, done: true };
}
}
//# sourceMappingURL=SqliteSqljs.js.map