Skip to content

Instantly share code, notes, and snippets.

@medelman17
Created January 7, 2020 18:39
Show Gist options
  • Save medelman17/7f54516d16741cd61b0d3088958584c4 to your computer and use it in GitHub Desktop.
Save medelman17/7f54516d16741cd61b0d3088958584c4 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const machine = getCharacterProcessor({ data: "dsfdsfsdfsdf", res: {} });
function createCharExtractor(context) {
return Machine(
{
id: "extractor",
initial: "idle",
context,
states: {
idle: {
on: {
START: "extracting"
}
},
done: { type: "final", data: (c, e) => c },
extracting: {
invoke: {
id: "dataExtract",
src: charExtract,
onError: {
actions: [
send((c, e) => ({
type: "DONE",
error: true,
data: e.error
}))
]
},
onDone: {
actions: [
send((c, e) => ({
type: "DONE",
error: false,
data: e.data
}))
]
}
},
on: {
DONE: [
{ target: "done", actions: "handleError", cond: "isError" },
{ target: "done", actions: "handleSuccess" }
]
}
}
}
},
{
actions: {
handleError: assign({
res: (c, e) => e.error
}),
handleSuccess: assign({
res: (c, e) => e.data
})
},
guards: {
isError: (_, event) => event.error === true
}
}
);
}
function createCharTransformer(context) {
return Machine(
{
id: "transformer",
initial: "idle",
context,
states: {
idle: {
on: {
START: "transforming"
}
},
done: { type: "final", data: (c, e) => c },
transforming: {
invoke: {
id: "dataTransform",
src: charTransform,
onError: {
actions: [
send((c, e) => ({
type: "DONE",
error: true,
data: e.error
}))
]
},
onDone: {
actions: [
send((c, e) => ({
type: "DONE",
error: false,
data: e.data
}))
]
}
},
on: {
DONE: [
{ target: "done", actions: "handleError", cond: "isError" },
{ target: "done", actions: "handleSuccess" }
]
}
}
}
},
{
actions: {
handleError: assign({
res: (c, e) => e.error
}),
handleSuccess: assign({
res: (c, e) => e.data
})
},
guards: {
isError: (_, event) => event.error === true
}
}
);
}
function getCharacterProcessor(context) {
return Machine(
{
id: "ETL Processor",
initial: "idle",
context,
states: {
idle: {
// entry: [send({ type: "START" })],
on: {
START: "extracting"
}
},
extracting: {
on: {
START: {
actions: [send({ type: "START" }, { to: "dataExtractor" })]
}
},
// entry: [send({ type: "START" }, { to: "charExtractor" })],
exit: ["bootstrap"],
invoke: {
id: "dataExtractor",
src: createCharExtractor,
onDone: {
target: "transforming"
},
onError: {
target: "failure"
}
}
},
transforming: {
on: {
START: {
actions: [send({ type: "START" }, { to: "dataTransformer" })]
}
},
// entry: [send({ type: "START" }, { to: "charTransformer" })],
exit: ["bootstrap"],
invoke: {
id: "dataTransformer",
src: createCharTransformer,
onDone: {
target: "loading"
},
onError: {
target: "failure"
}
}
},
loading: {
on: {
START: {
actions: [send({ type: "START" }, { to: "dataLoader" })]
}
},
// entry: [send({ type: "START" }, { to: "charLoader" })],
invoke: {
id: "dataLoader",
src: createPhotonMachine,
onDone: {
target: "success"
},
onError: {
target: "failure"
}
}
},
failure: { type: "final" },
success: { type: "final" }
}
},
{
actions: {
bootstrap: assign({
data: (c, e) => e.data.res,
prev: c => c.data
})
}
}
);
}
function createPhotonMachine(context) {
const config = getPhotonMachineConfig(context, uuid());
const options = getPhotonMachineOptions(context);
return Machine(config, options);
}
function getPhotonMachineConfig(context, id) {
return {
id,
initial: "idle",
context,
states: {
idle: {
on: {
START: "active"
}
},
active: {
entry: send("TRY", { delay: "backoff" }),
on: {
TRY: { target: "pending" }
}
},
pending: {
invoke: {
id: "photon",
src: "photon",
onDone: {
target: "done",
actions: ["resolve"]
},
onError: {
target: "failure"
}
}
},
failure: {
on: {
"": [
{ target: "active", cond: "canRetry", actions: "increment" },
{ target: "done" }
]
}
},
done: {
type: "final",
data: (context, event) => {
return Object.assign(Object.assign({}, context), {
res: event.data.res
});
}
}
}
};
}
function getPhotonMachineOptions(context) {
return {
guards: {
canRetry: ({ retries }) => retries < 5
},
actions: {
resolve: assign({
res: (_, event) => event.result
}),
increment: assign({
retries: ({ retries }) => retries + 1
})
},
activities: {},
services: {
photon: ({ data }, _) => photon.characters.create({ data })
},
delays: {
backoff: ({ retries }) => retries * 200
}
};
}
const photon = {
characters: {
create({ data }) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve({ res: { ...data } }), 2000);
});
}
}
};
function charTransform() {
return Promise.resolve({
name: "test",
unicode: "000A",
unicode_int: 0
});
}
function charLoader() {
return Promise.resolve();
}
function charExtract() {
return Promise.resolve({ code: "fasdf", name: "24r2342" });
}
function uuid() {
return "photon";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment