@qafka/react-native 2.4.1 → 2.4.2

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/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.4.2] — 2026-06-22
11
+
12
+ ### Fixed
13
+
14
+ - Voice could fail to connect (the orb stayed on the connecting/waiting state) in apps that did not pass an explicit `apiUrl`. The realtime WebSocket now falls back to the same default backend host as the REST/chat client, instead of building a host-less relative URL that could never complete its handshake. Apps relying on the default backend no longer need to set `apiUrl` just to make voice work.
15
+
10
16
  ## [2.4.1] — 2026-06-21
11
17
 
12
18
  ### Fixed
package/dist/QafkaSDK.js CHANGED
@@ -6,6 +6,7 @@ const BackendService_1 = require("./services/BackendService");
6
6
  const AttestationManager_1 = require("./services/AttestationManager");
7
7
  const ConversationManager_1 = require("./services/ConversationManager");
8
8
  const NavigationHandler_1 = require("./services/NavigationHandler");
9
+ const constants_1 = require("./constants");
9
10
  /**
10
11
  * QafkaSDK - Main SDK class
11
12
  * Provides AI-powered conversational interface for React Native apps
@@ -85,7 +86,7 @@ class QafkaSDK {
85
86
  await this.conversationManager.initialize();
86
87
  this.navigationHandler = new NavigationHandler_1.NavigationHandler(config.navigationRef);
87
88
  // Initialize device attestation
88
- const rawUrl = (config.apiUrl || 'https://api.qafka.com/api/v1').replace(/\/$/, '');
89
+ const rawUrl = (config.apiUrl || `${constants_1.DEFAULT_API_BASE}/api/v1`).replace(/\/$/, '');
89
90
  const attestApiUrl = rawUrl.includes('/api/v1') ? rawUrl : `${rawUrl}/api/v1`;
90
91
  this.attestationManager = new AttestationManager_1.AttestationManager({
91
92
  apiUrl: attestApiUrl,
@@ -49,6 +49,7 @@ const validate_end_user_1 = require("../validate-end-user");
49
49
  const ChatPage_1 = require("./ChatPage");
50
50
  const VoicePage_1 = require("./VoicePage");
51
51
  const useVoiceChat_1 = require("../hooks/useVoiceChat");
52
+ const constants_1 = require("../constants");
52
53
  const { width: SCREEN_WIDTH } = react_native_1.Dimensions.get('window');
53
54
  /**
54
55
  * Qafka Component
@@ -126,10 +127,10 @@ exports.Qafka = (0, react_1.forwardRef)(function Qafka({ style, apiUrl: apiUrlPr
126
127
  debounceMs: 500,
127
128
  });
128
129
  const voiceChat = (0, useVoiceChat_1.useVoiceChat)({
129
- // Voice WebSocket still uses apiKey-based auth. In dev, the resolved
130
- // developmentKey from qafka.config.js flows through. In production, this
131
- // is null and voice will fail at WS handshake.
132
- apiUrl: resolvedApiUrl || apiUrlProp || '',
130
+ // Voice realtime WebSocket. Fall back to the shared default backend host so
131
+ // the WS URL never resolves host-less (an empty apiUrl produced a relative
132
+ // `/v1/realtime` URL → handshake failure). Mirrors the REST client default.
133
+ apiUrl: resolvedApiUrl || apiUrlProp || constants_1.DEFAULT_API_BASE,
133
134
  apiKey: resolvedApiKey || '',
134
135
  userContext: currentContext,
135
136
  contextDescription,
@@ -8,10 +8,11 @@ import type { RuntimeConfig } from '../runtime-config-loader';
8
8
  /**
9
9
  * Augmentation hook for consumer-side projectId literal types.
10
10
  *
11
- * The Qafka CLI generates a `qafka.config.d.ts` file alongside
12
- * `qafka.config.js` whenever it writes the runtime config. That `.d.ts`
13
- * augments this interface with the consumer's project ids as keys —
14
- * giving `<Qafka projectId="..." />` autocomplete + typo validation.
11
+ * The Qafka CLI generates a `qafka.config.d.ts` file at the consumer
12
+ * project root whenever it writes the runtime config; the consumer's
13
+ * tsconfig file scan picks it up. That `.d.ts` augments this interface
14
+ * with the consumer's project ids as keys — giving
15
+ * `<Qafka projectId="..." />` autocomplete + typo validation.
15
16
  *
16
17
  * When the augmentation is absent (fresh project, `qafka init` not yet
17
18
  * run), `keyof QafkaProjectIds` is `never` and `ProjectIdOf` falls back
@@ -3,6 +3,16 @@
3
3
  */
4
4
  export declare const API_VERSION = "v1";
5
5
  export declare const DEFAULT_API_TIMEOUT = 30000;
6
+ /**
7
+ * Default Qafka backend base host (scheme + host only).
8
+ *
9
+ * The REST client appends `/api/v1` and the realtime voice client appends
10
+ * `/v1/realtime`, so this holds the bare base. Used as the fallback when neither
11
+ * an explicit `apiUrl` prop nor a runtime-config `apiUrl` is provided — keeps the
12
+ * REST and voice transports pointed at the same host instead of one silently
13
+ * defaulting while the other resolves to an empty (host-less) URL.
14
+ */
15
+ export declare const DEFAULT_API_BASE = "https://api.qafka.com";
6
16
  export declare const STORAGE_KEYS: {
7
17
  readonly CONFIG: "@qafka/config";
8
18
  readonly CONVERSATION_HISTORY: "@qafka/conversation_history";
package/dist/constants.js CHANGED
@@ -3,9 +3,19 @@
3
3
  * Shared constants for SDK
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.STORAGE_KEYS = exports.DEFAULT_API_TIMEOUT = exports.API_VERSION = void 0;
6
+ exports.STORAGE_KEYS = exports.DEFAULT_API_BASE = exports.DEFAULT_API_TIMEOUT = exports.API_VERSION = void 0;
7
7
  exports.API_VERSION = 'v1';
8
8
  exports.DEFAULT_API_TIMEOUT = 30000;
9
+ /**
10
+ * Default Qafka backend base host (scheme + host only).
11
+ *
12
+ * The REST client appends `/api/v1` and the realtime voice client appends
13
+ * `/v1/realtime`, so this holds the bare base. Used as the fallback when neither
14
+ * an explicit `apiUrl` prop nor a runtime-config `apiUrl` is provided — keeps the
15
+ * REST and voice transports pointed at the same host instead of one silently
16
+ * defaulting while the other resolves to an empty (host-less) URL.
17
+ */
18
+ exports.DEFAULT_API_BASE = 'https://api.qafka.com';
9
19
  exports.STORAGE_KEYS = {
10
20
  CONFIG: '@qafka/config',
11
21
  CONVERSATION_HISTORY: '@qafka/conversation_history',
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference path="../qafka.config.d.ts" />
2
1
  /**
3
2
  * QafkaSDK for React Native
4
3
  * AI-powered conversational interface with navigation intelligence
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qafka/react-native",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "description": "Drop-in AI assistant for React Native: chat, voice, and tool execution with screen-aware navigation.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "LICENSE"
24
24
  ],
25
25
  "scripts": {
26
- "build": "tsc && node -e \"const fs=require('fs'),p='dist/index.d.ts',c=fs.readFileSync(p,'utf-8');if(!c.startsWith('/// <reference'))fs.writeFileSync(p,'/// <reference path=\\\"../qafka.config.d.ts\\\" />\\n'+c,'utf-8');\"",
26
+ "build": "tsc",
27
27
  "dev": "tsc --watch",
28
28
  "clean": "rm -rf dist",
29
29
  "typecheck": "tsc --noEmit",