@syncular/server-workers 0.15.48 → 0.16.1

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
@@ -139,6 +139,10 @@ from a Worker scheduler, queue consumer, Workflow step, or Durable Object
139
139
  alarm according to the application's hosting model.
140
140
 
141
141
  Schedule `pruneReactions` per partition as a separate maintenance pass.
142
+ For commit-log pruning, expose the `SyncularRealtimeHost.pruneCommitLog` method
143
+ through the owning Durable Object and call its RPC from the scheduler. This
144
+ method uses the existing partition FIFO. Direct D1 pruning requires the same
145
+ external serialization assertion as push application.
142
146
  Defaults retain completed rows for 30 days and dead-lettered rows for 90 days,
143
147
  with at most 1,000 deletions per pass. Repeat while `mayHaveMore` is true.
144
148
  Pending and leased rows are never eligible. D1 executes each bounded cleanup
@@ -263,6 +267,9 @@ const realtimeDOConfig = (env: Env): RealtimeDOConfig => ({
263
267
  export class SyncularRealtimeDO extends DurableObject<Env> {
264
268
  #host = new SyncularRealtimeHost(this.ctx, this.env.DB, realtimeDOConfig(this.env));
265
269
  fetch(request: Request) { return this.#host.fetch(request); }
270
+ pruneCommitLog(partition: string, nowMs: number) {
271
+ return this.#host.pruneCommitLog({ partition, nowMs });
272
+ }
266
273
  webSocketMessage(ws: WebSocket, msg: ArrayBuffer | string) {
267
274
  return this.#host.webSocketMessage(ws, msg);
268
275
  }
@@ -67,7 +67,7 @@
67
67
  * partition serialization may call `/__wake` after its own commit so sockets
68
68
  * re-pull. See `durableObjectRealtimeNotifier` for that caller side.
69
69
  */
70
- import { D1ServerStorage, type RealtimeHubConfig } from '@syncular/server';
70
+ import { D1ServerStorage, type PruneOptions, type RealtimeHubConfig } from '@syncular/server';
71
71
  export interface DurableObjectStateLike {
72
72
  acceptWebSocket(ws: WebSocketLike, tags?: string[]): void;
73
73
  getWebSockets(tag?: string): WebSocketLike[];
@@ -153,6 +153,8 @@ export declare class SyncularRealtimeHost {
153
153
  * and accepts external-command wakes at `/__syncular_realtime/wake`.
154
154
  */
155
155
  fetch(request: Request): Promise<Response>;
156
+ /** Trusted maintenance shares the partition FIFO with HTTP/socket writes. */
157
+ pruneCommitLog(options: Omit<PruneOptions, 'storage'>): Promise<number>;
156
158
  /** Hibernation callback: an inbound frame. */
157
159
  webSocketMessage(ws: WebSocketLike, message: ArrayBuffer | string): Promise<void>;
158
160
  /** Hibernation callback: the socket closed. */
@@ -67,7 +67,7 @@
67
67
  * partition serialization may call `/__wake` after its own commit so sockets
68
68
  * re-pull. See `durableObjectRealtimeNotifier` for that caller side.
69
69
  */
70
- import { createRealtimeHub, D1ServerStorage, errorBody, handleSyncRequest, SSP2_CONTENT_TYPE, SyncError, } from '@syncular/server';
70
+ import { createRealtimeHub, D1ServerStorage, errorBody, handleSyncRequest, pruneCommitLog, SSP2_CONTENT_TYPE, SyncError, } from '@syncular/server';
71
71
  function isAttachment(value) {
72
72
  return (typeof value === 'object' &&
73
73
  value !== null &&
@@ -158,6 +158,13 @@ export class SyncularRealtimeHost {
158
158
  }
159
159
  return new Response('not found', { status: 404 });
160
160
  }
161
+ /** Trusted maintenance shares the partition FIFO with HTTP/socket writes. */
162
+ pruneCommitLog(options) {
163
+ return this.#serializePartition(async () => {
164
+ await this.#storage.migrate();
165
+ return pruneCommitLog({ ...options, storage: this.#storage });
166
+ });
167
+ }
161
168
  #serializePartition(operation) {
162
169
  const result = this.#partitionTail.then(operation, operation);
163
170
  this.#partitionTail = result.then(() => undefined, () => undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/server-workers",
3
- "version": "0.15.48",
3
+ "version": "0.16.1",
4
4
  "description": "Cloudflare Workers adapter for the Syncular sync server",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
@@ -45,10 +45,10 @@
45
45
  "!dist/**/*.test.d.ts"
46
46
  ],
47
47
  "dependencies": {
48
- "@syncular/server": "0.15.48",
49
- "@syncular/server-hono": "0.15.48"
48
+ "@syncular/server": "0.16.1",
49
+ "@syncular/server-hono": "0.16.1"
50
50
  },
51
51
  "devDependencies": {
52
- "@syncular/core": "0.15.48"
52
+ "@syncular/core": "0.16.1"
53
53
  }
54
54
  }
@@ -72,6 +72,8 @@ import {
72
72
  D1ServerStorage,
73
73
  errorBody,
74
74
  handleSyncRequest,
75
+ pruneCommitLog,
76
+ type PruneOptions,
75
77
  type RealtimeHub,
76
78
  type RealtimeHubConfig,
77
79
  type RealtimeSession,
@@ -249,6 +251,14 @@ export class SyncularRealtimeHost {
249
251
  return new Response('not found', { status: 404 });
250
252
  }
251
253
 
254
+ /** Trusted maintenance shares the partition FIFO with HTTP/socket writes. */
255
+ pruneCommitLog(options: Omit<PruneOptions, 'storage'>): Promise<number> {
256
+ return this.#serializePartition(async () => {
257
+ await this.#storage.migrate();
258
+ return pruneCommitLog({ ...options, storage: this.#storage });
259
+ });
260
+ }
261
+
252
262
  #serializePartition<T>(operation: () => Promise<T>): Promise<T> {
253
263
  const result = this.#partitionTail.then(operation, operation);
254
264
  this.#partitionTail = result.then(