{"id":15497236,"url":"https://github.com/jwerle/regl-combine","last_synced_at":"2025-06-11T19:33:48.705Z","repository":{"id":57352533,"uuid":"104906080","full_name":"jwerle/regl-combine","owner":"jwerle","description":"Compose hundreds or thousands of regl commands without worrying about \"too much recursion\" or \"maximum call stack size exceeded\" errors.","archived":false,"fork":false,"pushed_at":"2017-10-11T22:21:05.000Z","size":15,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-19T14:54:02.656Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jwerle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-26T15:51:22.000Z","updated_at":"2020-07-02T16:54:09.000Z","dependencies_parsed_at":"2022-09-16T08:11:25.725Z","dependency_job_id":null,"html_url":"https://github.com/jwerle/regl-combine","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwerle%2Fregl-combine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwerle%2Fregl-combine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwerle%2Fregl-combine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwerle%2Fregl-combine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwerle","download_url":"https://codeload.github.com/jwerle/regl-combine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250329051,"owners_count":21412745,"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":"2024-10-02T08:32:15.991Z","updated_at":"2025-04-22T21:33:29.825Z","avatar_url":"https://github.com/jwerle.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"regl-combine\n============\n\nCompbine hundreds or thousands of regl commands without worrying about\n[\"too much recursion\" or \"Maximum call stack size exceeded\"][tmm] errors. This module\nwill group and segment multiple sequential regl calls into a single regl function\nwhile also allowing for intermediate \"middleware\" functions.\n\n## Install\n\n```sh\n$ npm install regl-combine\n```\n\n## Why?\n\nJavascript recursion (or stack depth)\n[limits](https://rosettacode.org/wiki/Find_limit_of_recursion#JavaScript) vary\nfrom browser to browser.\n\nThey can cause errors like\n\n```js\nInternalError: too much recursion\n```\n\nor\n\n```js\nRangeError: Maximum call stack size exceeded.\n```\n\nwhich can happen quite easily if you build many small regl components\nthat inject contexts, provide shaders, and more. This module allows you\nto create small components and compose them together without the\noverhead or worry of recursion depth and stack overflows.\n\n## How?\n\nThis module composes regl commands together by capturing the constructor\noptions used to create the commands and merging them into a single object\nthat is used to create the new returned command. Commands are grouped\ntogether and are only segmented when a non-regl command is reached.\n\nThe following will segment the regl commands and create 4 function\ngroups where *group 1* contains `command1, command2, command3`,\n*group 2* contains `middleware1`, *group 3* contains `middleware2`,\nand *group 4* contains `command4`, and `command5`.\n\n```js\ncombine(\n    regl,\n    command1,\n    command2,\n    command3,\n    middleware1,\n    middleware2,\n    command4,\n    command5)\n```\n\n## Caveats\n\n### Parent Context Dependencies\n\nIn order to mitigate parent context dependencies, such as a `command2`\ndynamic context property depending on the result of a `command1` dynamic\ncontext property, you must ensure that `command2` is not \"combined\"\ndirectly with `command1` because the order in which their context\nproperties cannot be guaranteed. You can achieve this by doing the\nfollowing:\n\n```js\ncombine(regl, command1, (...args) =\u003e command2(...args))\n```\n\nwhich will produce two distinct groups.\n\n### Context Property Conflict\n\nIf a dynamic or static context property in `command2` exists as a\ndynamic or static context property in `command1`, `command1` will\noverwrite the context property in `command1` and void it from creation.\n\n## API\n\n### wrap(regl) -\u003e regl\n\nThis function accepts a regl constructor function and returns a new\nregl function that when invoked returns a regl command that injects the\noptions used to create it as an injected context propetry `reglOptions`.\nThis is needed for `combine()` to work properly if you provide it\nalready created regl commands. Otherwise, you will have to expose regl\ncommand options to `combine()` only.\n\n```js\nconst { wrap } = require('regl-combine')\nconst regl = wrap(require('regl')())\n```\n\n**note:** *If regl isn't wrapped with this function then the only input\nthat will work with `combine()` are regl constructor options\nobjects.*\n\n### combine(regl, commands) -\u003e Function\n\nThis function accepts a regl constructor function and an array of\ncommands. An element in the commands array may be a constructed regl\ncommand if regl was previously wrapped with `wrap()`. An element in\nthe comamnds array may also be a regl constructor options\nobject, which is required if regl wasn't wrapped with the `wrap()`\nfunction call.\n\n```js\nconst command = combine(regl, [\n  regl({ vert: ` ... ` }),\n  { frag: ` ... `},\n  { attributes: {position [ ... ]} }\n])\n```\n\n**note:** *If regl isn't wrapped with `wrap()` then the only input\nthat will work with this function are regl constructor options objects.*\n\n## Example\n\nThe following example composes several regl command functions into a single\nfunction.\n\n```js\nconst { combine, wrap } = require('regl-combine')\nconst regl = wrap(require('regl')()) // required\n\nconst drawTriangle = combine(regl, [\n  regl({\n    frag: `\n      precision mediump float;\n      uniform vec4 color;\n      void main() {\n        gl_FragColor = color;\n      }\n    `\n  }),\n\n  regl({\n    vert: `\n      precision mediump float;\n      attribute vec2 position;\n      void main() {\n        gl_Position = vec4(position, 0, 1);\n      }\n    `\n  }),\n\n  regl({\n\t\t attributes: {\n       position: regl.buffer([\n         [-2, -2],\n         [4, -2],\n         [4,  4]\n       ])\n     }\n  }),\n\n  regl({\n    uniforms: {\n      color: regl.prop('color')\n    }\n  }),\n\n  regl({\n    count: 3\n\t})\n])\n\nregl.frame(({time}) =\u003e {\n  drawTriangle({\n    color: [\n      Math.cos(time * 0.001),\n      Math.sin(time * 0.0008),\n      Math.cos(time * 0.003),\n      1\n    ]\n  })\n})\n```\n\n## License\n\nMIT\n\n[regl]: https://github.com/regl-project/regl\n[tmm]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Too_much_recursion\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwerle%2Fregl-combine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwerle%2Fregl-combine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwerle%2Fregl-combine/lists"}