@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,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