Skip to content

Commit

Permalink
ref(utils): convert memo from class to function (#4283)
Browse files Browse the repository at this point in the history
  • Loading branch information
AbhiPrasad authored and onurtemizkan committed Dec 19, 2021
1 parent 0b2249d commit 2ede32d
Showing 2 changed files with 25 additions and 38 deletions.
55 changes: 21 additions & 34 deletions packages/utils/src/memo.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,44 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/**
* Memo class used for decycle json objects. Uses WeakSet if available otherwise array.
*/
export class Memo {
/** Determines if WeakSet is available */
private readonly _hasWeakSet: boolean;
/** Either WeakSet or Array */
private readonly _inner: any;

public constructor() {
this._hasWeakSet = typeof WeakSet === 'function';
this._inner = this._hasWeakSet ? new WeakSet() : [];
}
export type MemoFunc = [(obj: any) => boolean, (obj: any) => void];

/**
* Sets obj to remember.
* @param obj Object to remember
*/
public memoize(obj: any): boolean {
if (this._hasWeakSet) {
if (this._inner.has(obj)) {
/**
* Helper to decycle json objects
*/
export function memoBuilder(): MemoFunc {
const hasWeakSet = typeof WeakSet === 'function';
const inner: any = hasWeakSet ? new WeakSet() : [];
function memoize(obj: any): boolean {
if (hasWeakSet) {
if (inner.has(obj)) {
return true;
}
this._inner.add(obj);
inner.add(obj);
return false;
}
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < this._inner.length; i++) {
const value = this._inner[i];
for (let i = 0; i < inner.length; i++) {
const value = inner[i];
if (value === obj) {
return true;
}
}
this._inner.push(obj);
inner.push(obj);
return false;
}

/**
* Removes object from internal storage.
* @param obj Object to forget
*/
public unmemoize(obj: any): void {
if (this._hasWeakSet) {
this._inner.delete(obj);
function unmemoize(obj: any): void {
if (hasWeakSet) {
inner.delete(obj);
} else {
for (let i = 0; i < this._inner.length; i++) {
if (this._inner[i] === obj) {
this._inner.splice(i, 1);
for (let i = 0; i < inner.length; i++) {
if (inner[i] === obj) {
inner.splice(i, 1);
break;
}
}
}
}
return [memoize, unmemoize];
}
8 changes: 4 additions & 4 deletions packages/utils/src/object.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import { ExtendedError, WrappedFunction } from '@sentry/types';

import { htmlTreeAsString } from './browser';
import { isElement, isError, isEvent, isInstanceOf, isPlainObject, isPrimitive, isSyntheticEvent } from './is';
import { Memo } from './memo';
import { memoBuilder, MemoFunc } from './memo';
import { getFunctionName } from './stacktrace';
import { truncate } from './string';

@@ -277,7 +277,7 @@ function normalizeValue<T>(value: T, key?: any): T | string {
* @param memo Optional Memo class handling decycling
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function walk(key: string, value: any, depth: number = +Infinity, memo: Memo = new Memo()): any {
export function walk(key: string, value: any, depth: number = +Infinity, memo: MemoFunc = memoBuilder()): any {
// If we reach the maximum depth, serialize whatever has left
if (depth === 0) {
return serializeValue(value);
@@ -303,7 +303,7 @@ export function walk(key: string, value: any, depth: number = +Infinity, memo: M
const acc = Array.isArray(value) ? [] : {};

// If we already walked that branch, bail out, as it's circular reference
if (memo.memoize(value)) {
if (memo[0](value)) {
return '[Circular ~]';
}

@@ -318,7 +318,7 @@ export function walk(key: string, value: any, depth: number = +Infinity, memo: M
}

// Once walked through all the branches, remove the parent from memo storage
memo.unmemoize(value);
memo[1](value);

// Return accumulated values
return acc;

0 comments on commit 2ede32d

Please sign in to comment.