Repository: sindresorhus/unstated-debug
Branch: main
Commit: e942c02e1f32
Files: 13
Total size: 7.9 KB
Directory structure:
gitextract_a1k8oauj/
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .npmrc
├── browser-env.js
├── index.d.ts
├── index.js
├── index.test-d.ts
├── license
├── package.json
├── readme.md
└── test.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.yml]
indent_style = space
indent_size = 2
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/workflows/main.yml
================================================
name: CI
on:
- push
- pull_request
jobs:
test:
name: Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
================================================
FILE: .gitignore
================================================
node_modules
yarn.lock
================================================
FILE: .npmrc
================================================
package-lock=false
================================================
FILE: browser-env.js
================================================
import browserEnv from 'browser-env';
browserEnv();
================================================
FILE: index.d.ts
================================================
import {Container} from 'unstated';
/**
When enabled, it exposes a global object `UNSTATED` which you can use in DevTools to explore the containers and their state.
In the root of your app, import `unstated-debug`:
@example
```
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'unstated';
import UNSTATED from 'unstated-debug';
import App from './components/App.js';
UNSTATED.logStateChanges = false;
render(
<Provider>
<App/>
</Provider>,
document.querySelector('#root')
);
```
*/
declare const UNSTATED: {
/**
Whether the debugger should be enabled or not.
@default true
*/
isEnabled: boolean;
/**
Whether state changes should be logged to the console.
@default true
*/
logStateChanges: boolean;
/**
Whether logs should be collapsed.
@default false
*/
isCollapsed: boolean;
/**
Your containers.
*/
containers: Record<string, Container<Record<string, unknown>>>;
/**
All of the state values.
*/
states: Record<string, Record<string, unknown>>;
/**
Logs the current state of your containers.
*/
logState: () => void;
};
export default UNSTATED;
================================================
FILE: index.js
================================================
import {detailedDiff} from 'deep-object-diff';
import {__SUPER_SECRET_CONTAINER_DEBUG_HOOK__} from 'unstated';
const UNSTATED = {
isEnabled: true,
isCollapsed: false,
logStateChanges: true,
containers: {},
get states() {
return Object.fromEntries(
Object.entries(this.containers).map(([key, value]) => [key, value.state])
);
},
logState() {
for (const [key, value] of Object.entries(this.containers)) {
console.log(`%c${key}\n`, 'font-weight:bold', value.state);
}
}
};
__SUPER_SECRET_CONTAINER_DEBUG_HOOK__(container => {
if (!UNSTATED.isEnabled) {
return;
}
const {name} = container.constructor;
UNSTATED.containers[name] = container;
let previousState = container.state;
container.subscribe(() => {
if (!(UNSTATED.isEnabled && UNSTATED.logStateChanges)) {
return;
}
const {state} = container;
const diff = detailedDiff(previousState, state);
const group = UNSTATED.isCollapsed ? console.groupCollapsed : console.group;
group(name);
const hasChanges = object => Object.keys(object).length > 0;
if (hasChanges(diff.added)) {
console.log('Added\n', diff.added);
}
if (hasChanges(diff.updated)) {
console.log('Updated\n', diff.updated);
}
if (hasChanges(diff.deleted)) {
console.log('Deleted\n', diff.deleted);
}
console.log('New state\n', state);
console.log('Old state\n', previousState);
console.groupEnd(name);
previousState = state;
});
});
if (typeof window !== 'undefined') {
window.UNSTATED = UNSTATED;
}
export default UNSTATED;
================================================
FILE: index.test-d.ts
================================================
import {expectType} from 'tsd';
import {Container} from 'unstated';
import UNSTATED from './index.js';
expectType<boolean>(UNSTATED.isEnabled);
expectType<boolean>(UNSTATED.logStateChanges);
expectType<Record<string, Container<Record<string, unknown>>>>(UNSTATED.containers);
expectType<() => void>(UNSTATED.logState);
expectType<Record<string, Record<string, unknown>>>(
UNSTATED.states
);
================================================
FILE: license
================================================
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: package.json
================================================
{
"name": "unstated-debug",
"version": "1.0.0",
"description": "Debug your Unstated containers with ease",
"license": "MIT",
"repository": "sindresorhus/unstated-debug",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"unstated",
"debug",
"container",
"containers",
"react",
"state",
"component",
"debugging",
"debuggable",
"inspect",
"devtools"
],
"dependencies": {
"deep-object-diff": "^1.1.0"
},
"devDependencies": {
"@types/react": "^17.0.4",
"ava": "^3.15.0",
"browser-env": "^3.3.0",
"react": "^16.0.0",
"tsd": "^0.14.0",
"unstated": "^2.1.1",
"xo": "^0.39.1"
},
"peerDependencies": {
"unstated": "^2.1.1"
},
"xo": {
"envs": [
"node",
"browser"
]
},
"ava": {
"require": [
"./browser-env"
]
}
}
================================================
FILE: readme.md
================================================
# unstated-debug
> Debug your [Unstated](https://github.com/jamiebuilds/unstated) containers with ease
<br>
<img src="screenshot.png" width="1145">
## Install
```
$ npm install unstated-debug
```
## Setup
In the root of your app, import `unstated-debug`:
```js
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'unstated';
import UNSTATED from 'unstated-debug';
import App from './components/App.js';
UNSTATED.logStateChanges = false;
render(
<Provider>
<App/>
</Provider>,
document.querySelector('#root')
);
```
## Usage
When enabled, it exposes a global object `UNSTATED` which you can use in DevTools to explore the containers and their state.
<img src="screenshot-explore.png" width="400">
The object contains the following properties:
- `isEnabled` - Same as the below option, but you can change it after init.
- `logStateChanges` - Same as the below option, but you can change it after init.
- `isCollapsed` - Collapse logs. (Default: false)
- `containers` - Your containers.
- `states` - The state objects of your containers.
- `logState()` - Logs the current state of your containers.
## API
### UNSTATED
##### isEnabled
Type: `boolean`\
Default: `true`
Toggle debugging.
For example, if you use this in an Electron app, you could pass it [`is.development`](https://github.com/sindresorhus/electron-util#is) to ensure debugging is disabled in production.
##### logStateChanges
Type: `boolean`\
Default: `true`
Logs a diff for each state change to the containers. This gives you a live insight into state changes in your app.
<img src="screenshot-diff.png" width="400">
================================================
FILE: test.js
================================================
import test from 'ava';
import {Container} from 'unstated';
import UNSTATED from './index.js';
class FixtureContainer extends Container {
constructor() {
super();
this.state = {
foo: true
};
}
}
const container = new FixtureContainer();
test('main', t => {
t.true(container.state.foo);
});
test('exposes window global', t => {
t.is(UNSTATED, window.UNSTATED);
t.is(typeof window.UNSTATED, 'object');
t.true(window.UNSTATED.containers.FixtureContainer.state.foo);
});
gitextract_a1k8oauj/ ├── .editorconfig ├── .gitattributes ├── .github/ │ └── workflows/ │ └── main.yml ├── .gitignore ├── .npmrc ├── browser-env.js ├── index.d.ts ├── index.js ├── index.test-d.ts ├── license ├── package.json ├── readme.md └── test.js
SYMBOL INDEX (5 symbols across 2 files)
FILE: index.js
constant UNSTATED (line 4) | const UNSTATED = {
method states (line 9) | get states() {
method logState (line 14) | logState() {
FILE: test.js
class FixtureContainer (line 5) | class FixtureContainer extends Container {
method constructor (line 6) | constructor() {
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (9K chars).
[
{
"path": ".editorconfig",
"chars": 175,
"preview": "root = true\n\n[*]\nindent_style = tab\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newlin"
},
{
"path": ".gitattributes",
"chars": 19,
"preview": "* text=auto eol=lf\n"
},
{
"path": ".github/workflows/main.yml",
"chars": 436,
"preview": "name: CI\non:\n - push\n - pull_request\njobs:\n test:\n name: Node.js ${{ matrix.node-version }}\n runs-on: ubuntu-la"
},
{
"path": ".gitignore",
"chars": 23,
"preview": "node_modules\nyarn.lock\n"
},
{
"path": ".npmrc",
"chars": 19,
"preview": "package-lock=false\n"
},
{
"path": "browser-env.js",
"chars": 53,
"preview": "import browserEnv from 'browser-env';\n\nbrowserEnv();\n"
},
{
"path": "index.d.ts",
"chars": 1126,
"preview": "import {Container} from 'unstated';\n\n/**\nWhen enabled, it exposes a global object `UNSTATED` which you can use in DevToo"
},
{
"path": "index.js",
"chars": 1532,
"preview": "import {detailedDiff} from 'deep-object-diff';\nimport {__SUPER_SECRET_CONTAINER_DEBUG_HOOK__} from 'unstated';\n\nconst UN"
},
{
"path": "index.test-d.ts",
"chars": 396,
"preview": "import {expectType} from 'tsd';\nimport {Container} from 'unstated';\nimport UNSTATED from './index.js';\n\nexpectType<boole"
},
{
"path": "license",
"chars": 1117,
"preview": "MIT License\n\nCopyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n\nPermission is hereby grant"
},
{
"path": "package.json",
"chars": 1085,
"preview": "{\n\t\"name\": \"unstated-debug\",\n\t\"version\": \"1.0.0\",\n\t\"description\": \"Debug your Unstated containers with ease\",\n\t\"license\""
},
{
"path": "readme.md",
"chars": 1640,
"preview": "# unstated-debug\n\n> Debug your [Unstated](https://github.com/jamiebuilds/unstated) containers with ease\n\n<br>\n<img src=\""
},
{
"path": "test.js",
"chars": 487,
"preview": "import test from 'ava';\nimport {Container} from 'unstated';\nimport UNSTATED from './index.js';\n\nclass FixtureContainer e"
}
]
About this extraction
This page contains the full source code of the sindresorhus/unstated-debug GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (7.9 KB), approximately 2.5k tokens, and a symbol index with 5 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.