@dabble/patches 0.2.22 → 0.2.24

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.
@@ -8,6 +8,7 @@ export * from './webrtc/WebRTCTransport.js';
8
8
  export * from './websocket/AuthorizationProvider.js';
9
9
  export * from './websocket/onlineState.js';
10
10
  export * from './websocket/PatchesWebSocket.js';
11
+ export * from './websocket/RPCServer.js';
11
12
  export * from './websocket/SignalingService.js';
12
13
  export * from './websocket/WebSocketServer.js';
13
14
  export * from './websocket/WebSocketTransport.js';
package/dist/net/index.js CHANGED
@@ -6,6 +6,7 @@ export * from './webrtc/WebRTCTransport.js';
6
6
  export * from './websocket/AuthorizationProvider.js';
7
7
  export * from './websocket/onlineState.js';
8
8
  export * from './websocket/PatchesWebSocket.js';
9
+ export * from './websocket/RPCServer.js';
9
10
  export * from './websocket/SignalingService.js';
10
11
  export * from './websocket/WebSocketServer.js';
11
12
  export * from './websocket/WebSocketTransport.js';
@@ -1,6 +1,6 @@
1
1
  import { type Signal, type Unsubscriber } from '../../event-signal.js';
2
2
  import type { AuthContext } from '../websocket/AuthorizationProvider.js';
3
- import type { Notification } from './types.js';
3
+ import type { Message, Notification, Response } from './types.js';
4
4
  export type ConnectionSignalSubscriber = (params: any, clientId?: string) => any;
5
5
  export type MessageHandler<P = any, R = any> = (params: P, ctx?: AuthContext) => Promise<R> | R;
6
6
  /**
@@ -60,6 +60,7 @@ export declare class JSONRPCServer {
60
60
  * internally; the returned string is forwarded over the socket.
61
61
  */
62
62
  processMessage(raw: string, ctx?: AuthContext): Promise<string | undefined>;
63
+ processMessage(message: Message, ctx?: AuthContext): Promise<Response | undefined>;
63
64
  /**
64
65
  * Maps JSON-RPC method names to {@link PatchesServer} calls.
65
66
  * @param connectionId - The WebSocket transport object.
@@ -66,31 +66,25 @@ export class JSONRPCServer {
66
66
  const msg = { jsonrpc: '2.0', method, params };
67
67
  this.onNotify.emit(msg, exceptConnectionId);
68
68
  }
69
- /**
70
- * Synchronously processes a raw JSON-RPC frame from a client and returns the
71
- * encoded response frame – or `undefined` when the message is a notification
72
- * (no response expected).
73
- *
74
- * This helper makes the RPC engine usable for stateless transports such as
75
- * HTTP: the host simply passes the request body and sends back the returned
76
- * string (if any).
77
- *
78
- * WebSocket and other bidirectional transports delegate to the same logic
79
- * internally; the returned string is forwarded over the socket.
80
- */
81
69
  async processMessage(raw, ctx) {
82
70
  let message;
71
+ const respond = typeof raw === 'string' ? JSON.stringify : (r) => r;
83
72
  // --- Parse & basic validation ------------------------------------------------
84
- try {
85
- message = JSON.parse(raw);
73
+ if (typeof raw === 'string') {
74
+ try {
75
+ message = JSON.parse(raw);
76
+ }
77
+ catch (err) {
78
+ return respond(rpcError(-32700, 'Parse error', err));
79
+ }
86
80
  }
87
- catch (err) {
88
- return rpcError(-32700, 'Parse error', err);
81
+ else {
82
+ message = raw;
89
83
  }
90
84
  // Ensure it looks like a JSON-RPC call (must have a method field)
91
85
  if (!message || typeof message !== 'object' || !('method' in message)) {
92
86
  const invalidId = message?.id ?? null;
93
- return rpcError(-32600, 'Invalid Request', invalidId);
87
+ return respond(rpcError(-32600, 'Invalid Request', invalidId));
94
88
  }
95
89
  // --- Distinguish request vs. notification -----------------------------------
96
90
  if ('id' in message && message.id !== undefined) {
@@ -98,10 +92,10 @@ export class JSONRPCServer {
98
92
  try {
99
93
  const result = await this._dispatch(message.method, message.params, ctx);
100
94
  const response = { jsonrpc: '2.0', id: message.id, result };
101
- return JSON.stringify(response);
95
+ return respond(response);
102
96
  }
103
97
  catch (err) {
104
- return rpcError(err?.code ?? -32000, err?.message ?? 'Server error', err?.stack);
98
+ return respond(rpcError(err?.code ?? -32000, err?.message ?? 'Server error', err?.stack));
105
99
  }
106
100
  }
107
101
  else {
@@ -133,5 +127,5 @@ export class JSONRPCServer {
133
127
  }
134
128
  }
135
129
  function rpcError(code, message, data) {
136
- return JSON.stringify({ jsonrpc: '2.0', id: null, error: { code, message, data } });
130
+ return { jsonrpc: '2.0', id: null, error: { code, message, data } };
137
131
  }
@@ -3,7 +3,6 @@ import type { PatchesHistoryManager } from '../../server/PatchesHistoryManager.j
3
3
  import type { PatchesServer } from '../../server/PatchesServer.js';
4
4
  import type { Change, EditableVersionMetadata, ListChangesOptions, ListVersionsOptions } from '../../types.js';
5
5
  import { JSONRPCServer } from '../protocol/JSONRPCServer.js';
6
- import type { ServerTransport } from '../protocol/types.js';
7
6
  import type { AuthContext, AuthorizationProvider } from './AuthorizationProvider.js';
8
7
  /**
9
8
  * High-level client for the Patches real-time collaboration service.
@@ -11,7 +10,6 @@ import type { AuthContext, AuthorizationProvider } from './AuthorizationProvider
11
10
  * versioning, and other OT-specific functionality over a JSON RPC interface.
12
11
  */
13
12
  export interface RPCServerOptions {
14
- transport: ServerTransport;
15
13
  patches: PatchesServer;
16
14
  history?: PatchesHistoryManager;
17
15
  branches?: PatchesBranchManager;
@@ -113,8 +111,8 @@ export declare class RPCServer {
113
111
  branchId: string;
114
112
  }, ctx?: AuthContext): Promise<Change[]>;
115
113
  protected assertAccess(ctx: AuthContext | undefined, docId: string, kind: 'read' | 'write', method: string, params?: Record<string, any>): Promise<void>;
116
- protected assertRead(ctx: AuthContext | undefined, docId: string, method: string, params?: Record<string, any>): Promise<void>;
117
- protected assertWrite(ctx: AuthContext | undefined, docId: string, method: string, params?: Record<string, any>): Promise<void>;
114
+ assertRead(ctx: AuthContext | undefined, docId: string, method: string, params?: Record<string, any>): Promise<void>;
115
+ assertWrite(ctx: AuthContext | undefined, docId: string, method: string, params?: Record<string, any>): Promise<void>;
118
116
  protected assertHistoryEnabled(): void;
119
117
  protected assertBranchingEnabled(): void;
120
118
  }
@@ -1,4 +1,4 @@
1
- import type { Branch, Change, EditableVersionMetadata, ListChangesOptions, ListVersionsOptions, VersionMetadata } from '../types';
1
+ import type { Branch, Change, EditableVersionMetadata, ListChangesOptions, ListVersionsOptions, PatchesState, VersionMetadata } from '../types';
2
2
  /**
3
3
  * Interface for a backend storage system for patch synchronization.
4
4
  * Defines methods needed by PatchesServer, PatchesHistoryManager, etc.
@@ -8,6 +8,10 @@ export interface PatchesStoreBackend {
8
8
  saveChanges(docId: string, changes: Change[]): Promise<void>;
9
9
  /** Lists committed server changes based on revision numbers. */
10
10
  listChanges(docId: string, options: ListChangesOptions): Promise<Change[]>;
11
+ /** Loads the last version state for a document. Optional method for performance. */
12
+ loadLastVersionState?: (docId: string) => Promise<PatchesState | undefined>;
13
+ /** Saves the last version state for a document. Optional method for performance. */
14
+ saveLastVersionState?: (docId: string, rev: number, state: any) => Promise<void>;
11
15
  /**
12
16
  * Saves version metadata, its state snapshot, and the original changes that constitute it.
13
17
  * State and changes are stored separately from the core metadata.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dabble/patches",
3
- "version": "0.2.22",
3
+ "version": "0.2.24",
4
4
  "description": "Immutable JSON Patch implementation based on RFC 6902 supporting operational transformation and last-writer-wins",
5
5
  "author": "Jacob Wright <jacwright@gmail.com>",
6
6
  "bugs": {
@@ -55,11 +55,11 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "alphacounter": "^2.x",
58
- "crypto-id": "^0.2.3",
59
- "simple-peer": "^9.11.1"
58
+ "crypto-id": "^0.2.3"
60
59
  },
61
60
  "peerDependencies": {
62
- "@dabble/delta": "^1.2.4"
61
+ "@dabble/delta": "^1.2.4",
62
+ "simple-peer": "^9.11.1"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@sveltejs/package": "^2.3.11",