{"id":15580756,"url":"https://github.com/mar10/persisto","last_synced_at":"2025-04-13T16:10:52.990Z","repository":{"id":6997561,"uuid":"55518879","full_name":"mar10/persisto","owner":"mar10","description":"Persistent Javascript objects and web forms using Web Storage","archived":false,"fork":false,"pushed_at":"2023-01-24T05:01:18.000Z","size":1648,"stargazers_count":20,"open_issues_count":9,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-14T16:29:53.472Z","etag":null,"topics":["html-forms","web-storage"],"latest_commit_sha":null,"homepage":"https://mar10.github.io/persisto/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mar10.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-05T15:19:07.000Z","updated_at":"2023-09-06T20:14:57.000Z","dependencies_parsed_at":"2023-02-13T17:50:40.490Z","dependency_job_id":null,"html_url":"https://github.com/mar10/persisto","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mar10%2Fpersisto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mar10%2Fpersisto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mar10%2Fpersisto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mar10%2Fpersisto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mar10","download_url":"https://codeload.github.com/mar10/persisto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741200,"owners_count":21154255,"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":["html-forms","web-storage"],"created_at":"2024-10-02T19:36:44.652Z","updated_at":"2025-04-13T16:10:52.964Z","avatar_url":"https://github.com/mar10.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# persisto\n\n[![GitHub version](https://img.shields.io/github/release/mar10/persisto.svg)](https://github.com/mar10/persisto/releases/latest)\n[![Build Status](https://travis-ci.org/mar10/persisto.svg?branch=master)](https://travis-ci.org/github/mar10/persisto)\n[![npm](https://img.shields.io/npm/dm/persisto.svg)](https://www.npmjs.com/package/persisto)\n[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/persisto/badge)](https://www.jsdelivr.com/package/npm/persisto)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)\n[![Released with: grunt-yabs](https://img.shields.io/badge/released%20with-grunt--yabs-yellowgreen)](https://github.com/mar10/grunt-yabs)\n[![StackOverflow: persisto](https://img.shields.io/badge/StackOverflow-persisto-blue.svg)](https://stackoverflow.com/questions/tagged/persisto)\n\n\u003e Persistent JavaScript objects and web forms using Web Storage.\n\n**Features**\n\n1. Persist JavaScript objects (`{...}`) to\n   [`localStorage` / `sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API).\u003cbr\u003e\n   Use the `get()`/`set()` API for direct (even nested) access, avoiding the\n   need to convert from/to JSON.\n2. Cache access to\n   [`localStorage` / `sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)\n   (deferred writing appears to be 10-15 times faster).\n3. Make JavaScript objects editable in HTML forms.\u003cbr\u003e\n   A simple naming convention maps data properties to form elements.\u003cbr\u003e\n   Listen for input change events and automatically store data.\n4. Optionally synchronize the data with a remote endpoint.\n\n[Demo](https://mar10.github.io/persisto) \u0026mdash;\n[API Documentation](https://mar10.github.io/persisto/api)\n\nOverview:\n\n![sample](https://rawgit.com/mar10/persisto/master/assets/architecture.png?raw=true)\n\nRequirements:\n\n- \u003cstrike\u003ejQuery\u003c/strike\u003e not required since v2.0\n- Recent major browser (Internet Explorer is **not** supported!)\n\nRequirements for [version 1.x](https://github.com/mar10/persisto/tree/maintain_1.x):\n\n- jQuery\n- IE 8+ or any recent major browser\n\n## Usage\n\n[Download the latest persisto.js](https://github.com/mar10/persisto/releases)\nor include directly from CDN: [![](https://data.jsdelivr.com/v1/package/npm/persisto/badge)](https://www.jsdelivr.com/package/npm/persisto) or\n[UNPKG](https://unpkg.com/persisto@latest/dist/persisto.umd.min.js):\n\n```html\n\u003cscript src=\"//cdn.jsdelivr.net/npm/persisto@latest/dist/persisto.umd.min.js\"\u003e\u003c/script\u003e\n```\n\nthen instantiate a `PersistentObject`:\n\n```js\nlet store = new mar10.PersistentObject(\"mySettings\", {\n  defaults: {\n    theme: \"default\",\n  },\n});\n```\n\n`store` now contains the data that was stored in `localStorage.mySettings` if\npresent. Otherwise, `store` is initialized to the default values that we\npassed with the `.defaults` option.\n\nWe can access data using `set`, `get`, `remove`, `reset`:\n\n```js\nstore.get(\"theme\"); // -\u003e 'default'\nstore.set(\"owner\", { name: \"joe\", age: 42 });\nstore.set(\"owner.role\", \"manager\");\nstore.get(\"owner.age\"); // -\u003e 42\nstore.remove(\"owner.age\");\n// -\u003e store now holds {theme: \"default\", owner: {name: \"joe\", role: \"manager\"}}\n```\n\nEvery _modifying_ operation triggers a deferred commit, so that shortly afterwards\nthe data is serialized to JSON and written to `localStorage.mySettings`.\n\n**More:**\n\n- Try the [online example](https://plnkr.co/plunk/PI8Z2lqn0WfcHvL8).\n- Run the [unit tests](https://rawgit.com/mar10/persisto/master/test/unit/test-core.html).\n\n## Synchronize Data with HTML Forms\n\nForm input elements can be synchronized with a `PersistentObject` by using two\nAPI calls (`readFromForm()` and `writeToForm()`).\nThis can be automated by passing the `attachForm` option.\nExample:\n\n```js\ndocument.addEventListener(\"DOMContentLoaded\", function (event) {\n  // Maintain client's preferences and define some defaults:\n  var settingsStore = new mar10.PersistentObject(\"mySettings\", {\n    attachForm: \"#form1\", // Allow users to edit and save settings\n    // remote: \"https://example.com/my/data-store\",\n    defaults: {\n      nickname: \"anonymous\",\n      theme: \"default\",\n    },\n  });\n\n  settingsStore.ready\n    .then((value) =\u003e {\n      console.log(settingsStore + \":  is initialized.\");\n    })\n    .catch((reason) =\u003e {\n      console.log(settingsStore + \": init failed.\");\n    });\n});\n```\n\nSupported elements are `\u003cinput\u003e` (type text, checkbox, or radio), `\u003ctextarea\u003e`,\nand `\u003cselect\u003e` (single and multivalue).\nBy convention, the html form **must use element names that match the data properties**.\u003cbr\u003e\n\n```html\n\u003cform id=\"settingsForm\" action=\"\"\u003e\n  \u003clabel\u003eNickname:\u003cinput name=\"nickname\" type=\"text\" value=\"\" /\u003e\u003c/label\u003e\u003cbr /\u003e\n  \u003clabel\n    \u003eTheme:\n    \u003cfieldset\u003e\n      \u003clabel\u003e\n        \u003cinput name=\"theme\" type=\"radio\" value=\"default\" /\u003e Standard \u003c/label\n      \u003e\u003cbr /\u003e\n      \u003clabel\u003e \u003cinput name=\"theme\" type=\"radio\" value=\"light\" /\u003e Light \u003c/label\n      \u003e\u003cbr /\u003e\n      \u003clabel\u003e \u003cinput name=\"theme\" type=\"radio\" value=\"dark\" /\u003e Dark \u003c/label\u003e\n    \u003c/fieldset\u003e\n  \u003c/label\u003e\n  \u003cbutton type=\"Submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n\nNote also that only fields are synchronized, that already existed in the storage\ndata. Use the `addNew` option if _all_ form fields should be evaluated and create\nnew properties in the store object:\n\n```js\nsettingsStore.readFromForm(this, {\n  addNew: true,\n});\n```\n\n## Pros and Cons\n\n- Any `PersistentObject` instance is stored as one monolythic JSON string.\u003cbr\u003e\n  _Persisto_ deferres and collates these updates, but modifying a single\n  property of a large data object still comes with some overhead.\u003cbr\u003e\n  Splitting data into several `PersistentObject`s may remedy the problem.\u003cbr\u003e\n  But if your data model is more like a table with hundredth's of rows, a\n  responsive database backend may be a better choice.\n\n- Asynchronous operations bear the risk of potential conflicts.\n  There is currently no builtin support for resolving those.\n\n# HOWTOs\n\n### Storing Arrays\n\nArrays are only a special form of plain JavaScript objects, so we can store and\naccess them as top level type like this:\n\n```js\nlet store = new mar10.PersistentObject(\"mySettings\", {\n  defaults: [\"a\", \"b\", \"c\"],\n});\nstore.get(\"[0]\"); // 'a'\nstore.set(\"[1]\", \"b2\");\n```\n\nHowever if we use child properties, it is even easier:\n\n```js\nlet store = new mar10.PersistentObject(\"mySettings\", {\n        defaults: {\n          values: [\"a\", \"b\", \"c\"]\n        }\n      });\nstore.get(\"values\")[0];  // 'a'\nstore.get(\"values[0]\");  // 'a'\nS.each(store.get(\"values\"), function(idx, obj) { ... });\n\nstore.set(\"values[1]\", \"b2\");\n```\n\n### Performance and Direct Access\n\nIn general, performance costs of `set()` and `get()` calls should be\nneglectable, compared to the resulting synchronization times, but in some cases\ndirect access of the internal data object may be preferred.\u003cbr\u003e\nIn this case modifications must be signalled by a call to `setDirty()`.\n\n```js\nstore._data.owner = { name: \"joe\", age: 42 };\nstore._data.owner.role = \"manager\";\ndelete store._data.owner.age;\nstore.setDirty(); // schedule a commit\n```\n\n### Asynchronous Operation\n\nBy default, changed values will be commited to webStorage after a small delay\n(see `.commitDelay` option). This allows to collate sequences of multiple changes\ninto one single write command.\n\nHowever there are situations, where this is not desirable:\n\n```js\nstore.set(\"foo\", \"bar\");\n\n// Page reload would prevent the delayed commit from happen, so we force\n// synchronization:\nstore.commit();\n\nlocation.reload();\n```\n\nAn alternative would be to disable delay completely by setting `commitDelay: 0`.\n\n### Synchronize with Remote Endpoints\n\nOptionally, we may specify an endpoint URL that is used to synchronize the data\nwith a web server using HTTP REST requests (GET and PUT):\n\n```js\n// Wait fpr page beeing loaded...\ndocument.addEventListener(\"DOMContentLoaded\", function (event) {\n  let store = new mar10.PersistentObject(\"mySettings\", {\n    remote: \"persist/settings\",\n  });\n\n  store.ready\n    .then(function (value) {\n      console.log(\"PersistentStore is initialized and has pulled data.\");\n    })\n    .catch(function (reason) {\n      console.error(\"Error loading persistent objects\", arguments);\n    });\n});\n```\n\n# API Reference\n\n### Options and Events\n\nThe following options are available:\n\nhttps://mar10.github.io/persisto/api/interfaces/persisto_options.persistooptions.html\n\n### Methods\n\nFollowing a list of available methods:\n\nhttps://mar10.github.io/persisto/api/classes/persisto.persistentobject.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmar10%2Fpersisto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmar10%2Fpersisto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmar10%2Fpersisto/lists"}