HNHacker News
TopNewBestAskShowJobs

fregante

40 karma · joined November 17, 2020

Find me at https://github.com/fregante
submissionscomments
fregante··on Zero regrets: Firefox power user kept 7,500 tabs open for two years
I know you’d rather see it native but if you’re open to sponsor its development, I could make a custom addon for that.
fregante··on HTML Attributes vs. DOM Properties
This is a good read for JS developers.

TL;DR: they’re not the same thing. Only sometimes they match (e.g. `id`) but often they don’t.

Something fun: JSX does not use attributes, even if they look like it. That’s why they have unusual naming/formatting (`htmlFor` and `className`)

fregante··on Ask HN: Those making $500/month on side projects in 2023 – Show and tell
https://github.com/refined-github/refined-github

I never intended it to be a side project, I just liked the extension and started contributing heavily to it, to the point where I became the maintainer for the next several years.

I get about that amount per month in GitHub Sponsorships. Not nearly worth the amount of time I put into it, but it’s relatively effortless work. It makes my regular work on other GitHub projects more enjoyable (due to the features that Refined GitHub adds)

fregante··on Ask HN: Techwise, how did TikTok get so good?
The fun part is that they completely botched an experience that iOS can delivery natively. I built a mini app to extract the HSL stream from a URL and have iOS play it. It usually solves my problems with it: https://arte.vercel.app/
fregante··on For your next side project, make a browser extension
Only pre-existing MV2 extensions can be updated. New extensions have had to be MV3 for exactly 12 months already: since January 17th 2022.
fregante··on For your next side project, make a browser extension
Look into chrome.storage.session, they created it explicitly to allow in-memory storage for those scenarios. Not as easy as just setting a property, but good enough.
fregante··on Ask HN: If I get locked out of everything, please try to help me
> Please do not treat them this way. They do not grant access to your account.

Can you expand on that? Once I have such code, what’s stopping me from “stealing” the account?

fregante··on Ask HN: If I get locked out of everything, please try to help me
Italy has SPID. It’s a federated login system based on your fiscal code (every Italian has one). You can use it to log into any government service and potentially banks and such. If you do lose access to your 2FA (required, it’s your phone), you can:

- re-verify yourself with the provider, with a real ID

- get a new ID with another provider, which still points to the same fiscal code

As a global solution, it would be great to have a “real identity provider” that offers this but also allows me to log into services without giving them too much information.

Apple ID seems relatively good for this given that it lets me hide the address and change my name during registration.

fregante··on Aria-label is a code smell
I don’t think it's actually a net benefit. Adding the wrong value degrades the experience.

I've seen links marked with `role=button` for no reason and generally roles added when one is implied (role=link is implied on anchors for example).

If aria attributes are treated as "private/testing API", then one wouldn't be surprised when the value only makes sense to bots and not humans.

fregante··on The Restaurant Industry’s Worst Idea: QR Code Menus
Digital menus aren't bad, but very few can implement them effectively. I do like having access to the menu for the whole dinner though and not have to wait for the waiter, ever.

In general, yeah, give me a piece of paper, there are far more people who can print some text than developers who can make a decent menu page — and it's quite sad, given it should just be a single, flat HTML page with an "index"

fregante··on GitHub Copi­lot inves­ti­ga­tion
If this becomes illegal, it will pretty much mark the death of free/open ML and its sets.

If you can't train on data before asking for permission, the data set becomes sparse. Thje only people who will be able to afford this will be, you guessed it, established giants who can build their own sets.

fregante··on “You meant to install ripgrep”
Back when npm didn’t have any “similar name” restrictions I did the same for some popular packages. My redirects also helped me a couple of times as I wonder whether a package name had a dash or not.

https://github.com/fregante/npm-helpful-typosquatting

Here’s what it looks like: https://www.npmjs.com/package/webext

fregante··on Why don't you accept donations?
Yeah but… money. You can’t pay rent with smiles. Accepting donations would probably mean having to work less at their main job. Or they could re-donate it.

There are people willing and able to pay, leaving those money on the table is pure waste.

fregante··on uBlock, I exfiltrate: exploiting ad blockers with CSS
JSX requires a build though, it's easier to enforce syntax when a missing character will just work while writing it. There are no JSX errors at runtime for this reason.
fregante··on Why don't you accept donations?
It's kind of weird to work for free though, isn't it? Sure it's something we like doing, but I really see no reason to reject free money. For uBlock this free money would be a fairly large amount, I'm sure. Even if that'd require some legal setup, I assume those fees will be largely covered.
fregante··on Why don't you accept donations?
GitHub Sponsors is a technical solution, but I still need to handle the legal side of the equation.
fregante··on Why don't you accept donations?
> And some donated more than others

That's unrelated to donations. One can accept donations without putting their soul on sale.

As an extension developer I get offers for buying my extensions or adding donator-specific functionality: I just don't accept them, even though I accept simple donations/sponsorships. The extension is still free of ads (except in the readme)

fregante··on Ask HN: Is it worth it to invest in learning TypeScript?
Think of TypeScript as writing JavaScript with inline tests: It takes longer but it produces "safer" code (with fewer bugs)

Is it worth learning it? I'm sure type-less job offers will continue to exists in large numbers, so if you don't like it then don't study it.

Note: TS is generally not referred to as "testing", this is just my simplification. I've been using TS for years for everything and it has avoided a lot of bugs — which is something I notice when porting projects to TS.

fregante··on Show HN: Running a simple local HTTP server in a web page
For those who don’t understand what it’s doing (like me at first):

You first have to host these index.html and sw.js on a regular server (or use the URL in the readme) and then this service will serve a folder of your choice directly from your computer.

This is if you ran your trusty Python server from the CLI, except you did it from the browser, with an unchangeable host:port

The folder will appear to be published from the server that hosts that sw.js file.

fregante··on Google sets burial date for legacy Chrome Extensions, fears for ad-blockers grow
It's interesting that you mention Chrome’s silliness when I find Firefox’ dev tools to be severely lacking, especially for WebExtensions. Examples include:

    - complete inability to run code from the console into the content script context
    - content script errors are not shown in the console, you have to open a separate Browser Console
    - overall buggy dev tools (I don't remember anymore because I stopped using them a long time ago)
I guess every browser lacks something, it's just that we notice when we compare "my browser" to the next one.
fregante··on Unravelling `Async for` Loops
Async iterables are async generators. They call .next() on the iterable, that returns a promise, the promise resolves with either a new item to loop with, or with `done`, which will stop the loop.
fregante··on Unravelling `Async for` Loops
Your words:

> One might be tempted to use the thenable interface (don’t!):

The code that followed was fine and it had no race condition.

> Seems like it would work, but it actually only waits for the promises returned from item() and not the .then() part!

This is the wrong part. The blockness is irrelevant.

fregante··on Unravelling `Async for` Loops
> the pattern of awaiting in an async parallel loop in general reduces to what I wrote, does it not?

No.

    async item => {await item()} // Promise<void>
    item => item() // Promise<ReturnValue<typeof item>>
In general that's how you use maps (by returning something), but here the intent was not to map an array, it's just how to implement an "async for".

> The only case where you would need to await inside the mapper function is when you would further process some asynchronously returned value

Which is what map is for. Also, once again, that was just how the async loop can be implemented. If anything you're saying that it's "a misuse" of map and thus we need an "async for"

    >  arr.map(async item => handleItem(
    >    await item()
    >  ))
That doesn't make any sense, there's still an `await` in the function’s body, so you're still handling it — and there's nothing wrong with that.

> await arr.map()

That's actually a good QoL improvement, but it doesn't address either of the points I'm talking about (only works on arrays + it requires a function)

> but it actually only waits for the promises returned from item() and not the .then() part

Wrong. The mapper function returns a Promise that resolves with the return value of handleItem. `await a.then(b).then(c)` awaits the 3 promises in row.

To achieve that race condition, you should not return nor await the return value of `then` inside the map method:

    await Promise.all(
      arr.map(item => {
        const p = item();
        p.then(handleItem); // "Race condition"
        return p;
      })
    );
fregante··on Unravelling `Async for` Loops
That’s just an example piece of code. If I used your code there wouldn’t be an `await` in the loop and people wouldn’t understand.
fregante··on Unravelling `Async for` Loops
`for await` is for async iterables, which is different. The loop body will still block the loop. Compare it to the all/map example I wrote.
fregante··on Username ending with MIME type format is not allowed
My guess is that they were using /.mov$/ to check the username, which is missing an escape.
fregante··on Unravelling `Async for` Loops
Thanks! I think it wouldn’t await the whole loop though

  for (const item of iterable)
    async do {
      await item()
    }
This would be equivalent to

  Promise.all(arr.map(async item => {
    await item()
  })
Notice the lack of await before Promise.all
fregante··on Unravelling `Async for` Loops
This reminds me of something I’d like to see in JavaScript: Loops that accept `await` in their body without pausing the whole loop.

This is already possible with:

  await Promise.all(arr.map(async item => {
    await item()
  })
… but it requires turning the iterable into an array first and it requires calling a function.

Is anyone working on a proposal for this?

  async for (const item of iterable)
    await item()
fregante··on GitHub Actions limitations and gotchas
3.5 I was excited to see action composition until I realized that the composed action will still be showed as one step and that it can just compose actions instead of whole workflows.

I want to share whole jobs across my repos, including matrixes and all. I could wrap some common workflows into one action, but then the whole complexity will be hidden in a single step.

So I resorted to creating GHA Templates and manually synching them with a CLI tool[1], which isn't great, but at least I don't have to copy-paste changes across repos and I can keep a "main version" of the workflow

1: https://github.com/fregante/ghat

fregante··on macOS Monterey Beta 3: Apple Redesigns Safari Tab Interface Following Complaints
Each tab is a checkbox (selected or not), an input field, a drag handle for the page and a drag handle for the window, depending on how fast you start dragging and in which direction. If you hover it it shows a set of buttons, but if it’s focused the buttons disappear entirely and can’t be dragged or closed at all.

They hid a few buttons in a tiny dropdown that appears on hover; They kept a completely useless clickable lock icon in the middle-ish of field so now there’s a little chance that, while trying to do any of the above, you’ll end up with a popup that you have to close instead.

Page 1 of 2Next →