Unable to properly set zoom level on different devices via OpenLayers

I have tried everything and can’t seem to figure out how to properly set the zoom levels differently on map initialization and load for different devices. The goal is to have the “United States” be the boundaries, which is working perfectly on Macbook Pros w/ level 5 zoom, but it doesn’t work on other devices.

When I load the app, this is what I see:
On Load

This is what I would love to see:
Different map zoom-in size on different devices

I attempted to do something with calculateInitialZoom but it didn’t work.

I tried a few different methods and it didn’t work so I have reverted the code back to a working state and this is what I have:

<script setup>
import { ref, provide, reactive, computed } from 'vue';
import MapComponent from './components/organisms/map/MapComponent.vue';
import SearchPill from './components/molecules/forms/SearchPill.vue';
import LoadingSpinner from './components/atoms/feedback/LoadingSpinner.vue';
import Toast from './components/atoms/feedback/Toast.vue';
import { usePOIs, poiLoadingState } from './composables/usePOIs';
import { useToast } from './composables/useToast';
import RecentRoutes from './components/organisms/map/RecentRoutes.vue';

// Initialize toast system
const { showToast } = useToast();

// Create a reactive map state
const mapState = reactive({
  instance: null,
  center: [-95.7129, 37.0902],
  zoom: 5,
  layers: [],
  view: null,
  error: null
});

// Initialize POIs composable
const pois = usePOIs(mapState);

// Use the global loading state directly
const isLoading = computed(() => poiLoadingState.value);

// Function to calculate appropriate zoom level based on screen size
const calculateInitialZoom = () => {
  try {
    const width = window.innerWidth;
    const height = window.innerHeight;
    
    // Base zoom level for a standard screen (1920x1080)
    const baseZoom = 5;
    
    // Adjust zoom based on screen size
    // For larger screens, zoom out more
    // For smaller screens, zoom in more
    const widthFactor = Math.log2(width / 1920);
    const heightFactor = Math.log2(height / 1080);
    const averageFactor = (widthFactor + heightFactor) / 2;
    
    // Round to nearest integer and ensure it's between 3 and 7
    return Math.min(Math.max(Math.round(baseZoom - averageFactor), 3), 7);
  } catch (error) {
    showToast('Error calculating initial zoom level', 'error');
    return 5; // Fallback to default zoom
  }
};

// Update initial zoom based on screen size
mapState.zoom = calculateInitialZoom();

// Provide the map state to all components
provide('mapState', mapState);

// Reference to map component
const mapComponent = ref(null);
const searchPill = ref(null);

// Handle map initialization
const handleMapInit = (instance) => {
  try {
    console.log('Map initialized:', instance);
    mapState.instance = instance;
    mapState.layers = instance.getLayers().getArray();
    mapState.view = instance.getView();
    console.log('[handleMapInit]: Map initialized successfully.');
  } catch (error) {
    console.error('[handleMapInit]: Error initializing map:', error);
    mapState.error = error;
  }
};

// Handle route selection from RecentRoutes
const handleRouteSelect = (route) => {
  try {
    if (searchPill.value) {
      searchPill.value.handleRouteSelect(route);
      console.log('[handleRouteSelect]: Route selected successfully.');
    } else {
      console.log('[handleRouteSelect]: Search component not available.');
    }
  } catch (error) {
    console.error('[handleRouteSelect]: Error selecting route: ', error);
  }
};
</script>

<template>
  <!-- Root element with full viewport height and width -->
  <div class="min-h-screen w-full flex flex-col overflow-hidden">
    <!-- Main container with relative positioning for absolute children -->
    <div class="relative flex-1 w-full">
      <MapComponent 
        ref="mapComponent"
        :initial-center="mapState.center"
        :initial-zoom="mapState.zoom"
        @map-initialized="handleMapInit"
      />
      <SearchPill ref="searchPill" />
      <RecentRoutes @select-route="handleRouteSelect" />
      <LoadingSpinner :is-loading="isLoading" />
      <Toast />
    </div>
  </div>
</template>

All help is appreciated on some guidance forward.

Firebase functions V2: Package subpath ‘./database’ is not defined by “exports” in /workspace/node_modules/firebase-functions/package.json

I am trying to send notification to device when I receive message in chat in my app. At the moment I just want to read snapshot contents, but when trying to deploy, I am hit with an error: Package subpath ‘./database’ is not defined by “exports” in /workspace/node_modules/firebase-functions/.

I am using Node.js v20 in functions 1st gen.
Do you know how to fix this problem?

Thanks!

import { initializeApp } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";
import { getDatabase } from "firebase-admin/database";
import { getMessaging } from "firebase-admin/messaging";
import { log, warn } from "firebase-functions/logger";
import { onValueWritten } from "firebase-functions/v2/database";

initializeApp();
const auth = getAuth();
const db = getDatabase();
const messaging = getMessaging();

export const sendPushNotification = onValueWritten("/Chat/{id}", async (event) => {
    const snapshot = event.data.after.val();

    log("SNAP IS");
    log(snapshot);
});
Provided module can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './database' is not defined by "exports" in /workspace/node_modules/firebase-functions/package.json imported from /workspace/index.js
    at exportsNotFound (node:internal/modules/esm/resolve:322:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:670:9)
    at packageResolve (node:internal/modules/esm/resolve:856:14)
    at moduleResolve (node:internal/modules/esm/resolve:946:18)
    at defaultResolve (node:internal/modules/esm/resolve:1188:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:642:12)
    at #cachedDefaultResolve (node:internal/modules/esm/loader:591:25)
    at ModuleLoader.getModuleJobForRequire (node:internal/modules/esm/loader:347:53)
    at new ModuleJobSync (node:internal/modules/esm/module_job:333:34)
    at ModuleLoader.importSyncForRequire (node:internal/modules/esm/loader:320:11)

In JavaScript, Why Do Sorting Results Differ Based on Comparison Logic? [duplicate]

I am currently testing in Chrome and I have a question about the behavior of the comparison function.

const arr = [
  { isLeft: false, value: 5 },
  { isLeft: false, value: 18 },
  { isLeft: false, value: 3 },
  { isLeft: true, value: 10 },
  { isLeft: false, value: 8 },
];

const arr2 = [...arr].sort((a, b) => {
  if (b.isLeft) return 1;
  return a.value - b.value;
});

const arr3 = [...arr].sort((a, b) => {
  if (a.isLeft) return -1;
  return a.value - b.value;
});

console.log(arr2.map((v) => v.value)); // [3, 5, 10, 8, 18]
console.log(arr3.map((v) => v.value)); // [10, 3, 5, 8, 18]

In both arr2 and arr3, I am trying to ensure that values where isLeft is true are sorted to the left. However, they return different arrays. In arr2, it looks like the array is sorted by value, and only the item with isLeft: true is moved to the left. In arr3, it appears that the item with isLeft: true is moved all the way to the left, as I originally intended.

I expected arr2 and arr3 to give the same result, but I don’t understand why the results differ depending on whether I use if (b.isLeft) return 1; or if (a.isLeft) return -1;.

Shouldn’t the comparison function always maintain consistent behavior, regardless of whether a or b is passed in?

How can I implement an efficient undo/redo system for complex state changes in a React app without using external libraries?

I’m building a React application with a complex form editor where users can make multiple types of changes (e.g., add, delete, modify fields).

I want to implement an undo/redo feature to allow users to go backward and forward through their changes.

My questions:
• What is the best practice for tracking and applying undo/redo operations manually in React?
• Should I store full state snapshots, or just the diffs (changes) between states?

I’m looking for a clean, scalable approach without relying on third-party libraries like Redux Undo.

I tried saving the entire form state after each change, but it quickly became heavy and caused performance issues. I also considered tracking only the changes (diffs), but it became complicated to manage manually.

Why is my DELETE Blog API returning “Blog not found” when I try to delete a blog with a reference to a User?

I am working on a REST API where I am trying to delete a blog document from my MongoDB database. Everything works fine, and the blog is deleted when I don’t have a reference to a User in the blog document. However, when I add a reference to a User and try to delete the blog, I always get the response Blog not found.

blogController.js–

const { default: mongoose } = require("mongoose");
const blogModel = require("../models/blogModel");
const userModel = require("../models/userModel");

//get all blogs
exports.getAllBlogsController = async (req, res) => {
  try {
    const allblogs = await blogModel.find({});
    if (!allblogs) {
      return res.status(500).json({ message: "No blog is present" });
    }
    return res.status(200).json({ BlogCount: allblogs.length, allblogs });
  } catch (error) {
    return res.status(500).json({ message: "Server error", error });
  }
};

// Create blog
exports.createBlogController = async (req, res) => {
  try {
    const { title, description, image,user } = req.body;
    if (!title || !description || !image || !user) {
      return res.status(400).json({ message: "All fields are required" });
    }
    const existingUser= await userModel.findById(user)
    if(!existingUser){
      return res.status(404).json({"message":"Unable to find user"})
    }
    // we will use session of mongoose and then updatethe blog 

    const newBlog = new blogModel({ title, description, image,user });
    const session= await mongoose.startSession()
     session.startTransaction()
     await newBlog.save({session})
     existingUser.blogs.push(newBlog)
     await existingUser.save({session})
     await session.commitTransaction();
     session.endSession();
    return res.status(200).json({ message: "blog created", newBlog });
  } catch (error) {
    res.status(500).json({ message: "Server error", error });
  }
};

// update blog
exports.updatBlogController = async (req, res) => {
  try {
    const {id} = req.params;
    const { title, description, image } = req.body;
    const blog = await blogModel.findByIdAndUpdate(
      id,
      { ...req.body },
      { new: true }
    );
    return res.status(200).send({
      success: true,
      message: "Blog updated",
      blog,
    });
  } catch (error) {
    return res.status(500).json({ message: "Server error", error });
  }
};

// find specfic blog through id
exports.getBlogByIdController = async (req, res) => {
  try {
   const {id}= req.params
  const blog= await blogModel.findById(id);
  if(!blog){
   return res.status(500).json({"message":"No such kind of blog is present"})
  }
  return res.status(200).json({blog,"message":"fetched single blog"})


  } catch (error) {
    return res.status(500).json({ message: "Server error", error });
  }
};

// delete blog
exports.deleteBlogController = async (req, res) => {
  try {
    const { id } = req.params;

    // Validate if the provided ID is a valid ObjectId
    if (!mongoose.Types.ObjectId.isValid(id)) {
      return res.status(400).json({ message: "Invalid blog ID format" });
    }

    // Find the blog by ID and populate the user field
    const blog = await blogModel.findById(id).populate("user");

    // If no blog is found, return 404
    if (!blog) {
      return res.status(404).json({ message: "Blog not found" });
    }

    // Pull the blog's ObjectId from the user's blogs array
    if (blog.user && blog.user.blogs) {
      blog.user.blogs.pull(blog._id);
      await blog.user.save();
    } else {
      return res.status(400).json({ message: "User's blogs array not found" });
    }

    // Delete the blog from the blog collection
    await blogModel.findByIdAndDelete(id);

    // Successfully deleted the blog and updated the user
    return res.status(200).json({ message: "Blog deleted successfully" });

  } catch (error) {
    console.error(error); // Log for better debugging
    return res.status(500).json({ message: "Server error", error });
  }
};


blogModel.js —

const { default: mongoose } = require("mongoose");
const blogModel = require("../models/blogModel");
const userModel = require("../models/userModel");

//get all blogs
exports.getAllBlogsController = async (req, res) => {
  try {
    const allblogs = await blogModel.find({});
    if (!allblogs) {
      return res.status(500).json({ message: "No blog is present" });
    }
    return res.status(200).json({ BlogCount: allblogs.length, allblogs });
  } catch (error) {
    return res.status(500).json({ message: "Server error", error });
  }
};

// Create blog
exports.createBlogController = async (req, res) => {
  try {
    const { title, description, image,user } = req.body;
    if (!title || !description || !image || !user) {
      return res.status(400).json({ message: "All fields are required" });
    }
    const existingUser= await userModel.findById(user)
    if(!existingUser){
      return res.status(404).json({"message":"Unable to find user"})
    }
    // we will use session of mongoose and then updatethe blog 

    const newBlog = new blogModel({ title, description, image,user });
    const session= await mongoose.startSession()
     session.startTransaction()
     await newBlog.save({session})
     existingUser.blogs.push(newBlog)
     await existingUser.save({session})
     await session.commitTransaction();
     session.endSession();
    return res.status(200).json({ message: "blog created", newBlog });
  } catch (error) {
    res.status(500).json({ message: "Server error", error });
  }
};

// update blog
exports.updatBlogController = async (req, res) => {
  try {
    const {id} = req.params;
    const { title, description, image } = req.body;
    const blog = await blogModel.findByIdAndUpdate(
      id,
      { ...req.body },
      { new: true }
    );
    return res.status(200).send({
      success: true,
      message: "Blog updated",
      blog,
    });
  } catch (error) {
    return res.status(500).json({ message: "Server error", error });
  }
};

// find specfic blog through id
exports.getBlogByIdController = async (req, res) => {
  try {
   const {id}= req.params
  const blog= await blogModel.findById(id);
  if(!blog){
   return res.status(500).json({"message":"No such kind of blog is present"})
  }
  return res.status(200).json({blog,"message":"fetched single blog"})


  } catch (error) {
    return res.status(500).json({ message: "Server error", error });
  }
};

// delete blog
exports.deleteBlogController = async (req, res) => {
  try {
    const { id } = req.params;

    // Validate if the provided ID is a valid ObjectId
    if (!mongoose.Types.ObjectId.isValid(id)) {
      return res.status(400).json({ message: "Invalid blog ID format" });
    }

    // Find the blog by ID and populate the user field
    const blog = await blogModel.findById(id).populate("user");

    // If no blog is found, return 404
    if (!blog) {
      return res.status(404).json({ message: "Blog not found" });
    }

    // Pull the blog's ObjectId from the user's blogs array
    if (blog.user && blog.user.blogs) {
      blog.user.blogs.pull(blog._id);
      await blog.user.save();
    } else {
      return res.status(400).json({ message: "User's blogs array not found" });
    }

    // Delete the blog from the blog collection
    await blogModel.findByIdAndDelete(id);

    // Successfully deleted the blog and updated the user
    return res.status(200).json({ message: "Blog deleted successfully" });

  } catch (error) {
    console.error(error); // Log for better debugging
    return res.status(500).json({ message: "Server error", error });
  }
};


usermodel.js

const mongoose= require('mongoose')

const userSchema= new mongoose.Schema({
   username:{
      type:String,
      required:[true,'username is required']
   },
   email:{
      type:String,
      required:[true,'email is required'],
      unique:true
   },
   password:{
      type:String,
      required:[true,'password is required'],
      unique:true
   },
   blogs:[
      {
         type:mongoose.Types.ObjectId,
         ref: 'Blog',
         
      }
   ]
   
},{timestamps:true})

const userModel= mongoose.model('User',userSchema)
module.exports= userModel;

blogRoutes.js

//Delete blog
router.delete('/delete-blog/:id',deleteBlogController);

server.js —


//routes
app.use('/api/v1/user',userRoutes);
app.use('/api/v1/blog',blogRoutes);

enter image description hereenter image description here

Can I save some data to indexeddb when page is closed

Context

I understand that both events like pagehide and visibilitychange are less guaranteed to be fired, compared to unload and beforeunload, see: https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event
I want implement collection of troubleshooting data and how app features used (like, feature A activated via toolbar, then feature B via hotkey, than error happened) and than store it locally in indexeddb to give person who uses the app an option to include these logs into error report.

Problem

I need to remember prior usage events and other error details somewhere. And at some point I thought about using the localStorage for that. But as it is a “key-value” storage, it may be too much effort to store these events sequences per usage session sorted by event time.

What comes next to mind is indexedDb. But can I use it reliable within any of these events? :

  • pagehide
  • visibilitychange
  • beforeunload
  • unload

Fallback options

Due async nature of indexedDb I thought about using the localStorage instead as fallback, and thought about something like this: to store some limited sequence of events for current usage session, like 100 events max, in JSON, as array of arrays, with “row” array for these events saved in queue. if new event arrive and over 100 events queued already, next bunch stored in the another entry of localStorage having same prefix.
Like this:

{
   `_fancy_usage_log_{usage_id}`: { ep: 2 },
   `_fancy_usage_ep_{usage_id}_1`: [
      [...]
      [...]
      .....
      [...]
    ],
   `_fancy_usage_ep_{usage_id}_2`: [
      [...]
      [...]
      .....
      [...]
    ]

}

So, basically, should I use the localStorage or try use indexedDb for such usage events storage, in context of mentioned page lifecycle events such as visibilitychange, pagehide, beforeunload, and unload, if I don’t want update storage such as localStorage on every event, but save them once per minute or so, for sake of performance?

ActiveWin Only Counting VScode Tabs

I have created a code to track active time spent on websites and export it to a csv file called website_time_tracking.csv. When I ran it, it only gave the result of only tracking the amount of time spent on VScode, and when I switched to google, it didn’t track that time:

const activeWin = require('active-win');
const fs = require('fs');
const { createObjectCsvWriter } = require('csv-writer');

// Array to store usage records
const records = [];

// Setup CSV writer
const csvWriter = createObjectCsvWriter({
    path: 'activity_log.csv',
    header: [
        { id: 'start_time', title: 'Start Time' },
        { id: 'end_time', title: 'End Time' },
        { id: 'window_title', title: 'Window Title' },
        { id: 'app_name', title: 'App Name' },
        { id: 'duration_seconds', title: 'Duration (seconds)' }
    ]
});

// Track the previous active window
let previousApp = null;
let previousWindow = null;
let previousStartTime = null;

// Save the interval ID to clear later
const interval = setInterval(trackActiveWindow, 1000);

// Flag to prevent multiple saves
let isSaving = false;

// Function to check active window every second
async function trackActiveWindow() {
    try {
        const activeWindow = await activeWin();

        const now = new Date();

        if (!activeWindow) {
            // No active window detected (maybe locked screen?)
            if (previousApp && previousStartTime) {
                const durationSeconds = (now - previousStartTime) / 1000;

                records.push({
                    start_time: previousStartTime.toISOString(),
                    end_time: now.toISOString(),
                    window_title: previousWindow + ' (screen locked?)',
                    app_name: previousApp,
                    duration_seconds: durationSeconds.toFixed(2)
                });

                console.log(`Logged (locked screen): ${previousApp} - "${previousWindow}" for ${durationSeconds.toFixed(2)} seconds`);

                // Reset previous info
                previousApp = null;
                previousWindow = null;
                previousStartTime = null;
            }
            return;
        }

        const appName = activeWindow.owner.name;
        const windowTitle = activeWindow.title;

        // If we have a different window or app
        if (appName !== previousApp || windowTitle !== previousWindow) {
            // If we had a previous active window, log the duration
            if (previousApp && previousStartTime) {
                const durationSeconds = (now - previousStartTime) / 1000;

                records.push({
                    start_time: previousStartTime.toISOString(),
                    end_time: now.toISOString(),
                    window_title: previousWindow,
                    app_name: previousApp,
                    duration_seconds: durationSeconds.toFixed(2)
                });

                console.log(`Logged: ${previousApp} - "${previousWindow}" for ${durationSeconds.toFixed(2)} seconds`);
            }

            // Update to the new window
            previousApp = appName;
            previousWindow = windowTitle;
            previousStartTime = now;
        }
    } catch (err) {
        console.error('Error tracking window:', err);
    }
}

// Save to CSV when exiting
async function saveOnExit() {
    if (isSaving) return;
    isSaving = true;

    clearInterval(interval);
    await trackActiveWindow(); // Capture the latest window

    console.log('nSaving activity log...');

    try {
        if (records.length > 0) {
            await csvWriter.writeRecords(records);
            console.log('Activity log saved to activity_log.csv');
        } else {
            console.log('No activity recorded.');
        }
    } catch (err) {
        console.error('Error saving activity log:', err);
    } finally {
        process.exit();
    }
}

// Handle process exit
process.on('SIGINT', saveOnExit);
process.on('SIGTERM', saveOnExit);

I’ve tried switching to using the activeWIN, as shown above. But nothing’s worked, and I’m not sure why this is happening. So why is it only counting time spent on VScode?

How to share packages between apps in pnpm monorepo

I’m extremley confused with how monorepos work, I want to build an app with next.js and sanity studio so i have 2 folders

next
studio

both uses some similar packages like

react
react-dom
@types/react
@types/react-dom
@types/node
@typescript

so I dont want each folder to install them independently so i created

pnpm-workspace.yaml

packages:
    - "apps/*"
    - "packages/**/*"

packages/libraries/react/package.json

{
  "name": "@libraries/react",
  "version": "1.0.0",
  "peerDependencies": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "typescript": "^5.3.0"
  },
  "devDependencies": {
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0"
  }
}

so now inside my next folder

{
  "name": "next",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "@libraries/react": "workspace:*",
  },
  "devDependencies": {
    "@languages/typescript": "workspace:*",
    "@types/node": "^20"
  }
}

but then i get an error react cannot be found but the app working fine i can access it, am I misunderstanding things wrong ?

switching to full-screen yields different results when using the video button and a programmed equivalent

I have a simple web application to display media files (images as well as videos). By default, the application uses part of the screen for controls and the rest for display of the media files.
One of the possible actions the user may trigger is to switch to full-screen mode. This is implemented by invoking the requestFullscreen() method to the media container div. When this is done, the application switches to full-screen while two divs are shown on top with a reduced set of buttons (e.g. “next”, “prev”) and general info related to the shown media file.

When a video file is displays, the video player includes an equivalent button to switch to full-screen mode (and, of course, another button to return to normal). When this button is clicked, full-screen mode is entered BUT the two additional divs are now invisible. I checked setting the z-index very high but these divs remain hidden.

My question is: What is the difference in between the behavior of programmatically triggering full-screen vs. clicking on the video player button?

Alternatively, is there a way to instruct the media player to hide the full-screen button?

Thanks.

Firebase Auth import not recognizing any Modules

I installed Firebase in my Next Js, and I’ve initiallized it correctly. I’ve imported other firebase like (firestore, strage and app) and they work. yet when i try to import from firebase/auth it shows red under it’s imports (like getAuth, GoogleAuthProvider, …) and the error says “Module ‘”firebase/auth”‘ has no exported member ‘getAuth’.” and this is different for each auth imports.

Here is my config file

import { initializeApp, getApp, getApps } from "firebase/app";
import { getFirestore } from "firebase/firestore/lite";
import { getStorage } from "firebase/storage";
import { getAuth, GoogleAuthProvider, EmailAuthProvider } from "firebase/auth";

const firebaseConfig = {
    apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
    authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
    storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
    appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
    measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
};

const app = getApps().length ? getApp() : initializeApp(firebaseConfig);
const db = getFirestore(app);
const storage = getStorage(app);
const auth = getAuth(app)

const googleProvider = new GoogleAuthProvider();
const emailProvider = new EmailAuthProvider();

export { app, db, storage, auth, googleProvider, emailProvider };

it has no problem with recognizing “firebase/auth” and i even tried clearing the cache and reinstalling. downgrading the version and even restarting my IDE. i even tried changing my package manager from pnpm to npm. what am i doing wrong here?

Issue setting up anime.js v4.0.2

I am trying to learn how to use anime.js for a project of mine, but I am having issues making it run. All the tutorials I find are for older version. I tried following the documation provided on the anime.js site, but its still not working. Here are screenshots showing what my pathway and code looks like so far.My DirectoryHTML fileJS fileCSS FileHere is what my current output looks like, just a static boxOutput