From e28f5256d0855e29e8897f0d6c384cd546115d17 Mon Sep 17 00:00:00 2001 From: Johannes Schickling Date: Wed, 13 Nov 2024 17:40:24 +0100 Subject: [PATCH 1/4] init --- .../schedule-visualizer/ScheduleVisualizer.tsx | 3 +++ .../docs/docs/scheduling/schedule-visualizer.mdx | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 content/src/components/schedule-visualizer/ScheduleVisualizer.tsx create mode 100644 content/src/content/docs/docs/scheduling/schedule-visualizer.mdx diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx new file mode 100644 index 000000000..73324a8ed --- /dev/null +++ b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx @@ -0,0 +1,3 @@ +export const ScheduleVisualizer = () => { + return
ScheduleVisualizer
+} diff --git a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx new file mode 100644 index 000000000..9310bf7db --- /dev/null +++ b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx @@ -0,0 +1,10 @@ +--- +title: Schedule Visualizer +--- + +import { ScheduleVisualizer } from "@/components/schedule-visualizer/ScheduleVisualizer" + +# Schedule Visualizer + + + From ff0fedaa1d6a0188722833648e905ad57c179c81 Mon Sep 17 00:00:00 2001 From: Johannes Schickling Date: Wed, 13 Nov 2024 18:36:29 +0100 Subject: [PATCH 2/4] wip --- .../ScheduleVisualizer.css | 40 +++++++++ .../ScheduleVisualizer.tsx | 81 ++++++++++++++++++- .../docs/scheduling/schedule-visualizer.mdx | 11 ++- 3 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 content/src/components/schedule-visualizer/ScheduleVisualizer.css diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizer.css b/content/src/components/schedule-visualizer/ScheduleVisualizer.css new file mode 100644 index 000000000..f5332306a --- /dev/null +++ b/content/src/components/schedule-visualizer/ScheduleVisualizer.css @@ -0,0 +1,40 @@ +.arrow { + position: relative; + display: inline-block; + height: 2px; + margin: 12px 0; + border-radius: 9999px; + background-color: #000000; +} + +.arrow::before, +.arrow::after { + content: ""; + position: absolute; + top: calc(50% - 1px); + right: 0; + width: 19px; + height: 2px; + border-radius: 9999px; + background-color: #000000; + transform-origin: calc(100% - 1px) 50%; +} + +.arrow::before { + transform: rotate(45deg); +} + +.arrow::after { + transform: rotate(-45deg); +} + +@media (prefers-color-scheme: dark) { + .arrow { + background-color: #ffffff; + } + + .arrow::before, + .arrow::after { + background-color: #ffffff; + } +} \ No newline at end of file diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx index 73324a8ed..8b7740b2c 100644 --- a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx +++ b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx @@ -1,3 +1,80 @@ -export const ScheduleVisualizer = () => { - return
ScheduleVisualizer
+import React from "react" + +import "./ScheduleVisualizer.css" +import { Duration } from "effect" + +export type ScheduleVisualizerProps = { + code: string + items: ReadonlyArray +} + +type ScheduleItem = { + value: string + interval: Duration.Duration + clock: Duration.Duration + hasNewValue: boolean +} + +export const ScheduleVisualizer: React.FC = ({ + code, + items +}) => { + return ( +
+
{code}
+
+
+
+
time
+
+ output +
+
+
+ {items.map((item, index) => ( + + ))} +
+
+
+ ) +} + +const ScheduleItem: React.FC = ({ + value, + interval, + clock, + hasNewValue +}) => { + return ( +
+
{value}
+
+
+
+
+ {Duration.format(interval)} +
+
+
+ {Duration.toMillis(clock) === 0 ? "0s" : Duration.format(clock)} +
+
+ ) +} + +const durationToPixels = (duration: Duration.Duration) => { + return Math.round(Duration.toSeconds(duration) * 60) } diff --git a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx index 9310bf7db..747b9a71f 100644 --- a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx +++ b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx @@ -3,8 +3,17 @@ title: Schedule Visualizer --- import { ScheduleVisualizer } from "@/components/schedule-visualizer/ScheduleVisualizer" +import { Duration } from "effect" # Schedule Visualizer - + From 8669677df9a77c8af0e8b3d280b7b97b49257c83 Mon Sep 17 00:00:00 2001 From: Johannes Schickling Date: Wed, 13 Nov 2024 20:19:36 +0100 Subject: [PATCH 3/4] WIP --- .../ScheduleVisualizer.tsx | 54 +++++++++++++++---- .../ScheduleVisualizerAstro.astro | 21 ++++++++ .../schedule-visualizer/run-schedule.ts | 35 ++++++++++++ .../docs/scheduling/schedule-visualizer.mdx | 27 ++++++---- 4 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro create mode 100644 content/src/components/schedule-visualizer/run-schedule.ts diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx index 8b7740b2c..4b1af3a9d 100644 --- a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx +++ b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx @@ -1,7 +1,8 @@ import React from "react" import "./ScheduleVisualizer.css" -import { Duration } from "effect" +import { Duration, Effect, Schedule } from "effect" +import { sample } from "./run-schedule" export type ScheduleVisualizerProps = { code: string @@ -10,7 +11,7 @@ export type ScheduleVisualizerProps = { type ScheduleItem = { value: string - interval: Duration.Duration + interval: Duration.Duration | undefined clock: Duration.Duration hasNewValue: boolean } @@ -20,8 +21,8 @@ export const ScheduleVisualizer: React.FC = ({ items }) => { return ( -
-
{code}
+
+
{code}
@@ -30,7 +31,7 @@ export const ScheduleVisualizer: React.FC = ({ output
-
+
{items.map((item, index) => ( ))} @@ -58,17 +59,28 @@ const ScheduleItem: React.FC = ({
- {Duration.format(interval)} + {interval && Duration.toMillis(interval) > 0 + ? Duration.format(interval) + : "0"}
-
+
{Duration.toMillis(clock) === 0 ? "0s" : Duration.format(clock)}
@@ -76,5 +88,27 @@ const ScheduleItem: React.FC = ({ } const durationToPixels = (duration: Duration.Duration) => { - return Math.round(Duration.toSeconds(duration) * 60) + return Math.max(20, Math.round(Duration.toSeconds(duration) * 60)) +} + +export const scheduleToItems = async ( + schedule: Schedule.Schedule, + limit: number +) => { + let accDuration = Duration.millis(0) + return sample(schedule, limit).pipe( + Effect.map((_) => + _.map((duration) => { + accDuration = Duration.sum(accDuration, duration) + return { + interval: duration, + clock: accDuration, + hasNewValue: true, + value: "" + } satisfies ScheduleItem + }) + ), + Effect.tapErrorCause(Effect.logError), + Effect.runPromise + ) } diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro b/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro new file mode 100644 index 000000000..2319308e5 --- /dev/null +++ b/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro @@ -0,0 +1,21 @@ +--- +import { Schedule } from "effect" +import { ScheduleVisualizer, type ScheduleVisualizerProps, scheduleToItems } from "./ScheduleVisualizer" +// import { Code } from "astro:components" + +type Props = ScheduleVisualizerProps & { + schedule: Schedule.Schedule +} + + +const limit = 10 + +const items = await scheduleToItems(Astro.props.schedule, limit) + +const { code } = Astro.props +--- + + diff --git a/content/src/components/schedule-visualizer/run-schedule.ts b/content/src/components/schedule-visualizer/run-schedule.ts new file mode 100644 index 000000000..8632b6c50 --- /dev/null +++ b/content/src/components/schedule-visualizer/run-schedule.ts @@ -0,0 +1,35 @@ +import { + Array, + Duration, + Effect, + Fiber, + Schedule, + TestClock, + TestContext +} from "effect" + +export const sample = ( + schedule: Schedule.Schedule, + limit: number +) => { + return Effect.gen(function* () { + const output: Array = [] + + const fiber = yield* Effect.gen(function* () { + const now = yield* TestClock.currentTimeMillis + const previous = Array.reduce(output, Duration.zero, Duration.sum) + + output.push(Duration.subtract(now, previous)) + }).pipe( + Effect.schedule( + schedule.pipe(Schedule.intersect(Schedule.recurs(limit))) + ), + Effect.fork + ) + + yield* TestClock.adjust(Infinity) + yield* Fiber.join(fiber) + + return output + }).pipe(Effect.provide(TestContext.TestContext)) +} diff --git a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx index 747b9a71f..bab8765d7 100644 --- a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx +++ b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx @@ -2,18 +2,25 @@ title: Schedule Visualizer --- -import { ScheduleVisualizer } from "@/components/schedule-visualizer/ScheduleVisualizer" -import { Duration } from "effect" - -# Schedule Visualizer +import ScheduleVisualizer from "@/components/schedule-visualizer/ScheduleVisualizerAstro.astro" +import { Duration, Schedule } from "effect" + + + + + \ No newline at end of file From 3b9cf9cfae5cfeacc6a49c8bb0316b1f10ba07eb Mon Sep 17 00:00:00 2001 From: Johannes Schickling Date: Wed, 13 Nov 2024 22:59:48 +0100 Subject: [PATCH 4/4] clean up --- .../ScheduleVisualizer.tsx | 6 +-- .../ScheduleVisualizerAstro.astro | 12 +++--- .../docs/scheduling/schedule-visualizer.mdx | 42 ++++++++++++++----- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx index 4b1af3a9d..494a31b5a 100644 --- a/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx +++ b/content/src/components/schedule-visualizer/ScheduleVisualizer.tsx @@ -5,7 +5,6 @@ import { Duration, Effect, Schedule } from "effect" import { sample } from "./run-schedule" export type ScheduleVisualizerProps = { - code: string items: ReadonlyArray } @@ -17,12 +16,10 @@ type ScheduleItem = { } export const ScheduleVisualizer: React.FC = ({ - code, items }) => { return (
-
{code}
@@ -99,10 +96,11 @@ export const scheduleToItems = async ( return sample(schedule, limit).pipe( Effect.map((_) => _.map((duration) => { + const clock = accDuration accDuration = Duration.sum(accDuration, duration) return { interval: duration, - clock: accDuration, + clock, hasNewValue: true, value: "" } satisfies ScheduleItem diff --git a/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro b/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro index 2319308e5..761b75165 100644 --- a/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro +++ b/content/src/components/schedule-visualizer/ScheduleVisualizerAstro.astro @@ -1,21 +1,19 @@ --- import { Schedule } from "effect" -import { ScheduleVisualizer, type ScheduleVisualizerProps, scheduleToItems } from "./ScheduleVisualizer" +import { ScheduleVisualizer, scheduleToItems } from "./ScheduleVisualizer" // import { Code } from "astro:components" -type Props = ScheduleVisualizerProps & { +type Props = { + code: string schedule: Schedule.Schedule } - const limit = 10 - const items = await scheduleToItems(Astro.props.schedule, limit) - -const { code } = Astro.props --- + + diff --git a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx index bab8765d7..5fadcfe08 100644 --- a/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx +++ b/content/src/content/docs/docs/scheduling/schedule-visualizer.mdx @@ -5,22 +5,44 @@ title: Schedule Visualizer import ScheduleVisualizer from "@/components/schedule-visualizer/ScheduleVisualizerAstro.astro" import { Duration, Schedule } from "effect" - + + + ```ts + Schedule.fixed(Duration.seconds(1)) + ``` + + +> + + ```ts + Schedule.recurs(2) + ``` + + +> + + ```ts + Schedule.fibonacci(Duration.seconds(1)) + ``` + + \ No newline at end of file +> + + ```ts + Schedule.exponential(Duration.millis(10), 4).pipe( + Schedule.andThenEither(Schedule.spaced(Duration.seconds(1))), + Schedule.compose(Schedule.elapsed), + Schedule.whileOutput(Duration.lessThanOrEqualTo(Duration.seconds(10))) + ) + ``` + + \ No newline at end of file