@delta-comic/plugin 3.0.0-next.8 → 3.0.0-next.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/index.d.mts +945 -748
- package/dist/lib/index.mjs +2002 -126
- package/dist/lib/index.mjs.map +1 -1
- package/dist/vite/index.d.mts +2 -3
- package/dist/vite/index.mjs +1 -1
- package/dist/vite/index.mjs.map +1 -1
- package/package.json +18 -17
- package/dist/global-1Kghyz5c.mjs +0 -1446
- package/dist/global-1Kghyz5c.mjs.map +0 -1
- package/dist/native-CHH-Olpj.mjs +0 -63
- package/dist/native-CHH-Olpj.mjs.map +0 -1
- package/dist/runtime-rn2XMGzk.mjs +0 -663
- package/dist/runtime-rn2XMGzk.mjs.map +0 -1
- package/dist/storage-DMKDlPzl.mjs +0 -351
- package/dist/storage-DMKDlPzl.mjs.map +0 -1
package/dist/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["isRecord"],"sources":["../../lib/manifest.ts","../../lib/marketplace/types.ts","../../lib/marketplace/validation.ts","../../lib/marketplace/cache.ts","../../lib/marketplace/client.ts","../../lib/marketplace/index.ts","../../lib/pluginIcon.ts"],"sourcesContent":["import type { PluginArchiveDB } from '@delta-comic/db'\nimport semver from 'semver'\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst requiredRecord = (value: unknown, path: string) => {\n if (!isRecord(value)) throw new PluginManifestError(`${path} must be an object`)\n return value\n}\n\nconst requiredString = (value: unknown, path: string) => {\n if (typeof value !== 'string' || value.length === 0) {\n throw new PluginManifestError(`${path} must be a non-empty string`)\n }\n return value\n}\n\nconst optionalPath = (value: unknown, path: string) => {\n const text = requiredString(value, path)\n const normalized = text.replaceAll('\\\\', '/')\n if (normalized.startsWith('/') || normalized.split('/').includes('..')) {\n throw new PluginManifestError(`${path} must be a safe relative path`)\n }\n return text\n}\n\nexport type PluginIconReference =\n | { type: 'local'; path: string; fragment: string }\n | { type: 'remote'; url: string }\n\nconst decodeLocalIconPath = (value: string, path: string) => {\n let decoded = value\n for (let index = 0; index < 5; index += 1) {\n let next: string\n try {\n next = decodeURIComponent(decoded)\n } catch {\n throw new PluginManifestError(`${path} must be a valid URL path`)\n }\n if (next === decoded) break\n decoded = next\n }\n\n const normalized = decoded.replaceAll('\\\\', '/')\n const segments = normalized.split('/')\n if (\n !normalized ||\n normalized.startsWith('/') ||\n /^[a-z]:($|\\/)/i.test(normalized) ||\n normalized.includes('\\0') ||\n segments.some(segment => segment === '..')\n ) {\n throw new PluginManifestError(`${path} must be a safe relative path`)\n }\n return segments.filter(segment => segment && segment !== '.').join('/')\n}\n\n/**\n * Accepts a credential-free HTTP(S) URL or a safe path inside the plugin archive.\n * Query strings and fragments are kept for both forms.\n */\nexport const parsePluginIconReference = (\n value: unknown,\n path = 'manifest.icon',\n): PluginIconReference => {\n const text = requiredString(value, path).trim()\n if (!text) throw new PluginManifestError(`${path} must be a non-empty string`)\n\n if (/^[a-z][a-z\\d+.-]*:/i.test(text) || text.startsWith('//')) {\n let url: URL\n try {\n url = new URL(text)\n } catch {\n throw new PluginManifestError(`${path} must be an HTTP(S) URL or a safe relative path`)\n }\n if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {\n throw new PluginManifestError(\n `${path} must be a credential-free HTTP(S) URL or a safe relative path`,\n )\n }\n return { type: 'remote', url: text }\n }\n\n const rawPath = text.split(/[?#]/, 1)[0] ?? ''\n const resolvedPath = decodeLocalIconPath(rawPath, path)\n if (!resolvedPath) throw new PluginManifestError(`${path} must be a safe relative path`)\n\n const fragmentIndex = text.indexOf('#')\n return {\n fragment: fragmentIndex < 0 ? '' : text.slice(fragmentIndex),\n path: resolvedPath,\n type: 'local',\n }\n}\n\nexport class PluginManifestError extends Error {\n public constructor(message: string) {\n super(`Invalid Delta Comic manifest: ${message}`)\n this.name = 'PluginManifestError'\n }\n}\n\n/**\n * Validates the exact manifest format emitted by the `deltaComic` Vite plugin.\n * The returned value is safe to use as the persisted plugin metadata shape.\n */\nexport const parsePluginManifest = (value: unknown): PluginArchiveDB.Meta => {\n const manifest = requiredRecord(value, 'manifest')\n const name = requiredRecord(manifest.name, 'manifest.name')\n const version = requiredRecord(manifest.version, 'manifest.version')\n const id = requiredString(name.id, 'manifest.name.id')\n if (id === '.' || id === '..' || /[\\\\/]/.test(id)) {\n throw new PluginManifestError('manifest.name.id contains an unsafe path segment')\n }\n\n const requireValue = manifest.require\n if (!Array.isArray(requireValue)) {\n throw new PluginManifestError('manifest.require must be an array')\n }\n const require = requireValue.map((dependency, index) => {\n const record = requiredRecord(dependency, `manifest.require[${index}]`)\n const download = record.download\n if (download !== undefined && typeof download !== 'string') {\n throw new PluginManifestError(`manifest.require[${index}].download must be a string`)\n }\n return {\n id: requiredString(record.id, `manifest.require[${index}].id`),\n ...(download === undefined ? {} : { download }),\n }\n })\n\n const result: PluginArchiveDB.Meta = {\n author: requiredString(manifest.author, 'manifest.author'),\n description: requiredString(manifest.description, 'manifest.description'),\n name: { display: requiredString(name.display, 'manifest.name.display'), id },\n require,\n version: {\n plugin: requiredString(version.plugin, 'manifest.version.plugin'),\n supportCore: requiredString(version.supportCore, 'manifest.version.supportCore'),\n },\n }\n\n if (manifest.icon !== undefined) {\n const icon = parsePluginIconReference(manifest.icon)\n result.icon =\n icon.type === 'remote' ? icon.url : requiredString(manifest.icon, 'manifest.icon').trim()\n }\n\n if (manifest.entry !== undefined) {\n const entry = requiredRecord(manifest.entry, 'manifest.entry')\n result.entry = {\n jsPath: optionalPath(entry.jsPath, 'manifest.entry.jsPath'),\n ...(entry.cssPath === undefined\n ? {}\n : { cssPath: optionalPath(entry.cssPath, 'manifest.entry.cssPath') }),\n }\n }\n\n if (manifest.kind !== undefined) {\n if (manifest.kind !== 'normal' && manifest.kind !== 'preboot') {\n throw new PluginManifestError('manifest.kind must be \"normal\" or \"preboot\"')\n }\n result.kind = manifest.kind\n }\n\n if (manifest.integrity !== undefined) {\n const integrity = requiredRecord(manifest.integrity, 'manifest.integrity')\n if (integrity.algorithm !== 'blake3' && integrity.algorithm !== 'sha256') {\n throw new PluginManifestError('manifest.integrity.algorithm is unsupported')\n }\n result.integrity = {\n algorithm: integrity.algorithm,\n digest: requiredString(integrity.digest, 'manifest.integrity.digest'),\n }\n }\n\n return result\n}\n\nexport const isPluginManifestCompatible = (manifest: PluginArchiveDB.Meta, coreVersion: string) =>\n semver.satisfies(coreVersion, manifest.version.supportCore)","import type { PluginArchiveDB } from '@delta-comic/db'\n\nexport const AWESOME_REGISTRY_BASE_URL =\n 'https://raw.githubusercontent.com/delta-comic/awesome-plugins/main/'\nexport const AWESOME_REGISTRY_INDEX_PATH = 'registry/index.json'\nexport const AWESOME_REGISTRY_SCHEMA_VERSION = 1 as const\n\nexport interface AwesomeRegistryPageReference {\n page: number\n items: number\n path: string\n}\n\nexport interface AwesomeRegistryIndex {\n schemaVersion: typeof AWESOME_REGISTRY_SCHEMA_VERSION\n pageSize: number\n totalItems: number\n totalPages: number\n pages: AwesomeRegistryPageReference[]\n}\n\nexport interface AwesomeRegistryPagination {\n page: number\n pageSize: number\n totalItems: number\n totalPages: number\n previous: string | null\n next: string | null\n}\n\nexport type AwesomePluginDownload =\n | { type: 'github'; repository: string }\n | { type: 'url'; url: string }\n\nexport interface AwesomePluginRepository {\n owner: string\n name: string\n url: string\n defaultBranch: string\n lastCommitAt: string\n readmeUrl?: string\n}\n\nexport interface AwesomePluginRelease {\n version: string\n url: string\n publishedAt: string\n manifestUrl: string | null\n}\n\nexport interface AwesomePluginListing {\n schemaVersion: typeof AWESOME_REGISTRY_SCHEMA_VERSION\n id: string\n authors: string[]\n download: AwesomePluginDownload\n repository?: AwesomePluginRepository\n release?: AwesomePluginRelease\n}\n\nexport interface AwesomeRegistryPage {\n schemaVersion: typeof AWESOME_REGISTRY_SCHEMA_VERSION\n pagination: AwesomeRegistryPagination\n items: AwesomePluginListing[]\n}\n\nexport interface AwesomeRegistryResult<T> {\n data: T\n cachedAt: string\n stale: boolean\n}\n\nexport interface AwesomeMarketplaceEntry {\n listing: AwesomePluginListing\n manifest?: PluginArchiveDB.Meta\n manifestError?: string\n}\n\nexport interface MarketplaceStorage {\n getItem(key: string): string | null\n removeItem(key: string): void\n setItem(key: string, value: string): void\n}","import {\n AWESOME_REGISTRY_SCHEMA_VERSION,\n type AwesomePluginDownload,\n type AwesomePluginListing,\n type AwesomePluginRelease,\n type AwesomePluginRepository,\n type AwesomeRegistryIndex,\n type AwesomeRegistryPage,\n type AwesomeRegistryPagination,\n type AwesomeRegistryPageReference,\n} from './types'\n\nconst PAGE_PATH_PATTERN = /^registry\\/pages\\/[1-9][0-9]*\\.json$/\nconst PLUGIN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/\nconst GITHUB_LOGIN_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/\nconst GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst record = (value: unknown, path: string) => {\n if (!isRecord(value)) throw new AwesomeRegistryValidationError(`${path} must be an object`)\n return value\n}\n\nconst exactKeys = (value: Record<string, unknown>, allowed: readonly string[], path: string) => {\n const extras = Object.keys(value).filter(key => !allowed.includes(key))\n if (extras.length > 0) {\n throw new AwesomeRegistryValidationError(`${path} has unknown fields: ${extras.join(', ')}`)\n }\n}\n\nconst string = (value: unknown, path: string) => {\n if (typeof value !== 'string' || value.length === 0) {\n throw new AwesomeRegistryValidationError(`${path} must be a non-empty string`)\n }\n return value\n}\n\nconst integer = (value: unknown, path: string, minimum: number, maximum = Infinity) => {\n if (!Number.isInteger(value) || (value as number) < minimum || (value as number) > maximum) {\n throw new AwesomeRegistryValidationError(\n `${path} must be an integer between ${minimum} and ${maximum}`,\n )\n }\n return value as number\n}\n\nconst schemaVersion = (value: unknown, path: string) => {\n if (value !== AWESOME_REGISTRY_SCHEMA_VERSION) {\n throw new AwesomeRegistryVersionError(value, path)\n }\n return AWESOME_REGISTRY_SCHEMA_VERSION\n}\n\nconst path = (value: unknown, field: string) => {\n const result = string(value, field)\n if (!PAGE_PATH_PATTERN.test(result)) {\n throw new AwesomeRegistryValidationError(`${field} must be a registry page path`)\n }\n return result\n}\n\nconst httpUrl = (value: unknown, field: string) => {\n const result = string(value, field)\n let parsed: URL\n try {\n parsed = new URL(result)\n } catch {\n throw new AwesomeRegistryValidationError(`${field} must be an absolute URL`)\n }\n if (!['http:', 'https:'].includes(parsed.protocol) || parsed.username || parsed.password) {\n throw new AwesomeRegistryValidationError(`${field} must be a credential-free HTTP(S) URL`)\n }\n return result\n}\n\nconst dateTime = (value: unknown, field: string) => {\n const result = string(value, field)\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(result) || Number.isNaN(Date.parse(result))) {\n throw new AwesomeRegistryValidationError(`${field} must be an ISO date-time`)\n }\n return result\n}\n\nconst parsePageReference = (value: unknown, field: string): AwesomeRegistryPageReference => {\n const item = record(value, field)\n exactKeys(item, ['page', 'items', 'path'], field)\n return {\n page: integer(item.page, `${field}.page`, 1),\n items: integer(item.items, `${field}.items`, 1),\n path: path(item.path, `${field}.path`),\n }\n}\n\nconst parseDownload = (value: unknown, field: string): AwesomePluginDownload => {\n const download = record(value, field)\n if (download.type === 'github') {\n exactKeys(download, ['type', 'repository'], field)\n const repository = string(download.repository, `${field}.repository`)\n if (!GITHUB_REPOSITORY_PATTERN.test(repository)) {\n throw new AwesomeRegistryValidationError(`${field}.repository is invalid`)\n }\n return { type: 'github', repository }\n }\n if (download.type === 'url') {\n exactKeys(download, ['type', 'url'], field)\n return { type: 'url', url: httpUrl(download.url, `${field}.url`) }\n }\n throw new AwesomeRegistryValidationError(`${field}.type is unsupported`)\n}\n\nconst parseRepository = (value: unknown, field: string): AwesomePluginRepository => {\n const repository = record(value, field)\n exactKeys(\n repository,\n ['owner', 'name', 'url', 'defaultBranch', 'lastCommitAt', 'readmeUrl'],\n field,\n )\n return {\n owner: string(repository.owner, `${field}.owner`),\n name: string(repository.name, `${field}.name`),\n url: httpUrl(repository.url, `${field}.url`),\n defaultBranch: string(repository.defaultBranch, `${field}.defaultBranch`),\n lastCommitAt: dateTime(repository.lastCommitAt, `${field}.lastCommitAt`),\n ...(repository.readmeUrl === undefined\n ? {}\n : { readmeUrl: httpUrl(repository.readmeUrl, `${field}.readmeUrl`) }),\n }\n}\n\nconst parseRelease = (value: unknown, field: string): AwesomePluginRelease => {\n const release = record(value, field)\n exactKeys(release, ['version', 'url', 'publishedAt', 'manifestUrl'], field)\n return {\n version: string(release.version, `${field}.version`),\n url: httpUrl(release.url, `${field}.url`),\n publishedAt: dateTime(release.publishedAt, `${field}.publishedAt`),\n manifestUrl:\n release.manifestUrl === null ? null : httpUrl(release.manifestUrl, `${field}.manifestUrl`),\n }\n}\n\nexport class AwesomeRegistryValidationError extends Error {\n public constructor(message: string) {\n super(`Invalid awesome-plugins registry: ${message}`)\n this.name = 'AwesomeRegistryValidationError'\n }\n}\n\nexport class AwesomeRegistryVersionError extends AwesomeRegistryValidationError {\n public constructor(\n public readonly received: unknown,\n path: string,\n ) {\n super(`${path} has unsupported schemaVersion ${String(received)}`)\n this.name = 'AwesomeRegistryVersionError'\n }\n}\n\nexport const parseAwesomeRegistryIndex = (value: unknown): AwesomeRegistryIndex => {\n const index = record(value, 'index')\n exactKeys(index, ['schemaVersion', 'pageSize', 'totalItems', 'totalPages', 'pages'], 'index')\n if (!Array.isArray(index.pages)) {\n throw new AwesomeRegistryValidationError('index.pages must be an array')\n }\n const result: AwesomeRegistryIndex = {\n schemaVersion: schemaVersion(index.schemaVersion, 'index'),\n pageSize: integer(index.pageSize, 'index.pageSize', 1, 100),\n totalItems: integer(index.totalItems, 'index.totalItems', 0),\n totalPages: integer(index.totalPages, 'index.totalPages', 0),\n pages: index.pages.map((item, itemIndex) =>\n parsePageReference(item, `index.pages[${itemIndex}]`),\n ),\n }\n if (result.pages.length !== result.totalPages) {\n throw new AwesomeRegistryValidationError('index.pages length must equal index.totalPages')\n }\n if (result.pages.reduce((total, page) => total + page.items, 0) !== result.totalItems) {\n throw new AwesomeRegistryValidationError('index page item counts must equal index.totalItems')\n }\n result.pages.forEach((page, itemIndex) => {\n if (page.page !== itemIndex + 1 || page.items > result.pageSize) {\n throw new AwesomeRegistryValidationError('index pages must be ordered and respect pageSize')\n }\n })\n return result\n}\n\nexport const parseAwesomePluginListing = (\n value: unknown,\n field = 'listing',\n): AwesomePluginListing => {\n const listing = record(value, field)\n exactKeys(listing, ['schemaVersion', 'id', 'authors', 'download', 'repository', 'release'], field)\n const id = string(listing.id, `${field}.id`)\n if (!PLUGIN_ID_PATTERN.test(id)) {\n throw new AwesomeRegistryValidationError(`${field}.id is invalid`)\n }\n if (!Array.isArray(listing.authors) || listing.authors.length === 0) {\n throw new AwesomeRegistryValidationError(`${field}.authors must be a non-empty array`)\n }\n const authors = listing.authors.map((author, index) => {\n const login = string(author, `${field}.authors[${index}]`)\n if (!GITHUB_LOGIN_PATTERN.test(login)) {\n throw new AwesomeRegistryValidationError(`${field}.authors[${index}] is invalid`)\n }\n return login\n })\n if (new Set(authors).size !== authors.length) {\n throw new AwesomeRegistryValidationError(`${field}.authors must be unique`)\n }\n return {\n schemaVersion: schemaVersion(listing.schemaVersion, field),\n id,\n authors,\n download: parseDownload(listing.download, `${field}.download`),\n ...(listing.repository === undefined\n ? {}\n : { repository: parseRepository(listing.repository, `${field}.repository`) }),\n ...(listing.release === undefined\n ? {}\n : { release: parseRelease(listing.release, `${field}.release`) }),\n }\n}\n\nconst parsePagination = (value: unknown, field: string): AwesomeRegistryPagination => {\n const pagination = record(value, field)\n exactKeys(pagination, ['page', 'pageSize', 'totalItems', 'totalPages', 'previous', 'next'], field)\n return {\n page: integer(pagination.page, `${field}.page`, 1),\n pageSize: integer(pagination.pageSize, `${field}.pageSize`, 1, 100),\n totalItems: integer(pagination.totalItems, `${field}.totalItems`, 0),\n totalPages: integer(pagination.totalPages, `${field}.totalPages`, 1),\n previous: pagination.previous === null ? null : path(pagination.previous, `${field}.previous`),\n next: pagination.next === null ? null : path(pagination.next, `${field}.next`),\n }\n}\n\nexport const parseAwesomeRegistryPage = (value: unknown): AwesomeRegistryPage => {\n const page = record(value, 'page')\n exactKeys(page, ['schemaVersion', 'pagination', 'items'], 'page')\n if (!Array.isArray(page.items)) {\n throw new AwesomeRegistryValidationError('page.items must be an array')\n }\n const result: AwesomeRegistryPage = {\n schemaVersion: schemaVersion(page.schemaVersion, 'page'),\n pagination: parsePagination(page.pagination, 'page.pagination'),\n items: page.items.map((item, index) => parseAwesomePluginListing(item, `page.items[${index}]`)),\n }\n if (result.items.length > result.pagination.pageSize) {\n throw new AwesomeRegistryValidationError('page.items exceeds pageSize')\n }\n const expectedPrevious = result.pagination.page === 1 ? null : result.pagination.page - 1\n const expectedNext =\n result.pagination.page === result.pagination.totalPages ? null : result.pagination.page + 1\n if (\n (expectedPrevious === null) !== (result.pagination.previous === null) ||\n (expectedNext === null) !== (result.pagination.next === null)\n ) {\n throw new AwesomeRegistryValidationError('page pagination links are inconsistent')\n }\n return result\n}\n\nexport const assertAwesomeRegistryPagePath = (value: string) => path(value, 'page path')","import type { AwesomeRegistryIndex, AwesomeRegistryPage, MarketplaceStorage } from './types'\nimport { parseAwesomeRegistryIndex, parseAwesomeRegistryPage } from './validation'\n\ninterface CacheEnvelope {\n cachedAt: string\n data: unknown\n}\n\nconst parseEnvelope = (value: string): CacheEnvelope | undefined => {\n try {\n const envelope = JSON.parse(value) as Partial<CacheEnvelope>\n if (typeof envelope.cachedAt !== 'string' || !('data' in envelope)) return undefined\n return { cachedAt: envelope.cachedAt, data: envelope.data }\n } catch {\n return undefined\n }\n}\n\nexport class AwesomeRegistryCache {\n public constructor(\n private readonly storage?: MarketplaceStorage,\n private readonly prefix = 'delta-comic:awesome-registry:v1',\n ) {}\n\n public readIndex() {\n return this.read(`${this.prefix}:index`, parseAwesomeRegistryIndex)\n }\n\n public writeIndex(data: AwesomeRegistryIndex) {\n return this.write(`${this.prefix}:index`, data)\n }\n\n public readPage(path: string) {\n return this.read(`${this.prefix}:page:${path}`, parseAwesomeRegistryPage)\n }\n\n public writePage(path: string, data: AwesomeRegistryPage) {\n return this.write(`${this.prefix}:page:${path}`, data)\n }\n\n private read<T>(key: string, parse: (value: unknown) => T) {\n if (!this.storage) return undefined\n let stored: string | null\n try {\n stored = this.storage.getItem(key)\n } catch {\n return undefined\n }\n if (!stored) return undefined\n const envelope = parseEnvelope(stored)\n if (!envelope) {\n this.remove(key)\n return undefined\n }\n try {\n return { cachedAt: envelope.cachedAt, data: parse(envelope.data) }\n } catch {\n this.remove(key)\n return undefined\n }\n }\n\n private remove(key: string) {\n try {\n this.storage?.removeItem(key)\n } catch {}\n }\n\n private write(key: string, data: AwesomeRegistryIndex | AwesomeRegistryPage) {\n const cachedAt = new Date().toISOString()\n try {\n this.storage?.setItem(key, JSON.stringify({ cachedAt, data } satisfies CacheEnvelope))\n } catch {}\n return cachedAt\n }\n}","import type { PluginArchiveDB } from '@delta-comic/db'\nimport { logger } from '@delta-comic/logger'\nimport ky from 'ky'\n\nimport { parsePluginManifest } from '../manifest'\n\nimport { AwesomeRegistryCache } from './cache'\nimport {\n AWESOME_REGISTRY_BASE_URL,\n AWESOME_REGISTRY_INDEX_PATH,\n type AwesomePluginListing,\n type AwesomeRegistryIndex,\n type AwesomeRegistryPage,\n type AwesomeRegistryResult,\n type MarketplaceStorage,\n} from './types'\nimport {\n assertAwesomeRegistryPagePath,\n parseAwesomeRegistryIndex,\n parseAwesomeRegistryPage,\n AwesomeRegistryValidationError,\n} from './validation'\n\nconst marketplaceLogger = logger.scoped('plugin:marketplace')\n\nexport interface AwesomeRegistryClientOptions {\n baseUrl?: string\n cache?: AwesomeRegistryCache\n requestJson?: (url: string) => Promise<unknown>\n storage?: MarketplaceStorage\n}\n\nconst defaultRequestJson = async (url: string) =>\n await ky.get(url, { retry: 2, timeout: 30_000 }).json<unknown>()\n\nconst defaultStorage = () => {\n try {\n return globalThis.localStorage\n } catch {\n return undefined\n }\n}\n\nexport class AwesomeRegistryNetworkError extends Error {\n public constructor(\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = 'AwesomeRegistryNetworkError'\n }\n}\n\nexport class AwesomeRegistryClient {\n private readonly baseUrl: string\n private readonly cache: AwesomeRegistryCache\n private readonly requestJson: (url: string) => Promise<unknown>\n\n public constructor(options: AwesomeRegistryClientOptions = {}) {\n this.baseUrl = new URL(options.baseUrl ?? AWESOME_REGISTRY_BASE_URL).href\n this.cache = options.cache ?? new AwesomeRegistryCache(options.storage ?? defaultStorage())\n this.requestJson = options.requestJson ?? defaultRequestJson\n }\n\n public async loadIndex(): Promise<AwesomeRegistryResult<AwesomeRegistryIndex>> {\n return await this.load(\n AWESOME_REGISTRY_INDEX_PATH,\n parseAwesomeRegistryIndex,\n () => this.cache.readIndex(),\n data => this.cache.writeIndex(data),\n )\n }\n\n public async loadPage(path: string): Promise<AwesomeRegistryResult<AwesomeRegistryPage>> {\n const safePath = assertAwesomeRegistryPagePath(path)\n return await this.load(\n safePath,\n parseAwesomeRegistryPage,\n () => this.cache.readPage(safePath),\n data => this.cache.writePage(safePath, data),\n )\n }\n\n public async findListing(id: string): Promise<AwesomePluginListing> {\n marketplaceLogger.debug('searching marketplace listing', { plugin: id })\n const { data: index } = await this.loadIndex()\n for (const pageReference of index.pages) {\n const { data: page } = await this.loadPage(pageReference.path)\n const listing = page.items.find(item => item.id === id)\n if (listing) {\n marketplaceLogger.debug('marketplace listing found', { plugin: id })\n return listing\n }\n }\n throw new Error(`Plugin \"${id}\" is not registered in awesome-plugins`)\n }\n\n public async loadManifest(\n listing: AwesomePluginListing,\n ): Promise<PluginArchiveDB.Meta | undefined> {\n const manifestUrl = listing.release?.manifestUrl\n if (!manifestUrl) return undefined\n const manifest = parsePluginManifest(await this.requestJson(manifestUrl))\n if (manifest.name.id !== listing.id) {\n throw new AwesomeRegistryValidationError(\n `listing ${listing.id} points to manifest for ${manifest.name.id}`,\n )\n }\n return manifest\n }\n\n private async load<T>(\n path: string,\n parse: (value: unknown) => T,\n readCache: () => { data: T; cachedAt: string } | undefined,\n writeCache: (data: T) => string,\n ): Promise<AwesomeRegistryResult<T>> {\n let payload: unknown\n try {\n payload = await this.requestJson(new URL(path, this.baseUrl).href)\n } catch (error) {\n if (error instanceof AwesomeRegistryValidationError || error instanceof SyntaxError)\n throw error\n const cached = readCache()\n if (cached) {\n marketplaceLogger.warn('marketplace request failed; using stale cache', { path }, error)\n return { ...cached, stale: true }\n }\n marketplaceLogger.error('marketplace request failed without cache', { path }, error)\n throw new AwesomeRegistryNetworkError(`Failed to request awesome-plugins ${path}`, error)\n }\n const data = parse(payload)\n marketplaceLogger.debug('marketplace response cached', { path })\n return { cachedAt: writeCache(data), data, stale: false }\n }\n}","export * from './cache'\nexport * from './client'\nexport * from './types'\nexport * from './validation'\n\nimport type { AwesomePluginDownload, AwesomePluginListing } from './types'\n\nexport const marketplaceDownloadToInstallInput = (download: AwesomePluginDownload) =>\n download.type === 'github' ? `gh:${download.repository}` : download.url\n\nexport const marketplaceListingInstallId = (listing: AwesomePluginListing) => `ap:${listing.id}`\n\nexport const marketplaceListingSource = (listing: AwesomePluginListing) =>\n listing.download.type === 'github'\n ? `https://github.com/${listing.download.repository}`\n : listing.download.url","import { createPluginAssetUrl } from './driver/init/storage'\nimport { parsePluginIconReference } from './manifest'\n\n/** Resolves persisted plugin icon metadata into a URL that an `<img>` can consume. */\nexport const resolvePluginIconUrl = async (\n pluginId: string | undefined,\n icon: string | undefined,\n): Promise<string | undefined> => {\n if (icon === undefined) return undefined\n const reference = parsePluginIconReference(icon, 'plugin icon')\n if (reference.type === 'remote') return reference.url\n if (!pluginId) throw new Error('A plugin id is required to resolve a local plugin icon')\n return `${await createPluginAssetUrl(pluginId, reference.path)}${reference.fragment}`\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#modules","#entries","#controller","#disposers","#disposePromise","#dispose","isRecord","record","DELTA_COMIC_PLUGIN_API_VERSION","defaultStorage","useDbConfig","#database","#store","#open","#key","#root","#urls","CorePlugin","pkg.version","__import_glob__0_0_","#active","#options","#prebootReport","#prebootOperation","#load","#writeRecovery","#normalOperation","#track","#unload","#deactivate","#selectWithDependencies"],"sources":["../../lib/api/config.ts","../../lib/api/model/content.ts","../../lib/api/model/expose.ts","../../lib/api/model/remote.ts","../../lib/api/model/resource.ts","../../lib/api/model/social.ts","../../lib/api/model/special.ts","../../lib/api/model/user.ts","../../lib/api/plugin.ts","../../lib/kernel/candidate.ts","../../lib/kernel/capability.ts","../../lib/kernel/contribution.ts","../../lib/kernel/dependency.ts","../../lib/kernel/scope.ts","../../lib/capabilities/auth.ts","../../lib/capabilities/config.ts","../../lib/capabilities/registryBinding.ts","../../lib/capabilities/content.ts","../../lib/capabilities/i18n.ts","../../lib/capabilities/lifecycle.ts","../../lib/capabilities/channels.ts","../../lib/capabilities/model.ts","../../lib/capabilities/endpointProbe.ts","../../lib/capabilities/remote.ts","../../lib/capabilities/resource.ts","../../lib/capabilities/special.ts","../../lib/capabilities/user.ts","../../lib/capabilities/index.ts","../../lib/install/manifest.ts","../../lib/adapters/awesomeRegistry/types.ts","../../lib/adapters/awesomeRegistry/schema.ts","../../lib/adapters/awesomeRegistry/cache.ts","../../lib/adapters/awesomeRegistry/client.ts","../../lib/adapters/configStore.ts","../../lib/install/candidateProvider.ts","../../lib/install/catalog.ts","../../lib/install/codec.ts","../../lib/install/moduleReader.ts","../../lib/install/repository.ts","../../lib/install/service.ts","../../lib/install/source.ts","../../lib/adapters/fileStore.ts","../../lib/adapters/i18n.ts","../../package.json","../../lib/core/env.ts","../../lib/core/config.ts","../../lib/core/share.ts","../../lib/core/index.ts","../../lib/builtins/core.builtin.ts","../../lib/builtins/index.ts","../../lib/runtime/store.ts","../../lib/runtime/engine.ts","../../lib/runtime/providers.ts","../../lib/composition.ts"],"sourcesContent":["import type { FormSingleConfigure } from '@delta-comic/model'\n\nexport type ConfigDescription = Record<\n string,\n Required<Pick<FormSingleConfigure, 'defaultValue'>> & FormSingleConfigure\n>\n\nexport type UnwrapConfigPointer<T extends ConfigPointer> = T['_type']\n\nexport class ConfigPointer<T extends ConfigDescription = ConfigDescription> {\n public readonly key: symbol\n public readonly _type = {} as T\n\n public constructor(\n public readonly pluginName: string,\n public readonly config: T,\n public readonly configName: string,\n ) {\n this.key = Symbol.for(`config:${pluginName}`)\n }\n}","import type {\n StreamQuery,\n UniCommentRow,\n UniContentDownloadProvider,\n UniContentLayoutComponent,\n UniContentPageLike,\n UniItem,\n UniItemCardComponent,\n UniItemTranslator,\n} from '@delta-comic/model'\nimport type { Component } from 'vue'\n\nexport interface ContentModel {\n models?: Model[]\n search?: Search\n promotes?: Promotes\n}\n\n// model\nexport interface Model {\n name: string\n ItemCard?: UniItemCardComponent\n CommentRow?: UniCommentRow\n Layout?: UniContentLayoutComponent\n ContentPage?: UniContentPageLike\n DownloadProvider?: UniContentDownloadProvider\n ItemTranslator?: UniItemTranslator\n}\n\n// search\nexport interface Search {\n methods: SearchMethod[]\n barcode?: Barcode[]\n getHotSearch: HotSearchProvider\n}\n\nexport type HotSearchProvider = (signal: AbortSignal) => Promise<SearchAim[]>\n\nexport interface SearchMethod {\n name: string\n id: string\n sorts: { options: { label: string; id: string }[]; default: string }\n\n fetchSearchResult: StreamQuery<UniItem, { aim: SearchAim }>\n getAutoComplete: AutoCompleteProvider\n}\n\nexport type AutoCompleteProvider = (\n input: string,\n signal: AbortSignal,\n) => Promise<SearchAim[] | Component>\n\nexport interface SearchAim {\n input: string\n search: { method: string; sort?: string }\n}\n\nexport interface Barcode {\n name: string\n id: string\n getTipText: (aim: SearchAim) => string\n isMatch: (aim: SearchAim) => boolean\n}\n\n// promotes\nexport interface Promotes {\n tabbar?: Tabbar[]\n categories?: Category[]\n hotPageContent?: HotPageContent\n\n fetchRandomItems?: ItemProvider\n}\n\nexport type ItemProvider = (signal: AbortSignal) => Promise<UniItem[]>\n\nexport interface Category {\n title: string\n namespace: string\n search: SearchAim\n}\n\nexport interface Tabbar {\n title: string\n id: string\n comp: Component<{ isActive: boolean; tabbar: Tabbar }>\n}\n\n// promotes - hotPageContent\n\nexport interface HotPageContent {\n levelboard?: HotLevelboard[]\n topButton?: HotTopButton[]\n categories?: HotCategory[]\n}\n\nexport interface HotLevelboard {\n name: string\n id: string\n content: ItemProvider\n}\nexport interface HotCategory {\n name: string\n content: ItemProvider\n}\nexport interface HotTopButton {\n name: string\n icon: Component\n bgColor: string\n}","export type ExposeModel = Record<string, any>","export type RemoteModel = TestGroup[]\n\nexport interface TestGroup {\n name: string\n test: TestFunction\n remotes: Definition[]\n allowNoConnected?: boolean\n}\n\nexport interface Definition {\n name: string\n url: string\n /**\n * cover root `test` method\n */\n test?: TestFunction\n}\n\nexport type TestFunction = (url: string, signal: AbortSignal) => Promise<void>","import type { UniResourceProcessInstance, UniResourceType } from '@delta-comic/model'\n\n/** Declarative resource schemes and their pathname processors. */\nexport interface ResourceModel {\n process?: Record<string, UniResourceProcessInstance>\n types?: UniResourceType[]\n}","import type {\n UniContentPage,\n UniImage,\n StreamQuery,\n UniItem,\n UniItemAuthor,\n} from '@delta-comic/model'\nimport type { Component } from 'vue'\n\nexport interface SocialModel {\n share?: Share\n subscribe?: Subscribe\n}\n\n// share\nexport interface Share {\n initiative?: InitiativeItem[]\n tokenListen?: ShareToken[]\n}\n\nexport interface ShareToken {\n key: string\n name: string\n isMatched(chipboard: string): boolean\n show(chipboard: string): Promise<SharePopupConfig>\n}\n\nexport interface SharePopupConfig {\n title: string\n detail: string\n onPositive(): void\n onNegative(): void\n}\n\nexport interface InitiativeItem {\n key: string\n name: string\n icon: Component | UniImage\n bgColor?: string\n call(page: UniContentPage): Promise<{ token?: string } | void>\n filter(page: UniContentPage): boolean\n}\n\n// subscribe\nexport interface Subscribe {\n getUpdateList: SubscribeListProvider\n fetchAuthorContent: StreamQuery<UniItem, { author: UniItemAuthor }>\n}\n\nexport type SubscribeListProvider = (\n olds: { author: UniItemAuthor; list: UniItem[] }[],\n signal: AbortSignal,\n) => Promise<{ isUpdated: boolean; whichUpdated: UniItemAuthor[] }>","export type SpecialModel = Step[]\n\nexport interface Step {\n name: string\n call: (setDescription: (description: string) => void) => Promise<void>\n}","import type { FormConfigure, FormSingleResult } from '@delta-comic/model'\nimport type { UniItem, UniItemAuthor, UniItemRaw, UniUserCardComponent } from '@delta-comic/model'\nimport type { Component, MaybeRefOrGetter } from 'vue'\n\nexport interface UserModel {\n auth: Auth\n edit?: Component\n card?: UniUserCardComponent\n /**\n * 你希望展示的(`userActions`)自己的板块的页面\n */\n userActionPages?: UserActionPage[]\n /**\n * 在用户界面,在历史记录那个板块的下方,你希望展示的自己的板块\n */\n userActions?: UserAction[]\n\n favourites: Favourites\n}\n\n// auth\nexport interface Auth {\n selections: Selection[]\n /**\n * @returns `string` -> id; `false` -> by user; `true` -> no auth\n */\n default: () => Promise<string | boolean>\n}\n\nexport interface Selection {\n name: string\n id: string\n call: (by: Method) => Promise<void>\n}\n\nexport type Method = {\n form<T extends FormConfigure>(\n form: T,\n ): Promise<{\n [x in keyof T]: FormSingleResult<T[x]>\n }>\n /**\n * @param injectCode 你可以在js调用`callback(...)`来完成鉴权,传值为你给的回调\n */\n website<T>(url: string, injectCode: InjectCode): Promise<CallbackResult<T>>\n}\n\nexport interface InjectCode {\n js: string\n css: string\n}\n\nexport interface CallbackResult<T> {\n callbackValue: T\n cookie: string\n localStorage: Record<string, string>\n sessionStorage: Record<string, string>\n href: string\n title: string\n}\n\n// user\n\nexport interface UserAction {\n call(author: UniItemAuthor): any\n name: string\n id: string\n icon?: Component\n}\n\nexport interface UserActionPage {\n title?: string\n items: ActionPageItem[]\n\n clickPage?: Component\n clickText?: string\n}\nexport type ActionPageItem =\n | {\n name: string\n key: string\n type: 'button'\n icon: Component\n\n page: Component\n }\n | {\n name: string\n key: string\n type: 'statistic'\n icon?: Component\n\n value: MaybeRefOrGetter<string | number>\n }\n\nexport interface Favourites {\n download: (signal: AbortSignal) => Promise<UniItem[]>\n upload: (items: UniItemRaw[], signal: AbortSignal) => Promise<void>\n}","import { isFunction } from 'es-toolkit'\n\nimport type { ConfigPointer } from './config'\nimport type { ConfigEnv } from './env'\nimport type { PluginConfigHooks } from './hook'\nimport type { PluginLocaleMessages } from './i18n'\nimport type { PluginConfigModel } from './model'\n\nexport interface DCPluginConfig {\n /** Stable plugin id. It must equal the candidate manifest id. */\n name: string\n /** At most one declarative configuration form can be contributed by a plugin. */\n config?: ConfigPointer\n i18n?: PluginLocaleMessages\n model?: PluginConfigModel\n hooks?: PluginConfigHooks\n}\n\nexport type PluginConfigFactory<T extends DCPluginConfig = DCPluginConfig> = (env: ConfigEnv) => T\n\nexport const defineDeltaComicPlugin = <T extends DCPluginConfig>(\n config: T | PluginConfigFactory<T>,\n): PluginConfigFactory<T> => {\n if (isFunction(config)) return config\n return () => config\n}","import type { PluginManifest } from '@delta-comic/model'\n\nimport type { PluginConfigFactory } from '../api'\n\nexport type PluginOrigin = 'builtin' | 'installed'\n\nexport interface PluginManagementCapabilities {\n readonly canDisable: boolean\n readonly canUninstall: boolean\n readonly canUpdate: boolean\n}\n\nexport interface LoadedPluginModule {\n readonly factory: PluginConfigFactory\n dispose?(): Promise<void> | void\n}\n\nexport interface PluginCandidate {\n readonly manifest: PluginManifest\n readonly origin: PluginOrigin\n readonly enabled: boolean\n readonly management: PluginManagementCapabilities\n load(signal: AbortSignal): Promise<LoadedPluginModule>\n}\n\nexport interface PluginCandidateProvider {\n readonly id: string\n list(signal: AbortSignal): Promise<readonly PluginCandidate[]>\n}\n\nexport interface InternalPluginDefinition {\n readonly manifest: PluginManifest\n readonly factory: PluginConfigFactory\n readonly canDisable?: boolean\n readonly enabledByDefault?: boolean\n}\n\nexport const defineInternalPlugin = <T extends InternalPluginDefinition>(definition: T) =>\n definition","import type { DCPluginConfig } from '../api'\n\nimport type { PluginScope } from './scope'\n\nexport interface ActivationStepUpdate {\n readonly description?: string\n readonly name?: string\n}\n\nexport interface ActivationContext {\n readonly owner: string\n readonly scope: PluginScope\n readonly signal: AbortSignal\n report(update: ActivationStepUpdate | string): void\n}\n\nexport interface CapabilityModule {\n readonly id: string\n activate(plugin: DCPluginConfig, context: ActivationContext): Promise<boolean>\n}\n\nexport interface CapabilityDefinition<T> {\n readonly id: string\n select(plugin: DCPluginConfig): T | undefined\n activate(model: T, context: ActivationContext): Promise<void> | void\n}\n\nexport const defineCapability = <T>(definition: CapabilityDefinition<T>): CapabilityModule => ({\n id: definition.id,\n async activate(plugin, context) {\n const model = definition.select(plugin)\n if (model === undefined) return false\n await definition.activate(model, context)\n return true\n },\n})\n\nexport class ActivationPipeline {\n readonly #modules: readonly CapabilityModule[]\n\n public constructor(modules: readonly CapabilityModule[]) {\n const ids = new Set<string>()\n for (const module of modules) {\n if (!module.id) throw new Error('capability id cannot be empty')\n if (ids.has(module.id)) throw new Error(`duplicate capability \"${module.id}\"`)\n ids.add(module.id)\n }\n this.#modules = [...modules]\n }\n\n public async activate(plugin: DCPluginConfig, context: ActivationContext) {\n const activated: string[] = []\n for (const module of this.#modules) {\n if (context.signal.aborted) throw context.signal.reason\n context.report({ description: '', name: module.id })\n if (await module.activate(plugin, context)) activated.push(module.id)\n }\n return activated\n }\n}","import { shallowReactive } from 'vue'\n\nimport type { PluginScope } from './scope'\n\nexport interface Contribution<T> {\n readonly owner: string\n readonly id: string\n readonly value: T\n}\n\nexport interface ContributionChannel<T> {\n readonly key: string\n readonly __type?: T\n}\n\nexport const defineContributionChannel = <T>(key: string): ContributionChannel<T> => ({ key })\n\nconst contributionKey = (owner: string, id: string) => JSON.stringify([owner, id])\n\nexport class ContributionRegistry<T> {\n readonly #entries = shallowReactive(new Map<string, Contribution<T>>())\n\n public get size() {\n return this.#entries.size\n }\n\n public get entries(): ReadonlyMap<string, Contribution<T>> {\n return this.#entries\n }\n\n public register(owner: string, id: string, value: T) {\n if (!owner) throw new Error('contribution owner cannot be empty')\n if (!id) throw new Error('contribution id cannot be empty')\n\n const key = contributionKey(owner, id)\n if (this.#entries.has(key)) {\n throw new Error(`duplicate contribution \"${owner}:${id}\"`)\n }\n\n const contribution: Contribution<T> = { id, owner, value }\n this.#entries.set(key, contribution)\n\n let active = true\n return () => {\n if (!active) return false\n active = false\n return this.#entries.delete(key)\n }\n }\n\n public get(owner: string, id: string) {\n return this.#entries.get(contributionKey(owner, id))\n }\n\n public byOwner(owner: string) {\n return [...this.#entries.values()].filter(entry => entry.owner === owner)\n }\n\n public removeOwner(owner: string) {\n for (const [key, entry] of this.#entries) {\n if (entry.owner === owner) this.#entries.delete(key)\n }\n }\n\n public values() {\n return this.#entries.values()\n }\n}\n\nexport class ContributionHub {\n private readonly registries = new Map<string, ContributionRegistry<unknown>>()\n\n public channel<T>(channel: ContributionChannel<T>): ContributionRegistry<T> {\n let registry = this.registries.get(channel.key)\n if (!registry) {\n registry = new ContributionRegistry<unknown>()\n this.registries.set(channel.key, registry)\n }\n return registry as ContributionRegistry<T>\n }\n\n public register<T>(scope: PluginScope, channel: ContributionChannel<T>, id: string, value: T) {\n const unregister = this.channel(channel).register(scope.owner, id, value)\n scope.defer(() => void unregister())\n return unregister\n }\n\n public removeOwner(owner: string) {\n for (const registry of this.registries.values()) registry.removeOwner(owner)\n }\n}","import type { PluginCandidate } from './candidate'\n\nexport interface MissingPluginDependency {\n readonly plugin: string\n readonly dependency: string\n}\n\nexport interface PluginDependencyPlan {\n readonly levels: PluginCandidate[][]\n readonly missing: MissingPluginDependency[]\n readonly cycles: string[][]\n}\n\nconst dependenciesOf = (candidate: PluginCandidate) =>\n candidate.manifest.require.map(dependency => dependency.id)\n\nconst canonicalCycleKey = (cycle: readonly string[]) => {\n const nodes = cycle.slice(0, -1)\n const rotations = nodes.map((_, index) => nodes.slice(index).concat(nodes.slice(0, index)))\n rotations.sort((left, right) => left.join('\\0').localeCompare(right.join('\\0')))\n return rotations[0]?.join('\\0') ?? ''\n}\n\nexport const findPluginDependencyCycles = (candidates: readonly PluginCandidate[]) => {\n const candidateIds = new Set(candidates.map(candidate => candidate.manifest.name.id))\n const dependencies = new Map(\n candidates.map(candidate => [\n candidate.manifest.name.id,\n dependenciesOf(candidate).filter(dependency => candidateIds.has(dependency)),\n ]),\n )\n const state = new Map<string, 'visiting' | 'visited'>()\n const path: string[] = []\n const keys = new Set<string>()\n const cycles: string[][] = []\n\n const visit = (plugin: string) => {\n state.set(plugin, 'visiting')\n path.push(plugin)\n for (const dependency of dependencies.get(plugin) ?? []) {\n if (state.get(dependency) === 'visiting') {\n const start = path.lastIndexOf(dependency)\n if (start < 0) continue\n const cycle = path.slice(start).concat(dependency)\n const key = canonicalCycleKey(cycle)\n if (!keys.has(key)) {\n keys.add(key)\n cycles.push(cycle)\n }\n } else if (state.get(dependency) !== 'visited') {\n visit(dependency)\n }\n }\n path.pop()\n state.set(plugin, 'visited')\n }\n\n for (const candidate of candidates) {\n const id = candidate.manifest.name.id\n if (!state.has(id)) visit(id)\n }\n return cycles\n}\n\nexport const planPluginDependencies = (\n candidates: readonly PluginCandidate[],\n): PluginDependencyPlan => {\n const byId = new Map(candidates.map(candidate => [candidate.manifest.name.id, candidate]))\n const degree = new Map<string, number>()\n const dependents = new Map<string, string[]>()\n const missing: MissingPluginDependency[] = []\n\n for (const candidate of candidates) {\n const id = candidate.manifest.name.id\n const installed = dependenciesOf(candidate).filter(dependency => {\n if (byId.has(dependency)) return true\n missing.push({ dependency, plugin: id })\n return false\n })\n degree.set(id, installed.length)\n for (const dependency of installed) {\n const entries = dependents.get(dependency) ?? []\n entries.push(id)\n dependents.set(dependency, entries)\n }\n }\n\n const queue = [...degree].filter(([, value]) => value === 0).map(([id]) => id)\n const levels: PluginCandidate[][] = []\n while (queue.length > 0) {\n const current = queue.splice(0)\n const level = current.flatMap(id => {\n const candidate = byId.get(id)\n return candidate ? [candidate] : []\n })\n if (level.length > 0) levels.push(level)\n for (const id of current) {\n for (const dependent of dependents.get(id) ?? []) {\n const next = (degree.get(dependent) ?? 0) - 1\n degree.set(dependent, next)\n if (next === 0) queue.push(dependent)\n }\n }\n }\n\n const unresolved = candidates.filter(\n candidate => (degree.get(candidate.manifest.name.id) ?? 0) > 0,\n )\n return { cycles: findPluginDependencyCycles(unresolved), levels, missing }\n}","export type PluginDisposer = () => Promise<void> | void\n\nexport class PluginScope {\n readonly #controller = new AbortController()\n readonly #disposers: PluginDisposer[] = []\n #disposePromise?: Promise<void>\n\n public constructor(public readonly owner: string) {}\n\n public get signal() {\n return this.#controller.signal\n }\n\n public get disposed() {\n return this.#disposePromise !== undefined\n }\n\n public defer(disposer: PluginDisposer) {\n if (this.disposed) throw new Error(`plugin scope \"${this.owner}\" is already disposed`)\n this.#disposers.push(disposer)\n return disposer\n }\n\n public dispose(reason?: unknown) {\n return (this.#disposePromise ??= this.#dispose(reason))\n }\n\n async #dispose(reason?: unknown) {\n this.#controller.abort(reason)\n const errors: unknown[] = []\n\n for (const disposer of this.#disposers.reverse()) {\n try {\n await disposer()\n } catch (error) {\n errors.push(error)\n }\n }\n this.#disposers.length = 0\n\n if (errors.length > 0) {\n throw new AggregateError(errors, `failed to dispose plugin scope \"${this.owner}\"`)\n }\n }\n}","import { defineCapability, type CapabilityModule } from '../kernel'\n\nimport type { PluginCapabilityServices } from './services'\n\nexport const createAuthCapability = (services: PluginCapabilityServices): CapabilityModule =>\n defineCapability({\n id: 'auth',\n select: config => config.model?.user?.auth,\n async activate(auth, context) {\n if (services.phase === 'preboot') {\n throw new Error('plugin authentication is only available during normal activation')\n }\n if (!services.auth) throw new Error('plugin authentication requires a host auth gateway')\n context.report({ name: 'auth', description: 'checking authentication' })\n await services.auth.authenticate(context.owner, auth, context.signal)\n },\n })","import { defineCapability, type CapabilityModule } from '../kernel'\n\nimport type { PluginCapabilityServices } from './services'\n\nexport const createConfigCapability = (services: PluginCapabilityServices): CapabilityModule =>\n defineCapability({\n id: 'config',\n select: config => config.config,\n async activate(pointer, context) {\n if (pointer.pluginName !== context.scope.owner) {\n throw new Error(\n `plugin config owner mismatch: ${context.scope.owner} / ${pointer.pluginName}`,\n )\n }\n context.report({ description: pointer.configName })\n const registered = services.config.register(pointer)\n context.scope.defer(() => services.config.unregister(pointer))\n await registered.ready\n },\n })","import type { PluginScope } from '../kernel'\n\ninterface MutableRegistry<TKey, TValue> {\n delete(key: TKey): boolean\n get(key: TKey): TValue | undefined\n has(key: TKey): boolean\n set(key: TKey, value: TValue): unknown\n}\n\n/** Bind a host registry entry and restore exactly the value that existed before activation. */\nexport const bindRegistryValue = <TKey, TValue>(\n scope: PluginScope,\n registry: MutableRegistry<TKey, TValue>,\n key: TKey,\n value: TValue | undefined,\n) => {\n if (value === undefined) return\n const hadPrevious = registry.has(key)\n const previous = registry.get(key)\n registry.set(key, value)\n scope.defer(() => {\n if (hadPrevious) registry.set(key, previous as TValue)\n else registry.delete(key)\n })\n}","import { UniComment, UniContentPage, UniItem } from '@delta-comic/model'\n\nimport { defineCapability, type CapabilityModule } from '../kernel'\n\nimport { bindRegistryValue } from './registryBinding'\n\nexport const createContentCapability = (): CapabilityModule =>\n defineCapability({\n id: 'content-bindings',\n select: config => config.model?.content?.models,\n activate(models, context) {\n const names = new Set<string>()\n for (const model of models) {\n if (!model.name) throw new Error('content model name cannot be empty')\n if (names.has(model.name)) throw new Error(`duplicate content model \"${model.name}\"`)\n names.add(model.name)\n const key: [plugin: string, name: string] = [context.owner, model.name]\n bindRegistryValue(context.scope, UniContentPage.layouts, key, model.Layout)\n bindRegistryValue(context.scope, UniItem.itemCards, key, model.ItemCard)\n bindRegistryValue(context.scope, UniContentPage.contentPages, key, model.ContentPage)\n bindRegistryValue(\n context.scope,\n UniContentPage.downloadProviders,\n key,\n model.DownloadProvider,\n )\n bindRegistryValue(context.scope, UniComment.commentRow, key, model.CommentRow)\n bindRegistryValue(context.scope, UniItem.itemTranslator, key, model.ItemTranslator)\n }\n },\n })","import { defineCapability, type CapabilityModule } from '../kernel'\n\nimport type { PluginCapabilityServices } from './services'\n\nexport const createI18nCapability = (services: PluginCapabilityServices): CapabilityModule =>\n defineCapability({\n id: 'i18n',\n select: config => config.i18n,\n activate(messages, context) {\n services.i18n.register(context.scope.owner, messages)\n context.scope.defer(() => services.i18n.remove(context.scope.owner))\n },\n })","import { defineCapability, type CapabilityModule } from '../kernel'\n\nimport type { PluginCapabilityServices } from './services'\n\nexport const createLifecycleCapability = (services: PluginCapabilityServices): CapabilityModule =>\n defineCapability({\n id: 'lifecycle',\n select: config => {\n const hooks = config.hooks\n return hooks?.onBooted || hooks?.onPreboot || hooks?.onUnload || hooks?.onUninstall\n ? hooks\n : undefined\n },\n async activate(hooks, context) {\n if (hooks.onUnload) context.scope.defer(() => hooks.onUnload?.())\n\n if (services.phase === 'preboot') {\n if (!services.app) throw new Error('preboot activation requires a Vue app')\n const cleanup = await hooks.onPreboot?.({ app: services.app })\n if (cleanup) context.scope.defer(cleanup)\n return\n }\n await hooks.onBooted?.()\n },\n })","import type {\n ContentModel,\n ExposeModel,\n RemoteModel,\n ResourceModel,\n SocialModel,\n SpecialModel,\n UserModel,\n} from '../api/model'\nimport { defineContributionChannel } from '../kernel'\n\nexport const pluginModelChannels = {\n content: defineContributionChannel<ContentModel>('model:content'),\n expose: defineContributionChannel<ExposeModel>('model:expose'),\n remote: defineContributionChannel<RemoteModel>('model:remote'),\n resource: defineContributionChannel<ResourceModel>('model:resource'),\n social: defineContributionChannel<SocialModel>('model:social'),\n special: defineContributionChannel<SpecialModel>('model:special'),\n user: defineContributionChannel<UserModel>('model:user'),\n} as const","import type { PluginConfigModel } from '../api/model'\nimport { defineCapability, type CapabilityModule, type ContributionChannel } from '../kernel'\n\nimport { pluginModelChannels } from './channels'\nimport type { PluginCapabilityServices } from './services'\n\nexport const createModelCapability = (services: PluginCapabilityServices): CapabilityModule =>\n defineCapability({\n id: 'model',\n select: config => config.model,\n activate(model: PluginConfigModel, context) {\n const register = <T>(channel: ContributionChannel<T>, value: T | undefined) => {\n if (value !== undefined) {\n services.contributions.register(context.scope, channel, 'default', value)\n }\n }\n\n register(pluginModelChannels.content, model.content)\n register(pluginModelChannels.expose, model.expose)\n register(pluginModelChannels.remote, model.remotes)\n register(pluginModelChannels.resource, model.resource)\n register(pluginModelChannels.social, model.social)\n register(pluginModelChannels.special, model.special)\n register(pluginModelChannels.user, model.user)\n },\n })","export interface EndpointProbeCandidate<T> {\n readonly test: (url: string, signal: AbortSignal) => PromiseLike<void>\n readonly url: string\n readonly value: T\n}\n\nexport interface EndpointProbeResult<T> {\n readonly latencyMs: number\n readonly url: string\n readonly value: T\n}\n\nconst probeOne = async <T>(\n candidate: EndpointProbeCandidate<T>,\n parentSignal: AbortSignal,\n timeoutMs: number,\n controllers: Set<AbortController>,\n) => {\n const controller = new AbortController()\n controllers.add(controller)\n const relayAbort = () => controller.abort(parentSignal.reason)\n parentSignal.addEventListener('abort', relayAbort, { once: true })\n const timeout = setTimeout(\n () => controller.abort(new Error('endpoint probe timed out')),\n timeoutMs,\n )\n const startedAt = performance.now()\n try {\n await candidate.test(candidate.url, controller.signal)\n return { latencyMs: performance.now() - startedAt, url: candidate.url, value: candidate.value }\n } finally {\n clearTimeout(timeout)\n parentSignal.removeEventListener('abort', relayAbort)\n controllers.delete(controller)\n }\n}\n\n/** Probe independently in parallel and stop remaining attempts after the first reachable endpoint. */\nexport const selectFastestEndpoint = async <T>(\n candidates: readonly EndpointProbeCandidate<T>[],\n signal: AbortSignal,\n timeoutMs = 10_000,\n): Promise<EndpointProbeResult<T> | undefined> => {\n signal.throwIfAborted()\n const controllers = new Set<AbortController>()\n try {\n return await Promise.any(\n candidates.map(candidate => probeOne(candidate, signal, timeoutMs, controllers)),\n )\n } catch (error) {\n signal.throwIfAborted()\n if (error instanceof AggregateError) return undefined\n throw error\n } finally {\n for (const controller of controllers)\n controller.abort(new Error('another endpoint was selected'))\n }\n}","import type { Remote } from '../api'\nimport { defineCapability, defineContributionChannel, type CapabilityModule } from '../kernel'\n\nimport { selectFastestEndpoint } from './endpointProbe'\nimport type { PluginCapabilityServices } from './services'\n\nexport interface RemoteSelection {\n readonly group: Remote.TestGroup\n readonly latencyMs?: number\n readonly remote: Remote.Definition | false\n}\n\nexport const pluginRemoteSelectionChannel = defineContributionChannel<RemoteSelection>(\n 'runtime:remote-selection',\n)\n\nexport const createRemoteCapability = (services: PluginCapabilityServices): CapabilityModule =>\n defineCapability({\n id: 'remote',\n select: config =>\n config.model?.remotes ? { hooks: config.hooks, remotes: config.model.remotes } : undefined,\n async activate({ hooks, remotes }, context) {\n const groups = new Set<string>()\n for (const group of remotes) {\n if (!group.name) throw new Error('remote group name cannot be empty')\n if (groups.has(group.name)) throw new Error(`duplicate remote group \"${group.name}\"`)\n groups.add(group.name)\n context.report({ name: 'remote', description: `probing ${group.name}` })\n const selected = await selectFastestEndpoint(\n group.remotes.map(remote => ({\n test: remote.test ?? group.test,\n url: remote.url,\n value: remote,\n })),\n context.signal,\n )\n if (!selected && !group.allowNoConnected) {\n throw new Error(`no reachable endpoint for remote group \"${group.name}\"`)\n }\n const selection: RemoteSelection = {\n group,\n latencyMs: selected?.latencyMs,\n remote: selected?.value ?? false,\n }\n services.contributions.register(\n context.scope,\n pluginRemoteSelectionChannel,\n group.name,\n selection,\n )\n hooks?.onRemoteTestDone?.(group, selection.remote)\n }\n },\n })","import { UniResource } from '@delta-comic/model'\n\nimport { defineCapability, type CapabilityModule } from '../kernel'\n\nimport { selectFastestEndpoint } from './endpointProbe'\nimport { bindRegistryValue } from './registryBinding'\n\nexport const createResourceCapability = (): CapabilityModule =>\n defineCapability({\n id: 'resource',\n select: config => config.model?.resource,\n async activate(resource, context) {\n const names = new Set<string>()\n for (const type of resource.types ?? []) {\n if (!type.type) throw new Error('resource type cannot be empty')\n if (names.has(type.type)) throw new Error(`duplicate resource type \"${type.type}\"`)\n names.add(type.type)\n const key: [plugin: string, type: string] = [context.owner, type.type]\n bindRegistryValue(context.scope, UniResource.fork, key, type)\n context.report({ name: 'resource', description: `probing ${type.type}` })\n const selected = await selectFastestEndpoint(\n type.urls.map(url => ({ test: type.test, url, value: url })),\n context.signal,\n )\n if (!selected) throw new Error(`no reachable endpoint for resource \"${type.type}\"`)\n bindRegistryValue(context.scope, UniResource.precedenceFork, key, selected.url)\n }\n for (const [name, process] of Object.entries(resource.process ?? {})) {\n if (!name) throw new Error('resource process name cannot be empty')\n bindRegistryValue(\n context.scope,\n UniResource.processInstances,\n [context.owner, name],\n process,\n )\n }\n },\n })","import { defineCapability, type CapabilityModule } from '../kernel'\n\nexport const createSpecialCapability = (): CapabilityModule =>\n defineCapability({\n id: 'special',\n select: config => config.model?.special,\n async activate(steps, context) {\n for (const step of steps) {\n context.signal.throwIfAborted()\n if (!step.name) throw new Error('special step name cannot be empty')\n context.report({ name: step.name, description: '' })\n await step.call(description => context.report({ name: step.name, description }))\n }\n },\n })","import { UniUser } from '@delta-comic/model'\n\nimport { defineCapability, type CapabilityModule } from '../kernel'\n\nimport { bindRegistryValue } from './registryBinding'\n\nexport const createUserCapability = (): CapabilityModule =>\n defineCapability({\n id: 'user-bindings',\n select: config => config.model?.user,\n activate(user, context) {\n bindRegistryValue(context.scope, UniUser.userCards, context.owner, user.card)\n bindRegistryValue(context.scope, UniUser.userEditorBase, context.owner, user.edit)\n },\n })","import type { CapabilityModule } from '../kernel'\n\nimport { createAuthCapability } from './auth'\nimport { createConfigCapability } from './config'\nimport { createContentCapability } from './content'\nimport { createI18nCapability } from './i18n'\nimport { createLifecycleCapability } from './lifecycle'\nimport { createModelCapability } from './model'\nimport { createRemoteCapability } from './remote'\nimport { createResourceCapability } from './resource'\nimport type { PluginCapabilityServices } from './services'\nimport { createSpecialCapability } from './special'\nimport { createUserCapability } from './user'\n\nexport * from './auth'\nexport * from './channels'\nexport * from './config'\nexport * from './content'\nexport * from './i18n'\nexport * from './lifecycle'\nexport * from './model'\nexport * from './remote'\nexport * from './resource'\nexport * from './services'\nexport * from './special'\nexport * from './user'\n\n/** Fixed host-owned activation topology. Third-party plugins only provide data to it. */\nexport const createDefaultCapabilities = (\n services: PluginCapabilityServices,\n): readonly CapabilityModule[] => [\n createConfigCapability(services),\n createI18nCapability(services),\n createModelCapability(services),\n createContentCapability(),\n createUserCapability(),\n createResourceCapability(),\n createRemoteCapability(services),\n createAuthCapability(services),\n createSpecialCapability(),\n createLifecycleCapability(services),\n]","import { DELTA_COMIC_PLUGIN_API_VERSION, type PluginManifest } from '@delta-comic/model'\nimport semver from 'semver'\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst record = (value: unknown, path: string) => {\n if (!isRecord(value)) throw new PluginManifestError(`${path} must be an object`)\n return value\n}\n\nconst text = (value: unknown, path: string) => {\n if (typeof value !== 'string' || value.length === 0) {\n throw new PluginManifestError(`${path} must be a non-empty string`)\n }\n return value\n}\n\nconst pluginId = (value: unknown, path: string) => {\n const id = text(value, path)\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(id)) {\n throw new PluginManifestError(`${path} must be a portable 1-64 character plugin identifier`)\n }\n return id\n}\n\nexport const safePluginPath = (value: unknown, path: string) => {\n const normalized = text(value, path).replaceAll('\\\\', '/')\n if (\n normalized.startsWith('/') ||\n /^[a-z]:($|\\/)/i.test(normalized) ||\n normalized.includes('\\0') ||\n normalized.split('/').some(segment => segment === '..')\n ) {\n throw new PluginManifestError(`${path} must be a safe relative path`)\n }\n return normalized\n .split('/')\n .filter(segment => segment && segment !== '.')\n .join('/')\n}\n\nexport class PluginManifestError extends Error {\n public constructor(message: string) {\n super(`Invalid Delta Comic manifest: ${message}`)\n this.name = 'PluginManifestError'\n }\n}\n\nconst pluginIcon = (value: unknown) => {\n const icon = text(value, 'manifest.icon').trim()\n if (!/^[a-z][a-z\\d+.-]*:/i.test(icon)) return safePluginPath(icon, 'manifest.icon')\n let url: URL\n try {\n url = new URL(icon)\n } catch {\n throw new PluginManifestError('manifest.icon must be an HTTP(S) URL or a safe relative path')\n }\n if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {\n throw new PluginManifestError(\n 'manifest.icon must be a credential-free HTTP(S) URL or a safe relative path',\n )\n }\n return icon\n}\n\nexport const parsePluginManifest = (value: unknown): PluginManifest => {\n const manifest = record(value, 'manifest')\n if (manifest.apiVersion !== DELTA_COMIC_PLUGIN_API_VERSION) {\n throw new PluginManifestError(`manifest.apiVersion must be ${DELTA_COMIC_PLUGIN_API_VERSION}`)\n }\n const name = record(manifest.name, 'manifest.name')\n const version = record(manifest.version, 'manifest.version')\n const id = pluginId(name.id, 'manifest.name.id')\n if (!Array.isArray(manifest.require)) {\n throw new PluginManifestError('manifest.require must be an array')\n }\n\n const result: PluginManifest = {\n apiVersion: DELTA_COMIC_PLUGIN_API_VERSION,\n author: text(manifest.author, 'manifest.author'),\n description: text(manifest.description, 'manifest.description'),\n name: { display: text(name.display, 'manifest.name.display'), id },\n require: manifest.require.map((value, index) => {\n const dependency = record(value, `manifest.require[${index}]`)\n return {\n id: pluginId(dependency.id, `manifest.require[${index}].id`),\n ...(dependency.download === undefined\n ? {}\n : { download: text(dependency.download, `manifest.require[${index}].download`) }),\n }\n }),\n version: {\n plugin: text(version.plugin, 'manifest.version.plugin'),\n supportCore: text(version.supportCore, 'manifest.version.supportCore'),\n },\n }\n\n if (manifest.icon !== undefined) result.icon = pluginIcon(manifest.icon)\n if (manifest.entry !== undefined) {\n const entry = record(manifest.entry, 'manifest.entry')\n result.entry = {\n jsPath: safePluginPath(entry.jsPath, 'manifest.entry.jsPath'),\n ...(entry.cssPath === undefined\n ? {}\n : { cssPath: safePluginPath(entry.cssPath, 'manifest.entry.cssPath') }),\n }\n }\n if (manifest.kind !== undefined) {\n if (manifest.kind !== 'normal' && manifest.kind !== 'preboot') {\n throw new PluginManifestError('manifest.kind must be \"normal\" or \"preboot\"')\n }\n result.kind = manifest.kind\n }\n if (manifest.integrity !== undefined) {\n const integrity = record(manifest.integrity, 'manifest.integrity')\n if (integrity.algorithm !== 'blake3' && integrity.algorithm !== 'sha256') {\n throw new PluginManifestError('manifest.integrity.algorithm is unsupported')\n }\n result.integrity = {\n algorithm: integrity.algorithm,\n digest: text(integrity.digest, 'manifest.integrity.digest'),\n }\n }\n return result\n}\n\nexport const isPluginManifestCompatible = (manifest: PluginManifest, coreVersion: string) =>\n semver.satisfies(coreVersion, manifest.version.supportCore)","export const AWESOME_REGISTRY_BASE_URL =\n 'https://raw.githubusercontent.com/delta-comic/awesome-plugins/main/'\nexport const AWESOME_REGISTRY_INDEX_PATH = 'registry/index.json'\nexport const AWESOME_REGISTRY_SCHEMA_VERSION = 1 as const\n\nexport interface AwesomeRegistryPageReference {\n page: number\n items: number\n path: string\n}\n\nexport interface AwesomeRegistryIndex {\n schemaVersion: typeof AWESOME_REGISTRY_SCHEMA_VERSION\n pageSize: number\n totalItems: number\n totalPages: number\n pages: AwesomeRegistryPageReference[]\n}\n\nexport interface AwesomeRegistryPagination {\n page: number\n pageSize: number\n totalItems: number\n totalPages: number\n previous: string | null\n next: string | null\n}\n\nexport type AwesomePluginDownload =\n | { type: 'github'; repository: string }\n | { type: 'url'; url: string }\n\nexport interface AwesomePluginRepository {\n owner: string\n name: string\n url: string\n defaultBranch: string\n lastCommitAt: string\n readmeUrl?: string\n}\n\nexport interface AwesomePluginRelease {\n version: string\n url: string\n publishedAt: string\n manifestUrl: string | null\n}\n\nexport interface AwesomePluginListing {\n schemaVersion: typeof AWESOME_REGISTRY_SCHEMA_VERSION\n id: string\n authors: string[]\n download: AwesomePluginDownload\n repository?: AwesomePluginRepository\n release?: AwesomePluginRelease\n}\n\nexport interface AwesomeRegistryPage {\n schemaVersion: typeof AWESOME_REGISTRY_SCHEMA_VERSION\n pagination: AwesomeRegistryPagination\n items: AwesomePluginListing[]\n}\n\nexport interface AwesomeRegistryResult<T> {\n data: T\n cachedAt: string\n stale: boolean\n}\n\nexport interface AwesomeRegistryStorage {\n getItem(key: string): string | null\n removeItem(key: string): void\n setItem(key: string, value: string): void\n}","import {\n AWESOME_REGISTRY_SCHEMA_VERSION,\n type AwesomePluginDownload,\n type AwesomePluginListing,\n type AwesomePluginRelease,\n type AwesomePluginRepository,\n type AwesomeRegistryIndex,\n type AwesomeRegistryPage,\n type AwesomeRegistryPagination,\n type AwesomeRegistryPageReference,\n} from './types'\n\n/** Paths are validated before they are resolved against the configured registry origin. */\nconst PAGE_PATH_PATTERN = /^registry\\/pages\\/[1-9][0-9]*\\.json$/\nconst PLUGIN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/\nconst GITHUB_LOGIN_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/\nconst GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst record = (value: unknown, path: string) => {\n if (!isRecord(value)) throw new AwesomeRegistryValidationError(`${path} must be an object`)\n return value\n}\n\nconst exactKeys = (value: Record<string, unknown>, allowed: readonly string[], path: string) => {\n const extras = Object.keys(value).filter(key => !allowed.includes(key))\n if (extras.length > 0) {\n throw new AwesomeRegistryValidationError(`${path} has unknown fields: ${extras.join(', ')}`)\n }\n}\n\nconst string = (value: unknown, path: string) => {\n if (typeof value !== 'string' || value.length === 0) {\n throw new AwesomeRegistryValidationError(`${path} must be a non-empty string`)\n }\n return value\n}\n\nconst integer = (value: unknown, path: string, minimum: number, maximum = Infinity) => {\n if (!Number.isInteger(value) || (value as number) < minimum || (value as number) > maximum) {\n throw new AwesomeRegistryValidationError(\n `${path} must be an integer between ${minimum} and ${maximum}`,\n )\n }\n return value as number\n}\n\nconst schemaVersion = (value: unknown, path: string) => {\n if (value !== AWESOME_REGISTRY_SCHEMA_VERSION) {\n throw new AwesomeRegistryVersionError(value, path)\n }\n return AWESOME_REGISTRY_SCHEMA_VERSION\n}\n\nconst path = (value: unknown, field: string) => {\n const result = string(value, field)\n if (!PAGE_PATH_PATTERN.test(result)) {\n throw new AwesomeRegistryValidationError(`${field} must be a registry page path`)\n }\n return result\n}\n\nconst httpUrl = (value: unknown, field: string) => {\n const result = string(value, field)\n let parsed: URL\n try {\n parsed = new URL(result)\n } catch {\n throw new AwesomeRegistryValidationError(`${field} must be an absolute URL`)\n }\n if (!['http:', 'https:'].includes(parsed.protocol) || parsed.username || parsed.password) {\n throw new AwesomeRegistryValidationError(`${field} must be a credential-free HTTP(S) URL`)\n }\n return result\n}\n\nconst dateTime = (value: unknown, field: string) => {\n const result = string(value, field)\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(result) || Number.isNaN(Date.parse(result))) {\n throw new AwesomeRegistryValidationError(`${field} must be an ISO date-time`)\n }\n return result\n}\n\nconst parsePageReference = (value: unknown, field: string): AwesomeRegistryPageReference => {\n const item = record(value, field)\n exactKeys(item, ['page', 'items', 'path'], field)\n return {\n page: integer(item.page, `${field}.page`, 1),\n items: integer(item.items, `${field}.items`, 1),\n path: path(item.path, `${field}.path`),\n }\n}\n\nconst parseDownload = (value: unknown, field: string): AwesomePluginDownload => {\n const download = record(value, field)\n if (download.type === 'github') {\n exactKeys(download, ['type', 'repository'], field)\n const repository = string(download.repository, `${field}.repository`)\n if (!GITHUB_REPOSITORY_PATTERN.test(repository)) {\n throw new AwesomeRegistryValidationError(`${field}.repository is invalid`)\n }\n return { type: 'github', repository }\n }\n if (download.type === 'url') {\n exactKeys(download, ['type', 'url'], field)\n return { type: 'url', url: httpUrl(download.url, `${field}.url`) }\n }\n throw new AwesomeRegistryValidationError(`${field}.type is unsupported`)\n}\n\nconst parseRepository = (value: unknown, field: string): AwesomePluginRepository => {\n const repository = record(value, field)\n exactKeys(\n repository,\n ['owner', 'name', 'url', 'defaultBranch', 'lastCommitAt', 'readmeUrl'],\n field,\n )\n return {\n owner: string(repository.owner, `${field}.owner`),\n name: string(repository.name, `${field}.name`),\n url: httpUrl(repository.url, `${field}.url`),\n defaultBranch: string(repository.defaultBranch, `${field}.defaultBranch`),\n lastCommitAt: dateTime(repository.lastCommitAt, `${field}.lastCommitAt`),\n ...(repository.readmeUrl === undefined\n ? {}\n : { readmeUrl: httpUrl(repository.readmeUrl, `${field}.readmeUrl`) }),\n }\n}\n\nconst parseRelease = (value: unknown, field: string): AwesomePluginRelease => {\n const release = record(value, field)\n exactKeys(release, ['version', 'url', 'publishedAt', 'manifestUrl'], field)\n return {\n version: string(release.version, `${field}.version`),\n url: httpUrl(release.url, `${field}.url`),\n publishedAt: dateTime(release.publishedAt, `${field}.publishedAt`),\n manifestUrl:\n release.manifestUrl === null ? null : httpUrl(release.manifestUrl, `${field}.manifestUrl`),\n }\n}\n\nexport class AwesomeRegistryValidationError extends Error {\n public constructor(message: string) {\n super(`Invalid awesome-plugins registry: ${message}`)\n this.name = 'AwesomeRegistryValidationError'\n }\n}\n\nexport class AwesomeRegistryVersionError extends AwesomeRegistryValidationError {\n public constructor(\n public readonly received: unknown,\n path: string,\n ) {\n super(`${path} has unsupported schemaVersion ${String(received)}`)\n this.name = 'AwesomeRegistryVersionError'\n }\n}\n\nexport const parseAwesomeRegistryIndex = (value: unknown): AwesomeRegistryIndex => {\n const index = record(value, 'index')\n exactKeys(index, ['schemaVersion', 'pageSize', 'totalItems', 'totalPages', 'pages'], 'index')\n if (!Array.isArray(index.pages)) {\n throw new AwesomeRegistryValidationError('index.pages must be an array')\n }\n const result: AwesomeRegistryIndex = {\n schemaVersion: schemaVersion(index.schemaVersion, 'index'),\n pageSize: integer(index.pageSize, 'index.pageSize', 1, 100),\n totalItems: integer(index.totalItems, 'index.totalItems', 0),\n totalPages: integer(index.totalPages, 'index.totalPages', 0),\n pages: index.pages.map((item, itemIndex) =>\n parsePageReference(item, `index.pages[${itemIndex}]`),\n ),\n }\n if (result.pages.length !== result.totalPages) {\n throw new AwesomeRegistryValidationError('index.pages length must equal index.totalPages')\n }\n if (result.pages.reduce((total, page) => total + page.items, 0) !== result.totalItems) {\n throw new AwesomeRegistryValidationError('index page item counts must equal index.totalItems')\n }\n result.pages.forEach((page, itemIndex) => {\n if (page.page !== itemIndex + 1 || page.items > result.pageSize) {\n throw new AwesomeRegistryValidationError('index pages must be ordered and respect pageSize')\n }\n })\n return result\n}\n\nexport const parseAwesomePluginListing = (\n value: unknown,\n field = 'listing',\n): AwesomePluginListing => {\n const listing = record(value, field)\n exactKeys(listing, ['schemaVersion', 'id', 'authors', 'download', 'repository', 'release'], field)\n const id = string(listing.id, `${field}.id`)\n if (!PLUGIN_ID_PATTERN.test(id)) {\n throw new AwesomeRegistryValidationError(`${field}.id is invalid`)\n }\n if (!Array.isArray(listing.authors) || listing.authors.length === 0) {\n throw new AwesomeRegistryValidationError(`${field}.authors must be a non-empty array`)\n }\n const authors = listing.authors.map((author, index) => {\n const login = string(author, `${field}.authors[${index}]`)\n if (!GITHUB_LOGIN_PATTERN.test(login)) {\n throw new AwesomeRegistryValidationError(`${field}.authors[${index}] is invalid`)\n }\n return login\n })\n if (new Set(authors).size !== authors.length) {\n throw new AwesomeRegistryValidationError(`${field}.authors must be unique`)\n }\n return {\n schemaVersion: schemaVersion(listing.schemaVersion, field),\n id,\n authors,\n download: parseDownload(listing.download, `${field}.download`),\n ...(listing.repository === undefined\n ? {}\n : { repository: parseRepository(listing.repository, `${field}.repository`) }),\n ...(listing.release === undefined\n ? {}\n : { release: parseRelease(listing.release, `${field}.release`) }),\n }\n}\n\nconst parsePagination = (value: unknown, field: string): AwesomeRegistryPagination => {\n const pagination = record(value, field)\n exactKeys(pagination, ['page', 'pageSize', 'totalItems', 'totalPages', 'previous', 'next'], field)\n return {\n page: integer(pagination.page, `${field}.page`, 1),\n pageSize: integer(pagination.pageSize, `${field}.pageSize`, 1, 100),\n totalItems: integer(pagination.totalItems, `${field}.totalItems`, 0),\n totalPages: integer(pagination.totalPages, `${field}.totalPages`, 1),\n previous: pagination.previous === null ? null : path(pagination.previous, `${field}.previous`),\n next: pagination.next === null ? null : path(pagination.next, `${field}.next`),\n }\n}\n\nexport const parseAwesomeRegistryPage = (value: unknown): AwesomeRegistryPage => {\n const page = record(value, 'page')\n exactKeys(page, ['schemaVersion', 'pagination', 'items'], 'page')\n if (!Array.isArray(page.items)) {\n throw new AwesomeRegistryValidationError('page.items must be an array')\n }\n const result: AwesomeRegistryPage = {\n schemaVersion: schemaVersion(page.schemaVersion, 'page'),\n pagination: parsePagination(page.pagination, 'page.pagination'),\n items: page.items.map((item, index) => parseAwesomePluginListing(item, `page.items[${index}]`)),\n }\n if (result.items.length > result.pagination.pageSize) {\n throw new AwesomeRegistryValidationError('page.items exceeds pageSize')\n }\n const expectedPrevious = result.pagination.page === 1 ? null : result.pagination.page - 1\n const expectedNext =\n result.pagination.page === result.pagination.totalPages ? null : result.pagination.page + 1\n if (\n (expectedPrevious === null) !== (result.pagination.previous === null) ||\n (expectedNext === null) !== (result.pagination.next === null)\n ) {\n throw new AwesomeRegistryValidationError('page pagination links are inconsistent')\n }\n return result\n}\n\nexport const assertAwesomeRegistryPagePath = (value: string) => path(value, 'page path')","import { parseAwesomeRegistryIndex, parseAwesomeRegistryPage } from './schema'\nimport type { AwesomeRegistryIndex, AwesomeRegistryPage, AwesomeRegistryStorage } from './types'\n\ninterface CacheEnvelope {\n cachedAt: string\n data: unknown\n}\n\nconst parseEnvelope = (value: string): CacheEnvelope | undefined => {\n try {\n const envelope = JSON.parse(value) as Partial<CacheEnvelope>\n if (typeof envelope.cachedAt !== 'string' || !('data' in envelope)) return undefined\n return { cachedAt: envelope.cachedAt, data: envelope.data }\n } catch {\n return undefined\n }\n}\n\nexport class AwesomeRegistryCache {\n public constructor(\n private readonly storage?: AwesomeRegistryStorage,\n private readonly prefix = 'delta-comic:awesome-registry:v1',\n ) {}\n\n public readIndex() {\n return this.read(`${this.prefix}:index`, parseAwesomeRegistryIndex)\n }\n\n public writeIndex(data: AwesomeRegistryIndex) {\n return this.write(`${this.prefix}:index`, data)\n }\n\n public readPage(path: string) {\n return this.read(`${this.prefix}:page:${path}`, parseAwesomeRegistryPage)\n }\n\n public writePage(path: string, data: AwesomeRegistryPage) {\n return this.write(`${this.prefix}:page:${path}`, data)\n }\n\n private read<T>(key: string, parse: (value: unknown) => T) {\n if (!this.storage) return undefined\n let stored: string | null\n try {\n stored = this.storage.getItem(key)\n } catch {\n return undefined\n }\n if (!stored) return undefined\n const envelope = parseEnvelope(stored)\n if (!envelope) {\n this.remove(key)\n return undefined\n }\n try {\n return { cachedAt: envelope.cachedAt, data: parse(envelope.data) }\n } catch {\n this.remove(key)\n return undefined\n }\n }\n\n private remove(key: string) {\n try {\n this.storage?.removeItem(key)\n } catch {}\n }\n\n private write(key: string, data: AwesomeRegistryIndex | AwesomeRegistryPage) {\n const cachedAt = new Date().toISOString()\n try {\n this.storage?.setItem(key, JSON.stringify({ cachedAt, data } satisfies CacheEnvelope))\n } catch {}\n return cachedAt\n }\n}","import { logger } from '@delta-comic/logger'\nimport type { PluginManifest } from '@delta-comic/model'\nimport ky from 'ky'\n\nimport type {\n PluginCatalog,\n PluginCatalogIndex,\n PluginCatalogListing,\n PluginCatalogPage,\n PluginCatalogResult,\n} from '../../install/catalog'\nimport { parsePluginManifest } from '../../install/manifest'\n\nimport { AwesomeRegistryCache } from './cache'\nimport {\n assertAwesomeRegistryPagePath,\n parseAwesomeRegistryIndex,\n parseAwesomeRegistryPage,\n AwesomeRegistryValidationError,\n} from './schema'\nimport {\n AWESOME_REGISTRY_BASE_URL,\n AWESOME_REGISTRY_INDEX_PATH,\n type AwesomePluginListing,\n type AwesomeRegistryIndex,\n type AwesomeRegistryPage,\n type AwesomeRegistryResult,\n type AwesomeRegistryStorage,\n} from './types'\n\nconst marketplaceLogger = logger.scoped('plugin:marketplace')\n\nexport interface AwesomeRegistryClientOptions {\n baseUrl?: string\n cache?: AwesomeRegistryCache\n requestJson?: (url: string, signal?: AbortSignal) => Promise<unknown>\n storage?: AwesomeRegistryStorage\n}\n\nconst defaultRequestJson = async (url: string, signal?: AbortSignal) =>\n await ky.get(url, { retry: 2, signal, timeout: 30_000 }).json<unknown>()\n\nconst defaultStorage = () => {\n try {\n return globalThis.localStorage\n } catch {\n return undefined\n }\n}\n\nexport class AwesomeRegistryNetworkError extends Error {\n public constructor(\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message)\n this.name = 'AwesomeRegistryNetworkError'\n }\n}\n\nconst catalogIndex = (index: AwesomeRegistryIndex): PluginCatalogIndex => ({\n pageSize: index.pageSize,\n pages: index.pages,\n totalItems: index.totalItems,\n totalPages: index.totalPages,\n})\n\nconst catalogListing = (listing: AwesomePluginListing): PluginCatalogListing => ({\n authors: listing.authors,\n id: listing.id,\n ...(listing.release ? { release: listing.release } : {}),\n ...(listing.repository ? { repository: listing.repository } : {}),\n source: listing.download,\n})\n\nconst catalogPage = (page: AwesomeRegistryPage): PluginCatalogPage => ({\n items: page.items.map(catalogListing),\n pagination: page.pagination,\n})\n\nexport class AwesomeRegistryClient implements PluginCatalog {\n private readonly baseUrl: string\n private readonly cache: AwesomeRegistryCache\n private readonly requestJson: (url: string, signal?: AbortSignal) => Promise<unknown>\n\n public constructor(options: AwesomeRegistryClientOptions = {}) {\n this.baseUrl = new URL(options.baseUrl ?? AWESOME_REGISTRY_BASE_URL).href\n this.cache = options.cache ?? new AwesomeRegistryCache(options.storage ?? defaultStorage())\n this.requestJson = options.requestJson ?? defaultRequestJson\n }\n\n public async loadIndex(signal?: AbortSignal): Promise<PluginCatalogResult<PluginCatalogIndex>> {\n const result = await this.load(\n AWESOME_REGISTRY_INDEX_PATH,\n parseAwesomeRegistryIndex,\n () => this.cache.readIndex(),\n data => this.cache.writeIndex(data),\n signal,\n )\n return { ...result, data: catalogIndex(result.data) }\n }\n\n public async loadPage(\n path: string,\n signal?: AbortSignal,\n ): Promise<PluginCatalogResult<PluginCatalogPage>> {\n const safePath = assertAwesomeRegistryPagePath(path)\n const result = await this.load(\n safePath,\n parseAwesomeRegistryPage,\n () => this.cache.readPage(safePath),\n data => this.cache.writePage(safePath, data),\n signal,\n )\n return { ...result, data: catalogPage(result.data) }\n }\n\n public async resolveInstallInput(id: string, signal: AbortSignal) {\n const listing = await this.findListing(id, signal)\n return listing.source.type === 'github' ? `gh:${listing.source.repository}` : listing.source.url\n }\n\n public async findListing(id: string, signal?: AbortSignal): Promise<PluginCatalogListing> {\n marketplaceLogger.debug('searching marketplace listing', { plugin: id })\n const { data: index } = await this.loadIndex(signal)\n for (const pageReference of index.pages) {\n const { data: page } = await this.loadPage(pageReference.path, signal)\n const listing = page.items.find(item => item.id === id)\n if (listing) {\n marketplaceLogger.debug('marketplace listing found', { plugin: id })\n return listing\n }\n }\n throw new Error(`Plugin \"${id}\" is not registered in awesome-plugins`)\n }\n\n public async loadManifest(\n listing: PluginCatalogListing,\n signal?: AbortSignal,\n ): Promise<PluginManifest | undefined> {\n const manifestUrl = listing.release?.manifestUrl\n if (!manifestUrl) return undefined\n const manifest = parsePluginManifest(await this.requestJson(manifestUrl, signal))\n if (manifest.name.id !== listing.id) {\n throw new AwesomeRegistryValidationError(\n `listing ${listing.id} points to manifest for ${manifest.name.id}`,\n )\n }\n return manifest\n }\n\n private async load<T>(\n path: string,\n parse: (value: unknown) => T,\n readCache: () => { data: T; cachedAt: string } | undefined,\n writeCache: (data: T) => string,\n signal?: AbortSignal,\n ): Promise<AwesomeRegistryResult<T>> {\n let payload: unknown\n try {\n payload = await this.requestJson(new URL(path, this.baseUrl).href, signal)\n } catch (error) {\n if (signal?.aborted) throw signal.reason\n if (error instanceof AwesomeRegistryValidationError || error instanceof SyntaxError)\n throw error\n const cached = readCache()\n if (cached) {\n marketplaceLogger.warn('marketplace request failed; using stale cache', { path }, error)\n return { ...cached, stale: true }\n }\n marketplaceLogger.error('marketplace request failed without cache', { path }, error)\n throw new AwesomeRegistryNetworkError(`Failed to request awesome-plugins ${path}`, error)\n }\n const data = parse(payload)\n marketplaceLogger.debug('marketplace response cached', { path })\n return { cachedAt: writeCache(data), data, stale: false }\n }\n}","import { useConfig as useDbConfig } from '@delta-comic/db'\nimport type { FormDefaultValue, FormResult } from '@delta-comic/model'\nimport { shallowReactive, type Ref } from 'vue'\n\nimport type { ConfigPointer, UnwrapConfigPointer } from '../api'\n\nexport type ConfigSave<T extends ConfigPointer = ConfigPointer> = {\n form: UnwrapConfigPointer<T>\n data: Ref<FormResult<T['config']>>\n name: string\n ready: Promise<void>\n}\n\ntype StoredConfigSave = {\n data: Ref<Record<string, FormDefaultValue[keyof FormDefaultValue]>>\n form: ConfigPointer['config']\n name: string\n ready: Promise<void>\n}\n\nexport type PluginConfigLoader = <T extends ConfigPointer>(pointer: T) => ConfigSave<T>\n\nconst loadDatabaseConfig: PluginConfigLoader = pointer => {\n const store = useDbConfig(pointer.pluginName, pointer.config)\n return { data: store as any, form: pointer.config, name: pointer.configName, ready: store.ready }\n}\n\nexport class ConfigStore {\n private readonly entries = shallowReactive(new Map<symbol, StoredConfigSave>())\n private readonly pointers = new Map<string, ConfigPointer>()\n private readonly isSystemDark =\n globalThis.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false\n\n public constructor(private readonly loadConfig: PluginConfigLoader = loadDatabaseConfig) {}\n\n public get form(): ReadonlyMap<symbol, StoredConfigSave> {\n return this.entries\n }\n\n public get isDark() {\n const pointer = this.pointers.get('core')\n if (!pointer) return this.isSystemDark\n const mode = (this.load(pointer).data.value as { darkMode?: string }).darkMode\n if (mode === 'light') return false\n if (mode === 'dark') return true\n return this.isSystemDark\n }\n\n public load<T extends ConfigPointer>(pointer: T): ConfigSave<T> {\n const value = this.entries.get(pointer.key)\n if (!value) throw new Error(`not found config by plugin \"${pointer.pluginName}\"`)\n return value as ConfigSave<T>\n }\n\n public has(pointer: ConfigPointer) {\n return this.entries.has(pointer.key)\n }\n\n public register<T extends ConfigPointer>(pointer: T) {\n const registered = this.entries.get(pointer.key)\n const ownerPointer = this.pointers.get(pointer.pluginName)\n if (registered && ownerPointer === pointer) return registered as ConfigSave<T>\n if (ownerPointer) {\n throw new Error(`plugin \"${pointer.pluginName}\" can only register one config`)\n }\n\n const saved = this.loadConfig(pointer)\n this.entries.set(pointer.key, saved as StoredConfigSave)\n this.pointers.set(pointer.pluginName, pointer)\n return saved\n }\n\n public unregister(pointer: ConfigPointer) {\n if (this.pointers.get(pointer.pluginName) !== pointer) return\n this.pointers.delete(pointer.pluginName)\n this.entries.delete(pointer.key)\n }\n}","import type { PluginCandidate, PluginCandidateProvider } from '../kernel'\n\nimport type { PluginArchiveRepository, PluginModuleReader } from './contracts'\n\n/** Normalize persisted archives into the same candidate protocol used by internal plugins. */\nexport class InstalledPluginCandidateProvider implements PluginCandidateProvider {\n public readonly id = 'installed'\n\n public constructor(\n private readonly repository: PluginArchiveRepository,\n private readonly reader: PluginModuleReader,\n ) {}\n\n public async list(signal: AbortSignal): Promise<PluginCandidate[]> {\n const archives = await this.repository.list()\n signal.throwIfAborted()\n return archives.map(archive => ({\n enabled: archive.enable,\n load: async loadSignal =>\n await this.reader.read(archive.pluginName, archive.meta, loadSignal),\n management: {\n canDisable: true,\n canUninstall: true,\n canUpdate: archive.installInput.length > 0,\n },\n manifest: archive.meta,\n origin: 'installed',\n }))\n }\n}","import type { PluginManifest } from '@delta-comic/model'\n\nexport type PluginCatalogSource =\n | { readonly type: 'github'; readonly repository: string }\n | { readonly type: 'url'; readonly url: string }\n\nexport interface PluginCatalogRepository {\n readonly defaultBranch: string\n readonly lastCommitAt: string\n readonly name: string\n readonly owner: string\n readonly readmeUrl?: string\n readonly url: string\n}\n\nexport interface PluginCatalogRelease {\n readonly manifestUrl: string | null\n readonly publishedAt: string\n readonly url: string\n readonly version: string\n}\n\nexport interface PluginCatalogListing {\n readonly authors: readonly string[]\n readonly id: string\n readonly release?: PluginCatalogRelease\n readonly repository?: PluginCatalogRepository\n readonly source: PluginCatalogSource\n}\n\nexport interface PluginCatalogPageReference {\n readonly items: number\n readonly page: number\n readonly path: string\n}\n\nexport interface PluginCatalogIndex {\n readonly pageSize: number\n readonly pages: readonly PluginCatalogPageReference[]\n readonly totalItems: number\n readonly totalPages: number\n}\n\nexport interface PluginCatalogPagination {\n readonly next: string | null\n readonly page: number\n readonly pageSize: number\n readonly previous: string | null\n readonly totalItems: number\n readonly totalPages: number\n}\n\nexport interface PluginCatalogPage {\n readonly items: readonly PluginCatalogListing[]\n readonly pagination: PluginCatalogPagination\n}\n\nexport interface PluginCatalogResult<T> {\n readonly cachedAt: string\n readonly data: T\n readonly stale: boolean\n}\n\n/** The narrow catalog port required by an install source resolver. */\nexport interface PluginInstallCatalog {\n resolveInstallInput(plugin: string, signal: AbortSignal): Promise<string>\n}\n\n/** Host-facing catalog operations used by the marketplace feature. */\nexport interface PluginCatalog extends PluginInstallCatalog {\n loadIndex(signal?: AbortSignal): Promise<PluginCatalogResult<PluginCatalogIndex>>\n loadManifest(\n listing: PluginCatalogListing,\n signal?: AbortSignal,\n ): Promise<PluginManifest | undefined>\n loadPage(path: string, signal?: AbortSignal): Promise<PluginCatalogResult<PluginCatalogPage>>\n}\n\nconst catalogInstallInputPattern = /^ap:([A-Za-z0-9][A-Za-z0-9_-]{0,63})$/\n\nexport const pluginCatalogInstallInput = (plugin: string) => {\n const input = `ap:${plugin}`\n if (!catalogInstallInputPattern.test(input)) {\n throw new TypeError(`invalid plugin catalog id: ${plugin}`)\n }\n return input\n}\n\nexport const pluginCatalogIdFromInstallInput = (input: unknown) =>\n typeof input === 'string' ? catalogInstallInputPattern.exec(input)?.[1] : undefined","import type { PluginManifest } from '@delta-comic/model'\nimport JSZip from 'jszip'\n\nimport type { DecodedPluginPackage, PluginPackageCodec } from './contracts'\nimport { parsePluginManifest, safePluginPath } from './manifest'\n\nconst sha256 = async (bytes: Uint8Array) => {\n const digest = await globalThis.crypto.subtle.digest('SHA-256', Uint8Array.from(bytes).buffer)\n return [...new Uint8Array(digest)].map(value => value.toString(16).padStart(2, '0')).join('')\n}\n\nconst withIntegrity = async (manifest: PluginManifest, bytes: Uint8Array) => ({\n ...manifest,\n integrity: { algorithm: 'sha256' as const, digest: await sha256(bytes) },\n})\n\nexport class ZipPackageCodec implements PluginPackageCodec {\n public readonly id = 'zip'\n\n public matches(file: File) {\n return file.name.toLowerCase().endsWith('.zip') || file.type === 'application/zip'\n }\n\n public async decode(file: File, signal: AbortSignal): Promise<DecodedPluginPackage> {\n const bytes = new Uint8Array(await file.arrayBuffer())\n if (signal.aborted) throw signal.reason\n const archive = await JSZip.loadAsync(bytes)\n const manifestFile = archive.file('manifest.json')\n if (!manifestFile) throw new Error('plugin archive does not contain manifest.json')\n const manifest = await withIntegrity(\n parsePluginManifest(JSON.parse(await manifestFile.async('text'))),\n bytes,\n )\n const files = new Map<string, Uint8Array>()\n for (const entry of Object.values(archive.files)) {\n if (signal.aborted) throw signal.reason\n if (entry.dir) continue\n const path = safePluginPath(entry.name, `archive entry ${entry.name}`)\n files.set(path, await entry.async('uint8array'))\n }\n return { codecId: this.id, files, manifest }\n }\n}\n\nconst description = '@description'\n\nexport class DevScriptCodec implements PluginPackageCodec {\n public readonly id = 'dev-script'\n\n public matches(file: File) {\n return /\\.(?:js|mjs|user\\.js)$/i.test(file.name)\n }\n\n public async decode(file: File, signal: AbortSignal): Promise<DecodedPluginPackage> {\n const bytes = new Uint8Array(await file.arrayBuffer())\n if (signal.aborted) throw signal.reason\n const code = new TextDecoder().decode(bytes)\n const start = code.indexOf(description)\n if (start < 0) throw new Error('development plugin does not contain @description metadata')\n const [line] = code\n .slice(start + description.length)\n .trimStart()\n .split(/\\r?\\n/, 1)\n const manifest = await withIntegrity(parsePluginManifest(JSON.parse(line)), bytes)\n return {\n codecId: this.id,\n files: new Map([['index.mjs', bytes]]),\n manifest: { ...manifest, entry: { ...manifest.entry, jsPath: 'index.mjs' } },\n }\n }\n}","import type { PluginConfigFactory, PluginManifest } from '../api'\nimport type { LoadedPluginModule } from '../kernel'\n\nimport type { PluginFileStore, PluginModuleReader } from './contracts'\n\nconst asFactory = (value: unknown, plugin: string): PluginConfigFactory => {\n if (typeof value !== 'function') {\n throw new TypeError(`plugin entry has no default factory: ${plugin}`)\n }\n return value as PluginConfigFactory\n}\n\nexport class StoredPluginModuleReader implements PluginModuleReader {\n public constructor(private readonly files: PluginFileStore) {}\n\n public async read(\n plugin: string,\n manifest: PluginManifest,\n signal: AbortSignal,\n ): Promise<LoadedPluginModule> {\n const entry = manifest.entry?.jsPath ?? 'index.mjs'\n const url = await this.files.createModuleUrl(plugin, entry)\n if (signal.aborted) {\n this.files.release(plugin)\n throw signal.reason\n }\n let style: HTMLStyleElement | undefined\n try {\n const module = (await import(/* @vite-ignore */ url)) as { default?: unknown }\n signal.throwIfAborted()\n if (manifest.entry?.cssPath && typeof document !== 'undefined') {\n style = document.createElement('style')\n style.dataset.plugin = plugin\n style.textContent = new TextDecoder().decode(\n await this.files.read(plugin, manifest.entry.cssPath),\n )\n signal.throwIfAborted()\n document.head.append(style)\n }\n return {\n factory: asFactory(module.default, plugin),\n dispose: () => {\n style?.remove()\n this.files.release(plugin)\n },\n }\n } catch (error) {\n style?.remove()\n this.files.release(plugin)\n throw error\n }\n }\n}","import { db, type PluginArchiveDB } from '@delta-comic/db'\n\nimport type { PluginArchiveRepository } from './contracts'\n\nexport class DatabasePluginArchiveRepository implements PluginArchiveRepository {\n public async find(plugin: string) {\n return await db\n .selectFrom('plugin')\n .selectAll()\n .where('pluginName', '=', plugin)\n .executeTakeFirst()\n }\n\n public async list() {\n return await db.selectFrom('plugin').selectAll().execute()\n }\n\n public async remove(plugin: string) {\n await db.deleteFrom('plugin').where('pluginName', '=', plugin).execute()\n }\n\n public async upsert(archive: PluginArchiveDB.Archive) {\n await db\n .replaceInto('plugin')\n .values({ ...archive, meta: JSON.stringify(archive.meta) })\n .execute()\n }\n}","import type { PluginArchiveDB } from '@delta-comic/db'\n\nimport type {\n PluginArchiveRepository,\n PluginFileStore,\n PluginInstallInput,\n PluginInstallReporter,\n PluginPackageCodec,\n PluginSourceResolver,\n} from './contracts'\n\nexport interface PluginInstallServiceOptions {\n readonly codecs: readonly PluginPackageCodec[]\n readonly files: PluginFileStore\n readonly repository: PluginArchiveRepository\n readonly reservedIds?: ReadonlySet<string>\n readonly resolvers: readonly PluginSourceResolver[]\n}\n\nexport class PluginInstallService {\n public constructor(private readonly options: PluginInstallServiceOptions) {}\n\n public async install(\n input: PluginInstallInput,\n signal = new AbortController().signal,\n report: PluginInstallReporter = () => {},\n ) {\n report({ phase: 'resolve', progress: 0 })\n const resolver = this.options.resolvers.find(candidate => candidate.matches(input))\n if (!resolver) throw new Error('no plugin source resolver accepts this input')\n const source = await resolver.resolve(input, signal)\n report({ description: source.file.name, phase: 'resolve', progress: 100 })\n\n const codec = this.options.codecs.find(candidate => candidate.matches(source.file))\n if (!codec) throw new Error('no plugin package codec accepts this file')\n report({ description: codec.id, phase: 'decode', progress: 0 })\n const decoded = await codec.decode(source.file, signal)\n const plugin = decoded.manifest.name.id\n if (this.options.reservedIds?.has(plugin)) {\n throw new Error(`plugin id \"${plugin}\" is reserved by an internal plugin`)\n }\n report({ description: plugin, phase: 'decode', progress: 100 })\n\n const previous = await this.options.repository.find(plugin)\n const replacement = await this.options.files.replace(plugin, decoded.files)\n const archive: PluginArchiveDB.Archive = {\n displayName: decoded.manifest.name.display,\n enable: previous?.enable ?? true,\n installerName: source.resolverId,\n installInput: source.installInput,\n loaderName: decoded.codecId,\n meta: decoded.manifest,\n pluginName: plugin,\n }\n\n try {\n report({ description: plugin, phase: 'persist', progress: 50 })\n await this.options.repository.upsert(archive)\n await replacement.commit()\n report({ description: plugin, phase: 'persist', progress: 100 })\n return archive\n } catch (error) {\n const rollbackErrors: unknown[] = []\n try {\n await replacement.rollback()\n } catch (rollbackError) {\n rollbackErrors.push(rollbackError)\n }\n try {\n if (previous) await this.options.repository.upsert(previous)\n else await this.options.repository.remove(plugin)\n } catch (rollbackError) {\n rollbackErrors.push(rollbackError)\n }\n if (rollbackErrors.length > 0) {\n throw new AggregateError([error, ...rollbackErrors], `failed to install plugin \"${plugin}\"`)\n }\n throw error\n }\n }\n\n /** Remove archive metadata and files as one compensating transaction. */\n public async uninstall(plugin: string) {\n const previous = await this.options.repository.find(plugin)\n const replacement = await this.options.files.replace(plugin, new Map())\n try {\n await this.options.repository.remove(plugin)\n await replacement.commit()\n } catch (error) {\n const rollbackErrors: unknown[] = []\n try {\n await replacement.rollback()\n } catch (rollbackError) {\n rollbackErrors.push(rollbackError)\n }\n try {\n if (previous) await this.options.repository.upsert(previous)\n } catch (rollbackError) {\n rollbackErrors.push(rollbackError)\n }\n if (rollbackErrors.length > 0) {\n throw new AggregateError(\n [error, ...rollbackErrors],\n `failed to uninstall plugin \"${plugin}\"`,\n )\n }\n throw error\n }\n }\n}","import { Octokit } from '@octokit/rest'\n\nimport { pluginCatalogIdFromInstallInput, type PluginInstallCatalog } from './catalog'\nimport type { PluginInstallInput, PluginSourceResolver, ResolvedPluginSource } from './contracts'\nimport { isPluginManifestCompatible, parsePluginManifest } from './manifest'\n\nexport class LocalFileSourceResolver implements PluginSourceResolver {\n public readonly id = 'local-file'\n\n public matches(input: PluginInstallInput): input is File {\n return typeof input !== 'string'\n }\n\n public async resolve(input: PluginInstallInput): Promise<ResolvedPluginSource> {\n if (typeof input === 'string') throw new TypeError('local file resolver requires a File')\n return { file: input, installInput: '', resolverId: this.id }\n }\n}\n\nexport class HttpSourceResolver implements PluginSourceResolver {\n public readonly id = 'http'\n\n public matches(input: PluginInstallInput): input is string {\n return typeof input === 'string' && /^https?:\\/\\//i.test(input)\n }\n\n public async resolve(\n input: PluginInstallInput,\n signal: AbortSignal,\n ): Promise<ResolvedPluginSource> {\n if (typeof input !== 'string') throw new TypeError('HTTP resolver requires a URL')\n const response = await fetch(input, { signal })\n if (!response.ok) throw new Error(`plugin download failed: ${response.status}`)\n const name = new URL(input).pathname.split('/').at(-1) || 'plugin.zip'\n return {\n file: new File([await response.blob()], name),\n installInput: input,\n resolverId: this.id,\n }\n }\n}\n\nexport interface GitHubSourceResolverOptions {\n readonly coreVersion: string\n readonly token?: string\n}\n\nexport class GitHubSourceResolver implements PluginSourceResolver {\n public readonly id = 'github'\n\n public constructor(private readonly options: GitHubSourceResolverOptions) {}\n\n public matches(input: PluginInstallInput): input is string {\n return typeof input === 'string' && /^gh:[^/]+\\/[^/]+$/.test(input)\n }\n\n public async resolve(input: PluginInstallInput, signal: AbortSignal) {\n if (typeof input !== 'string') throw new TypeError('GitHub resolver requires a repository')\n const [owner, repo] = input.slice(3).split('/') as [string, string]\n const octokit = new Octokit({ auth: this.options.token })\n const pages = octokit.paginate.iterator(octokit.rest.repos.listReleases, {\n owner,\n per_page: 100,\n repo,\n request: { signal },\n })\n for await (const page of pages) {\n for (const release of page.data) {\n if (release.draft || release.prerelease) continue\n const manifestAsset = release.assets.find(asset => asset.name === 'manifest.json')\n const packageAsset = release.assets.find(asset => asset.name === 'plugin.zip')\n if (!manifestAsset || !packageAsset) continue\n const manifestResponse = await fetch(manifestAsset.browser_download_url, { signal })\n if (!manifestResponse.ok) continue\n const manifest = parsePluginManifest(await manifestResponse.json())\n if (!isPluginManifestCompatible(manifest, this.options.coreVersion)) continue\n const packageResponse = await fetch(packageAsset.browser_download_url, { signal })\n if (!packageResponse.ok)\n throw new Error(`plugin download failed: ${packageResponse.status}`)\n return {\n file: new File([await packageResponse.blob()], packageAsset.name),\n installInput: input,\n resolverId: this.id,\n }\n }\n }\n throw new Error(`no compatible plugin release found for ${owner}/${repo}`)\n }\n}\n\nexport class MarketplaceSourceResolver implements PluginSourceResolver {\n public readonly id = 'marketplace'\n\n public constructor(\n private readonly catalog: PluginInstallCatalog,\n private readonly sources: readonly PluginSourceResolver[],\n ) {}\n\n public matches(input: PluginInstallInput): input is string {\n return pluginCatalogIdFromInstallInput(input) !== undefined\n }\n\n public async resolve(input: PluginInstallInput, signal: AbortSignal) {\n if (typeof input !== 'string') {\n throw new TypeError('marketplace resolver requires a plugin catalog id')\n }\n const plugin = pluginCatalogIdFromInstallInput(input)\n if (!plugin) throw new TypeError('marketplace resolver requires a plugin catalog id')\n const redirected = await this.catalog.resolveInstallInput(plugin, signal)\n const resolver = this.sources.find(source => source.matches(redirected))\n if (!resolver)\n throw new Error(`plugin catalog returned an unsupported install source: ${redirected}`)\n const source = await resolver.resolve(redirected, signal)\n return { ...source, installInput: input, resolverId: this.id }\n }\n}","import { isTauri } from '@tauri-apps/api/core'\n\nimport type { PluginFileReplacement, PluginFileStore } from '../install'\nimport { safePluginPath } from '../install'\n\ntype PluginFiles = ReadonlyMap<string, Uint8Array>\n\ninterface PluginFileBackend {\n read(plugin: string, path: string): Promise<Uint8Array>\n snapshot(plugin: string): Promise<Map<string, Uint8Array>>\n replace(plugin: string, files: PluginFiles): Promise<void>\n moduleUrl?(plugin: string, path: string): Promise<string>\n}\n\nconst cloneFiles = (files: PluginFiles) =>\n new Map([...files].map(([path, bytes]) => [path, Uint8Array.from(bytes)]))\n\nconst mimeType = (path: string) =>\n ({\n avif: 'image/avif',\n gif: 'image/gif',\n jpeg: 'image/jpeg',\n jpg: 'image/jpeg',\n png: 'image/png',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n })[path.split('.').at(-1)?.toLowerCase() ?? ''] ?? 'application/octet-stream'\n\nexport class MemoryPluginFileStore implements PluginFileStore {\n readonly #files = new Map<string, Map<string, Uint8Array>>()\n readonly #urls = new Map<string, Set<string>>()\n\n public async replace(plugin: string, files: PluginFiles): Promise<PluginFileReplacement> {\n const previous = cloneFiles(this.#files.get(plugin) ?? new Map())\n this.#files.set(plugin, cloneFiles(files))\n let settled = false\n return {\n commit: async () => {\n settled = true\n },\n rollback: async () => {\n if (settled) return\n settled = true\n this.#files.set(plugin, previous)\n },\n }\n }\n\n public async remove(plugin: string) {\n this.release(plugin)\n this.#files.delete(plugin)\n }\n\n public async read(plugin: string, path: string) {\n const bytes = this.#files.get(plugin)?.get(safePluginPath(path, 'plugin file path'))\n if (!bytes) throw new Error(`plugin file not found: ${plugin}/${path}`)\n return Uint8Array.from(bytes)\n }\n\n public async createModuleUrl(plugin: string, path: string) {\n return await this.#createUrl(plugin, path, 'text/javascript')\n }\n\n public async createAssetUrl(plugin: string, path: string) {\n return await this.#createUrl(plugin, path, mimeType(path))\n }\n\n async #createUrl(plugin: string, path: string, type: string) {\n const bytes = await this.read(plugin, path)\n const url = URL.createObjectURL(new Blob([Uint8Array.from(bytes)], { type }))\n const urls = this.#urls.get(plugin) ?? new Set<string>()\n urls.add(url)\n this.#urls.set(plugin, urls)\n return url\n }\n\n public release(plugin: string) {\n for (const url of this.#urls.get(plugin) ?? []) URL.revokeObjectURL(url)\n this.#urls.delete(plugin)\n }\n}\n\nclass IndexedDbPluginFileBackend implements PluginFileBackend {\n readonly #database = 'delta-comic-plugin-files-v2'\n readonly #store = 'files'\n\n async #open() {\n return await new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(this.#database, 1)\n request.onupgradeneeded = () => {\n if (!request.result.objectStoreNames.contains(this.#store)) {\n request.result.createObjectStore(this.#store)\n }\n }\n request.onsuccess = () => resolve(request.result)\n request.onerror = () => reject(request.error)\n })\n }\n\n #key(plugin: string, path: string) {\n return `${plugin}/${path}`\n }\n\n public async read(plugin: string, path: string) {\n const database = await this.#open()\n try {\n return await new Promise<Uint8Array>((resolve, reject) => {\n const transaction = database.transaction(this.#store, 'readonly')\n const request = transaction.objectStore(this.#store).get(this.#key(plugin, path))\n request.onsuccess = () => {\n if (!request.result) reject(new Error(`plugin file not found: ${plugin}/${path}`))\n else resolve(Uint8Array.from(request.result as Uint8Array))\n }\n request.onerror = () => reject(request.error)\n })\n } finally {\n database.close()\n }\n }\n\n public async snapshot(plugin: string) {\n const database = await this.#open()\n try {\n return await new Promise<Map<string, Uint8Array>>((resolve, reject) => {\n const files = new Map<string, Uint8Array>()\n const transaction = database.transaction(this.#store, 'readonly')\n const request = transaction.objectStore(this.#store).openCursor()\n const prefix = `${plugin}/`\n request.onsuccess = () => {\n const cursor = request.result\n if (!cursor) return\n const key = String(cursor.key)\n if (key.startsWith(prefix))\n files.set(key.slice(prefix.length), Uint8Array.from(cursor.value))\n cursor.continue()\n }\n request.onerror = () => reject(request.error)\n transaction.oncomplete = () => resolve(files)\n transaction.onerror = () => reject(transaction.error)\n })\n } finally {\n database.close()\n }\n }\n\n public async replace(plugin: string, files: PluginFiles) {\n const database = await this.#open()\n try {\n await new Promise<void>((resolve, reject) => {\n const transaction = database.transaction(this.#store, 'readwrite')\n const store = transaction.objectStore(this.#store)\n const prefix = `${plugin}/`\n const cursor = store.openKeyCursor()\n cursor.onsuccess = () => {\n if (cursor.result) {\n if (String(cursor.result.key).startsWith(prefix)) cursor.result.delete()\n cursor.result.continue()\n return\n }\n for (const [path, bytes] of files) store.put(bytes, this.#key(plugin, path))\n }\n cursor.onerror = () => reject(cursor.error)\n transaction.oncomplete = () => resolve()\n transaction.onerror = () => reject(transaction.error)\n transaction.onabort = () => reject(transaction.error)\n })\n } finally {\n database.close()\n }\n }\n}\n\nclass TauriPluginFileBackend implements PluginFileBackend {\n async #root(plugin: string) {\n const { appLocalDataDir, join } = await import('@tauri-apps/api/path')\n return await join(await appLocalDataDir(), 'plugin', plugin)\n }\n\n public async read(plugin: string, path: string) {\n const [{ join }, fs] = await Promise.all([\n import('@tauri-apps/api/path'),\n import('@tauri-apps/plugin-fs'),\n ])\n return await fs.readFile(await join(await this.#root(plugin), path))\n }\n\n public async snapshot(plugin: string) {\n const [{ join }, fs] = await Promise.all([\n import('@tauri-apps/api/path'),\n import('@tauri-apps/plugin-fs'),\n ])\n const root = await this.#root(plugin)\n const files = new Map<string, Uint8Array>()\n if (!(await fs.exists(root))) return files\n const visit = async (directory: string, prefix = '') => {\n for (const entry of await fs.readDir(directory)) {\n const path = prefix ? `${prefix}/${entry.name}` : entry.name\n const absolute = await join(directory, entry.name)\n if (entry.isDirectory) await visit(absolute, path)\n else if (entry.isFile) files.set(path, await fs.readFile(absolute))\n }\n }\n await visit(root)\n return files\n }\n\n public async replace(plugin: string, files: PluginFiles) {\n const [{ appLocalDataDir, join }, fs] = await Promise.all([\n import('@tauri-apps/api/path'),\n import('@tauri-apps/plugin-fs'),\n ])\n const appData = await appLocalDataDir()\n const base = await join(appData, 'plugin')\n const token = crypto.randomUUID()\n const live = await join(base, plugin)\n const stagingRoot = await join(appData, 'plugin-staging')\n const backupRoot = await join(appData, 'plugin-backup')\n const staging = await join(stagingRoot, `${plugin}-${token}`)\n const backup = await join(backupRoot, `${plugin}-${token}`)\n await fs.mkdir(staging, { recursive: true })\n try {\n for (const [path, bytes] of files) {\n const segments = safePluginPath(path, 'plugin file path').split('/')\n const target = await join(staging, ...segments)\n const parent = await join(staging, ...segments.slice(0, -1))\n await fs.mkdir(parent, { recursive: true })\n await fs.writeFile(target, bytes)\n }\n const existed = await fs.exists(live)\n if (existed) {\n await fs.mkdir(backupRoot, { recursive: true })\n await fs.rename(live, backup)\n }\n try {\n await fs.rename(staging, live)\n } catch (error) {\n if (existed && (await fs.exists(backup))) await fs.rename(backup, live)\n throw error\n }\n if (await fs.exists(backup)) {\n await fs.remove(backup, { recursive: true }).catch(() => undefined)\n }\n } catch (error) {\n if (await fs.exists(staging)) await fs.remove(staging, { recursive: true })\n throw error\n }\n }\n\n public async moduleUrl(plugin: string, path: string) {\n const { convertFileSrc } = await import('@tauri-apps/api/core')\n const { join } = await import('@tauri-apps/api/path')\n return convertFileSrc(await join(await this.#root(plugin), path))\n }\n}\n\nexport class AtomicPluginFileStore implements PluginFileStore {\n readonly #urls = new Map<string, Set<string>>()\n\n public constructor(private readonly backend: PluginFileBackend) {}\n\n public async replace(plugin: string, files: PluginFiles) {\n const previous = await this.backend.snapshot(plugin)\n await this.backend.replace(plugin, files)\n let settled = false\n return {\n commit: async () => {\n settled = true\n },\n rollback: async () => {\n if (settled) return\n settled = true\n await this.backend.replace(plugin, previous)\n },\n }\n }\n\n public async remove(plugin: string) {\n this.release(plugin)\n await this.backend.replace(plugin, new Map())\n }\n\n public read(plugin: string, path: string) {\n return this.backend.read(plugin, safePluginPath(path, 'plugin file path'))\n }\n\n public async createModuleUrl(plugin: string, path: string) {\n const safePath = safePluginPath(path, 'plugin module path')\n if (this.backend.moduleUrl) return await this.backend.moduleUrl(plugin, safePath)\n const bytes = await this.backend.read(plugin, safePath)\n const url = URL.createObjectURL(new Blob([Uint8Array.from(bytes)], { type: 'text/javascript' }))\n const urls = this.#urls.get(plugin) ?? new Set<string>()\n urls.add(url)\n this.#urls.set(plugin, urls)\n return url\n }\n\n public async createAssetUrl(plugin: string, path: string) {\n const safePath = safePluginPath(path, 'plugin asset path')\n if (this.backend.moduleUrl) return await this.backend.moduleUrl(plugin, safePath)\n const bytes = await this.backend.read(plugin, safePath)\n const url = URL.createObjectURL(new Blob([Uint8Array.from(bytes)], { type: mimeType(path) }))\n const urls = this.#urls.get(plugin) ?? new Set<string>()\n urls.add(url)\n this.#urls.set(plugin, urls)\n return url\n }\n\n public release(plugin: string) {\n for (const url of this.#urls.get(plugin) ?? []) URL.revokeObjectURL(url)\n this.#urls.delete(plugin)\n }\n}\n\nexport const createDefaultPluginFileStore = () =>\n new AtomicPluginFileStore(\n isTauri() ? new TauriPluginFileBackend() : new IndexedDbPluginFileBackend(),\n )","import type { PluginLocaleMessage, PluginLocaleMessages } from '../api/i18n'\n\nexport type { PluginLocaleMessage, PluginLocaleMessages } from '../api/i18n'\n\nexport interface PluginI18nAdapter {\n setLocaleMessage(locale: string, message: PluginLocaleMessage): void\n translate?(key: string, params?: Record<string, number | string>): string\n}\n\nconst messageKeyPrefix = 'i18n:'\n\nconst unsafeKeys = new Set(['__proto__', 'constructor', 'prototype'])\n\nconst mergeMessages = (\n target: PluginLocaleMessage,\n source: PluginLocaleMessage | undefined,\n): PluginLocaleMessage => {\n if (!source) return target\n for (const [key, value] of Object.entries(source)) {\n if (unsafeKeys.has(key)) continue\n if (typeof value === 'string') {\n target[key] = value\n continue\n }\n const current = target[key]\n target[key] = mergeMessages(typeof current === 'object' ? { ...current } : {}, value)\n }\n return target\n}\n\nexport class PluginI18nRegistry {\n private adapter?: PluginI18nAdapter\n private baseMessages: PluginLocaleMessages = {}\n private readonly pluginMessages = new Map<string, PluginLocaleMessages>()\n\n public install(adapter: PluginI18nAdapter, baseMessages: PluginLocaleMessages) {\n this.adapter = adapter\n this.baseMessages = baseMessages\n this.refresh(this.locales())\n }\n\n public register(plugin: string, messages: PluginLocaleMessages) {\n const previous = this.pluginMessages.get(plugin)\n this.pluginMessages.delete(plugin)\n this.pluginMessages.set(plugin, messages)\n this.refresh(new Set([...Object.keys(previous ?? {}), ...Object.keys(messages)]))\n }\n\n public remove(plugin: string) {\n const messages = this.pluginMessages.get(plugin)\n if (!messages) return\n this.pluginMessages.delete(plugin)\n this.refresh(new Set(Object.keys(messages)))\n }\n\n public translate(key: string, params?: Record<string, number | string>) {\n return this.adapter?.translate?.(key, params) ?? key\n }\n\n private compose(locale: string) {\n const message = mergeMessages({}, this.baseMessages[locale])\n for (const messages of this.pluginMessages.values()) mergeMessages(message, messages[locale])\n return message\n }\n\n private locales() {\n const locales = new Set(Object.keys(this.baseMessages))\n for (const messages of this.pluginMessages.values()) {\n for (const locale of Object.keys(messages)) locales.add(locale)\n }\n return locales\n }\n\n private refresh(locales: Iterable<string>) {\n if (!this.adapter) return\n for (const locale of locales) this.adapter.setLocaleMessage(locale, this.compose(locale))\n }\n}\n\nexport const pluginI18n = new PluginI18nRegistry()\n\nexport const pluginMessageKey = (key: string) => `${messageKeyPrefix}${key}`\n\nexport const translatePluginText = (value: string) =>\n value.startsWith(messageKeyPrefix)\n ? pluginI18n.translate(value.slice(messageKeyPrefix.length))\n : value","","export const pluginName = 'core'","import { ConfigPointer } from '../api/config'\n\nimport { pluginName } from './env'\n\nexport const cfg = new ConfigPointer(\n pluginName,\n {\n recordHistory: { type: 'switch', defaultValue: true, info: 'plugin.core.config.recordHistory' },\n showAIProject: { type: 'switch', defaultValue: true, info: 'plugin.core.config.showAiWorks' },\n darkMode: {\n type: 'radio',\n defaultValue: 'system',\n info: 'plugin.core.config.theme.title',\n comp: 'select',\n selects: [\n { label: 'plugin.core.config.theme.light', value: 'light' },\n { label: 'plugin.core.config.theme.dark', value: 'dark' },\n { label: 'plugin.core.config.systemDefault', value: 'system' },\n ],\n },\n language: {\n type: 'radio',\n defaultValue: 'system',\n info: 'plugin.core.config.language.title',\n comp: 'select',\n selects: [\n { label: 'plugin.core.config.language.zhCN', value: 'zh-CN' },\n { label: 'plugin.core.config.language.zhTW', value: 'zh-TW' },\n { label: 'plugin.core.config.language.enUS', value: 'en-US' },\n { label: 'plugin.core.config.systemDefault', value: 'system' },\n ],\n },\n easilyTitle: {\n type: 'switch',\n defaultValue: false,\n info: 'plugin.core.config.simplifiedTitle',\n },\n githubToken: {\n type: 'string',\n defaultValue: '',\n info: 'plugin.core.config.githubToken.title',\n placeholder: 'plugin.core.config.githubToken.placeholder',\n },\n receivePerReleaseUpdate: {\n type: 'switch',\n defaultValue: false,\n info: 'plugin.core.config.prereleaseUpdates',\n },\n cloudEnabled: { type: 'switch', defaultValue: false, info: 'plugin.core.config.cloud.enabled' },\n cloudServerUrl: {\n type: 'string',\n defaultValue: '',\n info: 'plugin.core.config.cloud.serverUrl',\n placeholder: 'plugin.core.config.cloud.serverUrlPlaceholder',\n },\n installOverride: {\n type: 'pairs',\n defaultValue: [],\n info: 'plugin.core.config.installOverride',\n required: true,\n },\n },\n 'plugin.core.config.name',\n)","import { UniContentPage } from '@delta-comic/model'\nimport { SharedFunction } from '@delta-comic/utils'\nimport { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from 'lz-string'\n\nimport { pluginI18n, pluginMessageKey } from '../adapters'\nimport type { Social } from '../api'\n\ninterface CorePluginTokenShareMeta {\n item: { name: string; contentType: string; ep: string }\n plugin: string\n id: string\n}\n\nexport const tokenInit: Social.InitiativeItem = {\n filter: page => !!page.preload,\n icon: {},\n key: 'token',\n name: pluginMessageKey('plugin.share.copyToken'),\n async call(page) {\n const item = page.preload?.toJSON()\n if (!item) throw new Error('Not found preload in content. Maybe not fetch detail?')\n\n const compressed = compressToEncodedURIComponent(\n JSON.stringify(<CorePluginTokenShareMeta>{\n item: {\n contentType: UniContentPage.contentPages.key.toString(item.contentType),\n ep: item.thisEp.id,\n name: item.title,\n },\n plugin: page.plugin,\n id: page.id,\n }),\n )\n return { token: `[${item.title}](复制这条口令,打开Delta Comic)${compressed}` }\n },\n}\n\nexport const nativeInit: Social.InitiativeItem = {\n filter: page => !!page.preload,\n icon: {},\n key: 'native',\n name: pluginMessageKey('plugin.share.native'),\n async call(page) {\n const item = page.preload?.toJSON()\n if (!item) throw new Error('Not found preload in content. Maybe not fetch detail?')\n\n const compressed = compressToEncodedURIComponent(\n JSON.stringify(<CorePluginTokenShareMeta>{\n item: {\n contentType: UniContentPage.contentPages.key.toString(item.contentType),\n ep: item.thisEp.id,\n name: item.title,\n },\n plugin: page.plugin,\n id: page.id,\n }),\n )\n const token = `[${item.title}](复制这条口令,打开Delta Comic)${compressed}`\n await navigator.share({ title: pluginI18n.translate('plugin.share.nativeTitle'), text: token })\n\n return { token }\n },\n}\n\nexport const tokenShare: Social.ShareToken = {\n key: 'token',\n name: pluginMessageKey('plugin.share.defaultToken'),\n isMatched(chipboard) {\n return /^\\[.+\\]\\(复制这条口令,打开Delta Comic\\).+/.test(chipboard)\n },\n async show(chipboard) {\n // const pluginStore = usePluginStore()\n const meta: CorePluginTokenShareMeta = JSON.parse(\n decompressFromEncodedURIComponent(\n chipboard.replace(/^\\[.+\\]/, '').replaceAll('(复制这条口令,打开Delta Comic)', ''),\n ),\n )\n return {\n title: pluginI18n.translate('plugin.share.tokenTitle'),\n detail: pluginI18n.translate('plugin.share.tokenDetail', { item: meta.item.name }),\n onNegative() {},\n onPositive() {\n return SharedFunction.call(\n 'routeToContent',\n UniContentPage.contentPages.key.toJSON(meta.item.contentType),\n meta.id,\n meta.item.ep,\n )\n },\n }\n },\n}","import { defineDeltaComicPlugin } from '../api'\n\nimport { cfg } from './config'\nexport { cfg } from './config'\n\nimport { pluginName } from './env'\nimport { tokenInit, nativeInit, tokenShare } from './share'\n\nexport default defineDeltaComicPlugin(() => ({\n config: cfg,\n name: pluginName,\n model: { social: { share: { initiative: [tokenInit, nativeInit], tokenListen: [tokenShare] } } },\n}))","import pkg from '../../package.json'\nimport { DELTA_COMIC_PLUGIN_API_VERSION } from '../api'\nimport CorePlugin from '../core'\nimport { defineInternalPlugin } from '../kernel'\n\nexport const corePluginDefinition = defineInternalPlugin({\n canDisable: false,\n factory: CorePlugin,\n manifest: {\n apiVersion: DELTA_COMIC_PLUGIN_API_VERSION,\n author: 'Delta Comic',\n description: 'Delta Comic host capabilities',\n kind: 'preboot',\n name: { display: 'core', id: 'core' },\n require: [],\n version: { plugin: pkg.version, supportCore: '*' },\n },\n})\n\nexport default corePluginDefinition","import type { InternalPluginDefinition } from '../kernel'\n\nexport * from './core.builtin'\n\nconst builtinModules = import.meta.glob<{ default: InternalPluginDefinition }>('./*.builtin.ts', {\n eager: true,\n})\n\n/** Files are the registration boundary: adding a built-in does not change the composition root. */\nexport const internalPluginDefinitions = Object.entries(builtinModules)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([path, module]) => {\n if (!module.default)\n throw new Error(`built-in plugin module has no default definition: ${path}`)\n return module.default\n })","import { shallowReactive, type Raw } from 'vue'\n\nimport type { DCPluginConfig } from '../api'\nimport type { PluginCandidate } from '../kernel'\n\nexport class PluginStore {\n private readonly candidateEntries = shallowReactive(new Map<string, PluginCandidate>())\n private readonly loadingEntries = shallowReactive(new Map<string, Raw<DCPluginConfig>>())\n private readonly pluginEntries = shallowReactive(new Map<string, Raw<DCPluginConfig>>())\n private readonly readyEntries = shallowReactive(new Set<string>())\n\n public constructor(private readonly translateText: (value: string) => string = value => value) {}\n\n public get candidates(): ReadonlyMap<string, PluginCandidate> {\n return this.candidateEntries\n }\n\n public get loading(): ReadonlyMap<string, Raw<DCPluginConfig>> {\n return this.loadingEntries\n }\n\n public get plugins(): ReadonlyMap<string, Raw<DCPluginConfig>> {\n return this.pluginEntries\n }\n\n public get ready(): ReadonlySet<string> {\n return this.readyEntries\n }\n\n public replaceCandidates(candidates: readonly PluginCandidate[]) {\n this.candidateEntries.clear()\n for (const candidate of candidates) {\n this.candidateEntries.set(candidate.manifest.name.id, candidate)\n }\n }\n\n public markLoading(plugin: string, config: Raw<DCPluginConfig>) {\n this.readyEntries.delete(plugin)\n this.loadingEntries.set(plugin, config)\n this.pluginEntries.delete(plugin)\n }\n\n public markReady(plugin: string) {\n const config = this.loadingEntries.get(plugin)\n if (!config) throw new Error(`plugin \"${plugin}\" was not marked as loading`)\n this.loadingEntries.delete(plugin)\n this.pluginEntries.set(plugin, config)\n this.readyEntries.add(plugin)\n }\n\n public markUnloaded(plugin: string) {\n this.readyEntries.delete(plugin)\n this.loadingEntries.delete(plugin)\n this.pluginEntries.delete(plugin)\n }\n\n public isLoaded(plugin: string) {\n return this.readyEntries.has(plugin)\n }\n\n public displayName(plugin: string) {\n return this.translateText(this.candidateEntries.get(plugin)?.manifest.name.display ?? plugin)\n }\n\n public modelEntries<K extends keyof NonNullable<DCPluginConfig['model']>>(key: K) {\n type Model = NonNullable<NonNullable<DCPluginConfig['model']>[K]>\n return [...this.pluginEntries].flatMap(([plugin, config]) => {\n const model = config.model?.[key]\n return model === undefined ? [] : ([[plugin, model]] as [string, Model][])\n })\n }\n}","import { markRaw, ref, type App, type Ref } from 'vue'\n\nimport type { ConfigEnv } from '../api'\nimport {\n ActivationPipeline,\n planPluginDependencies,\n PluginScope,\n type CapabilityModule,\n type PluginCandidate,\n type PluginCandidateProvider,\n} from '../kernel'\n\nimport { PluginStore } from './store'\n\nexport interface PluginLoadingInfo {\n progress: {\n errorReason?: string\n status: 'done' | 'error' | 'process' | 'wait'\n stepsIndex: number\n }\n steps: { description: string; name: string }[]\n}\n\nexport interface PluginRuntimeFailure {\n readonly error: unknown\n readonly phase: 'normal' | 'preboot'\n readonly plugin: string\n}\n\nexport interface PluginRuntimeReport {\n readonly activated: string[]\n readonly failures: PluginRuntimeFailure[]\n}\n\nexport interface PluginRuntimeOperation {\n readonly operation: Promise<PluginRuntimeReport>\n readonly progress: Ref<Record<string, PluginLoadingInfo>>\n}\n\nexport interface LoadNormalOptions {\n readonly pluginNames?: readonly string[]\n}\n\nexport interface PrebootRecovery {\n failedAt: number\n plugins: string[]\n reason: string\n}\n\nexport interface PluginRuntimeOptions {\n readonly capabilities: (phase: 'normal' | 'preboot', app?: App) => readonly CapabilityModule[]\n readonly environment: () => ConfigEnv\n readonly provider: PluginCandidateProvider\n readonly remove: (plugin: string) => Promise<void>\n readonly store?: PluginStore\n}\n\nconst recoveryKey = 'delta-comic:preboot-recovery:v2'\n\nconst errorText = (error: unknown) => (error instanceof Error ? error.message : String(error))\n\nconst loadingInfo = (): PluginLoadingInfo => ({\n progress: { status: 'wait', stepsIndex: 0 },\n steps: [{ description: '', name: 'waiting' }],\n})\n\nexport class PluginRuntime {\n readonly #active = new Map<string, { candidate: PluginCandidate; scope: PluginScope }>()\n readonly #options: PluginRuntimeOptions\n #normalOperation?: Promise<PluginRuntimeReport>\n #prebootOperation?: Promise<PluginRuntimeReport>\n #prebootReport?: PluginRuntimeReport\n\n public readonly store: PluginStore\n\n public constructor(options: PluginRuntimeOptions) {\n this.#options = options\n this.store = options.store ?? new PluginStore()\n }\n\n public get activeNormalPluginNames() {\n return [...this.#active]\n .filter(([, value]) => (value.candidate.manifest.kind ?? 'normal') === 'normal')\n .map(([plugin]) => plugin)\n }\n\n public async preparePreboot(app: App) {\n if (this.#prebootReport) return this.#prebootReport\n if (this.#prebootOperation) return await this.#prebootOperation\n const operation = (async () => {\n const progress = ref<Record<string, PluginLoadingInfo>>({})\n const report = await this.#load('preboot', progress, undefined, app)\n this.#prebootReport = report\n if (report.failures.length > 0) this.#writeRecovery(report.failures)\n return report\n })()\n this.#prebootOperation = operation\n try {\n return await operation\n } finally {\n this.#prebootOperation = undefined\n }\n }\n\n public loadNormal(options: LoadNormalOptions = {}): PluginRuntimeOperation {\n if (this.#normalOperation) throw new Error('normal plugins are already loading')\n if (this.activeNormalPluginNames.length > 0) {\n throw new Error('normal plugins are already active; use reloadNormal()')\n }\n const progress = ref<Record<string, PluginLoadingInfo>>({})\n const operation = this.#load('normal', progress, options.pluginNames)\n this.#track(operation)\n return { operation, progress }\n }\n\n public reloadNormal(options: LoadNormalOptions = {}): PluginRuntimeOperation {\n if (this.#normalOperation) throw new Error('normal plugins are already loading')\n const progress = ref<Record<string, PluginLoadingInfo>>({})\n const operation = (async () => {\n await this.#unload(candidate => (candidate.manifest.kind ?? 'normal') === 'normal')\n return await this.#load('normal', progress, options.pluginNames)\n })()\n this.#track(operation)\n return { operation, progress }\n }\n\n public async uninstall(plugin: string) {\n const candidate = this.store.candidates.get(plugin)\n if (!candidate) throw new Error(`plugin \"${plugin}\" is not a known candidate`)\n if (!candidate.management.canUninstall) {\n throw new Error(`plugin \"${plugin}\" cannot be uninstalled`)\n }\n const active = this.#active.get(plugin)\n if (active) await this.#deactivate(plugin, active.scope)\n else {\n const scope = new PluginScope(plugin)\n try {\n const loaded = await candidate.load(scope.signal)\n if (loaded.dispose) scope.defer(loaded.dispose)\n const config = loaded.factory(this.#options.environment())\n await config.hooks?.onUninstall?.()\n } finally {\n await scope.dispose()\n }\n }\n await this.#options.remove(plugin)\n await this.refreshCandidates()\n }\n\n public async refreshCandidates() {\n const candidates = await this.#options.provider.list(new AbortController().signal)\n this.store.replaceCandidates(candidates)\n return candidates\n }\n\n public readRecovery(): PrebootRecovery | null {\n try {\n const value = globalThis.localStorage?.getItem(recoveryKey)\n return value ? (JSON.parse(value) as PrebootRecovery) : null\n } catch {\n return null\n }\n }\n\n public clearRecovery() {\n globalThis.localStorage?.removeItem(recoveryKey)\n }\n\n async #load(\n phase: 'normal' | 'preboot',\n progress: Ref<Record<string, PluginLoadingInfo>>,\n selected?: readonly string[],\n app?: App,\n ): Promise<PluginRuntimeReport> {\n const candidates = await this.refreshCandidates()\n const activeDependencies = new Set(this.#active.keys())\n const phaseCandidates = candidates\n .filter(candidate => candidate.enabled && (candidate.manifest.kind ?? 'normal') === phase)\n .map(candidate => ({\n ...candidate,\n manifest: {\n ...candidate.manifest,\n require: candidate.manifest.require.filter(value => !activeDependencies.has(value.id)),\n },\n }))\n const chosen = selected\n ? this.#selectWithDependencies(phaseCandidates, selected)\n : phaseCandidates\n const plan = planPluginDependencies(chosen)\n if (plan.missing.length > 0 || plan.cycles.length > 0) {\n const missing = plan.missing.map(value => `${value.plugin} -> ${value.dependency}`).join(', ')\n const cycles = plan.cycles.map(value => value.join(' -> ')).join(', ')\n throw new Error(\n [missing && `missing: ${missing}`, cycles && `cycles: ${cycles}`]\n .filter(Boolean)\n .join('; '),\n )\n }\n\n const activated: string[] = []\n const failures: PluginRuntimeFailure[] = []\n const failed = new Set<string>()\n for (const level of plan.levels) {\n for (const candidate of level) {\n const plugin = candidate.manifest.name.id\n const info = (progress.value[plugin] = loadingInfo())\n const blockedBy = candidate.manifest.require\n .map(value => value.id)\n .filter(dependency => failed.has(dependency))\n if (blockedBy.length > 0) {\n const error = new Error(`dependency activation failed: ${blockedBy.join(', ')}`)\n info.progress = { errorReason: error.message, status: 'error', stepsIndex: 0 }\n failures.push({ error, phase, plugin })\n failed.add(plugin)\n continue\n }\n const scope = new PluginScope(plugin)\n try {\n info.progress.status = 'process'\n info.steps[0] = { description: '', name: 'module' }\n const loaded = await candidate.load(scope.signal)\n if (loaded.dispose) scope.defer(loaded.dispose)\n const config = markRaw(loaded.factory(this.#options.environment()))\n if (config.name !== plugin)\n throw new Error(`plugin name mismatch: ${plugin} / ${config.name}`)\n this.store.markLoading(plugin, config)\n scope.defer(() => this.store.markUnloaded(plugin))\n const pipeline = new ActivationPipeline(this.#options.capabilities(phase, app))\n await pipeline.activate(config, {\n owner: plugin,\n report: update => {\n const value = typeof update === 'string' ? { description: update } : update\n info.steps[0] = { ...info.steps[0], ...value }\n },\n scope,\n signal: scope.signal,\n })\n this.#active.set(plugin, { candidate, scope })\n this.store.markReady(plugin)\n info.progress.status = 'done'\n activated.push(plugin)\n } catch (error) {\n info.progress = { errorReason: errorText(error), status: 'error', stepsIndex: 0 }\n failures.push({ error, phase, plugin })\n failed.add(plugin)\n await scope.dispose(error).catch(disposeError => {\n failures.push({ error: disposeError, phase, plugin })\n })\n }\n }\n }\n return { activated, failures }\n }\n\n #selectWithDependencies(candidates: readonly PluginCandidate[], selected: readonly string[]) {\n const byId = new Map(candidates.map(candidate => [candidate.manifest.name.id, candidate]))\n const result = new Map<string, PluginCandidate>()\n const visit = (plugin: string) => {\n const candidate = byId.get(plugin)\n if (!candidate || result.has(plugin)) return\n for (const dependency of candidate.manifest.require) visit(dependency.id)\n result.set(plugin, candidate)\n }\n for (const plugin of selected) visit(plugin)\n return [...result.values()]\n }\n\n #track(operation: Promise<PluginRuntimeReport>) {\n this.#normalOperation = operation\n void operation.then(\n () => (this.#normalOperation = undefined),\n () => (this.#normalOperation = undefined),\n )\n }\n\n async #unload(predicate: (candidate: PluginCandidate) => boolean) {\n const targets = [...this.#active].filter(([, value]) => predicate(value.candidate)).reverse()\n const errors: unknown[] = []\n for (const [plugin, value] of targets) {\n try {\n await this.#deactivate(plugin, value.scope)\n } catch (error) {\n errors.push(error)\n }\n }\n if (errors.length > 0) throw new AggregateError(errors, 'some plugins failed to unload')\n }\n\n async #deactivate(plugin: string, scope: PluginScope) {\n this.#active.delete(plugin)\n await scope.dispose()\n }\n\n #writeRecovery(failures: readonly PluginRuntimeFailure[]) {\n try {\n globalThis.localStorage?.setItem(\n recoveryKey,\n JSON.stringify({\n failedAt: Date.now(),\n plugins: failures.map(value => value.plugin),\n reason: failures.map(value => errorText(value.error)).join('\\n'),\n } satisfies PrebootRecovery),\n )\n } catch {}\n }\n}","import type { InternalPluginDefinition, PluginCandidate, PluginCandidateProvider } from '../kernel'\n\nconst defaultStorage = () => {\n try {\n return globalThis.localStorage\n } catch {\n return undefined\n }\n}\n\nexport interface InternalPluginPreferences {\n enabled(plugin: string, fallback: boolean): Promise<boolean>\n setEnabled(plugin: string, enabled: boolean): Promise<void>\n}\n\nexport class LocalInternalPluginPreferences implements InternalPluginPreferences {\n public constructor(\n private readonly storage: Storage | undefined = defaultStorage(),\n private readonly prefix = 'delta-comic:internal-plugin:',\n ) {}\n\n public async enabled(plugin: string, fallback: boolean) {\n try {\n const value = this.storage?.getItem(`${this.prefix}${plugin}`)\n return value === null || value === undefined ? fallback : value === 'true'\n } catch {\n return fallback\n }\n }\n\n public async setEnabled(plugin: string, enabled: boolean) {\n try {\n this.storage?.setItem(`${this.prefix}${plugin}`, String(enabled))\n } catch {}\n }\n}\n\nexport class InternalPluginCandidateProvider implements PluginCandidateProvider {\n public readonly id = 'internal'\n\n public constructor(\n private readonly definitions: readonly InternalPluginDefinition[],\n private readonly preferences: InternalPluginPreferences = new LocalInternalPluginPreferences(),\n ) {}\n\n public async list(signal: AbortSignal) {\n const candidates: PluginCandidate[] = []\n for (const definition of this.definitions) {\n if (signal.aborted) throw signal.reason\n candidates.push({\n enabled:\n definition.canDisable === false\n ? true\n : await this.preferences.enabled(\n definition.manifest.name.id,\n definition.enabledByDefault ?? true,\n ),\n load: async () => ({ factory: definition.factory }),\n management: {\n canDisable: definition.canDisable ?? true,\n canUninstall: false,\n canUpdate: false,\n },\n manifest: definition.manifest,\n origin: 'builtin',\n })\n }\n return candidates\n }\n}\n\nexport class CompositePluginCandidateProvider implements PluginCandidateProvider {\n public readonly id = 'composite'\n\n public constructor(private readonly providers: readonly PluginCandidateProvider[]) {}\n\n public async list(signal: AbortSignal) {\n const candidates = (\n await Promise.all(this.providers.map(provider => provider.list(signal)))\n ).flat()\n const owners = new Map<string, PluginCandidate>()\n for (const candidate of candidates) {\n const id = candidate.manifest.name.id\n const previous = owners.get(id)\n if (previous) {\n throw new Error(\n `duplicate plugin candidate \"${id}\" from ${previous.origin} and ${candidate.origin}`,\n )\n }\n owners.set(id, candidate)\n }\n return [...owners.values()]\n }\n}","import { isTauri } from '@tauri-apps/api/core'\n\nimport {\n AwesomeRegistryClient,\n ConfigStore,\n createDefaultPluginFileStore,\n pluginI18n,\n} from './adapters'\nimport { corePluginDefinition, internalPluginDefinitions } from './builtins'\nimport { createDefaultCapabilities, type PluginAuthGateway } from './capabilities'\nimport {\n DatabasePluginArchiveRepository,\n DevScriptCodec,\n GitHubSourceResolver,\n HttpSourceResolver,\n InstalledPluginCandidateProvider,\n LocalFileSourceResolver,\n MarketplaceSourceResolver,\n type PluginCatalog,\n PluginInstallService,\n StoredPluginModuleReader,\n ZipPackageCodec,\n} from './install'\nimport { ContributionHub } from './kernel'\nimport {\n CompositePluginCandidateProvider,\n InternalPluginCandidateProvider,\n LocalInternalPluginPreferences,\n PluginRuntime,\n PluginStore,\n} from './runtime'\n\nexport const pluginContributions = new ContributionHub()\nexport const pluginStore = new PluginStore(value =>\n value.startsWith('i18n:') ? pluginI18n.translate(value.slice('i18n:'.length)) : value,\n)\nexport const pluginConfigStore = new ConfigStore()\nexport const useConfig = () => pluginConfigStore\n\nexport interface PluginHostServices {\n readonly auth?: PluginAuthGateway\n}\n\nconst pluginHostServices: PluginHostServices = {}\n\n/** Install host-only integrations without exposing UI or platform details to the runtime kernel. */\nexport const configurePluginHost = (services: PluginHostServices) => {\n Object.assign(pluginHostServices, services)\n}\n\nconst pluginFiles = createDefaultPluginFileStore()\nconst pluginRepository = new DatabasePluginArchiveRepository()\nconst pluginReader = new StoredPluginModuleReader(pluginFiles)\nconst internalPreferences = new LocalInternalPluginPreferences()\nconst internalProvider = new InternalPluginCandidateProvider(\n internalPluginDefinitions,\n internalPreferences,\n)\nconst candidateProvider = new CompositePluginCandidateProvider([\n internalProvider,\n new InstalledPluginCandidateProvider(pluginRepository, pluginReader),\n])\n\nconst httpSource = new HttpSourceResolver()\nconst githubSource = new GitHubSourceResolver({\n coreVersion: corePluginDefinition.manifest.version.plugin,\n})\nconst awesomeRegistry = new AwesomeRegistryClient()\nconst marketplaceSource = new MarketplaceSourceResolver(awesomeRegistry, [githubSource, httpSource])\n\nexport const pluginCatalog: PluginCatalog = awesomeRegistry\n\nexport const pluginInstaller = new PluginInstallService({\n codecs: [new ZipPackageCodec(), new DevScriptCodec()],\n files: pluginFiles,\n repository: pluginRepository,\n reservedIds: new Set(internalPluginDefinitions.map(definition => definition.manifest.name.id)),\n resolvers: [new LocalFileSourceResolver(), marketplaceSource, githubSource, httpSource],\n})\n\nexport const pluginRuntime = new PluginRuntime({\n capabilities: (phase, app) =>\n createDefaultCapabilities({\n app,\n auth: pluginHostServices.auth,\n config: pluginConfigStore,\n contributions: pluginContributions,\n i18n: pluginI18n,\n phase,\n }),\n environment: () => ({\n platform: isTauri() ? 'tauri' : 'web',\n safe: (globalThis as typeof globalThis & { $$safe$$?: boolean }).$$safe$$ ?? true,\n }),\n provider: candidateProvider,\n remove: plugin => pluginInstaller.uninstall(plugin),\n store: pluginStore,\n})\n\nexport const installPlugin = async (input: File | string) => {\n const archive = await pluginInstaller.install(input)\n await pluginRuntime.refreshCandidates()\n return archive\n}\n\nexport const updatePlugin = async (archive: { installInput: string }) => {\n if (!archive.installInput) throw new Error('plugin has no reusable install source')\n return await installPlugin(archive.installInput)\n}\n\nexport const updatePluginByName = async (plugin: string) => {\n const archive = await pluginRepository.find(plugin)\n if (!archive) throw new Error(`installed plugin not found: ${plugin}`)\n return await updatePlugin(archive)\n}\n\nexport const setPluginEnabled = async (plugin: string, enabled: boolean) => {\n const candidate = pluginStore.candidates.get(plugin)\n if (!candidate?.management.canDisable) throw new Error(`plugin \"${plugin}\" cannot be disabled`)\n if (candidate.origin === 'builtin') await internalPreferences.setEnabled(plugin, enabled)\n else {\n const archive = await pluginRepository.find(plugin)\n if (!archive) throw new Error(`installed plugin not found: ${plugin}`)\n await pluginRepository.upsert({ ...archive, enable: enabled })\n }\n await pluginRuntime.refreshCandidates()\n}\n\nexport const setPluginKind = async (plugin: string, kind: 'normal' | 'preboot') => {\n const archive = await pluginRepository.find(plugin)\n if (!archive) throw new Error(`installed plugin not found: ${plugin}`)\n await pluginRepository.upsert({ ...archive, meta: { ...archive.meta, kind } })\n await pluginRuntime.refreshCandidates()\n}\n\nexport const uninstallPlugin = async (plugin: string) => await pluginRuntime.uninstall(plugin)\n\nexport const resolvePluginIconUrl = async (\n plugin: string | undefined,\n icon: string | undefined,\n) => {\n if (!icon) return undefined\n if (/^https?:\\/\\//i.test(icon)) return icon\n if (!plugin) throw new Error('a plugin id is required to resolve a local plugin icon')\n return await pluginFiles.createAssetUrl(plugin, icon)\n}\n\nexport {\n pluginI18n,\n pluginMessageKey,\n translatePluginText,\n type PluginI18nAdapter,\n type PluginLocaleMessages,\n} from './adapters'\n\nexport const usePluginStore = () => pluginStore"],"mappings":"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"}
|
package/dist/vite/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { PluginManifest } from "@delta-comic/model";
|
|
3
2
|
//#region vite/index.d.ts
|
|
4
3
|
type DeltaComicBundleAssetSource = string | Uint8Array;
|
|
5
4
|
type DeltaComicPluginContext = {
|
|
@@ -27,7 +26,7 @@ type DeltaComicPlugin = {
|
|
|
27
26
|
generateBundle?(this: DeltaComicPluginContext, options: unknown, bundle: DeltaComicOutputBundle): void | Promise<void>;
|
|
28
27
|
};
|
|
29
28
|
type DeltaComicPluginOption = DeltaComicPlugin | DeltaComicPluginOption[] | false | null | undefined;
|
|
30
|
-
declare const deltaComic: (meta:
|
|
29
|
+
declare const deltaComic: (meta: PluginManifest, command: "build" | "serve") => DeltaComicPluginOption[];
|
|
31
30
|
//#endregion
|
|
32
31
|
export { deltaComic };
|
|
33
32
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/vite/index.mjs
CHANGED