Socket
Socket
Sign inDemoInstall

@memlab/core

Package Overview
Dependencies
158
Maintainers
3
Versions
38
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.2 to 1.1.3

3

dist/lib/Config.d.ts

@@ -174,2 +174,3 @@ /**

_scenario: Optional<IScenario>;
_isHeadfulBrowser: boolean;
externalLeakFilter?: Optional<ILeakFilter>;

@@ -196,2 +197,4 @@ monoRepoDir: string;

get browser(): string;
set isHeadfulBrowser(isHeadful: boolean);
get isHeadfulBrowser(): boolean;
get browserBinaryPath(): string;

@@ -198,0 +201,0 @@ set reportLeaksInTimers(flag: boolean);

@@ -57,2 +57,3 @@ "use strict";

this._timerEdges = [];
this._isHeadfulBrowser = false;
this.targetApp = Constant_1.default.unset;

@@ -70,2 +71,3 @@ this.targetTab = Constant_1.default.unset;

this.puppeteerConfig = {
headless: !this._isHeadfulBrowser,
devtools: this.openDevtoolsConsole,

@@ -363,2 +365,13 @@ // IMPORTANT: test ContinuousTest before change this config

}
set isHeadfulBrowser(isHeadful) {
this._isHeadfulBrowser = isHeadful;
this.puppeteerConfig.headless = !isHeadful;
if (isHeadful) {
// if running in headful mode
this.disableXvfb();
}
}
get isHeadfulBrowser() {
return this._isHeadfulBrowser;
}
get browserBinaryPath() {

@@ -365,0 +378,0 @@ return path_1.default.join(this.browserDir, this.browser);

4

dist/lib/Constant.js

@@ -16,4 +16,4 @@ "use strict";

isFRL: false,
defaultEngine: 'v8',
supportedEngines: ['v8', 'hermes'],
defaultEngine: 'V8',
supportedEngines: ['V8', 'hermes'],
supportedBrowsers: Object.create(null),

@@ -20,0 +20,0 @@ internalDir: 'fb-internal',

@@ -34,3 +34,3 @@ /**

forEachReference(callback: EdgeIterationCallback): void;
findReference(predicate: Predicator<IHeapEdge>): Nullable<IHeapEdge>;
findAnyReference(predicate: Predicator<IHeapEdge>): Nullable<IHeapEdge>;
findAnyReferrer(predicate: Predicator<IHeapEdge>): Nullable<IHeapEdge>;

@@ -37,0 +37,0 @@ findReferrers(predicate: Predicator<IHeapEdge>): IHeapEdge[];

@@ -134,3 +134,3 @@ /**

}
findReference(predicate) {
findAnyReference(predicate) {
let found = null;

@@ -137,0 +137,0 @@ this.forEachReference((edge) => {

@@ -85,2 +85,5 @@ /**

get(idx) {
if (idx < 0 || idx >= self._nodeCount) {
return null;
}
return new HeapNode_1.default(self, idx);

@@ -113,2 +116,5 @@ },

get(idx) {
if (idx < 0 || idx >= self._edgeCount) {
return null;
}
return new HeapEdge_1.default(self, idx);

@@ -185,3 +191,3 @@ },

// check if the table has any weak reference to any object
const ref = table.findReference((edge) => edge.type === 'weak' && edge.toNode.name !== 'system / Oddball');
const ref = table.findAnyReference((edge) => edge.type === 'weak' && edge.toNode.name !== 'system / Oddball');
return ref != null;

@@ -188,0 +194,0 @@ }

@@ -105,3 +105,3 @@ /**

Console_1.default.overwrite('identifying snapshot engine...');
let engine = 'v8';
let engine = 'V8';
snapshot.nodes.forEach((node) => {

@@ -108,0 +108,0 @@ if (node.type === 'object' && node.name.startsWith('Object(')) {

@@ -185,2 +185,5 @@ "use strict";

const parent = node.snapshot.nodes.get(index);
if (!parent) {
continue;
}
const parentInfo = getNodeNameInJSON(parent, args);

@@ -597,3 +600,3 @@ key = `${key}: --return (property)---> ${parentInfo}`;

nodeImpact = options.color
? chalk_1.default.grey('[') + chalk_1.default.blue(nodeRetainSize) + chalk_1.default.grey(']')
? chalk_1.default.grey('[') + chalk_1.default.blue.bold(nodeRetainSize) + chalk_1.default.grey(']')
: `[${nodeRetainSize}]`;

@@ -600,0 +603,0 @@ }

@@ -99,3 +99,3 @@ /**

getDomainPrefixes(): string[];
getCookieFile(visitPlan: IE2EScenarioVisitPlan): string | null;
getCookieFile(visitPlan: IE2EScenarioVisitPlan): Nullable<string>;
getAvailableSteps(): IE2EStepBasic[];

@@ -147,12 +147,45 @@ getNodeNameBlocklist(): string[];

/**
* The type for defining custom leak-filtering logic.
* * **Examples**:
* The `ILeakFilter` interface allows you to define a leak detector and
* customize the leak filtering logic in memlab (instead of using the
* built-in leak filters).
*
* Use the leak filter definition in command line interface to filter
* leaks detected from browser interactions
* ```bash
* memlab run --scenario <SCENARIO FILE> --leak-filter <PATH TO leak-filter.js>
* ```
*
* If you have already run `memlab run` or `memlab snapshot` which saved
* heap snapshot and other meta data on disk, use the following command
* to filter leaks based on those saved heap snapshots (query the default
* data location by `memlab get-default-work-dir`).
*
* ```bash
* memlab find-leaks --leak-filter <PATH TO leak-filter.js>
* ```
* Here is an example TypeScript file defining a leak filter.
* The command line interface only accepts compiled JavaScript file.
* You can also define the leak filter in JavaScript (without the
* type annotations.
*
* ```typescript
* const scenario = {
* import {IHeapNode, IHeapSnapshot, HeapNodeIdSet, utils} from '@memlab/core';
*
* };
*
* let map = Object.create(null);
* function initMap(snapshot: IHeapSnapshot): Record<string, number> {
* const map = Object.create(null);
* snapshot.nodes.forEach(node => {
* if (node.type !== 'string') {
* return;
* }
* const str = utils.getStringNodeValue(node);
* if (str in map) {
* ++map[str];
* } else {
* map[str] = 1;
* }
* });
* return map;
* }
* const beforeLeakFilter = (snapshot: IHeapSnapshot, _leakedNodeIds: HeapNodeIdSet): void => {
* map = initializeMapUsingSnapshot(snapshot);
* map = initMap(snapshot);
* };

@@ -173,3 +206,77 @@ *

export interface ILeakFilter {
/**
* Lifecycle function callback that is invoked initially once before
* the subsequent `leakFilter` function calls. This callback could
* be used to initialize some data stores or any one-off
* preprocessings.
*
* * **Parameters**:
* * snapshot: `IHeapSnapshot` | the final heap snapshot taken after
* all browser interactions are done.
* Check out {@link IHeapSnapshot} for more APIs that queries the heap snapshot.
* * leakedNodeIds: `Set<number>` | the set of ids of all JS heap objects
* allocated by the `action` call but not released after the `back` call
* in browser.
*
* * **Examples**:
* ```typescript
* module.exports = {
* beforeLeakFilter: (snapshot, leakedNodeIds) {
* // initialize some data stores
* },
* leakFilter(node, snapshot, leakedNodeIds) {
* // use the data stores
* },
* };
* ```
*/
beforeLeakFilter?: InitLeakFilterCallback;
/**
* This callback defines how you want to filter out the
* leaked objects. The callback is called for every node (JS heap
* object in browser) allocated by the `action` callback, but not
* released after the `back` callback. Those objects could be caches
* that are retained in memory on purpose, or they are memory leaks.
*
* This optional callback allows you to define your own algorithm
* to cherry pick memory leaks for specific JS program under test.
*
* If this optional callback is not defined, memlab will use its
* built-in leak filter, which considers detached DOM elements
* and unmounted Fiber nodes (detached from React Fiber tree) as
* memory leaks.
*
* * **Parameters**:
* * node: `IHeapNode` | one of the heap object allocated but not released.
* * snapshot: `IHeapSnapshot` | the final heap snapshot taken after
* all browser interactions are done.
* Check out {@link IHeapSnapshot} for more APIs that queries the heap snapshot.
* * leakedNodeIds: `Set<number>` | the set of ids of all JS heap objects
* allocated by the `action` call but not released after the `back` call
* in browser.
*
* * **Returns**: the boolean value indicating whether the given node in
* the snapshot should be considered as leaked.
*
*
* ```javascript
* // save as leak-filter.js
* module.exports = {
* leakFilter(node, snapshot, leakedNodeIds) {
* // any unreleased node (JS heap object) with 1MB+
* // retained size is considered a memory leak
* return node.retainedSize > 1000000;
* },
* };
* ```
*
* Use the leak filter definition in command line interface:
* ```bash
* memlab find-leaks --leak-filter <PATH TO leak-filter.js>
* ```
*
* ```bash
* memlab run --scenario <SCENARIO FILE> --leak-filter <PATH TO leak-filter.js>
* ```
*/
leakFilter: LeakFilterCallback;

@@ -223,2 +330,5 @@ }

* back: async () => ... ,
* cookies: () => ... , // optional
* repeat: () => ... , // optional
* ...
* };

@@ -237,2 +347,5 @@ * ```

* back: async () => ... ,
* cookies: () => ... , // optional
* repeat: () => ... , // optional
* ...
* };

@@ -251,3 +364,7 @@ * const leaks = await run({scenario});

* specific cookie(s) to be set, you can pass them as
* a list of <name, value> pairs.
* a list of `<name, value, domain>` tuples.
*
* **Note**: please make sure that you provide the correct `domain` field for
* the cookies tuples.
*
* @returns cookie list

@@ -259,6 +376,6 @@ * * **Examples**:

* cookies: () => [
* {"name":"cm_j","value":"none"},
* {"name":"datr","value":"yJvIY..."},
* {"name":"c_user","value":"8917..."},
* {"name":"xs","value":"95:9WQ..."},
* {name:'cm_j', value: 'none', domain: '.facebook.com'},
* {name:'datr', value: 'yJvIY...', domain: '.facebook.com'},
* {name:'c_user', value: '8917...', domain: '.facebook.com'},
* {name:'xs', value: '95:9WQ...', domain: '.facebook.com'},
* // ...

@@ -364,3 +481,3 @@ * ],

* Optional callback function that checks if the web page is loaded
* after for initial page loading and subsequent browser interactions.
* for the initial page load and subsequent browser interactions.
*

@@ -401,3 +518,3 @@ * If this callback is not provided, memlab by default

* the subsequent `leakFilter` function calls. This callback could
* be used to initialize some data stores or to do some one-off
* be used to initialize some data stores or to any one-off
* preprocessings.

@@ -427,3 +544,3 @@ *

/**
* This callback that defines how you want to filter out the
* This callback defines how you want to filter out the
* leaked objects. The callback is called for every node (JS heap

@@ -619,2 +736,8 @@ * object in browser) allocated by the `action` callback, but not

};
/**
* A heap snapshot is generally a graph where graph nodes are JS heap objects
* and graph edges are JS references among JS heap objects. For more details
* on the structure of nodes and edges in the heap graph, check out
* {@link IHeapNode} and {@link IHeapEdge}.
*/
export interface IHeapSnapshot {

@@ -793,2 +916,6 @@ /** @internal */

* a marker tagged by {@link tagObject}.
*
* The `tagObject` API does not modify the object instance in any way
* (e.g., no additional or hidden properties added to the tagged object).
*
* @param tag marker name on the object instances tagged by {@link tagObject}

@@ -828,28 +955,195 @@ * @returns returns `true` if there is at least one such object in the heap

}
/**
* An `IHeapLocation` instance contains a source location information
* associated with a JS heap object.
* A heap snapshot is generally a graph where graph nodes are JS heap objects
* and graph edges are JS references among JS heap objects.
*
* @readonly it is not recommended to modify any `IHeapLocation` instance
*
* * **Examples**: V8 or hermes heap snapshot can be parsed by the
* {@link getHeapFromFile} API.
*
* ```typescript
* import type {IHeapSnapshot, IHeapNode, IHeapLocation} from '@memlab/core';
* import {dumpNodeHeapSnapshot} from '@memlab/core';
* import {getHeapFromFile} from '@memlab/heap-analysis';
*
* (async function () {
* const heapFile = dumpNodeHeapSnapshot();
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
*
* // iterate over each node (heap object)
* heap.nodes.forEach((node: IHeapNode, i: number) => {
* const location: Nullable<IHeapLocation> = node.location;
* if (location) {
* // use the location API here
* location.line;
* // ...
* }
* });
* })();
* ```
*/
export interface IHeapLocation {
/**
* get the {@link IHeapSnapshot} containing this location instance
*/
snapshot: IHeapSnapshot;
/**
* get the script ID of the source file
*/
script_id: number;
/**
* get the line number
*/
line: number;
/**
* get the column number
*/
column: number;
}
/** @internal */
export interface IHeapEdgeBasic {
/**
* name of the JS reference. If this is a reference to an array element
* or internal table element, it is an numeric index
*/
name_or_index: number | string;
/**
* type of the JS reference, all types:
* `context`, `element`, `property`, `internal`, `hidden`, `shortcut`, `weak`
*/
type: string;
}
/**
* An `IHeapEdge` instance represents a JS reference in a heap snapshot.
* A heap snapshot is generally a graph where graph nodes are JS heap objects
* and graph edges are JS references among JS heap objects.
*
* @readonly it is not recommended to modify any `IHeapEdge` instance
*
* * **Examples**: V8 or hermes heap snapshot can be parsed by the
* {@link getHeapFromFile} API.
*
* ```typescript
* import type {IHeapSnapshot, IHeapEdge} from '@memlab/core';
* import {dumpNodeHeapSnapshot} from '@memlab/core';
* import {getHeapFromFile} from '@memlab/heap-analysis';
*
* (async function () {
* const heapFile = dumpNodeHeapSnapshot();
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
*
* // iterate over each edge (JS reference in heap)
* heap.edges.forEach((edge: IHeapEdge, i: number) => {
* // use the heap edge APIs here
* const nameOrIndex = edge.name_or_index;
* // ...
* });
* })();
* ```
*/
export interface IHeapEdge extends IHeapEdgeBasic {
/**
* get the {@link IHeapSnapshot} containing this JS reference
*/
snapshot: IHeapSnapshot;
/**
* index of this JS reference inside the `edge.snapshot.edges` pseudo array
*/
edgeIndex: number;
/**
* if `true`, means this is a reference to an array element
* or internal table element (`edge.name_or_index` will return a number),
* otherwise this is a reference with a string name (`edge.name_or_index`
* will return a string)
*/
is_index: boolean;
/**
* the index of the JS heap object pointed to by this reference
*/
to_node: number;
/**
* returns an {@link IHeapNode} instance representing the JS heap object
* pointed to by this reference
*/
toNode: IHeapNode;
/**
* returns an {@link IHeapNode} instance representing the hosting
* JS heap object where this reference starts
*/
fromNode: IHeapNode;
}
/**
* A pseudo array containing all heap graph edges (references to heap objects
* in heap). A JS heap could contain millions of references, so memlab uses
* a pseudo array as the collection of all the heap edges. The pseudo
* array provides API to query and traverse all heap references.
*
* @readonly modifying this pseudo array is not recommended
*
* * **Examples**:
* ```typescript
* import type {IHeapSnapshot, IHeapEdges} from '@memlab/core';
* import {dumpNodeHeapSnapshot} from '@memlab/core';
* import {getHeapFromFile} from '@memlab/heap-analysis';
*
* (async function () {
* const heapFile = dumpNodeHeapSnapshot();
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
*
* const edges: IHeapEdges = heap.edges;
* edges.length;
* edges.get(0);
* edges.forEach((edge, i) => {
* if (stopIteration) {
* return false;
* }
* });
* })();
* ```
*/
export interface IHeapEdges {
/**
* The total number of edges in heap graph (or JS references in heap
* snapshot).
*/
length: number;
get(index: number): IHeapEdge;
/**
* get an {@link IHeapEdge} element at the specified index
* @param index the index of an element in the pseudo array, the index ranges
* from 0 to array length - 1. Notice that this is not the heap node id.
* @returns When 0 <= `index` < array.length, this API returns the element
* at the specified index, otherwise it returns `null`.
*/
get(index: number): Nullable<IHeapEdge>;
/**
* Iterate over all array elements and apply the callback
* to each element in ascending order of element index.
* @param callback the callback does not need to return any value, if
* the callback returns `false` when iterating on element at index `i`,
* then all elements after `i` won't be iterated.
*/
forEach(callback: (edge: IHeapEdge, index: number) => void | boolean): void;
}
/** @internal */
export interface IHeapNodeBasic {
/**
* the type of the heap node object. All possible types:
* This is engine-specific, for example all types in V8:
* `hidden`, `array`, `string`, `object`, `code`, `closure`, `regexp`,
* `number`, `native`, `synthetic`, `concatenated string`, `sliced string`,
* `symbol`, `bigint`
*/
type: string;
/**
* this is the `name` field associated with the heap object,
* for JS object instances (type `object`), `name` is the constructor's name
* of the object instance. for `string`, `name` is the string value.
*/
name: string;
/**
* unique id of the heap object
*/
id: number;

@@ -860,40 +1154,399 @@ }

}>;
/**
* An `IHeapNode` instance represents a JS heap object in a heap snapshot.
* A heap snapshot is generally a graph where graph nodes are JS heap objects
* and graph edges are JS references among JS heap objects.
*
* @readonly it is not recommended to modify any `IHeapNode` instance
*
* * **Examples**: V8 or hermes heap snapshot can be parsed by the
* {@link getHeapFromFile} API.
*
* ```typescript
* import type {IHeapSnapshot, IHeapNode} from '@memlab/core';
* import {dumpNodeHeapSnapshot} from '@memlab/core';
* import {getHeapFromFile} from '@memlab/heap-analysis';
*
* (async function () {
* const heapFile = dumpNodeHeapSnapshot();
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
*
* // iterate over each node (heap object)
* heap.nodes.forEach((node: IHeapNode, i: number) => {
* // use the heap node APIs here
* const id = node.id;
* const type = node.type;
* // ...
* });
* })();
* ```
*/
export interface IHeapNode extends IHeapNodeBasic {
/**
* get the {@link IHeapSnapshot} containing this heap object
*/
snapshot: IHeapSnapshot;
/**
* * If the heap object is a DOM element and the DOM element is detached
* from the DOM tree, `is_detached` will be `true`;
* * If the heap object is a React Fiber node and the Fiber node is unmounted
* from the React Fiber tree, `is_detached` will be `true`;
* otherwise it will be `false`
*/
is_detached: boolean;
/** @internal */
detachState: number;
/** @internal */
markAsDetached(): void;
/** @internal */
attributes: number;
/**
* The *shallow size* of the heap object (i.e., the size of memory that is held
* by the object itself.). For difference between **shallow size** and
* **retained size**, check out
* [this doc](https://developer.chrome.com/docs/devtools/memory-problems/memory-101/#object_sizes).
*/
self_size: number;
/**
* The total number of outgoing JS references (including engine-internal,
* native, and JS references).
*/
edge_count: number;
/** @internal */
trace_node_id: number;
/**
* Get a JS array containing all outgoing JS references from this heap object
* (including engine-internal, native, and JS references).
*/
references: IHeapEdge[];
/**
* Get a JS array containing all incoming JS references pointing to this heap
* object (including engine-internal, native, and JS references).
*/
referrers: IHeapEdge[];
/**
* The incoming edge which leads to the parent node
* on the shortest path to GC root.
*/
pathEdge: IHeapEdge | null;
/**
* index of this heap object inside the `node.snapshot.nodes` pseudo array
*/
nodeIndex: number;
/**
* The *retained size* of the heap object (i.e., the total size of memory that
* could be released if this object is released). For difference between
* **retained size** and **shallow size**, check out
* [this doc](https://developer.chrome.com/docs/devtools/memory-problems/memory-101/#object_sizes).
*/
retainedSize: number;
dominatorNode: IHeapNode | null;
location: IHeapLocation | null;
/**
* get the dominator node of this node. If the dominator node gets released
* there will be no path from GC to this node, and therefore this node can
* also be released.
* For more information on what a dominator node is, please check out
* [this doc](https://developer.chrome.com/docs/devtools/memory-problems/memory-101/#dominators).
*/
dominatorNode: Nullable<IHeapNode>;
/**
* source location information of this heap object (if it is recorded by
* the heap snapshot).
*/
location: Nullable<IHeapLocation>;
/** @internal */
highlight?: boolean;
/**
* check if this a string node (normal string node, concatenated string node
* or sliced string node)
*/
isString: boolean;
/**
* convert to an {@link IHeapStringNode} object if this node is a string node.
* The {@link IHeapStringNode} object supports querying the string content
* inside the string node.
*/
toStringNode(): Nullable<IHeapStringNode>;
/**
* executes a provided callback once for each JavaScript reference in the
* hosting node (or outgoing edges from the node)
* @param callback the callback for each outgoing JavaScript reference
* @returns this API returns void
*
* * **Examples**:
* ```typescript
* node.forEachReference((edge: IHeapEdge) => {
* // process edge ...
*
* // if no need to iterate over remaining edges after
* // the current edge in the node.references list
* return {stop: true};
* });
* ```
*/
forEachReference(callback: EdgeIterationCallback): void;
/**
* executes a provided callback once for each JavaScript reference pointing
* to the hosting node (or incoming edges to the node)
* @param callback the callback for each incoming JavaScript reference
* @returns this API returns void
*
* * **Examples**:
* ```typescript
* node.forEachReferrer((edge: IHeapEdge) => {
* // process edge ...
*
* // if no need to iterate over remaining edges after
* // the current edge in the node.referrers list
* return {stop: true};
* });
* ```
*/
forEachReferrer(callback: EdgeIterationCallback): void;
findReference: (predicate: Predicator<IHeapEdge>) => Nullable<IHeapEdge>;
/**
* executes a provided predicate callback once for each JavaScript reference
* in the hosting node (or outgoing edges from the node) until the predicate
* returns `true`
* @param predicate the callback for each outgoing JavaScript reference
* @returns the first outgoing edge for which the predicate returns `true`,
* otherwise returns `null` if no such edge is found.
*
* * **Examples**:
* ```typescript
* const reference = node.findAnyReference((edge: IHeapEdge) => {
* // find the outgoing reference with name "ref"
* return edge.name_or_index === 'ref';
* });
* ```
*/
findAnyReference: (predicate: Predicator<IHeapEdge>) => Nullable<IHeapEdge>;
/**
* executes a provided predicate callback once for each JavaScript reference
* pointing to the hosting node (or incoming edges to the node) until the
* predicate returns `true`
* @param predicate the callback for each incoming JavaScript reference
* @returns the first incoming edge for which the predicate returns `true`,
* otherwise returns `null` if no such edge is found.
*
* * **Examples**:
* ```typescript
* const referrer = node.findAnyReferrer((edge: IHeapEdge) => {
* // find the incoming reference with name "ref"
* return edge.name_or_index === 'ref';
* });
* ```
*/
findAnyReferrer: (predicate: Predicator<IHeapEdge>) => Nullable<IHeapEdge>;
/**
* executes a provided predicate callback once for each JavaScript reference
* pointing to the hosting node (or incoming edges to the node)
* @param predicate the callback for each incoming JavaScript reference
* @returns an array containing all the incoming edges for which the
* predicate returns `true`, otherwise returns an empty array if no such
* edge is found.
*
* * **Examples**:
* ```typescript
* const referrers = node.findReferrers((edge: IHeapEdge) => {
* // find all the incoming references with name "ref"
* return edge.name_or_index === 'ref';
* });
* ```
*/
findReferrers: (predicate: Predicator<IHeapEdge>) => IHeapEdge[];
/**
* Given a JS reference's name and type, this API finds an outgoing JS
* reference from the hosting node.
* @param edgeName the name of the outgoing JavaScript reference
* @param edgeType optional parameter specifying the type of the outgoing
* JavaScript reference
* @returns the outgoing edge that meets the specification
*
* * **Examples**:
* ```typescript
* // find the internal reference to node's hidden class
* const reference = node.getReference('map', 'hidden');
* ```
*/
getReference: (edgeName: string | number, edgeType?: string) => Nullable<IHeapEdge>;
/**
* Given a JS reference's name and type, this API finds the outgoing JS
* reference from the hosting node, and returns the JS heap object pointed to
* by the outgoing JS reference.
* @param edgeName the name of the outgoing JavaScript reference
* @param edgeType optional parameter specifying the type of the outgoing
* JavaScript reference
* @returns the node pointed to by the outgoing reference that meets
* the specification
*
* * **Examples**:
* ```typescript
* // find the node's hidden class
* const hiddenClassNode = node.getReferenceNode('map', 'hidden');
* // this is equivalent to
* const hiddenClassNode2 = node.getReference('map', 'hidden')?.toNode;
* ```
*/
getReferenceNode: (edgeName: string | number, edgeType?: string) => Nullable<IHeapNode>;
/**
* Given a JS reference's name and type, this API finds an incoming JS
* reference pointing to the hosting node.
* @param edgeName the name of the incoming JavaScript reference
* @param edgeType optional parameter specifying the type of the incoming
* JavaScript reference
* @returns the incoming edge that meets the specification
*
* * **Examples**:
* ```typescript
* // find one of the JS reference named "ref" pointing to node
* const reference = node.getAnyReferrer('ref', 'property');
* ```
*/
getAnyReferrer: (edgeName: string | number, edgeType?: string) => Nullable<IHeapEdge>;
/**
* Given a JS reference's name and type, this API finds one of the incoming JS
* references pointing to the hosting node, and returns the JS heap object
* containing the incoming reference.
* @param edgeName the name of the incoming JavaScript reference
* @param edgeType optional parameter specifying the type of the incoming
* JavaScript reference
* @returns the node containing the incoming JS reference that meets
* the specification
*
* * **Examples**:
* ```typescript
* // find one of the JS heap object with a JS reference
* // named "ref" pointing to node
* const n1 = node.getAnyReferrerNode('ref', 'property');
* // this is equivalent to
* const n2 = node.getAnyReferrer('ref', 'property')?.fromNode;
* ```
*/
getAnyReferrerNode: (edgeName: string | number, edgeType?: string) => Nullable<IHeapNode>;
/**
* Given a JS reference's name and type, this API finds all the incoming JS
* reference pointing to the hosting node.
* @param edgeName the name of the incoming JavaScript reference
* @param edgeType optional parameter specifying the type of the incoming
* JavaScript reference
* @returns an array containing all the incoming edges that
* meet the specification
*
* * **Examples**:
* ```typescript
* // find all of of the JS reference named "ref" pointing to node
* const referrers = node.getReferrers('ref', 'property');
* ```
*/
getReferrers: (edgeName: string | number, edgeType?: string) => IHeapEdge[];
/**
* Given a JS reference's name and type, this API finds all of the incoming JS
* references pointing to the hosting node, and returns an array containing
* the hosting node for each of the incoming JS references.
* @param edgeName the name of the incoming JavaScript reference
* @param edgeType optional parameter specifying the type of the incoming
* JavaScript reference
* @returns an array containing the hosting nodes, with each node corresponds
* to each incoming JS reference that meets the specification
*
* * **Examples**:
* ```typescript
* // find all of the JS heap object with a JS reference
* // named "ref" pointing to node
* const nodes1 = node.getReferrerNodes('ref', 'property');
* // this is equivalent to
* const nodes2 = node.getReferrers('ref', 'property')
* .map(edge => edge.fromNode);
* ```
*/
getReferrerNodes: (edgeName: string | number, edgeType?: string) => IHeapNode[];
}
/**
* An `IHeapStringNode` instance represents a JS string in a heap snapshot.
* A heap snapshot is generally a graph where graph nodes are JS heap objects
* and graph edges are JS references among JS heap objects.
*
* @readonly it is not recommended to modify any `IHeapStringNode` instance
*
* * **Examples**: V8 or hermes heap snapshot can be parsed by the
* {@link getHeapFromFile} API.
*
* ```typescript
* import type {IHeapSnapshot, IHeapNode, IHeapStringNode} from '@memlab/core';
* import {dumpNodeHeapSnapshot} from '@memlab/core';
* import {getHeapFromFile} from '@memlab/heap-analysis';
*
* (async function () {
* const heapFile = dumpNodeHeapSnapshot();
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
*
* // iterate over each node (heap object)
* heap.nodes.forEach((node: IHeapNode, i: number) => {
* if (node.isString) {
* const stringNode: IheapStringNode = node.toStringNode();
* // get the string value
* stringNode.stringValue;
* }
* });
* })();
* ```
*/
export interface IHeapStringNode extends IHeapNode {
/**
* get the string value of the JS string heap object associated with
* this `IHeapStringNode` instance in heap
*/
stringValue: string;
}
/**
* A pseudo array containing all heap graph nodes (JS objects
* in heap). A JS heap could contain millions of objects, so memlab uses
* a pseudo array as the collection of all the heap nodes. The pseudo
* array provides API to query and traverse all heap objects.
*
* @readonly modifying this pseudo array is not recommended
*
* * **Examples**:
* ```typescript
* import type {IHeapSnapshot, IHeapNodes} from '@memlab/core';
* import {dumpNodeHeapSnapshot} from '@memlab/core';
* import {getHeapFromFile} from '@memlab/heap-analysis';
*
* (async function () {
* const heapFile = dumpNodeHeapSnapshot();
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
*
* const nodes: IHeapNodes = heap.nodes;
* nodes.length;
* nodes.get(0);
* nodes.forEach((node, i) => {
* if (stopIteration) {
* return false;
* }
* });
* })();
* ```
*/
export interface IHeapNodes {
/**
* The total number of nodes in heap graph (or JS objects in heap
* snapshot).
*/
length: number;
get(index: number): IHeapNode;
/**
* get an {@link IHeapNode} element at the specified index
* @param index the index of an element in the pseudo array, the index ranges
* from 0 to array length - 1. Notice that this is not the heap node id.
* @returns When 0 <= `index` < array.length, this API returns the element
* at the specified index, otherwise it returns `null`.
*/
get(index: number): Nullable<IHeapNode>;
/**
* Iterate over all array elements and apply the callback
* to each element in ascending order of element index.
* @param callback the callback does not need to return any value, if
* the callback returns `false` when iterating on element at index `i`,
* then all elements after `i` won't be iterated.
*/
forEach(callback: (node: IHeapNode, index: number) => void | boolean): void;
/** @internal */
forEachTraceable(callback: (node: IHeapNode, index: number) => void | boolean): void;

@@ -900,0 +1553,0 @@ }

@@ -584,3 +584,3 @@ "use strict";

}
return node.findReference((edge) => edge.name_or_index === edgeName &&
return node.findAnyReference((edge) => edge.name_or_index === edgeName &&
(type === undefined || edge.type === type));

@@ -592,3 +592,3 @@ }

}
return node.findReference(edge => typeof edge.name_or_index === 'string' &&
return node.findAnyReference(edge => typeof edge.name_or_index === 'string' &&
edge.name_or_index.startsWith(prefix));

@@ -595,0 +595,0 @@ }

@@ -162,3 +162,4 @@ "use strict";

}
const childNodeIndex = forwardEdges.get(edgeIndex).toNode.nodeIndex;
const childNodeIndex = forwardEdges.get(edgeIndex)
.toNode.nodeIndex;
if (visited[childNodeIndex]) {

@@ -282,3 +283,4 @@ continue;

}
const childNodeIndex = forwardEdges.get(edgeIndex).toNode.nodeIndex;
const childNodeIndex = forwardEdges.get(edgeIndex).toNode
.nodeIndex;
nodesWithOutdatedDominatorInfo[nodeIndex2PostOrderIndex[childNodeIndex]] = 1;

@@ -285,0 +287,0 @@ }

@@ -37,3 +37,3 @@ /**

forEachReferrer(_callback: EdgeIterationCallback): void;
findReference(): Nullable<IHeapEdge>;
findAnyReference(): Nullable<IHeapEdge>;
findAnyReferrer(): Nullable<IHeapEdge>;

@@ -40,0 +40,0 @@ findReferrers(): IHeapEdge[];

@@ -73,4 +73,4 @@ "use strict";

}
findReference() {
throw new Error('NodeRecord.findReference is not implemented');
findAnyReference() {
throw new Error('NodeRecord.findAnyReference is not implemented');
}

@@ -77,0 +77,0 @@ findAnyReferrer() {

{
"name": "@memlab/core",
"version": "1.1.2",
"version": "1.1.3",
"license": "MIT",

@@ -5,0 +5,0 @@ "description": "memlab core libraries",

@@ -5,3 +5,4 @@ ## memlab Core Library

## Full documentation
https://facebookincubator.github.io/memlab
## Online Resources
* [Official Website and Demo](https://facebookincubator.github.io/memlab)
* [Documentation](https://facebookincubator.github.io/memlab/docs/intro)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc