@stackwright-services/runtime 0.1.0 → 0.3.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.mts CHANGED
@@ -689,7 +689,7 @@ interface DataSourceDescriptor {
689
689
  */
690
690
  id: string;
691
691
  /** Transport protocol this source is backed by */
692
- transport: 'openapi' | 'pulse';
692
+ transport: 'openapi' | 'pulse' | 'websocket' | 'sse';
693
693
  /** List of named operations this source supports */
694
694
  operations: string[];
695
695
  /** Human-readable description (optional, from adapter metadata) */
@@ -794,14 +794,30 @@ declare const noopDataSourceProvider: NoopDataSourceProvider;
794
794
  * });
795
795
  * ```
796
796
  *
797
+ * @example Streaming WebSocket/SSE provider
798
+ * ```typescript
799
+ * const provider = createDataSourceProvider({
800
+ * provider: 'websocket',
801
+ * config: {
802
+ * sources: [{
803
+ * id: 'ais-vessels',
804
+ * transport: 'websocket',
805
+ * operations: { getLatestPositions: () => vesselCache.snapshot() },
806
+ * }],
807
+ * },
808
+ * });
809
+ * ```
810
+ *
797
811
  * @example Environment-level override (force noop in isolated tests)
798
812
  * ```bash
799
813
  * DATA_SOURCE_PROVIDER=noop node my-service.js
800
814
  * DATA_SOURCE_PROVIDER=pulse node my-service.js # force pulse even if openapi is installed
815
+ * DATA_SOURCE_PROVIDER=websocket node my-service.js # force streaming (WebSocket)
816
+ * DATA_SOURCE_PROVIDER=sse node my-service.js # force streaming (SSE)
801
817
  * ```
802
818
  */
803
819
  declare function createDataSourceProvider(options?: {
804
- /** Override the provider type ('openapi' | 'pulse' | 'noop') */
820
+ /** Override the provider type ('openapi' | 'pulse' | 'websocket' | 'sse' | 'noop') */
805
821
  provider?: string;
806
822
  /** Provider-specific config passed through to the adapter */
807
823
  config?: Record<string, unknown>;
package/dist/index.d.ts CHANGED
@@ -689,7 +689,7 @@ interface DataSourceDescriptor {
689
689
  */
690
690
  id: string;
691
691
  /** Transport protocol this source is backed by */
692
- transport: 'openapi' | 'pulse';
692
+ transport: 'openapi' | 'pulse' | 'websocket' | 'sse';
693
693
  /** List of named operations this source supports */
694
694
  operations: string[];
695
695
  /** Human-readable description (optional, from adapter metadata) */
@@ -794,14 +794,30 @@ declare const noopDataSourceProvider: NoopDataSourceProvider;
794
794
  * });
795
795
  * ```
796
796
  *
797
+ * @example Streaming WebSocket/SSE provider
798
+ * ```typescript
799
+ * const provider = createDataSourceProvider({
800
+ * provider: 'websocket',
801
+ * config: {
802
+ * sources: [{
803
+ * id: 'ais-vessels',
804
+ * transport: 'websocket',
805
+ * operations: { getLatestPositions: () => vesselCache.snapshot() },
806
+ * }],
807
+ * },
808
+ * });
809
+ * ```
810
+ *
797
811
  * @example Environment-level override (force noop in isolated tests)
798
812
  * ```bash
799
813
  * DATA_SOURCE_PROVIDER=noop node my-service.js
800
814
  * DATA_SOURCE_PROVIDER=pulse node my-service.js # force pulse even if openapi is installed
815
+ * DATA_SOURCE_PROVIDER=websocket node my-service.js # force streaming (WebSocket)
816
+ * DATA_SOURCE_PROVIDER=sse node my-service.js # force streaming (SSE)
801
817
  * ```
802
818
  */
803
819
  declare function createDataSourceProvider(options?: {
804
- /** Override the provider type ('openapi' | 'pulse' | 'noop') */
820
+ /** Override the provider type ('openapi' | 'pulse' | 'websocket' | 'sse' | 'noop') */
805
821
  provider?: string;
806
822
  /** Provider-specific config passed through to the adapter */
807
823
  config?: Record<string, unknown>;
package/dist/index.js CHANGED
@@ -856,6 +856,7 @@ var OpenApiDataSourceProvider = class {
856
856
  this.config = config;
857
857
  this.sourcesMap = new Map(config.sources.map((s) => [s.id, s]));
858
858
  }
859
+ config;
859
860
  name = "openapi";
860
861
  sourcesMap;
861
862
  listSources() {
@@ -903,6 +904,7 @@ var PulseDataSourceProvider = class {
903
904
  this.config = config;
904
905
  this.sourcesMap = new Map(config.sources.map((s) => [s.id, s]));
905
906
  }
907
+ config;
906
908
  name = "pulse";
907
909
  sourcesMap;
908
910
  listSources() {
@@ -943,6 +945,51 @@ function listDataSources2() {
943
945
  return [];
944
946
  }
945
947
 
948
+ // src/datasource/streaming-adapter.ts
949
+ var LOG_PREFIX4 = "stackwright-services:datasource:streaming";
950
+ var StreamingDataSourceProvider = class {
951
+ constructor(config) {
952
+ this.config = config;
953
+ this.sourcesMap = new Map(config.sources.map((s) => [s.id, s]));
954
+ }
955
+ config;
956
+ name = "streaming";
957
+ sourcesMap;
958
+ listSources() {
959
+ return Array.from(this.sourcesMap.values()).map((s) => ({
960
+ id: s.id,
961
+ transport: s.transport,
962
+ operations: Object.keys(s.operations),
963
+ ...s.description !== void 0 && { description: s.description }
964
+ }));
965
+ }
966
+ async execute(source, operation, params) {
967
+ const registration = this.sourcesMap.get(source);
968
+ if (!registration) {
969
+ const knownSources = Array.from(this.sourcesMap.keys());
970
+ return Promise.reject(
971
+ new Error(
972
+ `${LOG_PREFIX4} Unknown source "${source}". ` + (knownSources.length > 0 ? `Known sources: ${knownSources.join(", ")}.` : "No sources are registered. Pass sources in StreamingAdapterConfig.")
973
+ )
974
+ );
975
+ }
976
+ const handler = registration.operations[operation];
977
+ if (!handler) {
978
+ const knownOps = Object.keys(registration.operations);
979
+ return Promise.reject(
980
+ new Error(
981
+ `${LOG_PREFIX4} Unknown operation "${operation}" on source "${source}". ` + (knownOps.length > 0 ? `Known operations: ${knownOps.join(", ")}.` : "No operations are registered for this source.")
982
+ )
983
+ );
984
+ }
985
+ const data = await handler(params);
986
+ return { data };
987
+ }
988
+ };
989
+ function createStreamingDataSourceProvider(config) {
990
+ return new StreamingDataSourceProvider(config);
991
+ }
992
+
946
993
  // src/datasource/factory.ts
947
994
  function createDataSourceProvider(options) {
948
995
  const providerType = options?.provider ?? process.env["DATA_SOURCE_PROVIDER"] ?? _autoDiscover();
@@ -959,6 +1006,12 @@ function createDataSourceProvider(options) {
959
1006
  options?.config ?? { sources: [] }
960
1007
  );
961
1008
  }
1009
+ case "websocket":
1010
+ case "sse": {
1011
+ return createStreamingDataSourceProvider(
1012
+ options?.config ?? { sources: [] }
1013
+ );
1014
+ }
962
1015
  default:
963
1016
  if (providerType !== "noop") {
964
1017
  console.warn(
@@ -976,7 +1029,10 @@ function _autoDiscover() {
976
1029
  // registration and does NOT trigger auto-discovery.
977
1030
  { pkg: "@stackwright-pro/openapi/datasource-adapter", providerType: "openapi" },
978
1031
  // @stackwright-pro/pulse follows the same pattern for Pulse-backed data sources.
979
- { pkg: "@stackwright-pro/pulse/datasource-adapter", providerType: "pulse" }
1032
+ { pkg: "@stackwright-pro/pulse/datasource-adapter", providerType: "pulse" },
1033
+ // @stackwright-pro/pulse also ships a streaming-datasource-adapter for WebSocket/SSE sources.
1034
+ // websocket wins if both pulse and streaming are installed (use DATA_SOURCE_PROVIDER to override).
1035
+ { pkg: "@stackwright-pro/pulse/streaming-datasource-adapter", providerType: "websocket" }
980
1036
  ];
981
1037
  for (const { pkg, providerType } of candidates) {
982
1038
  try {