Skip to content

chore: version packages#31

Merged
jonlaing merged 1 commit into
mainfrom
changeset-release/main
Jul 12, 2026
Merged

chore: version packages#31
jonlaing merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@effex/dom@1.2.0

Minor Changes

  • b650fd8: Add animation groups — declarative sequencing across multiple animated blocks. Solves the "chained word-by-word intro" case where each word is its own each and word N should only start after word N-1 finishes.

    import { $, Animation, collect, each, stagger } from "@effex/dom";
    
    const App = () =>
      Effect.gen(function* () {
        const [greeting, name, tagline] = yield* Animation.sequence(3);
        return $.div(
          {},
          collect(
            each(greetingLetters, {
              key: (l) => l.id,
              render: (l) => $.span({}, $.of(l.char)),
              animate: {
                enter: "letter-in",
                stagger: stagger(40),
                group: greeting,
              },
            }),
            each(nameLetters, {
              key: (l) => l.id,
              render: (l) => $.span({}, $.of(l.char)),
              animate: { enter: "letter-in", stagger: stagger(40), group: name },
            }),
            each(taglineLetters, {
              key: (l) => l.id,
              render: (l) => $.span({}, $.of(l.char)),
              animate: {
                enter: "letter-in",
                stagger: stagger(40),
                group: tagline,
              },
            }),
          ),
        );
      });

    New API:

    • Animation.group() — creates a group with a gate (unresolved) and a completion signal.
    • Animation.sequence(count) — returns count groups wired end-to-end: group 0's gate is open immediately, group N's gate opens when group N-1's registered animations all complete.
    • Animation.parallel(count) — returns count groups with all gates open (useful nested inside sequence for concurrent segments in a follow-up release).
    • animate.group: AnimationGroup — new option on any animated control (each, when, match, ...). The animation registers with the group synchronously, awaits the gate before starting, and signals completion when finished.

    Groups finalize when their pending count returns to zero for the first time after having been non-zero. Late registrations that arrive after finalization run immediately (gate is already open) — intended semantics for one-shot intros where post-sequence additions behave like ordinary animations.

  • ee8a4d1: Add an intro?: boolean flag on each — and symmetrically on when, match, matchOption, matchEither, and redraw — to opt into re-animating SSR/SSG-rendered content during hydration.

    Default behaviour stays as-is: hydration attaches handlers to pre-existing DOM without re-running enter animations — the right choice for content lists (feeds, sidebars, todos) that shouldn't jitter into view on every page load. Setting intro: true flips that for decorative sequences where the animation is the point:

    each(letters, {
      key: (l) => l.id,
      render: (l) => $.span({}, $.of(Readable.map(l, (v) => v.char))),
      animate: {
        enterFrom: "opacity-0 translate-y-4",
        enter: "opacity-100 translate-y-0 transition duration-300",
        stagger: stagger(40),
      },
      intro: true,
    });

    The same flag makes sense on single-slot controls too — a hero fade-in for a when-gated banner, or an animated card for a match-selected state:

    when(isReady, {
      onTrue: () => Hero(),
      onFalse: () => Placeholder(),
      animate: {
        enterFrom: "opacity-0",
        enter: "opacity-100 transition duration-500",
      },
      intro: true,
    });

    On the client, intro is a no-op — animations already fire normally when there's no pre-existing DOM. It only affects the hydration path.

    FOUC caveat. Between the SSR paint and hydration applying the enterFrom state, there's a brief visual flash of the final state. To eliminate it, hide the container in CSS until hydration completes (e.g. visibility: hidden on a class you toggle from your client entry). A first-class FOUC-prevention mechanism is planned for a follow-up.

    Respects prefers-reduced-motion via runEnterAnimation.

Patch Changes

  • 12654be: Deprecate five under-used animation helpers with @deprecated JSDoc tags. All continue to work — they'll be removed in a future major.

    • staggerEased — compose your own: (index, total) => easingFn(index / (total - 1)) * totalDurationMs
    • delay — use Effect.delay(effect, ms) directly
    • sequence — use Effect.all([...], { concurrency: 1 }) directly
    • parallel — use Effect.all([...], { concurrency: "unbounded" }) directly
    • calculateStaggerDelay — was only ever an internal helper; not re-exported by anything downstream

    These wrapped effect combinators without adding real value beyond a slightly shorter name; the framework should be a thin layer over Effect rather than shadow its stdlib.

  • 0dd6440: Fix inline animation serialization in addSlot / removeSlot. Previously each enter/exit animation was awaited via yield*, which serialized the reconcile sync loop — for a list of [a, b, c] added at once, item b's animation would only start after item a's finished. Made stagger configs effectively double-counted (each addSlot's stagger delay applied after the previous animation completed rather than concurrently).

    Now enter animations are forked into the slot's scope so multiple slots animate concurrently, and exit animations run in a fiber attached to the parent scope so removeSlot returns immediately (letting the reconcile loop continue) while the exit still plays before the DOM node is removed. If a slot is removed mid-enter, closing the slot scope interrupts the enter animation before exit starts. This applies to ClientControlCtx and both factories in HydrationControlCtx.

    @effex/router will receive an automatic patch via updateInternalDependencies since it depends on @effex/dom as a workspace dependency.

  • 3c5da0c: Fix the renderToString return-type inference so provided dependencies (RendererContext, ControlCtx, SuspenseBoundaryCtx, Scope) are properly subtracted from the output R. Previously the signature used Deps | R, which TypeScript can't do set-subtraction from, so those tags leaked into the returned Effect's requirements — callers whose element required Scope (from Signal.make) or the other provided tags saw them appear in Effect.runPromise arguments even though renderToString itself provides them internally. Switched to Exclude<R, Deps>; the runtime behaviour is unchanged.

@effex/router@1.2.2

Patch Changes

docs@0.0.14

Patch Changes

  • Updated dependencies [b650fd8]
  • Updated dependencies [12654be]
  • Updated dependencies [ee8a4d1]
  • Updated dependencies [0dd6440]
  • Updated dependencies [3c5da0c]
    • @effex/dom@1.2.0
    • @effex/router@1.2.2

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying effex-api with  Cloudflare Pages  Cloudflare Pages

Latest commit: eee20c0
Status: ✅  Deploy successful!
Preview URL: https://cfd37bb2.effex-api.pages.dev
Branch Preview URL: https://changeset-release-main.effex-api.pages.dev

View logs

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from b93a0d7 to a397ddf Compare July 2, 2026 22:41
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying effex with  Cloudflare Pages  Cloudflare Pages

Latest commit: eee20c0
Status: ✅  Deploy successful!
Preview URL: https://5a8188d6.effex.pages.dev
Branch Preview URL: https://changeset-release-main.effex.pages.dev

View logs

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 2 times, most recently from e4f72f4 to 19f77cb Compare July 12, 2026 12:17
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 19f77cb to eee20c0 Compare July 12, 2026 12:43
@jonlaing
jonlaing merged commit 13389a7 into main Jul 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant