Skip to content

Commit 4c0d7ba

Browse files
feat(core): prevent caching of ephemeral events
Ephemeral events (kind 20000-29999) are not meant to be stored. This change prevents them from being saved to the cache. A test case has been added to ensure that ephemeral events are not passed to the cache adapter.
1 parent 0de3c74 commit 4c0d7ba

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

core/src/subscription.test.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
1+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
22
import { EventGenerator, RelayPoolMock } from "../test";
3-
import NDK, { type NDKEvent, type NDKFilter, NDKKind, type NDKRelay, NDKRelaySet, NDKSubscription } from "./index";
3+
import NDK, {
4+
NDKSubscriptionCacheUsage,
5+
type NDKEvent,
6+
type NDKFilter,
7+
NDKKind,
8+
type NDKRelay,
9+
NDKRelaySet,
10+
NDKSubscription,
11+
} from "./index";
412

513
describe("NDKSubscription", () => {
614
let ndk: NDK;
@@ -120,4 +128,48 @@ describe("NDKSubscription", () => {
120128
expect(eoseReceived).toBe(true);
121129
expect(closedReceived).toBe(true);
122130
});
131+
132+
it("should not cache ephemeral events", async () => {
133+
// Mock cache adapter
134+
const mockCacheAdapter = {
135+
setEvent: vi.fn(),
136+
query: vi.fn().mockResolvedValue([]),
137+
};
138+
// @ts-expect-error - We're intentionally replacing the cache for testing
139+
ndk.cacheAdapter = mockCacheAdapter;
140+
141+
// Create replaceable and ephemeral events
142+
const replaceableEvent = EventGenerator.createEvent(10002, "replaceable");
143+
await replaceableEvent.sign();
144+
const ephemeralEvent = EventGenerator.createEvent(20000, "ephemeral");
145+
await ephemeralEvent.sign();
146+
147+
// Get the first relay
148+
const relaysArray = Array.from(pool.relays);
149+
const mockRelay = relaysArray[0];
150+
const relaySet = new NDKRelaySet(new Set([mockRelay as unknown as NDKRelay]), ndk);
151+
const filter: NDKFilter = {
152+
kinds: [replaceableEvent.kind as number, ephemeralEvent.kind as number],
153+
};
154+
const sub = new NDKSubscription(ndk, filter, {
155+
subId: "test-subscription-cache",
156+
skipVerification: true,
157+
skipValidation: true,
158+
relaySet,
159+
cacheUsage: NDKSubscriptionCacheUsage.ONLY_RELAY,
160+
});
161+
162+
// Start subscription and simulate events
163+
sub.start();
164+
await mockRelay.simulateEvent(replaceableEvent, sub.subId!);
165+
await mockRelay.simulateEvent(ephemeralEvent, sub.subId!);
166+
mockRelay.simulateEOSE(sub.subId!);
167+
// Verify cache adapter was only called for the replaceable event
168+
expect(mockCacheAdapter.setEvent).toHaveBeenCalledTimes(1);
169+
expect(mockCacheAdapter.setEvent).toHaveBeenCalledWith(
170+
expect.objectContaining({ id: replaceableEvent.id }),
171+
expect.any(Array),
172+
expect.any(Object)
173+
);
174+
});
123175
});

core/src/subscription/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ export class NDKSubscription extends EventEmitter<{
823823
}
824824
}
825825

826-
if (this.ndk.cacheAdapter && !this.opts.dontSaveToCache) {
826+
if (this.ndk.cacheAdapter && !this.opts.dontSaveToCache && !kindIsEphemeral(ndkEvent.kind as NDKKind)) {
827827
this.ndk.cacheAdapter.setEvent(ndkEvent, this.filters, relay);
828828
}
829829
}

0 commit comments

Comments
 (0)