forked from mystiq/hydrogen-web
add ILogger and ILogExport interface, to give export correct return type
also move logging related types to own file
This commit is contained in:
parent
1b13f32d94
commit
695996d6e2
17 changed files with 119 additions and 84 deletions
|
@ -17,10 +17,10 @@ limitations under the License.
|
|||
|
||||
import {LogItem} from "./LogItem";
|
||||
import {LogLevel, LogFilter} from "./LogFilter";
|
||||
import type {FilterCreator, LabelOrValues, LogCallback, ILogItem} from "./LogItem";
|
||||
import type {ILogger, ILogExport, FilterCreator, LabelOrValues, LogCallback, ILogItem} from "./types";
|
||||
import type {Platform} from "../platform/web/Platform.js";
|
||||
|
||||
export abstract class BaseLogger {
|
||||
export abstract class BaseLogger implements ILogger {
|
||||
protected _openItems: Set<ILogItem> = new Set();
|
||||
protected _platform: Platform;
|
||||
|
||||
|
@ -141,7 +141,7 @@ export abstract class BaseLogger {
|
|||
|
||||
abstract _persistItem(item: ILogItem, filter?: LogFilter, forced?: boolean): void;
|
||||
|
||||
abstract export(): void;
|
||||
abstract export(): Promise<ILogExport | undefined>;
|
||||
|
||||
// expose log level without needing
|
||||
get level(): typeof LogLevel {
|
||||
|
|
|
@ -14,15 +14,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
import {BaseLogger} from "./BaseLogger";
|
||||
import type {ILogItem, LogItemValues} from "./LogItem";
|
||||
import type {ILogItem, LogItemValues, ILogExport} from "./types";
|
||||
|
||||
export class ConsoleLogger extends BaseLogger {
|
||||
_persistItem(item: ILogItem): void {
|
||||
printToConsole(item);
|
||||
}
|
||||
|
||||
export(): void {
|
||||
throw new Error("Cannot export from ConsoleLogger");
|
||||
async export(): Promise<ILogExport | undefined> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import {BaseLogger} from "./BaseLogger";
|
|||
import type {Interval} from "../platform/web/dom/Clock";
|
||||
import type {Platform} from "../platform/web/Platform.js";
|
||||
import type {BlobHandle} from "../platform/web/dom/BlobHandle.js";
|
||||
import type {ILogItem} from "./LogItem";
|
||||
import type {ILogItem, ILogExport} from "./types";
|
||||
import type {LogFilter} from "./LogFilter";
|
||||
|
||||
type QueuedItem = {
|
||||
|
@ -131,7 +131,7 @@ export class IDBLogger extends BaseLogger {
|
|||
}
|
||||
}
|
||||
|
||||
async export(): Promise<IDBLogExport> {
|
||||
async export(): Promise<ILogExport> {
|
||||
const db = await this._openDB();
|
||||
try {
|
||||
const txn = db.transaction(["logs"], "readonly");
|
||||
|
@ -171,7 +171,7 @@ export class IDBLogger extends BaseLogger {
|
|||
}
|
||||
}
|
||||
|
||||
class IDBLogExport {
|
||||
class IDBLogExport implements ILogExport {
|
||||
private readonly _items: QueuedItem[];
|
||||
private readonly _logger: IDBLogger;
|
||||
private readonly _platform: Platform;
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import type {ILogItem, ISerializedItem} from "./LogItem";
|
||||
import type {ILogItem, ISerializedItem} from "./types";
|
||||
|
||||
export enum LogLevel {
|
||||
All = 1,
|
||||
|
|
|
@ -17,58 +17,7 @@ limitations under the License.
|
|||
|
||||
import {LogLevel, LogFilter} from "./LogFilter";
|
||||
import type {BaseLogger} from "./BaseLogger";
|
||||
|
||||
export interface ISerializedItem {
|
||||
s: number;
|
||||
d?: number;
|
||||
v: LogItemValues;
|
||||
l: LogLevel;
|
||||
e?: {
|
||||
stack?: string;
|
||||
name: string;
|
||||
message: string;
|
||||
};
|
||||
f?: boolean;
|
||||
c?: Array<ISerializedItem>;
|
||||
};
|
||||
|
||||
export interface ILogItem {
|
||||
logger: any;
|
||||
level: typeof LogLevel;
|
||||
duration?: number;
|
||||
end?: number;
|
||||
start?: number;
|
||||
logLevel: LogLevel;
|
||||
children?: Array<ILogItem>;
|
||||
values: LogItemValues;
|
||||
error?: Error;
|
||||
wrap<T>(labelOrValues: LabelOrValues, callback: LogCallback<T>, logLevel?: LogLevel, filterCreator?: FilterCreator): T;
|
||||
log(labelOrValues: LabelOrValues, logLevel?: LogLevel): void;
|
||||
set(key: string | object, value: unknown): void;
|
||||
run<T>(callback: LogCallback<T>): T;
|
||||
runDetached(labelOrValues: LabelOrValues, callback: LogCallback<unknown>, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem;
|
||||
wrapDetached(labelOrValues: LabelOrValues, callback: LogCallback<unknown>, logLevel?: LogLevel, filterCreator?: FilterCreator): void;
|
||||
refDetached(logItem: ILogItem, logLevel?: LogLevel): void;
|
||||
ensureRefId(): void;
|
||||
catch(err: Error): Error;
|
||||
finish(): void;
|
||||
child(labelOrValues: LabelOrValues, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem;
|
||||
serialize(filter: LogFilter, parentStartTime: number | undefined, forced: boolean): ISerializedItem | undefined;
|
||||
}
|
||||
|
||||
export type LogItemValues = {
|
||||
l?: string;
|
||||
t?: string;
|
||||
id?: unknown;
|
||||
status?: string | number;
|
||||
refId?: number;
|
||||
ref?: number;
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export type LabelOrValues = string | LogItemValues;
|
||||
export type FilterCreator = ((filter: LogFilter, item: ILogItem) => LogFilter);
|
||||
export type LogCallback<T> = (item: ILogItem) => T;
|
||||
import type {ISerializedItem, ILogItem, LogItemValues, LabelOrValues, FilterCreator, LogCallback} from "./types";
|
||||
|
||||
export class LogItem implements ILogItem {
|
||||
public readonly start: number;
|
||||
|
|
|
@ -14,20 +14,20 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
import {LogLevel} from "./LogFilter";
|
||||
import type {ILogItem, LabelOrValues, LogCallback, LogItemValues} from "./LogItem";
|
||||
import type {ILogger, ILogExport, ILogItem, LabelOrValues, LogCallback, LogItemValues} from "./types";
|
||||
|
||||
function noop (): void {}
|
||||
|
||||
export class NullLogger {
|
||||
export class NullLogger implements ILogger {
|
||||
public readonly item: ILogItem = new NullLogItem(this);
|
||||
|
||||
log(): void {}
|
||||
|
||||
run<T>(_, callback: LogCallback<T>): T | Promise<T> {
|
||||
run<T>(_, callback: LogCallback<T>): T {
|
||||
return callback(this.item);
|
||||
}
|
||||
|
||||
wrapOrRun<T>(item: ILogItem, _, callback: LogCallback<T>): T | Promise<T> {
|
||||
wrapOrRun<T>(item: ILogItem | undefined, _, callback: LogCallback<T>): T {
|
||||
if (item) {
|
||||
return item.wrap(_, callback);
|
||||
} else {
|
||||
|
@ -35,12 +35,13 @@ export class NullLogger {
|
|||
}
|
||||
}
|
||||
|
||||
runDetached(_, callback) {
|
||||
runDetached(_, callback): ILogItem {
|
||||
new Promise(r => r(callback(this.item))).then(noop, noop);
|
||||
return this.item;
|
||||
}
|
||||
|
||||
async export(): Promise<null> {
|
||||
return null;
|
||||
async export(): Promise<ILogExport | undefined> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get level(): typeof LogLevel {
|
||||
|
|
87
src/logging/types.ts
Normal file
87
src/logging/types.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {LogLevel, LogFilter} from "./LogFilter";
|
||||
import type {BaseLogger} from "./BaseLogger";
|
||||
import type {BlobHandle} from "../platform/web/dom/BlobHandle.js";
|
||||
|
||||
export interface ISerializedItem {
|
||||
s: number;
|
||||
d?: number;
|
||||
v: LogItemValues;
|
||||
l: LogLevel;
|
||||
e?: {
|
||||
stack?: string;
|
||||
name: string;
|
||||
message: string;
|
||||
};
|
||||
f?: boolean;
|
||||
c?: Array<ISerializedItem>;
|
||||
};
|
||||
|
||||
export interface ILogItem {
|
||||
logger: any;
|
||||
level: typeof LogLevel;
|
||||
duration?: number;
|
||||
end?: number;
|
||||
start?: number;
|
||||
logLevel: LogLevel;
|
||||
children?: Array<ILogItem>;
|
||||
values: LogItemValues;
|
||||
error?: Error;
|
||||
wrap<T>(labelOrValues: LabelOrValues, callback: LogCallback<T>, logLevel?: LogLevel, filterCreator?: FilterCreator): T;
|
||||
log(labelOrValues: LabelOrValues, logLevel?: LogLevel): void;
|
||||
set(key: string | object, value: unknown): void;
|
||||
run<T>(callback: LogCallback<T>): T;
|
||||
runDetached(labelOrValues: LabelOrValues, callback: LogCallback<unknown>, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem;
|
||||
wrapDetached(labelOrValues: LabelOrValues, callback: LogCallback<unknown>, logLevel?: LogLevel, filterCreator?: FilterCreator): void;
|
||||
refDetached(logItem: ILogItem, logLevel?: LogLevel): void;
|
||||
ensureRefId(): void;
|
||||
catch(err: Error): Error;
|
||||
finish(): void;
|
||||
child(labelOrValues: LabelOrValues, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem;
|
||||
serialize(filter: LogFilter, parentStartTime: number | undefined, forced: boolean): ISerializedItem | undefined;
|
||||
}
|
||||
|
||||
export interface ILogger {
|
||||
log(labelOrValues: LabelOrValues, logLevel?: LogLevel): void;
|
||||
wrapOrRun<T>(item: ILogItem | undefined, labelOrValues: LabelOrValues, callback: LogCallback<T>, logLevel?: LogLevel, filterCreator?: FilterCreator): T;
|
||||
runDetached<T>(labelOrValues: LabelOrValues, callback: LogCallback<T>, logLevel?: LogLevel, filterCreator?: FilterCreator): ILogItem;
|
||||
run<T>(labelOrValues: LabelOrValues, callback: LogCallback<T>, logLevel?: LogLevel, filterCreator?: FilterCreator): T;
|
||||
export(): Promise<ILogExport | undefined>;
|
||||
get level(): typeof LogLevel;
|
||||
}
|
||||
|
||||
export interface ILogExport {
|
||||
get count(): number;
|
||||
removeFromStore(): Promise<void>;
|
||||
asBlob(): BlobHandle;
|
||||
}
|
||||
|
||||
export type LogItemValues = {
|
||||
l?: string;
|
||||
t?: string;
|
||||
id?: unknown;
|
||||
status?: string | number;
|
||||
refId?: number;
|
||||
ref?: number;
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export type LabelOrValues = string | LogItemValues;
|
||||
export type FilterCreator = ((filter: LogFilter, item: ILogItem) => LogFilter);
|
||||
export type LogCallback<T> = (item: ILogItem) => T;
|
|
@ -2,7 +2,7 @@
|
|||
// 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";
|
||||
import type {FilterCreator, ILogItem, LabelOrValues, LogCallback} from "./LogItem";
|
||||
import type {FilterCreator, ILogItem, LabelOrValues, LogCallback} from "./types";
|
||||
import {LogLevel} from "./LogFilter";
|
||||
|
||||
export function wrapOrRunNullLogger<T>(logItem: ILogItem | undefined, labelOrValues: LabelOrValues, callback: LogCallback<T>, logLevel?: LogLevel, filterCreator?: FilterCreator): T | Promise<T> {
|
||||
|
|
|
@ -26,7 +26,7 @@ import type {OlmWorker} from "../OlmWorker";
|
|||
import type {Transaction} from "../../storage/idb/Transaction";
|
||||
import type {TimelineEvent} from "../../storage/types";
|
||||
import type {DecryptionResult} from "../DecryptionResult";
|
||||
import type {ILogItem} from "../../../logging/LogItem";
|
||||
import type {ILogItem} from "../../../logging/types";
|
||||
|
||||
export class Decryption {
|
||||
private keyLoader: KeyLoader;
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import {iterateCursor, DONE, NOT_DONE, reqAsPromise} from "./utils";
|
||||
import {StorageError} from "../common";
|
||||
import {ILogItem} from "../../../logging/LogItem";
|
||||
import {ILogItem} from "../../../logging/types";
|
||||
import {IDBKey} from "./Transaction";
|
||||
|
||||
// this is the part of the Transaction class API that is used here and in the Store subclass,
|
||||
|
|
|
@ -18,7 +18,7 @@ import {IDOMStorage} from "./types";
|
|||
import {Transaction} from "./Transaction";
|
||||
import { STORE_NAMES, StoreNames, StorageError } from "../common";
|
||||
import { reqAsPromise } from "./utils";
|
||||
import { BaseLogger } from "../../../logging/BaseLogger";
|
||||
import { ILogger } from "../../../logging/types";
|
||||
|
||||
const WEBKITEARLYCLOSETXNBUG_BOGUS_KEY = "782rh281re38-boguskey";
|
||||
|
||||
|
@ -26,13 +26,13 @@ export class Storage {
|
|||
private _db: IDBDatabase;
|
||||
private _hasWebkitEarlyCloseTxnBug: boolean;
|
||||
|
||||
readonly logger: BaseLogger;
|
||||
readonly logger: ILogger;
|
||||
readonly idbFactory: IDBFactory
|
||||
readonly IDBKeyRange: typeof IDBKeyRange;
|
||||
readonly storeNames: typeof StoreNames;
|
||||
readonly localStorage: IDOMStorage;
|
||||
|
||||
constructor(idbDatabase: IDBDatabase, idbFactory: IDBFactory, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean, localStorage: IDOMStorage, logger: BaseLogger) {
|
||||
constructor(idbDatabase: IDBDatabase, idbFactory: IDBFactory, _IDBKeyRange: typeof IDBKeyRange, hasWebkitEarlyCloseTxnBug: boolean, localStorage: IDOMStorage, logger: ILogger) {
|
||||
this._db = idbDatabase;
|
||||
this.idbFactory = idbFactory;
|
||||
this.IDBKeyRange = _IDBKeyRange;
|
||||
|
|
|
@ -20,8 +20,7 @@ import { openDatabase, reqAsPromise } from "./utils";
|
|||
import { exportSession, importSession, Export } from "./export";
|
||||
import { schema } from "./schema";
|
||||
import { detectWebkitEarlyCloseTxnBug } from "./quirks";
|
||||
import { BaseLogger } from "../../../logging/BaseLogger";
|
||||
import { ILogItem } from "../../../logging/LogItem";
|
||||
import { ILogItem } from "../../../logging/types";
|
||||
|
||||
const sessionName = (sessionId: string) => `hydrogen_session_${sessionId}`;
|
||||
const openDatabaseWithSessionId = function(sessionId: string, idbFactory: IDBFactory, localStorage: IDOMStorage, log: ILogItem) {
|
||||
|
|
|
@ -18,7 +18,7 @@ import {QueryTarget, IDBQuery, ITransaction} from "./QueryTarget";
|
|||
import {IDBRequestError, IDBRequestAttemptError} from "./error";
|
||||
import {reqAsPromise} from "./utils";
|
||||
import {Transaction, IDBKey} from "./Transaction";
|
||||
import {ILogItem} from "../../../logging/LogItem";
|
||||
import {ILogItem} from "../../../logging/types";
|
||||
|
||||
const LOG_REQUESTS = false;
|
||||
|
||||
|
|
|
@ -36,8 +36,7 @@ import {OutboundGroupSessionStore} from "./stores/OutboundGroupSessionStore";
|
|||
import {GroupSessionDecryptionStore} from "./stores/GroupSessionDecryptionStore";
|
||||
import {OperationStore} from "./stores/OperationStore";
|
||||
import {AccountDataStore} from "./stores/AccountDataStore";
|
||||
import {ILogItem} from "../../../logging/LogItem";
|
||||
import {BaseLogger} from "../../../logging/BaseLogger";
|
||||
import type {ILogger, ILogItem} from "../../../logging/types";
|
||||
|
||||
export type IDBKey = IDBValidKey | IDBKeyRange;
|
||||
|
||||
|
@ -77,7 +76,7 @@ export class Transaction {
|
|||
return this._storage.databaseName;
|
||||
}
|
||||
|
||||
get logger(): BaseLogger {
|
||||
get logger(): ILogger {
|
||||
return this._storage.logger;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import {SessionStore} from "./stores/SessionStore";
|
|||
import {Store} from "./Store";
|
||||
import {encodeScopeTypeKey} from "./stores/OperationStore";
|
||||
import {MAX_UNICODE} from "./stores/common";
|
||||
import {ILogItem} from "../../../logging/LogItem";
|
||||
import {ILogItem} from "../../../logging/types";
|
||||
|
||||
|
||||
export type MigrationFunc = (db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: ILogItem) => Promise<void> | void;
|
||||
|
|
|
@ -16,8 +16,8 @@ limitations under the License.
|
|||
import {Store} from "../Store";
|
||||
import {IDOMStorage} from "../types";
|
||||
import {SESSION_E2EE_KEY_PREFIX} from "../../../e2ee/common.js";
|
||||
import {ILogItem} from "../../../../logging/LogItem";
|
||||
import {parse, stringify} from "../../../../utils/typedJSON";
|
||||
import type {ILogItem} from "../../../../logging/types";
|
||||
|
||||
export interface SessionEntry {
|
||||
key: string;
|
||||
|
|
|
@ -20,7 +20,7 @@ import { encodeUint32, decodeUint32 } from "../utils";
|
|||
import {KeyLimits} from "../../common";
|
||||
import {Store} from "../Store";
|
||||
import {TimelineEvent, StateEvent} from "../../types";
|
||||
import {ILogItem} from "../../../../logging/LogItem";
|
||||
import {ILogItem} from "../../../../logging/types";
|
||||
|
||||
interface Annotation {
|
||||
count: number;
|
||||
|
|
Loading…
Reference in a new issue