mirror of
https://github.com/jaronpate/unicord.git
synced 2026-10-18 21:47:40 +00:00
regorganizing and attempting to allow rehydration
This commit is contained in:
@@ -7,12 +7,34 @@ import type { Client } from "./client";
|
||||
|
||||
export type GatewayObject = Message;
|
||||
export type Hydrateable = Context | GatewayObject
|
||||
export type Hydrated<T extends Hydrateable, K extends Array<Expectation>> =
|
||||
export type Hydrated<T extends Hydrateable, K extends Array<Expectation>> =
|
||||
T extends Message ? HydratedMessage<K> :
|
||||
T extends Context ? HydratedContext<K> : never;
|
||||
|
||||
export async function hydrator<T extends Hydrateable, K extends Array<Expectation>>(data: T, expectations: K, client: Client, api: API): Promise<(data: unknown) => data is Hydrated<T, K>> {
|
||||
let hydrated = true;
|
||||
/**
|
||||
* Hydrates a given data object based on the provided expectations.
|
||||
*
|
||||
* @template T - The type of the data object to be hydrated. Must extend `Hydrateable`.
|
||||
* @template K - An array of `Expectation` types that specify what properties should be hydrated.
|
||||
*
|
||||
* @param data - The data object to be hydrated. Can be of type `Context` or `Message`.
|
||||
* @param expectations - An array of expectations that specify what properties should be hydrated.
|
||||
* @param client - The client instance used to fetch additional data required for hydration.
|
||||
* @param api - The API instance used to fetch additional data required for hydration.
|
||||
*
|
||||
* @returns A promise that resolves to the hydrated data object.
|
||||
*
|
||||
* @throws Will throw an error if an expectation cannot be resolved.
|
||||
*/
|
||||
export async function hydrate<T extends Hydrateable | Hydrated<any, any>, K extends Array<Expectation>>(
|
||||
data: T,
|
||||
expectations: K,
|
||||
client: Client,
|
||||
api: API
|
||||
): Promise<T extends Hydrated<infer U, infer H> ? Hydrated<T & U, [...H, ...K]> : Hydrated<T, K>> {
|
||||
// TODO: add clone trait. Make it a requirement for hydrateable objects.
|
||||
// Then clone the object and return the hydrated object.
|
||||
let hydrated: Hydrated<T, K>;
|
||||
|
||||
if (data instanceof Context) {
|
||||
for (const expectation of expectations) {
|
||||
@@ -20,8 +42,7 @@ export async function hydrator<T extends Hydrateable, K extends Array<Expectatio
|
||||
let context = data as unknown as HydratedContext<[Expectation.Guild, ...Expectation[]]>;
|
||||
context.guild = await client.guilds.get(data.guild_id);
|
||||
} else {
|
||||
hydrated = false;
|
||||
break;
|
||||
throw new Error(`Could not resolve expectation: ${expectation}`);
|
||||
}
|
||||
}
|
||||
} else if (data instanceof Message) {
|
||||
@@ -33,13 +54,45 @@ export async function hydrator<T extends Hydrateable, K extends Array<Expectatio
|
||||
let message = data as unknown as HydratedMessage<[Expectation.Guild, ...Expectation[]]>;
|
||||
message.guild = await client.guilds.get(data.guild_id);
|
||||
} else {
|
||||
hydrated = false;
|
||||
break;
|
||||
throw new Error(`Could not resolve expectation: ${expectation}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return function (data: unknown): data is Hydrated<T, K> {
|
||||
return data as unknown as (T extends Hydrated<infer U, infer H> ? Hydrated<T & U, [...H, ...K]> : Hydrated<T, K>);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper function that attempts to hydrate a given data object and returns a type guard function.
|
||||
*
|
||||
* @template T - The type of the data object to be hydrated. Must extend `Hydrateable`.
|
||||
* @template K - An array of `Expectation` types that specify what properties should be hydrated.
|
||||
*
|
||||
* @param data - The data object to be hydrated. Can be of type `Context` or `Message`.
|
||||
* @param expectations - An array of expectations that specify what properties should be hydrated.
|
||||
* @param client - The client instance used to fetch additional data required for hydration.
|
||||
* @param api - The API instance used to fetch additional data required for hydration.
|
||||
*
|
||||
* @returns A promise that resolves to a type guard function. The type guard function returns `true` if the data object was successfully hydrated, otherwise `false`.
|
||||
*/
|
||||
export async function hydrator<T extends Hydrateable | Hydrated<any, any>, K extends Array<Expectation>>(
|
||||
data: T,
|
||||
expectations: K,
|
||||
client: Client,
|
||||
api: API
|
||||
): Promise<(data: unknown) => data is T extends Hydrated<infer U, infer H> ? Hydrated<T & U, [...H, ...K]> : Hydrated<T, K>> {
|
||||
let hydrated = true;
|
||||
|
||||
try {
|
||||
// TODO: When clone is implemented we will receive a clone of the object here
|
||||
// So in hydrator we will need to copy the properties from the clone to the original object
|
||||
await hydrate(data, expectations, client, api);
|
||||
} catch (error) {
|
||||
hydrated = false;
|
||||
}
|
||||
|
||||
// BUG: Resolves to never after hydrations on an already hydrated object
|
||||
return function (data: unknown): data is T extends Hydrated<infer U, infer H> ? Hydrated<T & U, [...H, ...K]> : Hydrated<T, K> {
|
||||
return hydrated;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user