{"id":19475859,"url":"https://github.com/remotelib/exval","last_synced_at":"2025-06-11T02:39:49.875Z","repository":{"id":57232053,"uuid":"67552618","full_name":"remotelib/exval","owner":"remotelib","description":"Take snapshot of JavaScript objects, functions or classes and run them on other machine.","archived":false,"fork":false,"pushed_at":"2017-09-08T21:05:06.000Z","size":39,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T16:47:50.550Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/remotelib.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-09-06T22:51:45.000Z","updated_at":"2017-09-08T21:02:52.000Z","dependencies_parsed_at":"2022-09-04T21:20:27.052Z","dependency_job_id":null,"html_url":"https://github.com/remotelib/exval","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remotelib%2Fexval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remotelib%2Fexval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remotelib%2Fexval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remotelib%2Fexval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remotelib","download_url":"https://codeload.github.com/remotelib/exval/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240699603,"owners_count":19843513,"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":[],"created_at":"2024-11-10T19:35:18.999Z","updated_at":"2025-02-25T15:48:21.186Z","avatar_url":"https://github.com/remotelib.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# exval\n\n[![build](https://img.shields.io/travis/remotelib/exval.svg?branch=master)](https://travis-ci.org/remotelib/exval)\n[![npm](https://img.shields.io/npm/v/exval.svg)](https://npmjs.org/package/exval)\n[![Join the chat at https://gitter.im/remotelib/Lobby](https://badges.gitter.im/remotelib/Lobby.svg)](https://gitter.im/remotelib/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![npm](https://img.shields.io/npm/l/exval.svg)](LICENSE)\n\n\n[exval](https://npmjs.org/package/exval) allows `uneval` JavaScript \nobjects back to source code (including functions and classes!).\nThis allows making shallow copy of an object and recreate it on other\nmachine.\n\n**This library is under development.**\nIf you find a bug, please open an issue or consider contributing to \nthis project.\n\nIf you're interested on running JavaScript on a remote machine you should checkout [remote-lib](https://github.com/remotelib/remote-lib) as well.\n\n\n## Examples\n\n### Object Cloning\n\n```js\nconst Exval = require('exval'); // require exval\nconst exval = new Exval(); // create a new exval instance\n\nconst obj = {\n  foo: 'bar',\n  deep: {\n    hello: 'world',\n  },\n  pow: Math.pow,\n};\n\nconst output = exval.stringify(obj);\nconsole.log(output); // {foo:'bar',deep:{hello:'world'},pow:Math.pow}\n\nconst obj2 = eval(`(${output})`);\nassert(obj2 !== obj);\nassert(obj2.deep !== obj.deep);\nassert.deepEqual(obj2, obj);\n```\n\n### Class Instance\n\n```js\nconst Exval = require('exval'); // require exval\nconst exval = new Exval(); // create a new exval instance\n\n// create a counter instance\nconst c1 = (() =\u003e {\n  class Counter {\n    constructor(init) {\n      this.counter = init;\n    }\n\n    inc(a) {\n      this.counter += a;\n    }\n  }\n  \n  return new Counter(100);\n}());\n\n// notice that we didn't define `Counter` class here\nassert.equal(typeof Counter, 'undefined');\n  \n// update the counter and add some custom properties\nc1.inc(2);\nc1.foo = 'bar';\n\n// generate the counter instance code and run it\nconst output = exval.stringify(c1);\nconst c2 = eval(`(${output})`);\n\n// Counter class is still undefined but our counter cloned successfully\nassert.equal(typeof Counter, 'undefined');\nassert.equal(c2.counter, c1.counter);\nassert.equal(c2.foo, c1.foo);\n\n// we can even continue to use it as normal!\nc2.inc(1);\nassert.equal(c2.counter, 103);\n\n// the original counter stay the same\nassert.equal(c1.counter, 102);\n```\n      \n### Multiple References\n\n```js\nconst Exval = require('exval'); // require exval\nconst exval = new Exval(); // create a new exval instance\n\nconst a = { name: 'a' };\n\nconst obj = {\n  a1: a,\n  a2: a,\n};\n\nconst output = exval.stringify(obj);\nconsole.log(output); // function(){var a={name:'a'};return {a1:a,a2:a}}()\n\nconst obj2 = eval(`(${output})`);\nassert.deepEqual(obj2, obj);\nassert(obj2.a1 === obj2.a2);\n``` \n     \n### Close Loop References\n\n```js\nconst Exval = require('exval'); // require exval\nconst exval = new Exval(); // create a new exval instance\n\nconst obj = { foo: 'bar' };\nobj.obj = obj;\n\nconst output = exval.stringify(obj);\nconst obj2 = eval(`(${output})`);\n                  \nassert(obj2 !== obj); \nassert(obj2.foo === obj.foo);\nassert(obj2.obj === obj2);\n```\n\n## Limitations\n\n### Global Vars\n\n*exvar* will not copy outer scope variables that has been used in your \ncode (including globals and environment variables). It's **your \nresponsibility** to make sure that all the globals variables are \ncorrectly copied and transferred between your machines.\n \n```js\nlet glob = 1;\n \nfunction counter() {\n  return glob++;\n}\n \nconst output = exval.stringify(counter);\n\nconsole.log(output); // prints 'function counter() {\\nreturn glob++;\\n}'\n                     // notice that the variable `glob` has been ommited\n``` \n\n\n### Closures\n\n*exvar* [can't](http://stackoverflow.com/q/4472529/518153)\n[access](http://stackoverflow.com/a/39429547/518153)\nvariables in your inner closure. Therefore it's **your responsibility**\nto regenerate them before you can use the generated code.\n \n```js\nconst inc = (() =\u003e {\n  let counter = 0;\n  \n  return () =\u003e counter++;\n})();\n\nconsole.log(inc()) // \"0\"\nconsole.log(inc()) // \"1\"\nconsole.log(typeof counter) // \"undefined\"\n \nconst output = exval.stringify(inc);\nconst inc2 = eval(`{$output}`);\n\ninc2(); // Throws \"ReferenceError: counter is not defined\"\n```\n\n\n### The `supper` Keyword\n\nIt's impossible to know a method parent class outside the class context.\nTherefore, calling methods that using the `super` keyword will fail to\nrun, although `exval`ing the hole class **will works**! \n \n```js\nclass Foo {\n  getName() {\n    return 'Foo';\n  }\n}\n \nclass FooBar extends Foo {\n  getName() {\n    return `${super.getName()}Bar`;\n  }\n}\n\n// create shallow copy of the hole class will work\nexval.stringify(FooBar);\n\n// create shallow copy of the method `getName`\n// throws \"SyntaxError: 'super' keyword unexpected here\"\nexval.stringify(FooBar.prototype.getName);\n```\n\n\n### Function `.bind`\n\nBinding a function will hide it sourcecode so *exvar* couldn't access\nthe original function sourcecode. Please prefer to use [arrow functions](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) \ninstead of `.bind`.\n \n```js\nfunction foo(a) { return a + 1; }\nconst foo2 = () =\u003e foo(2);\nconst foo5 = foo.bind(null, 5);\n\n// exval'ing arrow function will work\nexval.stringify(foo2); // returns \"() =\u003e foo(2)\"\n\n// exval'ing bind function will not work\n// throws ReferenceError: Couldn't encode native code \"function () { [native code] }\"\nexval.stringify(foo5);\n```\n\n### Symbols\n\nExval currently ignoring object's symbols:\n\n```js\nconst kFoo = Symbol('foo');\nconst obj = {\n  [kFoo]: 'Foo!'\n};\n\nexval.stringify(obj); // returns \"{}\"\n```\n\n\n## License\n\n[MIT License](LICENSE).\nCopyright \u0026copy; 2016 [Moshe Simantov](https://github.com/moshest)\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremotelib%2Fexval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremotelib%2Fexval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremotelib%2Fexval/lists"}