Subscription Types

Purpose

Subscription Types define the TypeScript contracts that specify how external real-time data sources integrate with the subscription middleware in this project. They establish the shape and behavior of subscription options, callback signatures, and the response structure returned by subscription hooks. This typing layer ensures type safety, consistency, and clear developer guidance when implementing or consuming subscription hooks, which are crucial for managing real-time updates with proper lifecycle handling.

While the parent topic explains subscription middleware and lifecycle management, Subscription Types focus specifically on formalizing the interfaces and generics that govern subscription interactions, enabling flexible, typed subscription implementations that can adapt to various data shapes and error handling strategies.

Functionality

The key components defined here include:

Critical Interaction Example

The next callback within SWRSubscriptionOptions enables the subscription function to push updates or errors asynchronously into SWR’s state management:

type SWRSubscriptionOptions<Data, Error> = {
  next: (err?: Error | null, data?: Data | MutatorCallback<Data>) => void
}

The subscription function type adapts if the key is a function returning parameters or a static key:

type SWRSubscription<SWRSubKey, Data, Error> =
  SWRSubKey extends () => infer Arg | null | undefined | false
    ? (key: Arg, { next }: SWRSubscriptionOptions<Data, Error>) => void
    : SWRSubKey extends null | undefined | false
    ? never
    : SWRSubKey extends infer Arg
    ? (key: Arg, { next }: SWRSubscriptionOptions<Data, Error>) => void
    : never

This conditional typing ensures that subscription implementations receive the correct key argument shape, promoting both flexibility and type safety.

Relationship

Subscription Types serve as the foundation for the Subscription Middleware by:

By defining these types separately, the system supports extensible subscription implementations, facilitates code reuse, and improves developer experience with robust autocomplete and compile-time checks.


Diagram

classDiagram
    class SWRSubscriptionOptions {
        +next(err?: Error|null, data?: Data|MutatorCallback<Data>): void
    }

    class SWRSubscription {
        <<type>>
        +invoke(key: Arg, options: SWRSubscriptionOptions): void
    }

    class SWRSubscriptionResponse {
        +data: Data
        +error: Error
    }

    class SWRSubscriptionHook {
        <<type>>
        +invoke(key: SWRSubKey, subscribe: SWRSubscription, config?: SWRConfiguration): SWRSubscriptionResponse
    }

    SWRSubscriptionOptions <.. SWRSubscription : uses
    SWRSubscription --> SWRSubscriptionHook : parameter
    SWRSubscriptionResponse <-- SWRSubscriptionHook : returns

This class diagram illustrates the core types and their relationships that define the subscription contract in the system. It highlights how the subscription function uses options including the next callback to push updates, and how the subscription hook returns a typed response containing data and error states.