How do you call a function every second in a Chrome Extension Manifest V3 Background Service Worker?

Service workers replace background pages in Manifest v3 Google Chrome Extensions, and I’m trying to use one for my extension. The documentation says timers (setTimeout and setInterval) should be avoided because timers get canceled when service workers terminate (which may happen at any time). Unlike background pages, service workers can’t be persistent and will always be subject to termination. The documentation recommends using the Alarms API instead.

I need to be able to run a function periodically in a Manifest v3 service worker, but alarms don’t suit my use case because they’re slow. The shortest allowed alarm duration is 1 minute, but I want to run a function in shorter intervals—a second or a few seconds.

I tried using event.waitUntil to keep the service worker alive per this Stack Overflow answer. Here’s my attempted solution at mimicking a 1-second setInterval with repeating waitUntil calls:

var e;

function doThisEachSecond(resolver) {

    console.log('running function')

    // … CODE …

    e.waitUntil(new Promise(resolve => setTimeout(() => {doThisEachSecond(resolve);}, 1000)));
    resolver();
}

self.onactivate = event => {

    event.waitUntil(new Promise(resolve => {
        e = event;
        doThisEachSecond(resolve);
    }));

    console.log('activated');
};

It has big problems :

Since event.waitUntil makes the event dispatcher wait, these events don’t fire when my bootleg setInterval is running:

chrome.tabs.onUpdated.addListener(…);
chrome.tabs.onReplaced.addListener(…);
chrome.runtime.onMessage.addListener(…);

And I found that doThisEverySecond eventually stops getting called if the service worker is left to run for some time like a few minutes. When this occurs, the events that queued up during waitUntil periods fire all at once.

Looks like my approach isn’t the way to go.

How do you call a function every second in a Chrome Extension Manifest V3 Background Service Worker?

object.property returns undefined

My ajax success function returns response as {"allOrders":[0,0,0,0,0,0,0,0,0,0,0,27]}. I need to pass this allOrders into another function. So I tried t print the result in console, but it returns undefined.
I have tried like this

success:function(response){
{
    console.log(response.allOrders)     // returns undefined
}

What happens when I call the update function returned by React.useState()?

I just learned the hooks in react, so I used it to write a small feature that displays hidden texts when users click on hyperlinks. I finally made the code work, but it seems that my code is messed up. Could someone tell me:

  1. Why the “true” is printed two times in the console and what indeed happens when I call the update function returned by React.useState()? How can I improve my code to prevent this?
  2. How to clearly pass attributes into a functional React component? It seems that my method is really complicated (compressing in an attribute object).

This is the feature:
Before click
After click

Here’s my code:

/*
    params:
    attributes: {
        // Required params
        text: the text using the style of hiddenTextLinks with each part separated by a '#'. 
        Ex: "Hey, here is the #HiddenTextLinks#, a wonderful style for texts#!"
        
        // Optional params
        plainStyle: customized style for plain contents.
        plainFont: customized font for plain content (no use if plainStyle is specified).
        plainColor: customized font for plain text color (no use if plainStyle is specified).

        linkStyle: customized style for link contents. 
            Notice: the link here is indeed a button styled as a "link". Therefore, I suggest you to provide 
            the following attributes:
                background: "none",
                border: "none",
                padding: 0,
                textDecoration: "none",
                fontSize: "16px",
        linkFont: customized font for links (no use if linkStyle is specified).
        linkColor: customized font for link color (no use if linkStyle is specified).
        
        hiddenStyle: customized style for hidden texts.
        hiddenFont: customized font for hidden texts. (no use if hiddenStyle is specified).
        hiddenColor: customized color for hidden texts. (no use if hiddenStyle is specified).
    }
*/
function HiddenTextLinks(props) {
  console.log("runned");
  props = props.attributes;
  var text = props.text;
  const plainStyle = props.plainStyle || {
    fontFamily: props.plainFont || "arial, sans-serif",
    color: props.plainColor || "#000000",
  };
  const linkStyle = props.linkStyle || {
    background: "none",
    border: "none",
    padding: 0,
    fontSize: "16px",
    textDecoration: "none",
    fontFamily: props.linkFont || "arial, sans-serif",
    color: props.linkColor || "#000000",
    cursor: "pointer",
  };
  const hiddenStyle = props.hiddenStyle || {
    position: "relative",
    fontFamily: props.hiddenFont || "arial, sans-serif",
    color: props.hiddenColor || "#9e9a9a",
  };
  const [temp] = React.useState(text.split(/(?<!\)#/));
  const [visibility, setVisibility] = React.useState(
    Array(Math.floor(temp.length / 3)).fill(false)
  );
  const [renderedContent, setRenderedContent] = React.useState(render(temp));

  function render(array) {
    console.log("render");
    return array.map((value, index) => {
      if (index % 3 === 0) {
        return (
          <span key={`content${Math.floor(index / 3)}`} style={plainStyle}>
            {value}
          </span>
        );
      } else if (index % 3 === 1) {
        return (
          <button
            key={`link${Math.floor(index / 3)}`}
            style={linkStyle}
            onClick={() => setVisible(Math.floor(index / 3))}
          >
            {value}
          </button>
        );
      } else {
        console.log(visibility[Math.floor(index / 3)]);
        if (visibility[Math.floor(index / 3)]) {
          return (
            <span key={`hidden${Math.floor(index / 3)}`} style={hiddenStyle}>
              {value}
            </span>
          );
        } else {
          return <span key={`hidden${Math.floor(index / 3)}`}></span>;
        }
      }
    });
  }

  function setVisible(index) {
    visibility[index] = !visibility[index];
    setVisibility(visibility);
    setRenderedContent(render(temp));
  }
  console.log("returned");
  return <span>{renderedContent}</span>;
}

This is how I used it in an upper level:

const attributes = {
      text: "Hey, here is the #HiddenTextLinks#, a wonderful style for texts#!",
      plainFont: "Bakbak One, cursive",
      linkFont: "Bakbak One, cursive",
      hiddenFont: "Bakbak One, cursive",
      linkColor: "#d1519c",
      hiddenColor: "#9e9a9a",
    };
return <HiddenTextLinks attributes={attributes} />;

Here’s the console log (I clicked only once):
console log

Thank you so much.

combine await and callback javascript

I’ve been impressed with an async await callback attempt in nodejs, but I don’t know if it’s the right thing to do. I have a function that takes hours, and I need to return a percentage of progress. I have tried doing a trial and error callback. which worked for me and I wanted to know what you think and if there is another more elegant way. I am working in cluster mode

import { setTimeout } from 'timers/promises';

    let files = await generateFiles({ 
        callback: e => console.log(e) //percentage of progress
    });


    const generateFiles = async ({ callback }) => {

       var item = [1,2,3]

       for (var x of item) {

         callback(item.indexOf(x) * 100 / item.length)

         await setTimeout(60000, 'sleep');

      }
   }

why I cannot view the barchart in localhost with chart js?

$sum_1, “label” => “Jan”),
array(“y” => $sum_2, “label” => “Feb”),
array(“y” => $sum_3, “label” => “Mac”),
array(“y” => $sum_4, “label” => “Apr”),
array(“y” => $sum_5, “label” => “May”),
array(“y” => $sum_6, “label” => “Jun”),
array(“y” => $sum_7, “label” => “Jul”),
array(“y” => $sum_8, “label” => “Aug”),
array(“y” => $sum_9, “label” => “Sep”),
array(“y” => $sum_10, “label” => “Oct”),
array(“y” => $sum_11, “label” => “Nov”),
array(“y” => $sum_12, “label” => “Dec”),
);
?>

$(function () {
var chart1 = new CanvasJS.Chart(“chartContainer1”,{
theme: “light3”,
animationEnabled: true,
title: {
text: “Monthly Electricity Bill”
},
axisY: {
title: “Total Amount (RM)”
},
data: [{
type: “column”,
showInLegend: true,
legendMarkerColor: “grey”,
legendText: “Month”,
dataPoints:
}]
});

chart1.render();

});

How to integrate charts with js and jQuery?

I am trying to get data from an API and edit the endpoint based on the selected value from a dropdown and show the respective chart for it, can I integrate js, jQuery and charts all together? Below is my code where I tried this:

async function bruh(){
  $( document ).ready(function() {
  $('select').on('change', async function() {
    this.value = this.value.toLowerCase();
    const apiUrl = 'https://api.covidtracking.com/v1/states/'+this.value+'/daily.json';

  const response = await fetch(apiUrl)
  const barChatData = await response.json()
  console.log(barChatData)
  const positive = barChatData.map((x) => x.positive)
  const date = barChatData.map((x) => x.date)
  positives = positive
  dates = date
  });
})
}
async function dummyChartbruh() {
  await bruh()
  const ctx = document.getElementById('yourChart').getContext('2d');

  const chart = new Chart(ctx, {
      
      type: 'line',
  
      
      data: {
          labels: dates,
          datasets: [{
              label: 'Positive',
              backgroundColor: 'blue',
              borderColor: 'rgb(255, 99, 132)',
              data: positives,
              fill: false
          }
         
        ]
      },
  
    
      options: {
        tooltips: {
          mode: 'index'
        }
      }
  })
  document.getElementById("yourChart").removeAttribute("hidden");
  $('#yourChart').show()
}

dummyChartbruh() 

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
  <link rel="stylesheet" href="/styles.css" />
  <title>Covid Data</title>
</head>
<body>
  <div class="card text-center m-5">
  <div class="card-header">
  <h2>Covid Data</h2>
  <select>
    <option value="AL">Alabama</option>
    <option value="AK">Alaska</option>
    <option value="AZ">Arizona</option>
    <option value="AR">Arkansas</option>
    <option value="CA">California</option>
    <option value="CO">Colorado</option>
    <option value="CT">Connecticut</option>
    <option value="DE">Delaware</option>
    <option value="DC">District Of Columbia</option>
    <option value="FL">Florida</option>
    <option value="GA">Georgia</option>
    <option value="HI">Hawaii</option>
    <option value="ID">Idaho</option>
    <option value="IL">Illinois</option>
    <option value="IN">Indiana</option>
    <option value="IA">Iowa</option>
    <option value="KS">Kansas</option>
    <option value="KY">Kentucky</option>
    <option value="LA">Louisiana</option>
    <option value="ME">Maine</option>
    <option value="MD">Maryland</option>
    <option value="MA">Massachusetts</option>
    <option value="MI">Michigan</option>
    <option value="MN">Minnesota</option>
    <option value="MS">Mississippi</option>
    <option value="MO">Missouri</option>
    <option value="MT">Montana</option>
    <option value="NE">Nebraska</option>
    <option value="NV">Nevada</option>
    <option value="NH">New Hampshire</option>
    <option value="NJ">New Jersey</option>
    <option value="NM">New Mexico</option>
    <option value="NY">New York</option>
    <option value="NC">North Carolina</option>
    <option value="ND">North Dakota</option>
    <option value="OH">Ohio</option>
    <option value="OK">Oklahoma</option>
    <option value="OR">Oregon</option>
    <option value="PA">Pennsylvania</option>
    <option value="RI">Rhode Island</option>
    <option value="SC">South Carolina</option>
    <option value="SD">South Dakota</option>
    <option value="TN">Tennessee</option>
    <option value="TX">Texas</option>
    <option value="UT">Utah</option>
    <option value="VT">Vermont</option>
    <option value="VA">Virginia</option>
    <option value="WA">Washington</option>
    <option value="WV">West Virginia</option>
    <option value="WI">Wisconsin</option>
    <option value="WY">Wyoming</option>
</select>   

  </div>
  <canvas id="myChart" ></canvas>
  <canvas id="yourChart" hidden></canvas>
</div>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <script src="app.js"></script>
</body>
</html>

However it does not display any values on the chart when the dropdowns are changed, how do I correct this?

javascript chrome extenstion stops working after two reloads

im trying to change the color of a class on bybit exchange. the problem is that the extension stops working after reloading two times and then I have to clear my cache to get it runnig again. im pretty new to programming so yeah… 🙂 here is the code

function btn4() {

var recent = document.getElementsByClassName("rt__head full flex");

recent[0].style.backgroundColor = "lightblue";
}
btn4();

this is my manifest file below:

  "name": "Bybit orderbook color",


"version": "1.1",
  "manifest_version": 2,

  "content_scripts": [
    {
      "matches": [ "https://www.bybit.com/trade/usdt/BTCUSDT/*" ],
      "run_at": "document_idle",
      "js": [ "background.js" ]

    }

  ],

  "permissions": [ "activeTab" ]


}

How to block form submit with same trigger button but different function?

So, I have some problem. I have a search bar to search for a product, and can also redirect to another page if I type a word is match with pageKeywords array value. So in 1 searchbar there can be 2 triggers.

The first is when I click on search keywords and when it matches it will lead to another page:

$('#submitForm').on("click",function(e){
   pageKeywords($("#searchKeywords").val(),e)
})

And will also direct to the result page if the word written does not contain pageKeyword:

$('#submitForm').on('click', function () {
    console.log("another function submit")
    $('#fform').submit()
    return false;
});

The problem I’m having is, when I click Search, it will trigger the form submit. How to prevent form submission when the words typed in the searchbar match with pageKeywords? If it doesn’t match ,the form submit can run. These two events cannot be contested, here I give an example of the code that I have made

function pageKeywords(searchValue,evt){
  const pageKeywords = {
    "home": "/homepage",
    "about": "/about-us"
  }
  const getInputVal = searchValue;
  
  if(pageKeywords[getInputVal]) {
    evt.preventDefault();
    console.log(pageKeywords[getInputVal])
    return false;
  }else{
    console.log('not found')
  }
}

$(document).ready(function() {

  $('#submitForm').on("click",function(e){
    pageKeywords($("#searchKeywords").val(),e)
  })
  
  $('#submitForm').on('click', function () {
        console.log("another function submit")
        $('#fform').submit()
    return false;
    });

  $("#searchKeywords").on("keypress", function(e) {
    if (e.which === 13) {
      pageKeywords($(this).val(),e)
    }
  });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id="fform" action="#">
   <input type="text" id="searchKeywords">
   <button id="submitForm">Search</button>
</form>

Executing code pre and post mutation graphql neo4j apollo server

I’m just getting started with GraphQL and I’ve worked mostly with featherjs to build REST APIs so far. There’s the concept of hooks to run code before or after interacting with a service. I wanted to know if there’s a way to achieve something similar in a graphql setup.

The specific stack I’m using is neo4j and graphql, express, and apollo server. Since neo4j has a graphql module, I’m not writing the general queries and mutations, just the model types.

For a concrete example, below is a basic API server. It’s put together using docker compose and has users and applications. I would like to in general be able to run arbitrary code before or after a mutation with access to the model being modified. Things like more complex validation before, or side effects after.

Those things could be here, for example, before changing the state of an application to declined, make sure that a note is added. Or after changing the state to approved, send an email to the applicant.

I’m not sure how or where to implement this kind of thing, any help is appreciated! Or also if I’m thinking about graphql wrong and there’s a better way of doing what I’m trying to do.

Thanks!

import http from 'http';
import express from 'express';
import neo4j from 'neo4j-driver';
import {Neo4jGraphQL} from '@neo4j/graphql';
import {gql, ApolloServer} from 'apollo-server-express';
import {ApolloServerPluginDrainHttpServer} from 'apollo-server-core';

const typeDefs=gql`
type User {
    email: String!
    applications: [Application!] @relationship(type: "APPLICANT", direction: OUT)
}

type Application {
    user: User! @relationship(type: "APPLICANT", direction: IN)
    state: String!
    note: String
}
`;

const driver=neo4j.driver(
    'neo4j://neo4j:7687',
    neo4j.auth.basic('neo4j', 'password')
);

const {schema}=new Neo4jGraphQL({typeDefs, driver});

(async ()=>{
    const app=express();
    const server=http.createServer(app);
    const apollo=new ApolloServer({
        schema,
        plugins: [ApolloServerPluginDrainHttpServer({httpServer: server})]
    });
    await apollo.start();
    apollo.applyMiddleware({app});
    await new Promise(r=>server.listen({port: 4000}, r));
    console.log('GraphQL server listening at '+apollo.graphqlPath);
})();

Ionic/Capacitor React App API Requests returning HTML on iOS

The current behavior:

All API requests to the localhost server are returning the index.html file of the React.js app on the iOS build, but requests work fine on browser and PWA builds.

The expected behavior:

Requests return the intended data (usually JSON)


Details

Typically, API requests go to localhost:5000/api/[route]. In the iOS build they are going to capacitor://localhost/api/[route]

Because the route is returning HTML and not JSON data, I am getting the following error (one of many, as each API route, has the same error) which causes a white screen:

TypeError: undefined is not a function (near '...a.map...')

I tried adding a hostname (location where the production server is hosted) to the capacitor.config.json file in my root directory, but it still fails. Dev API server is running on localhost:5000

How can I route my requests on the iOS build to direct to the correct location?

How to do I set the default value for a member of the type BOOLEAN_FIELD in a derived class from foundry.abstract.DocumentData in foundry vvt?

Is there a hook / overwriteable function, when a placeable foundry vvt object was succesfully added to the scene and is ready to be used?

calling

const myown_data = { give_me_icecream: true }
canvas.scene.updateEmbeddedDocuments('ContainerName',[{ _id: this.data._id, ...myown_data }])

in

 _onCreate

complains that the data could not be written / saved when I create the object. But when I reload the scene the data is written to all objects of the type without a problem. I would like to just to set some default values for a BOOLEAN_FIELD or any other DocumentField in a foundry.abstract.DocumentData Class, which should be used only when the object is created for the first time.

jQuery functions not available after compilation

After the compilation of Javascript file with Browserify/Babel (preset-end) or Rollup.js there is not reponse from the script, in the browser. What I want to do is to write a script including node_modules and to transpile it in Javascript browser compatible.

The setup I used with Gulp:

function babel_client() {
    return src('./client/js/Controller_ui.js')
        .pipe(babel({
            presets: [
                [
                    "@babel/preset-env",
                    {
                        "useBuiltIns": "usage",
                        "corejs": "3.10.0"
                    }
                ]
            ]
        }))
        .pipe(dest('build/'));
}

function rollup_client() {
  return src('./client/js/Controller_ui.js')
        .pipe(rollup({
      input: './client/js/Controller_ui.js',
            external: ['jquery'],
            output: {
                format: 'iife',
                globals: {
                    jquery: '$'
                }
            }
    }))
    .pipe(dest('./build'));
}


function lint_client() {
    return src('./client/js/Controller_ui.js')
        .pipe(jshint());
}

function browserify_client() {
    return src('./build/Controller_ui.js')
        .pipe(browserify({
            insertGlobals: true
        }))
        .pipe(rename('Controller_uix.js'))
        .pipe(dest('./public'));
}


exports.browserify = series(lint_client, rollup_client, browserify_client);
exports.build = series(lint_client, rollup_client, node_server, browserify_client);

Controller_ui.js file user by rollup_client or babel_client function

'use strict';

//var $ = require('jquery');
import $ from 'jquery';

window.$ = $;

console.log(window);

$(window).ready(function () {
  console.log('aaäö');
});

the transpile file looks like this

(function ($) {
  'use strict';

  $ = $ && $.hasOwnProperty('default') ? $['default'] : $;

  window.$ = $;

  console.log(window);

  $(window).ready(function () {
    console.log('aaäö');
  });

}($));

looks good, there seems to be wrapped in a function so the browser will not output the content od the function untless it is called. Also if the jquery plugin is included with browserify, there is still no response from the browser.

What will be the best resolution in this regard, Bower?

Get the referenced value of a CSS variable

Given

<div></div>

<style>
body {
  --var1: 3;
  --var2: var(--var1);
}

div {
  --var3: var(--var2);
  width: var(--var3);
}
</style>

How can I obtain the reference list of css variables?

getReferenceList(divElement, 'width')

Would result in

['--var3', '--var2', '--var1', 3]