{"version":3,"sources":["../../../src/core/experimental/handlers-controller.ts"],"sourcesContent":["import { invariant } from 'outvariant'\nimport { type RequestHandler } from '../handlers/RequestHandler'\nimport { type WebSocketHandler } from '../handlers/WebSocketHandler'\nimport { devUtils } from '../utils/internal/devUtils'\nimport { getSiblingHandlers } from '../utils/internal/attachSiblingHandlers'\n\nexport type AnyHandler = RequestHandler | WebSocketHandler\nexport type HandlersMap = Partial<Record<AnyHandler['kind'], Array<AnyHandler>>>\n\nexport function groupHandlersByKind(handlers: Array<AnyHandler>): HandlersMap {\n  const groups: HandlersMap = {}\n\n  const pushUnique = (kind: AnyHandler['kind'], handler: AnyHandler) => {\n    const bucket = (groups[kind] ||= [])\n\n    if (!bucket.includes(handler)) {\n      bucket.push(handler)\n    }\n  }\n\n  /**\n   * @note `Object.groupBy` is not implemented in Node.js v20.\n   */\n  for (const handler of handlers) {\n    pushUnique(handler.kind, handler)\n\n    for (const sibling of getSiblingHandlers(handler)) {\n      pushUnique(sibling.kind, sibling)\n    }\n  }\n\n  return groups\n}\n\nexport interface HandlersControllerState {\n  initialHandlers: HandlersMap\n  handlers: HandlersMap\n}\n\nexport abstract class HandlersController {\n  protected getInitialState(\n    initialHandlers: Array<AnyHandler>,\n  ): HandlersControllerState {\n    invariant(\n      this.#validateHandlers(initialHandlers),\n      devUtils.formatMessage(\n        'Failed to apply given request handlers: invalid input. Did you forget to spread the request handlers Array?',\n      ),\n    )\n\n    const normalizedInitialHandlers = groupHandlersByKind(initialHandlers)\n\n    return {\n      initialHandlers: normalizedInitialHandlers,\n      handlers: { ...normalizedInitialHandlers },\n    }\n  }\n\n  protected abstract getState(): HandlersControllerState\n  protected abstract setState(nextState: Partial<HandlersControllerState>): void\n\n  public currentHandlers(): Array<AnyHandler> {\n    return Object.values(this.getState().handlers)\n      .flat()\n      .filter((handler) => handler != null)\n  }\n\n  public getHandlersByKind(kind: AnyHandler['kind']): Array<AnyHandler> {\n    return this.getState().handlers[kind] || []\n  }\n\n  public use(nextHandlers: Array<AnyHandler>): void {\n    invariant(\n      this.#validateHandlers(nextHandlers),\n      devUtils.formatMessage(\n        '[MSW] Failed to call \"use()\" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?',\n      ),\n    )\n\n    if (nextHandlers.length === 0) {\n      return\n    }\n\n    const { handlers } = this.getState()\n    const overrides = groupHandlersByKind(nextHandlers)\n\n    // Prepend overrides to their respective kind buckets so they take\n    // priority over existing handlers while preserving input order.\n    for (const kind in overrides) {\n      const overridesForKind = overrides[kind as AnyHandler['kind']]!\n      const existingForKind = handlers[kind as AnyHandler['kind']]\n      handlers[kind as AnyHandler['kind']] = existingForKind\n        ? [...overridesForKind, ...existingForKind]\n        : overridesForKind\n    }\n\n    this.setState({ handlers })\n  }\n\n  public reset(nextHandlers: Array<AnyHandler>): void {\n    invariant(\n      nextHandlers.length > 0 ? this.#validateHandlers(nextHandlers) : true,\n      devUtils.formatMessage(\n        'Failed to replace initial handlers during reset: invalid handlers. Did you forget to spread the handlers array?',\n      ),\n    )\n\n    for (const handler of this.currentHandlers()) {\n      if ('reset' in handler) {\n        handler['reset']()\n      }\n    }\n\n    const { initialHandlers } = this.getState()\n\n    if (nextHandlers.length === 0) {\n      this.setState({\n        handlers: { ...initialHandlers },\n      })\n\n      return\n    }\n\n    const normalizedNextHandlers = groupHandlersByKind(nextHandlers)\n\n    this.setState({\n      initialHandlers: normalizedNextHandlers,\n      handlers: { ...normalizedNextHandlers },\n    })\n  }\n\n  public restore(): void {\n    for (const handler of this.currentHandlers()) {\n      if ('restore' in handler) {\n        handler['restore']()\n      }\n    }\n  }\n\n  #validateHandlers(handlers: Array<AnyHandler>): boolean {\n    return handlers.every((handler) => !Array.isArray(handler))\n  }\n}\n\nexport class InMemoryHandlersController extends HandlersController {\n  #handlers: HandlersMap\n  #initialHandlers: HandlersMap\n\n  constructor(initialHandlers: Array<AnyHandler>) {\n    super()\n\n    const initialState = this.getInitialState(initialHandlers)\n\n    this.#initialHandlers = initialState.initialHandlers\n    this.#handlers = initialState.handlers\n  }\n\n  protected getState(): HandlersControllerState {\n    return {\n      initialHandlers: this.#initialHandlers,\n      handlers: this.#handlers,\n    }\n  }\n\n  protected setState(nextState: Partial<HandlersControllerState>): void {\n    if (nextState.initialHandlers) {\n      this.#initialHandlers = nextState.initialHandlers\n    }\n\n    if (nextState.handlers) {\n      this.#handlers = nextState.handlers\n    }\n  }\n}\n"],"mappings":"AAAA,SAAS,iBAAiB;AAC1B,eAAoC;AACpC,eAAsC;AACtC,SAAS,gBAAgB;AACzB,SAAS,0BAA0B;AAK5B,SAAS,oBAAoB,UAA0C;AAC5E,QAAM,SAAsB,CAAC;AAE7B,QAAM,aAAa,CAAC,MAA0B,YAAwB;AACpE,UAAM,SAAU,OAAO,IAAI,MAAM,CAAC;AAElC,QAAI,CAAC,OAAO,SAAS,OAAO,GAAG;AAC7B,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AAKA,aAAW,WAAW,UAAU;AAC9B,eAAW,QAAQ,MAAM,OAAO;AAEhC,eAAW,WAAW,mBAAmB,OAAO,GAAG;AACjD,iBAAW,QAAQ,MAAM,OAAO;AAAA,IAClC;AAAA,EACF;AAEA,SAAO;AACT;AAOO,MAAe,mBAAmB;AAAA,EAC7B,gBACR,iBACyB;AACzB;AAAA,MACE,KAAK,kBAAkB,eAAe;AAAA,MACtC,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,UAAM,4BAA4B,oBAAoB,eAAe;AAErE,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,UAAU,EAAE,GAAG,0BAA0B;AAAA,IAC3C;AAAA,EACF;AAAA,EAKO,kBAAqC;AAC1C,WAAO,OAAO,OAAO,KAAK,SAAS,EAAE,QAAQ,EAC1C,KAAK,EACL,OAAO,CAAC,YAAY,WAAW,IAAI;AAAA,EACxC;AAAA,EAEO,kBAAkB,MAA6C;AACpE,WAAO,KAAK,SAAS,EAAE,SAAS,IAAI,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEO,IAAI,cAAuC;AAChD;AAAA,MACE,KAAK,kBAAkB,YAAY;AAAA,MACnC,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAa,WAAW,GAAG;AAC7B;AAAA,IACF;AAEA,UAAM,EAAE,SAAS,IAAI,KAAK,SAAS;AACnC,UAAM,YAAY,oBAAoB,YAAY;AAIlD,eAAW,QAAQ,WAAW;AAC5B,YAAM,mBAAmB,UAAU,IAA0B;AAC7D,YAAM,kBAAkB,SAAS,IAA0B;AAC3D,eAAS,IAA0B,IAAI,kBACnC,CAAC,GAAG,kBAAkB,GAAG,eAAe,IACxC;AAAA,IACN;AAEA,SAAK,SAAS,EAAE,SAAS,CAAC;AAAA,EAC5B;AAAA,EAEO,MAAM,cAAuC;AAClD;AAAA,MACE,aAAa,SAAS,IAAI,KAAK,kBAAkB,YAAY,IAAI;AAAA,MACjE,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,eAAW,WAAW,KAAK,gBAAgB,GAAG;AAC5C,UAAI,WAAW,SAAS;AACtB,gBAAQ,OAAO,EAAE;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,EAAE,gBAAgB,IAAI,KAAK,SAAS;AAE1C,QAAI,aAAa,WAAW,GAAG;AAC7B,WAAK,SAAS;AAAA,QACZ,UAAU,EAAE,GAAG,gBAAgB;AAAA,MACjC,CAAC;AAED;AAAA,IACF;AAEA,UAAM,yBAAyB,oBAAoB,YAAY;AAE/D,SAAK,SAAS;AAAA,MACZ,iBAAiB;AAAA,MACjB,UAAU,EAAE,GAAG,uBAAuB;AAAA,IACxC,CAAC;AAAA,EACH;AAAA,EAEO,UAAgB;AACrB,eAAW,WAAW,KAAK,gBAAgB,GAAG;AAC5C,UAAI,aAAa,SAAS;AACxB,gBAAQ,SAAS,EAAE;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBAAkB,UAAsC;AACtD,WAAO,SAAS,MAAM,CAAC,YAAY,CAAC,MAAM,QAAQ,OAAO,CAAC;AAAA,EAC5D;AACF;AAEO,MAAM,mCAAmC,mBAAmB;AAAA,EACjE;AAAA,EACA;AAAA,EAEA,YAAY,iBAAoC;AAC9C,UAAM;AAEN,UAAM,eAAe,KAAK,gBAAgB,eAAe;AAEzD,SAAK,mBAAmB,aAAa;AACrC,SAAK,YAAY,aAAa;AAAA,EAChC;AAAA,EAEU,WAAoC;AAC5C,WAAO;AAAA,MACL,iBAAiB,KAAK;AAAA,MACtB,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEU,SAAS,WAAmD;AACpE,QAAI,UAAU,iBAAiB;AAC7B,WAAK,mBAAmB,UAAU;AAAA,IACpC;AAEA,QAAI,UAAU,UAAU;AACtB,WAAK,YAAY,UAAU;AAAA,IAC7B;AAAA,EACF;AACF;","names":[]}