How to use Google Chrome DevTools’s JavaScript Debugger API in custom JS code to create full function calls log trace?

I’ve found the official Chrome DevTools Debugger API for JavaScript and it’s domains, like Debugger domain.

The thing is, the docs aren’t that thoroughly describing the example usage of the API, so it’s kinda not that easy to write a method which would hook into debugger’s function execution step-by-step and log all the functions call stack until some point or the end of whole chain of executions.

What I want to achieve here is just log all the executions steps “in fly”, without needing to pause for every new method call or loop inside method.

Basically I’m planning on writing small custom execution frames recorder.

Anyone used the chrome.debugger for creating methods/classess for SPA webapps, besides browser extensions?

Filter in MapLibre GL JS with multiple images as points

I’m quite new in using MapLibre GL, but I have a huge problem setting up my map:
I followed the example available at https://maplibre.org/maplibre-gl-js/docs/examples/add-image/ and set up multiple images as points.
I also added a property to diversify each category of points.
Now I used the information available at https://maplibre.org/maplibre-gl-js/docs/examples/filter-markers/ to setup a filter box, but every try was useless…

Do you have any suggestion on how to program the filter box.
Thank you in advance for any help you’ll be able to give me!

Here there is an example of two of the points:

map.loadImage(
            'https://politichediateneo.unito.it/wp-content/uploads/2020/11/king.png',
            (error, image) => {
                if (error) throw error;
                map.addImage('king', image);
                map.addSource('king', {
                    'type': 'geojson',
                    'data': {
                        'type': 'FeatureCollection',
                        'features': [
                            {
                                'type': 'Feature',
                                'properties': {'tipo': 'scuola'},
                                'geometry': {
                                    'type': 'Point',
                                    'coordinates': [7.60529012, 45.0687483]
                                }
                            }
                        ]
                    }
                });
                map.addLayer({
                    'id': 'king',
                    'type': 'symbol',
                    'source': 'king',
                    'class': 'scuole',
                    'layout': {
                        'icon-image': 'king',
                        'icon-size': ['interpolate', ['linear'], ['zoom'], 13, 0, 15, 1]
                    }
                });
            }
        );

map.loadImage(
            'https://politichediateneo.unito.it/wp-content/uploads/2020/11/curie.png',
            (error, image) => {
                if (error) throw error;
                map.addImage('curie', image);
                map.addSource('curie', {
                    'type': 'geojson',
                    'data': {
                        'type': 'FeatureCollection',
                        'features': [
                            {
                                'type': 'Feature',
                                'properties': {'tipo': 'scuola'},
                                'geometry': {
                                    'type': 'Point',
                                    'coordinates': [7.61222455, 45.05011125]
                                }
                            }
                        ]
                    }
                });
                map.addLayer({
                    'id': 'curie',
                    'type': 'symbol',
                    'source': 'curie',
                    'class': 'scuole',
                    'layout': {
                        'icon-image': 'curie',
                        'icon-size': ['interpolate', ['linear'], ['zoom'], 13, 0, 15, 1]
                    }
                });
            }
        );

How to prevent Content from appearing when user press the Enter or Space keys

In my code I use the radix library https://www.radix-ui.com/primitives/docs/components/dropdown-menu

My code has a DropdownMenu. When the user clicks on the TriggerIcon, he sees DropdownMenu.Content, that is, two buttons (Delete and Edit). With Delete everything is clear and there are no questions, but the Edit button calls up the Dialog (a modal window in which the user can make changes).

The problem is that the TriggerIcon button reacts to a click of the left key (everything is fine here), and to pressing the Enter and Space keys (I would like to change this behavior).

Tell me how to prevent DropdownMenu.Content from appearing when user press the Enter or Space keys

<>
  <DropdownMenu.Root open={isOpenSubMenu}>
    <DropdownMenu.Trigger>
      <TriggerIcon />
    </DropdownMenu.Trigger>
    <DropdownMenu.Portal forceMount>
      {isOpenSubMenu && (
        <DropdownMenu.Content>
          <DropdownMenu.Item>Edit</DropdownMenu.Item>
          <DropdownMenu.Item>Delete</DropdownMenu.Item>
        </DropdownMenu.Content>
      )}
    </DropdownMenu.Portal>
  </DropdownMenu.Root>

  <Dialog.Root open={isOpenForm}>
    <Dialog.Portal>
      <Dialog.Overlay />
      <div>
        <EditForm />
      </div>
    </Dialog.Portal>
  </Dialog.Root>
</>

Use of eval is strongly discouraged error comes while vite build

While the vite is building for production I can see the message as shown in the image below:

enter image description here

Can someone please help me with this message? Should I consider this as warning or error?

Moreover, I have not used eval in the code anywhere. Is it showing because of any installed library is using eval function?

Thank you in advance.

I have updated all the dependencies and check that if this message is still showing. But the message is still there.

Service Worker script persists in browser sources after unregistering it

I need to completely remove the service worker script (sw.js) from my webpage; I can successfully unregister it via

// index.js
try {
    navigator.serviceWorker.getRegistrations().then((registrations) => {
        for (let registration of registrations) {
            // console.log('Reg:')
            // console.log(registration)

            if (registration.scope.endsWith('/my_scope/')) {
                registration.unregister().then((unregRes => {
                    if (unregRes) {
                        console.log('Unregistration success');
                    }
                    else console.log('Unregistration failed');
                }));
            }
        }
    }).catch(function(err) {
        console.log('Service Worker unregistration failed: ', err);

    });
} catch(e) {
    swRes['error'] = e.message;
}

It says ‘Unregistration success’ without errors, but I still see sw.js in Chrome DevTools => Sources. In chrome://serviceworker-internals/, I see

Unregistered worker:
Installation Status: REDUNDANT
Running Status: RUNNING
Fetch handler existence: DOES_NOT_EXIST
Fetch handler type: NO_HANDLER
Script: https://my.site/my_scope/sw.js
Version ID: 577
Renderer process ID: 11084
Renderer thread ID: 4
DevTools agent route ID: 18

I can stop sw.js in chrome://serviceworker-internals/ by clicking the Stop button, and the file goes away from Sources, but I need automated file removal due to project requirements.

I feel like Running Status: RUNNING restricts me from removing my worker, but I don’t know how to change this status. Alos I tried self-destroying worker from https://github.com/NekR/self-destroying-sw , but the behavior stays the same.

Any explanations of how to automatically remove SW’s file from the browser storage are welcome.

Close div if another with the same name showing on

I would like to write a script that detects whether a given div is already open and if so, closes the previous one and opens a new one. The class name when the div is open is .collapse in, and the class name of the div that shows is

(function () {
  $('.collapse in').on ('click', function() {
    $(".accordianNav").each(function() {
      $(this).find(".accordianNav").hide();
    });
  });
})();

I tried to write something like that but its not working. I am new and need a easy tip or full solution.

Javscript Array to String (Automatic Conversion)

New to JS, so still learning lots

I came across this (See Image) on https://www.w3schools.com/js/js_array_methods.asp

It states this “JavaScript automatically converts an array to a comma separated string when a primitive value is expected.”

On their own website, this works fine and they state it should return the same result (String)

But when I try it on Chrome Console, I get the following results:

const fruits = [“Banana”, “Orange”, “Apple”, “Mango”];

console.log(fruits);

Result: (4) [‘Banana’, ‘Orange’, ‘Apple’, ‘Mango’]

0: “Banana”
1: “Orange”
2: “Apple”
3: “Mango”
length: 4

Note: This returns an Array


const fruits = [“Banana”, “Orange”, “Apple”, “Mango”];

console.log(fruits.toString());

Result: Banana,Orange,Apple,Mango

Note: This returns a string

I someone could clarify which is the correct way, that would be much appreciated

Thanks

Array to String

Stub GET request via Cypress to emulate an error while getting a file with a blob

I’m trying to stub a http request with a blob to emulate an error on the server while running e2e spec in Cypress. I’ve tried to pass a blob object into cy.intercept() but the request still goes to backend.

I’ve tried running this code in it() block:

        const responseBody = {"code": 400,"text":"Error text from backend"}; // error message from backend
        const blob = new Blob([JSON.stringify(responseBody, null, 2)], {
            type: "application/json",
        }); // blob object

        cy.intercept(
            {
            method: 'GET',
            url: '/some/url/here',
            },
            blob).as('blob');

What I’m trying to achive is a response with status code 500 and given blob as response body. Tried different approaches as fixture, creating response object but it all didn’t work. Stubbing with JSON works flawlessly but with a blob I can’t put my finger on it

Tried stubbing with blob object, fixture and response object with blob in the body

javascript debugger vue 3 js stopped working, how do I make it work?

I’m developing .vue-pages in vue3. A few days ago javascript debugging stopped working.
I don’t know if I maybe did something by mistake or if there was a chrome update or something.

What I’m talking about is to type “debugger;” somewhere in your code and then opening chrome devtools to break on the debugger.

I’ve verified that “disable javascript” is NOT checked in chrome…
What else could it be? I’ve tried in Edge also but the debugger doesn’t work there either.
However, I have a project in vue2 where debuggers still work. I recently updated vue3 to the latest version (3.3.12)… could that have something to do with it?

How to convert cURL command to Axios

I’m trying to make a React Native app that uses YouTube’s Secret API for subtitles. And here is the cURL command that I found on the internet:

curl -s 'https://www.youtube.com/youtubei/v1/get_transcript?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8' -H 'Content-Type: application/json' --data-raw "{"context":{"client":{"clientName":"WEB","clientVersion":"2.2021111"}},"params":"$(printf 'nx0bVIDEO_ID' | base64)"}"

There is a part that I don’t understand, that is: $(printf 'nx0bVIDEO_ID' | base64).
And I want to convert this cURL command to JavaScript

Sorting mixed format version tags in Node.js

I’m attempting to sort a list of tags in order to find the highest tag number. The tags are from a third-party source like Dockerhub, and are in a mixed format (not all semver) i.e.

const tagList = ['0.0.1', '0.0.2', '0.0.3-alpha1', '1.10-alpine3', '1.9.2']

I’ve been trying to use the compare-versions library but it falls over on non-semantic versions.

I’ve previously used a python library to sort tags like this:

from packaging.version import LegacyVersion
 
tag_list = ['0.0.1', '0.0.2', '0.0.3-alpha1', '1.10-alpine3', '1.9.2']

sorted_tags = sorted(tag_list, key=LegacyVersion)

Is there any equivalent package for nodejs, or failing that, a way of sorting these tags?

So far, I have only been able to find compare-versions, but this isn’t sufficient. I tried the following:

import { compareVersions } from 'compare-versions';

const versions = ['0.0.1', '0.0.2', '0.0.3-alpha1', '1.10-alpine3', '1.9.2'];
let latest;
try {
  latest = versions.sort(compareVersions).pop();
} catch {
  latest = versions.sort((a,b)=>a-b).pop();
};

console.log(latest);

Expected:

1.10-alpine3

Actual Output:

1.9.2

When I remove the try/catch and just force it to use the compareVersions sort function, I get the following error:

/Users/banbone/project/node_modules/compare-versions/lib/umd/index.js:14
            throw new Error(`Invalid argument not valid semver ('${version}' received)`);
                  ^

Error: Invalid argument not valid semver ('1.10-alpine3' received)
    at validateAndParse (/Users/banbone/project/node_modules/compare-versions/lib/umd/index.js:14:19)
    at compareVersions (/Users/banbone/project/node_modules/compare-versions/lib/umd/index.js:53:20)
    at Array.sort (<anonymous>)
    at file:///Users/banbone/project/test.js:5:19
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v21.2.0

Aggregate query doesnt work properly with dates $lte & $gte

if date range is 2 days, like
startDate = 2023-11-26
endDate = 2023-11-27
all working fine, when dates are equal, campaigns array is empty, how to make this $gte and $lte comparsion work? Im sure that data for this day is present and problem is in aggregate part

async getCampaigns(query, res) {
console.log(query);

try {
  let { offset = 0, limit = 30, startDate, endDate } = query;

  const startDateString = startDate;
  endDate = new Date(endDate);
  offset = parseInt(offset);
  limit = Math.min(
    parseInt(limit),
    await this.campaignModel.countDocuments(),
  );
  startDate = startDate
    ? new Date(startDate)
    : new Date(endDate.getTime() - 14 * 24 * 60 * 60 * 1000);
  
  if (isNaN(offset) || isNaN(limit)) {
    throw new BadRequestError('Invalid offset or limit');
  }
  const dates = getAllDatesBetween(`${startDateString}/${endDate}`);
  const campaigns = await this.campaignModel.aggregate([
    { $addFields: { datesArray: { $objectToArray: '$dates' } } },
    { $unwind: '$datesArray' },
    {
      $match: {
        'datesArray.k': {
          $gte: startDate.toISOString(),
          $lte: endDate.toISOString(),
        },
      },
    },
    {
      $group: {
        _id: '$_id',
        totalCost: { $sum: '$datesArray.v.cost' },
        document: { $first: '$$ROOT' },
      },
    },
    { $sort: { totalCost: -1 } },
    { $skip: offset },
    { $limit: limit },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: ['$document', { totalCost: '$totalCost' }],
        },
      },
    },
  ]);
  console.log(campaigns);
...
} catch (error) {
  throw new InternalServerError('Internal Server Error');
}}

Nested anonymous function call doesn’t update the call to find()

Below is a nested call to the same function via an anonymous call. The element under el is expected to be updated by something else but while it has the .updating class, should keep calling itself. Once this find() returns false, execute the else. The problem is even though the .updating is gone because some other code has removed it, the find is still returning true, so it loops indefinitely. Or is there a better way to do this? Ideally it should only be 1 call / nest, and if .updating class is still there, the call just sleeps for a certain interval.

    this.TryClick = function (el) {
        if ($(el).find('.updating')) {
            setTimeout(() => {
                self.TryClick(el);
            }, 1000);
        } else {
            const btn = $(el).find('.myclass');
            btn.click();
        }
    };