UNPKG

@foxglove/rosbag2-web

Version:

ROS2 (Robot Operating System) bag reader and writer for the browser

193 lines 8.94 kB
"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