{"id":23640940,"url":"https://github.com/pedromsilvapt/clui-live","last_synced_at":"2025-08-31T17:32:13.620Z","repository":{"id":57200937,"uuid":"172791807","full_name":"pedromsilvapt/clui-live","owner":"pedromsilvapt","description":"Simply update text on the terminal, even after subsequent output is written","archived":false,"fork":false,"pushed_at":"2024-11-16T07:47:00.000Z","size":237,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-17T19:47:00.651Z","etag":null,"topics":["ansi-codes","console","progress","terminal","ui"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedromsilvapt.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}},"created_at":"2019-02-26T21:15:49.000Z","updated_at":"2024-06-28T10:23:29.000Z","dependencies_parsed_at":"2022-09-15T11:22:27.975Z","dependency_job_id":null,"html_url":"https://github.com/pedromsilvapt/clui-live","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/pedromsilvapt%2Fclui-live","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromsilvapt%2Fclui-live/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromsilvapt%2Fclui-live/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedromsilvapt%2Fclui-live/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedromsilvapt","download_url":"https://codeload.github.com/pedromsilvapt/clui-live/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231610637,"owners_count":18400207,"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":["ansi-codes","console","progress","terminal","ui"],"created_at":"2024-12-28T09:53:27.883Z","updated_at":"2024-12-28T09:53:28.321Z","avatar_url":"https://github.com/pedromsilvapt.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# clui-live\n\u003e Simply update text on the terminal, even after subsequent output is written\n\n![Running the demo file demo/demo.ts](demo/demo.gif)\n\u003e Demo code available at [demo/demo.ts](demo/demo.ts)\n\n## Installation\n```shell\nnpm install --save clui-live\n```\n\n## Usage\n\nThere are two ways to use this method. The first is to just use a single `LiveArea` and update it any time by calling the `LiveArea#write()` method. With this method, only one `LiveArea` can be active at each time.\n```typescript\nimport { LiveArea } from 'clui-live';\n\nconst area = new LiveArea();\n\nfor ( let i = 0; i \u003c 100; i++ ) {\n    area.write( 'Progress' + i );\n\n    await sleepRandom();\n}\n\n// Closing the `LiveArea` will keep any text that was written to it last on screen and prevent any further updates. To avoid that, call area.clear().close() instead\narea.close();\n```\n\nBut sometimes we want to update more than one thing at the same time, and that's the really hard part. This module makes it easy though.\nJust create a `LiveContainer` and add as many `LiveArea`s to it as needed. \n\n\u003e **Note** that when using a container, you can only use `LiveArea`s that belong to it. Using others will result in unexpected behavior.\n\n```typescript\nimport { LiveContainer, LiveArea } from 'clui-live';\n\nconst container = new LiveContainer();\n\n// How to add an area to a container\nconst area1 = new LiveArea();\n\ncontainer.addLiveArea( area );\n\n// A shortcut for that is\nconst area2 = container.createLiveArea();\n\nfor ( let i = 0; i \u003c 100; i++ ) {\n    // Update each area in an alternated way. They will both be updated in place\n    // If the first area grew (or shrinked), the vertical positions of all areas below would adjust accordingly\n    if ( i % 2 == 0 ) {\n        area1.write( 'Progress' + i );\n    } else {\n        area2.write( 'Progress' + i * 2 );\n    }\n\n    await sleepRandom();\n}\n\n// Also, since the terminal doesn't allow to update text outside the viewport (when the text is above the buffer and you would\n// have to scroll to see it), and so when any LiveArea falls off view, it's state is \"forgotten\" and when it updates next it \n// will be appended at the bottom.\n```\n\nBut what about when other people use `console.log`? Doesn't that wreck things? Yes, but there is a simple fix for that: simply call `LiveContainer#hook()` when creating it.\n\n```typescript\nconst container = new LiveContainer().hook();\n```\n\nSometimes you don't want to have to create a container and pass around references to it. In those instances you can use the global container (one that is lazily created when it is first used) by calling the `hook()` method on each live area (instead of calling it on a container) like so:\n```typescript\nconst area1 = new LiveArea().hook();\nconst area2 = new LiveArea().hook();\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedromsilvapt%2Fclui-live","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedromsilvapt%2Fclui-live","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedromsilvapt%2Fclui-live/lists"}