{"id":16398833,"url":"https://github.com/sauldoescode/craft-observable","last_synced_at":"2025-03-23T05:31:00.718Z","repository":{"id":9067258,"uuid":"60710679","full_name":"SaulDoesCode/craft-observable","owner":"SaulDoesCode","description":"small proxy driven observable objects to fit any framework or library","archived":false,"fork":false,"pushed_at":"2022-12-03T15:38:45.000Z","size":245,"stargazers_count":5,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T18:02:04.636Z","etag":null,"topics":["craft-observable","observable","proxy"],"latest_commit_sha":null,"homepage":null,"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/SaulDoesCode.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":"2016-06-08T15:58:19.000Z","updated_at":"2023-03-08T03:30:13.000Z","dependencies_parsed_at":"2023-01-13T15:08:55.121Z","dependency_job_id":null,"html_url":"https://github.com/SaulDoesCode/craft-observable","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaulDoesCode%2Fcraft-observable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaulDoesCode%2Fcraft-observable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaulDoesCode%2Fcraft-observable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaulDoesCode%2Fcraft-observable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SaulDoesCode","download_url":"https://codeload.github.com/SaulDoesCode/craft-observable/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245061382,"owners_count":20554563,"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":["craft-observable","observable","proxy"],"created_at":"2024-10-11T05:14:02.078Z","updated_at":"2025-03-23T05:31:00.398Z","avatar_url":"https://github.com/SaulDoesCode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# craft-observable\n\nsmall proxy driven observable objects to fit any framework or library\n\n## craft-observable uses\n\n- Proxy (optional)\n- ES6 syntax (optional)\n- Set\n- Array.from\n- Object.assign\n\n## observables have the following properties\n\n- .isObservable - true if it is an observable\n- .set, .get - old school non proxy accessors\n- .$set, .$get - listeners for access events\n- .on , .once , .off , .emit, .stopall - event system\n- .defineHandle - define event methods instead of using .on('xyz',function) all the time\n\n### observables code demo\n\nbasic instanciator `observable(=[obj|function])`\n\n```javascript\n  // node.js style requiring works but will be global if not available\n  const { observable, eventsys } = require('craft-observable');\n\n  let farm = observable();\n\n  // listen for set events\n  farm.$set('farmer', (key, value, observable, isnew) =\u003e {\n      console.log('a new farmer is set');\n      if (value.includes(' ')) {\n          value = value.split(' ');\n          return {\n              firstname: value[0],\n              lastname: value[1],\n          }\n      }\n  });\n\n  farm.farmer = 'Bob Brown';\n\n  console.log(farm.farmer); // -\u003e { firstname : \"Bob\" , lastname : \"Brown\" }\n\n  farm.animals = {\n    cows: 2\n  };\n\n  farm.animals.$get((key, obj) =\u003e {\n      return `the farm has ${obj[key] == undefined ? 'no ' + key : obj[key] + ' ' + key}`;\n  });\n\n  console.log(farm.animals.sheep); // -\u003e the farm has no sheep\n  // if proxy is not available in your browser || javascript environment use the traditional get and set accessor methods\n  console.log(farm.animals.get('sheep')); // -\u003e the farm has no sheep\n\n  console.log(farm.animals.cows); // -\u003e the farm has 2 cows\n```\n\n### event system\n\nthe observables also include a build in event system to help make them as useful as possible\n\n```javascript\n  let notifier = observable();\n\n  notifier.on('ui-change',(html,...otherargs) =\u003e {\n    let article = document.createElement('article');\n    article.innerHTML = html;\n    document.querySelector('div.articles').appendChild(article);\n  });\n\n  // some seriously async code\n  fetch('/doodle.html')\n  .then(checkerrors)\n  .then(response =\u003e response.text())\n  .then(text =\u003e {\n    notifier.emit('ui-change',text);\n  });\n\n  // to access methods on the listener assign it as a variable\n  let uiChange = notifier.on('ui-change',(html,...otherargs) =\u003e {\n    let article = document.createElement('article');\n    article.innerHTML = html;\n    document.querySelector('div.articles').appendChild(article);\n  });\n  // lets say you want to stop recieving ui-change events\n  uiChange.off();\n  // but now you want to enable them again\n  uiChange.on();\n  // or\n  uiChange.once();\n```\n\n### separate use of event system\n\n```javascript\n  let messager = eventsys({});\n\n  // .on, .once listeners have same interface\n  messager.on('msg', event =\u003e {\n    console.log('new message',event);\n  });\n\n  // .emit takes a string event identifier\n  // any arguments that follow will be sent to listeners\n  // there are no type biases any argument will do\n  messager.emit('msg',{\n    body : 'new piece of information'\n  });\n\n  messager.emit('msg','new piece of info','code 3' /*...*/);\n  // this halts any events being emited\n  // .stopall([true|false])\n  messager.stopall(); // stopped\n  // the bool is optional to turn event emitting on again\n  // just call .stopall again with false\n  messager.stopall(false); // working again\n```\n\n## crazy meta objects\n\nimplement cool features by chaging the behavior of objects\nhere is an example of what is possible, note this is probably a bad example\nbut still it demonstrates the potential of observables to create new behaviour in objects\n```javascript\n  const fs = require('fs');\n  const {observable} = require('craft-observable');\n  const metaobject = observable({\n    logloc : './log.txt'\n  });\n\n\n  metaobject.$set('log',(key,val,obj) =\u003e {\n    fs.appendFile(obj.logloc, val, err =\u003e {\n        if (err) throw err;\n        console.log(val);\n    });\n  });\n\n  metaobject.$get('log',(key,obj) =\u003e fs.readFileSync(obj.logloc,'utf8'));\n\n  const getfile = observable();\n\n  getfile.$get((key,obj) =\u003e {\n    const path = __dirname+'/'+key;\n    const stats = fs.statSync(path);\n    if(stats.isFile()) return fs.readFileSync(path,'utf8');\n  });\n\n  const server = require('http').createServer((req, res) =\u003e {\n    res.statusCode = 200;\n    res.setHeader('Content-Type', 'text/html');\n    res.end(getfile['index.html']);\n    metaobject.log = `${Date.now()} : request made \\n`;\n  });\n\n  server.listen(3000, '127.0.0.1', () =\u003e {\n    console.log(`Server running at http://127.0.0.1:3000/`);\n  });\n```\n\n## Notes\n\nThis little doodle is subject to change but we'll try and keep it working as much as posible with no breaking changes. if you are experiencing issues or want to improve a feature do fork, raise issues tell us about bugs and so forth.\n\nThank you very much enjoy the observables\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsauldoescode%2Fcraft-observable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsauldoescode%2Fcraft-observable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsauldoescode%2Fcraft-observable/lists"}