Skip to content

Commit

Permalink
chore: add new derive events and some proxy fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kravetsone committed Apr 11, 2024
1 parent 368b178 commit a0e16c9
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 30 deletions.
Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
],
"devDependencies": {
"@types/bun": "^1.0.12",
"gramio": "^0.0.26",
"typescript": "^5.4.4"
"gramio": "^0.0.27",
"typescript": "^5.4.5"
},
"peerDependencies": {
"gramio": "^0.0.20"
"gramio": "^0.0.27"
},
"dependencies": {
"@gramio/storage": "^0.0.1"
"@gramio/storage": "^0.0.2"
},
"files": [
"dist"
Expand Down
127 changes: 101 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,73 @@ import {
type ContextType,
type MaybePromise,
Plugin,
isPlainObject,
} from "gramio";

type Events = [
"message",
"callback_query",
"channel_post",
"chat_join_request",
"chosen_inline_result",
"inline_query",
"web_app_data",
"successful_payment",
"video_chat_started",
"video_chat_ended",
"video_chat_scheduled",
"video_chat_participants_invited",
"passport_data",
"new_chat_title",
"new_chat_photo",
"pinned_message",
"poll_answer",
"pre_checkout_query",
"proximity_alert_triggered",
"shipping_query",
"group_chat_created",
"delete_chat_photo",
"location",
"invoice",
"message_auto_delete_timer_changed",
"migrate_from_chat_id",
"migrate_to_chat_id",
"new_chat_members",
][number];

interface SessionOptions<
Data = unknown,
Key extends string | undefined = "session",
> {
key?: Key;
storage?: Storage;
getSessionKey?: (
context: ContextType<BotLike, "message">,
context: ContextType<BotLike, Events>,
) => MaybePromise<string>;
initial?: (context: ContextType<BotLike, "message">) => MaybePromise<Data>;
initial?: (context: ContextType<BotLike, Events>) => MaybePromise<Data>;
}

// biome-ignore lint/suspicious/noExplicitAny: <explanation>
function createProxy(value: any, storage: Storage, sessionKey: string) {
function createProxy<T>(
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
value: any,
onUpdate: () => unknown,
sessionKey: string,
): T {
if (typeof value !== "object") return value;

return new Proxy(value, {
get(target, key) {
return target[key];
const value = target[key];

return isPlainObject(value) || Array.isArray(value)
? createProxy(value, onUpdate, sessionKey)
: value;
},
set(target, key, newValue) {
target[key] = newValue;

storage.set(sessionKey, target);
onUpdate();

return true;
},
});
Expand All @@ -42,29 +85,61 @@ export function session<Data = unknown, Key extends string = "session">(
const storage = options.storage ?? inMemoryStorage();
const getSessionKey =
options.getSessionKey ??
((context: ContextType<BotLike, "message">) => `${context.senderId}`);
((context: ContextType<BotLike, Events>) => `${context.senderId}`);

return new Plugin("@gramio/session").derive("message", async (context) => {
const obj = {} as { [key in typeof key]: Data };
return new Plugin("@gramio/session").derive(
[
"message",
"callback_query",
"channel_post",
"chat_join_request",
"chosen_inline_result",
"inline_query",
"web_app_data",
"successful_payment",
"video_chat_started",
"video_chat_ended",
"video_chat_scheduled",
"video_chat_participants_invited",
"passport_data",
"new_chat_title",
"new_chat_photo",
"pinned_message",
"poll_answer",
"pre_checkout_query",
"proximity_alert_triggered",
"shipping_query",
"group_chat_created",
"delete_chat_photo",
"location",
"invoice",
"message_auto_delete_timer_changed",
"migrate_from_chat_id",
"migrate_to_chat_id",
"new_chat_members",
],
async (context) => {
const obj = {} as { [key in typeof key]: Data };

const sessionKey = await getSessionKey(context);
const sessionKey = await getSessionKey(context);

const session =
(await storage.get(sessionKey)) ??
(options.initial && (await options.initial(context))) ??
{};
const sessionData =
(await storage.get(sessionKey)) ??
(options.initial && (await options.initial(context))) ??
{};
const onUpdate: () => unknown = () => storage.set(sessionKey, session);

Object.defineProperty(obj, key, {
enumerable: true,
get() {
return createProxy(session, storage, sessionKey);
},
set(value) {
// TODO: optimize it
storage.set(sessionKey, value);
},
});
let session = createProxy(sessionData, onUpdate, sessionKey);

return obj;
});
Object.defineProperty(obj, key, {
enumerable: true,
get: () => session,
set(value) {
session = createProxy(value, onUpdate, sessionKey);
},
});

return obj;
},
);
}

0 comments on commit a0e16c9

Please sign in to comment.