899028e20f
- RomConfig/RomCache on the kit's ConfigService/CacheStore; RomSync wires the pure domain into the kit SyncEngine (poll/watch/coalesce/fingerprint) and ProviderClient; EngineStatus assembly shared by REST + SSE - makeApi: HttpApiBuilder groups over live service values (handler runtime shares the plugin runtime's singletons) + sseRoute status feed - index.ts: definePluginKit entry (async-main boundary); headless-first (UI serve failure logged, engine continues) - cli.ts on the kit dispatcher: scan/detect/preview offline, sync/uninstall online; set-password is gone with the standalone server - dev.ts: auth-free loopback API server (:5885) — the dev:live proxy target; never bundled - verified live host-less: raw config round-trip on disk, status/platforms/ preview endpoints, soft-fail reconcile without a host - CI: workspace install, per-package typecheck, publish from plugin/ Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
// 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<typeof CacheSchema>
|
|
>()("rom-manager/RomCache") {
|
|
static readonly layer: Layer.Layer<RomCache, never, PluginInfo> =
|
|
Layer.effect(RomCache)(
|
|
makeCacheStore({ schema: CacheSchema, empty: emptyCache }),
|
|
);
|
|
}
|