From c4811acf0403d8b8b38669d72d6dd20feb9b34bb Mon Sep 17 00:00:00 2001 From: kmmiio99o <164557248+kmmiio99o@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:30:27 +0100 Subject: [PATCH] feat: Fix some plugins not starting up I totally not chosen kettu index.ts file over shiggycord one :trolley: --- bun.lock | 1 + package.json | 112 ++++++++++++++++++++++---------------------- src/index.ts | 130 ++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 160 insertions(+), 83 deletions(-) diff --git a/bun.lock b/bun.lock index c8be63b..f3d769c 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "Kettu", diff --git a/package.json b/package.json index 78d95d7..15930e8 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,57 @@ { - "name": "Kettu", - "private": true, - "author": { - "name": "cocobo1", - "url": "https://github.com/C0C0B01" - }, - "scripts": { - "build": "node scripts/build.mjs", - "serve": "node scripts/serve.mjs", - "serve:adb": "bun run serve --adb", - "lint": "eslint ./src --ext .js,.jsx,.ts,.tsx" - }, - "license": "BSD-3-Clause", - "devDependencies": { - "@saithodev/semantic-release-backmerge": "^4.0.1", - "@semantic-release/changelog": "^6.0.3", - "@semantic-release/exec": "^6.0.3", - "@semantic-release/git": "^10.0.1", - "semantic-release": "^24.2.7", - "@swc/core": "^1.13.1", - "@swc/helpers": "^0.5.17", - "@types/node": "^20.19.9", - "@types/yargs-parser": "^21.0.3", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", - "@typescript-eslint/typescript-estree": "^7.18.0", - "chalk": "^5.4.1", - "esbuild": "^0.20.2", - "esbuild-plugin-globals": "^0.2.0", - "eslint": "^8.57.1", - "eslint-plugin-import-alias": "^1.2.0", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-simple-import-sort": "^12.1.1", - "eslint-plugin-unused-imports": "^3.2.0", - "typescript": "^5.8.3", - "yargs-parser": "^21.1.1" - }, - "dependencies": { - "@gullerya/object-observer": "^6.1.4", - "@tanstack/react-query": "^5.83.0", - "@types/chroma-js": "~2.4.5", - "@types/lodash": "~4.17.20", - "@types/react": "19.1.8", - "es-toolkit": "^1.39.7", - "fuzzysort": "^3.1.0", - "intl-messageformat": "^10.7.16", - "moment": "2.22.2", - "react-native": "0.78.0", - "react-native-reanimated": "^3.18.0", - "spitroast": "^1.4.4", - "type-fest": "^4.41.0" - }, - "trustedDependencies": [ - "@swc/core" - ] -} \ No newline at end of file + "name": "ShiggyCord", + "private": true, + "author": { + "name": "kmmiio99o", + "url": "https://github.com/kmmiio99o" + }, + "scripts": { + "build": "node scripts/build.mjs", + "serve": "node scripts/serve.mjs", + "serve:adb": "bun run serve --adb", + "lint": "eslint ./src --ext .js,.jsx,.ts,.tsx" + }, + "license": "BSD-3-Clause", + "devDependencies": { + "@saithodev/semantic-release-backmerge": "^4.0.1", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/exec": "^6.0.3", + "@semantic-release/git": "^10.0.1", + "semantic-release": "^24.2.7", + "@swc/core": "^1.13.1", + "@swc/helpers": "^0.5.17", + "@types/node": "^20.19.9", + "@types/yargs-parser": "^21.0.3", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", + "@typescript-eslint/typescript-estree": "^7.18.0", + "chalk": "^5.4.1", + "esbuild": "^0.20.2", + "esbuild-plugin-globals": "^0.2.0", + "eslint": "^8.57.1", + "eslint-plugin-import-alias": "^1.2.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-unused-imports": "^3.2.0", + "typescript": "^5.8.3", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "@gullerya/object-observer": "^6.1.4", + "@tanstack/react-query": "^5.83.0", + "@types/chroma-js": "~2.4.5", + "@types/lodash": "~4.17.20", + "@types/react": "19.1.8", + "es-toolkit": "^1.39.7", + "fuzzysort": "^3.1.0", + "intl-messageformat": "^10.7.16", + "moment": "2.22.2", + "react-native": "0.78.0", + "react-native-reanimated": "^3.18.0", + "spitroast": "^1.4.4", + "type-fest": "^4.41.0" + }, + "trustedDependencies": [ + "@swc/core" + ] +} diff --git a/src/index.ts b/src/index.ts index 89aaccf..9bab7dc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,9 +3,7 @@ import initFixes from "@core/fixes"; import { initFetchI18nStrings } from "@core/i18n"; import initSettings from "@core/ui/settings"; import { initVendettaObject } from "@core/vendetta/api"; -import { VdPluginManager } from "@core/vendetta/plugins"; import { updateFonts } from "@lib/addons/fonts"; -import { initPlugins, updatePlugins } from "@lib/addons/plugins"; import { initThemes } from "@lib/addons/themes"; import { patchCommands } from "@lib/api/commands"; import { patchLogHook } from "@lib/api/debug"; @@ -13,36 +11,114 @@ import { injectFluxInterceptor } from "@lib/api/flux"; import { patchJsx } from "@lib/api/react/jsx"; import { logger } from "@lib/utils/logger"; import { patchSettings } from "@ui/settings"; +import { InteractionManager } from "react-native"; +import { updaterSettings } from "@lib/api/settings"; +import { getDebugInfo } from "@lib/api/debug"; + +// Debug toggle helper (temporary runtime fallback). The helper is dynamically +// imported when needed (to avoid bundling it permanently) and removed after use. import * as lib from "./lib"; +/** + * Start sequence split into critical (UI) and deferred (network/plugin) work. + * The goal is to get the UI ready quickly and run heavy tasks after interactions. + */ export default async () => { - // Load everything in parallel + // Critical initializers that are required for the app's UI and basic features. + const criticalInits = [ + initThemes(), + injectFluxInterceptor(), + patchSettings(), + patchLogHook(), + patchCommands(), + patchJsx(), + patchErrorBoundary(), + initVendettaObject(), + initFetchI18nStrings(), + initSettings(), + initFixes(), + ]; - await Promise.all([ - initThemes(), - injectFluxInterceptor(), - patchSettings(), - patchLogHook(), - patchCommands(), - patchJsx(), - initVendettaObject(), - initFetchI18nStrings(), - initSettings(), - initFixes(), - patchErrorBoundary(), - updatePlugins(), - updateFonts(), - initPlugins(), - VdPluginManager.initPlugins(), - ]).then( - // Push them all to unloader - u => u.forEach(f => f && lib.unload.push(f)) + // Run critical inits and collect unpatchers/cleanup handlers. + await Promise.all(criticalInits) + .then((u) => u.forEach((f) => f && lib.unload.push(f))) + .catch((e) => { + // Log but don't abort — critical inits failing should be visible in logs. + console.warn("Critical initialization error:", e); + }); + + // Expose the library object early so UI and other code can access window.bunny. + window.bunny = lib; + + logger.log( + "ShiggyCord: UI-critical initialization complete — deferring plugin & network work", + ); + + // Deferred work: run after interactions to avoid blocking initial paint and navigation. + const runDeferred = async () => { + const { VdPluginManager } = await import("@core/vendetta/plugins"); + const { initPlugins, updatePlugins } = await import("@lib/addons/plugins"); + + // Initialize Vendetta plugins (may start many plugins) — do not block UI. + VdPluginManager.initPlugins() + .then((u) => lib.unload.push(u)) + .catch((e) => logger.log("Vendetta init failed:", e)); + + // Start ShiggyCord (Bunny) plugins now without forcing repository updates. + // Plugin repository fetching is deferred so the app can finish launching first. + // Stagger plugin startup to reduce CPU/memory spikes: use smaller batches and a small interval. + // This keeps the UI responsive while plugins initialize in the background. + initPlugins({ staggerInterval: 500, batchSize: 2 }); + + // Attempt a lightweight recovery toggle if some core plugins failed to start. + try { + // Dynamically import the helper (if present) but suppress verbose errors. + const mod = await import("@core/debug/toggleCorePlugins").catch( + () => null, + ); + if (mod?.default) { + // Run helper with minimal noise; ignore failures. + mod.default({ offDuration: 1500 }).catch(() => {}); + } + + // Try to remove the helper source file (best-effort, ignore failures). + await import("@lib/api/native/fs") + .then((fs) => fs.removeFile("src/core/debug/toggleCorePlugins.ts")) + .catch(() => {}); + } catch { + // suppressed + } + + // Update fonts in background + updateFonts().catch((e) => logger.log("updateFonts failed:", e)); + + // Schedule plugin repository update after a delay (5 minutes) so update work + // does not impact initial launch performance. + setTimeout( + () => { + updatePlugins().catch((e) => + logger.log("updatePlugins failed (deferred 5min):", e), + ); + }, + 5 * 60 * 1000, ); - // Assign window object - window.bunny = lib; + // Note: we intentionally moved the call to `updatePlugins()` above so core + // plugins are registered prior to calling `initPlugins()`. + }; - // We good :) - logger.log("Kettu is ready!"); -}; \ No newline at end of file + // Preferred: wait until interactions finish (animations / navigation). + try { + InteractionManager.runAfterInteractions(() => { + // small delay to ensure native lifecycle settled + setTimeout(runDeferred, 50); + }); + } catch (e) { + // Fallback if InteractionManager isn't available for any reason. + setTimeout(runDeferred, 200); + } + + // Final ready log for basic UI availability. + logger.log("ShiggyCord is ready."); +};