{"id":19104150,"url":"https://github.com/buildthomas/MockDataStoreService","last_synced_at":"2025-04-18T19:33:00.235Z","repository":{"id":39121631,"uuid":"138953493","full_name":"buildthomas/MockDataStoreService","owner":"buildthomas","description":"Emulation of Roblox's DataStoreService for seamless offline development \u0026 testing","archived":false,"fork":false,"pushed_at":"2023-08-15T04:54:08.000Z","size":220,"stargazers_count":69,"open_issues_count":7,"forks_count":18,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-11-09T04:03:18.764Z","etag":null,"topics":["datastore","datastoreservice","emulation","roblox"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/buildthomas.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,"publiccode":null,"codemeta":null}},"created_at":"2018-06-28T01:58:41.000Z","updated_at":"2024-10-23T13:08:23.000Z","dependencies_parsed_at":"2024-11-09T04:02:52.750Z","dependency_job_id":"30fb09d6-b390-4b97-8e0c-1da0daaa375b","html_url":"https://github.com/buildthomas/MockDataStoreService","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildthomas%2FMockDataStoreService","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildthomas%2FMockDataStoreService/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildthomas%2FMockDataStoreService/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildthomas%2FMockDataStoreService/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/buildthomas","download_url":"https://codeload.github.com/buildthomas/MockDataStoreService/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249536308,"owners_count":21287576,"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":["datastore","datastoreservice","emulation","roblox"],"created_at":"2024-11-09T04:00:56.347Z","updated_at":"2025-04-18T19:33:00.227Z","avatar_url":"https://github.com/buildthomas.png","language":"Lua","funding_links":[],"categories":["Libraries"],"sub_categories":["DataStore"],"readme":"\u003ch1 align=\"center\"\u003eMockDataStoreService\u003c/h1\u003e\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.com/buildthomas/MockDataStoreService\"\u003e\n        \u003cimg src=\"https://travis-ci.com/buildthomas/MockDataStoreService.svg?branch=master\" /\u003e\n    \u003c/a\u003e\n    \u003c!--\u003ca href=\"https://coveralls.io/github/buildthomas/MockDataStoreService?branch=master\"\u003e\n        \u003cimg src=\"https://coveralls.io/repos/github/buildthomas/MockDataStoreService/badge.svg?branch=master\" /\u003e\n    \u003c/a\u003e--\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003cb\u003eEmulation of Roblox's DataStoreService for seamless offline development \u0026 testing\u003c/b\u003e\n\u003c/div\u003e\n\n\u003cdiv\u003e\u0026nbsp;\u003c/div\u003e\n\nThis is a set of modules that emulates datastores in Lua rather than using the actual service. This is useful for testing in offline projects / local place files with code/frameworks that need to have access to datastores.\n\nThe MockDataStoreService behaves exactly like DataStoreService: it has the same API, and will also work even if the place is not currently published to a game with Studio API access enabled (it will act as a DataStoreService with no data stored on the back-end, unless you import some data from a json string manually using the module).\n\nA small top-level helper module is provided (DataStoreService) that automatically detects and selects which datastores should be used (real datastores for published games with API access, mock datastores for offline games / published games without API access).\n\nIt is recommended to use this code in the structure that it is provided in, and to simply call  `require(path.to.DataStoreService)`  instead of  `game:GetService(\"DataStoreService\")` anywhere in your code to use it properly.\n\n-----\n\n**Usage:**\n\n```lua\nlocal DataStoreService = require(the.path.to.DataStoreService)\n\n-- Use as actual DataStoreService, i.e.:\n\nlocal gds = DataStoreService:GetGlobalDataStore()\nlocal ds = DataStoreService:GetDataStore(\"TestName\", \"TestScope\")\nlocal ods = DataStoreService:GetOrderedDataStore(\"TestName\")\n\nlocal value = ds:GetAsync(\"TestKey\")\nds:SetAsync(\"TestKey\", \"TestValue\")\nlocal value = ds:IncrementAsync(\"IntegerKey\", 3)\nlocal value = ds:UpdateAsync(\"UpdateKey\", function(oldValue) return newValue end)\nlocal value = ds:RemoveAsync(\"TestKey\")\nlocal connection = ds:OnUpdate(\"UpdateKey\", function(value) print(value) end)\n\nlocal pages = ods:GetSortedAsync(true, 50, 1, 100)\nrepeat\n    for _, pair in ipairs(pages:GetCurrentPage()) do\n        local key, value = pair.key, pair.value\n        -- (...)\n    end\nuntil pages.IsFinished or pages:AdvanceToNextPageAsync()\n\nlocal budget = DataStoreService:GetRequestBudgetForRequestType(\n    Enum.DataStoreRequestType.UpdateAsync\n)\n\n-- Import/export data to a specific datastore:\n\nds:ImportFromJSON({ -- feed table or json string representing contents of datastore\n    TestKey = \"Hello world!\"; -- a key value pair\n    AnotherKey = {a = 1, b = 2}; -- another key value pair\n    -- (...)\n})\n\nprint(ds:ExportToJSON())\n\n-- Import/export entirety of DataStoreService:\n\nDataStoreService:ImportFromJSON({ -- feed table or json string\n    DataStore = { -- regular datastores\n        TestName = { -- name of datastore\n            TestScope = { -- scope of datastore\n                TestKey = \"Hello world!\"; -- a key value pair\n                AnotherKey = {1,2,3}; -- another key value pair\n                -- (...)\n            }\n        }\n    };\n    GlobalDataStore = { -- the (one) globaldatastore\n        TestKey = \"Hello world!\"; -- a key value pair\n        AnotherKey = {1,2,3}; -- another key value pair\n        -- (...)\n    };\n    OrderedDataStore = { -- ordered datastores\n        TestName = { -- name of ordered datastore\n            TestScope = { -- scope of ordered datastore\n                TestKey = 15; -- a key value pair\n                AnotherKey = 3; -- another key value pair\n                -- (...)\n            }\n        }\n    };\n}\n\nprint(DataStoreService:ExportToJSON())\n\n```\n\nReview the API of datastores here:\n\n- \u003chttp://wiki.roblox.com/index.php?title=API:Class/DataStoreService\u003e\n- \u003chttp://wiki.roblox.com/index.php?title=API:Class/GlobalDataStore\u003e\n- \u003chttp://wiki.roblox.com/index.php?title=API:Class/OrderedDataStore\u003e\n- \u003chttp://wiki.roblox.com/index.php?title=API:Class/DataStorePages\u003e\n\n-----\n\n**Features:**\n\n- Identical API and near-identical behavior compared to real DataStoreService.\n- Error messages are more verbose/accurate than the ones generated by actual datastores, which makes development/bug-fixing easier.\n- Throws descriptive errors for attempts at storing invalid data, telling you exactly which part of the data is invalid. (credit to @Corecii's helper function)\n- Emulates the yielding of datastore requests (waits a random amount of time before returning from the call).\n- Extra API for json-exporting/importing contents of one/all datastores for easy testing.\n- All operations safely deep-copy values where necessary (not possible to alter values in the datastore by externally altering tables, etc).\n- Enforces the \"6 seconds between writes on the same key\" rule.\n- Enforces datastore budgets correctly: budget are set and increased at the rates of the actual service, requests will be throttled if the budget is exceeded, and if there are too many throttled requests in the queue then new requests will error instead of throttling.\n- Functionality for simulating errors at a certain rate (similar to deprecated/removed Diabolical Mode that Studio used to have).\n\n-----\n\n**TODOs:**\n\n- Add more test cases for budgeting\n- Refine existing tests\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuildthomas%2FMockDataStoreService","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuildthomas%2FMockDataStoreService","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuildthomas%2FMockDataStoreService/lists"}