What does “avoid imports of package:package_name/src/” mean in the docs

In the dart documentation it says

For the best performance when developing with the development
JavaScript compiler through webdev serve, put implementation files
under /lib/src, instead of elsewhere under /lib. Also, avoid imports
of package:package_name/src/….

With the “Also, avoid imports of package:package_name/src/….” do they mean other packages? Or do they also mean avoid doing that inside your own package? So do they mean use relative imports with that? Or are they simply referring to the fact that other packages have their src folder reserved for private implementation code which should not be imported. Or both?

Hungarian words in an array sort with JavaScript

Sorting words(Hungarian words with Hungarian accents) in an array.

How to reach the following sort order: [ 'ab', 'abbb', 'áb' ]
From the following source: ['áb', 'ab', 'abbb'] with sort in JavaScript?

Which is the best so simplest and shortest way of that than the following code?

const hunCharsOrder = 'aábcdeéfggyhiíjklmnoóöőpqrsttyuúüűvwxyz';
const order = new Map([... hunCharsOrder].map((c, i) => [c, i + 1]));

const comparator = (a, b) => {
    const minLength = a.length < b.length ? a.length : b.length;

    for (let i = 0; i < minLength; i++) {
        const diff = (order.get(a[i]) || 0) - (order.get(b[i]) || 0);
        if (diff !== 0) return diff;
    }
    return a.length - b.length;
};

Which one should I choose Next or Remix? [closed]

I am a React developer and now I want to select a framework that is best for SSR and CSR.

I hear that Next.js may cause issues when upgrading, and that its app router is not the fastest. I also hear that Remix is faster than Next.js in terms of loading and processing.

I am confused. I need to focus on SEO, UX, UI, code splitting, and other aspects.

I have watched many YouTube videos and read comments, but I am still confused about which one to choose.

Tampermonkey: This script was not executed yet

I have a tampermonkey script that doesn’t fire on a page it should. I click on the tampermonkey extension icon in the browser frame and I see my script (so the URL match is right). I mouse over that and see:

This script was not executed yet

I’ve tried uninstalling/reinstalling the extension in Chrome along with restarting Chrome (per the FAQ).

Any ideas on troubleshooting this? Could it be that onload never fires? Is this a known issue?

Further, sometimes the script doesn’t show up in the menu, as though the URL didn’t match.

Tampermonkey v5.3.2 on Chrome 131.0.6778.86 64-bit.

Firebase RTDB Completion Callback Not Catching Errors

I am missing something in what the completion callback actually captures, as far as errors are concerned. When I pass bad data to the update call, it simply errors out and stops processing.

export async function set (seller) {
    const updates = {};
    
    updates[ `sellers/12345/name-first` ] = seller.firstName;

    // I have tried this both as async/await and with then/catch
    return await database.ref().set(updates, error => { return error; });
};

This will produce the error Error: update failed: value argument contains an invalid key (sellers/12345/name-first) as one would expect, but my function does not return. It stops processing as it would on any unhandled error. According to the documentation, this is how to set it up, but it seems to ignore it. I have even tried putting it in a try-catch block. I have tried invalid keys and undefined data, but neither will let the update function return as expected. Good data returns as expected.

If the completion callback cannot catch invalid keys or undefined data, what kind of errors will it catch? More importantly, if the try-catch won’t even catch the errors, then how can they be handled? This is why I have got to be missing something, IMHO.

I am running express 4.21, Node 22.11.0, and firebase-admin 13.0.1.

Cache Storage vs IndexDB for short lived data

I need to handle a 500MB file upload where the user may be redirected to a login page and later return to resume the upload. To store the file temporarily, options like IndexedDB or CacheStorage seem viable, but they may have limitations with large files and short-lived data. The FileSystemAccess API was considered but isn’t widely supported across browsers. What is the best solution for this use case?”

Which is better in terms of speed and security for temporarily storing a 500MB file: IndexedDB or CacheStorage?

Service worker not triggering visible notification

I am testing a new integration with push notifications, and I get the correct console.logs, but in the end, there is no browser notification showing up.

This is my service worker:

self.addEventListener("install", (event) => {
  console.log("Service Worker installing");
  // Skip waiting to immediately activate the service worker
  self.skipWaiting();
});

self.addEventListener("activate", (event) => {
  console.log("Service Worker activated");
});
self.addEventListener("push", function (event) {
  console.log("here");
  if (event.data) {
    console.log("Push event!! ", JSON.parse(event.data.text()));
    showLocalNotification(
      "Notification ",
      JSON.parse(event.data.text()),
      self.registration
    );
  } else {
    console.log("Push event but no data");
  }
});

const showLocalNotification = (title, data, swRegistration) => {
  console.log("server contacted me for notification");
  swRegistration.showNotification(title, data);
};

I have vapid keys, I use NodeJS with express, and the REST POST endpoint is correctly subscribing to, storing and retrieving a subscription for use, and sending it to the client. So I am correctly installing, activating but not actually displaying, the notification. It logs “server contacted me for notification”

How to access the .textContent of a textarea INSIDE a dialog tag

Goal: I want to display a dialog box, with a textarea in it, that my user can enter text into, then click “Save” and the text in the textarea element will be programmatically sent to my server. I can get this to work only if the textarea is in the main body of the document. But, if the textarea is in a dialog tag, it can be located using .querySelector, but the text inside cannot be obtained by .textContent. … it’s always blank.

Question: How can I obtain the text contents of a textarea in a dialog element?

<dialog class="dlg" id="div_dialog" style="padding:10px 10px 10px 
10px; background-color: #F9F9F9;">    
  <!-- Dialog Contents -->
</dialog>    



function addDashComment(pst_rid) {
  var log = document.getElementById('div_comment_log');
  alert('log: ' + log);
  var txa = div_dlg.querySelector('textarea');
  alert('txa: ' + txa);  /*  Found the textarea ok! */
  var cmn = txa.textContent;  /* Shows nothing! */
  alert('cmn: ' + cmn);

Best approach for dynamically controlling CSS animations with JavaScript (start, pause, reverse)?

I’m currently working on a project where I need to control CSS animations dynamically using JavaScript based on user interactions. I have a few elements with animations applied via CSS, and I want to be able to:

Start the animation when the user clicks a button or performs some other action.
Pause the animation when the user clicks again or interacts with other parts of the page.
Reverse the animation when the user hovers over the element or triggers a different event.

I’ve used the animation-play-state property to pause and resume animations based on user interaction. For example, I tried setting animation-play-state: paused when a user clicks a button and animation-play-state: running when they click again to resume the animation. To reverse the animation, I’ve used animation-direction: reverse when the user hovers over an element.

What I expected:

I expected to be able to start, pause, and reverse the animations smoothly based on user interactions, without restarting the animation from the beginning each time. The animations should continue from where they left off when resumed, and reverse seamlessly on hover or other events.

How to change icon when collapse/expand a div?

I have the following in a razor component:

@{
    var id = $"collapseNotes{itemId}";
    var href = $"#{id}";

    <div>
        <i class="fas fa-angle-right"></i>
        <a data-toggle="collapse" href="@(href)" role="link" aria-expanded="false" aria-controls="@(id)">
            More info
        </a>
        <div class="collapse pl-3 pr-3" id="@(id)">
            <p>long text...</p>
        </div>       
    </div>
}

Collapsing and expanding is working fine.

However, I would like to change the icon on expanding and then back to the original state when collapsed.

Is it easily achievable just by using css or is js necessary? Either way, what is the best practice implementation?

antd: Upload `value` is not a valid prop, do you mean `fileList`? Error Component Stack

I have to use uplaod in ant design but in the browser console there is an error in the next.js app.

enter image description here

This is my form submission code.

"use client";
import {
  Form,
  Upload,
  Input,
  Select,
  Typography,
  Image,
  Button,
  message,
  Row,
  Col,
  Divider,
  Spin,
} from "antd";
import TextArea from "antd/es/input/TextArea";
import React, { useEffect, useState } from "react";
import { InboxOutlined, PlusOutlined, ProductFilled } from "@ant-design/icons";
import SupplierPageTitle from "@/components/supplier/SupplierPageTitle.js";
import useAuthGuard from "@/utils/useAuthGuard.js";
import { AddNewProduct } from "@/services/productService.js";
import { fetchProductCategories } from "@/services/productCategoryService.js";
import SupplierPageContainer from "@/components/supplier/SupplierPageContainer";
import useNotification from "@/utils/useNotification";
import { LoadingOutlined } from "@ant-design/icons";
import "./styles.css";

const { Title } = Typography;

const getBase64 = (file) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });

const AddProduct = () => {
  const [previewOpen, setPreviewOpen] = useState(false);
  const [categories, setCategories] = useState([]);
  const [previewImage, setPreviewImage] = useState("");
  const [fileList, setFileList] = useState([]);
  const [videoFile, setVideoFile] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [loading, setLoading] = useState(false);
  const { openNotification, contextHolder } = useNotification();
  const [form] = Form.useForm();

  const { user } = useAuthGuard({ middleware: "auth" });

  const handlePreview = async (file) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }
    setPreviewImage(file.url || file.preview);
    setPreviewOpen(true);
  };

  const handleImageChange = ({ fileList: newFileList }) => {
    if (newFileList.length > 6) {
      openNotification("error", "Error", "You can only upload up to 6 images!");
    } else {
      setFileList(newFileList);
    }
  };

  const onFinish = async (values) => {
    try {
      if (!fileList || fileList.length !== 6) {
        openNotification("error", "Error", "Please upload at least 6 images.");
        return;
      }

      const seoTagsArray = values.seoTags
        ?.split(",")
        .map((tag) => tag.trim())
        .filter((tag) => tag !== "");

      if (!seoTagsArray || seoTagsArray.length === 0) {
        openNotification(
          "error",
          "Error",
          "Please provide valid SEO tags as comma-separated values."
        );
        return;
      }

      const formData = new FormData();

      fileList.forEach((file, index) => {
        formData.append("images", file.originFileObj, `image${index}.jpg`);
      });

      if (videoFile) {
        formData.append("videoFile", videoFile);
      }

      formData.append("productName", values.productName);
      formData.append("description", values.description);
      formData.append("stockQuantity", values.stockQuantity);
      formData.append("wholesalePrice", values.WholePrice);
      formData.append("retailPrice", values.RetailPrice);
      formData.append("seoTags", JSON.stringify(seoTagsArray));
      formData.append("supplier", user?.id);
      formData.append("category", values.productCategory);

      setLoading(true);
      await AddNewProduct(formData);
      openNotification("success", "Success", "Product added Successfully");
      form.resetFields();
      setFileList([]);
    } catch (error) {
      console.error("Error uploading product:", error);
      openNotification(
        "error",
        "Error",
        "An unexpected error occurred while uploading product"
      );
    } finally {
      setLoading(false);
    }
  };

  const fetchCategories = async () => {
    try {
      const result = await fetchProductCategories();
      setCategories(result);
    } catch (error) {
      console.error("Error fetching categories:", error);
      openNotification("error", "Error", "Failed to fetch categories.");
    }
  };

  useEffect(() => {
    fetchCategories();
  }, []);

  const uploadButton = (
    <button
      style={{
        border: 0,
        background: "none",
      }}
      type="button"
    >
      <PlusOutlined />
      <div
        style={{
          marginTop: 8,
        }}
      >
        Upload
      </div>
    </button>
  );

  return (
    <>
      {contextHolder}

      <Row gutter={[16, 16]} justify="start">
        <Col xs={24} sm={12} md={12} lg={12} xl={12}>
          <SupplierPageTitle
            icon={<ProductFilled />}
            pageTitle="Add new Product"
          />
        </Col>

        <Col span={24}>
          <Divider />
        </Col>
      </Row>
      <SupplierPageContainer
        childern={
          <Row gutter={[16, 16]} justify="start">
            <Col span={24} style={{ position: "relative" }}>
              <Spin
                spinning={loading}
                indicator={
                  <LoadingOutlined
                    style={{
                      fontSize: 48,
                    }}
                    spin
                  />
                }
                style={{
                  position: "absolute",
                  top: "40%",
                }}
                size="large"
              >
                <div className={loading ? "blur-effect" : ""}>
                  <Form
                    form={form}
                    labelCol={{ span: 8 }}
                    wrapperCol={{ span: 16 }}
                    layout="horizontal"
                    style={{ maxWidth: 1000 }}
                    onFinish={onFinish}
                  >
                    <Form.Item
                      label="Product Name"
                      name="productName"
                      rules={[
                        {
                          required: true,
                          message: "Please input product name!",
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                    <Form.Item
                      label="Description"
                      name="description"
                      rules={[
                        { required: true, message: "Please fill description!" },
                      ]}
                    >
                      <TextArea rows={4} />
                    </Form.Item>
                    <Form.Item
                      label="Stock Quantity"
                      name="stockQuantity"
                      rules={[
                        {
                          required: true,
                          message: "Please input stock quantity!",
                        },
                        {
                          validator: (_, value) => {
                            if (!value) {
                              return Promise.reject(
                                new Error("Stock quantity is required.")
                              );
                            }
                            if (!/^d+$/.test(value)) {
                              return Promise.reject(
                                new Error(
                                  "Stock quantity must be a valid integer."
                                )
                              );
                            }
                            return Promise.resolve();
                          },
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                    <Form.Item
                      label="Whole Sale Price"
                      name="WholePrice"
                      rules={[
                        { required: true, message: "Please input price!" },
                        {
                          validator: (_, value) => {
                            if (!value) {
                              return Promise.reject(
                                new Error("Wholesale price is required.")
                              );
                            }
                            if (!/^d+(.d{1,2})?$/.test(value)) {
                              return Promise.reject(
                                new Error(
                                  "Wholesale price must be a valid float (e.g., 100.00, 999.99)."
                                )
                              );
                            }
                            return Promise.resolve();
                          },
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                    <Form.Item
                      label="Retail Price"
                      name="RetailPrice"
                      rules={[
                        {
                          required: true,
                          message: "Please input retail price!",
                        },
                        {
                          validator: (_, value) => {
                            if (!value) {
                              return Promise.reject(
                                new Error("Retail price is required.")
                              );
                            }
                            if (!/^d+(.d{1,2})?$/.test(value)) {
                              return Promise.reject(
                                new Error(
                                  "Retail price must be a valid float (e.g., 100.00, 999.99)."
                                )
                              );
                            }
                            return Promise.resolve();
                          },
                        },
                      ]}
                    >
                      <Input />
                    </Form.Item>
                    <Form.Item
                      label="Product Category"
                      name="productCategory"
                      rules={[
                        { required: true, message: "Please select category!" },
                      ]}
                    >
                      <Select
                        showSearch
                        placeholder="Search to Select"
                        optionFilterProp="label"
                        filterSort={(optionA, optionB) =>
                          (optionA?.label ?? "")
                            .toLowerCase()
                            .localeCompare((optionB?.label ?? "").toLowerCase())
                        }
                        options={categories.map((category) => ({
                          value: category.categoryId,
                          label: category.categoryName,
                        }))}
                      />
                    </Form.Item>
                    <Form.Item
                      label="SEO Tags"
                      name="seoTags"
                      rules={[
                        { required: true },
                        {
                          validator: (_, value) => {
                            if (!value || value.trim() === "") {
                              return Promise.reject(
                                new Error("SEO tags cannot be empty.")
                              );
                            }

                            const seoTagsArray = value
                              .split(",")
                              .map((tag) => tag.trim())
                              .filter((tag) => tag !== "");

                            if (seoTagsArray.length === 0) {
                              return Promise.reject(
                                new Error(
                                  "Please provide at least one valid tag."
                                )
                              );
                            }

                            return Promise.resolve();
                          },
                        },
                      ]}
                    >
                      <TextArea
                        rows={4}
                        placeholder="Add SEO tags as comma-separated values. eg: tag1, tag2, tag3"
                      />
                    </Form.Item>
                    <Form.Item label="Product Images" name="images">
                      <div>
                        <Upload
                          listType="picture-card"
                          fileList={fileList}
                          onPreview={handlePreview}
                          onChange={handleImageChange}
                          beforeUpload={(file) => {
                            const isJpgOrJpeg =
                              file.type === "image/jpeg" ||
                              file.type === "image/jpg" ||
                              file.type === "image/png";
                            const isLt2M = file.size / 1024 / 1024 < 2;

                            if (!isJpgOrJpeg) {
                              message.error(
                                "Only JPG/JPEG/PNG images are allowed!"
                              );
                              return Upload.LIST_IGNORE;
                            }

                            if (!isLt2M) {
                              message.error("Image must be smaller than 2MB!");
                              return Upload.LIST_IGNORE;
                            }

                            return true;
                          }}
                        >
                          {fileList.length < 6 ? uploadButton : null}
                        </Upload>
                        {previewImage && (
                          <Image
                            wrapperStyle={{ display: "none" }}
                            preview={{
                              visible: previewOpen,
                              onVisibleChange: (visible) =>
                                setPreviewOpen(visible),
                              afterOpenChange: (visible) =>
                                !visible && setPreviewImage(""),
                            }}
                            alt="gmart.com"
                            src={previewImage}
                          />
                        )}
                      </div>
                    </Form.Item>

                    <Form.Item label="Product Video" name="video">
                      <Upload.Dragger
                        name="file"
                        beforeUpload={(file) => {
                          const isMp4 = file.type === "video/mp4";
                          if (!isMp4) {
                            message.error("You can only upload MP4 files!");
                            return Upload.LIST_IGNORE;
                          }
                          const isLt20MB = file.size / 1024 / 1024 < 20;
                          if (!isLt20MB) {
                            message.error("Video must be smaller than 20MB!");
                            return Upload.LIST_IGNORE;
                          }
                          setVideoFile(file);
                          return false;
                        }}
                        maxCount={1}
                      >
                        <p className="ant-upload-drag-icon">
                          <InboxOutlined />
                        </p>
                        <p className="ant-upload-text">
                          Click or drag video file to this area to upload
                        </p>
                      </Upload.Dragger>
                    </Form.Item>
                    <Form.Item
                      style={{ display: "flex", justifyContent: "flex-end" }}
                    >
                      <Button
                        type="primary"
                        htmlType="submit"
                        loading={uploading}
                        style={{ width: 150 }}
                      >
                        {uploading ? "Uploading..." : "Add Product"}
                      </Button>
                    </Form.Item>
                  </Form>
                </div>
              </Spin>
            </Col>
          </Row>
        }
      />
    </>
  );
};

export default AddProduct;

This is the image file list uplaod section in the code.

<Form.Item label="Product Images" name="images">
                      <div>
                        <Upload
                          listType="picture-card"
                          fileList={fileList}
                          onPreview={handlePreview}
                          onChange={handleImageChange}
                          beforeUpload={(file) => {
                            const isJpgOrJpeg =
                              file.type === "image/jpeg" ||
                              file.type === "image/jpg" ||
                              file.type === "image/png";
                            const isLt2M = file.size / 1024 / 1024 < 2;

                            if (!isJpgOrJpeg) {
                              message.error(
                                "Only JPG/JPEG/PNG images are allowed!"
                              );
                              return Upload.LIST_IGNORE;
                            }

                            if (!isLt2M) {
                              message.error("Image must be smaller than 2MB!");
                              return Upload.LIST_IGNORE;
                            }

                            return true;
                          }}
                        >
                          {fileList.length < 6 ? uploadButton : null}
                        </Upload>
                        {previewImage && (
                          <Image
                            wrapperStyle={{ display: "none" }}
                            preview={{
                              visible: previewOpen,
                              onVisibleChange: (visible) =>
                                setPreviewOpen(visible),
                              afterOpenChange: (visible) =>
                                !visible && setPreviewImage(""),
                            }}
                            alt="gmart.com"
                            src={previewImage}
                          />
                        )}
                      </div>
                    </Form.Item>

How to debug this type of error. I followed the ant design documentation also but I didn’t got any clue. Guid me to how to solve this issue step by step

Windows cutoff bug on bottom of screen that is not visible on Macs

I’ve seen a bug that is present on Windows that isn’t there on Macs. There is a cutoff at the bottom of the page that cuts off all elements, including the chart, legend, and bar chart.

In the chart, you can see those bottom two rows, the data isn’t being displayed, but for some reason, the MUI chart borders still are.

In the bar chart/legend, you can clearly see the X-axis is not visible, nor is the data in the legend (weirdly enough, the border of the legend is still visible).

When the user resizes their viewport in any direction, the data becomes visible again and the bug is fixed. This isn’t a media-query thing, because the user could shrink or expand the window and the bug resolves itself.

I don’t own a PC so this bug is really difficult to check and resolve.

The chart is done with Recharts.js, and is finicky, so I needed to put some unusual vertical sizing on the parent element to get the children (bar chart, chart, and legend) to scroll. Notably:

max-height: calc(100vh - 60px);

Removing this fixes the bug, but prevents any scrolling of the elements (hence why I included this). This calculation was the only way to be able to view/scroll the entire page.

chart with cutoff visible at the bottom. no data is displayed, but the chart borders are still there

(separation two screenshots to make things more clear)

bar chart and legend with cutoff visible at the bottom

I’m trying to download file like pdf, csv which are store in s3 bucket. Downloading of this media is not working after deployment on amplify

When i’m adding the bucket link in anchor tag it showing access denied on deployment while getting downloaded locally. project is build on next 14

I have also update the rewrite and redirect in app setting project still not working
</^[^.]+$|.(?!(pdf|csv|css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/> into /index.html

Redis error in restify server (azure webapp)

I’m having this error using restify and redis on Azure:

redis Application has thrown an uncaught exception and its terminated Error read ECONNRESET at TCP.onStreamRead(node:internal/stream_base_commons)

I have this mini web app made with restify, which expose just three endpoints. Those endpoints will get the redis client and then proceed doing stuffs.. this is how I create the server:

const corsMiddleware = require("restify-cors-middleware2");

const cors = corsMiddleware({
  origins: ["*"],
  allowHeaders: ["*"],
  exposeHeaders: ["*"],
});

const serverApiKey = process.env.API_KEY;
if (!serverApiKey) {
  console.log("API_KEY not set");
  process.exit(1);
}

const alignRedisApiKey = process.env.ALIGN_REDIS_API_KEY;

// Create HTTP server.
const server = restify.createServer();

server.pre(cors.preflight);
server.use(cors.actual);

server.use(restify.plugins.bodyParser());
const port = process.env.PORT ?? 3978;
server.listen(port, () => {
  console.log(`nApp Started, ${server.name} listening to ${server.url}`);
});

Those instead, are the redis methods:

// Get the Redis client to interact with the cache using host name and access key
const getRedisClient = () => {
  const redis = require("redis");

  // Environment variables for cache
  const cacheHostName = process.env.REDIS_HOST_NAME;
  const cachePassword = process.env.REDIS_ACCESS_KEY;

  if (!cacheHostName || !cachePassword) {
    console.log("Cache configuration not found");
    return null;
  }

  return redis.createClient({
    // redis for TLS
    url: `redis://${cacheHostName}:6380`,
    password: cachePassword,
  });
};

// Retrieve member from Redis cache from its email
export async function getMemberFromRedis(email: string) {
  if (!email) return null;

  const cacheConnection = getRedisClient();
  if (!cacheConnection) return null;

  try {
    await cacheConnection.connect();
    const member = await cacheConnection.get(email);
    cacheConnection.disconnect();

    return JSON.parse(member);
  } catch (ex) {
    console.error(ex);
    cacheConnection.disconnect();

    return null;
  }
}

What am I doing wrong? I think it’s crashing (and I see the console error on Azure) when it tries to connect to Redis.. Assuming that Redis is working (we tested it, pinged and it works), am I doing something wrong connecting to redis in my syntax? is there another way to connect other than TCP? are there alternative ways to connect?