dolphin-server-modules 2.12.1 → 2.12.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/README.md +1 -0
- package/dist/client/api.d.ts +24 -0
- package/dist/client/api.js +113 -0
- package/dist/client/api.js.map +1 -0
- package/dist/client/auth.d.ts +53 -0
- package/dist/client/auth.js +121 -0
- package/dist/client/auth.js.map +1 -0
- package/dist/client/core.d.ts +97 -0
- package/dist/client/core.js +342 -0
- package/dist/client/core.js.map +1 -0
- package/dist/client/dom.d.ts +1 -0
- package/dist/client/dom.js +228 -0
- package/dist/client/dom.js.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +12 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/store.d.ts +18 -0
- package/dist/client/store.js +132 -0
- package/dist/client/store.js.map +1 -0
- package/dist/client.test.d.ts +1 -22
- package/dist/client.test.js +1 -1
- package/dist/client.test.js.map +1 -1
- package/dist/client_dom.test.d.ts +1 -0
- package/dist/client_dom.test.js +99 -0
- package/dist/client_dom.test.js.map +1 -0
- package/dist/server/client-serve.js +1 -1
- package/dist/server/client-serve.js.map +1 -1
- package/package.json +178 -176
- package/scripts/client.js +874 -1003
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
Dolphin Framework को विस्तृत र आधिकारिक गाइड उपलब्ध छ। यसमा **Auth, CRUD, Models, र Controllers** को १००% ट्युटोरियल समावेश छ।
|
|
15
15
|
|
|
16
16
|
👉 **[Dolphin Master Guide (Web Version)](https://raw.githack.com/Phuyalshankar/dolphin-server-modules/main/guide.html)** *(Most Up-to-Date)*
|
|
17
|
+
👉 **[Dolphin Client Tutorial (Nepali) - MD](./CLIENT_TUTORIAL_NEPALI.md)** | **[PDF Version](./CLIENT_TUTORIAL_NEPALI.pdf)**
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare class APIHandler {
|
|
2
|
+
/** @param {DolphinClient} client */
|
|
3
|
+
constructor(client: any);
|
|
4
|
+
/** @private */
|
|
5
|
+
_createProxy(pathParts: any): {
|
|
6
|
+
(options: any): any;
|
|
7
|
+
get(pathOrOptions: any, options: any): any;
|
|
8
|
+
post(pathOrBody: any, bodyOrOptions: any, options: any): any;
|
|
9
|
+
put(pathOrBody: any, bodyOrOptions: any, options: any): any;
|
|
10
|
+
patch(pathOrBody: any, bodyOrOptions: any, options: any): any;
|
|
11
|
+
del(pathOrOptions: any, options: any): any;
|
|
12
|
+
request(method: any, subPath: any, body: any, options: any): any;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Make an HTTP request with timeout + auto token refresh.
|
|
16
|
+
* @param {string} method
|
|
17
|
+
* @param {string} path
|
|
18
|
+
* @param {any} [body]
|
|
19
|
+
* @param {RequestInit} [options]
|
|
20
|
+
* @param {boolean} [_isRetry=false] — internal: prevent infinite refresh loop
|
|
21
|
+
* @returns {Promise<any>}
|
|
22
|
+
*/
|
|
23
|
+
request(method: any, path: any, body?: null, options?: {}): any;
|
|
24
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export class APIHandler {
|
|
2
|
+
/** @param {DolphinClient} client */
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
return this._createProxy([]);
|
|
6
|
+
}
|
|
7
|
+
/** @private */
|
|
8
|
+
_createProxy(pathParts) {
|
|
9
|
+
const joined = pathParts.join('/');
|
|
10
|
+
const target = (options) => this.request('GET', joined, null, options);
|
|
11
|
+
target.get = (pathOrOptions, options) => typeof pathOrOptions === 'string'
|
|
12
|
+
? this.request('GET', pathOrOptions, null, options)
|
|
13
|
+
: this.request('GET', joined, null, pathOrOptions);
|
|
14
|
+
target.post = (pathOrBody, bodyOrOptions, options) => typeof pathOrBody === 'string'
|
|
15
|
+
? this.request('POST', pathOrBody, bodyOrOptions, options)
|
|
16
|
+
: this.request('POST', joined, pathOrBody, bodyOrOptions);
|
|
17
|
+
target.put = (pathOrBody, bodyOrOptions, options) => typeof pathOrBody === 'string'
|
|
18
|
+
? this.request('PUT', pathOrBody, bodyOrOptions, options)
|
|
19
|
+
: this.request('PUT', joined, pathOrBody, bodyOrOptions);
|
|
20
|
+
target.patch = (pathOrBody, bodyOrOptions, options) => typeof pathOrBody === 'string'
|
|
21
|
+
? this.request('PATCH', pathOrBody, bodyOrOptions, options)
|
|
22
|
+
: this.request('PATCH', joined, pathOrBody, bodyOrOptions);
|
|
23
|
+
target.del = (pathOrOptions, options) => typeof pathOrOptions === 'string'
|
|
24
|
+
? this.request('DELETE', pathOrOptions, null, options)
|
|
25
|
+
: this.request('DELETE', joined, null, pathOrOptions);
|
|
26
|
+
target.request = (method, subPath, body, options) => {
|
|
27
|
+
const finalPath = subPath
|
|
28
|
+
? `${joined}/${subPath.startsWith('/') ? subPath.slice(1) : subPath}`
|
|
29
|
+
: joined;
|
|
30
|
+
return this.request(method, finalPath, body, options);
|
|
31
|
+
};
|
|
32
|
+
const methods = ['get', 'post', 'put', 'patch', 'del', 'request'];
|
|
33
|
+
return new Proxy(target, {
|
|
34
|
+
get: (t, prop) => {
|
|
35
|
+
if (typeof prop === 'string' && !methods.includes(prop)) {
|
|
36
|
+
return this._createProxy([...pathParts, prop]);
|
|
37
|
+
}
|
|
38
|
+
return t[prop];
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Make an HTTP request with timeout + auto token refresh.
|
|
44
|
+
* @param {string} method
|
|
45
|
+
* @param {string} path
|
|
46
|
+
* @param {any} [body]
|
|
47
|
+
* @param {RequestInit} [options]
|
|
48
|
+
* @param {boolean} [_isRetry=false] — internal: prevent infinite refresh loop
|
|
49
|
+
* @returns {Promise<any>}
|
|
50
|
+
*/
|
|
51
|
+
async request(method, path, body = null, options = {}) {
|
|
52
|
+
const _isRetry = options._isRetry === true;
|
|
53
|
+
const url = `${this.client.httpUrl}${path.startsWith('/') ? path : '/' + path}`;
|
|
54
|
+
const controller = new AbortController();
|
|
55
|
+
const timeoutId = setTimeout(() => controller.abort(), this.client.options.timeout);
|
|
56
|
+
const headers = {
|
|
57
|
+
'Content-Type': 'application/json',
|
|
58
|
+
...(options.headers || {}),
|
|
59
|
+
};
|
|
60
|
+
if (this.client.accessToken) {
|
|
61
|
+
headers['Authorization'] = `Bearer ${this.client.accessToken}`;
|
|
62
|
+
}
|
|
63
|
+
const fetchOptions = { ...options };
|
|
64
|
+
delete fetchOptions._isRetry;
|
|
65
|
+
try {
|
|
66
|
+
const response = await fetch(url, {
|
|
67
|
+
method,
|
|
68
|
+
headers,
|
|
69
|
+
signal: controller.signal,
|
|
70
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
71
|
+
...fetchOptions,
|
|
72
|
+
});
|
|
73
|
+
clearTimeout(timeoutId);
|
|
74
|
+
// Auto-refresh: 401 + not a retry + autoRefreshToken enabled
|
|
75
|
+
if (response.status === 401 &&
|
|
76
|
+
!_isRetry &&
|
|
77
|
+
this.client.options.autoRefreshToken) {
|
|
78
|
+
const refreshed = await this.client.auth._silentRefresh();
|
|
79
|
+
if (refreshed) {
|
|
80
|
+
return this.request(method, path, body, { ...options, _isRetry: true });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const contentType = response.headers.get('content-type') || '';
|
|
84
|
+
const data = contentType.includes('application/json')
|
|
85
|
+
? await response.json()
|
|
86
|
+
: await response.text();
|
|
87
|
+
if (!response.ok)
|
|
88
|
+
throw { status: response.status, data };
|
|
89
|
+
// Hookless auth token auto-save
|
|
90
|
+
if (data && typeof data === 'object') {
|
|
91
|
+
if (data.accessToken) {
|
|
92
|
+
this.client.setToken(data.accessToken);
|
|
93
|
+
if (data.user)
|
|
94
|
+
this.client.auth.user = data.user;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Auto-broadcast data changes
|
|
98
|
+
if (this.client.options.autoBroadcast && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method.toUpperCase())) {
|
|
99
|
+
const cleanPath = path.startsWith('/') ? path.substring(1) : path;
|
|
100
|
+
this.client.publish(cleanPath, { method: method.toUpperCase(), payload: body, result: data });
|
|
101
|
+
}
|
|
102
|
+
return data;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
clearTimeout(timeoutId);
|
|
106
|
+
if (err.name === 'AbortError') {
|
|
107
|
+
throw { status: 408, data: { error: 'Request timed out' } };
|
|
108
|
+
}
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/client/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare class AuthHandler {
|
|
2
|
+
/** @param {DolphinClient} client */
|
|
3
|
+
constructor(client: any);
|
|
4
|
+
/**
|
|
5
|
+
* Login with email + password.
|
|
6
|
+
* @param {string} email
|
|
7
|
+
* @param {string} password
|
|
8
|
+
*/
|
|
9
|
+
login(email: any, password: any): Promise<any>;
|
|
10
|
+
/**
|
|
11
|
+
* Register a new account.
|
|
12
|
+
* @param {{ email: string, password: string, [key: string]: any }} data
|
|
13
|
+
*/
|
|
14
|
+
register(data: any): Promise<any>;
|
|
15
|
+
/** Get current user profile. */
|
|
16
|
+
me(): Promise<any>;
|
|
17
|
+
/** Logout and clear token. */
|
|
18
|
+
logout(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Manually refresh the access token using the httpOnly refresh-token cookie.
|
|
21
|
+
* Called automatically on 401 if autoRefreshToken is enabled.
|
|
22
|
+
* @returns {Promise<boolean>} — true if refresh succeeded
|
|
23
|
+
*/
|
|
24
|
+
refresh(): Promise<boolean>;
|
|
25
|
+
/** @private */
|
|
26
|
+
_silentRefresh(): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Verify a 2FA TOTP code after login.
|
|
29
|
+
* @param {string} code — 6-digit TOTP code
|
|
30
|
+
* @param {string} [email] — email (if not already in user)
|
|
31
|
+
*/
|
|
32
|
+
verify2FA(code: any, email: any): Promise<any>;
|
|
33
|
+
/**
|
|
34
|
+
* Enable 2FA — returns QR code URL and secret.
|
|
35
|
+
*/
|
|
36
|
+
enable2FA(): Promise<any>;
|
|
37
|
+
/**
|
|
38
|
+
* Disable 2FA.
|
|
39
|
+
* @param {string} code — current TOTP code to confirm
|
|
40
|
+
*/
|
|
41
|
+
disable2FA(code: any): Promise<any>;
|
|
42
|
+
/**
|
|
43
|
+
* Request a password reset email.
|
|
44
|
+
* @param {string} email
|
|
45
|
+
*/
|
|
46
|
+
forgotPassword(email: any): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Reset password using the token from email.
|
|
49
|
+
* @param {string} token
|
|
50
|
+
* @param {string} newPassword
|
|
51
|
+
*/
|
|
52
|
+
resetPassword(token: any, newPassword: any): Promise<any>;
|
|
53
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export class AuthHandler {
|
|
2
|
+
/** @param {DolphinClient} client */
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
/** @type {any|null} */
|
|
6
|
+
this.user = null;
|
|
7
|
+
this._refreshing = false;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Login with email + password.
|
|
11
|
+
* @param {string} email
|
|
12
|
+
* @param {string} password
|
|
13
|
+
*/
|
|
14
|
+
async login(email, password) {
|
|
15
|
+
const res = await this.client.api.post('/api/auth/login', { email, password });
|
|
16
|
+
if (res.accessToken) {
|
|
17
|
+
this.client.setToken(res.accessToken);
|
|
18
|
+
this.user = res.user || null;
|
|
19
|
+
}
|
|
20
|
+
return res;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a new account.
|
|
24
|
+
* @param {{ email: string, password: string, [key: string]: any }} data
|
|
25
|
+
*/
|
|
26
|
+
async register(data) {
|
|
27
|
+
return this.client.api.post('/api/auth/register', data);
|
|
28
|
+
}
|
|
29
|
+
/** Get current user profile. */
|
|
30
|
+
async me() {
|
|
31
|
+
const res = await this.client.api.get('/api/auth/me');
|
|
32
|
+
if (res.success)
|
|
33
|
+
this.user = res.data;
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
/** Logout and clear token. */
|
|
37
|
+
async logout() {
|
|
38
|
+
try {
|
|
39
|
+
await this.client.api.post('/api/auth/logout');
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
this.client.setToken(null);
|
|
43
|
+
this.user = null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Manually refresh the access token using the httpOnly refresh-token cookie.
|
|
47
|
+
* Called automatically on 401 if autoRefreshToken is enabled.
|
|
48
|
+
* @returns {Promise<boolean>} — true if refresh succeeded
|
|
49
|
+
*/
|
|
50
|
+
async refresh() {
|
|
51
|
+
return this._silentRefresh();
|
|
52
|
+
}
|
|
53
|
+
/** @private */
|
|
54
|
+
async _silentRefresh() {
|
|
55
|
+
if (this._refreshing)
|
|
56
|
+
return false;
|
|
57
|
+
this._refreshing = true;
|
|
58
|
+
try {
|
|
59
|
+
const res = await this.client.api.post('/api/auth/refresh', null, { _isRetry: true });
|
|
60
|
+
if (res.accessToken) {
|
|
61
|
+
this.client.setToken(res.accessToken);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
this.client.setToken(null);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
this._refreshing = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Verify a 2FA TOTP code after login.
|
|
76
|
+
* @param {string} code — 6-digit TOTP code
|
|
77
|
+
* @param {string} [email] — email (if not already in user)
|
|
78
|
+
*/
|
|
79
|
+
async verify2FA(code, email) {
|
|
80
|
+
const payload = {
|
|
81
|
+
code,
|
|
82
|
+
email: email || this.user?.email,
|
|
83
|
+
};
|
|
84
|
+
const res = await this.client.api.post('/api/auth/2fa/verify', payload);
|
|
85
|
+
if (res.accessToken) {
|
|
86
|
+
this.client.setToken(res.accessToken);
|
|
87
|
+
if (res.user)
|
|
88
|
+
this.user = res.user;
|
|
89
|
+
}
|
|
90
|
+
return res;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Enable 2FA — returns QR code URL and secret.
|
|
94
|
+
*/
|
|
95
|
+
async enable2FA() {
|
|
96
|
+
return this.client.api.post('/api/auth/2fa/enable');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Disable 2FA.
|
|
100
|
+
* @param {string} code — current TOTP code to confirm
|
|
101
|
+
*/
|
|
102
|
+
async disable2FA(code) {
|
|
103
|
+
return this.client.api.post('/api/auth/2fa/disable', { code });
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Request a password reset email.
|
|
107
|
+
* @param {string} email
|
|
108
|
+
*/
|
|
109
|
+
async forgotPassword(email) {
|
|
110
|
+
return this.client.api.post('/api/auth/forgot-password', { email });
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Reset password using the token from email.
|
|
114
|
+
* @param {string} token
|
|
115
|
+
* @param {string} newPassword
|
|
116
|
+
*/
|
|
117
|
+
async resetPassword(token, newPassword) {
|
|
118
|
+
return this.client.api.post('/api/auth/reset-password', { token, newPassword });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export declare class DolphinClient {
|
|
2
|
+
constructor(url?: string, deviceId?: string, options?: {});
|
|
3
|
+
/** Save or clear the access token */
|
|
4
|
+
setToken(token: any): void;
|
|
5
|
+
/** Connect to the Dolphin realtime server */
|
|
6
|
+
connect(): Promise<unknown>;
|
|
7
|
+
/** Disconnect cleanly */
|
|
8
|
+
disconnect(): void;
|
|
9
|
+
/** @private */
|
|
10
|
+
_handleMessage(data: any): void;
|
|
11
|
+
/** @private */
|
|
12
|
+
_dispatch(pattern: any, payload: any, topic: any): void;
|
|
13
|
+
/** @private */
|
|
14
|
+
_sendRaw(msg: any): void;
|
|
15
|
+
/** Flush buffered messages after reconnect @private */
|
|
16
|
+
_flushOfflineQueue(): void;
|
|
17
|
+
/** @private */
|
|
18
|
+
_sendAck(to: any, msgId: any): void;
|
|
19
|
+
/** MQTT wildcard topic matching @private */
|
|
20
|
+
_matchTopic(pattern: any, topic: any): boolean;
|
|
21
|
+
/** @private */
|
|
22
|
+
_maybeReconnect(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Subscribe to a topic (MQTT wildcards supported: + and #).
|
|
25
|
+
* @param {string} topic
|
|
26
|
+
* @param {TopicCallback} callback
|
|
27
|
+
*/
|
|
28
|
+
subscribe(topic: any, callback: any): void;
|
|
29
|
+
/**
|
|
30
|
+
* Unsubscribe from a topic.
|
|
31
|
+
* @param {string} topic
|
|
32
|
+
* @param {TopicCallback} callback
|
|
33
|
+
*/
|
|
34
|
+
unsubscribe(topic: any, callback: any): void;
|
|
35
|
+
/**
|
|
36
|
+
* Publish a message to a topic. Queued if offline.
|
|
37
|
+
* @param {string} topic
|
|
38
|
+
* @param {any} payload
|
|
39
|
+
*/
|
|
40
|
+
publish(topic: any, payload: any): void;
|
|
41
|
+
/**
|
|
42
|
+
* High-frequency data push (IoT sensors).
|
|
43
|
+
* @param {string} topic
|
|
44
|
+
* @param {any} payload
|
|
45
|
+
*/
|
|
46
|
+
pubPush(topic: any, payload: any): void;
|
|
47
|
+
/**
|
|
48
|
+
* Request historical data from a topic.
|
|
49
|
+
* @param {string} topic
|
|
50
|
+
* @param {number} [count=10]
|
|
51
|
+
*/
|
|
52
|
+
subPull(topic: any, count?: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Upload a file to the server in chunks.
|
|
55
|
+
* @param {string} fileId
|
|
56
|
+
* @param {Blob|ArrayBuffer|Uint8Array} fileData
|
|
57
|
+
* @param {string} [filename]
|
|
58
|
+
* @param {function(number): void} [onProgress] — progress callback (0-100)
|
|
59
|
+
* @returns {Promise<void>}
|
|
60
|
+
*/
|
|
61
|
+
pubFile(fileId: any, fileData: any, filename: string | undefined, onProgress: any): Promise<void>;
|
|
62
|
+
/** @private */
|
|
63
|
+
_uint8ToBase64(uint8: any): string;
|
|
64
|
+
/**
|
|
65
|
+
* Download a file from the server by chunks.
|
|
66
|
+
* @param {string} fileId
|
|
67
|
+
* @param {number} [startChunk=0]
|
|
68
|
+
*/
|
|
69
|
+
subFile(fileId: any, startChunk?: number): void;
|
|
70
|
+
/**
|
|
71
|
+
* Resume a file download from saved progress.
|
|
72
|
+
* @param {string} fileId
|
|
73
|
+
*/
|
|
74
|
+
resumeFile(fileId: any): void;
|
|
75
|
+
/**
|
|
76
|
+
* Save download chunk progress.
|
|
77
|
+
* @param {string} fileId
|
|
78
|
+
* @param {number} chunkIndex
|
|
79
|
+
*/
|
|
80
|
+
saveFileProgress(fileId: any, chunkIndex: any): void;
|
|
81
|
+
/**
|
|
82
|
+
* @param {function(SignalMessage): void} handler
|
|
83
|
+
*/
|
|
84
|
+
onSignal(handler: any): void;
|
|
85
|
+
/**
|
|
86
|
+
* @param {function(SignalMessage): void} handler
|
|
87
|
+
*/
|
|
88
|
+
offSignal(handler: any): void;
|
|
89
|
+
/**
|
|
90
|
+
* @param {function(FileMetadata): void} handler
|
|
91
|
+
*/
|
|
92
|
+
onFileAvailable(handler: any): void;
|
|
93
|
+
/**
|
|
94
|
+
* @param {function(FileMetadata): void} handler
|
|
95
|
+
*/
|
|
96
|
+
offFileAvailable(handler: any): void;
|
|
97
|
+
}
|