@orpc/publisher 2.0.0-beta.18 → 2.0.0-beta.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,11 +49,14 @@ You can read the documentation [here](https://orpc.dev).
49
49
  **Framework & ecosystem integrations**
50
50
 
51
51
  - [@orpc/next](https://www.npmjs.com/package/@orpc/next): Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
52
+ - [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
52
53
  - [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
54
+ - [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
53
55
  - [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
54
56
  - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
55
57
  - [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).
56
58
  - [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/).
59
+ - [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc): Reuse existing [tRPC](https://trpc.io/) routers within oRPC.
57
60
 
58
61
  **Observability**
59
62
 
@@ -105,11 +108,10 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
105
108
  <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&amp;v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
106
109
  <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&amp;v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
107
110
  <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&amp;v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
108
- <td align="center"><a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="139" alt="Andrew Peters"/><br />Andrew Peters</a></td>
109
111
  <td align="center"><a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&amp;v=4" width="139" alt="Ryan Vogel"/><br />Ryan Vogel</a></td>
112
+ <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
110
113
  </tr>
111
114
  <tr>
112
- <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
113
115
  <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
114
116
  <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="139" alt="shota"/><br />shota</a></td>
115
117
  </tr>
@@ -169,6 +171,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
169
171
  <a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&amp;v=4" width="32" height="32" alt="Nelson Lai" /></a>
170
172
  <a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&amp;v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a>
171
173
  <a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&amp;v=4" width="32" height="32" alt="Robert Soriano" /></a>
174
+ <a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a>
172
175
  <a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a>
173
176
  <a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&amp;v=4" width="32" height="32" alt="Peter Adam" /></a>
174
177
  <a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a>
@@ -3,16 +3,16 @@ import '@orpc/shared';
3
3
 
4
4
  interface MemoryPublisherOptions extends PublisherOptions {
5
5
  /**
6
- * Configuration for event replay support.
6
+ * Configuration for event resume support.
7
7
  *
8
8
  * When enabled, published events are temporarily stored so new
9
9
  * subscribers can resume from a previous position using `lastEventId`.
10
10
  *
11
11
  * @default { enabled: false }
12
12
  */
13
- replay?: {
13
+ resume?: {
14
14
  /**
15
- * Whether event replay support is enabled.
15
+ * Whether event resume support is enabled.
16
16
  *
17
17
  * When enabled, published events are temporarily stored so new
18
18
  * subscribers can resume from a previous position using `lastEventId`.
@@ -21,7 +21,7 @@ interface MemoryPublisherOptions extends PublisherOptions {
21
21
  */
22
22
  enabled: boolean;
23
23
  /**
24
- * How long (in seconds) to retain events for replay.
24
+ * How long (in seconds) to retain events for resume.
25
25
  *
26
26
  * Expired events are cleaned up lazily for performance reasons, so
27
27
  * some events may remain available slightly longer than this period.
@@ -35,9 +35,9 @@ declare class MemoryPublisher<T extends Record<string, object>> extends Publishe
35
35
  private readonly listenersMap;
36
36
  private readonly idGenerator;
37
37
  private readonly eventsMap;
38
- private readonly replayEnabled;
39
- private readonly replaySeconds;
40
- constructor({ replay, ...options }?: MemoryPublisherOptions);
38
+ private readonly resumeEnabled;
39
+ private readonly resumeSeconds;
40
+ constructor({ resume, ...options }?: MemoryPublisherOptions);
41
41
  publish<K extends keyof T & string>(event: K, payload: T[K]): Promise<void>;
42
42
  protected subscribeListener<K extends keyof T & string>(event: K, listener: (payload: T[K]) => void, options?: PublisherSubscribeListenerOptions): Promise<() => Promise<void>>;
43
43
  private lastCleanupTime;
@@ -3,16 +3,16 @@ import '@orpc/shared';
3
3
 
4
4
  interface MemoryPublisherOptions extends PublisherOptions {
5
5
  /**
6
- * Configuration for event replay support.
6
+ * Configuration for event resume support.
7
7
  *
8
8
  * When enabled, published events are temporarily stored so new
9
9
  * subscribers can resume from a previous position using `lastEventId`.
10
10
  *
11
11
  * @default { enabled: false }
12
12
  */
13
- replay?: {
13
+ resume?: {
14
14
  /**
15
- * Whether event replay support is enabled.
15
+ * Whether event resume support is enabled.
16
16
  *
17
17
  * When enabled, published events are temporarily stored so new
18
18
  * subscribers can resume from a previous position using `lastEventId`.
@@ -21,7 +21,7 @@ interface MemoryPublisherOptions extends PublisherOptions {
21
21
  */
22
22
  enabled: boolean;
23
23
  /**
24
- * How long (in seconds) to retain events for replay.
24
+ * How long (in seconds) to retain events for resume.
25
25
  *
26
26
  * Expired events are cleaned up lazily for performance reasons, so
27
27
  * some events may remain available slightly longer than this period.
@@ -35,9 +35,9 @@ declare class MemoryPublisher<T extends Record<string, object>> extends Publishe
35
35
  private readonly listenersMap;
36
36
  private readonly idGenerator;
37
37
  private readonly eventsMap;
38
- private readonly replayEnabled;
39
- private readonly replaySeconds;
40
- constructor({ replay, ...options }?: MemoryPublisherOptions);
38
+ private readonly resumeEnabled;
39
+ private readonly resumeSeconds;
40
+ constructor({ resume, ...options }?: MemoryPublisherOptions);
41
41
  publish<K extends keyof T & string>(event: K, payload: T[K]): Promise<void>;
42
42
  protected subscribeListener<K extends keyof T & string>(event: K, listener: (payload: T[K]) => void, options?: PublisherSubscribeListenerOptions): Promise<() => Promise<void>>;
43
43
  private lastCleanupTime;
@@ -6,17 +6,17 @@ class MemoryPublisher extends Publisher {
6
6
  listenersMap = /* @__PURE__ */ new Map();
7
7
  idGenerator = new SequentialIdGenerator();
8
8
  eventsMap = /* @__PURE__ */ new Map();
9
- replayEnabled;
10
- replaySeconds;
11
- constructor({ replay, ...options } = {}) {
9
+ resumeEnabled;
10
+ resumeSeconds;
11
+ constructor({ resume, ...options } = {}) {
12
12
  super(options);
13
- this.replayEnabled = replay?.enabled ?? false;
14
- this.replaySeconds = replay?.seconds ?? 300;
13
+ this.resumeEnabled = resume?.enabled ?? false;
14
+ this.resumeSeconds = resume?.seconds ?? 300;
15
15
  }
16
16
  async publish(event, payload) {
17
17
  this.cleanup();
18
- if (this.replayEnabled) {
19
- const expiresAt = Date.now() + this.replaySeconds * 1e3;
18
+ if (this.resumeEnabled) {
19
+ const expiresAt = Date.now() + this.resumeSeconds * 1e3;
20
20
  let bucket = this.eventsMap.get(event);
21
21
  if (!bucket) {
22
22
  this.eventsMap.set(event, bucket = []);
@@ -30,10 +30,10 @@ class MemoryPublisher extends Publisher {
30
30
  }
31
31
  async subscribeListener(event, listener, options) {
32
32
  this.cleanup();
33
- if (this.replayEnabled && options?.lastEventId !== void 0) {
33
+ if (this.resumeEnabled && options?.lastEventId !== void 0) {
34
34
  const bucket = this.eventsMap.get(event);
35
35
  if (bucket?.length) {
36
- const startIdx = findReplayStartIndex(bucket, options.lastEventId);
36
+ const startIdx = findResumeStartIndex(bucket, options.lastEventId);
37
37
  for (let i = startIdx; i < bucket.length; i++) {
38
38
  listener(bucket[i].payload);
39
39
  }
@@ -53,11 +53,11 @@ class MemoryPublisher extends Publisher {
53
53
  }
54
54
  lastCleanupTime = 0;
55
55
  cleanup() {
56
- if (!this.replayEnabled) {
56
+ if (!this.resumeEnabled) {
57
57
  return;
58
58
  }
59
59
  const now = Date.now();
60
- if (now - this.lastCleanupTime < this.replaySeconds * 1e3) {
60
+ if (now - this.lastCleanupTime < this.resumeSeconds * 1e3) {
61
61
  return;
62
62
  }
63
63
  this.lastCleanupTime = now;
@@ -69,7 +69,7 @@ class MemoryPublisher extends Publisher {
69
69
  }
70
70
  }
71
71
  }
72
- function findReplayStartIndex(bucket, lastEventId) {
72
+ function findResumeStartIndex(bucket, lastEventId) {
73
73
  let lo = 0;
74
74
  let hi = bucket.length;
75
75
  while (lo < hi) {
@@ -25,16 +25,16 @@ interface RedisPublisherOptions extends PublisherOptions {
25
25
  */
26
26
  serializer?: undefined | Pick<RPCSerializer, keyof RPCSerializer>;
27
27
  /**
28
- * Configuration for event replay support.
28
+ * Configuration for event resume support.
29
29
  *
30
30
  * When enabled, published events are temporarily stored so new
31
31
  * subscribers can resume from a previous position using `lastEventId`.
32
32
  *
33
33
  * @default { enabled: false }
34
34
  */
35
- replay?: {
35
+ resume?: {
36
36
  /**
37
- * Whether event replay support is enabled.
37
+ * Whether event resume support is enabled.
38
38
  *
39
39
  * When enabled, published events are temporarily stored so new
40
40
  * subscribers can resume from a previous position using `lastEventId`.
@@ -43,7 +43,7 @@ interface RedisPublisherOptions extends PublisherOptions {
43
43
  */
44
44
  enabled: boolean;
45
45
  /**
46
- * How long (in seconds) to retain events for replay.
46
+ * How long (in seconds) to retain events for resume.
47
47
  *
48
48
  * Expired events are cleaned up lazily for performance reasons, so
49
49
  * some events may remain available slightly longer than this period.
@@ -58,8 +58,8 @@ declare class RedisPublisher<T extends Record<string, object>> extends Publisher
58
58
  private readonly subscriber;
59
59
  private readonly prefix;
60
60
  private readonly serializer;
61
- private readonly replayEnabled;
62
- private readonly replaySeconds;
61
+ private readonly resumeEnabled;
62
+ private readonly resumeSeconds;
63
63
  /**
64
64
  * The exactness of the `XTRIM` command.
65
65
  * Used for testing purpose.
@@ -25,16 +25,16 @@ interface RedisPublisherOptions extends PublisherOptions {
25
25
  */
26
26
  serializer?: undefined | Pick<RPCSerializer, keyof RPCSerializer>;
27
27
  /**
28
- * Configuration for event replay support.
28
+ * Configuration for event resume support.
29
29
  *
30
30
  * When enabled, published events are temporarily stored so new
31
31
  * subscribers can resume from a previous position using `lastEventId`.
32
32
  *
33
33
  * @default { enabled: false }
34
34
  */
35
- replay?: {
35
+ resume?: {
36
36
  /**
37
- * Whether event replay support is enabled.
37
+ * Whether event resume support is enabled.
38
38
  *
39
39
  * When enabled, published events are temporarily stored so new
40
40
  * subscribers can resume from a previous position using `lastEventId`.
@@ -43,7 +43,7 @@ interface RedisPublisherOptions extends PublisherOptions {
43
43
  */
44
44
  enabled: boolean;
45
45
  /**
46
- * How long (in seconds) to retain events for replay.
46
+ * How long (in seconds) to retain events for resume.
47
47
  *
48
48
  * Expired events are cleaned up lazily for performance reasons, so
49
49
  * some events may remain available slightly longer than this period.
@@ -58,8 +58,8 @@ declare class RedisPublisher<T extends Record<string, object>> extends Publisher
58
58
  private readonly subscriber;
59
59
  private readonly prefix;
60
60
  private readonly serializer;
61
- private readonly replayEnabled;
62
- private readonly replaySeconds;
61
+ private readonly resumeEnabled;
62
+ private readonly resumeSeconds;
63
63
  /**
64
64
  * The exactness of the `XTRIM` command.
65
65
  * Used for testing purpose.
@@ -9,15 +9,15 @@ class RedisPublisher extends Publisher {
9
9
  this.redis = redis;
10
10
  this.prefix = options.prefix ?? "";
11
11
  this.serializer = options.serializer ?? new RPCSerializer();
12
- this.replayEnabled = options.replay?.enabled ?? false;
13
- this.replaySeconds = options.replay?.seconds ?? 300;
12
+ this.resumeEnabled = options.resume?.enabled ?? false;
13
+ this.resumeSeconds = options.resume?.seconds ?? 300;
14
14
  this.subscriber = options.subscriber ?? redis.duplicate();
15
15
  }
16
16
  subscriber;
17
17
  prefix;
18
18
  serializer;
19
- replayEnabled;
20
- replaySeconds;
19
+ resumeEnabled;
20
+ resumeSeconds;
21
21
  /**
22
22
  * The exactness of the `XTRIM` command.
23
23
  * Used for testing purpose.
@@ -31,16 +31,16 @@ class RedisPublisher extends Publisher {
31
31
  if (!this.redis.isOpen) {
32
32
  await this.redis.connect();
33
33
  }
34
- if (this.replayEnabled) {
34
+ if (this.resumeEnabled) {
35
35
  const now = Date.now();
36
36
  for (const [event2, firstPublishTime] of this.firstPublishTimeMap) {
37
- if (firstPublishTime + this.replaySeconds * 1e3 < now) {
37
+ if (firstPublishTime + this.resumeSeconds * 1e3 < now) {
38
38
  this.firstPublishTimeMap.delete(event2);
39
39
  }
40
40
  }
41
41
  if (!this.firstPublishTimeMap.has(event)) {
42
42
  this.firstPublishTimeMap.set(event, now);
43
- const result = await this.redis.multi().xAdd(redisKey, "*", { data: stringifyJSON(data) }).xTrim(redisKey, "MINID", `${now - this.replaySeconds * 1e3}-0`, { strategyModifier: this.xTrimExactness }).expire(redisKey, this.replaySeconds * 2).exec();
43
+ const result = await this.redis.multi().xAdd(redisKey, "*", { data: stringifyJSON(data) }).xTrim(redisKey, "MINID", `${now - this.resumeSeconds * 1e3}-0`, { strategyModifier: this.xTrimExactness }).expire(redisKey, this.resumeSeconds * 2).exec();
44
44
  id = result[0];
45
45
  } else {
46
46
  id = await this.redis.xAdd(redisKey, "*", { data: stringifyJSON(data) });
@@ -54,14 +54,14 @@ class RedisPublisher extends Publisher {
54
54
  await this.subscriber.connect();
55
55
  }
56
56
  let pendingPayloads = [];
57
- const replayedIds = /* @__PURE__ */ new Set();
57
+ const resumedIds = /* @__PURE__ */ new Set();
58
58
  const deduplicatingListener = (payload) => {
59
59
  if (pendingPayloads) {
60
60
  pendingPayloads.push(payload);
61
61
  return;
62
62
  }
63
63
  const id = getEventMeta(payload)?.id;
64
- if (id !== void 0 && replayedIds.has(id)) {
64
+ if (id !== void 0 && resumedIds.has(id)) {
65
65
  return;
66
66
  }
67
67
  originalListener(payload);
@@ -78,7 +78,7 @@ class RedisPublisher extends Publisher {
78
78
  try {
79
79
  const subscribePromise = this.subscriber.subscribe(redisKey, redisListener);
80
80
  try {
81
- if (this.replayEnabled && lastEventId !== void 0) {
81
+ if (this.resumeEnabled && lastEventId !== void 0) {
82
82
  if (!this.redis.isOpen) {
83
83
  await this.redis.connect();
84
84
  }
@@ -89,7 +89,7 @@ class RedisPublisher extends Publisher {
89
89
  const rawData = message.data;
90
90
  const data = parseEmptyableJSON(rawData);
91
91
  const payload = this.deserializePayload(id, data);
92
- replayedIds.add(id);
92
+ resumedIds.add(id);
93
93
  originalListener(payload);
94
94
  }
95
95
  }
@@ -17,16 +17,16 @@ interface UpstashPublisherOptions extends PublisherOptions {
17
17
  */
18
18
  serializer?: undefined | Pick<RPCSerializer, keyof RPCSerializer>;
19
19
  /**
20
- * Configuration for event replay support.
20
+ * Configuration for event resume support.
21
21
  *
22
22
  * When enabled, published events are temporarily stored so new
23
23
  * subscribers can resume from a previous position using `lastEventId`.
24
24
  *
25
25
  * @default { enabled: false }
26
26
  */
27
- replay?: {
27
+ resume?: {
28
28
  /**
29
- * Whether event replay support is enabled.
29
+ * Whether event resume support is enabled.
30
30
  *
31
31
  * When enabled, published events are temporarily stored so new
32
32
  * subscribers can resume from a previous position using `lastEventId`.
@@ -35,7 +35,7 @@ interface UpstashPublisherOptions extends PublisherOptions {
35
35
  */
36
36
  enabled: boolean;
37
37
  /**
38
- * How long (in seconds) to retain events for replay.
38
+ * How long (in seconds) to retain events for resume.
39
39
  *
40
40
  * Expired events are cleaned up lazily for performance reasons, so
41
41
  * some events may remain available slightly longer than this period.
@@ -52,14 +52,14 @@ declare class UpstashPublisher<T extends Record<string, object>> extends Publish
52
52
  private readonly listenersMap;
53
53
  private readonly onErrorsMap;
54
54
  private readonly subscriptionMap;
55
- private readonly replayEnabled;
56
- private readonly replaySeconds;
55
+ private readonly resumeEnabled;
56
+ private readonly resumeSeconds;
57
57
  /**
58
58
  * The exactness of the `XTRIM` command.
59
59
  * Used for testing purpose.
60
60
  */
61
61
  private readonly xTrimExactness;
62
- constructor(redis: Redis, { replay, prefix, serializer, ...options }?: UpstashPublisherOptions);
62
+ constructor(redis: Redis, { resume, prefix, serializer, ...options }?: UpstashPublisherOptions);
63
63
  private readonly firstPublishTimeMap;
64
64
  publish<K extends keyof T & string>(event: K, payload: T[K]): Promise<void>;
65
65
  protected subscribeListener<K extends keyof T & string>(event: K, originalListener: (payload: T[K]) => void, { lastEventId, onError }?: PublisherSubscribeListenerOptions): Promise<() => Promise<void>>;
@@ -17,16 +17,16 @@ interface UpstashPublisherOptions extends PublisherOptions {
17
17
  */
18
18
  serializer?: undefined | Pick<RPCSerializer, keyof RPCSerializer>;
19
19
  /**
20
- * Configuration for event replay support.
20
+ * Configuration for event resume support.
21
21
  *
22
22
  * When enabled, published events are temporarily stored so new
23
23
  * subscribers can resume from a previous position using `lastEventId`.
24
24
  *
25
25
  * @default { enabled: false }
26
26
  */
27
- replay?: {
27
+ resume?: {
28
28
  /**
29
- * Whether event replay support is enabled.
29
+ * Whether event resume support is enabled.
30
30
  *
31
31
  * When enabled, published events are temporarily stored so new
32
32
  * subscribers can resume from a previous position using `lastEventId`.
@@ -35,7 +35,7 @@ interface UpstashPublisherOptions extends PublisherOptions {
35
35
  */
36
36
  enabled: boolean;
37
37
  /**
38
- * How long (in seconds) to retain events for replay.
38
+ * How long (in seconds) to retain events for resume.
39
39
  *
40
40
  * Expired events are cleaned up lazily for performance reasons, so
41
41
  * some events may remain available slightly longer than this period.
@@ -52,14 +52,14 @@ declare class UpstashPublisher<T extends Record<string, object>> extends Publish
52
52
  private readonly listenersMap;
53
53
  private readonly onErrorsMap;
54
54
  private readonly subscriptionMap;
55
- private readonly replayEnabled;
56
- private readonly replaySeconds;
55
+ private readonly resumeEnabled;
56
+ private readonly resumeSeconds;
57
57
  /**
58
58
  * The exactness of the `XTRIM` command.
59
59
  * Used for testing purpose.
60
60
  */
61
61
  private readonly xTrimExactness;
62
- constructor(redis: Redis, { replay, prefix, serializer, ...options }?: UpstashPublisherOptions);
62
+ constructor(redis: Redis, { resume, prefix, serializer, ...options }?: UpstashPublisherOptions);
63
63
  private readonly firstPublishTimeMap;
64
64
  publish<K extends keyof T & string>(event: K, payload: T[K]): Promise<void>;
65
65
  protected subscribeListener<K extends keyof T & string>(event: K, originalListener: (payload: T[K]) => void, { lastEventId, onError }?: PublisherSubscribeListenerOptions): Promise<() => Promise<void>>;
@@ -4,12 +4,12 @@ import { unwrapEvent, withEventMeta, getEventMeta } from '@standardserver/core';
4
4
  import { P as Publisher } from '../shared/publisher.BSQf8ybR.mjs';
5
5
 
6
6
  class UpstashPublisher extends Publisher {
7
- constructor(redis, { replay, prefix, serializer, ...options } = {}) {
7
+ constructor(redis, { resume, prefix, serializer, ...options } = {}) {
8
8
  super(options);
9
9
  this.redis = redis;
10
10
  this.prefix = prefix ?? "";
11
- this.replayEnabled = replay?.enabled ?? false;
12
- this.replaySeconds = replay?.seconds ?? 300;
11
+ this.resumeEnabled = resume?.enabled ?? false;
12
+ this.resumeSeconds = resume?.seconds ?? 300;
13
13
  this.serializer = serializer ?? new RPCSerializer();
14
14
  }
15
15
  prefix;
@@ -18,8 +18,8 @@ class UpstashPublisher extends Publisher {
18
18
  onErrorsMap = /* @__PURE__ */ new Map();
19
19
  subscriptionMap = /* @__PURE__ */ new Map();
20
20
  // Upstash subscription objects
21
- replayEnabled;
22
- replaySeconds;
21
+ resumeEnabled;
22
+ resumeSeconds;
23
23
  /**
24
24
  * The exactness of the `XTRIM` command.
25
25
  * Used for testing purpose.
@@ -30,16 +30,16 @@ class UpstashPublisher extends Publisher {
30
30
  const redisKey = `${this.prefix}${event}`;
31
31
  const data = this.serializePayload(payload);
32
32
  let id;
33
- if (this.replayEnabled) {
33
+ if (this.resumeEnabled) {
34
34
  const now = Date.now();
35
35
  for (const [event2, firstPublishTime] of this.firstPublishTimeMap) {
36
- if (firstPublishTime + this.replaySeconds * 1e3 < now) {
36
+ if (firstPublishTime + this.resumeSeconds * 1e3 < now) {
37
37
  this.firstPublishTimeMap.delete(event2);
38
38
  }
39
39
  }
40
40
  if (!this.firstPublishTimeMap.has(event)) {
41
41
  this.firstPublishTimeMap.set(event, now);
42
- const results = await this.redis.multi().xadd(redisKey, "*", { data }).xtrim(redisKey, { strategy: "MINID", exactness: this.xTrimExactness, threshold: `${now - this.replaySeconds * 1e3}-0` }).expire(redisKey, this.replaySeconds * 2).exec();
42
+ const results = await this.redis.multi().xadd(redisKey, "*", { data }).xtrim(redisKey, { strategy: "MINID", exactness: this.xTrimExactness, threshold: `${now - this.resumeSeconds * 1e3}-0` }).expire(redisKey, this.resumeSeconds * 2).exec();
43
43
  id = results[0];
44
44
  } else {
45
45
  id = await this.redis.xadd(redisKey, "*", { data });
@@ -50,14 +50,14 @@ class UpstashPublisher extends Publisher {
50
50
  async subscribeListener(event, originalListener, { lastEventId, onError } = {}) {
51
51
  const redisKey = `${this.prefix}${event}`;
52
52
  let pendingPayloads = [];
53
- const replayedIds = /* @__PURE__ */ new Set();
53
+ const resumedIds = /* @__PURE__ */ new Set();
54
54
  const deduplicatingListener = (payload) => {
55
55
  if (pendingPayloads) {
56
56
  pendingPayloads.push(payload);
57
57
  return;
58
58
  }
59
59
  const id = getEventMeta(payload)?.id;
60
- if (id !== void 0 && replayedIds.has(id)) {
60
+ if (id !== void 0 && resumedIds.has(id)) {
61
61
  return;
62
62
  }
63
63
  originalListener(payload);
@@ -70,14 +70,14 @@ class UpstashPublisher extends Publisher {
70
70
  try {
71
71
  const subscribeEventPromise = this.subscribeEvent(event);
72
72
  try {
73
- if (this.replayEnabled && lastEventId !== void 0) {
73
+ if (this.resumeEnabled && lastEventId !== void 0) {
74
74
  const results = await this.redis.xread(redisKey, lastEventId);
75
75
  if (results && results[0]) {
76
76
  const [_, items] = results[0];
77
77
  for (const [id, fields] of items) {
78
78
  const data = fields[1];
79
79
  const payload = this.deserializePayload(id, data);
80
- replayedIds.add(id);
80
+ resumedIds.add(id);
81
81
  originalListener(payload);
82
82
  }
83
83
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/publisher",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.18",
4
+ "version": "2.0.0-beta.19",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.dev",
7
7
  "repository": {
@@ -53,8 +53,8 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@standardserver/core": "^0.5.0",
56
- "@orpc/client": "2.0.0-beta.18",
57
- "@orpc/shared": "2.0.0-beta.18"
56
+ "@orpc/client": "2.0.0-beta.19",
57
+ "@orpc/shared": "2.0.0-beta.19"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@upstash/redis": "^1.38.0",