@ibm-aspera/sdk 0.16.0 → 0.19.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 CHANGED
@@ -20,6 +20,7 @@ To include this SDK via `script` tag directly in your web application's HTML, re
20
20
  ```html
21
21
  <script src="https://cdn.jsdelivr.net/npm/@ibm-aspera/sdk@0.2.30/dist/js/aspera-sdk.js"></script>
22
22
  ```
23
+ Check npmjs.com for the latest version (https://www.npmjs.com/package/@ibm-aspera/sdk).
23
24
 
24
25
  ## Usage
25
26
 
@@ -1,5 +1,5 @@
1
1
  import { AsperaSdkInfo, TransferResponse } from '../models/aspera-sdk.model';
2
- import { CustomBrandingOptions, DataTransferResponse, DropzoneEventData, DropzoneOptions, AsperaSdkSpec, AsperaSdkTransfer, FileDialogOptions, FolderDialogOptions, SaveFileDialogOptions, InitOptions, ModifyTransferOptions, Pagination, PaginatedFilesResponse, ResumeTransferOptions, TransferSpec, WebsocketEvent, ReadChunkAsArrayBufferResponse, ReadAsArrayBufferResponse, SdkCapabilities, GetChecksumOptions, ChecksumFileResponse, ReadDirectoryOptions, ReadDirectoryResponse, ShowPreferencesPageOptions, TestSshPortsOptions } from '../models/models';
2
+ import { CustomBrandingOptions, DataTransferResponse, DropzoneEventData, DropzoneOptions, AsperaSdkSpec, AsperaSdkTransfer, FileDialogOptions, FolderDialogOptions, SaveFileDialogOptions, InitOptions, ModifyTransferOptions, Pagination, PaginatedFilesResponse, ResumeTransferOptions, TransferSpec, ReadChunkAsArrayBufferResponse, ReadAsArrayBufferResponse, SdkCapabilities, SdkStatus, GetChecksumOptions, ChecksumFileResponse, ReadDirectoryOptions, ReadDirectoryResponse, ShowPreferencesPageOptions, TestSshPortsOptions } from '../models/models';
3
3
  /**
4
4
  * Check if IBM Aspera for Desktop connection works. This function is called by init
5
5
  * when initializing the SDK. This function can be used at any point for checking.
@@ -16,24 +16,129 @@ export declare const testConnection: () => Promise<any>;
16
16
  */
17
17
  export declare const initDragDrop: (initCall?: boolean) => Promise<boolean>;
18
18
  /**
19
- * Initialize IBM Aspera client. If client cannot (reject/catch), then
20
- * client should attempt fixing server URL or trying again. If still fails disable UI elements.
19
+ * Get the current SDK lifecycle status synchronously.
21
20
  *
22
- * @param options initialization options:
21
+ * @returns the current status, or undefined if no init has been called yet
22
+ */
23
+ export declare const getStatus: () => SdkStatus | undefined;
24
+ /**
25
+ * Initialize the SDK and connect to a transfer client. Returns a promise that resolves
26
+ * when the transfer client is ready, or rejects if it cannot be reached.
27
+ *
28
+ * By default, the SDK connects to IBM Aspera for desktop. Set `connectSettings.useConnect`
29
+ * to use IBM Aspera Connect instead. If `httpGatewaySettings` is provided, the gateway is
30
+ * set up first — when `forceGateway` is true it becomes the sole transport; when false it
31
+ * is set up as a supplementary transport and the primary client (Desktop or Connect) is
32
+ * still initialized afterward.
23
33
  *
24
- * - `appId` the unique ID for the website. Transfers initiated during this session
25
- * will be associated with this ID. It is recommended to use a unique ID to keep transfer
26
- * information private from other websites.
34
+ * Note that the promise behavior varies by transfer client. For Desktop, the promise
35
+ * remains pending until the application is detected. For Connect, the promise resolves
36
+ * immediately after initialization begins — use {@link registerStatusCallback} to track
37
+ * when Connect is actually ready. For a non-blocking alternative that provides consistent
38
+ * lifecycle status events across all transfer clients, see {@link initSession}.
27
39
  *
28
- * - `supportMultipleUsers` when enabled (defaults to false), the SDK will iterate over a port
29
- * range and generate a session id to determine the running instance of the desktop app for the
30
- * current user. This is needed when multiple users may be logged into the same machine
31
- * simultaneously, for example on a Windows Server.
40
+ * @param options - Initialization options. See {@link InitOptions}.
32
41
  *
33
- * @returns a promise that resolves if IBM Aspera Desktop is running properly or
34
- * rejects if unable to connect
42
+ * @returns a promise that resolves with SDK metadata when the transfer client is ready
43
+ *
44
+ * @example
45
+ * init({ appId: 'my-app' })
46
+ * .then(() => {
47
+ * // Transfer client is ready — enable UI
48
+ * })
49
+ * .catch(error => {
50
+ * // Could not connect — prompt user to install or launch
51
+ * });
35
52
  */
36
53
  export declare const init: (options?: InitOptions) => Promise<any>;
54
+ /**
55
+ * Initialize the SDK and begin detecting a transfer client. This function returns
56
+ * immediately — lifecycle status is communicated asynchronously via {@link registerStatusCallback}.
57
+ *
58
+ * The SDK supports three transfer clients. By default, IBM Aspera for desktop is used.
59
+ * Set `connectSettings.useConnect` to use IBM Aspera Connect instead. Desktop and Connect
60
+ * are mutually exclusive — one or the other is detected, not both.
61
+ *
62
+ * ## HTTP Gateway
63
+ *
64
+ * HTTP Gateway is a server-side component that enables browser-based transfers without
65
+ * a desktop application. It can be used in two modes:
66
+ *
67
+ * - **Sole transport** (`forceGateway: true`): HTTP Gateway is the only transport.
68
+ * No Desktop or Connect detection occurs. Status transitions to `RUNNING` when the
69
+ * gateway responds successfully, or `FAILED` if it does not.
70
+ *
71
+ * - **Supplementary transport** (`forceGateway: false`): HTTP Gateway is set up first
72
+ * as an additional transport for browser-based uploads and downloads. The primary
73
+ * transfer client (Desktop or Connect) is then detected separately. If HTTP Gateway
74
+ * setup fails, the primary client is still detected. Features that require a desktop
75
+ * application (native file dialogs, drag and drop, etc.) are only available when the
76
+ * primary client is running.
77
+ *
78
+ * ## Status lifecycle
79
+ *
80
+ * Use {@link registerStatusCallback} to receive status updates. Use {@link getStatus} to
81
+ * read the current status synchronously at any time.
82
+ *
83
+ * **Desktop path**: `INITIALIZING` → `RUNNING` (app detected), `DEGRADED` (timeout but
84
+ * HTTP Gateway is available as a supplementary transport), or `FAILED` (timeout, no
85
+ * fallback). Detection continues in the background after `DEGRADED` or `FAILED` — if the
86
+ * user launches the app later, the status transitions to `RUNNING`.
87
+ *
88
+ * **Connect path**: `INITIALIZING` → `RUNNING`, `FAILED`, `OUTDATED`, or
89
+ * `EXTENSION_INSTALL` depending on the state of the Connect browser extension
90
+ * and application.
91
+ *
92
+ * **HTTP Gateway path** (`forceGateway: true`): `INITIALIZING` → `RUNNING` or `FAILED`.
93
+ *
94
+ * @param options - Initialization options. See {@link InitOptions}.
95
+ *
96
+ * @example
97
+ * // Detect IBM Aspera for desktop (default)
98
+ * initSession({ appId: 'my-app' });
99
+ *
100
+ * @example
101
+ * // Detect IBM Aspera for desktop with status handling
102
+ * registerStatusCallback(status => {
103
+ * if (status === 'RUNNING') {
104
+ * // Transfer client is ready — enable UI
105
+ * } else if (status === 'FAILED') {
106
+ * // Not detected — prompt user to install or launch
107
+ * }
108
+ * });
109
+ *
110
+ * initSession({ appId: 'my-app' });
111
+ *
112
+ * @example
113
+ * // Use IBM Aspera Connect
114
+ * initSession({
115
+ * appId: 'my-app',
116
+ * connectSettings: {
117
+ * useConnect: true,
118
+ * },
119
+ * });
120
+ *
121
+ * @example
122
+ * // Use HTTP Gateway as the sole transport (no desktop app needed)
123
+ * initSession({
124
+ * appId: 'my-app',
125
+ * httpGatewaySettings: {
126
+ * url: 'https://example.com/aspera/http-gwy',
127
+ * forceGateway: true,
128
+ * },
129
+ * });
130
+ *
131
+ * @example
132
+ * // HTTP Gateway as supplementary transport with Desktop as primary
133
+ * initSession({
134
+ * appId: 'my-app',
135
+ * httpGatewaySettings: {
136
+ * url: 'https://example.com/aspera/http-gwy',
137
+ * forceGateway: false,
138
+ * },
139
+ * });
140
+ */
141
+ export declare const initSession: (options?: InitOptions) => void;
37
142
  /**
38
143
  * Tests SSH port connectivity to a transfer server.
39
144
  *
@@ -78,17 +183,45 @@ export declare const registerActivityCallback: (callback: (transfers: TransferRe
78
183
  */
79
184
  export declare const deregisterActivityCallback: (id: string) => void;
80
185
  /**
81
- * Register a callback for getting updates about the connection status of IBM Aspera SDK.
186
+ * Register a callback for SDK lifecycle status changes. The callback fires immediately
187
+ * with the current status (if one exists) and again whenever the status changes.
188
+ *
189
+ * Status values:
82
190
  *
83
- * For example, to be notified of when the SDK loses connection with the application or connection
84
- * is re-established. This can be useful if you want to handle the case where the user quits IBM Aspera
85
- * after `init` has already been called, and want to prompt the user to relaunch the application.
191
+ * - `INITIALIZING` The SDK is detecting a transfer client.
192
+ * - `RUNNING` A transfer client is ready. Full functionality is available.
193
+ * - `DEGRADED` The primary transfer client (IBM Aspera for desktop) was not detected, but HTTP
194
+ * Gateway is available as a fallback. This is only available if XXX...
195
+ * - `FAILED` — No transfer client could be reached. This could be because the user does
196
+ * not have a transfer client installed, it is not running, or in the case of HTTP Gateway,
197
+ * it was not reachable.
198
+ * - `DISCONNECTED` — The transfer client was previously running but lost connection. This is specific
199
+ * to IBM Aspera for desktop. For example, if the user quits the app this status will trigger.
200
+ * - `OUTDATED` — (Connect only) The Connect installation needs updating.
201
+ * - `EXTENSION_INSTALL` — (Connect only) The browser extension needs to be installed.
86
202
  *
87
- * @param callback callback function to receive events
203
+ * For IBM Aspera for desktop, detection continues in the background after `FAILED` or `DEGRADED`.
204
+ * If the user launches the application later, the status transitions to `RUNNING`.
205
+ *
206
+ * @param callback callback function to receive status events
88
207
  *
89
208
  * @returns ID representing the callback for deregistration purposes
90
- */
91
- export declare const registerStatusCallback: (callback: (status: WebsocketEvent) => void) => string;
209
+ *
210
+ * @example
211
+ * const id = registerStatusCallback(status => {
212
+ * if (status === 'RUNNING') {
213
+ * // Full functionality — enable all UI
214
+ * } else if (status === 'DEGRADED') {
215
+ * // Transfers work via HTTP Gateway
216
+ * } else if (status === 'FAILED') {
217
+ * // Nothing available — prompt user to install
218
+ * }
219
+ * });
220
+ *
221
+ * // Later, to stop listening:
222
+ * deregisterStatusCallback(id);
223
+ */
224
+ export declare const registerStatusCallback: (callback: (status: SdkStatus) => void) => string;
92
225
  /**
93
226
  * Remove a callback from getting connection status events.
94
227
  *
@@ -11,14 +11,14 @@ var __assign = (this && this.__assign) || function () {
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.hasCapability = exports.getCapabilities = exports.readDirectory = exports.getChecksum = exports.readChunkAsArrayBuffer = exports.readAsArrayBuffer = exports.getInfo = exports.removeDropzone = exports.createDropzone = exports.setBranding = exports.modifyTransfer = exports.showDirectory = exports.getFilesList = exports.getTransfer = exports.getAllTransfers = exports.showTransferMonitor = exports.showPreferencesPage = exports.showTransferManager = exports.showPreferences = exports.showAbout = exports.showSaveFileDialog = exports.showSelectFolderDialog = exports.showSelectFileDialog = exports.resumeTransfer = exports.stopTransfer = exports.removeTransfer = exports.deregisterStatusCallback = exports.registerStatusCallback = exports.deregisterActivityCallback = exports.registerActivityCallback = exports.startTransfer = exports.authenticate = exports.testSshPorts = exports.init = exports.initDragDrop = exports.testConnection = void 0;
14
+ exports.hasCapability = exports.getCapabilities = exports.readDirectory = exports.getChecksum = exports.readChunkAsArrayBuffer = exports.readAsArrayBuffer = exports.getInfo = exports.removeDropzone = exports.createDropzone = exports.setBranding = exports.modifyTransfer = exports.showDirectory = exports.getFilesList = exports.getTransfer = exports.getAllTransfers = exports.showTransferMonitor = exports.showPreferencesPage = exports.showTransferManager = exports.showPreferences = exports.showAbout = exports.showSaveFileDialog = exports.showSelectFolderDialog = exports.showSelectFileDialog = exports.resumeTransfer = exports.stopTransfer = exports.removeTransfer = exports.deregisterStatusCallback = exports.registerStatusCallback = exports.deregisterActivityCallback = exports.registerActivityCallback = exports.startTransfer = exports.authenticate = exports.testSshPorts = exports.initSession = exports.init = exports.getStatus = exports.initDragDrop = exports.testConnection = void 0;
15
15
  var messages_1 = require("../constants/messages");
16
16
  var client_1 = require("../helpers/client/client");
17
17
  var helpers_1 = require("../helpers/helpers");
18
18
  var http_gateway_1 = require("../http-gateway");
19
19
  var core_1 = require("../http-gateway/core");
20
20
  var index_1 = require("../index");
21
- var connect_sdk_js_1 = require("@ibm-aspera/connect-sdk-js");
21
+ var status_1 = require("./status");
22
22
  var core_2 = require("../connect/core");
23
23
  /**
24
24
  * Check if IBM Aspera for Desktop connection works. This function is called by init
@@ -27,8 +27,7 @@ var core_2 = require("../connect/core");
27
27
  * @returns a promise that resolves if server can connect or rejects if not
28
28
  */
29
29
  var testConnection = function () {
30
- // FIXME: If force HTTP gateway is false this ends up preventing SDK from verifying IBM Aspera for desktop is running.
31
- if (index_1.asperaSdk.useHttpGateway || index_1.asperaSdk.useConnect) {
30
+ if (index_1.asperaSdk.isReady || index_1.asperaSdk.useConnect) {
32
31
  return Promise.resolve(index_1.asperaSdk.globals.sdkResponseData);
33
32
  }
34
33
  return client_1.client.request('get_info')
@@ -40,12 +39,16 @@ var testConnection = function () {
40
39
  };
41
40
  exports.testConnection = testConnection;
42
41
  /**
43
- * RPC discovery used internally when initializing the SDK.
42
+ * RPC discovery used internally during IBM Aspera for desktop initialization to determine
43
+ * the supported RPC methods of the user's version of IBM Aspera for desktop.
44
+ *
45
+ * For convenience, this function will return an empty [] if the SDK is currently configured to use
46
+ * either HTTP Gateway or Connect transfer clients.
44
47
  *
45
48
  * @returns a promise that resolves if discovery is successful
46
49
  */
47
50
  var rpcDiscover = function () {
48
- if (index_1.asperaSdk.useConnect || index_1.asperaSdk.useHttpGateway) {
51
+ if (index_1.asperaSdk.useHttpGateway || index_1.asperaSdk.useConnect) {
49
52
  return Promise.resolve({ methods: [] });
50
53
  }
51
54
  if (!index_1.asperaSdk.isReady) {
@@ -92,99 +95,222 @@ var initDragDrop = function (initCall) {
92
95
  };
93
96
  exports.initDragDrop = initDragDrop;
94
97
  /**
95
- * Initialize IBM Aspera client. If client cannot (reject/catch), then
96
- * client should attempt fixing server URL or trying again. If still fails disable UI elements.
97
- *
98
- * @param options initialization options:
99
- *
100
- * - `appId` the unique ID for the website. Transfers initiated during this session
101
- * will be associated with this ID. It is recommended to use a unique ID to keep transfer
102
- * information private from other websites.
98
+ * Get the current SDK lifecycle status synchronously.
103
99
  *
104
- * - `supportMultipleUsers` when enabled (defaults to false), the SDK will iterate over a port
105
- * range and generate a session id to determine the running instance of the desktop app for the
106
- * current user. This is needed when multiple users may be logged into the same machine
107
- * simultaneously, for example on a Windows Server.
108
- *
109
- * @returns a promise that resolves if IBM Aspera Desktop is running properly or
110
- * rejects if unable to connect
100
+ * @returns the current status, or undefined if no init has been called yet
111
101
  */
112
- var init = function (options) {
113
- var _a, _b, _c;
114
- var appId = (_a = options === null || options === void 0 ? void 0 : options.appId) !== null && _a !== void 0 ? _a : (0, helpers_1.randomUUID)();
115
- index_1.asperaSdk.globals.appId = appId;
102
+ var getStatus = function () {
103
+ return status_1.statusService.getStatus();
104
+ };
105
+ exports.getStatus = getStatus;
106
+ var setupAppId = function (options) {
107
+ var _a;
108
+ index_1.asperaSdk.globals.appId = (_a = options === null || options === void 0 ? void 0 : options.appId) !== null && _a !== void 0 ? _a : (0, helpers_1.randomUUID)();
116
109
  if (options === null || options === void 0 ? void 0 : options.supportMultipleUsers) {
117
110
  index_1.asperaSdk.globals.supportMultipleUsers = true;
118
111
  index_1.asperaSdk.globals.sessionId = (0, helpers_1.randomUUID)();
119
112
  }
113
+ };
114
+ var connectDesktop = function () {
115
+ return index_1.asperaSdk.activityTracking.setup()
116
+ .then(function () { return (0, exports.testConnection)(); })
117
+ .then(function () { return rpcDiscover(); })
118
+ .then(function () { return (0, exports.initDragDrop)(true); })
119
+ .then(function () { return undefined; });
120
+ };
121
+ /**
122
+ * Initialize the SDK and connect to a transfer client. Returns a promise that resolves
123
+ * when the transfer client is ready, or rejects if it cannot be reached.
124
+ *
125
+ * By default, the SDK connects to IBM Aspera for desktop. Set `connectSettings.useConnect`
126
+ * to use IBM Aspera Connect instead. If `httpGatewaySettings` is provided, the gateway is
127
+ * set up first — when `forceGateway` is true it becomes the sole transport; when false it
128
+ * is set up as a supplementary transport and the primary client (Desktop or Connect) is
129
+ * still initialized afterward.
130
+ *
131
+ * Note that the promise behavior varies by transfer client. For Desktop, the promise
132
+ * remains pending until the application is detected. For Connect, the promise resolves
133
+ * immediately after initialization begins — use {@link registerStatusCallback} to track
134
+ * when Connect is actually ready. For a non-blocking alternative that provides consistent
135
+ * lifecycle status events across all transfer clients, see {@link initSession}.
136
+ *
137
+ * @param options - Initialization options. See {@link InitOptions}.
138
+ *
139
+ * @returns a promise that resolves with SDK metadata when the transfer client is ready
140
+ *
141
+ * @example
142
+ * init({ appId: 'my-app' })
143
+ * .then(() => {
144
+ * // Transfer client is ready — enable UI
145
+ * })
146
+ * .catch(error => {
147
+ * // Could not connect — prompt user to install or launch
148
+ * });
149
+ */
150
+ var init = function (options) {
151
+ var _a;
152
+ setupAppId(options);
120
153
  var handleErrors = function (error) {
121
154
  (0, helpers_1.errorLog)(messages_1.messages.serverError, error);
122
155
  index_1.asperaSdk.globals.asperaAppVerified = false;
123
156
  throw (0, helpers_1.generateErrorBody)(messages_1.messages.serverError, error);
124
157
  };
125
- var getConnectStartCalls = function () {
126
- index_1.asperaSdk.globals.connect = new connect_sdk_js_1.Connect({
127
- minVersion: options.connectSettings.minVersion || '3.10.1',
128
- dragDropEnabled: options.connectSettings.dragDropEnabled,
129
- connectMethod: options.connectSettings.method,
130
- });
131
- index_1.asperaSdk.globals.connectInstaller = new connect_sdk_js_1.ConnectInstaller({
132
- sdkLocation: options.connectSettings.sdkLocation,
133
- correlationId: options.connectSettings.correlationId,
134
- style: 'carbon',
135
- version: options.connectSettings.version,
136
- });
137
- index_1.asperaSdk.globals.connectAW4 = {
138
- Connect: connect_sdk_js_1.Connect,
139
- ConnectInstaller: connect_sdk_js_1.ConnectInstaller,
140
- };
141
- return (0, core_2.initConnect)(!options.connectSettings.hideIncludedInstaller);
142
- };
143
158
  var getDesktopStartCalls = function () {
144
- return index_1.asperaSdk.activityTracking.setup()
145
- .then(function () { return (0, exports.testConnection)(); })
146
- .then(function () { return rpcDiscover(); })
147
- .then(function () { return (0, exports.initDragDrop)(true); })
159
+ return connectDesktop()
148
160
  .then(function () { return index_1.asperaSdk.globals.sdkResponseData; })
149
161
  .catch(handleErrors);
150
162
  };
151
- if (((_b = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _b === void 0 ? void 0 : _b.url) && !index_1.asperaSdk.globals.httpGatewayVerified) {
152
- var finalHttpGatewayUrl = options.httpGatewaySettings.url.trim();
153
- if (finalHttpGatewayUrl.indexOf('http') !== 0) {
154
- finalHttpGatewayUrl = "https://".concat(finalHttpGatewayUrl);
155
- }
156
- if (finalHttpGatewayUrl.endsWith('/')) {
157
- finalHttpGatewayUrl = finalHttpGatewayUrl.slice(0, -1);
158
- }
159
- index_1.asperaSdk.globals.httpGatewayUrl = finalHttpGatewayUrl;
160
- return fetch("".concat(index_1.asperaSdk.globals.httpGatewayUrl, "/info"), { method: 'GET' }).then(function (response) {
161
- return response.json().then(function (responseData) {
162
- if (response.status >= 400) {
163
- throw Error(responseData);
164
- }
165
- return responseData;
166
- });
167
- }).then(function (response) {
168
- return (0, http_gateway_1.initHttpGateway)(response);
169
- }).then(function () {
170
- var _a, _b;
163
+ var getTransferClientCalls = function () {
164
+ var _a;
165
+ return ((_a = options === null || options === void 0 ? void 0 : options.connectSettings) === null || _a === void 0 ? void 0 : _a.useConnect) ? (0, core_2.initConnect)(options.connectSettings) : getDesktopStartCalls();
166
+ };
167
+ if (((_a = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _a === void 0 ? void 0 : _a.url) && !index_1.asperaSdk.globals.httpGatewayVerified) {
168
+ return (0, http_gateway_1.setupHttpGateway)(options.httpGatewaySettings.url).then(function () {
169
+ var _a;
171
170
  if ((_a = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _a === void 0 ? void 0 : _a.forceGateway) {
172
171
  return Promise.resolve(index_1.asperaSdk.globals.sdkResponseData);
173
172
  }
174
- return ((_b = options === null || options === void 0 ? void 0 : options.connectSettings) === null || _b === void 0 ? void 0 : _b.useConnect) ? getConnectStartCalls() : getDesktopStartCalls();
173
+ return getTransferClientCalls();
175
174
  }).catch(function (error) {
176
- var _a, _b;
177
- // If HTTP Gateway fails log and move on to transfer client
175
+ var _a;
178
176
  (0, helpers_1.errorLog)(messages_1.messages.httpInitFail, error);
179
177
  if ((_a = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _a === void 0 ? void 0 : _a.forceGateway) {
180
178
  throw (0, helpers_1.generateErrorBody)(messages_1.messages.httpInitFail, error);
181
179
  }
182
- return ((_b = options === null || options === void 0 ? void 0 : options.connectSettings) === null || _b === void 0 ? void 0 : _b.useConnect) ? getConnectStartCalls() : getDesktopStartCalls();
180
+ return getTransferClientCalls();
183
181
  });
184
182
  }
185
- return ((_c = options === null || options === void 0 ? void 0 : options.connectSettings) === null || _c === void 0 ? void 0 : _c.useConnect) ? getConnectStartCalls() : getDesktopStartCalls();
183
+ return getTransferClientCalls();
186
184
  };
187
185
  exports.init = init;
186
+ /**
187
+ * Initialize the SDK and begin detecting a transfer client. This function returns
188
+ * immediately — lifecycle status is communicated asynchronously via {@link registerStatusCallback}.
189
+ *
190
+ * The SDK supports three transfer clients. By default, IBM Aspera for desktop is used.
191
+ * Set `connectSettings.useConnect` to use IBM Aspera Connect instead. Desktop and Connect
192
+ * are mutually exclusive — one or the other is detected, not both.
193
+ *
194
+ * ## HTTP Gateway
195
+ *
196
+ * HTTP Gateway is a server-side component that enables browser-based transfers without
197
+ * a desktop application. It can be used in two modes:
198
+ *
199
+ * - **Sole transport** (`forceGateway: true`): HTTP Gateway is the only transport.
200
+ * No Desktop or Connect detection occurs. Status transitions to `RUNNING` when the
201
+ * gateway responds successfully, or `FAILED` if it does not.
202
+ *
203
+ * - **Supplementary transport** (`forceGateway: false`): HTTP Gateway is set up first
204
+ * as an additional transport for browser-based uploads and downloads. The primary
205
+ * transfer client (Desktop or Connect) is then detected separately. If HTTP Gateway
206
+ * setup fails, the primary client is still detected. Features that require a desktop
207
+ * application (native file dialogs, drag and drop, etc.) are only available when the
208
+ * primary client is running.
209
+ *
210
+ * ## Status lifecycle
211
+ *
212
+ * Use {@link registerStatusCallback} to receive status updates. Use {@link getStatus} to
213
+ * read the current status synchronously at any time.
214
+ *
215
+ * **Desktop path**: `INITIALIZING` → `RUNNING` (app detected), `DEGRADED` (timeout but
216
+ * HTTP Gateway is available as a supplementary transport), or `FAILED` (timeout, no
217
+ * fallback). Detection continues in the background after `DEGRADED` or `FAILED` — if the
218
+ * user launches the app later, the status transitions to `RUNNING`.
219
+ *
220
+ * **Connect path**: `INITIALIZING` → `RUNNING`, `FAILED`, `OUTDATED`, or
221
+ * `EXTENSION_INSTALL` depending on the state of the Connect browser extension
222
+ * and application.
223
+ *
224
+ * **HTTP Gateway path** (`forceGateway: true`): `INITIALIZING` → `RUNNING` or `FAILED`.
225
+ *
226
+ * @param options - Initialization options. See {@link InitOptions}.
227
+ *
228
+ * @example
229
+ * // Detect IBM Aspera for desktop (default)
230
+ * initSession({ appId: 'my-app' });
231
+ *
232
+ * @example
233
+ * // Detect IBM Aspera for desktop with status handling
234
+ * registerStatusCallback(status => {
235
+ * if (status === 'RUNNING') {
236
+ * // Transfer client is ready — enable UI
237
+ * } else if (status === 'FAILED') {
238
+ * // Not detected — prompt user to install or launch
239
+ * }
240
+ * });
241
+ *
242
+ * initSession({ appId: 'my-app' });
243
+ *
244
+ * @example
245
+ * // Use IBM Aspera Connect
246
+ * initSession({
247
+ * appId: 'my-app',
248
+ * connectSettings: {
249
+ * useConnect: true,
250
+ * },
251
+ * });
252
+ *
253
+ * @example
254
+ * // Use HTTP Gateway as the sole transport (no desktop app needed)
255
+ * initSession({
256
+ * appId: 'my-app',
257
+ * httpGatewaySettings: {
258
+ * url: 'https://example.com/aspera/http-gwy',
259
+ * forceGateway: true,
260
+ * },
261
+ * });
262
+ *
263
+ * @example
264
+ * // HTTP Gateway as supplementary transport with Desktop as primary
265
+ * initSession({
266
+ * appId: 'my-app',
267
+ * httpGatewaySettings: {
268
+ * url: 'https://example.com/aspera/http-gwy',
269
+ * forceGateway: false,
270
+ * },
271
+ * });
272
+ */
273
+ var initSession = function (options) {
274
+ var _a, _b, _c;
275
+ setupAppId(options);
276
+ var retryInterval = (_a = options === null || options === void 0 ? void 0 : options.retryInterval) !== null && _a !== void 0 ? _a : 2000;
277
+ var retryTimeout = (_b = options === null || options === void 0 ? void 0 : options.retryTimeout) !== null && _b !== void 0 ? _b : 5000;
278
+ var startDesktopDetection = function () {
279
+ status_1.statusService.startPolling(connectDesktop, retryInterval, retryTimeout);
280
+ };
281
+ var startTransferClient = function () {
282
+ var _a;
283
+ if ((_a = options === null || options === void 0 ? void 0 : options.connectSettings) === null || _a === void 0 ? void 0 : _a.useConnect) {
284
+ (0, core_2.initConnect)(options.connectSettings);
285
+ }
286
+ else {
287
+ startDesktopDetection();
288
+ }
289
+ };
290
+ // HTTP Gateway path
291
+ if (((_c = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _c === void 0 ? void 0 : _c.url) && !index_1.asperaSdk.globals.httpGatewayVerified) {
292
+ status_1.statusService.setStatus('INITIALIZING');
293
+ (0, http_gateway_1.setupHttpGateway)(options.httpGatewaySettings.url).then(function () {
294
+ var _a;
295
+ if ((_a = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _a === void 0 ? void 0 : _a.forceGateway) {
296
+ status_1.statusService.setStatus('RUNNING');
297
+ return;
298
+ }
299
+ startTransferClient();
300
+ }).catch(function (error) {
301
+ var _a;
302
+ (0, helpers_1.errorLog)(messages_1.messages.httpInitFail, error);
303
+ if ((_a = options === null || options === void 0 ? void 0 : options.httpGatewaySettings) === null || _a === void 0 ? void 0 : _a.forceGateway) {
304
+ status_1.statusService.setStatus('FAILED');
305
+ return;
306
+ }
307
+ startTransferClient();
308
+ });
309
+ return;
310
+ }
311
+ startTransferClient();
312
+ };
313
+ exports.initSession = initSession;
188
314
  /**
189
315
  * Tests SSH port connectivity to a transfer server.
190
316
  *
@@ -319,18 +445,46 @@ var deregisterActivityCallback = function (id) {
319
445
  };
320
446
  exports.deregisterActivityCallback = deregisterActivityCallback;
321
447
  /**
322
- * Register a callback for getting updates about the connection status of IBM Aspera SDK.
448
+ * Register a callback for SDK lifecycle status changes. The callback fires immediately
449
+ * with the current status (if one exists) and again whenever the status changes.
323
450
  *
324
- * For example, to be notified of when the SDK loses connection with the application or connection
325
- * is re-established. This can be useful if you want to handle the case where the user quits IBM Aspera
326
- * after `init` has already been called, and want to prompt the user to relaunch the application.
451
+ * Status values:
327
452
  *
328
- * @param callback callback function to receive events
453
+ * - `INITIALIZING` The SDK is detecting a transfer client.
454
+ * - `RUNNING` — A transfer client is ready. Full functionality is available.
455
+ * - `DEGRADED` — The primary transfer client (IBM Aspera for desktop) was not detected, but HTTP
456
+ * Gateway is available as a fallback. This is only available if XXX...
457
+ * - `FAILED` — No transfer client could be reached. This could be because the user does
458
+ * not have a transfer client installed, it is not running, or in the case of HTTP Gateway,
459
+ * it was not reachable.
460
+ * - `DISCONNECTED` — The transfer client was previously running but lost connection. This is specific
461
+ * to IBM Aspera for desktop. For example, if the user quits the app this status will trigger.
462
+ * - `OUTDATED` — (Connect only) The Connect installation needs updating.
463
+ * - `EXTENSION_INSTALL` — (Connect only) The browser extension needs to be installed.
464
+ *
465
+ * For IBM Aspera for desktop, detection continues in the background after `FAILED` or `DEGRADED`.
466
+ * If the user launches the application later, the status transitions to `RUNNING`.
467
+ *
468
+ * @param callback callback function to receive status events
329
469
  *
330
470
  * @returns ID representing the callback for deregistration purposes
471
+ *
472
+ * @example
473
+ * const id = registerStatusCallback(status => {
474
+ * if (status === 'RUNNING') {
475
+ * // Full functionality — enable all UI
476
+ * } else if (status === 'DEGRADED') {
477
+ * // Transfers work via HTTP Gateway
478
+ * } else if (status === 'FAILED') {
479
+ * // Nothing available — prompt user to install
480
+ * }
481
+ * });
482
+ *
483
+ * // Later, to stop listening:
484
+ * deregisterStatusCallback(id);
331
485
  */
332
486
  var registerStatusCallback = function (callback) {
333
- return index_1.asperaSdk.activityTracking.setWebSocketEventCallback(callback);
487
+ return status_1.statusService.registerCallback(callback);
334
488
  };
335
489
  exports.registerStatusCallback = registerStatusCallback;
336
490
  /**
@@ -339,7 +493,7 @@ exports.registerStatusCallback = registerStatusCallback;
339
493
  * @param id the ID returned by `registerStatusCallback`
340
494
  */
341
495
  var deregisterStatusCallback = function (id) {
342
- index_1.asperaSdk.activityTracking.removeWebSocketEventCallback(id);
496
+ status_1.statusService.deregisterCallback(id);
343
497
  };
344
498
  exports.deregisterStatusCallback = deregisterStatusCallback;
345
499
  /**
@@ -0,0 +1,24 @@
1
+ import { SdkStatus } from '../models/models';
2
+ type StatusCallback = (status: SdkStatus) => void;
3
+ declare class StatusService {
4
+ private currentStatus;
5
+ private callbacks;
6
+ private pollTimerId;
7
+ private failTimeoutId;
8
+ getStatus(): SdkStatus | undefined;
9
+ setStatus(status: SdkStatus): void;
10
+ registerCallback(cb: StatusCallback): string;
11
+ deregisterCallback(id: string): void;
12
+ /**
13
+ * Start Desktop detection polling loop.
14
+ *
15
+ * @param detectFn async function that resolves if Desktop is found, rejects if not
16
+ * @param interval ms between attempts
17
+ * @param failTimeout ms before transitioning to FAILED or DEGRADED
18
+ */
19
+ startPolling(detectFn: () => Promise<void>, interval: number, failTimeout: number): void;
20
+ stopPolling(): void;
21
+ reset(): void;
22
+ }
23
+ export declare const statusService: StatusService;
24
+ export {};