@loaders.gl/core 5.0.0-alpha.5 → 5.0.0-alpha.7
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/dist/dist.dev.js +398 -49
- package/dist/dist.min.js +3 -3
- package/dist/index.cjs +405 -51
- package/dist/index.cjs.map +3 -3
- package/dist/lib/api/parse-in-batches.d.ts.map +1 -1
- package/dist/lib/api/parse-in-batches.js +6 -2
- package/dist/lib/api/parse-in-batches.js.map +1 -1
- package/dist/lib/api/parse.js +2 -2
- package/dist/lib/api/parse.js.map +1 -1
- package/dist/lib/init.js +1 -1
- package/dist/lib/loader-utils/get-fetch-function.d.ts.map +1 -1
- package/dist/lib/loader-utils/get-fetch-function.js +2 -1
- package/dist/lib/loader-utils/get-fetch-function.js.map +1 -1
- package/dist/lib/loader-utils/loader-context.d.ts +1 -1
- package/dist/lib/loader-utils/loader-context.d.ts.map +1 -1
- package/dist/lib/loader-utils/loader-context.js +6 -3
- package/dist/lib/loader-utils/loader-context.js.map +1 -1
- package/dist/lib/loader-utils/option-defaults.d.ts.map +1 -1
- package/dist/lib/loader-utils/option-defaults.js +1 -0
- package/dist/lib/loader-utils/option-defaults.js.map +1 -1
- package/dist/lib/loader-utils/option-utils.d.ts.map +1 -1
- package/dist/lib/loader-utils/option-utils.js +12 -1
- package/dist/lib/loader-utils/option-utils.js.map +1 -1
- package/dist/null-loader.js +1 -1
- package/dist/null-worker-node.js +29 -3
- package/dist/null-worker.js +29 -3
- package/package.json +6 -6
- package/src/lib/api/parse-in-batches.ts +11 -2
- package/src/lib/api/parse.ts +2 -2
- package/src/lib/loader-utils/get-fetch-function.ts +2 -1
- package/src/lib/loader-utils/loader-context.ts +6 -3
- package/src/lib/loader-utils/option-defaults.ts +1 -0
- package/src/lib/loader-utils/option-utils.ts +13 -1
package/dist/dist.dev.js
CHANGED
|
@@ -925,6 +925,10 @@ var __exports__ = (() => {
|
|
|
925
925
|
name;
|
|
926
926
|
source;
|
|
927
927
|
url;
|
|
928
|
+
/** Lazily resolves the classic worker URL used as a fallback. */
|
|
929
|
+
getUrl;
|
|
930
|
+
/** Creates a browser Worker directly. */
|
|
931
|
+
loadWorker;
|
|
928
932
|
terminated = false;
|
|
929
933
|
worker;
|
|
930
934
|
onMessage;
|
|
@@ -935,11 +939,13 @@ var __exports__ = (() => {
|
|
|
935
939
|
return typeof Worker !== "undefined" && isBrowser3 || typeof NodeWorker !== "undefined" && !isBrowser3;
|
|
936
940
|
}
|
|
937
941
|
constructor(props) {
|
|
938
|
-
const { name, source, url } = props;
|
|
939
|
-
assert3(source || url);
|
|
942
|
+
const { name, source, url, getUrl, loadWorker } = props;
|
|
943
|
+
assert3(source || url || getUrl || loadWorker);
|
|
940
944
|
this.name = name;
|
|
941
945
|
this.source = source;
|
|
942
946
|
this.url = url;
|
|
947
|
+
this.getUrl = getUrl;
|
|
948
|
+
this.loadWorker = loadWorker;
|
|
943
949
|
this.onMessage = NOOP;
|
|
944
950
|
this.onError = (error) => console.log(error);
|
|
945
951
|
this.worker = isBrowser3 ? this._createBrowserWorker() : this._createNodeWorker();
|
|
@@ -985,7 +991,7 @@ var __exports__ = (() => {
|
|
|
985
991
|
*/
|
|
986
992
|
_getErrorFromErrorEvent(event) {
|
|
987
993
|
let message = "Failed to load ";
|
|
988
|
-
message += `worker ${this.name} from ${this.url}. `;
|
|
994
|
+
message += `worker ${this.name} from ${this.url || "built-in worker factory"}. `;
|
|
989
995
|
if (event.message) {
|
|
990
996
|
message += `${event.message} in `;
|
|
991
997
|
}
|
|
@@ -998,8 +1004,25 @@ var __exports__ = (() => {
|
|
|
998
1004
|
* Creates a worker thread on the browser
|
|
999
1005
|
*/
|
|
1000
1006
|
_createBrowserWorker() {
|
|
1001
|
-
|
|
1007
|
+
if (this.loadWorker) {
|
|
1008
|
+
try {
|
|
1009
|
+
const worker2 = this.loadWorker();
|
|
1010
|
+
if (worker2) {
|
|
1011
|
+
return this._initializeBrowserWorker(worker2);
|
|
1012
|
+
}
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
if (!this.source && !this.url && !this.getUrl) {
|
|
1015
|
+
throw error;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
const url = this.url || this.getUrl?.();
|
|
1020
|
+
this._loadableURL = getLoadableWorkerURL({ source: this.source, url });
|
|
1002
1021
|
const worker = new Worker(this._loadableURL, { name: this.name });
|
|
1022
|
+
return this._initializeBrowserWorker(worker);
|
|
1023
|
+
}
|
|
1024
|
+
/** Attaches protocol handlers to a browser worker. */
|
|
1025
|
+
_initializeBrowserWorker(worker) {
|
|
1003
1026
|
worker.onmessage = (event) => {
|
|
1004
1027
|
if (!event.data) {
|
|
1005
1028
|
this.onError(new Error("No data received"));
|
|
@@ -1049,6 +1072,10 @@ var __exports__ = (() => {
|
|
|
1049
1072
|
source;
|
|
1050
1073
|
// | Function;
|
|
1051
1074
|
url;
|
|
1075
|
+
/** Lazily resolves a classic worker fallback URL. */
|
|
1076
|
+
getUrl;
|
|
1077
|
+
/** Creates a browser Worker directly. */
|
|
1078
|
+
loadWorker;
|
|
1052
1079
|
maxConcurrency = 1;
|
|
1053
1080
|
maxMobileConcurrency = 1;
|
|
1054
1081
|
onDebug = () => {
|
|
@@ -1057,6 +1084,7 @@ var __exports__ = (() => {
|
|
|
1057
1084
|
props = {};
|
|
1058
1085
|
jobQueue = [];
|
|
1059
1086
|
idleQueue = [];
|
|
1087
|
+
activeJobs = /* @__PURE__ */ new Set();
|
|
1060
1088
|
count = 0;
|
|
1061
1089
|
isDestroyed = false;
|
|
1062
1090
|
/** Checks if workers are supported on this platform */
|
|
@@ -1070,13 +1098,19 @@ var __exports__ = (() => {
|
|
|
1070
1098
|
constructor(props) {
|
|
1071
1099
|
this.source = props.source;
|
|
1072
1100
|
this.url = props.url;
|
|
1101
|
+
this.getUrl = props.getUrl;
|
|
1102
|
+
this.loadWorker = props.loadWorker;
|
|
1073
1103
|
this.setProps(props);
|
|
1074
1104
|
}
|
|
1075
1105
|
/**
|
|
1076
|
-
* Terminates all workers in the pool
|
|
1106
|
+
* Terminates all workers in the pool and aborts active jobs.
|
|
1107
|
+
* @param reason Optional error delivered to active jobs.
|
|
1077
1108
|
* @note Can free up significant memory
|
|
1078
1109
|
*/
|
|
1079
|
-
destroy() {
|
|
1110
|
+
destroy(reason = new Error("Worker pool was destroyed")) {
|
|
1111
|
+
this.activeJobs.forEach((job) => job.abort(reason));
|
|
1112
|
+
const queuedJobs = this.jobQueue.splice(0);
|
|
1113
|
+
queuedJobs.forEach((queuedJob) => queuedJob.onReject(reason));
|
|
1080
1114
|
this.idleQueue.forEach((worker) => worker.destroy());
|
|
1081
1115
|
this.isDestroyed = true;
|
|
1082
1116
|
}
|
|
@@ -1099,8 +1133,11 @@ var __exports__ = (() => {
|
|
|
1099
1133
|
}
|
|
1100
1134
|
}
|
|
1101
1135
|
async startJob(name, onMessage2 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
|
|
1102
|
-
|
|
1103
|
-
|
|
1136
|
+
if (this.isDestroyed) {
|
|
1137
|
+
return Promise.reject(new Error("Worker pool was destroyed"));
|
|
1138
|
+
}
|
|
1139
|
+
const startPromise = new Promise((onStart, onReject) => {
|
|
1140
|
+
this.jobQueue.push({ name, onMessage: onMessage2, onError, onStart, onReject });
|
|
1104
1141
|
return this;
|
|
1105
1142
|
});
|
|
1106
1143
|
this._startQueuedJob();
|
|
@@ -1128,6 +1165,7 @@ var __exports__ = (() => {
|
|
|
1128
1165
|
backlog: this.jobQueue.length
|
|
1129
1166
|
});
|
|
1130
1167
|
const job = new WorkerJob(queuedJob.name, workerThread);
|
|
1168
|
+
this.activeJobs.add(job);
|
|
1131
1169
|
workerThread.ref();
|
|
1132
1170
|
workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload);
|
|
1133
1171
|
workerThread.onError = (error) => queuedJob.onError(job, error);
|
|
@@ -1136,6 +1174,7 @@ var __exports__ = (() => {
|
|
|
1136
1174
|
await job.result;
|
|
1137
1175
|
} catch {
|
|
1138
1176
|
} finally {
|
|
1177
|
+
this.activeJobs.delete(job);
|
|
1139
1178
|
this.returnWorkerToQueue(workerThread);
|
|
1140
1179
|
}
|
|
1141
1180
|
}
|
|
@@ -1179,7 +1218,13 @@ var __exports__ = (() => {
|
|
|
1179
1218
|
if (this.count < this._getMaxConcurrency()) {
|
|
1180
1219
|
this.count++;
|
|
1181
1220
|
const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`;
|
|
1182
|
-
return new WorkerThread({
|
|
1221
|
+
return new WorkerThread({
|
|
1222
|
+
name,
|
|
1223
|
+
source: this.source,
|
|
1224
|
+
url: this.url,
|
|
1225
|
+
getUrl: this.getUrl,
|
|
1226
|
+
loadWorker: this.loadWorker
|
|
1227
|
+
});
|
|
1183
1228
|
}
|
|
1184
1229
|
return null;
|
|
1185
1230
|
}
|
|
@@ -1196,6 +1241,8 @@ var __exports__ = (() => {
|
|
|
1196
1241
|
onDebug: () => {
|
|
1197
1242
|
}
|
|
1198
1243
|
};
|
|
1244
|
+
var loadWorkerIds = /* @__PURE__ */ new WeakMap();
|
|
1245
|
+
var nextLoadWorkerId = 1;
|
|
1199
1246
|
var WorkerFarm = class _WorkerFarm {
|
|
1200
1247
|
props;
|
|
1201
1248
|
workerPools = /* @__PURE__ */ new Map();
|
|
@@ -1218,12 +1265,13 @@ var __exports__ = (() => {
|
|
|
1218
1265
|
this.workerPools = /* @__PURE__ */ new Map();
|
|
1219
1266
|
}
|
|
1220
1267
|
/**
|
|
1221
|
-
* Terminate all workers in the farm
|
|
1268
|
+
* Terminate all workers in the farm and abort active jobs.
|
|
1269
|
+
* @param reason Optional error delivered to active jobs.
|
|
1222
1270
|
* @note Can free up significant memory
|
|
1223
1271
|
*/
|
|
1224
|
-
destroy() {
|
|
1272
|
+
destroy(reason) {
|
|
1225
1273
|
for (const workerPool of this.workerPools.values()) {
|
|
1226
|
-
workerPool.destroy();
|
|
1274
|
+
workerPool.destroy(reason);
|
|
1227
1275
|
}
|
|
1228
1276
|
this.workerPools = /* @__PURE__ */ new Map();
|
|
1229
1277
|
}
|
|
@@ -1239,24 +1287,28 @@ var __exports__ = (() => {
|
|
|
1239
1287
|
}
|
|
1240
1288
|
/**
|
|
1241
1289
|
* Returns a worker pool for the specified worker
|
|
1242
|
-
* @param options
|
|
1243
|
-
* @param options.name
|
|
1244
|
-
* @param options.url
|
|
1245
|
-
* @param options.source
|
|
1290
|
+
* @param options Worker target used to identify and initialize the pool.
|
|
1291
|
+
* @param options.name Worker name used as the base pool identity.
|
|
1292
|
+
* @param options.url Worker script URL.
|
|
1293
|
+
* @param options.source Inline worker source.
|
|
1294
|
+
* @param options.loadWorker Built-in browser worker factory.
|
|
1246
1295
|
* @example
|
|
1247
1296
|
* const job = WorkerFarm.getWorkerFarm().getWorkerPool({name, url}).startJob(...);
|
|
1248
1297
|
*/
|
|
1249
1298
|
getWorkerPool(options) {
|
|
1250
|
-
const { name, source, url } = options;
|
|
1251
|
-
|
|
1299
|
+
const { name, source, url, getUrl, loadWorker } = options;
|
|
1300
|
+
const workerPoolKey = getWorkerPoolKey(options);
|
|
1301
|
+
let workerPool = this.workerPools.get(workerPoolKey);
|
|
1252
1302
|
if (!workerPool) {
|
|
1253
1303
|
workerPool = new WorkerPool({
|
|
1254
1304
|
name,
|
|
1255
1305
|
source,
|
|
1256
|
-
url
|
|
1306
|
+
url,
|
|
1307
|
+
getUrl,
|
|
1308
|
+
loadWorker
|
|
1257
1309
|
});
|
|
1258
1310
|
workerPool.setProps(this._getWorkerPoolProps());
|
|
1259
|
-
this.workerPools.set(
|
|
1311
|
+
this.workerPools.set(workerPoolKey, workerPool);
|
|
1260
1312
|
}
|
|
1261
1313
|
return workerPool;
|
|
1262
1314
|
}
|
|
@@ -1269,6 +1321,91 @@ var __exports__ = (() => {
|
|
|
1269
1321
|
};
|
|
1270
1322
|
}
|
|
1271
1323
|
};
|
|
1324
|
+
function getWorkerPoolKey(options) {
|
|
1325
|
+
const { name, source, url, urlKey, loadWorker } = options;
|
|
1326
|
+
const sourceKey = source ? `source:${source}` : "";
|
|
1327
|
+
const urlKeyPart = url || urlKey ? `url:${url || urlKey}` : "";
|
|
1328
|
+
const loadWorkerKey = loadWorker ? `loadWorker:${getLoadWorkerId(loadWorker)}` : "";
|
|
1329
|
+
return [name, sourceKey, urlKeyPart, loadWorkerKey].filter(Boolean).join("|");
|
|
1330
|
+
}
|
|
1331
|
+
function getLoadWorkerId(loadWorker) {
|
|
1332
|
+
let loadWorkerId = loadWorkerIds.get(loadWorker);
|
|
1333
|
+
if (!loadWorkerId) {
|
|
1334
|
+
loadWorkerId = nextLoadWorkerId++;
|
|
1335
|
+
loadWorkerIds.set(loadWorker, loadWorkerId);
|
|
1336
|
+
}
|
|
1337
|
+
return loadWorkerId;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
// ../worker-utils/src/lib/async-queue/async-queue.ts
|
|
1341
|
+
var AsyncQueue = class {
|
|
1342
|
+
_values;
|
|
1343
|
+
_settlers;
|
|
1344
|
+
_closed;
|
|
1345
|
+
constructor() {
|
|
1346
|
+
this._values = [];
|
|
1347
|
+
this._settlers = [];
|
|
1348
|
+
this._closed = false;
|
|
1349
|
+
}
|
|
1350
|
+
/** Return an async iterator for this queue */
|
|
1351
|
+
[Symbol.asyncIterator]() {
|
|
1352
|
+
return this;
|
|
1353
|
+
}
|
|
1354
|
+
/** Push a new value - the async iterator will yield a promise resolved to this value */
|
|
1355
|
+
push(value) {
|
|
1356
|
+
return this.enqueue(value);
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* Push a new value - the async iterator will yield a promise resolved to this value
|
|
1360
|
+
* Add an error - the async iterator will yield a promise rejected with this value
|
|
1361
|
+
*/
|
|
1362
|
+
enqueue(value) {
|
|
1363
|
+
if (this._closed) {
|
|
1364
|
+
throw new Error("Closed");
|
|
1365
|
+
}
|
|
1366
|
+
if (this._settlers.length > 0) {
|
|
1367
|
+
if (this._values.length > 0) {
|
|
1368
|
+
throw new Error("Illegal internal state");
|
|
1369
|
+
}
|
|
1370
|
+
const settler = this._settlers.shift();
|
|
1371
|
+
if (value instanceof Error) {
|
|
1372
|
+
settler.reject(value);
|
|
1373
|
+
} else {
|
|
1374
|
+
settler.resolve({ value });
|
|
1375
|
+
}
|
|
1376
|
+
} else {
|
|
1377
|
+
this._values.push(value);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
/** Indicate that we not waiting for more values - The async iterator will be done */
|
|
1381
|
+
close() {
|
|
1382
|
+
while (this._settlers.length > 0) {
|
|
1383
|
+
const settler = this._settlers.shift();
|
|
1384
|
+
settler.resolve({ done: true });
|
|
1385
|
+
}
|
|
1386
|
+
this._closed = true;
|
|
1387
|
+
}
|
|
1388
|
+
// ITERATOR IMPLEMENTATION
|
|
1389
|
+
/** @returns a Promise for an IteratorResult */
|
|
1390
|
+
next() {
|
|
1391
|
+
if (this._values.length > 0) {
|
|
1392
|
+
const value = this._values.shift();
|
|
1393
|
+
if (value instanceof Error) {
|
|
1394
|
+
return Promise.reject(value);
|
|
1395
|
+
}
|
|
1396
|
+
return Promise.resolve({ done: false, value });
|
|
1397
|
+
}
|
|
1398
|
+
if (this._closed) {
|
|
1399
|
+
if (this._settlers.length > 0) {
|
|
1400
|
+
throw new Error("Illegal internal state");
|
|
1401
|
+
}
|
|
1402
|
+
return Promise.resolve({ done: true, value: void 0 });
|
|
1403
|
+
}
|
|
1404
|
+
return new Promise((resolve2, reject) => {
|
|
1405
|
+
this._settlers.push({ resolve: resolve2, reject });
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1272
1409
|
|
|
1273
1410
|
// ../worker-utils/src/lib/worker-api/get-worker-url.ts
|
|
1274
1411
|
var warnedWorkerVersionFallbacks = /* @__PURE__ */ new Set();
|
|
@@ -1276,34 +1413,41 @@ var __exports__ = (() => {
|
|
|
1276
1413
|
const warning = worker.version !== VERSION3 ? ` (worker-utils@${VERSION3})` : "";
|
|
1277
1414
|
return `${worker.name}@${worker.version}${warning}`;
|
|
1278
1415
|
}
|
|
1279
|
-
function
|
|
1416
|
+
function getCustomWorkerURL(worker, options = {}) {
|
|
1280
1417
|
const workerOptions = options[worker.id] || {};
|
|
1281
|
-
const workerFile = isBrowser3 ? `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
|
|
1418
|
+
const workerFile = isBrowser3 ? worker.workerFile || `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
|
|
1282
1419
|
let url = workerOptions.workerUrl;
|
|
1283
|
-
if (!url && typeof worker.worker === "string") {
|
|
1284
|
-
url = worker.worker;
|
|
1285
|
-
}
|
|
1286
1420
|
if (!url && worker.id === "compression") {
|
|
1287
1421
|
url = options.workerUrl;
|
|
1288
1422
|
}
|
|
1289
1423
|
const workerType = options._workerType || options?.core?._workerType;
|
|
1290
|
-
if (workerType === "test") {
|
|
1424
|
+
if (!url && workerType === "test") {
|
|
1291
1425
|
if (isBrowser3) {
|
|
1292
1426
|
url = `modules/${worker.module}/dist/${workerFile}`;
|
|
1293
1427
|
} else {
|
|
1294
1428
|
url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`;
|
|
1295
1429
|
}
|
|
1296
1430
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1431
|
+
return url || null;
|
|
1432
|
+
}
|
|
1433
|
+
function getWorkerURL(worker, options = {}) {
|
|
1434
|
+
const customWorkerUrl = getCustomWorkerURL(worker, options);
|
|
1435
|
+
const descriptorWorkerUrl = typeof worker.worker === "string" ? worker.worker : null;
|
|
1436
|
+
const url = customWorkerUrl || descriptorWorkerUrl || getDefaultWorkerURL(worker, true);
|
|
1437
|
+
assert3(url);
|
|
1438
|
+
return url;
|
|
1439
|
+
}
|
|
1440
|
+
function getDefaultWorkerURL(worker, warn = false) {
|
|
1441
|
+
const workerFile = isBrowser3 ? worker.workerFile || `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
|
|
1442
|
+
let version2 = worker.version;
|
|
1443
|
+
if (version2 === "latest") {
|
|
1444
|
+
version2 = NPM_TAG;
|
|
1445
|
+
}
|
|
1446
|
+
const versionTag = version2 ? `@${version2}` : "";
|
|
1447
|
+
const url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
|
|
1448
|
+
if (warn) {
|
|
1304
1449
|
warnIfUsingNpmTagFallback(worker, url);
|
|
1305
1450
|
}
|
|
1306
|
-
assert3(url);
|
|
1307
1451
|
return url;
|
|
1308
1452
|
}
|
|
1309
1453
|
function warnIfUsingNpmTagFallback(worker, url) {
|
|
@@ -1326,18 +1470,15 @@ var __exports__ = (() => {
|
|
|
1326
1470
|
return false;
|
|
1327
1471
|
}
|
|
1328
1472
|
const workerOptions = options?.[worker.id];
|
|
1329
|
-
return Boolean(
|
|
1473
|
+
return Boolean(
|
|
1474
|
+
(worker.worker || worker.loadWorker || workerOptions?.workerUrl) && options?.worker
|
|
1475
|
+
);
|
|
1330
1476
|
}
|
|
1331
1477
|
async function processOnWorker(worker, data, options = {}, context = {}, jobContext = {}) {
|
|
1332
1478
|
throwIfAborted(options.signal);
|
|
1333
1479
|
const name = getWorkerName(worker);
|
|
1334
1480
|
const workerFarm = WorkerFarm.getWorkerFarm(options);
|
|
1335
|
-
const
|
|
1336
|
-
const workerPoolProps = { name, source };
|
|
1337
|
-
if (!source) {
|
|
1338
|
-
workerPoolProps.url = getWorkerURL(worker, options);
|
|
1339
|
-
}
|
|
1340
|
-
const workerPool = workerFarm.getWorkerPool(workerPoolProps);
|
|
1481
|
+
const workerPool = workerFarm.getWorkerPool(getWorkerPoolTarget(worker, options, name));
|
|
1341
1482
|
const jobName = options.jobName || worker.name;
|
|
1342
1483
|
const job = await workerPool.startJob(
|
|
1343
1484
|
jobName,
|
|
@@ -1366,6 +1507,114 @@ var __exports__ = (() => {
|
|
|
1366
1507
|
options.signal?.removeEventListener("abort", abortJob);
|
|
1367
1508
|
}
|
|
1368
1509
|
}
|
|
1510
|
+
function processOnWorkerInBatches(worker, input, options = {}, context = {}, jobContext = {}) {
|
|
1511
|
+
return processOnWorkerInBatchesIterator(worker, input, options, context, jobContext);
|
|
1512
|
+
}
|
|
1513
|
+
async function* processOnWorkerInBatchesIterator(worker, input, options, context, jobContext) {
|
|
1514
|
+
throwIfAborted(options.signal);
|
|
1515
|
+
const name = getWorkerName(worker);
|
|
1516
|
+
const workerFarm = WorkerFarm.getWorkerFarm(options);
|
|
1517
|
+
const workerPool = workerFarm.getWorkerPool(getWorkerPoolTarget(worker, options, name));
|
|
1518
|
+
const outputBatches = new AsyncQueue();
|
|
1519
|
+
const inputIterator = getAsyncIterator(input);
|
|
1520
|
+
let outputFinished = false;
|
|
1521
|
+
let inputFinished = false;
|
|
1522
|
+
let inputRequest = Promise.resolve();
|
|
1523
|
+
const batchJobFailed = new Error("Worker batch job failed");
|
|
1524
|
+
const finishOutput = () => {
|
|
1525
|
+
if (!outputFinished) {
|
|
1526
|
+
outputFinished = true;
|
|
1527
|
+
outputBatches.close();
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
const failOutput = (_error) => {
|
|
1531
|
+
if (!outputFinished) {
|
|
1532
|
+
outputFinished = true;
|
|
1533
|
+
outputBatches.enqueue(batchJobFailed);
|
|
1534
|
+
outputBatches.close();
|
|
1535
|
+
}
|
|
1536
|
+
};
|
|
1537
|
+
const job = await workerPool.startJob(
|
|
1538
|
+
options.jobName || worker.name,
|
|
1539
|
+
(activeJob, type, payload) => {
|
|
1540
|
+
switch (type) {
|
|
1541
|
+
case "input-request":
|
|
1542
|
+
inputRequest = inputRequest.then(async () => {
|
|
1543
|
+
const nextBatch = await inputIterator.next();
|
|
1544
|
+
if (!activeJob.isRunning) {
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
if (nextBatch.done) {
|
|
1548
|
+
inputFinished = true;
|
|
1549
|
+
activeJob.postMessage("input-done", {});
|
|
1550
|
+
} else {
|
|
1551
|
+
activeJob.postMessage("input-batch", { input: nextBatch.value });
|
|
1552
|
+
}
|
|
1553
|
+
}).catch((error) => activeJob.abort(error));
|
|
1554
|
+
break;
|
|
1555
|
+
case "output-batch":
|
|
1556
|
+
outputBatches.push(payload.result);
|
|
1557
|
+
break;
|
|
1558
|
+
case "done":
|
|
1559
|
+
activeJob.done(payload);
|
|
1560
|
+
finishOutput();
|
|
1561
|
+
break;
|
|
1562
|
+
case "error": {
|
|
1563
|
+
const error = new Error(payload.error || "Worker batch processing failed");
|
|
1564
|
+
activeJob.error(error);
|
|
1565
|
+
failOutput(error);
|
|
1566
|
+
break;
|
|
1567
|
+
}
|
|
1568
|
+
case "process":
|
|
1569
|
+
void onMessage(context, activeJob, type, payload);
|
|
1570
|
+
break;
|
|
1571
|
+
default: {
|
|
1572
|
+
const error = new Error(`Unexpected worker batch message: ${type}`);
|
|
1573
|
+
activeJob.error(error);
|
|
1574
|
+
failOutput(error);
|
|
1575
|
+
break;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
);
|
|
1580
|
+
const abortJob = () => job.abort(getAbortReason(options.signal));
|
|
1581
|
+
options.signal?.addEventListener("abort", abortJob, { once: true });
|
|
1582
|
+
if (options.signal?.aborted) {
|
|
1583
|
+
abortJob();
|
|
1584
|
+
}
|
|
1585
|
+
void job.result.catch(failOutput);
|
|
1586
|
+
try {
|
|
1587
|
+
const { signal: _signal, ...workerOptions } = options;
|
|
1588
|
+
if (job.isRunning) {
|
|
1589
|
+
job.postMessage("process-in-batches", {
|
|
1590
|
+
options: getTransferListForWriter(workerOptions),
|
|
1591
|
+
context: getTransferListForWriter(jobContext)
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
try {
|
|
1595
|
+
for await (const outputBatch of outputBatches) {
|
|
1596
|
+
yield outputBatch;
|
|
1597
|
+
if (job.isRunning) {
|
|
1598
|
+
job.postMessage("output-ack", {});
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
} catch (error) {
|
|
1602
|
+
if (error === batchJobFailed) {
|
|
1603
|
+
await job.result;
|
|
1604
|
+
}
|
|
1605
|
+
throw error;
|
|
1606
|
+
}
|
|
1607
|
+
await job.result;
|
|
1608
|
+
} finally {
|
|
1609
|
+
options.signal?.removeEventListener("abort", abortJob);
|
|
1610
|
+
if (job.isRunning) {
|
|
1611
|
+
job.abort(createAbortError2("Worker batch iterator was closed"));
|
|
1612
|
+
}
|
|
1613
|
+
if (!inputFinished) {
|
|
1614
|
+
closeInputIterator(inputIterator);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1369
1618
|
function throwIfAborted(signal) {
|
|
1370
1619
|
if (!signal?.aborted) {
|
|
1371
1620
|
return;
|
|
@@ -1380,6 +1629,38 @@ var __exports__ = (() => {
|
|
|
1380
1629
|
error.name = "AbortError";
|
|
1381
1630
|
return error;
|
|
1382
1631
|
}
|
|
1632
|
+
function getAsyncIterator(input) {
|
|
1633
|
+
if (Symbol.asyncIterator in input) {
|
|
1634
|
+
return input[Symbol.asyncIterator]();
|
|
1635
|
+
}
|
|
1636
|
+
return (async function* iterateSynchronously() {
|
|
1637
|
+
yield* input;
|
|
1638
|
+
})();
|
|
1639
|
+
}
|
|
1640
|
+
function closeInputIterator(inputIterator) {
|
|
1641
|
+
try {
|
|
1642
|
+
void Promise.resolve(inputIterator.return?.()).catch(() => void 0);
|
|
1643
|
+
} catch {
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
function getWorkerPoolTarget(worker, options, name) {
|
|
1647
|
+
if (options.source) {
|
|
1648
|
+
return { name, source: options.source };
|
|
1649
|
+
}
|
|
1650
|
+
const customWorkerUrl = getCustomWorkerURL(worker, options);
|
|
1651
|
+
if (customWorkerUrl) {
|
|
1652
|
+
return { name, url: customWorkerUrl };
|
|
1653
|
+
}
|
|
1654
|
+
if (isBrowser3 && worker.loadWorker) {
|
|
1655
|
+
return {
|
|
1656
|
+
name,
|
|
1657
|
+
loadWorker: worker.loadWorker,
|
|
1658
|
+
getUrl: () => getWorkerURL(worker, options),
|
|
1659
|
+
urlKey: getDefaultWorkerURL(worker)
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
return { name, url: getWorkerURL(worker, options) };
|
|
1663
|
+
}
|
|
1383
1664
|
async function onMessage(context, job, type, payload) {
|
|
1384
1665
|
switch (type) {
|
|
1385
1666
|
case "done":
|
|
@@ -1424,7 +1705,7 @@ var __exports__ = (() => {
|
|
|
1424
1705
|
if (!isBrowser3 && !nodeWorkers) {
|
|
1425
1706
|
return false;
|
|
1426
1707
|
}
|
|
1427
|
-
if (loader.id === "
|
|
1708
|
+
if (loader.id === "las" && (options?.las?.shape ?? "arrow-table") === "arrow-table") {
|
|
1428
1709
|
return false;
|
|
1429
1710
|
}
|
|
1430
1711
|
if (loader.id === "csv" && !shouldParseCSVWithWorker(options)) {
|
|
@@ -1432,12 +1713,29 @@ var __exports__ = (() => {
|
|
|
1432
1713
|
}
|
|
1433
1714
|
return Boolean(canProcessOnWorker(loader, workerOptions));
|
|
1434
1715
|
}
|
|
1716
|
+
function shouldParseWithWorker(loader, data, options, context, estimateLoader = loader) {
|
|
1717
|
+
if (!canParseWithWorker(loader, options)) {
|
|
1718
|
+
return false;
|
|
1719
|
+
}
|
|
1720
|
+
if (options?.core?.worker !== "auto" || !estimateLoader.getWorkerEstimate) {
|
|
1721
|
+
return true;
|
|
1722
|
+
}
|
|
1723
|
+
try {
|
|
1724
|
+
const estimate = estimateLoader.getWorkerEstimate(data, options, context);
|
|
1725
|
+
if (estimate === void 0 || !Number.isFinite(estimate) || estimate < 0 || estimate > 1) {
|
|
1726
|
+
return true;
|
|
1727
|
+
}
|
|
1728
|
+
return estimate >= (options.core?.workerThreshold ?? 0.1);
|
|
1729
|
+
} catch {
|
|
1730
|
+
return true;
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1435
1733
|
async function parseWithWorker(loader, data, options, context, parseOnMainThread, signal) {
|
|
1436
1734
|
const workerSignal = signal || getWorkerAbortSignal(options);
|
|
1437
1735
|
const result = await processOnWorker(
|
|
1438
1736
|
loader,
|
|
1439
1737
|
data,
|
|
1440
|
-
{ ...getWorkerOptions(options), signal: workerSignal },
|
|
1738
|
+
{ ...getWorkerOptions(options, loader), signal: workerSignal },
|
|
1441
1739
|
{
|
|
1442
1740
|
process: async (input, processOptions, _workerContext, parseContext) => {
|
|
1443
1741
|
if (!parseOnMainThread) {
|
|
@@ -1456,6 +1754,32 @@ var __exports__ = (() => {
|
|
|
1456
1754
|
);
|
|
1457
1755
|
return isLoaderWithWorkerResultDeserializer(loader) ? loader.deserializeWorkerResult(result, options, context) : result;
|
|
1458
1756
|
}
|
|
1757
|
+
async function* parseWithWorkerInBatches(loader, inputIterator, options, context, parseOnMainThread, signal) {
|
|
1758
|
+
const workerSignal = signal || getWorkerAbortSignal(options);
|
|
1759
|
+
const outputIterator = processOnWorkerInBatches(
|
|
1760
|
+
loader,
|
|
1761
|
+
inputIterator,
|
|
1762
|
+
{ ...getWorkerOptions(options), signal: workerSignal },
|
|
1763
|
+
{
|
|
1764
|
+
process: async (input, processOptions, _workerContext, parseContext) => {
|
|
1765
|
+
if (!parseOnMainThread) {
|
|
1766
|
+
throw new Error("Worker not set up to parse on main thread");
|
|
1767
|
+
}
|
|
1768
|
+
const mainThreadContext = context ? { ...context, ...parseContext || {} } : void 0;
|
|
1769
|
+
return await callParseOnMainThread(
|
|
1770
|
+
parseOnMainThread,
|
|
1771
|
+
input,
|
|
1772
|
+
processOptions,
|
|
1773
|
+
mainThreadContext
|
|
1774
|
+
);
|
|
1775
|
+
}
|
|
1776
|
+
},
|
|
1777
|
+
getSerializableLoaderContext(context)
|
|
1778
|
+
);
|
|
1779
|
+
for await (const batch of outputIterator) {
|
|
1780
|
+
yield loader.deserializeWorkerBatch ? loader.deserializeWorkerBatch(batch, options, context) : batch;
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1459
1783
|
function getWorkerAbortSignal(options) {
|
|
1460
1784
|
const parquetSignal = options?.parquet?.signal;
|
|
1461
1785
|
if (typeof AbortSignal !== "undefined" && parquetSignal instanceof AbortSignal) {
|
|
@@ -1469,12 +1793,19 @@ var __exports__ = (() => {
|
|
|
1469
1793
|
}
|
|
1470
1794
|
return parseOnMainThread(input, void 0, options, context);
|
|
1471
1795
|
}
|
|
1472
|
-
function getWorkerOptions(options = {}) {
|
|
1796
|
+
function getWorkerOptions(options = {}, loader) {
|
|
1473
1797
|
const serializedOptions = JSON.parse(JSON.stringify(options));
|
|
1474
|
-
|
|
1798
|
+
const workerOptions = {
|
|
1475
1799
|
...serializedOptions.core,
|
|
1476
1800
|
...serializedOptions
|
|
1477
1801
|
};
|
|
1802
|
+
if (workerOptions.worker === "auto") {
|
|
1803
|
+
workerOptions.worker = true;
|
|
1804
|
+
}
|
|
1805
|
+
if (loader) {
|
|
1806
|
+
workerOptions._workerLoaderId = loader.id;
|
|
1807
|
+
}
|
|
1808
|
+
return workerOptions;
|
|
1478
1809
|
}
|
|
1479
1810
|
function getSerializableLoaderContext(context) {
|
|
1480
1811
|
if (!context) {
|
|
@@ -2728,6 +3059,7 @@ var __exports__ = (() => {
|
|
|
2728
3059
|
CDN: "https://unpkg.com/@loaders.gl",
|
|
2729
3060
|
worker: true,
|
|
2730
3061
|
// By default, use worker if provided by loader.
|
|
3062
|
+
workerThreshold: 0.1,
|
|
2731
3063
|
maxConcurrency: 3,
|
|
2732
3064
|
// How many worker instances should be created for each loader.
|
|
2733
3065
|
maxMobileConcurrency: 1,
|
|
@@ -2803,6 +3135,7 @@ var __exports__ = (() => {
|
|
|
2803
3135
|
"useLocalLibraries",
|
|
2804
3136
|
"CDN",
|
|
2805
3137
|
"worker",
|
|
3138
|
+
"workerThreshold",
|
|
2806
3139
|
"maxConcurrency",
|
|
2807
3140
|
"maxMobileConcurrency",
|
|
2808
3141
|
"reuseWorkers",
|
|
@@ -2843,7 +3176,10 @@ var __exports__ = (() => {
|
|
|
2843
3176
|
loaders = loaders || [];
|
|
2844
3177
|
loaders = Array.isArray(loaders) ? loaders : [loaders];
|
|
2845
3178
|
validateOptions(options, loaders);
|
|
2846
|
-
|
|
3179
|
+
validateWorkerThreshold(options);
|
|
3180
|
+
const normalizedOptions = normalizeLoaderOptions(normalizeOptionsInternal(loader, options, url));
|
|
3181
|
+
validateWorkerThreshold(normalizedOptions);
|
|
3182
|
+
return normalizedOptions;
|
|
2847
3183
|
}
|
|
2848
3184
|
function normalizeLoaderOptions(options) {
|
|
2849
3185
|
const normalized = cloneLoaderOptions(options);
|
|
@@ -2867,6 +3203,12 @@ var __exports__ = (() => {
|
|
|
2867
3203
|
validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders);
|
|
2868
3204
|
}
|
|
2869
3205
|
}
|
|
3206
|
+
function validateWorkerThreshold(options) {
|
|
3207
|
+
const threshold = options.core?.workerThreshold;
|
|
3208
|
+
if (threshold !== void 0 && (!Number.isFinite(threshold) || threshold < 0 || threshold > 1)) {
|
|
3209
|
+
throw new Error("core.workerThreshold must be a finite number between 0 and 1");
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
2870
3212
|
function validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) {
|
|
2871
3213
|
const loaderName = id || "Top level";
|
|
2872
3214
|
const prefix = id ? `${id}.` : "";
|
|
@@ -3580,7 +3922,8 @@ var __exports__ = (() => {
|
|
|
3580
3922
|
if (typeof fetchOption === "function") {
|
|
3581
3923
|
fetchFunction = fetchOption;
|
|
3582
3924
|
} else if (isObject(fetchOption)) {
|
|
3583
|
-
|
|
3925
|
+
const baseFetch = context?.fetch || fetchFile;
|
|
3926
|
+
fetchFunction = (url, requestOptions) => baseFetch(url, mergeFetchOptions(fetchOption, requestOptions));
|
|
3584
3927
|
} else if (context?.fetch) {
|
|
3585
3928
|
fetchFunction = context.fetch;
|
|
3586
3929
|
} else {
|
|
@@ -3898,6 +4241,9 @@ var __exports__ = (() => {
|
|
|
3898
4241
|
options?.core?.transforms || []
|
|
3899
4242
|
);
|
|
3900
4243
|
if (loader.parseInBatches) {
|
|
4244
|
+
if (loader.id === "csv" && isBrowser && canParseWithWorker(loader, options)) {
|
|
4245
|
+
return parseWithWorkerInBatches(loader, transformedIterator, options, context, parse);
|
|
4246
|
+
}
|
|
3901
4247
|
return loader.parseInBatches(transformedIterator, options, context);
|
|
3902
4248
|
}
|
|
3903
4249
|
return parseChunkInBatches(transformedIterator, loader, options, context);
|
|
@@ -4084,7 +4430,10 @@ var __exports__ = (() => {
|
|
|
4084
4430
|
// src/lib/loader-utils/loader-context.ts
|
|
4085
4431
|
function getLoaderContext(context, options, parentContext) {
|
|
4086
4432
|
if (parentContext) {
|
|
4087
|
-
return
|
|
4433
|
+
return {
|
|
4434
|
+
...parentContext,
|
|
4435
|
+
fetch: getFetchFunction(options, parentContext)
|
|
4436
|
+
};
|
|
4088
4437
|
}
|
|
4089
4438
|
const newContext = {
|
|
4090
4439
|
...context,
|
|
@@ -4157,7 +4506,7 @@ var __exports__ = (() => {
|
|
|
4157
4506
|
context.response = { headers, ok, redirected, status, statusText, type, url };
|
|
4158
4507
|
}
|
|
4159
4508
|
const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
|
|
4160
|
-
if (
|
|
4509
|
+
if (shouldParseWithWorker(loaderWithParser, data, options, context, loader)) {
|
|
4161
4510
|
data = await getArrayBufferFromData(data, options);
|
|
4162
4511
|
return await parseWithWorker(loaderWithParser, data, options, context, parse);
|
|
4163
4512
|
}
|