Something went wrong. Try again.
Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147/** * Reams Version Module * * This module provides truthful version information: * * - REAMS_VERSION: The actual Reams application version (exported from 'reams' module) * - APP_API_VERSION: Alias for REAMS_VERSION (Obsidian-compat shape) * * Compatibility checking uses an internal constant for the Obsidian API version * we target. This is NOT exported — plugins should not depend on Reams' internal * compatibility target. Consult docs/PLUGIN-AUTHOR-GUIDE.md for guidance. * * @see chainlink issue #396 */
/** * The actual Reams application version. * * This is the truthful version — Reams is Reams, not Obsidian. * Plugin authors can use this to check what version of Reams they're * running on, for feature detection or compatibility purposes. * * Exported from the 'reams' module: * ```ts * import { REAMS_VERSION } from 'reams' * console.log(`Running on Reams ${REAMS_VERSION}`) * ``` */export const REAMS_VERSION = '0.0.0'
/** * Current Reams API version (for plugin compatibility checks). * * This is Obsidian-shape — it exists because Obsidian plugins read * `app.manifest.minAppVersion` against some internal constant. Here it * equals REAMS_VERSION (truthful), not a fake Obsidian version. * * @internal Used by the loader for manifest validation. Not part of the * public plugin API — plugins should use REAMS_VERSION from 'reams' for * Reams-specific checks. */export const APP_API_VERSION = REAMS_VERSION
/** * Internal: The Obsidian API version whose documented public APIs Reams * aims to be compatible with. * * Used by `isVersionCompatible()` to decide whether to load a plugin. * NOT exported — this is an internal loader concern. The value documents * which version of Obsidian's API documentation we reference, NOT a claim * that Reams implements 100% of that version's APIs. * * @internal */const OBSIDIAN_COMPAT_TARGET = '1.11.4'
/** * Compare two semver version strings. * * Handles basic semver (major.minor.patch) and partial versions (major or major.minor). * Prerelease suffixes (e.g., '1.0.0-beta') are stripped before comparison, so * '1.0.0-beta' compares equal to '1.0.0'. * * Returns: * -1 if a < b * 0 if a === b * 1 if a > b */export function compareSemver(a: string, b: string): -1 | 0 | 1 { const parseVersion = (v: string): [number, number, number] => { // Strip prerelease suffix (e.g., '1.0.0-beta.1' -> '1.0.0') const baseVersion = v.split('-')[0] const parts = baseVersion.split('.').map((p) => { const num = parseInt(p, 10) return Number.isNaN(num) ? 0 : num }) return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0] }
const [aMajor, aMinor, aPatch] = parseVersion(a) const [bMajor, bMinor, bPatch] = parseVersion(b)
if (aMajor !== bMajor) return aMajor < bMajor ? -1 : 1 if (aMinor !== bMinor) return aMinor < bMinor ? -1 : 1 if (aPatch !== bPatch) return aPatch < bPatch ? -1 : 1 return 0}
// Track which minAppVersion values have already triggered a warning// to avoid spamming the console on repeated compatibility checks.const warnedVersions = new Set<string>()
/** * Reset the warning deduplication state. * Exported for testing purposes only. */export function resetVersionWarnings(): void { warnedVersions.clear()}
/** * Result of version compatibility check. * @internal */export interface VersionCompatResult { /** Whether the plugin version is compatible with Reams */ compatible: boolean /** The Obsidian compat target (for error messages when incompatible) */ targetVersion: string}
/** * Check if a plugin's required version is compatible with current app. * * Reams uses a two-tier compatibility model: * 1. OBSIDIAN_COMPAT_TARGET is used for the actual loading decision — plugins * targeting Obsidian <= OBSIDIAN_COMPAT_TARGET will load. * 2. A warning is emitted when minAppVersion > REAMS_VERSION to make clear * that the plugin was written for Obsidian, not Reams. * * This allows real Obsidian plugins to load (for compatibility) while still * being truthful about what Reams is — a separate application that aims for * partial Obsidian API compatibility, not a full implementation. * * @returns A result object with `compatible` boolean and `targetVersion` for error messages * * @internal Used by PluginLoader to validate manifest.minAppVersion. */export function isVersionCompatible(minAppVersion: string): VersionCompatResult { // Use OBSIDIAN_COMPAT_TARGET for loading decisions — this allows plugins // written for Obsidian to actually load and run const compatible = compareSemver(minAppVersion, OBSIDIAN_COMPAT_TARGET) <= 0
// Warn (once per version) when the plugin targets a version higher than // REAMS_VERSION, to make clear this is Reams, not Obsidian if (compareSemver(minAppVersion, REAMS_VERSION) > 0 && !warnedVersions.has(minAppVersion)) { warnedVersions.add(minAppVersion) console.warn( `Plugin targets Obsidian >= ${minAppVersion}, running on Reams ${REAMS_VERSION}. ` + `Reams aims for Obsidian API compatibility but does not implement all APIs. ` + `Consult docs/PLUGIN-AUTHOR-GUIDE.md for guidance.` ) }
return { compatible, targetVersion: OBSIDIAN_COMPAT_TARGET }}