@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/README.md +76 -160
- package/dist/index.d.ts +138 -237
- package/dist/index.js +178 -313
- package/package.json +2 -2
- package/src/e2e/server.test.ts +12 -12
- package/src/handlers/http.test.ts +2 -2
- package/src/handlers/index.ts +3 -20
- package/src/handlers/ws.test.ts +3 -3
- package/src/index.ts +25 -41
- package/src/server/create.test.ts +34 -34
- package/src/server/create.ts +143 -14
- package/src/server/types.ts +34 -8
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 -
|
|
564
|
+
* Lens server interface - Callable HTTP handler with executor methods
|
|
565
565
|
*
|
|
566
|
-
* The
|
|
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
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
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
|
-
*
|
|
574
|
-
*
|
|
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
|
|
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
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
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,
|
|
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 };
|