feat!: new repo system + versioning system support + bug fixes
BREAKING CHANGES:
- New versioning system: Allowing any amount of number segments, with prerelease support.
- Any number of segments is supported: 1, 1.0, 1.0.0, 1.0.0.0, ...
- Prerelease labels are compared "digit-run", similar to Debian.
- Plugins must specify a version.
- User-facing plugins should use CalVer. API plugins should use SemVer.
Revenge APIs use SemVer while the new `discord` dependency parses the Discord version string directly.
- Dependency is now a Map, with support for version ranges and optional. Suggested URL is removed. (See new repo system)
- Plugins will now have to declare a dependency on `revenge.api` (Revenge API version) and `discord` (Discord version).
- Manifest now requires a format version (currently `1`)
New APIs:
- lib/plugins/utils: Utilities to format versioning
Features:
- New repo system: Repository design is inspired by Linux package repositories.
- Repos host manifest, versions, channels, download URL/size, and hash for multiple plugins.
- New dependency system: Plugins are versioned, and shouldn't break when updates come.
Plugins can now declare dependency on supported Discord/Revenge API versions, so they won't break with auto-updates.
Dependencies can be optional, but dependency on `revenge.api` and `discord` must be required.
Dependents are soft-disabled when dependencies don't satisfy. Once satisfied, the plugin can start again.
- All updates for running plugins REQUIRE a reload to prevent stale linking issues. Both native and JS-side.
- Update checking is handled entirely by JS. But the native-side still handles installation, indexing, and verification.
- Local indexes are updated against remote indexes. Dependency checking always uses local indexes.
- Users can add custom repositories and custom their priority order. URL is the identity.
- Plugins can now have custom data URI icons instead of being restricted to React Native app assets.
- External plugin installs require UI confirmation before installing.
- Pending Update and Pending Reload filters in Plugins page.
- Ability to browse external plugins in repositories. Official repository will be added soon.
Fixes/Refactor:
- Refactored Plugin-related settings to a separate "Plugin Settings" plugin.
- Masonry layout fixes in landscape.
- Updated plugins now show "reload to apply" toast instead.
- Removed dead code.
2026-07-25 23:35:23 +07:00
|
|
|
import { getPluginDependencies, isPluginStartable } from '../_internal'
|
2026-04-07 22:34:34 +07:00
|
|
|
import { pApis } from './decorators'
|
2025-07-20 23:06:56 +07:00
|
|
|
import type { AnyPlugin } from '../_internal'
|
|
|
|
|
|
|
|
|
|
/// PLUGIN DEPENDENCY GRAPHING
|
|
|
|
|
|
|
|
|
|
// We don't store the graph as a tree, but rather as a set of nodes.
|
|
|
|
|
|
|
|
|
|
// Root nodes are plugins that have dependencies, but no dependents. These plugins are the starting points of the dependency graph.
|
|
|
|
|
// Leaf nodes are plugins that have no dependencies, but may have dependents. These plugins are the end points of the dependency graph.
|
|
|
|
|
|
|
|
|
|
// Start order: Single nodes (no dependencies & dependents) -> Leaf nodes (no dependencies, maybe dependents) -> Root nodes (with dependencies, no dependents)
|
|
|
|
|
// This way we can ensure that all dependencies are started before the plugin itself.
|
|
|
|
|
|
|
|
|
|
export const pRootNodes = new Set<AnyPlugin>()
|
|
|
|
|
export const pLeafOrSingleNodes = new Set<AnyPlugin>()
|
|
|
|
|
|
2025-07-21 14:01:21 +07:00
|
|
|
// Visited non-leaf nodes
|
2025-07-26 01:58:17 +07:00
|
|
|
const visited = new Set<AnyPlugin>()
|
2025-07-20 23:34:31 +07:00
|
|
|
|
2025-07-20 23:06:56 +07:00
|
|
|
// Ordered list of plugins to be started
|
2025-07-20 23:34:31 +07:00
|
|
|
export const pListOrdered: AnyPlugin[] = []
|
2025-07-20 23:06:56 +07:00
|
|
|
// Pending plugins to be computed
|
|
|
|
|
export const pPending = new Set<AnyPlugin>()
|
|
|
|
|
|
feat!: new repo system + versioning system support + bug fixes
BREAKING CHANGES:
- New versioning system: Allowing any amount of number segments, with prerelease support.
- Any number of segments is supported: 1, 1.0, 1.0.0, 1.0.0.0, ...
- Prerelease labels are compared "digit-run", similar to Debian.
- Plugins must specify a version.
- User-facing plugins should use CalVer. API plugins should use SemVer.
Revenge APIs use SemVer while the new `discord` dependency parses the Discord version string directly.
- Dependency is now a Map, with support for version ranges and optional. Suggested URL is removed. (See new repo system)
- Plugins will now have to declare a dependency on `revenge.api` (Revenge API version) and `discord` (Discord version).
- Manifest now requires a format version (currently `1`)
New APIs:
- lib/plugins/utils: Utilities to format versioning
Features:
- New repo system: Repository design is inspired by Linux package repositories.
- Repos host manifest, versions, channels, download URL/size, and hash for multiple plugins.
- New dependency system: Plugins are versioned, and shouldn't break when updates come.
Plugins can now declare dependency on supported Discord/Revenge API versions, so they won't break with auto-updates.
Dependencies can be optional, but dependency on `revenge.api` and `discord` must be required.
Dependents are soft-disabled when dependencies don't satisfy. Once satisfied, the plugin can start again.
- All updates for running plugins REQUIRE a reload to prevent stale linking issues. Both native and JS-side.
- Update checking is handled entirely by JS. But the native-side still handles installation, indexing, and verification.
- Local indexes are updated against remote indexes. Dependency checking always uses local indexes.
- Users can add custom repositories and custom their priority order. URL is the identity.
- Plugins can now have custom data URI icons instead of being restricted to React Native app assets.
- External plugin installs require UI confirmation before installing.
- Pending Update and Pending Reload filters in Plugins page.
- Ability to browse external plugins in repositories. Official repository will be added soon.
Fixes/Refactor:
- Refactored Plugin-related settings to a separate "Plugin Settings" plugin.
- Masonry layout fixes in landscape.
- Updated plugins now show "reload to apply" toast instead.
- Removed dead code.
2026-07-25 23:35:23 +07:00
|
|
|
// Reserved dependencies verified by native
|
|
|
|
|
export const ApiDependencyId = 'revenge.api'
|
|
|
|
|
export const DiscordDependencyId = 'discord'
|
|
|
|
|
|
|
|
|
|
export function isReservedDependency(id: string) {
|
|
|
|
|
return id === ApiDependencyId || id === DiscordDependencyId
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Whether the plugin has start-order dependencies. Reserved dependencies don't count.
|
|
|
|
|
*/
|
|
|
|
|
function hasGraphableDependencies(plugin: AnyPlugin): boolean {
|
|
|
|
|
const deps = plugin.manifest.dependencies
|
|
|
|
|
if (!deps) return false
|
|
|
|
|
for (const id in deps) if (!isReservedDependency(id)) return true
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-20 23:06:56 +07:00
|
|
|
export function computePendingNodes() {
|
feat!: new repo system + versioning system support + bug fixes
BREAKING CHANGES:
- New versioning system: Allowing any amount of number segments, with prerelease support.
- Any number of segments is supported: 1, 1.0, 1.0.0, 1.0.0.0, ...
- Prerelease labels are compared "digit-run", similar to Debian.
- Plugins must specify a version.
- User-facing plugins should use CalVer. API plugins should use SemVer.
Revenge APIs use SemVer while the new `discord` dependency parses the Discord version string directly.
- Dependency is now a Map, with support for version ranges and optional. Suggested URL is removed. (See new repo system)
- Plugins will now have to declare a dependency on `revenge.api` (Revenge API version) and `discord` (Discord version).
- Manifest now requires a format version (currently `1`)
New APIs:
- lib/plugins/utils: Utilities to format versioning
Features:
- New repo system: Repository design is inspired by Linux package repositories.
- Repos host manifest, versions, channels, download URL/size, and hash for multiple plugins.
- New dependency system: Plugins are versioned, and shouldn't break when updates come.
Plugins can now declare dependency on supported Discord/Revenge API versions, so they won't break with auto-updates.
Dependencies can be optional, but dependency on `revenge.api` and `discord` must be required.
Dependents are soft-disabled when dependencies don't satisfy. Once satisfied, the plugin can start again.
- All updates for running plugins REQUIRE a reload to prevent stale linking issues. Both native and JS-side.
- Update checking is handled entirely by JS. But the native-side still handles installation, indexing, and verification.
- Local indexes are updated against remote indexes. Dependency checking always uses local indexes.
- Users can add custom repositories and custom their priority order. URL is the identity.
- Plugins can now have custom data URI icons instead of being restricted to React Native app assets.
- External plugin installs require UI confirmation before installing.
- Pending Update and Pending Reload filters in Plugins page.
- Ability to browse external plugins in repositories. Official repository will be added soon.
Fixes/Refactor:
- Refactored Plugin-related settings to a separate "Plugin Settings" plugin.
- Masonry layout fixes in landscape.
- Updated plugins now show "reload to apply" toast instead.
- Removed dead code.
2026-07-25 23:35:23 +07:00
|
|
|
for (const plugin of pPending)
|
|
|
|
|
if (isPluginStartable(plugin)) resolvePluginGraph(plugin)
|
2025-07-20 23:06:56 +07:00
|
|
|
|
2026-04-07 22:34:34 +07:00
|
|
|
const apis: AnyPlugin[] = []
|
|
|
|
|
|
|
|
|
|
for (const plugin of pLeafOrSingleNodes) {
|
|
|
|
|
if (pApis.has(plugin)) apis.push(plugin)
|
|
|
|
|
else pListOrdered.unshift(plugin)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const plugin of apis) pListOrdered.unshift(plugin)
|
2025-07-21 15:32:32 +07:00
|
|
|
|
2025-07-20 23:06:56 +07:00
|
|
|
const stack = [...pRootNodes]
|
|
|
|
|
while (stack.length) {
|
2025-07-21 21:27:17 +07:00
|
|
|
const plugin = stack.shift()!
|
2025-07-20 23:06:56 +07:00
|
|
|
|
2025-07-21 21:27:17 +07:00
|
|
|
if (visited.has(plugin)) {
|
2025-07-20 23:34:31 +07:00
|
|
|
pListOrdered.push(plugin)
|
2025-07-21 21:27:17 +07:00
|
|
|
continue
|
2025-07-20 23:34:31 +07:00
|
|
|
}
|
2025-07-21 21:27:17 +07:00
|
|
|
|
feat!: new repo system + versioning system support + bug fixes
BREAKING CHANGES:
- New versioning system: Allowing any amount of number segments, with prerelease support.
- Any number of segments is supported: 1, 1.0, 1.0.0, 1.0.0.0, ...
- Prerelease labels are compared "digit-run", similar to Debian.
- Plugins must specify a version.
- User-facing plugins should use CalVer. API plugins should use SemVer.
Revenge APIs use SemVer while the new `discord` dependency parses the Discord version string directly.
- Dependency is now a Map, with support for version ranges and optional. Suggested URL is removed. (See new repo system)
- Plugins will now have to declare a dependency on `revenge.api` (Revenge API version) and `discord` (Discord version).
- Manifest now requires a format version (currently `1`)
New APIs:
- lib/plugins/utils: Utilities to format versioning
Features:
- New repo system: Repository design is inspired by Linux package repositories.
- Repos host manifest, versions, channels, download URL/size, and hash for multiple plugins.
- New dependency system: Plugins are versioned, and shouldn't break when updates come.
Plugins can now declare dependency on supported Discord/Revenge API versions, so they won't break with auto-updates.
Dependencies can be optional, but dependency on `revenge.api` and `discord` must be required.
Dependents are soft-disabled when dependencies don't satisfy. Once satisfied, the plugin can start again.
- All updates for running plugins REQUIRE a reload to prevent stale linking issues. Both native and JS-side.
- Update checking is handled entirely by JS. But the native-side still handles installation, indexing, and verification.
- Local indexes are updated against remote indexes. Dependency checking always uses local indexes.
- Users can add custom repositories and custom their priority order. URL is the identity.
- Plugins can now have custom data URI icons instead of being restricted to React Native app assets.
- External plugin installs require UI confirmation before installing.
- Pending Update and Pending Reload filters in Plugins page.
- Ability to browse external plugins in repositories. Official repository will be added soon.
Fixes/Refactor:
- Refactored Plugin-related settings to a separate "Plugin Settings" plugin.
- Masonry layout fixes in landscape.
- Updated plugins now show "reload to apply" toast instead.
- Removed dead code.
2026-07-25 23:35:23 +07:00
|
|
|
if (hasGraphableDependencies(plugin)) {
|
|
|
|
|
for (const dep of getPluginDependencies(plugin, false))
|
2025-07-25 20:10:33 +07:00
|
|
|
if (!pLeafOrSingleNodes.has(dep)) stack.push(dep)
|
|
|
|
|
|
2025-07-21 21:27:17 +07:00
|
|
|
stack.push(plugin)
|
|
|
|
|
visited.add(plugin)
|
|
|
|
|
} else pListOrdered.push(plugin)
|
2025-07-20 23:06:56 +07:00
|
|
|
}
|
2025-07-25 20:10:33 +07:00
|
|
|
|
|
|
|
|
pPending.clear()
|
|
|
|
|
pLeafOrSingleNodes.clear()
|
|
|
|
|
pRootNodes.clear()
|
2025-07-26 01:58:17 +07:00
|
|
|
visited.clear()
|
2025-07-20 23:06:56 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function resolvePluginGraph(plugin: AnyPlugin) {
|
feat!: new repo system + versioning system support + bug fixes
BREAKING CHANGES:
- New versioning system: Allowing any amount of number segments, with prerelease support.
- Any number of segments is supported: 1, 1.0, 1.0.0, 1.0.0.0, ...
- Prerelease labels are compared "digit-run", similar to Debian.
- Plugins must specify a version.
- User-facing plugins should use CalVer. API plugins should use SemVer.
Revenge APIs use SemVer while the new `discord` dependency parses the Discord version string directly.
- Dependency is now a Map, with support for version ranges and optional. Suggested URL is removed. (See new repo system)
- Plugins will now have to declare a dependency on `revenge.api` (Revenge API version) and `discord` (Discord version).
- Manifest now requires a format version (currently `1`)
New APIs:
- lib/plugins/utils: Utilities to format versioning
Features:
- New repo system: Repository design is inspired by Linux package repositories.
- Repos host manifest, versions, channels, download URL/size, and hash for multiple plugins.
- New dependency system: Plugins are versioned, and shouldn't break when updates come.
Plugins can now declare dependency on supported Discord/Revenge API versions, so they won't break with auto-updates.
Dependencies can be optional, but dependency on `revenge.api` and `discord` must be required.
Dependents are soft-disabled when dependencies don't satisfy. Once satisfied, the plugin can start again.
- All updates for running plugins REQUIRE a reload to prevent stale linking issues. Both native and JS-side.
- Update checking is handled entirely by JS. But the native-side still handles installation, indexing, and verification.
- Local indexes are updated against remote indexes. Dependency checking always uses local indexes.
- Users can add custom repositories and custom their priority order. URL is the identity.
- Plugins can now have custom data URI icons instead of being restricted to React Native app assets.
- External plugin installs require UI confirmation before installing.
- Pending Update and Pending Reload filters in Plugins page.
- Ability to browse external plugins in repositories. Official repository will be added soon.
Fixes/Refactor:
- Refactored Plugin-related settings to a separate "Plugin Settings" plugin.
- Masonry layout fixes in landscape.
- Updated plugins now show "reload to apply" toast instead.
- Removed dead code.
2026-07-25 23:35:23 +07:00
|
|
|
if (hasGraphableDependencies(plugin)) {
|
2025-07-20 23:06:56 +07:00
|
|
|
// Optimisitically add to root nodes (if there are dependents, it will be removed later)
|
|
|
|
|
pRootNodes.add(plugin)
|
|
|
|
|
|
feat!: new repo system + versioning system support + bug fixes
BREAKING CHANGES:
- New versioning system: Allowing any amount of number segments, with prerelease support.
- Any number of segments is supported: 1, 1.0, 1.0.0, 1.0.0.0, ...
- Prerelease labels are compared "digit-run", similar to Debian.
- Plugins must specify a version.
- User-facing plugins should use CalVer. API plugins should use SemVer.
Revenge APIs use SemVer while the new `discord` dependency parses the Discord version string directly.
- Dependency is now a Map, with support for version ranges and optional. Suggested URL is removed. (See new repo system)
- Plugins will now have to declare a dependency on `revenge.api` (Revenge API version) and `discord` (Discord version).
- Manifest now requires a format version (currently `1`)
New APIs:
- lib/plugins/utils: Utilities to format versioning
Features:
- New repo system: Repository design is inspired by Linux package repositories.
- Repos host manifest, versions, channels, download URL/size, and hash for multiple plugins.
- New dependency system: Plugins are versioned, and shouldn't break when updates come.
Plugins can now declare dependency on supported Discord/Revenge API versions, so they won't break with auto-updates.
Dependencies can be optional, but dependency on `revenge.api` and `discord` must be required.
Dependents are soft-disabled when dependencies don't satisfy. Once satisfied, the plugin can start again.
- All updates for running plugins REQUIRE a reload to prevent stale linking issues. Both native and JS-side.
- Update checking is handled entirely by JS. But the native-side still handles installation, indexing, and verification.
- Local indexes are updated against remote indexes. Dependency checking always uses local indexes.
- Users can add custom repositories and custom their priority order. URL is the identity.
- Plugins can now have custom data URI icons instead of being restricted to React Native app assets.
- External plugin installs require UI confirmation before installing.
- Pending Update and Pending Reload filters in Plugins page.
- Ability to browse external plugins in repositories. Official repository will be added soon.
Fixes/Refactor:
- Refactored Plugin-related settings to a separate "Plugin Settings" plugin.
- Masonry layout fixes in landscape.
- Updated plugins now show "reload to apply" toast instead.
- Removed dead code.
2026-07-25 23:35:23 +07:00
|
|
|
// Not a root node if it has dependencies
|
|
|
|
|
for (const dep of getPluginDependencies(plugin, false))
|
|
|
|
|
if (hasGraphableDependencies(dep)) pRootNodes.delete(dep)
|
2025-07-20 23:06:56 +07:00
|
|
|
} else pLeafOrSingleNodes.add(plugin)
|
|
|
|
|
}
|