From 79348ed96a9348f10c3246a4dd9bc4260cf64463 Mon Sep 17 00:00:00 2001 From: sleepyfran Date: Tue, 30 Jul 2024 00:15:20 +0200 Subject: [PATCH] Partially re-implement user library in Rx --- packages/components/library/index.ts | 1 + packages/components/library/package.json | 21 +++++++ packages/components/library/src/Library.tsx | 55 +++++++++++++++++++ packages/components/library/src/vite-env.d.ts | 1 + packages/components/library/tsconfig.json | 7 +++ packages/core/types/src/services/library.ts | 9 ++- packages/web/package.json | 1 + packages/web/src/App.tsx | 42 +------------- 8 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 packages/components/library/index.ts create mode 100644 packages/components/library/package.json create mode 100644 packages/components/library/src/Library.tsx create mode 100644 packages/components/library/src/vite-env.d.ts create mode 100644 packages/components/library/tsconfig.json diff --git a/packages/components/library/index.ts b/packages/components/library/index.ts new file mode 100644 index 0000000..5d080ec --- /dev/null +++ b/packages/components/library/index.ts @@ -0,0 +1 @@ +export { UserLibraryWithSuspense as UserLibrary } from "./src/Library"; diff --git a/packages/components/library/package.json b/packages/components/library/package.json new file mode 100644 index 0000000..ddc8cfd --- /dev/null +++ b/packages/components/library/package.json @@ -0,0 +1,21 @@ +{ + "name": "@echo/components-library", + "private": true, + "version": "1.0.0", + "scripts": { + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@echo/core-types": "^1.0.0", + "@echo/services-bootstrap": "^1.0.0", + "@echo/services-library": "^1.0.0", + "@effect-rx/rx": "^0.33.8", + "@effect-rx/rx-react": "^0.30.11", + "effect": "^3.2.8" + }, + "devDependencies": { + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22" + } +} \ No newline at end of file diff --git a/packages/components/library/src/Library.tsx b/packages/components/library/src/Library.tsx new file mode 100644 index 0000000..9e88713 --- /dev/null +++ b/packages/components/library/src/Library.tsx @@ -0,0 +1,55 @@ +import { Library, type Track } from "@echo/core-types"; +import { MainLive } from "@echo/services-bootstrap"; +import { Rx } from "@effect-rx/rx"; +import { Layer, Match, Stream } from "effect"; +import { Suspense, useState } from "react"; +import { LibraryLive } from "@echo/services-library"; +import { useRx } from "@effect-rx/rx-react"; + +const runtime = Rx.runtime(LibraryLive.pipe(Layer.provide(MainLive))); +const observeLibrary = runtime.pull(Stream.unwrap(Library.observeAlbums()), { + initialValue: [], +}); + +const UserLibrary = () => { + const [src, setSrc] = useState(undefined); + const [result] = useRx(observeLibrary); + + const playFirstTrack = (tracks: Track[]) => { + const track = tracks[0]; + switch (track.resource.type) { + case "file": + setSrc(track.resource.uri); + break; + case "api": + break; + } + }; + + return Match.value(result).pipe( + Match.tag("Initial", () =>
Loading...
), + // FIXME: Why does this render only one? + Match.tag("Success", ({ value: { items } }) => ( +
+
+
+ )), + Match.tag("Failure", (error) =>
{JSON.stringify(error)}
), + Match.exhaustive, + ); +}; + +export const UserLibraryWithSuspense = () => ( + + + +); diff --git a/packages/components/library/src/vite-env.d.ts b/packages/components/library/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/packages/components/library/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/components/library/tsconfig.json b/packages/components/library/tsconfig.json new file mode 100644 index 0000000..25a3349 --- /dev/null +++ b/packages/components/library/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": [ + "src", + "index.ts" + ], + "extends": "../../../tsconfig.json" +} \ No newline at end of file diff --git a/packages/core/types/src/services/library.ts b/packages/core/types/src/services/library.ts index 7ffbfb7..daca9e3 100644 --- a/packages/core/types/src/services/library.ts +++ b/packages/core/types/src/services/library.ts @@ -1,4 +1,4 @@ -import { Context, Effect, Stream } from "effect"; +import { Effect, Stream } from "effect"; import type { Album, ArtistId, Track } from "../model"; /** @@ -15,7 +15,7 @@ export class NonExistingArtistReferenced extends Error { /** * Service that provides access to the user's library. */ -export type Library = { +export type ILibrary = { /** * Returns a stream of albums that are currently stored in the database. */ @@ -27,4 +27,7 @@ export type Library = { /** * Tag to identify the library service. */ -export const Library = Context.GenericTag("@echo/core-types/Library"); +export class Library extends Effect.Tag("@echo/core-types/Library")< + Library, + ILibrary +>() {} diff --git a/packages/web/package.json b/packages/web/package.json index 9f315f1..9075ba3 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@echo/components-add-provider": "^1.0.0", + "@echo/components-library": "^1.0.0", "@echo/components-provider-status": "^1.0.0", "@echo/core-types": "^1.0.0", "@echo/services-bootstrap": "^1.0.0", diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx index adeb372..3f5cc5d 100644 --- a/packages/web/src/App.tsx +++ b/packages/web/src/App.tsx @@ -1,49 +1,11 @@ import { AddProvider } from "@echo/components-add-provider"; +import { UserLibrary } from "@echo/components-library"; import { ProviderStatus } from "@echo/components-provider-status"; export const App = () => (
+
); - -// const observeLibrary = Effect.gen(function* () { -// const library = yield* Library; -// return yield* library.observeAlbums(); -// }).pipe(Effect.provide(MainLive)); - -// const UserLibrary = () => { -// const [src, setSrc] = useState(undefined); -// const [albumStream, matcher] = useStream(observeLibrary); - -// const playFirstTrack = (tracks: Track[]) => { -// const track = tracks[0]; -// switch (track.resource.type) { -// case "file": -// setSrc(track.resource.uri); -// break; -// case "api": -// break; -// } -// }; - -// return matcher.pipe( -// Match.tag("empty", () =>

Nothing in your library

), -// Match.tag("items", ({ items }) => ( -//
-//
-// )), -// Match.tag("failure", () =>

Failed to load library

), -// Match.exhaustive, -// )(albumStream); -// };