@cloudparse/up-miniapps-sdk 0.5.7 → 0.6.1

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.cts CHANGED
@@ -70,6 +70,8 @@ interface IUserProfile {
70
70
  countryCode: string;
71
71
  /** Phone number without country code. */
72
72
  localNumber: string;
73
+ /** How the user's account was created/registered. */
74
+ registrationType: "up" | "apple" | "google";
73
75
  /** Admin status. */
74
76
  admin: boolean;
75
77
  /** UP points balance. */
@@ -1528,6 +1530,13 @@ declare class MiniAppSDK {
1528
1530
  * @param options The options to provide to the shell app
1529
1531
  */
1530
1532
  initialize(options: IInitializationOptions): Promise<IInitializationResponse>;
1533
+ /**
1534
+ * Returns the last known `env` (shell-provided config like `backendUrl`),
1535
+ * refreshed automatically by `initialize()` and every `UPDATE_CONTEXT`
1536
+ * push — read this instead of caching your own copy of `env` values.
1537
+ * Returns `null` before the first successful `initialize()`/context push.
1538
+ */
1539
+ getEnv<T extends Record<string, unknown> = Record<string, unknown>>(): T | null;
1531
1540
  /**
1532
1541
  * Registers a callback for a specific event from the native shell.
1533
1542
  * @param event The name of the event to listen for.
@@ -1548,4 +1557,216 @@ declare class MiniAppSDK {
1548
1557
  */
1549
1558
  declare const sdk: MiniAppSDK;
1550
1559
 
1551
- export { type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type CenterCallbackParams, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
1560
+ interface CreateApiServiceOptions {
1561
+ /**
1562
+ * Backend URL to use before the shell has ever supplied one via
1563
+ * `initialize()`/`UPDATE_CONTEXT`, or if a boot ever completes without
1564
+ * one (e.g. a degraded/standalone fallback). Should be the app's real
1565
+ * production backend, typically read from a build-time env var baked
1566
+ * via `.env.production` — never a local dev address, since that value
1567
+ * is what actually reaches the network if the live one is ever missing.
1568
+ */
1569
+ defaultBaseUrl: string;
1570
+ /** Same fallback role as `defaultBaseUrl`, for `wsUrl` instead of `baseUrl`. Optional — omit if this app derives its WS URL from `baseUrl` itself. */
1571
+ defaultWsBackendUrl?: string;
1572
+ }
1573
+ interface ApiServiceClient {
1574
+ /** Current backend URL — see `getBaseUrl`'s doc comment below for the full resolution order. */
1575
+ readonly baseUrl: string;
1576
+ /** Current WebSocket backend URL, same resolution order as `baseUrl` but reading the dedicated ws fields instead. `undefined` if neither the shell nor `defaultWsBackendUrl` ever supplied one. */
1577
+ readonly wsUrl: string | undefined;
1578
+ get<T = unknown>(path: string): Promise<INetworkResponse<T>>;
1579
+ post<T = unknown>(path: string, body?: unknown): Promise<INetworkResponse<T>>;
1580
+ patch<T = unknown>(path: string, body?: unknown): Promise<INetworkResponse<T>>;
1581
+ delete(path: string): Promise<INetworkResponse<void>>;
1582
+ graphqlQuery<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<INetworkResponse<{
1583
+ data: T;
1584
+ errors?: {
1585
+ message: string;
1586
+ }[];
1587
+ }>>;
1588
+ }
1589
+ /**
1590
+ * Creates a small REST/GraphQL client that always proxies through
1591
+ * `sdk.network.request` and always resolves the backend URL LIVE — from
1592
+ * `window.__UP_BACKEND_URLS__` (earliest, synchronous, see
1593
+ * `getEarlyBackendUrl` above), then `sdk.getEnv()` (updated by
1594
+ * `initialize()`/`UPDATE_CONTEXT`) — never from a value cached at some
1595
+ * earlier point in the boot sequence. This is the fix for a real,
1596
+ * repeatedly reproduced bug: apps used to assign a mutable `baseUrl` field
1597
+ * imperatively from `initialize()`'s response / `UPDATE_CONTEXT`; if that
1598
+ * one assignment was ever skipped (e.g. the underlying bridge request
1599
+ * losing its response — see `Bridge.send`'s retry, which reduces but does
1600
+ * not entirely eliminate that risk) the field stayed wrong for the rest of
1601
+ * the session, silently sending requests to `defaultBaseUrl` instead.
1602
+ * Reading fresh here means the very next call after either source is
1603
+ * populated self-heals automatically, and there is no second, independent
1604
+ * copy of the URL that can go stale.
1605
+ *
1606
+ * Response shape is the raw `INetworkResponse<T>` (status/data/headers) —
1607
+ * this stays a thin transport client; app-specific response unwrapping,
1608
+ * error-message translation, etc. belong in each app's own thin wrapper
1609
+ * around this, not here.
1610
+ */
1611
+ declare function createApiService(options: CreateApiServiceOptions): ApiServiceClient;
1612
+
1613
+ interface WsMessage {
1614
+ event?: string;
1615
+ [key: string]: unknown;
1616
+ }
1617
+ interface BaseWsServiceOptions<TMessage extends WsMessage> {
1618
+ /**
1619
+ * The REST client from `createApiService` — reused here for two things:
1620
+ * its live `wsUrl` (so this shares the exact same URL resolution as
1621
+ * every REST/GraphQL call, no separate copy to go stale), and its
1622
+ * `post()` to mint a short-lived WS auth ticket in production (see
1623
+ * `ticketPath` below).
1624
+ */
1625
+ api: Pick<ApiServiceClient, "post" | "wsUrl">;
1626
+ /**
1627
+ * REST path (relative, via `api.post`) that mints a short-lived,
1628
+ * single-use ticket for the WS handshake — a mini-app's JS never holds
1629
+ * its own real bearer token in production (`sdk.network.request` proxies
1630
+ * every REST/GraphQL call through the native host shell, which injects
1631
+ * auth on its own side; a raw browser `WebSocket` has no equivalent
1632
+ * bridge and no way to set a custom header, so it authenticates via a
1633
+ * ticket fetched over that same working REST path instead). Expected to
1634
+ * return `{ ticket: string }`. Defaults to `"/ws-ticket"`, matching the
1635
+ * established backend convention (see up-miniapps-backend's
1636
+ * `GetWSTicket`). Pass `null` to disable ticket auth entirely — only
1637
+ * appropriate for a mini-app whose backend has no ws-ticket route yet,
1638
+ * or a genuinely public route (see `requireAuth` below).
1639
+ */
1640
+ ticketPath?: string | null;
1641
+ /**
1642
+ * Raw JWT to use when NOT running inside the native shell (standalone
1643
+ * dev browser) — the consuming app reads its own build-time
1644
+ * `import.meta.env.VITE_DEV_TOKEN` and passes it here; the SDK itself
1645
+ * has no access to a consuming app's Vite env (this package is bundled
1646
+ * by tsup, not Vite). Only ever used outside the shell — a ticket is
1647
+ * always preferred when `isRunningInsideNativeShell()` is true.
1648
+ */
1649
+ devToken?: string | null;
1650
+ /**
1651
+ * Overrides the resolved WS URL outright, for a mini-app whose WS
1652
+ * gateway genuinely lives somewhere `api.wsUrl` doesn't cover. Most
1653
+ * consumers should leave this unset and rely on `api.wsUrl`.
1654
+ */
1655
+ baseUrl?: string;
1656
+ /**
1657
+ * Extra static query params appended to every connection URL. Browsers
1658
+ * (and this WebView) give a raw `WebSocket` no custom-header API — a
1659
+ * query param is the closest equivalent, e.g. for a custom auth scheme
1660
+ * on top of the ticket/token this already sends.
1661
+ */
1662
+ query?: Record<string, string>;
1663
+ /**
1664
+ * When unset/`true` (the default), `connect()` refuses — warns and
1665
+ * delays rather than opening an unauthenticated socket — if neither a
1666
+ * ticket nor `devToken` is available. This is a deliberate safety net:
1667
+ * a channel-scoped app (ticket-authorized per-room access) accidentally
1668
+ * shipping with no auth configured would silently become an open room,
1669
+ * not a loud failure.
1670
+ *
1671
+ * Set to `false` only for a backend route that's genuinely public with
1672
+ * no per-connection identity at all — e.g. up-miniapps-by-night's `/ws`,
1673
+ * which has no auth middleware by design, broadcasts the same public
1674
+ * data to every connection, and has no rooms to gate. `connect()` then
1675
+ * opens the socket with no ticket/token query param whatsoever. Pair
1676
+ * with `ticketPath: null` (no point minting a ticket nobody checks).
1677
+ */
1678
+ requireAuth?: boolean;
1679
+ }
1680
+ /** Options for the channel-scoped mode — pass `channelField` to subscribe/unsubscribe to specific rooms. */
1681
+ interface CreateChannelWsServiceOptions<TMessage extends WsMessage = WsMessage> extends BaseWsServiceOptions<TMessage> {
1682
+ /**
1683
+ * Name of the field on each message that identifies which "room"/channel
1684
+ * it belongs to (e.g. `"groupUuid"`, `"gameUuid"`). Also the field name
1685
+ * used in the `{action, [channelField]: id}` subscribe/unsubscribe wire
1686
+ * messages sent to the backend. Presence of this field is what selects
1687
+ * channel mode over broadcast mode — see `CreateBroadcastWsServiceOptions`.
1688
+ */
1689
+ channelField: string;
1690
+ }
1691
+ /** Options for broadcast mode — omit `channelField` for a single global socket with no room concept. */
1692
+ interface CreateBroadcastWsServiceOptions<TMessage extends WsMessage = WsMessage> extends BaseWsServiceOptions<TMessage> {
1693
+ channelField?: undefined;
1694
+ }
1695
+ type CreateWsServiceOptions<TMessage extends WsMessage = WsMessage> = CreateChannelWsServiceOptions<TMessage> | CreateBroadcastWsServiceOptions<TMessage>;
1696
+ interface WsServiceClient<TMessage extends WsMessage = WsMessage> {
1697
+ /** Opens the connection if not already open/connecting. Safe to call repeatedly. */
1698
+ connect(): Promise<void>;
1699
+ /** Closes the connection and cancels any pending reconnect — no further automatic reconnect happens until `connect()`/`subscribe()` is called again. */
1700
+ disconnect(): void;
1701
+ /**
1702
+ * Subscribes to every message for one channel id. Sends the shared
1703
+ * `{action: "subscribe", [channelField]: id}` wire message automatically
1704
+ * on the first subscriber for that channel (and `"unsubscribe"` on the
1705
+ * last one leaving), and implicitly calls `connect()`. Returns an
1706
+ * unsubscribe function. Multiple concurrent channel ids are fully
1707
+ * supported — each gets its own wire subscribe/unsubscribe message and
1708
+ * its own dispatch, independent of every other channel's subscribers.
1709
+ */
1710
+ subscribe(channelId: string, callback: (message: TMessage) => void): () => void;
1711
+ /**
1712
+ * Subscribes to every message this socket ever receives, regardless of
1713
+ * channel — no wire message is sent for this (there's nothing to
1714
+ * subscribe/unsubscribe to, it's just an additional tap on the same
1715
+ * stream). Runs *alongside* any active `subscribe()` channel
1716
+ * subscriptions, socket.io-style ("join specific rooms AND listen
1717
+ * globally at once") — a message matching an active channel id is
1718
+ * delivered to both that channel's subscribers and every `onMessage`
1719
+ * listener. Implicitly calls `connect()`. Returns an unsubscribe
1720
+ * function.
1721
+ */
1722
+ onMessage(callback: (message: TMessage) => void): () => void;
1723
+ }
1724
+ interface BroadcastWsServiceClient<TMessage extends WsMessage = WsMessage> {
1725
+ /** Opens the connection if not already open/connecting. Safe to call repeatedly. */
1726
+ connect(): Promise<void>;
1727
+ /** Closes the connection and cancels any pending reconnect. */
1728
+ disconnect(): void;
1729
+ /**
1730
+ * Subscribes to every message this socket ever receives — there's no
1731
+ * room/channel concept in broadcast mode, so no subscribe/unsubscribe
1732
+ * wire message is ever sent; the backend just pushes to every connected
1733
+ * client. Implicitly calls `connect()`. Returns an unsubscribe function.
1734
+ */
1735
+ onMessage(callback: (message: TMessage) => void): () => void;
1736
+ }
1737
+ /**
1738
+ * Creates a reconnecting, (usually) authenticated WebSocket client — the WS
1739
+ * counterpart to `createApiService`. Centralizes exactly what every
1740
+ * `up-miniapps-*` app was independently hand-rolling with small drifting
1741
+ * bugs (one app's WS URL was captured once at construction and never
1742
+ * recomputed for the whole session; another always used a dev-only token
1743
+ * even in production, so it could never actually authenticate on a real
1744
+ * device): live URL resolution, ticket-based production auth with a
1745
+ * standalone-dev-token fallback, and exponential-backoff reconnect.
1746
+ *
1747
+ * Two modes, selected by whether `channelField` is present:
1748
+ * - **Channel mode** (`channelField` set): room-scoped pub/sub, matches
1749
+ * up-miniapps-split/up-miniapps-cursor's group/game-room shape. Returns a
1750
+ * `WsServiceClient` with `subscribe(channelId, cb)` — multiple concurrent
1751
+ * channel ids are fully supported — PLUS `onMessage(cb)`, a catch-all that
1752
+ * runs alongside any active channel subscriptions (socket.io-style: join
1753
+ * specific rooms and listen globally at the same time, on one socket).
1754
+ * - **Broadcast mode** (`channelField` omitted): one global socket, no
1755
+ * rooms, no subscribe/unsubscribe wire protocol — every message goes to
1756
+ * every listener. Matches up-miniapps-by-night's public live-update feed
1757
+ * (reactions/flash/favorite counts), which has no per-room access to gate
1758
+ * in the first place. Returns a `BroadcastWsServiceClient` with only
1759
+ * `onMessage(cb)` (no `subscribe` — there's no channel id to subscribe to).
1760
+ *
1761
+ * Deliberately stays a thin transport in both modes, same boundary as
1762
+ * `createApiService`: message *content* interpretation (e.g. treating one
1763
+ * event name as carrying real payload while every other message is a bare
1764
+ * cache-invalidation ping) belongs in each app's own thin wrapper around
1765
+ * this, not here — apps differ enough in what they consider safe to expose
1766
+ * over WS that baking that policy into the SDK would be the wrong
1767
+ * boundary.
1768
+ */
1769
+ declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateChannelWsServiceOptions<TMessage>): WsServiceClient<TMessage>;
1770
+ declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateBroadcastWsServiceOptions<TMessage>): BroadcastWsServiceClient<TMessage>;
1771
+
1772
+ export { type ApiServiceClient, type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type BroadcastWsServiceClient, type CenterCallbackParams, type CreateApiServiceOptions, type CreateBroadcastWsServiceOptions, type CreateChannelWsServiceOptions, type CreateWsServiceOptions, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, type WsMessage, type WsServiceClient, createApiService, createWsService, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
package/dist/index.d.ts CHANGED
@@ -70,6 +70,8 @@ interface IUserProfile {
70
70
  countryCode: string;
71
71
  /** Phone number without country code. */
72
72
  localNumber: string;
73
+ /** How the user's account was created/registered. */
74
+ registrationType: "up" | "apple" | "google";
73
75
  /** Admin status. */
74
76
  admin: boolean;
75
77
  /** UP points balance. */
@@ -1528,6 +1530,13 @@ declare class MiniAppSDK {
1528
1530
  * @param options The options to provide to the shell app
1529
1531
  */
1530
1532
  initialize(options: IInitializationOptions): Promise<IInitializationResponse>;
1533
+ /**
1534
+ * Returns the last known `env` (shell-provided config like `backendUrl`),
1535
+ * refreshed automatically by `initialize()` and every `UPDATE_CONTEXT`
1536
+ * push — read this instead of caching your own copy of `env` values.
1537
+ * Returns `null` before the first successful `initialize()`/context push.
1538
+ */
1539
+ getEnv<T extends Record<string, unknown> = Record<string, unknown>>(): T | null;
1531
1540
  /**
1532
1541
  * Registers a callback for a specific event from the native shell.
1533
1542
  * @param event The name of the event to listen for.
@@ -1548,4 +1557,216 @@ declare class MiniAppSDK {
1548
1557
  */
1549
1558
  declare const sdk: MiniAppSDK;
1550
1559
 
1551
- export { type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type CenterCallbackParams, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
1560
+ interface CreateApiServiceOptions {
1561
+ /**
1562
+ * Backend URL to use before the shell has ever supplied one via
1563
+ * `initialize()`/`UPDATE_CONTEXT`, or if a boot ever completes without
1564
+ * one (e.g. a degraded/standalone fallback). Should be the app's real
1565
+ * production backend, typically read from a build-time env var baked
1566
+ * via `.env.production` — never a local dev address, since that value
1567
+ * is what actually reaches the network if the live one is ever missing.
1568
+ */
1569
+ defaultBaseUrl: string;
1570
+ /** Same fallback role as `defaultBaseUrl`, for `wsUrl` instead of `baseUrl`. Optional — omit if this app derives its WS URL from `baseUrl` itself. */
1571
+ defaultWsBackendUrl?: string;
1572
+ }
1573
+ interface ApiServiceClient {
1574
+ /** Current backend URL — see `getBaseUrl`'s doc comment below for the full resolution order. */
1575
+ readonly baseUrl: string;
1576
+ /** Current WebSocket backend URL, same resolution order as `baseUrl` but reading the dedicated ws fields instead. `undefined` if neither the shell nor `defaultWsBackendUrl` ever supplied one. */
1577
+ readonly wsUrl: string | undefined;
1578
+ get<T = unknown>(path: string): Promise<INetworkResponse<T>>;
1579
+ post<T = unknown>(path: string, body?: unknown): Promise<INetworkResponse<T>>;
1580
+ patch<T = unknown>(path: string, body?: unknown): Promise<INetworkResponse<T>>;
1581
+ delete(path: string): Promise<INetworkResponse<void>>;
1582
+ graphqlQuery<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<INetworkResponse<{
1583
+ data: T;
1584
+ errors?: {
1585
+ message: string;
1586
+ }[];
1587
+ }>>;
1588
+ }
1589
+ /**
1590
+ * Creates a small REST/GraphQL client that always proxies through
1591
+ * `sdk.network.request` and always resolves the backend URL LIVE — from
1592
+ * `window.__UP_BACKEND_URLS__` (earliest, synchronous, see
1593
+ * `getEarlyBackendUrl` above), then `sdk.getEnv()` (updated by
1594
+ * `initialize()`/`UPDATE_CONTEXT`) — never from a value cached at some
1595
+ * earlier point in the boot sequence. This is the fix for a real,
1596
+ * repeatedly reproduced bug: apps used to assign a mutable `baseUrl` field
1597
+ * imperatively from `initialize()`'s response / `UPDATE_CONTEXT`; if that
1598
+ * one assignment was ever skipped (e.g. the underlying bridge request
1599
+ * losing its response — see `Bridge.send`'s retry, which reduces but does
1600
+ * not entirely eliminate that risk) the field stayed wrong for the rest of
1601
+ * the session, silently sending requests to `defaultBaseUrl` instead.
1602
+ * Reading fresh here means the very next call after either source is
1603
+ * populated self-heals automatically, and there is no second, independent
1604
+ * copy of the URL that can go stale.
1605
+ *
1606
+ * Response shape is the raw `INetworkResponse<T>` (status/data/headers) —
1607
+ * this stays a thin transport client; app-specific response unwrapping,
1608
+ * error-message translation, etc. belong in each app's own thin wrapper
1609
+ * around this, not here.
1610
+ */
1611
+ declare function createApiService(options: CreateApiServiceOptions): ApiServiceClient;
1612
+
1613
+ interface WsMessage {
1614
+ event?: string;
1615
+ [key: string]: unknown;
1616
+ }
1617
+ interface BaseWsServiceOptions<TMessage extends WsMessage> {
1618
+ /**
1619
+ * The REST client from `createApiService` — reused here for two things:
1620
+ * its live `wsUrl` (so this shares the exact same URL resolution as
1621
+ * every REST/GraphQL call, no separate copy to go stale), and its
1622
+ * `post()` to mint a short-lived WS auth ticket in production (see
1623
+ * `ticketPath` below).
1624
+ */
1625
+ api: Pick<ApiServiceClient, "post" | "wsUrl">;
1626
+ /**
1627
+ * REST path (relative, via `api.post`) that mints a short-lived,
1628
+ * single-use ticket for the WS handshake — a mini-app's JS never holds
1629
+ * its own real bearer token in production (`sdk.network.request` proxies
1630
+ * every REST/GraphQL call through the native host shell, which injects
1631
+ * auth on its own side; a raw browser `WebSocket` has no equivalent
1632
+ * bridge and no way to set a custom header, so it authenticates via a
1633
+ * ticket fetched over that same working REST path instead). Expected to
1634
+ * return `{ ticket: string }`. Defaults to `"/ws-ticket"`, matching the
1635
+ * established backend convention (see up-miniapps-backend's
1636
+ * `GetWSTicket`). Pass `null` to disable ticket auth entirely — only
1637
+ * appropriate for a mini-app whose backend has no ws-ticket route yet,
1638
+ * or a genuinely public route (see `requireAuth` below).
1639
+ */
1640
+ ticketPath?: string | null;
1641
+ /**
1642
+ * Raw JWT to use when NOT running inside the native shell (standalone
1643
+ * dev browser) — the consuming app reads its own build-time
1644
+ * `import.meta.env.VITE_DEV_TOKEN` and passes it here; the SDK itself
1645
+ * has no access to a consuming app's Vite env (this package is bundled
1646
+ * by tsup, not Vite). Only ever used outside the shell — a ticket is
1647
+ * always preferred when `isRunningInsideNativeShell()` is true.
1648
+ */
1649
+ devToken?: string | null;
1650
+ /**
1651
+ * Overrides the resolved WS URL outright, for a mini-app whose WS
1652
+ * gateway genuinely lives somewhere `api.wsUrl` doesn't cover. Most
1653
+ * consumers should leave this unset and rely on `api.wsUrl`.
1654
+ */
1655
+ baseUrl?: string;
1656
+ /**
1657
+ * Extra static query params appended to every connection URL. Browsers
1658
+ * (and this WebView) give a raw `WebSocket` no custom-header API — a
1659
+ * query param is the closest equivalent, e.g. for a custom auth scheme
1660
+ * on top of the ticket/token this already sends.
1661
+ */
1662
+ query?: Record<string, string>;
1663
+ /**
1664
+ * When unset/`true` (the default), `connect()` refuses — warns and
1665
+ * delays rather than opening an unauthenticated socket — if neither a
1666
+ * ticket nor `devToken` is available. This is a deliberate safety net:
1667
+ * a channel-scoped app (ticket-authorized per-room access) accidentally
1668
+ * shipping with no auth configured would silently become an open room,
1669
+ * not a loud failure.
1670
+ *
1671
+ * Set to `false` only for a backend route that's genuinely public with
1672
+ * no per-connection identity at all — e.g. up-miniapps-by-night's `/ws`,
1673
+ * which has no auth middleware by design, broadcasts the same public
1674
+ * data to every connection, and has no rooms to gate. `connect()` then
1675
+ * opens the socket with no ticket/token query param whatsoever. Pair
1676
+ * with `ticketPath: null` (no point minting a ticket nobody checks).
1677
+ */
1678
+ requireAuth?: boolean;
1679
+ }
1680
+ /** Options for the channel-scoped mode — pass `channelField` to subscribe/unsubscribe to specific rooms. */
1681
+ interface CreateChannelWsServiceOptions<TMessage extends WsMessage = WsMessage> extends BaseWsServiceOptions<TMessage> {
1682
+ /**
1683
+ * Name of the field on each message that identifies which "room"/channel
1684
+ * it belongs to (e.g. `"groupUuid"`, `"gameUuid"`). Also the field name
1685
+ * used in the `{action, [channelField]: id}` subscribe/unsubscribe wire
1686
+ * messages sent to the backend. Presence of this field is what selects
1687
+ * channel mode over broadcast mode — see `CreateBroadcastWsServiceOptions`.
1688
+ */
1689
+ channelField: string;
1690
+ }
1691
+ /** Options for broadcast mode — omit `channelField` for a single global socket with no room concept. */
1692
+ interface CreateBroadcastWsServiceOptions<TMessage extends WsMessage = WsMessage> extends BaseWsServiceOptions<TMessage> {
1693
+ channelField?: undefined;
1694
+ }
1695
+ type CreateWsServiceOptions<TMessage extends WsMessage = WsMessage> = CreateChannelWsServiceOptions<TMessage> | CreateBroadcastWsServiceOptions<TMessage>;
1696
+ interface WsServiceClient<TMessage extends WsMessage = WsMessage> {
1697
+ /** Opens the connection if not already open/connecting. Safe to call repeatedly. */
1698
+ connect(): Promise<void>;
1699
+ /** Closes the connection and cancels any pending reconnect — no further automatic reconnect happens until `connect()`/`subscribe()` is called again. */
1700
+ disconnect(): void;
1701
+ /**
1702
+ * Subscribes to every message for one channel id. Sends the shared
1703
+ * `{action: "subscribe", [channelField]: id}` wire message automatically
1704
+ * on the first subscriber for that channel (and `"unsubscribe"` on the
1705
+ * last one leaving), and implicitly calls `connect()`. Returns an
1706
+ * unsubscribe function. Multiple concurrent channel ids are fully
1707
+ * supported — each gets its own wire subscribe/unsubscribe message and
1708
+ * its own dispatch, independent of every other channel's subscribers.
1709
+ */
1710
+ subscribe(channelId: string, callback: (message: TMessage) => void): () => void;
1711
+ /**
1712
+ * Subscribes to every message this socket ever receives, regardless of
1713
+ * channel — no wire message is sent for this (there's nothing to
1714
+ * subscribe/unsubscribe to, it's just an additional tap on the same
1715
+ * stream). Runs *alongside* any active `subscribe()` channel
1716
+ * subscriptions, socket.io-style ("join specific rooms AND listen
1717
+ * globally at once") — a message matching an active channel id is
1718
+ * delivered to both that channel's subscribers and every `onMessage`
1719
+ * listener. Implicitly calls `connect()`. Returns an unsubscribe
1720
+ * function.
1721
+ */
1722
+ onMessage(callback: (message: TMessage) => void): () => void;
1723
+ }
1724
+ interface BroadcastWsServiceClient<TMessage extends WsMessage = WsMessage> {
1725
+ /** Opens the connection if not already open/connecting. Safe to call repeatedly. */
1726
+ connect(): Promise<void>;
1727
+ /** Closes the connection and cancels any pending reconnect. */
1728
+ disconnect(): void;
1729
+ /**
1730
+ * Subscribes to every message this socket ever receives — there's no
1731
+ * room/channel concept in broadcast mode, so no subscribe/unsubscribe
1732
+ * wire message is ever sent; the backend just pushes to every connected
1733
+ * client. Implicitly calls `connect()`. Returns an unsubscribe function.
1734
+ */
1735
+ onMessage(callback: (message: TMessage) => void): () => void;
1736
+ }
1737
+ /**
1738
+ * Creates a reconnecting, (usually) authenticated WebSocket client — the WS
1739
+ * counterpart to `createApiService`. Centralizes exactly what every
1740
+ * `up-miniapps-*` app was independently hand-rolling with small drifting
1741
+ * bugs (one app's WS URL was captured once at construction and never
1742
+ * recomputed for the whole session; another always used a dev-only token
1743
+ * even in production, so it could never actually authenticate on a real
1744
+ * device): live URL resolution, ticket-based production auth with a
1745
+ * standalone-dev-token fallback, and exponential-backoff reconnect.
1746
+ *
1747
+ * Two modes, selected by whether `channelField` is present:
1748
+ * - **Channel mode** (`channelField` set): room-scoped pub/sub, matches
1749
+ * up-miniapps-split/up-miniapps-cursor's group/game-room shape. Returns a
1750
+ * `WsServiceClient` with `subscribe(channelId, cb)` — multiple concurrent
1751
+ * channel ids are fully supported — PLUS `onMessage(cb)`, a catch-all that
1752
+ * runs alongside any active channel subscriptions (socket.io-style: join
1753
+ * specific rooms and listen globally at the same time, on one socket).
1754
+ * - **Broadcast mode** (`channelField` omitted): one global socket, no
1755
+ * rooms, no subscribe/unsubscribe wire protocol — every message goes to
1756
+ * every listener. Matches up-miniapps-by-night's public live-update feed
1757
+ * (reactions/flash/favorite counts), which has no per-room access to gate
1758
+ * in the first place. Returns a `BroadcastWsServiceClient` with only
1759
+ * `onMessage(cb)` (no `subscribe` — there's no channel id to subscribe to).
1760
+ *
1761
+ * Deliberately stays a thin transport in both modes, same boundary as
1762
+ * `createApiService`: message *content* interpretation (e.g. treating one
1763
+ * event name as carrying real payload while every other message is a bare
1764
+ * cache-invalidation ping) belongs in each app's own thin wrapper around
1765
+ * this, not here — apps differ enough in what they consider safe to expose
1766
+ * over WS that baking that policy into the SDK would be the wrong
1767
+ * boundary.
1768
+ */
1769
+ declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateChannelWsServiceOptions<TMessage>): WsServiceClient<TMessage>;
1770
+ declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateBroadcastWsServiceOptions<TMessage>): BroadcastWsServiceClient<TMessage>;
1771
+
1772
+ export { type ApiServiceClient, type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type BroadcastWsServiceClient, type CenterCallbackParams, type CreateApiServiceOptions, type CreateBroadcastWsServiceOptions, type CreateChannelWsServiceOptions, type CreateWsServiceOptions, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, type WsMessage, type WsServiceClient, createApiService, createWsService, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };