Skip to content

Instantly share code, notes, and snippets.

Nathan Ridley axefrog

Block or report user

Report or block axefrog

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
axefrog / suffix-tree-console.js
Last active May 10, 2019
Simple suffix tree implementation in JavaScript. Install chalk to run the script below, or strip it down and remove all the debug messages and test cases.
View suffix-tree-console.js
const defaultIfZero = (a, x) => x === 0 ? a : x;
const isDefined = x => x !== void 0;
const isUndefined = x => x === void 0;
const NONE = Symbol('NONE');
const chalk = require('chalk');
const val = x => (x === NONE ? (x = 'none', chalk.bold.grey) : chalk.cyan)(String(x));
let highlightActiveNode = null;
let highlightedEdges = [];
axefrog /
Last active Apr 19, 2018
My note-taking process, followed by an example taken from my own notes in 2016.

My process for designing systems and solving problems is fairly simple, and in a way it seems like an obvious approach, but the degree of effectiveness of the technique is greater than what you'd intuitively expect. When most developers write notes and try to work out how to tackle some kind of architectural design challenge, it usually takes the form of a few whiteboard notes, some scribbles in a notepad, etc. Usually this is fine because the problem is small and constrained to a manageable level. If you want to tackle something bigger and more challenging though, or if you want to design a much more effective system in the first iteration, rather than two-to-three years down the track after several deployments finally lead you to the conclusions you'd like to reach up front, then this process works really well. It does feel like you're committing to a chore if you haven't done it before, and the reason it works isn't itself obvious, which is part of the reason I get pushback from a lot of developers before

axefrog / extensible.ts
Last active Jun 16, 2017
Hot-swappable pipelines for Most.js streams
View extensible.ts
import {Stream, Sink, Scheduler, Disposable} from '@most/types';
import {disposeOnce, disposeAll} from '@most/disposable';
export type ActivateExtension<A = any> = (source: Stream<A>) => Stream<A>;
export type DeactivateExtension = null;
export type ExtensionAction<A = any> = ActivateExtension<A>|DeactivateExtension;
export type ExtensionLifecycle<A = any> = Stream<ExtensionAction<A>>;
export function extensible<A>(source: Stream<A>, extensions: Stream<ExtensionLifecycle<A>>): Stream<A> {
return new ExtensiblePipeline(extensions, source);
axefrog / (a) inspect.ts
Last active Jun 6, 2017
Most.js introspection concept
View (a) inspect.ts
function identity<T>(value: T): T {
return value;
let wrap = identity;
export function inspect<T>(fn: (value: T) => T): void {
wrap = fn;
axefrog / preprocessor.js
Created Feb 26, 2017
Simple DEV vs PROD preprocessor for JS and TS source code
View preprocessor.js
Preprocessor Directives
// --- OMIT A SINGLE LINE ----------------------------------------------------
log("This line will be excluded from the build"); // ## DEV ##
// --- OMIT A WHOLE BLOCK ----------------------------------------------------
axefrog / CriticalSection.ts
Last active Jan 17, 2017
A stream-flavoured critical section implementation for isolating access to a stream subgraph
View CriticalSection.ts
# CriticalSection
"A stream-flavoured critical section implementation for isolating access to a stream subgraph"
Events entering a stream graph fenced off by a critical section will cause all other entry points to switch into
blocking mode, with events received at a given entry point being retained in that entry point's internal buffer,
and the entry point buffer enqueued for subsequent processing. Each time an event flows through an exit point, the
next entry point in the queue will be dequeued and its next buffered event emitted into the inner stream graph.
When no data is buffered at any entry point, the critical section unblocks, allowing direct dispatch of the next
future data item to arrive, at which point it will switch back into blocking mode. Errors ignore critical section
View fast-array-copy.ts
function copyArray<T>(values: T[]): T[] {
switch(value.length) {
case 0: return [];
case 1: return [value[0]];
case 2: return [value[0], value[1]];
case 3: return [value[0], value[1], value[2]];
case 4: return [value[0], value[1], value[2], value[3]];
case 5: return [value[0], value[1], value[2], value[3], value[4]];
case 6: return [value[0], value[1], value[2], value[3], value[4], value[5]];
case 7: return [value[0], value[1], value[2], value[3], value[4], value[5], value[6]];
axefrog / example.js
Last active Jan 17, 2017
A cleaner abstraction for creating and resolving stream proxies
View example.js
import {using} from 'proxy-abstraction';
function render() {
// The `using` function takes a callback function. It looks at the functions `.length` property
// and generates a proxy for each. You then return a tuple containing the value you want to
// persist, and fulfillment streams for each of the referenced proxies. The using function will
// automatically complete the proxies internally and return the first tuple argument.
return using((click$, hover$) => {
const view = div(......);
return [
axefrog / debug.js
Last active Jan 17, 2017
Full-featured console-based log/trace debugger for most.js, borrowing ideas from CQRS.
View debug.js
import Immutable from 'immutable';
import formatDate from 'date-fns/format';
import immutableDiff from 'immutablediff';
/* eslint-disable no-underscore-dangle */
var colors = {
0: ['white', '#7fbad8', '#0075b2'],
1: ['white', '#91a0ce', '#24429e'],
2: ['white', '#ab86e0', '#570ec1'],
axefrog / flatScan.js
Last active Aug 12, 2016
A multi-pass scan operator for most.js
View flatScan.js
import {sample} from '@most/sample';
import {proxy as makeProxy} from 'most-proxy';
* FlatScan is a multi-pass accumulation operator. It takes a first-stage
* initiator function and an initial state value, and returns a function that
* takes a stream of values and returns a stream of cumulatively-updated values.
* For each input value received from the source stream, the initiator function
* is called with the current accumulated state, the input value, and an
You can’t perform that action at this time.