From be79d6328905d00058c42bf8b0ad544fad45a545 Mon Sep 17 00:00:00 2001 From: Qianyu Yang Date: Sun, 5 Jul 2026 21:16:38 +0900 Subject: [PATCH 1/5] refactor: Make generateSnakeAnimation Vercel serverless compatible - Keep core function pure and serverless-compatible - Returns in-memory strings for both SVG and GIF formats - No filesystem or child_process usage - Maintains identical behavior for actual generation --- .../generateSnakeAnimation.ts | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/generate-snake-animation/generateSnakeAnimation.ts b/packages/generate-snake-animation/generateSnakeAnimation.ts index 5634a5978f..c45d323ac1 100644 --- a/packages/generate-snake-animation/generateSnakeAnimation.ts +++ b/packages/generate-snake-animation/generateSnakeAnimation.ts @@ -20,12 +20,17 @@ export type Source = | { platform: "gitlab"; username: string; baseUrl?: string } | { platform: "forgejo"; username: string; baseUrl: string }; -export type Output = { +export type OutputConfig = { format: "svg" | "gif"; drawOptions: DrawOptions; animationOptions: AnimationOptions; }; +/** + * Result from generateSnakeAnimation - can be a string (SVG/GIF data) or null + */ +export type GenerationResult = string | Buffer | null; + export const getUserContribution = async (source: Source) => { switch (source.platform) { case "github": @@ -44,10 +49,18 @@ export const getUserContribution = async (source: Source) => { } }; +/** + * Generates snake animation in-memory without filesystem access. + * Returns results as strings/buffers ready for serverless environments. + * + * @param source - User contribution source (GitHub, GitLab, or Forgejo) + * @param outputs - Array of output configurations (SVG/GIF) + * @returns Promise of results - SVG as string, GIF as Buffer, or null if output is null + */ export const generateSnakeAnimation = async ( source: Source, - outputs: (Output | null)[], -) => { + outputs: (OutputConfig | null)[], +): Promise => { console.log(`🎣 fetching user contribution from ${source.platform}`); const cells = await getUserContribution(source); const grid = cellsToGrid(cells); @@ -59,7 +72,7 @@ export const generateSnakeAnimation = async ( return Promise.all( outputs.map(async (out, i) => { - if (!out) return; + if (!out) return null; const { format, drawOptions, animationOptions } = out; switch (format) { case "svg": { @@ -73,6 +86,7 @@ export const generateSnakeAnimation = async ( return createGif(grid, cells, chain, drawOptions, animationOptions); } } + return null; }), ); }; From 65750389baf828c55f655147c4d452be2c201334 Mon Sep 17 00:00:00 2001 From: Qianyu Yang Date: Sun, 5 Jul 2026 21:36:58 +0900 Subject: [PATCH 2/5] Update generateSnakeAnimation.ts --- .../generateSnakeAnimation.ts | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/generate-snake-animation/generateSnakeAnimation.ts b/packages/generate-snake-animation/generateSnakeAnimation.ts index c45d323ac1..5634a5978f 100644 --- a/packages/generate-snake-animation/generateSnakeAnimation.ts +++ b/packages/generate-snake-animation/generateSnakeAnimation.ts @@ -20,17 +20,12 @@ export type Source = | { platform: "gitlab"; username: string; baseUrl?: string } | { platform: "forgejo"; username: string; baseUrl: string }; -export type OutputConfig = { +export type Output = { format: "svg" | "gif"; drawOptions: DrawOptions; animationOptions: AnimationOptions; }; -/** - * Result from generateSnakeAnimation - can be a string (SVG/GIF data) or null - */ -export type GenerationResult = string | Buffer | null; - export const getUserContribution = async (source: Source) => { switch (source.platform) { case "github": @@ -49,18 +44,10 @@ export const getUserContribution = async (source: Source) => { } }; -/** - * Generates snake animation in-memory without filesystem access. - * Returns results as strings/buffers ready for serverless environments. - * - * @param source - User contribution source (GitHub, GitLab, or Forgejo) - * @param outputs - Array of output configurations (SVG/GIF) - * @returns Promise of results - SVG as string, GIF as Buffer, or null if output is null - */ export const generateSnakeAnimation = async ( source: Source, - outputs: (OutputConfig | null)[], -): Promise => { + outputs: (Output | null)[], +) => { console.log(`🎣 fetching user contribution from ${source.platform}`); const cells = await getUserContribution(source); const grid = cellsToGrid(cells); @@ -72,7 +59,7 @@ export const generateSnakeAnimation = async ( return Promise.all( outputs.map(async (out, i) => { - if (!out) return null; + if (!out) return; const { format, drawOptions, animationOptions } = out; switch (format) { case "svg": { @@ -86,7 +73,6 @@ export const generateSnakeAnimation = async ( return createGif(grid, cells, chain, drawOptions, animationOptions); } } - return null; }), ); }; From cc6cea38e0979b92343f3a177dea9e42a271cca6 Mon Sep 17 00:00:00 2001 From: Qianyu Yang Date: Sun, 5 Jul 2026 21:38:01 +0900 Subject: [PATCH 3/5] Update generateSnakeAnimation function signature and types Refactor generateSnakeAnimation to use OutputConfig type and update return handling for null outputs. --- .../generateSnakeAnimation.ts | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/generate-snake-animation/generateSnakeAnimation.ts b/packages/generate-snake-animation/generateSnakeAnimation.ts index 5634a5978f..8f3830ef64 100644 --- a/packages/generate-snake-animation/generateSnakeAnimation.ts +++ b/packages/generate-snake-animation/generateSnakeAnimation.ts @@ -20,12 +20,17 @@ export type Source = | { platform: "gitlab"; username: string; baseUrl?: string } | { platform: "forgejo"; username: string; baseUrl: string }; -export type Output = { +export type OutputConfig = { format: "svg" | "gif"; drawOptions: DrawOptions; animationOptions: AnimationOptions; }; +/** + * Result from generateSnakeAnimation - can be a string (SVG/GIF data) or null + */ +export type GenerationResult = string | Buffer | null; + export const getUserContribution = async (source: Source) => { switch (source.platform) { case "github": @@ -44,10 +49,18 @@ export const getUserContribution = async (source: Source) => { } }; +/** + * Generates snake animation in-memory without filesystem access. + * Returns results as strings/buffers ready for serverless environments. + * + * @param source - User contribution source (GitHub, GitLab, or Forgejo) + * @param outputs - Array of output configurations (SVG/GIF) + * @returns Promise of results - SVG as string, GIF as Buffer, or null if output is null + */ export const generateSnakeAnimation = async ( source: Source, - outputs: (Output | null)[], -) => { + outputs: (OutputConfig | null)[], +): Promise => { console.log(`🎣 fetching user contribution from ${source.platform}`); const cells = await getUserContribution(source); const grid = cellsToGrid(cells); @@ -59,7 +72,7 @@ export const generateSnakeAnimation = async ( return Promise.all( outputs.map(async (out, i) => { - if (!out) return; + if (!out) return null; const { format, drawOptions, animationOptions } = out; switch (format) { case "svg": { @@ -73,6 +86,7 @@ export const generateSnakeAnimation = async ( return createGif(grid, cells, chain, drawOptions, animationOptions); } } + return null; }), ); }; From 684a6f43480ee4004a4d9b02be4b92a0c3a628e4 Mon Sep 17 00:00:00 2001 From: Qianyu Yang Date: Sun, 5 Jul 2026 21:38:36 +0900 Subject: [PATCH 4/5] Revert "Update generateSnakeAnimation function signature and types" --- .../generateSnakeAnimation.ts | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/generate-snake-animation/generateSnakeAnimation.ts b/packages/generate-snake-animation/generateSnakeAnimation.ts index 8f3830ef64..5634a5978f 100644 --- a/packages/generate-snake-animation/generateSnakeAnimation.ts +++ b/packages/generate-snake-animation/generateSnakeAnimation.ts @@ -20,17 +20,12 @@ export type Source = | { platform: "gitlab"; username: string; baseUrl?: string } | { platform: "forgejo"; username: string; baseUrl: string }; -export type OutputConfig = { +export type Output = { format: "svg" | "gif"; drawOptions: DrawOptions; animationOptions: AnimationOptions; }; -/** - * Result from generateSnakeAnimation - can be a string (SVG/GIF data) or null - */ -export type GenerationResult = string | Buffer | null; - export const getUserContribution = async (source: Source) => { switch (source.platform) { case "github": @@ -49,18 +44,10 @@ export const getUserContribution = async (source: Source) => { } }; -/** - * Generates snake animation in-memory without filesystem access. - * Returns results as strings/buffers ready for serverless environments. - * - * @param source - User contribution source (GitHub, GitLab, or Forgejo) - * @param outputs - Array of output configurations (SVG/GIF) - * @returns Promise of results - SVG as string, GIF as Buffer, or null if output is null - */ export const generateSnakeAnimation = async ( source: Source, - outputs: (OutputConfig | null)[], -): Promise => { + outputs: (Output | null)[], +) => { console.log(`🎣 fetching user contribution from ${source.platform}`); const cells = await getUserContribution(source); const grid = cellsToGrid(cells); @@ -72,7 +59,7 @@ export const generateSnakeAnimation = async ( return Promise.all( outputs.map(async (out, i) => { - if (!out) return null; + if (!out) return; const { format, drawOptions, animationOptions } = out; switch (format) { case "svg": { @@ -86,7 +73,6 @@ export const generateSnakeAnimation = async ( return createGif(grid, cells, chain, drawOptions, animationOptions); } } - return null; }), ); }; From 9e0227aa78768c0ec90712139d40aa466c3bb35b Mon Sep 17 00:00:00 2001 From: Qianyu Yang Date: Sun, 5 Jul 2026 21:40:20 +0900 Subject: [PATCH 5/5] Update generateSnakeAnimation.ts --- .../generateSnakeAnimation.ts | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/generate-snake-animation/generateSnakeAnimation.ts b/packages/generate-snake-animation/generateSnakeAnimation.ts index 5634a5978f..8f3830ef64 100644 --- a/packages/generate-snake-animation/generateSnakeAnimation.ts +++ b/packages/generate-snake-animation/generateSnakeAnimation.ts @@ -20,12 +20,17 @@ export type Source = | { platform: "gitlab"; username: string; baseUrl?: string } | { platform: "forgejo"; username: string; baseUrl: string }; -export type Output = { +export type OutputConfig = { format: "svg" | "gif"; drawOptions: DrawOptions; animationOptions: AnimationOptions; }; +/** + * Result from generateSnakeAnimation - can be a string (SVG/GIF data) or null + */ +export type GenerationResult = string | Buffer | null; + export const getUserContribution = async (source: Source) => { switch (source.platform) { case "github": @@ -44,10 +49,18 @@ export const getUserContribution = async (source: Source) => { } }; +/** + * Generates snake animation in-memory without filesystem access. + * Returns results as strings/buffers ready for serverless environments. + * + * @param source - User contribution source (GitHub, GitLab, or Forgejo) + * @param outputs - Array of output configurations (SVG/GIF) + * @returns Promise of results - SVG as string, GIF as Buffer, or null if output is null + */ export const generateSnakeAnimation = async ( source: Source, - outputs: (Output | null)[], -) => { + outputs: (OutputConfig | null)[], +): Promise => { console.log(`🎣 fetching user contribution from ${source.platform}`); const cells = await getUserContribution(source); const grid = cellsToGrid(cells); @@ -59,7 +72,7 @@ export const generateSnakeAnimation = async ( return Promise.all( outputs.map(async (out, i) => { - if (!out) return; + if (!out) return null; const { format, drawOptions, animationOptions } = out; switch (format) { case "svg": { @@ -73,6 +86,7 @@ export const generateSnakeAnimation = async ( return createGif(grid, cells, chain, drawOptions, animationOptions); } } + return null; }), ); };