Why does stream read not return in BYOD mode, even when closed

I am working with ReadableStreams in JS/Browser code and hit the following issue. When using a ReadableStreamBYOBReader to control the size of stream reads, if the stream is closed during a read request without enqueued data, the read never returns. See the first snippet below.

The last read returns as expected when ReadableStreamDefaultReader is used to read the stream. See the second snippet below (the stream implementations are identical in the snippets).

Given that this works the same in Chrome and FF, I’m assuming it expected behavior. But if so, how do you close a stream being read BYOD mode when you don’t know how much data is remaining until each read request is made? Raising an error closes the stream, but that’s rather ugly.

These snippets run in Chrome and FF, but not Safari because Safari doesn’t have the full stream API yet. Also, please ignore that byobRequest is not used and that reading isn’t optimized. My goal was to simplify the logic.

// Hangs if you try to read and the stream closes (when readBlocks > streamBlocks)
const readBlocks = 4;
const streamBlocks = 3;
const blockSize = 1024;

const stream = makeStream(streamBlocks);
const reader = stream.getReader({ mode: "byob" });
let buffer = new Uint8Array(blockSize * readBlocks);

readAllBYOB(reader, buffer).then(([blocks, done]) => {
  reader.releaseLock();
  let byteLen = 0;
  for(const block of blocks) {
     byteLen += block.byteLength;
  }
  console.log("all done, bytes read:", byteLen, done);
});

function makeStream(loops) {
  let totalBytesOutput = 0;
  console.log("creating stream size:", loops * blockSize);

  return new ReadableStream({
    type: "bytes",

    async start(controller) {
      console.log(
        `stream start- ${controller.constructor.name}.byobRequest = ${controller.byobRequest}`,
      );

      try {
        const data = new TextEncoder().encode("s".repeat(blockSize));
        totalBytesOutput += data.byteLength;
        console.log("stream start- enqueuing, total:", data.byteLength, totalBytesOutput);
        controller.enqueue(data);
      } catch (err) {
        console.error("stream start- error, closing", err);
        controller.error(err);
      }
    },

    async pull(controller) {
      // ignoring actual byobReuest object
      console.log(
        `stream pull- ${controller.constructor.name}.byobRequest = ${controller.byobRequest}`,
      );

      try {
        // Pretend we don't know when data runs out until the request is made.
        // In BYOD mode, the read never returns. Unless you do one of the following:
        //  1. Enqueueing data before calling close (but we don't have any to enqueue)
        //  2. Call controller.error() instead, but that's ugly
        if (totalBytesOutput >= blockSize * loops) {
          console.log("stream pull- closing");
          controller.close();
          return;
        }

        const data = new TextEncoder().encode("p".repeat(blockSize));
        totalBytesOutput += data.byteLength;
        console.log("stream pull- enqueuing, total:", data.byteLength, totalBytesOutput);
        controller.enqueue(data);
      } catch (err) {
        console.error("stream pull- error, closing", err);
        controller.error(err);
      }
    },
  });
}

async function readAllBYOB(reader, output) {
  let targetBytes = output.byteLength;
  let readBytes = 0;
  let blocks = [];
  let streamDone = false;
  console.log('readAllBYOB- start: ', targetBytes);

  while (readBytes < targetBytes) {
    console.log('readAllBYOB- try reading:', output.byteLength);

    // This does not return on the final read, even when stream is closed
    let { done, value } = await reader.read(output);
    console.log('readAllBYOB- read, done:', value?.byteLength, done);

    streamDone = done;
    if (value) {
      blocks.push(value);
      readBytes += value.byteLength;
    }

    if (done || !value) {
      break;
    }
    if (readBytes < targetBytes) {
      output = new Uint8Array(targetBytes - readBytes);
    }
  }

  console.log(
    'readAllBYOB- blocks, remainingBytes, done:',
    blocks.length,
    targetBytes - readBytes,
    streamDone
  );

  return [blocks, streamDone];
}
// Works as expected
const streamBlocks = 3;
const blockSize = 1024;

const stream = makeStream(streamBlocks);
const reader = stream.getReader();

readAll(reader).then(([blocks, done]) => {
  reader.releaseLock();
  let byteLen = 0;
  for(const block of blocks) {
     byteLen += block.byteLength;
  }
  console.log("all done, bytes read:", byteLen, done);
});

function makeStream(loops) {
  let totalBytesOutput = 0;
  console.log("creating stream size:", loops * blockSize);

  return new ReadableStream({
    type: "bytes",

    async start(controller) {
      console.log(
        `stream start- ${controller.constructor.name}.byobRequest = ${controller.byobRequest}`,
      );

      try {
        const data = new TextEncoder().encode("s".repeat(blockSize));
        totalBytesOutput += data.byteLength;
        console.log("stream start- enqueuing, total:", data.byteLength, totalBytesOutput);
        controller.enqueue(data);
      } catch (err) {
        console.error("stream start- error, closing", err);
        controller.error(err);
      }
    },

    async pull(controller) {
      // ignoring actual byobReuest object
      console.log(
        `stream pull- ${controller.constructor.name}.byobRequest = ${controller.byobRequest}`,
      );

      try {
        // Pretend we don't know when data runs out until the request is made.
        // In BYOD mode, the read never returns. Unless you do one of the following:
        //  1. Enqueueing data before calling close (but we don't have any to enqueue)
        //  2. Call controller.error() instead, but that's ugly
        if (totalBytesOutput >= blockSize * loops) {
          console.log("stream pull- closing");
          controller.close();
          return;
        }

        const data = new TextEncoder().encode("p".repeat(blockSize));
        totalBytesOutput += data.byteLength;
        console.log("stream pull- enqueuing, total:", data.byteLength, totalBytesOutput);
        controller.enqueue(data);
      } catch (err) {
        console.error("stream pull- error, closing", err);
        controller.error(err);
      }
    },
  });
}

async function readAll(reader) {
  let readBytes = 0;
  let blocks = [];
  let streamDone = false;
  console.log('readAll- start');

  while (true) {
    console.log('readAll- try reading');

    // This always returns as expected
    let { done, value } = await reader.read();
    console.log('readAll- read, done:', value?.byteLength, done);

    streamDone = done;
    if (value) {
      blocks.push(value);
      readBytes += value.byteLength;
    }

    if (done || !value) {
      break;
    }
  }

  console.log(
    'readAll- blocks, done:',
    blocks.length,
    streamDone
  );

  return [blocks, streamDone];
}

Issue when submitting form with Remix + shadcn/ui + react-hook-form

OBS: I decided to open a answered question here because I have seen so many posts in Reddit and Github about submitting a form with shadcnui/react-hook-form in a Remix app.

I had an issue building a form with Remix and shadcn/ui (which uses react-hook-form) and I just solved it after hours.

To build the form, I followed these pages:

The problem was happening when I was submitting the form, not receiving any logs that I put in some sections of my code.

I checked other cases and tried some things to resolve it:

  • changing form onSubmit attribute to various structures
  • verified if some fields were not “registered” in form (I added the UI components, that are registered by itself)
  • verified any validation errors that could not be showed in screen.
  • added field values (from render attribute in my Switch component from shadcn, like that:
<Switch
  checked={field.value}
  onCheckedChange={field.onChange}
  name={field.name}
  ref={field.ref}
  disabled={field.disabled}
  onBlur={field.onBlur}
/>

How to connect to an existing websocket in Laravel

Good morning everyone.
I have a project in Laravel in which I want to connect to a websocket of which I have the URI, the ClientToken and AccesToken. The problem I have is that I have tried several methods to use websockets in Laravel, but none of them works for me. I have the following code:

use WebSocketClient;

class MewsWebSocket extends Controller
{
   public function index()
   {
      $client = new Client("wss://ws.mews-demo.com/ws/connector?ClientToken=E0D439EE522F44368DC78E1BFB03710C-D24FB11DBE31D4621C4817E028D9E1D&AccessToken=C66EF7B239D24632943D115EDE9CB810-EA00F8FD8294692C940F6B5A8F9453D");

      while (true) {
          $message = $client->receive();
          echo “Message received: {$message}”;

          sleep(1);
      }
   }
}

enter image description here

(There is no problem showing the tokens as they are public for the demo environment).

The problem I have is that I have copied the host and used it in another file that I have created in js to see if the URI works, and if I connect to the socket and receive messages, while with the PHP code does not.

const WebSocket = require('ws');

let ws = new WebSocket("wss://ws.mews-demo.com/ws/connector? ClientToken=E0D439EE522F44368DC78E1BFB03710C-D24FB11DBE31D4621C4817E028D9E1D&AccessToken=C66EF7B239D24632943D115EDE9CB810-EA00F8FD8294692C940F6B5A8F9453D");

ws.onmessage = function(ms) {
    console.log(ms.data);
}

I wanted to know if anyone knows any way to use websockets in Laravel in the way I need it for my project.

Google apps script: Replacement of document text with sheets values

I am working on a form that takes values and puts them in a spreadsheet. I want to take the values from that spreadsheet and use them as replacements in a sheet (with the intent of saving to .pdf, which I will learn next)

Here is a snippet of my code. I was expecting the values in the {{}} to be replaced with the values from the spreadsheet. It’s not happening though. It NAMES the document appropriately, but I think I’m using the wrong function call for the body.

function createNewGoogleDoc(){

const googleDocTemplate = DriveApp.getFileById('<myTemplateID>');
const destinationFolder = DriveApp.getFolderById('<myFolderID>');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 1');
const rows = sheet.getDataRange().getValues()

rows.forEach(function(row,index){
  if (index === 0) return; //using strict equality check to see if this is the header row. If so, pass.
  if (row[38]) return;//38
  const copy = googleDocTemplate.makeCopy(`${row[4]}`+''s Service Contract',destinationFolder);
  const doc = DocumentApp.openById(copy.getId())
  const body = doc.getBody().replaceText();
  //const friendlyDate = new Date(row[31]).toLocaleDateString();
  //const friendlyDate2 = new Date(row[32]).toLocaleDateString();

  body.replaceText(`{{Email}}`, `${row[1]}`);   <--- this here.

AWS API gateway won’t save settings on ‘Enable Cors’ on my resource

Proof is in this screenrecording https://www.loom.com/share/5225e46c060a4357ad39531372fe0c8e?sid=6e42106c-35fe-4937-a1eb-b073fb87e3f4

I have enabled/ensured Access-Control-Allow-Origin , Access-Control-Allow-Methods , Access-Control-Allow-Headers and appropriate values like ‘*’ and ‘POST,OPTIONS’ in both the intergration response and method response in both my OPTIONS and POST methods (the only methods I have right now).

Then made sure to deploy but I still get this when posting from axios from localhost:3000 in my react frontend :

XMLHttpRequest at ‘https://[api-gateway-id].execute-api.eu-west-1.amazonaws.com/Dev’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.

However when I POST with curl from terminal with -H “Content-Type: application/json” I get :

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 157 100 53 100 104 143 281 –:–:– –:–:– –:–:– 424{“statusCode”: 200, “body”: “”Hello from Lambda!””}

Showing my endpoint url is correct and there is a connection

I’m having trouble adding the micromodal library

I am having trouble adding the micromodal library to my project.

This is the link to the library:
https://micromodal.vercel.app/#introduction

I followed all the steps in the documentation but without success.

This is my code:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Modale</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/micromodal/0.4.10/micromodal.min.js" integrity="sha512-qcwcAul7d7yUcoz3MmQABiaGDa+gVkaDWgZX6wEd/z3I6z62nQCDW3EqioQG+O+QlGCpxmJLdH5snh4IaDPiPA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

</head>

<body>
    <button id="openmodal">Open</button>
    <!-- [1] -->
    <div id="modal-1" aria-hidden="true">

        <!-- [2] -->
        <div tabindex="-1" data-micromodal-close>

            <!-- [3] -->
            <div role="dialog" aria-modal="true" aria-labelledby="modal-1-title">


                <header>
                    <h2 id="modal-1-title">
                        Modal Title
                    </h2>

                    <!-- [4] -->
                    <button aria-label="Close modal" data-micromodal-close>Close</button>
                </header>

                <div id="modal-1-content">
                    Modal Content
                </div>

            </div>
        </div>
    </div>
    <script>
       document.getElementById('openmodal').addEventListener('click',function(){
        MicroModal.show('modal-1'); // [1]
       }) 
    </script>
</body>

</html>

Can someone please help me?

No Return on API JSON, Want to Display a Text

I am using an API from Aeris Weather Alerts and when there is no alerts for the area, the response is blank (“response”: []). Using the code below, is there a code I can use when the response is blank to have a default text that reads “No Weather Alerts”?

window.onload = () => {
const target = document.getElementById('alerts');
const aeris = new AerisWeather('CODE', 'PASSWORD');
const request = aeris.api().endpoint('alerts').place('SDZ047').filter('county').limit(3);
request.get().then((result) => {
    const reports = result.data;
    if (reports.length > 0) {
      let html = '';
      reports.forEach((details) => {
        html += `
<div class="cardalert">
<div class="cardalert-body" style="background-color:#${details.details.color || '000000'};">
<div class="alertmessage">
<p><img class="iconalert" src="${details.details.color || 'N/A'}.gif"></p>
<p class="textalert">${details.details.name || ''}<br><span>Issued: ${aeris.utils.dates.format(new Date(details.timestamps.issued * 1000), 'MM/dd/yyyy h:mm a')} - Expires: ${aeris.utils.dates.format(new Date(details.timestamps.expires * 1000), 'MM/dd/yyyy h:mm a')}</span></font>
</div>
</div>
<br><p class="bodytext">${details.details.body}</p><br>
</div>
`;
      });
      target.innerHTML = html;
    }
  });
};

</script>

Nothing at this time besides putting a second layer with a text.

Why is an inline cache for retrieving property from an object invalidated whenever someone changes any prototype above it, not below it?

I’m reading Mathias and Meurer’s article JavaScript engine fundamentals: optimizing prototypes. The article says:

This ValidityCell is invalidated whenever someone changes the associated prototype or any prototype above it.

I can’t understand why the cache was invalidated when the prototypes above were changed.

For example, given a prototype chain:

kitty ---> Cat.prototype ---> Animal.prototype ---> Object.prototype

And a method eat stored in Animal.prototype.eat.

If the code tries to retrieve a method kitty.eat(), why will its cache be invalidated when the Object.prototype is mutated, not when Cat.prototype is mutated?

kitty.eat(); // While executing, the engine makes an IC for Animal.prototype.eat

Object.prototype.x = 0; // Should not have any effect on the chain from kitty to Animal.prototype?

kitty.eat(); // But the cache is invalidated so we need to traverse the chain to find `eat` again?

A npm package to select/extract images from a website

I am working on an extension to search/edit images from a website. I am stuck and can’t find a package that lets me select an image on a website

The behavior I want goes like this:

  • Click the button on the extension
  • Then when I hover on the images on the website it should be outlined so I can pick it
  • this is what I need help with, will I have to manipulate the dom for
    all the images on a website do it or is there and extension to do it ?

Any help is appreciated, npm package, a repo or past experiences implementing such a thing.

how to set value on class with jquery

I have below table :

.
.
.

<td >
    <input type="text"   class="car_color"     >
    <input type="hidden" class="number_car" name="my_timelist[times][]" value="0">
</td> 
 
<td >
    <input type="text"   class="car_color"     >
    <input type="hidden" class="number_car" name="my_timelist[times][]" value="0">
</td> 

<td >
    <input type="text"   class="car_color"     >
    <input type="hidden" class="number_car" name="my_timelist[times][]" value="0">
 </td> 
 
.
.
.

I want set value on input with class name class="number_car" by jquery with below code, But this effect on all inputs(have the class name). But I want effect value just on same td.

` $(‘.car_color’).change(function(){

    let datetime    = $(this).val();

   $('.number_car').val( 123456);
}); 

`
How can I fix?

How to make Vue only change browser link but not refresh all browser

I used to run Vue “inside” Laravel project by writing .js, .vue files in resources/js folder of a Laravel project.
When I run website, browser (Chrome) did not refresh when clicking any link.

But when I split that project into Laravel and Vue seperately (with same packages) as follow:

project
|___backend
|___frontend

The browser refresh every time I click any link.

Browser refresing

Additionally, website’s performance is down. It takes more time to load.

How can i Duplicate a slide using office js?

I am trying to develop a powerpoint add-in using officejs and it seems the simplest of the things, duplicating a slide, is not available. Anyone faced this issue before and has found a workaround it ?

I have tried to add a new slide and copy all the shapes of the slide I want to copy. But it is not working. Also, when should we use .load() function and for what items ??

Thank you for your help.