// The plugin's disposable derived state (cache.json), on the kit's CacheStore: art // verdicts keyed by external_id, the last detection result, and the last-sync // fingerprint. Corrupt/absent → empty; every mutation is write-through. import { type CacheStore, makeCacheStore, type PluginInfo, } from "@punktfunk/plugin-kit"; import { Artwork } from "@punktfunk/plugin-kit/wire"; import { DetectedEmulator, LastSync, Os } from "@rom-manager/contract"; import { Context, Effect, Layer, Schema } from "effect"; export const ArtVerdictSchema = Schema.Struct({ art: Schema.NullOr(Artwork), provider: Schema.String, matcher: Schema.Number, }); export const CacheSchema = Schema.Struct({ art: Schema.Record(Schema.String, ArtVerdictSchema).pipe( Schema.withDecodingDefaultKey(Effect.succeed({}), { encodingStrategy: "passthrough", }), ), detect: Schema.optionalKey( Schema.Struct({ at: Schema.Number, os: Os, emulators: Schema.Array(DetectedEmulator), }), ), lastSync: Schema.optionalKey(LastSync), }); export type Cache = typeof CacheSchema.Type; export const emptyCache: Cache = { art: {} }; export class RomCache extends Context.Service< RomCache, CacheStore >()("rom-manager/RomCache") { static readonly layer: Layer.Layer = Layer.effect(RomCache)( makeCacheStore({ schema: CacheSchema, empty: emptyCache }), ); }