@loaders.gl/scene 5.0.0-beta.4 → 5.0.0-beta.5

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 (177) hide show
  1. package/DRACO-README.md +1 -1
  2. package/GLTF-README.md +1 -1
  3. package/OBJ-README.md +1 -1
  4. package/README.md +6 -1
  5. package/THIRD-PARTY-NOTICES.md +6 -0
  6. package/dist/dist.dev.js +2958 -750
  7. package/dist/dist.min.js +18 -18
  8. package/dist/draco/draco-javascript-loader-with-parser.d.ts +2 -2
  9. package/dist/draco/draco-loader-types.cjs +3 -3
  10. package/dist/draco/draco-loader-types.cjs.map +2 -2
  11. package/dist/draco/draco-loader-types.d.ts +1 -1
  12. package/dist/draco/draco-loader-types.d.ts.map +1 -1
  13. package/dist/draco/draco-loader-types.js +1 -1
  14. package/dist/draco/draco-loader-types.js.map +1 -1
  15. package/dist/draco/draco-loader.d.ts +2 -2
  16. package/dist/draco/draco-wasm-loader-with-parser.d.ts +2 -2
  17. package/dist/draco/draco3d-loader-with-parser.d.ts +2 -2
  18. package/dist/draco/lib/utils/version.cjs +1 -1
  19. package/dist/draco/lib/utils/version.js +1 -1
  20. package/dist/draco-worker-node.js +400 -113
  21. package/dist/draco-worker-node.js.map +4 -4
  22. package/dist/draco-worker.js +394 -113
  23. package/dist/draco-worker.js.map +4 -4
  24. package/dist/draco-writer-worker-node.cjs +654 -85
  25. package/dist/draco-writer-worker-node.cjs.map +4 -4
  26. package/dist/draco-writer-worker.js +624 -69
  27. package/dist/draco-writer-worker.js.map +4 -4
  28. package/dist/gltf/lib/extensions/KHR_gaussian_splatting.cjs +11 -4
  29. package/dist/gltf/lib/extensions/KHR_gaussian_splatting.cjs.map +2 -2
  30. package/dist/gltf/lib/extensions/KHR_gaussian_splatting.d.ts.map +1 -1
  31. package/dist/gltf/lib/extensions/KHR_gaussian_splatting.js +12 -2
  32. package/dist/gltf/lib/extensions/KHR_gaussian_splatting.js.map +1 -1
  33. package/dist/gltf/lib/parsers/parse-gltf.cjs.map +2 -2
  34. package/dist/gltf/lib/parsers/parse-gltf.d.ts +2 -0
  35. package/dist/gltf/lib/parsers/parse-gltf.d.ts.map +1 -1
  36. package/dist/gltf/lib/parsers/parse-gltf.js.map +1 -1
  37. package/dist/gltf/lib/types/gltf-additional-extension-schemas.cjs +22 -0
  38. package/dist/gltf/lib/types/gltf-additional-extension-schemas.cjs.map +2 -2
  39. package/dist/gltf/lib/types/gltf-additional-extension-schemas.d.ts +23 -0
  40. package/dist/gltf/lib/types/gltf-additional-extension-schemas.d.ts.map +1 -1
  41. package/dist/gltf/lib/types/gltf-additional-extension-schemas.js +22 -0
  42. package/dist/gltf/lib/types/gltf-additional-extension-schemas.js.map +1 -1
  43. package/dist/gltf/lib/types/gltf-extension-schemas.cjs +8 -0
  44. package/dist/gltf/lib/types/gltf-extension-schemas.cjs.map +2 -2
  45. package/dist/gltf/lib/types/gltf-extension-schemas.d.ts +27 -0
  46. package/dist/gltf/lib/types/gltf-extension-schemas.d.ts.map +1 -1
  47. package/dist/gltf/lib/types/gltf-extension-schemas.js +8 -1
  48. package/dist/gltf/lib/types/gltf-extension-schemas.js.map +1 -1
  49. package/dist/gltf/lib/types/gltf-json-schema.cjs.map +1 -1
  50. package/dist/gltf/lib/types/gltf-json-schema.d.ts +2 -2
  51. package/dist/gltf/lib/types/gltf-json-schema.d.ts.map +1 -1
  52. package/dist/gltf/lib/types/gltf-version-zod-schemas.d.ts +34 -0
  53. package/dist/gltf/lib/types/gltf-version-zod-schemas.d.ts.map +1 -1
  54. package/dist/gltf/lib/types/gltf-zod-schema.cjs +1 -1
  55. package/dist/gltf/lib/types/gltf-zod-schema.cjs.map +2 -2
  56. package/dist/gltf/lib/types/gltf-zod-schema.d.ts +51 -0
  57. package/dist/gltf/lib/types/gltf-zod-schema.d.ts.map +1 -1
  58. package/dist/gltf/lib/types/gltf-zod-schema.js +2 -2
  59. package/dist/gltf/lib/types/gltf-zod-schema.js.map +1 -1
  60. package/dist/gltf/lib/utils/version.cjs +1 -1
  61. package/dist/gltf/lib/utils/version.js +1 -1
  62. package/dist/index.cjs +4 -1
  63. package/dist/index.cjs.map +2 -2
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +2 -1
  67. package/dist/index.js.map +1 -1
  68. package/dist/mtl-loader-types.cjs +1 -1
  69. package/dist/obj/mtl-loader-types.cjs +1 -1
  70. package/dist/obj/mtl-loader-types.js +1 -1
  71. package/dist/obj/obj-loader-types.cjs +3 -3
  72. package/dist/obj/obj-loader-types.cjs.map +2 -2
  73. package/dist/obj/obj-loader-types.d.ts +1 -1
  74. package/dist/obj/obj-loader-types.d.ts.map +1 -1
  75. package/dist/obj/obj-loader-types.js +2 -2
  76. package/dist/obj/obj-loader-types.js.map +1 -1
  77. package/dist/obj/obj-loader.cjs +5 -5
  78. package/dist/obj/obj-loader.cjs.map +2 -2
  79. package/dist/obj/obj-loader.d.ts +1 -1
  80. package/dist/obj/obj-loader.d.ts.map +1 -1
  81. package/dist/obj/obj-loader.js +1 -1
  82. package/dist/obj/obj-loader.js.map +1 -1
  83. package/dist/obj/obj-writer.cjs +1 -1
  84. package/dist/obj/obj-writer.js +1 -1
  85. package/dist/obj-loader-types.cjs +3 -3
  86. package/dist/obj-loader-types.cjs.map +2 -2
  87. package/dist/obj-loader.cjs +5 -5
  88. package/dist/obj-loader.cjs.map +2 -2
  89. package/dist/obj-worker.js +568 -287
  90. package/dist/obj-writer.cjs +1 -1
  91. package/dist/stl/parse-stl.cjs +100 -0
  92. package/dist/stl/parse-stl.cjs.map +7 -0
  93. package/dist/stl/parse-stl.d.ts +4 -0
  94. package/dist/stl/parse-stl.d.ts.map +1 -0
  95. package/dist/stl/parse-stl.js +84 -0
  96. package/dist/stl/parse-stl.js.map +1 -0
  97. package/dist/stl-loader-types.cjs +58 -0
  98. package/dist/stl-loader-types.cjs.map +7 -0
  99. package/dist/stl-loader-types.d.ts +32 -0
  100. package/dist/stl-loader-types.d.ts.map +1 -0
  101. package/dist/stl-loader-types.js +25 -0
  102. package/dist/stl-loader-types.js.map +1 -0
  103. package/dist/stl-loader.cjs +38 -0
  104. package/dist/stl-loader.cjs.map +7 -0
  105. package/dist/stl-loader.d.ts +17 -0
  106. package/dist/stl-loader.d.ts.map +1 -0
  107. package/dist/stl-loader.js +13 -0
  108. package/dist/stl-loader.js.map +1 -0
  109. package/dist/usd/index.cjs.map +1 -1
  110. package/dist/usd/index.d.ts +1 -1
  111. package/dist/usd/index.d.ts.map +1 -1
  112. package/dist/usd/lib/parse-usd.cjs +42 -5
  113. package/dist/usd/lib/parse-usd.cjs.map +2 -2
  114. package/dist/usd/lib/parse-usd.d.ts.map +1 -1
  115. package/dist/usd/lib/parse-usd.js +53 -6
  116. package/dist/usd/lib/parse-usd.js.map +1 -1
  117. package/dist/usd/lib/parse-usdc.cjs +187 -0
  118. package/dist/usd/lib/parse-usdc.cjs.map +7 -0
  119. package/dist/usd/lib/parse-usdc.d.ts +4 -0
  120. package/dist/usd/lib/parse-usdc.d.ts.map +1 -0
  121. package/dist/usd/lib/parse-usdc.js +176 -0
  122. package/dist/usd/lib/parse-usdc.js.map +1 -0
  123. package/dist/usd/lib/parse-usdz.cjs +22 -0
  124. package/dist/usd/lib/parse-usdz.cjs.map +2 -2
  125. package/dist/usd/lib/parse-usdz.d.ts.map +1 -1
  126. package/dist/usd/lib/parse-usdz.js +26 -0
  127. package/dist/usd/lib/parse-usdz.js.map +1 -1
  128. package/dist/usd/lib/usd-types.cjs.map +1 -1
  129. package/dist/usd/lib/usd-types.d.ts +14 -1
  130. package/dist/usd/lib/usd-types.d.ts.map +1 -1
  131. package/dist/usd/lib/usd-types.js +1 -1
  132. package/dist/usd/lib/usd-types.js.map +1 -1
  133. package/dist/usd/libs/README.md +27 -0
  134. package/dist/usd/libs/THREE-LICENSE +21 -0
  135. package/dist/usd/libs/usdc-parser.d.ts +78 -0
  136. package/dist/usd/libs/usdc-parser.d.ts.map +1 -0
  137. package/dist/usd/libs/usdc-parser.js +1669 -0
  138. package/dist/usd/libs/usdc-parser.js.map +1 -0
  139. package/dist/usd/usd-loader-types.cjs +4 -4
  140. package/dist/usd/usd-loader-types.cjs.map +2 -2
  141. package/dist/usd/usd-loader-types.d.ts +7 -7
  142. package/dist/usd/usd-loader-types.d.ts.map +1 -1
  143. package/dist/usd/usd-loader-types.js +6 -6
  144. package/dist/usd/usd-loader-types.js.map +1 -1
  145. package/dist/usd/usd-loader.cjs.map +1 -1
  146. package/dist/usd/usd-loader.d.ts +4 -4
  147. package/dist/usd/usd-loader.d.ts.map +1 -1
  148. package/dist/usd/usd-loader.js +2 -2
  149. package/dist/usd/usd-loader.js.map +1 -1
  150. package/dist/usd-loader-types.cjs +4 -4
  151. package/dist/usd-loader-types.cjs.map +2 -2
  152. package/dist/usd-loader.cjs.map +1 -1
  153. package/package.json +14 -8
  154. package/src/draco/draco-loader-types.ts +1 -1
  155. package/src/gltf/lib/extensions/KHR_gaussian_splatting.ts +14 -4
  156. package/src/gltf/lib/parsers/parse-gltf.ts +2 -0
  157. package/src/gltf/lib/types/gltf-additional-extension-schemas.ts +32 -0
  158. package/src/gltf/lib/types/gltf-extension-schemas.ts +12 -0
  159. package/src/gltf/lib/types/gltf-json-schema.ts +2 -1
  160. package/src/gltf/lib/types/gltf-zod-schema.ts +2 -1
  161. package/src/index.ts +3 -1
  162. package/src/obj/obj-loader-types.ts +1 -1
  163. package/src/obj/obj-loader.ts +1 -1
  164. package/src/stl/parse-stl.ts +90 -0
  165. package/src/stl-loader-types.ts +28 -0
  166. package/src/stl-loader.ts +12 -0
  167. package/src/usd/index.ts +1 -0
  168. package/src/usd/lib/parse-usd.ts +68 -7
  169. package/src/usd/lib/parse-usdc.ts +188 -0
  170. package/src/usd/lib/parse-usdz.ts +28 -0
  171. package/src/usd/lib/usd-types.ts +16 -2
  172. package/src/usd/libs/README.md +27 -0
  173. package/src/usd/libs/THREE-LICENSE +21 -0
  174. package/src/usd/libs/usdc-parser.d.ts +18 -0
  175. package/src/usd/libs/usdc-parser.js +1669 -0
  176. package/src/usd/usd-loader-types.ts +5 -5
  177. package/src/usd/usd-loader.ts +2 -2
@@ -50,7 +50,7 @@
50
50
 
51
51
  // ../core/src/worker-utils/lib/env-utils/version.ts
52
52
  function getVersion() {
53
- const version = false ? NPM_TAG : "5.0.0-beta.4";
53
+ const version = false ? NPM_TAG : "5.0.0-beta.5";
54
54
  globalThis._loadersgl_ = globalThis._loadersgl_ || {};
55
55
  globalThis._loadersgl_.version ||= version;
56
56
  return version;
@@ -84,23 +84,23 @@
84
84
  var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
85
85
  var nodeVersion = matches && parseFloat(matches[1]) || 0;
86
86
 
87
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/npm-tag.js
87
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/npm-tag.js
88
88
  var NPM_TAG2 = "latest";
89
89
 
90
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/env-utils/version.js
90
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/env-utils/version.js
91
91
  function getVersion2() {
92
- return false ? NPM_TAG2 : "5.0.0-beta.4";
92
+ return false ? NPM_TAG2 : "5.0.0-beta.5";
93
93
  }
94
94
  var VERSION2 = getVersion2();
95
95
 
96
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/env-utils/assert.js
96
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/env-utils/assert.js
97
97
  function assert2(condition, message) {
98
98
  if (!condition) {
99
99
  throw new Error(message || "loaders.gl assertion failed.");
100
100
  }
101
101
  }
102
102
 
103
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/env-utils/globals.js
103
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/env-utils/globals.js
104
104
  var globals2 = {
105
105
  self: typeof self !== "undefined" && self,
106
106
  window: typeof window !== "undefined" && window,
@@ -119,7 +119,7 @@
119
119
  var matches2 = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
120
120
  var nodeVersion2 = matches2 && parseFloat(matches2[1]) || 0;
121
121
 
122
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-farm/worker-job.js
122
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-farm/worker-job.js
123
123
  var WorkerJob = class {
124
124
  constructor(jobName, workerThread) {
125
125
  this.isRunning = true;
@@ -236,7 +236,7 @@
236
236
  return error;
237
237
  }
238
238
 
239
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/node/worker_threads-browser.js
239
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/node/worker_threads-browser.js
240
240
  var NodeWorker = class {
241
241
  /** Restores the native worker constructor when this browser shim is embedded in a Node bundle. */
242
242
  constructor(...arguments_) {
@@ -252,7 +252,7 @@
252
252
  };
253
253
  var parentPort = globalThis.process?.getBuiltinModule?.("node:worker_threads")?.parentPort ?? null;
254
254
 
255
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-utils/get-loadable-worker-url.js
255
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-utils/get-loadable-worker-url.js
256
256
  var workerURLCache = /* @__PURE__ */ new Map();
257
257
  function getLoadableWorkerURL(props) {
258
258
  assert2(props.source && !props.url || !props.source && props.url);
@@ -301,7 +301,7 @@
301
301
  }`;
302
302
  }
303
303
 
304
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-utils/get-transfer-list.js
304
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-utils/get-transfer-list.js
305
305
  function getTransferList(object, recursive = true, transfers) {
306
306
  const transfersSet = transfers || /* @__PURE__ */ new Set();
307
307
  const seen = /* @__PURE__ */ new Set();
@@ -385,7 +385,7 @@
385
385
  return object === null ? {} : clone(object);
386
386
  }
387
387
 
388
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-farm/worker-thread.js
388
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-farm/worker-thread.js
389
389
  var NOOP = () => {
390
390
  };
391
391
  var WorkerThread = class {
@@ -566,7 +566,7 @@
566
566
  }
567
567
  };
568
568
 
569
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-farm/worker-pool.js
569
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-farm/worker-pool.js
570
570
  var WorkerPool = class {
571
571
  /** Snapshot; byte figures describe input buffers, not total heap memory. */
572
572
  get stats() {
@@ -1092,7 +1092,7 @@
1092
1092
  }
1093
1093
  };
1094
1094
 
1095
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-farm/worker-farm.js
1095
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-farm/worker-farm.js
1096
1096
  var DEFAULT_PROPS = {
1097
1097
  maxQueuedJobs: Infinity,
1098
1098
  maxPendingAdmissions: 128,
@@ -1213,7 +1213,7 @@
1213
1213
  return loadWorkerId;
1214
1214
  }
1215
1215
 
1216
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-farm/worker-body.js
1216
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-farm/worker-body.js
1217
1217
  async function getParentPort() {
1218
1218
  return parentPort;
1219
1219
  }
@@ -1300,7 +1300,7 @@
1300
1300
  return messageData && typeof messageData.source === "string" && messageData.source.startsWith("loaders.gl") ? messageData : null;
1301
1301
  }
1302
1302
 
1303
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/async-queue/async-queue.js
1303
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/async-queue/async-queue.js
1304
1304
  var AsyncQueue = class {
1305
1305
  constructor() {
1306
1306
  this._values = [];
@@ -1367,7 +1367,7 @@
1367
1367
  }
1368
1368
  };
1369
1369
 
1370
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-api/get-worker-url.js
1370
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-api/get-worker-url.js
1371
1371
  var warnedWorkerVersionFallbacks = /* @__PURE__ */ new Set();
1372
1372
  function getWorkerName(worker) {
1373
1373
  const warning = worker.version !== VERSION2 ? ` (worker-utils@${VERSION2})` : "";
@@ -1381,7 +1381,7 @@
1381
1381
  if (isBrowser2) {
1382
1382
  url = `modules/${worker.module}/dist/${workerFile}`;
1383
1383
  } else {
1384
- const workerSourceDirectory = worker.module === "core" && worker.workerNode?.startsWith("worker-utils/") ? "worker-utils/workers" : "workers";
1384
+ const workerSourceDirectory = worker.module === "tasks" && worker.workerNode?.startsWith("worker-utils/") ? "worker-utils/workers" : "workers";
1385
1385
  const workerSourceNode = worker.workerSourceNode || `${workerSourceDirectory}/${worker.id}-worker-node.ts`;
1386
1386
  url = `modules/${worker.module}/src/${workerSourceNode}`;
1387
1387
  }
@@ -1425,7 +1425,7 @@
1425
1425
  console.warn(`loaders.gl: ${worker.name} loader worker version is "latest" because __VERSION__ was not injected. Fetching ${url} from CDN.`);
1426
1426
  }
1427
1427
 
1428
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-api/shared-state.js
1428
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-api/shared-state.js
1429
1429
  function getWorkerCapabilities() {
1430
1430
  const isolated = typeof globalThis.crossOriginIsolated === "boolean" ? globalThis.crossOriginIsolated : void 0;
1431
1431
  const capabilities = {
@@ -1508,7 +1508,7 @@
1508
1508
  return options;
1509
1509
  }
1510
1510
 
1511
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-utils/get-input-byte-length.js
1511
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-utils/get-input-byte-length.js
1512
1512
  function getInputByteLength(input) {
1513
1513
  const seen = /* @__PURE__ */ new Set();
1514
1514
  let bytes = 0;
@@ -1537,14 +1537,14 @@
1537
1537
  return bytes;
1538
1538
  }
1539
1539
 
1540
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-api/validate-output-ownership.js
1540
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-api/validate-output-ownership.js
1541
1541
  function validateOutputOwnership(ownership) {
1542
1542
  if (ownership !== void 0 && ownership !== "copy" && ownership !== "transfer") {
1543
1543
  throw new Error("Invalid worker output ownership");
1544
1544
  }
1545
1545
  }
1546
1546
 
1547
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-api/process-on-worker.js
1547
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-api/process-on-worker.js
1548
1548
  async function processOnWorker(worker, data, options = {}, context = {}, jobContext = {}) {
1549
1549
  validateOutputOwnership(options.outputOwnership);
1550
1550
  if (options.inputOwnership !== void 0 && !["copy", "transfer", "share"].includes(options.inputOwnership))
@@ -1838,7 +1838,7 @@
1838
1838
  return inputOptions;
1839
1839
  }
1840
1840
 
1841
- // ../../node_modules/@math.gl/core/dist/worker-utils/lib/worker-api/create-worker.js
1841
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/lib/worker-api/create-worker.js
1842
1842
  var requestId = 0;
1843
1843
  var activeController = null;
1844
1844
  var activeInputBatches = null;
@@ -2046,12 +2046,12 @@
2046
2046
  };
2047
2047
  }
2048
2048
 
2049
- // ../../node_modules/@math.gl/core/dist/worker-utils/index.js
2049
+ // ../../node_modules/@math.gl/tasks/dist/worker-utils/index.js
2050
2050
  var import_meta = {};
2051
2051
  var path = typeof __filename === "string" ? __filename.replace(/\\/g, "/") : "";
2052
2052
  var moduleUrl = path ? `file://${path.startsWith("/") ? "" : "/"}${encodeURI(path).replace(/#/g, "%23").replace(/\?/g, "%3F")}` : import_meta.url;
2053
2053
 
2054
- // ../../node_modules/@math.gl/core/dist/tasks/task-preload.js
2054
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-preload.js
2055
2055
  var pending = /* @__PURE__ */ new WeakMap();
2056
2056
  var loaded = /* @__PURE__ */ new WeakSet();
2057
2057
  function preloadTaskCode(task, signal) {
@@ -2091,7 +2091,151 @@
2091
2091
  });
2092
2092
  }
2093
2093
 
2094
- // ../../node_modules/@math.gl/core/dist/tasks/task-runtime.js
2094
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-channel.js
2095
+ var TaskRequestError = class extends Error {
2096
+ };
2097
+ var TaskChannel = class {
2098
+ constructor(options) {
2099
+ this.options = options;
2100
+ this.nextId = 1;
2101
+ this.pending = /* @__PURE__ */ new Map();
2102
+ this.incoming = /* @__PURE__ */ new Map();
2103
+ }
2104
+ /** Send a request without serializing other in-flight requests. */
2105
+ request(operation, value, signal, transfer = []) {
2106
+ if (this.failure)
2107
+ return Promise.reject(this.failure.reason);
2108
+ if (signal?.aborted)
2109
+ return Promise.reject(signal.reason);
2110
+ const id = this.nextId++;
2111
+ return new Promise((resolve, reject) => {
2112
+ const abort = () => {
2113
+ const pending2 = this.pending.get(id);
2114
+ if (!pending2)
2115
+ return;
2116
+ this.pending.delete(id);
2117
+ pending2.cleanup();
2118
+ reject(signal?.reason);
2119
+ this.send({ source: "math.gl/tasks", kind: "cancel", id });
2120
+ };
2121
+ this.pending.set(id, {
2122
+ resolve,
2123
+ reject,
2124
+ cleanup: () => signal?.removeEventListener("abort", abort)
2125
+ });
2126
+ signal?.addEventListener("abort", abort, { once: true });
2127
+ this.send({ source: "math.gl/tasks", kind: "request", id, operation, value }, transfer);
2128
+ });
2129
+ }
2130
+ /** Send a one-way notification. */
2131
+ emit(operation, value, transfer = []) {
2132
+ if (this.failure)
2133
+ throw this.failure.reason;
2134
+ this.send({ source: "math.gl/tasks", kind: "event", id: 0, operation, value }, transfer);
2135
+ }
2136
+ /** Dispatch a transport message; unrelated protocols are ignored. */
2137
+ receive(message) {
2138
+ if (this.failure || message?.source !== "math.gl/tasks")
2139
+ return;
2140
+ if (message.kind === "failure") {
2141
+ const reason = new Error(message.error?.message ?? "Task channel failed");
2142
+ this.close(reason);
2143
+ this.options.onFailure?.(reason);
2144
+ } else if (message.kind === "result" || message.kind === "error") {
2145
+ const pending2 = this.pending.get(message.id);
2146
+ if (!pending2)
2147
+ return;
2148
+ this.pending.delete(message.id);
2149
+ pending2.cleanup();
2150
+ if (message.kind === "result")
2151
+ pending2.resolve(message.value);
2152
+ else {
2153
+ const error = new TaskRequestError(message.error?.message ?? "Task request failed");
2154
+ error.name = message.error?.name ?? "Error";
2155
+ pending2.reject(error);
2156
+ }
2157
+ } else if (message.kind === "cancel") {
2158
+ this.incoming.get(message.id)?.abort(new DOMException("Task request cancelled", "AbortError"));
2159
+ } else if (message.kind === "event") {
2160
+ try {
2161
+ this.options.handleEvent?.(message.operation, message.value);
2162
+ } catch (error) {
2163
+ this.fail(error);
2164
+ }
2165
+ } else if (message.kind === "request") {
2166
+ if (this.incoming.has(message.id)) {
2167
+ this.fail(new Error("Duplicate task request identifier"));
2168
+ return;
2169
+ }
2170
+ const controller = new AbortController();
2171
+ this.incoming.set(message.id, controller);
2172
+ void Promise.resolve().then(() => {
2173
+ controller.signal.throwIfAborted();
2174
+ return this.options.handleRequest(message.operation, message.value, controller.signal);
2175
+ }).then((value) => {
2176
+ if (!controller.signal.aborted && !this.failure) {
2177
+ this.send({ source: "math.gl/tasks", kind: "result", id: message.id, value }, this.options.getResultTransferList?.(value, message.value));
2178
+ }
2179
+ }).catch((reason) => {
2180
+ if (!controller.signal.aborted && !this.failure) {
2181
+ this.send({
2182
+ source: "math.gl/tasks",
2183
+ kind: "error",
2184
+ id: message.id,
2185
+ error: {
2186
+ name: reason instanceof Error ? reason.name : "Error",
2187
+ message: reason instanceof Error ? reason.message : String(reason)
2188
+ }
2189
+ });
2190
+ }
2191
+ }).finally(() => this.incoming.delete(message.id));
2192
+ }
2193
+ }
2194
+ /** Reject all outstanding calls with a common cause and abort incoming callbacks. */
2195
+ close(reason = new Error("Task channel closed")) {
2196
+ if (this.failure)
2197
+ return;
2198
+ this.failure = { reason };
2199
+ for (const pending2 of this.pending.values()) {
2200
+ pending2.cleanup();
2201
+ pending2.reject(reason);
2202
+ }
2203
+ this.pending.clear();
2204
+ for (const controller of this.incoming.values())
2205
+ controller.abort(reason);
2206
+ this.incoming.clear();
2207
+ }
2208
+ send(message, transfer = []) {
2209
+ if (this.failure)
2210
+ return;
2211
+ try {
2212
+ this.options.send(message, transfer);
2213
+ } catch (error) {
2214
+ this.fail(error);
2215
+ }
2216
+ }
2217
+ /** Invalidate the channel and notify the peer when the transport still works. */
2218
+ fail(reason) {
2219
+ if (this.failure)
2220
+ return;
2221
+ this.close(reason);
2222
+ try {
2223
+ this.options.send({
2224
+ source: "math.gl/tasks",
2225
+ kind: "failure",
2226
+ id: 0,
2227
+ error: {
2228
+ name: reason instanceof Error ? reason.name : "Error",
2229
+ message: reason instanceof Error ? reason.message : String(reason)
2230
+ }
2231
+ }, []);
2232
+ } catch {
2233
+ }
2234
+ this.options.onFailure?.(reason);
2235
+ }
2236
+ };
2237
+
2238
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-runtime.js
2095
2239
  function assertPayload(value) {
2096
2240
  if (!value || typeof value !== "object" || Object.getPrototypeOf(value) !== Object.prototype) {
2097
2241
  throw new TypeError("Task payloads must be plain objects with named fields");
@@ -2113,6 +2257,16 @@
2113
2257
  return {
2114
2258
  state,
2115
2259
  signal,
2260
+ requestHost: async (operation, payload, controls) => {
2261
+ signal.throwIfAborted();
2262
+ if (!context.requestHost)
2263
+ throw new Error("No host request handler configured");
2264
+ return context.requestHost(operation, payload, controls);
2265
+ },
2266
+ emitHost: (operation, payload) => {
2267
+ signal.throwIfAborted();
2268
+ context.emitHost?.(operation, payload);
2269
+ },
2116
2270
  throwIfAborted: () => {
2117
2271
  signal.throwIfAborted();
2118
2272
  context.throwIfAborted?.();
@@ -2177,6 +2331,69 @@
2177
2331
  throw new Error("A task is already installed in this worker");
2178
2332
  installed = true;
2179
2333
  const runtime = new TaskRuntime(task);
2334
+ let channelStream;
2335
+ const channel = new TaskChannel({
2336
+ getResultTransferList: (value, request) => request.outputOwnership === "transfer" ? getTransferList(value) : [],
2337
+ send: (message, transfer) => {
2338
+ const snapshot = structuredClone(message, { transfer });
2339
+ void WorkerBody.postMessage("task-channel", snapshot).catch((reason) => channel.fail(reason));
2340
+ },
2341
+ handleRequest: async (operation, value, signal) => {
2342
+ const request = value;
2343
+ const context = {
2344
+ signal,
2345
+ reportProgress: (progress) => channel.emit("task:progress", { id: request.progressId, progress }),
2346
+ requestHost: (operation2, payload, controls = {}) => {
2347
+ const request2 = {
2348
+ operation: operation2,
2349
+ payload: clonePayload(payload, controls.inputOwnership),
2350
+ outputOwnership: controls.outputOwnership ?? "copy"
2351
+ };
2352
+ return channel.request("task:host-request", request2, signal, getTransferList(request2));
2353
+ },
2354
+ emitHost: (operation2, payload) => channel.emit("task:host-event", { operation: operation2, payload, id: request.progressId })
2355
+ };
2356
+ switch (operation) {
2357
+ case "initialize":
2358
+ return runtime.initialize(request.input, context);
2359
+ case "process":
2360
+ return runtime.process(request.input, request.options, context);
2361
+ case "stream-open": {
2362
+ if (channelStream)
2363
+ throw new Error("A task stream is already open");
2364
+ async function* inputs() {
2365
+ while (true) {
2366
+ const result = await channel.request("task:next-input", { outputOwnership: "transfer" }, signal);
2367
+ if (result.done)
2368
+ return;
2369
+ yield result.value;
2370
+ }
2371
+ }
2372
+ channelStream = runtime.stream(inputs(), request.options, context)[Symbol.asyncIterator]();
2373
+ return {};
2374
+ }
2375
+ case "stream-next":
2376
+ if (!channelStream)
2377
+ throw new Error("No active task stream");
2378
+ return channelStream.next();
2379
+ case "stream-close":
2380
+ try {
2381
+ await channelStream?.return?.();
2382
+ } finally {
2383
+ channelStream = void 0;
2384
+ }
2385
+ return {};
2386
+ case "destroy":
2387
+ return runtime.destroy();
2388
+ default:
2389
+ throw new Error("Unknown task channel operation");
2390
+ }
2391
+ }
2392
+ });
2393
+ await WorkerBody.addEventListener((type, payload) => {
2394
+ if (type === "task-channel")
2395
+ channel.receive(payload);
2396
+ });
2180
2397
  let streamOptions = {};
2181
2398
  return createWorker(async (request, _options, context) => {
2182
2399
  switch (request.operation) {
@@ -2214,7 +2431,7 @@
2214
2431
  };
2215
2432
  }
2216
2433
 
2217
- // ../../node_modules/@math.gl/core/dist/tasks/task-sync.js
2434
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-sync.js
2218
2435
  function runTaskSync(task, input, request = {}) {
2219
2436
  if (!isTaskCodeLoaded(task))
2220
2437
  throw new Error("Preload task on the main thread before runTaskSync");
@@ -2294,18 +2511,155 @@
2294
2511
  return Boolean(value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function");
2295
2512
  }
2296
2513
 
2297
- // ../../node_modules/@math.gl/core/dist/tasks/task-runner.js
2514
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-operation-queue.js
2515
+ var TaskOperationQueue = class {
2516
+ constructor(maxConcurrency) {
2517
+ this.maxConcurrency = maxConcurrency;
2518
+ this.pending = [];
2519
+ this.active = 0;
2520
+ this.exclusive = false;
2521
+ this.closed = false;
2522
+ this.idleWaiters = /* @__PURE__ */ new Set();
2523
+ if (!Number.isSafeInteger(maxConcurrency) || maxConcurrency < 1) {
2524
+ throw new RangeError("maxConcurrency must be a positive safe integer");
2525
+ }
2526
+ }
2527
+ /** Queue an operation; aborting before it starts removes it without running it. */
2528
+ run(mode, operation, signal) {
2529
+ if (this.closed)
2530
+ return Promise.reject(new Error("Task operation queue is closed"));
2531
+ if (mode !== "parallel" && mode !== "exclusive")
2532
+ return Promise.reject(new TypeError("Invalid operation mode"));
2533
+ if (signal?.aborted)
2534
+ return Promise.reject(signal.reason);
2535
+ return new Promise((resolve, reject) => {
2536
+ const onAbort = () => {
2537
+ const index = this.pending.indexOf(entry);
2538
+ if (index >= 0) {
2539
+ this.pending.splice(index, 1);
2540
+ entry.cancel(signal?.reason);
2541
+ this.pump();
2542
+ }
2543
+ };
2544
+ const entry = {
2545
+ mode,
2546
+ cancel: (reason) => {
2547
+ signal?.removeEventListener("abort", onAbort);
2548
+ reject(reason);
2549
+ },
2550
+ start: () => {
2551
+ signal?.removeEventListener("abort", onAbort);
2552
+ this.active++;
2553
+ if (mode === "exclusive")
2554
+ this.exclusive = true;
2555
+ void Promise.resolve().then(() => {
2556
+ signal?.throwIfAborted();
2557
+ return operation();
2558
+ }).then(resolve, reject).finally(() => {
2559
+ this.active--;
2560
+ if (mode === "exclusive")
2561
+ this.exclusive = false;
2562
+ this.pump();
2563
+ });
2564
+ }
2565
+ };
2566
+ this.pending.push(entry);
2567
+ signal?.addEventListener("abort", onAbort, { once: true });
2568
+ if (signal?.aborted)
2569
+ onAbort();
2570
+ else
2571
+ this.pump();
2572
+ });
2573
+ }
2574
+ /** Reject queued calls with one cause while allowing active operations to settle. */
2575
+ cancelPending(reason) {
2576
+ this.closed = true;
2577
+ for (const entry of this.pending.splice(0))
2578
+ entry.cancel(reason);
2579
+ this.pump();
2580
+ }
2581
+ /** Stop accepting new work; accepted operations continue to completion. */
2582
+ close() {
2583
+ this.closed = true;
2584
+ return this.whenIdle();
2585
+ }
2586
+ /** Wait until the queue has no running or waiting operations. */
2587
+ whenIdle() {
2588
+ if (!this.active && !this.pending.length)
2589
+ return Promise.resolve();
2590
+ return new Promise((resolve) => this.idleWaiters.add(resolve));
2591
+ }
2592
+ pump() {
2593
+ while (!this.exclusive && this.pending.length && this.active < this.maxConcurrency) {
2594
+ const entry = this.pending[0];
2595
+ if (entry.mode === "exclusive" && this.active)
2596
+ break;
2597
+ this.pending.shift();
2598
+ entry.start();
2599
+ if (entry.mode === "exclusive")
2600
+ break;
2601
+ }
2602
+ if (!this.active && !this.pending.length) {
2603
+ for (const resolve of this.idleWaiters)
2604
+ resolve();
2605
+ this.idleWaiters.clear();
2606
+ }
2607
+ }
2608
+ };
2609
+
2610
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-worker-channel.js
2611
+ var TaskWorkerChannel = class {
2612
+ constructor(name, target, options) {
2613
+ this.thread = new WorkerThread({
2614
+ name,
2615
+ url: target.url?.toString(),
2616
+ loadWorker: target.create,
2617
+ workerType: "module"
2618
+ });
2619
+ this.channel = new TaskChannel({
2620
+ ...options,
2621
+ send: (message, transfer) => this.thread.postMessage({ source: "loaders.gl/tasks", type: "task-channel", payload: message }, transfer)
2622
+ });
2623
+ this.thread.onMessage = (message) => {
2624
+ if (message?.type === "task-channel")
2625
+ this.channel.receive(message.payload);
2626
+ };
2627
+ this.thread.onError = (reason) => {
2628
+ this.channel.close(reason);
2629
+ options.onFailure?.(reason);
2630
+ };
2631
+ }
2632
+ /** Settle pending calls and terminate the worker without replacing its state. */
2633
+ async destroy(reason) {
2634
+ this.channel.close(reason);
2635
+ await this.thread.destroy();
2636
+ }
2637
+ };
2638
+
2639
+ // ../../node_modules/@math.gl/tasks/dist/tasks/task-runner.js
2298
2640
  var InitializedTask = class {
2299
2641
  /** @internal Use TaskRunner.initializeTask. */
2300
- constructor(task, release, controls) {
2642
+ constructor(task, release, initializationControls) {
2301
2643
  this.task = task;
2302
2644
  this.release = release;
2303
- this.tail = Promise.resolve();
2645
+ this.initializationControls = initializationControls;
2646
+ this.nextProgressId = 1;
2647
+ this.progressCallbacks = /* @__PURE__ */ new Map();
2648
+ this.callbackFailures = /* @__PURE__ */ new Map();
2304
2649
  this.closed = false;
2650
+ this.finalized = false;
2305
2651
  this.streams = /* @__PURE__ */ new Set();
2306
2652
  this.invalid = false;
2307
2653
  this.controller = new AbortController();
2654
+ const controls = initializationControls;
2308
2655
  this.runtime = new TaskRuntime(task);
2656
+ const concurrency = controls.operationConcurrency ?? 1;
2657
+ const maximum = task.concurrency?.maxConcurrency ?? 1;
2658
+ if (!Number.isSafeInteger(maximum) || maximum < 1 || !Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > maximum) {
2659
+ throw new RangeError("Task concurrency must be between 1 and the task maximum");
2660
+ }
2661
+ this.operationQueue = new TaskOperationQueue(concurrency);
2662
+ this.concurrent = concurrency > 1;
2309
2663
  const execution = controls.execution ?? "auto";
2310
2664
  if (!["auto", "main-thread", "worker"].includes(execution))
2311
2665
  throw new TypeError("Invalid execution mode");
@@ -2315,6 +2669,47 @@
2315
2669
  const target = task.worker;
2316
2670
  if (Boolean(target.url) === Boolean(target.create))
2317
2671
  throw new Error("Supply exactly one worker URL or factory");
2672
+ if (this.concurrent || controls.onRequest || controls.onEvent) {
2673
+ this.workerChannel = new TaskWorkerChannel(task.id, target, {
2674
+ handleRequest: async (operation, payload, signal) => {
2675
+ if (operation === "task:next-input") {
2676
+ if (!this.channelInputs)
2677
+ throw new Error("No active task stream");
2678
+ return this.channelInputs.next();
2679
+ }
2680
+ if (!controls.onRequest)
2681
+ throw new Error("No host request handler configured");
2682
+ const request = payload;
2683
+ if (operation !== "task:host-request")
2684
+ throw new Error("Unknown host request");
2685
+ return controls.onRequest(request.operation, request.payload, signal);
2686
+ },
2687
+ getResultTransferList: (value, request) => request.outputOwnership === "transfer" ? getTransferList(value) : [],
2688
+ handleEvent: (operation, payload) => {
2689
+ const { id } = payload;
2690
+ try {
2691
+ if (operation === "task:progress") {
2692
+ const event = payload;
2693
+ (this.progressCallbacks.get(event.id) ?? this.streamProgress)?.(event.progress);
2694
+ } else if (operation === "task:host-event") {
2695
+ const event = payload;
2696
+ controls.onEvent?.(event.operation, event.payload);
2697
+ }
2698
+ } catch (reason) {
2699
+ if (this.progressCallbacks.has(id) || this.streamProgressId === id) {
2700
+ if (!this.callbackFailures.has(id))
2701
+ this.callbackFailures.set(id, { reason });
2702
+ }
2703
+ }
2704
+ },
2705
+ onFailure: (reason) => {
2706
+ this.invalid = true;
2707
+ this.operationQueue.cancelPending(reason);
2708
+ this.controller.abort(reason);
2709
+ }
2710
+ });
2711
+ return;
2712
+ }
2318
2713
  this.pool = new WorkerPool({
2319
2714
  name: task.id,
2320
2715
  url: target.url?.toString(),
@@ -2326,7 +2721,7 @@
2326
2721
  this.descriptor = {
2327
2722
  id: task.id,
2328
2723
  name: task.id,
2329
- module: "core",
2724
+ module: "tasks",
2330
2725
  version: "prototype",
2331
2726
  options: {},
2332
2727
  worker: target.url?.toString() ?? true,
@@ -2346,23 +2741,48 @@
2346
2741
  }
2347
2742
  }
2348
2743
  runTask(input, ...args) {
2349
- return this.enqueue(async () => {
2744
+ if (this.invalid)
2745
+ return Promise.reject(new Error("Initialized task is invalid; initialize a new instance"));
2746
+ if (this.closed)
2747
+ return Promise.reject(new Error("Initialized task is closed"));
2748
+ const timeout = args[0]?.timeout;
2749
+ if (timeout !== void 0 && (!Number.isSafeInteger(timeout) || timeout < 0 || timeout > 4294967295)) {
2750
+ return Promise.reject(new RangeError("Invalid task timeout"));
2751
+ }
2752
+ const deadline = timeout === void 0 ? void 0 : AbortSignal.timeout(timeout);
2753
+ const signal = deadline && args[0]?.signal ? AbortSignal.any([deadline, args[0].signal]) : deadline ?? args[0]?.signal;
2754
+ const controls = { ...args[0], signal };
2755
+ const mode = this.task.concurrency?.getSchedulingMode?.(input) ?? "exclusive";
2756
+ return this.operationQueue.run(mode, async () => {
2757
+ signal?.throwIfAborted();
2350
2758
  this.checkCapability("atomic");
2351
- return this.invoke("process", input, args[0]?.options ?? {}, args[0]);
2352
- });
2759
+ const invalidate = () => {
2760
+ if (this.concurrent) {
2761
+ this.invalid = true;
2762
+ this.operationQueue.cancelPending(signal?.reason);
2763
+ this.controller.abort(signal?.reason);
2764
+ }
2765
+ };
2766
+ signal?.addEventListener("abort", invalidate, { once: true });
2767
+ try {
2768
+ return await this.invoke("process", input, args[0]?.options ?? {}, controls);
2769
+ } finally {
2770
+ signal?.removeEventListener("abort", invalidate);
2771
+ }
2772
+ }, signal);
2353
2773
  }
2354
2774
  /** Independent calls sharing this instance, always serial and in input order. */
2355
- async *runTasks(inputs, ...args) {
2356
- yield* this.serialStream(async function* (self2) {
2775
+ runTasks(inputs, ...args) {
2776
+ return this.serialStream(async function* (self2) {
2357
2777
  self2.checkCapability("atomic");
2358
2778
  for await (const input of asAsync(inputs, self2.controls(args[0]).signal)) {
2359
2779
  yield await self2.invoke("process", input, args[0]?.options ?? {}, args[0]);
2360
2780
  }
2361
- });
2781
+ }, args[0]?.signal);
2362
2782
  }
2363
2783
  /** One processor invocation for the entire input iterable. */
2364
- async *runTaskInBatches(inputs, ...args) {
2365
- yield* this.serialStream(async function* (self2) {
2784
+ runTaskInBatches(inputs, ...args) {
2785
+ return this.serialStream(async function* (self2) {
2366
2786
  self2.checkCapability("streaming");
2367
2787
  const controls = self2.controls(args[0]);
2368
2788
  const options = clonePayload(args[0]?.options ?? {});
@@ -2375,7 +2795,31 @@
2375
2795
  }
2376
2796
  let completed = false;
2377
2797
  try {
2378
- if (self2.pool) {
2798
+ if (self2.workerChannel) {
2799
+ self2.channelInputs = prepared()[Symbol.asyncIterator]();
2800
+ self2.streamProgress = controls.onProgress;
2801
+ try {
2802
+ await self2.invoke("stream-open", {}, options, controls);
2803
+ while (true) {
2804
+ const result = await self2.invoke("stream-next", {}, {}, controls);
2805
+ if (result.done)
2806
+ break;
2807
+ yield result.value;
2808
+ }
2809
+ } finally {
2810
+ try {
2811
+ if (!self2.invalid)
2812
+ await self2.invoke("stream-close", {}, {}, controls);
2813
+ } finally {
2814
+ await self2.channelInputs.return?.();
2815
+ self2.channelInputs = void 0;
2816
+ self2.streamProgress = void 0;
2817
+ if (self2.streamProgressId !== void 0)
2818
+ self2.callbackFailures.delete(self2.streamProgressId);
2819
+ self2.streamProgressId = void 0;
2820
+ }
2821
+ }
2822
+ } else if (self2.pool) {
2379
2823
  await self2.invoke("stream-options", {}, options, controls);
2380
2824
  yield* processOnWorkerInBatches(self2.descriptor, prepared(), {
2381
2825
  ...self2.workerOptions(controls),
@@ -2383,13 +2827,19 @@
2383
2827
  workerInBatches: true
2384
2828
  });
2385
2829
  } else {
2386
- for await (const output of self2.runtime.stream(prepared(), options, localContext(controls))) {
2830
+ for await (const output of self2.runtime.stream(prepared(), options, self2.runtimeContext(controls))) {
2387
2831
  controls.signal?.throwIfAborted();
2388
2832
  yield clonePayload(output, controls.outputOwnership ?? "transfer");
2389
2833
  }
2390
2834
  }
2391
2835
  completed = true;
2392
2836
  } catch (error) {
2837
+ if (self2.workerChannel) {
2838
+ self2.invalid = true;
2839
+ self2.operationQueue.cancelPending(error);
2840
+ self2.controller.abort(error);
2841
+ await self2.workerChannel.destroy(error);
2842
+ }
2393
2843
  if (self2.pool) {
2394
2844
  self2.invalid = true;
2395
2845
  await self2.pool.destroy(error);
@@ -2398,8 +2848,23 @@
2398
2848
  } finally {
2399
2849
  if (self2.pool && !completed)
2400
2850
  self2.invalid = true;
2851
+ if (self2.workerChannel && !completed && !self2.invalid) {
2852
+ const reason = new Error("Worker stream ended before completion");
2853
+ self2.invalid = true;
2854
+ self2.operationQueue.cancelPending(reason);
2855
+ self2.controller.abort(reason);
2856
+ await self2.workerChannel.destroy(reason);
2857
+ }
2401
2858
  }
2402
- });
2859
+ }, args[0]?.signal);
2860
+ }
2861
+ /** Lifecycle status of this initialized task. */
2862
+ get state() {
2863
+ if (this.invalid)
2864
+ return "invalid";
2865
+ if (this.finalized)
2866
+ return "closed";
2867
+ return this.closed ? "closing" : "ready";
2403
2868
  }
2404
2869
  /** Drain accepted work, invoke destroy, and release execution capacity. */
2405
2870
  close() {
@@ -2407,13 +2872,17 @@
2407
2872
  this.closed = true;
2408
2873
  this.closing = (async () => {
2409
2874
  try {
2410
- await this.tail;
2875
+ await this.operationQueue.close();
2411
2876
  if (!this.invalid)
2412
2877
  await this.invoke("destroy", {}, {});
2878
+ else if (!this.pool && !this.workerChannel)
2879
+ await this.runtime.destroy();
2413
2880
  } finally {
2414
2881
  try {
2415
2882
  await this.pool?.destroy();
2883
+ await this.workerChannel?.destroy();
2416
2884
  } finally {
2885
+ this.finalized = true;
2417
2886
  this.release();
2418
2887
  }
2419
2888
  }
@@ -2423,7 +2892,12 @@
2423
2892
  }
2424
2893
  /** Abort work. Local JavaScript must settle before its state can be destroyed. */
2425
2894
  async terminate(reason = new Error("Task terminated")) {
2895
+ this.operationQueue.cancelPending(reason);
2426
2896
  this.controller.abort(reason);
2897
+ if (this.workerChannel) {
2898
+ this.invalid = true;
2899
+ await this.workerChannel.destroy(reason);
2900
+ }
2427
2901
  if (this.pool) {
2428
2902
  this.invalid = true;
2429
2903
  await this.pool.destroy(reason);
@@ -2432,7 +2906,7 @@
2432
2906
  await this.close();
2433
2907
  }
2434
2908
  checkCapability(kind) {
2435
- if (this.pool ? !this.task.worker?.capabilities[kind] : !(kind === "atomic" ? this.task.process : this.task.processInBatches)) {
2909
+ if (this.pool || this.workerChannel ? !this.task.worker?.capabilities[kind] : !(kind === "atomic" ? this.task.process : this.task.processInBatches)) {
2436
2910
  throw new Error(`Task has no ${kind} processor for this execution route`);
2437
2911
  }
2438
2912
  }
@@ -2463,6 +2937,38 @@
2463
2937
  assertPayload(input);
2464
2938
  assertNoTransferAlias(input, options, prepared.inputOwnership);
2465
2939
  const copiedOptions = clonePayload(options);
2940
+ if (this.workerChannel) {
2941
+ const progressId = this.nextProgressId++;
2942
+ const request = {
2943
+ input: clonePayload(input, prepared.inputOwnership),
2944
+ options: copiedOptions,
2945
+ outputOwnership: prepared.outputOwnership ?? "transfer",
2946
+ progressId
2947
+ };
2948
+ if (operation === "stream-open")
2949
+ this.streamProgressId = progressId;
2950
+ this.progressCallbacks.set(progressId, prepared.onProgress);
2951
+ let callbackFailure;
2952
+ try {
2953
+ const result2 = await this.workerChannel.channel.request(operation, request, prepared.signal, getTransferList(request));
2954
+ callbackFailure = this.callbackFailures.get(progressId) ?? (operation.startsWith("stream-") && this.streamProgressId !== void 0 ? this.callbackFailures.get(this.streamProgressId) : void 0);
2955
+ if (callbackFailure)
2956
+ throw callbackFailure.reason;
2957
+ return result2;
2958
+ } catch (reason) {
2959
+ if (operation === "process" && !prepared.signal?.aborted && (reason instanceof TaskRequestError || callbackFailure))
2960
+ throw reason;
2961
+ this.invalid = true;
2962
+ this.operationQueue.cancelPending(reason);
2963
+ this.controller.abort(reason);
2964
+ await this.workerChannel.destroy(reason);
2965
+ throw reason;
2966
+ } finally {
2967
+ this.progressCallbacks.delete(progressId);
2968
+ if (this.streamProgressId !== progressId)
2969
+ this.callbackFailures.delete(progressId);
2970
+ }
2971
+ }
2466
2972
  if (this.pool) {
2467
2973
  try {
2468
2974
  return await processOnWorker(this.descriptor, { operation, input: clonePayload(input, prepared.inputOwnership), options: copiedOptions }, this.workerOptions({ ...prepared, inputOwnership: "transfer" }));
@@ -2475,7 +2981,7 @@
2475
2981
  if (operation === "destroy")
2476
2982
  return this.runtime.destroy();
2477
2983
  const copied = clonePayload(input, prepared.inputOwnership);
2478
- const context = localContext(prepared);
2984
+ const context = this.runtimeContext(prepared);
2479
2985
  if (operation === "initialize") {
2480
2986
  const result2 = await this.runtime.initialize(copied, context);
2481
2987
  prepared.signal?.throwIfAborted();
@@ -2485,27 +2991,76 @@
2485
2991
  prepared.signal?.throwIfAborted();
2486
2992
  return clonePayload(result, prepared.outputOwnership ?? "transfer");
2487
2993
  }
2994
+ runtimeContext(prepared) {
2995
+ return {
2996
+ ...localContext(prepared),
2997
+ requestHost: async (operation, payload, controls = {}) => {
2998
+ const signal = prepared.signal ?? this.controller.signal;
2999
+ signal.throwIfAborted();
3000
+ const handler = this.initializationControls.onRequest;
3001
+ if (!handler)
3002
+ throw new Error("No host request handler configured");
3003
+ const result = await handler(operation, clonePayload(payload, controls.inputOwnership), signal);
3004
+ signal.throwIfAborted();
3005
+ return structuredClone(result, {
3006
+ transfer: controls.outputOwnership === "transfer" ? getTransferList(result) : []
3007
+ });
3008
+ },
3009
+ emitHost: (operation, payload) => this.initializationControls.onEvent?.(operation, structuredClone(payload))
3010
+ };
3011
+ }
2488
3012
  enqueue(operation) {
2489
3013
  if (this.closed)
2490
3014
  return Promise.reject(new Error("Initialized task is closed"));
2491
- const result = this.tail.then(operation);
2492
- this.tail = result.catch(() => {
3015
+ return this.operationQueue.run("exclusive", operation);
3016
+ }
3017
+ serialStream(operation, signal) {
3018
+ const waiting = new AbortController();
3019
+ const queueSignal = AbortSignal.any([waiting.signal, this.controller.signal, signal].filter((value) => Boolean(value)));
3020
+ let started = false;
3021
+ const iterator = this.acquireStream(operation, queueSignal, () => {
3022
+ started = true;
2493
3023
  });
2494
- return result;
3024
+ const cancelWaiting = () => {
3025
+ if (!started)
3026
+ waiting.abort(new Error("Stream returned before execution"));
3027
+ };
3028
+ return {
3029
+ [Symbol.asyncIterator]() {
3030
+ return this;
3031
+ },
3032
+ next: () => iterator.next(),
3033
+ return: async () => {
3034
+ cancelWaiting();
3035
+ return iterator.return(void 0);
3036
+ },
3037
+ throw: async (reason) => {
3038
+ cancelWaiting();
3039
+ return iterator.throw(reason);
3040
+ }
3041
+ };
2495
3042
  }
2496
- async *serialStream(operation) {
3043
+ async *acquireStream(operation, signal, onStart) {
2497
3044
  if (this.closed)
2498
3045
  throw new Error("Initialized task is closed");
2499
- const before = this.tail;
3046
+ let acquire;
3047
+ const acquired = new Promise((resolve) => {
3048
+ acquire = resolve;
3049
+ });
2500
3050
  let release;
2501
- this.tail = new Promise((resolve) => {
3051
+ const held = new Promise((resolve) => {
2502
3052
  release = resolve;
2503
3053
  });
2504
- await before;
2505
- if (this.controller.signal.aborted) {
3054
+ const lease = this.operationQueue.run("exclusive", async () => {
3055
+ acquire();
3056
+ await held;
3057
+ }, signal);
3058
+ await Promise.race([acquired, lease]);
3059
+ if (signal.aborted) {
2506
3060
  release();
2507
- throw this.controller.signal.reason;
3061
+ throw signal.reason;
2508
3062
  }
3063
+ onStart();
2509
3064
  const iterator = operation(this)[Symbol.asyncIterator]();
2510
3065
  let stopping;
2511
3066
  const stop = () => {
@@ -2821,21 +3376,6 @@
2821
3376
  }
2822
3377
  }
2823
3378
 
2824
- // ../core/src/worker-utils/lib/worker-api/task-runtime.ts
2825
- function normalizeTaskProgress(progress) {
2826
- return { ...progress, phase: progress.phase ?? "process", unit: progress.unit ?? "items" };
2827
- }
2828
- async function isWorkerThread() {
2829
- if (typeof self !== "undefined" && typeof document === "undefined" && typeof self.postMessage === "function")
2830
- return true;
2831
- if (typeof process !== "undefined" && process.versions?.node) {
2832
- const { isMainThread } = await Promise.resolve().then(() => (init_worker_threads_browser(), worker_threads_browser_exports));
2833
- return !isMainThread;
2834
- }
2835
- return false;
2836
- }
2837
- var initializeTaskWorker2 = initializeTaskWorker;
2838
-
2839
3379
  // ../core/src/worker-utils/lib/worker-api/get-worker-url.ts
2840
3380
  var warnedWorkerVersionFallbacks2 = /* @__PURE__ */ new Set();
2841
3381
  function getCustomWorkerURL2(worker, options = {}) {
@@ -2891,6 +3431,21 @@
2891
3431
  );
2892
3432
  }
2893
3433
 
3434
+ // ../core/src/worker-utils/lib/worker-api/task-runtime.ts
3435
+ function normalizeTaskProgress(progress) {
3436
+ return { ...progress, phase: progress.phase ?? "process", unit: progress.unit ?? "items" };
3437
+ }
3438
+ async function isWorkerThread() {
3439
+ if (typeof self !== "undefined" && typeof document === "undefined" && typeof self.postMessage === "function")
3440
+ return true;
3441
+ if (typeof process !== "undefined" && process.versions?.node) {
3442
+ const { isMainThread } = await Promise.resolve().then(() => (init_worker_threads_browser(), worker_threads_browser_exports));
3443
+ return !isMainThread;
3444
+ }
3445
+ return false;
3446
+ }
3447
+ var initializeTaskWorker2 = initializeTaskWorker;
3448
+
2894
3449
  // ../core/src/worker-utils/lib/worker-utils/get-transfer-list.ts
2895
3450
  function getTransferList2(object, recursive = true, transfers) {
2896
3451
  const transfersSet = transfers || /* @__PURE__ */ new Set();
@@ -18476,7 +19031,7 @@ return true;`);
18476
19031
  }
18477
19032
 
18478
19033
  // src/draco/lib/utils/version.ts
18479
- var VERSION3 = true ? "5.0.0-beta.4" : "latest";
19034
+ var VERSION3 = true ? "5.0.0-beta.5" : "latest";
18480
19035
 
18481
19036
  // src/draco/draco-format.ts
18482
19037
  var DracoFormat = {