js-gei 1.0.0 → 1.0.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/Library/RpcClient.ts +362 -0
- package/dist/Library/RpcClient.js +284 -0
- package/dist/index.js +18 -3
- package/index.ts +23 -2
- package/package.json +1 -1
- package/Library/jsonrpc-2.0.js +0 -869
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import axios, { AxiosResponse } from 'axios';
|
|
2
|
+
|
|
3
|
+
interface RpcPacket {
|
|
4
|
+
method: string;
|
|
5
|
+
params: any;
|
|
6
|
+
id?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface ConfigTemplate {
|
|
10
|
+
url: string;
|
|
11
|
+
cors:boolean;
|
|
12
|
+
batch: boolean;
|
|
13
|
+
jsonRpcPreemptAfter: number;
|
|
14
|
+
autoQueryPreempted: boolean;
|
|
15
|
+
log: (message?: any, ...optionalParams: any[]) => void;
|
|
16
|
+
unhandledError: (error: any) => void;
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface PreemptedItem {
|
|
21
|
+
id: number;
|
|
22
|
+
ticket: string;
|
|
23
|
+
processor: Processor;
|
|
24
|
+
progressor: Progressor | null;
|
|
25
|
+
context: RpcContext;
|
|
26
|
+
queue: any[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface Processor {
|
|
30
|
+
process: (response: any, xhr?: XMLHttpRequest) => void;
|
|
31
|
+
context: RpcContext;
|
|
32
|
+
callbacks: ((response: any, xhr?: XMLHttpRequest) => void)[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Progressor {
|
|
36
|
+
progress: (report: any) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface RpcContext {
|
|
40
|
+
id: number;
|
|
41
|
+
count: number;
|
|
42
|
+
rpcErrorHandlers: ((error: any) => void)[];
|
|
43
|
+
apiErrorHandlers: ((error: any) => void)[];
|
|
44
|
+
apiSuccessHandlers: ((response: any) => void)[];
|
|
45
|
+
responsePreviewers: ((response: any) => boolean)[];
|
|
46
|
+
finallyHandlers: (() => void)[];
|
|
47
|
+
preempted?: string[] | null;
|
|
48
|
+
|
|
49
|
+
onRpcError(callback: (error: any) => void): RpcContext;
|
|
50
|
+
onDefaultApiError(callback: (error: any) => void): RpcContext;
|
|
51
|
+
onDefaultApiSuccess(callback: (response: any) => void): RpcContext;
|
|
52
|
+
onFinally(callback: () => void): RpcContext;
|
|
53
|
+
onPreviewResponse(callback: (response: any) => boolean): RpcContext;
|
|
54
|
+
__enter(): void;
|
|
55
|
+
__preview(response: any): boolean;
|
|
56
|
+
__rpcFail(error: any): void;
|
|
57
|
+
__defaultApiFail(error: any): void;
|
|
58
|
+
__defaultApiSucceed(response: any): void;
|
|
59
|
+
__leave(): void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const RpcClient = (() => {
|
|
63
|
+
let _id = Date.now();
|
|
64
|
+
let _ctxid = 0;
|
|
65
|
+
let _preempted: PreemptedItem[] | null = null;
|
|
66
|
+
let _pendingAjaxCount = 0;
|
|
67
|
+
|
|
68
|
+
const _currentPath = window.location.pathname.trim().replace(/(^[\/]*|[\/]*$)/g, "");
|
|
69
|
+
const _currentPathTopLevel = (() => {
|
|
70
|
+
try {
|
|
71
|
+
return window.top?.location.pathname.trim().replace(/(^[\/]*|[\/]*$)/g, "") || '(unavailable)';
|
|
72
|
+
} catch {
|
|
73
|
+
return '(unavailable)';
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
|
|
77
|
+
const configTemplate: ConfigTemplate = {
|
|
78
|
+
url: "json.rpc",
|
|
79
|
+
batch: true,
|
|
80
|
+
cors:false,
|
|
81
|
+
jsonRpcPreemptAfter: 7,
|
|
82
|
+
autoQueryPreempted: true,
|
|
83
|
+
log: console.log,
|
|
84
|
+
unhandledError: console.log
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const baseUrl = (() => {
|
|
88
|
+
const baseElement = document.querySelector("head base");
|
|
89
|
+
return baseElement ? baseElement.getAttribute("href") : null;
|
|
90
|
+
})();
|
|
91
|
+
|
|
92
|
+
const urlCombine = (parts: string[]): string =>
|
|
93
|
+
parts.map(part => part.trim().replace(/(^[\/]*|[\/]*$)/g, "")).join("/");
|
|
94
|
+
|
|
95
|
+
if (_currentPath) {
|
|
96
|
+
configTemplate.url = baseUrl
|
|
97
|
+
? urlCombine([baseUrl, _currentPath, configTemplate.url])
|
|
98
|
+
: urlCombine([_currentPath, configTemplate.url]);
|
|
99
|
+
} else if (baseUrl) {
|
|
100
|
+
configTemplate.url = urlCombine([baseUrl, configTemplate.url]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const preparePacket = (method: string, ...args: any[]): RpcPacket => ({
|
|
104
|
+
method,
|
|
105
|
+
params: args.length === 1 && (Array.isArray(args[0]) || typeof args[0] === 'object') ? args[0] : args
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const schedulePreemptedQuery = (
|
|
109
|
+
id: number,
|
|
110
|
+
ticket: string,
|
|
111
|
+
processor: Processor,
|
|
112
|
+
progressor: Progressor | null,
|
|
113
|
+
context: RpcContext,
|
|
114
|
+
queue: any[]
|
|
115
|
+
) => {
|
|
116
|
+
if (!_preempted) _preempted = [];
|
|
117
|
+
_preempted.push({ id, ticket, processor, progressor, context, queue });
|
|
118
|
+
|
|
119
|
+
const query = () => {
|
|
120
|
+
if (!_preempted || !_preempted.length) {
|
|
121
|
+
_preempted = null;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const ctx = RpcClient.context().onFinally(() => setTimeout(query, 2000));
|
|
126
|
+
const tickets = _preempted.map(item => item.ticket);
|
|
127
|
+
|
|
128
|
+
RpcClient.call('$.QueryPreemptedResponses', { tickets })
|
|
129
|
+
.done((response: any) => {
|
|
130
|
+
if (response.error) {
|
|
131
|
+
const items = _preempted!.splice(0, tickets.length);
|
|
132
|
+
items.forEach(item => item.processor.process(response));
|
|
133
|
+
items.forEach(item => {
|
|
134
|
+
if (item.context.preempted) {
|
|
135
|
+
item.context.preempted = null;
|
|
136
|
+
item.context.__leave();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
Object.entries(response.result).forEach(([ticket, report]: [string, any]) => {
|
|
143
|
+
const idx = _preempted!.findIndex(p => p.ticket === ticket);
|
|
144
|
+
if (idx === -1) return;
|
|
145
|
+
|
|
146
|
+
const item = _preempted![idx];
|
|
147
|
+
if (report.status === 'error') {
|
|
148
|
+
_preempted!.splice(idx, 1);
|
|
149
|
+
item.processor.process({ id: item.id, error: { code: -1, message: report.reason } });
|
|
150
|
+
} else if (report.status === 'ok') {
|
|
151
|
+
RpcClient.call('$.RetrievePreemptedResponse', { ticket })
|
|
152
|
+
.done((realResponse: any) => item.processor.process(realResponse))
|
|
153
|
+
.post(ctx);
|
|
154
|
+
} else if (item.progressor) {
|
|
155
|
+
item.progressor.progress(report);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return false;
|
|
160
|
+
})
|
|
161
|
+
.post(ctx);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
setTimeout(query, 2000);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const dispatcher = (() => {
|
|
168
|
+
let _queue: { batch: any[]; context: RpcContext; fail: (rpc: boolean, e: any) => void }[] = [];
|
|
169
|
+
let _last: Date | null = null;
|
|
170
|
+
const _delay = 700;
|
|
171
|
+
|
|
172
|
+
const postQueue = (config: ConfigTemplate) => {
|
|
173
|
+
const queue = _queue;
|
|
174
|
+
_queue = [];
|
|
175
|
+
if (!queue.length) return;
|
|
176
|
+
|
|
177
|
+
const batch = queue.length === 1 ? queue[0].batch : queue.flatMap(q => q.batch);
|
|
178
|
+
const request = batch.length === 1
|
|
179
|
+
? batch[0].request
|
|
180
|
+
: [{ method: '$.BeginSynchronizedBatch', params: [] }, ...batch.map(b => b.request)];
|
|
181
|
+
|
|
182
|
+
const handler = (data: any, xhr?: XMLHttpRequest) => {
|
|
183
|
+
if (!data) {
|
|
184
|
+
queue.forEach(q => q.fail(true, "Server returned an empty response."));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const responses = Array.isArray(data) ? data : [data];
|
|
189
|
+
responses.forEach(response => {
|
|
190
|
+
const item = queue.find(q => q.batch.some(b => b.request.id === response.id));
|
|
191
|
+
if (!item) return;
|
|
192
|
+
|
|
193
|
+
const processor: Processor = {
|
|
194
|
+
context: item.context,
|
|
195
|
+
callbacks: item.batch.find(b => b.request.id === response.id)!.callbacks,
|
|
196
|
+
process: (response: any) => {
|
|
197
|
+
const doDefaultProcessing = processor.context.__preview(response);
|
|
198
|
+
if (!doDefaultProcessing) return;
|
|
199
|
+
|
|
200
|
+
processor.callbacks.forEach(callback => callback(response, xhr));
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
if (response.error && response.error.code === -32099 && config.autoQueryPreempted) {
|
|
205
|
+
const ticket = response.error.data;
|
|
206
|
+
if (!item.context.preempted) item.context.preempted = [];
|
|
207
|
+
item.context.preempted.push(ticket);
|
|
208
|
+
schedulePreemptedQuery(response.id, ticket, processor, null, item.context, queue);
|
|
209
|
+
} else {
|
|
210
|
+
processor.process(response, xhr);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
queue.forEach(q => {
|
|
215
|
+
if (!q.context.preempted) q.context.__leave();
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
axios.post(config.url, request, { headers: config.headers, timeout: 0, responseType: 'blob', withCredentials: true })
|
|
220
|
+
.then((response: AxiosResponse) => handler(JSON.parse(response.data), response.request))
|
|
221
|
+
.catch(error => handler({ error: { status: error.code, details: error.message }, ajaxCallFailed: true }));
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
dispatch: (
|
|
226
|
+
batch: any[],
|
|
227
|
+
context: RpcContext,
|
|
228
|
+
fail: (rpc: boolean, e: any) => void,
|
|
229
|
+
config: ConfigTemplate
|
|
230
|
+
) => {
|
|
231
|
+
const now = new Date();
|
|
232
|
+
if (!_queue.length) (_queue as any).created = now;
|
|
233
|
+
_queue.push({ batch, context, fail });
|
|
234
|
+
|
|
235
|
+
if (!config.batch || !_pendingAjaxCount) {
|
|
236
|
+
postQueue(config);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const diff = _last ? now.getTime() - _last.getTime() : 0;
|
|
241
|
+
const span = now.getTime() - (_queue as any).created.getTime();
|
|
242
|
+
if (span < 3000 && (_pendingAjaxCount > 3 || diff < _delay)) {
|
|
243
|
+
clearTimeout((_queue as any).timeoutHandle);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
(_queue as any).timeoutHandle = setTimeout(() => postQueue(config), _delay + 50);
|
|
247
|
+
_last = now;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
})();
|
|
251
|
+
|
|
252
|
+
const main = (packet: RpcPacket, config: ConfigTemplate) => {
|
|
253
|
+
const batch: { request: RpcPacket; callbacks: ((response: any) => void)[]; progressCallbacks: any[] }[] = [
|
|
254
|
+
{ request: packet, callbacks: [], progressCallbacks: [] }
|
|
255
|
+
];
|
|
256
|
+
let context: RpcContext | null = null;
|
|
257
|
+
|
|
258
|
+
const fail = (rpc: boolean, e: any) => {
|
|
259
|
+
if (context && rpc === true && context.__rpcFail(e)) return;
|
|
260
|
+
if (config && config.unhandledError) config.unhandledError(e);
|
|
261
|
+
else console.log(e);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
call: function (...args: [string, ...any[]]) {
|
|
266
|
+
const p = preparePacket(...args);
|
|
267
|
+
_id++;
|
|
268
|
+
p.id = _id;
|
|
269
|
+
batch.push({ request: p, callbacks: [], progressCallbacks: [] });
|
|
270
|
+
return this;
|
|
271
|
+
},
|
|
272
|
+
notify: function (...args: [string, ...any[]]) {
|
|
273
|
+
const p = preparePacket(...args);
|
|
274
|
+
batch.push({ request: p, callbacks: [], progressCallbacks: [] });
|
|
275
|
+
return this;
|
|
276
|
+
},
|
|
277
|
+
done: function (callback: (response: any) => void) {
|
|
278
|
+
if (typeof callback === 'function') batch[batch.length - 1].callbacks.push(callback);
|
|
279
|
+
return this;
|
|
280
|
+
},
|
|
281
|
+
post: function (ctx?: RpcContext, customConfig?: ConfigTemplate) {
|
|
282
|
+
context = ctx || RpcClient.context();
|
|
283
|
+
context.__enter();
|
|
284
|
+
|
|
285
|
+
const config = customConfig || RpcClient.config;
|
|
286
|
+
if (!config) {
|
|
287
|
+
fail(true, "RpcClient was invoked without a valid config object!");
|
|
288
|
+
context.__leave();
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
dispatcher.dispatch(batch, context, fail, config);
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
config: configTemplate,
|
|
299
|
+
call: function (...args: [string, ...any[]]) {
|
|
300
|
+
const packet = preparePacket(...args);
|
|
301
|
+
_id++;
|
|
302
|
+
packet.id = _id;
|
|
303
|
+
return main(packet, this.config);
|
|
304
|
+
},
|
|
305
|
+
notify: function (...args: [string, ...any[]]) {
|
|
306
|
+
const packet = preparePacket(...args);
|
|
307
|
+
return main(packet, this.config);
|
|
308
|
+
},
|
|
309
|
+
context: function (): RpcContext {
|
|
310
|
+
_ctxid++;
|
|
311
|
+
const ctx: RpcContext = {
|
|
312
|
+
id: _ctxid,
|
|
313
|
+
count: 0,
|
|
314
|
+
rpcErrorHandlers: [],
|
|
315
|
+
apiErrorHandlers: [],
|
|
316
|
+
apiSuccessHandlers: [],
|
|
317
|
+
responsePreviewers: [],
|
|
318
|
+
finallyHandlers: [],
|
|
319
|
+
onRpcError(callback: (error: any) => void) {
|
|
320
|
+
if (typeof callback === 'function') this.rpcErrorHandlers.push(callback);
|
|
321
|
+
return this;
|
|
322
|
+
},
|
|
323
|
+
onDefaultApiError(callback: (error: any) => void) {
|
|
324
|
+
if (typeof callback === 'function') this.apiErrorHandlers.push(callback);
|
|
325
|
+
return this;
|
|
326
|
+
},
|
|
327
|
+
onDefaultApiSuccess(callback: (response: any) => void) {
|
|
328
|
+
if (typeof callback === 'function') this.apiSuccessHandlers.push(callback);
|
|
329
|
+
return this;
|
|
330
|
+
},
|
|
331
|
+
onFinally(callback: () => void) {
|
|
332
|
+
if (typeof callback === 'function') this.finallyHandlers.push(callback);
|
|
333
|
+
return this;
|
|
334
|
+
},
|
|
335
|
+
onPreviewResponse(callback: (response: any) => boolean) {
|
|
336
|
+
if (typeof callback === 'function') this.responsePreviewers.push(callback);
|
|
337
|
+
return this;
|
|
338
|
+
},
|
|
339
|
+
__enter() {
|
|
340
|
+
this.count++;
|
|
341
|
+
},
|
|
342
|
+
__preview(response: any) {
|
|
343
|
+
return this.responsePreviewers.every(callback => callback(response));
|
|
344
|
+
},
|
|
345
|
+
__rpcFail(error: any) {
|
|
346
|
+
this.rpcErrorHandlers.forEach(callback => callback(error));
|
|
347
|
+
},
|
|
348
|
+
__defaultApiFail(error: any) {
|
|
349
|
+
this.apiErrorHandlers.forEach(callback => callback(error));
|
|
350
|
+
},
|
|
351
|
+
__defaultApiSucceed(response: any) {
|
|
352
|
+
this.apiSuccessHandlers.forEach(callback => callback(response));
|
|
353
|
+
},
|
|
354
|
+
__leave() {
|
|
355
|
+
if (--this.count === 0) this.finallyHandlers.forEach(callback => callback());
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
return ctx;
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
})();
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RpcClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
exports.RpcClient = (() => {
|
|
9
|
+
let _id = Date.now();
|
|
10
|
+
let _ctxid = 0;
|
|
11
|
+
let _preempted = null;
|
|
12
|
+
let _pendingAjaxCount = 0;
|
|
13
|
+
const _currentPath = window.location.pathname.trim().replace(/(^[\/]*|[\/]*$)/g, "");
|
|
14
|
+
const _currentPathTopLevel = (() => {
|
|
15
|
+
var _a;
|
|
16
|
+
try {
|
|
17
|
+
return ((_a = window.top) === null || _a === void 0 ? void 0 : _a.location.pathname.trim().replace(/(^[\/]*|[\/]*$)/g, "")) || '(unavailable)';
|
|
18
|
+
}
|
|
19
|
+
catch (_b) {
|
|
20
|
+
return '(unavailable)';
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
const configTemplate = {
|
|
24
|
+
url: "json.rpc",
|
|
25
|
+
batch: true,
|
|
26
|
+
cors: false,
|
|
27
|
+
jsonRpcPreemptAfter: 7,
|
|
28
|
+
autoQueryPreempted: true,
|
|
29
|
+
log: console.log,
|
|
30
|
+
unhandledError: console.log
|
|
31
|
+
};
|
|
32
|
+
const baseUrl = (() => {
|
|
33
|
+
const baseElement = document.querySelector("head base");
|
|
34
|
+
return baseElement ? baseElement.getAttribute("href") : null;
|
|
35
|
+
})();
|
|
36
|
+
const urlCombine = (parts) => parts.map(part => part.trim().replace(/(^[\/]*|[\/]*$)/g, "")).join("/");
|
|
37
|
+
if (_currentPath) {
|
|
38
|
+
configTemplate.url = baseUrl
|
|
39
|
+
? urlCombine([baseUrl, _currentPath, configTemplate.url])
|
|
40
|
+
: urlCombine([_currentPath, configTemplate.url]);
|
|
41
|
+
}
|
|
42
|
+
else if (baseUrl) {
|
|
43
|
+
configTemplate.url = urlCombine([baseUrl, configTemplate.url]);
|
|
44
|
+
}
|
|
45
|
+
const preparePacket = (method, ...args) => ({
|
|
46
|
+
method,
|
|
47
|
+
params: args.length === 1 && (Array.isArray(args[0]) || typeof args[0] === 'object') ? args[0] : args
|
|
48
|
+
});
|
|
49
|
+
const schedulePreemptedQuery = (id, ticket, processor, progressor, context, queue) => {
|
|
50
|
+
if (!_preempted)
|
|
51
|
+
_preempted = [];
|
|
52
|
+
_preempted.push({ id, ticket, processor, progressor, context, queue });
|
|
53
|
+
const query = () => {
|
|
54
|
+
if (!_preempted || !_preempted.length) {
|
|
55
|
+
_preempted = null;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const ctx = exports.RpcClient.context().onFinally(() => setTimeout(query, 2000));
|
|
59
|
+
const tickets = _preempted.map(item => item.ticket);
|
|
60
|
+
exports.RpcClient.call('$.QueryPreemptedResponses', { tickets })
|
|
61
|
+
.done((response) => {
|
|
62
|
+
if (response.error) {
|
|
63
|
+
const items = _preempted.splice(0, tickets.length);
|
|
64
|
+
items.forEach(item => item.processor.process(response));
|
|
65
|
+
items.forEach(item => {
|
|
66
|
+
if (item.context.preempted) {
|
|
67
|
+
item.context.preempted = null;
|
|
68
|
+
item.context.__leave();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
Object.entries(response.result).forEach(([ticket, report]) => {
|
|
74
|
+
const idx = _preempted.findIndex(p => p.ticket === ticket);
|
|
75
|
+
if (idx === -1)
|
|
76
|
+
return;
|
|
77
|
+
const item = _preempted[idx];
|
|
78
|
+
if (report.status === 'error') {
|
|
79
|
+
_preempted.splice(idx, 1);
|
|
80
|
+
item.processor.process({ id: item.id, error: { code: -1, message: report.reason } });
|
|
81
|
+
}
|
|
82
|
+
else if (report.status === 'ok') {
|
|
83
|
+
exports.RpcClient.call('$.RetrievePreemptedResponse', { ticket })
|
|
84
|
+
.done((realResponse) => item.processor.process(realResponse))
|
|
85
|
+
.post(ctx);
|
|
86
|
+
}
|
|
87
|
+
else if (item.progressor) {
|
|
88
|
+
item.progressor.progress(report);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return false;
|
|
92
|
+
})
|
|
93
|
+
.post(ctx);
|
|
94
|
+
};
|
|
95
|
+
setTimeout(query, 2000);
|
|
96
|
+
};
|
|
97
|
+
const dispatcher = (() => {
|
|
98
|
+
let _queue = [];
|
|
99
|
+
let _last = null;
|
|
100
|
+
const _delay = 700;
|
|
101
|
+
const postQueue = (config) => {
|
|
102
|
+
const queue = _queue;
|
|
103
|
+
_queue = [];
|
|
104
|
+
if (!queue.length)
|
|
105
|
+
return;
|
|
106
|
+
const batch = queue.length === 1 ? queue[0].batch : queue.flatMap(q => q.batch);
|
|
107
|
+
const request = batch.length === 1
|
|
108
|
+
? batch[0].request
|
|
109
|
+
: [{ method: '$.BeginSynchronizedBatch', params: [] }, ...batch.map(b => b.request)];
|
|
110
|
+
const handler = (data, xhr) => {
|
|
111
|
+
if (!data) {
|
|
112
|
+
queue.forEach(q => q.fail(true, "Server returned an empty response."));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const responses = Array.isArray(data) ? data : [data];
|
|
116
|
+
responses.forEach(response => {
|
|
117
|
+
const item = queue.find(q => q.batch.some(b => b.request.id === response.id));
|
|
118
|
+
if (!item)
|
|
119
|
+
return;
|
|
120
|
+
const processor = {
|
|
121
|
+
context: item.context,
|
|
122
|
+
callbacks: item.batch.find(b => b.request.id === response.id).callbacks,
|
|
123
|
+
process: (response) => {
|
|
124
|
+
const doDefaultProcessing = processor.context.__preview(response);
|
|
125
|
+
if (!doDefaultProcessing)
|
|
126
|
+
return;
|
|
127
|
+
processor.callbacks.forEach(callback => callback(response, xhr));
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
if (response.error && response.error.code === -32099 && config.autoQueryPreempted) {
|
|
131
|
+
const ticket = response.error.data;
|
|
132
|
+
if (!item.context.preempted)
|
|
133
|
+
item.context.preempted = [];
|
|
134
|
+
item.context.preempted.push(ticket);
|
|
135
|
+
schedulePreemptedQuery(response.id, ticket, processor, null, item.context, queue);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
processor.process(response, xhr);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
queue.forEach(q => {
|
|
142
|
+
if (!q.context.preempted)
|
|
143
|
+
q.context.__leave();
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
axios_1.default.post(config.url, request, { headers: config.headers, timeout: 0, responseType: 'blob', withCredentials: true })
|
|
147
|
+
.then((response) => handler(JSON.parse(response.data), response.request))
|
|
148
|
+
.catch(error => handler({ error: { status: error.code, details: error.message }, ajaxCallFailed: true }));
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
dispatch: (batch, context, fail, config) => {
|
|
152
|
+
const now = new Date();
|
|
153
|
+
if (!_queue.length)
|
|
154
|
+
_queue.created = now;
|
|
155
|
+
_queue.push({ batch, context, fail });
|
|
156
|
+
if (!config.batch || !_pendingAjaxCount) {
|
|
157
|
+
postQueue(config);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const diff = _last ? now.getTime() - _last.getTime() : 0;
|
|
161
|
+
const span = now.getTime() - _queue.created.getTime();
|
|
162
|
+
if (span < 3000 && (_pendingAjaxCount > 3 || diff < _delay)) {
|
|
163
|
+
clearTimeout(_queue.timeoutHandle);
|
|
164
|
+
}
|
|
165
|
+
_queue.timeoutHandle = setTimeout(() => postQueue(config), _delay + 50);
|
|
166
|
+
_last = now;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
})();
|
|
170
|
+
const main = (packet, config) => {
|
|
171
|
+
const batch = [
|
|
172
|
+
{ request: packet, callbacks: [], progressCallbacks: [] }
|
|
173
|
+
];
|
|
174
|
+
let context = null;
|
|
175
|
+
const fail = (rpc, e) => {
|
|
176
|
+
if (context && rpc === true && context.__rpcFail(e))
|
|
177
|
+
return;
|
|
178
|
+
if (config && config.unhandledError)
|
|
179
|
+
config.unhandledError(e);
|
|
180
|
+
else
|
|
181
|
+
console.log(e);
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
call: function (...args) {
|
|
185
|
+
const p = preparePacket(...args);
|
|
186
|
+
_id++;
|
|
187
|
+
p.id = _id;
|
|
188
|
+
batch.push({ request: p, callbacks: [], progressCallbacks: [] });
|
|
189
|
+
return this;
|
|
190
|
+
},
|
|
191
|
+
notify: function (...args) {
|
|
192
|
+
const p = preparePacket(...args);
|
|
193
|
+
batch.push({ request: p, callbacks: [], progressCallbacks: [] });
|
|
194
|
+
return this;
|
|
195
|
+
},
|
|
196
|
+
done: function (callback) {
|
|
197
|
+
if (typeof callback === 'function')
|
|
198
|
+
batch[batch.length - 1].callbacks.push(callback);
|
|
199
|
+
return this;
|
|
200
|
+
},
|
|
201
|
+
post: function (ctx, customConfig) {
|
|
202
|
+
context = ctx || exports.RpcClient.context();
|
|
203
|
+
context.__enter();
|
|
204
|
+
const config = customConfig || exports.RpcClient.config;
|
|
205
|
+
if (!config) {
|
|
206
|
+
fail(true, "RpcClient was invoked without a valid config object!");
|
|
207
|
+
context.__leave();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
dispatcher.dispatch(batch, context, fail, config);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
config: configTemplate,
|
|
216
|
+
call: function (...args) {
|
|
217
|
+
const packet = preparePacket(...args);
|
|
218
|
+
_id++;
|
|
219
|
+
packet.id = _id;
|
|
220
|
+
return main(packet, this.config);
|
|
221
|
+
},
|
|
222
|
+
notify: function (...args) {
|
|
223
|
+
const packet = preparePacket(...args);
|
|
224
|
+
return main(packet, this.config);
|
|
225
|
+
},
|
|
226
|
+
context: function () {
|
|
227
|
+
_ctxid++;
|
|
228
|
+
const ctx = {
|
|
229
|
+
id: _ctxid,
|
|
230
|
+
count: 0,
|
|
231
|
+
rpcErrorHandlers: [],
|
|
232
|
+
apiErrorHandlers: [],
|
|
233
|
+
apiSuccessHandlers: [],
|
|
234
|
+
responsePreviewers: [],
|
|
235
|
+
finallyHandlers: [],
|
|
236
|
+
onRpcError(callback) {
|
|
237
|
+
if (typeof callback === 'function')
|
|
238
|
+
this.rpcErrorHandlers.push(callback);
|
|
239
|
+
return this;
|
|
240
|
+
},
|
|
241
|
+
onDefaultApiError(callback) {
|
|
242
|
+
if (typeof callback === 'function')
|
|
243
|
+
this.apiErrorHandlers.push(callback);
|
|
244
|
+
return this;
|
|
245
|
+
},
|
|
246
|
+
onDefaultApiSuccess(callback) {
|
|
247
|
+
if (typeof callback === 'function')
|
|
248
|
+
this.apiSuccessHandlers.push(callback);
|
|
249
|
+
return this;
|
|
250
|
+
},
|
|
251
|
+
onFinally(callback) {
|
|
252
|
+
if (typeof callback === 'function')
|
|
253
|
+
this.finallyHandlers.push(callback);
|
|
254
|
+
return this;
|
|
255
|
+
},
|
|
256
|
+
onPreviewResponse(callback) {
|
|
257
|
+
if (typeof callback === 'function')
|
|
258
|
+
this.responsePreviewers.push(callback);
|
|
259
|
+
return this;
|
|
260
|
+
},
|
|
261
|
+
__enter() {
|
|
262
|
+
this.count++;
|
|
263
|
+
},
|
|
264
|
+
__preview(response) {
|
|
265
|
+
return this.responsePreviewers.every(callback => callback(response));
|
|
266
|
+
},
|
|
267
|
+
__rpcFail(error) {
|
|
268
|
+
this.rpcErrorHandlers.forEach(callback => callback(error));
|
|
269
|
+
},
|
|
270
|
+
__defaultApiFail(error) {
|
|
271
|
+
this.apiErrorHandlers.forEach(callback => callback(error));
|
|
272
|
+
},
|
|
273
|
+
__defaultApiSucceed(response) {
|
|
274
|
+
this.apiSuccessHandlers.forEach(callback => callback(response));
|
|
275
|
+
},
|
|
276
|
+
__leave() {
|
|
277
|
+
if (--this.count === 0)
|
|
278
|
+
this.finallyHandlers.forEach(callback => callback());
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
return ctx;
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
})();
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SetConfig = SetConfig;
|
|
3
4
|
exports.GetViewObject = GetViewObject;
|
|
4
|
-
|
|
5
|
+
const RpcClient_1 = require("./Library/RpcClient");
|
|
6
|
+
function SetConfig(url) {
|
|
7
|
+
RpcClient_1.RpcClient.config.url = url;
|
|
8
|
+
RpcClient_1.RpcClient.config.cors = true;
|
|
9
|
+
}
|
|
10
|
+
function GetViewObject(legislation, seller, buyer, properties, document, payments, ctx, cb) {
|
|
11
|
+
CallRT("GEI.EvaluateObject1", {
|
|
12
|
+
Legislation: legislation,
|
|
13
|
+
ReturnType: ["View"],
|
|
14
|
+
Seller: seller,
|
|
15
|
+
Buyer: buyer,
|
|
16
|
+
Properties: properties,
|
|
17
|
+
Document: document,
|
|
18
|
+
Payments: payments
|
|
19
|
+
}, ctx, cb);
|
|
5
20
|
}
|
|
6
21
|
function CallRT(method, params, ctx, cb) {
|
|
7
|
-
RpcClient.call(method, params)
|
|
22
|
+
RpcClient_1.RpcClient.call(method, params)
|
|
8
23
|
.done(function (response) {
|
|
9
24
|
console.log(response);
|
|
10
25
|
cb(response);
|
|
@@ -12,7 +27,7 @@ function CallRT(method, params, ctx, cb) {
|
|
|
12
27
|
.post(getStdRpcContext());
|
|
13
28
|
}
|
|
14
29
|
function getStdRpcContext() {
|
|
15
|
-
return RpcClient.context().onRpcError(function (e) {
|
|
30
|
+
return RpcClient_1.RpcClient.context().onRpcError(function (e) {
|
|
16
31
|
}).onDefaultApiError(function (e) {
|
|
17
32
|
}).onDefaultApiSuccess(function (res) {
|
|
18
33
|
});
|