Skip to content

Instantly share code, notes, and snippets.

James K Nelson jamesknelson

View GitHub Profile
View concatStringsAndStreams.js
const CombinedStream = require('combined-stream2');
function concatStringsAndStreams(strings, ...args) {
let combinedStream = CombinedStream.create()
combinedStream.append(Buffer.from(strings[0], 'utf8'))
for (let i = 0; i < args.length; i++) {
let arg = args[i]
let string = strings[i+1]
if (arg && arg.pipe) {
combinedStream.append(arg)
View mapObservableToChunkIterator.md

mapObservableToChunkIterator(observable, mapValueToChunks, mapErrorToChunks?): Generator<Promise | Chunk[]>

A function that accepts an Observable with a subscribe() method, and optionally with a getCurrentValue() or getCurrentResult() method.

It returns a Generator that yields Promise (when waiting for a new value) or Chunk objects (i.e. objects that extend { type: string }).

By default, mapErrorToChunks takes the error emitted by an observable, and yields [{ type: 'error', error: error }].

When the observable is complete, the Generator's next() function will return { done: true }.

@jamesknelson
jamesknelson / component-routing.js
Last active Mar 19, 2019
Two APIs for routing with React that support POST methods and SSR.
View component-routing.js
/**
UPDATE:
This component and hook based routing/fetching API won't work, as `useAsync()`
is an impossible component.
In order to use async functions to respond to route changes, the functions will
need to be registered with a parent cache/provider with a unique key. As such, a
more natural component-based architecture would involve a `<Route path>` component
View UpdatePasswordForm.jsx
import { map, redirect, route } from 'navi'
function UpdatePasswordForm({ submitErrors }) {
return (
<Form
method='post'
submitErrors={submitErrors}
validate={value =>
value.password !== value.passwordConfirmation &&
{
View gist:432f00af5522ea07cbb39990a8105e0c
A React app can be split into a number of different types of functions and components, where *each type can depend only on the types above it in the hierarchy*.
This makes gives you a way to split up components and functions over your filesystem. It also helps you to keep components from growing too large, and encourages practices that make testing easier.
```
types (TypeScript typings)
^
utils (plain javascript functions)
^
contexts (React context, and provider components)
@jamesknelson
jamesknelson / create-cruv-app.sh
Last active Aug 22, 2018
React CRUV - 4 directories to solve project structure for good
View create-cruv-app.sh
create-react-app myapp
cd myapp/src
mkdir containers routes utils views
touch config.js contexts.js
mv App.* routes
sed -i '' -e 's/.\/App/.\/routes\/App/g' index.js
View typeof-documentstorage.ts
// typeof DocumentStorage
type DocumentStorage = Batchable<{
willUpdate: false | {
source: boolean | CompoundValueNode<boolean>;
undoHistories: boolean | CompoundValueNode<boolean>;
};
isAwaitingInitialData: false | {
source: boolean | CompoundValueNode<boolean>;
undoHistories: boolean | CompoundValueNode<boolean>;
View TextFieldControl-accessibility.md

I want to make a <TextFieldControl> component that passes a <Description> component to its render function.

Rendering a <Description> would automatically add an id to the element, and then add that id to the aria-describedby prop of the associated input.

For example, this component:

const EmailField = ({ error, value, onChange }) =>
View GovernRedux.js
import * as Govern from 'govern'
/**
* This component subscribes to a Redux store, outputting its current state.
*
* Typically, you'll use this component as an element in another component's
* `subscribe()` method. For example:
*
* ```js
* class Identity extends Govern.Component {
View HTTPOperation.ts
import * as Govern from 'govern'
import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios'
export interface HTTPOperation<Success = any, Rejection = any> {
hasEnded: boolean
isBusy: boolean
wasCancelled: boolean
wasSuccessful: boolean
wasRejected: boolean
You can’t perform that action at this time.