@mosano-product-framework/sdk 0.2.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.
Files changed (74) hide show
  1. package/README.md +827 -0
  2. package/README.react.md +348 -0
  3. package/dist/auth/claims-types.d.ts +89 -0
  4. package/dist/auth/claims.d.ts +125 -0
  5. package/dist/auth/cross-tab.d.ts +114 -0
  6. package/dist/auth/errors.d.ts +40 -0
  7. package/dist/auth/index.d.ts +18 -0
  8. package/dist/auth/index.js +5 -0
  9. package/dist/auth/index.js.map +1 -0
  10. package/dist/auth/oauth-state.d.ts +93 -0
  11. package/dist/auth/session-manager.d.ts +253 -0
  12. package/dist/auth/storage.d.ts +36 -0
  13. package/dist/auth/tenant-directory.d.ts +59 -0
  14. package/dist/auth/tenant-selection.d.ts +92 -0
  15. package/dist/chunk-7WAV52EO.js +621 -0
  16. package/dist/chunk-7WAV52EO.js.map +1 -0
  17. package/dist/chunk-AJWM5MDZ.js +410 -0
  18. package/dist/chunk-AJWM5MDZ.js.map +1 -0
  19. package/dist/chunk-EXPYHNPV.js +212 -0
  20. package/dist/chunk-EXPYHNPV.js.map +1 -0
  21. package/dist/chunk-GPWGOYCA.js +85 -0
  22. package/dist/chunk-GPWGOYCA.js.map +1 -0
  23. package/dist/chunk-GQJ3QQPH.js +339 -0
  24. package/dist/chunk-GQJ3QQPH.js.map +1 -0
  25. package/dist/chunk-K2ELAI2X.js +64 -0
  26. package/dist/chunk-K2ELAI2X.js.map +1 -0
  27. package/dist/chunk-LRM6JJ63.js +616 -0
  28. package/dist/chunk-LRM6JJ63.js.map +1 -0
  29. package/dist/chunk-XAXFIIRT.js +959 -0
  30. package/dist/chunk-XAXFIIRT.js.map +1 -0
  31. package/dist/client/core/client-factory.d.ts +61 -0
  32. package/dist/client/core/client.d.ts +144 -0
  33. package/dist/client/core/errors.d.ts +105 -0
  34. package/dist/client/core/index.d.ts +9 -0
  35. package/dist/client/core/middleware.d.ts +67 -0
  36. package/dist/client/core/types.d.ts +99 -0
  37. package/dist/client/graphql/client.d.ts +66 -0
  38. package/dist/client/graphql/factory.d.ts +84 -0
  39. package/dist/client/graphql/operation.d.ts +24 -0
  40. package/dist/client/graphql/types.d.ts +60 -0
  41. package/dist/client/graphql/ws-client.d.ts +116 -0
  42. package/dist/client/index.d.ts +17 -0
  43. package/dist/client/index.js +227 -0
  44. package/dist/client/index.js.map +1 -0
  45. package/dist/client/middlewares/admin-auth.d.ts +90 -0
  46. package/dist/client/middlewares/auth.d.ts +81 -0
  47. package/dist/client/middlewares/index.d.ts +12 -0
  48. package/dist/client/middlewares/logging.d.ts +102 -0
  49. package/dist/client/middlewares/retry.d.ts +138 -0
  50. package/dist/client/middlewares/tenant.d.ts +60 -0
  51. package/dist/client/middlewares/turnstile.d.ts +41 -0
  52. package/dist/client/peer-free.d.ts +25 -0
  53. package/dist/client/utils/url.d.ts +19 -0
  54. package/dist/identity/index.d.ts +85 -0
  55. package/dist/identity/index.js +6 -0
  56. package/dist/identity/index.js.map +1 -0
  57. package/dist/identity/types.d.ts +690 -0
  58. package/dist/identity/v0.d.ts +594 -0
  59. package/dist/index.d.ts +50 -0
  60. package/dist/index.js +24 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/react/context.d.ts +47 -0
  63. package/dist/react/hooks.d.ts +120 -0
  64. package/dist/react/index.d.ts +19 -0
  65. package/dist/react/index.js +308 -0
  66. package/dist/react/index.js.map +1 -0
  67. package/dist/react/provider.d.ts +68 -0
  68. package/dist/react/store.d.ts +85 -0
  69. package/dist/storage/index.d.ts +31 -0
  70. package/dist/storage/index.js +5 -0
  71. package/dist/storage/index.js.map +1 -0
  72. package/dist/storage/types.d.ts +107 -0
  73. package/dist/storage/v0.d.ts +120 -0
  74. package/package.json +99 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Core types for the MPF SDK
3
+ */
4
+ /** Token provider interface for SDK consumers */
5
+ export interface TokenProvider {
6
+ getAccessToken: () => string | null | Promise<string | null>;
7
+ /**
8
+ * Called when a 401 is final — a token was attached and renewal was not
9
+ * possible or already failed. The "log out" hook.
10
+ */
11
+ onTokenExpired?: () => void | Promise<void>;
12
+ /**
13
+ * Called on the first 401 of a request that carried a token. Attempt a
14
+ * renewal; resolve `true` to have the request retried once with a fresh
15
+ * token. Wire this to `SessionManager.renew()`.
16
+ */
17
+ onUnauthorized?: () => Promise<boolean>;
18
+ }
19
+ /**
20
+ * Request context passed through the middleware chain
21
+ */
22
+ export interface RequestContext {
23
+ /** The full URL being requested */
24
+ url: string;
25
+ /** The fetch RequestInit options */
26
+ init: RequestInit;
27
+ /** Custom metadata that middlewares can use to pass data */
28
+ metadata: Record<string, unknown>;
29
+ /** The original request options, available for middleware inspection */
30
+ options?: RequestOptions;
31
+ }
32
+ /**
33
+ * Response context passed through the middleware chain
34
+ */
35
+ export interface ResponseContext<T = unknown> {
36
+ /** The raw fetch Response object */
37
+ response: Response;
38
+ /** The parsed response data */
39
+ data: T;
40
+ /** Custom metadata that middlewares can use to pass data */
41
+ metadata: Record<string, unknown>;
42
+ }
43
+ /**
44
+ * Configuration options for the MPF client
45
+ */
46
+ export interface ClientConfig {
47
+ /** Base URL for all API requests (e.g., "https://api.example.com") */
48
+ baseUrl: string;
49
+ /** Default headers to include in all requests */
50
+ headers?: Record<string, string>;
51
+ /** Middlewares to apply to all requests */
52
+ middlewares?: import('./middleware.js').Middleware[];
53
+ }
54
+ /**
55
+ * Options for individual requests
56
+ */
57
+ export interface RequestOptions {
58
+ /** Additional headers for this specific request */
59
+ headers?: Record<string, string>;
60
+ /** AbortSignal for request cancellation */
61
+ signal?: AbortSignal;
62
+ /** Query parameters to append to the URL */
63
+ params?: Record<string, string | number | boolean | undefined>;
64
+ /** When true, the auth middleware will skip injecting the Authorization header */
65
+ skipAuth?: boolean;
66
+ /**
67
+ * Tenant scope for this request. Three meaningful states:
68
+ *
69
+ * - `undefined` — inherit the client-wide tenant selection (the default).
70
+ * - `null` — deliberately unscoped: send no tenant header for this request.
71
+ * - a string — use that tenant for this request only.
72
+ *
73
+ * The `undefined` vs `null` distinction matters: without it, "I did not say"
74
+ * and "I said no tenant" collapse into the same value and a deliberately
75
+ * unscoped call would silently pick up the ambient selection.
76
+ */
77
+ tenant?: string | null;
78
+ /**
79
+ * Role to select within the tenant. Omit to let the server apply that
80
+ * tenant's default role — its `tnts[].dfr` when the token carries one, else
81
+ * `tnts[].rls[0]`.
82
+ */
83
+ tenantRole?: string;
84
+ /** When true, the tenant middleware sends no tenant headers at all. */
85
+ skipTenant?: boolean;
86
+ }
87
+ /**
88
+ * Standard API error response shape
89
+ */
90
+ export interface APIErrorResponse {
91
+ /** Error code identifier */
92
+ code?: string;
93
+ /** Human-readable error message */
94
+ message?: string;
95
+ /** Error string from Go backend */
96
+ error?: string;
97
+ /** Additional error details */
98
+ details?: unknown;
99
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * GraphQL client that extends the base MPF client
3
+ */
4
+ import { MPFClient } from '../core/client.js';
5
+ import type { ClientConfig } from '../core/types.js';
6
+ import type { TypedDocumentNode, GraphQLRequestOptions } from './types.js';
7
+ /**
8
+ * Configuration options for the GraphQL client
9
+ */
10
+ export interface GraphQLClientConfig extends ClientConfig {
11
+ /**
12
+ * GraphQL endpoint path (default: '/graphql')
13
+ */
14
+ endpoint?: string;
15
+ }
16
+ /**
17
+ * GraphQL client for MPF services
18
+ *
19
+ * Supports both raw query strings and typed document nodes for type-safe operations.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const client = new MPFGraphQLClient({ baseUrl: 'https://api.example.com' });
24
+ *
25
+ * // Using raw query string
26
+ * const result = await client.query(`
27
+ * query GetUser($id: ID!) {
28
+ * user(id: $id) { id name email }
29
+ * }
30
+ * `, { id: '123' });
31
+ *
32
+ * // Using typed document node (from codegen)
33
+ * const typedResult = await client.query(GetUserDocument, { id: '123' });
34
+ * ```
35
+ */
36
+ export declare class MPFGraphQLClient extends MPFClient {
37
+ /** The GraphQL endpoint path */
38
+ protected graphqlEndpoint: string;
39
+ constructor(config: GraphQLClientConfig);
40
+ /**
41
+ * Execute a GraphQL query operation
42
+ *
43
+ * @param document - The GraphQL query (string or typed document node)
44
+ * @param variables - Optional variables for the query
45
+ * @param options - Optional request options (headers, signal)
46
+ * @returns The query result data
47
+ * @throws {MPFAPIError} When GraphQL errors occur or no data is returned
48
+ */
49
+ query<TData, TVariables = Record<string, unknown>>(document: TypedDocumentNode<TData, TVariables> | string, variables?: TVariables, options?: GraphQLRequestOptions): Promise<TData>;
50
+ /**
51
+ * Execute a GraphQL mutation operation
52
+ *
53
+ * @param document - The GraphQL mutation (string or typed document node)
54
+ * @param variables - Optional variables for the mutation
55
+ * @param options - Optional request options (headers, signal)
56
+ * @returns The mutation result data
57
+ * @throws {MPFAPIError} When GraphQL errors occur or no data is returned
58
+ */
59
+ mutate<TData, TVariables = Record<string, unknown>>(document: TypedDocumentNode<TData, TVariables> | string, variables?: TVariables, options?: GraphQLRequestOptions): Promise<TData>;
60
+ /**
61
+ * Execute a GraphQL operation (query or mutation)
62
+ *
63
+ * @internal
64
+ */
65
+ private executeOperation;
66
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * `createGraphQLClient` — the GraphQL counterpart to `createAuthClient` /
3
+ * `createStorageClient`, built on the same `attachStandardMiddlewares`
4
+ * wiring (see `core/client-factory.ts`) so it shares one `tokenProvider` /
5
+ * `tenantProvider` with every other client an app constructs.
6
+ *
7
+ * Adds one more axis specific to GraphQL: `mode`, which decides HTTP vs
8
+ * `graphql-ws` per operation. This is a deliberately small stand-in for an
9
+ * Apollo-Link-style split link — enough to route by operation kind, not a
10
+ * general link-chaining system. If usage grows past "route by operation
11
+ * kind" (retry links, batching links, etc.) that is the point to reach for
12
+ * an actual link abstraction; this does not try to anticipate that.
13
+ */
14
+ import { type HttpClientOptions } from '../core/client-factory.js';
15
+ import { type GraphQLWsCreateClientParams, type GraphQLWsClientLike } from './ws-client.js';
16
+ import type { TypedDocumentNode, GraphQLRequestOptions, GraphQLResponse } from './types.js';
17
+ /**
18
+ * How a `createGraphQLClient` routes operations.
19
+ *
20
+ * - `'individual-requests'` — every operation (query/mutation) goes over
21
+ * plain HTTP POST. No socket is ever opened; `subscribe()` throws.
22
+ * - `'websocket'` — every operation, including query/mutation, goes over one
23
+ * `graphql-ws` connection.
24
+ * - `'hybrid'` (default) — starts in `'individual-requests'` behavior.
25
+ * Query/mutation always stay on HTTP (cheaper: no connection to keep
26
+ * alive for the common case). The FIRST `subscribe()` call lazily opens
27
+ * the `graphql-ws` connection; every subscription after that reuses it.
28
+ */
29
+ export type GraphQLConnectionMode = 'individual-requests' | 'websocket' | 'hybrid';
30
+ export interface GraphQLClientOptions extends HttpClientOptions {
31
+ /** GraphQL HTTP endpoint path. @default '/graphql' */
32
+ endpoint?: string;
33
+ /** @default 'hybrid' */
34
+ mode?: GraphQLConnectionMode;
35
+ /**
36
+ * `ws://`/`wss://` endpoint for the `graphql-ws` transport. Defaults to
37
+ * `baseUrl` with `http(s)` swapped for `ws(s)` and `endpoint` appended —
38
+ * correct for Hasura, which serves GraphQL-over-HTTP and `graphql-ws` on
39
+ * the same path. Override for a service that splits them.
40
+ */
41
+ wsUrl?: string;
42
+ /** `WebSocket` implementation for non-browser runtimes (e.g. the `ws` package in Node). */
43
+ webSocketImpl?: unknown;
44
+ /** `graphql-ws` reconnect attempts. @default 5 */
45
+ wsRetryAttempts?: number;
46
+ /**
47
+ * Injectable `graphql-ws` `createClient`, forwarded to
48
+ * {@link createGraphQLWsTransport}. Lets tests exercise `'websocket'`/
49
+ * `'hybrid'` routing with a fake socket instead of a real one — see
50
+ * `ws-client.ts`'s `GraphQLWsClientOptions.createClient` doc.
51
+ */
52
+ wsCreateClient?: (params: GraphQLWsCreateClientParams) => GraphQLWsClientLike;
53
+ }
54
+ export interface GraphQLSubscriptionHandlers<TData> {
55
+ onData: (result: GraphQLResponse<TData>) => void;
56
+ onError?: (error: unknown) => void;
57
+ onComplete?: () => void;
58
+ }
59
+ export interface MPFGraphQLHybridClient {
60
+ query<TData, TVariables = Record<string, unknown>>(document: TypedDocumentNode<TData, TVariables> | string, variables?: TVariables, options?: GraphQLRequestOptions): Promise<TData>;
61
+ mutate<TData, TVariables = Record<string, unknown>>(document: TypedDocumentNode<TData, TVariables> | string, variables?: TVariables, options?: GraphQLRequestOptions): Promise<TData>;
62
+ /**
63
+ * Subscribe to a `subscription` document. Throws synchronously in
64
+ * `'individual-requests'` mode — that mode has no transport for it.
65
+ *
66
+ * @returns An unsubscribe function.
67
+ */
68
+ subscribe<TData, TVariables = Record<string, unknown>>(document: TypedDocumentNode<TData, TVariables> | string, variables: TVariables | undefined, handlers: GraphQLSubscriptionHandlers<TData>): () => void;
69
+ /**
70
+ * Force the `graphql-ws` socket closed; it reopens with a fresh token and
71
+ * resubscribes every live subscription. Wire this to fire on every token
72
+ * renewal — e.g. from `SessionManagerOptions.onTokensChanged` — so a
73
+ * subscription never outlives the token it was opened with. A no-op if no
74
+ * socket has been opened yet (nothing to reconnect).
75
+ */
76
+ reconnectWebSocket(): void;
77
+ /** Release the HTTP client's resources (none currently) and close any open socket. */
78
+ dispose(): void;
79
+ }
80
+ /**
81
+ * Create a GraphQL client with the standard auth/tenant middlewares wired in
82
+ * and a `mode`-selected HTTP/`graphql-ws` transport.
83
+ */
84
+ export declare function createGraphQLClient(options: GraphQLClientOptions): MPFGraphQLHybridClient;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Cheap operation-kind detection — no `graphql` parser dependency.
3
+ *
4
+ * The hybrid client only needs ONE bit: "is this a subscription". A full AST
5
+ * parse (`graphql`'s `parse()` + `getOperationAST()`) would answer that too,
6
+ * but it drags `graphql` into the HTTP-only path as a hard dependency, which
7
+ * defeats the point of `graphql` staying an optional peer (see
8
+ * `graphql/ws-client.ts`). A GraphQL document's operation keyword is always
9
+ * the first non-trivia token — `query`/`mutation`/`subscription`, or omitted
10
+ * entirely for the anonymous-query shorthand (`{ ... }`) — so a regex over the
11
+ * leading trivia is exact, not a heuristic.
12
+ */
13
+ /** The three GraphQL operation kinds, plus `unknown` for an unparseable document. */
14
+ export type OperationKind = 'query' | 'mutation' | 'subscription' | 'unknown';
15
+ /**
16
+ * Determine a GraphQL document's operation kind from its source text.
17
+ *
18
+ * `{ ... }` (no keyword) is the anonymous-query shorthand and is always a
19
+ * `query` — a `subscription` document is never allowed to omit its keyword,
20
+ * per the GraphQL spec, so this cannot misclassify a subscription as a query.
21
+ */
22
+ export declare function getOperationKind(document: string): OperationKind;
23
+ /** Whether a GraphQL document is a subscription. */
24
+ export declare function isSubscription(document: string): boolean;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * GraphQL-specific types for the MPF SDK
3
+ */
4
+ /**
5
+ * Minimal typed document representation
6
+ * Compatible with graphql-request, urql, Apollo, and other GraphQL clients
7
+ */
8
+ export interface TypedDocumentNode<TData = unknown, TVariables = unknown> {
9
+ /** Type brand for compile-time type inference */
10
+ __apiType?: (variables: TVariables) => TData;
11
+ /** Returns the GraphQL query string */
12
+ toString(): string;
13
+ }
14
+ /**
15
+ * Represents a single GraphQL error from the response
16
+ */
17
+ export interface GraphQLError {
18
+ /** Human-readable error message */
19
+ message: string;
20
+ /** Locations in the GraphQL document where the error occurred */
21
+ locations?: Array<{
22
+ line: number;
23
+ column: number;
24
+ }>;
25
+ /** Path to the field that caused the error */
26
+ path?: Array<string | number>;
27
+ /** Additional error metadata */
28
+ extensions?: Record<string, unknown>;
29
+ }
30
+ /**
31
+ * Standard GraphQL response structure
32
+ */
33
+ export interface GraphQLResponse<T = unknown> {
34
+ /** The data returned from the operation */
35
+ data?: T;
36
+ /** Any errors that occurred during execution */
37
+ errors?: GraphQLError[];
38
+ }
39
+ /**
40
+ * Options for individual GraphQL requests
41
+ */
42
+ export interface GraphQLRequestOptions {
43
+ /** Additional headers for this request */
44
+ headers?: Record<string, string>;
45
+ /** AbortSignal for request cancellation */
46
+ signal?: AbortSignal;
47
+ /**
48
+ * Tenant scope for this operation. `undefined` inherits the client-wide
49
+ * selection, `null` is deliberately unscoped, a string selects that tenant.
50
+ *
51
+ * @see {@link import('../core/types.js').RequestOptions.tenant}
52
+ */
53
+ tenant?: string | null;
54
+ /** Role within the tenant. Omit to let the server apply the tenant default. */
55
+ tenantRole?: string;
56
+ /** When true, send no tenant headers for this operation. */
57
+ skipTenant?: boolean;
58
+ /** When true, send no Authorization header for this operation. */
59
+ skipAuth?: boolean;
60
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * `graphql-ws` transport, wired to the SAME `tokenProvider`/`tenantProvider`
3
+ * every REST and HTTP-GraphQL client uses.
4
+ *
5
+ * This is meant to be a project-wide standard, not a go-hasura special case:
6
+ * any microservice exposing `graphql-ws` subscriptions (Hasura's, or a Go
7
+ * service's own) authenticates the same way every other MPF client does —
8
+ * `connectionParams` carries the identical `Authorization: Bearer <jwt>` (plus
9
+ * `X-MPF-Tenant`/`X-MPF-Tenant-Role` when a tenant is selected) that the HTTP
10
+ * middlewares put on REST/GraphQL-over-HTTP requests. A service just needs to
11
+ * read those three keys off the `connection_init` payload at its own webhook
12
+ * auth boundary — no new token format.
13
+ *
14
+ * They are carried under a `headers` key of the `connection_init` payload —
15
+ * `{ headers: { Authorization, 'X-MPF-Tenant', ... } }` — NOT flat at the top
16
+ * level. That is what Hasura reads: over the websocket path it takes
17
+ * `payload.headers` and replays those as the request headers it hands to the
18
+ * auth webhook (hasura-authd). Flat top-level keys are silently ignored, so
19
+ * the socket connects and every subscription then fails as unauthenticated —
20
+ * verified end-to-end against a live stack in
21
+ * `e2e/tests/go-identity/graphql-subscriptions.e2e.test.ts`. It is also the
22
+ * shape the wider `graphql-ws` ecosystem uses for header-style auth, so a Go
23
+ * service reading `payload.headers` stays consistent with both.
24
+ */
25
+ import type { TokenProvider } from '../core/types.js';
26
+ import type { TenantSelectionStore } from '../../auth/tenant-selection.js';
27
+ import type { GraphQLResponse } from './types.js';
28
+ /**
29
+ * The subset of a `graphql-ws` `Client` this module uses. Kept as our own
30
+ * interface (not `import type { Client } from 'graphql-ws'`) so this file
31
+ * never has a hard, non-dynamic dependency on the `graphql-ws` types either —
32
+ * matches `cross-tab.ts`'s `LockManagerLike`/`BroadcastChannelLike` pattern.
33
+ */
34
+ export interface GraphQLWsClientLike {
35
+ subscribe<TData = unknown>(payload: {
36
+ query: string;
37
+ variables?: Record<string, unknown>;
38
+ }, sink: {
39
+ next: (value: {
40
+ data?: TData | null;
41
+ errors?: readonly unknown[];
42
+ }) => void;
43
+ error: (err: unknown) => void;
44
+ complete: () => void;
45
+ }): () => void;
46
+ terminate(): void;
47
+ dispose(): void | Promise<void>;
48
+ }
49
+ /** Options `createGraphQLWsTransport` forwards to `graphql-ws`'s `createClient`. */
50
+ export interface GraphQLWsCreateClientParams {
51
+ url: string;
52
+ lazy: boolean;
53
+ retryAttempts: number;
54
+ webSocketImpl?: unknown;
55
+ /**
56
+ * Resolved per connection attempt. Shape is `{ headers: { ... } }` — see
57
+ * the module doc for why the auth headers are nested rather than flat.
58
+ */
59
+ connectionParams: () => Promise<{
60
+ headers: Record<string, string>;
61
+ }>;
62
+ }
63
+ export interface GraphQLWsClientOptions {
64
+ /** `ws://` or `wss://` endpoint. */
65
+ url: string;
66
+ /** Same token provider passed to the HTTP transport — see module docs. */
67
+ tokenProvider?: TokenProvider;
68
+ /** Same tenant provider passed to the HTTP transport. */
69
+ tenantProvider?: TenantSelectionStore;
70
+ /**
71
+ * `WebSocket` implementation for non-browser environments (Node has no
72
+ * global `WebSocket` before v22). Pass the `ws` package's export there.
73
+ */
74
+ webSocketImpl?: unknown;
75
+ /** Reconnect attempts before giving up on a dropped socket. @default 5 */
76
+ retryAttempts?: number;
77
+ /**
78
+ * Open the socket only when the first subscription starts, close it when
79
+ * the last one ends. @default true — matches `hybrid` mode's "no socket
80
+ * until a subscription shows up" contract.
81
+ */
82
+ lazy?: boolean;
83
+ /**
84
+ * Injectable `graphql-ws` `createClient`. Defaults to a dynamic
85
+ * `import('graphql-ws')`. Tests supply a fake here to exercise the full
86
+ * subscribe/reconnect/dispose contract without a real socket or the
87
+ * `graphql-ws` package — same reason `cross-tab.ts` takes an injectable
88
+ * `locks`/`channelFactory`.
89
+ */
90
+ createClient?: (params: GraphQLWsCreateClientParams) => GraphQLWsClientLike;
91
+ }
92
+ export interface GraphQLSubscriptionSink<TData> {
93
+ next: (result: GraphQLResponse<TData>) => void;
94
+ error: (error: unknown) => void;
95
+ complete: () => void;
96
+ }
97
+ export interface GraphQLWsTransport {
98
+ /** Subscribe; returns an unsubscribe function. */
99
+ subscribe<TData = unknown, TVariables = Record<string, unknown>>(document: {
100
+ toString(): string;
101
+ } | string, variables: TVariables | undefined, sink: GraphQLSubscriptionSink<TData>): () => void;
102
+ /**
103
+ * Force the current socket closed. `graphql-ws`'s own retry logic reopens
104
+ * it with a FRESH `connectionParams` call (so a rotated token is picked up)
105
+ * and resubscribes every still-registered operation automatically.
106
+ *
107
+ * Call this right after a `SessionManager` renewal — see
108
+ * `createGraphQLClient`'s `mode: 'websocket' | 'hybrid'` wiring — so a live
109
+ * subscription is never carried on a token past its renewal point.
110
+ */
111
+ reconnect(): void;
112
+ /** Close the socket and release it for good. Registered subscriptions end. */
113
+ dispose(): void;
114
+ }
115
+ /** Create a `graphql-ws`-backed subscription transport. */
116
+ export declare function createGraphQLWsTransport(options: GraphQLWsClientOptions): GraphQLWsTransport;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `@mosano-product-framework/sdk/client` — the generic transport layer.
3
+ *
4
+ * Everything here is service-agnostic: the HTTP client, the middleware
5
+ * machinery and the built-in middlewares, the error types, and the GraphQL
6
+ * clients (HTTP, WebSocket and hybrid).
7
+ *
8
+ * The root barrel re-exports this module as a `client` namespace, but only the
9
+ * `./peer-free.js` half of it — `createGraphQLClient` and
10
+ * `createGraphQLWsTransport` are subpath-only because they reach the optional
11
+ * `graphql-ws` peer. See the comment at the top of `peer-free.ts`.
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ export * from './peer-free.js';
16
+ export { createGraphQLClient, type GraphQLClientOptions, type GraphQLConnectionMode, type MPFGraphQLHybridClient, type GraphQLSubscriptionHandlers, } from './graphql/factory.js';
17
+ export { createGraphQLWsTransport, type GraphQLWsClientLike, type GraphQLWsCreateClientParams, type GraphQLWsClientOptions, type GraphQLWsTransport, type GraphQLSubscriptionSink, } from './graphql/ws-client.js';