Unverified Commit c6a44140 authored by Hong Minhee's avatar Hong Minhee
Browse files

Fix JSR publishing hang by removing function overloads

The @fedify/testing package was hanging indefinitely during JSR's type
analysis stage. After extensive binary search testing, the root cause
was identified as TypeScript function overload signatures in MockContext
and MockFederation classes.

Removed all function overloads from the following methods:

- MockContext.sendActivity (had 5 overload signatures)
- MockContext.lookupNodeInfo (had 2 overload signatures)
- MockContext.getDocumentLoader (had 2 overload signatures)
- MockContext.getInboxUri (had 2 overload signatures)
- MockFederation.createContext (had 2 overload signatures)

All overloaded methods have been simplified to single signatures using
`any` types where necessary. This is a workaround for a bug in JSR's
type analyzer that struggles with certain function overload patterns.

Also removed unused imports that resulted from simplifying the type
signatures.

Fixes https://github.com/fedify-dev/fedify/issues/464



Co-Authored-By: default avatarClaude <noreply@anthropic.com>
parent 2c9d075a
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -10,13 +10,11 @@ To be released.

### @fedify/testing

 -  **Breaking change:** The `MockContext` class is no longer exported from
    the public API.  This was necessary to fix JSR publishing hanging
    indefinitely at the *processing* stage, as the class contained complex
    type dependencies that caused JSR's type analyzer to hang during
    processing.  If you were using `MockContext` directly, please use
    `createContext()`, `createRequestContext()`, or `createInboxContext()`
    functions instead.  [[#468], [#470]]
 -  Fixed JSR publishing hanging indefinitely at the *processing* stage.
    The issue was caused by TypeScript function overload signatures in
    `MockContext` and `MockFederation` classes that triggered a bug in JSR's
    type analyzer.  All method overloads have been removed and simplified to
    use `any` types where necessary.  [[#468], [#470]]

[#468]: https://github.com/fedify-dev/fedify/issues/468
[#470]: https://github.com/fedify-dev/fedify/pull/470
+12 −81
Original line number Diff line number Diff line
@@ -18,11 +18,7 @@ import type {
  ParseUriResult,
  RequestContext,
  RouteActivityOptions,
  SendActivityOptions,
  SendActivityOptionsForCollection,
  SenderKeyPair,
} from "@fedify/fedify/federation";
import type { JsonValue, NodeInfo } from "@fedify/fedify/nodeinfo";
import type { DocumentLoader } from "@fedify/fedify/runtime";
import type {
  Activity,
@@ -499,15 +495,10 @@ export class MockFederation<TContextData> implements Federation<TContextData> {
    // no queue in mock type. process immediately
  }

  createContext(baseUrl: URL, contextData: TContextData): Context<TContextData>;
  createContext(
    request: Request,
    contextData: TContextData,
  ): RequestContext<TContextData>;
  createContext(
    baseUrlOrRequest: URL | Request,
    baseUrlOrRequest: any,
    contextData: TContextData,
  ): Context<TContextData> | RequestContext<TContextData> {
  ): any {
    // deno-lint-ignore no-this-alias
    const mockFederation = this;

@@ -675,7 +666,7 @@ export class MockContext<TContextData> implements Context<TContextData> {

  private sentActivities: Array<{
    sender: any;
    recipients: Recipient | Recipient[] | "followers";
    recipients: any;
    activity: Activity;
  }> = [];

@@ -769,9 +760,7 @@ export class MockContext<TContextData> implements Context<TContextData> {
    return new URL(`/users/${identifier}/outbox`, this.origin);
  }

  getInboxUri(identifier: string): URL;
  getInboxUri(): URL;
  getInboxUri(identifier?: string): URL {
  getInboxUri(identifier?: any): URL {
    if (identifier) {
      if (
        this.federation instanceof MockFederation && this.federation.inboxPath
@@ -888,13 +877,7 @@ export class MockContext<TContextData> implements Context<TContextData> {
    return Promise.resolve([]);
  }

  getDocumentLoader(
    params: { handle: string } | { identifier: string },
  ): Promise<DocumentLoader>;
  getDocumentLoader(
    params: { keyId: URL; privateKey: CryptoKey },
  ): DocumentLoader;
  getDocumentLoader(params: any): DocumentLoader | Promise<DocumentLoader> {
  getDocumentLoader(params: any): any {
    // return the same document loader
    if ("keyId" in params) {
      return this.documentLoader;
@@ -922,17 +905,9 @@ export class MockContext<TContextData> implements Context<TContextData> {
  }

  lookupNodeInfo(
    url: URL | string,
    options?: { parse?: "strict" | "best-effort" } & any,
  ): Promise<NodeInfo | undefined>;
  lookupNodeInfo(
    url: URL | string,
    options?: { parse: "none" } & any,
  ): Promise<JsonValue | undefined>;
  lookupNodeInfo(
    _url: URL | string,
    _url: any,
    _options?: any,
  ): Promise<NodeInfo | JsonValue | undefined> {
  ): Promise<any> {
    return Promise.resolve(undefined);
  }

@@ -944,49 +919,10 @@ export class MockContext<TContextData> implements Context<TContextData> {
  }

  sendActivity(
    sender:
      | SenderKeyPair
      | SenderKeyPair[]
      | { identifier: string }
      | { username: string }
      | { handle: string },
    recipients: Recipient | Recipient[],
    activity: Activity,
    options?: SendActivityOptions,
  ): Promise<void>;
  sendActivity(
    sender: { identifier: string } | { username: string } | { handle: string },
    recipients: "followers",
    sender: any,
    recipients: any,
    activity: Activity,
    options?: SendActivityOptionsForCollection,
  ): Promise<void>;
  sendActivity(
    sender:
      | SenderKeyPair
      | SenderKeyPair[]
      | { identifier: string }
      | { username: string }
      | { handle: string },
    recipients: Recipient | Recipient[],
    activity: Activity,
    options?: SendActivityOptions,
  ): Promise<void>;
  sendActivity(
    sender: { identifier: string } | { username: string } | { handle: string },
    recipients: "followers",
    activity: Activity,
    options?: SendActivityOptionsForCollection,
  ): Promise<void>;
  sendActivity(
    sender:
      | SenderKeyPair
      | SenderKeyPair[]
      | { identifier: string }
      | { username: string }
      | { handle: string },
    recipients: Recipient | Recipient[] | "followers",
    activity: Activity,
    _options?: SendActivityOptions | SendActivityOptionsForCollection,
    _options?: any,
  ): Promise<void> {
    this.sentActivities.push({ sender, recipients, activity });

@@ -1020,13 +956,8 @@ export class MockContext<TContextData> implements Context<TContextData> {
   * @returns An array of sent activity records.
   */
  getSentActivities(): Array<{
    sender:
      | SenderKeyPair
      | SenderKeyPair[]
      | { identifier: string }
      | { username: string }
      | { handle: string };
    recipients: Recipient | Recipient[] | "followers";
    sender: any;
    recipients: any;
    activity: Activity;
  }> {
    return [...this.sentActivities];