{"id":"mark-marks/sapphire-data","name":"sapphire-data","scope":"mark-marks","platform":"roblox","description":"Mirrored from the Wally registry.","version":"0.1.2","latest":"0.1.2","versions":["0.1.0","0.1.2"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{"nezuo/delta-compress":{"version":"^0.1.3","alias":"delta_compress"},"ffrostflame/keyform":{"version":"^0.2.2","alias":"keyform"},"red-blox/signal":{"version":"^2.0.2","alias":"signal"}},"integrity":"d0dfbf536460b8d46c501b5f9be220981f3b9afbb92ee0eefb027feeb603a8d4","likes":0,"downloads":0,"install":"forest install mark-marks/sapphire-data","url":"https://forest.dev/p/roblox/mark-marks/sapphire-data","files":"https://api.forest.dev/ai/package/roblox/mark-marks/sapphire-data/files","readme":"# sapphire-data\r\nA lightweight wrapper around [ffrostfall/keyForm](https://github.com/ffrostfall/keyForm) for [Mark-Marks/sapphire](https://github.com/Mark-Marks/sapphire)\r\n\r\n# Installation\r\n1. Install it with wally\r\n```toml\r\n[dependencies]\r\nsapphire_data = \"mark-marks/sapphire-data@LATEST\" # replace LATEST with the latest version\r\n```\r\n`wally install`\r\n2. Set it up\r\n```luau\r\nlocal sapphire_data = require(\"@pkg/sapphire_data\")\r\n\r\nlocal template = {\r\n    ...\r\n}\r\nexport type data = typeof(template)\r\n\r\nreturn sapphire_data.server({\r\n    store_name = \"data\",\r\n    template = template,\r\n})\r\n-- or on the client:\r\nreturn sapphire_data.client({\r\n    template = template,\r\n})\r\n```\r\n3. Extend sapphire with it\r\n```luau\r\nlocal data = require(\".../data\")\r\n\r\nsapphire\r\n    :use(data)\r\n```\r\n\r\n# API\r\n\r\n## Types\r\n\r\n### server<data>\r\n```luau\r\ntype server<data> = {\r\n    --- @private\r\n    identifier: string,\r\n    --- @private\r\n    extension: () -> (),\r\n    --- @private\r\n    methods: {},\r\n\r\n    get_data: (player: Player) -> data,\r\n    on_data_changed: (fn: (Player, data) -> ()) -> () -> (),\r\n    create_transform: <T...>(fn: (data, T...) -> data) -> (Player, T...) -> (),\r\n    transform: (player: Player, fn: (data) -> data) -> (),\r\n    calculate_difference: (player: Player, exposable_data: any) -> buffer?,\r\n}\r\n```\r\n\r\n### server_settings<data>\r\n```luau\r\ntype server_settings<data> = {\r\n    --- Store name.\r\n    store_name: string,\r\n    --- Player data template.\r\n    --- ⚠️ Expected to be a table!\r\n    template: data,\r\n}\r\n```\r\n\r\n### client<data>\r\n```luau\r\ntype client<data> = {\r\n    --- @private\r\n    identifier: string,\r\n    --- @private\r\n    extension: () -> (),\r\n    --- @private\r\n    methods: {},\r\n\r\n    get_data: () -> data?,\r\n    apply_difference: (difference: buffer) -> (),\r\n    on_data_changed: (fn: (data) -> ()) -> () -> (),\r\n}\r\n```\r\n\r\n### client_settings<data>\r\n```luau\r\ntype client_settings<data> = {\r\n    --- Player data template.\r\n    --- ⚠️ Expected to be a table!\r\n    template: data,\r\n}\r\n```\r\n\r\n## Registered methods\r\n\r\n## Functions\r\n\r\n### .server()\r\n```luau\r\n<data>(\r\n    settings: server_settings<data>\r\n) -> server<data>\r\n```\r\n\r\n### .client()\r\n```luau\r\n<data>(\r\n    settings: client_settings<data>\r\n) -> client<data>\r\n```\r\n\r\n## server<data>\r\n\r\n### .get_data()\r\nGets the players data.\r\n```luau\r\n(\r\n    player: Player\r\n) -> data\r\n```\r\n\r\n### .on_data_changed()\r\nListens to data changes. Returns a disconnect function.\r\n```luau\r\n(\r\n    fn: (Player, data) -> ()\r\n) -> () -> ()\r\n```\r\n\r\n### .create_transform()\r\nCreates a transform for player data.\r\nUse `sapphire_data.transform()` for one time data changes.\r\n```luau\r\n<T...>(\r\n    fn: (data, T...) -> data\r\n) -> (\r\n    player: Player,\r\n    T...\r\n) -> ()\r\n```\r\n```luau\r\nlocal increment_coins = sapphire_data.create_transform(function(data, n: number)\r\n    data.coins += n\r\n    return data\r\nend)\r\nincrement_coins(player, 10)\r\n```\r\n\r\n### .transform()\r\nTransforms player data with the given function.\r\nUse `.create_transform()` for multiple data changes.\r\n```luau\r\n(\r\n    player: Player\r\n) -> (\r\n    data: data\r\n) -> data\r\n```\r\n```luau\r\nsapphire_data.transform(player, function(data)\r\n    data.coins += 10\r\n    return data\r\nend)\r\n```\r\n\r\n### .calculate_difference()\r\nCalculates the difference between the player's last calculated difference and their current data.\r\nReturns a buffer representing the difference.\r\n```luau\r\n(\r\n    player: Player,\r\n    exposable_data: any\r\n) -> buffer?\r\n```\r\n```luau\r\nlocal difference = sapphire_data.calculate_difference(player)\r\nif not difference then\r\n    return\r\nend\r\ndata_replication_event.send_to(player, difference)\r\n```\r\nYou may also provide the new data yourself to expose only what you need to to the client.\r\n```luau\r\nlocal exposed_data = make_exposable(sapphire_data.get_data(player))\r\nlocal difference = sapphire_data.calculate_difference(player, exposed_data)\r\nif not difference then\r\n    return\r\nend\r\ndata_replication_event.send_to(player, difference)\r\n```\r\n\r\n## client<data>\r\n\r\n### .get_data()\r\nGets the local players data.\r\n```luau\r\n() -> data?\r\n```\r\n\r\n### .apply_difference()\r\nApplies the difference received from the server's `sapphire_data.calculate_difference()`.\r\n```luau\r\n(\r\n    difference: buffer\r\n) -> ()\r\n```\r\n```luau\r\ndata_replication_event.listen(function(difference)\r\n    sapphire_data.apply_difference(difference)\r\nend)\r\n```\r\n\r\n### .on_data_changed()\r\nListens to data changes. The received data is guaranteed to not be nil.\r\nReturns a disconnect function.\r\n```luau\r\n(\r\n    fn: (data) -> ()\r\n) -> () -> ()\r\n","readmeTruncated":false}