{"id":19451260,"url":"https://github.com/thekashey/react-queue","last_synced_at":"2025-09-23T15:31:28.278Z","repository":{"id":57343041,"uuid":"140159814","full_name":"theKashey/react-queue","owner":"theKashey","description":"⛓ Declarative task scheduler","archived":false,"fork":false,"pushed_at":"2018-11-03T02:12:45.000Z","size":127,"stargazers_count":23,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-11T06:51:53.867Z","etag":null,"topics":["exection","queue","scheduler","sequence","task"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/theKashey.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":"2018-07-08T10:56:59.000Z","updated_at":"2023-04-28T10:50:23.000Z","dependencies_parsed_at":"2022-09-16T07:51:18.318Z","dependency_job_id":null,"html_url":"https://github.com/theKashey/react-queue","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theKashey%2Freact-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theKashey%2Freact-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theKashey%2Freact-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theKashey%2Freact-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theKashey","download_url":"https://codeload.github.com/theKashey/react-queue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233984694,"owners_count":18761311,"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":["exection","queue","scheduler","sequence","task"],"created_at":"2024-11-10T16:41:01.772Z","updated_at":"2025-09-23T15:31:22.905Z","avatar_url":"https://github.com/theKashey.png","language":"TypeScript","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eReact ⏳ Queue\u003c/h1\u003e\n  \u003cbr/\u003e\n  A declarative scheduler\n  \u003cbr/\u003e\n    \n  \u003ca href=\"https://www.npmjs.com/package/react-queue\"\u003e\n   \u003cimg src=\"https://img.shields.io/npm/v/react-queue.svg?style=flat-square\" /\u003e\n  \u003c/a\u003e\n  \n  \u003ca href=\"https://codecov.io/github/theKashey/react-queue\"\u003e\n     \u003cimg src=\"https://img.shields.io/codecov/c/github/theKashey/react-queue.svg?style=flat-square\" /\u003e\n   \u003c/a\u003e\n   \n   \u003ca href=\"https://travis-ci.org/theKashey/react-queue\"\u003e\n     \u003cimg src=\"https://img.shields.io/travis/theKashey/react-queue/master.svg\"\u003e\n   \u003c/a\u003e\n\n  \u003cbr/\u003e  \n\u003c/div\u003e  \n\nTo schedule events one-after another. To play _lazy_ animations in order, correlated with their position on the page.\n\n# API\n## Scheduler\n- `Scheduler` - task scheduler. Collect tasks and execute them with `stepDelay` between in the `priority` order.\n  - `stepDelay` - delay between two events\n  - `[reverse]` - reverses the queue\n  - `[source]` - priority calculation function\n  - `[withSideEffect]` - indicates that Scheduler has  side effects, and enabled auto update(re-render) on task execution. __Affects performance__. \n  - `[observe]` - cache buster property. Scheduler sorts queue only on element change, in case of using `source` you might need \"inform\"\n  - `[noInitialDelay]` - remove delay from the first task.\n  - `[disabled]` - disables ticking\n  it to resort queue.\n  \n  \n```js\nimport {Scheduler} from 'react-queue';\n\n\u003cScheduler stepDelay={1000} \u003e\n  {channel =\u003e .... }\n\u003c/Scheduler\u003e\n\n// use source to create priority based on element position on the page\n\u003cScheduler stepDelay={1000} source={ ({ref}) =\u003e ref.getBoundingClientRect().top} /\u003e\n```\n`channel` also provides `channel.reset()` function, to clear all `executed` bits, and start everything from the scratch.\n\n## Queue\n- `Queue` - queued event. It just got executed, nothing more. \"When\", in \"when order\" - that is the question.\n  - `channel` - channel acquired from Scheduler\n  - `callback` - callback to execute. In case if callback will return a number, or a promise resolving to number, it would be used to _shift_ delay to the next step.\n  - `priority` - pririty in queue, where 0-s should be executed before 1-s.\n  - [`shift`] - sub priority change. `shift={-1}` will swap this task with previous sibling.\n  - [`disabled`] - holds queue execution (sets priority to Infitity).\n  next tick will be moved by {number}ms. In case of just Promise - next tick will wait to for promise to be resolved.\n  - [`children`] - any DOM node, Queue will pass as `ref` into scheduler's `source` \n\n```js\nimport {Scheduler, Queue} from 'react-queue';\n\n\u003cScheduler stepDelay={1000} \u003e\n    {channel =\u003e \n      \u003cQueue channel={channel} priority={1} callback={doSomething} /\u003e\n      \n      // this one will report `ref` to the scheduler\n      \u003cQueue channel={channel} callback={doSomething}\u003e\n        \u003cdiv\u003e42\u003c/div\u003e\n      \u003c/Queue\u003e  \n         \n      \u003cQueue channel={channel} callback={() =\u003e this.setState({x: 1})}\u003e\n        \u003cdiv style={{position: 'absolute', top: 50}}\u003e 1 {x == 1 \u0026\u0026 \"selected!!\"}\u003c/div\u003e\n      \u003c/Queue\u003e\n\n      \u003cQueue channel={channel} callback={() =\u003e this.setState({x: 2})}\u003e\n        \u003cdiv style={{position: 'absolute', top: 10}}\u003e 2 {x == 2 \u0026\u0026 \"selected!!\"}\u003c/div\u003e\n      \u003c/Queue\u003e\n\n      \u003cQueue channel={channel} callback={() =\u003e this.setState({x: 3})}\u003e\n        \u003cdiv style={{position: 'absolute', top: 100}}\u003e 3 {x == 3 \u0026\u0026 \"selected!!\"}\u003c/div\u003e\n      \u003c/Queue\u003e\n    }\n\u003c/Scheduler\u003e\n```\n\n## FlattenPriorityGroup\n- `FlattenPriorityGroup` - \"flattens\" all priority changes inside. Could help manage nested tasks.\n  - `channel` - channel acquired from Scheduler\n  - [`children`] - render function  \n  - [`priority`] - task priority. Would be set for all nested tasks.\n  - [`shift`] - sub priority change. `shift={-1}` will swap this task with previous sibling.\n  - [`disabled`] - holds queue execution (sets priority to Infitity).\n  \nIn the next example executing order would be - 2, 1, 4, 3.\n```js\n \u003cScheduler stepDelay={1000} \u003e\n   {channel =\u003e (\n      \u003cReact.Fragment\u003e\n          \u003cFlattenPriorityGroup channel={channel}\u003e\n          { pchannel =\u003e [\n            \u003cPromised priority={1}\u003e1\u003c/Promised\u003e,\n            \u003cPromised priority={0}\u003e2\u003c/Promised\u003e\n          ]}\n          \u003c/FlattenPriorityGroup\u003e\n          \u003cFlattenPriorityGroup channel={channel}\u003e\n          { pchannel =\u003e [\n             \u003cPromised priority={1}\u003e3\u003c/Promised\u003e,\n             \u003cPromised priority={0}\u003e4\u003c/Promised\u003e\n          ]}\n          \u003c/FlattenPriorityGroup\u003e\n      \u003c/React.Fragment\u003e\n   )}  \n\u003c/Scheduler\u003e   \n``` \n\n\n## Promised\n- `Promised` - promised event. Once it started it should all `done` when it's done. This is a more complex form of queue, with much stronger feedback.\n  - `channel` - channel acquired from Scheduler\n  - [`children`] - render function\n  - [`autoexecuted`] - auto \"done\" the promised. boolean or number. If number - would be used to shift next step.\n  - [`priority`] - task priority. Lower goes first\n  - [`shift`] - sub priority change. `shift={-1}` will swap this task with previous sibling.\n  - [`disabled`] - holds queue execution (sets priority to Infitity).\n```js\nimport {Scheduler, Promised} from 'react-queue';\nimport {Trigger} from 'recondition';\n\n\u003cScheduler stepDelay={1000} \u003e\n    {channel =\u003e \n      \u003cPromised channel={channel} priority={1}\u003e\n      {({executed, active, done, forwardRed}) =\u003e (\n        \u003cdiv ref={forwardRed}\u003e\n          {executed \u0026\u0026 \"task is done\"}\n          {active \u0026\u0026 \"task is running\"}\n          // don't call anything in render\n          \u003cTrigger when={active} then={() =\u003e done(42/* make next step by 42ms later*/)}/\u003e\n        \u003c/div\u003e\n      )\n      \u003c/Promised\u003e      \n    }\n\u003c/Scheduler\u003e\n\n// this code has the same behavior\n\u003cScheduler stepDelay={1000} \u003e\n    {channel =\u003e \n      \u003cPromised channel={channel} priority={1} autoexecuted={42}\u003e\n      {({executed, active, done, forwardRed}) =\u003e (\n        \u003cdiv ref={forwardRed}\u003e\n          {executed \u0026\u0026 \"task is done\"}\n          {active \u0026\u0026 \"task is running\"}          \n        \u003c/div\u003e\n      )\n      \u003c/Promised\u003e      \n    }\n\u003c/Scheduler\u003e\n```  \n\nFor example - animation - it will execute one `Promised` after another, and triggering waterfall animation.\n```js\nimport {Scheduler, Promised} from 'react-queue';\nimport {Trigger} from 'recondition';\n\n\u003cScheduler stepDelay={300} \u003e\n    {channel =\u003e \n      \u003cPromised channel={channel} autoexecuted\u003e\n      {({executed, active, fired}) =\u003e (\u003cdiv style={styles[executed||active ? styleA : styleB}\u003eLine1\u003c/div\u003e)}\n      \u003c/Promised\u003e      \n      \n      \u003cPromised channel={channel} autoexecuted\u003e\n      {({executed, active, fired}) =\u003e (\u003cdiv style={styles[executed||active ? styleA : styleB}\u003eLine2\u003c/div\u003e)}\n      \u003c/Promised\u003e      \n\n      \u003cPromised channel={channel} autoexecuted\u003e\n      {({executed, active, fired}) =\u003e (\u003cdiv style={styles[executed||active ? styleA : styleB}\u003eLine3\u003c/div\u003e)}\n      \u003c/Promised\u003e      \n\n      \u003cPromised channel={channel} autoexecuted\u003e\n      {({executed, active, fired}) =\u003e (\u003cdiv style={styles[executed||active ? styleA : styleB}\u003eLine4\u003c/div\u003e)}\n      \u003c/Promised\u003e      \n    }\n\u003c/Scheduler\u003e\n```  \n\n## Examples\n[react-remock + react-queue](https://codesandbox.io/s/q89q2jm8qw) - simple and complex example - \"jquery like\" image lazy loading with queued execution.\n[react-visibility-sensor + react-queue](https://codesandbox.io/s/6xvr42y6xr) - animate element appearance based on visibility check.\n\n# Licence\n MIT\n \n \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthekashey%2Freact-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthekashey%2Freact-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthekashey%2Freact-queue/lists"}