npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@deepkit/framework-debug-api

v1.0.1-alpha.146

Published

This is the API package of the Deepkit Framework Debugger.

Downloads

3,557

Readme

Framework Debugger API

This is the API package of the Deepkit Framework Debugger.

Storage Architecture

The debugger storage works together with @deepkit/stopwatch. Stopwatcher is a library that exposes the classes, functions, and decorators to work indirectly with the debugger storage. It collects all data points and puts them into a queue. The debugger (if enabled) then reads this queue and puts it on disk and streams changes to a broker, so GUI clients can display the data in real-time.

Example:


const stopwatch = new Stopwatch;

const frame = stopwatch.start('my/frame');

frame.data({arbitrary: 'data'});

frame.end();

When start is called a frame is created with the current timestamp using performance.now and a unique id. Once stop is called the frame is ended and can not be used anymore. With data(T) the user can provide additional data as arbitrary object.

Frames and Data

There are two different fundamental data types: Frames and Frame Data.

Frames is a union of 3 types: FrameStart, FrameData, and FrameEnd. Each frame has a unique id which is shared among those 3 types. Each has also a timestamp and other metadata. Using the id and timestamp all frames can be displayed on a flamegraph.

Frame Data is additional data that is not directly displayed in the flamegraph, however can be displayed when a frame is clicked/hovered. This data is stored in a separate file.

Frame itself is binary and stored in one big file called FrameLog. The data might be spread across different files to not get too big file sizes. All processes write to the same file, always appending the data.

A FrameStart package is a custom binary structure: . Each FrameStart package has a total byte size of min (32 +8 + 8 + 64 + 32 + 8 + 8)/8 = 20 bytes.

A FrameEnd package is a custom binary structure: . Each FrameEnd package has a total byte size of min (32 + 8 + 8 + 64)/8 = 14 bytes.

Sample calculation to get a feeling of how big a FrameLog can become: A program executes 20 methods which are profiled, 5 events, 1 request, 5 workflow events, making total of 31 frames, average label size of 8 characters => (31)(20+8)B = 868 bytes for FrameStart => (31)(14)B = 434 bytes for FrameEnd ==> total of 1302 bytes for all frames per program profiling. Logging 768 such program executions costs 1 megabytes.

Frame Data format is a custom binary structure: Each Frame Data entry has a little header, and a BSON body: Since has a size prefix, the whole file is seekable.

Frame Data has also a header file along with it, allowing it to seek fast to certain positions. The header file is a custom binary structure as well: seek defines at which position in the Frame Data file the actual data is stored. This make it possible to fopen/fseek to the data fast enough. Note: There can be multiple entries for the same id:worker combination, since Stopwatch supports updating Frame Data.

The GUI reads the FrameLog as a stream in real-time. Frame Data file is read on-demand when a certain window of the flamegraph is selected. This is because the Frame Data file can potentially become very big since there are all other (possibly verbose) data stored.

Limitations: Since all data is stored in an append-only fashion, writing and reading is very fast. However, modifying or deleting Frames or Frames Data are relatively expensive, but there's no use-case yet to modify or delete them. When this will be allowed, it means that the Frame Data header file needs to be rewritten entirely, which might cost some time (but doesn't matter that much as it's not time sensitive).

Model

enum FrameCategory {
    http, rpc, cli, job, function, lock, workflow, event, database, email, template
}

interface FrameStart {
    id: number;
    worker: number;
    label: string;
    timestamp: number;
    context: number;
    category: FrameCategory;
}
interface FrameEnd {
    id: number;
    worker: number;
    timestamp: number;
}

Use-Cases

  1. DB query: We want to log which query took how long. We store at the FrameStart label "EntityName: Type" (Type=Update|Insert|Delete). The full query including parameters are stored in Frame Data.