{"id":26975149,"url":"https://github.com/izure1/revix","last_synced_at":"2025-04-03T11:19:12.393Z","repository":{"id":153652107,"uuid":"630190644","full_name":"izure1/revix","owner":"izure1","description":"Manage variables with realms, scopes, and reasons.","archived":false,"fork":false,"pushed_at":"2024-04-17T15:47:53.000Z","size":90,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-10T12:54:34.450Z","etag":null,"topics":["realm","state-management","store","variable"],"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/izure1.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,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-04-19T21:29:22.000Z","updated_at":"2023-04-22T22:40:49.000Z","dependencies_parsed_at":"2024-04-17T03:04:12.894Z","dependency_job_id":"cce1921d-ae73-431f-8148-934a871727f4","html_url":"https://github.com/izure1/revix","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/izure1%2Frevix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izure1%2Frevix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izure1%2Frevix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izure1%2Frevix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/izure1","download_url":"https://codeload.github.com/izure1/revix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246989732,"owners_count":20865331,"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":["realm","state-management","store","variable"],"created_at":"2025-04-03T11:19:11.919Z","updated_at":"2025-04-03T11:19:12.382Z","avatar_url":"https://github.com/izure1.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Revix\r\n\r\n[![](https://data.jsdelivr.com/v1/package/npm/revix/badge)](https://www.jsdelivr.com/package/npm/revix)\r\n\r\nManage variables with realms, scopes, and reasons.\r\n\r\n```typescript\r\nimport { openRealm, destroyRealm } from 'revix'\r\n\r\nconst { use } = openRealm('clock')\r\n\r\nconst [count, setCount, subsCount, destroyCount] = use('count', 0)\r\n\r\nsubsCount(({ before, after, reason }) =\u003e {\r\n  console.log(`Updated to ${after} from ${before} cause ${reason}`)\r\n})\r\n\r\ncount() // 0\r\nsetCount(count()+1, 'updating test')\r\n// Logging: Updated to 1 from 0 cause updating test\r\ncount() // 1\r\n```\r\n\r\n## Why use `Revix`?\r\n\r\n`Revix` is a JavaScript library that manages variables in units called realms. `Revix` treats variables as plain objects with states, and allows you to subscribe to changes in variable values.\r\n\r\n`Revix` helps you to define the scope and dependency of variables clearly, track state changes easily, and improve the readability and maintainability of your code.\r\n\r\n### **Manage realm**\r\n\r\n`openRealm`(scope: `any`)\r\n\r\nGet or create a realm for this scope.\r\nIf this realm has never been used before, it will create a new realm with this value. Otherwise, get an existing realm.\r\n\r\n```typescript\r\nconst { use, exists } = openRealm('realm name')\r\n// or\r\nconst actor = new Actor()\r\nconst { use, exists } = openRealm(actor)\r\n```\r\n\r\n`destroyRealm`(scope: `any`)\r\n\r\nDestroy the realm. All variables belonging to this realm are also destroyed.\r\n\r\n### **Realm functions**\r\n\r\n`use`(key: `string`, initialValue: `T`): [`getter`, `setter`, `subscribe`, `destroy`]\r\n\r\nGet or create a variable manager for this realm. If this variable has never been created before, it will create a new variable with a `initialValue`. Otherwise, get an existing variable manager.\r\n\r\n```typescript\r\nconst [name, setName, subsName, destroyName] = use('name', 'baba')\r\n\r\nname() // baba\r\nsetName('keke', 'no reason')\r\nname() // keke\r\n\r\nsubsName(({ before, after, reason }) =\u003e {\r\n  console.log(`The name variable did update from ${before} to ${after} because ${reason}`)\r\n})\r\n```\r\n\r\n`exists`(key: `string`): `boolean`\r\n\r\nReturns `true` if a variable exists in the realm, or `false` if not.\r\n\r\n### **Variable manager functions**\r\n\r\nThe variable manager is an array and each item is the same as the next,\r\n\r\n```typescript\r\n[getter, setter, subscribe, destroy] = use(key, value)\r\n```\r\n\r\n`getter`(): `T`\r\n\r\nGet a value.\r\n\r\n`setter`(value: `T`, reason?: `string`): `T`\r\n\r\nSet a value.\r\n\r\n`subscribe`(callback: ({ before: `T`, after: `T`, reason: `string` }) =\u003e `void`): `Unsubscribe`\r\n\r\nYou can register subscribe callbacks to watch this variable change.\r\nIf the variable is changed, all subscribe callbacks will be called.\r\n\r\nThis function returns a new function that can be cancel unsubscribed. If you want, just call the returned function.\r\n\r\n```typescript\r\nconst unsubscribe = subscribe(({ before, after, reason }) =\u003e {\r\n  if (reason === 'destroy') {\r\n    unsubscribe()\r\n  }\r\n})\r\n```\r\n\r\n`destroy`(reason?: `string`): `void`\r\n\r\nDestroy a variable.\r\n\r\n**WARNING!** You can't use a same name of variable after destroyed. You should use this function when you are sure the variable will never be used again.\r\n\r\n## With TypeScript\r\n\r\nYou can use strict variable types with TypeScript.  \r\nJust use the `openRealm` function with the generic type.\r\n\r\n### Simple example\r\n\r\n```typescript\r\ninterface Member {\r\n  name: string\r\n  age: number\r\n}\r\n\r\nconst { use } = openRealm\u003cMember\u003e(memberName)\r\nconst [name, setName] = use('name', initialName)\r\nconst [age, setAge] = use('age', initialAge)\r\n```\r\n\r\n### Advanced usage\r\n\r\n```typescript\r\ninterface IActor {\r\n  hp: number\r\n  mp: number\r\n}\r\n\r\nclass Actor implements IActor {\r\n  constructor() {\r\n    const { use } = openRealm\u003cIActor\u003e(this)\r\n    const [hp, setHp, subsHp, destroyHp] = use('hp', 100)\r\n    const [mp, setMp, subsMp, destroyMp] = use('mp', 100)\r\n\r\n    subsHp(() =\u003e {\r\n      // ...TODO\r\n    })\r\n    subsMp(() =\u003e {\r\n      // ...TODO\r\n    })\r\n  }\r\n\r\n  get hp() {\r\n    const { use } = openRealm\u003cIActor\u003e(this)\r\n    const [hp] = use('hp', 100)\r\n    return hp()\r\n  }\r\n\r\n  get mp() {\r\n    const { use } = openRealm\u003cIActor\u003e(this)\r\n    const [mp] = use('mp', 100)\r\n    return mp()\r\n  }\r\n\r\n  gotDamage(damage: number) {\r\n    const { use } = openRealm\u003cIActor\u003e(this)\r\n    const [hp, setHp] = use('hp', 100)\r\n    setHp(hp()-damage, 'Got a damage')\r\n  }\r\n}\r\n```\r\n\r\nOr, you can create your own store.\r\n\r\n```typescript\r\n// store.ts\r\nimport { openRealm } from 'revix'\r\n\r\ninterface Store {\r\n  a: number\r\n  b: string\r\n  c: boolean\r\n}\r\n\r\nexport const STORE_SYMBOL = Symbol('store')\r\nexport const { use } = openRealm\u003cStore\u003e(STORE_SYMBOL)\r\n\r\nexport const [a, setA, subsA, destroyA] = use('a', 0)\r\n\r\n// another.ts\r\nimport { destroyRealm } from 'revix'\r\nimport { subsA } from './store.ts'\r\n\r\nsubsA(({ reason }) =\u003e {\r\n  if (reason === 'unknown') {\r\n    destroyRealm(STORE_SYMBOL, 'error')\r\n  }\r\n})\r\n```\r\n\r\n## Install\r\n\r\n|Site|Link|\r\n|---|---|\r\n|**NPM**|[View](https://www.npmjs.com/package/revix)|\r\n|**Github**|[View](https://github.com/izure1/revix)|\r\n|**jsdelivr**|[Download](https://cdn.jsdelivr.net/npm/revix@1.x.x/dist/esm/index.min.js)|\r\n\r\n### Node.js (commonjs)\r\n\r\n```bash\r\nnpm i revix\r\n```\r\n\r\n### Browser (esmodule)\r\n\r\n```html\r\n\u003cscript type=\"module\"\u003e\r\n  import { openRealm, destroyRealm } from 'https://cdn.jsdelivr.net/npm/revix@1.x.x/dist/esm/index.min.js'\r\n\u003c/script\u003e\r\n```\r\n\r\n## License\r\n\r\nMIT LICENSE\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizure1%2Frevix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fizure1%2Frevix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizure1%2Frevix/lists"}