@sylphx/lens-server 2.14.0 → 2.14.2
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/dist/index.d.ts +50 -88
- package/dist/index.js +154 -136
- package/package.json +2 -2
- package/src/handlers/index.ts +2 -0
- package/src/handlers/ws-types.ts +27 -0
- package/src/handlers/ws.ts +210 -70
- package/src/index.ts +2 -0
- package/src/server/create.test.ts +0 -201
- package/src/server/create.ts +19 -180
- package/src/server/dataloader.test.ts +279 -0
- package/src/server/types.ts +16 -101
- package/src/sse/handler.ts +7 -0
package/dist/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ import { AnyQueryDef, ContextValue as ContextValue2, EntityDef, InferRouterConte
|
|
|
51
51
|
/**
|
|
52
52
|
* Context passed to onSubscribe hook.
|
|
53
53
|
*/
|
|
54
|
-
interface
|
|
54
|
+
interface SubscribeContext {
|
|
55
55
|
/** Client ID */
|
|
56
56
|
clientId: string;
|
|
57
57
|
/** Subscription ID (unique per client) */
|
|
@@ -70,7 +70,7 @@ interface SubscribeContext2 {
|
|
|
70
70
|
/**
|
|
71
71
|
* Context passed to onUnsubscribe hook.
|
|
72
72
|
*/
|
|
73
|
-
interface
|
|
73
|
+
interface UnsubscribeContext {
|
|
74
74
|
/** Client ID */
|
|
75
75
|
clientId: string;
|
|
76
76
|
/** Subscription ID */
|
|
@@ -183,7 +183,7 @@ interface AfterMutationContext {
|
|
|
183
183
|
/**
|
|
184
184
|
* Context passed to onReconnect hook.
|
|
185
185
|
*/
|
|
186
|
-
interface
|
|
186
|
+
interface ReconnectContext {
|
|
187
187
|
/** Client ID */
|
|
188
188
|
clientId: string;
|
|
189
189
|
/** Subscriptions to restore */
|
|
@@ -202,7 +202,7 @@ interface ReconnectContext2 {
|
|
|
202
202
|
/**
|
|
203
203
|
* Result from onReconnect hook.
|
|
204
204
|
*/
|
|
205
|
-
interface
|
|
205
|
+
interface ReconnectHookResult {
|
|
206
206
|
/** Subscription ID */
|
|
207
207
|
id: string;
|
|
208
208
|
/** Entity type */
|
|
@@ -227,7 +227,7 @@ interface ReconnectHookResult2 {
|
|
|
227
227
|
/**
|
|
228
228
|
* Context passed to onUpdateFields hook.
|
|
229
229
|
*/
|
|
230
|
-
interface
|
|
230
|
+
interface UpdateFieldsContext {
|
|
231
231
|
/** Client ID */
|
|
232
232
|
clientId: string;
|
|
233
233
|
/** Subscription ID */
|
|
@@ -291,11 +291,11 @@ interface ServerPlugin {
|
|
|
291
291
|
* Called when a client subscribes to an operation.
|
|
292
292
|
* Can modify the context or return false to reject.
|
|
293
293
|
*/
|
|
294
|
-
onSubscribe?: (ctx:
|
|
294
|
+
onSubscribe?: (ctx: SubscribeContext) => void | boolean | Promise<void | boolean>;
|
|
295
295
|
/**
|
|
296
296
|
* Called when a client unsubscribes.
|
|
297
297
|
*/
|
|
298
|
-
onUnsubscribe?: (ctx:
|
|
298
|
+
onUnsubscribe?: (ctx: UnsubscribeContext) => void | Promise<void>;
|
|
299
299
|
/**
|
|
300
300
|
* Called before sending data to a client.
|
|
301
301
|
* Can modify the data to be sent.
|
|
@@ -322,11 +322,11 @@ interface ServerPlugin {
|
|
|
322
322
|
*
|
|
323
323
|
* @returns Array of sync results, or null to let other plugins handle
|
|
324
324
|
*/
|
|
325
|
-
onReconnect?: (ctx:
|
|
325
|
+
onReconnect?: (ctx: ReconnectContext) => ReconnectHookResult[] | null | Promise<ReconnectHookResult[] | null>;
|
|
326
326
|
/**
|
|
327
327
|
* Called when a client updates subscribed fields for an entity.
|
|
328
328
|
*/
|
|
329
|
-
onUpdateFields?: (ctx:
|
|
329
|
+
onUpdateFields?: (ctx: UpdateFieldsContext) => void | Promise<void>;
|
|
330
330
|
/**
|
|
331
331
|
* Called for each operation when building handshake metadata.
|
|
332
332
|
* Plugin can add fields to meta (e.g., optimistic config).
|
|
@@ -384,11 +384,11 @@ declare class PluginManager {
|
|
|
384
384
|
* Run onSubscribe hooks.
|
|
385
385
|
* Returns false if any plugin rejects the subscription.
|
|
386
386
|
*/
|
|
387
|
-
runOnSubscribe(ctx:
|
|
387
|
+
runOnSubscribe(ctx: SubscribeContext): Promise<boolean>;
|
|
388
388
|
/**
|
|
389
389
|
* Run onUnsubscribe hooks.
|
|
390
390
|
*/
|
|
391
|
-
runOnUnsubscribe(ctx:
|
|
391
|
+
runOnUnsubscribe(ctx: UnsubscribeContext): Promise<void>;
|
|
392
392
|
/**
|
|
393
393
|
* Run beforeSend hooks.
|
|
394
394
|
* Each plugin can modify the data.
|
|
@@ -411,11 +411,11 @@ declare class PluginManager {
|
|
|
411
411
|
* Run onReconnect hooks.
|
|
412
412
|
* Returns the first non-null result from a plugin.
|
|
413
413
|
*/
|
|
414
|
-
runOnReconnect(ctx:
|
|
414
|
+
runOnReconnect(ctx: ReconnectContext): Promise<ReconnectHookResult[] | null>;
|
|
415
415
|
/**
|
|
416
416
|
* Run onUpdateFields hooks.
|
|
417
417
|
*/
|
|
418
|
-
runOnUpdateFields(ctx:
|
|
418
|
+
runOnUpdateFields(ctx: UpdateFieldsContext): Promise<void>;
|
|
419
419
|
/**
|
|
420
420
|
* Run enhanceOperationMeta hooks.
|
|
421
421
|
* Each plugin can add fields to the operation metadata.
|
|
@@ -556,21 +556,17 @@ interface WebSocketLike {
|
|
|
556
556
|
onerror?: ((error: unknown) => void) | null;
|
|
557
557
|
}
|
|
558
558
|
/**
|
|
559
|
-
* Lens server interface
|
|
559
|
+
* Lens server interface - Pure Executor
|
|
560
|
+
*
|
|
561
|
+
* The server is a pure operation executor. It receives operations and returns results.
|
|
562
|
+
* Runtime concerns (connections, transport, protocol) are handled by adapters/handlers.
|
|
560
563
|
*
|
|
561
564
|
* Core methods:
|
|
562
565
|
* - getMetadata() - Server metadata for transport handshake
|
|
563
|
-
* - execute() - Execute any operation
|
|
564
|
-
*
|
|
565
|
-
* Subscription support (used by adapters):
|
|
566
|
-
* - addClient() / removeClient() - Client connection management
|
|
567
|
-
* - subscribe() / unsubscribe() - Subscription lifecycle
|
|
568
|
-
* - send() - Send data to client (runs through plugin hooks)
|
|
569
|
-
* - broadcast() - Broadcast to all entity subscribers
|
|
570
|
-
* - handleReconnect() - Handle client reconnection
|
|
566
|
+
* - execute() - Execute any operation (returns Observable)
|
|
571
567
|
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
568
|
+
* For handlers that need plugin integration (WS, SSE with state management),
|
|
569
|
+
* use getPluginManager() to access plugin hooks directly.
|
|
574
570
|
*/
|
|
575
571
|
interface LensServer {
|
|
576
572
|
/** Get server metadata for transport handshake */
|
|
@@ -589,71 +585,17 @@ interface LensServer {
|
|
|
589
585
|
*/
|
|
590
586
|
execute(op: LensOperation): Observable<LensResult>;
|
|
591
587
|
/**
|
|
592
|
-
*
|
|
593
|
-
* Call when a client connects via WebSocket/SSE.
|
|
594
|
-
*/
|
|
595
|
-
addClient(clientId: string, send: ClientSendFn): Promise<boolean>;
|
|
596
|
-
/**
|
|
597
|
-
* Remove a client connection.
|
|
598
|
-
* Call when a client disconnects.
|
|
599
|
-
*/
|
|
600
|
-
removeClient(clientId: string, subscriptionCount: number): void;
|
|
601
|
-
/**
|
|
602
|
-
* Subscribe a client to an entity.
|
|
603
|
-
* Runs plugin hooks and sets up state tracking (if clientState is enabled).
|
|
604
|
-
*/
|
|
605
|
-
subscribe(ctx: import("../plugin/types.js").SubscribeContext): Promise<boolean>;
|
|
606
|
-
/**
|
|
607
|
-
* Unsubscribe a client from an entity.
|
|
608
|
-
* Runs plugin hooks and cleans up state tracking.
|
|
609
|
-
*/
|
|
610
|
-
unsubscribe(ctx: import("../plugin/types.js").UnsubscribeContext): void;
|
|
611
|
-
/**
|
|
612
|
-
* Send data to a client for a specific subscription.
|
|
613
|
-
* Runs through plugin hooks (beforeSend/afterSend) for optimization.
|
|
614
|
-
*/
|
|
615
|
-
send(clientId: string, subscriptionId: string, entity: string, entityId: string, data: Record<string, unknown>, isInitial: boolean): Promise<void>;
|
|
616
|
-
/**
|
|
617
|
-
* Broadcast data to all subscribers of an entity.
|
|
618
|
-
* Runs through plugin hooks for each subscriber.
|
|
619
|
-
*/
|
|
620
|
-
broadcast(entity: string, entityId: string, data: Record<string, unknown>): Promise<void>;
|
|
621
|
-
/**
|
|
622
|
-
* Handle a reconnection request from a client.
|
|
623
|
-
* Uses plugin hooks (onReconnect) for reconnection logic.
|
|
624
|
-
*/
|
|
625
|
-
handleReconnect(ctx: import("../plugin/types.js").ReconnectContext): Promise<import("../plugin/types.js").ReconnectHookResult[] | null>;
|
|
626
|
-
/**
|
|
627
|
-
* Update subscribed fields for a client's subscription.
|
|
628
|
-
* Runs plugin hooks (onUpdateFields) to sync state.
|
|
629
|
-
*/
|
|
630
|
-
updateFields(ctx: import("../plugin/types.js").UpdateFieldsContext): Promise<void>;
|
|
631
|
-
/**
|
|
632
|
-
* Get the plugin manager for direct hook access.
|
|
633
|
-
*/
|
|
634
|
-
getPluginManager(): PluginManager;
|
|
635
|
-
/**
|
|
636
|
-
* Check if any selected field (recursively) is a subscription.
|
|
637
|
-
*
|
|
638
|
-
* @deprecated Use client-side subscription detection with `getMetadata().entities` instead.
|
|
639
|
-
* The client should use the entities metadata to determine transport routing.
|
|
588
|
+
* Get the plugin manager for handlers that need plugin integration.
|
|
640
589
|
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
590
|
+
* Handlers should use this to call plugin hooks directly:
|
|
591
|
+
* - pluginManager.runOnConnect() - When client connects
|
|
592
|
+
* - pluginManager.runOnDisconnect() - When client disconnects
|
|
593
|
+
* - pluginManager.runOnSubscribe() - When client subscribes
|
|
594
|
+
* - pluginManager.runOnUnsubscribe() - When client unsubscribes
|
|
595
|
+
* - pluginManager.runOnReconnect() - For reconnection handling
|
|
596
|
+
* - etc.
|
|
644
597
|
*/
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* Check if an operation requires streaming transport.
|
|
648
|
-
*
|
|
649
|
-
* @deprecated Use client-side transport detection with `getMetadata().entities` instead.
|
|
650
|
-
* The client should determine transport based on operation type from metadata
|
|
651
|
-
* and entity field modes.
|
|
652
|
-
*
|
|
653
|
-
* @param path - Operation path
|
|
654
|
-
* @param select - Selection object for return type fields
|
|
655
|
-
*/
|
|
656
|
-
requiresStreamingTransport(path: string, select?: SelectionObject): boolean;
|
|
598
|
+
getPluginManager(): PluginManager;
|
|
657
599
|
}
|
|
658
600
|
type InferInput<T> = T extends QueryDef<infer I, any> ? I : T extends MutationDef<infer I, any> ? I : never;
|
|
659
601
|
type InferOutput<T> = T extends QueryDef<any, infer O> ? O : T extends MutationDef<any, infer O> ? O : T extends FieldType<infer F> ? F : never;
|
|
@@ -809,6 +751,7 @@ declare class SSEHandler {
|
|
|
809
751
|
send(clientId: string, message: unknown): boolean;
|
|
810
752
|
/**
|
|
811
753
|
* Send a named event to a specific client.
|
|
754
|
+
* Event names are validated to prevent header injection attacks.
|
|
812
755
|
*/
|
|
813
756
|
sendEvent(clientId: string, event: string, data: unknown): boolean;
|
|
814
757
|
/**
|
|
@@ -1107,6 +1050,25 @@ interface WSHandlerOptions {
|
|
|
1107
1050
|
};
|
|
1108
1051
|
}
|
|
1109
1052
|
/**
|
|
1053
|
+
* WebSocket handler configuration with all required values.
|
|
1054
|
+
*/
|
|
1055
|
+
interface WSHandlerConfig {
|
|
1056
|
+
/** Maximum message size in bytes */
|
|
1057
|
+
maxMessageSize: number;
|
|
1058
|
+
/** Maximum subscriptions per client */
|
|
1059
|
+
maxSubscriptionsPerClient: number;
|
|
1060
|
+
/** Maximum total connections */
|
|
1061
|
+
maxConnections: number;
|
|
1062
|
+
/** Rate limit: messages per window */
|
|
1063
|
+
rateLimitMaxMessages: number;
|
|
1064
|
+
/** Rate limit: window in milliseconds */
|
|
1065
|
+
rateLimitWindowMs: number;
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Default WebSocket handler configuration.
|
|
1069
|
+
*/
|
|
1070
|
+
declare const DEFAULT_WS_HANDLER_CONFIG: WSHandlerConfig;
|
|
1071
|
+
/**
|
|
1110
1072
|
* WebSocket adapter for Bun's websocket handler.
|
|
1111
1073
|
*/
|
|
1112
1074
|
interface WSHandler {
|
|
@@ -1755,4 +1717,4 @@ declare function toBasicLogger(structuredLogger: StructuredLogger): {
|
|
|
1755
1717
|
warn: (message: string, ...args: unknown[]) => void;
|
|
1756
1718
|
error: (message: string, ...args: unknown[]) => void;
|
|
1757
1719
|
};
|
|
1758
|
-
export { useContext, tryUseContext, toBasicLogger, runWithContextAsync, runWithContext, router, query, prettyOutput, optimisticPlugin, opLog, mutation, memoryStorage, jsonOutput, isOptimisticPlugin, isOpLogPlugin, hasContext, handleWebSSE, handleWebQuery, handleWebMutation, extendContext, estimatePatchSize, createWSHandler, createStructuredLogger, createServerClientProxy, createSSEHandler, createPluginManager, createHandler, createHTTPHandler, createFrameworkHandler, createContext, createApp, coalescePatches, WebSocketLike, WebSocketContext, WSHandlerOptions, WSHandler,
|
|
1720
|
+
export { useContext, tryUseContext, toBasicLogger, runWithContextAsync, runWithContext, router, query, prettyOutput, optimisticPlugin, opLog, mutation, memoryStorage, jsonOutput, isOptimisticPlugin, isOpLogPlugin, hasContext, handleWebSSE, handleWebQuery, handleWebMutation, extendContext, estimatePatchSize, createWSHandler, createStructuredLogger, createServerClientProxy, createSSEHandler, createPluginManager, createHandler, createHTTPHandler, createFrameworkHandler, createContext, createApp, coalescePatches, WebSocketLike, WebSocketContext, WSHandlerOptions, WSHandlerConfig, WSHandler, UnsubscribeContext, SubscribeContext, StructuredLoggerOptions, StructuredLogger, StoredPatchEntry, StoredEntityState, ServerPlugin, ServerMetadata, LensServerConfig as ServerConfig, SelectionObject, SSEHandlerConfig as SSEHandlerOptions, SSEHandlerConfig, SSEHandler, SSEClient, RouterRoutes, RouterDef3 as RouterDef, ResolverFn, ResolverContext, RequestContext, QueryDef2 as QueryDef, QueriesMap, PluginManager, PerformanceContext, OptimisticPluginOptions, OperationsMap, OperationMeta, OperationLog, OpLogStorageConfig, OpLogStorage, OpLogPlugin, OpLogOptions, MutationsMap, MutationDef2 as MutationDef, LogOutput, LogLevel, LogEntry, LogContext, LensServer, LensResult, LensOperation, InferRouterContext3 as InferRouterContext, InferOutput, InferInput, InferApi, HandlerOptions, Handler, HTTPHandlerOptions, HTTPHandler, FrameworkHandlerOptions, ErrorContext, EntitiesMap, EnhanceOperationMetaContext, EmitResult, DisconnectContext, DEFAULT_WS_HANDLER_CONFIG, DEFAULT_STORAGE_CONFIG, ConnectContext, ClientSendFn, BroadcastResult, BeforeSendContext, BeforeMutationContext, AfterSendContext, AfterMutationContext };
|