forked from mystiq/hydrogen-web
Use interface ILogItem
This commit is contained in:
parent
a7d059b3ed
commit
520e0f1b89
23 changed files with 155 additions and 114 deletions
|
@ -184,7 +184,7 @@ import {Clock as MockClock} from "../../../../mocks/Clock.js";
|
||||||
import {createMockStorage} from "../../../../mocks/Storage";
|
import {createMockStorage} from "../../../../mocks/Storage";
|
||||||
import {ListObserver} from "../../../../mocks/ListObserver.js";
|
import {ListObserver} from "../../../../mocks/ListObserver.js";
|
||||||
import {createEvent, withTextBody, withContent} from "../../../../mocks/event.js";
|
import {createEvent, withTextBody, withContent} from "../../../../mocks/event.js";
|
||||||
import {NullLogItem, NullLogger} from "../../../../logging/NullLogger.js";
|
import {NullLogItem, NullLogger} from "../../../../logging/NullLogger";
|
||||||
import {HomeServer as MockHomeServer} from "../../../../mocks/HomeServer.js";
|
import {HomeServer as MockHomeServer} from "../../../../mocks/HomeServer.js";
|
||||||
// other imports
|
// other imports
|
||||||
import {BaseMessageTile} from "./tiles/BaseMessageTile.js";
|
import {BaseMessageTile} from "./tiles/BaseMessageTile.js";
|
||||||
|
|
|
@ -17,14 +17,14 @@ limitations under the License.
|
||||||
|
|
||||||
import {LogItem} from "./LogItem";
|
import {LogItem} from "./LogItem";
|
||||||
import {LogLevel, LogFilter} from "./LogFilter";
|
import {LogLevel, LogFilter} from "./LogFilter";
|
||||||
import type {FilterCreator, LabelOrValues, LogCallback} from "./LogItem";
|
import type {FilterCreator, LabelOrValues, LogCallback, ILogItem} from "./LogItem";
|
||||||
import type {LogLevelOrNull} from "./LogFilter";
|
import type {LogLevelOrNull} from "./LogFilter";
|
||||||
// todo: should this import be here just for getting the type? should it instead be done when Platform.js --> Platform.ts?
|
// todo: should this import be here just for getting the type? should it instead be done when Platform.js --> Platform.ts?
|
||||||
import type {Platform} from "../platform/web/Platform.js";
|
import type {Platform} from "../platform/web/Platform.js";
|
||||||
|
|
||||||
|
|
||||||
export abstract class BaseLogger {
|
export abstract class BaseLogger {
|
||||||
protected _openItems: Set<LogItem> = new Set();
|
protected _openItems: Set<ILogItem> = new Set();
|
||||||
protected _platform: Platform;
|
protected _platform: Platform;
|
||||||
|
|
||||||
constructor({platform}) {
|
constructor({platform}) {
|
||||||
|
@ -38,7 +38,7 @@ export abstract class BaseLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** if item is a log item, wrap the callback in a child of it, otherwise start a new root log item. */
|
/** if item is a log item, wrap the callback in a child of it, otherwise start a new root log item. */
|
||||||
wrapOrRun(item: LogItem, labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull = null, filterCreator: FilterCreator = null): unknown {
|
wrapOrRun(item: ILogItem, labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull = null, filterCreator: FilterCreator = null): unknown {
|
||||||
if (item) {
|
if (item) {
|
||||||
return item.wrap(labelOrValues, callback, logLevel, filterCreator);
|
return item.wrap(labelOrValues, callback, logLevel, filterCreator);
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,7 +51,7 @@ export abstract class BaseLogger {
|
||||||
Useful to pair with LogItem.refDetached.
|
Useful to pair with LogItem.refDetached.
|
||||||
|
|
||||||
@return {LogItem} the log item added, useful to pass to LogItem.refDetached */
|
@return {LogItem} the log item added, useful to pass to LogItem.refDetached */
|
||||||
runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull = null, filterCreator: FilterCreator = null): LogItem {
|
runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull = null, filterCreator: FilterCreator = null): ILogItem {
|
||||||
// todo: Remove jsdoc type?
|
// todo: Remove jsdoc type?
|
||||||
if (logLevel === null) {
|
if (logLevel === null) {
|
||||||
logLevel = LogLevel.Info;
|
logLevel = LogLevel.Info;
|
||||||
|
@ -72,7 +72,7 @@ export abstract class BaseLogger {
|
||||||
return this._run(item, callback, logLevel!, filterCreator, true);
|
return this._run(item, callback, logLevel!, filterCreator, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_run(item: LogItem, callback: LogCallback, logLevel: LogLevel, filterCreator: FilterCreator, shouldThrow: boolean): unknown {
|
_run(item: ILogItem, callback: LogCallback, logLevel: LogLevel, filterCreator: FilterCreator, shouldThrow: boolean): unknown {
|
||||||
this._openItems.add(item);
|
this._openItems.add(item);
|
||||||
|
|
||||||
const finishItem = () => {
|
const finishItem = () => {
|
||||||
|
@ -135,7 +135,7 @@ export abstract class BaseLogger {
|
||||||
this._openItems.clear();
|
this._openItems.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract _persistItem(item: LogItem, filter?: LogFilter, forced?: boolean): void;
|
abstract _persistItem(item: ILogItem, filter?: LogFilter, forced?: boolean): void;
|
||||||
|
|
||||||
abstract export(): void;
|
abstract export(): void;
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
import {BaseLogger} from "./BaseLogger";
|
import {BaseLogger} from "./BaseLogger";
|
||||||
import type {LogItem, LogItemValues} from "./LogItem";
|
import type {ILogItem, LogItemValues} from "./LogItem";
|
||||||
|
|
||||||
export class ConsoleLogger extends BaseLogger {
|
export class ConsoleLogger extends BaseLogger {
|
||||||
_persistItem(item: LogItem): void {
|
_persistItem(item: ILogItem): void {
|
||||||
printToConsole(item);
|
printToConsole(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ function filterValues(values: LogItemValues): LogItemValues | null {
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function printToConsole(item: LogItem): void {
|
function printToConsole(item: ILogItem): void {
|
||||||
const label = `${itemCaption(item)} (${item.duration}ms)`;
|
const label = `${itemCaption(item)} (${item.duration}ms)`;
|
||||||
const filteredValues = filterValues(item.values);
|
const filteredValues = filterValues(item.values);
|
||||||
const shouldGroup = item.children || filteredValues;
|
const shouldGroup = item.children || filteredValues;
|
||||||
|
@ -74,7 +74,7 @@ function printToConsole(item: LogItem): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function itemCaption(item: LogItem): string {
|
function itemCaption(item: ILogItem): string {
|
||||||
if (item.values.t === "network") {
|
if (item.values.t === "network") {
|
||||||
return `${item.values.method} ${item.values.url}`;
|
return `${item.values.method} ${item.values.url}`;
|
||||||
} else if (item.values.l && typeof item.values.id !== "undefined") {
|
} else if (item.values.l && typeof item.values.id !== "undefined") {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {BaseLogger} from "./BaseLogger";
|
||||||
import type {Interval} from "../platform/web/dom/Clock";
|
import type {Interval} from "../platform/web/dom/Clock";
|
||||||
import type {Platform} from "../platform/web/Platform.js";
|
import type {Platform} from "../platform/web/Platform.js";
|
||||||
import type {BlobHandle} from "../platform/web/dom/BlobHandle.js";
|
import type {BlobHandle} from "../platform/web/dom/BlobHandle.js";
|
||||||
import type {LogItem} from "./LogItem";
|
import type {ILogItem} from "./LogItem";
|
||||||
import type {LogFilter} from "./LogFilter";
|
import type {LogFilter} from "./LogFilter";
|
||||||
|
|
||||||
type QueuedItem = {
|
type QueuedItem = {
|
||||||
|
@ -116,8 +116,8 @@ export class IDBLogger extends BaseLogger {
|
||||||
return openDatabase(this._name, db => db.createObjectStore("logs", {keyPath: "id", autoIncrement: true}), 1);
|
return openDatabase(this._name, db => db.createObjectStore("logs", {keyPath: "id", autoIncrement: true}), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_persistItem(logItem: LogItem, filter: LogFilter, forced: boolean): void {
|
_persistItem(logItem: ILogItem, filter: LogFilter, forced: boolean): void {
|
||||||
const serializedItem = logItem.serialize(filter, undefined, forced);
|
const serializedItem = logItem.serialize(filter, null, forced);
|
||||||
this._queuedItems.push({
|
this._queuedItems.push({
|
||||||
json: JSON.stringify(serializedItem)
|
json: JSON.stringify(serializedItem)
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {LogItem} from "./LogItem";
|
import type {ILogItem} from "./LogItem";
|
||||||
|
|
||||||
export enum LogLevel {
|
export enum LogLevel {
|
||||||
All = 1,
|
All = 1,
|
||||||
|
@ -37,7 +37,7 @@ export class LogFilter {
|
||||||
this._parentFilter = parentFilter;
|
this._parentFilter = parentFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
filter(item: LogItem, children: Array<unknown> | null): boolean {
|
filter(item: ILogItem, children: Array<unknown> | null): boolean {
|
||||||
if (this._parentFilter) {
|
if (this._parentFilter) {
|
||||||
if (!this._parentFilter.filter(item, children)) {
|
if (!this._parentFilter.filter(item, children)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -33,6 +33,30 @@ interface ISerializedItem {
|
||||||
c?: Array<ISerializedItem>;
|
c?: Array<ISerializedItem>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface ILogItem {
|
||||||
|
logger: any;
|
||||||
|
level: typeof LogLevel;
|
||||||
|
duration?: number;
|
||||||
|
end?: number | null;
|
||||||
|
start?: number;
|
||||||
|
logLevel: LogLevel;
|
||||||
|
children: Array<ILogItem> | null;
|
||||||
|
values: LogItemValues;
|
||||||
|
error: Error | null;
|
||||||
|
wrap(labelOrValues: LabelOrValues, callback: LogCallback, level: LogLevelOrNull, filterCreator: FilterCreator): unknown;
|
||||||
|
log(labelOrValues: LabelOrValues, logLevel: LogLevelOrNull): void;
|
||||||
|
set(key: string | object, value: unknown): void;
|
||||||
|
run(callback: LogCallback): unknown;
|
||||||
|
runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull, filterCreator: FilterCreator): ILogItem;
|
||||||
|
wrapDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull, filterCreator: FilterCreator): void;
|
||||||
|
refDetached(logItem: ILogItem, logLevel: LogLevelOrNull): void;
|
||||||
|
ensureRefId(): void;
|
||||||
|
catch(err: Error): Error;
|
||||||
|
finish(): void;
|
||||||
|
child(labelOrValues: LabelOrValues, logLevel: LogLevelOrNull, filterCreator: FilterCreator): ILogItem;
|
||||||
|
serialize(filter: LogFilter, parentStartTime: number | null, forced: boolean): ISerializedItem | null;
|
||||||
|
}
|
||||||
|
|
||||||
export type LogItemValues = {
|
export type LogItemValues = {
|
||||||
l?: string;
|
l?: string;
|
||||||
t?: string;
|
t?: string;
|
||||||
|
@ -44,10 +68,10 @@ export type LogItemValues = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LabelOrValues = string | LogItemValues;
|
export type LabelOrValues = string | LogItemValues;
|
||||||
export type FilterCreator = ((filter: LogFilter, item: LogItem) => LogFilter) | null;
|
export type FilterCreator = ((filter: LogFilter, item: ILogItem) => LogFilter) | null;
|
||||||
export type LogCallback = (item: LogItem) => unknown;
|
export type LogCallback = (item: ILogItem) => unknown;
|
||||||
|
|
||||||
export class LogItem {
|
export class LogItem implements ILogItem {
|
||||||
public readonly start: number;
|
public readonly start: number;
|
||||||
public logLevel: LogLevel;
|
public logLevel: LogLevel;
|
||||||
public error: Error | null;
|
public error: Error | null;
|
||||||
|
@ -70,7 +94,7 @@ export class LogItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** start a new root log item and run it detached mode, see BaseLogger.runDetached */
|
/** start a new root log item and run it detached mode, see BaseLogger.runDetached */
|
||||||
runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull, filterCreator: FilterCreator): LogItem {
|
runDetached(labelOrValues: LabelOrValues, callback: LogCallback, logLevel: LogLevelOrNull, filterCreator: FilterCreator): ILogItem {
|
||||||
return this._logger.runDetached(labelOrValues, callback, logLevel, filterCreator);
|
return this._logger.runDetached(labelOrValues, callback, logLevel, filterCreator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +105,9 @@ export class LogItem {
|
||||||
|
|
||||||
/** logs a reference to a different log item, usually obtained from runDetached.
|
/** logs a reference to a different log item, usually obtained from runDetached.
|
||||||
This is useful if the referenced operation can't be awaited. */
|
This is useful if the referenced operation can't be awaited. */
|
||||||
refDetached(logItem: LogItem, logLevel: LogLevelOrNull = null): void {
|
refDetached(logItem: ILogItem, logLevel: LogLevelOrNull = null): void {
|
||||||
logItem.ensureRefId();
|
logItem.ensureRefId();
|
||||||
this.log({ref: logItem._values.refId as number}, logLevel);
|
this.log({ref: (logItem as LogItem)._values.refId}, logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureRefId(): void {
|
ensureRefId(): void {
|
||||||
|
@ -267,7 +291,7 @@ export class LogItem {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
child(labelOrValues: LabelOrValues, logLevel: LogLevelOrNull, filterCreator: FilterCreator): LogItem {
|
child(labelOrValues: LabelOrValues, logLevel: LogLevelOrNull, filterCreator: FilterCreator): ILogItem {
|
||||||
if (this.end !== null) {
|
if (this.end !== null) {
|
||||||
console.trace("log item is finished, additional logs will likely not be recorded");
|
console.trace("log item is finished, additional logs will likely not be recorded");
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,18 +14,17 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
import {LogLevel} from "./LogFilter";
|
import {LogLevel} from "./LogFilter";
|
||||||
|
import type {ILogItem, LabelOrValues, LogCallback, LogItemValues} from "./LogItem";
|
||||||
|
|
||||||
function noop () {}
|
function noop (): void {}
|
||||||
|
|
||||||
|
|
||||||
export class NullLogger {
|
export class NullLogger {
|
||||||
constructor() {
|
public readonly item: ILogItem = new NullLogItem(this);
|
||||||
this.item = new NullLogItem(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
log() {}
|
log(): void {}
|
||||||
|
|
||||||
run(_, callback) {
|
run(_: null, callback) {
|
||||||
return callback(this.item);
|
return callback(this.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,50 +49,61 @@ export class NullLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NullLogItem {
|
export class NullLogItem implements ILogItem {
|
||||||
constructor(logger) {
|
public readonly logger: NullLogger;
|
||||||
|
public readonly logLevel: LogLevel;
|
||||||
|
public children: Array<ILogItem> | null = null;
|
||||||
|
public values: LogItemValues;
|
||||||
|
public error: Error | null = null;
|
||||||
|
|
||||||
|
constructor(logger: NullLogger) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap(_, callback) {
|
wrap(_: LabelOrValues, callback: LogCallback): unknown {
|
||||||
return callback(this);
|
return callback(this);
|
||||||
}
|
}
|
||||||
log() {}
|
log(): void {}
|
||||||
set() {}
|
set(): void {}
|
||||||
|
|
||||||
runDetached(_, callback) {
|
runDetached(_: LabelOrValues, callback: LogCallback): ILogItem {
|
||||||
new Promise(r => r(callback(this))).then(noop, noop);
|
new Promise(r => r(callback(this))).then(noop, noop);
|
||||||
}
|
|
||||||
|
|
||||||
wrapDetached(_, callback) {
|
|
||||||
return this.refDetached(null, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
run(callback) {
|
|
||||||
return callback(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
refDetached() {}
|
|
||||||
|
|
||||||
ensureRefId() {}
|
|
||||||
|
|
||||||
get level() {
|
|
||||||
return LogLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
get duration() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
catch(err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
child() {
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
finish() {}
|
wrapDetached(_: LabelOrValues, _callback: LogCallback): void {
|
||||||
|
return this.refDetached();
|
||||||
|
}
|
||||||
|
|
||||||
|
run(callback: LogCallback): unknown {
|
||||||
|
return callback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
refDetached(): void {}
|
||||||
|
|
||||||
|
ensureRefId(): void {}
|
||||||
|
|
||||||
|
get level(): typeof LogLevel {
|
||||||
|
return LogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
get duration(): 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(err: Error): Error {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
child() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish(): void {}
|
||||||
|
|
||||||
|
serialize() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Instance = new NullLogger();
|
export const Instance = new NullLogger();
|
|
@ -1,7 +1,7 @@
|
||||||
// these are helper functions if you can't assume you always have a log item (e.g. some code paths call with one set, others don't)
|
// these are helper functions if you can't assume you always have a log item (e.g. some code paths call with one set, others don't)
|
||||||
// if you know you always have a log item, better to use the methods on the log item than these utility functions.
|
// if you know you always have a log item, better to use the methods on the log item than these utility functions.
|
||||||
|
|
||||||
import {Instance as NullLoggerInstance} from "./NullLogger.js";
|
import {Instance as NullLoggerInstance} from "./NullLogger";
|
||||||
|
|
||||||
export function wrapOrRunNullLogger(logItem, labelOrValues, callback, logLevel = null, filterCreator = null) {
|
export function wrapOrRunNullLogger(logItem, labelOrValues, callback, logLevel = null, filterCreator = null) {
|
||||||
if (logItem) {
|
if (logItem) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import type {OlmWorker} from "../OlmWorker";
|
||||||
import type {Transaction} from "../../storage/idb/Transaction";
|
import type {Transaction} from "../../storage/idb/Transaction";
|
||||||
import type {TimelineEvent} from "../../storage/types";
|
import type {TimelineEvent} from "../../storage/types";
|
||||||
import type {DecryptionResult} from "../DecryptionResult";
|
import type {DecryptionResult} from "../DecryptionResult";
|
||||||
import type {LogItem} from "../../../logging/LogItem";
|
import type {ILogItem} from "../../../logging/LogItem";
|
||||||
|
|
||||||
export class Decryption {
|
export class Decryption {
|
||||||
private keyLoader: KeyLoader;
|
private keyLoader: KeyLoader;
|
||||||
|
@ -136,7 +136,7 @@ export class Decryption {
|
||||||
* Extracts room keys from decrypted device messages.
|
* Extracts room keys from decrypted device messages.
|
||||||
* The key won't be persisted yet, you need to call RoomKey.write for that.
|
* The key won't be persisted yet, you need to call RoomKey.write for that.
|
||||||
*/
|
*/
|
||||||
roomKeysFromDeviceMessages(decryptionResults: DecryptionResult[], log: LogItem): IncomingRoomKey[] {
|
roomKeysFromDeviceMessages(decryptionResults: DecryptionResult[], log: ILogItem): IncomingRoomKey[] {
|
||||||
const keys: IncomingRoomKey[] = [];
|
const keys: IncomingRoomKey[] = [];
|
||||||
for (const dr of decryptionResults) {
|
for (const dr of decryptionResults) {
|
||||||
if (dr.event?.type !== "m.room_key" || dr.event.content?.algorithm !== MEGOLM_ALGORITHM) {
|
if (dr.event?.type !== "m.room_key" || dr.event.content?.algorithm !== MEGOLM_ALGORITHM) {
|
||||||
|
@ -152,7 +152,7 @@ export class Decryption {
|
||||||
log.logLevel = log.level.Warn;
|
log.logLevel = log.level.Warn;
|
||||||
log.set("invalid", true);
|
log.set("invalid", true);
|
||||||
}
|
}
|
||||||
}, log.level.Detail);
|
}, log.level.Detail, null);
|
||||||
}
|
}
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ export class Invite extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import {NullLogItem} from "../../logging/NullLogger.js";
|
import {NullLogItem} from "../../logging/NullLogger";
|
||||||
import {Clock as MockClock} from "../../mocks/Clock.js";
|
import {Clock as MockClock} from "../../mocks/Clock.js";
|
||||||
import {default as roomInviteFixture} from "../../fixtures/matrix/invites/room.js";
|
import {default as roomInviteFixture} from "../../fixtures/matrix/invites/room.js";
|
||||||
import {default as dmInviteFixture} from "../../fixtures/matrix/invites/dm.js";
|
import {default as dmInviteFixture} from "../../fixtures/matrix/invites/dm.js";
|
||||||
|
|
|
@ -353,7 +353,7 @@ export class SendQueue {
|
||||||
import {HomeServer as MockHomeServer} from "../../../mocks/HomeServer.js";
|
import {HomeServer as MockHomeServer} from "../../../mocks/HomeServer.js";
|
||||||
import {createMockStorage} from "../../../mocks/Storage";
|
import {createMockStorage} from "../../../mocks/Storage";
|
||||||
import {ListObserver} from "../../../mocks/ListObserver.js";
|
import {ListObserver} from "../../../mocks/ListObserver.js";
|
||||||
import {NullLogger, NullLogItem} from "../../../logging/NullLogger.js";
|
import {NullLogger, NullLogItem} from "../../../logging/NullLogger";
|
||||||
import {createEvent, withTextBody, withTxnId} from "../../../mocks/event.js";
|
import {createEvent, withTextBody, withTxnId} from "../../../mocks/event.js";
|
||||||
import {poll} from "../../../mocks/poll.js";
|
import {poll} from "../../../mocks/poll.js";
|
||||||
import {createAnnotation} from "../timeline/relations.js";
|
import {createAnnotation} from "../timeline/relations.js";
|
||||||
|
|
|
@ -346,7 +346,7 @@ import {Clock as MockClock} from "../../../mocks/Clock.js";
|
||||||
import {createMockStorage} from "../../../mocks/Storage";
|
import {createMockStorage} from "../../../mocks/Storage";
|
||||||
import {ListObserver} from "../../../mocks/ListObserver.js";
|
import {ListObserver} from "../../../mocks/ListObserver.js";
|
||||||
import {createEvent, withTextBody, withContent, withSender} from "../../../mocks/event.js";
|
import {createEvent, withTextBody, withContent, withSender} from "../../../mocks/event.js";
|
||||||
import {NullLogItem} from "../../../logging/NullLogger.js";
|
import {NullLogItem} from "../../../logging/NullLogger";
|
||||||
import {EventEntry} from "./entries/EventEntry.js";
|
import {EventEntry} from "./entries/EventEntry.js";
|
||||||
import {User} from "../../User.js";
|
import {User} from "../../User.js";
|
||||||
import {PendingEvent} from "../sending/PendingEvent.js";
|
import {PendingEvent} from "../sending/PendingEvent.js";
|
||||||
|
|
|
@ -205,7 +205,7 @@ import {FragmentIdComparer} from "../FragmentIdComparer.js";
|
||||||
import {RelationWriter} from "./RelationWriter.js";
|
import {RelationWriter} from "./RelationWriter.js";
|
||||||
import {createMockStorage} from "../../../../mocks/Storage";
|
import {createMockStorage} from "../../../../mocks/Storage";
|
||||||
import {FragmentBoundaryEntry} from "../entries/FragmentBoundaryEntry.js";
|
import {FragmentBoundaryEntry} from "../entries/FragmentBoundaryEntry.js";
|
||||||
import {NullLogItem} from "../../../../logging/NullLogger.js";
|
import {NullLogItem} from "../../../../logging/NullLogger";
|
||||||
import {TimelineMock, eventIds, eventId} from "../../../../mocks/TimelineMock.ts";
|
import {TimelineMock, eventIds, eventId} from "../../../../mocks/TimelineMock.ts";
|
||||||
import {SyncWriter} from "./SyncWriter.js";
|
import {SyncWriter} from "./SyncWriter.js";
|
||||||
import {MemberWriter} from "./MemberWriter.js";
|
import {MemberWriter} from "./MemberWriter.js";
|
||||||
|
|
|
@ -257,7 +257,7 @@ import {createMockStorage} from "../../../../mocks/Storage";
|
||||||
import {createEvent, withTextBody, withRedacts, withContent} from "../../../../mocks/event.js";
|
import {createEvent, withTextBody, withRedacts, withContent} from "../../../../mocks/event.js";
|
||||||
import {createAnnotation} from "../relations.js";
|
import {createAnnotation} from "../relations.js";
|
||||||
import {FragmentIdComparer} from "../FragmentIdComparer.js";
|
import {FragmentIdComparer} from "../FragmentIdComparer.js";
|
||||||
import {NullLogItem} from "../../../../logging/NullLogger.js";
|
import {NullLogItem} from "../../../../logging/NullLogger";
|
||||||
|
|
||||||
export function tests() {
|
export function tests() {
|
||||||
const fragmentIdComparer = new FragmentIdComparer([]);
|
const fragmentIdComparer = new FragmentIdComparer([]);
|
||||||
|
|
|
@ -258,7 +258,7 @@ export class SyncWriter {
|
||||||
|
|
||||||
import {createMockStorage} from "../../../../mocks/Storage";
|
import {createMockStorage} from "../../../../mocks/Storage";
|
||||||
import {createEvent, withTextBody} from "../../../../mocks/event.js";
|
import {createEvent, withTextBody} from "../../../../mocks/event.js";
|
||||||
import {Instance as nullLogger} from "../../../../logging/NullLogger.js";
|
import {Instance as nullLogger} from "../../../../logging/NullLogger";
|
||||||
export function tests() {
|
export function tests() {
|
||||||
const roomId = "!abc:hs.tld";
|
const roomId = "!abc:hs.tld";
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import {iterateCursor, DONE, NOT_DONE, reqAsPromise} from "./utils";
|
import {iterateCursor, DONE, NOT_DONE, reqAsPromise} from "./utils";
|
||||||
import {StorageError} from "../common";
|
import {StorageError} from "../common";
|
||||||
import {LogItem} from "../../../logging/LogItem";
|
import {ILogItem} from "../../../logging/LogItem";
|
||||||
import {IDBKey} from "./Transaction";
|
import {IDBKey} from "./Transaction";
|
||||||
|
|
||||||
// this is the part of the Transaction class API that is used here and in the Store subclass,
|
// this is the part of the Transaction class API that is used here and in the Store subclass,
|
||||||
|
@ -25,7 +25,7 @@ export interface ITransaction {
|
||||||
idbFactory: IDBFactory;
|
idbFactory: IDBFactory;
|
||||||
IDBKeyRange: typeof IDBKeyRange;
|
IDBKeyRange: typeof IDBKeyRange;
|
||||||
databaseName: string;
|
databaseName: string;
|
||||||
addWriteError(error: StorageError, refItem: LogItem | undefined, operationName: string, keys: IDBKey[] | undefined);
|
addWriteError(error: StorageError, refItem: ILogItem | undefined, operationName: string, keys: IDBKey[] | undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reducer<A,B> = (acc: B, val: A) => B
|
type Reducer<A,B> = (acc: B, val: A) => B
|
||||||
|
@ -277,7 +277,7 @@ export function tests() {
|
||||||
|
|
||||||
class MockTransaction extends MockIDBImpl {
|
class MockTransaction extends MockIDBImpl {
|
||||||
get databaseName(): string { return "mockdb"; }
|
get databaseName(): string { return "mockdb"; }
|
||||||
addWriteError(error: StorageError, refItem: LogItem | undefined, operationName: string, keys: IDBKey[] | undefined) {}
|
addWriteError(error: StorageError, refItem: ILogItem | undefined, operationName: string, keys: IDBKey[] | undefined) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TestEntry {
|
interface TestEntry {
|
||||||
|
|
|
@ -21,10 +21,10 @@ import { exportSession, importSession, Export } from "./export";
|
||||||
import { schema } from "./schema";
|
import { schema } from "./schema";
|
||||||
import { detectWebkitEarlyCloseTxnBug } from "./quirks";
|
import { detectWebkitEarlyCloseTxnBug } from "./quirks";
|
||||||
import { BaseLogger } from "../../../logging/BaseLogger";
|
import { BaseLogger } from "../../../logging/BaseLogger";
|
||||||
import { LogItem } from "../../../logging/LogItem";
|
import { ILogItem } from "../../../logging/LogItem";
|
||||||
|
|
||||||
const sessionName = (sessionId: string) => `hydrogen_session_${sessionId}`;
|
const sessionName = (sessionId: string) => `hydrogen_session_${sessionId}`;
|
||||||
const openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory, localStorage: IDOMStorage, log: LogItem) {
|
const openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory, localStorage: IDOMStorage, log: ILogItem) {
|
||||||
const create = (db, txn, oldVersion, version) => createStores(db, txn, oldVersion, version, localStorage, log);
|
const create = (db, txn, oldVersion, version) => createStores(db, txn, oldVersion, version, localStorage, log);
|
||||||
return openDatabase(sessionName(sessionId), create, schema.length, idbFactory);
|
return openDatabase(sessionName(sessionId), create, schema.length, idbFactory);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ export class StorageFactory {
|
||||||
this._localStorage = localStorage;
|
this._localStorage = localStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(sessionId: string, log: LogItem): Promise<Storage> {
|
async create(sessionId: string, log: ILogItem): Promise<Storage> {
|
||||||
await this._serviceWorkerHandler?.preventConcurrentSessionAccess(sessionId);
|
await this._serviceWorkerHandler?.preventConcurrentSessionAccess(sessionId);
|
||||||
requestPersistedStorage().then(persisted => {
|
requestPersistedStorage().then(persisted => {
|
||||||
// Firefox lies here though, and returns true even if the user denied the request
|
// Firefox lies here though, and returns true even if the user denied the request
|
||||||
|
@ -83,23 +83,30 @@ export class StorageFactory {
|
||||||
return reqAsPromise(req);
|
return reqAsPromise(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
async export(sessionId: string, log: LogItem): Promise<Export> {
|
async export(sessionId: string, log: ILogItem): Promise<Export> {
|
||||||
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);
|
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);
|
||||||
return await exportSession(db);
|
return await exportSession(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
async import(sessionId: string, data: Export, log: LogItem): Promise<void> {
|
async import(sessionId: string, data: Export, log: ILogItem): Promise<void> {
|
||||||
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);
|
const db = await openDatabaseWithSessionId(sessionId, this._idbFactory, this._localStorage, log);
|
||||||
return await importSession(db, data);
|
return await importSession(db, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number, localStorage: IDOMStorage, log: LogItem): Promise<void> {
|
async function createStores(db: IDBDatabase, txn: IDBTransaction, oldVersion: number | null, version: number, localStorage: IDOMStorage, log: ILogItem): Promise<void> {
|
||||||
const startIdx = oldVersion || 0;
|
const startIdx = oldVersion || 0;
|
||||||
return log.wrap({l: "storage migration", oldVersion, version}, async log => {
|
return log.wrap(
|
||||||
for(let i = startIdx; i < version; ++i) {
|
{ l: "storage migration", oldVersion, version },
|
||||||
const migrationFunc = schema[i];
|
async (log) => {
|
||||||
await log.wrap(`v${i + 1}`, log => migrationFunc(db, txn, localStorage, log));
|
for (let i = startIdx; i < version; ++i) {
|
||||||
}
|
const migrationFunc = schema[i];
|
||||||
}) as Promise<void>;
|
await log.wrap(`v${i + 1}`, (log) =>
|
||||||
|
migrationFunc(db, txn, localStorage, log), null, null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
) as Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {QueryTarget, IDBQuery, ITransaction} from "./QueryTarget";
|
||||||
import {IDBRequestError, IDBRequestAttemptError} from "./error";
|
import {IDBRequestError, IDBRequestAttemptError} from "./error";
|
||||||
import {reqAsPromise} from "./utils";
|
import {reqAsPromise} from "./utils";
|
||||||
import {Transaction, IDBKey} from "./Transaction";
|
import {Transaction, IDBKey} from "./Transaction";
|
||||||
import {LogItem} from "../../../logging/LogItem";
|
import {ILogItem} from "../../../logging/LogItem";
|
||||||
|
|
||||||
const LOG_REQUESTS = false;
|
const LOG_REQUESTS = false;
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ export class Store<T> extends QueryTarget<T> {
|
||||||
return new QueryTarget<T>(new QueryTargetWrapper<T>(this._idbStore.index(indexName)), this._transaction);
|
return new QueryTarget<T>(new QueryTargetWrapper<T>(this._idbStore.index(indexName)), this._transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
put(value: T, log?: LogItem): void {
|
put(value: T, log?: ILogItem): void {
|
||||||
// If this request fails, the error will bubble up to the transaction and abort it,
|
// If this request fails, the error will bubble up to the transaction and abort it,
|
||||||
// which is the behaviour we want. Therefore, it is ok to not create a promise for this
|
// which is the behaviour we want. Therefore, it is ok to not create a promise for this
|
||||||
// request and await it.
|
// request and await it.
|
||||||
|
@ -160,13 +160,13 @@ export class Store<T> extends QueryTarget<T> {
|
||||||
this._prepareErrorLog(request, log, "put", undefined, value);
|
this._prepareErrorLog(request, log, "put", undefined, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(value: T, log?: LogItem): void {
|
add(value: T, log?: ILogItem): void {
|
||||||
// ok to not monitor result of request, see comment in `put`.
|
// ok to not monitor result of request, see comment in `put`.
|
||||||
const request = this._idbStore.add(value);
|
const request = this._idbStore.add(value);
|
||||||
this._prepareErrorLog(request, log, "add", undefined, value);
|
this._prepareErrorLog(request, log, "add", undefined, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
async tryAdd(value: T, log: LogItem): Promise<boolean> {
|
async tryAdd(value: T, log: ILogItem): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await reqAsPromise(this._idbStore.add(value));
|
await reqAsPromise(this._idbStore.add(value));
|
||||||
return true;
|
return true;
|
||||||
|
@ -181,13 +181,13 @@ export class Store<T> extends QueryTarget<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(keyOrKeyRange: IDBValidKey | IDBKeyRange, log?: LogItem): void {
|
delete(keyOrKeyRange: IDBValidKey | IDBKeyRange, log?: ILogItem): void {
|
||||||
// ok to not monitor result of request, see comment in `put`.
|
// ok to not monitor result of request, see comment in `put`.
|
||||||
const request = this._idbStore.delete(keyOrKeyRange);
|
const request = this._idbStore.delete(keyOrKeyRange);
|
||||||
this._prepareErrorLog(request, log, "delete", keyOrKeyRange, undefined);
|
this._prepareErrorLog(request, log, "delete", keyOrKeyRange, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _prepareErrorLog(request: IDBRequest, log: LogItem | undefined, operationName: string, key: IDBKey | undefined, value: T | undefined) {
|
private _prepareErrorLog(request: IDBRequest, log: ILogItem | undefined, operationName: string, key: IDBKey | undefined, value: T | undefined) {
|
||||||
if (log) {
|
if (log) {
|
||||||
log.ensureRefId();
|
log.ensureRefId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore";
|
||||||
import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore";
|
import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore";
|
||||||
import {OperationStore} from "./stores/OperationStore";
|
import {OperationStore} from "./stores/OperationStore";
|
||||||
import {AccountDataStore} from "./stores/AccountDataStore";
|
import {AccountDataStore} from "./stores/AccountDataStore";
|
||||||
import {LogItem} from "../../../logging/LogItem";
|
import {ILogItem} from "../../../logging/LogItem";
|
||||||
import {BaseLogger} from "../../../logging/BaseLogger";
|
import {BaseLogger} from "../../../logging/BaseLogger";
|
||||||
|
|
||||||
export type IDBKey = IDBValidKey | IDBKeyRange;
|
export type IDBKey = IDBValidKey | IDBKeyRange;
|
||||||
|
@ -44,7 +44,7 @@ export type IDBKey = IDBValidKey | IDBKeyRange;
|
||||||
class WriteErrorInfo {
|
class WriteErrorInfo {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly error: StorageError,
|
public readonly error: StorageError,
|
||||||
public readonly refItem: LogItem | undefined,
|
public readonly refItem: ILogItem | undefined,
|
||||||
public readonly operationName: string,
|
public readonly operationName: string,
|
||||||
public readonly keys: IDBKey[] | undefined,
|
public readonly keys: IDBKey[] | undefined,
|
||||||
) {}
|
) {}
|
||||||
|
@ -169,7 +169,7 @@ export class Transaction {
|
||||||
return this._store(StoreNames.accountData, idbStore => new AccountDataStore(idbStore));
|
return this._store(StoreNames.accountData, idbStore => new AccountDataStore(idbStore));
|
||||||
}
|
}
|
||||||
|
|
||||||
async complete(log?: LogItem): Promise<void> {
|
async complete(log?: ILogItem): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await txnAsPromise(this._txn);
|
await txnAsPromise(this._txn);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -190,7 +190,7 @@ export class Transaction {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(log?: LogItem): void {
|
abort(log?: ILogItem): void {
|
||||||
// TODO: should we wrap the exception in a StorageError?
|
// TODO: should we wrap the exception in a StorageError?
|
||||||
try {
|
try {
|
||||||
this._txn.abort();
|
this._txn.abort();
|
||||||
|
@ -202,14 +202,14 @@ export class Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addWriteError(error: StorageError, refItem: LogItem | undefined, operationName: string, keys: IDBKey[] | undefined) {
|
addWriteError(error: StorageError, refItem: ILogItem | undefined, operationName: string, keys: IDBKey[] | undefined) {
|
||||||
// don't log subsequent `AbortError`s
|
// don't log subsequent `AbortError`s
|
||||||
if (error.errcode !== "AbortError" || this._writeErrors.length === 0) {
|
if (error.errcode !== "AbortError" || this._writeErrors.length === 0) {
|
||||||
this._writeErrors.push(new WriteErrorInfo(error, refItem, operationName, keys));
|
this._writeErrors.push(new WriteErrorInfo(error, refItem, operationName, keys));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _logWriteErrors(parentItem: LogItem | undefined) {
|
private _logWriteErrors(parentItem: ILogItem | undefined) {
|
||||||
const callback = errorGroupItem => {
|
const callback = errorGroupItem => {
|
||||||
// we don't have context when there is no parentItem, so at least log stores
|
// we don't have context when there is no parentItem, so at least log stores
|
||||||
if (!parentItem) {
|
if (!parentItem) {
|
||||||
|
@ -226,7 +226,7 @@ export class Transaction {
|
||||||
};
|
};
|
||||||
const label = `${this._writeErrors.length} storage write operation(s) failed`;
|
const label = `${this._writeErrors.length} storage write operation(s) failed`;
|
||||||
if (parentItem) {
|
if (parentItem) {
|
||||||
parentItem.wrap(label, callback);
|
parentItem.wrap(label, callback, null, null);
|
||||||
} else {
|
} else {
|
||||||
this.logger.run(label, callback);
|
this.logger.run(label, callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ import {SessionStore} from "./stores/SessionStore";
|
||||||
import {Store} from "./Store";
|
import {Store} from "./Store";
|
||||||
import {encodeScopeTypeKey} from "./stores/OperationStore";
|
import {encodeScopeTypeKey} from "./stores/OperationStore";
|
||||||
import {MAX_UNICODE} from "./stores/common";
|
import {MAX_UNICODE} from "./stores/common";
|
||||||
import {LogItem} from "../../../logging/LogItem";
|
import {ILogItem} from "../../../logging/LogItem";
|
||||||
|
|
||||||
|
|
||||||
export type MigrationFunc = (db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: LogItem) => Promise<void> | void;
|
export type MigrationFunc = (db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) => Promise<void> | void;
|
||||||
// FUNCTIONS SHOULD ONLY BE APPENDED!!
|
// FUNCTIONS SHOULD ONLY BE APPENDED!!
|
||||||
// the index in the array is the database version
|
// the index in the array is the database version
|
||||||
export const schema: MigrationFunc[] = [
|
export const schema: MigrationFunc[] = [
|
||||||
|
@ -166,7 +166,7 @@ function createTimelineRelationsStore(db: IDBDatabase) : void {
|
||||||
}
|
}
|
||||||
|
|
||||||
//v11 doesn't change the schema, but ensures all userIdentities have all the roomIds they should (see #470)
|
//v11 doesn't change the schema, but ensures all userIdentities have all the roomIds they should (see #470)
|
||||||
async function fixMissingRoomsInUserIdentities(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: LogItem) {
|
async function fixMissingRoomsInUserIdentities(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) {
|
||||||
const roomSummaryStore = txn.objectStore("roomSummary");
|
const roomSummaryStore = txn.objectStore("roomSummary");
|
||||||
const trackedRoomIds: string[] = [];
|
const trackedRoomIds: string[] = [];
|
||||||
await iterateCursor<SummaryData>(roomSummaryStore.openCursor(), roomSummary => {
|
await iterateCursor<SummaryData>(roomSummaryStore.openCursor(), roomSummary => {
|
||||||
|
@ -196,7 +196,7 @@ async function fixMissingRoomsInUserIdentities(db: IDBDatabase, txn: IDBTransact
|
||||||
const updatedIdentity = addRoomToIdentity(identity, userId, roomId);
|
const updatedIdentity = addRoomToIdentity(identity, userId, roomId);
|
||||||
if (updatedIdentity) {
|
if (updatedIdentity) {
|
||||||
log.log({l: `fixing up`, id: userId,
|
log.log({l: `fixing up`, id: userId,
|
||||||
roomsBefore: originalRoomCount, roomsAfter: updatedIdentity.roomIds.length});
|
roomsBefore: originalRoomCount, roomsAfter: updatedIdentity.roomIds.length}, null);
|
||||||
userIdentitiesStore.put(updatedIdentity);
|
userIdentitiesStore.put(updatedIdentity);
|
||||||
foundMissing = true;
|
foundMissing = true;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ async function fixMissingRoomsInUserIdentities(db: IDBDatabase, txn: IDBTransact
|
||||||
// so we'll create a new one on the next message that will be properly shared
|
// so we'll create a new one on the next message that will be properly shared
|
||||||
outboundGroupSessionsStore.delete(roomId);
|
outboundGroupSessionsStore.delete(roomId);
|
||||||
}
|
}
|
||||||
});
|
}, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ async function changeSSSSKeyPrefix(db: IDBDatabase, txn: IDBTransaction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// v13
|
// v13
|
||||||
async function backupAndRestoreE2EEAccountToLocalStorage(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: LogItem) {
|
async function backupAndRestoreE2EEAccountToLocalStorage(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) {
|
||||||
const session = txn.objectStore("session");
|
const session = txn.objectStore("session");
|
||||||
// the Store object gets passed in several things through the Transaction class (a wrapper around IDBTransaction),
|
// the Store object gets passed in several things through the Transaction class (a wrapper around IDBTransaction),
|
||||||
// the only thing we should need here is the databaseName though, so we mock it out.
|
// the only thing we should need here is the databaseName though, so we mock it out.
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
import {Store} from "../Store";
|
import {Store} from "../Store";
|
||||||
import {IDOMStorage} from "../types";
|
import {IDOMStorage} from "../types";
|
||||||
import {SESSION_E2EE_KEY_PREFIX} from "../../../e2ee/common.js";
|
import {SESSION_E2EE_KEY_PREFIX} from "../../../e2ee/common.js";
|
||||||
import {LogItem} from "../../../../logging/LogItem";
|
import {ILogItem} from "../../../../logging/LogItem";
|
||||||
import {parse, stringify} from "../../../../utils/typedJSON";
|
import {parse, stringify} from "../../../../utils/typedJSON";
|
||||||
|
|
||||||
export interface SessionEntry {
|
export interface SessionEntry {
|
||||||
|
@ -64,7 +64,7 @@ export class SessionStore {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async tryRestoreE2EEIdentityFromLocalStorage(log: LogItem): Promise<boolean> {
|
async tryRestoreE2EEIdentityFromLocalStorage(log: ILogItem): Promise<boolean> {
|
||||||
let success = false;
|
let success = false;
|
||||||
const lsPrefix = this._localStorageKeyPrefix;
|
const lsPrefix = this._localStorageKeyPrefix;
|
||||||
const prefix = lsPrefix + SESSION_E2EE_KEY_PREFIX;
|
const prefix = lsPrefix + SESSION_E2EE_KEY_PREFIX;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { encodeUint32, decodeUint32 } from "../utils";
|
||||||
import {KeyLimits} from "../../common";
|
import {KeyLimits} from "../../common";
|
||||||
import {Store} from "../Store";
|
import {Store} from "../Store";
|
||||||
import {TimelineEvent, StateEvent} from "../../types";
|
import {TimelineEvent, StateEvent} from "../../types";
|
||||||
import {LogItem} from "../../../../logging/LogItem";
|
import {ILogItem} from "../../../../logging/LogItem";
|
||||||
|
|
||||||
interface Annotation {
|
interface Annotation {
|
||||||
count: number;
|
count: number;
|
||||||
|
@ -286,7 +286,7 @@ export class TimelineEventStore {
|
||||||
*
|
*
|
||||||
* Returns if the event was not yet known and the entry was written.
|
* Returns if the event was not yet known and the entry was written.
|
||||||
*/
|
*/
|
||||||
tryInsert(entry: TimelineEventEntry, log: LogItem): Promise<boolean> {
|
tryInsert(entry: TimelineEventEntry, log: ILogItem): Promise<boolean> {
|
||||||
(entry as TimelineEventStorageEntry).key = encodeKey(entry.roomId, entry.fragmentId, entry.eventIndex);
|
(entry as TimelineEventStorageEntry).key = encodeKey(entry.roomId, entry.fragmentId, entry.eventIndex);
|
||||||
(entry as TimelineEventStorageEntry).eventIdKey = encodeEventIdKey(entry.roomId, entry.event.event_id);
|
(entry as TimelineEventStorageEntry).eventIdKey = encodeEventIdKey(entry.roomId, entry.event.event_id);
|
||||||
return this._timelineStore.tryAdd(entry as TimelineEventStorageEntry, log);
|
return this._timelineStore.tryAdd(entry as TimelineEventStorageEntry, log);
|
||||||
|
@ -320,7 +320,7 @@ export class TimelineEventStore {
|
||||||
import {createMockStorage} from "../../../../mocks/Storage";
|
import {createMockStorage} from "../../../../mocks/Storage";
|
||||||
import {createEvent, withTextBody} from "../../../../mocks/event.js";
|
import {createEvent, withTextBody} from "../../../../mocks/event.js";
|
||||||
import {createEventEntry} from "../../../room/timeline/persistence/common.js";
|
import {createEventEntry} from "../../../room/timeline/persistence/common.js";
|
||||||
import {Instance as logItem} from "../../../../logging/NullLogger.js";
|
import {Instance as nullLogger} from "../../../../logging/NullLogger";
|
||||||
|
|
||||||
export function tests() {
|
export function tests() {
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ export function tests() {
|
||||||
let eventKey = EventKey.defaultFragmentKey(109);
|
let eventKey = EventKey.defaultFragmentKey(109);
|
||||||
for (const insertedId of insertedIds) {
|
for (const insertedId of insertedIds) {
|
||||||
const entry = createEventEntry(eventKey.nextKey(), roomId, createEventWithId(insertedId));
|
const entry = createEventEntry(eventKey.nextKey(), roomId, createEventWithId(insertedId));
|
||||||
assert(await txn.timelineEvents.tryInsert(entry, logItem));
|
assert(await txn.timelineEvents.tryInsert(entry, nullLogger.item));
|
||||||
eventKey = eventKey.nextKey();
|
eventKey = eventKey.nextKey();
|
||||||
}
|
}
|
||||||
const eventKeyMap = await txn.timelineEvents.getEventKeysForIds(roomId, checkedIds);
|
const eventKeyMap = await txn.timelineEvents.getEventKeysForIds(roomId, checkedIds);
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {FDBFactory, FDBKeyRange} from "../../lib/fake-indexeddb/index.js";
|
||||||
import {StorageFactory} from "../matrix/storage/idb/StorageFactory";
|
import {StorageFactory} from "../matrix/storage/idb/StorageFactory";
|
||||||
import {IDOMStorage} from "../matrix/storage/idb/types";
|
import {IDOMStorage} from "../matrix/storage/idb/types";
|
||||||
import {Storage} from "../matrix/storage/idb/Storage";
|
import {Storage} from "../matrix/storage/idb/Storage";
|
||||||
import {Instance as nullLogger} from "../logging/NullLogger.js";
|
import {Instance as nullLogger} from "../logging/NullLogger";
|
||||||
import {openDatabase, CreateObjectStore} from "../matrix/storage/idb/utils";
|
import {openDatabase, CreateObjectStore} from "../matrix/storage/idb/utils";
|
||||||
|
|
||||||
export function createMockStorage(): Promise<Storage> {
|
export function createMockStorage(): Promise<Storage> {
|
||||||
|
|
Loading…
Reference in a new issue