@editor-x/wme-logstream 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/README.md +216 -0
- package/dist/index.cjs.js +980 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +954 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.iife.js +2 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/types/core/Dispatcher.d.ts +8 -0
- package/dist/types/core/LogPayload.d.ts +17 -0
- package/dist/types/core/LogStream.d.ts +128 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/pipes/BasePipe.d.ts +5 -0
- package/dist/types/pipes/ConsolePipe.d.ts +14 -0
- package/dist/types/pipes/IndexedDBPipe.d.ts +11 -0
- package/dist/types/storage/IndexedDBManager.d.ts +85 -0
- package/dist/types/storage/SessionManager.d.ts +32 -0
- package/dist/types/storage/ZipStreamer.d.ts +9 -0
- package/dist/types/utils/EventChannel.d.ts +21 -0
- package/dist/types/utils/idb.d.ts +16 -0
- package/dist/types/utils/session.d.ts +4 -0
- package/dist/types/utils/window.d.ts +4 -0
- package/package.json +51 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type LogLevel = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL';
|
|
2
|
+
export interface LogPayload {
|
|
3
|
+
timestamp: number;
|
|
4
|
+
level: LogLevel;
|
|
5
|
+
scopes: string[];
|
|
6
|
+
message: string;
|
|
7
|
+
data?: any;
|
|
8
|
+
}
|
|
9
|
+
export interface SessionMetadata {
|
|
10
|
+
id: string;
|
|
11
|
+
createdAt: number;
|
|
12
|
+
lastUpdated: number;
|
|
13
|
+
scriptVersion: string;
|
|
14
|
+
wmeVersion: string;
|
|
15
|
+
loggerVersion: string;
|
|
16
|
+
schemaVersion: string;
|
|
17
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Dispatcher } from './Dispatcher.js';
|
|
2
|
+
import { BasePipe } from '../pipes/BasePipe.js';
|
|
3
|
+
import { LogLevel } from './LogPayload.js';
|
|
4
|
+
import { ConsolePipeConfig } from '../pipes/ConsolePipe.js';
|
|
5
|
+
import { IndexedDBManager } from '../storage/IndexedDBManager.js';
|
|
6
|
+
/**
|
|
7
|
+
* Configuration options for the standard LogStream constructor.
|
|
8
|
+
*/
|
|
9
|
+
export interface LogStreamConfig {
|
|
10
|
+
/** The minimum log level required for a log to be processed. Defaults to 'INFO'. */
|
|
11
|
+
minLogLevel?: LogLevel;
|
|
12
|
+
/** Custom base pipes to dispatch logs to. */
|
|
13
|
+
pipes?: BasePipe[];
|
|
14
|
+
/** Optional pre-configured IndexedDBManager to enable export and download methods. */
|
|
15
|
+
dbManager?: IndexedDBManager;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Configuration options for creating a WME LogStream using the simplified factory method.
|
|
19
|
+
*/
|
|
20
|
+
export interface UnifiedLogStreamConfig {
|
|
21
|
+
/** The minimum log level required for a log to be processed. Defaults to 'INFO'. */
|
|
22
|
+
minLogLevel?: LogLevel;
|
|
23
|
+
/** Whether to enable IndexedDB persistence and multi-tab isolation. Defaults to false. */
|
|
24
|
+
persist?: boolean;
|
|
25
|
+
/** Unique database prefix identifier. Required if `persist` is true. */
|
|
26
|
+
dbPrefix?: string;
|
|
27
|
+
/** Current userscript or extension version. Required if `persist` is true. */
|
|
28
|
+
scriptVersion?: string;
|
|
29
|
+
/** Native WME SDK instance to defensively query editor versions. */
|
|
30
|
+
wmeSDK?: any;
|
|
31
|
+
/** Maximum number of completed archived database sessions to preserve. Defaults to 5. */
|
|
32
|
+
maxArchivedSessions?: number;
|
|
33
|
+
/** Delay in milliseconds before flushing logs in queue to IndexedDB. Defaults to 2000. */
|
|
34
|
+
flushIntervalMs?: number;
|
|
35
|
+
/** Custom console styling prefix and color options. Set to `null` to disable console logging. */
|
|
36
|
+
brand?: ConsolePipeConfig | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The main logger class for WME LogStream.
|
|
40
|
+
* Handles hierarchical scoping, console styling, state diff tracking, and persistent database exports.
|
|
41
|
+
*/
|
|
42
|
+
export declare class LogStream {
|
|
43
|
+
private minLogLevel;
|
|
44
|
+
private dispatcher;
|
|
45
|
+
private scopes;
|
|
46
|
+
private states;
|
|
47
|
+
private patcher;
|
|
48
|
+
private dbManagerPromise;
|
|
49
|
+
/**
|
|
50
|
+
* Initializes a LogStream instance.
|
|
51
|
+
* Prefer using `LogStream.create()` for a simplified, zero-boilerplate setup.
|
|
52
|
+
*/
|
|
53
|
+
constructor(config: LogStreamConfig, internal?: {
|
|
54
|
+
dispatcher: Dispatcher;
|
|
55
|
+
scopes: string[];
|
|
56
|
+
states: Map<string, any>;
|
|
57
|
+
dbManagerPromise?: Promise<IndexedDBManager> | null;
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Synchronously creates a configured LogStream instance, initializing console outputs
|
|
61
|
+
* and setting up background persistence/session managers if enabled.
|
|
62
|
+
*
|
|
63
|
+
* @param config The unified configuration options for console branding and persistence.
|
|
64
|
+
* @returns A pre-configured LogStream instance ready to log immediately.
|
|
65
|
+
*/
|
|
66
|
+
static create(config: UnifiedLogStreamConfig): LogStream;
|
|
67
|
+
/**
|
|
68
|
+
* Spawns a child logger with a hierarchical scope prefix appended to the console/db entries.
|
|
69
|
+
*
|
|
70
|
+
* @param name The scope namespace (e.g. 'API', 'Auth').
|
|
71
|
+
* @returns A new LogStream child instance carrying the hierarchical scope.
|
|
72
|
+
*/
|
|
73
|
+
scope(name: string): LogStream;
|
|
74
|
+
/** Logs a TRACE level message. */
|
|
75
|
+
trace(message: string, data?: any): void;
|
|
76
|
+
/** Logs a DEBUG level message. */
|
|
77
|
+
debug(message: string, data?: any): void;
|
|
78
|
+
/** Logs an INFO level message. */
|
|
79
|
+
info(message: string, data?: any): void;
|
|
80
|
+
/** Logs a WARN level message. */
|
|
81
|
+
warn(message: string, data?: any): void;
|
|
82
|
+
/** Logs an ERROR level message. */
|
|
83
|
+
error(message: string, data?: any): void;
|
|
84
|
+
/** Logs a FATAL level message. */
|
|
85
|
+
fatal(message: string, data?: any): void;
|
|
86
|
+
/**
|
|
87
|
+
* Compares the given state object against its previous version, calculating the deep-diff
|
|
88
|
+
* and logging only modified properties as a DEBUG entry.
|
|
89
|
+
*
|
|
90
|
+
* @param name The state tracking key.
|
|
91
|
+
* @param state The state object to track.
|
|
92
|
+
* @param options Config options, e.g., max depth for nested objects.
|
|
93
|
+
*/
|
|
94
|
+
stateDelta(name: string, state: any, options?: {
|
|
95
|
+
maxDepth?: number;
|
|
96
|
+
}): void;
|
|
97
|
+
/**
|
|
98
|
+
* Returns a bound function that tracks changes to a specific state key over time.
|
|
99
|
+
*
|
|
100
|
+
* @param name The state tracking key.
|
|
101
|
+
* @param options Config options, e.g., max depth for nested objects.
|
|
102
|
+
* @returns A function accepting a state object to diff and log.
|
|
103
|
+
*/
|
|
104
|
+
createStateTracker(name: string, options?: {
|
|
105
|
+
maxDepth?: number;
|
|
106
|
+
}): (state: any) => void;
|
|
107
|
+
/**
|
|
108
|
+
* Asynchronously exports all stored database sessions and logs into a single compressed ZIP file.
|
|
109
|
+
*
|
|
110
|
+
* @returns A promise resolving to the compressed ZIP Blob.
|
|
111
|
+
*/
|
|
112
|
+
exportLogs(): Promise<Blob>;
|
|
113
|
+
/**
|
|
114
|
+
* Triggers a browser-native file download of the compressed log sessions.
|
|
115
|
+
*
|
|
116
|
+
* @param filename Custom download filename. Defaults to `wme-logs-<timestamp>.xlog`.
|
|
117
|
+
*/
|
|
118
|
+
downloadLogs(filename?: string): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Triggers a flush of all buffered logs on registered pipes.
|
|
121
|
+
*/
|
|
122
|
+
flush(): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Closes underlying active database connections if persistence is enabled.
|
|
125
|
+
*/
|
|
126
|
+
close(): Promise<void>;
|
|
127
|
+
private log;
|
|
128
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LogStream, LogStreamConfig, UnifiedLogStreamConfig } from './core/LogStream.js';
|
|
2
|
+
import { ConsolePipe, ConsolePipeConfig } from './pipes/ConsolePipe.js';
|
|
3
|
+
import { IndexedDBPipe } from './pipes/IndexedDBPipe.js';
|
|
4
|
+
import { ZipStreamer } from './storage/ZipStreamer.js';
|
|
5
|
+
import { SessionManager, SessionManagerConfig } from './storage/SessionManager.js';
|
|
6
|
+
import { IndexedDBManager, IndexedDBManagerConfig } from './storage/IndexedDBManager.js';
|
|
7
|
+
import { LogPayload, LogLevel, SessionMetadata } from './core/LogPayload.js';
|
|
8
|
+
export { LogStream, ConsolePipe, IndexedDBPipe, ZipStreamer, SessionManager, IndexedDBManager };
|
|
9
|
+
export type { LogStreamConfig, UnifiedLogStreamConfig, ConsolePipeConfig, SessionManagerConfig, IndexedDBManagerConfig, LogPayload, LogLevel, SessionMetadata, };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BasePipe } from './BasePipe.js';
|
|
2
|
+
import { LogPayload } from '../core/LogPayload.js';
|
|
3
|
+
export interface ConsolePipeConfig {
|
|
4
|
+
scriptPrefix?: string;
|
|
5
|
+
brandColor?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class ConsolePipe extends BasePipe {
|
|
8
|
+
private scriptPrefix;
|
|
9
|
+
private brandColor;
|
|
10
|
+
private styles;
|
|
11
|
+
constructor(config?: ConsolePipeConfig);
|
|
12
|
+
write(payload: LogPayload): void;
|
|
13
|
+
flush(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BasePipe } from './BasePipe.js';
|
|
2
|
+
import { IndexedDBManager } from '../storage/IndexedDBManager.js';
|
|
3
|
+
import { LogPayload } from '../core/LogPayload.js';
|
|
4
|
+
export declare class IndexedDBPipe extends BasePipe {
|
|
5
|
+
private dbManager;
|
|
6
|
+
private initPromise;
|
|
7
|
+
private buffer;
|
|
8
|
+
constructor(dbManagerOrPromise: IndexedDBManager | Promise<IndexedDBManager>);
|
|
9
|
+
write(payload: LogPayload): Promise<void>;
|
|
10
|
+
flush(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { LogPayload, SessionMetadata } from '../core/LogPayload.js';
|
|
2
|
+
export interface IndexedDBManagerConfig {
|
|
3
|
+
dbPrefix: string;
|
|
4
|
+
scriptVersion: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
wmeVersion: string | null;
|
|
7
|
+
maxArchivedSessions?: number;
|
|
8
|
+
flushIntervalMs?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class IndexedDBManager {
|
|
11
|
+
private dbPrefix;
|
|
12
|
+
private maxArchivedSessions;
|
|
13
|
+
private scriptVersion;
|
|
14
|
+
private sessionId;
|
|
15
|
+
private wmeVersion;
|
|
16
|
+
private flushIntervalMs;
|
|
17
|
+
private db;
|
|
18
|
+
private queue;
|
|
19
|
+
private flushTimer;
|
|
20
|
+
private heartbeatTimer;
|
|
21
|
+
private loggerVersion;
|
|
22
|
+
private schemaVersion;
|
|
23
|
+
constructor(config: IndexedDBManagerConfig);
|
|
24
|
+
/**
|
|
25
|
+
* Returns the database name with prefix.
|
|
26
|
+
*/
|
|
27
|
+
getDatabaseName(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Initializes the database connection and saves session metadata.
|
|
30
|
+
*/
|
|
31
|
+
init(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Saves a session metadata record.
|
|
34
|
+
*/
|
|
35
|
+
saveSessionMetadata(metadata: SessionMetadata): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Periodically updates the current session's lastUpdated timestamp.
|
|
38
|
+
*/
|
|
39
|
+
touchSession(): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Starts the session heartbeat interval.
|
|
42
|
+
*/
|
|
43
|
+
private startHeartbeat;
|
|
44
|
+
/**
|
|
45
|
+
* Stops the session heartbeat interval.
|
|
46
|
+
*/
|
|
47
|
+
private stopHeartbeat;
|
|
48
|
+
/**
|
|
49
|
+
* Writes a log entry, scheduling a flush or flushing immediately for high priority.
|
|
50
|
+
*/
|
|
51
|
+
writeLog(payload: LogPayload): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Schedules a background flush if not already scheduled.
|
|
54
|
+
*/
|
|
55
|
+
private scheduleFlush;
|
|
56
|
+
/**
|
|
57
|
+
* Instantly flushes the in-memory queue to IndexedDB.
|
|
58
|
+
*/
|
|
59
|
+
flush(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Writes a batch of logs in a single transaction.
|
|
62
|
+
*/
|
|
63
|
+
writeLogsBatch(logs: LogPayload[]): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Retrieves all logs for a specific session.
|
|
66
|
+
*/
|
|
67
|
+
getLogsForSession(sessionId: string): Promise<LogPayload[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves all archived session records.
|
|
70
|
+
*/
|
|
71
|
+
getAllSessions(): Promise<SessionMetadata[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Prunes older sessions, keeping maxArchivedSessions.
|
|
74
|
+
* Protects active sessions in other tabs (updated in last 30s) and the current active session.
|
|
75
|
+
*/
|
|
76
|
+
pruneSessions(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Streams logs for a session via cursor.
|
|
79
|
+
*/
|
|
80
|
+
streamLogsForSession(sessionId: string, onLog: (log: LogPayload) => void): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Flushes outstanding logs, stops heartbeat, and closes connection.
|
|
83
|
+
*/
|
|
84
|
+
close(): Promise<void>;
|
|
85
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { WmeSDK } from 'wme-sdk-typings';
|
|
2
|
+
export interface SessionManagerConfig {
|
|
3
|
+
dbPrefix: string;
|
|
4
|
+
scriptVersion: string;
|
|
5
|
+
wmeSDK?: WmeSDK;
|
|
6
|
+
}
|
|
7
|
+
export declare class SessionManager {
|
|
8
|
+
private dbPrefix;
|
|
9
|
+
private scriptVersion;
|
|
10
|
+
private wmeSDK?;
|
|
11
|
+
private sessionId;
|
|
12
|
+
private tabId;
|
|
13
|
+
private channel;
|
|
14
|
+
constructor(config: SessionManagerConfig);
|
|
15
|
+
/**
|
|
16
|
+
* Initializes the session, handling tab isolation and duplicates.
|
|
17
|
+
*/
|
|
18
|
+
initSession(): Promise<string>;
|
|
19
|
+
private _probeConflict;
|
|
20
|
+
/**
|
|
21
|
+
* Defensively extract the WME version from passed SDK or global window context.
|
|
22
|
+
*/
|
|
23
|
+
getWmeVersion(): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Returns current session ID if initialized
|
|
26
|
+
*/
|
|
27
|
+
getSessionId(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Closes the session event channel
|
|
30
|
+
*/
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IndexedDBManager } from './IndexedDBManager.js';
|
|
2
|
+
export declare class ZipStreamer {
|
|
3
|
+
private dbManager;
|
|
4
|
+
constructor(dbManager: IndexedDBManager);
|
|
5
|
+
/**
|
|
6
|
+
* Exports all sessions and their logs from IndexedDB into a Zip compressed Blob.
|
|
7
|
+
*/
|
|
8
|
+
exportAllSessions(): Promise<Blob>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface EventChannelMessage<T = any> {
|
|
2
|
+
type: string;
|
|
3
|
+
payload: T;
|
|
4
|
+
}
|
|
5
|
+
export declare class EventChannel {
|
|
6
|
+
private channel;
|
|
7
|
+
private listeners;
|
|
8
|
+
constructor(name: string);
|
|
9
|
+
/**
|
|
10
|
+
* Publishes an event to the BroadcastChannel.
|
|
11
|
+
*/
|
|
12
|
+
publish<T>(type: string, payload: T): void;
|
|
13
|
+
/**
|
|
14
|
+
* Subscribes to a specific event type. Returns an unsubscribe function.
|
|
15
|
+
*/
|
|
16
|
+
subscribe<T>(type: string, callback: (payload: T) => void): () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Closes the underlying BroadcastChannel.
|
|
19
|
+
*/
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface IDBOpenOptions {
|
|
2
|
+
onUpgradeNeeded?: (db: IDBDatabase, event: IDBVersionChangeEvent) => void;
|
|
3
|
+
onBlocked?: (event: Event) => void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Opens an IndexedDB connection and wraps the request in a Promise.
|
|
7
|
+
*/
|
|
8
|
+
export declare function openDB(name: string, version: number, options?: IDBOpenOptions): Promise<IDBDatabase>;
|
|
9
|
+
/**
|
|
10
|
+
* Wraps a standard IDBRequest in a Promise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function wrapRequest<T>(request: IDBRequest<T>): Promise<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Runs a transaction on the database and resolves when the transaction completes.
|
|
15
|
+
*/
|
|
16
|
+
export declare function runTransaction(db: IDBDatabase, storeNames: string | string[], mode: IDBTransactionMode, callback: (tx: IDBTransaction) => void): Promise<void>;
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@editor-x/wme-logstream",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Lightweight structured logging, state tracking, and IndexedDB persistence library for Waze Map Editor (WME) userscripts and extensions.",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest",
|
|
17
|
+
"build": "rollup -c",
|
|
18
|
+
"lint": "eslint .",
|
|
19
|
+
"lint:fix": "eslint . --fix",
|
|
20
|
+
"format": "prettier --write .",
|
|
21
|
+
"format:check": "prettier --check ."
|
|
22
|
+
},
|
|
23
|
+
"keywords": [],
|
|
24
|
+
"author": "David Slutsky",
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"fflate": "^0.8.3",
|
|
29
|
+
"jsondiffpatch": "^0.7.6"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@eslint/js": "^10.0.1",
|
|
33
|
+
"@rollup/plugin-commonjs": "^29.0.3",
|
|
34
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
35
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
36
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
37
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
38
|
+
"@types/node": "^26.0.0",
|
|
39
|
+
"eslint": "^10.5.0",
|
|
40
|
+
"eslint-config-prettier": "^10.1.8",
|
|
41
|
+
"fake-indexeddb": "^6.2.5",
|
|
42
|
+
"jsdom": "^29.1.1",
|
|
43
|
+
"prettier": "^3.8.4",
|
|
44
|
+
"rollup": "^4.62.2",
|
|
45
|
+
"tslib": "^2.8.1",
|
|
46
|
+
"typescript": "^6.0.3",
|
|
47
|
+
"typescript-eslint": "^8.62.0",
|
|
48
|
+
"vitest": "^4.1.9",
|
|
49
|
+
"wme-sdk-typings": "https://www.waze.com/editor/sdk/wme-sdk-typings.tgz"
|
|
50
|
+
}
|
|
51
|
+
}
|