Electron Js + Nuxt Js

Hello fellow developers,
I’ve been having issues packaging my Electron + Nuxt project.

I have been using electron packager, but after successful packaging and I try to open the app, it only shows a blank screen and nothing else.

What could be happening.

find the slow method in nodejs

I was wonder there is a way to find the nodejs slow method, for example, I have a function like this:

function a (){
    b();
    c();
    d();
}

I am using this way:

const lockStartTime = Date.now();
const lockHoldTime = Date.now() - lockStartTime;

to check the time take for each method, is there any way(like java jvm aop without change the code to tracing the time using of each method) to tracing the callstack and each stack takes how much time?

need help loading a wasm file into a node script (using web-tree-sitter)

i’m having trouble loading the wasm into my node script. This is my script …

const path = require('path');
const Parser = require('web-tree-sitter');

(async () => {
  await Parser.ready;
  const wasmPath = path.resolve(__dirname, 'wasm/tree-sitter-javascript.wasm');
  const Lang = await Parser.Language.load(wasmPath);

  const parser = new Parser.Parser();
  parser.setLanguage(Lang);

  const sourceCode = 'function greet() { return "hi"; }';
  const tree = parser.parse(sourceCode);

  console.log(tree.rootNode.toString());
})();

At the line const Lang = await Parser.Language.load(wasmPath); I get this error …

TypeError: Cannot read properties of undefined (reading 'loadWebAssemblyModule')
    at load (c:Usersmarkappsvscode-function-explorernode_modulesweb-tree-sittertree-sitter.cjs:3772:25)
    at processTicksAndRejections (<node_internals>/internal/process/task_queues:95:5)

web-tree-sitter is version 0.25.6.

What am I doing wrong? Can someone tell me the correct way to load wasm into a node script?

all the accordion with same styles opens up on click

I am trying to add some more accrodions to this sample web page design.

https://demo.themefisher.com/constra-bootstrap/index.html

But when I copy the accordion multiple times and try to open one of the accordion, all the accordion with same id opens up. Suppose, I copy the customer service accordion and paste two times. Now if I click on any of those copied accordion, all the three accordions open up. I can’t figure out how to stop it. Thank You!

<!--/ Accordion starts -->
          <div class="accordion accordion-group" id="our-values-accordion">
              <div class="card">
                <div class="card-header p-0 bg-transparent" id="headingOne">
                    <h2 class="mb-0">
                      <button class="btn btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
                          Safety
                      </button>
                    </h2>
                </div>

                <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#our-values-accordion">
                    <div class="card-body">
                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidata
                    </div>
                </div>
              </div>
              <div class="card">
                <div class="card-header p-0 bg-transparent" id="headingTwo">
                    <h2 class="mb-0">
                      <button class="btn btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
                          Customer Service
                      </button>
                    </h2>
                </div>
                <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#our-values-accordion">
                    <div class="card-body">
                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidata
                    </div>
                </div>
              </div>
              <div class="card">
                <div class="card-header p-0 bg-transparent" id="headingTwo">
                    <h2 class="mb-0">
                      <button class="btn btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
                          Customer Service
                      </button>
                    </h2>
                </div>
                <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#our-values-accordion">
                    <div class="card-body">
                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidata
                    </div>
                </div>
              </div>
              
              <div class="card">
                <div class="card-header p-0 bg-transparent" id="headingThree">
                    <h2 class="mb-0">
                      <button class="btn btn-block text-left collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
                          Integrity
                      </button>
                    </h2>
                </div>
                <div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#our-values-accordion">
                    <div class="card-body">
                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidata
                    </div>
                </div>
              </div>
          </div>
          <!--/ Accordion end -->

accordion section from the website

Deck.gl SolidPolygonLayer shader injection to offset extruded polygons

I am trying to to create a custom Deck.gl SolidPolygonLayer which adds an additional feature attribute to vertically offset extruded polygons (make them float above the map at variable heights).

Based on these docs:
https://deck.gl/docs/developer-guide/custom-layers/writing-shaders#standard-shader-hooks
https://deck.gl/docs/api-reference/core/project

I’ve come up with the following so far

shaders.inject = {
      'vs:#decl': `attribute float instanceBaseOffset;`,
      'vs:DECKGL_FILTER_GL_POSITION': `
        vec3 offsetWorldPosition = geometry.worldPosition + vec3(0.0, 0.01, 0.0);
        vec3 offsetWorldPosition64Low = vec3(0.0);
        vec3 commonPosition = project_position(offsetWorldPosition, offsetWorldPosition64Low);
        // position = project_common_position_to_clipspace(vec4(commonPosition, 1));
        position = vec4(position.x, position.y + 0.1, position.z, position.w);
      `
    }

I am able to access the geometry, offset it (by a constant for now), and then project it to clip space and set the position. The problem is that this resets the extrusion that Deck.gl had already calculated.

My understanding is that geometry.worldPosition contains the original geometry passed to the layer and that position contains the geometry after extrusions have been added and the projection has been calculated. Neither seems to allow me to do what I want.

I have also attempted to modify the worldPosition directly and inject that earlier before extrusions have been calculated, but I don’t seem to have access to the variable at vs:#main-start.

Any insight or suggestions would be helpful,
Thanks!

How to upload an entire folder into DataPower local folder?

I am not able to import an entire folder into datapower becouse it’s allows me to upload files only and I can’t use a JS liberay (e.g: ValidatorJS) in API Connect Gatewayscript becouse I can’t upload the lib folder

screenshot of datapower file system

I tried to upload a compressed file and extract in the datapower but I could not extract it and I do not know if it’s possible or not.

Uncaught ReferenceError: exports is not defined even I don’t use it

I have Electron application with overlay over the loaded website in React and I get error:

Uncaught ReferenceError: exports is not defined
    at index.js:2:23

this is on second line: Object.defineProperty(exports, "__esModule", { value: true });

even I don’t use any NodeJS modules inside React app.

This is my project structure:

/src
  |--assets/
  |--electron/
  |--overlay/
  |--shared/
  |-.eslintrc.cjs
  |-.gitignore
  |-package.json
  |-postcss.config.js
  |-tailwind.config.js
  |-tsconfig.electron.json
  |-tsconfig.overlay.json

Basically assets contains images, electron contains backend code in typescript, overlay contains React code, shared contains types shared between backend and frontend.

This is how my build looks like in package.json:

"build": "bun run build:css && bun run build:overlay && bun run build:electron && cpx "src/assets/**/*" dist/assets",
"build:css": "bunx tailwindcss -i ./src/overlay/index.css -o ./dist/overlay/index.css --minify",
"build:electron": "tsc -p tsconfig.electron.json",
"build:overlay": "bun build src/overlay/index.tsx --config tsconfig.overlay.json --outdir=dist/overlay --format=esm --target=browser --external=electron --external=fs --external=path --external=os --splitting",
"start": "bun run build && electron dist/electron/main.js",
    

/src/overlay contains bunfig.toml, global.d.ts, index.css and index.tsx

bunfig.toml:

entrypoint = "index.tsx"
outdir = "../../dist/overlay"
target = "browser"
sourcemap = true
minify = false
format = "iife"

global.d.ts:

import { Config } from "../shared/types";

export {};

declare global {
    interface Window {
        electronAPI: {
            onSidebarToggle: (callback: () => void) => void;
            openExternal: (url: string) => void;
            saveConfig: (config: Partial<Config>) => void;
            onConfigLoaded: (callback: (config: Config) => void) => void;
        };
    }
}

index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

index.tsx:

import "./index.css";

import { createRoot } from "react-dom/client";

const mount = document.createElement("div");
mount.id = "sidebar-root";
document.body.appendChild(mount);

const App = () => {
    return <></>;
};

createRoot(mount).render(<App />);

/src/shared contains types.ts:

export const defaultConfig: Config = {
    autofocus: false,
    notify: true,
    rpcEnabled: true,
    informed: false,
    accentColor: "",
};

export interface Config {
    autofocus: boolean;
    notify: boolean;
    rpcEnabled: boolean;
    informed: boolean;
    accentColor: string;
}

If it is important this is /src/electron/preload.ts:

import { contextBridge, ipcRenderer, clipboard, shell } from "electron";
import { Config } from "../shared/types";

declare global {
    interface Window {
        toggleSidebar: () => void;
    }
}

contextBridge.exposeInMainWorld("electronAPI", {
    onSidebarToggle: (callback: () => void) => {
        ipcRenderer.on("sidebar-toggle", (_event, ...args) => {
            console.log("sidebar-toggle event received in preload");
            callback();
        });
    },
    saveConfig: (config: Partial<Config>) =>
        ipcRenderer.send("save-config", config),
    onConfigLoaded: (callback: (config: Config) => void) => {
        console.log("Setting up config loaded listener");
        ipcRenderer.on("config-loaded", (event, config) => callback(config));
    },
    copyToClipboard: (text: string) => clipboard.writeText(text),
    openExternal: (url: string) => shell.openExternal(url),
    checkForUpdates: () => ipcRenderer.invoke("check-for-updates"),
    quitAndInstall: () => ipcRenderer.send("quit-and-install"),
    updateAvailable: (
        callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void
    ) => ipcRenderer.on("update-available", callback),
    updateDownloaded: (
        callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void
    ) => ipcRenderer.on("update-downloaded", callback),
    downloadUpdate: () => ipcRenderer.invoke("download-update"),
});

I inject overlay into website like:

function injectOverlay(mainWindow: BrowserWindow) {
    const { pathToFileURL } = require("url");
    const overlayScriptPath = path.join(__dirname, "../overlay/index.js");
    const overlayScriptUrl = pathToFileURL(overlayScriptPath).href;

    mainWindow.webContents.executeJavaScript(`
      const s = document.createElement("script");
      s.type = "module";
      s.src = "${overlayScriptUrl}";
      document.body.appendChild(s);
    `);
}

tsconfig.electron.json contains:

{
    "compilerOptions": {
        "outDir": "dist",
        "rootDir": "src",
        "module": "Node16",
        "target": "ESNext",
        "moduleResolution": "node16",
        "esModuleInterop": true,
        "strict": true,
        "jsx": "react-jsx",
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "exclude": ["node_modules"],
    "include": [
        "src/electron/**/*",
        "src/overlay/**/*",
        "postcss.config.js",
        "tailwind.config.js"
    ],
    "assets": ["src/assets/**/*"]
}

tsconfig.overlay.json contains:

{
    "compilerOptions": {
        "outDir": "dist/overlay",
        "rootDir": "src/overlay",
        "module": "ESNext",
        "target": "ESNext",
        "jsx": "react-jsx",
        "moduleResolution": "bundler",
        "esModuleInterop": true,
        "strict": true
    },
    "include": ["src/overlay/**/*"]
}

Fun fact is that if I run:

bun build src/overlay/index.tsx                                                                                                                                         
  --config tsconfig.overlay.json 
  --outdir=dist/overlay 
  --format=esm 
  --target=browser 
  --external=electron --external=fs --external=path --external=os 
  --splitting 

and then: electron dist/electron/main.js

I get no error, but when I run npm start, I get error, even build command is exactly same as in package.json.

ClientId Not Updating On Spotify’s Web API Authorization Example

I wanted to get my hands dirty with Spotify’s Web API, and it seems that the first thing I need to get a hang of is Authorization. So, I cloned Spotify’s Web API Examples repository from github and opened it in vscode. I followed the instructions on the README and replaced the client id with the one I received from Spotify after I created an app through Spotify For Developers. I also replaced their Redirect URI with https://127.0.0.1:8080. After this, I ran npm install, and finally npm start. At this point, I saw the first part of the application run correctly, but after I pressed Log In with Spotify, I got redirected to a page that said “Invalid Client ID”. I looked at the url and realized that the client id it was looking for was the default: “yourClientIdGoesHere” rather than the updated client Id I had replaced it with.

I made sure the changes were saved to the file, and I tried restarting the server multiple times, but that did not work.

Here is what my app.js looks like. I made no other changes to files in the directory.

/**
 * This is an example of a basic node.js script that performs
 * the Authorization Code with PKCE oAuth2 flow to authenticate 
 * against the Spotify Accounts.
 *
 * For more information, read
 * https://developer.spotify.com/documentation/web-api/tutorials/code-pkce-flow
 */

const clientId = 'ca93bf90292e4f13b9708468fbf516c0'; // your clientId
const redirectUrl = 'http://127.0.0.1:8080';        // your redirect URL - must be localhost URL and/or HTTPS

const authorizationEndpoint = "https://accounts.spotify.com/authorize";
const tokenEndpoint = "https://accounts.spotify.com/api/token";
const scope = 'user-read-private user-read-email';

// Data structure that manages the current active token, caching it in localStorage
const currentToken = {
  get access_token() { return localStorage.getItem('access_token') || null; },
  get refresh_token() { return localStorage.getItem('refresh_token') || null; },
  get expires_in() { return localStorage.getItem('refresh_in') || null },
  get expires() { return localStorage.getItem('expires') || null },

  save: function (response) {
    const { access_token, refresh_token, expires_in } = response;
    localStorage.setItem('access_token', access_token);
    localStorage.setItem('refresh_token', refresh_token);
    localStorage.setItem('expires_in', expires_in);

    const now = new Date();
    const expiry = new Date(now.getTime() + (expires_in * 1000));
    localStorage.setItem('expires', expiry);
  }
};

// On page load, try to fetch auth code from current browser search URL
const args = new URLSearchParams(window.location.search);
const code = args.get('code');

// If we find a code, we're in a callback, do a token exchange
if (code) {
  const token = await getToken(code);
  currentToken.save(token);

  // Remove code from URL so we can refresh correctly.
  const url = new URL(window.location.href);
  url.searchParams.delete("code");

  const updatedUrl = url.search ? url.href : url.href.replace('?', '');
  window.history.replaceState({}, document.title, updatedUrl);
}

// If we have a token, we're logged in, so fetch user data and render logged in template
if (currentToken.access_token) {
  const userData = await getUserData();
  renderTemplate("main", "logged-in-template", userData);
  renderTemplate("oauth", "oauth-template", currentToken);
}

// Otherwise we're not logged in, so render the login template
if (!currentToken.access_token) {
  renderTemplate("main", "login");
}

async function redirectToSpotifyAuthorize() {
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const randomValues = crypto.getRandomValues(new Uint8Array(64));
  const randomString = randomValues.reduce((acc, x) => acc + possible[x % possible.length], "");

  const code_verifier = randomString;
  const data = new TextEncoder().encode(code_verifier);
  const hashed = await crypto.subtle.digest('SHA-256', data);

  const code_challenge_base64 = btoa(String.fromCharCode(...new Uint8Array(hashed)))
    .replace(/=/g, '')
    .replace(/+/g, '-')
    .replace(///g, '_');

  window.localStorage.setItem('code_verifier', code_verifier);

  const authUrl = new URL(authorizationEndpoint)
  const params = {
    response_type: 'code',
    client_id: 'ca93bf90292e4f13b9708468fbf516c0',
    scope: scope,
    code_challenge_method: 'S256',
    code_challenge: code_challenge_base64,
    redirect_uri: redirectUrl,
  };

Would appreciate any help!

WebWorker giving a vague error. How do i understand what the error actually is?

I’m using a webworker to delegate some tasks related to world generation in a html/css/Javascript project.

I’m currently using replit static HTML to preview and run it.

The error message shows up in the eruda devtools console alongside all other diagnostic and debugging code but it’s the only error so far and the only vague one.

It states:

WorldGenerator: Worker encountered an error:
Event {isTrusted: true}

World generator is the link between the main js file and and this webworker. Regardless of what the error is i just want to be able to know where it stems from exactly in the worker. I’m aware that by default the message itself gets hidden for security reasons and that’s what I’m trying to get around.

I tried try-catch blocks and simple console logs yet it’s all obscured when this error appears so nothing else shows.

How do I make Vite work on a multi-page website?

I have a multi-page website built with vite. When I build and deploy the website, only my index.html file gets the file paths updated for my css and js files. My other .html files end up looking all weird since they are not reading properly the css and js files given that the file paths point out to my src folder instead of the dist/asset folder. I tried to update my vite.config file to add multi entry points but it hasn’t been working. The website works perfeclty fine until I build and deploy. I’m new to web dev so any help would be greatly appreciated 🙂

My file structure:
file structure

CSS and JS files imports:

    <link rel="stylesheet" href="src/styles/styles.css">
<link rel="stylesheet" href="src/styles/styles-threejs.css">

My vite.config.js:

import { defineConfig } from “vite”;
import react from “@vitejs/plugin-react”;

export default defineConfig({
plugins: [react()],
base: “/”,
build: {
outDir: “dist”,
assetsDir: “assets”,
sourcemap: true,
},
rollupOptions: {
input: {
index: “index.html”,
about: “/About.html”,
vt: “/VT.html”,
ksu: ‘/KSU.html’,
jhu: “/JHU.html”,
renderings: “/Renderings.html”,
},
},
});

Thanks in advance!

How to Identify Browser back, page close and redirect to another route in React Js

I need to Identify and display a custom confirmation modal on browser back, page close and redirect to another route in React. Below BeforeUnloadEvent give the behavior but can’t display a custom confirmation modal so that is not fulfill my requirement.

useEffect(() => {
  const handleBeforeUnload = (event: BeforeUnloadEvent) => {
    if (isDirty) {
      // Show default browser confirmation
      event.preventDefault();
      event.returnValue = '';
      // showConfirm();
    }
  };

  if (isDirty) {
    window.addEventListener('beforeunload', handleBeforeUnload);
  } else {
    window.removeEventListener('beforeunload', handleBeforeUnload);
  }

  return () => {
    window.removeEventListener('beforeunload', handleBeforeUnload);
  };
}, [isDirty]);

useBlocker from React-Router-DOM can use to identify and display a custom confirmation modal on browser back and on router change but it can’t identify the page/window close.

const blocker = useBlocker(useCallback(() => isDirty, [isDirty]));

What can I use to identify and display a custom confirmation modal on browser back, page close and redirect to another route?

HTML/Javascript that is filterable and submits on tab keystroke

I have an HTML select element that I can filter using selectize JS (based on this answer: Creating a select box with a search option .) However, I would also like to be able to submit the item selected on hitting tab. I would like the precise search functionality from the linked answer above but also the submit on tab ability. But it currently seems that, using selectize JS, I can have one or the other, but not both. Here is the version where I can search like I want but can’t submit on tab:

$(document).ready(function() {
  $('select').selectize({
    sortField: 'text'
  });
});
  <label>Select Team:</label>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/standalone/selectize.min.js" integrity="sha256-+C0A5Ilqmu4QcSPxrlGpaZxJ04VjsRjKu+G82kl5UJk=" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/css/selectize.bootstrap3.min.css" integrity="sha256-ze/OEYGcFbPRmvCnrSeKbRTtjG4vGLHXgOqsyLFTRjg=" crossorigin="anonymous" />
  <select name="team"  id="select-team" placeholder="Pick a team...">
    <option value="Bills">Bills</option> 
    <option value="Jaguars">Jaguars</option>
    <option value="Broncos">Broncos</option>
    <option value="Bears">Bears</option>
    <option value="Bengals">Bengals</option>
  </select>
</form>

(Obviously, this is just a slightly modified version of the linked answer.) However, when I add selectOnTab: true, it lets me select on tab (obviously) but now the ability to see what I’m typing is gone. It just auto-completes to the best match:

$(document).ready(function() {
  $('select').selectize({
    sortField: 'text';
    selectOnTab: true;
  });
});
  <label>Select Team:</label>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/standalone/selectize.min.js" integrity="sha256-+C0A5Ilqmu4QcSPxrlGpaZxJ04VjsRjKu+G82kl5UJk=" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/css/selectize.bootstrap3.min.css" integrity="sha256-ze/OEYGcFbPRmvCnrSeKbRTtjG4vGLHXgOqsyLFTRjg=" crossorigin="anonymous" />
  <select name="team"  id="select-team" placeholder="Pick a team...">
    <option value="Bills">Bills</option>
    <option value="Jaguars">Jaguars</option>
    <option value="Broncos">Broncos</option>
    <option value="Bears">Bears</option>
    <option value="Bengals">Bengals</option>
  </select>
</form>

How can I achieve both features at once?

In summary, I desire a <select> that:

  • Can be searched by typing.
  • Does not autocomplete or autoselect the best match (the user has to do the selecting).
  • Does select the top option matching what the user has typed on hitting tab.
  • Ideally, though not necessarily, uses selectize JS.

Thanks!

A dead loop problem in JavaScript about Set

Why the following code caused dead loop?

const s = new Set([1]);

s.forEach(e => {
    s.delete(e)
    s.add(e)
})

I tried to change the order about delete and add operation,the dead loop disapperd.

const s = new Set([1]);

s.forEach(e => {
    s.add(e)
    s.delete(e)
})