@loaders.gl/core 5.0.0-alpha.4 → 5.0.0-alpha.6
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 +379 -41
- package/dist/dist.min.js +3 -3
- package/dist/index.cjs +385 -42
- 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 = () => {
|
|
@@ -1070,6 +1097,8 @@ var __exports__ = (() => {
|
|
|
1070
1097
|
constructor(props) {
|
|
1071
1098
|
this.source = props.source;
|
|
1072
1099
|
this.url = props.url;
|
|
1100
|
+
this.getUrl = props.getUrl;
|
|
1101
|
+
this.loadWorker = props.loadWorker;
|
|
1073
1102
|
this.setProps(props);
|
|
1074
1103
|
}
|
|
1075
1104
|
/**
|
|
@@ -1179,7 +1208,13 @@ var __exports__ = (() => {
|
|
|
1179
1208
|
if (this.count < this._getMaxConcurrency()) {
|
|
1180
1209
|
this.count++;
|
|
1181
1210
|
const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`;
|
|
1182
|
-
return new WorkerThread({
|
|
1211
|
+
return new WorkerThread({
|
|
1212
|
+
name,
|
|
1213
|
+
source: this.source,
|
|
1214
|
+
url: this.url,
|
|
1215
|
+
getUrl: this.getUrl,
|
|
1216
|
+
loadWorker: this.loadWorker
|
|
1217
|
+
});
|
|
1183
1218
|
}
|
|
1184
1219
|
return null;
|
|
1185
1220
|
}
|
|
@@ -1196,6 +1231,8 @@ var __exports__ = (() => {
|
|
|
1196
1231
|
onDebug: () => {
|
|
1197
1232
|
}
|
|
1198
1233
|
};
|
|
1234
|
+
var loadWorkerIds = /* @__PURE__ */ new WeakMap();
|
|
1235
|
+
var nextLoadWorkerId = 1;
|
|
1199
1236
|
var WorkerFarm = class _WorkerFarm {
|
|
1200
1237
|
props;
|
|
1201
1238
|
workerPools = /* @__PURE__ */ new Map();
|
|
@@ -1239,24 +1276,28 @@ var __exports__ = (() => {
|
|
|
1239
1276
|
}
|
|
1240
1277
|
/**
|
|
1241
1278
|
* Returns a worker pool for the specified worker
|
|
1242
|
-
* @param options
|
|
1243
|
-
* @param options.name
|
|
1244
|
-
* @param options.url
|
|
1245
|
-
* @param options.source
|
|
1279
|
+
* @param options Worker target used to identify and initialize the pool.
|
|
1280
|
+
* @param options.name Worker name used as the base pool identity.
|
|
1281
|
+
* @param options.url Worker script URL.
|
|
1282
|
+
* @param options.source Inline worker source.
|
|
1283
|
+
* @param options.loadWorker Built-in browser worker factory.
|
|
1246
1284
|
* @example
|
|
1247
1285
|
* const job = WorkerFarm.getWorkerFarm().getWorkerPool({name, url}).startJob(...);
|
|
1248
1286
|
*/
|
|
1249
1287
|
getWorkerPool(options) {
|
|
1250
|
-
const { name, source, url } = options;
|
|
1251
|
-
|
|
1288
|
+
const { name, source, url, getUrl, loadWorker } = options;
|
|
1289
|
+
const workerPoolKey = getWorkerPoolKey(options);
|
|
1290
|
+
let workerPool = this.workerPools.get(workerPoolKey);
|
|
1252
1291
|
if (!workerPool) {
|
|
1253
1292
|
workerPool = new WorkerPool({
|
|
1254
1293
|
name,
|
|
1255
1294
|
source,
|
|
1256
|
-
url
|
|
1295
|
+
url,
|
|
1296
|
+
getUrl,
|
|
1297
|
+
loadWorker
|
|
1257
1298
|
});
|
|
1258
1299
|
workerPool.setProps(this._getWorkerPoolProps());
|
|
1259
|
-
this.workerPools.set(
|
|
1300
|
+
this.workerPools.set(workerPoolKey, workerPool);
|
|
1260
1301
|
}
|
|
1261
1302
|
return workerPool;
|
|
1262
1303
|
}
|
|
@@ -1269,6 +1310,91 @@ var __exports__ = (() => {
|
|
|
1269
1310
|
};
|
|
1270
1311
|
}
|
|
1271
1312
|
};
|
|
1313
|
+
function getWorkerPoolKey(options) {
|
|
1314
|
+
const { name, source, url, urlKey, loadWorker } = options;
|
|
1315
|
+
const sourceKey = source ? `source:${source}` : "";
|
|
1316
|
+
const urlKeyPart = url || urlKey ? `url:${url || urlKey}` : "";
|
|
1317
|
+
const loadWorkerKey = loadWorker ? `loadWorker:${getLoadWorkerId(loadWorker)}` : "";
|
|
1318
|
+
return [name, sourceKey, urlKeyPart, loadWorkerKey].filter(Boolean).join("|");
|
|
1319
|
+
}
|
|
1320
|
+
function getLoadWorkerId(loadWorker) {
|
|
1321
|
+
let loadWorkerId = loadWorkerIds.get(loadWorker);
|
|
1322
|
+
if (!loadWorkerId) {
|
|
1323
|
+
loadWorkerId = nextLoadWorkerId++;
|
|
1324
|
+
loadWorkerIds.set(loadWorker, loadWorkerId);
|
|
1325
|
+
}
|
|
1326
|
+
return loadWorkerId;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// ../worker-utils/src/lib/async-queue/async-queue.ts
|
|
1330
|
+
var AsyncQueue = class {
|
|
1331
|
+
_values;
|
|
1332
|
+
_settlers;
|
|
1333
|
+
_closed;
|
|
1334
|
+
constructor() {
|
|
1335
|
+
this._values = [];
|
|
1336
|
+
this._settlers = [];
|
|
1337
|
+
this._closed = false;
|
|
1338
|
+
}
|
|
1339
|
+
/** Return an async iterator for this queue */
|
|
1340
|
+
[Symbol.asyncIterator]() {
|
|
1341
|
+
return this;
|
|
1342
|
+
}
|
|
1343
|
+
/** Push a new value - the async iterator will yield a promise resolved to this value */
|
|
1344
|
+
push(value) {
|
|
1345
|
+
return this.enqueue(value);
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Push a new value - the async iterator will yield a promise resolved to this value
|
|
1349
|
+
* Add an error - the async iterator will yield a promise rejected with this value
|
|
1350
|
+
*/
|
|
1351
|
+
enqueue(value) {
|
|
1352
|
+
if (this._closed) {
|
|
1353
|
+
throw new Error("Closed");
|
|
1354
|
+
}
|
|
1355
|
+
if (this._settlers.length > 0) {
|
|
1356
|
+
if (this._values.length > 0) {
|
|
1357
|
+
throw new Error("Illegal internal state");
|
|
1358
|
+
}
|
|
1359
|
+
const settler = this._settlers.shift();
|
|
1360
|
+
if (value instanceof Error) {
|
|
1361
|
+
settler.reject(value);
|
|
1362
|
+
} else {
|
|
1363
|
+
settler.resolve({ value });
|
|
1364
|
+
}
|
|
1365
|
+
} else {
|
|
1366
|
+
this._values.push(value);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
/** Indicate that we not waiting for more values - The async iterator will be done */
|
|
1370
|
+
close() {
|
|
1371
|
+
while (this._settlers.length > 0) {
|
|
1372
|
+
const settler = this._settlers.shift();
|
|
1373
|
+
settler.resolve({ done: true });
|
|
1374
|
+
}
|
|
1375
|
+
this._closed = true;
|
|
1376
|
+
}
|
|
1377
|
+
// ITERATOR IMPLEMENTATION
|
|
1378
|
+
/** @returns a Promise for an IteratorResult */
|
|
1379
|
+
next() {
|
|
1380
|
+
if (this._values.length > 0) {
|
|
1381
|
+
const value = this._values.shift();
|
|
1382
|
+
if (value instanceof Error) {
|
|
1383
|
+
return Promise.reject(value);
|
|
1384
|
+
}
|
|
1385
|
+
return Promise.resolve({ done: false, value });
|
|
1386
|
+
}
|
|
1387
|
+
if (this._closed) {
|
|
1388
|
+
if (this._settlers.length > 0) {
|
|
1389
|
+
throw new Error("Illegal internal state");
|
|
1390
|
+
}
|
|
1391
|
+
return Promise.resolve({ done: true, value: void 0 });
|
|
1392
|
+
}
|
|
1393
|
+
return new Promise((resolve2, reject) => {
|
|
1394
|
+
this._settlers.push({ resolve: resolve2, reject });
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
};
|
|
1272
1398
|
|
|
1273
1399
|
// ../worker-utils/src/lib/worker-api/get-worker-url.ts
|
|
1274
1400
|
var warnedWorkerVersionFallbacks = /* @__PURE__ */ new Set();
|
|
@@ -1276,34 +1402,41 @@ var __exports__ = (() => {
|
|
|
1276
1402
|
const warning = worker.version !== VERSION3 ? ` (worker-utils@${VERSION3})` : "";
|
|
1277
1403
|
return `${worker.name}@${worker.version}${warning}`;
|
|
1278
1404
|
}
|
|
1279
|
-
function
|
|
1405
|
+
function getCustomWorkerURL(worker, options = {}) {
|
|
1280
1406
|
const workerOptions = options[worker.id] || {};
|
|
1281
|
-
const workerFile = isBrowser3 ? `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
|
|
1407
|
+
const workerFile = isBrowser3 ? worker.workerFile || `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
|
|
1282
1408
|
let url = workerOptions.workerUrl;
|
|
1283
|
-
if (!url && typeof worker.worker === "string") {
|
|
1284
|
-
url = worker.worker;
|
|
1285
|
-
}
|
|
1286
1409
|
if (!url && worker.id === "compression") {
|
|
1287
1410
|
url = options.workerUrl;
|
|
1288
1411
|
}
|
|
1289
1412
|
const workerType = options._workerType || options?.core?._workerType;
|
|
1290
|
-
if (workerType === "test") {
|
|
1413
|
+
if (!url && workerType === "test") {
|
|
1291
1414
|
if (isBrowser3) {
|
|
1292
1415
|
url = `modules/${worker.module}/dist/${workerFile}`;
|
|
1293
1416
|
} else {
|
|
1294
1417
|
url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`;
|
|
1295
1418
|
}
|
|
1296
1419
|
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1420
|
+
return url || null;
|
|
1421
|
+
}
|
|
1422
|
+
function getWorkerURL(worker, options = {}) {
|
|
1423
|
+
const customWorkerUrl = getCustomWorkerURL(worker, options);
|
|
1424
|
+
const descriptorWorkerUrl = typeof worker.worker === "string" ? worker.worker : null;
|
|
1425
|
+
const url = customWorkerUrl || descriptorWorkerUrl || getDefaultWorkerURL(worker, true);
|
|
1426
|
+
assert3(url);
|
|
1427
|
+
return url;
|
|
1428
|
+
}
|
|
1429
|
+
function getDefaultWorkerURL(worker, warn = false) {
|
|
1430
|
+
const workerFile = isBrowser3 ? worker.workerFile || `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
|
|
1431
|
+
let version2 = worker.version;
|
|
1432
|
+
if (version2 === "latest") {
|
|
1433
|
+
version2 = NPM_TAG;
|
|
1434
|
+
}
|
|
1435
|
+
const versionTag = version2 ? `@${version2}` : "";
|
|
1436
|
+
const url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
|
|
1437
|
+
if (warn) {
|
|
1304
1438
|
warnIfUsingNpmTagFallback(worker, url);
|
|
1305
1439
|
}
|
|
1306
|
-
assert3(url);
|
|
1307
1440
|
return url;
|
|
1308
1441
|
}
|
|
1309
1442
|
function warnIfUsingNpmTagFallback(worker, url) {
|
|
@@ -1326,18 +1459,15 @@ var __exports__ = (() => {
|
|
|
1326
1459
|
return false;
|
|
1327
1460
|
}
|
|
1328
1461
|
const workerOptions = options?.[worker.id];
|
|
1329
|
-
return Boolean(
|
|
1462
|
+
return Boolean(
|
|
1463
|
+
(worker.worker || worker.loadWorker || workerOptions?.workerUrl) && options?.worker
|
|
1464
|
+
);
|
|
1330
1465
|
}
|
|
1331
1466
|
async function processOnWorker(worker, data, options = {}, context = {}, jobContext = {}) {
|
|
1332
1467
|
throwIfAborted(options.signal);
|
|
1333
1468
|
const name = getWorkerName(worker);
|
|
1334
1469
|
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);
|
|
1470
|
+
const workerPool = workerFarm.getWorkerPool(getWorkerPoolTarget(worker, options, name));
|
|
1341
1471
|
const jobName = options.jobName || worker.name;
|
|
1342
1472
|
const job = await workerPool.startJob(
|
|
1343
1473
|
jobName,
|
|
@@ -1366,6 +1496,114 @@ var __exports__ = (() => {
|
|
|
1366
1496
|
options.signal?.removeEventListener("abort", abortJob);
|
|
1367
1497
|
}
|
|
1368
1498
|
}
|
|
1499
|
+
function processOnWorkerInBatches(worker, input, options = {}, context = {}, jobContext = {}) {
|
|
1500
|
+
return processOnWorkerInBatchesIterator(worker, input, options, context, jobContext);
|
|
1501
|
+
}
|
|
1502
|
+
async function* processOnWorkerInBatchesIterator(worker, input, options, context, jobContext) {
|
|
1503
|
+
throwIfAborted(options.signal);
|
|
1504
|
+
const name = getWorkerName(worker);
|
|
1505
|
+
const workerFarm = WorkerFarm.getWorkerFarm(options);
|
|
1506
|
+
const workerPool = workerFarm.getWorkerPool(getWorkerPoolTarget(worker, options, name));
|
|
1507
|
+
const outputBatches = new AsyncQueue();
|
|
1508
|
+
const inputIterator = getAsyncIterator(input);
|
|
1509
|
+
let outputFinished = false;
|
|
1510
|
+
let inputFinished = false;
|
|
1511
|
+
let inputRequest = Promise.resolve();
|
|
1512
|
+
const batchJobFailed = new Error("Worker batch job failed");
|
|
1513
|
+
const finishOutput = () => {
|
|
1514
|
+
if (!outputFinished) {
|
|
1515
|
+
outputFinished = true;
|
|
1516
|
+
outputBatches.close();
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
const failOutput = (_error) => {
|
|
1520
|
+
if (!outputFinished) {
|
|
1521
|
+
outputFinished = true;
|
|
1522
|
+
outputBatches.enqueue(batchJobFailed);
|
|
1523
|
+
outputBatches.close();
|
|
1524
|
+
}
|
|
1525
|
+
};
|
|
1526
|
+
const job = await workerPool.startJob(
|
|
1527
|
+
options.jobName || worker.name,
|
|
1528
|
+
(activeJob, type, payload) => {
|
|
1529
|
+
switch (type) {
|
|
1530
|
+
case "input-request":
|
|
1531
|
+
inputRequest = inputRequest.then(async () => {
|
|
1532
|
+
const nextBatch = await inputIterator.next();
|
|
1533
|
+
if (!activeJob.isRunning) {
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
if (nextBatch.done) {
|
|
1537
|
+
inputFinished = true;
|
|
1538
|
+
activeJob.postMessage("input-done", {});
|
|
1539
|
+
} else {
|
|
1540
|
+
activeJob.postMessage("input-batch", { input: nextBatch.value });
|
|
1541
|
+
}
|
|
1542
|
+
}).catch((error) => activeJob.abort(error));
|
|
1543
|
+
break;
|
|
1544
|
+
case "output-batch":
|
|
1545
|
+
outputBatches.push(payload.result);
|
|
1546
|
+
break;
|
|
1547
|
+
case "done":
|
|
1548
|
+
activeJob.done(payload);
|
|
1549
|
+
finishOutput();
|
|
1550
|
+
break;
|
|
1551
|
+
case "error": {
|
|
1552
|
+
const error = new Error(payload.error || "Worker batch processing failed");
|
|
1553
|
+
activeJob.error(error);
|
|
1554
|
+
failOutput(error);
|
|
1555
|
+
break;
|
|
1556
|
+
}
|
|
1557
|
+
case "process":
|
|
1558
|
+
void onMessage(context, activeJob, type, payload);
|
|
1559
|
+
break;
|
|
1560
|
+
default: {
|
|
1561
|
+
const error = new Error(`Unexpected worker batch message: ${type}`);
|
|
1562
|
+
activeJob.error(error);
|
|
1563
|
+
failOutput(error);
|
|
1564
|
+
break;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
);
|
|
1569
|
+
const abortJob = () => job.abort(getAbortReason(options.signal));
|
|
1570
|
+
options.signal?.addEventListener("abort", abortJob, { once: true });
|
|
1571
|
+
if (options.signal?.aborted) {
|
|
1572
|
+
abortJob();
|
|
1573
|
+
}
|
|
1574
|
+
void job.result.catch(failOutput);
|
|
1575
|
+
try {
|
|
1576
|
+
const { signal: _signal, ...workerOptions } = options;
|
|
1577
|
+
if (job.isRunning) {
|
|
1578
|
+
job.postMessage("process-in-batches", {
|
|
1579
|
+
options: getTransferListForWriter(workerOptions),
|
|
1580
|
+
context: getTransferListForWriter(jobContext)
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
try {
|
|
1584
|
+
for await (const outputBatch of outputBatches) {
|
|
1585
|
+
yield outputBatch;
|
|
1586
|
+
if (job.isRunning) {
|
|
1587
|
+
job.postMessage("output-ack", {});
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
} catch (error) {
|
|
1591
|
+
if (error === batchJobFailed) {
|
|
1592
|
+
await job.result;
|
|
1593
|
+
}
|
|
1594
|
+
throw error;
|
|
1595
|
+
}
|
|
1596
|
+
await job.result;
|
|
1597
|
+
} finally {
|
|
1598
|
+
options.signal?.removeEventListener("abort", abortJob);
|
|
1599
|
+
if (job.isRunning) {
|
|
1600
|
+
job.abort(createAbortError2("Worker batch iterator was closed"));
|
|
1601
|
+
}
|
|
1602
|
+
if (!inputFinished) {
|
|
1603
|
+
closeInputIterator(inputIterator);
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1369
1607
|
function throwIfAborted(signal) {
|
|
1370
1608
|
if (!signal?.aborted) {
|
|
1371
1609
|
return;
|
|
@@ -1380,6 +1618,38 @@ var __exports__ = (() => {
|
|
|
1380
1618
|
error.name = "AbortError";
|
|
1381
1619
|
return error;
|
|
1382
1620
|
}
|
|
1621
|
+
function getAsyncIterator(input) {
|
|
1622
|
+
if (Symbol.asyncIterator in input) {
|
|
1623
|
+
return input[Symbol.asyncIterator]();
|
|
1624
|
+
}
|
|
1625
|
+
return (async function* iterateSynchronously() {
|
|
1626
|
+
yield* input;
|
|
1627
|
+
})();
|
|
1628
|
+
}
|
|
1629
|
+
function closeInputIterator(inputIterator) {
|
|
1630
|
+
try {
|
|
1631
|
+
void Promise.resolve(inputIterator.return?.()).catch(() => void 0);
|
|
1632
|
+
} catch {
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
function getWorkerPoolTarget(worker, options, name) {
|
|
1636
|
+
if (options.source) {
|
|
1637
|
+
return { name, source: options.source };
|
|
1638
|
+
}
|
|
1639
|
+
const customWorkerUrl = getCustomWorkerURL(worker, options);
|
|
1640
|
+
if (customWorkerUrl) {
|
|
1641
|
+
return { name, url: customWorkerUrl };
|
|
1642
|
+
}
|
|
1643
|
+
if (isBrowser3 && worker.loadWorker) {
|
|
1644
|
+
return {
|
|
1645
|
+
name,
|
|
1646
|
+
loadWorker: worker.loadWorker,
|
|
1647
|
+
getUrl: () => getWorkerURL(worker, options),
|
|
1648
|
+
urlKey: getDefaultWorkerURL(worker)
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
return { name, url: getWorkerURL(worker, options) };
|
|
1652
|
+
}
|
|
1383
1653
|
async function onMessage(context, job, type, payload) {
|
|
1384
1654
|
switch (type) {
|
|
1385
1655
|
case "done":
|
|
@@ -1432,12 +1702,29 @@ var __exports__ = (() => {
|
|
|
1432
1702
|
}
|
|
1433
1703
|
return Boolean(canProcessOnWorker(loader, workerOptions));
|
|
1434
1704
|
}
|
|
1705
|
+
function shouldParseWithWorker(loader, data, options, context, estimateLoader = loader) {
|
|
1706
|
+
if (!canParseWithWorker(loader, options)) {
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1709
|
+
if (options?.core?.worker !== "auto" || !estimateLoader.getWorkerEstimate) {
|
|
1710
|
+
return true;
|
|
1711
|
+
}
|
|
1712
|
+
try {
|
|
1713
|
+
const estimate = estimateLoader.getWorkerEstimate(data, options, context);
|
|
1714
|
+
if (estimate === void 0 || !Number.isFinite(estimate) || estimate < 0 || estimate > 1) {
|
|
1715
|
+
return true;
|
|
1716
|
+
}
|
|
1717
|
+
return estimate >= (options.core?.workerThreshold ?? 0.1);
|
|
1718
|
+
} catch {
|
|
1719
|
+
return true;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1435
1722
|
async function parseWithWorker(loader, data, options, context, parseOnMainThread, signal) {
|
|
1436
1723
|
const workerSignal = signal || getWorkerAbortSignal(options);
|
|
1437
1724
|
const result = await processOnWorker(
|
|
1438
1725
|
loader,
|
|
1439
1726
|
data,
|
|
1440
|
-
{ ...getWorkerOptions(options), signal: workerSignal },
|
|
1727
|
+
{ ...getWorkerOptions(options, loader), signal: workerSignal },
|
|
1441
1728
|
{
|
|
1442
1729
|
process: async (input, processOptions, _workerContext, parseContext) => {
|
|
1443
1730
|
if (!parseOnMainThread) {
|
|
@@ -1456,6 +1743,32 @@ var __exports__ = (() => {
|
|
|
1456
1743
|
);
|
|
1457
1744
|
return isLoaderWithWorkerResultDeserializer(loader) ? loader.deserializeWorkerResult(result, options, context) : result;
|
|
1458
1745
|
}
|
|
1746
|
+
async function* parseWithWorkerInBatches(loader, inputIterator, options, context, parseOnMainThread, signal) {
|
|
1747
|
+
const workerSignal = signal || getWorkerAbortSignal(options);
|
|
1748
|
+
const outputIterator = processOnWorkerInBatches(
|
|
1749
|
+
loader,
|
|
1750
|
+
inputIterator,
|
|
1751
|
+
{ ...getWorkerOptions(options), signal: workerSignal },
|
|
1752
|
+
{
|
|
1753
|
+
process: async (input, processOptions, _workerContext, parseContext) => {
|
|
1754
|
+
if (!parseOnMainThread) {
|
|
1755
|
+
throw new Error("Worker not set up to parse on main thread");
|
|
1756
|
+
}
|
|
1757
|
+
const mainThreadContext = context ? { ...context, ...parseContext || {} } : void 0;
|
|
1758
|
+
return await callParseOnMainThread(
|
|
1759
|
+
parseOnMainThread,
|
|
1760
|
+
input,
|
|
1761
|
+
processOptions,
|
|
1762
|
+
mainThreadContext
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
},
|
|
1766
|
+
getSerializableLoaderContext(context)
|
|
1767
|
+
);
|
|
1768
|
+
for await (const batch of outputIterator) {
|
|
1769
|
+
yield loader.deserializeWorkerBatch ? loader.deserializeWorkerBatch(batch, options, context) : batch;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1459
1772
|
function getWorkerAbortSignal(options) {
|
|
1460
1773
|
const parquetSignal = options?.parquet?.signal;
|
|
1461
1774
|
if (typeof AbortSignal !== "undefined" && parquetSignal instanceof AbortSignal) {
|
|
@@ -1469,12 +1782,19 @@ var __exports__ = (() => {
|
|
|
1469
1782
|
}
|
|
1470
1783
|
return parseOnMainThread(input, void 0, options, context);
|
|
1471
1784
|
}
|
|
1472
|
-
function getWorkerOptions(options = {}) {
|
|
1785
|
+
function getWorkerOptions(options = {}, loader) {
|
|
1473
1786
|
const serializedOptions = JSON.parse(JSON.stringify(options));
|
|
1474
|
-
|
|
1787
|
+
const workerOptions = {
|
|
1475
1788
|
...serializedOptions.core,
|
|
1476
1789
|
...serializedOptions
|
|
1477
1790
|
};
|
|
1791
|
+
if (workerOptions.worker === "auto") {
|
|
1792
|
+
workerOptions.worker = true;
|
|
1793
|
+
}
|
|
1794
|
+
if (loader) {
|
|
1795
|
+
workerOptions._workerLoaderId = loader.id;
|
|
1796
|
+
}
|
|
1797
|
+
return workerOptions;
|
|
1478
1798
|
}
|
|
1479
1799
|
function getSerializableLoaderContext(context) {
|
|
1480
1800
|
if (!context) {
|
|
@@ -2728,6 +3048,7 @@ var __exports__ = (() => {
|
|
|
2728
3048
|
CDN: "https://unpkg.com/@loaders.gl",
|
|
2729
3049
|
worker: true,
|
|
2730
3050
|
// By default, use worker if provided by loader.
|
|
3051
|
+
workerThreshold: 0.1,
|
|
2731
3052
|
maxConcurrency: 3,
|
|
2732
3053
|
// How many worker instances should be created for each loader.
|
|
2733
3054
|
maxMobileConcurrency: 1,
|
|
@@ -2803,6 +3124,7 @@ var __exports__ = (() => {
|
|
|
2803
3124
|
"useLocalLibraries",
|
|
2804
3125
|
"CDN",
|
|
2805
3126
|
"worker",
|
|
3127
|
+
"workerThreshold",
|
|
2806
3128
|
"maxConcurrency",
|
|
2807
3129
|
"maxMobileConcurrency",
|
|
2808
3130
|
"reuseWorkers",
|
|
@@ -2843,7 +3165,10 @@ var __exports__ = (() => {
|
|
|
2843
3165
|
loaders = loaders || [];
|
|
2844
3166
|
loaders = Array.isArray(loaders) ? loaders : [loaders];
|
|
2845
3167
|
validateOptions(options, loaders);
|
|
2846
|
-
|
|
3168
|
+
validateWorkerThreshold(options);
|
|
3169
|
+
const normalizedOptions = normalizeLoaderOptions(normalizeOptionsInternal(loader, options, url));
|
|
3170
|
+
validateWorkerThreshold(normalizedOptions);
|
|
3171
|
+
return normalizedOptions;
|
|
2847
3172
|
}
|
|
2848
3173
|
function normalizeLoaderOptions(options) {
|
|
2849
3174
|
const normalized = cloneLoaderOptions(options);
|
|
@@ -2867,6 +3192,12 @@ var __exports__ = (() => {
|
|
|
2867
3192
|
validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders);
|
|
2868
3193
|
}
|
|
2869
3194
|
}
|
|
3195
|
+
function validateWorkerThreshold(options) {
|
|
3196
|
+
const threshold = options.core?.workerThreshold;
|
|
3197
|
+
if (threshold !== void 0 && (!Number.isFinite(threshold) || threshold < 0 || threshold > 1)) {
|
|
3198
|
+
throw new Error("core.workerThreshold must be a finite number between 0 and 1");
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
2870
3201
|
function validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) {
|
|
2871
3202
|
const loaderName = id || "Top level";
|
|
2872
3203
|
const prefix = id ? `${id}.` : "";
|
|
@@ -3580,7 +3911,8 @@ var __exports__ = (() => {
|
|
|
3580
3911
|
if (typeof fetchOption === "function") {
|
|
3581
3912
|
fetchFunction = fetchOption;
|
|
3582
3913
|
} else if (isObject(fetchOption)) {
|
|
3583
|
-
|
|
3914
|
+
const baseFetch = context?.fetch || fetchFile;
|
|
3915
|
+
fetchFunction = (url, requestOptions) => baseFetch(url, mergeFetchOptions(fetchOption, requestOptions));
|
|
3584
3916
|
} else if (context?.fetch) {
|
|
3585
3917
|
fetchFunction = context.fetch;
|
|
3586
3918
|
} else {
|
|
@@ -3898,6 +4230,9 @@ var __exports__ = (() => {
|
|
|
3898
4230
|
options?.core?.transforms || []
|
|
3899
4231
|
);
|
|
3900
4232
|
if (loader.parseInBatches) {
|
|
4233
|
+
if (loader.id === "csv" && isBrowser && canParseWithWorker(loader, options)) {
|
|
4234
|
+
return parseWithWorkerInBatches(loader, transformedIterator, options, context, parse);
|
|
4235
|
+
}
|
|
3901
4236
|
return loader.parseInBatches(transformedIterator, options, context);
|
|
3902
4237
|
}
|
|
3903
4238
|
return parseChunkInBatches(transformedIterator, loader, options, context);
|
|
@@ -4084,7 +4419,10 @@ var __exports__ = (() => {
|
|
|
4084
4419
|
// src/lib/loader-utils/loader-context.ts
|
|
4085
4420
|
function getLoaderContext(context, options, parentContext) {
|
|
4086
4421
|
if (parentContext) {
|
|
4087
|
-
return
|
|
4422
|
+
return {
|
|
4423
|
+
...parentContext,
|
|
4424
|
+
fetch: getFetchFunction(options, parentContext)
|
|
4425
|
+
};
|
|
4088
4426
|
}
|
|
4089
4427
|
const newContext = {
|
|
4090
4428
|
...context,
|
|
@@ -4157,7 +4495,7 @@ var __exports__ = (() => {
|
|
|
4157
4495
|
context.response = { headers, ok, redirected, status, statusText, type, url };
|
|
4158
4496
|
}
|
|
4159
4497
|
const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
|
|
4160
|
-
if (
|
|
4498
|
+
if (shouldParseWithWorker(loaderWithParser, data, options, context, loader)) {
|
|
4161
4499
|
data = await getArrayBufferFromData(data, options);
|
|
4162
4500
|
return await parseWithWorker(loaderWithParser, data, options, context, parse);
|
|
4163
4501
|
}
|