Skip to content

Instantly share code, notes, and snippets.

@marcelklehr
Created April 15, 2019 18:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelklehr/ae67cd246ef451c64173ff9e0d5ffed3 to your computer and use it in GitHub Desktop.
Save marcelklehr/ae67cd246ef451c64173ff9e0d5ffed3 to your computer and use it in GitHub Desktop.
const completable = {
_: 'pending',
pending: {
on: {
COMPLETE: 'completed'
}
},
completed: {
on: {
REASSIGN: 'pending'
}
}
};
const deletable = {
_: 'alive',
alive: {
on: {
DELETE: 'deleted'
}
},
deleted: {
final: true
}
};
const editable = {
_: 'content',
content: {
context: '',
on: {
EDIT: (action, state) => ({ _: 'content', context: action.payload })
}
}
};
const todoItem = {
_: 'main',
main: {
compose: {
completable,
deletable,
editable
}
}
};
const filterable = {
_: 'pending',
pending: {
on: {
FILTER_COMPLETED: 'completed',
FILTER_ALL: 'all'
}
},
completed: {
on: {
FILTER_PENDING: 'pending',
FILTER_ALL: 'all'
}
},
completed: {
on: {
FILTER_PENDING: 'pending',
FILTER_COMPLETED: 'completed'
}
}
};
const iterable = itemMachine => ({
_: 'list',
list: {
context: [],
on: {
ADD: (action, state) => ({
_: 'list',
context: [...state.context, transition(itemMachine)]
}),
REMOVE: (action, state) => ({
_: 'list',
context: state.context.filter((_, i) => i !== action.payload)
}),
// Pass on all other actions and remove deleted items
_: (action, state) => {
return {
_: 'list',
context: state.context
.map(state => transition(itemMachine, state, action))
.filter(state => !state.deletable || state.deletable !== 'deleted')
};
}
}
}
});
const todoList = {
_: 'main',
main: {
compose: {
filterable,
items: iterable(todoItem)
}
}
};
// Avice:
// If in doubt make a sub-machine
// If in doubt make actions as specific as possible (they should usually just be tokens)
// and thus only rarely use context
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment