{"flow":{"id":42,"summary":"a flow that uses a datetime part to cache a result","versions":[171,172],"created_by":"sindre svendby964","created_at":"2023-05-22T10:23:48.138Z","votes":0,"approved":false,"apps":["currencyapi","windmill"],"value":{"modules":[{"id":"a","value":{"lock":"","type":"rawscript","content":"import * as wmill from \"https://deno.land/x/windmill@v1.87.0/mod.ts\";\nimport {\n  format,\n  weekOfYear,\n} from \"https://deno.land/std@0.91.0/datetime/mod.ts\";\n\ntype periodType = \"Day\" | \"Month\" | \"Year\" | \"Hour\" | \"Week\";\n\nexport async function main(resourceCachePath: string, cachePeriod: string) {\n  let state;\n\n  const currentCachePeriod = format(\n    new Date(),\n    mapToFormatString(cachePeriod as periodType),\n  );\n\n  try {\n    state = await wmill.getResource(resourceCachePath);\n  } catch {\n    await wmill.setResource({}, resourceCachePath, \"state\");\n  }\n  console.log(state);\n  console.log(\"1state\");\n  if (!state) {\n    return {\n      cachePeriod: currentCachePeriod,\n      resourceCachePath: resourceCachePath,\n      cache: false,\n      value: undefined,\n    };\n  }\n\n  console.log(state.cachePeriod, currentCachePeriod);\n  if (state.cachePeriod == currentCachePeriod) {\n    return {\n      value: state.value,\n      cache: true,\n    };\n  }\n\n  return {\n    cache: false,\n    resourceCachePath: resourceCachePath,\n    cachePeriod: currentCachePeriod,\n    value: undefined,\n  };\n}\n\nfunction mapToFormatString(cachePeriod: periodType) {\n  switch (cachePeriod) {\n    case \"Day\":\n      return \"yyyy-MM-dd\";\n    case \"Hour\":\n      return \"yyyy-MM-dd:HH\";\n    case \"Month\":\n      return \"yyyy-MM\";\n    case \"Year\":\n      return \"yyyy\";\n    case \"Week\":\n      const week = weekOfYear(new Date());\n      return \"yyyy-week-\" + week;\n    default:\n      throw new Error(`Unsupported cachePeriod: ${cachePeriod}`)\n  }\n}\n","language":"deno","input_transforms":{"cachePeriod":{"expr":"flow_input.cachePeriod","type":"javascript"},"resourceCachePath":{"expr":"`${flow_input.cachePath}`","type":"javascript"}}},"summary":"check If cache exist"},{"id":"b","value":{"type":"branchone","default":[{"id":"f","value":{"type":"rawscript","content":"import type { Resource } from \"https://deno.land/x/windmill@v1.87.0/mod.ts\"\n\nexport async function main(\n  currencyApiResource: Resource<\"currencyapi\">,\n  base_currency: string,\n  currencies: string,\n) {\n  const paramString = new URLSearchParams({\n    base_currency: base_currency,\n    currencies: currencies,\n  }).toString();\n\n  const res = await fetch(\n    `https://api.currencyapi.com/v3/latest?${paramString}`,\n    {\n      headers: {\n        apikey: currencyApiResource.apiKey,\n      },\n    },\n  );\n  const data = await res.json();\n  const currency = data?.data;\n  return currency;\n}","language":"deno","input_transforms":{"currencies":{"type":"static","value":"NOK,DKK,EUR"},"base_currency":{"type":"static","value":"USD"},"currencyApiResource":{"type":"static","value":""}}}},{"id":"d","value":{"type":"rawscript","content":"import * as wmill from \"https://deno.land/x/windmill@v1.87.0/mod.ts\";\n\nexport async function main(\n  resourceCachePath: string,\n  cacheValue: any,\n  cachePeriod: string,\n) {\n  const state = {\n    cachePeriod,\n    value: JSON.stringify(cacheValue),\n  };\n\n  await wmill.setResource(state, resourceCachePath);\n\n  return cacheValue;\n}\n","language":"deno","input_transforms":{"cacheValue":{"expr":"results.f","type":"javascript"},"cachePeriod":{"expr":"`${results.a.cachePeriod}`","type":"javascript"},"resourceCachePath":{"expr":"results.a.resourceCachePath","type":"javascript"}}},"summary":"update cache with the new result"}],"branches":[{"expr":"results.a.cache === true && !flow_input.cleanCache","modules":[{"id":"e","value":{"type":"rawscript","content":"// import * as wmill from \"https://deno.land/x/windmill@v1.87.0/mod.ts\"\n\nexport async function main(value: any) {\n  return JSON.parse(value);\n}\n","language":"deno","input_transforms":{"value":{"expr":"results.a.value","type":"javascript"}}},"summary":"parse the state"}],"summary":""},{"expr":"flow_input.cleanCache","modules":[{"id":"g","value":{"type":"rawscript","content":"import * as wmill from \"https://deno.land/x/windmill@v1.87.0/mod.ts\";\n\nexport async function main(resourceCachePath: any) {\n  await wmill.setResource(undefined, resourceCachePath);\n  throw new Error(\"Cache Cleaned. Failing by default \");\n}\n","language":"deno","input_transforms":{"resourceCachePath":{"expr":"flow_input.cachePath","type":"javascript"}}},"summary":"clean cache and returns Error"}],"summary":""}]},"summary":""}]},"schema":{"type":"object","$schema":"https://json-schema.org/draft/2020-12/schema","required":["cachePeriod"],"properties":{"cachePath":{"type":"string","format":"","default":"","description":"the cache path needs to be in the format \"u/<your-user>/*\" or \"f/<valid-folder>/*\"\n"},"cleanCache":{"type":"boolean","format":"","default":false,"description":"a helper function to help you clean the cache"},"cachePeriod":{"type":"string","format":"","default":"Day","description":"One of \"Day\" | \"Month\" | \"Year\" | \"Hour\" | \"Week\".\n"}}},"description":"This example cache the result from an request to currencyapi.com. \nBut this approved could be used to cache whatever you want. \n\nSome notes;\n1. It's not meant to be used directly but adjusted to your needs. \n2. the getExchangeRate uses static inputs. If you have dynamic inputs you want to add those to the cache key in addition to the flow input and the exchange script\n3. the \"clean cache\" flow triggers an error. I only used it for testing purposes, and that worked out nice for me, I believe most people would like to change that. ","recording":null,"vcreated_at":"2023-05-22T10:27:14.477Z","vcreated_by":"sindre svendby964","comments":[]}}