import { JsonValue, RawCoMap } from "cojson"; import { Account, AnonymousJazzAgent, CoMapInit_DEPRECATED, CoValue, CoValueBase, CoValueClass, CoValueFromRaw, CoValueJazzApi, Group, ID, Settled, RefsToResolve, RefsToResolveStrict, Resolved, Simplify, SubscribeListenerOptions, SubscribeRestArgs, loadCoValueWithoutMe, parseSubscribeRestArgs, subscribeToCoValueWithoutMe, } from "../internal.js"; /** * Extends `SchemaUnion` with a non-abstract constructor. */ export type SchemaUnionConcreteSubclass = typeof SchemaUnion & CoValueClass; export type SchemaUnionDiscriminator = (discriminable: { get(key: string): JsonValue | undefined; }) => CoValueClass & CoValueFromRaw; /** * SchemaUnion allows you to create union types of CoValues that can be discriminated at runtime. * * @category CoValues */ export abstract class SchemaUnion extends CoValueBase implements CoValue { static create( this: CoValueClass, init: Simplify>, owner: Account | Group, ): V { throw new Error("Not implemented"); } /** * Create an instance from raw data. This is called internally and should not be used directly. * Use `co.discriminatedUnion(...)` to create union schemas instead. * * @internal */ static fromRaw( this: CoValueClass, raw: V["$jazz"]["raw"], ): V { throw new Error("Not implemented"); } /** * Load a `SchemaUnion` with a given ID, as a given account. * * @category Subscription & Loading */ static load = true>( this: CoValueClass, id: ID, options?: { resolve?: RefsToResolveStrict; loadAs?: Account | AnonymousJazzAgent; skipRetry?: boolean; }, ): Promise>> { return loadCoValueWithoutMe(this, id, options); } /** * Load and subscribe to a `CoMap` with a given ID, as a given account. * * Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener. * * Returns an unsubscribe function that you should call when you no longer need updates. * * Also see the `useCoState` hook to reactively subscribe to a CoValue in a React component. * * @category Subscription & Loading */ static subscribe< M extends SchemaUnion, const R extends RefsToResolve = true, >( this: CoValueClass, id: ID, listener: (value: Resolved, unsubscribe: () => void) => void, ): () => void; static subscribe< M extends SchemaUnion, const R extends RefsToResolve = true, >( this: CoValueClass, id: ID, options: SubscribeListenerOptions, listener: (value: Resolved, unsubscribe: () => void) => void, ): () => void; static subscribe>( this: CoValueClass, id: ID, ...args: SubscribeRestArgs ): () => void { const { options, listener } = parseSubscribeRestArgs(args); return subscribeToCoValueWithoutMe(this, id, options, listener); } } /** * @internal * Create a SchemaUnion subclass from a discriminator function. */ export function schemaUnionClassFromDiscriminator( discriminator: SchemaUnionDiscriminator, ): SchemaUnionConcreteSubclass { return class SchemaUnionClass extends SchemaUnion { declare $jazz: CoValueJazzApi; static override create( this: CoValueClass, init: Simplify>, owner: Account | Group, ): V { const ResolvedClass = discriminator(new Map(Object.entries(init))); // @ts-expect-error - create is a static method in the CoMap class return ResolvedClass.create(init, owner); } static override fromRaw( this: CoValueClass & CoValueFromRaw, raw: T["$jazz"]["raw"], ): T { const ResolvedClass = discriminator( raw as RawCoMap, ) as unknown as CoValueClass & CoValueFromRaw; return ResolvedClass.fromRaw(raw); } } as unknown as SchemaUnionConcreteSubclass; }