forked from camptocamp/ogc-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
118 lines (109 loc) · 3.14 KB
/
utils.ts
File metadata and controls
118 lines (109 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { getUniqueId } from '../shared/id.js';
import { decodeError, encodeError } from '../shared/errors.js';
type TaskParams = Record<string, unknown>;
type TaskResponse = Record<string, unknown>;
export type WorkerRequest = {
requestId: number;
taskName: string;
params: TaskParams;
};
export type WorkerResponse = {
requestId: number;
error?: Record<string, unknown>;
response?: TaskResponse;
};
const fallbackEventTarget = new EventTarget(); // this will be used if no worker is available
export function sendTaskRequest<T>(
taskName: string,
workerInstance: Worker,
params: TaskParams
): Promise<T> {
return new Promise((resolve, reject) => {
const requestId = getUniqueId();
const request: WorkerRequest = {
requestId,
taskName,
params,
};
if (workerInstance === null) {
fallbackEventTarget.dispatchEvent(
new CustomEvent('ogc-client.request', {
detail: request,
})
);
} else {
workerInstance.postMessage(request);
}
const handler = (response: WorkerResponse) => {
if (response.requestId === requestId) {
if (workerInstance === null) {
fallbackEventTarget.removeEventListener(
'ogc-client.response',
windowHandler
);
} else {
workerInstance.removeEventListener('message', workerHandler);
}
if ('error' in response) {
reject(decodeError(response.error));
} else {
resolve(response.response as T);
}
}
};
const windowHandler = (event) => handler(event.detail);
const workerHandler = (event) => handler(event.data);
if (workerInstance === null) {
fallbackEventTarget.addEventListener(
'ogc-client.response',
windowHandler
);
} else {
workerInstance.addEventListener('message', workerHandler);
}
});
}
/**
* @param {string} taskName
* @param {DedicatedWorkerGlobalScope|Window} scope
* @param {function(params: Object):Promise<Object>} handler
*/
export function addTaskHandler(
taskName: string,
scope: DedicatedWorkerGlobalScope | Window | typeof globalThis,
handler: (params: TaskParams) => Promise<TaskResponse>
) {
const useWorker = typeof WorkerGlobalScope !== 'undefined';
const eventHandler = async (request: WorkerRequest) => {
if (request.taskName === taskName) {
let response, error;
try {
response = await handler(request.params);
} catch (e) {
error = encodeError(e);
}
const message = /** @type {WorkerResponse} */ {
taskName,
requestId: request.requestId,
...(response && { response }),
...(error && { error }),
};
if (useWorker) {
scope.postMessage(message);
} else {
fallbackEventTarget.dispatchEvent(
new CustomEvent('ogc-client.response', {
detail: message,
})
);
}
}
};
if (useWorker) {
scope.addEventListener('message', (event) => eventHandler(event.data));
} else {
fallbackEventTarget.addEventListener('ogc-client.request', (event) =>
eventHandler(event.detail)
);
}
}