Skip to content

Instantly share code, notes, and snippets.

View cameronhunter's full-sized avatar

Cameron Hunter cameronhunter

View GitHub Profile
@cameronhunter
cameronhunter / semver.sh
Last active April 9, 2022 04:12
Parse a semver string in bash using a regular expression
#!/usr/bin/env bash
##
# Get the major/minor/patch semver from a string.
#
# Author: Cameron Hunter <hello@cameronhunter.co.uk>
# License: MIT 2022
#
# Examples:
# semver v14.22.1 major → 14

Keybase proof

I hereby claim:

  • I am cameronhunter on github.
  • I am cameronhunter (https://keybase.io/cameronhunter) on keybase.
  • I have a public key ASA3DI6aob5qHrmI2Zhe3-leKg8teAhnP4cFdtwJP9vsRwo

To claim this, I am signing this object:

{
"v": 2,
"parserID": "babylon7",
"toolID": "babelv7",
"settings": {
"babylon7": null
},
"versions": {
"babylon7": "7.0.0",
"babelv7": "7.0.0"
@cameronhunter
cameronhunter / keybase.md
Created November 19, 2016 22:04
keybase.md

Keybase proof

I hereby claim:

  • I am cameronhunter on github.
  • I am cameronhunter (https://keybase.io/cameronhunter) on keybase.
  • I have a public key whose fingerprint is 96DA 316E C416 C535 0DBA 285A B518 7FF2 2BD2 4938

To claim this, I am signing this object:

/**
* Identity
*
* 1. Ensure that the parent container has a max-width of 0 to
* guarantee correct text-overflow behavior in small widths.
*/
:root {
--Identity-avatar-size: 32px;
}
class Timer {
static delay(delay) {
return new Timer(
(delay ? (fn) => { setTimeout(fn, delay) } : (fn) => { fn() }),
(delay ? (id) => { clearTimeout(id) } : () => {})
);
}
static interval(interval) {
@cameronhunter
cameronhunter / array.bucket.js
Created July 23, 2015 01:53
Array#bucket for JavaScript in ES6
Array.prototype.bucket = function(fn) {
const results = [...Array(fn.length)].map(() => []);
const buckets = results.map(bucket => bucket.push.bind(bucket));
const noop = () => {};
this.forEach(item => (fn.apply(item, buckets) || noop)(item));
return results;
};
@cameronhunter
cameronhunter / EventDataCache.md
Last active August 29, 2015 14:05
[Experimental] FlightJS component that intercepts and caches event data.

This is an experiment in unobtrusively caching event data in FlightJS. It's a component which effectively slides between a UI and data component, intercepting requests for data, and caching responses. It doesn't require cache invalidation because it does not prevent the data component from retrieving updated data when there's a cache hit. This allows us to create a snappier UI by providing the "last known" data, but still allowing the data component to fetch and trigger with the most recent data at a later stage.

If a "with_data" mixin existed with methods such as this.get and this.post, then this could be a mixin using advice to surround these functions with caching. Perhaps that's a cleaner way of implementing this functionality – this is just an experiment.

This could also be mixed with the flight-storage component, so that the cached data could be served from localStorage or IndexDB.

@cameronhunter
cameronhunter / Data Binding Thoughts
Created July 31, 2013 18:33
Some research and thoughts around data-binding for flight.
## Definition ##
"Data binding is general technique that binds two data/information sources together and maintains synchronization of data." – http://en.wikipedia.org/wiki/Data_binding
UI data binding binds UI elements to an application domain model. Most frameworks employ the Observer pattern as the underlying binding mechanism. To work efficiently, UI data binding has to address input validation and data type mapping.
A bound control is a widget whose value is tied to a field in a recordset (i.e., a column in a row of a table). Changes made to data within the control are automatically saved to the database when the control's exit event triggers.
## Execution ##
From http://www.lucaongaro.eu/blog/2012/12/02/easy-two-way-data-binding-in-javascript/
@cameronhunter
cameronhunter / options-or-overloads.scala
Created April 19, 2013 18:44
Option doesn't solve everything. Sometimes overloaded functions provide a less confusing API.
/* Function using Option */
object Hello {
def to(name: Option[String] = None) =
"Hello " + (name getOrElse "world")
}
println(Hello.to(null)) // Causes NullPointerException