WIP. A little custom music server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

toy with layers a bit

+25 -22
+2 -2
backend/src/db/index.ts
··· 2 2 3 3 import * as SqliteDrizzle from "@effect/sql-drizzle/Sqlite"; 4 4 import { Config, Effect, Layer, pipe } from "effect"; 5 - import { BunFileSystem } from "@effect/platform-bun"; 5 + import { BunFileSystem, BunPath } from "@effect/platform-bun"; 6 6 import * as schema from "./schema"; 7 7 8 8 //export const SqlLive = SqliteClient.layer({ ··· 16 16 }); 17 17 18 18 export class DatabaseLive extends Effect.Service<DatabaseLive>()("DatabaseLive", { 19 - dependencies: [SqliteLive], 19 + dependencies: [SqliteLive, BunFileSystem.layer, BunPath.layer], 20 20 effect: SqliteDrizzle.make<typeof schema>({ 21 21 schema, 22 22 }),
+9 -9
backend/src/flac/service.ts
··· 3 3 import { FlacHeaderFromUint8Array, MetadataFromUint8Array } from "./transformers"; 4 4 import { FlacError } from "./errors"; 5 5 import { MetadataWithFilepathSchema } from "~/metadata"; 6 + import { BunFileSystem } from "@effect/platform-bun"; 6 7 7 8 const VORBIS_STREAMINFO = 4; 8 9 9 10 export class FlacService extends Effect.Service<FlacService>()("FlacService", { 11 + dependencies: [BunFileSystem.layer], 10 12 effect: Effect.gen(function* () { 11 13 const fs = yield* FileSystem.FileSystem; 12 14 ··· 22 24 return yield* Effect.fail( 23 25 new FlacError({ 24 26 message: "The file you are trying to parse as FLAC is NOT FLAC", 25 - }) 27 + }), 26 28 ); 27 29 } 28 30 ··· 50 52 51 53 return { 52 54 isFlac, 53 - readMetadata, 54 - }; 55 + readMetadata, 56 + } as const; 55 57 }), 56 58 }) {} 57 59 58 - 59 - 60 60 // Helpers 61 61 const readHeader = Effect.fn("flac-readHeader")(function* (file: Uint8Array, offset: number) { 62 62 const result = yield* Schema.decode(FlacHeaderFromUint8Array)({ ··· 68 68 new FlacError({ 69 69 cause: e, 70 70 message: "Failed reading header", 71 - }) 72 - ) 71 + }), 72 + ), 73 73 ); 74 74 75 75 return result; ··· 88 88 new FlacError({ 89 89 cause: e, 90 90 message: "Failed to parse Vorbis Comment", 91 - }) 92 - ) 91 + }), 92 + ), 93 93 ); 94 94 95 95 return vorbisComment;
+14 -11
backend/src/index.ts
··· 1 - import { BunContext, BunFileSystem, BunRuntime } from "@effect/platform-bun"; 2 - import { Config, Effect, Layer } from "effect"; 1 + import { BunContext, BunRuntime } from "@effect/platform-bun"; 2 + import { Config, Cron, Effect, Either, Layer, Option, Schedule } from "effect"; 3 3 import { DatabaseLive } from "./db"; 4 4 import { syncLibraryStream } from "./sync-library"; 5 5 import { OtelLive } from "./otel"; 6 6 import { startApi } from "./api"; 7 7 import { FlacService } from "./flac/service"; 8 8 9 - const layers = Layer.mergeAll( 10 - BunContext.layer, 11 - OtelLive, 12 - DatabaseLive.Default, 13 - FlacService.Default.pipe(Layer.provide(BunFileSystem.layer)), 9 + const AppLayer = FlacService.Default.pipe( 10 + // asdf 11 + Layer.provideMerge(DatabaseLive.Default), 12 + Layer.provideMerge(BunContext.layer), 13 + Layer.merge(OtelLive), 14 14 ); 15 15 16 - const main = Effect.gen(function* () { 17 - const folderPath = yield* Config.string("FOLDER_PATH"); 16 + const syncCron = Cron.parse("*/1 * * * *").pipe(Either.getRight, Option.getOrThrow); 17 + const syncSchedule = Schedule.cron(syncCron); 18 18 19 - yield* syncLibraryStream(folderPath); 19 + const main = Effect.gen(function* () { 20 + const folderPath = yield* Config.string("FOLDER_PATH"); 20 21 21 22 startApi(); 22 - }).pipe(Effect.provide(layers)); 23 + 24 + yield* syncLibraryStream(folderPath); 25 + }).pipe(Effect.provide(AppLayer)); 23 26 24 27 BunRuntime.runMain(main);