Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@testing-library/jest-dom';
import { TextDecoder, TextEncoder } from 'util';
import { performance } from 'perf_hooks';
import { deserialize, serialize } from 'v8';
import 'jest-canvas-mock';
import './__mocks__/dh-core';
import Log from '@deephaven/log';
Expand Down Expand Up @@ -79,6 +80,14 @@ Object.defineProperty(window, 'TextEncoder', {
value: TextEncoder,
});

// jsdom does not implement structuredClone, which IndexedDB relies on.
// v8 serialization gives real structured-clone semantics; the Uint8Array copy
// keeps the Buffer return type assignable to deserialize across TS versions.
Object.defineProperty(window, 'structuredClone', {
value: (value: unknown) => deserialize(new Uint8Array(serialize(value))),
writable: true,
});

Object.defineProperty(document, 'fonts', {
value: {
ready: Promise.resolve(),
Expand Down
23 changes: 22 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"conventional-changelog-conventionalcommits": "10.3.0",
"cross-env": "^7.0.2",
"eslint": "^8.29.0",
"fake-indexeddb": "^6.2.5",
"identity-obj-proxy": "^3.0.0",
"jasmine": "4.0.2",
"jest": "^29.3.1",
Expand Down
3 changes: 3 additions & 0 deletions packages/log/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
},
"dependencies": {
"event-target-shim": "^6.0.2",
"idb": "^8.0.3",
"jszip": "^3.10.1",
"lodash.throttle": "^4.1.1",
"nanoid": "^5.0.7",
Comment thread
dgodinez-dh marked this conversation as resolved.
"safe-stable-stringify": "^2.5.0"
},
"files": [
Expand Down
22 changes: 21 additions & 1 deletion packages/log/src/LogExport.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import JSZip from 'jszip';
import { configure } from 'safe-stable-stringify';
import type LogHistory from './LogHistory';
import { getLogIndexedDbHistory } from './LogInit';

export interface LogHistorySource {
getFormattedHistory: () => string | Promise<string>;
}

// List of paths to ignore
// '' represents the root object
Expand Down Expand Up @@ -109,6 +114,7 @@ function formatDate(date: Date): string {
* @param ignoreList List of JSON paths to ignore in redux data. A JSON path is a list representing the path to that value (e.g. client.data would be `['client', 'data']`). Wildcards (*) are accepted in the path.
* @param fileNamePrefix The zip file name without the .zip extension. Ex: test will be saved as test.zip
* @param maximumDepth The maximum depth to serialize the redux data to. Objects at the maximum depth will be replaced with "[Object]" or "[Array]".
* @param persistedHistory Logs retained across sessions, included as console-history.txt. Defaults to the store created by logInit, if any.
* @returns A promise that resolves successfully if the log archive is created and downloaded successfully, rejected if there's an error
*/
export async function exportLogs(
Expand All @@ -117,11 +123,25 @@ export async function exportLogs(
reduxData?: Record<string, unknown>,
ignoreList: string[][] = DEFAULT_PATH_IGNORE_LIST,
fileNamePrefix = `${formatDate(new Date())}_support_logs`,
maximumDepth: number = DEFAULT_MAXIMUM_DEPTH
maximumDepth: number = DEFAULT_MAXIMUM_DEPTH,
persistedHistory: LogHistorySource | null = getLogIndexedDbHistory()
): Promise<void> {
const zip = new JSZip();
const folder = zip.folder(fileNamePrefix) as JSZip;
folder.file('console.txt', logHistory.getFormattedHistory());

if (persistedHistory != null) {
// A failed read must not cost us the rest of the archive
try {
const history = await persistedHistory.getFormattedHistory();
if (history !== '') {
folder.file('console-history.txt', history);
}
} catch (e) {
folder.file('console-history.txt', `Failed to read persisted logs: ${e}`);
Comment thread
dgodinez-dh marked this conversation as resolved.
}
}

if (metadata != null) {
folder.file('metadata.json', getFormattedMetadata(metadata));
}
Expand Down
Loading
Loading