From 81e07a22fd551bafd1c0a4877b1c09f069b80c75 Mon Sep 17 00:00:00 2001 From: sleepyfran Date: Sat, 31 Aug 2024 22:34:01 +0200 Subject: [PATCH] Port library to Lit --- packages/components/library/index.ts | 1 + packages/components/library/package.json | 17 +++++++ .../components/library/src/user-library.ts | 44 +++++++++++++++++++ packages/components/library/src/vite-env.d.ts | 1 + packages/components/library/tsconfig.json | 7 +++ .../src/stream-effect.controller.ts | 21 ++++++--- .../services/bootstrap-runtime/package.json | 2 + .../services/bootstrap-runtime/src/runtime.ts | 11 +++-- packages/web/package.json | 1 + packages/web/src/main.ts | 4 +- tools/plop-templates/components/generator.cjs | 10 +++++ .../components/template/component.ts.hbs | 18 ++++++++ .../components/template/index.ts.hbs | 19 +------- .../components/template/package.json.hbs | 1 + .../components/template/vite-env.d.ts.hbs | 1 + 15 files changed, 129 insertions(+), 29 deletions(-) create mode 100644 packages/components/library/index.ts create mode 100644 packages/components/library/package.json create mode 100644 packages/components/library/src/user-library.ts create mode 100644 packages/components/library/src/vite-env.d.ts create mode 100644 packages/components/library/tsconfig.json create mode 100644 tools/plop-templates/components/template/component.ts.hbs create mode 100644 tools/plop-templates/components/template/vite-env.d.ts.hbs diff --git a/packages/components/library/index.ts b/packages/components/library/index.ts new file mode 100644 index 0000000..c8012fe --- /dev/null +++ b/packages/components/library/index.ts @@ -0,0 +1 @@ +export * from "./src/user-library"; diff --git a/packages/components/library/package.json b/packages/components/library/package.json new file mode 100644 index 0000000..f062786 --- /dev/null +++ b/packages/components/library/package.json @@ -0,0 +1,17 @@ +{ + "name": "@echo/components-library", + "private": true, + "version": "1.0.0", + "scripts": { + "lint": "eslint . --ext ts --report-unused-disable-directives --max-warnings 0", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@echo/components-shared-controllers": "^1.0.0", + "@echo/core-types": "^1.0.0", + "@echo/services-bootstrap-runtime": "^1.0.0", + "effect": "^3.6.5", + "lit": "^3.2.0", + "@lit/task": "^1.0.1" + } +} diff --git a/packages/components/library/src/user-library.ts b/packages/components/library/src/user-library.ts new file mode 100644 index 0000000..b07eec5 --- /dev/null +++ b/packages/components/library/src/user-library.ts @@ -0,0 +1,44 @@ +import { StreamEffectController } from "@echo/components-shared-controllers"; +import { EffectFnController } from "@echo/components-shared-controllers/src/effect-fn.controller"; +import { Library, Player } from "@echo/core-types"; +import { LitElement, html } from "lit"; +import { customElement } from "lit/decorators.js"; +import { map } from "lit/directives/map.js"; + +/** + * Component that displays the user's library of albums and allows them to + * play them. + */ +@customElement("user-library") +export class UserLibrary extends LitElement { + private _library = new StreamEffectController(this, Library.observeAlbums); + private _playAlbum = new EffectFnController(this, Player.playAlbum); + + render() { + return this._library.render({ + initial: () => html`

Loading...

`, + item: (albums) => html` +
+
+ ${map( + albums, + (album) => html` +
+

${album.name}

+

${album.artist.name}

+ +
+
+ `, + )} +
+ `, + }); + } +} + +declare global { + interface HTMLElementTagNameMap { + userLibrary: UserLibrary; + } +} 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/components/shared-controllers/src/stream-effect.controller.ts b/packages/components/shared-controllers/src/stream-effect.controller.ts index f68c8b0..4943332 100644 --- a/packages/components/shared-controllers/src/stream-effect.controller.ts +++ b/packages/components/shared-controllers/src/stream-effect.controller.ts @@ -41,6 +41,12 @@ const isSubscriptionRef = ( ): streamOrRef is SubscriptionRef.SubscriptionRef => "changes" in streamOrRef; +type OutputEffect = Effect.Effect< + Stream.Stream | SubscriptionRef.SubscriptionRef, + never, + EchoRuntimeServices +>; + /** * Controller that takes an effect that produces a stream or a subscription ref * and exposes a render method that renders maps the different states of the @@ -52,17 +58,20 @@ export class StreamEffectController implements ReactiveController { constructor( host: ReactiveControllerHost, - private readonly _streamEffect: Effect.Effect< - Stream.Stream | SubscriptionRef.SubscriptionRef, - never, - EchoRuntimeServices - >, + private readonly _streamEffect: + | OutputEffect + | (() => OutputEffect), ) { (this.host = host).addController(this); } hostConnected(): void { - const consumer$ = this._streamEffect.pipe( + const streamEffect = + typeof this._streamEffect === "function" + ? this._streamEffect() + : this._streamEffect; + + const consumer$ = streamEffect.pipe( Effect.flatMap((streamOrRef) => { const stream = isSubscriptionRef(streamOrRef) ? streamOrRef.changes diff --git a/packages/services/bootstrap-runtime/package.json b/packages/services/bootstrap-runtime/package.json index 30032f0..02ba2a1 100644 --- a/packages/services/bootstrap-runtime/package.json +++ b/packages/services/bootstrap-runtime/package.json @@ -13,6 +13,8 @@ "@echo/services-add-provider-workflow": "^1.0.0", "@echo/services-app-init": "^1.0.0", "@echo/services-bootstrap": "^1.0.0", + "@echo/services-library": "^1.0.0", + "@echo/services-player": "^1.0.0", "effect": "^3.6.5" } } \ No newline at end of file diff --git a/packages/services/bootstrap-runtime/src/runtime.ts b/packages/services/bootstrap-runtime/src/runtime.ts index 1008c25..4a8e92c 100644 --- a/packages/services/bootstrap-runtime/src/runtime.ts +++ b/packages/services/bootstrap-runtime/src/runtime.ts @@ -1,6 +1,8 @@ import { AddProviderWorkflowLive } from "@echo/services-add-provider-workflow"; import { AppInitLive } from "@echo/services-app-init"; import { MainLive } from "@echo/services-bootstrap"; +import { LibraryLive } from "@echo/services-library"; +import { PlayerLive } from "@echo/services-player"; import { Layer, ManagedRuntime } from "effect"; import { globalValue } from "effect/GlobalValue"; @@ -11,9 +13,12 @@ import { globalValue } from "effect/GlobalValue"; export const getOrCreateRuntime = () => globalValue("echo-runtime", () => ManagedRuntime.make( - Layer.mergeAll(AppInitLive, AddProviderWorkflowLive).pipe( - Layer.provideMerge(MainLive), - ), + Layer.mergeAll( + AppInitLive, + AddProviderWorkflowLive, + LibraryLive, + PlayerLive, + ).pipe(Layer.provideMerge(MainLive)), ), ); diff --git a/packages/web/package.json b/packages/web/package.json index 8fdecba..499d776 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-shared-controllers": "^1.0.0", "@echo/core-types": "^1.0.0", "@echo/services-bootstrap-runtime": "^1.0.0", diff --git a/packages/web/src/main.ts b/packages/web/src/main.ts index 729bcc8..e294ce9 100644 --- a/packages/web/src/main.ts +++ b/packages/web/src/main.ts @@ -4,6 +4,7 @@ import { initializeWorkers } from "@echo/services-bootstrap-workers"; import { AppInit } from "@echo/core-types"; import { EffectController } from "@echo/components-shared-controllers"; import "@echo/components-add-provider"; +import "@echo/components-library"; initializeWorkers(); @@ -20,8 +21,7 @@ export class MyElement extends LitElement { complete: () => html`
- - +
`, error: () => diff --git a/tools/plop-templates/components/generator.cjs b/tools/plop-templates/components/generator.cjs index 46000d7..c223447 100644 --- a/tools/plop-templates/components/generator.cjs +++ b/tools/plop-templates/components/generator.cjs @@ -17,6 +17,16 @@ module.exports = { path: "packages/components/{{dashCase name}}/index.ts", templateFile: `${__dirname}/template/index.ts.hbs`, }, + { + type: "add", + path: "packages/components/{{dashCase name}}/src/{{dashCase name}}.ts", + templateFile: `${__dirname}/template/component.ts.hbs`, + }, + { + type: "add", + path: "packages/components/{{dashCase name}}/src/vite-env.d.ts", + templateFile: `${__dirname}/template/vite-env.d.ts.hbs`, + }, { type: "add", path: "packages/components/{{dashCase name}}/package.json", diff --git a/tools/plop-templates/components/template/component.ts.hbs b/tools/plop-templates/components/template/component.ts.hbs new file mode 100644 index 0000000..f32631e --- /dev/null +++ b/tools/plop-templates/components/template/component.ts.hbs @@ -0,0 +1,18 @@ +import { LitElement, html } from "lit"; +import { customElement } from "lit/decorators.js"; + +/** + * Description of what the {{properCase name}} component does. + */ +@customElement("{{dashCase name}}") +export class {{pascalCase name}} extends LitElement { + render() { + return html`

{{pascalCase name}}

`; + } +} + +declare global { + interface HTMLElementTagNameMap { + "{{dashCase name}}": {{pascalCase name}}; + } +} diff --git a/tools/plop-templates/components/template/index.ts.hbs b/tools/plop-templates/components/template/index.ts.hbs index f32631e..aef6607 100644 --- a/tools/plop-templates/components/template/index.ts.hbs +++ b/tools/plop-templates/components/template/index.ts.hbs @@ -1,18 +1 @@ -import { LitElement, html } from "lit"; -import { customElement } from "lit/decorators.js"; - -/** - * Description of what the {{properCase name}} component does. - */ -@customElement("{{dashCase name}}") -export class {{pascalCase name}} extends LitElement { - render() { - return html`

{{pascalCase name}}

`; - } -} - -declare global { - interface HTMLElementTagNameMap { - "{{dashCase name}}": {{pascalCase name}}; - } -} +export * from "./src/{{dashCase name}}"; \ No newline at end of file diff --git a/tools/plop-templates/components/template/package.json.hbs b/tools/plop-templates/components/template/package.json.hbs index 63c0d19..3873086 100644 --- a/tools/plop-templates/components/template/package.json.hbs +++ b/tools/plop-templates/components/template/package.json.hbs @@ -7,6 +7,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@echo/components-shared-controllers": "^1.0.0", "@echo/core-types": "^1.0.0", "@echo/services-bootstrap-runtime": "^1.0.0", "effect": "^3.6.5", diff --git a/tools/plop-templates/components/template/vite-env.d.ts.hbs b/tools/plop-templates/components/template/vite-env.d.ts.hbs new file mode 100644 index 0000000..151aa68 --- /dev/null +++ b/tools/plop-templates/components/template/vite-env.d.ts.hbs @@ -0,0 +1 @@ +/// \ No newline at end of file