@loaders.gl/core 4.4.5 → 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +14 -3
  2. package/dist/dist.dev.js +800 -271
  3. package/dist/dist.min.js +4 -3
  4. package/dist/index.cjs +2191 -296
  5. package/dist/index.cjs.map +3 -4
  6. package/dist/index.d.ts +8 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +7 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/iterators/make-iterator/make-stream-iterator.js +48 -9
  11. package/dist/iterators/make-iterator/make-stream-iterator.js.map +1 -1
  12. package/dist/lib/api/core-api.d.ts +6 -0
  13. package/dist/lib/api/core-api.d.ts.map +1 -0
  14. package/dist/lib/api/core-api.js +23 -0
  15. package/dist/lib/api/core-api.js.map +1 -0
  16. package/dist/lib/api/create-data-source.d.ts +2 -2
  17. package/dist/lib/api/create-data-source.d.ts.map +1 -1
  18. package/dist/lib/api/create-data-source.js +15 -14
  19. package/dist/lib/api/create-data-source.js.map +1 -1
  20. package/dist/lib/api/load-in-batches.d.ts +4 -4
  21. package/dist/lib/api/load-in-batches.d.ts.map +1 -1
  22. package/dist/lib/api/load-in-batches.js +1 -1
  23. package/dist/lib/api/load-in-batches.js.map +1 -1
  24. package/dist/lib/api/load-loader.d.ts +8 -0
  25. package/dist/lib/api/load-loader.d.ts.map +1 -0
  26. package/dist/lib/api/load-loader.js +110 -0
  27. package/dist/lib/api/load-loader.js.map +1 -0
  28. package/dist/lib/api/load.d.ts +2 -2
  29. package/dist/lib/api/load.d.ts.map +1 -1
  30. package/dist/lib/api/load.js +66 -3
  31. package/dist/lib/api/load.js.map +1 -1
  32. package/dist/lib/api/parse-file.d.ts +15 -0
  33. package/dist/lib/api/parse-file.d.ts.map +1 -0
  34. package/dist/lib/api/parse-file.js +70 -0
  35. package/dist/lib/api/parse-file.js.map +1 -0
  36. package/dist/lib/api/parse-in-batches.d.ts +2 -2
  37. package/dist/lib/api/parse-in-batches.d.ts.map +1 -1
  38. package/dist/lib/api/parse-in-batches.js +6 -4
  39. package/dist/lib/api/parse-in-batches.js.map +1 -1
  40. package/dist/lib/api/parse-sync.d.ts +2 -2
  41. package/dist/lib/api/parse-sync.d.ts.map +1 -1
  42. package/dist/lib/api/parse-sync.js +10 -1
  43. package/dist/lib/api/parse-sync.js.map +1 -1
  44. package/dist/lib/api/parse.d.ts +2 -2
  45. package/dist/lib/api/parse.d.ts.map +1 -1
  46. package/dist/lib/api/parse.js +28 -16
  47. package/dist/lib/api/parse.js.map +1 -1
  48. package/dist/lib/api/preload.d.ts +11 -0
  49. package/dist/lib/api/preload.d.ts.map +1 -0
  50. package/dist/lib/api/preload.js +14 -0
  51. package/dist/lib/api/preload.js.map +1 -0
  52. package/dist/lib/api/register-loaders.js +1 -1
  53. package/dist/lib/api/register-loaders.js.map +1 -1
  54. package/dist/lib/api/select-loader.d.ts.map +1 -1
  55. package/dist/lib/api/select-loader.js +48 -5
  56. package/dist/lib/api/select-loader.js.map +1 -1
  57. package/dist/lib/api/select-source.d.ts +3 -3
  58. package/dist/lib/api/select-source.d.ts.map +1 -1
  59. package/dist/lib/api/select-source.js +2 -5
  60. package/dist/lib/api/select-source.js.map +1 -1
  61. package/dist/lib/fetch/fetch-error-message.js +1 -1
  62. package/dist/lib/fetch/fetch-error-message.js.map +1 -1
  63. package/dist/lib/init.js +1 -1
  64. package/dist/lib/init.js.map +1 -1
  65. package/dist/lib/loader-utils/check-errors.js +1 -1
  66. package/dist/lib/loader-utils/check-errors.js.map +1 -1
  67. package/dist/lib/loader-utils/get-data.d.ts +4 -0
  68. package/dist/lib/loader-utils/get-data.d.ts.map +1 -1
  69. package/dist/lib/loader-utils/get-data.js +26 -0
  70. package/dist/lib/loader-utils/get-data.js.map +1 -1
  71. package/dist/lib/loader-utils/get-fetch-function.d.ts +1 -1
  72. package/dist/lib/loader-utils/get-fetch-function.d.ts.map +1 -1
  73. package/dist/lib/loader-utils/get-fetch-function.js +1 -1
  74. package/dist/lib/loader-utils/get-fetch-function.js.map +1 -1
  75. package/dist/lib/loader-utils/loader-context.d.ts +1 -1
  76. package/dist/lib/loader-utils/loader-context.d.ts.map +1 -1
  77. package/dist/lib/loader-utils/loader-context.js +3 -1
  78. package/dist/lib/loader-utils/loader-context.js.map +1 -1
  79. package/dist/lib/loader-utils/loggers.d.ts +19 -0
  80. package/dist/lib/loader-utils/loggers.d.ts.map +1 -1
  81. package/dist/lib/loader-utils/loggers.js +28 -2
  82. package/dist/lib/loader-utils/loggers.js.map +1 -1
  83. package/dist/lib/loader-utils/option-defaults.d.ts +1 -0
  84. package/dist/lib/loader-utils/option-defaults.d.ts.map +1 -1
  85. package/dist/lib/loader-utils/option-defaults.js +2 -0
  86. package/dist/lib/loader-utils/option-defaults.js.map +1 -1
  87. package/dist/lib/loader-utils/option-utils.d.ts.map +1 -1
  88. package/dist/lib/loader-utils/option-utils.js +50 -2
  89. package/dist/lib/loader-utils/option-utils.js.map +1 -1
  90. package/dist/lib/utils/response-utils.js +3 -3
  91. package/dist/lib/utils/response-utils.js.map +1 -1
  92. package/dist/null-loader.d.ts.map +1 -1
  93. package/dist/null-loader.js +1 -1
  94. package/dist/null-loader.js.map +1 -1
  95. package/dist/null-worker-node.js +199 -36
  96. package/dist/null-worker.js +199 -36
  97. package/package.json +6 -6
  98. package/src/index.ts +10 -1
  99. package/src/iterators/make-iterator/make-stream-iterator.ts +47 -9
  100. package/src/lib/api/core-api.ts +25 -0
  101. package/src/lib/api/create-data-source.ts +24 -24
  102. package/src/lib/api/load-in-batches.ts +16 -11
  103. package/src/lib/api/load-loader.ts +152 -0
  104. package/src/lib/api/load.ts +98 -5
  105. package/src/lib/api/parse-file.ts +143 -0
  106. package/src/lib/api/parse-in-batches.ts +13 -5
  107. package/src/lib/api/parse-sync.ts +27 -2
  108. package/src/lib/api/parse.ts +49 -18
  109. package/src/lib/api/preload.ts +31 -0
  110. package/src/lib/api/register-loaders.ts +1 -1
  111. package/src/lib/api/select-loader.ts +57 -5
  112. package/src/lib/api/select-source.ts +7 -10
  113. package/src/lib/fetch/fetch-error-message.ts +1 -1
  114. package/src/lib/loader-utils/check-errors.ts +1 -1
  115. package/src/lib/loader-utils/get-data.ts +36 -0
  116. package/src/lib/loader-utils/get-fetch-function.ts +3 -2
  117. package/src/lib/loader-utils/loader-context.ts +5 -2
  118. package/src/lib/loader-utils/loggers.ts +28 -2
  119. package/src/lib/loader-utils/option-defaults.ts +2 -0
  120. package/src/lib/loader-utils/option-utils.ts +59 -2
  121. package/src/lib/utils/response-utils.ts +3 -3
  122. package/src/null-loader.ts +3 -3
package/dist/dist.dev.js CHANGED
@@ -10,7 +10,6 @@ var __exports__ = (() => {
10
10
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
11
  var __getOwnPropNames = Object.getOwnPropertyNames;
12
12
  var __hasOwnProp = Object.prototype.hasOwnProperty;
13
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
13
  var __export = (target, all) => {
15
14
  for (var name in all)
16
15
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -24,10 +23,6 @@ var __exports__ = (() => {
24
23
  return to;
25
24
  };
26
25
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
- var __publicField = (obj, key, value) => {
28
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
29
- return value;
30
- };
31
26
 
32
27
  // bundle.ts
33
28
  var bundle_exports = {};
@@ -39,10 +34,11 @@ var __exports__ = (() => {
39
34
  RequestScheduler: () => RequestScheduler,
40
35
  _BrowserFileSystem: () => BrowserFileSystem,
41
36
  _fetchProgress: () => fetchProgress,
42
- _selectSource: () => selectSource2,
37
+ _selectSource: () => selectSource,
43
38
  _unregisterLoaders: () => _unregisterLoaders,
44
39
  assert: () => assert,
45
40
  concatenateArrayBuffersAsync: () => concatenateArrayBuffersAsync,
41
+ coreApi: () => coreApi,
46
42
  createDataSource: () => createDataSource,
47
43
  document: () => document_,
48
44
  encode: () => encode,
@@ -78,8 +74,11 @@ var __exports__ = (() => {
78
74
  makeTextDecoderIterator: () => makeTextDecoderIterator,
79
75
  makeTextEncoderIterator: () => makeTextEncoderIterator,
80
76
  parse: () => parse,
77
+ parseFile: () => parseFile,
81
78
  parseInBatches: () => parseInBatches,
82
79
  parseSync: () => parseSync,
80
+ preload: () => preload,
81
+ preloadSync: () => preloadSync,
83
82
  readArrayBuffer: () => readArrayBuffer,
84
83
  registerLoaders: () => registerLoaders,
85
84
  resolvePath: () => resolvePath,
@@ -682,7 +681,7 @@ var __exports__ = (() => {
682
681
  }
683
682
  const options = { ...baseOptions };
684
683
  for (const [key, newValue] of Object.entries(newOptions)) {
685
- if (newValue && typeof newValue === "object" && !Array.isArray(newValue)) {
684
+ if (isPureObject(newValue)) {
686
685
  options[key] = mergeOptionsRecursively(
687
686
  options[key] || {},
688
687
  newOptions[key],
@@ -706,16 +705,11 @@ var __exports__ = (() => {
706
705
  var NPM_TAG = "latest";
707
706
 
708
707
  // ../worker-utils/src/lib/env-utils/version.ts
709
- var warningIssued = false;
710
708
  function getVersion() {
711
709
  if (!globalThis._loadersgl_?.version) {
712
710
  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
- );
711
+ if (typeof __VERSION__ === "undefined") {
717
712
  globalThis._loadersgl_.version = NPM_TAG;
718
- warningIssued = true;
719
713
  } else {
720
714
  globalThis._loadersgl_.version = __VERSION__;
721
715
  }
@@ -785,7 +779,9 @@ var __exports__ = (() => {
785
779
  * Call to resolve the `result` Promise with the supplied value
786
780
  */
787
781
  done(value) {
788
- assert3(this.isRunning);
782
+ if (!this.isRunning) {
783
+ return;
784
+ }
789
785
  this.isRunning = false;
790
786
  this._resolve(value);
791
787
  }
@@ -793,14 +789,35 @@ var __exports__ = (() => {
793
789
  * Call to reject the `result` Promise with the supplied error
794
790
  */
795
791
  error(error) {
796
- assert3(this.isRunning);
792
+ if (!this.isRunning) {
793
+ return;
794
+ }
797
795
  this.isRunning = false;
798
796
  this._reject(error);
799
797
  }
798
+ /** Terminates the worker executing this job and rejects its result with an abort error. */
799
+ abort() {
800
+ if (!this.isRunning) {
801
+ return;
802
+ }
803
+ const error = new Error(`Worker job "${this.name}" was aborted`);
804
+ error.name = "AbortError";
805
+ this.workerThread.destroy();
806
+ this.error(error);
807
+ }
800
808
  };
801
809
 
802
810
  // ../worker-utils/src/lib/node/worker_threads-browser.ts
803
811
  var NodeWorker = class {
812
+ /** Restores the native worker constructor when this browser shim is embedded in a Node bundle. */
813
+ constructor(...arguments_) {
814
+ const runtimeProcess = globalThis.process;
815
+ const WorkerConstructor = runtimeProcess?.getBuiltinModule?.("node:worker_threads").Worker;
816
+ if (WorkerConstructor) {
817
+ return new WorkerConstructor(...arguments_);
818
+ }
819
+ }
820
+ /** No-op browser fallback matching the native Worker API. */
804
821
  terminate() {
805
822
  }
806
823
  };
@@ -930,6 +947,18 @@ var __exports__ = (() => {
930
947
  this.worker.terminate();
931
948
  this.terminated = true;
932
949
  }
950
+ /** Keeps this worker from preventing Node.js process exit while idle. */
951
+ unref() {
952
+ if (!isBrowser3 && typeof this.worker.unref === "function") {
953
+ this.worker.unref();
954
+ }
955
+ }
956
+ /** Keeps this worker alive while it is actively processing a job. */
957
+ ref() {
958
+ if (!isBrowser3 && typeof this.worker.ref === "function") {
959
+ this.worker.ref();
960
+ }
961
+ }
933
962
  get isRunning() {
934
963
  return Boolean(this.onMessage);
935
964
  }
@@ -987,8 +1016,9 @@ var __exports__ = (() => {
987
1016
  if (this.url) {
988
1017
  const absolute = this.url.includes(":/") || this.url.startsWith("/");
989
1018
  const url = absolute ? this.url : `./${this.url}`;
1019
+ const workerUrl = url.startsWith("file:") ? new URL(url) : url;
990
1020
  const type = this.url.endsWith(".ts") || this.url.endsWith(".mjs") ? "module" : "commonjs";
991
- worker = new NodeWorker(url, { eval: false, type });
1021
+ worker = new NodeWorker(workerUrl, { eval: false, type });
992
1022
  } else if (this.source) {
993
1023
  worker = new NodeWorker(this.source, { eval: true });
994
1024
  } else {
@@ -1000,7 +1030,7 @@ var __exports__ = (() => {
1000
1030
  worker.on("error", (error) => {
1001
1031
  this.onError(error);
1002
1032
  });
1003
- worker.on("exit", (code) => {
1033
+ worker.on("exit", (_code) => {
1004
1034
  });
1005
1035
  return worker;
1006
1036
  }
@@ -1061,9 +1091,9 @@ var __exports__ = (() => {
1061
1091
  this.onDebug = props.onDebug;
1062
1092
  }
1063
1093
  }
1064
- async startJob(name, onMessage3 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
1094
+ async startJob(name, onMessage2 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
1065
1095
  const startPromise = new Promise((onStart) => {
1066
- this.jobQueue.push({ name, onMessage: onMessage3, onError, onStart });
1096
+ this.jobQueue.push({ name, onMessage: onMessage2, onError, onStart });
1067
1097
  return this;
1068
1098
  });
1069
1099
  this._startQueuedJob();
@@ -1091,13 +1121,13 @@ var __exports__ = (() => {
1091
1121
  backlog: this.jobQueue.length
1092
1122
  });
1093
1123
  const job = new WorkerJob(queuedJob.name, workerThread);
1124
+ workerThread.ref();
1094
1125
  workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload);
1095
1126
  workerThread.onError = (error) => queuedJob.onError(job, error);
1096
1127
  queuedJob.onStart(job);
1097
1128
  try {
1098
1129
  await job.result;
1099
- } catch (error) {
1100
- console.error(`Worker exception: ${error}`);
1130
+ } catch {
1101
1131
  } finally {
1102
1132
  this.returnWorkerToQueue(workerThread);
1103
1133
  }
@@ -1113,17 +1143,19 @@ var __exports__ = (() => {
1113
1143
  */
1114
1144
  returnWorkerToQueue(worker) {
1115
1145
  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
1146
+ // Aborted jobs terminate their worker immediately.
1147
+ worker.terminated || // If the pool is destroyed, there is no reason to keep the worker around
1119
1148
  this.isDestroyed || // If the app has disabled worker reuse, any completed workers should be destroyed
1120
1149
  !this.reuseWorkers || // If concurrency has been lowered, this worker might be surplus to requirements
1121
1150
  this.count > this._getMaxConcurrency()
1122
1151
  );
1123
1152
  if (shouldDestroyWorker) {
1124
- worker.destroy();
1153
+ if (!worker.terminated) {
1154
+ worker.destroy();
1155
+ }
1125
1156
  this.count--;
1126
1157
  } else {
1158
+ worker.unref();
1127
1159
  this.idleQueue.push(worker);
1128
1160
  }
1129
1161
  if (!this.isDestroyed) {
@@ -1157,9 +1189,11 @@ var __exports__ = (() => {
1157
1189
  onDebug: () => {
1158
1190
  }
1159
1191
  };
1160
- var _WorkerFarm = class {
1192
+ var WorkerFarm = class _WorkerFarm {
1161
1193
  props;
1162
1194
  workerPools = /* @__PURE__ */ new Map();
1195
+ // singleton
1196
+ static _workerFarm;
1163
1197
  /** Checks if workers are supported on this platform */
1164
1198
  static isSupported() {
1165
1199
  return WorkerThread.isSupported();
@@ -1228,11 +1262,9 @@ var __exports__ = (() => {
1228
1262
  };
1229
1263
  }
1230
1264
  };
1231
- var WorkerFarm = _WorkerFarm;
1232
- // singleton
1233
- __publicField(WorkerFarm, "_workerFarm");
1234
1265
 
1235
1266
  // ../worker-utils/src/lib/worker-api/get-worker-url.ts
1267
+ var warnedWorkerVersionFallbacks = /* @__PURE__ */ new Set();
1236
1268
  function getWorkerName(worker) {
1237
1269
  const warning = worker.version !== VERSION3 ? ` (worker-utils@${VERSION3})` : "";
1238
1270
  return `${worker.name}@${worker.version}${warning}`;
@@ -1241,6 +1273,9 @@ var __exports__ = (() => {
1241
1273
  const workerOptions = options[worker.id] || {};
1242
1274
  const workerFile = isBrowser3 ? `${worker.id}-worker.js` : `${worker.id}-worker-node.js`;
1243
1275
  let url = workerOptions.workerUrl;
1276
+ if (!url && typeof worker.worker === "string") {
1277
+ url = worker.worker;
1278
+ }
1244
1279
  if (!url && worker.id === "compression") {
1245
1280
  url = options.workerUrl;
1246
1281
  }
@@ -1259,13 +1294,35 @@ var __exports__ = (() => {
1259
1294
  }
1260
1295
  const versionTag = version2 ? `@${version2}` : "";
1261
1296
  url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
1297
+ warnIfUsingNpmTagFallback(worker, url);
1262
1298
  }
1263
1299
  assert3(url);
1264
1300
  return url;
1265
1301
  }
1302
+ function warnIfUsingNpmTagFallback(worker, url) {
1303
+ if (worker.version !== "latest") {
1304
+ return;
1305
+ }
1306
+ const workerId = `${worker.module}:${worker.id}`;
1307
+ if (warnedWorkerVersionFallbacks.has(workerId)) {
1308
+ return;
1309
+ }
1310
+ warnedWorkerVersionFallbacks.add(workerId);
1311
+ console.warn(
1312
+ `loaders.gl: ${worker.name} loader worker version is "latest" because __VERSION__ was not injected. Fetching ${url} from CDN.`
1313
+ );
1314
+ }
1266
1315
 
1267
1316
  // ../worker-utils/src/lib/worker-api/process-on-worker.ts
1268
- async function processOnWorker(worker, data, options = {}, context = {}) {
1317
+ function canProcessOnWorker(worker, options) {
1318
+ if (!WorkerFarm.isSupported()) {
1319
+ return false;
1320
+ }
1321
+ const workerOptions = options?.[worker.id];
1322
+ return Boolean((worker.worker || workerOptions?.workerUrl) && options?.worker);
1323
+ }
1324
+ async function processOnWorker(worker, data, options = {}, context = {}, jobContext = {}) {
1325
+ throwIfAborted(options.signal);
1269
1326
  const name = getWorkerName(worker);
1270
1327
  const workerFarm = WorkerFarm.getWorkerFarm(options);
1271
1328
  const { source } = options;
@@ -1280,10 +1337,35 @@ var __exports__ = (() => {
1280
1337
  // eslint-disable-next-line
1281
1338
  onMessage.bind(null, context)
1282
1339
  );
1283
- const transferableOptions = getTransferListForWriter(options);
1284
- job.postMessage("process", { input: data, options: transferableOptions });
1285
- const result = await job.result;
1286
- return result.result;
1340
+ const abortJob = () => job.abort();
1341
+ options.signal?.addEventListener("abort", abortJob, { once: true });
1342
+ if (options.signal?.aborted) {
1343
+ abortJob();
1344
+ }
1345
+ try {
1346
+ const { signal: _signal, ...workerOptions } = options;
1347
+ const transferableOptions = getTransferListForWriter(workerOptions);
1348
+ const transferableContext = getTransferListForWriter(jobContext);
1349
+ if (job.isRunning) {
1350
+ job.postMessage("process", {
1351
+ input: data,
1352
+ options: transferableOptions,
1353
+ context: transferableContext
1354
+ });
1355
+ }
1356
+ const result = await job.result;
1357
+ return result.result;
1358
+ } finally {
1359
+ options.signal?.removeEventListener("abort", abortJob);
1360
+ }
1361
+ }
1362
+ function throwIfAborted(signal) {
1363
+ if (!signal?.aborted) {
1364
+ return;
1365
+ }
1366
+ const error = new Error("Worker job was aborted");
1367
+ error.name = "AbortError";
1368
+ throw error;
1287
1369
  }
1288
1370
  async function onMessage(context, job, type, payload) {
1289
1371
  switch (type) {
@@ -1300,7 +1382,7 @@ var __exports__ = (() => {
1300
1382
  job.postMessage("error", { id, error: "Worker not set up to process on main thread" });
1301
1383
  return;
1302
1384
  }
1303
- const result = await context.process(input, options);
1385
+ const result = await context.process(input, options, void 0, payload.context || {});
1304
1386
  job.postMessage("done", { id, result });
1305
1387
  } catch (error) {
1306
1388
  const message = error instanceof Error ? error.message : "unknown error";
@@ -1324,59 +1406,76 @@ var __exports__ = (() => {
1324
1406
 
1325
1407
  // ../loader-utils/src/lib/worker-loader-utils/parse-with-worker.ts
1326
1408
  function canParseWithWorker(loader, options) {
1327
- if (!WorkerFarm.isSupported()) {
1409
+ const workerOptions = getWorkerOptions(options);
1410
+ const nodeWorkers = workerOptions._nodeWorkers;
1411
+ if (!isBrowser3 && !nodeWorkers) {
1328
1412
  return false;
1329
1413
  }
1330
- const nodeWorkers = options?._nodeWorkers ?? options?.core?._nodeWorkers;
1331
- if (!isBrowser3 && !nodeWorkers) {
1414
+ if (loader.id === "excel" && options?.excel?.shape === "arrow-table" || loader.id === "ply" && options?.ply?.shape === "arrow-table") {
1332
1415
  return false;
1333
1416
  }
1334
- const useWorkers = options?.worker ?? options?.core?.worker;
1335
- return Boolean(loader.worker && useWorkers);
1417
+ if (loader.id === "csv" && !shouldParseCSVWithWorker(options)) {
1418
+ return false;
1419
+ }
1420
+ return Boolean(canProcessOnWorker(loader, workerOptions));
1336
1421
  }
1337
1422
  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
1423
+ const signal = getWorkerAbortSignal(options);
1424
+ const result = await processOnWorker(
1425
+ loader,
1426
+ data,
1427
+ { ...getWorkerOptions(options), signal },
1428
+ {
1429
+ process: async (input, processOptions, _workerContext, parseContext) => {
1430
+ if (!parseOnMainThread) {
1431
+ throw new Error("Worker not set up to parse on main thread");
1432
+ }
1433
+ const mainThreadContext = context ? { ...context, ...parseContext || {} } : void 0;
1434
+ return await callParseOnMainThread(
1435
+ parseOnMainThread,
1436
+ input,
1437
+ processOptions,
1438
+ mainThreadContext
1439
+ );
1440
+ }
1441
+ },
1442
+ getSerializableLoaderContext(context)
1349
1443
  );
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;
1444
+ return isLoaderWithWorkerResultDeserializer(loader) ? loader.deserializeWorkerResult(result, options, context) : result;
1358
1445
  }
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}`);
1446
+ function getWorkerAbortSignal(options) {
1447
+ const parquetSignal = options?.parquet?.signal;
1448
+ if (typeof AbortSignal !== "undefined" && parquetSignal instanceof AbortSignal) {
1449
+ return parquetSignal;
1450
+ }
1451
+ return void 0;
1452
+ }
1453
+ function callParseOnMainThread(parseOnMainThread, input, options, context) {
1454
+ if (parseOnMainThread.length <= 2) {
1455
+ return parseOnMainThread(input, options);
1379
1456
  }
1457
+ return parseOnMainThread(input, void 0, options, context);
1458
+ }
1459
+ function getWorkerOptions(options = {}) {
1460
+ const serializedOptions = JSON.parse(JSON.stringify(options));
1461
+ return {
1462
+ ...serializedOptions.core,
1463
+ ...serializedOptions
1464
+ };
1465
+ }
1466
+ function getSerializableLoaderContext(context) {
1467
+ if (!context) {
1468
+ return {};
1469
+ }
1470
+ const { fetch: fetch2, loaders, coreApi: coreApi2, _parse, _parseSync, _parseInBatches, ...serializableContext } = context;
1471
+ return JSON.parse(JSON.stringify(serializableContext));
1472
+ }
1473
+ function shouldParseCSVWithWorker(options) {
1474
+ const csvOptions = options;
1475
+ return (csvOptions?.csv?.shape ?? csvOptions?.core?.shape) === "arrow-table";
1476
+ }
1477
+ function isLoaderWithWorkerResultDeserializer(loader) {
1478
+ return typeof loader.deserializeWorkerResult === "function";
1380
1479
  }
1381
1480
 
1382
1481
  // ../loader-utils/src/lib/worker-loader-utils/encode-with-worker.ts
@@ -1442,10 +1541,12 @@ var __exports__ = (() => {
1442
1541
  for await (const textChunk of textIterator) {
1443
1542
  previous += textChunk;
1444
1543
  let eolIndex;
1445
- while ((eolIndex = previous.indexOf("\n")) >= 0) {
1544
+ eolIndex = previous.indexOf("\n");
1545
+ while (eolIndex >= 0) {
1446
1546
  const line = previous.slice(0, eolIndex + 1);
1447
1547
  previous = previous.slice(eolIndex + 1);
1448
1548
  yield line;
1549
+ eolIndex = previous.indexOf("\n");
1449
1550
  }
1450
1551
  }
1451
1552
  if (previous.length > 0) {
@@ -1892,89 +1993,6 @@ var __exports__ = (() => {
1892
1993
  return filename2;
1893
1994
  }
1894
1995
 
1895
- // ../loader-utils/src/json-loader.ts
1896
- var VERSION4 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
1897
- var JSONLoader = {
1898
- dataType: null,
1899
- batchType: null,
1900
- name: "JSON",
1901
- id: "json",
1902
- module: "json",
1903
- version: VERSION4,
1904
- extensions: ["json", "geojson"],
1905
- mimeTypes: ["application/json"],
1906
- category: "json",
1907
- text: true,
1908
- parseTextSync,
1909
- parse: async (arrayBuffer) => parseTextSync(new TextDecoder().decode(arrayBuffer)),
1910
- options: {}
1911
- };
1912
- function parseTextSync(text) {
1913
- return JSON.parse(text);
1914
- }
1915
-
1916
- // ../loader-utils/src/lib/node/buffer.browser.ts
1917
- function toArrayBuffer(buffer) {
1918
- return buffer;
1919
- }
1920
-
1921
- // ../loader-utils/src/lib/binary-utils/memory-conversion-utils.ts
1922
- function isBuffer(value) {
1923
- return value && typeof value === "object" && value.isBuffer;
1924
- }
1925
- function toArrayBuffer2(data) {
1926
- if (isBuffer(data)) {
1927
- return toArrayBuffer(data);
1928
- }
1929
- if (data instanceof ArrayBuffer) {
1930
- return data;
1931
- }
1932
- if (isSharedArrayBuffer(data)) {
1933
- return copyToArrayBuffer2(data);
1934
- }
1935
- if (ArrayBuffer.isView(data)) {
1936
- const buffer = data.buffer;
1937
- if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
1938
- return buffer;
1939
- }
1940
- return buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
1941
- }
1942
- if (typeof data === "string") {
1943
- const text = data;
1944
- const uint8Array = new TextEncoder().encode(text);
1945
- return uint8Array.buffer;
1946
- }
1947
- if (data && typeof data === "object" && data._toArrayBuffer) {
1948
- return data._toArrayBuffer();
1949
- }
1950
- throw new Error("toArrayBuffer");
1951
- }
1952
- function ensureArrayBuffer(bufferSource) {
1953
- if (bufferSource instanceof ArrayBuffer) {
1954
- return bufferSource;
1955
- }
1956
- if (isSharedArrayBuffer(bufferSource)) {
1957
- return copyToArrayBuffer2(bufferSource);
1958
- }
1959
- const { buffer, byteOffset, byteLength } = bufferSource;
1960
- if (buffer instanceof ArrayBuffer && byteOffset === 0 && byteLength === buffer.byteLength) {
1961
- return buffer;
1962
- }
1963
- return copyToArrayBuffer2(buffer, byteOffset, byteLength);
1964
- }
1965
- function copyToArrayBuffer2(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
1966
- const view = new Uint8Array(buffer, byteOffset, byteLength);
1967
- const copy = new Uint8Array(view.length);
1968
- copy.set(view);
1969
- return copy.buffer;
1970
- }
1971
- function toArrayBufferView(data) {
1972
- if (ArrayBuffer.isView(data)) {
1973
- return data;
1974
- }
1975
- return new Uint8Array(data);
1976
- }
1977
-
1978
1996
  // ../loader-utils/src/lib/path-utils/path.ts
1979
1997
  var path_exports = {};
1980
1998
  __export(path_exports, {
@@ -2118,6 +2136,91 @@ var __exports__ = (() => {
2118
2136
  return res;
2119
2137
  }
2120
2138
 
2139
+ // ../loader-utils/src/json-loader.ts
2140
+ var VERSION4 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
2141
+ var JSONLoader = {
2142
+ dataType: null,
2143
+ batchType: null,
2144
+ name: "JSON",
2145
+ id: "json",
2146
+ module: "json",
2147
+ version: VERSION4,
2148
+ encoding: "json",
2149
+ format: "json",
2150
+ extensions: ["json", "geojson"],
2151
+ mimeTypes: ["application/json"],
2152
+ category: "json",
2153
+ text: true,
2154
+ parseTextSync,
2155
+ parse: async (arrayBuffer) => parseTextSync(new TextDecoder().decode(arrayBuffer)),
2156
+ options: {}
2157
+ };
2158
+ function parseTextSync(text) {
2159
+ return JSON.parse(text);
2160
+ }
2161
+
2162
+ // ../loader-utils/src/lib/node/buffer.browser.ts
2163
+ function toArrayBuffer(buffer) {
2164
+ return buffer;
2165
+ }
2166
+
2167
+ // ../loader-utils/src/lib/binary-utils/memory-conversion-utils.ts
2168
+ function isBuffer(value) {
2169
+ return value && typeof value === "object" && value.isBuffer;
2170
+ }
2171
+ function toArrayBuffer2(data) {
2172
+ if (isBuffer(data)) {
2173
+ return toArrayBuffer(data);
2174
+ }
2175
+ if (data instanceof ArrayBuffer) {
2176
+ return data;
2177
+ }
2178
+ if (isSharedArrayBuffer(data)) {
2179
+ return copyToArrayBuffer2(data);
2180
+ }
2181
+ if (ArrayBuffer.isView(data)) {
2182
+ const buffer = data.buffer;
2183
+ if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
2184
+ return buffer;
2185
+ }
2186
+ return buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
2187
+ }
2188
+ if (typeof data === "string") {
2189
+ const text = data;
2190
+ const uint8Array = new TextEncoder().encode(text);
2191
+ return uint8Array.buffer;
2192
+ }
2193
+ if (data && typeof data === "object" && data._toArrayBuffer) {
2194
+ return data._toArrayBuffer();
2195
+ }
2196
+ throw new Error("toArrayBuffer");
2197
+ }
2198
+ function ensureArrayBuffer(bufferSource) {
2199
+ if (bufferSource instanceof ArrayBuffer) {
2200
+ return bufferSource;
2201
+ }
2202
+ if (isSharedArrayBuffer(bufferSource)) {
2203
+ return copyToArrayBuffer2(bufferSource);
2204
+ }
2205
+ const { buffer, byteOffset, byteLength } = bufferSource;
2206
+ if (buffer instanceof ArrayBuffer && byteOffset === 0 && byteLength === buffer.byteLength) {
2207
+ return buffer;
2208
+ }
2209
+ return copyToArrayBuffer2(buffer, byteOffset, byteLength);
2210
+ }
2211
+ function copyToArrayBuffer2(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
2212
+ const view = new Uint8Array(buffer, byteOffset, byteLength);
2213
+ const copy = new Uint8Array(view.length);
2214
+ copy.set(view);
2215
+ return copy.buffer;
2216
+ }
2217
+ function toArrayBufferView(data) {
2218
+ if (ArrayBuffer.isView(data)) {
2219
+ return data;
2220
+ }
2221
+ return new Uint8Array(data);
2222
+ }
2223
+
2121
2224
  // ../loader-utils/src/lib/files/blob-file.ts
2122
2225
  var BlobFile = class {
2123
2226
  handle;
@@ -2139,8 +2242,14 @@ var __exports__ = (() => {
2139
2242
  isDirectory: false
2140
2243
  };
2141
2244
  }
2142
- async read(start, length) {
2245
+ async read(start, length, signal) {
2246
+ if (signal?.aborted) {
2247
+ throw new Error("Request aborted");
2248
+ }
2143
2249
  const arrayBuffer = await this.handle.slice(Number(start), Number(start) + Number(length)).arrayBuffer();
2250
+ if (signal?.aborted) {
2251
+ throw new Error("Request aborted");
2252
+ }
2144
2253
  return arrayBuffer;
2145
2254
  }
2146
2255
  };
@@ -2186,6 +2295,11 @@ var __exports__ = (() => {
2186
2295
  }
2187
2296
  };
2188
2297
 
2298
+ // ../loader-utils/src/source-types.ts
2299
+ function isSourceLoader(loader) {
2300
+ return Boolean(loader && typeof loader === "object" && "createDataSource" in loader);
2301
+ }
2302
+
2189
2303
  // src/lib/fetch/fetch-error.ts
2190
2304
  var FetchError = class extends Error {
2191
2305
  constructor(message, info) {
@@ -2337,7 +2451,7 @@ var __exports__ = (() => {
2337
2451
  try {
2338
2452
  const contentType = response.headers.get("Content-Type");
2339
2453
  info.reason = !response.bodyUsed && contentType?.includes("application/json") ? await response.json() : await response.text();
2340
- } catch (error) {
2454
+ } catch (_error) {
2341
2455
  }
2342
2456
  return new FetchError(message, info);
2343
2457
  }
@@ -2413,37 +2527,64 @@ var __exports__ = (() => {
2413
2527
  // src/lib/loader-utils/loggers.ts
2414
2528
  var probeLog = new ProbeLog({ id: "loaders.gl" });
2415
2529
  var NullLog = class {
2530
+ /** Drops a log message. */
2416
2531
  log() {
2417
2532
  return () => {
2418
2533
  };
2419
2534
  }
2535
+ /** Drops an info message. */
2420
2536
  info() {
2421
2537
  return () => {
2422
2538
  };
2423
2539
  }
2540
+ /** Logs one message once; no-op for the null logger. */
2541
+ once() {
2542
+ return () => {
2543
+ };
2544
+ }
2545
+ /** Drops a warning message. */
2424
2546
  warn() {
2425
2547
  return () => {
2426
2548
  };
2427
2549
  }
2550
+ /** Drops an error message. */
2428
2551
  error() {
2429
2552
  return () => {
2430
2553
  };
2431
2554
  }
2432
2555
  };
2433
2556
  var ConsoleLog = class {
2557
+ /** Console-like object used for message output. */
2434
2558
  console;
2559
+ /** Messages already emitted through `once`. */
2560
+ onceMessages = /* @__PURE__ */ new Set();
2561
+ /** Creates a console-backed logger. */
2435
2562
  constructor() {
2436
2563
  this.console = console;
2437
2564
  }
2565
+ /** Logs a message to the console. */
2438
2566
  log(...args) {
2439
2567
  return this.console.log.bind(this.console, ...args);
2440
2568
  }
2569
+ /** Logs an informational message to the console. */
2441
2570
  info(...args) {
2442
2571
  return this.console.info.bind(this.console, ...args);
2443
2572
  }
2444
- warn(...args) {
2573
+ /** Logs one message once to the console. */
2574
+ once(...args) {
2575
+ const message = String(args[0]);
2576
+ if (this.onceMessages.has(message)) {
2577
+ return () => {
2578
+ };
2579
+ }
2580
+ this.onceMessages.add(message);
2581
+ return this.console.info.bind(this.console, ...args);
2582
+ }
2583
+ /** Logs a warning message to the console. */
2584
+ warn(...args) {
2445
2585
  return this.console.warn.bind(this.console, ...args);
2446
2586
  }
2587
+ /** Logs an error message to the console. */
2447
2588
  error(...args) {
2448
2589
  return this.console.error.bind(this.console, ...args);
2449
2590
  }
@@ -2459,6 +2600,7 @@ var __exports__ = (() => {
2459
2600
  fallbackMimeType: void 0,
2460
2601
  ignoreRegisteredLoaders: void 0,
2461
2602
  nothrow: false,
2603
+ shape: void 0,
2462
2604
  log: new ConsoleLog(),
2463
2605
  // A probe.gl compatible (`log.log()()` syntax) that just logs to console
2464
2606
  useLocalLibraries: false,
@@ -2504,6 +2646,7 @@ var __exports__ = (() => {
2504
2646
  _worker: "core._workerType",
2505
2647
  limit: "core.limit",
2506
2648
  _limitMB: "core._limitMB",
2649
+ shape: "core.shape",
2507
2650
  batchSize: "core.batchSize",
2508
2651
  batchDebounceMs: "core.batchDebounceMs",
2509
2652
  metadata: "core.metadata",
@@ -2542,10 +2685,12 @@ var __exports__ = (() => {
2542
2685
  "maxConcurrency",
2543
2686
  "maxMobileConcurrency",
2544
2687
  "reuseWorkers",
2688
+ "workerTransferBufferCopy",
2545
2689
  "_nodeWorkers",
2546
2690
  "_workerType",
2547
2691
  "limit",
2548
2692
  "_limitMB",
2693
+ "shape",
2549
2694
  "batchSize",
2550
2695
  "batchDebounceMs",
2551
2696
  "metadata",
@@ -2656,10 +2801,34 @@ var __exports__ = (() => {
2656
2801
  mergeNestedFields(mergedOptions, normalizeLoaderOptions(getGlobalLoaderOptions()));
2657
2802
  const userOptions = normalizeLoaderOptions(options);
2658
2803
  mergeNestedFields(mergedOptions, userOptions);
2804
+ applyCoreShapeDefault(mergedOptions, userOptions, loader);
2659
2805
  addUrlOptions(mergedOptions, url);
2660
2806
  addDeprecatedTopLevelOptions(mergedOptions);
2661
2807
  return mergedOptions;
2662
2808
  }
2809
+ function applyCoreShapeDefault(mergedOptions, userOptions, loader) {
2810
+ const coreShape = mergedOptions.core?.shape;
2811
+ if (coreShape === void 0) {
2812
+ return;
2813
+ }
2814
+ const loaderScopedDefaults = loader.options?.[loader.id];
2815
+ if (!isPureObject(loaderScopedDefaults) || !("shape" in loaderScopedDefaults)) {
2816
+ return;
2817
+ }
2818
+ const globalLoaderScopedOptions = getGlobalLoaderOptions()[loader.id];
2819
+ if (isPureObject(globalLoaderScopedOptions) && "shape" in globalLoaderScopedOptions) {
2820
+ return;
2821
+ }
2822
+ const userLoaderScopedOptions = userOptions[loader.id];
2823
+ if (isPureObject(userLoaderScopedOptions) && "shape" in userLoaderScopedOptions) {
2824
+ return;
2825
+ }
2826
+ const loaderScopedOptions = mergedOptions[loader.id];
2827
+ mergedOptions[loader.id] = {
2828
+ ...isPureObject(loaderScopedOptions) ? loaderScopedOptions : {},
2829
+ shape: coreShape
2830
+ };
2831
+ }
2663
2832
  function mergeNestedFields(mergedOptions, options) {
2664
2833
  for (const key in options) {
2665
2834
  if (key in options) {
@@ -2701,7 +2870,8 @@ var __exports__ = (() => {
2701
2870
  }
2702
2871
  for (const key of CORE_LOADER_OPTION_KEYS) {
2703
2872
  if (options[key] !== void 0) {
2704
- const coreOptions = options.core = options.core || {};
2873
+ options.core ||= {};
2874
+ const coreOptions = options.core;
2705
2875
  const coreRecord = coreOptions;
2706
2876
  if (coreRecord[key] === void 0) {
2707
2877
  coreRecord[key] = options[key];
@@ -2861,16 +3031,27 @@ var __exports__ = (() => {
2861
3031
  const testUrl = stripQueryString(url) || context?.url;
2862
3032
  let loader = null;
2863
3033
  let reason = "";
3034
+ const sourceType = options?.core && "type" in options.core ? options.core.type : void 0;
3035
+ if (sourceType && sourceType !== "auto") {
3036
+ loader = findSourceLoaderByType(loaders, sourceType);
3037
+ reason = loader ? `match forced by supplied source type ${sourceType}` : "";
3038
+ }
2864
3039
  if (options?.core?.mimeType) {
2865
3040
  loader = findLoaderByMIMEType(loaders, options?.core?.mimeType);
2866
3041
  reason = `match forced by supplied MIME type ${options?.core?.mimeType}`;
2867
3042
  }
3043
+ loader = loader || findSourceLoaderByTestURL(loaders, testUrl);
3044
+ reason = reason || (loader ? `matched source url ${testUrl}` : "");
2868
3045
  loader = loader || findLoaderByUrl(loaders, testUrl);
2869
3046
  reason = reason || (loader ? `matched url ${testUrl}` : "");
2870
3047
  loader = loader || findLoaderByMIMEType(loaders, type);
2871
3048
  reason = reason || (loader ? `matched MIME type ${type}` : "");
2872
3049
  loader = loader || findLoaderByInitialBytes(loaders, data);
2873
3050
  reason = reason || (loader ? `matched initial data ${getFirstCharacters(data)}` : "");
3051
+ if (!loader && isBlob(data)) {
3052
+ loader = findSourceLoaderByTestData(loaders, data);
3053
+ reason = reason || (loader ? "matched source testData" : "");
3054
+ }
2874
3055
  if (options?.core?.fallbackMimeType) {
2875
3056
  loader = loader || findLoaderByMIMEType(loaders, options?.core?.fallbackMimeType);
2876
3057
  reason = reason || (loader ? `matched fallback MIME type ${type}` : "");
@@ -2920,6 +3101,35 @@ var __exports__ = (() => {
2920
3101
  }
2921
3102
  return null;
2922
3103
  }
3104
+ function findSourceLoaderByType(loaders, type) {
3105
+ for (const loader of loaders) {
3106
+ if (isSourceLoader(loader) && loader.type === type) {
3107
+ return loader;
3108
+ }
3109
+ }
3110
+ return null;
3111
+ }
3112
+ function findSourceLoaderByTestURL(loaders, url) {
3113
+ if (!url) {
3114
+ return null;
3115
+ }
3116
+ for (const loader of loaders) {
3117
+ if (isSourceLoader(loader) && loader.testURL(url)) {
3118
+ return loader;
3119
+ }
3120
+ }
3121
+ return null;
3122
+ }
3123
+ function findSourceLoaderByTestData(loaders, data) {
3124
+ for (const loader of loaders) {
3125
+ if (isSourceLoader(loader)) {
3126
+ if (loader.testData?.(data)) {
3127
+ return loader;
3128
+ }
3129
+ }
3130
+ }
3131
+ return null;
3132
+ }
2923
3133
  function findLoaderByMIMEType(loaders, mimeType) {
2924
3134
  for (const loader of loaders) {
2925
3135
  if (loader.mimeTypes?.some((mimeType1) => compareMIMETypes(mimeType, mimeType1))) {
@@ -3051,20 +3261,57 @@ var __exports__ = (() => {
3051
3261
  async function* makeBrowserStreamIterator(stream, options) {
3052
3262
  const reader = stream.getReader();
3053
3263
  let nextBatchPromise;
3264
+ let streamFinished = false;
3265
+ let streamReadFailed = false;
3266
+ let iteratorFailed = false;
3054
3267
  try {
3055
3268
  while (true) {
3056
3269
  const currentBatchPromise = nextBatchPromise || reader.read();
3057
- if (options?._streamReadAhead) {
3058
- nextBatchPromise = reader.read();
3270
+ nextBatchPromise = void 0;
3271
+ let batch;
3272
+ try {
3273
+ batch = await currentBatchPromise;
3274
+ } catch (error) {
3275
+ streamReadFailed = true;
3276
+ throw error;
3059
3277
  }
3060
- const { done, value } = await currentBatchPromise;
3278
+ const { done, value } = batch;
3061
3279
  if (done) {
3280
+ streamFinished = true;
3062
3281
  return;
3063
3282
  }
3283
+ if (options?._streamReadAhead) {
3284
+ nextBatchPromise = reader.read();
3285
+ void nextBatchPromise.catch(() => {
3286
+ });
3287
+ }
3064
3288
  yield toArrayBuffer2(value);
3065
3289
  }
3066
3290
  } catch (error) {
3067
- reader.releaseLock();
3291
+ iteratorFailed = true;
3292
+ throw error;
3293
+ } finally {
3294
+ let cleanupFailed = false;
3295
+ let cleanupError;
3296
+ if (!streamFinished && !streamReadFailed) {
3297
+ try {
3298
+ await reader.cancel();
3299
+ } catch (error) {
3300
+ cleanupFailed = true;
3301
+ cleanupError = error;
3302
+ }
3303
+ }
3304
+ try {
3305
+ reader.releaseLock();
3306
+ } catch (error) {
3307
+ if (!cleanupFailed) {
3308
+ cleanupFailed = true;
3309
+ cleanupError = error;
3310
+ }
3311
+ }
3312
+ if (!iteratorFailed && cleanupFailed) {
3313
+ throw cleanupError;
3314
+ }
3068
3315
  }
3069
3316
  }
3070
3317
  async function* makeNodeStreamIterator(stream, options) {
@@ -3135,6 +3382,28 @@ var __exports__ = (() => {
3135
3382
  }
3136
3383
  throw new Error(ERR_DATA);
3137
3384
  }
3385
+ async function getArrayBufferFromData(data, options) {
3386
+ if (typeof data === "string") {
3387
+ return new TextEncoder().encode(data).buffer;
3388
+ }
3389
+ if (isArrayBufferLike(data)) {
3390
+ return toArrayBuffer2(toArrayBufferView(data));
3391
+ }
3392
+ if (isBlob(data)) {
3393
+ data = await makeResponse(data);
3394
+ }
3395
+ if (isResponse(data)) {
3396
+ await checkResponse(data);
3397
+ return await data.arrayBuffer();
3398
+ }
3399
+ if (isReadableStream(data)) {
3400
+ data = makeIterator(data, options);
3401
+ }
3402
+ if (isIterable(data) || isAsyncIterable(data)) {
3403
+ return concatenateArrayBuffersAsync(data);
3404
+ }
3405
+ throw new Error(ERR_DATA);
3406
+ }
3138
3407
  async function getAsyncIterableFromData(data, options) {
3139
3408
  if (isPromise(data)) {
3140
3409
  data = await data;
@@ -3163,14 +3432,14 @@ var __exports__ = (() => {
3163
3432
  }
3164
3433
  function getIterableFromData(data) {
3165
3434
  if (ArrayBuffer.isView(data)) {
3166
- return function* oneChunk() {
3435
+ return (function* oneChunk() {
3167
3436
  yield toArrayBuffer2(data);
3168
- }();
3437
+ })();
3169
3438
  }
3170
3439
  if (isArrayBufferLike(data)) {
3171
- return function* oneChunk() {
3440
+ return (function* oneChunk() {
3172
3441
  yield toArrayBuffer2(data);
3173
- }();
3442
+ })();
3174
3443
  }
3175
3444
  if (isIterator(data)) {
3176
3445
  return data;
@@ -3198,91 +3467,151 @@ var __exports__ = (() => {
3198
3467
  return fetchFile;
3199
3468
  }
3200
3469
 
3201
- // src/lib/loader-utils/loader-context.ts
3202
- function getLoaderContext(context, options, parentContext) {
3203
- if (parentContext) {
3204
- return parentContext;
3470
+ // src/lib/api/load-loader.ts
3471
+ var loaderImplementationPromises = /* @__PURE__ */ new Map();
3472
+ var loaderImplementations = /* @__PURE__ */ new Map();
3473
+ async function getLoaderImplementation(loader, options, url) {
3474
+ if (isLoaderWithParser(loader)) {
3475
+ return loader;
3205
3476
  }
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);
3477
+ const implementationCacheKey = getLoaderImplementationCacheKey(loader, options);
3478
+ const loaderImplementation = loaderImplementations.get(loader)?.get(implementationCacheKey);
3479
+ if (loaderImplementation) {
3480
+ return loaderImplementation;
3481
+ }
3482
+ let loaderImplementationPromisesForLoader = loaderImplementationPromises.get(loader);
3483
+ if (!loaderImplementationPromisesForLoader) {
3484
+ loaderImplementationPromisesForLoader = /* @__PURE__ */ new Map();
3485
+ loaderImplementationPromises.set(loader, loaderImplementationPromisesForLoader);
3486
+ }
3487
+ let loaderImplementationPromise = loaderImplementationPromisesForLoader.get(implementationCacheKey);
3488
+ if (!loaderImplementationPromise) {
3489
+ loaderImplementationPromise = resolveLoaderImplementation(loader, options, url).then((implementation) => {
3490
+ let loaderImplementationsForLoader = loaderImplementations.get(loader);
3491
+ if (!loaderImplementationsForLoader) {
3492
+ loaderImplementationsForLoader = /* @__PURE__ */ new Map();
3493
+ loaderImplementations.set(loader, loaderImplementationsForLoader);
3494
+ }
3495
+ loaderImplementationsForLoader.set(implementationCacheKey, implementation);
3496
+ return implementation;
3497
+ }).catch((error) => {
3498
+ loaderImplementationPromisesForLoader.delete(implementationCacheKey);
3499
+ if (loaderImplementationPromisesForLoader.size === 0) {
3500
+ loaderImplementationPromises.delete(loader);
3501
+ }
3502
+ throw error;
3503
+ });
3504
+ loaderImplementationPromisesForLoader.set(implementationCacheKey, loaderImplementationPromise);
3216
3505
  }
3217
- if (!Array.isArray(newContext.loaders)) {
3218
- newContext.loaders = null;
3506
+ return await loaderImplementationPromise;
3507
+ }
3508
+ function getLoaderImplementationSync(loader) {
3509
+ if (isLoaderWithParser(loader)) {
3510
+ return loader;
3219
3511
  }
3220
- return newContext;
3512
+ const implementationCacheKey = getLoaderImplementationCacheKey(loader);
3513
+ return loaderImplementations.get(loader)?.get(implementationCacheKey) || null;
3221
3514
  }
3222
- function getLoadersFromContext(loaders, context) {
3223
- if (loaders && !Array.isArray(loaders)) {
3224
- return loaders;
3515
+ function isLoaderWithParser(loader) {
3516
+ const candidate = loader;
3517
+ return Boolean(
3518
+ candidate.parse || candidate.parseSync || candidate.parseInBatches || candidate.parseText || candidate.parseTextSync || candidate.parseFile || candidate.parseFileInBatches
3519
+ );
3520
+ }
3521
+ async function resolveLoaderImplementation(loader, options, url) {
3522
+ if (loader.preload) {
3523
+ const preloadedLoader = await loader.preload(url || "", options);
3524
+ if (isLoaderWithParser(preloadedLoader)) {
3525
+ return preloadedLoader;
3526
+ }
3527
+ throw new Error(`${loader.id} loader preload() did not return a parser-bearing loader`);
3225
3528
  }
3226
- let candidateLoaders;
3227
- if (loaders) {
3228
- candidateLoaders = Array.isArray(loaders) ? loaders : [loaders];
3529
+ const implementationSpecifier = getLoaderImplementationSpecifier(loader, options);
3530
+ return await importLoaderImplementation(implementationSpecifier, loader.id);
3531
+ }
3532
+ function getLoaderImplementationSpecifier(loader, options) {
3533
+ const workerType = options?._workerType || options?.core?._workerType;
3534
+ if (workerType === "test") {
3535
+ const sourcePath = `modules/${loader.module}/src/${loader.id}-loader.ts`;
3536
+ if (typeof window !== "undefined") {
3537
+ return `/${sourcePath}`;
3538
+ }
3539
+ if (typeof process !== "undefined" && process.cwd) {
3540
+ return new URL(sourcePath, `file://${process.cwd()}/`).toString();
3541
+ }
3542
+ return sourcePath;
3229
3543
  }
3230
- if (context && context.loaders) {
3231
- const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders];
3232
- candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders;
3544
+ throw new Error(
3545
+ `${loader.id} loader does not provide a parser implementation. Import a parser-bearing loader directly, or use preload() before parse/load.`
3546
+ );
3547
+ }
3548
+ function getLoaderImplementationCacheKey(loader, options) {
3549
+ const loaderOptions = options?.[loader.id];
3550
+ const defaultLoaderOptions = loader.options?.[loader.id];
3551
+ return String(loaderOptions?.backend || defaultLoaderOptions?.backend || "");
3552
+ }
3553
+ async function importLoaderImplementation(implementationSpecifier, loaderId) {
3554
+ const moduleExports = await import(
3555
+ /* webpackIgnore: true */
3556
+ /* @vite-ignore */
3557
+ implementationSpecifier
3558
+ );
3559
+ for (const exportValue of Object.values(moduleExports)) {
3560
+ if (exportValue && typeof exportValue === "object" && exportValue.id === loaderId && isLoaderWithParser(exportValue)) {
3561
+ return exportValue;
3562
+ }
3233
3563
  }
3234
- return candidateLoaders && candidateLoaders.length ? candidateLoaders : void 0;
3564
+ throw new Error(
3565
+ `Could not find parser implementation for ${loaderId} in ${implementationSpecifier}`
3566
+ );
3235
3567
  }
3236
3568
 
3237
- // src/lib/api/parse.ts
3238
- async function parse(data, loaders, options, context) {
3569
+ // src/lib/api/parse-file.ts
3570
+ async function parseFile(file, loaders, options, context) {
3239
3571
  if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {
3240
3572
  context = void 0;
3241
3573
  options = loaders;
3242
3574
  loaders = void 0;
3243
3575
  }
3244
- data = await data;
3245
3576
  options = options || {};
3246
- const url = getResourceUrl(data);
3577
+ const url = file.url || "";
3247
3578
  const typedLoaders = loaders;
3248
3579
  const candidateLoaders = getLoadersFromContext(typedLoaders, context);
3249
- const loader = await selectLoader(data, candidateLoaders, options);
3580
+ const loader = await selectLoader(url, candidateLoaders, options);
3250
3581
  if (!loader) {
3251
3582
  return null;
3252
3583
  }
3584
+ if (isSourceLoader(loader)) {
3585
+ throw new Error(
3586
+ `${loader.id} is a SourceLoader. Use load() to create a runtime source object instead of parseFile().`
3587
+ );
3588
+ }
3253
3589
  const strictOptions = normalizeOptions(options, loader, candidateLoaders, url);
3254
3590
  context = getLoaderContext(
3255
- // @ts-expect-error
3591
+ // @ts-expect-error candidateLoaders may be a single forced loader
3256
3592
  { url, _parse: parse, loaders: candidateLoaders },
3257
3593
  strictOptions,
3258
3594
  context || null
3259
3595
  );
3260
- return await parseWithLoader(loader, data, strictOptions, context);
3596
+ return await parseFileWithLoader(loader, file, strictOptions, context);
3261
3597
  }
3262
- async function parseWithLoader(loader, data, options, context) {
3598
+ async function parseFileWithLoader(loader, file, options, context) {
3263
3599
  validateWorkerVersion(loader);
3264
3600
  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);
3601
+ const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
3602
+ if (loaderWithParser.parseFile) {
3603
+ return await loaderWithParser.parseFile(file, options, context);
3604
+ }
3605
+ const parseFunction = loaderWithParser.parse;
3606
+ if (parseFunction) {
3607
+ const length = file.bigsize > 0n ? Number(file.bigsize) : file.size;
3608
+ if (!length) {
3609
+ throw new Error(`${loader.id} loader - cannot fall back to parse without a file size`);
3610
+ }
3611
+ const data = await file.read(0n, length);
3612
+ return await parse(data, loaderWithParser, options, context);
3283
3613
  }
3284
- assert3(!loaderWithParser.parseSync);
3285
- throw new Error(`${loader.id} loader - no parser found and worker is disabled`);
3614
+ throw new Error(`${loader.id} loader - no file parser found`);
3286
3615
  }
3287
3616
 
3288
3617
  // src/lib/api/parse-sync.ts
@@ -3299,6 +3628,11 @@ var __exports__ = (() => {
3299
3628
  if (!loader) {
3300
3629
  return null;
3301
3630
  }
3631
+ if (isSourceLoader(loader)) {
3632
+ throw new Error(
3633
+ `${loader.id} is a SourceLoader. Use load() to create a runtime source object instead of parseSync().`
3634
+ );
3635
+ }
3302
3636
  const strictOptions = normalizeOptions(options, loader, candidateLoaders);
3303
3637
  const url = getResourceUrl(data);
3304
3638
  const parse2 = () => {
@@ -3309,7 +3643,13 @@ var __exports__ = (() => {
3309
3643
  strictOptions,
3310
3644
  context || null
3311
3645
  );
3312
- return parseWithLoaderSync(loader, data, strictOptions, context);
3646
+ const loaderWithParser = getLoaderImplementationSync(loader);
3647
+ return parseWithLoaderSync(
3648
+ loaderWithParser || loader,
3649
+ data,
3650
+ strictOptions,
3651
+ context
3652
+ );
3313
3653
  }
3314
3654
  function parseWithLoaderSync(loader, data, options, context) {
3315
3655
  data = getArrayBufferOrStringFromDataSync(data, loader, options);
@@ -3319,6 +3659,11 @@ var __exports__ = (() => {
3319
3659
  if (loader.parseSync && data instanceof ArrayBuffer) {
3320
3660
  return loader.parseSync(data, options, context);
3321
3661
  }
3662
+ if (loader.preload) {
3663
+ throw new Error(
3664
+ `${loader.name} loader: 'parseSync' requires a parser-bearing loader. Import the loader implementation directly, or call preload(loader) before parseSync(). ${context.url || ""}`
3665
+ );
3666
+ }
3322
3667
  throw new Error(
3323
3668
  `${loader.name} loader: 'parseSync' not supported by this loader, use 'parse' instead. ${context.url || ""}`
3324
3669
  );
@@ -3387,9 +3732,10 @@ var __exports__ = (() => {
3387
3732
  strictOptions,
3388
3733
  context || null
3389
3734
  );
3390
- return await parseWithLoaderInBatches(loader, data, strictOptions, context);
3735
+ const loaderWithParser = await getLoaderImplementation(loader, strictOptions, context.url);
3736
+ return await parseWithLoaderInBatches(loader, loaderWithParser, data, strictOptions, context);
3391
3737
  }
3392
- async function parseWithLoaderInBatches(loader, data, options, context) {
3738
+ async function parseWithLoaderInBatches(originalLoader, loader, data, options, context) {
3393
3739
  const outputIterator = await parseToOutputIterator(loader, data, options, context);
3394
3740
  if (!options?.core?.metadata) {
3395
3741
  return outputIterator;
@@ -3398,7 +3744,7 @@ var __exports__ = (() => {
3398
3744
  shape: "metadata",
3399
3745
  batchType: "metadata",
3400
3746
  metadata: {
3401
- _loader: loader,
3747
+ _loader: originalLoader,
3402
3748
  _context: context
3403
3749
  },
3404
3750
  // Populate with some default fields to avoid crashing
@@ -3452,6 +3798,34 @@ var __exports__ = (() => {
3452
3798
  return iteratorChain;
3453
3799
  }
3454
3800
 
3801
+ // src/lib/api/load-in-batches.ts
3802
+ function loadInBatches(files, loaders, options, context) {
3803
+ let loadersArray;
3804
+ if (!Array.isArray(loaders) && !isLoaderObject(loaders)) {
3805
+ context = void 0;
3806
+ options = loaders;
3807
+ loadersArray = void 0;
3808
+ } else {
3809
+ loadersArray = loaders;
3810
+ }
3811
+ const fetch2 = getFetchFunction(options || {});
3812
+ if (!Array.isArray(files)) {
3813
+ return loadOneFileInBatches(files, loadersArray, options || {}, fetch2);
3814
+ }
3815
+ const promises = files.map(
3816
+ (file) => loadOneFileInBatches(file, loadersArray, options || {}, fetch2)
3817
+ );
3818
+ return promises;
3819
+ }
3820
+ async function loadOneFileInBatches(file, loaders, options, fetch2) {
3821
+ if (typeof file === "string") {
3822
+ const url = file;
3823
+ const response = await fetch2(url);
3824
+ return Array.isArray(loaders) ? await parseInBatches(response, loaders, options) : await parseInBatches(response, loaders, options);
3825
+ }
3826
+ return Array.isArray(loaders) ? await parseInBatches(file, loaders, options) : await parseInBatches(file, loaders, options);
3827
+ }
3828
+
3455
3829
  // src/lib/api/load.ts
3456
3830
  async function load(url, loaders, options, context) {
3457
3831
  let resolvedLoaders;
@@ -3464,6 +3838,62 @@ var __exports__ = (() => {
3464
3838
  resolvedLoaders = loaders;
3465
3839
  resolvedOptions = options;
3466
3840
  }
3841
+ if (!Array.isArray(resolvedLoaders) && isSourceLoader(resolvedLoaders)) {
3842
+ const sourceLoader = await resolveSourceLoader(resolvedLoaders, url, resolvedOptions);
3843
+ const runtimeCoreApi = {
3844
+ fetchFile,
3845
+ parse,
3846
+ parseFile,
3847
+ parseSync,
3848
+ parseInBatches,
3849
+ load,
3850
+ loadInBatches
3851
+ };
3852
+ return sourceLoader.createDataSource(
3853
+ url,
3854
+ resolvedOptions || {},
3855
+ runtimeCoreApi
3856
+ );
3857
+ }
3858
+ if (Array.isArray(resolvedLoaders) && resolvedLoaders.length === 1 && isSourceLoader(resolvedLoaders[0])) {
3859
+ const sourceLoader = await resolveSourceLoader(resolvedLoaders[0], url, resolvedOptions);
3860
+ const runtimeCoreApi = {
3861
+ fetchFile,
3862
+ parse,
3863
+ parseFile,
3864
+ parseSync,
3865
+ parseInBatches,
3866
+ load,
3867
+ loadInBatches
3868
+ };
3869
+ return sourceLoader.createDataSource(
3870
+ url,
3871
+ resolvedOptions || {},
3872
+ runtimeCoreApi
3873
+ );
3874
+ }
3875
+ if (typeof url === "string" || isBlob(url)) {
3876
+ const selectedLoader = await selectLoader(url, resolvedLoaders, {
3877
+ ...resolvedOptions,
3878
+ core: { ...resolvedOptions?.core, nothrow: true }
3879
+ });
3880
+ if (selectedLoader && isSourceLoader(selectedLoader)) {
3881
+ const sourceLoader = await resolveSourceLoader(selectedLoader, url, resolvedOptions);
3882
+ return sourceLoader.createDataSource(
3883
+ url,
3884
+ resolvedOptions || {},
3885
+ {
3886
+ fetchFile,
3887
+ parse,
3888
+ parseFile,
3889
+ parseSync,
3890
+ parseInBatches,
3891
+ load,
3892
+ loadInBatches
3893
+ }
3894
+ );
3895
+ }
3896
+ }
3467
3897
  const fetch2 = getFetchFunction(resolvedOptions);
3468
3898
  let data = url;
3469
3899
  if (typeof url === "string") {
@@ -3484,35 +3914,140 @@ var __exports__ = (() => {
3484
3914
  };
3485
3915
  }
3486
3916
  }
3487
- return Array.isArray(resolvedLoaders) ? await parse(data, resolvedLoaders, resolvedOptions) : await parse(data, resolvedLoaders, resolvedOptions);
3917
+ return Array.isArray(resolvedLoaders) ? await parse(data, resolvedLoaders, resolvedOptions, context) : await parse(data, resolvedLoaders, resolvedOptions, context);
3918
+ }
3919
+ async function resolveSourceLoader(loader, url, options) {
3920
+ if (!loader.preload) {
3921
+ return loader;
3922
+ }
3923
+ const sourceLoader = await loader.preload(typeof url === "string" ? url : "", options);
3924
+ if (!isSourceLoader(sourceLoader)) {
3925
+ throw new Error(`${loader.id} source loader preload() did not return a runtime source loader`);
3926
+ }
3927
+ return sourceLoader;
3488
3928
  }
3489
3929
 
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)) {
3930
+ // src/lib/api/core-api.ts
3931
+ var coreApi = Object.freeze({
3932
+ fetchFile,
3933
+ parse,
3934
+ parseFile,
3935
+ parseSync,
3936
+ parseInBatches,
3937
+ load,
3938
+ loadInBatches
3939
+ });
3940
+
3941
+ // src/lib/loader-utils/loader-context.ts
3942
+ function getLoaderContext(context, options, parentContext) {
3943
+ if (parentContext) {
3944
+ return parentContext;
3945
+ }
3946
+ const newContext = {
3947
+ ...context,
3948
+ fetch: getFetchFunction(options, context),
3949
+ coreApi: context.coreApi || coreApi
3950
+ };
3951
+ if (newContext.url) {
3952
+ const baseUrl = stripQueryString(newContext.url);
3953
+ newContext.baseUrl = baseUrl;
3954
+ newContext.queryString = extractQueryString(newContext.url);
3955
+ newContext.filename = path_exports.filename(baseUrl);
3956
+ newContext.baseUrl = path_exports.dirname(baseUrl);
3957
+ }
3958
+ if (!Array.isArray(newContext.loaders)) {
3959
+ newContext.loaders = null;
3960
+ }
3961
+ return newContext;
3962
+ }
3963
+ function getLoadersFromContext(loaders, context) {
3964
+ if (loaders && !Array.isArray(loaders)) {
3965
+ return loaders;
3966
+ }
3967
+ let candidateLoaders;
3968
+ if (loaders) {
3969
+ candidateLoaders = Array.isArray(loaders) ? loaders : [loaders];
3970
+ }
3971
+ if (context && context.loaders) {
3972
+ const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders];
3973
+ candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders;
3974
+ }
3975
+ return candidateLoaders && candidateLoaders.length ? candidateLoaders : void 0;
3976
+ }
3977
+
3978
+ // src/lib/api/parse.ts
3979
+ async function parse(data, loaders, options, context) {
3980
+ if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {
3494
3981
  context = void 0;
3495
3982
  options = loaders;
3496
- loadersArray = void 0;
3497
- } else {
3498
- loadersArray = loaders;
3983
+ loaders = void 0;
3499
3984
  }
3500
- const fetch2 = getFetchFunction(options || {});
3501
- if (!Array.isArray(files)) {
3502
- return loadOneFileInBatches(files, loadersArray, options || {}, fetch2);
3985
+ data = await data;
3986
+ options = options || {};
3987
+ const url = getResourceUrl(data);
3988
+ const typedLoaders = loaders;
3989
+ const candidateLoaders = getLoadersFromContext(typedLoaders, context);
3990
+ const loader = await selectLoader(data, candidateLoaders, options);
3991
+ if (!loader) {
3992
+ return null;
3503
3993
  }
3504
- const promises = files.map(
3505
- (file) => loadOneFileInBatches(file, loadersArray, options || {}, fetch2)
3994
+ if (isSourceLoader(loader)) {
3995
+ throw new Error(
3996
+ `${loader.id} is a SourceLoader. Use load() to create a runtime source object instead of parse().`
3997
+ );
3998
+ }
3999
+ const strictOptions = normalizeOptions(options, loader, candidateLoaders, url);
4000
+ context = getLoaderContext(
4001
+ // @ts-expect-error
4002
+ { url, _parse: parse, loaders: candidateLoaders },
4003
+ strictOptions,
4004
+ context || null
3506
4005
  );
3507
- return promises;
4006
+ return await parseWithLoader(loader, data, strictOptions, context);
3508
4007
  }
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);
4008
+ async function parseWithLoader(loader, data, options, context) {
4009
+ validateWorkerVersion(loader);
4010
+ options = mergeOptions(loader.options, options);
4011
+ if (isResponse(data)) {
4012
+ const { ok, redirected, status, statusText, type, url } = data;
4013
+ const headers = Object.fromEntries(data.headers.entries());
4014
+ context.response = { headers, ok, redirected, status, statusText, type, url };
3514
4015
  }
3515
- return Array.isArray(loaders) ? await parseInBatches(file, loaders, options) : await parseInBatches(file, loaders, options);
4016
+ const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
4017
+ if (canParseWithWorker(loaderWithParser, options)) {
4018
+ data = await getArrayBufferFromData(data, options);
4019
+ return await parseWithWorker(loaderWithParser, data, options, context, parse);
4020
+ }
4021
+ if (isBlob(data) && loaderWithParser.parseBlob) {
4022
+ return await loaderWithParser.parseBlob(data, options, context);
4023
+ }
4024
+ data = await getArrayBufferOrStringFromData(data, loader, options);
4025
+ return await parseWithLoaderImplementation(loaderWithParser, data, options, context);
4026
+ }
4027
+ async function parseWithLoaderImplementation(loader, data, options, context) {
4028
+ if (loader.parseText && typeof data === "string") {
4029
+ return await loader.parseText(data, options, context);
4030
+ }
4031
+ if (loader.parseTextSync && typeof data === "string") {
4032
+ return loader.parseTextSync(data, options, context);
4033
+ }
4034
+ if (loader.parse) {
4035
+ return await loader.parse(data, options, context);
4036
+ }
4037
+ if (loader.parseSync) {
4038
+ throw new Error(
4039
+ `${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 || ""}`
4040
+ );
4041
+ }
4042
+ throw new Error(`${loader.id} loader - no parser found and worker is disabled`);
4043
+ }
4044
+
4045
+ // src/lib/api/preload.ts
4046
+ async function preload(loader, options, url) {
4047
+ return await getLoaderImplementation(loader, options, url);
4048
+ }
4049
+ function preloadSync(loader) {
4050
+ return getLoaderImplementationSync(loader);
3516
4051
  }
3517
4052
 
3518
4053
  // src/lib/api/encode-table.ts
@@ -3638,20 +4173,18 @@ var __exports__ = (() => {
3638
4173
 
3639
4174
  // src/lib/api/create-data-source.ts
3640
4175
  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);
4176
+ const resolvedOptions = options || {};
4177
+ const type = resolvedOptions?.core?.type || resolvedOptions.type || "auto";
4178
+ const source = sources.length === 1 ? sources[0] : type === "auto" ? selectLoaderSync(data, sources, {
4179
+ // `createDataSource` supports non-fetch inputs such as in-memory tables.
4180
+ // Selection remains best-effort for those cases.
4181
+ ...resolvedOptions,
4182
+ core: { ...resolvedOptions?.core, type: "auto" }
4183
+ }) : getSourceOfType(type, sources);
3643
4184
  if (!source) {
3644
4185
  throw new Error("Not a valid source type");
3645
4186
  }
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;
4187
+ return source.createDataSource(data, resolvedOptions, coreApi);
3655
4188
  }
3656
4189
  function getSourceOfType(type, sources) {
3657
4190
  for (const service of sources) {
@@ -3663,15 +4196,11 @@ var __exports__ = (() => {
3663
4196
  }
3664
4197
 
3665
4198
  // src/lib/api/select-source.ts
3666
- function selectSource2(url, sources, options) {
4199
+ function selectSource(url, sources, options) {
3667
4200
  const type = options?.type || "auto";
3668
4201
  let selectedSource = null;
3669
4202
  if (type === "auto") {
3670
- for (const source of sources) {
3671
- if (typeof url === "string" && source.testURL && source.testURL(url)) {
3672
- return source;
3673
- }
3674
- }
4203
+ selectedSource = selectLoaderSync(url, sources, { core: { nothrow: true } });
3675
4204
  } else {
3676
4205
  selectedSource = getSourceOfType2(type, sources);
3677
4206
  }