@itwin/core-mobile 4.0.0-dev.8 → 4.0.0-dev.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/README.md +1 -1
  3. package/lib/cjs/MobileBackend.d.ts +7 -7
  4. package/lib/cjs/MobileBackend.js +28 -24
  5. package/lib/cjs/MobileBackend.js.map +1 -1
  6. package/lib/cjs/MobileFrontend.d.ts +5 -5
  7. package/lib/cjs/MobileFrontend.js +25 -21
  8. package/lib/cjs/MobileFrontend.js.map +1 -1
  9. package/lib/cjs/__DOC_ONLY__.d.ts +33 -33
  10. package/lib/cjs/__DOC_ONLY__.js +56 -52
  11. package/lib/cjs/__DOC_ONLY__.js.map +1 -1
  12. package/lib/cjs/backend/MobileAuthorizationBackend.d.ts +17 -17
  13. package/lib/cjs/backend/MobileAuthorizationBackend.js +46 -46
  14. package/lib/cjs/backend/MobileAuthorizationBackend.js.map +1 -1
  15. package/lib/cjs/backend/MobileFileHandler.d.ts +112 -112
  16. package/lib/cjs/backend/MobileFileHandler.d.ts.map +1 -1
  17. package/lib/cjs/backend/MobileFileHandler.js +263 -263
  18. package/lib/cjs/backend/MobileFileHandler.js.map +1 -1
  19. package/lib/cjs/backend/MobileHost.d.ts +72 -72
  20. package/lib/cjs/backend/MobileHost.d.ts.map +1 -1
  21. package/lib/cjs/backend/MobileHost.js +149 -156
  22. package/lib/cjs/backend/MobileHost.js.map +1 -1
  23. package/lib/cjs/backend/MobileRpcServer.d.ts +19 -19
  24. package/lib/cjs/backend/MobileRpcServer.js +156 -156
  25. package/lib/cjs/backend/MobileRpcServer.js.map +1 -1
  26. package/lib/cjs/backend/Request.d.ts +117 -149
  27. package/lib/cjs/backend/Request.d.ts.map +1 -1
  28. package/lib/cjs/backend/Request.js +255 -267
  29. package/lib/cjs/backend/Request.js.map +1 -1
  30. package/lib/cjs/common/MobileAppChannel.d.ts +4 -4
  31. package/lib/cjs/common/MobileAppChannel.js +11 -11
  32. package/lib/cjs/common/MobileAppProps.d.ts +35 -35
  33. package/lib/cjs/common/MobileAppProps.d.ts.map +1 -1
  34. package/lib/cjs/common/MobileAppProps.js +26 -26
  35. package/lib/cjs/common/MobileEventLoop.d.ts +11 -11
  36. package/lib/cjs/common/MobileEventLoop.js +30 -30
  37. package/lib/cjs/common/MobileEventLoop.js.map +1 -1
  38. package/lib/cjs/common/MobileIpc.d.ts +17 -17
  39. package/lib/cjs/common/MobileIpc.js +70 -70
  40. package/lib/cjs/common/MobilePush.d.ts +20 -20
  41. package/lib/cjs/common/MobilePush.js +53 -53
  42. package/lib/cjs/common/MobilePush.js.map +1 -1
  43. package/lib/cjs/common/MobileRpcManager.d.ts +40 -40
  44. package/lib/cjs/common/MobileRpcManager.js +110 -110
  45. package/lib/cjs/common/MobileRpcManager.js.map +1 -1
  46. package/lib/cjs/common/MobileRpcProtocol.d.ts +58 -58
  47. package/lib/cjs/common/MobileRpcProtocol.d.ts.map +1 -1
  48. package/lib/cjs/common/MobileRpcProtocol.js +277 -277
  49. package/lib/cjs/common/MobileRpcProtocol.js.map +1 -1
  50. package/lib/cjs/common/MobileRpcRequest.d.ts +20 -20
  51. package/lib/cjs/common/MobileRpcRequest.js +50 -50
  52. package/lib/cjs/frontend/MobileApp.d.ts +23 -23
  53. package/lib/cjs/frontend/MobileApp.d.ts.map +1 -1
  54. package/lib/cjs/frontend/MobileApp.js +79 -80
  55. package/lib/cjs/frontend/MobileApp.js.map +1 -1
  56. package/lib/cjs/frontend/MobileAuthorizationFrontend.d.ts +17 -17
  57. package/lib/cjs/frontend/MobileAuthorizationFrontend.d.ts.map +1 -1
  58. package/lib/cjs/frontend/MobileAuthorizationFrontend.js +54 -46
  59. package/lib/cjs/frontend/MobileAuthorizationFrontend.js.map +1 -1
  60. package/lib/cjs/test/ios/MobilePlatform.test.d.ts +1 -1
  61. package/lib/cjs/test/ios/MobilePlatform.test.js +84 -84
  62. package/package.json +18 -26
@@ -1,157 +1,157 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.setupMobileRpc = exports.MobileRpcServer = void 0;
8
- const ws = require("ws");
9
- const core_common_1 = require("@itwin/core-common");
10
- const MobileRpcProtocol_1 = require("../common/MobileRpcProtocol");
11
- const MobileRpcManager_1 = require("../common/MobileRpcManager");
12
- const MobileHost_1 = require("./MobileHost");
13
- const core_bentley_1 = require("@itwin/core-bentley");
14
- let addon;
15
- /** @internal */
16
- class MobileRpcServer {
17
- constructor() {
18
- /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from
19
- * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server
20
- * listening event is not fired as node yield to kevent and wait for some io event to happen.
21
- * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we
22
- * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.
23
- * This allow listening event to go through quickly (max 5ms). Once the listening event occur we
24
- * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally
25
- * be effective
26
- */
27
- this._pingTimer = setInterval(() => { }, 5);
28
- this._port = MobileRpcManager_1.MobileRpcConfiguration.setup.obtainPort();
29
- this._server = new ws.Server({ port: this._port });
30
- this._connectionId = ++MobileRpcServer._nextId;
31
- MobileRpcServer.interop.connectionId = this._connectionId;
32
- this._onListening();
33
- this._onConnection();
34
- }
35
- _onListening() {
36
- this._server.on("listening", () => {
37
- const address = this._server.address();
38
- this._port = address.port;
39
- clearInterval(this._pingTimer);
40
- this._notifyListening();
41
- });
42
- }
43
- _notifyListening() {
44
- MobileRpcServer.interop.port = this._port;
45
- if (addon) {
46
- addon.notifyListening(this._port);
47
- }
48
- if (this._connectionId !== 0) {
49
- MobileHost_1.MobileHost.reconnect(this._port);
50
- }
51
- }
52
- _onConnection() {
53
- this._server.on("connection", (connection) => {
54
- this._connection = connection;
55
- this._connection.on("message", (data) => this._onConnectionMessage(data));
56
- this._createSender();
57
- global.__iTwinJsRpcReady = true;
58
- });
59
- }
60
- _createSender() {
61
- const sender = (message, connectionId) => {
62
- if (connectionId !== this._connectionId) {
63
- return;
64
- }
65
- this._connection.send(message, (err) => {
66
- if (err) {
67
- throw err;
68
- }
69
- });
70
- };
71
- MobileRpcServer.interop.sendString = sender;
72
- MobileRpcServer.interop.sendBinary = sender;
73
- }
74
- _onConnectionMessage(data) {
75
- let message = data;
76
- if (Array.isArray(message)) {
77
- throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Unsupported data type");
78
- }
79
- if (Buffer.isBuffer(message)) {
80
- if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {
81
- message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
82
- }
83
- else {
84
- message = message.buffer;
85
- }
86
- }
87
- MobileRpcServer.interop.handler(message, this._connectionId);
88
- }
89
- dispose() {
90
- clearInterval(this._pingTimer);
91
- if (this._connection) {
92
- MobileRpcServer.interop.sendString = () => { };
93
- MobileRpcServer.interop.sendBinary = () => { };
94
- this._connection.close();
95
- }
96
- this._server.close();
97
- }
98
- }
99
- exports.MobileRpcServer = MobileRpcServer;
100
- MobileRpcServer._nextId = -1;
101
- MobileRpcServer.interop = {
102
- handler: (_payload) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Not implemented."); },
103
- sendString: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
104
- sendBinary: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
105
- port: 0,
106
- connectionId: 0,
107
- };
108
- let mobileReady = false;
109
- let hasSuspended = false;
110
- function setupMobileRpc() {
111
- if (mobileReady) {
112
- return;
113
- }
114
- if (core_bentley_1.ProcessDetector.isMobileAppBackend) {
115
- addon = process._linkedBinding("iModelJsMobile");
116
- addon === null || addon === void 0 ? void 0 : addon.registerDeviceImpl();
117
- }
118
- let server = new MobileRpcServer();
119
- /* The UV event loop (internal to node) is retained by handles,
120
- such as those created for setInterval/setTimeout and client/server connections.
121
- In a simple app, the RPC server may be the only handle retaining the UV loop.
122
- Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.
123
- */
124
- let retainUvLoop;
125
- MobileHost_1.MobileHost.onEnterBackground.addListener(() => {
126
- hasSuspended = true;
127
- if (server === null) {
128
- return;
129
- }
130
- retainUvLoop = setInterval(() => { }, 1000);
131
- server.dispose();
132
- server = null;
133
- });
134
- MobileHost_1.MobileHost.onEnterForeground.addListener(() => {
135
- if (!hasSuspended) {
136
- return;
137
- }
138
- server = new MobileRpcServer();
139
- clearInterval(retainUvLoop);
140
- retainUvLoop = undefined;
141
- });
142
- MobileHost_1.MobileHost.onWillTerminate.addListener(() => {
143
- if (typeof (retainUvLoop) !== "undefined") {
144
- clearInterval(retainUvLoop);
145
- retainUvLoop = undefined;
146
- }
147
- if (server === null) {
148
- return;
149
- }
150
- server.dispose();
151
- server = null;
152
- });
153
- MobileRpcProtocol_1.MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;
154
- mobileReady = true;
155
- }
156
- exports.setupMobileRpc = setupMobileRpc;
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.setupMobileRpc = exports.MobileRpcServer = void 0;
8
+ const ws = require("ws");
9
+ const core_common_1 = require("@itwin/core-common");
10
+ const MobileRpcProtocol_1 = require("../common/MobileRpcProtocol");
11
+ const MobileRpcManager_1 = require("../common/MobileRpcManager");
12
+ const MobileHost_1 = require("./MobileHost");
13
+ const core_bentley_1 = require("@itwin/core-bentley");
14
+ let addon;
15
+ /** @internal */
16
+ class MobileRpcServer {
17
+ constructor() {
18
+ /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from
19
+ * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server
20
+ * listening event is not fired as node yield to kevent and wait for some io event to happen.
21
+ * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we
22
+ * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.
23
+ * This allow listening event to go through quickly (max 5ms). Once the listening event occur we
24
+ * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally
25
+ * be effective
26
+ */
27
+ this._pingTimer = setInterval(() => { }, 5);
28
+ this._port = MobileRpcManager_1.MobileRpcConfiguration.setup.obtainPort();
29
+ this._server = new ws.Server({ port: this._port });
30
+ this._connectionId = ++MobileRpcServer._nextId;
31
+ MobileRpcServer.interop.connectionId = this._connectionId;
32
+ this._onListening();
33
+ this._onConnection();
34
+ }
35
+ _onListening() {
36
+ this._server.on("listening", () => {
37
+ const address = this._server.address();
38
+ this._port = address.port;
39
+ clearInterval(this._pingTimer);
40
+ this._notifyListening();
41
+ });
42
+ }
43
+ _notifyListening() {
44
+ MobileRpcServer.interop.port = this._port;
45
+ if (addon) {
46
+ addon.notifyListening(this._port);
47
+ }
48
+ if (this._connectionId !== 0) {
49
+ MobileHost_1.MobileHost.reconnect(this._port);
50
+ }
51
+ }
52
+ _onConnection() {
53
+ this._server.on("connection", (connection) => {
54
+ this._connection = connection;
55
+ this._connection.on("message", (data) => this._onConnectionMessage(data));
56
+ this._createSender();
57
+ global.__iTwinJsRpcReady = true;
58
+ });
59
+ }
60
+ _createSender() {
61
+ const sender = (message, connectionId) => {
62
+ if (connectionId !== this._connectionId) {
63
+ return;
64
+ }
65
+ this._connection.send(message, (err) => {
66
+ if (err) {
67
+ throw err;
68
+ }
69
+ });
70
+ };
71
+ MobileRpcServer.interop.sendString = sender;
72
+ MobileRpcServer.interop.sendBinary = sender;
73
+ }
74
+ _onConnectionMessage(data) {
75
+ let message = data;
76
+ if (Array.isArray(message)) {
77
+ throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Unsupported data type");
78
+ }
79
+ if (Buffer.isBuffer(message)) {
80
+ if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {
81
+ message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
82
+ }
83
+ else {
84
+ message = message.buffer;
85
+ }
86
+ }
87
+ MobileRpcServer.interop.handler(message, this._connectionId);
88
+ }
89
+ dispose() {
90
+ clearInterval(this._pingTimer);
91
+ if (this._connection) {
92
+ MobileRpcServer.interop.sendString = () => { };
93
+ MobileRpcServer.interop.sendBinary = () => { };
94
+ this._connection.close();
95
+ }
96
+ this._server.close();
97
+ }
98
+ }
99
+ MobileRpcServer._nextId = -1;
100
+ MobileRpcServer.interop = {
101
+ handler: (_payload) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Not implemented."); },
102
+ sendString: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
103
+ sendBinary: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
104
+ port: 0,
105
+ connectionId: 0,
106
+ };
107
+ exports.MobileRpcServer = MobileRpcServer;
108
+ let mobileReady = false;
109
+ let hasSuspended = false;
110
+ function setupMobileRpc() {
111
+ if (mobileReady) {
112
+ return;
113
+ }
114
+ if (core_bentley_1.ProcessDetector.isMobileAppBackend) {
115
+ addon = process._linkedBinding("iModelJsMobile");
116
+ addon?.registerDeviceImpl();
117
+ }
118
+ let server = new MobileRpcServer();
119
+ /* The UV event loop (internal to node) is retained by handles,
120
+ such as those created for setInterval/setTimeout and client/server connections.
121
+ In a simple app, the RPC server may be the only handle retaining the UV loop.
122
+ Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.
123
+ */
124
+ let retainUvLoop;
125
+ MobileHost_1.MobileHost.onEnterBackground.addListener(() => {
126
+ hasSuspended = true;
127
+ if (server === null) {
128
+ return;
129
+ }
130
+ retainUvLoop = setInterval(() => { }, 1000);
131
+ server.dispose();
132
+ server = null;
133
+ });
134
+ MobileHost_1.MobileHost.onEnterForeground.addListener(() => {
135
+ if (!hasSuspended) {
136
+ return;
137
+ }
138
+ server = new MobileRpcServer();
139
+ clearInterval(retainUvLoop);
140
+ retainUvLoop = undefined;
141
+ });
142
+ MobileHost_1.MobileHost.onWillTerminate.addListener(() => {
143
+ if (typeof (retainUvLoop) !== "undefined") {
144
+ clearInterval(retainUvLoop);
145
+ retainUvLoop = undefined;
146
+ }
147
+ if (server === null) {
148
+ return;
149
+ }
150
+ server.dispose();
151
+ server = null;
152
+ });
153
+ MobileRpcProtocol_1.MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;
154
+ mobileReady = true;
155
+ }
156
+ exports.setupMobileRpc = setupMobileRpc;
157
157
  //# sourceMappingURL=MobileRpcServer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MobileRpcServer.js","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as ws from \"ws\";\r\nimport { BentleyStatus, IModelError } from \"@itwin/core-common\";\r\nimport { MobileRpcGateway, MobileRpcProtocol } from \"../common/MobileRpcProtocol\";\r\nimport { MobileRpcConfiguration } from \"../common/MobileRpcManager\";\r\nimport { MobileHost } from \"./MobileHost\";\r\nimport { ProcessDetector } from \"@itwin/core-bentley\";\r\n\r\n/* eslint-disable deprecation/deprecation */\r\n\r\ninterface MobileAddon {\r\n notifyListening: (port: number) => void;\r\n registerDeviceImpl: () => void;\r\n}\r\n\r\nlet addon: MobileAddon | undefined;\r\n\r\n/** @internal */\r\nexport class MobileRpcServer {\r\n private static _nextId = -1;\r\n\r\n public static interop: MobileRpcGateway = {\r\n handler: (_payload: ArrayBuffer | string) => { throw new IModelError(BentleyStatus.ERROR, \"Not implemented.\"); },\r\n sendString: (_message: string, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\r\n sendBinary: (_message: Uint8Array, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\r\n port: 0,\r\n connectionId: 0,\r\n };\r\n\r\n private _server: ws.Server;\r\n private _connection: ws | undefined;\r\n private _port: number;\r\n private _connectionId: number;\r\n private _pingTimer: NodeJS.Timeout;\r\n public constructor() {\r\n /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from\r\n * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server\r\n * listening event is not fired as node yield to kevent and wait for some io event to happen.\r\n * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we\r\n * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.\r\n * This allow listening event to go through quickly (max 5ms). Once the listening event occur we\r\n * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally\r\n * be effective\r\n */\r\n this._pingTimer = setInterval(() => { }, 5);\r\n this._port = MobileRpcConfiguration.setup.obtainPort();\r\n this._server = new ws.Server({ port: this._port });\r\n this._connectionId = ++MobileRpcServer._nextId;\r\n MobileRpcServer.interop.connectionId = this._connectionId;\r\n this._onListening();\r\n this._onConnection();\r\n }\r\n\r\n private _onListening() {\r\n this._server.on(\"listening\", () => {\r\n const address = this._server.address() as ws.AddressInfo;\r\n this._port = address.port;\r\n clearInterval(this._pingTimer);\r\n this._notifyListening();\r\n });\r\n }\r\n\r\n private _notifyListening() {\r\n MobileRpcServer.interop.port = this._port;\r\n\r\n if (addon) {\r\n addon.notifyListening(this._port);\r\n }\r\n\r\n if (this._connectionId !== 0) {\r\n MobileHost.reconnect(this._port);\r\n }\r\n }\r\n\r\n private _onConnection() {\r\n this._server.on(\"connection\", (connection) => {\r\n this._connection = connection;\r\n this._connection.on(\"message\", (data) => this._onConnectionMessage(data));\r\n this._createSender();\r\n (global as any).__iTwinJsRpcReady = true;\r\n });\r\n }\r\n\r\n private _createSender() {\r\n const sender = (message: string | Uint8Array, connectionId: number) => {\r\n if (connectionId !== this._connectionId) {\r\n return;\r\n }\r\n\r\n this._connection!.send(message, (err) => {\r\n if (err) {\r\n throw err;\r\n }\r\n });\r\n };\r\n\r\n MobileRpcServer.interop.sendString = sender;\r\n MobileRpcServer.interop.sendBinary = sender;\r\n }\r\n\r\n private _onConnectionMessage(data: ws.Data) {\r\n let message = data;\r\n if (Array.isArray(message)) {\r\n throw new IModelError(BentleyStatus.ERROR, \"Unsupported data type\");\r\n }\r\n\r\n if (Buffer.isBuffer(message)) {\r\n if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {\r\n message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\r\n } else {\r\n message = message.buffer;\r\n }\r\n }\r\n\r\n MobileRpcServer.interop.handler(message, this._connectionId);\r\n }\r\n\r\n public dispose() {\r\n clearInterval(this._pingTimer);\r\n if (this._connection) {\r\n MobileRpcServer.interop.sendString = () => { };\r\n MobileRpcServer.interop.sendBinary = () => { };\r\n this._connection.close();\r\n }\r\n\r\n this._server.close();\r\n }\r\n}\r\n\r\nlet mobileReady = false;\r\nlet hasSuspended = false;\r\n\r\nexport function setupMobileRpc() {\r\n if (mobileReady) {\r\n return;\r\n }\r\n\r\n if (ProcessDetector.isMobileAppBackend) {\r\n addon = (process as any)._linkedBinding(\"iModelJsMobile\");\r\n addon?.registerDeviceImpl();\r\n }\r\n\r\n let server: MobileRpcServer | null = new MobileRpcServer();\r\n\r\n /* The UV event loop (internal to node) is retained by handles,\r\n such as those created for setInterval/setTimeout and client/server connections.\r\n In a simple app, the RPC server may be the only handle retaining the UV loop.\r\n Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.\r\n */\r\n let retainUvLoop: NodeJS.Timer | undefined;\r\n\r\n MobileHost.onEnterBackground.addListener(() => {\r\n hasSuspended = true;\r\n\r\n if (server === null) {\r\n return;\r\n }\r\n\r\n retainUvLoop = setInterval(() => { }, 1000);\r\n server.dispose();\r\n server = null;\r\n });\r\n\r\n MobileHost.onEnterForeground.addListener(() => {\r\n if (!hasSuspended) {\r\n return;\r\n }\r\n\r\n server = new MobileRpcServer();\r\n clearInterval(retainUvLoop);\r\n retainUvLoop = undefined;\r\n });\r\n\r\n MobileHost.onWillTerminate.addListener(() => {\r\n if (typeof (retainUvLoop) !== \"undefined\") {\r\n clearInterval(retainUvLoop);\r\n retainUvLoop = undefined;\r\n }\r\n\r\n if (server === null) {\r\n return;\r\n }\r\n\r\n server.dispose();\r\n server = null;\r\n });\r\n\r\n MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;\r\n mobileReady = true;\r\n}\r\n"]}
1
+ {"version":3,"file":"MobileRpcServer.js","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as ws from \"ws\";\r\nimport { BentleyStatus, IModelError } from \"@itwin/core-common\";\r\nimport { MobileRpcGateway, MobileRpcProtocol } from \"../common/MobileRpcProtocol\";\r\nimport { MobileRpcConfiguration } from \"../common/MobileRpcManager\";\r\nimport { MobileHost } from \"./MobileHost\";\r\nimport { ProcessDetector } from \"@itwin/core-bentley\";\r\n\r\n/* eslint-disable deprecation/deprecation */\r\n\r\ninterface MobileAddon {\r\n notifyListening: (port: number) => void;\r\n registerDeviceImpl: () => void;\r\n}\r\n\r\nlet addon: MobileAddon | undefined;\r\n\r\n/** @internal */\r\nexport class MobileRpcServer {\r\n private static _nextId = -1;\r\n\r\n public static interop: MobileRpcGateway = {\r\n handler: (_payload: ArrayBuffer | string) => { throw new IModelError(BentleyStatus.ERROR, \"Not implemented.\"); },\r\n sendString: (_message: string, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\r\n sendBinary: (_message: Uint8Array, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\r\n port: 0,\r\n connectionId: 0,\r\n };\r\n\r\n private _server: ws.Server;\r\n private _connection: ws | undefined;\r\n private _port: number;\r\n private _connectionId: number;\r\n private _pingTimer: NodeJS.Timeout;\r\n public constructor() {\r\n /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from\r\n * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server\r\n * listening event is not fired as node yield to kevent and wait for some io event to happen.\r\n * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we\r\n * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.\r\n * This allow listening event to go through quickly (max 5ms). Once the listening event occur we\r\n * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally\r\n * be effective\r\n */\r\n this._pingTimer = setInterval(() => { }, 5);\r\n this._port = MobileRpcConfiguration.setup.obtainPort();\r\n this._server = new ws.Server({ port: this._port });\r\n this._connectionId = ++MobileRpcServer._nextId;\r\n MobileRpcServer.interop.connectionId = this._connectionId;\r\n this._onListening();\r\n this._onConnection();\r\n }\r\n\r\n private _onListening() {\r\n this._server.on(\"listening\", () => {\r\n const address = this._server.address() as ws.AddressInfo;\r\n this._port = address.port;\r\n clearInterval(this._pingTimer);\r\n this._notifyListening();\r\n });\r\n }\r\n\r\n private _notifyListening() {\r\n MobileRpcServer.interop.port = this._port;\r\n\r\n if (addon) {\r\n addon.notifyListening(this._port);\r\n }\r\n\r\n if (this._connectionId !== 0) {\r\n MobileHost.reconnect(this._port);\r\n }\r\n }\r\n\r\n private _onConnection() {\r\n this._server.on(\"connection\", (connection) => {\r\n this._connection = connection;\r\n this._connection.on(\"message\", (data) => this._onConnectionMessage(data));\r\n this._createSender();\r\n (global as any).__iTwinJsRpcReady = true;\r\n });\r\n }\r\n\r\n private _createSender() {\r\n const sender = (message: string | Uint8Array, connectionId: number) => {\r\n if (connectionId !== this._connectionId) {\r\n return;\r\n }\r\n\r\n this._connection!.send(message, (err) => {\r\n if (err) {\r\n throw err;\r\n }\r\n });\r\n };\r\n\r\n MobileRpcServer.interop.sendString = sender;\r\n MobileRpcServer.interop.sendBinary = sender;\r\n }\r\n\r\n private _onConnectionMessage(data: ws.Data) {\r\n let message = data;\r\n if (Array.isArray(message)) {\r\n throw new IModelError(BentleyStatus.ERROR, \"Unsupported data type\");\r\n }\r\n\r\n if (Buffer.isBuffer(message)) {\r\n if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {\r\n message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\r\n } else {\r\n message = message.buffer;\r\n }\r\n }\r\n\r\n MobileRpcServer.interop.handler(message, this._connectionId);\r\n }\r\n\r\n public dispose() {\r\n clearInterval(this._pingTimer);\r\n if (this._connection) {\r\n MobileRpcServer.interop.sendString = () => { };\r\n MobileRpcServer.interop.sendBinary = () => { };\r\n this._connection.close();\r\n }\r\n\r\n this._server.close();\r\n }\r\n}\r\n\r\nlet mobileReady = false;\r\nlet hasSuspended = false;\r\n\r\nexport function setupMobileRpc() {\r\n if (mobileReady) {\r\n return;\r\n }\r\n\r\n if (ProcessDetector.isMobileAppBackend) {\r\n addon = (process as any)._linkedBinding(\"iModelJsMobile\");\r\n addon?.registerDeviceImpl();\r\n }\r\n\r\n let server: MobileRpcServer | null = new MobileRpcServer();\r\n\r\n /* The UV event loop (internal to node) is retained by handles,\r\n such as those created for setInterval/setTimeout and client/server connections.\r\n In a simple app, the RPC server may be the only handle retaining the UV loop.\r\n Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.\r\n */\r\n let retainUvLoop: NodeJS.Timer | undefined;\r\n\r\n MobileHost.onEnterBackground.addListener(() => {\r\n hasSuspended = true;\r\n\r\n if (server === null) {\r\n return;\r\n }\r\n\r\n retainUvLoop = setInterval(() => { }, 1000);\r\n server.dispose();\r\n server = null;\r\n });\r\n\r\n MobileHost.onEnterForeground.addListener(() => {\r\n if (!hasSuspended) {\r\n return;\r\n }\r\n\r\n server = new MobileRpcServer();\r\n clearInterval(retainUvLoop);\r\n retainUvLoop = undefined;\r\n });\r\n\r\n MobileHost.onWillTerminate.addListener(() => {\r\n if (typeof (retainUvLoop) !== \"undefined\") {\r\n clearInterval(retainUvLoop);\r\n retainUvLoop = undefined;\r\n }\r\n\r\n if (server === null) {\r\n return;\r\n }\r\n\r\n server.dispose();\r\n server = null;\r\n });\r\n\r\n MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;\r\n mobileReady = true;\r\n}\r\n"]}
@@ -1,150 +1,118 @@
1
- /// <reference types="node" />
2
- import * as https from "https";
3
- import { BentleyError, GetMetaDataFunction, HttpStatus } from "@itwin/core-bentley";
4
- /** @internal */
5
- export declare const requestIdHeaderName = "X-Correlation-Id";
6
- /** Typical option to query REST API. Note that services may not quite support these fields,
7
- * and the interface is only provided as a hint.
8
- * @internal
9
- */
10
- export interface RequestQueryOptions {
11
- /**
12
- * Select string used by the query (use the mapped EC property names, and not TypeScript property names)
13
- * Example: "Name,Size,Description"
14
- */
15
- $select?: string;
16
- /**
17
- * Filter string used by the query (use the mapped EC property names, and not TypeScript property names)
18
- * Example: "Name like '*.pdf' and Size lt 1000"
19
- */
20
- $filter?: string;
21
- /** Sets the limit on the number of entries to be returned by the query */
22
- $top?: number;
23
- /** Sets the number of entries to be skipped */
24
- $skip?: number;
25
- /**
26
- * Orders the return values (use the mapped EC property names, and not TypeScript property names)
27
- * Example: "Size desc"
28
- */
29
- $orderby?: string;
30
- /**
31
- * Sets the limit on the number of entries to be returned by a single response.
32
- * Can be used with a Top option. For example if Top is set to 1000 and PageSize
33
- * is set to 100 then 10 requests will be performed to get result.
34
- */
35
- $pageSize?: number;
36
- }
37
- /** @internal */
38
- export interface RequestQueryStringifyOptions {
39
- delimiter?: string;
40
- encode?: boolean;
41
- }
42
- /** Option to control the time outs
43
- * Use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow,
44
- * but reliable, networks. Note that both of these timers limit how long uploads of attached files are allowed to take. Use long
45
- * timeouts if you're uploading files.
46
- * @internal
47
- */
48
- export interface RequestTimeoutOptions {
49
- /** Sets a deadline (in milliseconds) for the entire request (including all uploads, redirects, server processing time) to complete.
50
- * If the response isn't fully downloaded within that time, the request will be aborted
51
- */
52
- deadline?: number;
53
- /** Sets maximum time (in milliseconds) to wait for the first byte to arrive from the server, but it does not limit how long the entire
54
- * download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because
55
- * it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.
56
- */
57
- response?: number;
58
- }
59
- /** @internal */
60
- export interface RequestOptions {
61
- method: string;
62
- headers?: any;
63
- body?: any;
64
- qs?: any | RequestQueryOptions;
65
- responseType?: string;
66
- timeout?: RequestTimeoutOptions;
67
- stream?: any;
68
- readStream?: any;
69
- buffer?: any;
70
- parser?: any;
71
- accept?: string;
72
- redirects?: number;
73
- errorCallback?: (response: any) => ResponseError;
74
- retryCallback?: (error: any, response: any) => boolean;
75
- progressCallback?: ProgressCallback;
76
- agent?: https.Agent;
77
- retries?: number;
78
- useCorsProxy?: boolean;
79
- }
80
- /** Response object if the request was successful. Note that the status within the range of 200-299 are considered as a success.
81
- * @internal
82
- */
83
- export interface Response {
84
- body: any;
85
- text: string | undefined;
86
- header: any;
87
- status: number;
88
- }
89
- /** @internal */
90
- export interface ProgressInfo {
91
- percent?: number;
92
- total?: number;
93
- loaded: number;
94
- }
95
- /** @internal */
96
- export declare type ProgressCallback = (progress: ProgressInfo) => void;
97
- /** Error object that's thrown/rejected if the Request fails due to a network error, or if the status is *not* in the range of 200-299 (inclusive)
98
- * @internal
99
- */
100
- export declare class ResponseError extends BentleyError {
101
- protected _data?: any;
102
- status?: number;
103
- description?: string;
104
- constructor(errorNumber: number | HttpStatus, message?: string, getMetaData?: GetMetaDataFunction);
105
- /**
106
- * Parses error from server's response
107
- * @param response Http response from the server.
108
- * @returns Parsed error.
109
- * @internal
110
- */
111
- static parse(response: any, log?: boolean): ResponseError;
112
- /**
113
- * Decides whether request should be retried or not
114
- * @param error Error returned by request
115
- * @param response Response returned by request
116
- * @internal
117
- */
118
- static shouldRetry(error: any, response: any): boolean;
119
- /**
120
- * @internal
121
- */
122
- static parseHttpStatus(statusType: number): HttpStatus;
123
- /**
124
- * @internal
125
- */
126
- logMessage(): string;
127
- /**
128
- * Logs this error
129
- * @internal
130
- */
131
- log(): void;
132
- }
133
- /** Wrapper around making HTTP requests with the specific options.
134
- *
135
- * Usable in both a browser and node based environment.
136
- *
137
- * @param url Server URL to address the request
138
- * @param options Options to pass to the request
139
- * @returns Resolves to the response from the server
140
- * @throws ResponseError if the request fails due to network issues, or if the returned status is *outside* the range of 200-299 (inclusive)
141
- * @internal
142
- */
143
- export declare function request(url: string, options: RequestOptions): Promise<Response>;
144
- /**
145
- * fetch json from HTTP request
146
- * @param url server URL to address the request
147
- * @internal
148
- */
149
- export declare function getJson(url: string): Promise<any>;
1
+ /// <reference types="node" />
2
+ import * as https from "https";
3
+ import { BentleyError, GetMetaDataFunction, HttpStatus } from "@itwin/core-bentley";
4
+ /** @internal */
5
+ export declare const requestIdHeaderName = "X-Correlation-Id";
6
+ /** @internal */
7
+ export interface RequestQueryStringifyOptions {
8
+ delimiter?: string;
9
+ encode?: boolean;
10
+ }
11
+ /** Option to control the time outs
12
+ * Use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow,
13
+ * but reliable, networks. Note that both of these timers limit how long uploads of attached files are allowed to take. Use long
14
+ * timeouts if you're uploading files.
15
+ * @internal
16
+ */
17
+ export interface RequestTimeoutOptions {
18
+ /** Sets a deadline (in milliseconds) for the entire request (including all uploads, redirects, server processing time) to complete.
19
+ * If the response isn't fully downloaded within that time, the request will be aborted
20
+ */
21
+ deadline?: number;
22
+ /** Sets maximum time (in milliseconds) to wait for the first byte to arrive from the server, but it does not limit how long the entire
23
+ * download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because
24
+ * it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.
25
+ */
26
+ response?: number;
27
+ }
28
+ /** @internal */
29
+ export interface RequestOptions {
30
+ method: string;
31
+ headers?: any;
32
+ body?: any;
33
+ responseType?: string;
34
+ timeout?: RequestTimeoutOptions;
35
+ stream?: any;
36
+ readStream?: any;
37
+ buffer?: any;
38
+ parser?: any;
39
+ accept?: string;
40
+ redirects?: number;
41
+ errorCallback?: (response: any) => ResponseError;
42
+ retryCallback?: (error: any, response: any) => boolean;
43
+ progressCallback?: ProgressCallback;
44
+ agent?: https.Agent;
45
+ retries?: number;
46
+ useCorsProxy?: boolean;
47
+ }
48
+ /** Response object if the request was successful. Note that the status within the range of 200-299 are considered as a success.
49
+ * @internal
50
+ */
51
+ export interface Response {
52
+ body: any;
53
+ text: string | undefined;
54
+ header: any;
55
+ status: number;
56
+ }
57
+ /** @internal */
58
+ export interface ProgressInfo {
59
+ percent?: number;
60
+ total?: number;
61
+ loaded: number;
62
+ }
63
+ /** @internal */
64
+ export type ProgressCallback = (progress: ProgressInfo) => void;
65
+ /** Error object that's thrown/rejected if the Request fails due to a network error, or if the status is *not* in the range of 200-299 (inclusive)
66
+ * @internal
67
+ */
68
+ export declare class ResponseError extends BentleyError {
69
+ protected _data?: any;
70
+ status?: number;
71
+ description?: string;
72
+ constructor(errorNumber: number | HttpStatus, message?: string, getMetaData?: GetMetaDataFunction);
73
+ /**
74
+ * Parses error from server's response
75
+ * @param response Http response from the server.
76
+ * @returns Parsed error.
77
+ * @internal
78
+ */
79
+ static parse(response: any, log?: boolean): ResponseError;
80
+ /**
81
+ * Decides whether request should be retried or not
82
+ * @param error Error returned by request
83
+ * @param response Response returned by request
84
+ * @internal
85
+ */
86
+ static shouldRetry(error: any, response: any): boolean;
87
+ /**
88
+ * @internal
89
+ */
90
+ static parseHttpStatus(statusType: number): HttpStatus;
91
+ /**
92
+ * @internal
93
+ */
94
+ logMessage(): string;
95
+ /**
96
+ * Logs this error
97
+ * @internal
98
+ */
99
+ log(): void;
100
+ }
101
+ /** Wrapper around making HTTP requests with the specific options.
102
+ *
103
+ * Usable in both a browser and node based environment.
104
+ *
105
+ * @param url Server URL to address the request
106
+ * @param options Options to pass to the request
107
+ * @returns Resolves to the response from the server
108
+ * @throws ResponseError if the request fails due to network issues, or if the returned status is *outside* the range of 200-299 (inclusive)
109
+ * @internal
110
+ */
111
+ export declare function request(url: string, options: RequestOptions): Promise<Response>;
112
+ /**
113
+ * fetch json from HTTP request
114
+ * @param url server URL to address the request
115
+ * @internal
116
+ */
117
+ export declare function getJson(url: string): Promise<any>;
150
118
  //# sourceMappingURL=Request.d.ts.map