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

Refactor collection handlers

parent cf19cf40
Loading
Loading
Loading
Loading
+39 −17
Original line number Diff line number Diff line
@@ -5,9 +5,6 @@ import {
  CollectionCursor,
  CollectionDispatcher,
  InboxListener,
  OutboxCounter,
  OutboxCursor,
  OutboxDispatcher,
} from "./callback.ts";
import { RequestContext } from "./context.ts";
import { verify } from "../httpsig/mod.ts";
@@ -75,14 +72,36 @@ export async function handleActor<TContextData>(
  });
}

/**
 * Callbacks for handling a collection.
 */
export interface CollectionCallbacks<TItem, TContextData> {
  /**
   * A callback that dispatches a collection.
   */
  dispatcher: CollectionDispatcher<TItem, TContextData>;

  /**
   * A callback that counts the number of items in a collection.
   */
  counter?: CollectionCounter<TContextData>;

  /**
   * A callback that returns the first cursor for a collection.
   */
  firstCursor?: CollectionCursor<TContextData>;

  /**
   * A callback that returns the last cursor for a collection.
   */
  lastCursor?: CollectionCursor<TContextData>;
}

export interface CollectionHandlerParameters<TItem, TContextData> {
  handle: string;
  context: RequestContext<TContextData>;
  documentLoader: DocumentLoader;
  collectionDispatcher?: CollectionDispatcher<TItem, TContextData>;
  collectionCounter?: CollectionCounter<TContextData>;
  collectionFirstCursor?: CollectionCursor<TContextData>;
  collectionLastCursor?: CollectionCursor<TContextData>;
  collectionCallbacks?: CollectionCallbacks<TItem, TContextData>;
  onNotFound(request: Request): Response | Promise<Response>;
  onNotAcceptable(request: Request): Response | Promise<Response>;
}
@@ -96,15 +115,12 @@ export async function handleCollection<
    handle,
    context,
    documentLoader,
    collectionDispatcher,
    collectionCounter,
    collectionFirstCursor,
    collectionLastCursor,
    collectionCallbacks,
    onNotFound,
    onNotAcceptable,
  }: CollectionHandlerParameters<TItem, TContextData>,
): Promise<Response> {
  if (collectionDispatcher == null) {
  if (collectionCallbacks == null) {
    const response = onNotFound(request);
    return response instanceof Promise ? await response : response;
  }
@@ -116,16 +132,19 @@ export async function handleCollection<
  const cursor = url.searchParams.get("cursor");
  let collection: OrderedCollection | OrderedCollectionPage;
  if (cursor == null) {
    const firstCursorPromise = collectionFirstCursor?.(context, handle);
    const firstCursorPromise = collectionCallbacks.firstCursor?.(
      context,
      handle,
    );
    const firstCursor = firstCursorPromise instanceof Promise
      ? await firstCursorPromise
      : firstCursorPromise;
    const totalItemsPromise = collectionCounter?.(context, handle);
    const totalItemsPromise = collectionCallbacks.counter?.(context, handle);
    const totalItems = totalItemsPromise instanceof Promise
      ? await totalItemsPromise
      : totalItemsPromise;
    if (firstCursor == null) {
      const pagePromise = collectionDispatcher(context, handle, null);
      const pagePromise = collectionCallbacks.dispatcher(context, handle, null);
      const page = pagePromise instanceof Promise
        ? await pagePromise
        : pagePromise;
@@ -139,7 +158,10 @@ export async function handleCollection<
        items,
      });
    } else {
      const lastCursorPromise = collectionLastCursor?.(context, handle);
      const lastCursorPromise = collectionCallbacks.lastCursor?.(
        context,
        handle,
      );
      const lastCursor = lastCursorPromise instanceof Promise
        ? await lastCursorPromise
        : lastCursorPromise;
@@ -157,7 +179,7 @@ export async function handleCollection<
      });
    }
  } else {
    const pagePromise = collectionDispatcher(context, handle, cursor);
    const pagePromise = collectionCallbacks.dispatcher(context, handle, cursor);
    const page = pagePromise instanceof Promise
      ? await pagePromise
      : pagePromise;
+24 −22
Original line number Diff line number Diff line
@@ -16,7 +16,12 @@ import {
  InboxListener,
} from "./callback.ts";
import { Context, RequestContext } from "./context.ts";
import { handleActor, handleCollection, handleInbox } from "./handler.ts";
import {
  CollectionCallbacks,
  handleActor,
  handleCollection,
  handleInbox,
} from "./handler.ts";
import { OutboxMessage } from "./queue.ts";
import { Router, RouterError } from "./router.ts";
import { extractInboxes, sendActivity } from "./send.ts";
@@ -280,7 +285,8 @@ export class Federation<TContextData> {
   *             ([RFC 6570](https://tools.ietf.org/html/rfc6570)).  The path
   *             must have one variable: `{handle}`.
   * @param dispatcher An actor dispatcher callback to register.
   * @throws {@link RouterError} Thrown if the path pattern is invalid.
   * @returns An object with methods to set other actor dispatcher callbacks.
   * @throws {RouterError} Thrown if the path pattern is invalid.
   */
  setActorDispatcher(
    path: string,
@@ -358,7 +364,9 @@ export class Federation<TContextData> {
   *             ([RFC 6570](https://tools.ietf.org/html/rfc6570)).  The path
   *             must have one variable: `{handle}`.
   * @param dispatcher A following collection callback to register.
   * @throws {@link RouterError} Thrown if the path pattern is invalid.
   * @returns An object with methods to set other following collection
   *          callbacks.
   * @throws {RouterError} Thrown if the path pattern is invalid.
   */
  setFollowingDispatcher(
    path: string,
@@ -401,6 +409,8 @@ export class Federation<TContextData> {
   *             ([RFC 6570](https://tools.ietf.org/html/rfc6570)).  The path
   *             must have one variable: `{handle}`.
   * @param dispatcher A followers collection callback to register.
   * @returns An object with methods to set other followers collection
   *          callbacks.
   * @throws {@link RouterError} Thrown if the path pattern is invalid.
   */
  setFollowersDispatcher(
@@ -437,6 +447,14 @@ export class Federation<TContextData> {
    return setters;
  }

  /**
   * Assigns the URL patth for the inbox and starts setting inbox listeners.
   * @param path The URI path pattern for the inbox.  The syntax is based on
   *             URI Template ([RFC 6570](https://tools.ietf.org/html/rfc6570)).
   *             The path must have one variable: `{handle}`.
   * @returns An object to register inbox listeners.
   * @throws {RouteError} Thrown if the path pattern is invalid.
   */
  setInboxListeners(path: string): InboxListenerSetter<TContextData> {
    if (this.#router.has("inbox")) {
      throw new RouterError("Inbox already set.");
@@ -548,10 +566,7 @@ export class Federation<TContextData> {
          handle: route.values.handle,
          context,
          documentLoader: this.#documentLoader,
          collectionDispatcher: this.#outboxCallbacks?.dispatcher,
          collectionCounter: this.#outboxCallbacks?.counter,
          collectionFirstCursor: this.#outboxCallbacks?.firstCursor,
          collectionLastCursor: this.#outboxCallbacks?.lastCursor,
          collectionCallbacks: this.#outboxCallbacks,
          onNotFound,
          onNotAcceptable,
        });
@@ -572,10 +587,7 @@ export class Federation<TContextData> {
          handle: route.values.handle,
          context,
          documentLoader: this.#documentLoader,
          collectionDispatcher: this.#followingCallbacks?.dispatcher,
          collectionCounter: this.#followingCallbacks?.counter,
          collectionFirstCursor: this.#followingCallbacks?.firstCursor,
          collectionLastCursor: this.#followingCallbacks?.lastCursor,
          collectionCallbacks: this.#followingCallbacks,
          onNotFound,
          onNotAcceptable,
        });
@@ -584,10 +596,7 @@ export class Federation<TContextData> {
          handle: route.values.handle,
          context,
          documentLoader: this.#documentLoader,
          collectionDispatcher: this.#followersCallbacks?.dispatcher,
          collectionCounter: this.#followersCallbacks?.counter,
          collectionFirstCursor: this.#followersCallbacks?.firstCursor,
          collectionLastCursor: this.#followersCallbacks?.lastCursor,
          collectionCallbacks: this.#followersCallbacks,
          onNotFound,
          onNotAcceptable,
        });
@@ -634,13 +643,6 @@ export interface ActorCallbackSetters<TContextData> {
  ): ActorCallbackSetters<TContextData>;
}

interface CollectionCallbacks<TItem, TContextData> {
  dispatcher: CollectionDispatcher<TItem, TContextData>;
  counter?: CollectionCounter<TContextData>;
  firstCursor?: CollectionCursor<TContextData>;
  lastCursor?: CollectionCursor<TContextData>;
}

/**
 * Additional settings for a collection dispatcher.
 */
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ export async function verify(
    }
    if (!matched) return null;
  }
  const date: Temporal.Instant = new Date(dateHeader).toTemporalInstant();
  const date = Temporal.Instant.from(new Date(dateHeader).toISOString());
  const now = Temporal.Now.instant();
  if (Temporal.Instant.compare(date, now.add({ seconds: 30 })) > 0) {
    // Too far in the future