{"id":17559841,"url":"https://github.com/a-bentofreire/jstracetoix","last_synced_at":"2026-01-24T14:03:49.066Z","repository":{"id":257823755,"uuid":"871673127","full_name":"a-bentofreire/jstracetoix","owner":"a-bentofreire","description":"A JavaScript expression tracer for debugging React or Vue components, arrow functions, method chaining and expressions","archived":false,"fork":false,"pushed_at":"2024-10-25T20:46:06.000Z","size":195,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-31T03:29:09.545Z","etag":null,"topics":["debug","debugger","expressions","javacript","react","reactjs","tracer","vue","vuejs"],"latest_commit_sha":null,"homepage":"https://www.devtoix.com/en/projects/jstracetoix","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/a-bentofreire.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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,"zenodo":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"abentofreire","thanks_dev":null,"custom":null}},"created_at":"2024-10-12T16:08:30.000Z","updated_at":"2024-11-13T06:16:12.000Z","dependencies_parsed_at":"2025-04-24T05:42:29.306Z","dependency_job_id":"475ab907-021a-4184-b4a5-bfca0232a0f1","html_url":"https://github.com/a-bentofreire/jstracetoix","commit_stats":null,"previous_names":["a-bentofreire/jstracetoix"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/a-bentofreire/jstracetoix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-bentofreire%2Fjstracetoix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-bentofreire%2Fjstracetoix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-bentofreire%2Fjstracetoix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-bentofreire%2Fjstracetoix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a-bentofreire","download_url":"https://codeload.github.com/a-bentofreire/jstracetoix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a-bentofreire%2Fjstracetoix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28729411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["debug","debugger","expressions","javacript","react","reactjs","tracer","vue","vuejs"],"created_at":"2024-10-21T11:07:53.547Z","updated_at":"2026-01-24T14:03:49.036Z","avatar_url":"https://github.com/a-bentofreire.png","language":"JavaScript","funding_links":["https://buymeacoffee.com/abentofreire","https://www.paypal.com/donate/?business=MCZDHYSK6TCKJ\u0026no_recurring=0\u0026item_name=Support+Open+Source\u0026currency_code=EUR"],"categories":[],"sub_categories":[],"readme":"# Description\n\n![NPM Version](https://img.shields.io/npm/v/jstracetoix)\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/a-bentofreire/jstracetoix/.github%2Fworkflows%2Fnpm-package.yml)\n\n[JsTraceToIX](https://www.devtoix.com/en/projects/jstracetoix) is an expression tracer for debugging React or Vue components, arrow functions, method chaining, and expressions in general.\n\nCode editors typically cannot set breakpoints within such expressions, requiring significant code changes to debug.\n\nJsTraceToIX provides a straightforward solution to this problem.\n\nIt was designed to be simple, with easily identifiable functions that can be removed once the bug is found.\n\nJsTraceToIX has 2 major functions:\n- `c__` capture the input of an expression input. ex: `c__(x)`\n- `d__` display the result of an expression and all the captured inputs. ex: `d__(c__(x) + c__(y))`\n\nAnd 2 optional functions:\n- `init__` initializes display format, output stream, multithreading, enable/disable processing `c__`, `d__` and `t__`.\n- `t__` defines a name for the current thread.\n\nIf you find this project useful, please, read the [Support this Project](https://www.devtoix.com/en/projects/jstracetoix#support-this-project) on how to contribute.\n\n## Features\n\n- No external dependencies.\n- Runs on Node.js (es6 module and commonjs), browsers, React components, and Vue components.\n- Minimalist function names that are simple and short.\n- Traces Results along with Inputs.\n- Configurable Result and Input naming.\n- Outputs to console.debug on browsers, React and Vue, and to a stream on Node.js.\n- Supports multiple levels.\n- Capture Input method with customizable `allow` and `name` callbacks.\n- Display Result method with customizable `allow`, `before`, and `after` callbacks.\n- Support to globally disable the processing `c__`, `d__`, `t__`.\n- Result and Inputs can be reformatted and overridden.\n- Configurable [formatting](https://www.devtoix.com/en/projects/jstracetoix#formatting) at both global and function levels.\n- Supports [Multithreading](https://www.devtoix.com/en/projects/jstracetoix#multithreading).\n\n## Python Version\n\nThis package is also available in Python for similar debugging purposes. The Python version, called **PyTraceToIX**, allows tracing input and output values during debugging and can be found on [PyTraceToIX](https://www.devtoix.com/en/projects/pytracetoix).\n\nIt offers the same `c__` and `d__` tracing functionality for Python, providing a seamless debugging experience across both languages.\n\n## Installation\n\n| Environment | Require Installation |\n| ----- | ------------------- |\n| Browser | No  |\n| Node.js | Yes |\n| React | Optional |\n| Vue | Yes |\n\n```bash\nnpm install jstracetoix --save-dev\n```\n\n## React Usage\n\nIn this example:\n- `cityTax` arrow function captures the input price and names it 'Price'.\n- On `ShoppingList` function:\n  - `c__` captures the title in the first `\u003ctd\u003e`.\n  - `c__` captures the output of the cityTax and names it `CityTax` in the 2nd `\u003ctd\u003e`.\n  - `d__` displays the aggregated information in a single line: title, price, cityTax, total Price.\n\nThe `d__` will generate this output:\n\n```plaintext\ni0:`Rice` | Price:`10` | CityTax:`5` | _:`15`\ni0:`Coffee` | Price:`30` | CityTax:`15` | _:`45`\ni0:`Shoes` | Price:`100` | CityTax:`15` | _:`115`\n```\n\n```javascript\nimport './App.css';\n// Without local installation\nimport { c__, d__ } from 'https://cdn.jsdelivr.net/npm/jstracetoix@latest/component/jstracetoix.mjs';\n\n// If it's installed locally via \"npm install jstracetoix --save-dev\"\n// import { c__, d__ } from 'jstracetoix/component';\n\nconst cityTax = (price) =\u003e c__(price, {name: 'Price'}) \u003e 20 ? 15 : 5;\nconst products = [\n    { title: 'Rice', price: 10, id: 1 },\n    { title: 'Coffee', price: 30, id: 2 },\n    { title: 'Shoes', price: 100, id: 3 },\n];\n\nfunction ShoppingList() {\n    const listItems = products.map(product =\u003e\n        \u003ctr key={product.id}\u003e\n            \u003ctd\u003e{c__(product.title)}\u003c/td\u003e\n            \u003ctd\u003e{d__(product.price + c__(cityTax(product.price), { name: 'CityTax' }))}\u003c/td\u003e\n        \u003c/tr\u003e\n    );\n\n    return (\n        \u003ctable\u003e\u003ctbody\u003e{listItems}\u003c/tbody\u003e\u003c/table\u003e\n    );\n}\n\nfunction App() {\n    return (\n        \u003cdiv className=\"App\"\u003e\n            \u003cheader className=\"App-header\"\u003e\n                \u003cShoppingList /\u003e\n            \u003c/header\u003e\n        \u003c/div\u003e\n    );\n}\n\nexport default App;\n```\n\n## Browser Usage\n\nThis example is similar to the React example, but instead the products are collected from a remote JSON.\n- `c__` captures the price and the tax, and names `tax` the 2nd input.\n- `d__` displays the aggregate information if `tax` is 0.15.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\n\u003chead\u003e\n  \u003cmeta charset=\"UTF-8\"\u003e\n  \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n  \u003ctitle\u003eProduct List\u003c/title\u003e\n  \u003cscript src=\"https://cdn.jsdelivr.net/npm/jstracetoix@latest/browser/jstracetoix.js\"\u003e\u003c/script\u003e\n  \u003cscript src=\"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js\"\u003e\u003c/script\u003e\n  \u003cstyle\u003e\n    table { width: 50%; border-collapse: collapse; margin: 20px auto; }\n    th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }\n    th { background-color: #f2f2f2; }\n  \u003c/style\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n  \u003ch2 style=\"text-align:center;\"\u003eProduct List\u003c/h2\u003e\n  \u003ctable id=\"productTable\"\u003e\n    \u003cthead\u003e\n      \u003ctr\u003e\n        \u003cth\u003eProduct Name\u003c/th\u003e\n        \u003cth\u003ePrice\u003c/th\u003e\n      \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\u003c/tbody\u003e\n  \u003c/table\u003e\n  \u003cscript\u003e\n    const tax = (price) =\u003e price \u003e 40 ? 0.15 : 0.10;\n\n    axios.get('https://cdn.jsdelivr.net/gh/a-bentofreire/jstracetoix@latest/examples/products.json')\n      .then(function (response) {\n        const products = response.data;\n        const tableBody = document.querySelector('#productTable tbody');\n        products.forEach(product =\u003e {\n          const row = document.createElement('tr');\n          row.innerHTML = `\u003ctd\u003e${c__(product.name)}\u003c/td\u003e`\n            + `\u003ctd\u003e$${d__(c__(product.price) * (1 + c__(tax(product.price), { name: 'tax' })),\n              { allow: (data) =\u003e data['tax'] === 0.15 }).toFixed(2)}\u003c/td\u003e`;\n          tableBody.appendChild(row);\n        });\n      })\n      .catch(function (error) {\n        console.error('Error fetching the product list:', error);\n      });\n  \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Vue Usage\n\n- This example is similar to the React example.\n\n```html\n\u003ctemplate\u003e\n  \u003cdiv class=\"App\"\u003e\n    \u003cheader class=\"App-header\"\u003e\n      \u003ctable\u003e\n        \u003ctbody\u003e\n          \u003ctr v-for=\"product in products\" :key=\"product.id\"\u003e\n            \u003ctd\u003e{{ c__(product.title) }}\u003c/td\u003e\n            \u003ctd\u003e{{ d__(product.price + c__(cityTax(product.price), { name: 'CityTax' })) }}\u003c/td\u003e\n           \u003c/tr\u003e\n        \u003c/tbody\u003e\n      \u003c/table\u003e\n    \u003c/header\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport { c__, d__ } from 'jstracetoix/component'\n\nexport default {\n  name: 'App',\n  data() {\n    return {\n      products: [\n        { title: 'Rice', price: 10, id: 1 },\n        { title: 'Coffee', price: 30, id: 2 },\n        { title: 'Shoes', price: 100, id: 3 },\n      ]\n    };\n  },\n  methods: {\n    c__(value, options = {}) { return c__(value, options); },\n    d__(value, options = {}) { return d__(value, options); },\n    cityTax(price) {\n      return c__(price, { name: 'Price' }) \u003e 20 ? 15 : 5;\n    }\n  }\n};\n\u003c/script\u003e\n\n\u003cstyle\u003e\n.App {\n  text-align: center;\n}\n\n.App-header {\n  background-color: #282c34;\n  padding: 20px;\n  color: white;\n}\n\u003c/style\u003e\n```\n\n## Node.js Usage\n\n| Format | Usage |\n|-|-|\n| es6 module | `import { c__, d__ } from 'jstracetoix'` |\n| commonjs | `const { c__, d__ } = require('jstracetoix');` |\n\nIn this example:\n- `c__`.`allow()` - overrides the input value being debugged when value \u003e 40.00,  \n  for other values it doesn't captures the input.\n- `d__`.`allow()` - overrides the result value being debugged.\n- `d__`.`after()` - stops the program after displaying the result and the captured fields.\n\n```javascript\n// from a es6 module\nimport { c__, d__ } from 'jstracetoix';\n// from a \"commonjs\" file\n// const { c__, d__ } = require('jstracetoix');\n\nconst products = [\n    { \"name\": \"Smartphone 128GB\", \"price\": 699.00 },\n    { \"name\": \"Coffee Maker\", \"price\": 49.99 },\n    { \"name\": \"Electric Toothbrush\", \"price\": 39.95 },\n    { \"name\": \"4K Ultra HD TV\", \"price\": 999.99 },\n    { \"name\": \"Gaming Laptop\", \"price\": 1299.00 }];\n\nconst factor = (price) =\u003e price \u003c 1000 ? 1.10 : 1;\n\nconst prices = d__(products.map(product =\u003e c__(product.price,\n    {\n        allow: (index, name, value) =\u003e value \u003e 40.00 ?\n            Math.floor(value * factor(value)) : false,\n        name: product.name.substring(0, 10)\n    })), {\n    allow: (data) =\u003e data._.map((v, i) =\u003e `${i}:${v}`),\n    after: (data) =\u003e process.exit() // exits after displaying the results\n});\n// Smartphone:`768` | Coffee Mak:`54` | 4K Ultra H:`1099` | Gaming Lap:`1299` | _:`[\"0:699\",\"1:49.99\",\"2:39.95\",\"3:999.99\",\"4:1299\"]`\n\n// this code is unreachable\nfor (const price in prices) {\n    let value = price;\n}\n```\n\n## Detailed Usage and Examples\n\n```javascript\nimport { c__, d__, init__, t__ } from 'jstracetoix';\n\nlet [x, y, w, k, u] = [1, 2, 3, 4 + 4, (x) =\u003e x];\n\n// Expression evaluation\nlet z = x + y * w + (k * u(5));\n\n// Display expression result without inputs\nz = d__(x + y * w + (k * u(5)));\n// Output:\n// _:`47`\n\n// Display expression result with inputs\nz = d__(c__(x) + y * c__(w) + (k * u(5)));\n// Output:\n// i0:`1` | i1:`3` | _:`47`\n\n// Display expression result with nested inputs\nz = d__(c__(x) + y * c__(w) + d__(k * c__(u(5), { level: 1 })));\n// Output:\n// i0:`5` | _:`40`\n// i0:`1` | i1:`3` | _:`47`\n\n// Arrow function\nlet f = (x, y) =\u003e x + (y + 1);\nf(5, 6);\n\n// Display Arrow function result and inputs\nf = (x, y) =\u003e d__(c__(x) + c__(y + 1));\nf(5, 6);\n// Output:\n// i0:`5` | i1:`7` | _:`12`\n\n// Display Arrow function inputs and result with custom input and result names\nf = (x, y) =\u003e d__(c__(x, { name: 'x' }) + c__(y + 1, { name: 'y+1' }), { name: 'f' });\nf(5, 6);\n// Output:\n// x:`5` | y+1:`7` | f:`12`\n\n// Method chaining\nlet l = [[10, 20], [30, 40]].map(([x, y]) =\u003e 5 * y * x);\n\n// Display method chaining with custom input and result names\nl = d__([[10, 20], [30, 40]].map(([x, y]) =\u003e\n    5 * c__(y, { name: `y${y}` }) * c__(x, { name: (index) =\u003e `v${index}` })\n));\n// Output:\n// y20:`20` | v1:`10` | y40:`40` | v3:`30` | _:`[1000, 6000]`\n\n// Conditional display based on input count\nd__(c__(x) + c__(y), { allow: (data) =\u003e data.input_count__ === 2 });\n// Output:\n// i0:`1` | i1:`2` | _:`3`\n\n// Conditional display based on first input value\nd__(c__(x) + c__(y), { allow: (data) =\u003e data.i0 === 10.0 });\n// No output\n\n// Conditional display with override based on input count\nd__(c__(x, { allow: (index, name, value) =\u003e value \u003e 10 }) + c__(y), {\n    allow: (data) =\u003e data.allow_input_count__ === 2\n});\n// No output\n\n// Method chaining with custom condition before display\nd__(['10', '20'].map(x =\u003e c__(x)), { before: (data) =\u003e data.output__.includes('10') });\n// Output:\n// i0:`10` | i1:`20` | _:`[\"10\",\"20\"]`\n\n\n// Method chaining with condition and after-call\nd__(['10', '20'].map(x =\u003e c__(x)), {\n    allow: (data) =\u003e data.allow_input_count__ === 2,\n    after: (data) =\u003e callAfter(data) ? \"\" : \"\"\n});\n// Output:\n// i0:`10` | i1:`20` | _:`[\"10\",\"20\"]`\n\n// Method chaining with allow input override\nd__([['10', '20'], ['30', '40'], ['50', '60']].map((x) =\u003e c__(x, { allow: (index, name, value) =\u003e value[0] })));\n// Output:\n// i0:`10` | i1:`30` | i2:`50` | _:`[[\"10\",\"20\"],[\"30\",\"40\"],[\"50\",\"60\"]]`\n\n// Method chaining with allow result override\nd__([['10', '20'], ['30', '40'], ['50', '60']].map((x) =\u003e c__(x)), { allow: (data) =\u003e data._.slice(0, 2) });\n// Output:\n// i0:`[\"10\",\"20\"]` | i1:`[\"30\",\"40\"]` | i2:`[\"50\",\"60\"]` | _:`[[\"10\",\"20\"],[\"30\",\"40\"]]`\n\n// Chain class with map and filter methods\nclass Chain {\n    constructor(data) {\n        this.data = data;\n    }\n\n    map(func) {\n        this.data = this.data.map(func);\n        return this;\n    }\n\n    filter(func) {\n        this.data = this.data.filter(func);\n        return this;\n    }\n}\n\n// Using the Chain class\nnew Chain([10, 20, 30, 40, 50]).map(x =\u003e x * 2).filter(x =\u003e x \u003e 70);\n\n// Display the chain results with captured inputs and results\nd__(new Chain([10, 20, 30, 40, 50]).map(x =\u003e c__(x * 2)).filter(x =\u003e c__(x \u003e 70)).data);\n// Output:\n// i0:`20` | i1:`40` | i2:`60` | i3:`80` | i4:`100` | i5:`false` | i6:`false` | i7:`false` | i8:`true` | i9:`true` | _:`[80,100]`\n```\n\n## Formatting\n\nThe `d__` function can override the default formatting, and it can also be defined at global level.\n\n```javascript\nimport { c__, d__, init__, t__ } from 'jstracetoix';\n\ninit__({format={\n    result: '{name}:`{value}`',\n    input: '{name}:`{value}`',\n    thread: '{id}: ',\n    sep: ' | ',\n    new_line: true\n}})\n```\n\nFormatting parameters:\n- `result`: The result value format will be displayed.\n- `input`: The input value format will be displayed.\n- `thread`: The thread Id format will be displayed. (Node.js only).\n- `sep`: The separator text between each input and the result.\n- `new_line`: If `true` it will add a new line at the end of output.\n\n## Multithreading\n\nTo activate the multithreading support (Node.js only):\n\n```javascript\n\nimport { Worker, isMainThread, workerData } from 'worker_threads';\nimport { c__, d__, init__, t__ } from 'jstracetoix';\n\n// Initializing with multithreading\ninit__({ multithreading: true });\n\n// It displays the threadId: i0: `4` | _: `5`\nconst threadFunction = () =\u003e {\n    d__(c__(4) + 1);\n};\n\n// It displays the something: i0: `4` | _: `5`\nconst threadFunctionWithName = () =\u003e {\n    t__('something');\n    d__(c__(4) + 1);\n};\n\nif (isMainThread) {\n    const threads = [];\n\n    // Create 5 workers\n    for (let i = 0; i \u003c 5; i++) {\n        const worker = new Worker(__filename);\n        threads.push(worker);\n    }\n\n    const workerWithName = new Worker(__filename, { workerData: { withName: true } });\n    threads.push(workerWithName);\n    threads.forEach(thread =\u003e {\n        thread.on('message', message =\u003e {\n            console.log('From worker:', message);\n        });\n\n        thread.on('exit', () =\u003e {\n            console.log('Thread finished');\n        });\n    });\n\n} else {\n    if (workerData \u0026\u0026 workerData.withName) {\n        threadFunctionWithName();\n    } else {\n        threadFunction();\n    }\n}\n```\n\n## Output\n\n| Environment | Default Output Function |\n| ----- | ------------------- |\n| Browser | console.debug  |\n| Node.js | process.stdout |\n| React | console.debug |\n| Vue | console.debug |\n\nExcept for Node.js environment, the output is displayed in the browser's developer tools under the \"Console Tab\".\nSince the output is generated using `console.debug`, it can easily be filtered out from regular `console.log` messages.  \nThe default output function can be override using `init__({'stream': new_stream.log })`\n\n## Metadata\n\n The `d__` function callbacks `allow`, `before` and `after` will receive a parameter `data` with the allowed inputs plus the following `meta` items:\n\n- `meta__`: list of meta keys including the name key.\n- `thread_id__`: thread_id being executed\n- `allow_input_count__`: total number of inputs that are allowed.\n- `input_count__`: total number of inputs being captured.\n- `allow__`: If false it wasn't allowed. Use this for `after` callback.\n- `output__`: Text passed to `before` without `new_line`.\n- name: name parameter\n\n## Documentation\n\n [Package Documentation](https://www.devtoix.com/docs/jstracetoix/en/latest/)\n\n## Support this Project\n\nIf you find this project useful, consider supporting it:\n\n- Donate:\n\n[![Donate via PayPal](https://www.paypalobjects.com/webstatic/en_US/i/btn/png/blue-rect-paypal-34px.png)](https://www.paypal.com/donate/?business=MCZDHYSK6TCKJ\u0026no_recurring=0\u0026item_name=Support+Open+Source\u0026currency_code=EUR)\n\n[![Buy me a Coffee](https://www.devtoix.com/assets/buymeacoffee-small.png)](https://buymeacoffee.com/abentofreire)\n\n- Visit the project [homepage](https://www.devtoix.com/en/projects/jstracetoix)\n- Give the project a ⭐ on [Github](https://github.com/a-bentofreire/jstracetoix)\n- Spread the word\n- Follow me:\n  - [Github](https://github.com/a-bentofreire)\n  - [LinkedIn](https://www.linkedin.com/in/abentofreire)\n  - [Twitter/X](https://x.com/devtoix)\n\n## License\n\nMIT License\n\n## Copyrights\n\n(c) 2024 [Alexandre Bento Freire](https://www.a-bentofreire.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa-bentofreire%2Fjstracetoix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa-bentofreire%2Fjstracetoix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa-bentofreire%2Fjstracetoix/lists"}