@itwin/core-mobile 4.0.0-dev.7 → 4.0.0-dev.70

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 (58) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/lib/cjs/MobileBackend.d.ts +7 -7
  3. package/lib/cjs/MobileBackend.js +28 -24
  4. package/lib/cjs/MobileBackend.js.map +1 -1
  5. package/lib/cjs/MobileFrontend.d.ts +5 -5
  6. package/lib/cjs/MobileFrontend.js +25 -21
  7. package/lib/cjs/MobileFrontend.js.map +1 -1
  8. package/lib/cjs/__DOC_ONLY__.d.ts +33 -33
  9. package/lib/cjs/__DOC_ONLY__.js +56 -52
  10. package/lib/cjs/__DOC_ONLY__.js.map +1 -1
  11. package/lib/cjs/backend/MobileAuthorizationBackend.d.ts +17 -17
  12. package/lib/cjs/backend/MobileAuthorizationBackend.js +46 -46
  13. package/lib/cjs/backend/MobileAuthorizationBackend.js.map +1 -1
  14. package/lib/cjs/backend/MobileFileHandler.d.ts +112 -112
  15. package/lib/cjs/backend/MobileFileHandler.js +263 -263
  16. package/lib/cjs/backend/MobileHost.d.ts +72 -72
  17. package/lib/cjs/backend/MobileHost.d.ts.map +1 -1
  18. package/lib/cjs/backend/MobileHost.js +155 -156
  19. package/lib/cjs/backend/MobileHost.js.map +1 -1
  20. package/lib/cjs/backend/MobileRpcServer.d.ts +19 -19
  21. package/lib/cjs/backend/MobileRpcServer.js +156 -156
  22. package/lib/cjs/backend/MobileRpcServer.js.map +1 -1
  23. package/lib/cjs/backend/Request.d.ts +149 -149
  24. package/lib/cjs/backend/Request.d.ts.map +1 -1
  25. package/lib/cjs/backend/Request.js +267 -267
  26. package/lib/cjs/common/MobileAppChannel.d.ts +4 -4
  27. package/lib/cjs/common/MobileAppChannel.js +11 -11
  28. package/lib/cjs/common/MobileAppProps.d.ts +35 -35
  29. package/lib/cjs/common/MobileAppProps.d.ts.map +1 -1
  30. package/lib/cjs/common/MobileAppProps.js +26 -26
  31. package/lib/cjs/common/MobileEventLoop.d.ts +11 -11
  32. package/lib/cjs/common/MobileEventLoop.js +30 -30
  33. package/lib/cjs/common/MobileEventLoop.js.map +1 -1
  34. package/lib/cjs/common/MobileIpc.d.ts +17 -17
  35. package/lib/cjs/common/MobileIpc.js +70 -70
  36. package/lib/cjs/common/MobilePush.d.ts +20 -20
  37. package/lib/cjs/common/MobilePush.js +53 -53
  38. package/lib/cjs/common/MobilePush.js.map +1 -1
  39. package/lib/cjs/common/MobileRpcManager.d.ts +40 -40
  40. package/lib/cjs/common/MobileRpcManager.js +110 -110
  41. package/lib/cjs/common/MobileRpcManager.js.map +1 -1
  42. package/lib/cjs/common/MobileRpcProtocol.d.ts +58 -58
  43. package/lib/cjs/common/MobileRpcProtocol.d.ts.map +1 -1
  44. package/lib/cjs/common/MobileRpcProtocol.js +277 -277
  45. package/lib/cjs/common/MobileRpcProtocol.js.map +1 -1
  46. package/lib/cjs/common/MobileRpcRequest.d.ts +20 -20
  47. package/lib/cjs/common/MobileRpcRequest.js +50 -50
  48. package/lib/cjs/frontend/MobileApp.d.ts +23 -23
  49. package/lib/cjs/frontend/MobileApp.d.ts.map +1 -1
  50. package/lib/cjs/frontend/MobileApp.js +79 -80
  51. package/lib/cjs/frontend/MobileApp.js.map +1 -1
  52. package/lib/cjs/frontend/MobileAuthorizationFrontend.d.ts +17 -17
  53. package/lib/cjs/frontend/MobileAuthorizationFrontend.d.ts.map +1 -1
  54. package/lib/cjs/frontend/MobileAuthorizationFrontend.js +54 -46
  55. package/lib/cjs/frontend/MobileAuthorizationFrontend.js.map +1 -1
  56. package/lib/cjs/test/ios/MobilePlatform.test.d.ts +1 -1
  57. package/lib/cjs/test/ios/MobilePlatform.test.js +84 -84
  58. package/package.json +18 -18
@@ -1,278 +1,278 @@
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
- /** @packageDocumentation
7
- * @module RpcInterface
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.MobileRpcProtocol = void 0;
11
- const core_bentley_1 = require("@itwin/core-bentley");
12
- const core_common_1 = require("@itwin/core-common");
13
- const MobileEventLoop_1 = require("./MobileEventLoop");
14
- const MobileIpc_1 = require("./MobileIpc");
15
- const MobilePush_1 = require("./MobilePush");
16
- const MobileRpcManager_1 = require("./MobileRpcManager");
17
- const MobileRpcRequest_1 = require("./MobileRpcRequest");
18
- /** RPC interface protocol for an Mobile-based application.
19
- * @internal
20
- */
21
- class MobileRpcProtocol extends core_common_1.RpcProtocol {
22
- constructor(configuration, endPoint) {
23
- super(configuration);
24
- this.socket = undefined;
25
- this.requests = new Map();
26
- this._pending = [];
27
- this._capacity = Number.MAX_SAFE_INTEGER;
28
- this._sendInterval = undefined;
29
- this._sendIntervalHandler = () => this.trySend();
30
- this.requestType = MobileRpcRequest_1.MobileRpcRequest;
31
- this._partialRequest = undefined;
32
- this._partialFulfillment = undefined;
33
- this._partialData = [];
34
- this._port = 0;
35
- if (endPoint === core_common_1.RpcEndpoint.Frontend) {
36
- this.initializeFrontend();
37
- }
38
- else if (endPoint === core_common_1.RpcEndpoint.Backend) {
39
- this.initializeBackend();
40
- }
41
- this._ipc = new MobileIpc_1.MobileIpcTransport(this);
42
- core_common_1.IpcWebSocket.transport = this._ipc;
43
- }
44
- static obtainInterop() { throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Not implemented."); }
45
- static async encodeRequest(request) {
46
- const serialized = await request.protocol.serialize(request);
47
- const data = serialized.parameters.data;
48
- serialized.parameters.data = data.map((v) => v.byteLength);
49
- return [JSON.stringify(serialized), ...data];
50
- }
51
- static encodeResponse(fulfillment) {
52
- const data = fulfillment.result.data;
53
- fulfillment.result.data = data.map((v) => v.byteLength);
54
- const raw = fulfillment.rawResult;
55
- fulfillment.rawResult = undefined;
56
- const encoded = [JSON.stringify(fulfillment), ...data];
57
- fulfillment.rawResult = raw;
58
- return encoded;
59
- }
60
- initializeFrontend() {
61
- if (typeof (WebSocket) === "undefined") {
62
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "MobileRpcProtocol on frontend require websocket to work");
63
- }
64
- if (!MobileRpcManager_1.MobileRpcConfiguration.args.port) {
65
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "MobileRpcProtocol require 'port' parameter");
66
- }
67
- this._port = MobileRpcManager_1.MobileRpcConfiguration.args.port;
68
- this.connect(this._port, false);
69
- window._imodeljs_rpc_reconnect = (port) => {
70
- this.socket.close();
71
- window.location.hash = window.location.hash.replace(`port=${this._port}`, `port=${port}`);
72
- this._port = port;
73
- this.connect(port, true);
74
- };
75
- const transport = new MobilePush_1.MobilePushTransport(this);
76
- this._transport = transport;
77
- core_common_1.RpcPushChannel.setup(transport);
78
- }
79
- connect(port, reset) {
80
- const socket = new WebSocket(`ws://localhost:${port}`);
81
- socket.binaryType = "arraybuffer";
82
- this.connectMessageHandler(socket);
83
- this.connectOpenHandler(socket, reset);
84
- this.connectErrorHandler(socket);
85
- this.socket = socket;
86
- }
87
- connectMessageHandler(socket) {
88
- socket.addEventListener("message", async (event) => {
89
- if (this.socket !== socket) {
90
- return;
91
- }
92
- this.handleMessageFromBackend(event.data);
93
- });
94
- }
95
- connectOpenHandler(socket, reset) {
96
- socket.addEventListener("open", (_event) => {
97
- if (this.socket !== socket) {
98
- return;
99
- }
100
- if (reset) {
101
- this.reset();
102
- const requests = new Map(core_common_1.RpcRequest.activeRequests);
103
- requests.forEach((req) => {
104
- req.cancel();
105
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
106
- req.submit();
107
- });
108
- }
109
- this.scheduleSend();
110
- });
111
- }
112
- connectErrorHandler(socket) {
113
- socket.addEventListener("error", (_event) => {
114
- if (this.socket !== socket) {
115
- return;
116
- }
117
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Socket error.");
118
- });
119
- }
120
- reset() {
121
- this.requests.clear();
122
- this._capacity = Number.MAX_SAFE_INTEGER;
123
- if (typeof (this._sendInterval) !== "undefined") {
124
- window.clearInterval(this._sendInterval);
125
- this._sendInterval = undefined;
126
- }
127
- this._partialRequest = undefined;
128
- this._partialFulfillment = undefined;
129
- this._partialData.length = 0;
130
- }
131
- scheduleSend() {
132
- if (!this._pending.length) {
133
- return;
134
- }
135
- this.trySend();
136
- if (this._pending.length && typeof (this._sendInterval) === "undefined") {
137
- this._sendInterval = window.setInterval(this._sendIntervalHandler, 0);
138
- }
139
- }
140
- trySend() {
141
- if (this.socket.readyState !== WebSocket.OPEN) {
142
- return;
143
- }
144
- while (this._capacity !== 0 && this._pending.length) {
145
- --this._capacity;
146
- const next = this._pending.shift();
147
- for (const chunk of next) {
148
- this.socket.send(chunk);
149
- }
150
- }
151
- if (!this._pending.length && typeof (this._sendInterval) !== "undefined") {
152
- window.clearInterval(this._sendInterval);
153
- this._sendInterval = undefined;
154
- }
155
- }
156
- handleMessageFromBackend(data) {
157
- if (typeof (data) === "string") {
158
- this.handleStringFromBackend(data);
159
- }
160
- else {
161
- this.handleBinaryFromBackend(data);
162
- }
163
- }
164
- handleStringFromBackend(data) {
165
- if (this._partialFulfillment) {
166
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (already receiving response).");
167
- }
168
- const response = JSON.parse(data);
169
- this._partialFulfillment = response;
170
- if (!response.result.data.length) {
171
- this.notifyResponse();
172
- }
173
- }
174
- handleBinaryFromBackend(data) {
175
- const fulfillment = this._partialFulfillment;
176
- if (!fulfillment) {
177
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no response received).");
178
- }
179
- this._partialData.push(new Uint8Array(data));
180
- if (this._partialData.length === fulfillment.result.data.length) {
181
- this.notifyResponse();
182
- }
183
- }
184
- notifyResponse() {
185
- const response = this._partialFulfillment;
186
- if (!response) {
187
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no response exists).");
188
- }
189
- ++this._capacity;
190
- this.consumePartialData(response.result);
191
- this._partialFulfillment = undefined;
192
- if (this._transport && this._transport.consume(response)) {
193
- return;
194
- }
195
- if (this._ipc.consumeResponse(response)) {
196
- return;
197
- }
198
- const request = this.requests.get(response.id);
199
- this.requests.delete(response.id);
200
- request.notifyResponse(response);
201
- }
202
- consumePartialData(value) {
203
- for (let i = 0, l = value.data.length; i !== l; ++i) {
204
- value.data[i] = this._partialData[i];
205
- }
206
- this._partialData.length = 0;
207
- }
208
- initializeBackend() {
209
- const mobilegateway = MobileRpcProtocol.obtainInterop();
210
- if (mobilegateway === undefined || mobilegateway == null) {
211
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "MobileRpcProtocol on backend require native bridge to be setup");
212
- }
213
- mobilegateway.handler = (payload, connectionId) => this.handleMessageFromFrontend(payload, connectionId);
214
- core_common_1.RpcPushConnection.for = (channel, client) => new MobilePush_1.MobilePushConnection(channel, client, this);
215
- core_common_1.RpcPushChannel.enabled = true;
216
- }
217
- handleMessageFromFrontend(data, connectionId) {
218
- if (typeof (data) === "string") {
219
- this.handleStringFromFrontend(data, connectionId);
220
- }
221
- else {
222
- this.handleBinaryFromFrontend(data, connectionId);
223
- }
224
- }
225
- handleStringFromFrontend(data, connection) {
226
- if (this._partialRequest) {
227
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (already receiving request).");
228
- }
229
- const request = JSON.parse(data);
230
- this._partialRequest = request;
231
- if (!request.parameters.data.length) {
232
- this.notifyRequest(connection); // eslint-disable-line @typescript-eslint/no-floating-promises
233
- }
234
- }
235
- handleBinaryFromFrontend(data, connection) {
236
- const request = this._partialRequest;
237
- if (!request) {
238
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no request received).");
239
- }
240
- this._partialData.push(new Uint8Array(data));
241
- if (this._partialData.length === request.parameters.data.length) {
242
- this.notifyRequest(connection); // eslint-disable-line @typescript-eslint/no-floating-promises
243
- }
244
- }
245
- async notifyRequest(connection) {
246
- const request = this._partialRequest;
247
- if (!request) {
248
- throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no request exists).");
249
- }
250
- this.consumePartialData(request.parameters);
251
- this._partialRequest = undefined;
252
- if (this._ipc.consumeRequest(request)) {
253
- return;
254
- }
255
- MobileEventLoop_1.MobileEventLoop.addTask();
256
- const fulfillment = await this.fulfill(request);
257
- MobileEventLoop_1.MobileEventLoop.removeTask();
258
- const response = MobileRpcProtocol.encodeResponse(fulfillment);
259
- this.sendToFrontend(response, connection);
260
- }
261
- sendToBackend(message) {
262
- this._pending.push(message);
263
- this.scheduleSend();
264
- }
265
- sendToFrontend(message, connection) {
266
- const mobilegateway = MobileRpcProtocol.obtainInterop();
267
- for (const chunk of message) {
268
- if (typeof (chunk) === "string") {
269
- mobilegateway.sendString(chunk, connection || mobilegateway.connectionId);
270
- }
271
- else {
272
- mobilegateway.sendBinary(chunk, connection || mobilegateway.connectionId);
273
- }
274
- }
275
- }
276
- }
277
- exports.MobileRpcProtocol = MobileRpcProtocol;
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
+ /** @packageDocumentation
7
+ * @module RpcInterface
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MobileRpcProtocol = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const core_common_1 = require("@itwin/core-common");
13
+ const MobileEventLoop_1 = require("./MobileEventLoop");
14
+ const MobileIpc_1 = require("./MobileIpc");
15
+ const MobilePush_1 = require("./MobilePush");
16
+ const MobileRpcManager_1 = require("./MobileRpcManager");
17
+ const MobileRpcRequest_1 = require("./MobileRpcRequest");
18
+ /** RPC interface protocol for an Mobile-based application.
19
+ * @internal
20
+ */
21
+ class MobileRpcProtocol extends core_common_1.RpcProtocol {
22
+ static obtainInterop() { throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Not implemented."); }
23
+ static async encodeRequest(request) {
24
+ const serialized = await request.protocol.serialize(request);
25
+ const data = serialized.parameters.data;
26
+ serialized.parameters.data = data.map((v) => v.byteLength);
27
+ return [JSON.stringify(serialized), ...data];
28
+ }
29
+ static encodeResponse(fulfillment) {
30
+ const data = fulfillment.result.data;
31
+ fulfillment.result.data = data.map((v) => v.byteLength);
32
+ const raw = fulfillment.rawResult;
33
+ fulfillment.rawResult = undefined;
34
+ const encoded = [JSON.stringify(fulfillment), ...data];
35
+ fulfillment.rawResult = raw;
36
+ return encoded;
37
+ }
38
+ constructor(configuration, endPoint) {
39
+ super(configuration);
40
+ this.socket = undefined;
41
+ this.requests = new Map();
42
+ this._pending = [];
43
+ this._capacity = Number.MAX_SAFE_INTEGER;
44
+ this._sendInterval = undefined;
45
+ this._sendIntervalHandler = () => this.trySend();
46
+ this.requestType = MobileRpcRequest_1.MobileRpcRequest;
47
+ this._partialRequest = undefined;
48
+ this._partialFulfillment = undefined;
49
+ this._partialData = [];
50
+ this._port = 0;
51
+ if (endPoint === core_common_1.RpcEndpoint.Frontend) {
52
+ this.initializeFrontend();
53
+ }
54
+ else if (endPoint === core_common_1.RpcEndpoint.Backend) {
55
+ this.initializeBackend();
56
+ }
57
+ this._ipc = new MobileIpc_1.MobileIpcTransport(this);
58
+ core_common_1.IpcWebSocket.transport = this._ipc;
59
+ }
60
+ initializeFrontend() {
61
+ if (typeof (WebSocket) === "undefined") {
62
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "MobileRpcProtocol on frontend require websocket to work");
63
+ }
64
+ if (!MobileRpcManager_1.MobileRpcConfiguration.args.port) {
65
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "MobileRpcProtocol require 'port' parameter");
66
+ }
67
+ this._port = MobileRpcManager_1.MobileRpcConfiguration.args.port;
68
+ this.connect(this._port, false);
69
+ window._imodeljs_rpc_reconnect = (port) => {
70
+ this.socket.close();
71
+ window.location.hash = window.location.hash.replace(`port=${this._port}`, `port=${port}`);
72
+ this._port = port;
73
+ this.connect(port, true);
74
+ };
75
+ const transport = new MobilePush_1.MobilePushTransport(this);
76
+ this._transport = transport;
77
+ core_common_1.RpcPushChannel.setup(transport);
78
+ }
79
+ connect(port, reset) {
80
+ const socket = new WebSocket(`ws://localhost:${port}`);
81
+ socket.binaryType = "arraybuffer";
82
+ this.connectMessageHandler(socket);
83
+ this.connectOpenHandler(socket, reset);
84
+ this.connectErrorHandler(socket);
85
+ this.socket = socket;
86
+ }
87
+ connectMessageHandler(socket) {
88
+ socket.addEventListener("message", async (event) => {
89
+ if (this.socket !== socket) {
90
+ return;
91
+ }
92
+ this.handleMessageFromBackend(event.data);
93
+ });
94
+ }
95
+ connectOpenHandler(socket, reset) {
96
+ socket.addEventListener("open", (_event) => {
97
+ if (this.socket !== socket) {
98
+ return;
99
+ }
100
+ if (reset) {
101
+ this.reset();
102
+ const requests = new Map(core_common_1.RpcRequest.activeRequests);
103
+ requests.forEach((req) => {
104
+ req.cancel();
105
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
106
+ req.submit();
107
+ });
108
+ }
109
+ this.scheduleSend();
110
+ });
111
+ }
112
+ connectErrorHandler(socket) {
113
+ socket.addEventListener("error", (_event) => {
114
+ if (this.socket !== socket) {
115
+ return;
116
+ }
117
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Socket error.");
118
+ });
119
+ }
120
+ reset() {
121
+ this.requests.clear();
122
+ this._capacity = Number.MAX_SAFE_INTEGER;
123
+ if (typeof (this._sendInterval) !== "undefined") {
124
+ window.clearInterval(this._sendInterval);
125
+ this._sendInterval = undefined;
126
+ }
127
+ this._partialRequest = undefined;
128
+ this._partialFulfillment = undefined;
129
+ this._partialData.length = 0;
130
+ }
131
+ scheduleSend() {
132
+ if (!this._pending.length) {
133
+ return;
134
+ }
135
+ this.trySend();
136
+ if (this._pending.length && typeof (this._sendInterval) === "undefined") {
137
+ this._sendInterval = window.setInterval(this._sendIntervalHandler, 0);
138
+ }
139
+ }
140
+ trySend() {
141
+ if (this.socket.readyState !== WebSocket.OPEN) {
142
+ return;
143
+ }
144
+ while (this._capacity !== 0 && this._pending.length) {
145
+ --this._capacity;
146
+ const next = this._pending.shift();
147
+ for (const chunk of next) {
148
+ this.socket.send(chunk);
149
+ }
150
+ }
151
+ if (!this._pending.length && typeof (this._sendInterval) !== "undefined") {
152
+ window.clearInterval(this._sendInterval);
153
+ this._sendInterval = undefined;
154
+ }
155
+ }
156
+ handleMessageFromBackend(data) {
157
+ if (typeof (data) === "string") {
158
+ this.handleStringFromBackend(data);
159
+ }
160
+ else {
161
+ this.handleBinaryFromBackend(data);
162
+ }
163
+ }
164
+ handleStringFromBackend(data) {
165
+ if (this._partialFulfillment) {
166
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (already receiving response).");
167
+ }
168
+ const response = JSON.parse(data);
169
+ this._partialFulfillment = response;
170
+ if (!response.result.data.length) {
171
+ this.notifyResponse();
172
+ }
173
+ }
174
+ handleBinaryFromBackend(data) {
175
+ const fulfillment = this._partialFulfillment;
176
+ if (!fulfillment) {
177
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no response received).");
178
+ }
179
+ this._partialData.push(new Uint8Array(data));
180
+ if (this._partialData.length === fulfillment.result.data.length) {
181
+ this.notifyResponse();
182
+ }
183
+ }
184
+ notifyResponse() {
185
+ const response = this._partialFulfillment;
186
+ if (!response) {
187
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no response exists).");
188
+ }
189
+ ++this._capacity;
190
+ this.consumePartialData(response.result);
191
+ this._partialFulfillment = undefined;
192
+ if (this._transport && this._transport.consume(response)) {
193
+ return;
194
+ }
195
+ if (this._ipc.consumeResponse(response)) {
196
+ return;
197
+ }
198
+ const request = this.requests.get(response.id);
199
+ this.requests.delete(response.id);
200
+ request.notifyResponse(response);
201
+ }
202
+ consumePartialData(value) {
203
+ for (let i = 0, l = value.data.length; i !== l; ++i) {
204
+ value.data[i] = this._partialData[i];
205
+ }
206
+ this._partialData.length = 0;
207
+ }
208
+ initializeBackend() {
209
+ const mobilegateway = MobileRpcProtocol.obtainInterop();
210
+ if (mobilegateway === undefined || mobilegateway == null) {
211
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "MobileRpcProtocol on backend require native bridge to be setup");
212
+ }
213
+ mobilegateway.handler = (payload, connectionId) => this.handleMessageFromFrontend(payload, connectionId);
214
+ core_common_1.RpcPushConnection.for = (channel, client) => new MobilePush_1.MobilePushConnection(channel, client, this);
215
+ core_common_1.RpcPushChannel.enabled = true;
216
+ }
217
+ handleMessageFromFrontend(data, connectionId) {
218
+ if (typeof (data) === "string") {
219
+ this.handleStringFromFrontend(data, connectionId);
220
+ }
221
+ else {
222
+ this.handleBinaryFromFrontend(data, connectionId);
223
+ }
224
+ }
225
+ handleStringFromFrontend(data, connection) {
226
+ if (this._partialRequest) {
227
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (already receiving request).");
228
+ }
229
+ const request = JSON.parse(data);
230
+ this._partialRequest = request;
231
+ if (!request.parameters.data.length) {
232
+ this.notifyRequest(connection); // eslint-disable-line @typescript-eslint/no-floating-promises
233
+ }
234
+ }
235
+ handleBinaryFromFrontend(data, connection) {
236
+ const request = this._partialRequest;
237
+ if (!request) {
238
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no request received).");
239
+ }
240
+ this._partialData.push(new Uint8Array(data));
241
+ if (this._partialData.length === request.parameters.data.length) {
242
+ this.notifyRequest(connection); // eslint-disable-line @typescript-eslint/no-floating-promises
243
+ }
244
+ }
245
+ async notifyRequest(connection) {
246
+ const request = this._partialRequest;
247
+ if (!request) {
248
+ throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Invalid state (no request exists).");
249
+ }
250
+ this.consumePartialData(request.parameters);
251
+ this._partialRequest = undefined;
252
+ if (this._ipc.consumeRequest(request)) {
253
+ return;
254
+ }
255
+ MobileEventLoop_1.MobileEventLoop.addTask();
256
+ const fulfillment = await this.fulfill(request);
257
+ MobileEventLoop_1.MobileEventLoop.removeTask();
258
+ const response = MobileRpcProtocol.encodeResponse(fulfillment);
259
+ this.sendToFrontend(response, connection);
260
+ }
261
+ sendToBackend(message) {
262
+ this._pending.push(message);
263
+ this.scheduleSend();
264
+ }
265
+ sendToFrontend(message, connection) {
266
+ const mobilegateway = MobileRpcProtocol.obtainInterop();
267
+ for (const chunk of message) {
268
+ if (typeof (chunk) === "string") {
269
+ mobilegateway.sendString(chunk, connection || mobilegateway.connectionId);
270
+ }
271
+ else {
272
+ mobilegateway.sendBinary(chunk, connection || mobilegateway.connectionId);
273
+ }
274
+ }
275
+ }
276
+ }
277
+ exports.MobileRpcProtocol = MobileRpcProtocol;
278
278
  //# sourceMappingURL=MobileRpcProtocol.js.map