Can setting innerText then copying innerHTML avoid XSS attacks?

I’m using library that creates certain HTML elements but only lets me set their innerHTML (not innerText) so I want to mitigate XSS attacks.

If I put untrusted text into a temporary element using innerText, then copy that element’s innerHTML into the innerHTML of a new element, is the new element vulnerable to XSS attacks?

For example, could newElement below be a vulnerable entry point for a script?

function libraryCodeToCreateElement(text) {
    const newElement = document.createElement('p');
    newElement.innerHTML = text;
    document.body.appendChild(newElement);
}

const untrustedText = 'some malicious string';
const sanitizingElement = document.createElement('span');
sanitizingElement.innerText = untrustedText;
libraryCodeToCreateElement(sanitizingElement.innerHTML);

This seems to protect against attacks I can come up with, but I could be missing something.

Property ‘children’ does not exist on type ‘AvatarFallbackProps’

I’m using Chakra UI with Ark (or @chakra-ui/react components like Avatar.Root, Avatar.Fallback, etc.) in a Next.js TypeScript project.I’m building a custom Avatar component using Chakra UI with Ark-style subcomponents like Avatar.Root, Avatar.Fallback, Avatar.Image, etc., in a Next.js + TypeScript project.

I created a custom AvatarFallback component using React.forwardRef, and inside it, I’m trying to access props.children. However, TypeScript throws the following error:

Type ‘{ children: string | number | bigint | true | Iterable<ReactNode> | Promise<AwaitedReactNode> | Element; ref: ForwardedRef<HTMLDivElement>; }’ is not assignable to type ‘IntrinsicAttributes & AvatarFallbackProps & RefAttributes<HTMLDivElement>’.

Property ‘children’ does not exist on type ‘IntrinsicAttributes & AvatarFallbackProps & RefAttributes<HTMLDivElement>

'use client'

import type { GroupProps, SlotRecipeProps } from '@chakra-ui/react'
import { Avatar as ChakraAvatar, Group } from '@chakra-ui/react'
import * as React from 'react'

type ImageProps = React.ImgHTMLAttributes<HTMLImageElement>

export interface AvatarProps extends ChakraAvatar.RootProps {
  name?: string
  src?: string
  srcSet?: string
  loading?: ImageProps['loading']
  icon?: React.ReactElement
  fallback?: React.ReactNode
}
export const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(function Avatar(props, ref) {
  const { name, src, srcSet, loading, icon, fallback, children, ...rest } = props
  return (
    <ChakraAvatar.Root ref={ref} {...rest}>
      <AvatarFallback name={name} icon={icon}>
        {fallback}
      </AvatarFallback>
      {/* Pass only the correct string values here */}
      <ChakraAvatar.Image
        src={typeof src === 'string' ? src : undefined}
        srcSet={typeof srcSet === 'string' ? srcSet : undefined}
        loading={loading}
        layout="fill"
        alt={name}
      />
      {children}
    </ChakraAvatar.Root>
  )
})

interface AvatarFallbackProps extends ChakraAvatar.FallbackProps {
  name?: string
  icon?: React.ReactElement
  children?: React.ReactNode
}

const AvatarFallback = React.forwardRef<HTMLDivElement, AvatarFallbackProps>(
  function AvatarFallback(props, ref) {
    const { name, icon, children, ...rest } = props
    let fallbackContent = null
    if (children) {
      fallbackContent = children
    } else if (name != null) {
      fallbackContent = <>{getInitials(name)}</>
    } else {
      fallbackContent = <ChakraAvatar.Icon asChild={!!icon}>{icon}</ChakraAvatar.Icon>
    }
    return (
      <ChakraAvatar.Fallback ref={ref} {...rest}>
        {fallbackContent}
      </ChakraAvatar.Fallback>
    )
  }
)

function getInitials(name: string) {
  const names = name.trim().split(' ')
  const firstName = names[0] != null ? names[0] : ''
  const lastName = names.length > 1 ? names[names.length - 1] : ''
  return firstName && lastName ? `${firstName.charAt(0)}${lastName.charAt(0)}` : firstName.charAt(0)
}

interface AvatarGroupProps extends GroupProps, SlotRecipeProps<'avatar'> {}

export const AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(function AvatarGroup(
  props,
  ref
) {
  const { size, variant, borderless, ...rest } = props
  return (
    <ChakraAvatar.PropsProvider value={{ size, variant, borderless }}>
      <Group gap="0" spaceX="-3" ref={ref} {...rest} />
    </ChakraAvatar.PropsProvider>
  )
})

This error is saying that the props you passed to include children, but your AvatarFallbackProps type does not define children — so TypeScript doesn’t allow it.

three js does not load model (Angular) (GLTF Loader)

I’m using an Angular 19 component to load a 3-D model of Earth and make it spin.
The only console message I see is
THREE.GLTFLoader: Unknown extension "KHR_materials_pbrSpecularGlossiness",
which doesn’t appear to stop the scene from rendering.
Has anyone run into this issue or know how to resolve it?
Thanks!

import { AfterViewInit, Component, OnInit } from '@angular/core';
import * as THREE from 'three';
import { DOCUMENT } from '@angular/common';
import { Directive, EventEmitter, HostListener, Inject, Input, Output } from '@angular/core';
import { ShowArticleComponent } from "../show-article/show-article.component";
import { OrbitControls } from 'three-orbitcontrols-ts';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

@Component({
  selector: 'app-world-spinning',
  imports: [],
  templateUrl: './world-spinning.component.html',
  styleUrl: './world-spinning.component.css'
})
export class WorldSpinningComponent implements OnInit, AfterViewInit {
  private doc: Document;
  
  // Three.js global variables
  private scene!: THREE.Scene;
  private camera!: THREE.PerspectiveCamera;
  private loader!: GLTFLoader;
  private loadedModel: any = null;
  private renderer!: THREE.WebGLRenderer;
  private topLight!: THREE.DirectionalLight;
  private topLight2!: THREE.DirectionalLight;
  private ambientLight!: THREE.AmbientLight;
  private controls!: OrbitControls;
  private startRotation: boolean = true;
  private canvas: any = null;

  constructor(@Inject(DOCUMENT) doc: any) {
    this.doc = doc;
  }

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    this.createThreeJsBox();
  }

  createThreeJsBox(): void {
    // Scene for animation + Camera

    this.canvas = this.doc.getElementById("canvas-box");

    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
    this.camera.position.set(100, 100, 400); // Position camera away from the model
    this.camera.lookAt(0, 0, 4); // Point camera to the origin

    // Loader
    this.loader = new GLTFLoader();

    // Render the model
    this.loader.load(
      `earth/scene.gltf`,
      (gltf) => {
        // Add to scene
        this.loadedModel = gltf.scene;
        this.scene.add(this.loadedModel);
      },
      (xhr) => {
        console.log((xhr.loaded / xhr.total * 100) + '% loaded');
      },
      (error) => {
        // In case of errors
        console.error(error);
      }
    );

    // Instantiate a new renderer and set its size
    this.renderer = new THREE.WebGLRenderer({ alpha: true }); // Alpha: true allows for the transparent background
    this.renderer.setSize(window.innerWidth, window.innerHeight);

    // Add the renderer to the DOM
    this.canvas.appendChild(this.renderer.domElement);

    // Add lights to the scene, so we can actually see the 3D model
    this.topLight = new THREE.DirectionalLight(0xffffff, 4); // (color, intensity)
    this.topLight.position.set(100, 100, 1000); // top-right-ish
    this.topLight.castShadow = true;
    this.scene.add(this.topLight);

    this.topLight2 = new THREE.DirectionalLight(0xffffff, 4); // (color, intensity)
    this.topLight2.position.set(500, 500, 500); // top-right-ish
    this.topLight2.castShadow = true;
    this.scene.add(this.topLight2);

    this.ambientLight = new THREE.AmbientLight(0x333333, 3);
    this.scene.add(this.ambientLight);

    this.renderer.render(this.scene, this.camera);

    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.minDistance = 0; // Prevent zooming too close
    this.controls.maxDistance = 1000; // Prevent zooming too far
    this.controls.update();

    // Animation Loop
    this.animate();

    // Resize Listener
    window.addEventListener("resize", () => {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    });
  }

  animate = (): void => {
    requestAnimationFrame(this.animate);
    
    if (this.loadedModel && this.startRotation) {
      this.loadedModel.rotation.y += 0.01; // Adjust speed as needed
    }
    
    this.controls.update();
    this.renderer.render(this.scene, this.camera);
  }
}

I have tried to change the camera position multiple times and also the camera.LookAt. I also put the gltf model in the public folder and it seems to be ok.

How to query a remote sqlserver? [closed]

in a Windows 11 pc (named : pcdata, ip : 10.20.30.40), i have installed sql server express, and created a database. I have published into this pc a web api for crud objects into the local IIS and named apiweb.com.

This service is created with ip 10.20.30.45 and ip port 5283. I can request this api remotely as apiweb.com:5283/api/product which gives me the list of the products.
So for memory : sqlserverexpress is : 10.20.30.40 and web api is apiweb.com:5283/api/product web api service with ip 10.20.30.45.
Now, from my dev PC, I want to create an aspnet core querying this web api with javascript.

my js file is :

'use strict'  
const uri = 'api/product';
let data = [];

function getItems() {
  
    fetch(uri)
            .then(response => response.json())
            .then(data => _displayItems(data))
        .catch(error => console.error('Unable to get items.', error));
}

The program uses the path descride in localsettings.json and concatene the uri located in my js file.

 "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5023",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },

My question is how to setup my aspnet core app to query the remote web api.

NextAuth v5 req.auth Undefined with `wrangler pages dev` on Cloudflare Pages, Works with `npm run dev`

I’m using NextAuth v5 with Next.js 15.3.2 for authentication with JWT strategy. Everything works as expected when running the app locally using:

npm run dev
The req.auth object in my middleware is properly populated after login, and auth.user contains the expected user information.

Problem:
When I run the app using:

wrangler pages dev
to emulate the Cloudflare Pages environment, I face this issue:

The authentication flow appears successful (cookies are set in the browser).

However, req.auth is undefined inside my Next.js middleware.ts.

Consequently, users are redirected to /login even after successful login.

My Middleware Example:

import { auth } from "@/auth";

export default auth((req) => {
  console.log("req.auth.user:", req.auth?.user);
  console.log("AUTH_SECRET:", process.env.AUTH_SECRET);

  if (!req.auth && req.nextUrl.pathname !== "/login") {
    return Response.redirect(new URL("/login", req.nextUrl));
  }
});

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

My NextAuth Config Snippet:

export const auth = NextAuth({
  providers: [/*...*/],
  secret: process.env.AUTH_SECRET,
  session: { strategy: 'jwt' },
  callbacks: {
    async authorized({ auth, request }) {
      console.log("auth.user:", auth?.user);
      console.log("AUTH_SECRET:", process.env.AUTH_SECRET);
      return !!auth?.user;
    },
  },
  experimental: {
    runtime: 'edge',
  },
});

What I’ve Verified:
Cookies like __Host-authjs.csrf-token, authjs.session-token, etc., are present in both environments.
process.env.AUTH_SECRET is defined and logged correctly in both environments.
In npm run dev, I see additional nextauth.message in localStorage, but unsure if that’s relevant.
Using JWT sessions, no database involved.
Login redirects appear to work, but req.auth stays undefined under wrangler pages dev.

Using latest versions: [email protected], NextAuth v5.

Question:
Why is req.auth undefined when running with wrangler pages dev, but working with npm run dev?
Is there additional NextAuth configuration required specifically for Cloudflare Pages or Workers runtime?

Is There a Simple Config to Export All Classes and Types in a Node Package?

I come from an OOP background, and having to add the export keyword to all my classes just to use them outside the file already felt odd, but whatever.

Now, setting up a monorepo, I have to repeat the nonsense twice—once in the class file, and again in index.ts to export everything. Here’s the repetitive mess:

// src/ClassA.ts
export class ClassA { /* ... */ }

// src/ClassB.ts
export class ClassB { /* ... */ }

// src/index.ts
export { ClassA } from './ClassA';
export { ClassB } from './ClassB';

And I also have to manually write the exports field in package.json:

{
  "exports": {
    ".": "./dist/index.js",
    "./ClassA": "./dist/ClassA.js"
  }
}

In Dart for example, code under lib/src is private while lib/ exposes public APIs. Is there any benefit to use `src` sub-folder inside `lib` folder

the library code lives under the lib directory and is public to other
packages. You can create any hierarchy under lib, as needed. By
convention, implementation code is placed under lib/src. Code under
lib/src is considered private;

Is there a similar folder-based configuration in Node/NPM/TypeScript to automatically export all public parts of a package? Or do I have to manually handle this with index.ts for each files? Any better solution for monorepos? Is there some single line config like exportAllModulesAndTypes: "/lib and hideAllModulesAndTypes: "/lib/src

Someone even made a VSCode Extension for it https://github.com/estruyf/vscode-typescript-exportallmodules but I refuse to believe that’s the only way.

How go through option in select?

how to go through option in select

I tried but I get an error here is the code:

       const valInput = modalBody.querySelector('#conditionValue');
    

        if (valInput ) {
            for (let i = 0; i < valInput.options.length; i++) {
                if (valInput.options[i]) {
                    const option = valInput.options[i];
                }
                option.className = option.value;
                const optionClass = option.className;
                const optionValue = option.value;

                console.log(` Class: : ${optionClass}`)
                console.log(` Value: : ${optionValue}`)
            }
        }

Expo-Managed React-Native for Web Drag & Drop “findDOMNode is deprecated” warning

I’m working on an Expo-managed React-Native for Web app and I’m trying to get some specific drag & drop functionality to work. I’ve tried a variety of changes to DraggableWord but everything I do either 1) creates the deprecation warning or 2) causes the DraggableWord to lose draggability (it simply acts like regular text).

I think the problem is inside DraggableWord but I’m not sure.

Here is a fully working, self-contained component script that should throw the warning when you test it.

import React, { useState, useEffect, useRef } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
import Animated, { useSharedValue, useAnimatedStyle, withSpring, withTiming, useAnimatedRef } from 'react-native-reanimated';

const theme = {
  colors: {
    primaryTwo: '#007bff',
    successTwo: '#28a745',
    error: '#dc3545',
    text: '#212529',
    textMuted: '#6c757d',
    grey: '#f8f9fa',
    border: '#dee2e6',
  },
};

const SentenceBlankAnimatedDropZone = ({ blankIndex, droppedWord, isCorrect, answer, hoverStates, onLayoutMeasured }) => {
  const viewRef = useRef(null);
  const isAttempted = droppedWord !== null;

  const animatedDropZoneStyle = useAnimatedStyle(() => {
    const isHovering = hoverStates.value[blankIndex] || false;
    return {
      borderColor: isHovering ? theme.colors.primaryTwo : (isAttempted ? (isCorrect ? theme.colors.successTwo : theme.colors.error) : theme.colors.text),
      borderWidth: isHovering ? 3 : 1,
    };
  });

  const handleLayout = () => {
    if (viewRef.current && typeof viewRef.current.getBoundingClientRect === 'function') {
      const rect = viewRef.current.getBoundingClientRect();
      onLayoutMeasured(blankIndex, {
        x: rect.left + window.scrollX,
        y: rect.top + window.scrollY,
        width: rect.width,
        height: rect.height,
      });
    }
  };

  const styles = StyleSheet.create({
    dropZone: { borderWidth: 1, borderRadius: 4, minWidth: 80, height: 40, justifyContent: 'center', alignItems: 'center', marginHorizontal: 5, paddingHorizontal: 8 },
    blankNumber: { color: theme.colors.textMuted, fontSize: 16 },
    droppedWordText: { fontSize: 22, color: theme.colors.text },
  });

  return (
    <Animated.View
      ref={viewRef}
      onLayout={handleLayout}
      style={[styles.dropZone, animatedDropZoneStyle]}
    >
      {isAttempted ? (<Text style={styles.droppedWordText}>{isCorrect ? droppedWord : answer}</Text>) : (<Text style={styles.blankNumber}>{blankIndex + 1}</Text>)}
    </Animated.View>
  );
};


const DraggableWord = ({ choice, answer, onDrop, dropZoneLayout, isAttempted, isCorrect, droppedWord, blankIndex, hoverStates }) => {
  const opacity = useSharedValue(1);
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);
  const animatedRef = useAnimatedRef();

  useEffect(() => { if (!isAttempted) { opacity.value = 1; } }, [isAttempted]);

  const panGesture = Gesture.Pan()
    .runOnJS(true)
    .enabled(!isAttempted)
    .onUpdate((event) => {
      translateX.value = event.translationX;
      translateY.value = event.translationY;

      let isHovering = false;
      if (dropZoneLayout) {
        isHovering = (
          event.absoluteX > dropZoneLayout.x && event.absoluteX < dropZoneLayout.x + dropZoneLayout.width &&
          event.absoluteY > dropZoneLayout.y && event.absoluteY < dropZoneLayout.y + dropZoneLayout.height
        );
      }
      hoverStates.value = { ...hoverStates.value, [blankIndex]: isHovering };
    })
    .onEnd((event) => {
      hoverStates.value = { ...hoverStates.value, [blankIndex]: false };

      const wordIsOverDropZone = dropZoneLayout && (
        event.absoluteX > dropZoneLayout.x && event.absoluteX < dropZoneLayout.x + dropZoneLayout.width &&
        event.absoluteY > dropZoneLayout.y && event.absoluteY < dropZoneLayout.y + dropZoneLayout.height
      );

      if (wordIsOverDropZone) {
        onDrop(blankIndex, choice);
        if (choice === answer) {
          opacity.value = withTiming(0, { duration: 200 });
        } else {
          translateX.value = withSpring(0);
          translateY.value = withSpring(0);
        }
      } else {
        translateX.value = withSpring(0);
        translateY.value = withSpring(0);
      }
    });

  const animatedStyle = useAnimatedStyle(() => {
    let backgroundColor = theme.colors.grey;
    if (isAttempted) {
      if (choice === answer) { backgroundColor = theme.colors.successTwo; }
      else if (choice === droppedWord && !isCorrect) { backgroundColor = theme.colors.error; }
    }
    return {
      transform: [{ translateX: translateX.value }, { translateY: translateY.value }],
      zIndex: translateX.value !== 0 || translateY.value !== 0 ? 100 : 1,
      opacity: opacity.value,
      backgroundColor,
      padding: 10,
      margin: 5,
      borderRadius: 8,
      borderWidth: 1,
      borderColor: theme.colors.border,
    };
  });

  const styles = StyleSheet.create({ wordText: { fontSize: 18, color: theme.colors.text } });

  // THIS WORKS BUT PRODUCES THE WARNING
  return (
    <GestureDetector gesture={panGesture}>
      <Animated.View ref={animatedRef} style={animatedStyle}>
        <Text style={styles.wordText}>{choice}</Text>
      </Animated.View>
    </GestureDetector>
  );
};


const WordBank = ({ blank, blankIndex, onDrop, dropZoneLayout, droppedWord, isCorrect, hoverStates }) => {
  const styles = StyleSheet.create({
    bankContainer: { alignItems: 'center', marginVertical: 10, padding: 10, borderWidth: 1, borderColor: theme.colors.border, borderRadius: 8, width: '100%' },
    bankTitle: { color: theme.colors.textMuted, fontSize: 16, marginBottom: 5 },
    wordsWrapper: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center' },
  });
  return (
    <View style={styles.bankContainer}>
      <Text style={styles.bankTitle}>Bank {blankIndex + 1}</Text>
      <View style={styles.wordsWrapper}>
        {blank.choices.map((choice) => (
          <DraggableWord
            key={choice} choice={choice} answer={blank.answer} onDrop={onDrop}
            dropZoneLayout={dropZoneLayout} isAttempted={droppedWord !== null}
            isCorrect={isCorrect} droppedWord={droppedWord} blankIndex={blankIndex}
            hoverStates={hoverStates}
          />
        ))}
      </View>
    </View>
  );
};


const CaseDragAndDrop = () => {
  const sentenceWithBlank = "The quick brown fox [BLANK] over the lazy dog.";
  const blanks = [
    {
      answer: "jumps",
      choices: ["runs", "sleeps", "jumps"],
    },
  ];
  const numBlanks = blanks.length;

  const [droppedWords, setDroppedWords] = useState(() => Array(numBlanks).fill(null));
  const [correctness, setCorrectness] = useState(() => Array(numBlanks).fill(null));
  const [dropZoneLayouts, setDropZoneLayouts] = useState({});
  const hoverStates = useSharedValue({});

  const handleDrop = (blankIndex, word) => {
    if (droppedWords[blankIndex]) return;
    setDroppedWords(prev => { const newWords = [...prev]; newWords[blankIndex] = word; return newWords; });
    setCorrectness(prev => { const newCorrectness = [...prev]; newCorrectness[blankIndex] = word === blanks[blankIndex].answer; return newCorrectness; });
  };

  const handleDropZoneLayout = (index, layout) => {
    if (JSON.stringify(dropZoneLayouts[index]) !== JSON.stringify(layout)) {
      setDropZoneLayouts(prev => ({ ...prev, [index]: layout }));
    }
  };

  const styles = StyleSheet.create({
    container: { flex: 1, alignItems: 'center', padding: 20, width: '100%', maxWidth: 700, alignSelf: 'center' },
    sentenceOuterContainer: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', alignItems: 'center', paddingHorizontal: 10, lineHeight: 50 },
    sentenceText: { fontSize: 22, color: theme.colors.text, marginHorizontal: 2, lineHeight: 40 },
    wordBanksContainer: { width: '100%', marginTop: 20 },
  });

  let blankCounter = 0;
  const renderedSentence = sentenceWithBlank.split(/([BLANK])/g).map((segment, index) => {
    if (segment === '[BLANK]') {
      const currentBlankIndex = blankCounter++;
      return (
        <SentenceBlankAnimatedDropZone
          key={`blank-${currentBlankIndex}`}
          blankIndex={currentBlankIndex}
          droppedWord={droppedWords[currentBlankIndex]}
          isCorrect={correctness[currentBlankIndex]}
          answer={blanks[currentBlankIndex].answer}
          hoverStates={hoverStates}
          onLayoutMeasured={handleDropZoneLayout}
        />
      );
    }
    return segment ? <Text style={styles.sentenceText} key={`text-${index}`}>{segment}</Text> : null;
  });

  return (
    <View style={styles.container}>
      <View style={{ height: 40 }} />
      <View style={styles.sentenceOuterContainer}>{renderedSentence}</View>
      <View style={{ height: 20 }} />
      <View style={styles.wordBanksContainer}>
        {blanks.map((blank, index) => (
          <WordBank
            key={`bank-${index}`} blank={blank} blankIndex={index} onDrop={handleDrop}
            dropZoneLayout={dropZoneLayouts[index]} droppedWord={droppedWords[index]}
            isCorrect={correctness[index]} hoverStates={hoverStates}
          />
        ))}
      </View>
    </View>
  );
};


export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <CaseDragAndDrop />
    </GestureHandlerRootView>
  );
}

Object.setPrototyeOf with ‘this’ as object’s new prototype

I noticed that I can access the properties of the function, ruter, returned by Ruter using ‘this’. My understanding of setPrototypeOf is that of inheritance. I don’t understand how the properties of the inner function get injected to the ‘this’?

function Ruter(options) {

  const opts = options || {};

  function ruter(req, res, next) {
    ruter.handler(req, res, next);
  }

  Object.setPrototypeOf(ruter, this);

  ruter.params = {};
  ruter.stack = [];
  ruter.store = {};
  ruter.iname = "Local Function";
  console.log(this);

  return ruter;

}

Ruter.prototype = function () {}

Ruter.prototype.param = function param(name, fn) {
    let params = this.params[name];
    console.log(this);
    if(!params) {
        params = this.params[name] = [];
    }

    params.push(fn);
    
    return this;
}

Ruter.prototype.handler = function handler(req, resp) {
    console.log("This is handler");
}


let ruter = new Ruter();
ruter.param("id", () => console.log("Way maker"));
console.log(ruter);
console.log(ruter.iname);
console.log(ruter.params)

Why does returning a Promise that I don’t want awaited from an async function await the promise?

I have an async function that returns a promise

async function paginate() {
  const recs = await db.selectFrom().execute()
  return db.selectFrom().select().where(recs.map(a => a.id))
}

I call await paginate()

but for some reason the function’s return value is being awaiting, but I don’t want to await it. Somehow, doing:

async function paginate() {
  const recs = await db.selectFrom().execute()
  return { builder: db.selectFrom().select().where(recs.map(a => a.id)) }
}

const builder = (await paginate()).builder

async function utilFunction(query) {
  return await query.select().execute()
}

utilFunction(builder)

works just fine! But I don’t like the unnecessary wrapping of the object.

For context:

I use Kysely. It has a .execute() function which actually performs the query. Currently, I omit the .execute() in favor of the utilFunction to run it. I believe what’s going on is that my query builder in it of itself is somehow a Promise because it emits a custom error from the library: don’t await SelectQueryBuilder instances directly. To execute the query you need to call execute or executeTakeFirst. at SelectQueryBuilderImpl.value

Can’t open fetched blob files in Firefox, on iOS only

In a react website, I’ve got the following code to open a blob file (PDF or a few image types) which I have fetched from the server after the user clicks a button.

const url = window.URL.createObjectURL(new Blob([blob], {type: blob.type}));
window.open(url);

My content security policy includes the following:

default-src 'self';
frame-src 'self' blob:;
img-src 'self' blob:;
object-src 'self' blob:;

With this code and configuration, my website works as intended on the latest versions of Chrome (Android & iOS), Safari (iOS), Edge (Android & iOS), and Firefox (Android) by opening a new tab with the blob contents. In some instances, I had to give permissions or unblock popups in settings, and that is to be expected.

For some reason, it simply doesn’t work on Firefox (iOS) even though I have unblocked popups. I have tested other websites on that browser and it seems to open new tabs just fine for them. For my website, it simply does nothing when I click the button. This behavior is similar to what I saw in Safari (iOS) before I unblocked popups there, but unblocking popups in Firefox (iOS) has not helped at all … a new tab is not opened when I click the button. I am hoping someone has seen this behavior and knows what is going on.

Looking for a Project Idea [closed]

I’m a computer engineer student. I’m looking for a project idea for this summer.
i do HTML/CSS , python, a little bit of java script and c++.
if u could help to to find a idea for a project i would love that. something not too hard to do but valuable.

please I’m so open for ideas.
since this community has a lot of potential, i would like your help.
thank you for your time.

FullCalendar: Optimize eventDidMount for “More Events” in Week View

Subject: FullCalendar: Optimize eventDidMount for “More Events” in Week View

I’m using FullCalendar with vanilla JavaScript. I’m utilizing the eventDidMount function to style events, specifically by adding images to them.

The problem arises when a user has a large number of events (e.g., 500 events in a weekly view). In this scenario, Chrome attempts to download all event images upfront, leading to significant RAM consumption and performance issues.

My goal is to optimize eventDidMount so that it only processes visible events initially. When the “+X more” button is clicked, I’d like the hidden events for that specific day to then have their images added. This approach should significantly improve performance.

I attempted to implement this by adding the following check at the beginning of my eventDidMount function:

if (info.el.closest('.fc-more-popover')) {
    return;
}

However, this only prevented images from being added to non-visible events. It didn’t trigger the image addition when the +X more button was clicked, because the eventDidMount function isn’t called again for those already-mounted-but-hidden events.

How can I modify my eventDidMount function or implement another strategy to achieve this lazy loading of event images when the +x more button is activated?