Skip to content

Instantly share code, notes, and snippets.

@kyle-aoki
Created July 11, 2021 21:44
Show Gist options
  • Save kyle-aoki/4f82483e13e0bf186adeb26227859844 to your computer and use it in GitHub Desktop.
Save kyle-aoki/4f82483e13e0bf186adeb26227859844 to your computer and use it in GitHub Desktop.
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
type UUID = string;
interface Meta {
id: UUID;
createAction: CreateActionFunction;
logic: any;
}
const getMeta = (logic: Function): Meta => {
const id = uuidv4();
const createAction = (payload?: any) => ({ type: id, payload });
return { id, createAction, logic }
};
interface Action {
type: UUID;
payload?: any;
}
type CreateActionFunction = (payload?: any) => Action;
type Put = Function;
type Dispatch = Function;
type PutOrDispatch = Put | Dispatch;
class ActionExecutor {
execute: PutOrDispatch;
constructor(execute: PutOrDispatch) {
this.execute = execute;
}
}
namespace NumberSystem {
export interface SHAPE {
counter: number;
}
const INITIAL_STATE: SHAPE = {
counter: 0
}
export namespace BASE {
export const meta = getMeta((state: SHAPE, action: Action) => ({ ...state }));
}
export namespace INCR_COUNTER {
export const meta = getMeta((state: SHAPE, action: Action) => ({ ...state, counter: state.counter + 1 }));
}
export function REDUCER(state: SHAPE = INITIAL_STATE, action: Action) {
switch (action.type) {
case INCR_COUNTER.meta.id: return INCR_COUNTER.meta.logic(state, action);
default: return BASE.meta.logic(state, action);
}
}
export class Instance extends ActionExecutor {
INCR_COUNTER = () => this.execute(INCR_COUNTER.meta.createAction());
}
}
const disp = (a: any) => console.log(`dispatching ${JSON.stringify(a)}!`);
const NumberSystemController = new NumberSystem.Instance(disp);
NumberSystemController.INCR_COUNTER();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment