@loaders.gl/core 4.5.3 → 5.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +14 -3
- package/dist/dist.dev.js +1789 -352
- package/dist/dist.min.js +4 -3
- package/dist/index.cjs +3087 -311
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/iterators/make-iterator/make-stream-iterator.js +48 -9
- package/dist/iterators/make-iterator/make-stream-iterator.js.map +1 -1
- package/dist/lib/api/core-api.d.ts +6 -0
- package/dist/lib/api/core-api.d.ts.map +1 -0
- package/dist/lib/api/core-api.js +23 -0
- package/dist/lib/api/core-api.js.map +1 -0
- package/dist/lib/api/create-data-source.d.ts +2 -2
- package/dist/lib/api/create-data-source.d.ts.map +1 -1
- package/dist/lib/api/create-data-source.js +36 -14
- package/dist/lib/api/create-data-source.js.map +1 -1
- package/dist/lib/api/load-in-batches.d.ts +4 -4
- package/dist/lib/api/load-in-batches.d.ts.map +1 -1
- package/dist/lib/api/load-in-batches.js +17 -6
- package/dist/lib/api/load-in-batches.js.map +1 -1
- package/dist/lib/api/load-loader.d.ts +10 -0
- package/dist/lib/api/load-loader.d.ts.map +1 -0
- package/dist/lib/api/load-loader.js +222 -0
- package/dist/lib/api/load-loader.js.map +1 -0
- package/dist/lib/api/load.d.ts +3 -3
- package/dist/lib/api/load.d.ts.map +1 -1
- package/dist/lib/api/load.js +84 -5
- package/dist/lib/api/load.js.map +1 -1
- package/dist/lib/api/parse-file.d.ts +15 -0
- package/dist/lib/api/parse-file.d.ts.map +1 -0
- package/dist/lib/api/parse-file.js +74 -0
- package/dist/lib/api/parse-file.js.map +1 -0
- package/dist/lib/api/parse-in-batches.d.ts +2 -2
- package/dist/lib/api/parse-in-batches.d.ts.map +1 -1
- package/dist/lib/api/parse-in-batches.js +18 -7
- package/dist/lib/api/parse-in-batches.js.map +1 -1
- package/dist/lib/api/parse-sync.d.ts +2 -2
- package/dist/lib/api/parse-sync.d.ts.map +1 -1
- package/dist/lib/api/parse-sync.js +10 -1
- package/dist/lib/api/parse-sync.js.map +1 -1
- package/dist/lib/api/parse.d.ts +2 -2
- package/dist/lib/api/parse.d.ts.map +1 -1
- package/dist/lib/api/parse.js +34 -17
- package/dist/lib/api/parse.js.map +1 -1
- package/dist/lib/api/preload.d.ts +14 -0
- package/dist/lib/api/preload.d.ts.map +1 -0
- package/dist/lib/api/preload.js +13 -0
- package/dist/lib/api/preload.js.map +1 -0
- package/dist/lib/api/register-loaders.js +1 -1
- package/dist/lib/api/register-loaders.js.map +1 -1
- package/dist/lib/api/select-loader.d.ts.map +1 -1
- package/dist/lib/api/select-loader.js +48 -5
- package/dist/lib/api/select-loader.js.map +1 -1
- package/dist/lib/api/select-source.d.ts +3 -3
- package/dist/lib/api/select-source.d.ts.map +1 -1
- package/dist/lib/api/select-source.js +2 -5
- package/dist/lib/api/select-source.js.map +1 -1
- package/dist/lib/fetch/fetch-error-message.js +1 -1
- package/dist/lib/fetch/fetch-error-message.js.map +1 -1
- package/dist/lib/filesystems/browser-filesystem.d.ts.map +1 -1
- package/dist/lib/filesystems/browser-filesystem.js +25 -11
- package/dist/lib/filesystems/browser-filesystem.js.map +1 -1
- package/dist/lib/init.js +1 -1
- package/dist/lib/init.js.map +1 -1
- package/dist/lib/loader-utils/check-errors.js +1 -1
- package/dist/lib/loader-utils/check-errors.js.map +1 -1
- package/dist/lib/loader-utils/get-data.d.ts +4 -0
- package/dist/lib/loader-utils/get-data.d.ts.map +1 -1
- package/dist/lib/loader-utils/get-data.js +26 -0
- package/dist/lib/loader-utils/get-data.js.map +1 -1
- package/dist/lib/loader-utils/get-fetch-function.d.ts +1 -1
- package/dist/lib/loader-utils/get-fetch-function.d.ts.map +1 -1
- package/dist/lib/loader-utils/get-fetch-function.js +16 -10
- package/dist/lib/loader-utils/get-fetch-function.js.map +1 -1
- package/dist/lib/loader-utils/loader-context.d.ts +2 -2
- package/dist/lib/loader-utils/loader-context.d.ts.map +1 -1
- package/dist/lib/loader-utils/loader-context.js +11 -4
- package/dist/lib/loader-utils/loader-context.js.map +1 -1
- package/dist/lib/loader-utils/loggers.d.ts +19 -0
- package/dist/lib/loader-utils/loggers.d.ts.map +1 -1
- package/dist/lib/loader-utils/loggers.js +28 -2
- package/dist/lib/loader-utils/loggers.js.map +1 -1
- package/dist/lib/loader-utils/option-defaults.d.ts +1 -0
- package/dist/lib/loader-utils/option-defaults.d.ts.map +1 -1
- package/dist/lib/loader-utils/option-defaults.js +5 -0
- package/dist/lib/loader-utils/option-defaults.js.map +1 -1
- package/dist/lib/loader-utils/option-utils.d.ts +7 -0
- package/dist/lib/loader-utils/option-utils.d.ts.map +1 -1
- package/dist/lib/loader-utils/option-utils.js +91 -3
- package/dist/lib/loader-utils/option-utils.js.map +1 -1
- package/dist/lib/utils/response-utils.js +5 -14
- package/dist/lib/utils/response-utils.js.map +1 -1
- package/dist/null-loader.d.ts.map +1 -1
- package/dist/null-loader.js +1 -1
- package/dist/null-loader.js.map +1 -1
- package/dist/null-worker-node.js +270 -42
- package/dist/null-worker.js +270 -42
- package/package.json +6 -6
- package/src/index.ts +10 -1
- package/src/iterators/make-iterator/make-stream-iterator.ts +47 -9
- package/src/lib/api/core-api.ts +25 -0
- package/src/lib/api/create-data-source.ts +53 -24
- package/src/lib/api/load-in-batches.ts +33 -21
- package/src/lib/api/load-loader.ts +306 -0
- package/src/lib/api/load.ts +160 -9
- package/src/lib/api/parse-file.ts +156 -0
- package/src/lib/api/parse-in-batches.ts +35 -8
- package/src/lib/api/parse-sync.ts +27 -2
- package/src/lib/api/parse.ts +61 -20
- package/src/lib/api/preload.ts +46 -0
- package/src/lib/api/register-loaders.ts +1 -1
- package/src/lib/api/select-loader.ts +57 -5
- package/src/lib/api/select-source.ts +7 -10
- package/src/lib/fetch/fetch-error-message.ts +1 -1
- package/src/lib/filesystems/browser-filesystem.ts +25 -11
- package/src/lib/loader-utils/check-errors.ts +1 -1
- package/src/lib/loader-utils/get-data.ts +36 -0
- package/src/lib/loader-utils/get-fetch-function.ts +17 -15
- package/src/lib/loader-utils/loader-context.ts +13 -5
- package/src/lib/loader-utils/loggers.ts +28 -2
- package/src/lib/loader-utils/option-defaults.ts +5 -0
- package/src/lib/loader-utils/option-utils.ts +106 -3
- package/src/lib/utils/response-utils.ts +5 -15
- package/src/null-loader.ts +3 -3
package/dist/null-worker.js
CHANGED
|
@@ -71,18 +71,18 @@
|
|
|
71
71
|
static async addEventListener(onMessage) {
|
|
72
72
|
let onMessageWrapper = onMessageWrapperMap.get(onMessage);
|
|
73
73
|
if (!onMessageWrapper) {
|
|
74
|
-
onMessageWrapper =
|
|
75
|
-
|
|
74
|
+
onMessageWrapper = (message) => {
|
|
75
|
+
const messageData = getWorkerMessageData(message);
|
|
76
|
+
if (!messageData) {
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
const { type, payload } = parentPort3 ? message : message.data;
|
|
80
|
-
onMessage(type, payload);
|
|
79
|
+
onMessage(messageData.type, messageData.payload);
|
|
81
80
|
};
|
|
81
|
+
onMessageWrapperMap.set(onMessage, onMessageWrapper);
|
|
82
82
|
}
|
|
83
83
|
const parentPort2 = await getParentPort();
|
|
84
84
|
if (parentPort2) {
|
|
85
|
-
|
|
85
|
+
parentPort2.on("message", onMessageWrapper);
|
|
86
86
|
} else {
|
|
87
87
|
globalThis.addEventListener("message", onMessageWrapper);
|
|
88
88
|
}
|
|
@@ -90,9 +90,12 @@
|
|
|
90
90
|
static async removeEventListener(onMessage) {
|
|
91
91
|
const onMessageWrapper = onMessageWrapperMap.get(onMessage);
|
|
92
92
|
onMessageWrapperMap.delete(onMessage);
|
|
93
|
+
if (!onMessageWrapper) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
93
96
|
const parentPort2 = await getParentPort();
|
|
94
97
|
if (parentPort2) {
|
|
95
|
-
|
|
98
|
+
parentPort2.off("message", onMessageWrapper);
|
|
96
99
|
} else {
|
|
97
100
|
globalThis.removeEventListener("message", onMessageWrapper);
|
|
98
101
|
}
|
|
@@ -113,44 +116,175 @@
|
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
118
|
};
|
|
116
|
-
function
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
function getWorkerMessageData(message) {
|
|
120
|
+
if (!message || typeof message !== "object") {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const messageData = "data" in message && message.type === "message" ? message.data : message;
|
|
124
|
+
return messageData && typeof messageData.source === "string" && messageData.source.startsWith("loaders.gl") ? messageData : null;
|
|
119
125
|
}
|
|
120
126
|
|
|
121
|
-
// ../
|
|
127
|
+
// ../worker-utils/src/lib/async-queue/async-queue.ts
|
|
128
|
+
var AsyncQueue = class {
|
|
129
|
+
_values;
|
|
130
|
+
_settlers;
|
|
131
|
+
_closed;
|
|
132
|
+
constructor() {
|
|
133
|
+
this._values = [];
|
|
134
|
+
this._settlers = [];
|
|
135
|
+
this._closed = false;
|
|
136
|
+
}
|
|
137
|
+
/** Return an async iterator for this queue */
|
|
138
|
+
[Symbol.asyncIterator]() {
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
/** Push a new value - the async iterator will yield a promise resolved to this value */
|
|
142
|
+
push(value) {
|
|
143
|
+
return this.enqueue(value);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Push a new value - the async iterator will yield a promise resolved to this value
|
|
147
|
+
* Add an error - the async iterator will yield a promise rejected with this value
|
|
148
|
+
*/
|
|
149
|
+
enqueue(value) {
|
|
150
|
+
if (this._closed) {
|
|
151
|
+
throw new Error("Closed");
|
|
152
|
+
}
|
|
153
|
+
if (this._settlers.length > 0) {
|
|
154
|
+
if (this._values.length > 0) {
|
|
155
|
+
throw new Error("Illegal internal state");
|
|
156
|
+
}
|
|
157
|
+
const settler = this._settlers.shift();
|
|
158
|
+
if (value instanceof Error) {
|
|
159
|
+
settler.reject(value);
|
|
160
|
+
} else {
|
|
161
|
+
settler.resolve({ value });
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
this._values.push(value);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** Indicate that we not waiting for more values - The async iterator will be done */
|
|
168
|
+
close() {
|
|
169
|
+
while (this._settlers.length > 0) {
|
|
170
|
+
const settler = this._settlers.shift();
|
|
171
|
+
settler.resolve({ done: true });
|
|
172
|
+
}
|
|
173
|
+
this._closed = true;
|
|
174
|
+
}
|
|
175
|
+
// ITERATOR IMPLEMENTATION
|
|
176
|
+
/** @returns a Promise for an IteratorResult */
|
|
177
|
+
next() {
|
|
178
|
+
if (this._values.length > 0) {
|
|
179
|
+
const value = this._values.shift();
|
|
180
|
+
if (value instanceof Error) {
|
|
181
|
+
return Promise.reject(value);
|
|
182
|
+
}
|
|
183
|
+
return Promise.resolve({ done: false, value });
|
|
184
|
+
}
|
|
185
|
+
if (this._closed) {
|
|
186
|
+
if (this._settlers.length > 0) {
|
|
187
|
+
throw new Error("Illegal internal state");
|
|
188
|
+
}
|
|
189
|
+
return Promise.resolve({ done: true, value: void 0 });
|
|
190
|
+
}
|
|
191
|
+
return new Promise((resolve, reject) => {
|
|
192
|
+
this._settlers.push({ resolve, reject });
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// ../worker-utils/src/lib/worker-api/create-worker.ts
|
|
122
198
|
var requestId = 0;
|
|
123
|
-
|
|
199
|
+
var activeInputBatches = null;
|
|
200
|
+
var activeOutputAcknowledgements = null;
|
|
201
|
+
async function createWorker(process, processInBatches) {
|
|
124
202
|
if (!await WorkerBody.inWorkerThread()) {
|
|
125
203
|
return;
|
|
126
204
|
}
|
|
205
|
+
const context = {
|
|
206
|
+
process: processOnMainThread
|
|
207
|
+
};
|
|
127
208
|
WorkerBody.onmessage = async (type, payload) => {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
209
|
+
try {
|
|
210
|
+
switch (type) {
|
|
211
|
+
case "preload":
|
|
212
|
+
WorkerBody.postMessage("done", {});
|
|
213
|
+
break;
|
|
214
|
+
case "process":
|
|
215
|
+
if (!process) {
|
|
216
|
+
throw new Error("Worker does not support atomic processing");
|
|
217
|
+
}
|
|
218
|
+
const result = await process(
|
|
219
|
+
payload.input,
|
|
220
|
+
payload.options || {},
|
|
221
|
+
context,
|
|
222
|
+
payload.context || {}
|
|
223
|
+
);
|
|
143
224
|
WorkerBody.postMessage("done", { result });
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
225
|
+
break;
|
|
226
|
+
case "process-in-batches":
|
|
227
|
+
if (!processInBatches) {
|
|
228
|
+
throw new Error("Worker does not support batched processing");
|
|
229
|
+
}
|
|
230
|
+
const inputBatches = new AsyncQueue();
|
|
231
|
+
const outputAcknowledgements = new AsyncQueue();
|
|
232
|
+
activeInputBatches = inputBatches;
|
|
233
|
+
activeOutputAcknowledgements = outputAcknowledgements;
|
|
234
|
+
try {
|
|
235
|
+
const resultIterator = processInBatches(
|
|
236
|
+
createDemandDrivenIterator(inputBatches),
|
|
237
|
+
payload.options || {},
|
|
238
|
+
context,
|
|
239
|
+
payload.context || {}
|
|
240
|
+
);
|
|
241
|
+
for await (const batch of resultIterator) {
|
|
242
|
+
await WorkerBody.postMessage("output-batch", { result: batch });
|
|
243
|
+
await outputAcknowledgements.next();
|
|
244
|
+
}
|
|
245
|
+
await WorkerBody.postMessage("done", {});
|
|
246
|
+
} finally {
|
|
247
|
+
activeInputBatches = null;
|
|
248
|
+
activeOutputAcknowledgements = null;
|
|
249
|
+
}
|
|
250
|
+
break;
|
|
251
|
+
case "input-batch":
|
|
252
|
+
if (!activeInputBatches) {
|
|
253
|
+
throw new Error("Worker has no active batched processing session");
|
|
254
|
+
}
|
|
255
|
+
activeInputBatches.push(payload.input);
|
|
256
|
+
break;
|
|
257
|
+
case "input-done":
|
|
258
|
+
if (!activeInputBatches) {
|
|
259
|
+
throw new Error("Worker has no active batched processing session");
|
|
260
|
+
}
|
|
261
|
+
activeInputBatches.close();
|
|
262
|
+
break;
|
|
263
|
+
case "output-ack":
|
|
264
|
+
if (!activeOutputAcknowledgements) {
|
|
265
|
+
throw new Error("Worker has no active batched processing session");
|
|
266
|
+
}
|
|
267
|
+
activeOutputAcknowledgements.push(void 0);
|
|
268
|
+
break;
|
|
269
|
+
default:
|
|
270
|
+
}
|
|
271
|
+
} catch (error) {
|
|
272
|
+
const message = error instanceof Error ? error.message : "";
|
|
273
|
+
WorkerBody.postMessage("error", { error: message });
|
|
150
274
|
}
|
|
151
275
|
};
|
|
152
276
|
}
|
|
153
|
-
function
|
|
277
|
+
async function* createDemandDrivenIterator(inputBatches) {
|
|
278
|
+
while (true) {
|
|
279
|
+
await WorkerBody.postMessage("input-request", {});
|
|
280
|
+
const nextBatch = await inputBatches.next();
|
|
281
|
+
if (nextBatch.done) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
yield nextBatch.value;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function processOnMainThread(arrayBuffer, options = {}, jobContext = {}) {
|
|
154
288
|
return new Promise((resolve, reject) => {
|
|
155
289
|
const id = requestId++;
|
|
156
290
|
const onMessage = (type, payload2) => {
|
|
@@ -170,10 +304,107 @@
|
|
|
170
304
|
}
|
|
171
305
|
};
|
|
172
306
|
WorkerBody.addEventListener(onMessage);
|
|
173
|
-
const payload = { id, input: arrayBuffer, options };
|
|
307
|
+
const payload = { id, input: arrayBuffer, options, context: jobContext };
|
|
174
308
|
WorkerBody.postMessage("process", payload);
|
|
175
309
|
});
|
|
176
310
|
}
|
|
311
|
+
|
|
312
|
+
// ../loader-utils/src/lib/worker-loader-utils/create-loader-worker.ts
|
|
313
|
+
async function createLoaderWorker(loader, selectLoader = () => loader) {
|
|
314
|
+
await createWorker(
|
|
315
|
+
(input, options, workerContext, loaderContext) => processLoaderWorkerData(
|
|
316
|
+
selectLoader(options || {}),
|
|
317
|
+
input,
|
|
318
|
+
options,
|
|
319
|
+
workerContext,
|
|
320
|
+
loaderContext
|
|
321
|
+
),
|
|
322
|
+
(inputIterator, options, workerContext, loaderContext) => processLoaderWorkerBatches(
|
|
323
|
+
selectLoader(options || {}),
|
|
324
|
+
inputIterator,
|
|
325
|
+
options,
|
|
326
|
+
workerContext,
|
|
327
|
+
loaderContext
|
|
328
|
+
)
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
async function processLoaderWorkerData(loader, input, options = {}, workerContext, loaderContext = {}) {
|
|
332
|
+
const result = await parseData({
|
|
333
|
+
loader,
|
|
334
|
+
arrayBuffer: input,
|
|
335
|
+
options,
|
|
336
|
+
context: {
|
|
337
|
+
...loaderContext,
|
|
338
|
+
coreApi: createWorkerCoreApi(),
|
|
339
|
+
_parse: createParseOnMainThread(workerContext?.process)
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
return loader.serializeWorkerResult ? loader.serializeWorkerResult(result, options, loaderContext) : result;
|
|
343
|
+
}
|
|
344
|
+
async function* processLoaderWorkerBatches(loader, inputIterator, options = {}, workerContext, loaderContext = {}) {
|
|
345
|
+
if (!loader.parseInBatches) {
|
|
346
|
+
throw new Error(`${loader.id} loader does not support batched parsing`);
|
|
347
|
+
}
|
|
348
|
+
const resultIterator = loader.parseInBatches(inputIterator, options, {
|
|
349
|
+
...loaderContext,
|
|
350
|
+
coreApi: createWorkerCoreApi(),
|
|
351
|
+
_parse: createParseOnMainThread(workerContext?.process)
|
|
352
|
+
});
|
|
353
|
+
for await (const batch of resultIterator) {
|
|
354
|
+
yield loader.serializeWorkerBatch ? loader.serializeWorkerBatch(batch, options, loaderContext) : batch;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function createWorkerCoreApi() {
|
|
358
|
+
const unavailable = (methodName) => () => {
|
|
359
|
+
throw new Error(`context.coreApi.${methodName} is unavailable inside worker loaders.`);
|
|
360
|
+
};
|
|
361
|
+
return {
|
|
362
|
+
fetchFile: async (urlOrData, fetchOptions) => await fetch(urlOrData, fetchOptions),
|
|
363
|
+
parseSync: unavailable("parseSync"),
|
|
364
|
+
parse: unavailable("parse"),
|
|
365
|
+
parseFile: unavailable("parseFile"),
|
|
366
|
+
parseInBatches: unavailable("parseInBatches"),
|
|
367
|
+
load: unavailable("load"),
|
|
368
|
+
loadInBatches: unavailable("loadInBatches")
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function createParseOnMainThread(processOnMainThread2) {
|
|
372
|
+
return (arrayBuffer, loaders, options, context) => {
|
|
373
|
+
if (!processOnMainThread2) {
|
|
374
|
+
throw new Error("Worker not set up to parse on main thread");
|
|
375
|
+
}
|
|
376
|
+
const parseArguments = getMainThreadParseArguments(loaders, options, context);
|
|
377
|
+
return processOnMainThread2(arrayBuffer, parseArguments.options, {
|
|
378
|
+
...parseArguments.context,
|
|
379
|
+
...Array.isArray(loaders) || loaders && isLoaderObject(loaders) ? {
|
|
380
|
+
_loaderIsArray: Array.isArray(loaders),
|
|
381
|
+
_loaderIds: (Array.isArray(loaders) ? loaders : [loaders]).map((loader) => loader.id)
|
|
382
|
+
} : {}
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function getMainThreadParseArguments(loaders, options, context) {
|
|
387
|
+
if (options) {
|
|
388
|
+
return { options, context: getSerializableLoaderContext(context) };
|
|
389
|
+
}
|
|
390
|
+
if (Array.isArray(loaders) || loaders && isLoaderObject(loaders)) {
|
|
391
|
+
return { options: void 0, context: getSerializableLoaderContext(context) };
|
|
392
|
+
}
|
|
393
|
+
if (loaders && !Array.isArray(loaders)) {
|
|
394
|
+
return { options: loaders };
|
|
395
|
+
}
|
|
396
|
+
return { options: void 0, context: getSerializableLoaderContext(context) };
|
|
397
|
+
}
|
|
398
|
+
function isLoaderObject(value) {
|
|
399
|
+
return "id" in value && "extensions" in value;
|
|
400
|
+
}
|
|
401
|
+
function getSerializableLoaderContext(context) {
|
|
402
|
+
if (!context) {
|
|
403
|
+
return void 0;
|
|
404
|
+
}
|
|
405
|
+
const { fetch: fetch2, loaders, coreApi, _parse, _parseSync, _parseInBatches, ...serializableContext } = context;
|
|
406
|
+
return JSON.parse(JSON.stringify(serializableContext));
|
|
407
|
+
}
|
|
177
408
|
async function parseData({
|
|
178
409
|
loader,
|
|
179
410
|
arrayBuffer,
|
|
@@ -182,9 +413,9 @@
|
|
|
182
413
|
}) {
|
|
183
414
|
let data;
|
|
184
415
|
let parser;
|
|
185
|
-
if (loader.
|
|
416
|
+
if (loader.parse || loader.parseSync) {
|
|
186
417
|
data = arrayBuffer;
|
|
187
|
-
parser = loader.
|
|
418
|
+
parser = loader.parse || loader.parseSync;
|
|
188
419
|
} else if (loader.parseTextSync) {
|
|
189
420
|
const textDecoder = new TextDecoder();
|
|
190
421
|
data = textDecoder.decode(arrayBuffer);
|
|
@@ -192,14 +423,11 @@
|
|
|
192
423
|
} else {
|
|
193
424
|
throw new Error(`Could not load data with ${loader.name} loader`);
|
|
194
425
|
}
|
|
195
|
-
const workerModules = Object.fromEntries(
|
|
196
|
-
Object.entries(options.modules || {}).filter(([, value]) => typeof value === "string")
|
|
197
|
-
);
|
|
198
426
|
options = {
|
|
199
427
|
...options,
|
|
200
428
|
modules: {
|
|
201
429
|
...loader && loader.options && loader.options.modules || {},
|
|
202
|
-
...
|
|
430
|
+
...options.modules || {}
|
|
203
431
|
},
|
|
204
432
|
core: {
|
|
205
433
|
...options.core,
|
|
@@ -210,7 +438,7 @@
|
|
|
210
438
|
}
|
|
211
439
|
|
|
212
440
|
// src/null-loader.ts
|
|
213
|
-
var VERSION = true ? "
|
|
441
|
+
var VERSION = true ? "5.0.0-alpha.10" : "latest";
|
|
214
442
|
var NullLoader = {
|
|
215
443
|
dataType: null,
|
|
216
444
|
batchType: null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-alpha.10",
|
|
4
4
|
"description": "The core API for working with loaders.gl loaders and writers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
"build-worker-node": "esbuild src/workers/null-worker.ts --outfile=dist/null-worker-node.js --bundle --platform=node --target=node16 --define:__VERSION__=\\\"$npm_package_version\\\""
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@loaders.gl/loader-utils": "
|
|
62
|
-
"@loaders.gl/schema": "
|
|
63
|
-
"@loaders.gl/schema-utils": "
|
|
64
|
-
"@loaders.gl/worker-utils": "
|
|
61
|
+
"@loaders.gl/loader-utils": "5.0.0-alpha.10",
|
|
62
|
+
"@loaders.gl/schema": "5.0.0-alpha.10",
|
|
63
|
+
"@loaders.gl/schema-utils": "5.0.0-alpha.10",
|
|
64
|
+
"@loaders.gl/worker-utils": "5.0.0-alpha.10",
|
|
65
65
|
"@probe.gl/log": "^4.1.1"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "7cbfaef633e86356c946541dab4977b522745b6c"
|
|
68
68
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type {
|
|
|
7
7
|
Loader,
|
|
8
8
|
LoaderWithParser,
|
|
9
9
|
LoaderContext,
|
|
10
|
+
CoreAPI,
|
|
10
11
|
LoaderOptions,
|
|
11
12
|
Writer,
|
|
12
13
|
WriterOptions,
|
|
@@ -19,6 +20,7 @@ export type {
|
|
|
19
20
|
FileSystem,
|
|
20
21
|
RandomAccessFileSystem
|
|
21
22
|
} from '@loaders.gl/loader-utils';
|
|
23
|
+
export type {SourceLoader} from '@loaders.gl/loader-utils';
|
|
22
24
|
|
|
23
25
|
// FILE READING AND WRITING
|
|
24
26
|
export {fetchFile} from './lib/fetch/fetch-file';
|
|
@@ -35,8 +37,11 @@ export {selectLoader, selectLoaderSync} from './lib/api/select-loader';
|
|
|
35
37
|
|
|
36
38
|
// LOADING (READING + PARSING)
|
|
37
39
|
export {parse} from './lib/api/parse';
|
|
40
|
+
export {parseFile} from './lib/api/parse-file';
|
|
38
41
|
export {parseSync} from './lib/api/parse-sync';
|
|
39
42
|
export {parseInBatches} from './lib/api/parse-in-batches';
|
|
43
|
+
export {preload, preloadSync} from './lib/api/preload';
|
|
44
|
+
export {coreApi} from './lib/api/core-api';
|
|
40
45
|
|
|
41
46
|
export {load} from './lib/api/load';
|
|
42
47
|
export {loadInBatches} from './lib/api/load-in-batches';
|
|
@@ -59,7 +64,7 @@ export {makeIterator} from './iterators/make-iterator/make-iterator';
|
|
|
59
64
|
export {makeStream} from './iterators/make-stream/make-stream';
|
|
60
65
|
|
|
61
66
|
// CORE LOADERS
|
|
62
|
-
export {
|
|
67
|
+
export {NullLoader} from './null-loader';
|
|
63
68
|
export {JSONLoader} from '@loaders.gl/loader-utils';
|
|
64
69
|
|
|
65
70
|
// EXPERIMENTAL
|
|
@@ -95,3 +100,7 @@ export {
|
|
|
95
100
|
isReadableStream,
|
|
96
101
|
isWritableStream
|
|
97
102
|
} from '@loaders.gl/loader-utils';
|
|
103
|
+
|
|
104
|
+
// DEPRECATED EXPORTS
|
|
105
|
+
/** @deprecated Use NullLoader. */
|
|
106
|
+
export {NullWorkerLoader} from './null-loader';
|
|
@@ -43,30 +43,68 @@ async function* makeBrowserStreamIterator(
|
|
|
43
43
|
const reader = stream.getReader();
|
|
44
44
|
|
|
45
45
|
let nextBatchPromise: Promise<{done?: boolean; value?: Uint8Array}> | undefined;
|
|
46
|
+
let streamFinished = false;
|
|
47
|
+
let streamReadFailed = false;
|
|
48
|
+
let iteratorFailed = false;
|
|
46
49
|
|
|
47
50
|
try {
|
|
48
51
|
// eslint-disable-next-line no-constant-condition
|
|
49
52
|
while (true) {
|
|
50
53
|
const currentBatchPromise = nextBatchPromise || reader.read();
|
|
51
|
-
|
|
52
|
-
// Idea is to make fetching happen in parallel with processing / parsing
|
|
53
|
-
if (options?._streamReadAhead) {
|
|
54
|
-
nextBatchPromise = reader.read();
|
|
55
|
-
}
|
|
54
|
+
nextBatchPromise = undefined;
|
|
56
55
|
// Read from the stream
|
|
57
56
|
// value is a Uint8Array
|
|
58
|
-
|
|
57
|
+
let batch;
|
|
58
|
+
try {
|
|
59
|
+
batch = await currentBatchPromise;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
streamReadFailed = true;
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
const {done, value} = batch;
|
|
59
65
|
// Exit if we're done
|
|
60
66
|
if (done) {
|
|
67
|
+
streamFinished = true;
|
|
61
68
|
return;
|
|
62
69
|
}
|
|
70
|
+
// Issue a read for an additional batch while the current batch is processed
|
|
71
|
+
if (options?._streamReadAhead) {
|
|
72
|
+
nextBatchPromise = reader.read();
|
|
73
|
+
// Observe a prefetched rejection even if the consumer stops before requesting it
|
|
74
|
+
void nextBatchPromise.catch(() => {});
|
|
75
|
+
}
|
|
63
76
|
// Else yield the chunk
|
|
64
77
|
yield toArrayBuffer(value);
|
|
65
78
|
}
|
|
66
79
|
} catch (error) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
iteratorFailed = true;
|
|
81
|
+
throw error;
|
|
82
|
+
} finally {
|
|
83
|
+
let cleanupFailed = false;
|
|
84
|
+
let cleanupError: unknown;
|
|
85
|
+
|
|
86
|
+
if (!streamFinished && !streamReadFailed) {
|
|
87
|
+
try {
|
|
88
|
+
await reader.cancel();
|
|
89
|
+
} catch (error) {
|
|
90
|
+
cleanupFailed = true;
|
|
91
|
+
cleanupError = error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
reader.releaseLock();
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (!cleanupFailed) {
|
|
99
|
+
cleanupFailed = true;
|
|
100
|
+
cleanupError = error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Preserve errors from iteration instead of replacing them with cleanup errors
|
|
105
|
+
if (!iteratorFailed && cleanupFailed) {
|
|
106
|
+
throw cleanupError;
|
|
107
|
+
}
|
|
70
108
|
}
|
|
71
109
|
}
|
|
72
110
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {CoreAPI} from '@loaders.gl/loader-utils';
|
|
6
|
+
import {fetchFile} from '../fetch/fetch-file';
|
|
7
|
+
import {parse} from './parse';
|
|
8
|
+
import {parseFile} from './parse-file';
|
|
9
|
+
import {parseSync} from './parse-sync';
|
|
10
|
+
import {parseInBatches} from './parse-in-batches';
|
|
11
|
+
import {load} from './load';
|
|
12
|
+
import {loadInBatches} from './load-in-batches';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Shared Core API surface that can be injected into contexts and sources.
|
|
16
|
+
*/
|
|
17
|
+
export const coreApi: CoreAPI = Object.freeze({
|
|
18
|
+
fetchFile,
|
|
19
|
+
parse,
|
|
20
|
+
parseFile,
|
|
21
|
+
parseSync,
|
|
22
|
+
parseInBatches,
|
|
23
|
+
load,
|
|
24
|
+
loadInBatches
|
|
25
|
+
});
|
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
SourceLoader,
|
|
7
|
+
SourceArrayOptionsType,
|
|
8
|
+
SourceArrayDataSourceType
|
|
9
|
+
} from '@loaders.gl/loader-utils';
|
|
10
|
+
import {resolveAuthenticationOptions} from '@loaders.gl/loader-utils';
|
|
11
|
+
import {coreApi} from './core-api';
|
|
12
|
+
import {selectLoaderSync} from './select-loader';
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
15
|
* Creates a source from a service
|
|
@@ -13,39 +20,61 @@ import {Source, SourceArrayOptionsType, SourceArrayDataSourceType} from '@loader
|
|
|
13
20
|
*/
|
|
14
21
|
// DataSourceOptionsT extends DataSourceOptions = DataSourceOptions,
|
|
15
22
|
// DataSourceT extends DataSource = DataSource
|
|
16
|
-
export function createDataSource<SourceArrayT extends
|
|
17
|
-
data:
|
|
23
|
+
export function createDataSource<SourceArrayT extends SourceLoader[]>(
|
|
24
|
+
data: unknown,
|
|
18
25
|
sources: Readonly<SourceArrayT>,
|
|
19
|
-
options: Readonly<
|
|
26
|
+
options: Readonly<
|
|
27
|
+
SourceArrayOptionsType<SourceArrayT>
|
|
28
|
+
> = {} as SourceArrayOptionsType<SourceArrayT>
|
|
20
29
|
): SourceArrayDataSourceType<SourceArrayT> {
|
|
21
|
-
const
|
|
22
|
-
const
|
|
30
|
+
const resolvedOptions = (options || {}) as SourceArrayOptionsType<SourceArrayT>;
|
|
31
|
+
const type = resolvedOptions?.core?.type || (resolvedOptions.type as unknown as string) || 'auto';
|
|
32
|
+
const source =
|
|
33
|
+
sources.length === 1
|
|
34
|
+
? sources[0]
|
|
35
|
+
: type === 'auto'
|
|
36
|
+
? (selectLoaderSync(data as never, sources as unknown as SourceLoader[], {
|
|
37
|
+
// `createDataSource` supports non-fetch inputs such as in-memory tables.
|
|
38
|
+
// Selection remains best-effort for those cases.
|
|
39
|
+
...resolvedOptions,
|
|
40
|
+
core: {...resolvedOptions?.core, type: 'auto'}
|
|
41
|
+
}) as SourceArrayT[number] | null)
|
|
42
|
+
: getSourceOfType(type, sources);
|
|
23
43
|
|
|
24
44
|
if (!source) {
|
|
25
45
|
throw new Error('Not a valid source type');
|
|
26
46
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
url: string | Blob,
|
|
35
|
-
sources: Readonly<SourceArrayT>
|
|
36
|
-
): SourceArrayT[number] | null {
|
|
37
|
-
for (const service of sources) {
|
|
38
|
-
// @ts-expect-error
|
|
39
|
-
if (service.testURL && service.testURL(url)) {
|
|
40
|
-
return service;
|
|
41
|
-
}
|
|
47
|
+
const contributions = resolvedOptions.core?.credentials?.length
|
|
48
|
+
? source.getAuthentications?.(typeof data === 'string' ? data : '', resolvedOptions)
|
|
49
|
+
: undefined;
|
|
50
|
+
if (contributions && 'then' in contributions) {
|
|
51
|
+
// Avoid an unhandled rejection from a hook that cannot be awaited by this sync API.
|
|
52
|
+
void contributions.catch(() => {});
|
|
53
|
+
throw new Error('Use load() with an asynchronous getAuthentications() hook.');
|
|
42
54
|
}
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
const authenticatedOptions = resolveAuthenticationOptions(
|
|
56
|
+
contributions?.length
|
|
57
|
+
? {
|
|
58
|
+
...resolvedOptions,
|
|
59
|
+
core: {
|
|
60
|
+
...resolvedOptions.core,
|
|
61
|
+
authentications: [
|
|
62
|
+
...(resolvedOptions.core?.authentications || []),
|
|
63
|
+
...(contributions || [])
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
: resolvedOptions
|
|
68
|
+
);
|
|
69
|
+
return source.createDataSource(
|
|
70
|
+
data as string | Blob,
|
|
71
|
+
authenticatedOptions,
|
|
72
|
+
coreApi
|
|
73
|
+
) as SourceArrayDataSourceType<SourceArrayT>;
|
|
45
74
|
}
|
|
46
75
|
|
|
47
76
|
/** Guess service type from URL */
|
|
48
|
-
function getSourceOfType(type: string, sources: Readonly<
|
|
77
|
+
function getSourceOfType(type: string, sources: Readonly<SourceLoader[]>): SourceLoader | null {
|
|
49
78
|
for (const service of sources) {
|
|
50
79
|
if (service.type === type) {
|
|
51
80
|
return service;
|