From b151328969d71a3b108b78da249f5869e67f1350 Mon Sep 17 00:00:00 2001 From: Awesome Stickz Date: Tue, 26 Nov 2024 21:04:38 +0530 Subject: [PATCH] docs: change wordings on caching and desired props page (#4010) * docs: change wordings on caching and desired props page * change value to property --- website/docs/bigbot/step-2-rest.md | 2 +- website/docs/bigbot/step-3-gateway.md | 2 +- website/docs/bigbot/step-4-bot.md | 2 +- website/docs/caching.md | 63 ++++++++++++++++++++++----- website/docs/desired-properties.md | 43 +++++++++++------- 5 files changed, 81 insertions(+), 31 deletions(-) diff --git a/website/docs/bigbot/step-2-rest.md b/website/docs/bigbot/step-2-rest.md index 9e48dbee8..dfaadcb84 100644 --- a/website/docs/bigbot/step-2-rest.md +++ b/website/docs/bigbot/step-2-rest.md @@ -232,7 +232,7 @@ BOT.rest = createRestManager({ BOT.rest.createBaseHeaders = () => { return { - 'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v19.0.0-alpha.1)`, + 'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v19.0.0)`, bot_id: BOT.rest.applicationId.toString(), } } diff --git a/website/docs/bigbot/step-3-gateway.md b/website/docs/bigbot/step-3-gateway.md index f08f365d6..75808a517 100644 --- a/website/docs/bigbot/step-3-gateway.md +++ b/website/docs/bigbot/step-3-gateway.md @@ -58,7 +58,7 @@ We are going to proceed with the understanding that we have 5,000 shards, 5,000, ```ts import { createGatewayManager } from '@discordeno/gateway' -import { logger } from '@discordeno/utils' +import { GatewayIntents } from '@discordeno/types' import { REST } from '../rest.ts' export const GATEWAY = createGatewayManager({ diff --git a/website/docs/bigbot/step-4-bot.md b/website/docs/bigbot/step-4-bot.md index 157559cbf..19e86aa08 100644 --- a/website/docs/bigbot/step-4-bot.md +++ b/website/docs/bigbot/step-4-bot.md @@ -153,7 +153,7 @@ BOT.gateway.requestMembers = async function (guildId, options) { } ``` -This will now send a request to our gateway manager whenever the bot makes a request to fetch members. +This will now send a request to our gateway manager whenever the bot makes a request to fetch members and the gateway process will send back `GUILD_MEMBERS_CHUNK` event(s) to the bot process. ## Caching diff --git a/website/docs/caching.md b/website/docs/caching.md index 8833365a5..bca2d4551 100644 --- a/website/docs/caching.md +++ b/website/docs/caching.md @@ -35,28 +35,28 @@ const getProxyCacheBot = (bot: Bot) => // Define what properties of individual cache you wish to cache. Caches no props by default. Or you can use the `undesiredProps` prop to reverse the behavior of `desiredProps`. desiredProps: { // Example props that are cached in channels and other cache. Accepts an array of props of the cache. All props are optional. - guilds: ['channels', 'icon', 'id', 'name', 'roles'], - users: ['avatar', 'id', 'username'], + guild: ['channels', 'icon', 'id', 'name', 'roles'], + user: ['avatar', 'id', 'username'], }, // Define what to cache in memory. All props are optional except `default`. By default, all props inside `cacheInMemory` are set to `true`. cacheInMemory: { // Whether or not to cache guilds. - guilds: true, - channels: true, + guild: true, + channel: true, // Default value for the properties that are not provided inside `cacheInMemory`. default: false, }, // Define what to cache outside memory. All props are optional except `default`. By default, all props inside `cacheOutsideMemory` are set to `false`. cacheOutsideMemory: { // Whether or not to cache channels. - channels: false, - roles: false, + channel: false, + role: false, // Default value for the properties that are not provided inside `cacheOutsideMemory`. default: true, }, // Function to get an item from outside cache. `getItem`, `setItem`, `removeItem` must be provided if you cache outside memory, can be omitted if you don't store outside memory. setItem: (table, item) => { - if (table === 'channels') { + if (table === 'channel') { // Custom code to store data into your cache outside memory, say redis or a database or whichever you use. } }, @@ -90,6 +90,18 @@ await bot.cache.guilds.get(guildId); Each cache will be in their own property under `bot.cache` and each of them have the following methods: `delete`, `get`, `set`, usage of these should be self explanatory from intellisense. If you cache in memory and need access to the collection directly, you can use `bot.cache.guilds.memory`, this will return a collection. +### Types Support + +The types of cached objects change based on the provided `desiredProperties` and `undesiredProperties`, so only the stored properties will appear in your intelliSense, making the package easier to use. + +These types are also exposed under `bot.cache.$inferredTypes`, and if you wish, you can export them as with a custom name for ease of use, like: + +```ts +export type CachedGuild = typeof bot.cache.$inferredTypes.guild; +``` + +Now you can import `CachedGuild` in your code and use it. + ### Important Points To Note - Make sure to include the correct `bot.transformers.desiredProperties` somewhere in your code, this must include at least **all** the properties from `bot.cache.options.desiredProps` for it to cache all those properties you want to cache. @@ -113,7 +125,9 @@ shouldCache: { #### `options.bulk`: -Lets you define how to deal with bulk removal of data. Useful to provide when you use cache outside memory. For example, if you store channels individually and separately from a guild, say in a database, when a guild is deleted, all of those channels will be deleted individually in individual queries, which is not ideal, so you can use `options.bulk.removeGuild` to delete the guild and all the channels related to that guild as one query or so, whichever gives better performance. +This option allows you to specify how to handle the removal of objects that may trigger bulk modifications or deletions of associated entities. + +For example, if you store guild channels individually in a database separate from the guild itself, deleting a guild could result in each channel being deleted one by one through individual queries. This method can be inefficient, especially as the number of channels increases. To improve permformance, you can use `options.bulk.removeGuild` to remove the guild and all associated channels in a single query. This provides the following props: (should be self explanatory with intellisense) @@ -121,13 +135,38 @@ This provides the following props: (should be self explanatory with intellisense - `options.bulk.removeRole` - `options.bulk.replaceInternalBulkRemover` - To set props under this prop to tell the cache proxy whether or not to run internal bulk removers. -#### `options.maxCacheInactiveTime`: +#### `options.sweeper`: -Lets you provide the amount of inactive time (in milliseconds) for a cached object after which it should be removed from cache. Useful if for example you want to cache only active guilds. +This option allows you to specify options for sweeper. This works for in-memory cache only. For outside memory cache, you should implement your own sweeper. -#### `options.cacheSweepInterval`: +This provides the following props: -Lets you define the interval (in milliseconds) in which the cache sweeper should check for inactive objects based on maxCacheInactiveTime to clear them. +- `options.sweeper.interval` +- `options.sweeper.filter` + +##### `options.sweeper.interval`: + +The interval (in milliseconds) at which the cache sweeper should run the provided filter functions. + +##### `options.sweeper.filter`: + +This option allows you to provide filter functions to decide which object to remove from cache and which to keep. Defaults to removing nothing from the cache, so you should provide your own filters if you enable cache sweeper. + +Note: You can use the `lastInteractedTime` property in the object to implement an NRU (Not Recently Used) cache if you'd like. For example, if you'd like to only remove the members that aren't accessed in the last 15 minutes and isn't the bot member, you can do: + +```js +sweeper: { + // Run the sweeper every 5 minutes + interval: 300000, + filter: { + member: (member) => { + // Remove member from cache if it hasn't been accessed in the last 15 minutes and if the member isn't bot member + if (Date.now() - member.lastInteractedTime > 900000 && member.id !== bot.id) return true; + else return false; + } + } +} +``` ## Manual Caching diff --git a/website/docs/desired-properties.md b/website/docs/desired-properties.md index 2d8461f3a..bab107549 100644 --- a/website/docs/desired-properties.md +++ b/website/docs/desired-properties.md @@ -5,7 +5,7 @@ sidebar_label: Desired Properties # Desired Properties -The `desiredProperties` feature in Discordeno gives developers full control over memory utilization. This enables a highly lightweight setup, where only essential data is stored. +The `desiredProperties` feature in Discordeno gives developers full control over resource utilization. This enables a highly lightweight setup, where only the essential data is processed and stored. With `desiredProperties`, you can specify which properties to cache for each object type—such as users, members, channels, and guilds. This flexibility allows you to tailor caching to the exact needs of your bot, preserving only the data you truly require. @@ -31,29 +31,29 @@ Check the [TypeScript](#typescript) section if you are using typescript ## Configuring -To configure desired proprieties you can use the `desiredProperties` option on the `createBot` function +To configure desired properties, you can use the `desiredProperties` option on the `createBot` function. -The objects inside `desiredProperties` contains all the names of the objects that have desired proprieties and in them you will find all the properties of the objects. +The objects inside `desiredProperties` contains all the names of the objects that have desired properties and inside them you'll find all the properties of the objects. :::info[Flags and toggles] -Usually flags and toggles will be stored in a BitField to save on memory, Discordeno does provide getters on the objects for these flags however they aren't in desired properties with their individual names, instead you will find them as `toggles` and / or `flags` most of the cases. +Usually flags and toggles will be stored in a BitField to save on memory, Discordeno does provide getters on the objects for these flags, however they aren't in desired properties with their individual names, instead you will find them as `toggles` and / or `flags` most of the cases. ::: :::danger[NOT RECOMMENDED - Changing the default for Desired Properties] -You can change the default value for desired properties, using `desiredProprieties: createDesiredPropertiesObject({}, true) as CompleteDesiredProprieties<{}, true>` in the `createBot` function, however this will negate all the benefits desired proprieties provide. +You can change the default value for desired properties, using `desiredProperties: createDesiredPropertiesObject({}, true) as CompleteDesiredProperties<{}, true>` in the `createBot` function to make discordeno process all properties on all objects, however this will negate all the benefits desired properties provide. -The reason why this is not recommended is because while Desired Proprieties can be an annoyance at first, they have a significant performance impact on both CPU and memory usage. +The reason why this is not recommended is because while Desired Properties can be an annoyance at first, they have a significant performance impact on both CPU and memory usage. Again, this is **NOT** RECOMMENDED, especially if you plan to ship your bot to production. ::: -### Computed values +### Computed Properties -Some values in these object may depend on some other value, notable examples are `user.bot` and `interaction.respond`. If you do not include all the values they depend on these require you might face undefined behavior using these values. +Some properties in these object may depend on some other property, notable examples are `user.bot` and `interaction.respond`. If you do not include all the properties they depend on, you might see undefined values / unexpected bheavior when using them. ### Examples -In this example we will configure desired properties to have `user.id`, `user.bot` and `user.username`. +In this example, we will configure desired properties to have `user.id`, `user.bot` and `user.username`. ```ts const bot = createBot({ @@ -70,14 +70,14 @@ const bot = createBot({ ## TypeScript -Discordeno will give change the types of the supported objects to match your desired proprieties, for this reason you might get an error when incorrectly typing your functions. +Discordeno will change the types of the supported objects to match your desired properties, for this reason, you might get an error when incorrectly typing your functions. -Along side `desiredProperties` in the bot option that is explained above, `desiredPropertiesBehavior` is a configuration option for how should typescript threat proprieties that are not desired in your configuration. +Alongside `desiredProperties` in the bot option that is explained above, `desiredPropertiesBehavior` is a configuration option for how should typescript threat properties that are not desired in your configuration. -Discordeno does expose the customized type according to your desired properties in the `bot.transformers.$inferredTypes` object, in these you will find all the types to be used in your functions / variables / ... +Discordeno does expose the customized type according to your desired properties in the `bot.transformers.$inferredTypes` object, inside this property you'll find all the types to be used in your functions / variables etc. :::info -The value `bot.transformers.$inferredTypes` only exists for typescript. It will be `undefined` if tried to access at runtime, as it is not intended to provide any value at runtime, and it is intended to be used along side the `typeof` operator in typescript +The property `bot.transformers.$inferredTypes` only exists in typescript. It will be `undefined` if tried to access at runtime, as it is not intended to provide any value at runtime, and only intended to be used alongside the `typeof` operator in typescript. ::: ### Example @@ -109,7 +109,18 @@ function processMessage(message: typeof bot.transformers.$inferredTypes.message) } ``` -### Configuring +For ease of use, you can also have a single file where you export all these inferred types under a single type name, for example: + +```ts +import { bot } from './index.ts' + +export type Guild = typeof bot.transformers.$inferredTypes.guild +export type Message = typeof bot.transformers.$inferredTypes.message + +// Repeat this for all other types you'd like +``` + +### Configuring Desired Properties Behavior There are 2 behaviors, `ChangeType` and `RemoveKey`. The default behavior is `RemoveKey`. @@ -137,11 +148,11 @@ All the "undesired" properties will be removed from the type of the object. This The caveats of this behavior are the following: - You don't know all the properties available on the object -- If a value requires other values to be enabled you won't know them without searching it up (when a computed value is missing a dependency it won't be shown) +- If a property requires other properties to be enabled, you won't know them without searching it up (when a computed property is missing a dependency, it won't be shown) #### `ChangeType` All the "undesired" properties will be typed with a string that will explain why the property is disabled, this may also include the dependencies for said property if those are present. The caveats of this behavior are the following: -- Typescript may not always error on the usage of undesired proprieties as in some context the string will be a valid option +- Typescript may not always error on the usage of undesired properties, as in some cases, strings can be a valid option (e.g. channel.name is always a string so typescript won't error)