import type { Canonical } from "atom.io/foundations/canonical" import type { Fn } from "atom.io/internal" import { arbitrary, IMPLICIT, subscribeInStore } from "atom.io/internal" import type { StateUpdate, TimelineUpdate, TransactionOutcomeEvent, } from "./events.ts" import type { TimelineManageable } from "./timeline.ts" import type { ReadableToken, TimelineFamilyToken, TimelineToken, TransactionToken, } from "./tokens.ts" export type UpdateHandler = (update: StateUpdate) => void export type TransactionUpdateHandler = ( data: TransactionOutcomeEvent>, ) => void /** * Subscribe to a state in the implicit store * @param token - The token of the state to subscribe to * @param handleUpdate - A function that will be called when the state is updated * @param key - A unique key for the subscription. If not provided, a random key will be generated. * @returns A function that can be called to unsubscribe from the state * @overload State */ export function subscribe( token: ReadableToken, handleUpdate: UpdateHandler, key?: string, ): () => void /** * Subscribe to a transaction in the implicit store * @param token - The token of the transaction to subscribe to * @param handleUpdate - A function that will be called when the transaction succeeds * @param key - A unique key for the subscription. If not provided, a random key will be generated. * @returns A function that can be called to unsubscribe from the transaction * @overload Transaction */ export function subscribe( token: TransactionToken, handleUpdate: TransactionUpdateHandler, key?: string, ): () => void /** * Subscribe to a timeline in the implicit store * @param token - The token of the timeline to subscribe to * @param handleUpdate - A function that will be called when a new update is available * @param key - A unique key for the subscription. If not provided, a random key will be generated. * @returns A function that can be called to unsubscribe from the timeline * @overload Timeline */ export function subscribe( token: TimelineToken, handleUpdate: (update: TimelineUpdate) => void, key?: string, ): () => void /** * Subscribe to a timeline-family member in the implicit store, creating it if needed. * @param family - A {@link TimelineFamilyToken}. * @param memberKey - The key of the timeline-family member. * @param handleUpdate - A function that will be called when a new update is available. * @param subscriptionKey - A unique key for the subscription. If not provided, a random key will be generated. * @returns A function that can be called to unsubscribe from the timeline-family member. * @overload Timeline Family Member */ export function subscribe( family: TimelineFamilyToken, memberKey: NoInfer, handleUpdate: (update: TimelineUpdate) => void, subscriptionKey?: string, ): () => void export function subscribe(...params: any[]): () => void { if (params[0].type === `timeline_family`) { return subscribeInStore( IMPLICIT.STORE, params[0], params[1] as Canonical, params[2] as (update: TimelineUpdate) => void, params[3] ?? arbitrary(), ) } return subscribeInStore( IMPLICIT.STORE, params[0] as ReadableToken | TimelineToken | TransactionToken, params[1] as (update: any) => void, (params[2] as string | undefined) ?? arbitrary(), ) }