{"id":24965762,"url":"https://github.com/allnulled/lsw-returner","last_synced_at":"2025-03-29T01:19:22.980Z","repository":{"id":274479399,"uuid":"923044542","full_name":"allnulled/lsw-returner","owner":"allnulled","description":"Function return controller tool for LSW","archived":false,"fork":false,"pushed_at":"2025-03-24T17:50:17.000Z","size":6,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T18:46:12.131Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allnulled.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-27T14:52:28.000Z","updated_at":"2025-03-24T17:50:20.000Z","dependencies_parsed_at":"2025-01-27T15:52:19.474Z","dependency_job_id":null,"html_url":"https://github.com/allnulled/lsw-returner","commit_stats":null,"previous_names":["allnulled/lsw-returner"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allnulled%2Flsw-returner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allnulled%2Flsw-returner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allnulled%2Flsw-returner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allnulled%2Flsw-returner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allnulled","download_url":"https://codeload.github.com/allnulled/lsw-returner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246122465,"owners_count":20726833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-03T11:16:08.380Z","updated_at":"2025-03-29T01:19:22.952Z","avatar_url":"https://github.com/allnulled.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lsw-returner\n\nAPI to return values through 1 outter function scope.\n\nBranch of [@allnulled/controlled-function](https://github.com/allnulled/controlled-function).\n\nAllows both:\n\n  - The **trascendent condition/if** pattern\n  - The **stuck loop/while** pattern, easying the **coliving combination** of others like:\n     - The **energetical while** pattern, like a being.\n     - The **timed-out while** pattern, like a shortcircuit.\n     - Probably others.\n\n## Installation\n\n```sh\nnpm i -s @allnulled/lsw-returner\n```\n\n## Importation\n\nIn node.js:\n\n```js\nrequire(\"@allnulled/lsw-returner\");\n```\n\nIn browser:\n\n```html\n\u003cscript src=\"node_modules/@allnulled/lsw-returner/controlled-function.js\"\u003e\u003c/script\u003e\n```\n\n## Why interests?\n\nThe thing is to be able to create **trascendent conditions** and **energetical loops**.\n\n## How?\n\nEl `ReturnControl` permite emitir un (signo de) `return` al controlador desde dentro del pipeo.\n\nEl `MutateControl` permite cambiar el estado del controlador (`ReturnController`) desde dentro del pipeo.\n\nEl `controller.hook(fn)` permite apendizar un middleware que el controlador (`ReturnController`) procesará después de cada step del pipeo.\n\nEl `controller.pipe(outputId, pipeNames)` lo que hace es:\n\n - Si algún step de la tubería returna un `MutateControl`, altera su propio `controller.properties` consecuentemente.\n - Si algún step de la tubería retorna un `ReturnControl`: devuelve `true`.\n    - Establece el valor del `ReturnControl` en la `controller.results[outputId]`. Para recuperarlo, `controller.solved(outputId)`.\n    - Devuelve `true`\n - Si no, devuelve `false`.\n\n### The TRASCENDENT-IF pattern\n\nEsto nos permite patrones como:\n\n\n```js\nconst id = \"output\";\nconst functions = {\n    stepOne() {\n        console.log(\"step 1\");\n    },\n    stepTwo() {\n        console.log(\"step 2\");\n        return new ReturnControl(\"Broken in step 2\");\n    },\n    stepThree() {\n        console.log(\"this is not gonna happen\");\n    }\n};\nconst names = [\"stepOne\", \"stepTwo\", \"stepThree];\ncontrol.reset().load(functions);\n// This sentence gives the functions to emit TRASCENDENT RETURNS in TRASCENDENT CONDITIONS:\nif(control.pipe(id, names)) return control.solved(id);\n```\n\nDe esta forma podemos rápidamente traspasar un `return` de una subllamada a la función que la llama.\n\nPodemos crear **condiciones supertrascendentes** con **retornos trascendentes**. Porque trascienden la función de arriba.\n\n### The STUCK-WHILE pattern\n\n```js\ncontrol.reset();\n// Iniciamos en 100 punto de energía:\ncontrol.prop({ cycles: 100 });\ncontrol.hook(c =\u003e {\n    if(c.properties.cycles === 0) {\n        // Implementamos la ley de no-energía:\n        return new ReturnControl(\"No more cycles\");\n    }\n});\ncontrol.load({\n    step1(c) {\n        return new MutateControl(c =\u003e {\n            return {\n                // Restamos 1 punto de energía en el step1:\n                cycles: c.properties.cicles - 1\n            };\n        });\n    }\n});\nwhile(!control.pipe(\"output\", [\"step1\"])) {\n    // @Intercycle code.\n}\n```\n\nDe esta forma, podemos crear **bucles energéticos**. Energéticos porque funcionan con energía, si la energía se agota, y tiene una ley implementada (que tienes que implementar, pueden ser energéticos o de otros tipos) para ello, el controlador mismo dejará de retornar `false` porque no ha habido **retornos trascendentes**, y retornará `true`, lo que rompería los bucles o desencadenaría los condicionales\n\n\n\n**NOTA:** Cuidado, en el ejemplo llamamos `control` al `controller` porque es más lógico desde fuera de ámbito.\n\n```js\nconst { ReturnController, ReturnControl, MutateControl } = ControlledFunction;\nconst controlledFunction = function () {\n\n  // Creando instancia:\n  const control = new ReturnController();\n\n  // Inicializando el estado:\n  control.reset();\n  \n  // Inicializando las propiedades:\n  control.prop({\n    cicles: 100\n  });\n  \n  // Inicializando el middleware de energía:\n  control.hook(c =\u003e {\n    if(c.properties.cicles === 0) {\n      return new ReturnControl(\"No more cicles\");\n    }\n  });\n  \n  // Inicializando funciones:\n  control.load({\n    step1() {\n      return new MutateControl(c =\u003e {\n        return {\n          cicles: c.properties.cicles - 1\n        };\n      });\n    },\n  });\n  \n  // Y luego puedes hacer así para crear artefactos con alcance limitado de vida:\n  let index = 0;\n  Ciclo_de_vida_en_repeticiones: {\n    while(!control.pipe(\"output\", [\"step1\"])) {\n      // @TOINJECT: intercycle code\n      console.log(\"Round: \" + (++index));\n    }\n  }\n\n  console.log(\"Finished cicles\");\n};\nconsole.log(controlledFunction());\n```\n\nWhat is happening here?\n\n1. `new ReturnController`. We create the basic instance of the API.\n2. `reset`. We unnecessarily reset `properties` and `results` of the instance.\n3. `prop`. We overwrite the `control.properties` object with new data.\n4. `hook`. This is a law. We push a function in `control.middlewares` so every time a pipe step is finished, this function is going to be called (unless a previous hook returns a `new ReturnControl` instance). You are also provided with `prehook` to prepend a middleware.\n5. `load`. This is the knowledge. Map of known functions. This way, we ensure *modularity* and *functional flatening*.\n6. `while + !control.pipe`. This expression is key. We say `until no energy` or `while energy`, then `keep steping` + `in loop`. This is the definition of life, more or less. That is why that expression is the key.\n\n\n\n\n## Usage\n\nThis is the test provided in source:\n\n```js\nrequire(__dirname + \"/controlled-function.js\");\n\ndescribe(\"ControlledFunction API Test\", function() {\n  \n  it(\"can work as expected with ReturnControl class\", async function() {\n    const { ReturnController, ReturnControl } = ControlledFunction;\n    const controlledFunction = function () {\n      const control = new ReturnController();\n      // Reseteando y cargando un nuevo conjunto de funciones\n      const knowledge = {\n        step1() {\n          return console.log(\"Happens 2!\");\n        },\n        step2() {\n          return new ReturnControl('step 2 Resolved');\n        },\n        step3() {\n          return console.log(\"No happens!\");\n        },\n        stepA() {\n          return console.log(\"Happens 5!\");\n        },\n        stepB() {\n          return new ReturnControl('step B Resolved');\n        },\n        stepC() {\n          return console.log(\"No happens!\");\n        }\n      };\n      control.reset().load(knowledge);\n      // Pasareleamos por los pipes usando la misma instancia para invocar y para acceder:\n      const output1 = (function() {\n        console.log(\"Happens 1!\");\n        if (control.pipe(\"output\", [\"step1\", \"step2\", \"step3\"])) {\n          return control.solved(\"output\");\n        }\n        console.log(\"No happens!\");\n      })();\n\n      if(output1 === \"step 2 Resolved\") {\n        console.log(\"Happens 3!\");\n      }\n\n      const output2 = (function() {\n        console.log(\"Happens 4!\");\n        if(control.pipe(\"output2\", [\"stepA\", \"stepB\", \"stepC\"])) {\n          return control.solved(\"output2\");\n        }\n        console.log(\"No happens!\");\n      })();\n\n      if(output2 === \"step B Resolved\") {\n        console.log(\"Happens 6!\");\n      }\n    };\n    controlledFunction();\n  });\n  \n  it(\"can work as expected with MutateControl class\", async function() {\n    const { ReturnController, ReturnControl, MutateControl } = ControlledFunction;\n    const controlledFunction = function () {\n      const control = new ReturnController();\n      // Inicializando el estado:\n      control.reset();\n      // Inicializando las propiedades:\n      control.prop({\n        cicles: 100\n      });\n      // Inicializando el middleware de energía:\n      control.hook(c =\u003e {\n        if(c.properties.cicles === 0) {\n          return new ReturnControl(\"No more cicles\");\n        }\n      });\n      // Inicializando funciones:\n      control.load({\n        step1() {\n          return new MutateControl(c =\u003e {\n            return {\n              cicles: c.properties.cicles - 1\n            };\n          });\n        },\n      });\n      let index = 0;\n      Ciclo_de_vida_en_repeticiones: {\n        while(!control.pipe(\"output\", [\"step1\"])) {\n          // @TOINJECT: intercycle code\n          console.log(\"Round: \" + (++index));\n        }\n      }\n      console.log(\"Finished cicles\");\n    };\n    console.log(controlledFunction());\n  });\n\n});\n```\n\n\n## Conclusion\n\nLet's see in the future. But I found this pattern useful because combining only 2 middlewares, I can get these 2 artifacts, from the basic `ReturnControl` API + the `MutateControl` API. The `MutateControl` API can be powerfull with `controller.hooks`, I think.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallnulled%2Flsw-returner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallnulled%2Flsw-returner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallnulled%2Flsw-returner/lists"}