Ctrl K
ComunidadGuías…

app/stores/RootStore.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import invariant from "invariant";
import { lowerFirst } from "es-toolkit/compat";
import pluralize from "pluralize";
import ApiKeysStore from "./ApiKeysStore";
import AuthStore from "./AuthStore";
import AuthenticationProvidersStore from "./AuthenticationProvidersStore";
import CollectionsStore from "./CollectionsStore";
import CommentsStore from "./CommentsStore";
import DialogsStore from "./DialogsStore";
import DocumentPresenceStore from "./DocumentPresenceStore";
import DocumentsStore from "./DocumentsStore";
import EventsStore from "./EventsStore";
import EmojisStore from "./EmojiStore";
import FileOperationsStore from "./FileOperationsStore";
import GroupMembershipsStore from "./GroupMembershipsStore";
import GroupUsersStore from "./GroupUsersStore";
import GroupsStore from "./GroupsStore";
import ImportsStore from "./ImportsStore";
import IntegrationsStore from "./IntegrationsStore";
import MembershipsStore from "./MembershipsStore";
import NotificationsStore from "./NotificationsStore";
import OAuthAuthenticationsStore from "./OAuthAuthenticationsStore";
import OAuthClientsStore from "./OAuthClientsStore";
import PinsStore from "./PinsStore";
import PoliciesStore from "./PoliciesStore";
import RevisionsStore from "./RevisionsStore";
import SearchesStore from "./SearchesStore";
import SharesStore from "./SharesStore";
import StarsStore from "./StarsStore";
import SubscriptionsStore from "./SubscriptionsStore";
import TemplatesStore from "./TemplatesStore";
import UiStore from "./UiStore";
import UnfurlsStore from "./UnfurlsStore";
import UserMembershipsStore from "./UserMembershipsStore";
import UsersStore from "./UsersStore";
import ViewsStore from "./ViewsStore";
import WebhookSubscriptionsStore from "./WebhookSubscriptionStore";
import Store from "./base/Store";

export default class RootStore {
  apiKeys: ApiKeysStore;
  auth: AuthStore;
  authenticationProviders: AuthenticationProvidersStore;
  collections: CollectionsStore;
  groupMemberships: GroupMembershipsStore;
  comments: CommentsStore;
  dialogs: DialogsStore;
  documents: DocumentsStore;
  emojis: EmojisStore;
  events: EventsStore;
  groups: GroupsStore;
  groupUsers: GroupUsersStore;
  imports: ImportsStore;
  integrations: IntegrationsStore;
  memberships: MembershipsStore;
  notifications: NotificationsStore;
  oauthAuthentications: OAuthAuthenticationsStore;
  oauthClients: OAuthClientsStore;
  presence: DocumentPresenceStore;
  pins: PinsStore;
  policies: PoliciesStore;
  revisions: RevisionsStore;
  searches: SearchesStore;
  shares: SharesStore;
  ui: UiStore;
  unfurls: UnfurlsStore;
  stars: StarsStore;
  subscriptions: SubscriptionsStore;
  templates: TemplatesStore;
  users: UsersStore;
  views: ViewsStore;
  fileOperations: FileOperationsStore;
  webhookSubscriptions: WebhookSubscriptionsStore;
  userMemberships: UserMembershipsStore;

  constructor() {
    // Models
    this.registerStore(ApiKeysStore);
    this.registerStore(AuthenticationProvidersStore);
    this.registerStore(CollectionsStore);
    this.registerStore(GroupMembershipsStore);
    this.registerStore(CommentsStore);
    this.registerStore(DocumentsStore);
    this.registerStore(EmojisStore);
    this.registerStore(EventsStore);
    this.registerStore(GroupsStore);
    this.registerStore(GroupUsersStore);
    this.registerStore(ImportsStore);
    this.registerStore(IntegrationsStore);
    this.registerStore(MembershipsStore);
    this.registerStore(NotificationsStore);
    this.registerStore(OAuthAuthenticationsStore, "oauthAuthentications");
    this.registerStore(OAuthClientsStore, "oauthClients");
    this.registerStore(PinsStore);
    this.registerStore(PoliciesStore);
    this.registerStore(RevisionsStore);
    this.registerStore(SearchesStore);
    this.registerStore(SharesStore);
    this.registerStore(StarsStore);
    this.registerStore(SubscriptionsStore);
    this.registerStore(TemplatesStore);
    this.registerStore(UnfurlsStore);
    this.registerStore(UsersStore);
    this.registerStore(ViewsStore);
    this.registerStore(FileOperationsStore);
    this.registerStore(WebhookSubscriptionsStore);
    this.registerStore(UserMembershipsStore);

    // Non-models
    this.registerStore(DocumentPresenceStore, "presence");
    this.registerStore(DialogsStore, "dialogs");
    this.registerStore(UiStore, "ui");

    // AuthStore must be initialized last as it makes use of the other stores.
    this.registerStore(AuthStore, "auth");

    // AuthStore will have synchronously rehydrated the current team from
    // localStorage at this point, if a session exists.
    this.enablePersistence();
  }

  /**
   * Enable IndexedDB persistence for all stores marked as persistable, scoped
   * to the current team. A no-op when there is no authenticated team or
   * persistence is already enabled.
   */
  public enablePersistence() {
    const teamId = this.auth.currentTeamId;
    if (!teamId) {
      return;
    }

    Object.values(this).forEach((store) => {
      if (store instanceof Store) {
        void store.enablePersistence(teamId);
      }
    });
  }

  /**
   * Disable IndexedDB persistence for all stores, closing any open connections
   * so that the databases can be deleted or upgraded.
   */
  public disablePersistence() {
    Object.values(this).forEach((store) => {
      if (store instanceof Store) {
        store.disablePersistence();
      }
    });
  }

  /**
   * Get a store by model name.
   *
   * @param modelName
   */
  public getStoreForModelName<K extends keyof RootStore>(modelName: string) {
    const storeName = this.getStoreNameForModelName(modelName);
    invariant(storeName, `No store found for model name "${modelName}"`);

    const store = this[storeName];
    return store as RootStore[K];
  }

  /**
   * Clear all data from the stores except for auth and ui.
   */
  public clear() {
    Object.getOwnPropertyNames(this)
      .filter((key) => ["auth", "ui"].includes(key) === false)
      .forEach((key: keyof RootStore) => {
        if ("clear" in this[key]) {
          // @ts-expect-error clear exists on all stores
          this[key].clear();
        }
      });
  }

  /**
   * Register a store with the root store.
   *
   * @param StoreClass
   */
  private registerStore<T = typeof Store>(
    StoreClass: T,
    name?: keyof RootStore
  ) {
    // @ts-expect-error TS thinks we are instantiating an abstract class.
    const store = new StoreClass(this);
    const storeName = name ?? this.getStoreNameForModelName(store.modelName);
    invariant(storeName, `No store found for model name "${store.modelName}"`);

    this[storeName] = store;
  }

  private getStoreNameForModelName(modelName: string) {
    for (const key of Object.keys(this)) {
      const store = this[key as keyof RootStore];
      if (store && "modelName" in store && store.modelName === modelName) {
        return key as keyof RootStore;
      }
    }

    const storeName = pluralize(lowerFirst(modelName)) as keyof RootStore;
    if (storeName) {
      return storeName;
    }

    return undefined;
  }
}