Skip to content

Instantly share code, notes, and snippets.

View axefrog's full-sized avatar

Nathan Ridley axefrog

  • Brisbane, Australia
View GitHub Profile
@axefrog
axefrog / extensible.ts
Last active June 16, 2017 02:31
Hot-swappable pipelines for Most.js streams
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
axefrog / (a) inspect.ts
Last active June 6, 2017 19:09
Most.js introspection concept
function identity<T>(value: T): T {
return value;
}
let wrap = identity;
export function inspect<T>(fn: (value: T) => T): void {
wrap = fn;
}
@axefrog
axefrog / preprocessor.js
Created February 26, 2017 17:22
Simple DEV vs PROD preprocessor for JS and TS source code
/*
Preprocessor Directives
=======================
// --- OMIT A SINGLE LINE ----------------------------------------------------
log("This line will be excluded from the build"); // ## DEV ##
// --- OMIT A WHOLE BLOCK ----------------------------------------------------
@axefrog
axefrog / debug.js
Last active January 17, 2017 04:17
Full-featured console-based log/trace debugger for most.js, borrowing ideas from CQRS.
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
axefrog / example.js
Last active January 17, 2017 04:17
A cleaner abstraction for creating and resolving stream proxies
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 [
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
axefrog / CriticalSection.ts
Last active January 17, 2017 04:14
A stream-flavoured critical section implementation for isolating access to a stream subgraph
/*
# 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
@axefrog
axefrog / limitFlow.js
Last active October 17, 2016 19:44
Flow control limiter for most.js. Unlike `throttle`, which drops events indiscriminately, `limitFlow` retains the most recent event and ensures that it is emitted when the specified period elapses.
// Limit the rate of flow to an event every 250ms:
// const stream$ = other$.thru(limitFlow(250));
export function limitFlow(period) {
return function limitFlow(stream) {
const source = new RateLimitSource(stream.source, period);
return new stream.constructor(source);
};
}
@axefrog
axefrog / example.js
Last active October 4, 2016 04:01
Logging driver for cycle.js
import {Rx} from '@cycle/core';
export default function (responses, strings) {
var log = responses.log.create('Sample');
var str$ = Rx.Observable
.from(strings)
.do(str => {
log.trace('Just tracing stuff');
log.debug('Here is a debug message');
log.success('The successful thing happened that we wanted to happen');
@axefrog
axefrog / ReplaySource.js
Last active September 12, 2016 04:36
A simple `replay` operator for most.js. Specialises `multicast` so that new sinks are replayed the history of events from the source, including termination events. If a termination event exists, the sink is not cached for future events. After a termination, future sinks will not trigger a fresh `run` operation on the source.
const MulticastSource = require('most/lib/source/MulticastSource');
const PropagateTask = require('most/lib/scheduler/PropagateTask');
const CompoundDisposable = require('most/lib/disposable/CompoundDisposable');
module.exports = ReplaySource;
function ReplaySource(source) {
this._buffer = [];
this._ended = false;
MulticastSource.call(this, source);