@sylphx/lens-server 4.0.0 → 4.1.0

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 CHANGED
@@ -561,19 +561,43 @@ interface WebSocketLike {
561
561
  onerror?: ((error: unknown) => void) | null;
562
562
  }
563
563
  /**
564
- * Lens server interface - Pure Executor
564
+ * Lens server interface - Callable HTTP handler with executor methods
565
565
  *
566
- * The server is a pure operation executor. It receives operations and returns results.
567
- * Runtime concerns (connections, transport, protocol) are handled by adapters/handlers.
566
+ * The app itself is a fetch handler. Just pass it directly to your runtime.
568
567
  *
569
- * Core methods:
570
- * - getMetadata() - Server metadata for transport handshake
571
- * - execute() - Execute any operation (returns Observable)
568
+ * @example
569
+ * ```typescript
570
+ * const app = createApp({ router, context: () => ({}) })
571
+ *
572
+ * // Bun - app is directly usable as handler
573
+ * Bun.serve(app)
574
+ *
575
+ * // Or with explicit fetch
576
+ * Bun.serve({ fetch: app.fetch })
572
577
  *
573
- * For handlers that need plugin integration (WS, SSE with state management),
574
- * use getPluginManager() to access plugin hooks directly.
578
+ * // Deno
579
+ * Deno.serve(app)
580
+ *
581
+ * // Cloudflare Workers
582
+ * app
583
+ * ```
575
584
  */
576
585
  interface LensServer {
586
+ /**
587
+ * Call the app directly as a fetch handler.
588
+ * This makes the app callable: `app(request)` or `Bun.serve(app)`
589
+ */
590
+ (request: Request): Promise<Response>;
591
+ /**
592
+ * HTTP fetch handler - Web standard Request/Response.
593
+ * Same as calling app directly: `app.fetch(req)` === `app(req)`
594
+ *
595
+ * Endpoints:
596
+ * - POST / → Execute operations
597
+ * - GET /__lens/metadata → Server metadata
598
+ * - GET /__lens/health → Health check
599
+ */
600
+ fetch: (request: Request) => Promise<Response>;
577
601
  /** Get server metadata for transport handshake */
578
602
  getMetadata(): ServerMetadata;
579
603
  /**
@@ -640,20 +664,31 @@ type ServerConfigLegacy<
640
664
  plugins?: ServerPlugin[];
641
665
  };
642
666
  /**
643
- * Create Lens server with optional plugin support.
667
+ * Create Lens app - a callable HTTP handler.
668
+ *
669
+ * The returned app is directly usable as a fetch handler.
670
+ * Works with any runtime: Bun, Deno, Cloudflare Workers, Node.js.
644
671
  *
645
672
  * @example
646
673
  * ```typescript
647
- * // Stateless mode (default)
648
- * const app = createApp({ router });
649
- * createWSHandler(app); // Sends full data on each update
650
- *
651
- * // Stateful mode (with clientState)
652
674
  * const app = createApp({
653
- * router,
654
- * plugins: [clientState()], // Enables per-client state tracking
655
- * });
656
- * createWSHandler(app); // Sends minimal diffs
675
+ * router: appRouter,
676
+ * entities: { User, Post },
677
+ * resolvers: [userResolver, postResolver],
678
+ * context: () => ({ db }),
679
+ * })
680
+ *
681
+ * // Bun - app is directly callable
682
+ * Bun.serve(app)
683
+ *
684
+ * // Deno
685
+ * Deno.serve(app)
686
+ *
687
+ * // Cloudflare Workers
688
+ * app
689
+ *
690
+ * // Or use app.fetch explicitly
691
+ * Bun.serve({ fetch: app.fetch })
657
692
  * ```
658
693
  */
659
694
  declare function createApp<
@@ -680,6 +715,90 @@ declare function createApp<
680
715
  };
681
716
  };
682
717
  /**
718
+ * Create a proxy object that provides typed access to server procedures.
719
+ *
720
+ * This proxy allows calling server procedures directly without going through
721
+ * HTTP. Useful for:
722
+ * - Server-side rendering (SSR)
723
+ * - Server Components
724
+ * - Testing
725
+ * - Same-process communication
726
+ *
727
+ * @example
728
+ * ```typescript
729
+ * const serverClient = createServerClientProxy(server);
730
+ *
731
+ * // Call procedures directly (typed!)
732
+ * const users = await serverClient.user.list();
733
+ * const user = await serverClient.user.get({ id: '123' });
734
+ * ```
735
+ */
736
+ declare function createServerClientProxy(server: LensServer): unknown;
737
+ /**
738
+ * Handle a query request using standard Web Request/Response API.
739
+ *
740
+ * Expects input in URL search params as JSON string.
741
+ *
742
+ * @example
743
+ * ```typescript
744
+ * // GET /api/lens/user.get?input={"id":"123"}
745
+ * const response = await handleWebQuery(server, 'user.get', url);
746
+ * ```
747
+ */
748
+ declare function handleWebQuery(server: LensServer, path: string, url: URL): Promise<Response>;
749
+ /**
750
+ * Handle a mutation request using standard Web Request/Response API.
751
+ *
752
+ * Expects input in request body as JSON.
753
+ *
754
+ * @example
755
+ * ```typescript
756
+ * // POST /api/lens/user.create with body { "input": { "name": "John" } }
757
+ * const response = await handleWebMutation(server, 'user.create', request);
758
+ * ```
759
+ */
760
+ declare function handleWebMutation(server: LensServer, path: string, request: Request): Promise<Response>;
761
+ /**
762
+ * Handle an SSE subscription request using standard Web Request/Response API.
763
+ *
764
+ * Creates a ReadableStream that emits SSE events from the subscription.
765
+ *
766
+ * @example
767
+ * ```typescript
768
+ * // GET /api/lens/events.stream with Accept: text/event-stream
769
+ * const response = handleWebSSE(server, 'events.stream', url, request.signal);
770
+ * ```
771
+ */
772
+ declare function handleWebSSE(server: LensServer, path: string, url: URL, signal?: AbortSignal): Response;
773
+ /**
774
+ * Options for creating a framework handler.
775
+ */
776
+ interface FrameworkHandlerOptions {
777
+ /** Base path to strip from request URLs */
778
+ basePath?: string;
779
+ }
780
+ /**
781
+ * Create a complete request handler for Web standard Request/Response.
782
+ *
783
+ * Handles:
784
+ * - GET requests → Query execution
785
+ * - POST requests → Mutation execution
786
+ * - SSE requests (Accept: text/event-stream) → Subscriptions
787
+ *
788
+ * @example
789
+ * ```typescript
790
+ * const handler = createFrameworkHandler(server, { basePath: '/api/lens' });
791
+ *
792
+ * // In Next.js App Router:
793
+ * const GET = handler;
794
+ * const POST = handler;
795
+ *
796
+ * // In Fresh:
797
+ * const handler = { GET: lensHandler, POST: lensHandler };
798
+ * ```
799
+ */
800
+ declare function createFrameworkHandler(server: LensServer, options?: FrameworkHandlerOptions): (request: Request) => Promise<Response>;
801
+ /**
683
802
  * @sylphx/lens-server - SSE Handler
684
803
  *
685
804
  * Pure transport handler for Server-Sent Events.
@@ -792,224 +911,6 @@ declare class SSEHandler {
792
911
  * Create SSE handler (pure transport).
793
912
  */
794
913
  declare function createSSEHandler(config?: SSEHandlerConfig): SSEHandler;
795
- /** Error sanitization options */
796
- interface ErrorSanitizationOptions {
797
- /**
798
- * Enable development mode - shows full error messages.
799
- * Default: false (production mode - sanitized errors only)
800
- */
801
- development?: boolean;
802
- /**
803
- * Custom error sanitizer function.
804
- * Return a safe error message to send to the client.
805
- */
806
- sanitize?: (error: Error) => string;
807
- }
808
- /**
809
- * Health check options
810
- */
811
- interface HealthCheckOptions {
812
- /**
813
- * Enable health check endpoint.
814
- * Default: true
815
- */
816
- enabled?: boolean;
817
- /**
818
- * Custom health check path.
819
- * Default: "/__lens/health"
820
- */
821
- path?: string;
822
- /**
823
- * Custom health check function.
824
- * Return additional checks to include in the response.
825
- */
826
- checks?: () => Promise<Record<string, {
827
- status: "pass" | "fail";
828
- message?: string;
829
- }>> | Record<string, {
830
- status: "pass" | "fail";
831
- message?: string;
832
- }>;
833
- }
834
- interface HTTPHandlerOptions {
835
- /**
836
- * Path prefix for Lens endpoints.
837
- * Default: "" (no prefix)
838
- *
839
- * @example
840
- * ```typescript
841
- * // All endpoints under /api
842
- * createHTTPHandler(app, { pathPrefix: '/api' })
843
- * // Metadata: GET /api/__lens/metadata
844
- * // Operations: POST /api
845
- * ```
846
- */
847
- pathPrefix?: string;
848
- /**
849
- * Custom CORS headers.
850
- * Default: Allow all origins in development, strict in production
851
- */
852
- cors?: {
853
- origin?: string | string[];
854
- methods?: string[];
855
- headers?: string[];
856
- };
857
- /**
858
- * Error sanitization options.
859
- * Controls what error information is exposed to clients.
860
- */
861
- errors?: ErrorSanitizationOptions;
862
- /**
863
- * Health check endpoint configuration.
864
- * Enabled by default at /__lens/health
865
- */
866
- health?: HealthCheckOptions;
867
- }
868
- interface HTTPHandler {
869
- /**
870
- * Handle HTTP request.
871
- * Compatible with fetch API (Bun, Cloudflare Workers, Vercel).
872
- */
873
- (request: Request): Promise<Response>;
874
- /**
875
- * Alternative method-style call.
876
- */
877
- handle(request: Request): Promise<Response>;
878
- }
879
- declare function createHTTPHandler(server: LensServer, options?: HTTPHandlerOptions): HTTPHandler;
880
- interface HandlerOptions extends HTTPHandlerOptions {
881
- /**
882
- * SSE endpoint path.
883
- * Default: "/__lens/sse"
884
- */
885
- ssePath?: string;
886
- /**
887
- * Heartbeat interval for SSE connections in ms.
888
- * Default: 30000
889
- */
890
- heartbeatInterval?: number;
891
- }
892
- interface Handler {
893
- /**
894
- * Handle HTTP/SSE request.
895
- * Compatible with fetch API (Bun, Cloudflare Workers, Vercel).
896
- */
897
- (request: Request): Promise<Response>;
898
- /**
899
- * Alternative method-style call.
900
- */
901
- handle(request: Request): Promise<Response>;
902
- /**
903
- * Access the SSE handler for manual operations.
904
- */
905
- sse: SSEHandler;
906
- }
907
- /**
908
- * Create a unified HTTP + SSE handler from a Lens app.
909
- *
910
- * Automatically routes:
911
- * - GET {ssePath} → SSE connection
912
- * - Other requests → HTTP handler
913
- *
914
- * @example
915
- * ```typescript
916
- * import { createApp, createHandler } from '@sylphx/lens-server'
917
- *
918
- * const app = createApp({ router })
919
- * const handler = createHandler(app)
920
- *
921
- * // Bun
922
- * Bun.serve({ port: 3000, fetch: handler })
923
- *
924
- * // SSE endpoint: GET /__lens/sse
925
- * // HTTP endpoints: POST /, GET /__lens/metadata
926
- * ```
927
- */
928
- declare function createHandler(server: LensServer, options?: HandlerOptions): Handler;
929
- /**
930
- * Create a proxy object that provides typed access to server procedures.
931
- *
932
- * This proxy allows calling server procedures directly without going through
933
- * HTTP. Useful for:
934
- * - Server-side rendering (SSR)
935
- * - Server Components
936
- * - Testing
937
- * - Same-process communication
938
- *
939
- * @example
940
- * ```typescript
941
- * const serverClient = createServerClientProxy(server);
942
- *
943
- * // Call procedures directly (typed!)
944
- * const users = await serverClient.user.list();
945
- * const user = await serverClient.user.get({ id: '123' });
946
- * ```
947
- */
948
- declare function createServerClientProxy(server: LensServer): unknown;
949
- /**
950
- * Handle a query request using standard Web Request/Response API.
951
- *
952
- * Expects input in URL search params as JSON string.
953
- *
954
- * @example
955
- * ```typescript
956
- * // GET /api/lens/user.get?input={"id":"123"}
957
- * const response = await handleWebQuery(server, 'user.get', url);
958
- * ```
959
- */
960
- declare function handleWebQuery(server: LensServer, path: string, url: URL): Promise<Response>;
961
- /**
962
- * Handle a mutation request using standard Web Request/Response API.
963
- *
964
- * Expects input in request body as JSON.
965
- *
966
- * @example
967
- * ```typescript
968
- * // POST /api/lens/user.create with body { "input": { "name": "John" } }
969
- * const response = await handleWebMutation(server, 'user.create', request);
970
- * ```
971
- */
972
- declare function handleWebMutation(server: LensServer, path: string, request: Request): Promise<Response>;
973
- /**
974
- * Handle an SSE subscription request using standard Web Request/Response API.
975
- *
976
- * Creates a ReadableStream that emits SSE events from the subscription.
977
- *
978
- * @example
979
- * ```typescript
980
- * // GET /api/lens/events.stream with Accept: text/event-stream
981
- * const response = handleWebSSE(server, 'events.stream', url, request.signal);
982
- * ```
983
- */
984
- declare function handleWebSSE(server: LensServer, path: string, url: URL, signal?: AbortSignal): Response;
985
- /**
986
- * Options for creating a framework handler.
987
- */
988
- interface FrameworkHandlerOptions {
989
- /** Base path to strip from request URLs */
990
- basePath?: string;
991
- }
992
- /**
993
- * Create a complete request handler for Web standard Request/Response.
994
- *
995
- * Handles:
996
- * - GET requests → Query execution
997
- * - POST requests → Mutation execution
998
- * - SSE requests (Accept: text/event-stream) → Subscriptions
999
- *
1000
- * @example
1001
- * ```typescript
1002
- * const handler = createFrameworkHandler(server, { basePath: '/api/lens' });
1003
- *
1004
- * // In Next.js App Router:
1005
- * const GET = handler;
1006
- * const POST = handler;
1007
- *
1008
- * // In Fresh:
1009
- * const handler = { GET: lensHandler, POST: lensHandler };
1010
- * ```
1011
- */
1012
- declare function createFrameworkHandler(server: LensServer, options?: FrameworkHandlerOptions): (request: Request) => Promise<Response>;
1013
914
  interface WSHandlerOptions {
1014
915
  /**
1015
916
  * Logger for debugging.
@@ -1726,4 +1627,4 @@ declare function toBasicLogger(structuredLogger: StructuredLogger): {
1726
1627
  warn: (message: string, ...args: unknown[]) => void;
1727
1628
  error: (message: string, ...args: unknown[]) => void;
1728
1629
  };
1729
- 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, 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 };
1630
+ 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, 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, 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, FrameworkHandlerOptions, ErrorContext, EntitiesMap, EnhanceOperationMetaContext, EmitResult, DisconnectContext, DEFAULT_WS_HANDLER_CONFIG, DEFAULT_STORAGE_CONFIG, ConnectContext, ClientSendFn, BroadcastResult, BeforeSendContext, BeforeMutationContext, AfterSendContext, AfterMutationContext };