Getting 401 unauthorized error when I reload my react app on any route?

Issue After Upgrading Node.js, Docker, and NPM – React App Reload Fails with 401

Environment Details:
I have recently upgraded to the following:

Node.js: v20.0.0
Docker: v20.0.0
NPM: v9.0.0

Additionally, I have updated all dependencies to ensure compatibility with Node.js v20 and removed deprecated ones. Necessary modifications were made to React components and test files to align with the upgraded dependencies.

How the App Works

  1. I have two server files:

    server.js (for production)
    dev-server.js (for development)
    
  2. For development, I start dev-server.js locally.

  3. The app loads a static HTML page in the browser, which contains a
    form with all the static data required for the API call (including
    the auth/SIF token).

  4. When I submit the form:

  • A new tab is opened at http://localhost:3000/.
  • The request is sent to the running server, which returns an HTML page
    containing the submitted API data, static files, and Webpack-bundled
    assets.
  • The React app mounts successfully on the browser.

Issue

The React app loads perfectly on the initial form submission.
However, when I reload the page on any route, http://localhost:3000/ is called and fails with a 401 (Unauthorized) error.

Observations

  • After reload, form data becomes undefined.
  • The http://localhost:3000/ request should be a POST call, but after
    reload, it becomes a GET request.
  • Reloading http://localhost:3000/static works fine and returns the
    expected HTML from the server without any issues.
  • If there is any syntax error in the React app after it loads, a POST
    request to http://localhost:3000/ is triggered even though the .jsx
    file has issues.
  • Cookies are getting deleted unexpectedly.

What I Have Tried So Far

  • Ensured that cookies are set properly.

They are no getting set after reload

  • Checked if authentication tokens persist across reloads.

No they do not persist after reload

  • Verified that form data is available at the time of reload.

No after reload the form data comes undefined.

  • Checked browser dev tools to inspect network requests and cookies.

They disappear after reload.

Expected Behavior

  • The app should persist the authentication state after a reload.

  • Form data should not be lost when reloading the page.

  • The request should remain a POST request instead of switching to GET.

  • Cookies should not be deleted automatically.

Sharing you my code with for your reference:

main.js

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <Provider store={store}>
    <Router>
      <Layout>
        <Routes>
          {indexRoute}
          <Route path="/resource/:resource_id" element={<ResourceLoader />} />
          {promptRoute}
        </Routes>
      </Layout>
    </Router>
  </Provider>
);

dev-server and server.js

app.static("node_modules/dist");

// Launch our UI APP
app.use(async (ctx) => {
  const items_script_url = config.urls.items;

  ctx.body = `
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
        <title>React APP</title>
        <link rel="shortcut icon" href="static/favicon.ico">
        <link rel="stylesheet" href="static/styles.css">
        
        <script>
          window.WebComponents = window.WebComponents || {};
          window.WebComponents.root = 'node_modules/@webcomponents/webcomponentsjs/';
        </script>

        <script type="application/javascript">
          window._LTI_PARAMS_ = ${JSON.stringify(ctx.request.body)};
        </script>

        <script src="${items_script_url}"></script>
      </head>
      <body>
        <div id="root"></div>
        <script type="application/javascript" src="static/vendor.js?version=1.0"></script>
        <script type="application/javascript" src="static/app.js?version=1.0"></script>
      </body>
    </html>
  `;
});

webpack.config.js

import webpack from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
import ESLintPlugin from 'eslint-webpack-plugin';
import config from '../config';
import debug from 'debug';

const _debug = debug('app:webpack:config');
const paths = config.utils_paths;
const { __DEV, __PROD, __TEST } = config.globals;

_debug('Create configuration.');
_debug('_DEV', __DEV);
_debug('PROD', __PROD);
_debug('TEST', __TEST);

const webpackConfig = {
  name: 'client',
  target: 'web',
  devtool: __PROD ? false : config.compiler_devtool,
  resolve: {
    modules: [paths.base(config.dir_client), 'node_modules'],
    extensions: ['.js', '.jsx', '.json'],
  },
  module: {},
};

// ------------------------------------
// Entry Points
// ------------------------------------
const APP_ENTRY_PATH = `${paths.base(config.dir_client)}/main.js`;

webpackConfig.entry = {
  app: __DEV
    ? [
        APP_ENTRY_PATH,
        `webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`,
      ]
    : [APP_ENTRY_PATH],
  vendor: config.compiler_vendor,
};

// ------------------------------------
// Bundle Output
// ------------------------------------
webpackConfig.output = {
  filename: '[name].js',
  path: paths.base(config.dir_dist),
  publicPath: config.compiler_public_path,
};

// ------------------------------------
// Plugins
// ------------------------------------
webpackConfig.plugins = [new webpack.DefinePlugin(config.globals)];

if (__DEV) {
  _debug('Enable plugins for live development (HMR, NoErrors).');
  webpackConfig.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new MiniCssExtractPlugin({ filename: 'styles.css' }),
    new ReactRefreshWebpackPlugin()
  );
} else if (__PROD) {
  _debug('Enable plugins for production.');
  webpackConfig.plugins.push(
    new HtmlWebpackPlugin({
      template: 'node_modules/dist/button.html',
      hash: false,
      filename: 'button.html',
      inject: 'head',
      minify: { collapseWhitespace: true },
    }),
    new HtmlWebpackPlugin({
      template: 'node_modules/dist/loader.html',
      hash: false,
      filename: 'loader.html',
      inject: 'head',
      minify: { collapseWhitespace: true },
    }),
    new MiniCssExtractPlugin({ filename: 'styles.css' })
  );
}

// ------------------------------------
// Integrated ESLint Plugin
// ------------------------------------
if (__DEV || __PROD) {
  webpackConfig.plugins.push(
    new ESLintPlugin({
      context: paths.base(config.dir_client),
      extensions: ['js', 'jsx'],
      emitWarning: __DEV,
      failOnError: __PROD,
      overrideConfigFile: paths.base('.eslintrc'),
    })
  );
}

// ------------------------------------
// Loaders
// ------------------------------------
webpackConfig.module.rules = [
  {
    test: /.(js|jsx)$/,
    exclude: /node_modules/,
    use: {
      loader: 'babel-loader',
      options: {
        cacheDirectory: true,
        presets: ['@babel/preset-env', '@babel/preset-react'],
        plugins: [
          '@babel/plugin-transform-runtime',
          ...(__DEV ? ['@babel/plugin-transform-react-jsx-source'] : []),
          ...(__PROD
            ? [
                'babel-plugin-transform-react-remove-prop-types',
                '@babel/plugin-transform-react-constant-elements',
              ]
            : []),
        ],
      },
    },
  },
  {
    test: /.json$/,
    type: 'javascript/auto',
    use: 'json-loader',
  },
  {
    test: /.css$/,
    include: /client/,
    sideEffects: true,
    use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
  },
  {
    test: /.(woff2?|otf|ttf|eot|svg)$/,
    type: 'asset/resource',
    generator: {
      filename: 'fonts/[name][ext][query]',
    },
  },
  {
    test: /.(png|jpg)$/,
    type: 'asset/inline',
  },
];

export default webpackConfig;

Below are the package.json dependencies:

{
  "dependencies": {
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@babel/runtime": "^7.12.5",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
    "@webcomponents/webcomponentsjs": "^2.8.0",
    "eslint": "^8.57.1",
    "fs": "0.0.2",
    "history": "2.1.2",
    "jquery": "^3.7.1",
    "js-cookie": "2.1.3",
    "jsdom": "^26.0.0",
    "koa-connect": "^2.1.0",
    "lodash": "4.17.21",
    "node-fetch": "^3.3.2",
    "postcss": "^8.5.1",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-redux": "^8.1.3",
    "react-router-dom": "^7.1.5",
    "react-router-redux": "^4.0.8",
    "redux": "^4.2.1",
    "redux-rest-resource": "^0.29.3",
    "redux-thunk": "^2.4.2",
    "resolve-url-loader": "^5.0.0",
    "uninstall": "^0.0.0",
    "validator": "^13.12.0",
    "webpack-dev-middleware": "^7.4.2",
    "webpack-hot-middleware": "^2.26.1",
    "yargs": "3.32.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.0.0",
    "@babel/core": "^7.0.0",
    "@babel/eslint-parser": "^7.26.5",
    "@babel/node": "^7.26.0",
    "@babel/plugin-transform-react-constant-elements": "^7.25.9",
    "@babel/plugin-transform-react-jsx-source": "^7.25.9",
    "@babel/preset-env": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "@babel/register": "^7.25.9",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.2.0",
    "autoprefixer": "^10.4.20",
    "ava": "^6.2.0",
    "babel-loader": "^9.2.1",
    "babel-plugin-react-transform": "2.0.2",
    "babel-plugin-rewire": "^1.2.0",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
    "babel-watch": "^7.8.1",
    "better-npm-run": "0.0.7",
    "css-loader": "^7.1.2",
    "cssnano": "^7.0.6",
    "deep-freeze-es6": "1.0.1",
    "eslint-config-standard": "^17.1.0",
    "eslint-config-standard-react": "^13.0.0",
    "eslint-plugin-babel": "^5.3.1",
    "eslint-plugin-flowtype": "^8.0.3",
    "eslint-plugin-import": "^2.31.0",
    "eslint-plugin-promise": "^6.6.0",
    "eslint-plugin-react": "^7.37.4",
    "eslint-webpack-plugin": "4.2.0",
    "expect": "1.20.2",
    "fs-extra": "0.26.7",
    "html-webpack-plugin": "^5.6.3",
    "imports-loader": "^5.0.0",
    "jest": "^29.7.0",
    "json-loader": "0.5.4",
    "loader-utils": "^1.4.2",
    "mini-css-extract-plugin": "2.9.2",
    "nodemon": "^3.1.9",
    "nyc": "^17.1.0",
    "postcss-css-variables": "^0.19.0",
    "postcss-import": "^16.1.0",
    "postcss-loader": "^8.1.1",
    "postcss-mixins": "^11.0.3",
    "postcss-nesting": "^13.0.1",
    "postcss-simple-vars": "^7.0.1",
    "react-refresh": "^0.16.0",
    "react-transform-catch-errors": "1.0.2",
    "react-transform-hmr": "1.0.4",
    "redux-mock-store": "1.2.0",
    "rimraf": "2.5.4",
    "webpack": "^5.97.1",
    "webpack-cli": "^6.0.1",
    "xo": "^0.60.0"
  }
}

Any insights or suggestions would be greatly appreciated!

Gradio: Chatbot.copy event to allow change of text before copying it

In gradio, when a user copies the text generated by the LLM, this triggers the event ChatBot.copy, which is great. But the listener only gives you the copied text, and does not let you modify it.

In order to comply with the EU AI Act, chatbots should give a kind of watermark on generated content. For text, a simple “Generated by AI” somewhere in the text is enough.

I tried something like this:

        def add_ai_tag(message):
            message[0][1] = message[0][1] + "Generated by AI"
            return message
    
        chatbot.copy(add_ai_tag, chatbot, chatbot)

But this changes the text on the chatbot dialogue itself, and not the text being sent to the clipboard, making me believe that Chatbox.copy happens after the copy has happened, or I am clearly doing something silly and I couldn’t understand the documentation (which is pretty difficult on the event listeners part).

Any hints are welcome, and an example on the documentation would be super useful (as everyone needs to do that in the EU now).

Why does history.pushState actually replace here?

In certain edge cases, immediately after page load my script may call replaceState(myState, "") and then pushState(myNewState, "", myNewUrl) in quick succession. When this happens, the URL changes but a new history entry is not created.

This is actually the desired behaviour, but I don’t understand why this is happening and I’m worried I can’t rely on this being consistent. I was expecting to implement a workaround in these edge cases to use replaceState instead of pushState.

I can’t find anything about exceptions to pushState‘s behaviour that could help me understand what is going on.

Here’s a very much simplified version of the script:

function setState(init) {
    let state = history.state || {};
    
    // add/replace things to state

    if (!init) {
        let url = new URL(myBaseUrl);

        // add searchParams to URL

        if (url.toString() == location.href) history.replaceState(state, "");
        else history.pushState(state, "", url);
    }
    else history.replaceState(state, "");
}

$(document).ready(function() {
    init = true;
    pluginElement.on("init", function() {
        if (!popstate) { // popstate is set to true when popstate event fires
            setState(init);
            init = false;
        }
        else popstate = false;

        if (history.state["myStateKey"] == someCondition) {
            pluginElement.init(); // this fires init event again
        }
    });

    pluginElement.init();
});

AI Inbound Call Agent Not Responding on Cloudflare (Works on Ngrok)

I’ve built an AI-powered inbound call agent using Twilio and OpenAI TTS. It works perfectly when hosted on ngrok, but after deploying on Cloudflare, the AI voice agent does not respond during calls.

The call connects successfully via Twilio.
AI responses work fine on ngrok but are missing on Cloudflare.
No explicit errors in Cloudflare logs.
I suspect Cloudflare might be interfering with Twilio WebSockets, TwiML responses, or OpenAI API calls. Could this be due to caching, security settings, or WebSocket restrictions? Any suggestions on configurations or settings to fix this?

Error code ‘80040e55’ when running Microsoft search on Windows 2012 R2

I have been asked to revive a very old Web site that has been dormant for a number of years. The Web site is a classic ASP site written in JavaScript. One of the functions of the Web Site is/was to a windows indexer to search for files located on the system. The site was moved on to its current Windows 2012 R2 server sometime in 2016. Based on the errors that were being encountered when I first started looking at this issue, my guess is nobody has used the functionality I am since the site was moved.

The initial error that site was producing when I started looking at the issue:

800a0e7a|Provider_cannot_be_found._It_may_not_be_properly_installed.

and looking at the line of code on the line where the error was created:

objConnection.ConnectionString = "provider=msidxs; data source=BQA"

I was able to determine that the problem initial issue was that the code was still looking for a deprecated tool msidxs.

I used this link to determine this.

Microsoft Search Service: Is there an OLE DB provider? (alternate: Index Server on Win2012?)

However, after installing the Windows Search Service and modifying the code and trying to run the modified code, I am now getting a message of 80040e55 with no additional information.

Searches on both Google and Bing are showing me similar error codes that are not exactly this same. Mostly the code that I am seeing that being returned have to do with failed windows update’s which is not what I am dealing with when I am getting the error.

How to download a file with POST request made by javascript? [duplicate]

I have a javascript object to use as POST body to request a binary file download.

I tried with

var xhr = new XMLHttpRequest();
xhr.open("POST", myurl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(myobj));

it works but the result is catched and it doesn’t prompt to download the file.

Please consider the file may be big, then I don’t consider to handle blob with js and moreover I don’t need an ajax call but I cannot image any other solution than building a fake form and submit replicating my input object using html input elements.

typescript return has erroneous and persistent errors

i have a CRA js/jsx project. i’m utilizing a library that contains ts/tsx. i can’t seem to get my visual studio to not complain about the code within my tsx return blocks. the code compiles and works fine. any help is appreciated – thanks in advance!

return statement screenshot

return block screenshot

my proj:

  • react ^18.3.1.
  • typescript ^4.9.5 (workspace and ide)

things i’ve tried:

  • restarting typescript server / restarting ide
  • adding in a tsconfig.json
  "compilerOptions": {
    "jsx": "react",
    "allowJs": true,
    "outDir": "dist",
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["./"]
}
  • adding to my user settings: “typescript.tsdk”: “/Users/merp/.nvm/versions/node/v22.14.0/lib/node_modules/typescript/lib”
  • encapsulating in <> </>

JavaScript on page works only after I reload the page with “Strg”+”R”

I have a HTML web page (written in Ruby on Rails .html.erb so some parsing is going on). On this page there is a button ID IncreaseInvoicePositions (see below). The JavaScript it triggers is supposed to increase the tr in table (ID: PositionTable, see below) and add form fields in the td elements table via JavaScript.

But the page just jumps to the top of the page. The JavaScript generally seems to works fine but only after I press ‘Ctrl+R’ for reload. This is obviously very user unfriendly and not intended.

What is Ctrl+R triggering for my stuff to work out of a sudden? The Link of the button links to "". The Javascript preventsDefault though. (I tried setting something else but instead of the link not working it tried linking to that place which was not existing anf failed 404).

<table class="table table-bordered ml-4" id="PositionTable" positions="<%= @in_invoice.invoice_positions.count < 2 ? 2 : @in_invoice.invoice_positions.count %>">
              <thead>
                <tr>
                  <th>
                    <%= t('activerecord.attributes.invoice_position.order') %>
                  </th>
                  <th>
                    <%= t('activerecord.attributes.invoice_position.description') %>
                    <% hover = t('invoice_positions.empty_hint') %>
                    <%= image_tag 'famfamfam/information.png', title: hover  %>
                  </th>
                  <th><%= t('activerecord.attributes.invoice_position.net') %></th>
                  <th>
                    <div class="row">
                      &nbsp;&nbsp;<%= t('activerecord.attributes.invoice_position.vat_rate') %><br>
                      <% hover = t('placeholder.index.table_header.vat_rate.hint') %>
                      <%= image_tag 'famfamfam/information.png', title: hover  %>
                    </div>
                  </th>
                </tr>
              </thead>
              <% @i = 0 %>
              <tbody>
              <%= f.fields_for :invoice_positions do |ff| %>
                <% @i = @i + 1 %>
                <tr>
                  <td align="center">
                    <%= @i %>
                  </td>
                  <td><%= ff.text_field :description, required: true, label: false, type: :text, class: 'form-control' %></td>
                  <td>
                    <div class="input-group-append">
                      <%= ff.text_field :net, required: true, label: false, class: 'form-control text-right col-sm-10', value: ff.object.net.to_s.gsub(".", ","), type: :text  %>
                      <span class="input-group-text" style="width: 40px;">€</span>
                    </div>
                  </td>
                  <td>
                    <div class="input-group-append">
                      <%= ff.text_field :vat_rate, required: true, label: false, class: 'form-control col-xs-1', type: :number %>
                      <span class="input-group-text" style="width: 40px;">%</span>
                    </div>
                  </td>
                </tr>
              <% end %>
              </tbody>
            </table>
            <%= link_to t('invoice_positions.increase'), "", id: "IncreaseInvoicePositions", class: "btn btn-secondary ml-4" %>
          </div>

The Javascript which the link button is triggering works fine. Here the code:

$(document).ready(function() {
    document.getElementById("IncreaseInvoicePositions").addEventListener("click",
        function(){
            event.preventDefault();
            var table = document.getElementById("PositionTable");
            amountPositions = parseInt(table.getAttribute("positions"));
            var row = table.insertRow();
            amountPositions = amountPositions + 1;
            table.setAttribute("positions", amountPositions)
            var cell = row.insertCell();
            cell.innerHTML = "<div class='center-text'>"+amountPositions+"</div>";
            cell = row.insertCell();
            cell.innerHTML = "<input required="required" label="false" type="text" class="form-control" name="out_invoice[invoice_positions_attributes]["+(amountPositions-1)+"][description]" id="out_invoice_invoice_positions_attributes_"+(amountPositions-1)+"_description">";
            cell = row.insertCell();
            cell.innerHTML = "<div class="input-group-append"><input required="required" label="false" type="text" class="form-control text-right" name="out_invoice[invoice_positions_attributes]["+(amountPositions-1)+"][net]" id="out_invoice_invoice_positions_attributes_"+(amountPositions-1)+"_net"><span class="input-group-text" style="width: 40px;">€</span></div>";
            cell = row.insertCell();
            cell.innerHTML = "<div class="input-group-append"><input required="required" label="false" type="text" class="form-control col-xs-1" name="out_invoice[invoice_positions_attributes]["+(amountPositions-1)+"][vat_rate]" id="out_invoice_invoice_positions_attributes_"+(amountPositions-1)+"_vat_rate"><span class="input-group-text" style="width: 40px;">%</span></div>";
            console.log("Invoice positions increased");
        }
    );
});

How to add namespaces in jquery plugins

I have this jquery plugin:

(function ( $ ) {
$.fn.ProductCarousel = function(options) {
    var settings = $.extend({
        height: null,
        width: "90%",
        backgroundColor: "#ffffff",
        showItems: 1,
        title: "This is a Carousel Title",
        titleFontSize: 18,
        titleColour: '#000000',
        buttonNavBackgorundColor: "#0D47A1",
        buttonNavIconColor: "#ffffff",
        buttonDisableNavIconColor: '#039BE5',
        seperatorWidth: 10,
    }, options );


    var thisControl = $(this);

    var arrayHtmlItems = Array();

    var initialShowItems = settings.showItems;

    for (var i = 0; i < $(this).children().length; i++) {
        arrayHtmlItems.push($(this).children().get(i));
    }

    var contentContainer = $("<div class='bullet-product-carousel-container'>");
    $(this).append(contentContainer); <-- Error lands here

    .... // more Jquery functionality

}( jQuery ));

At the moment i can access the plugin as:

$("#bulletProductCarousel").ProductCarousel({backgroundColor: "#0D47A1", showItems: 7, title: "FEATURED PRODUCTS", width: "100%", seperatorWidth: 10});

But i want to add a namespace $().BulletControls.ProductCarousel({});

$("#bulletProductCarousel").BulletControls.ProductCarousel({backgroundColor: "#0D47A1", showItems: 7, title: "FEATURED PRODUCTS", width: "100%", seperatorWidth: 10});

How would i add the [BulletControls] Prefix?

Making a slider (carousel) whenever the picture is clicked

I have a php file that calls the images from the db and creates the appropriate html code and displays them.
I want to have it so that whenever the user clicks on an image a slider (carousel) appears. It should contain all the pictures called from the database.
Maybe the answer is using a modal instead of sliders, but I don’t know how to “switch pages” between them, or if its even possible.

I tried using bootstrap’s sliders but it didn’t work (I wrapped the img in the correct bootstrap slider divs. I don’t remember the exact code, but I followed the main bootstrap instruction for creating sliders).
So I think this idea of using sliders is completely wrong.

Here is my php code:

if (mysqli_num_rows($result) > 0) {
    echo "<div class='gallery-container'>";

    while ($row = mysqli_fetch_assoc($result)) {
        echo "<div class='gallery-item'>"; 
        if (!empty($row['gallery_image']) && file_exists(__DIR__ . '/../public/images/gallery/' . basename($row['gallery_image']))) {
            $imagePath = '/public/images/gallery/' . basename($row['gallery_image']);
            echo "<img src='" . htmlspecialchars($imagePath) . "' alt='" .$row['title'] . "' title='" . $row['title'] . "'>";
            // echo "<p>DEBUG: " . htmlspecialchars($imagePath) . "</p>"; //debug
        }
        echo "<form method='POST' action='/includes/gallery_delete.php' onsubmit='return confirm("Biztosan törli ezt a képet?");'>";
        echo "<input type='hidden' name='gallery_id' value='{$row['id']}'>";
        echo "<button type='submit' class='btn btn-danger news-delete'>Törlés</button>";
        echo "</form>";
        echo "</div>";
    }
    echo "</div>";
} else {
    ErrorHandler::displayError("Nincs kép feltöltve az adatbázisba!");
}

How to efficiently manage state synchronization across nested asynchronous operations in a large-scale JavaScript application?

I am building a large-scale JavaScript application that involves complex state management with deeply nested asynchronous operations, including API calls, WebSocket streams, and scheduled tasks.

The challenge is ensuring state consistency across these async boundaries without causing race conditions, memory leaks, or performance issues. I’ve tried using Promises, async/await, RxJS, and Redux, but I still run into issues where:

State updates are out of sync when async operations complete in unpredictable orders.
Memory usage spikes when subscriptions or event listeners aren’t cleaned up properly.
UI re-renders are inefficient, causing performance bottlenecks.
I’ve experimented with approaches like:

Debouncing and throttling state updates, but it sometimes causes data to become stale.
Using AbortController to cancel async operations, but I still struggle with edge cases.
Combining useEffect with cleanup functions in React, but nested async calls still create issues.
Are there advanced patterns or tools that can help with:

Orchestrating complex async flows while keeping state consistent?
Efficiently handling async cancellations and cleanup to avoid memory leaks?
Minimizing UI re-renders without sacrificing data freshness?

Draw a videoframe using perspective on a canvas

so I know how to draw a videoframe on a canvas with this code I got from Codepen:

let v = document.querySelector("video");
let c = document.querySelector("canvas");
let ctx = c.getContext("2d");
let i;
function draw() {
  let times = v.videoWidth/270;
  let vHeight = v.videoHeight/times;
  c.width = 270;
  c.height = vHeight; 
  i = window.requestAnimationFrame(draw)
  ctx.drawImage(v, 0, 0, 270, vHeight)
}

v.addEventListener("loadeddata", function() {
  draw()
}, false);
v.addEventListener("play", function() {
  draw()
}, false);
v.addEventListener("pause", function() {
  window.cancelAnimationFrame(i);
  i = undefined;
}, false);
v.addEventListener("ended", function() {
  window.cancelAnimationFrame(i);
  i = undefined;
}, false); 

I also know how to draw an image with prespective on a canvas with the perspective.js from wanadev on github. Now my question is how to combine those two to get a drawn videoframe with perspective.
I tried to combine those two like this:

function zeichne() {
    let times = v.videoWidth/270;
    let vHeight = v.videoHeight/times;
    c.width = 270;
    c.height = vHeight; 
    i = window.requestAnimationFrame(zeichne)
    var p = new Perspective(ctx, v);
    //This is the original perspective draw
    /* p.draw([
            [0, 0],
            [image.width - 50, 50],
            [image.width - 70, image.height - 30],
            [10, image.height]
    ]); */
    //This is mine
    p.draw([
        [0, 0],
        [times - 50, 50],
        [times - 70, vHeight - 30],
        [10, vHeight]
    ]); 
    //ctx.drawImage(v, 40, 0, 270, vHeight)
  }
}

The problem is that I just get an error saying: ‘this.p is undefined’ in line 84 of perspective.js. But I checked the js and can’t see any mistakes in my code or the perspective.js.

Thanks in advance 🙂

FileReader.readAsArrayBuffer handling of non-ASCII including £ (pound sterling)

I am using FileReader.readAsArrayBuffer(file) and converting the result into a Uint8Array.

If the text file input contains a pound sterling sign (£), then this single character results in two byte codes, one for  and one for £. I understand that this is because £ is in the extended-ASCII set.

Is there a way to prevent this extra character? If not, will it always be an Â? If so, I can strip them out.

How to update Firefox browser silently using a PowerShell script without interrupting user session or without closing open instances by user

A script should auto update the browser to the latest version in local machine without closing open instances where user is working on browser window or tabs.
Also let me know can it be done by PowerShell script only OR does it require a combination of VB script and PS script as well?
Also let me know whether JavaScript is required along with them.

We tried PS script but not getting expected results.