HNHacker News
TopNewBestAskShowJobs

bluepnume

792 karma · joined February 4, 2012

daniel@onetext.com
submissionscomments
bluepnume··on Russians Engineer a Slot Machine Cheat and Casinos Have No Fix (2017)
I wouldn't think so. Whatever random result you get, you can bound it to make sure the probability works in your favor a fixed proportion of the time, right?

`if (pseudoRandom() < 0.57) houseWins()` gives the same payout as `if (trueRandom() < 0.57) houseWins()` for all intents and purposes; the only difference is the former is more predictable to people trying to game the machine.

bluepnume··on Show HN: Nothing.js – A chainable mock object which always returns itself
One thing I've been finding increasingly while using Flow in javascript is, null-pointer exceptions aren't really much of a problem any more.

Where they might have caused a bug, 90% of the time Flow will catch them, and insist that I do a null check and handle that case.

And when they do crop up, it's usually more of a serious failure that I'm happy to trigger an exception early, rather than having it propagate further down the stack by using something like nothing.js. Especially given the list of gotchas. The fact that `Nothing` is not falsy is really problematic.

I'm pretty convinced at this point that `a && a.b && a.b.c && a.b.c.d` is an anti-pattern in javascript anyway; if I'm that unsure about the structure of my data, I have more serious problems than just trying to avoid null pointers.

bluepnume··on Chrome 64 now trims messy links when you share them
Should be O(n) unless you're trying to optimize for every single permutation of query param, right? I'd assume the majority of the time the individual params would be independent from one another. Plus you'd only need to do it once in a while for any given base url and persist the result.
bluepnume··on Transpiled For-Of Loops Are Bad for the Client
You can set babel to `loose` mode to avoid having the transpiled output use `Symbol`. What I would love though is a "super-loose" mode which takes for-of and transpiles it directly to for-in -- i.e. excluding any support for iterators and just functioning on indexable collections with a defined `.length`. That would be enough to get concise output in most cases if you're confident you're always iterating over static collections.
bluepnume··on Introducing PayPal’s open-source cross-domain JavaScript suite
Thanks for the comment, I'll definitely pass along your thoughts. Right now, the sentiment over here is that collecting data in an iframe creates too much of a vector for phishing attacks, so that was the main driver in the decision to use a popup. But I'd love to find a way to mitigate that.
bluepnume··on Introducing PayPal’s open-source cross-domain JavaScript suite
We didn't discover any new real browser vulnerabilities, thankfully -- mainly just browser's being overly protective in some cases.

Most of the hacks were just to get IE up-to-par with the other browsers. For example, to send a postMessage between a popup and the parent page, the only way is to place a hidden iframe on the parent page, with the same domain as the popup. post-robot abstracts most of that away.

The line we had to walk in terms of security was, on top of not introducing any new vulnerabilities ourselves, making sure we didn't make it too easy for people to accidentally introduce any security loopholes using what we've built.

For example -- the idea of passing a function over to a different window is a fairly novel concept. The idea is, if you want to give the other window control over something, say to log out a user, you can just pass a `user.logout` function directly in a message to the target window. But then there's a risk people will absentmindedly pass functions in messages that they didn't expect to.

But then, on top of that, there's a lot we can do automatically to protect users, that doesn't happen automatically with regular browser apis. For example, if you render an xcomponent with a certain url, xcomponent will (by default) ensure that only messages from that domain are allowed up from the iframe. Which is something you'd need to remember to do manually if you were just listening for post-messages.

bluepnume··on Introducing PayPal’s open-source cross-domain JavaScript suite
If you see anything that's less than clear, or missing from the docs, please let me know! These tools only have a modest number of users right now, so we appreciate all the feedback we can get.
bluepnume··on Flow and TypeScript
I'm a huge Flow fan, and picked it over TypeScript because at the time I didn't like the idea of:

- Switching everything to .ts and .tsx files

- Switching a lot of tooling (TypeScript's built-in ES6 transpiler instead of Babel, tslint instead of eslint, etc.)

- At the time, TypeScript's types were nullable, Flow's were non-nullable, which makes a huge difference to me

- Given that TypeScript is a transpiler along with a static type-checker, it's not always easy to tell which features are going to have build-time vs run-time effects (e.g. private properties, property decorators)

That said, some of the errors from Flow can be incredibly confusing, and even with the latest versions I feel like there's improvement which needs to be made here. This (in my view) is the number one thing it needs to drive adoption.

bluepnume··on The Wonderful World of Webpack
I had the same problem -- after throwing together a few open source front-end libraries, and struggling with each to get webpack, babel, karma, flow, etc. all working seamlessly together, I put together https://github.com/krakenjs/grumbler and now just fork this every time I want to start something new.

Being able to just start writing code without spending forever setting up the perfect environment is hugely liberating. I'd encourage everyone to find good boilerplates for what they want to do (or put together their own if nothing else fits)

bluepnume··on Async Iterators: These Promises Are Killing My Performance
The biggest problem I had with forced promise asynchronicity was with browser promise polyfills, which use setTimeout to force success and error handlers to be called asynchronously.

This is fine, unless you're:

1. Modifying the DOM and hoping to avoid jankiness 2. Trying to work with popup windows, in a browser which deprioritizes setTimeout in all but the focused window.

I ended up implementing https://github.com/krakenjs/zalgo-promise to get around this. It intentionally "releases Zalgo" by allowing promises to be resolved/then'd synchronously, but my belief is this doesn't have to cause bugs if it's used consistently.

bluepnume··on Node.js is forked to Ayo.js (pronounced like “IO”)
I've been clicking around on twitter and github for five minutes and there seems to be zero specifics about what actually happened.

What's with the secrecy? Not saying this is a non-issue, but the best way to present your issue as a non-issue is to be this vague about what you're complaining about.

bluepnume··on Vue.js vs. React
For me, the best thing about jsx is the fact that it's so easy to create different implementations of `React.createElement` to solve different problems outside of the scope of React itself. Want a render function that uses jsx but returns a string, a DOM tree, or something entirely different? Totally possible! I didn't like jsx at first, but the fact that it's so decoupled from React itself counts extremely in its favor, in my view.

For example, for one of my libraries I wanted a really simple way to allow people to include custom templates. I started with string-based templates, but quickly realized that this was inflexible for any kind of event binding or later dom mutations. Achieving that was super easy with jsx -- I just implemented a custom jsx function which directly outputs DOM elements.

Step 1: implement a jsxDom function [^1] which takes (name, props, children) (e.g. https://github.com/krakenjs/xcomponent/blob/master/.babelrc#...)

Step 2: point babel to my jsxDom function (e.g. https://github.com/krakenjs/xcomponent/blob/master/src/lib/d...)

This even allowed some cool hacks like including iframes directly in the jsx, to sandbox sections of the page (since the library is geared towards creating components to be embedded on 3rd party sites):

  containerTemplate({ jsxDom }) {
    return (
      <iframe>
        <style>
          p {
            margin-top: 40px;
          }
        </style>

        <p>I can be sure the styles in this iframe won't affect the parent page</p>
      </iframe>
    )
  }
bluepnume··on Puppeteer: Headless Chrome Node API
I'm really loving headless chrome so far. I have around 650 tests which are mostly dealing with iframes and popup windows, and they run flawlessly. The first release seemed to have a memory leak which wasn't present in non-headless chrome, but that seems to have been fixed in version 60.

Even sped things up a little versus phantom.

bluepnume··on ‘This’ in JavaScript
I'm not sure I like this guide, because in several places it seems to imply the value of `this` is decided by where you define the function, which is only really true for arrow functions. For regular functions, unless you take control of `this`, it will be decided by the caller.

Best way I can think to describe `this`:

-----

1. Either you decide in advance exactly what you want `this` to be:

- Use `.bind()` on your function and fix the value of `this`

- Create an arrow function and get `this` from the lexical scope

- Alias `let self = this` in your desired scope, and only ever reference `self`

- Create a wrapper function which fixes the value of `this` (essentially, implement `.bind()`)

-----

2. Or `this` will be decided by your caller:

- Your caller will `.bind()` your function with an unknown value of `this`

- Your caller will call `.call()` or `.apply()` with an unknown value of `this`

- Your caller will attach your function to an unknown object, then call `unknownObject.yourFunction()`, setting `this` to `unknownObject`

- Your caller will call your function as a standalone function: `let newFunc = someObj.someFunc` - then call it, setting `this` to `global` or `window`

- Your caller will pass your function as a param to something like `setTimeout` and achieve the same effect, setting `this` to `global` or `window`

-----

Obviously, most of the time if you're going to use `this`, #1 is to be preferred, #2 is to be avoided, so it's imperative to decide in advance what you want `this` to be rather than allowing it to be decided by your caller.

(Unless that's absolutely what you want, and you have a good reason why -- like if you're writing a wrapper function which is agnostic to the value of `this` that's passed)

bluepnume··on Kill Google AMP before it kills the web
But it could be an argument from fallacy. https://en.wikipedia.org/wiki/Argument_from_fallacy
bluepnume··on There are no small changes (2011)
Not to mention "Does my character-counter work with unicode?"
bluepnume··on Show HN: 'Hack' the user cursor
Pretty smart once you figure out how it works. Wonder if there's some kind of advanced click-jacking attack you could achieve with a technique like this.
bluepnume··on Chrome 59 has cross-platform headless support
Very cool. Gonna have to check this out.
bluepnume··on Chrome 59 has cross-platform headless support
Glad they're working out for you! Let me know if you encounter any interesting situations they don't support.
bluepnume··on Chrome 59 has cross-platform headless support
A combination of:

- Making sure all promises are fulfilled or rejected, so window objects don't get caught indefinitely in closure scope for any .then() or .catch() handler functions.

- Using WeakMaps as much as possible, when we have things that are tied to a particular window, like message listeners or response handlers in post-robot

- Manually clearing up any global references to windows when we destroy an xcomponent instance

Finding the references was the tricky bit. A lot of the effort was finding a leaky test-case, running in 100 times in succession, and deleting code until the memory graph was flat -- then figuring out what I'd just deleted that caused the leak.

The problem started manifesting as I added more and more tests -- so now I'm actually checking my tests' memory usage on the fly and failing if they cross a threshold. Hopefully that should avoid getting into this kind of sticky situation ever again.

https://github.com/paypal/paypal-checkout/blob/master/test/t...

bluepnume··on Chrome 59 has cross-platform headless support
This is fantastic. I'm using a combination of Chrome and PhantomJS for karma testing right now, for https://github.com/paypal/paypal-checkout and https://github.com/krakenjs/xcomponent. There are hundreds of tests opening up hundreds of iframes and popup windows, and sending a lot of cross-window messages, and that ends up being really memory hungry.

Chrome deals pretty well with garbage collection, so long as I'm careful to de-reference closed windows properly¹, and only uses a maximum of 150mbs. PhantomJS eats up almost 6GB of memory before it's done, which makes it almost unusable on machines with less memory or CI boxes. Travis is a no-go.

I'm hoping running Chrome in headless mode should give a nice speedup for our tests.

-----

¹ Turns out even a closed popup window or iframe keeps a huge amount of memory hanging around. Who knew.

bluepnume··on The Glimmer VM: Boots Fast and Stays Fast
Yeah, that's essential in production. Totally agree. I'm mainly talking about the development experience for first-time users, or for people who just want to throw Glimmer onto one of their apps on localhost and play around with glimmer.Component. The thing that needs to be fast in those scenarios is the developer experience, not the app.
bluepnume··on The Glimmer VM: Boots Fast and Stays Fast
It's not possible to have a slower development build which does template->bytecode conversion on page load?

The point I'm trying to make it, there's already a huge amount of churn around the vast amount build tooling needed to write any javascript these days. Part of making a framework with a low barrier to entry is having the build tooling stay out of your way until you're ready to deploy.

I get that's not necessarily Glimmer/Ember's philosophy, I just think it's a shame that using the framework from day 1 requires buying into all of the technology choices around ember-cli.

bluepnume··on The Glimmer VM: Boots Fast and Stays Fast
I'm a big fan of what I'm seeing in Glimmer so far. I had fun adding support for xcomoponent yesterday, making Glimmer components work as cross-domain components.

https://medium.com/@bluepnume/introducing-support-for-cross-...

I'd love it if it were a little more flexible to get started with though. Rather than fire up ember-cli, I'd love to just be able to:

1. Load glimmer.js from a CDN

2. Extend glimmer.Component

3. Render my component into an element

I know ember-cli solves this problem for a lot of users, but I'd love for the number of steps to get a "hello world" working to be as simple as the above. I think that's one of the reasons React has been so successful: it's stupid-simple to get started with, and it draws you in from there.

bluepnume··on Glimmer – Fast and light-weight UI components
Coming from someone who loved writing apps with Ember, before moving on to other things, I think this is a step in the right direction. Having the UI library as its own standalone thing is a great move.

That said, it's way too hard to figure out how to buy into this thing without adopting the whole ember-cli ecosystem.

Ember-cli is a fantastic achievement, but for god's sake, give me a CDN link with a global `glimmer` object so I can at least play around with the thing in one of my projects, without buying into the entire ecosystem first!

I know that Ember is the "we'll take care of your whole app" framework, but with Glimmer maybe there's a chance here to cater to folks who love libraries like React, because they can get started with about 5 lines of code bunged into an html file and grow from there.

Let me start small, and make it easy for me to grow big.

bluepnume··on Modern JavaScript for Ancient Web Developers
After burning a lot of time getting all the javascript tooling I wanted working, for the umpteenth open source front-end javascript library I wanted to publish, I threw together this:

https://github.com/krakenjs/grumbler

Pretty opinionated on the tooling it uses, but good if you just want to say "Fuck it, I want to fork some boilerplate, write some code, and build/distribute it", then worry about the finer details later, and swap in specific tooling that you need later.

bluepnume··on Ask HN: Fatigued by the complexity of ES6 tooling. What to do?
It's not supposed to be a standard, in any way imaginable. It's just boilerplate that you can clone, and modify later if/when you feel like messing with javascript config files.

But hey, thanks for the largely irrelevant, but hilarious xkcd!

bluepnume··on Ask HN: Fatigued by the complexity of ES6 tooling. What to do?
After burning a lot of time to get all the tooling I wanted working, for the umpteenth open source front-end javascript library I wanted to publish, I threw together this:

https://github.com/krakenjs/grumbler

Pretty opinionated on the tooling it uses, but good if you just want to say "Fuck it, I want to clone some boilerplate, write some code, and build/distribute it", then worry about the finer details later.

bluepnume··on Don't remove the $(nop) command below
Wouldn't the $(nop) still have been better (more explicit, less likely to be accidentally removed) than the switch to blank lines?
bluepnume··on Things I hate about Git (2012)
The thing that gets me every time is the git sub-commands which have multiple orthogonal uses, without so much as a command line flag to differentiate them.

    git reset abc  # unstage file `abc`
    git reset xyz  # switch to commit `xyz`
or:

    git checkout mybranch  # switch to branch `mybranch`
    git checkout myfile    # remove any local changes to `myfile` since the last commit
---

Maybe this would work great in a typed language where I might have `reset(File x)` and `reset(Commit x)` with different signatures... but for a CLI where everything is stringly-typed? Not so fun.

Also, god knows what happens here if there's a branch name with the same name as a file...

← PreviousPage 5 of 7Next →