@loaders.gl/core 4.4.2 → 5.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/dist.dev.js +583 -162
  2. package/dist/dist.min.js +4 -3
  3. package/dist/index.cjs +499 -148
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +8 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +7 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/iterators/make-iterator/make-stream-iterator.js +1 -1
  10. package/dist/iterators/make-iterator/make-stream-iterator.js.map +1 -1
  11. package/dist/lib/api/core-api.d.ts +6 -0
  12. package/dist/lib/api/core-api.d.ts.map +1 -0
  13. package/dist/lib/api/core-api.js +23 -0
  14. package/dist/lib/api/core-api.js.map +1 -0
  15. package/dist/lib/api/create-data-source.d.ts +2 -2
  16. package/dist/lib/api/create-data-source.d.ts.map +1 -1
  17. package/dist/lib/api/create-data-source.js +15 -14
  18. package/dist/lib/api/create-data-source.js.map +1 -1
  19. package/dist/lib/api/load-in-batches.d.ts +4 -4
  20. package/dist/lib/api/load-in-batches.d.ts.map +1 -1
  21. package/dist/lib/api/load-in-batches.js +1 -1
  22. package/dist/lib/api/load-in-batches.js.map +1 -1
  23. package/dist/lib/api/load-loader.d.ts +8 -0
  24. package/dist/lib/api/load-loader.d.ts.map +1 -0
  25. package/dist/lib/api/load-loader.js +116 -0
  26. package/dist/lib/api/load-loader.js.map +1 -0
  27. package/dist/lib/api/load.d.ts +2 -2
  28. package/dist/lib/api/load.d.ts.map +1 -1
  29. package/dist/lib/api/load.js +52 -3
  30. package/dist/lib/api/load.js.map +1 -1
  31. package/dist/lib/api/parse-file.d.ts +15 -0
  32. package/dist/lib/api/parse-file.d.ts.map +1 -0
  33. package/dist/lib/api/parse-file.js +70 -0
  34. package/dist/lib/api/parse-file.js.map +1 -0
  35. package/dist/lib/api/parse-in-batches.d.ts +2 -2
  36. package/dist/lib/api/parse-in-batches.d.ts.map +1 -1
  37. package/dist/lib/api/parse-in-batches.js +6 -4
  38. package/dist/lib/api/parse-in-batches.js.map +1 -1
  39. package/dist/lib/api/parse-sync.d.ts +2 -2
  40. package/dist/lib/api/parse-sync.d.ts.map +1 -1
  41. package/dist/lib/api/parse-sync.js +10 -1
  42. package/dist/lib/api/parse-sync.js.map +1 -1
  43. package/dist/lib/api/parse.d.ts +2 -2
  44. package/dist/lib/api/parse.d.ts.map +1 -1
  45. package/dist/lib/api/parse.js +25 -16
  46. package/dist/lib/api/parse.js.map +1 -1
  47. package/dist/lib/api/preload.d.ts +11 -0
  48. package/dist/lib/api/preload.d.ts.map +1 -0
  49. package/dist/lib/api/preload.js +14 -0
  50. package/dist/lib/api/preload.js.map +1 -0
  51. package/dist/lib/api/register-loaders.js +1 -1
  52. package/dist/lib/api/register-loaders.js.map +1 -1
  53. package/dist/lib/api/select-loader.d.ts.map +1 -1
  54. package/dist/lib/api/select-loader.js +48 -5
  55. package/dist/lib/api/select-loader.js.map +1 -1
  56. package/dist/lib/api/select-source.d.ts +3 -3
  57. package/dist/lib/api/select-source.d.ts.map +1 -1
  58. package/dist/lib/api/select-source.js +2 -5
  59. package/dist/lib/api/select-source.js.map +1 -1
  60. package/dist/lib/fetch/fetch-error-message.js +1 -1
  61. package/dist/lib/fetch/fetch-error-message.js.map +1 -1
  62. package/dist/lib/init.js +1 -1
  63. package/dist/lib/init.js.map +1 -1
  64. package/dist/lib/loader-utils/check-errors.js +1 -1
  65. package/dist/lib/loader-utils/check-errors.js.map +1 -1
  66. package/dist/lib/loader-utils/get-data.d.ts +4 -0
  67. package/dist/lib/loader-utils/get-data.d.ts.map +1 -1
  68. package/dist/lib/loader-utils/get-data.js +26 -0
  69. package/dist/lib/loader-utils/get-data.js.map +1 -1
  70. package/dist/lib/loader-utils/get-fetch-function.d.ts +1 -1
  71. package/dist/lib/loader-utils/get-fetch-function.d.ts.map +1 -1
  72. package/dist/lib/loader-utils/get-fetch-function.js +1 -1
  73. package/dist/lib/loader-utils/get-fetch-function.js.map +1 -1
  74. package/dist/lib/loader-utils/loader-context.d.ts +1 -1
  75. package/dist/lib/loader-utils/loader-context.d.ts.map +1 -1
  76. package/dist/lib/loader-utils/loader-context.js +3 -1
  77. package/dist/lib/loader-utils/loader-context.js.map +1 -1
  78. package/dist/lib/loader-utils/loggers.d.ts +19 -0
  79. package/dist/lib/loader-utils/loggers.d.ts.map +1 -1
  80. package/dist/lib/loader-utils/loggers.js +28 -2
  81. package/dist/lib/loader-utils/loggers.js.map +1 -1
  82. package/dist/lib/loader-utils/option-defaults.d.ts +1 -0
  83. package/dist/lib/loader-utils/option-defaults.d.ts.map +1 -1
  84. package/dist/lib/loader-utils/option-defaults.js +2 -0
  85. package/dist/lib/loader-utils/option-defaults.js.map +1 -1
  86. package/dist/lib/loader-utils/option-utils.d.ts.map +1 -1
  87. package/dist/lib/loader-utils/option-utils.js +50 -2
  88. package/dist/lib/loader-utils/option-utils.js.map +1 -1
  89. package/dist/lib/utils/response-utils.js +3 -3
  90. package/dist/lib/utils/response-utils.js.map +1 -1
  91. package/dist/null-loader.d.ts.map +1 -1
  92. package/dist/null-loader.js +1 -1
  93. package/dist/null-loader.js.map +1 -1
  94. package/dist/null-worker-node.js +199 -36
  95. package/dist/null-worker.js +199 -36
  96. package/package.json +6 -6
  97. package/src/index.ts +10 -1
  98. package/src/iterators/make-iterator/make-stream-iterator.ts +1 -1
  99. package/src/lib/api/core-api.ts +25 -0
  100. package/src/lib/api/create-data-source.ts +24 -24
  101. package/src/lib/api/load-in-batches.ts +16 -11
  102. package/src/lib/api/load-loader.ts +163 -0
  103. package/src/lib/api/load.ts +78 -5
  104. package/src/lib/api/parse-file.ts +143 -0
  105. package/src/lib/api/parse-in-batches.ts +13 -5
  106. package/src/lib/api/parse-sync.ts +27 -2
  107. package/src/lib/api/parse.ts +44 -18
  108. package/src/lib/api/preload.ts +31 -0
  109. package/src/lib/api/register-loaders.ts +1 -1
  110. package/src/lib/api/select-loader.ts +57 -5
  111. package/src/lib/api/select-source.ts +7 -10
  112. package/src/lib/fetch/fetch-error-message.ts +1 -1
  113. package/src/lib/loader-utils/check-errors.ts +1 -1
  114. package/src/lib/loader-utils/get-data.ts +36 -0
  115. package/src/lib/loader-utils/get-fetch-function.ts +3 -2
  116. package/src/lib/loader-utils/loader-context.ts +5 -2
  117. package/src/lib/loader-utils/loggers.ts +28 -2
  118. package/src/lib/loader-utils/option-defaults.ts +2 -0
  119. package/src/lib/loader-utils/option-utils.ts +59 -2
  120. package/src/lib/utils/response-utils.ts +3 -3
  121. package/src/null-loader.ts +3 -3
package/dist/dist.dev.js CHANGED
@@ -39,10 +39,11 @@ var __exports__ = (() => {
39
39
  RequestScheduler: () => RequestScheduler,
40
40
  _BrowserFileSystem: () => BrowserFileSystem,
41
41
  _fetchProgress: () => fetchProgress,
42
- _selectSource: () => selectSource2,
42
+ _selectSource: () => selectSource,
43
43
  _unregisterLoaders: () => _unregisterLoaders,
44
44
  assert: () => assert,
45
45
  concatenateArrayBuffersAsync: () => concatenateArrayBuffersAsync,
46
+ coreApi: () => coreApi,
46
47
  createDataSource: () => createDataSource,
47
48
  document: () => document_,
48
49
  encode: () => encode,
@@ -78,8 +79,11 @@ var __exports__ = (() => {
78
79
  makeTextDecoderIterator: () => makeTextDecoderIterator,
79
80
  makeTextEncoderIterator: () => makeTextEncoderIterator,
80
81
  parse: () => parse,
82
+ parseFile: () => parseFile,
81
83
  parseInBatches: () => parseInBatches,
82
84
  parseSync: () => parseSync,
85
+ preload: () => preload,
86
+ preloadSync: () => preloadSync,
83
87
  readArrayBuffer: () => readArrayBuffer,
84
88
  registerLoaders: () => registerLoaders,
85
89
  resolvePath: () => resolvePath,
@@ -706,16 +710,11 @@ var __exports__ = (() => {
706
710
  var NPM_TAG = "latest";
707
711
 
708
712
  // ../worker-utils/src/lib/env-utils/version.ts
709
- var warningIssued = false;
710
713
  function getVersion() {
711
714
  if (!globalThis._loadersgl_?.version) {
712
715
  globalThis._loadersgl_ = globalThis._loadersgl_ || {};
713
- if (typeof __VERSION__ === "undefined" && !warningIssued) {
714
- console.warn(
715
- "loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN."
716
- );
716
+ if (typeof __VERSION__ === "undefined") {
717
717
  globalThis._loadersgl_.version = NPM_TAG;
718
- warningIssued = true;
719
718
  } else {
720
719
  globalThis._loadersgl_.version = __VERSION__;
721
720
  }
@@ -930,6 +929,18 @@ var __exports__ = (() => {
930
929
  this.worker.terminate();
931
930
  this.terminated = true;
932
931
  }
932
+ /** Keeps this worker from preventing Node.js process exit while idle. */
933
+ unref() {
934
+ if (!isBrowser3 && typeof this.worker.unref === "function") {
935
+ this.worker.unref();
936
+ }
937
+ }
938
+ /** Keeps this worker alive while it is actively processing a job. */
939
+ ref() {
940
+ if (!isBrowser3 && typeof this.worker.ref === "function") {
941
+ this.worker.ref();
942
+ }
943
+ }
933
944
  get isRunning() {
934
945
  return Boolean(this.onMessage);
935
946
  }
@@ -1000,7 +1011,7 @@ var __exports__ = (() => {
1000
1011
  worker.on("error", (error) => {
1001
1012
  this.onError(error);
1002
1013
  });
1003
- worker.on("exit", (code) => {
1014
+ worker.on("exit", (_code) => {
1004
1015
  });
1005
1016
  return worker;
1006
1017
  }
@@ -1061,9 +1072,9 @@ var __exports__ = (() => {
1061
1072
  this.onDebug = props.onDebug;
1062
1073
  }
1063
1074
  }
1064
- async startJob(name, onMessage3 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
1075
+ async startJob(name, onMessage2 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
1065
1076
  const startPromise = new Promise((onStart) => {
1066
- this.jobQueue.push({ name, onMessage: onMessage3, onError, onStart });
1077
+ this.jobQueue.push({ name, onMessage: onMessage2, onError, onStart });
1067
1078
  return this;
1068
1079
  });
1069
1080
  this._startQueuedJob();
@@ -1091,13 +1102,13 @@ var __exports__ = (() => {
1091
1102
  backlog: this.jobQueue.length
1092
1103
  });
1093
1104
  const job = new WorkerJob(queuedJob.name, workerThread);
1105
+ workerThread.ref();
1094
1106
  workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload);
1095
1107
  workerThread.onError = (error) => queuedJob.onError(job, error);
1096
1108
  queuedJob.onStart(job);
1097
1109
  try {
1098
1110
  await job.result;
1099
- } catch (error) {
1100
- console.error(`Worker exception: ${error}`);
1111
+ } catch {
1101
1112
  } finally {
1102
1113
  this.returnWorkerToQueue(workerThread);
1103
1114
  }
@@ -1113,9 +1124,7 @@ var __exports__ = (() => {
1113
1124
  */
1114
1125
  returnWorkerToQueue(worker) {
1115
1126
  const shouldDestroyWorker = (
1116
- // Workers on Node.js prevent the process from exiting.
1117
- // Until we figure out how to close them before exit, we always destroy them
1118
- !isBrowser3 || // If the pool is destroyed, there is no reason to keep the worker around
1127
+ // If the pool is destroyed, there is no reason to keep the worker around
1119
1128
  this.isDestroyed || // If the app has disabled worker reuse, any completed workers should be destroyed
1120
1129
  !this.reuseWorkers || // If concurrency has been lowered, this worker might be surplus to requirements
1121
1130
  this.count > this._getMaxConcurrency()
@@ -1124,6 +1133,7 @@ var __exports__ = (() => {
1124
1133
  worker.destroy();
1125
1134
  this.count--;
1126
1135
  } else {
1136
+ worker.unref();
1127
1137
  this.idleQueue.push(worker);
1128
1138
  }
1129
1139
  if (!this.isDestroyed) {
@@ -1233,6 +1243,7 @@ var __exports__ = (() => {
1233
1243
  __publicField(WorkerFarm, "_workerFarm");
1234
1244
 
1235
1245
  // ../worker-utils/src/lib/worker-api/get-worker-url.ts
1246
+ var warnedWorkerVersionFallbacks = /* @__PURE__ */ new Set();
1236
1247
  function getWorkerName(worker) {
1237
1248
  const warning = worker.version !== VERSION3 ? ` (worker-utils@${VERSION3})` : "";
1238
1249
  return `${worker.name}@${worker.version}${warning}`;
@@ -1259,13 +1270,33 @@ var __exports__ = (() => {
1259
1270
  }
1260
1271
  const versionTag = version2 ? `@${version2}` : "";
1261
1272
  url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
1273
+ warnIfUsingNpmTagFallback(worker, url);
1262
1274
  }
1263
1275
  assert3(url);
1264
1276
  return url;
1265
1277
  }
1278
+ function warnIfUsingNpmTagFallback(worker, url) {
1279
+ if (worker.version !== "latest") {
1280
+ return;
1281
+ }
1282
+ const workerId = `${worker.module}:${worker.id}`;
1283
+ if (warnedWorkerVersionFallbacks.has(workerId)) {
1284
+ return;
1285
+ }
1286
+ warnedWorkerVersionFallbacks.add(workerId);
1287
+ console.warn(
1288
+ `loaders.gl: ${worker.name} loader worker version is "latest" because __VERSION__ was not injected. Fetching ${url} from CDN.`
1289
+ );
1290
+ }
1266
1291
 
1267
1292
  // ../worker-utils/src/lib/worker-api/process-on-worker.ts
1268
- async function processOnWorker(worker, data, options = {}, context = {}) {
1293
+ function canProcessOnWorker(worker, options) {
1294
+ if (!WorkerFarm.isSupported()) {
1295
+ return false;
1296
+ }
1297
+ return worker.worker && options?.worker;
1298
+ }
1299
+ async function processOnWorker(worker, data, options = {}, context = {}, jobContext = {}) {
1269
1300
  const name = getWorkerName(worker);
1270
1301
  const workerFarm = WorkerFarm.getWorkerFarm(options);
1271
1302
  const { source } = options;
@@ -1281,7 +1312,12 @@ var __exports__ = (() => {
1281
1312
  onMessage.bind(null, context)
1282
1313
  );
1283
1314
  const transferableOptions = getTransferListForWriter(options);
1284
- job.postMessage("process", { input: data, options: transferableOptions });
1315
+ const transferableContext = getTransferListForWriter(jobContext);
1316
+ job.postMessage("process", {
1317
+ input: data,
1318
+ options: transferableOptions,
1319
+ context: transferableContext
1320
+ });
1285
1321
  const result = await job.result;
1286
1322
  return result.result;
1287
1323
  }
@@ -1300,7 +1336,7 @@ var __exports__ = (() => {
1300
1336
  job.postMessage("error", { id, error: "Worker not set up to process on main thread" });
1301
1337
  return;
1302
1338
  }
1303
- const result = await context.process(input, options);
1339
+ const result = await context.process(input, options, void 0, payload.context || {});
1304
1340
  job.postMessage("done", { id, result });
1305
1341
  } catch (error) {
1306
1342
  const message = error instanceof Error ? error.message : "unknown error";
@@ -1324,59 +1360,68 @@ var __exports__ = (() => {
1324
1360
 
1325
1361
  // ../loader-utils/src/lib/worker-loader-utils/parse-with-worker.ts
1326
1362
  function canParseWithWorker(loader, options) {
1327
- if (!WorkerFarm.isSupported()) {
1363
+ const workerOptions = getWorkerOptions(options);
1364
+ const nodeWorkers = workerOptions._nodeWorkers;
1365
+ if (!isBrowser3 && !nodeWorkers) {
1328
1366
  return false;
1329
1367
  }
1330
- const nodeWorkers = options?._nodeWorkers ?? options?.core?._nodeWorkers;
1331
- if (!isBrowser3 && !nodeWorkers) {
1368
+ if (loader.id === "excel" && options?.excel?.shape === "arrow-table" || loader.id === "ply" && options?.ply?.shape === "arrow-table") {
1332
1369
  return false;
1333
1370
  }
1334
- const useWorkers = options?.worker ?? options?.core?.worker;
1335
- return Boolean(loader.worker && useWorkers);
1371
+ if (loader.id === "csv" && !shouldParseCSVWithWorker(options)) {
1372
+ return false;
1373
+ }
1374
+ return Boolean(canProcessOnWorker(loader, workerOptions));
1336
1375
  }
1337
1376
  async function parseWithWorker(loader, data, options, context, parseOnMainThread) {
1338
- const name = loader.id;
1339
- const url = getWorkerURL(loader, options);
1340
- const workerFarm = WorkerFarm.getWorkerFarm(options?.core);
1341
- const workerPool = workerFarm.getWorkerPool({ name, url });
1342
- options = JSON.parse(JSON.stringify(options));
1343
- context = JSON.parse(JSON.stringify(context || {}));
1344
- const job = await workerPool.startJob(
1345
- "process-on-worker",
1346
- // @ts-expect-error
1347
- onMessage2.bind(null, parseOnMainThread)
1348
- // eslint-disable-line @typescript-eslint/no-misused-promises
1377
+ const result = await processOnWorker(
1378
+ loader,
1379
+ data,
1380
+ getWorkerOptions(options),
1381
+ {
1382
+ process: async (input, processOptions, _workerContext, parseContext) => {
1383
+ if (!parseOnMainThread) {
1384
+ throw new Error("Worker not set up to parse on main thread");
1385
+ }
1386
+ const mainThreadContext = context ? { ...context, ...parseContext || {} } : void 0;
1387
+ return await callParseOnMainThread(
1388
+ parseOnMainThread,
1389
+ input,
1390
+ processOptions,
1391
+ mainThreadContext
1392
+ );
1393
+ }
1394
+ },
1395
+ getSerializableLoaderContext(context)
1349
1396
  );
1350
- job.postMessage("process", {
1351
- // @ts-ignore
1352
- input: data,
1353
- options,
1354
- context
1355
- });
1356
- const result = await job.result;
1357
- return await result.result;
1397
+ return isLoaderWithWorkerResultDeserializer(loader) ? loader.deserializeWorkerResult(result, options, context) : result;
1358
1398
  }
1359
- async function onMessage2(parseOnMainThread, job, type, payload) {
1360
- switch (type) {
1361
- case "done":
1362
- job.done(payload);
1363
- break;
1364
- case "error":
1365
- job.error(new Error(payload.error));
1366
- break;
1367
- case "process":
1368
- const { id, input, options } = payload;
1369
- try {
1370
- const result = await parseOnMainThread(input, options);
1371
- job.postMessage("done", { id, result });
1372
- } catch (error) {
1373
- const message = error instanceof Error ? error.message : "unknown error";
1374
- job.postMessage("error", { id, error: message });
1375
- }
1376
- break;
1377
- default:
1378
- console.warn(`parse-with-worker unknown message ${type}`);
1399
+ function callParseOnMainThread(parseOnMainThread, input, options, context) {
1400
+ if (parseOnMainThread.length <= 2) {
1401
+ return parseOnMainThread(input, options);
1379
1402
  }
1403
+ return parseOnMainThread(input, void 0, options, context);
1404
+ }
1405
+ function getWorkerOptions(options = {}) {
1406
+ const serializedOptions = JSON.parse(JSON.stringify(options));
1407
+ return {
1408
+ ...serializedOptions.core,
1409
+ ...serializedOptions
1410
+ };
1411
+ }
1412
+ function getSerializableLoaderContext(context) {
1413
+ if (!context) {
1414
+ return {};
1415
+ }
1416
+ const { fetch: fetch2, loaders, coreApi: coreApi2, _parse, _parseSync, _parseInBatches, ...serializableContext } = context;
1417
+ return JSON.parse(JSON.stringify(serializableContext));
1418
+ }
1419
+ function shouldParseCSVWithWorker(options) {
1420
+ const csvOptions = options;
1421
+ return (csvOptions?.csv?.shape ?? csvOptions?.core?.shape) === "arrow-table";
1422
+ }
1423
+ function isLoaderWithWorkerResultDeserializer(loader) {
1424
+ return typeof loader.deserializeWorkerResult === "function";
1380
1425
  }
1381
1426
 
1382
1427
  // ../loader-utils/src/lib/worker-loader-utils/encode-with-worker.ts
@@ -1442,10 +1487,12 @@ var __exports__ = (() => {
1442
1487
  for await (const textChunk of textIterator) {
1443
1488
  previous += textChunk;
1444
1489
  let eolIndex;
1445
- while ((eolIndex = previous.indexOf("\n")) >= 0) {
1490
+ eolIndex = previous.indexOf("\n");
1491
+ while (eolIndex >= 0) {
1446
1492
  const line = previous.slice(0, eolIndex + 1);
1447
1493
  previous = previous.slice(eolIndex + 1);
1448
1494
  yield line;
1495
+ eolIndex = previous.indexOf("\n");
1449
1496
  }
1450
1497
  }
1451
1498
  if (previous.length > 0) {
@@ -1901,6 +1948,8 @@ var __exports__ = (() => {
1901
1948
  id: "json",
1902
1949
  module: "json",
1903
1950
  version: VERSION4,
1951
+ encoding: "json",
1952
+ format: "json",
1904
1953
  extensions: ["json", "geojson"],
1905
1954
  mimeTypes: ["application/json"],
1906
1955
  category: "json",
@@ -2186,6 +2235,11 @@ var __exports__ = (() => {
2186
2235
  }
2187
2236
  };
2188
2237
 
2238
+ // ../loader-utils/src/source-types.ts
2239
+ function isSourceLoader(loader) {
2240
+ return Boolean(loader && typeof loader === "object" && "createDataSource" in loader);
2241
+ }
2242
+
2189
2243
  // src/lib/fetch/fetch-error.ts
2190
2244
  var FetchError = class extends Error {
2191
2245
  constructor(message, info) {
@@ -2337,7 +2391,7 @@ var __exports__ = (() => {
2337
2391
  try {
2338
2392
  const contentType = response.headers.get("Content-Type");
2339
2393
  info.reason = !response.bodyUsed && contentType?.includes("application/json") ? await response.json() : await response.text();
2340
- } catch (error) {
2394
+ } catch (_error) {
2341
2395
  }
2342
2396
  return new FetchError(message, info);
2343
2397
  }
@@ -2413,37 +2467,64 @@ var __exports__ = (() => {
2413
2467
  // src/lib/loader-utils/loggers.ts
2414
2468
  var probeLog = new ProbeLog({ id: "loaders.gl" });
2415
2469
  var NullLog = class {
2470
+ /** Drops a log message. */
2416
2471
  log() {
2417
2472
  return () => {
2418
2473
  };
2419
2474
  }
2475
+ /** Drops an info message. */
2420
2476
  info() {
2421
2477
  return () => {
2422
2478
  };
2423
2479
  }
2480
+ /** Logs one message once; no-op for the null logger. */
2481
+ once() {
2482
+ return () => {
2483
+ };
2484
+ }
2485
+ /** Drops a warning message. */
2424
2486
  warn() {
2425
2487
  return () => {
2426
2488
  };
2427
2489
  }
2490
+ /** Drops an error message. */
2428
2491
  error() {
2429
2492
  return () => {
2430
2493
  };
2431
2494
  }
2432
2495
  };
2433
2496
  var ConsoleLog = class {
2497
+ /** Console-like object used for message output. */
2434
2498
  console;
2499
+ /** Messages already emitted through `once`. */
2500
+ onceMessages = /* @__PURE__ */ new Set();
2501
+ /** Creates a console-backed logger. */
2435
2502
  constructor() {
2436
2503
  this.console = console;
2437
2504
  }
2505
+ /** Logs a message to the console. */
2438
2506
  log(...args) {
2439
2507
  return this.console.log.bind(this.console, ...args);
2440
2508
  }
2509
+ /** Logs an informational message to the console. */
2441
2510
  info(...args) {
2442
2511
  return this.console.info.bind(this.console, ...args);
2443
2512
  }
2513
+ /** Logs one message once to the console. */
2514
+ once(...args) {
2515
+ const message = String(args[0]);
2516
+ if (this.onceMessages.has(message)) {
2517
+ return () => {
2518
+ };
2519
+ }
2520
+ this.onceMessages.add(message);
2521
+ return this.console.info.bind(this.console, ...args);
2522
+ }
2523
+ /** Logs a warning message to the console. */
2444
2524
  warn(...args) {
2445
2525
  return this.console.warn.bind(this.console, ...args);
2446
2526
  }
2527
+ /** Logs an error message to the console. */
2447
2528
  error(...args) {
2448
2529
  return this.console.error.bind(this.console, ...args);
2449
2530
  }
@@ -2459,6 +2540,7 @@ var __exports__ = (() => {
2459
2540
  fallbackMimeType: void 0,
2460
2541
  ignoreRegisteredLoaders: void 0,
2461
2542
  nothrow: false,
2543
+ shape: void 0,
2462
2544
  log: new ConsoleLog(),
2463
2545
  // A probe.gl compatible (`log.log()()` syntax) that just logs to console
2464
2546
  useLocalLibraries: false,
@@ -2504,6 +2586,7 @@ var __exports__ = (() => {
2504
2586
  _worker: "core._workerType",
2505
2587
  limit: "core.limit",
2506
2588
  _limitMB: "core._limitMB",
2589
+ shape: "core.shape",
2507
2590
  batchSize: "core.batchSize",
2508
2591
  batchDebounceMs: "core.batchDebounceMs",
2509
2592
  metadata: "core.metadata",
@@ -2542,10 +2625,12 @@ var __exports__ = (() => {
2542
2625
  "maxConcurrency",
2543
2626
  "maxMobileConcurrency",
2544
2627
  "reuseWorkers",
2628
+ "workerTransferBufferCopy",
2545
2629
  "_nodeWorkers",
2546
2630
  "_workerType",
2547
2631
  "limit",
2548
2632
  "_limitMB",
2633
+ "shape",
2549
2634
  "batchSize",
2550
2635
  "batchDebounceMs",
2551
2636
  "metadata",
@@ -2656,10 +2741,34 @@ var __exports__ = (() => {
2656
2741
  mergeNestedFields(mergedOptions, normalizeLoaderOptions(getGlobalLoaderOptions()));
2657
2742
  const userOptions = normalizeLoaderOptions(options);
2658
2743
  mergeNestedFields(mergedOptions, userOptions);
2744
+ applyCoreShapeDefault(mergedOptions, userOptions, loader);
2659
2745
  addUrlOptions(mergedOptions, url);
2660
2746
  addDeprecatedTopLevelOptions(mergedOptions);
2661
2747
  return mergedOptions;
2662
2748
  }
2749
+ function applyCoreShapeDefault(mergedOptions, userOptions, loader) {
2750
+ const coreShape = mergedOptions.core?.shape;
2751
+ if (coreShape === void 0) {
2752
+ return;
2753
+ }
2754
+ const loaderScopedDefaults = loader.options?.[loader.id];
2755
+ if (!isPureObject(loaderScopedDefaults) || !("shape" in loaderScopedDefaults)) {
2756
+ return;
2757
+ }
2758
+ const globalLoaderScopedOptions = getGlobalLoaderOptions()[loader.id];
2759
+ if (isPureObject(globalLoaderScopedOptions) && "shape" in globalLoaderScopedOptions) {
2760
+ return;
2761
+ }
2762
+ const userLoaderScopedOptions = userOptions[loader.id];
2763
+ if (isPureObject(userLoaderScopedOptions) && "shape" in userLoaderScopedOptions) {
2764
+ return;
2765
+ }
2766
+ const loaderScopedOptions = mergedOptions[loader.id];
2767
+ mergedOptions[loader.id] = {
2768
+ ...isPureObject(loaderScopedOptions) ? loaderScopedOptions : {},
2769
+ shape: coreShape
2770
+ };
2771
+ }
2663
2772
  function mergeNestedFields(mergedOptions, options) {
2664
2773
  for (const key in options) {
2665
2774
  if (key in options) {
@@ -2701,7 +2810,8 @@ var __exports__ = (() => {
2701
2810
  }
2702
2811
  for (const key of CORE_LOADER_OPTION_KEYS) {
2703
2812
  if (options[key] !== void 0) {
2704
- const coreOptions = options.core = options.core || {};
2813
+ options.core ||= {};
2814
+ const coreOptions = options.core;
2705
2815
  const coreRecord = coreOptions;
2706
2816
  if (coreRecord[key] === void 0) {
2707
2817
  coreRecord[key] = options[key];
@@ -2861,16 +2971,27 @@ var __exports__ = (() => {
2861
2971
  const testUrl = stripQueryString(url) || context?.url;
2862
2972
  let loader = null;
2863
2973
  let reason = "";
2974
+ const sourceType = options?.core && "type" in options.core ? options.core.type : void 0;
2975
+ if (sourceType && sourceType !== "auto") {
2976
+ loader = findSourceLoaderByType(loaders, sourceType);
2977
+ reason = loader ? `match forced by supplied source type ${sourceType}` : "";
2978
+ }
2864
2979
  if (options?.core?.mimeType) {
2865
2980
  loader = findLoaderByMIMEType(loaders, options?.core?.mimeType);
2866
2981
  reason = `match forced by supplied MIME type ${options?.core?.mimeType}`;
2867
2982
  }
2983
+ loader = loader || findSourceLoaderByTestURL(loaders, testUrl);
2984
+ reason = reason || (loader ? `matched source url ${testUrl}` : "");
2868
2985
  loader = loader || findLoaderByUrl(loaders, testUrl);
2869
2986
  reason = reason || (loader ? `matched url ${testUrl}` : "");
2870
2987
  loader = loader || findLoaderByMIMEType(loaders, type);
2871
2988
  reason = reason || (loader ? `matched MIME type ${type}` : "");
2872
2989
  loader = loader || findLoaderByInitialBytes(loaders, data);
2873
2990
  reason = reason || (loader ? `matched initial data ${getFirstCharacters(data)}` : "");
2991
+ if (!loader && isBlob(data)) {
2992
+ loader = findSourceLoaderByTestData(loaders, data);
2993
+ reason = reason || (loader ? "matched source testData" : "");
2994
+ }
2874
2995
  if (options?.core?.fallbackMimeType) {
2875
2996
  loader = loader || findLoaderByMIMEType(loaders, options?.core?.fallbackMimeType);
2876
2997
  reason = reason || (loader ? `matched fallback MIME type ${type}` : "");
@@ -2920,6 +3041,35 @@ var __exports__ = (() => {
2920
3041
  }
2921
3042
  return null;
2922
3043
  }
3044
+ function findSourceLoaderByType(loaders, type) {
3045
+ for (const loader of loaders) {
3046
+ if (isSourceLoader(loader) && loader.type === type) {
3047
+ return loader;
3048
+ }
3049
+ }
3050
+ return null;
3051
+ }
3052
+ function findSourceLoaderByTestURL(loaders, url) {
3053
+ if (!url) {
3054
+ return null;
3055
+ }
3056
+ for (const loader of loaders) {
3057
+ if (isSourceLoader(loader) && loader.testURL(url)) {
3058
+ return loader;
3059
+ }
3060
+ }
3061
+ return null;
3062
+ }
3063
+ function findSourceLoaderByTestData(loaders, data) {
3064
+ for (const loader of loaders) {
3065
+ if (isSourceLoader(loader)) {
3066
+ if (loader.testData?.(data)) {
3067
+ return loader;
3068
+ }
3069
+ }
3070
+ }
3071
+ return null;
3072
+ }
2923
3073
  function findLoaderByMIMEType(loaders, mimeType) {
2924
3074
  for (const loader of loaders) {
2925
3075
  if (loader.mimeTypes?.some((mimeType1) => compareMIMETypes(mimeType, mimeType1))) {
@@ -3063,7 +3213,7 @@ var __exports__ = (() => {
3063
3213
  }
3064
3214
  yield toArrayBuffer2(value);
3065
3215
  }
3066
- } catch (error) {
3216
+ } catch (_error) {
3067
3217
  reader.releaseLock();
3068
3218
  }
3069
3219
  }
@@ -3135,6 +3285,28 @@ var __exports__ = (() => {
3135
3285
  }
3136
3286
  throw new Error(ERR_DATA);
3137
3287
  }
3288
+ async function getArrayBufferFromData(data, options) {
3289
+ if (typeof data === "string") {
3290
+ return new TextEncoder().encode(data).buffer;
3291
+ }
3292
+ if (isArrayBufferLike(data)) {
3293
+ return toArrayBuffer2(toArrayBufferView(data));
3294
+ }
3295
+ if (isBlob(data)) {
3296
+ data = await makeResponse(data);
3297
+ }
3298
+ if (isResponse(data)) {
3299
+ await checkResponse(data);
3300
+ return await data.arrayBuffer();
3301
+ }
3302
+ if (isReadableStream(data)) {
3303
+ data = makeIterator(data, options);
3304
+ }
3305
+ if (isIterable(data) || isAsyncIterable(data)) {
3306
+ return concatenateArrayBuffersAsync(data);
3307
+ }
3308
+ throw new Error(ERR_DATA);
3309
+ }
3138
3310
  async function getAsyncIterableFromData(data, options) {
3139
3311
  if (isPromise(data)) {
3140
3312
  data = await data;
@@ -3198,91 +3370,156 @@ var __exports__ = (() => {
3198
3370
  return fetchFile;
3199
3371
  }
3200
3372
 
3201
- // src/lib/loader-utils/loader-context.ts
3202
- function getLoaderContext(context, options, parentContext) {
3203
- if (parentContext) {
3204
- return parentContext;
3373
+ // src/lib/api/load-loader.ts
3374
+ var loaderImplementationPromises = /* @__PURE__ */ new Map();
3375
+ var loaderImplementations = /* @__PURE__ */ new Map();
3376
+ async function getLoaderImplementation(loader, options, url) {
3377
+ if (isLoaderWithParser(loader)) {
3378
+ return loader;
3205
3379
  }
3206
- const newContext = {
3207
- fetch: getFetchFunction(options, context),
3208
- ...context
3209
- };
3210
- if (newContext.url) {
3211
- const baseUrl = stripQueryString(newContext.url);
3212
- newContext.baseUrl = baseUrl;
3213
- newContext.queryString = extractQueryString(newContext.url);
3214
- newContext.filename = path_exports.filename(baseUrl);
3215
- newContext.baseUrl = path_exports.dirname(baseUrl);
3380
+ const implementationCacheKey = getLoaderImplementationCacheKey(loader, options);
3381
+ const loaderImplementation = loaderImplementations.get(loader)?.get(implementationCacheKey);
3382
+ if (loaderImplementation) {
3383
+ return loaderImplementation;
3384
+ }
3385
+ let loaderImplementationPromisesForLoader = loaderImplementationPromises.get(loader);
3386
+ if (!loaderImplementationPromisesForLoader) {
3387
+ loaderImplementationPromisesForLoader = /* @__PURE__ */ new Map();
3388
+ loaderImplementationPromises.set(loader, loaderImplementationPromisesForLoader);
3389
+ }
3390
+ let loaderImplementationPromise = loaderImplementationPromisesForLoader.get(implementationCacheKey);
3391
+ if (!loaderImplementationPromise) {
3392
+ loaderImplementationPromise = resolveLoaderImplementation(loader, options, url).then((implementation) => {
3393
+ let loaderImplementationsForLoader = loaderImplementations.get(loader);
3394
+ if (!loaderImplementationsForLoader) {
3395
+ loaderImplementationsForLoader = /* @__PURE__ */ new Map();
3396
+ loaderImplementations.set(loader, loaderImplementationsForLoader);
3397
+ }
3398
+ loaderImplementationsForLoader.set(implementationCacheKey, implementation);
3399
+ return implementation;
3400
+ }).catch((error) => {
3401
+ loaderImplementationPromisesForLoader.delete(implementationCacheKey);
3402
+ if (loaderImplementationPromisesForLoader.size === 0) {
3403
+ loaderImplementationPromises.delete(loader);
3404
+ }
3405
+ throw error;
3406
+ });
3407
+ loaderImplementationPromisesForLoader.set(implementationCacheKey, loaderImplementationPromise);
3216
3408
  }
3217
- if (!Array.isArray(newContext.loaders)) {
3218
- newContext.loaders = null;
3409
+ return await loaderImplementationPromise;
3410
+ }
3411
+ function getLoaderImplementationSync(loader) {
3412
+ if (isLoaderWithParser(loader)) {
3413
+ return loader;
3219
3414
  }
3220
- return newContext;
3415
+ const implementationCacheKey = getLoaderImplementationCacheKey(loader);
3416
+ return loaderImplementations.get(loader)?.get(implementationCacheKey) || null;
3221
3417
  }
3222
- function getLoadersFromContext(loaders, context) {
3223
- if (loaders && !Array.isArray(loaders)) {
3224
- return loaders;
3418
+ function isLoaderWithParser(loader) {
3419
+ const candidate = loader;
3420
+ return Boolean(
3421
+ candidate.parse || candidate.parseSync || candidate.parseInBatches || candidate.parseText || candidate.parseTextSync || candidate.parseFile || candidate.parseFileInBatches
3422
+ );
3423
+ }
3424
+ async function resolveLoaderImplementation(loader, options, url) {
3425
+ if (loader.preload) {
3426
+ const preloadedLoader = await loader.preload(url || "", options);
3427
+ if (isLoaderWithParser(preloadedLoader)) {
3428
+ return preloadedLoader;
3429
+ }
3430
+ throw new Error(`${loader.id} loader preload() did not return a parser-bearing loader`);
3225
3431
  }
3226
- let candidateLoaders;
3227
- if (loaders) {
3228
- candidateLoaders = Array.isArray(loaders) ? loaders : [loaders];
3432
+ const implementationSpecifier = getLoaderImplementationSpecifier(loader, options);
3433
+ return await importLoaderImplementation(implementationSpecifier, loader.id);
3434
+ }
3435
+ function getLoaderImplementationSpecifier(loader, options) {
3436
+ const workerType = options?._workerType || options?.core?._workerType;
3437
+ if (workerType === "test") {
3438
+ const sourcePath = `modules/${loader.module}/src/${loader.id}-loader.ts`;
3439
+ if (typeof window !== "undefined") {
3440
+ return `/${sourcePath}`;
3441
+ }
3442
+ if (typeof process !== "undefined" && process.cwd) {
3443
+ return new URL(sourcePath, `file://${process.cwd()}/`).toString();
3444
+ }
3445
+ return sourcePath;
3229
3446
  }
3230
- if (context && context.loaders) {
3231
- const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders];
3232
- candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders;
3447
+ throw new Error(
3448
+ `${loader.id} loader does not provide a parser implementation. Import a parser-bearing loader directly, or use preload() before parse/load.`
3449
+ );
3450
+ }
3451
+ function getLoaderImplementationCacheKey(loader, options) {
3452
+ const loaderOptions = options?.[loader.id];
3453
+ const defaultLoaderOptions = loader.options?.[loader.id];
3454
+ return String(
3455
+ loaderOptions?.backend || getDeprecatedImplementationBackend(loaderOptions?.implementation) || defaultLoaderOptions?.backend || ""
3456
+ );
3457
+ }
3458
+ function getDeprecatedImplementationBackend(implementation) {
3459
+ return implementation === "js" ? "typescript" : implementation;
3460
+ }
3461
+ async function importLoaderImplementation(implementationSpecifier, loaderId) {
3462
+ const moduleExports = await import(
3463
+ /* webpackIgnore: true */
3464
+ /* @vite-ignore */
3465
+ implementationSpecifier
3466
+ );
3467
+ for (const exportValue of Object.values(moduleExports)) {
3468
+ if (exportValue && typeof exportValue === "object" && exportValue.id === loaderId && isLoaderWithParser(exportValue)) {
3469
+ return exportValue;
3470
+ }
3233
3471
  }
3234
- return candidateLoaders && candidateLoaders.length ? candidateLoaders : void 0;
3472
+ throw new Error(
3473
+ `Could not find parser implementation for ${loaderId} in ${implementationSpecifier}`
3474
+ );
3235
3475
  }
3236
3476
 
3237
- // src/lib/api/parse.ts
3238
- async function parse(data, loaders, options, context) {
3477
+ // src/lib/api/parse-file.ts
3478
+ async function parseFile(file, loaders, options, context) {
3239
3479
  if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {
3240
3480
  context = void 0;
3241
3481
  options = loaders;
3242
3482
  loaders = void 0;
3243
3483
  }
3244
- data = await data;
3245
3484
  options = options || {};
3246
- const url = getResourceUrl(data);
3485
+ const url = file.url || "";
3247
3486
  const typedLoaders = loaders;
3248
3487
  const candidateLoaders = getLoadersFromContext(typedLoaders, context);
3249
- const loader = await selectLoader(data, candidateLoaders, options);
3488
+ const loader = await selectLoader(url, candidateLoaders, options);
3250
3489
  if (!loader) {
3251
3490
  return null;
3252
3491
  }
3492
+ if (isSourceLoader(loader)) {
3493
+ throw new Error(
3494
+ `${loader.id} is a SourceLoader. Use load() to create a runtime source object instead of parseFile().`
3495
+ );
3496
+ }
3253
3497
  const strictOptions = normalizeOptions(options, loader, candidateLoaders, url);
3254
3498
  context = getLoaderContext(
3255
- // @ts-expect-error
3499
+ // @ts-expect-error candidateLoaders may be a single forced loader
3256
3500
  { url, _parse: parse, loaders: candidateLoaders },
3257
3501
  strictOptions,
3258
3502
  context || null
3259
3503
  );
3260
- return await parseWithLoader(loader, data, strictOptions, context);
3504
+ return await parseFileWithLoader(loader, file, strictOptions, context);
3261
3505
  }
3262
- async function parseWithLoader(loader, data, options, context) {
3506
+ async function parseFileWithLoader(loader, file, options, context) {
3263
3507
  validateWorkerVersion(loader);
3264
3508
  options = mergeOptions(loader.options, options);
3265
- if (isResponse(data)) {
3266
- const { ok, redirected, status, statusText, type, url } = data;
3267
- const headers = Object.fromEntries(data.headers.entries());
3268
- context.response = { headers, ok, redirected, status, statusText, type, url };
3269
- }
3270
- data = await getArrayBufferOrStringFromData(data, loader, options);
3271
- const loaderWithParser = loader;
3272
- if (loaderWithParser.parseTextSync && typeof data === "string") {
3273
- return loaderWithParser.parseTextSync(data, options, context);
3274
- }
3275
- if (canParseWithWorker(loader, options)) {
3276
- return await parseWithWorker(loader, data, options, context, parse);
3277
- }
3278
- if (loaderWithParser.parseText && typeof data === "string") {
3279
- return await loaderWithParser.parseText(data, options, context);
3280
- }
3281
- if (loaderWithParser.parse) {
3282
- return await loaderWithParser.parse(data, options, context);
3509
+ const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
3510
+ if (loaderWithParser.parseFile) {
3511
+ return await loaderWithParser.parseFile(file, options, context);
3512
+ }
3513
+ const parseFunction = loaderWithParser.parse;
3514
+ if (parseFunction) {
3515
+ const length = file.bigsize > 0n ? Number(file.bigsize) : file.size;
3516
+ if (!length) {
3517
+ throw new Error(`${loader.id} loader - cannot fall back to parse without a file size`);
3518
+ }
3519
+ const data = await file.read(0n, length);
3520
+ return await parse(data, loaderWithParser, options, context);
3283
3521
  }
3284
- assert3(!loaderWithParser.parseSync);
3285
- throw new Error(`${loader.id} loader - no parser found and worker is disabled`);
3522
+ throw new Error(`${loader.id} loader - no file parser found`);
3286
3523
  }
3287
3524
 
3288
3525
  // src/lib/api/parse-sync.ts
@@ -3299,6 +3536,11 @@ var __exports__ = (() => {
3299
3536
  if (!loader) {
3300
3537
  return null;
3301
3538
  }
3539
+ if (isSourceLoader(loader)) {
3540
+ throw new Error(
3541
+ `${loader.id} is a SourceLoader. Use load() to create a runtime source object instead of parseSync().`
3542
+ );
3543
+ }
3302
3544
  const strictOptions = normalizeOptions(options, loader, candidateLoaders);
3303
3545
  const url = getResourceUrl(data);
3304
3546
  const parse2 = () => {
@@ -3309,7 +3551,13 @@ var __exports__ = (() => {
3309
3551
  strictOptions,
3310
3552
  context || null
3311
3553
  );
3312
- return parseWithLoaderSync(loader, data, strictOptions, context);
3554
+ const loaderWithParser = getLoaderImplementationSync(loader);
3555
+ return parseWithLoaderSync(
3556
+ loaderWithParser || loader,
3557
+ data,
3558
+ strictOptions,
3559
+ context
3560
+ );
3313
3561
  }
3314
3562
  function parseWithLoaderSync(loader, data, options, context) {
3315
3563
  data = getArrayBufferOrStringFromDataSync(data, loader, options);
@@ -3319,6 +3567,11 @@ var __exports__ = (() => {
3319
3567
  if (loader.parseSync && data instanceof ArrayBuffer) {
3320
3568
  return loader.parseSync(data, options, context);
3321
3569
  }
3570
+ if (loader.preload) {
3571
+ throw new Error(
3572
+ `${loader.name} loader: 'parseSync' requires a parser-bearing loader. Import the loader implementation directly, or call preload(loader) before parseSync(). ${context.url || ""}`
3573
+ );
3574
+ }
3322
3575
  throw new Error(
3323
3576
  `${loader.name} loader: 'parseSync' not supported by this loader, use 'parse' instead. ${context.url || ""}`
3324
3577
  );
@@ -3387,9 +3640,10 @@ var __exports__ = (() => {
3387
3640
  strictOptions,
3388
3641
  context || null
3389
3642
  );
3390
- return await parseWithLoaderInBatches(loader, data, strictOptions, context);
3643
+ const loaderWithParser = await getLoaderImplementation(loader, strictOptions, context.url);
3644
+ return await parseWithLoaderInBatches(loader, loaderWithParser, data, strictOptions, context);
3391
3645
  }
3392
- async function parseWithLoaderInBatches(loader, data, options, context) {
3646
+ async function parseWithLoaderInBatches(originalLoader, loader, data, options, context) {
3393
3647
  const outputIterator = await parseToOutputIterator(loader, data, options, context);
3394
3648
  if (!options?.core?.metadata) {
3395
3649
  return outputIterator;
@@ -3398,7 +3652,7 @@ var __exports__ = (() => {
3398
3652
  shape: "metadata",
3399
3653
  batchType: "metadata",
3400
3654
  metadata: {
3401
- _loader: loader,
3655
+ _loader: originalLoader,
3402
3656
  _context: context
3403
3657
  },
3404
3658
  // Populate with some default fields to avoid crashing
@@ -3452,6 +3706,34 @@ var __exports__ = (() => {
3452
3706
  return iteratorChain;
3453
3707
  }
3454
3708
 
3709
+ // src/lib/api/load-in-batches.ts
3710
+ function loadInBatches(files, loaders, options, context) {
3711
+ let loadersArray;
3712
+ if (!Array.isArray(loaders) && !isLoaderObject(loaders)) {
3713
+ context = void 0;
3714
+ options = loaders;
3715
+ loadersArray = void 0;
3716
+ } else {
3717
+ loadersArray = loaders;
3718
+ }
3719
+ const fetch2 = getFetchFunction(options || {});
3720
+ if (!Array.isArray(files)) {
3721
+ return loadOneFileInBatches(files, loadersArray, options || {}, fetch2);
3722
+ }
3723
+ const promises = files.map(
3724
+ (file) => loadOneFileInBatches(file, loadersArray, options || {}, fetch2)
3725
+ );
3726
+ return promises;
3727
+ }
3728
+ async function loadOneFileInBatches(file, loaders, options, fetch2) {
3729
+ if (typeof file === "string") {
3730
+ const url = file;
3731
+ const response = await fetch2(url);
3732
+ return Array.isArray(loaders) ? await parseInBatches(response, loaders, options) : await parseInBatches(response, loaders, options);
3733
+ }
3734
+ return Array.isArray(loaders) ? await parseInBatches(file, loaders, options) : await parseInBatches(file, loaders, options);
3735
+ }
3736
+
3455
3737
  // src/lib/api/load.ts
3456
3738
  async function load(url, loaders, options, context) {
3457
3739
  let resolvedLoaders;
@@ -3464,6 +3746,59 @@ var __exports__ = (() => {
3464
3746
  resolvedLoaders = loaders;
3465
3747
  resolvedOptions = options;
3466
3748
  }
3749
+ if (!Array.isArray(resolvedLoaders) && isSourceLoader(resolvedLoaders)) {
3750
+ const runtimeCoreApi = {
3751
+ fetchFile,
3752
+ parse,
3753
+ parseFile,
3754
+ parseSync,
3755
+ parseInBatches,
3756
+ load,
3757
+ loadInBatches
3758
+ };
3759
+ return resolvedLoaders.createDataSource(
3760
+ url,
3761
+ resolvedOptions || {},
3762
+ runtimeCoreApi
3763
+ );
3764
+ }
3765
+ if (Array.isArray(resolvedLoaders) && resolvedLoaders.length === 1 && isSourceLoader(resolvedLoaders[0])) {
3766
+ const runtimeCoreApi = {
3767
+ fetchFile,
3768
+ parse,
3769
+ parseFile,
3770
+ parseSync,
3771
+ parseInBatches,
3772
+ load,
3773
+ loadInBatches
3774
+ };
3775
+ return resolvedLoaders[0].createDataSource(
3776
+ url,
3777
+ resolvedOptions || {},
3778
+ runtimeCoreApi
3779
+ );
3780
+ }
3781
+ if (typeof url === "string" || isBlob(url)) {
3782
+ const selectedLoader = await selectLoader(url, resolvedLoaders, {
3783
+ ...resolvedOptions,
3784
+ core: { ...resolvedOptions?.core, nothrow: true }
3785
+ });
3786
+ if (selectedLoader && isSourceLoader(selectedLoader)) {
3787
+ return selectedLoader.createDataSource(
3788
+ url,
3789
+ resolvedOptions || {},
3790
+ {
3791
+ fetchFile,
3792
+ parse,
3793
+ parseFile,
3794
+ parseSync,
3795
+ parseInBatches,
3796
+ load,
3797
+ loadInBatches
3798
+ }
3799
+ );
3800
+ }
3801
+ }
3467
3802
  const fetch2 = getFetchFunction(resolvedOptions);
3468
3803
  let data = url;
3469
3804
  if (typeof url === "string") {
@@ -3484,35 +3819,127 @@ var __exports__ = (() => {
3484
3819
  };
3485
3820
  }
3486
3821
  }
3487
- return Array.isArray(resolvedLoaders) ? await parse(data, resolvedLoaders, resolvedOptions) : await parse(data, resolvedLoaders, resolvedOptions);
3822
+ return Array.isArray(resolvedLoaders) ? await parse(data, resolvedLoaders, resolvedOptions, context) : await parse(data, resolvedLoaders, resolvedOptions, context);
3488
3823
  }
3489
3824
 
3490
- // src/lib/api/load-in-batches.ts
3491
- function loadInBatches(files, loaders, options, context) {
3492
- let loadersArray;
3493
- if (!Array.isArray(loaders) && !isLoaderObject(loaders)) {
3825
+ // src/lib/api/core-api.ts
3826
+ var coreApi = Object.freeze({
3827
+ fetchFile,
3828
+ parse,
3829
+ parseFile,
3830
+ parseSync,
3831
+ parseInBatches,
3832
+ load,
3833
+ loadInBatches
3834
+ });
3835
+
3836
+ // src/lib/loader-utils/loader-context.ts
3837
+ function getLoaderContext(context, options, parentContext) {
3838
+ if (parentContext) {
3839
+ return parentContext;
3840
+ }
3841
+ const newContext = {
3842
+ ...context,
3843
+ fetch: getFetchFunction(options, context),
3844
+ coreApi: context.coreApi || coreApi
3845
+ };
3846
+ if (newContext.url) {
3847
+ const baseUrl = stripQueryString(newContext.url);
3848
+ newContext.baseUrl = baseUrl;
3849
+ newContext.queryString = extractQueryString(newContext.url);
3850
+ newContext.filename = path_exports.filename(baseUrl);
3851
+ newContext.baseUrl = path_exports.dirname(baseUrl);
3852
+ }
3853
+ if (!Array.isArray(newContext.loaders)) {
3854
+ newContext.loaders = null;
3855
+ }
3856
+ return newContext;
3857
+ }
3858
+ function getLoadersFromContext(loaders, context) {
3859
+ if (loaders && !Array.isArray(loaders)) {
3860
+ return loaders;
3861
+ }
3862
+ let candidateLoaders;
3863
+ if (loaders) {
3864
+ candidateLoaders = Array.isArray(loaders) ? loaders : [loaders];
3865
+ }
3866
+ if (context && context.loaders) {
3867
+ const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders];
3868
+ candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders;
3869
+ }
3870
+ return candidateLoaders && candidateLoaders.length ? candidateLoaders : void 0;
3871
+ }
3872
+
3873
+ // src/lib/api/parse.ts
3874
+ async function parse(data, loaders, options, context) {
3875
+ if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {
3494
3876
  context = void 0;
3495
3877
  options = loaders;
3496
- loadersArray = void 0;
3497
- } else {
3498
- loadersArray = loaders;
3878
+ loaders = void 0;
3499
3879
  }
3500
- const fetch2 = getFetchFunction(options || {});
3501
- if (!Array.isArray(files)) {
3502
- return loadOneFileInBatches(files, loadersArray, options || {}, fetch2);
3880
+ data = await data;
3881
+ options = options || {};
3882
+ const url = getResourceUrl(data);
3883
+ const typedLoaders = loaders;
3884
+ const candidateLoaders = getLoadersFromContext(typedLoaders, context);
3885
+ const loader = await selectLoader(data, candidateLoaders, options);
3886
+ if (!loader) {
3887
+ return null;
3503
3888
  }
3504
- const promises = files.map(
3505
- (file) => loadOneFileInBatches(file, loadersArray, options || {}, fetch2)
3889
+ if (isSourceLoader(loader)) {
3890
+ throw new Error(
3891
+ `${loader.id} is a SourceLoader. Use load() to create a runtime source object instead of parse().`
3892
+ );
3893
+ }
3894
+ const strictOptions = normalizeOptions(options, loader, candidateLoaders, url);
3895
+ context = getLoaderContext(
3896
+ // @ts-expect-error
3897
+ { url, _parse: parse, loaders: candidateLoaders },
3898
+ strictOptions,
3899
+ context || null
3506
3900
  );
3507
- return promises;
3901
+ return await parseWithLoader(loader, data, strictOptions, context);
3508
3902
  }
3509
- async function loadOneFileInBatches(file, loaders, options, fetch2) {
3510
- if (typeof file === "string") {
3511
- const url = file;
3512
- const response = await fetch2(url);
3513
- return Array.isArray(loaders) ? await parseInBatches(response, loaders, options) : await parseInBatches(response, loaders, options);
3903
+ async function parseWithLoader(loader, data, options, context) {
3904
+ validateWorkerVersion(loader);
3905
+ options = mergeOptions(loader.options, options);
3906
+ if (isResponse(data)) {
3907
+ const { ok, redirected, status, statusText, type, url } = data;
3908
+ const headers = Object.fromEntries(data.headers.entries());
3909
+ context.response = { headers, ok, redirected, status, statusText, type, url };
3514
3910
  }
3515
- return Array.isArray(loaders) ? await parseInBatches(file, loaders, options) : await parseInBatches(file, loaders, options);
3911
+ const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
3912
+ if (canParseWithWorker(loaderWithParser, options)) {
3913
+ data = await getArrayBufferFromData(data, options);
3914
+ return await parseWithWorker(loaderWithParser, data, options, context, parse);
3915
+ }
3916
+ data = await getArrayBufferOrStringFromData(data, loader, options);
3917
+ return await parseWithLoaderImplementation(loaderWithParser, data, options, context);
3918
+ }
3919
+ async function parseWithLoaderImplementation(loader, data, options, context) {
3920
+ if (loader.parseText && typeof data === "string") {
3921
+ return await loader.parseText(data, options, context);
3922
+ }
3923
+ if (loader.parseTextSync && typeof data === "string") {
3924
+ return loader.parseTextSync(data, options, context);
3925
+ }
3926
+ if (loader.parse) {
3927
+ return await loader.parse(data, options, context);
3928
+ }
3929
+ if (loader.parseSync) {
3930
+ throw new Error(
3931
+ `${loader.name} loader: 'parse' not available on parser-bearing sync loader. Add an async 'parse' function to this loader, or call preload(loader) before parseSync(). ${context.url || ""}`
3932
+ );
3933
+ }
3934
+ throw new Error(`${loader.id} loader - no parser found and worker is disabled`);
3935
+ }
3936
+
3937
+ // src/lib/api/preload.ts
3938
+ async function preload(loader, options, url) {
3939
+ return await getLoaderImplementation(loader, options, url);
3940
+ }
3941
+ function preloadSync(loader) {
3942
+ return getLoaderImplementationSync(loader);
3516
3943
  }
3517
3944
 
3518
3945
  // src/lib/api/encode-table.ts
@@ -3638,20 +4065,18 @@ var __exports__ = (() => {
3638
4065
 
3639
4066
  // src/lib/api/create-data-source.ts
3640
4067
  function createDataSource(data, sources, options) {
3641
- const type = options?.core?.type || options.type || "auto";
3642
- const source = type === "auto" ? selectSource(data, sources) : getSourceOfType(type, sources);
4068
+ const resolvedOptions = options || {};
4069
+ const type = resolvedOptions?.core?.type || resolvedOptions.type || "auto";
4070
+ const source = sources.length === 1 ? sources[0] : type === "auto" ? selectLoaderSync(data, sources, {
4071
+ // `createDataSource` supports non-fetch inputs such as in-memory tables.
4072
+ // Selection remains best-effort for those cases.
4073
+ ...resolvedOptions,
4074
+ core: { ...resolvedOptions?.core, type: "auto" }
4075
+ }) : getSourceOfType(type, sources);
3643
4076
  if (!source) {
3644
4077
  throw new Error("Not a valid source type");
3645
4078
  }
3646
- return source.createDataSource(data, options);
3647
- }
3648
- function selectSource(url, sources) {
3649
- for (const service of sources) {
3650
- if (service.testURL && service.testURL(url)) {
3651
- return service;
3652
- }
3653
- }
3654
- return null;
4079
+ return source.createDataSource(data, resolvedOptions, coreApi);
3655
4080
  }
3656
4081
  function getSourceOfType(type, sources) {
3657
4082
  for (const service of sources) {
@@ -3663,15 +4088,11 @@ var __exports__ = (() => {
3663
4088
  }
3664
4089
 
3665
4090
  // src/lib/api/select-source.ts
3666
- function selectSource2(url, sources, options) {
4091
+ function selectSource(url, sources, options) {
3667
4092
  const type = options?.type || "auto";
3668
4093
  let selectedSource = null;
3669
4094
  if (type === "auto") {
3670
- for (const source of sources) {
3671
- if (typeof url === "string" && source.testURL && source.testURL(url)) {
3672
- return source;
3673
- }
3674
- }
4095
+ selectedSource = selectLoaderSync(url, sources, { core: { nothrow: true } });
3675
4096
  } else {
3676
4097
  selectedSource = getSourceOfType2(type, sources);
3677
4098
  }