import { $nameof } from "rbxts-transform-debug" ; import ClientAsyncFunction from "../client/ClientAsyncFunction" ; import ClientEvent from "../client/ClientEvent" ; import ClientFunction from "../client/ClientFunction" ; import { InferDefinition , ToClientBuilder } from "./NamespaceBuilder" ; import { AsyncClientFunctionDeclaration , DeclarationsOf , FilterGroups , NamespaceDeclaration , InferClientCallback , InferClientConnect , InferClientRemote , InferGroupDeclaration , RemoteDeclarations , ServerToClientEventDeclaration , } from "./Types" ; const declarationMap = new WeakMap < ClientDefinitionBuilder < RemoteDeclarations > , RemoteDeclarations > ( ) ; export class ClientDefinitionBuilder < T extends RemoteDeclarations > { public constructor ( declarations , private namespace = "" ) { declarationMap . set ( this , declarations ) ; } internal public toString ( ) { return `[${ $nameof ( ClientDefinitionBuilder ) }]` ; } /**
     * (Internally uses  WaitFor )
     *
     * Will yield the current thread until the remote is found, or after 60 seconds will error.
     *
     * If you want to fetch the remote asynchronously, please use  WaitFor instead.
     *
     *  param remoteId see OnEvent ,  OnFunction for nicer functional alternatives to grabbing remotes.
      Get < K extends keyof T & string > ( remoteId ) { return this . WaitFor ( remoteId ) . expect ( ) ; } param groupName GetNamespace < K extends keyof FilterGroups < T > & string > ( groupName ) { const group = declarationMap . get ( this ) ! [ groupName ] as NamespaceDeclaration < RemoteDeclarations > ; assert ( group . Type === "Namespace" ) ; return group . Definitions . _buildClientDefinition ( this . namespace !== "" ? [ this . namespace , groupName ] . join ( ":" ) : groupName ) ; } param remoteId see OnEvent ,  OnFunction for nicer functional alternatives to grabbing remotes.
      async WaitFor < K extends keyof T & string > ( remoteId ) { const item = declarationMap . get ( this ) ! [ remoteId ] ; remoteId = this . namespace !== "" ? ( [ this . namespace , remoteId ] . join ( ":" ) as K ) : remoteId ; assert ( item && item . Type , `'${ remoteId }' is not defined in this definition.` ) ; if ( item . Type === "Function" ) { return ClientFunction . Wait ( remoteId ) as Promise < InferClientRemote < T [ K ] > > ; } else if ( item . Type === "Event" ) { return ClientEvent . Wait ( remoteId ) as Promise < InferClientRemote < T [ K ] > > ; } else if ( item . Type === "AsyncFunction" ) { return ClientAsyncFunction . Wait ( remoteId ) as Promise < InferClientRemote < T [ K ] > > ; } throw `Invalid Type` ; } param name param fn async OnEvent < K extends keyof DeclarationsOf < T , ServerToClientEventDeclaration < unknown [ ] > > & string > ( name , fn ) { const result = ( await this . WaitFor ( name ) ) as InferClientRemote < ServerToClientEventDeclaration < any > > ; result . Connect ( fn ) ; } param name param fn async OnFunction < K extends keyof DeclarationsOf < T , AsyncClientFunctionDeclaration < any , any > > & string > ( name , fn ) { const result = ( await this . WaitFor ( name ) ) as InferClientRemote < AsyncClientFunctionDeclaration < any , any > > ; result . SetCallback ( fn ) ; } }