Unverified Commit 7f62c170 authored by Hong Minhee's avatar Hong Minhee
Browse files

Merge pull request #352 from allouis/fix-preloaded-context-reads

parents fea6e96f a2a79202
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -8,6 +8,13 @@ Version 1.7.8

To be released.

 -  Updated `kvCache()` wrapper to read from preloaded contexts rather than
    from the `KvStore`. This saves network and disk overheads when parsing
    activities and objects using the JSON-LD processor.
    [[#352] by Fabien O'Carroll]

[#352]: https://github.com/fedify-dev/fedify/pull/352


Version 1.7.7
-------------
+84 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import { mockDocumentLoader } from "../testing/docloader.ts";
import { test } from "../testing/mod.ts";
import preloadedContexts from "./contexts.ts";
import {
  type DocumentLoader,
  FetchError,
  getDocumentLoader,
  getUserAgent,
@@ -516,6 +517,89 @@ test("kvCache()", async (t) => {
      },
    });
  });

  await t.step("preloaded contexts bypass cache", async () => {
    const kv = new MemoryKvStore();
    let loaderCalled = false;
    const mockLoader: DocumentLoader = (url: string) => {
      loaderCalled = true;
      return Promise.resolve({
        contextUrl: null,
        documentUrl: url,
        document: { "mock": "document" },
      });
    };

    const loader = kvCache({
      kv,
      loader: mockLoader,
      prefix: ["_test", "preloaded"],
    });

    // Test that preloaded context URLs return preloaded data without calling the wrapped loader
    const activityStreamsUrl = "https://www.w3.org/ns/activitystreams";
    loaderCalled = false;
    const result = await loader(activityStreamsUrl);

    assertEquals(result, {
      contextUrl: null,
      documentUrl: activityStreamsUrl,
      document: preloadedContexts[activityStreamsUrl],
    });
    assertEquals(
      loaderCalled,
      false,
      "Loader should not be called for preloaded contexts",
    );

    // Verify that the preloaded context was not cached in KV store
    const cachedValue = await kv.get([
      "_test",
      "preloaded",
      activityStreamsUrl,
    ]);
    assertEquals(
      cachedValue,
      undefined,
      "Preloaded contexts should not be cached in KV store",
    );

    // Test another preloaded context
    const securityUrl = "https://w3id.org/security/v1";
    loaderCalled = false;
    const result2 = await loader(securityUrl);

    assertEquals(result2, {
      contextUrl: null,
      documentUrl: securityUrl,
      document: preloadedContexts[securityUrl],
    });
    assertEquals(
      loaderCalled,
      false,
      "Loader should not be called for preloaded contexts",
    );

    // Test that non-preloaded URLs still use the cache normally
    const nonPreloadedUrl = "https://example.com/not-preloaded";
    loaderCalled = false;
    const result3 = await loader(nonPreloadedUrl);

    assertEquals(result3, {
      contextUrl: null,
      documentUrl: nonPreloadedUrl,
      document: { "mock": "document" },
    });
    assertEquals(
      loaderCalled,
      true,
      "Loader should be called for non-preloaded URLs",
    );

    // Verify that non-preloaded URL was cached
    const cachedValue2 = await kv.get(["_test", "preloaded", nonPreloadedUrl]);
    assertEquals(cachedValue2, result3, "Non-preloaded URLs should be cached");
  });
});

test("getUserAgent()", () => {
+8 −0
Original line number Diff line number Diff line
@@ -456,6 +456,14 @@ export function kvCache(
  }

  return async (url: string): Promise<RemoteDocument> => {
    if (url in preloadedContexts) {
      logger.debug("Using preloaded context: {url}.", { url });
      return {
        contextUrl: null,
        document: preloadedContexts[url],
        documentUrl: url,
      };
    }
    const match = matchRule(url);
    if (match == null) return await loader(url);
    const key: KvKey = [...keyPrefix, url];